Skip to content

Commit

Permalink
[Minor] Fix building production queue issue (Phobos-developers#1508)
Browse files Browse the repository at this point in the history
Fix an issue: When the defensive buildings in the queue lose their
prerequisites, they will not be cancelled but will remain stuck forever.
The problem still comes from hardcoded `BuildCat::DontCare`.
  • Loading branch information
CrimRecya authored Jan 25, 2025
1 parent e064905 commit 17c008a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/Ext/Building/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,17 @@ DEFINE_HOOK(0x6A9789, StripClass_DrawStrip_NoGreyCameo, 0x6)
return (!RulesExt::Global()->BuildingProductionQueue && pType->WhatAmI() == AbstractType::BuildingType && clicked) ? SkipGameCode : ContinueCheck;
}

DEFINE_HOOK(0x6AA88D, StripClass_RecheckCameo_FindFactoryDehardCode, 0x6)
{
GET(TechnoTypeClass* const, pType, EBX);
LEA_STACK(BuildCat*, pBuildCat, STACK_OFFSET(0x158, -0x158));

if (const auto pBuildingType = abstract_cast<BuildingTypeClass*>(pType))
*pBuildCat = pBuildingType->BuildCat;

return 0;
}

#pragma endregion

#pragma region BarracksExitCell
Expand Down
2 changes: 1 addition & 1 deletion src/Ext/House/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ static inline bool CheckShouldDisableDefensesCameo(HouseClass* pHouse, TechnoTyp
const auto BuildLimit = pBldType->BuildLimit;

if (BuildLimit >= 0)
return BuildLimit - BuildingTypeExt::CountOwnedNowWithDeployOrUpgrade(pBldType, pHouse);
return BuildLimit - BuildingTypeExt::CountOwnedNowWithDeployOrUpgrade(pBldType, pHouse);
else
return -BuildLimit - pHouse->CountOwnedEver(pBldType);
};
Expand Down
57 changes: 57 additions & 0 deletions src/Ext/Sidebar/Body.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "Body.h"

#include <EventClass.h>
#include <HouseClass.h>
#include <SuperClass.h>

std::unique_ptr<SidebarExt::ExtData> SidebarExt::Data = nullptr;

SHPStruct* SidebarExt::TabProducingProgress[4];
Expand All @@ -14,6 +18,59 @@ void SidebarExt::Remove(SidebarClass* pThis)
Data = nullptr;
}

// Reversed from Ares source code (In fact, it's the same as Vanilla).
// And compared to 0.A, it has been encapsulated. That's why here's such a simple way to make modifications.
bool __stdcall SidebarExt::AresTabCameo_RemoveCameo(BuildType* pItem)
{
const auto pTechnoType = TechnoTypeClass::GetByTypeAndIndex(pItem->ItemType, pItem->ItemIndex);
const auto pCurrent = HouseClass::CurrentPlayer();

if (pTechnoType)
{
const auto pFactory = pTechnoType->FindFactory(true, false, false, pCurrent);

if (pFactory && pFactory->Owner->CanBuild(pTechnoType, false, true) != CanBuildResult::Unbuildable)
return false;
}
else
{
const auto& supers = pCurrent->Supers;

if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent)
return false;
}

if (pItem->CurrentFactory)
{
EventClass event = EventClass(pCurrent->ArrayIndex, EventType::Abandon, static_cast<int>(pItem->ItemType), pItem->ItemIndex, pTechnoType && pTechnoType->Naval);
EventClass::AddEvent(event);
}

if (pItem->ItemType == AbstractType::BuildingType || pItem->ItemType == AbstractType::Building)
{
DisplayClass::Instance->CurrentBuilding = nullptr;
DisplayClass::Instance->CurrentBuildingType = nullptr;
DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1;
DisplayClass::Instance->SetActiveFoundation(nullptr);
}

if (pTechnoType)
{
const auto absType = pTechnoType->WhatAmI();

// Here we make correction to the hardcoded BuildCat::DontCare
const auto buildCat = absType == AbstractType::BuildingType ? static_cast<BuildingTypeClass*>(pTechnoType)->BuildCat : BuildCat::DontCare;

if (pCurrent->GetPrimaryFactory(absType, pTechnoType->Naval, buildCat))
{
EventClass event = EventClass(pCurrent->ArrayIndex, EventType::AbandonAll, static_cast<int>(pItem->ItemType), pItem->ItemIndex, pTechnoType->Naval);
EventClass::AddEvent(event);
}
}

return true;
}

// =============================
// load / save

Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Sidebar/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ class SidebarExt
{
Global()->InvalidatePointer(ptr, removed);
}

static bool __stdcall AresTabCameo_RemoveCameo(BuildType* pItem);
};
8 changes: 8 additions & 0 deletions src/Misc/Hooks.Ares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <Utilities/AresHelper.h>
#include <Utilities/Helpers.Alex.h>

#include <Ext/Sidebar/Body.h>

// In vanilla YR, game destroys building animations directly by calling constructor.
// Ares changed this to call UnInit() which has a consequence of doing pointer invalidation on the AnimClass pointer.
// This notably causes an issue with Grinder that restores ActiveAnim if the building is sold/destroyed while SpecialAnim is playing even if the building is gone or in limbo.
Expand Down Expand Up @@ -46,6 +48,9 @@ void Apply_Ares3_0_Patches()
Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x528C8, &Helpers::Alex::getCellSpreadItems);
Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x5273A, &Helpers::Alex::getCellSpreadItems);

// Redirect Ares's RemoveCameo to our implementation:
Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(SidebarExt::AresTabCameo_RemoveCameo));

// InitialPayload creation:
Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x43D5D, &CreateInitialPayload);
}
Expand All @@ -62,6 +67,9 @@ void Apply_Ares3_0p1_Patches()
Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x53578, &Helpers::Alex::getCellSpreadItems);
Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x533EA, &Helpers::Alex::getCellSpreadItems);

// Redirect Ares's RemoveCameo to our implementation:
Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(SidebarExt::AresTabCameo_RemoveCameo));

// InitialPayload creation:
Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x4483D, &CreateInitialPayload);
}

0 comments on commit 17c008a

Please sign in to comment.