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;
|
||||
}
|
||||
|
||||
if(makingTurn)
|
||||
makingTurn->interrupt();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,10 +1256,10 @@ bool VCAI::moveHeroToTile(int3 dst, const CGHeroInstance * h)
|
||||
//tlog0 << "Moving " << h->name << " from " << h->getPosition() << " to " << endpos << std::endl;
|
||||
cb->moveHero(h,CGHeroInstance::convertPosition(endpos, true));
|
||||
waitTillFree(); //movement may cause battle or blocking dialog
|
||||
boost::this_thread::interruption_point();
|
||||
if(h->tempOwner != playerID) //we lost hero
|
||||
break;
|
||||
|
||||
boost::this_thread::interruption_point();
|
||||
}
|
||||
ret = !i;
|
||||
}
|
||||
@ -1662,6 +1661,12 @@ void VCAI::recruitHero(const CGTownInstance * t)
|
||||
cb->recruitHero(t, cb->getAvailableHeroes(t).front());
|
||||
}
|
||||
|
||||
void VCAI::finish()
|
||||
{
|
||||
if(makingTurn)
|
||||
makingTurn->interrupt();
|
||||
}
|
||||
|
||||
AIStatus::AIStatus()
|
||||
{
|
||||
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 serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||
virtual void finish() OVERRIDE;
|
||||
|
||||
virtual void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
|
||||
virtual void heroMoved(const TryMoveHero & details) OVERRIDE;
|
||||
|
@ -962,6 +962,8 @@ void CInfoBar::tick()
|
||||
toNextTick = -1;
|
||||
mode = NOTHING;
|
||||
}
|
||||
|
||||
if(adventureInt == GH.topInt())
|
||||
redraw();
|
||||
}
|
||||
|
||||
@ -1042,6 +1044,7 @@ endTurn(CGI->generaltexth->zelp[302].first,CGI->generaltexth->zelp[302].second,
|
||||
heroList(ADVOPT.hlistSize),
|
||||
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;
|
||||
spellBeingCasted = NULL;
|
||||
pos.x = pos.y = 0;
|
||||
@ -1248,8 +1251,13 @@ void CAdvMapInt::activate()
|
||||
tlog1 << "Error: advmapint already active...\n";
|
||||
return;
|
||||
}
|
||||
active |= GENERAL;
|
||||
|
||||
screenBuf = screen;
|
||||
GH.statusbar = &statusbar;
|
||||
if(!duringAITurn)
|
||||
{
|
||||
//assert(selection);
|
||||
activateMouseMove();
|
||||
|
||||
kingOverview.activate();
|
||||
@ -1273,7 +1281,11 @@ void CAdvMapInt::activate()
|
||||
LOCPLINT->cingconsole->activate();
|
||||
GH.fakeMouseMove(); //to restore the cursor
|
||||
}
|
||||
}
|
||||
void CAdvMapInt::deactivate()
|
||||
{
|
||||
active &= ~GENERAL;
|
||||
if(!duringAITurn)
|
||||
{
|
||||
deactivateMouseMove();
|
||||
scrollingDir = 0;
|
||||
@ -1298,6 +1310,7 @@ void CAdvMapInt::deactivate()
|
||||
if(LOCPLINT->cingconsole->active) //TODO
|
||||
LOCPLINT->cingconsole->deactivate();
|
||||
}
|
||||
}
|
||||
void CAdvMapInt::showAll(SDL_Surface * to)
|
||||
{
|
||||
blitAt(bg,0,0,to);
|
||||
@ -1715,6 +1728,10 @@ void CAdvMapInt::setPlayer(int Player)
|
||||
void CAdvMapInt::startTurn()
|
||||
{
|
||||
state = INGAME;
|
||||
if(LOCPLINT->cb->getCurrentPlayer() == LOCPLINT->playerID)
|
||||
{
|
||||
adjustActiveness(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::endingTurn()
|
||||
@ -2086,6 +2103,24 @@ const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *ob
|
||||
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()
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
@ -183,6 +183,7 @@ public:
|
||||
int3 position; //top left corner of visible map part
|
||||
int player;
|
||||
|
||||
bool duringAITurn;
|
||||
|
||||
enum{LEFT=1, RIGHT=2, UP=4, DOWN=8};
|
||||
ui8 scrollingDir; //uses enum: LEFT RIGHT, UP, DOWN
|
||||
@ -255,6 +256,9 @@ public:
|
||||
void startHotSeatWait(int Player);
|
||||
void startTurn();
|
||||
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 tileHovered(const int3 &tile);
|
||||
void tileRClicked(const int3 &mp);
|
||||
|
@ -577,11 +577,9 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
||||
return;
|
||||
}
|
||||
|
||||
while(showingDialog->get())
|
||||
SDL_Delay(20);
|
||||
waitForAllDialogs();
|
||||
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
|
||||
GH.pushInt(battleInt);
|
||||
}
|
||||
|
||||
@ -1258,12 +1256,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(showingDialog->mx);
|
||||
while(showingDialog->data)
|
||||
showingDialog->cond.wait(un);
|
||||
}
|
||||
|
||||
waitWhileDialog();
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
while(dialogs.size())
|
||||
{
|
||||
@ -1475,7 +1468,7 @@ void CPlayerInterface::update()
|
||||
if(terminate_cond.get())
|
||||
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
|
||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||
|
||||
@ -2371,15 +2364,23 @@ void CPlayerInterface::playerStartsTurn(ui8 player)
|
||||
{
|
||||
waitWhileDialog();
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
|
||||
adventureInt->minimap.redraw();
|
||||
adventureInt->infoBar.enemyTurn(player, 0.5);
|
||||
|
||||
//TODO AI turn music
|
||||
//TODO block GUI
|
||||
adventureInt->aiTurnStarted();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
spellbookLastPageBattle = spellbokLastPageAdvmap = 0;
|
||||
|
@ -199,6 +199,7 @@ public:
|
||||
void garrisonChanged(const CGObjectInstance * obj, bool updateInfobox = true);
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
void waitWhileDialog();
|
||||
void waitForAllDialogs();
|
||||
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 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*/ )
|
||||
{
|
||||
//suggest interfaces to finish their stuff (AI should interrupt any bg working threads)
|
||||
BOOST_FOREACH(auto i, playerint)
|
||||
i.second->finish();
|
||||
|
||||
// Game is ending
|
||||
// Tell the network thread to reach a stable state
|
||||
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 serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user