mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fixed crash in battles, when attempted to access <0 screen coordinates.
This commit is contained in:
parent
708b0c6f47
commit
385f4ab7f5
@ -351,9 +351,17 @@ void CCallback::castSpell(const CGHeroInstance *hero, SpellID spellID, const int
|
||||
void CCallback::unregisterMyInterface()
|
||||
{
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
auto playerInt = cl->playerint[*player];
|
||||
|
||||
cl->playerint.erase(*player);
|
||||
cl->battleints.erase(*player);
|
||||
//TODO? should callback be disabled as well?
|
||||
|
||||
//Disabled interface will be deleted very soon, so switch LOCPLINT to next player available
|
||||
if(playerInt == LOCPLINT && cl->playerint.size())
|
||||
{
|
||||
LOCPLINT = dynamic_cast<CPlayerInterface*>(cl->playerint.begin()->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CCallback::validatePaths()
|
||||
|
@ -649,6 +649,7 @@ void CAdvMapInt::deactivate()
|
||||
townList.deactivate();
|
||||
terrain.deactivate();
|
||||
infoBar.deactivate();
|
||||
if(LOCPLINT)
|
||||
LOCPLINT->cingconsole->deactivate();
|
||||
}
|
||||
}
|
||||
|
@ -129,20 +129,13 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
||||
|
||||
CPlayerInterface::~CPlayerInterface()
|
||||
{
|
||||
howManyPeople--;
|
||||
logGlobal->traceStream() << "\tHuman player interface for player " << playerID << " being destructed";
|
||||
//howManyPeople--;
|
||||
//delete pim;
|
||||
//vstd::clear_pointer(pim);
|
||||
delete showingDialog;
|
||||
if(adventureInt)
|
||||
{
|
||||
if(adventureInt->active & CIntObject::KEYBOARD)
|
||||
adventureInt->deactivateKeyboard();
|
||||
delete adventureInt;
|
||||
adventureInt = nullptr;
|
||||
}
|
||||
|
||||
delete cingconsole;
|
||||
|
||||
if(LOCPLINT == this)
|
||||
LOCPLINT = nullptr;
|
||||
}
|
||||
void CPlayerInterface::init(shared_ptr<CCallback> CB)
|
||||
@ -381,6 +374,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->name % playerID);
|
||||
|
||||
const CArmedInstance *newSelection = nullptr;
|
||||
if (makingTurn)
|
||||
@ -405,9 +399,9 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
paths.erase(hero);
|
||||
|
||||
adventureInt->heroList.update(hero);
|
||||
if (makingTurn)
|
||||
if (makingTurn && newSelection)
|
||||
adventureInt->select(newSelection, true);
|
||||
else
|
||||
else if(adventureInt->selection == hero)
|
||||
adventureInt->selection = nullptr;
|
||||
}
|
||||
|
||||
@ -619,14 +613,11 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
||||
cb->registerBattleInterface(autofightingAI);
|
||||
}
|
||||
|
||||
//Don't wait for dialogs when we are non-active hot-seat player
|
||||
if(LOCPLINT == this)
|
||||
waitForAllDialogs();
|
||||
|
||||
if(isAutoFightOn)
|
||||
GH.topInt()->deactivate();
|
||||
|
||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||
|
||||
GH.pushInt(battleInt);
|
||||
}
|
||||
|
||||
|
||||
@ -1569,6 +1560,10 @@ void CPlayerInterface::update()
|
||||
if(terminate_cond.get())
|
||||
return;
|
||||
|
||||
//While mutexes were locked away we may be have stopped being the active interface
|
||||
if(LOCPLINT != this)
|
||||
return;
|
||||
|
||||
//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());
|
||||
|
||||
@ -2067,8 +2062,6 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h
|
||||
void CPlayerInterface::gameOver(PlayerColor player, bool victory )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if(LOCPLINT != this)
|
||||
return;
|
||||
|
||||
if(player == playerID)
|
||||
{
|
||||
@ -2076,17 +2069,30 @@ void CPlayerInterface::gameOver(PlayerColor player, bool victory )
|
||||
showInfoDialog(CGI->generaltexth->allTexts[95]);
|
||||
// else
|
||||
// showInfoDialog("Placeholder message: you won!");
|
||||
|
||||
makingTurn = true;
|
||||
if(LOCPLINT == this)
|
||||
{
|
||||
GH.curInt = this; //waiting for dialogs requires this to get events
|
||||
waitForAllDialogs(); //wait till all dialogs are displayed and closed
|
||||
makingTurn = false;
|
||||
}
|
||||
|
||||
howManyPeople--;
|
||||
if(!howManyPeople //all human players eliminated
|
||||
&& cb->getStartInfo()->mode != StartInfo::CAMPAIGN) //campaigns are handled in proposeNextMission
|
||||
{
|
||||
if(adventureInt)
|
||||
{
|
||||
terminate_cond.setn(true);
|
||||
adventureInt->deactivate();
|
||||
if(GH.topInt() == adventureInt)
|
||||
GH.popInt(adventureInt);
|
||||
delete adventureInt;
|
||||
adventureInt = nullptr;
|
||||
}
|
||||
requestReturningToMainMenu();
|
||||
}
|
||||
if(GH.curInt == this)
|
||||
GH.curInt = nullptr;
|
||||
|
||||
cb->unregisterMyInterface(); //we already won/lost, nothing else matters
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,6 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
logNetwork->infoStream() << "Closed connection.";
|
||||
|
||||
GH.curInt = nullptr;
|
||||
LOCPLINT->terminate_cond.setn(true);
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
logNetwork->infoStream() << "Ending current game!";
|
||||
@ -606,9 +605,11 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
if(!gNoGUI && (!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL))
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
||||
auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
||||
Rect((screen->w - 800)/2,
|
||||
(screen->h - 600)/2, 800, 600), att, def);
|
||||
|
||||
GH.pushInt(bi);
|
||||
}
|
||||
|
||||
auto callBattleStart = [&](PlayerColor color, ui8 side){
|
||||
|
@ -401,7 +401,7 @@ ui8 * CCreatureAnimation::getPixelAddr(SDL_Surface * dest, int X, int Y) const
|
||||
template<int bpp>
|
||||
inline void CCreatureAnimation::putPixelAt(SDL_Surface * dest, int X, int Y, size_t index, const std::array<SDL_Color, 8> & special) const
|
||||
{
|
||||
if ( X < pos.x + pos.w && Y < pos.y + pos.h)
|
||||
if ( X < pos.x + pos.w && Y < pos.y + pos.h && X >= 0 && Y >= 0)
|
||||
putPixel<bpp>(getPixelAddr(dest, X, Y), palette[index], index, special);
|
||||
}
|
||||
|
||||
|
@ -5135,6 +5135,12 @@ void CGameHandler::checkLossVictory( PlayerColor player )
|
||||
sendAndApply(&ucs);
|
||||
}
|
||||
}
|
||||
|
||||
//If player making turn has lost his turn must be over as well
|
||||
if(gs->getPlayer(gs->currentPlayer)->status != EPlayerStatus::INGAME)
|
||||
{
|
||||
states.setFlag(gs->currentPlayer, &PlayerStatus::makingTurn, false);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::getLossVicMessage( PlayerColor player, si8 standard, bool victory, InfoWindow &out ) const
|
||||
|
Loading…
Reference in New Issue
Block a user