diff --git a/CREDITS.md b/CREDITS.md index 63a07c1565..ecde4dc755 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -391,6 +391,7 @@ This page lists all the individual contributions to the project by their author. - Skirmish AI "sell all buildings and set all technos to hunt" behavior dehardcode - Skirmish AI "gather when MCV deploy" behavior dehardcode - Global value of `RepairBaseNodes` + - Bunkerable checks dehardcode - **tyuah8** - Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix - **Aephiex** - initial fix for Ares academy not working on the initial payloads of vehicles built from a war factory - **Ares developers** diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 387522453c..9823bb5463 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1442,6 +1442,24 @@ DestroyAnim= ; Animation DestroySound= ; Sound ``` +## Vehicles + +### Bunker entering check dehardcode + +- In vanilla, vehicles entering tank bunkers are subject to a series of hardcoding restrictions, including having to have turrets, having to have weapons, and not having Hover speed types. Now you can skip these restrictions. +- This needs to be used with `Bunkerable=yes`. +- This flag only skips the static check, that is, the check on the unit type. The dynamic check (cannot be parasitized) remains unchanged. + +In `rulesmd.ini`: +```ini +[SOMEVEHICLE] ; VehicleType +BunkerableAnyway=false ; boolean +``` + +```{warning} +Skipping checks with this feature doesn't mean that vehicles and tank bunkers will interact correctly. Following the simple checks performed by the provider of this feature, bunkerability is mainly determined by Locomotor. The details can be found on ModEnc. +``` + ## Warheads ```{hint} diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 1c270e00d7..82f58928ae 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -317,6 +317,7 @@ New: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) - Custom exit cell for infantry factory (by Starkku) - Option for vehicles to keep target when issued move command (by Starkku) +- Bunkerable checks dehardcode (by TaranDahl) Vanilla fixes: - Aircraft will now behave as expected according to it's `MovementZone` and `SpeedType` when moving onto different surfaces. In particular, this fixes erratic behavior when vanilla aircraft is ordered to move onto water surface and instead the movement order changes to a shore nearby (by CrimRecya) diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index cb7cf4c3c2..5a688ff4ca 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -429,4 +429,31 @@ DEFINE_HOOK(0x51D7E0, InfantryClass_DoAction_Water, 0x5) return Continue; } +bool __fastcall LocomotorCheckForBunkerable(TechnoTypeClass* pType) +{ + auto const loco = pType->Locomotor; + + return loco != LocomotionClass::CLSIDs::Hover && + loco != LocomotionClass::CLSIDs::Mech && + loco != LocomotionClass::CLSIDs::Fly && + loco != LocomotionClass::CLSIDs::Droppod && + loco != LocomotionClass::CLSIDs::Rocket && + loco != LocomotionClass::CLSIDs::Ship; +} + +DEFINE_HOOK(0x70FB73, FootClass_IsBunkerableNow_Dehardcode, 0x6) +{ + enum { SkipVanillaChecks = 0x70FBAF, DoVanillaChecks = 0 }; + + GET(TechnoTypeClass*, pType, EAX); + GET(FootClass*, pThis, ESI); + + auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pType); + auto const loco = pType->Locomotor; + + if (pTypeExt && pTypeExt->BunkerableAnyway && !pThis->ParasiteEatingMe && LocomotorCheckForBunkerable(pType)) + return SkipVanillaChecks; + + return DoVanillaChecks; +} #pragma endregion diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index cc0b3b8c5b..97cf2cffdd 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -457,6 +457,7 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->Wake.Read(exINI, pSection, "Wake"); this->Wake_Grapple.Read(exINI, pSection, "Wake.Grapple"); this->Wake_Sinking.Read(exINI, pSection, "Wake.Sinking"); + this->BunkerableAnyway.Read(exINI, pSection, "BunkerableAnyway"); this->KeepTargetOnMove.Read(exINI, pSection, "KeepTargetOnMove"); this->KeepTargetOnMove_ExtraDistance.Read(exINI, pSection, "KeepTargetOnMove.ExtraDistance"); @@ -832,6 +833,7 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->Wake_Grapple) .Process(this->Wake_Sinking) + .Process(this->BunkerableAnyway) .Process(this->KeepTargetOnMove) .Process(this->KeepTargetOnMove_ExtraDistance) ; diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 0a947b973e..22d9ae165c 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -230,6 +230,7 @@ class TechnoTypeExt Nullable Wake_Grapple; Nullable Wake_Sinking; + Valueable BunkerableAnyway; Valueable KeepTargetOnMove; Valueable KeepTargetOnMove_ExtraDistance; @@ -456,6 +457,7 @@ class TechnoTypeExt , Wake_Grapple { } , Wake_Sinking { } + , BunkerableAnyway { false } , KeepTargetOnMove { false } , KeepTargetOnMove_ExtraDistance { Leptons(0) } { }