1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Stabilize vcmi (#488)

* Shared statusbar
* Fixed server fails on client disconnected
This commit is contained in:
KasyanDiGris 2018-08-26 19:09:56 +03:00 committed by Alexander Shishkin
parent 96494332a2
commit fa5a14e2d8
13 changed files with 53 additions and 44 deletions

View File

@ -59,7 +59,7 @@ class CGuiHandler
public:
CFramerateManager * mainFPSmng; //to keep const framerate
std::list<std::shared_ptr<IShowActivatable>> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
CGStatusBar * statusbar;
std::shared_ptr<CGStatusBar> statusbar;
private:
std::vector<std::shared_ptr<IShowActivatable>> disposed;

View File

@ -370,7 +370,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
blitAt(CPicture("MUMAP.bmp"), 16, 77, *background);
pos = background->center(); //center, window has size of bg graphic
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 465, 440, 18), 0)); //226, 472
statusBar = CGStatusBar::create(std::make_shared<CPicture>(Rect(7, 465, 440, 18), 0)); //226, 472
playerName = std::make_shared<CTextInput>(Rect(19, 436, 334, 16), *background);
playerName->setText(settings["general"]["playerName"].String());
playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1);
@ -420,7 +420,7 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S
buttonOk = std::make_shared<CButton>(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), SDLK_RETURN);
buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 381, 348, 18), 0)); //226, 472
statusBar = CGStatusBar::create(std::make_shared<CPicture>(Rect(7, 381, 348, 18), 0)); //226, 472
inputNames[0]->setText(firstPlayer, true);
inputNames[0]->giveFocus();
@ -478,7 +478,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
inputPort->setText(CServerHandler::getDefaultPortStr(), true);
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 186, 218, 18), 0));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(Rect(7, 186, 218, 18), 0));
}
void CSimpleJoinScreen::connectToServer()

View File

@ -351,7 +351,6 @@ void CGStatusBar::clear()
CGStatusBar::CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font, EAlignment Align, const SDL_Color & Color)
: CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "")
{
init();
background = background_;
addChild(background.get());
pos = background->pos;
@ -363,7 +362,6 @@ CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw)
: CLabel(x, y, FONT_SMALL, CENTER)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
init();
background = std::make_shared<CPicture>(name);
pos = background->pos;
if((unsigned int)maxw < pos.w)
@ -387,7 +385,7 @@ void CGStatusBar::show(SDL_Surface * to)
void CGStatusBar::init()
{
oldStatusBar = GH.statusbar;
GH.statusbar = this;
GH.statusbar = shared_from_this();
}
Point CGStatusBar::getBorderSize()

View File

@ -114,23 +114,31 @@ public:
};
/// Status bar which is shown at the bottom of the in-game screens
class CGStatusBar : public CLabel
class CGStatusBar : public CLabel, public std::enable_shared_from_this<CGStatusBar>
{
bool textLock; //Used for blocking changes to the text
void init();
CGStatusBar * oldStatusBar;
std::shared_ptr<CGStatusBar> oldStatusBar;
CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color & Color = Colors::WHITE);
CGStatusBar(int x, int y, std::string name, int maxw = -1);
protected:
Point getBorderSize() override;
public:
template<typename ...Args>
static std::shared_ptr<CGStatusBar> create(Args... args)
{
std::shared_ptr<CGStatusBar> ret{new CGStatusBar{args...}};
ret->init();
return ret;
}
void clear();//clears statusbar and refreshes
void setText(const std::string & Text) override; //prints text and refreshes statusbar
void show(SDL_Surface * to) override; //shows statusbar (with current text)
CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color & Color = Colors::WHITE);
CGStatusBar(int x, int y, std::string name, int maxw = -1);
~CGStatusBar();
void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called

View File

@ -244,7 +244,7 @@ void CTerrainRect::hover(bool on)
{
if (!on)
{
adventureInt->statusbar.clear();
adventureInt->statusbar->clear();
CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
}
//Hoverable::hover(on);
@ -555,7 +555,7 @@ CAdvMapInt::CAdvMapInt():
mode(EAdvMapMode::NORMAL),
worldViewScale(0.0f), //actual init later in changeMode
minimap(Rect(ADVOPT.minimapX, ADVOPT.minimapY, ADVOPT.minimapW, ADVOPT.minimapH)),
statusbar(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG),
statusbar(CGStatusBar::create(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG)),
heroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD),
townList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD),
infoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192)), state(NA),
@ -930,7 +930,7 @@ void CAdvMapInt::activate()
CIntObject::activate(KEYBOARD);
screenBuf = screen;
GH.statusbar = &statusbar;
GH.statusbar = statusbar;
if(!duringAITurn)
{
activeMapPanel->activate();
@ -1001,7 +1001,7 @@ void CAdvMapInt::showAll(SDL_Surface * to)
resdatabar.showAll(to);
statusbar.show(to);
statusbar->show(to);
LOCPLINT->cingconsole->show(to);
}
@ -1079,7 +1079,7 @@ void CAdvMapInt::show(SDL_Surface * to)
}
infoBar.show(to);
statusbar.showAll(to);
statusbar->showAll(to);
}
void CAdvMapInt::handleMapScrollingUpdate()
@ -1645,7 +1645,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
if(!LOCPLINT->cb->isVisible(mapPos))
{
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
statusbar.clear();
statusbar->clear();
return;
}
auto objRelations = PlayerRelations::ALLIES;
@ -1655,13 +1655,13 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
objRelations = LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner);
std::string text = curHero() ? objAtTile->getHoverText(curHero()) : objAtTile->getHoverText(LOCPLINT->playerID);
boost::replace_all(text,"\n"," ");
statusbar.setText(text);
statusbar->setText(text);
}
else
{
std::string hlp;
CGI->mh->getTerrainDescr(mapPos, hlp, false);
statusbar.setText(hlp);
statusbar->setText(hlp);
}
if(spellBeingCasted)

View File

@ -168,7 +168,7 @@ public:
SDL_Surface * bgWorldView;
std::vector<std::shared_ptr<CAnimImage>> gems;
CMinimap minimap;
CGStatusBar statusbar;
std::shared_ptr<CGStatusBar> statusbar;
std::shared_ptr<CButton> kingOverview;
std::shared_ptr<CButton> underground;

View File

@ -1130,7 +1130,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
Rect barRect(9, 182, 732, 18);
auto statusbarBackground = std::make_shared<CPicture>(*(panel.get()), barRect, 9, 555, false);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
resdatabar = std::make_shared<CResDataBar>("ARESBAR", 3, 575, 32, 2, 85, 85);
townlist = std::make_shared<CTownList>(3, Point(744, 414), "IAM014", "IAM015");
@ -1326,7 +1326,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
Rect barRect(5, 556, 740, 18);
auto statusbarBackground = std::make_shared<CPicture>(*background, barRect, 5, 556, false);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->Name());
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, SDLK_RETURN);
@ -1373,7 +1373,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
auto statusbarBackground = std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
name = std::make_shared<CLabel>(197, 30, FONT_MEDIUM, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->hcommands[7]) % building->Name()));
description = std::make_shared<CTextBox>(building->Description(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, CENTER);
@ -1549,7 +1549,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
Rect barRect(4, 554, 740, 18);
auto statusbarBackground = std::make_shared<CPicture>(*background, barRect, 4, 554, false);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
}
std::string CFortScreen::getBgName(const CGTownInstance * town)
@ -1690,7 +1690,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem)
Rect barRect(7, 556, 737, 18);
auto statusbarBackground = std::make_shared<CPicture>(*background, barRect, 7, 556, false);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE);
@ -1757,7 +1757,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
Rect barRect(8, pos.h - 26, pos.w - 16, 19);
auto statusbarBackground = std::make_shared<CPicture>(*background, barRect, 8, pos.h - 26, false);
statusbar = std::make_shared<CGStatusBar>(statusbarBackground);
statusbar = CGStatusBar::create(statusbarBackground);
animBG = std::make_shared<CPicture>("TPSMITBK", 64, 50);
animBG->needRefresh = true;

View File

@ -110,7 +110,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
name = std::make_shared<CLabel>(190, 38, EFonts::FONT_BIG, EAlignment::CENTER, Colors::YELLOW);
title = std::make_shared<CLabel>(190, 65, EFonts::FONT_MEDIUM, EAlignment::CENTER, Colors::WHITE);
statusBar = std::make_shared<CGStatusBar>(7, 559, "ADROLLVR.bmp", 660);
statusBar = CGStatusBar::create(7, 559, "ADROLLVR.bmp", 660);
quitButton = std::make_shared<CButton>(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, SDLK_RETURN);
quitButton->assignedKeys.insert(SDLK_ESCAPE);

View File

@ -472,7 +472,7 @@ CKingdomInterface::CKingdomInterface()
generateMinesList(ownedObjects);
generateButtons();
statusbar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>("KSTATBAR", 10,pos.h - 45));
statusbar = CGStatusBar::create(std::make_shared<CPicture>("KSTATBAR", 10,pos.h - 45));
resdatabar = std::make_shared<CResDataBar>("KRESBAR", 3, 111+footerPos, 32, 2, 76, 76);
}

View File

@ -184,7 +184,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
for(auto item : schoolBorders)
item->preload();
mana = std::make_shared<CLabel>(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana));
statusBar = std::make_shared<CGStatusBar>(7, 569, "Spelroll.bmp");
statusBar = CGStatusBar::create(7, 569, "Spelroll.bmp");
SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y);
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fexitb, this), 460, this));

View File

@ -659,7 +659,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
madeTransaction = false;
bool sliderNeeded = true;
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
std::string title;
@ -1135,7 +1135,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero,
//Total experience on the Altar
texts.push_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW));
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, SDLK_RETURN);
ok->assignedKeys.insert(SDLK_ESCAPE);

View File

@ -205,7 +205,7 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, c
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
slider = std::make_shared<CSlider>(Point(176,279),135,std::bind(&CRecruitmentWindow::sliderMoved,this, _1),0,0,0,true);
@ -656,7 +656,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj)
auto rumorText = boost::str(boost::format(CGI->generaltexth->allTexts[216]) % LOCPLINT->cb->getTavernRumor(tavernObj));
rumor = std::make_shared<CTextBox>(rumorText, Rect(32, 190, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
cancel = std::make_shared<CButton>(Point(310, 428), "ICANCEL.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), SDLK_ESCAPE);
recruit = std::make_shared<CButton>(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN);
thiefGuild = std::make_shared<CButton>(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t);
@ -920,7 +920,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
questlogButton[1] = std::make_shared<CButton>(Point(740, 44), "hsbtns4.def", CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1));
Rect barRect(5, 578, 725, 18);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, barRect, 5, 578, false));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, barRect, 5, 578, false));
//garrison interface
garr = std::make_shared<CGarrisonInt>(69, 131, 4, Point(418,0), heroInst[0], heroInst[1], true, true);
@ -1013,7 +1013,7 @@ CShipyardWindow::CShipyardWindow(const std::vector<si32> & cost, int state, int
}
}
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
title = std::make_shared<CLabel>(164, 27, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[13]);
costLabel = std::make_shared<CLabel>(164, 220, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->jktexts[14]);
@ -1178,7 +1178,7 @@ CTransformerWindow::CTransformerWindow(const CGHeroInstance * _hero, const CGTow
all = std::make_shared<CButton>(Point(146, 416), "ALTARMY.DEF", CGI->generaltexth->zelp[590], [&](){ addAll(); }, SDLK_a);
convert = std::make_shared<CButton>(Point(269, 416), "ALTSACR.DEF", CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, SDLK_RETURN);
cancel = std::make_shared<CButton>(Point(392, 416), "ICANCEL.DEF", CGI->generaltexth->zelp[592], [&](){ close(); },SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
titleLeft = std::make_shared<CLabel>(153, 29,FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[485]);//holding area
titleRight = std::make_shared<CLabel>(153+295, 29, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[486]);//transformer
@ -1283,7 +1283,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
items.push_back(std::make_shared<CItem>(this, goods[i], 54+i*104, 234));
cancel = std::make_shared<CButton>(Point(200, 313), "IOKAY.DEF", CGI->generaltexth->zelp[632], [&](){ close(); }, SDLK_RETURN);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
}
void CUniversityWindow::makeDeal(int skill)
@ -1324,7 +1324,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo
confirm->block(!available);
cancel = std::make_shared<CButton>(Point(252,299), "ICANCEL.DEF", CGI->generaltexth->zelp[631], [&](){ close(); }, SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
}
void CUnivConfirmWindow::makeDeal(int skill)
@ -1409,7 +1409,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI
upgradeAll->addImage(image);
quit = std::make_shared<CButton>(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), SDLK_RETURN);
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
statusBar = CGStatusBar::create(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
garr = std::make_shared<CGarrisonInt>(108, 60, 18, Point(), hero, nullptr);
updateGarrisons();
@ -1590,7 +1590,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
exitb = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, SDLK_RETURN);
exitb->assignedKeys.insert(SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(3, 555, "TStatBar.bmp", 742);
statusBar = CGStatusBar::create(3, 555, "TStatBar.bmp", 742);
resdatabar = std::make_shared<CMinorResDataBar>();
resdatabar->moveBy(pos.topLeft(), true);

View File

@ -443,14 +443,17 @@ void CVCMIServer::clientConnected(std::shared_ptr<CConnection> c, std::vector<st
void CVCMIServer::clientDisconnected(std::shared_ptr<CConnection> c)
{
connections -= c;
for(auto & pair : playerNames)
for(auto it = playerNames.begin(); it != playerNames.end();)
{
if(pair.second.connection != c->connectionID)
if(it->second.connection != c->connectionID)
{
it++;
continue;
}
int id = pair.first;
int id = it->first;
announceTxt(boost::str(boost::format("%s (pid %d cid %d) left the game") % id % playerNames[id].name % c->connectionID));
playerNames.erase(id);
playerNames.erase(it++);
// Reset in-game players client used back to AI
if(PlayerSettings * s = si->getPlayersSettings(id))