diff --git a/YRpp b/YRpp index 3e4db25b..aacc52ba 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 3e4db25bb775d44ec896392bcded614628452c2d +Subproject commit aacc52ba8a73ea42ca5e0cdb6323f3f920d1384e diff --git a/src/Misc/Observers.cpp b/src/Misc/Observers.cpp index c386076a..77f05d11 100644 --- a/src/Misc/Observers.cpp +++ b/src/Misc/Observers.cpp @@ -44,24 +44,30 @@ DEFINE_HOOK(0x5C98E5, MultiplayerScore__5C98A0_SkipObserverScore, 0x6) } // Use correct colors in diplomacy menu for all observers -DEFINE_HOOK(0x65838B, RadarClass__658330_SetObserverColorScheme, 0x5) +DEFINE_HOOK(0x6583B2, RadarClass__658330_SetObserverColorScheme, 0x5) { if (!Spawner::Enabled) return 0; + enum { SelectLightGrey = 0x658397 }; GET(HouseClass*, pHouse, EBX); - R->EAX(pHouse->IsInitiallyObserver() ? HouseClass::CurrentPlayer : (HouseClass*) nullptr); - return 0x65838B + 0x5; + + if (pHouse->IsHumanPlayer && pHouse->IsInitiallyObserver()) + return SelectLightGrey; + + return 0; } // Use correct flag icon in diplomacy menu for all observers -DEFINE_HOOK(0x65846D, RadarClass__658330_SetObserverFlag, 0x6) +DEFINE_HOOK(0x658473, RadarClass__658330_SetObserverFlag, 0x5) { if (!Spawner::Enabled) return 0; GET(HouseClass*, pHouse, EBX); - R->ECX(pHouse->IsInitiallyObserver() ? -3 : pHouse->Type->ArrayIndex); + if (pHouse->IsHumanPlayer && pHouse->Defeated && pHouse->IsInitiallyObserver()) + R->ECX(HouseTypeClass::TempObserverID); + return 0x658485; } diff --git a/src/Spawner/Spawner.Hook.cpp b/src/Spawner/Spawner.Hook.cpp index 83d3f90b..01d42dbd 100644 --- a/src/Spawner/Spawner.Hook.cpp +++ b/src/Spawner/Spawner.Hook.cpp @@ -126,7 +126,7 @@ DEFINE_HOOK(0x4FC262, HouseClass__MPlayerDefeated_SkipObserver, 0x6) if (!MPlayerDefeated::pThis) return 0; - return MPlayerDefeated::pThis->IsObserver() + return MPlayerDefeated::pThis->IsInitiallyObserver() ? ProcEpilogue : 0; } @@ -166,8 +166,24 @@ DEFINE_HOOK(0x4FC57C, HouseClass__MPlayerDefeated_CheckAliveAndHumans, 0x7) GET_STACK(int, numHumans, STACK_OFFSET(0xC0, -0xA8)); GET_STACK(int, numAlive, STACK_OFFSET(0xC0, -0xAC)); - bool continueWithoutHumans = Spawner::GetConfig()->ContinueWithoutHumans || - (SessionClass::IsSkirmish() && HouseClass::CurrentPlayer->IsInitiallyObserver()); + bool continueWithoutHumans = Spawner::GetConfig()->ContinueWithoutHumans + || MPlayerDefeated::pThis->IsInitiallyObserver(); + + if (!continueWithoutHumans && !MPlayerDefeated::pThis->IsHumanPlayer) + { + bool isHasAliveHumanPlayers = false; + for (const auto pHouse : HouseClass::Array) + { + if (pHouse->IsHumanPlayer && !pHouse->Defeated) + { + isHasAliveHumanPlayers = true; + break; + } + } + + if (!isHasAliveHumanPlayers) + continueWithoutHumans = true; + } if (numAlive > 1 && (numHumans != 0 || continueWithoutHumans)) { diff --git a/src/Spawner/Spawner.cpp b/src/Spawner/Spawner.cpp index a8891eec..11a3a2ab 100644 --- a/src/Spawner/Spawner.cpp +++ b/src/Spawner/Spawner.cpp @@ -105,11 +105,7 @@ void Spawner::AssignHouses() const auto pHousesConfig = &Spawner::Config->Houses[indexOfHouseArray]; const int nSpawnLocations = pHousesConfig->SpawnLocations; - const bool isObserver = pHouse->IsHumanPlayer && ( - pHousesConfig->IsObserver - || nSpawnLocations == -1 - || nSpawnLocations == 90 - ); + const bool isObserver = pHouse->IsHumanPlayer && pHousesConfig->IsObserver; // Set Alliances for (char i = 0; i < (char)std::size(pHousesConfig->Alliances); ++i) @@ -143,9 +139,9 @@ void Spawner::AssignHouses() // Set SpawnLocations if (!isObserver) { - pHouse->StartingPoint = (nSpawnLocations != -2) - ? std::clamp(nSpawnLocations, 0, 7) - : nSpawnLocations; + pHouse->StartingPoint = (nSpawnLocations < 0) + ? -2 + : std::clamp(nSpawnLocations, 0, 7); } else { @@ -266,7 +262,7 @@ bool Spawner::StartScenario(const char* pScenarioName) if (pPlayer->IsObserver && !Spawner::Config->IsCampaign) { if (pNode->Country < 0) - pNode->Country = -3; + pNode->Country = HouseTypeClass::TempObserverID; pNode->SpectatorFlag = 0xFFFFFFFF;