Skip to content

Commit

Permalink
Allow excluding specific factory buildings from providing MultipleFac…
Browse files Browse the repository at this point in the history
…tory bonus
  • Loading branch information
Starkku committed Aug 27, 2024
1 parent 6369e23 commit fe8f447
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ This page lists all the individual contributions to the project by their author.
- Customizing height at which subterranean units travel
- `MovementZone=Subterannean` harvester fix
- AI superweapon delay timer customization
- Disabling `MultipleFactory` bonus from specific BuildingType
- **Morton (MortonPL)**:
- `XDrawOffset` for animations
- Shield passthrough & absorption
Expand Down
10 changes: 10 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,16 @@ In `rulesmd.ini`:
SellBuildupLength=23 ; integer, number of buildup frames to play
```

### Exclude Factory from providing multiple factory bonus

- It is now possible to exclude a building with `Factory` from counting towards `MultipleFactory` bonus.

In `rulesmd.ini`:
```ini
[SOMEBUILDING] ; BuildingType
ExcludeFromMultipleFactoryBonus=false ; boolean
```

## Particle systems

### Fire particle target coordinate adjustment when firer rotates
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ New:
- Allow customizing voxel light source position (by Kerbiter, Morton, based on knowledge of thomassnedon)
- Option to fix voxel light source being offset and incorrectly tilting on slopes (by Kerbiter)
- AI superweapon delay timer customization (by Starkku)
- Disabling `MultipleFactory` bonus from specific BuildingType (by Starkku)
Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/BuildingType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ void BuildingTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->CanC4_AllowZeroDamage.Read(exINI, pSection, "CanC4.AllowZeroDamage");

this->InitialStrength_Cloning.Read(exINI, pSection, "InitialStrength.Cloning");
this->ExcludeFromMultipleFactoryBonus.Read(exINI, pSection, "ExcludeFromMultipleFactoryBonus");

this->Grinding_AllowAllies.Read(exINI, pSection, "Grinding.AllowAllies");
this->Grinding_AllowOwner.Read(exINI, pSection, "Grinding.AllowOwner");
Expand Down Expand Up @@ -233,6 +234,7 @@ void BuildingTypeExt::ExtData::Serialize(T& Stm)
.Process(this->AllowAirstrike)
.Process(this->CanC4_AllowZeroDamage)
.Process(this->InitialStrength_Cloning)
.Process(this->ExcludeFromMultipleFactoryBonus)
.Process(this->Refinery_UseStorage)
.Process(this->Grinding_AllowAllies)
.Process(this->Grinding_AllowOwner)
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/BuildingType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class BuildingTypeExt
Valueable<bool> CanC4_AllowZeroDamage;
Valueable<bool> Refinery_UseStorage;
Valueable<PartialVector2D<double>> InitialStrength_Cloning;
Valueable<bool> ExcludeFromMultipleFactoryBonus;

ValueableIdx<VocClass> Grinding_Sound;
Valueable<WeaponTypeClass*> Grinding_Weapon;
Expand Down Expand Up @@ -75,6 +76,7 @@ class BuildingTypeExt
, AllowAirstrike {}
, CanC4_AllowZeroDamage { false }
, InitialStrength_Cloning { { 1.0, 0.0 } }
, ExcludeFromMultipleFactoryBonus { false }
, Refinery_UseStorage { false }
, Grinding_AllowAllies { false }
, Grinding_AllowOwner { true }
Expand Down
68 changes: 68 additions & 0 deletions src/Ext/House/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,69 @@ int HouseExt::ExtData::CountOwnedPresentAndLimboed(TechnoTypeClass* pTechnoType)
return count;
}

void HouseExt::ExtData::UpdateNonMFBFactoryCounts(AbstractType rtti, bool remove, bool isNaval)
{
int* count = nullptr;

switch (rtti)
{
case AbstractType::Aircraft:
case AbstractType::AircraftType:
count = &this->NumAirpads_NonMFB;
break;
case AbstractType::Building:
case AbstractType::BuildingType:
count = &this->NumConYards_NonMFB;
break;
case AbstractType::Infantry:
case AbstractType::InfantryType:
count = &this->NumBarracks_NonMFB;
break;
case AbstractType::Unit:
case AbstractType::UnitType:
count = isNaval ? &this->NumShipyards_NonMFB : &this->NumWarFactories_NonMFB;
break;
default:
break;
}

if (count)
*count += remove ? -1 : 1;
}

int HouseExt::ExtData::GetFactoryCountWithoutNonMFB(AbstractType rtti, bool isNaval)
{
auto const pThis = this->OwnerObject();
int count = 0;

switch (rtti)
{
case AbstractType::Aircraft:
case AbstractType::AircraftType:
count = pThis->NumAirpads - this->NumAirpads_NonMFB;
break;
case AbstractType::Building:
case AbstractType::BuildingType:
count = pThis->NumConYards - this->NumConYards_NonMFB;
break;
case AbstractType::Infantry:
case AbstractType::InfantryType:
count = pThis->NumBarracks - this->NumBarracks_NonMFB;
break;
case AbstractType::Unit:
case AbstractType::UnitType:
if (isNaval)
count = pThis->NumShipyards - this->NumShipyards_NonMFB;
else
count = pThis->NumWarFactories - this->NumWarFactories_NonMFB;
break;
default:
break;
}

return Math::max(count, 0);
}

void HouseExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
{
const char* pSection = this->OwnerObject()->PlainName;
Expand Down Expand Up @@ -533,6 +596,11 @@ void HouseExt::ExtData::Serialize(T& Stm)
.Process(this->RepairBaseNodes)
.Process(this->LastBuiltNavalVehicleType)
.Process(this->ProducingNavalUnitTypeIndex)
.Process(this->NumAirpads_NonMFB)
.Process(this->NumBarracks_NonMFB)
.Process(this->NumWarFactories_NonMFB)
.Process(this->NumConYards_NonMFB)
.Process(this->NumShipyards_NonMFB)
;
}

Expand Down
14 changes: 14 additions & 0 deletions src/Ext/House/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ class HouseExt
int LastBuiltNavalVehicleType;
int ProducingNavalUnitTypeIndex;

// Factories that exist but don't count towards multiple factory bonus.
int NumAirpads_NonMFB;
int NumBarracks_NonMFB;
int NumWarFactories_NonMFB;
int NumConYards_NonMFB;
int NumShipyards_NonMFB;

ExtData(HouseClass* OwnerObject) : Extension<HouseClass>(OwnerObject)
, PowerPlantEnhancers {}
, OwnedLimboDeliveredBuildings {}
Expand All @@ -59,12 +66,19 @@ class HouseExt
, RepairBaseNodes { false,false,false }
, LastBuiltNavalVehicleType { -1 }
, ProducingNavalUnitTypeIndex { -1 }
, NumAirpads_NonMFB { 0 }
, NumBarracks_NonMFB { 0 }
, NumWarFactories_NonMFB { 0 }
, NumConYards_NonMFB { 0 }
, NumShipyards_NonMFB { 0 }
{ }

bool OwnsLimboDeliveredBuilding(BuildingClass* pBuilding);
void AddToLimboTracking(TechnoTypeClass* pTechnoType);
void RemoveFromLimboTracking(TechnoTypeClass* pTechnoType);
int CountOwnedPresentAndLimboed(TechnoTypeClass* pTechnoType);
void UpdateNonMFBFactoryCounts(AbstractType rtti, bool remove, bool isNaval);
int GetFactoryCountWithoutNonMFB(AbstractType rtti, bool isNaval);

virtual ~ExtData() = default;

Expand Down
31 changes: 31 additions & 0 deletions src/Ext/House/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,34 @@ DEFINE_HOOK(0x4F9038, HouseClass_AI_Superweapons, 0x5)

return 0;
}

DEFINE_HOOK_AGAIN(0x4FFA99, HouseClass_ExcludeFromMultipleFactoryBonus, 0x6)
DEFINE_HOOK(0x4FF9C9, HouseClass_ExcludeFromMultipleFactoryBonus, 0x6)
{
GET(BuildingClass*, pBuilding, ESI);

if (BuildingTypeExt::ExtMap.Find(pBuilding->Type)->ExcludeFromMultipleFactoryBonus)
{
GET(HouseClass*, pThis, EDI);
GET(bool, isNaval, ECX);

auto const pExt = HouseExt::ExtMap.Find(pThis);
pExt->UpdateNonMFBFactoryCounts(pBuilding->Type->Factory, R->Origin() == 0x4FF9C9, isNaval);
}

return 0;
}

DEFINE_HOOK(0x500910, HouseClass_GetFactoryCount, 0x5)
{
enum { SkipGameCode = 0x50095D };

GET(HouseClass*, pThis, ECX);
GET_STACK(AbstractType, rtti, 0x4);
GET_STACK(bool, isNaval, 0x8);

auto const pExt = HouseExt::ExtMap.Find(pThis);
R->EAX(pExt->GetFactoryCountWithoutNonMFB(rtti, isNaval));

return SkipGameCode;
}

0 comments on commit fe8f447

Please sign in to comment.