diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 8176d9ced5..400742afa3 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -33,6 +33,14 @@ In `FAData.ini`: ## Changelog +### 0.2.2.2 + +Phobos fixes: +- Fixed shield type info not saving properly (by Uranusian) +- Fixed extended building upgrades logic not properly interacting with Ares' BuildLimit check (by Uranusian) +- Fix more random crashes for Cameo Priority (by Uranusian) +- Fix aircraft weapons causing game freeze when burst index was not correctly reset after firing (by Starkku) + ### 0.2.2.1 Phobos fixes: diff --git a/src/Ext/Aircraft/Body.cpp b/src/Ext/Aircraft/Body.cpp index 2e83a6251a..a389a1c2f0 100644 --- a/src/Ext/Aircraft/Body.cpp +++ b/src/Ext/Aircraft/Body.cpp @@ -12,15 +12,12 @@ void AircraftExt::FireBurst(AircraftClass* pThis, AbstractClass* pTarget, int sh if (weaponType->Burst > 0) { - while (pThis->CurrentBurstIndex < weaponType->Burst) + for (int i = 0; i < weaponType->Burst; i++) { if (weaponType->Burst < 2 && pWeaponTypeExt->Strafing_SimulateBurst) pThis->CurrentBurstIndex = shotNumber; pThis->Fire(pThis->Target, weaponIndex); - - if (pThis->CurrentBurstIndex == 0) - break; } } } diff --git a/src/Ext/Aircraft/Hooks.cpp b/src/Ext/Aircraft/Hooks.cpp index 90cc1fec43..fed8bbc168 100644 --- a/src/Ext/Aircraft/Hooks.cpp +++ b/src/Ext/Aircraft/Hooks.cpp @@ -9,7 +9,7 @@ DEFINE_HOOK(0x417FF1, AircraftClass_Mission_Attack_StrafeShots, 0x6) GET(AircraftClass*, pThis, ESI); if (pThis->MissionStatus < (int)AirAttackStatus::FireAtTarget2_Strafe - || pThis->MissionStatus >(int)AirAttackStatus::FireAtTarget5_Strafe) + || pThis->MissionStatus > (int)AirAttackStatus::FireAtTarget5_Strafe) { return 0; } diff --git a/src/Ext/BuildingType/Hooks.Upgrade.cpp b/src/Ext/BuildingType/Hooks.Upgrade.cpp index 5ca0af4c91..3883314cbf 100644 --- a/src/Ext/BuildingType/Hooks.Upgrade.cpp +++ b/src/Ext/BuildingType/Hooks.Upgrade.cpp @@ -4,6 +4,7 @@ #include #include #include "Body.h" +#include bool BuildingTypeExt::CanUpgrade(BuildingClass* pBuilding, BuildingTypeClass* pUpgradeType, HouseClass* pUpgradeOwner) { auto extUpgrade = BuildingTypeExt::ExtMap.Find(pUpgradeType); @@ -56,3 +57,97 @@ DEFINE_HOOK(0x4408EB, BuildingClass_Unlimbo_UpgradeBuildings, 0xA) return ForbidUpgrade; } + +#pragma region UpgradesInteraction + +int CountOwnedNowTotal(HouseClass const* const pHouse, TechnoTypeClass const* const pItem) +{ + int sum = 0; + const BuildingTypeClass* pBType = nullptr; + const char* pPowersUp = nullptr; + + auto checkUpgrade = [pHouse, pBType, &sum](BuildingTypeClass* pTPowersUp) + { + for (auto const& pBld : pHouse->Buildings) + { + if (pBld->Type == pTPowersUp) + { + for (auto const& pUpgrade : pBld->Upgrades) + { + if (pUpgrade == pBType) + ++sum; + } + } + } + }; + + switch (pItem->WhatAmI()) + { + case AbstractType::BuildingType: + pBType = static_cast(pItem); + pPowersUp = pBType->PowersUpBuilding; + if (pPowersUp[0]) + { + if (auto const pTPowersUp = BuildingTypeClass::Find(pPowersUp)) + checkUpgrade(pTPowersUp); + } + + if (auto pBuildingExt = BuildingTypeExt::ExtMap.Find(pBType)) + { + for (auto pTPowersUp : pBuildingExt->PowersUp_Buildings) + checkUpgrade(pTPowersUp); + } + + break; + + default: + __assume(0); + } + + return sum; +} + +int BuildLimitRemaining(HouseClass const* const pHouse, TechnoTypeClass const* const pItem) +{ + auto const BuildLimit = pItem->BuildLimit; + + if (BuildLimit >= 0) + return BuildLimit - CountOwnedNowTotal(pHouse, pItem); + else + return -BuildLimit - pHouse->CountOwnedEver(pItem); +} + +int CheckBuildLimit(HouseClass const* const pHouse, TechnoTypeClass const* const pItem, bool const includeQueued) +{ + enum { NotReached = 1, ReachedPermanently = -1, ReachedTemporarily = 0 }; + + int BuildLimit = pItem->BuildLimit; + int Remaining = BuildLimitRemaining(pHouse, pItem); + + if (BuildLimit >= 0 && Remaining <= 0) + return (includeQueued && FactoryClass::FindByOwnerAndProduct(pHouse, pItem)) ? NotReached : ReachedPermanently; + + return Remaining > 0 ? NotReached : ReachedTemporarily; + +} + +DEFINE_HOOK(0x4F8361, HouseClass_CanBuild_UpgradesInteraction, 0x3) +{ + GET(HouseClass const* const, pThis, ECX); + GET_STACK(TechnoTypeClass const* const, pItem, 0x4); + GET_STACK(bool const, includeInProduction, 0xC); + GET(CanBuildResult const, resultOfAres, EAX); + + if (auto pBuilding = static_cast(pItem)) + { + if (auto pBuildingExt = BuildingTypeExt::ExtMap.Find(pBuilding)) + { + if (pBuildingExt->PowersUp_Buildings.size() > 0 && resultOfAres == CanBuildResult::Buildable) + R->EAX(CheckBuildLimit(pThis, pItem, includeInProduction)); + } + } + + return 0; +} + +#pragma endregion \ No newline at end of file diff --git a/src/Misc/Hooks.UI.cpp b/src/Misc/Hooks.UI.cpp index eec71f7eab..d10815a59c 100644 --- a/src/Misc/Hooks.UI.cpp +++ b/src/Misc/Hooks.UI.cpp @@ -109,10 +109,14 @@ DEFINE_HOOK(0x6A8463, StripClass_OperatorLessThan_CameoPriority, 0x5) GET_STACK(TechnoTypeClass*, pRight, STACK_OFFS(0x1C, 0x4)); GET_STACK(int, idxLeft, STACK_OFFS(0x1C, -0x8)); GET_STACK(int, idxRight, STACK_OFFS(0x1C, -0x10)); + GET_STACK(AbstractType, rttiLeft, STACK_OFFS(0x1C, -0x4)); + GET_STACK(AbstractType, rttiRight, STACK_OFFS(0x1C, -0xC)); auto pLeftTechnoExt = TechnoTypeExt::ExtMap.Find(pLeft); auto pRightTechnoExt = TechnoTypeExt::ExtMap.Find(pRight); - auto pLeftSWExt = pLeftTechnoExt ? SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItem(idxLeft)) : nullptr; - auto pRightSWExt = pRightTechnoExt ? SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItem(idxRight)) : nullptr; + auto pLeftSWExt = (rttiLeft == AbstractType::Special || rttiLeft == AbstractType::Super || rttiLeft == AbstractType::SuperWeaponType) + ? SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItem(idxLeft)) : nullptr; + auto pRightSWExt = (rttiRight == AbstractType::Special || rttiRight == AbstractType::Super || rttiRight == AbstractType::SuperWeaponType) + ? SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItem(idxRight)) : nullptr; if ((pLeftTechnoExt || pLeftSWExt) && (pRightTechnoExt || pRightSWExt)) { diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 3522aa9c21..286b3666a5 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -51,6 +51,7 @@ bool ShieldClass::Serialize(T& Stm) .Process(this->Online) .Process(this->Temporal) .Process(this->Available) + .Process(this->Type) .Success(); } diff --git a/src/Phobos.version.h b/src/Phobos.version.h index 6601a99ffd..1a19e1fb1b 100644 --- a/src/Phobos.version.h +++ b/src/Phobos.version.h @@ -18,12 +18,12 @@ #define VERSION_REVISION 2 // Indicates Phobos-related bugfixes only -#define VERSION_PATCH 1 +#define VERSION_PATCH 2 #pragma endregion // Build number. Incremented on each released build. -#define BUILD_NUMBER 21 +#define BUILD_NUMBER 23 // Nightly defines GIT_COMMIT and GIT_BRANCH in GH Actions