From 1ba3dfb1b846d64089f82e397ad5069419dcecfb Mon Sep 17 00:00:00 2001 From: Desmond Brand Date: Sun, 15 Jun 2014 17:03:39 -0700 Subject: [PATCH] Enforce active turn for first warring human Who knows if this will have bad side-effects, but it seems to work in the lobby. Test plan: Load up my bad save game and check that India's turn is active in the lobby. It does. Hopefully we can make it through India's turn and then through every other warring players turns too. Fingers crossed on that. Also, I tried to reproduce the bad save game in a two player game. Unfortunately (?), this game seems to load fine. I can load this working save with the patch applied, and have verified that it doesn't break anything. --- CvGameCoreDLL_Expansion2/CvPlayer.cpp | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/CvGameCoreDLL_Expansion2/CvPlayer.cpp b/CvGameCoreDLL_Expansion2/CvPlayer.cpp index 1684ac35..8a472e34 100644 --- a/CvGameCoreDLL_Expansion2/CvPlayer.cpp +++ b/CvGameCoreDLL_Expansion2/CvPlayer.cpp @@ -22194,6 +22194,50 @@ void CvPlayer::Read(FDataStream& kStream) //m_pDiplomacyRequests->Read(kStream); } + /** + * Warring sequential humans deadlock fix + * + * Upon loading an autosave, all human players at war were loaded into the + * game with inactive turns, making it impossible for them to end the turn. + * + * The following hack detects and fixes that problem by forcing the first + * human player in sequential turn mode to be active. + * + * Hopefully this has no side effects but it's impossible for me to know. + */ + if(GC.getGame().isOption(GAMEOPTION_DYNAMIC_TURNS) && isHuman()) { + NET_MESSAGE_DEBUG_OSTR_ALWAYS("read() for human player " << getName()); + NET_MESSAGE_DEBUG_OSTR_ALWAYS("m_bTurnActive is " << m_bTurnActive); + NET_MESSAGE_DEBUG_OSTR_ALWAYS("m_bAutoMoves is " << m_bAutoMoves); + NET_MESSAGE_DEBUG_OSTR_ALWAYS("m_bProcessedAutoMoves is " << m_bProcessedAutoMoves); + NET_MESSAGE_DEBUG_OSTR_ALWAYS("m_bDynamicTurnsSimultMode is " << m_bDynamicTurnsSimultMode); + + if (!m_bDynamicTurnsSimultMode) { + // this human is in sequential turns mode, + // so make sure there is an active human in the game + static bool s_bVerified1stSeqentialHumanIsActive = false; + if (!s_bVerified1stSeqentialHumanIsActive) { + s_bVerified1stSeqentialHumanIsActive = true; + + if (m_bTurnActive) { + NET_MESSAGE_DEBUG_OSTR_ALWAYS( + "first sequential human was already active"); + } else { + NET_MESSAGE_DEBUG_OSTR_ALWAYS( + "hacktivating unexpectedly inactive player :("); + + // force the player to be active + m_bTurnActive = true; + + // also turn off automoves - without this, the turn + // becomes inactive before the player can do anything + m_bAutoMoves = false; + m_bProcessedAutoMoves = false; + } + } + } + } + if(m_bTurnActive) GC.getGame().changeNumGameTurnActive(1, std::string("setTurnActive() [loading save game] for player ") + getName());