From 0c35ec915c669629b856a6c085b33d18f608fc32 Mon Sep 17 00:00:00 2001 From: captainurist <73941350+captainurist@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:50:56 +0800 Subject: [PATCH] Fix #1315 --- src/Application/Game.cpp | 7 ++++++- src/Engine/Engine.cpp | 38 ++++++++++++++++++++++++-------------- src/Engine/Engine.h | 2 ++ src/Engine/Party.cpp | 7 +++++++ src/Engine/Party.h | 5 +++++ 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/Application/Game.cpp b/src/Application/Game.cpp index 61f10dae95b6..8b3eda2abac7 100644 --- a/src/Application/Game.cpp +++ b/src/Application/Game.cpp @@ -2000,8 +2000,13 @@ void Game::gameLoop() { if (!pEventTimer->bPaused && uGameState == GAME_STATE_PLAYING) { onTimer(); - if (!pEventTimer->bTackGameTime) + if (!pEventTimer->bTackGameTime) { _494035_timed_effects__water_walking_damage__etc(); + } else { + // Need to process party death in turn-based mode. + maybeWakeSoloSurvivor(); + updatePartyDeathState(); + } if (dword_6BE364_game_settings_1 & GAME_SETTINGS_SKIP_WORLD_UPDATE) { dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_SKIP_WORLD_UPDATE; diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index f26dfc2fc9d6..e2781892c8b6 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -1444,20 +1444,8 @@ void _494035_timed_effects__water_walking_damage__etc() { } } - if (!numPlayersCouldAct) { - if (current_screen_type != SCREEN_REST) { - for (Character &character : pParty->pCharacters) { - // if someone is sleeping - wake them up - if (character.conditions.Has(CONDITION_SLEEP)) { - character.conditions.Reset(CONDITION_SLEEP); - numPlayersCouldAct = 1; - break; - } - } - if (!numPlayersCouldAct) - uGameState = GAME_STATE_PARTY_DIED; - } - } + maybeWakeSoloSurvivor(); + updatePartyDeathState(); if (pParty->hasActiveCharacter()) { if (current_screen_type != SCREEN_REST) { @@ -1468,6 +1456,28 @@ void _494035_timed_effects__water_walking_damage__etc() { } } +void maybeWakeSoloSurvivor() { + if (current_screen_type == SCREEN_REST) + return; + + if (pParty->canActCount() != 0) + return; + + // Try waking up a single character. + for (Character &character : pParty->pCharacters) { + if (character.conditions.Has(CONDITION_SLEEP)) { + character.conditions.Reset(CONDITION_SLEEP); + pParty->setActiveToFirstCanAct(); + break; + } + } +} + +void updatePartyDeathState() { + if (current_screen_type != SCREEN_REST && pParty->canActCount() == 0) + uGameState = GAME_STATE_PARTY_DIED; +} + void RegeneratePartyHealthMana() { constexpr int MINUTES_BETWEEN_REGEN = 5; int cur_minutes = pParty->GetPlayingTime().GetMinutes(); diff --git a/src/Engine/Engine.h b/src/Engine/Engine.h index d8180619f9c1..119d2275b75a 100644 --- a/src/Engine/Engine.h +++ b/src/Engine/Engine.h @@ -192,6 +192,8 @@ void setFacesBit(int sCogNumber, FaceAttribute bit, int on); */ void setDecorationSprite(uint16_t uCog, bool bHide, const std::string &pFileName); // idb void _494035_timed_effects__water_walking_damage__etc(); +void maybeWakeSoloSurvivor(); +void updatePartyDeathState(); /** * Modify party health or mana based on party or players conditions/buffs. diff --git a/src/Engine/Party.cpp b/src/Engine/Party.cpp index f751252d9058..acc4294f221d 100644 --- a/src/Engine/Party.cpp +++ b/src/Engine/Party.cpp @@ -219,6 +219,13 @@ bool Party::_497FC5_check_party_perception_against_level() { return result; } +int Party::canActCount() const { + int result = 0; + for (const Character &character : pCharacters) + result += character.CanAct(); + return result; +} + void Party::setHoldingItem(ItemGen *pItem) { placeHeldItemInInventoryOrDrop(); pPickedItem = *pItem; diff --git a/src/Engine/Party.h b/src/Engine/Party.h index cd05673d7157..7b0bbed50327 100644 --- a/src/Engine/Party.h +++ b/src/Engine/Party.h @@ -91,6 +91,11 @@ struct Party { void switchToNextActiveCharacter(); bool _497FC5_check_party_perception_against_level(); + /** + * @return Total number of characters who can act. + */ + int canActCount() const; + /** * @offset 0x48C6F6 */