mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* adventure map GUI should be properly blocked during AI turn
* battle window will wait till all dialogs are closed * fixed problems with AI working after the game ended * fixed problems with overzealous redrawing of infobar
This commit is contained in:
parent
08417cd42a
commit
e18419f5d2
@ -469,8 +469,7 @@ void VCAI::gameOver(ui8 player, bool victory)
|
|||||||
*(int*)NULL = 666;
|
*(int*)NULL = 666;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(makingTurn)
|
finish();
|
||||||
makingTurn->interrupt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,10 +1256,10 @@ bool VCAI::moveHeroToTile(int3 dst, const CGHeroInstance * h)
|
|||||||
//tlog0 << "Moving " << h->name << " from " << h->getPosition() << " to " << endpos << std::endl;
|
//tlog0 << "Moving " << h->name << " from " << h->getPosition() << " to " << endpos << std::endl;
|
||||||
cb->moveHero(h,CGHeroInstance::convertPosition(endpos, true));
|
cb->moveHero(h,CGHeroInstance::convertPosition(endpos, true));
|
||||||
waitTillFree(); //movement may cause battle or blocking dialog
|
waitTillFree(); //movement may cause battle or blocking dialog
|
||||||
|
boost::this_thread::interruption_point();
|
||||||
if(h->tempOwner != playerID) //we lost hero
|
if(h->tempOwner != playerID) //we lost hero
|
||||||
break;
|
break;
|
||||||
|
|
||||||
boost::this_thread::interruption_point();
|
|
||||||
}
|
}
|
||||||
ret = !i;
|
ret = !i;
|
||||||
}
|
}
|
||||||
@ -1662,6 +1661,12 @@ void VCAI::recruitHero(const CGTownInstance * t)
|
|||||||
cb->recruitHero(t, cb->getAvailableHeroes(t).front());
|
cb->recruitHero(t, cb->getAvailableHeroes(t).front());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCAI::finish()
|
||||||
|
{
|
||||||
|
if(makingTurn)
|
||||||
|
makingTurn->interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
AIStatus::AIStatus()
|
AIStatus::AIStatus()
|
||||||
{
|
{
|
||||||
battle = NO_BATTLE;
|
battle = NO_BATTLE;
|
||||||
|
@ -185,6 +185,7 @@ public:
|
|||||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||||
virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||||
virtual void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
virtual void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||||
|
virtual void finish() OVERRIDE;
|
||||||
|
|
||||||
virtual void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
|
virtual void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
|
||||||
virtual void heroMoved(const TryMoveHero & details) OVERRIDE;
|
virtual void heroMoved(const TryMoveHero & details) OVERRIDE;
|
||||||
|
@ -962,7 +962,9 @@ void CInfoBar::tick()
|
|||||||
toNextTick = -1;
|
toNextTick = -1;
|
||||||
mode = NOTHING;
|
mode = NOTHING;
|
||||||
}
|
}
|
||||||
redraw();
|
|
||||||
|
if(adventureInt == GH.topInt())
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInfoBar::show(SDL_Surface * to)
|
void CInfoBar::show(SDL_Surface * to)
|
||||||
@ -1042,6 +1044,7 @@ endTurn(CGI->generaltexth->zelp[302].first,CGI->generaltexth->zelp[302].second,
|
|||||||
heroList(ADVOPT.hlistSize),
|
heroList(ADVOPT.hlistSize),
|
||||||
townList(ADVOPT.tlistSize,ADVOPT.tlistX,ADVOPT.tlistY,ADVOPT.tlistAU,ADVOPT.tlistAD)//(5,&genRect(192,48,747,196),747,196,747,372),
|
townList(ADVOPT.tlistSize,ADVOPT.tlistX,ADVOPT.tlistY,ADVOPT.tlistAU,ADVOPT.tlistAD)//(5,&genRect(192,48,747,196),747,196,747,372),
|
||||||
{
|
{
|
||||||
|
duringAITurn = false;
|
||||||
state = NA;
|
state = NA;
|
||||||
spellBeingCasted = NULL;
|
spellBeingCasted = NULL;
|
||||||
pos.x = pos.y = 0;
|
pos.x = pos.y = 0;
|
||||||
@ -1248,55 +1251,65 @@ void CAdvMapInt::activate()
|
|||||||
tlog1 << "Error: advmapint already active...\n";
|
tlog1 << "Error: advmapint already active...\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
active |= GENERAL;
|
||||||
|
|
||||||
screenBuf = screen;
|
screenBuf = screen;
|
||||||
GH.statusbar = &statusbar;
|
GH.statusbar = &statusbar;
|
||||||
activateMouseMove();
|
if(!duringAITurn)
|
||||||
|
{
|
||||||
|
//assert(selection);
|
||||||
|
activateMouseMove();
|
||||||
|
|
||||||
kingOverview.activate();
|
kingOverview.activate();
|
||||||
underground.activate();
|
underground.activate();
|
||||||
questlog.activate();
|
questlog.activate();
|
||||||
sleepWake.activate();
|
sleepWake.activate();
|
||||||
moveHero.activate();
|
moveHero.activate();
|
||||||
spellbook.activate();
|
spellbook.activate();
|
||||||
sysOptions.activate();
|
sysOptions.activate();
|
||||||
advOptions.activate();
|
advOptions.activate();
|
||||||
nextHero.activate();
|
nextHero.activate();
|
||||||
endTurn.activate();
|
endTurn.activate();
|
||||||
|
|
||||||
minimap.activate();
|
minimap.activate();
|
||||||
heroList.activate();
|
heroList.activate();
|
||||||
townList.activate();
|
townList.activate();
|
||||||
terrain.activate();
|
terrain.activate();
|
||||||
infoBar.activate();
|
infoBar.activate();
|
||||||
|
|
||||||
if(!LOCPLINT->cingconsole->active)
|
if(!LOCPLINT->cingconsole->active)
|
||||||
LOCPLINT->cingconsole->activate();
|
LOCPLINT->cingconsole->activate();
|
||||||
GH.fakeMouseMove(); //to restore the cursor
|
GH.fakeMouseMove(); //to restore the cursor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void CAdvMapInt::deactivate()
|
void CAdvMapInt::deactivate()
|
||||||
{
|
{
|
||||||
deactivateMouseMove();
|
active &= ~GENERAL;
|
||||||
scrollingDir = 0;
|
if(!duringAITurn)
|
||||||
|
{
|
||||||
|
deactivateMouseMove();
|
||||||
|
scrollingDir = 0;
|
||||||
|
|
||||||
CCS->curh->changeGraphic(0,0);
|
CCS->curh->changeGraphic(0,0);
|
||||||
kingOverview.deactivate();
|
kingOverview.deactivate();
|
||||||
underground.deactivate();
|
underground.deactivate();
|
||||||
questlog.deactivate();
|
questlog.deactivate();
|
||||||
sleepWake.deactivate();
|
sleepWake.deactivate();
|
||||||
moveHero.deactivate();
|
moveHero.deactivate();
|
||||||
spellbook.deactivate();
|
spellbook.deactivate();
|
||||||
advOptions.deactivate();
|
advOptions.deactivate();
|
||||||
sysOptions.deactivate();
|
sysOptions.deactivate();
|
||||||
nextHero.deactivate();
|
nextHero.deactivate();
|
||||||
endTurn.deactivate();
|
endTurn.deactivate();
|
||||||
minimap.deactivate();
|
minimap.deactivate();
|
||||||
heroList.deactivate();
|
heroList.deactivate();
|
||||||
townList.deactivate();
|
townList.deactivate();
|
||||||
terrain.deactivate();
|
terrain.deactivate();
|
||||||
infoBar.deactivate();
|
infoBar.deactivate();
|
||||||
|
|
||||||
if(LOCPLINT->cingconsole->active) //TODO
|
if(LOCPLINT->cingconsole->active) //TODO
|
||||||
LOCPLINT->cingconsole->deactivate();
|
LOCPLINT->cingconsole->deactivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void CAdvMapInt::showAll(SDL_Surface * to)
|
void CAdvMapInt::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
@ -1715,6 +1728,10 @@ void CAdvMapInt::setPlayer(int Player)
|
|||||||
void CAdvMapInt::startTurn()
|
void CAdvMapInt::startTurn()
|
||||||
{
|
{
|
||||||
state = INGAME;
|
state = INGAME;
|
||||||
|
if(LOCPLINT->cb->getCurrentPlayer() == LOCPLINT->playerID)
|
||||||
|
{
|
||||||
|
adjustActiveness(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::endingTurn()
|
void CAdvMapInt::endingTurn()
|
||||||
@ -2086,6 +2103,24 @@ const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *ob
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAdvMapInt::aiTurnStarted()
|
||||||
|
{
|
||||||
|
adjustActiveness(true);
|
||||||
|
CCS->musich->playMusicFromSet(CCS->musich->aiMusics);
|
||||||
|
adventureInt->minimap.redraw();
|
||||||
|
adventureInt->infoBar.enemyTurn(LOCPLINT->cb->getCurrentPlayer(), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAdvMapInt::adjustActiveness(bool aiTurnStart)
|
||||||
|
{
|
||||||
|
bool wasActive = isActive();
|
||||||
|
|
||||||
|
if(wasActive)
|
||||||
|
deactivate();
|
||||||
|
adventureInt->duringAITurn = aiTurnStart;
|
||||||
|
if(wasActive)
|
||||||
|
activate();
|
||||||
|
}
|
||||||
CAdventureOptions::CAdventureOptions()
|
CAdventureOptions::CAdventureOptions()
|
||||||
{
|
{
|
||||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
@ -183,6 +183,7 @@ public:
|
|||||||
int3 position; //top left corner of visible map part
|
int3 position; //top left corner of visible map part
|
||||||
int player;
|
int player;
|
||||||
|
|
||||||
|
bool duringAITurn;
|
||||||
|
|
||||||
enum{LEFT=1, RIGHT=2, UP=4, DOWN=8};
|
enum{LEFT=1, RIGHT=2, UP=4, DOWN=8};
|
||||||
ui8 scrollingDir; //uses enum: LEFT RIGHT, UP, DOWN
|
ui8 scrollingDir; //uses enum: LEFT RIGHT, UP, DOWN
|
||||||
@ -255,6 +256,9 @@ public:
|
|||||||
void startHotSeatWait(int Player);
|
void startHotSeatWait(int Player);
|
||||||
void startTurn();
|
void startTurn();
|
||||||
void endingTurn();
|
void endingTurn();
|
||||||
|
void aiTurnStarted();
|
||||||
|
|
||||||
|
void adjustActiveness(bool aiTurnStart); //should be called everytime at AI/human turn transition; blocks GUI during AI turn
|
||||||
void tileLClicked(const int3 &mp);
|
void tileLClicked(const int3 &mp);
|
||||||
void tileHovered(const int3 &tile);
|
void tileHovered(const int3 &tile);
|
||||||
void tileRClicked(const int3 &mp);
|
void tileRClicked(const int3 &mp);
|
||||||
|
@ -577,11 +577,9 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(showingDialog->get())
|
waitForAllDialogs();
|
||||||
SDL_Delay(20);
|
|
||||||
|
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
|
|
||||||
GH.pushInt(battleInt);
|
GH.pushInt(battleInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,12 +1256,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
waitWhileDialog();
|
||||||
boost::unique_lock<boost::mutex> un(showingDialog->mx);
|
|
||||||
while(showingDialog->data)
|
|
||||||
showingDialog->cond.wait(un);
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
while(dialogs.size())
|
while(dialogs.size())
|
||||||
{
|
{
|
||||||
@ -1475,7 +1468,7 @@ void CPlayerInterface::update()
|
|||||||
if(terminate_cond.get())
|
if(terminate_cond.get())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim, boost::adopt_lock); //create lock from owned mutex (defer_lock)
|
boost::unique_lock<boost::recursive_mutex> un(*pim, boost::adopt_lock); //create lock from already owned mutex
|
||||||
//make sure that gamestate won't change when GUI objects may obtain its parts on event processing or drawing request
|
//make sure that gamestate won't change when GUI objects may obtain its parts on event processing or drawing request
|
||||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||||
|
|
||||||
@ -2371,15 +2364,23 @@ void CPlayerInterface::playerStartsTurn(ui8 player)
|
|||||||
{
|
{
|
||||||
waitWhileDialog();
|
waitWhileDialog();
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
|
adventureInt->aiTurnStarted();
|
||||||
adventureInt->minimap.redraw();
|
|
||||||
adventureInt->infoBar.enemyTurn(player, 0.5);
|
|
||||||
|
|
||||||
//TODO AI turn music
|
|
||||||
//TODO block GUI
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayerInterface::waitForAllDialogs()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
|
while(dialogs.size())
|
||||||
|
{
|
||||||
|
auto unlock = vstd::makeUnlockGuard(*pim);
|
||||||
|
SDL_Delay(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
waitWhileDialog();
|
||||||
|
}
|
||||||
|
|
||||||
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
|
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
|
||||||
{
|
{
|
||||||
spellbookLastPageBattle = spellbokLastPageAdvmap = 0;
|
spellbookLastPageBattle = spellbokLastPageAdvmap = 0;
|
||||||
|
@ -199,6 +199,7 @@ public:
|
|||||||
void garrisonChanged(const CGObjectInstance * obj, bool updateInfobox = true);
|
void garrisonChanged(const CGObjectInstance * obj, bool updateInfobox = true);
|
||||||
void heroKilled(const CGHeroInstance* hero);
|
void heroKilled(const CGHeroInstance* hero);
|
||||||
void waitWhileDialog();
|
void waitWhileDialog();
|
||||||
|
void waitForAllDialogs();
|
||||||
bool shiftPressed() const; //determines if shift key is pressed (left or right or both)
|
bool shiftPressed() const; //determines if shift key is pressed (left or right or both)
|
||||||
bool ctrlPressed() const; //determines if ctrl key is pressed (left or right or both)
|
bool ctrlPressed() const; //determines if ctrl key is pressed (left or right or both)
|
||||||
bool altPressed() const; //determines if alt key is pressed (left or right or both)
|
bool altPressed() const; //determines if alt key is pressed (left or right or both)
|
||||||
|
@ -180,6 +180,10 @@ void CClient::save(const std::string & fname)
|
|||||||
|
|
||||||
void CClient::endGame( bool closeConnection /*= true*/ )
|
void CClient::endGame( bool closeConnection /*= true*/ )
|
||||||
{
|
{
|
||||||
|
//suggest interfaces to finish their stuff (AI should interrupt any bg working threads)
|
||||||
|
BOOST_FOREACH(auto i, playerint)
|
||||||
|
i.second->finish();
|
||||||
|
|
||||||
// Game is ending
|
// Game is ending
|
||||||
// Tell the network thread to reach a stable state
|
// Tell the network thread to reach a stable state
|
||||||
if(closeConnection)
|
if(closeConnection)
|
||||||
|
@ -78,6 +78,7 @@ public:
|
|||||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||||
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||||
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
||||||
|
virtual void finish(){}; //if for some reason we want to end
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CDynLibHandler
|
class DLL_LINKAGE CDynLibHandler
|
||||||
|
Loading…
Reference in New Issue
Block a user