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()
|
void CCallback::unregisterMyInterface()
|
||||||
{
|
{
|
||||||
ASSERT_IF_CALLED_WITH_PLAYER
|
ASSERT_IF_CALLED_WITH_PLAYER
|
||||||
|
auto playerInt = cl->playerint[*player];
|
||||||
|
|
||||||
cl->playerint.erase(*player);
|
cl->playerint.erase(*player);
|
||||||
cl->battleints.erase(*player);
|
cl->battleints.erase(*player);
|
||||||
//TODO? should callback be disabled as well?
|
//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()
|
void CCallback::validatePaths()
|
||||||
|
@ -649,7 +649,8 @@ void CAdvMapInt::deactivate()
|
|||||||
townList.deactivate();
|
townList.deactivate();
|
||||||
terrain.deactivate();
|
terrain.deactivate();
|
||||||
infoBar.deactivate();
|
infoBar.deactivate();
|
||||||
LOCPLINT->cingconsole->deactivate();
|
if(LOCPLINT)
|
||||||
|
LOCPLINT->cingconsole->deactivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CAdvMapInt::showAll(SDL_Surface * to)
|
void CAdvMapInt::showAll(SDL_Surface * to)
|
||||||
|
@ -129,21 +129,14 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
|||||||
|
|
||||||
CPlayerInterface::~CPlayerInterface()
|
CPlayerInterface::~CPlayerInterface()
|
||||||
{
|
{
|
||||||
howManyPeople--;
|
logGlobal->traceStream() << "\tHuman player interface for player " << playerID << " being destructed";
|
||||||
|
//howManyPeople--;
|
||||||
//delete pim;
|
//delete pim;
|
||||||
//vstd::clear_pointer(pim);
|
//vstd::clear_pointer(pim);
|
||||||
delete showingDialog;
|
delete showingDialog;
|
||||||
if(adventureInt)
|
|
||||||
{
|
|
||||||
if(adventureInt->active & CIntObject::KEYBOARD)
|
|
||||||
adventureInt->deactivateKeyboard();
|
|
||||||
delete adventureInt;
|
|
||||||
adventureInt = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete cingconsole;
|
delete cingconsole;
|
||||||
|
if(LOCPLINT == this)
|
||||||
LOCPLINT = nullptr;
|
LOCPLINT = nullptr;
|
||||||
}
|
}
|
||||||
void CPlayerInterface::init(shared_ptr<CCallback> CB)
|
void CPlayerInterface::init(shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
@ -381,6 +374,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->name % playerID);
|
||||||
|
|
||||||
const CArmedInstance *newSelection = nullptr;
|
const CArmedInstance *newSelection = nullptr;
|
||||||
if (makingTurn)
|
if (makingTurn)
|
||||||
@ -405,9 +399,9 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
|||||||
paths.erase(hero);
|
paths.erase(hero);
|
||||||
|
|
||||||
adventureInt->heroList.update(hero);
|
adventureInt->heroList.update(hero);
|
||||||
if (makingTurn)
|
if (makingTurn && newSelection)
|
||||||
adventureInt->select(newSelection, true);
|
adventureInt->select(newSelection, true);
|
||||||
else
|
else if(adventureInt->selection == hero)
|
||||||
adventureInt->selection = nullptr;
|
adventureInt->selection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,14 +613,11 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
|||||||
cb->registerBattleInterface(autofightingAI);
|
cb->registerBattleInterface(autofightingAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForAllDialogs();
|
//Don't wait for dialogs when we are non-active hot-seat player
|
||||||
|
if(LOCPLINT == this)
|
||||||
if(isAutoFightOn)
|
waitForAllDialogs();
|
||||||
GH.topInt()->deactivate();
|
|
||||||
|
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
GH.pushInt(battleInt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1569,6 +1560,10 @@ void CPlayerInterface::update()
|
|||||||
if(terminate_cond.get())
|
if(terminate_cond.get())
|
||||||
return;
|
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
|
//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());
|
||||||
|
|
||||||
@ -2067,8 +2062,6 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h
|
|||||||
void CPlayerInterface::gameOver(PlayerColor player, bool victory )
|
void CPlayerInterface::gameOver(PlayerColor player, bool victory )
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
if(LOCPLINT != this)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(player == playerID)
|
if(player == playerID)
|
||||||
{
|
{
|
||||||
@ -2076,17 +2069,30 @@ void CPlayerInterface::gameOver(PlayerColor player, bool victory )
|
|||||||
showInfoDialog(CGI->generaltexth->allTexts[95]);
|
showInfoDialog(CGI->generaltexth->allTexts[95]);
|
||||||
// else
|
// else
|
||||||
// showInfoDialog("Placeholder message: you won!");
|
// showInfoDialog("Placeholder message: you won!");
|
||||||
|
if(LOCPLINT == this)
|
||||||
makingTurn = true;
|
{
|
||||||
waitForAllDialogs(); //wait till all dialogs are displayed and closed
|
GH.curInt = this; //waiting for dialogs requires this to get events
|
||||||
makingTurn = false;
|
waitForAllDialogs(); //wait till all dialogs are displayed and closed
|
||||||
|
}
|
||||||
|
|
||||||
howManyPeople--;
|
howManyPeople--;
|
||||||
if(!howManyPeople //all human players eliminated
|
if(!howManyPeople //all human players eliminated
|
||||||
&& cb->getStartInfo()->mode != StartInfo::CAMPAIGN) //campaigns are handled in proposeNextMission
|
&& 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();
|
requestReturningToMainMenu();
|
||||||
}
|
}
|
||||||
|
if(GH.curInt == this)
|
||||||
|
GH.curInt = nullptr;
|
||||||
|
|
||||||
cb->unregisterMyInterface(); //we already won/lost, nothing else matters
|
cb->unregisterMyInterface(); //we already won/lost, nothing else matters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,6 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
|||||||
logNetwork->infoStream() << "Closed connection.";
|
logNetwork->infoStream() << "Closed connection.";
|
||||||
|
|
||||||
GH.curInt = nullptr;
|
GH.curInt = nullptr;
|
||||||
LOCPLINT->terminate_cond.setn(true);
|
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||||
logNetwork->infoStream() << "Ending current game!";
|
logNetwork->infoStream() << "Ending current game!";
|
||||||
@ -606,9 +605,11 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
if(!gNoGUI && (!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL))
|
if(!gNoGUI && (!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL))
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
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,
|
Rect((screen->w - 800)/2,
|
||||||
(screen->h - 600)/2, 800, 600), att, def);
|
(screen->h - 600)/2, 800, 600), att, def);
|
||||||
|
|
||||||
|
GH.pushInt(bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto callBattleStart = [&](PlayerColor color, ui8 side){
|
auto callBattleStart = [&](PlayerColor color, ui8 side){
|
||||||
|
@ -401,7 +401,7 @@ ui8 * CCreatureAnimation::getPixelAddr(SDL_Surface * dest, int X, int Y) const
|
|||||||
template<int bpp>
|
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
|
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);
|
putPixel<bpp>(getPixelAddr(dest, X, Y), palette[index], index, special);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5135,6 +5135,12 @@ void CGameHandler::checkLossVictory( PlayerColor player )
|
|||||||
sendAndApply(&ucs);
|
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
|
void CGameHandler::getLossVicMessage( PlayerColor player, si8 standard, bool victory, InfoWindow &out ) const
|
||||||
|
Loading…
Reference in New Issue
Block a user