Skip to content

Commit 65afee2

Browse files
committed
Rework ammo-based deploy functionality
- Unify deploy allow checks so they are only checked in one place. - Move functionality that could hypothetically be called from multiple locations to TechnoExt functions. - Extend auto-deploy / deploy blocking to all vehicle deploy functions. - Remove Hooks.Unload.cpp as it had too few remaining hooks to be worth keeping around. - In general leave the functionality in such state that it will be easier to extend to other types if need be.
1 parent 80e57a0 commit 65afee2

File tree

12 files changed

+162
-217
lines changed

12 files changed

+162
-217
lines changed

Phobos.vcxproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@
162162
<ClCompile Include="src\Ext\Unit\Hooks.DisallowMoving.cpp" />
163163
<ClCompile Include="src\Ext\Unit\Hooks.DeploysInto.cpp" />
164164
<ClCompile Include="src\Ext\Unit\Hooks.Jumpjet.cpp" />
165-
<ClCompile Include="src\Ext\Unit\Hooks.Unload.cpp" />
166165
<ClCompile Include="src\Ext\WarheadType\Detonate.cpp" />
167166
<ClCompile Include="src\Ext\Techno\Hooks.WeaponEffects.cpp" />
168167
<ClCompile Include="src\Ext\Techno\Hooks.Tint.cpp" />

docs/Fixed-or-Improved-Logics.md

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,37 +1734,13 @@ DestroyAnim.Random=true ; boolean
17341734

17351735
### `IsSimpleDeployer` vehicle ammo change on deploy
17361736

1737-
- `Ammo.AddOnDeploy` determines the number of ammo added or substracted on unit deploy.
1738-
1739-
In `rulesmd.ini`:
1740-
```ini
1741-
[SOMEVEHICLE] ; VehicleType
1742-
Ammo.AddOnDeploy=0 ; integer
1743-
```
1744-
1745-
```{warning}
1746-
Due to technical constraints, units that use `Convert.Deploy` from [Ares' Type Conversion](https://ares-developers.github.io/Ares-docs/new/typeconversion.html) to change type with `Ammo.AddOnDeploy` will add or substract ammo despite of convertion success. This will also happen when unit exits tank bunker.
1747-
```
1748-
1749-
### `IsSimpleDeployer` vehicle auto-deploy / deploy block on ammo change
1750-
1751-
- Vehicle deployment can now be affected by ammo count.
1752-
- `Ammo.AutoDeployMinimumAmount` determines the minimal number of ammo at which a vehicle converts/deploys automatically.
1753-
- `Ammo.DeployUnlockMinimumAmount` determines the minimal number of ammo that unlocks issuing vehicle converting/deploying command.
1754-
- `Ammo.AutoDeployMaximumAmount` and `Ammo.DeployUnlockMaximumAmount` behave analogically.
1755-
- Setting a negative number will disable ammo count check.
1756-
1737+
- `Ammo.AddOnDeploy` determines the number of ammo added or subtracted after the vehicle has deployed or undeployed.
1738+
- Ammo count cannot go below 0 or above the maximum ammo for vehicle's type (in case the deploy results in type conversion, type is the one after the conversion).
1739+
17571740
In `rulesmd.ini`:
17581741
```ini
1759-
[SOMEVEHICLE] ; VehicleType
1760-
Ammo.AutoDeployMinimumAmount=-1 ; integer
1761-
Ammo.AutoDeployMaximumAmount=-1 ; integer
1762-
Ammo.DeployUnlockMinimumAmount=-1 ; integer
1763-
Ammo.DeployUnlockMaximumAmount=-1 ; integer
1764-
```
1765-
1766-
```{warning}
1767-
Auto-deploy feature requires `Convert.Deploy` from [Ares' Type Conversion](https://ares-developers.github.io/Ares-docs/new/typeconversion.html) to change type. Unit without it will constantly use deploy command on self until ammo is changed.
1742+
[SOMEVEHICLE] ; VehicleType
1743+
Ammo.AddOnDeploy=0 ; integer
17681744
```
17691745

17701746
### IsSimpleDeployer facing and animation customization

docs/New-or-Enhanced-Logics.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,21 @@ AmphibiousEnter= ; boolean, default to [General] -> AmphibiousEnter
20062006
AmphibiousUnload= ; boolean, default to [General] -> AmphibiousUnload
20072007
```
20082008

2009+
### Automatic deploy and blocking deploying based on ammo
2010+
2011+
- It is now possible for deployable vehicles (`DeploysInto`, `DeployFire`, `IsSimpleDeployer` and those that have passengers) to automatically deploy or prevent deploying based on their current ammo.
2012+
- `Ammo.AutoDeployMinimumAmount` & `Ammo.AutoDeployMaximumAmount` determine minimum and maximum ammo the vehicle should have for it to automatically deploy. Negative values disable the check.
2013+
- `Ammo.DeployUnlockMinimumAmount` & `Ammo.AutoDeployMaximumAmount` determine minimum and maximum ammo the vehicle should have for deploying to be available in general. Negative values disable the check.
2014+
2015+
In `rulesmd.ini`:
2016+
```ini
2017+
[SOMEVEHICLE] ; VehicleType
2018+
Ammo.AutoDeployMinimumAmount=-1 ; integer
2019+
Ammo.AutoDeployMaximumAmount=-1 ; integer
2020+
Ammo.DeployUnlockMinimumAmount=-1 ; integer
2021+
Ammo.DeployUnlockMaximumAmount=-1 ; integer
2022+
```
2023+
20092024
### Damaged unit image changes
20102025

20112026
- When a unit is damaged (health points percentage is lower than `[AudioVisual] -> ConditionYellow` percentage), it now may use different image set by `Image.ConditionYellow` VehicleType.

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ New:
440440
- [Customize hardcoded projectile initial facing behavior](Fixed-or-Improved-Logics.md#customizing-initial-facing-behavior) (by Starkku)
441441
- Health bar permanently displayed (by FlyStar)
442442
- [`IsSimpleDeployer` facing customization & directional deploy animations](Fixed-or-Improved-Logics.md#issimpleDeployer-facing-and-animation-customization) (by Starkku)
443+
- [Ammo-based deploy customizations for vehicles expanded to non-IsSimpleDeployer deploy functions](New-or-Enhancerd-Logics.md#Automatic-deploy-and-blocking-deploying-based on-ammo) (by Starkku)
443444
444445
Vanilla fixes:
445446
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)

src/Ext/Techno/Body.Update.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,40 @@ void TechnoExt::ExtData::ApplyInterceptor()
177177

178178
void TechnoExt::ExtData::DepletedAmmoActions()
179179
{
180-
auto const pThis = static_cast<UnitClass*>(this->OwnerObject());
181-
auto const pType = pThis->Type;
180+
auto const pThis = this->OwnerObject();
181+
auto const pTypeExt = this->TypeExtData;
182+
auto const pType = pTypeExt->OwnerObject();
182183

183-
if (pType->Ammo <= 0 || !pType->IsSimpleDeployer)
184+
if (pType->Ammo <= 0)
184185
return;
185186

186-
auto const pTypeExt = this->TypeExtData;
187-
const bool skipMinimum = pTypeExt->Ammo_AutoDeployMinimumAmount < 0;
188-
const bool skipMaximum = pTypeExt->Ammo_AutoDeployMaximumAmount < 0;
187+
auto const rtti = pThis->WhatAmI();
189188

190-
if (skipMinimum && skipMaximum)
189+
if (rtti == AbstractType::Unit)
190+
{
191+
auto const pUnit = static_cast<UnitClass*>(pThis);
192+
auto const pUnitType = pUnit->Type;
193+
194+
if (!pUnitType->IsSimpleDeployer && !pUnitType->DeploysInto && !pUnitType->DeployFire
195+
&& pUnitType->Passengers < 1 && pUnit->Passengers.NumPassengers < 1)
196+
{
197+
return;
198+
}
199+
}
200+
201+
int const min = pTypeExt->Ammo_AutoDeployMinimumAmount;
202+
int const max = pTypeExt->Ammo_AutoDeployMaximumAmount;
203+
204+
if (min < 0 && max < 0)
191205
return;
192206

193-
const bool moreThanMinimum = pThis->Ammo >= pTypeExt->Ammo_AutoDeployMinimumAmount;
194-
const bool lessThanMaximum = pThis->Ammo <= pTypeExt->Ammo_AutoDeployMaximumAmount;
207+
int const ammo = pThis->Ammo;
195208

196-
if ((skipMinimum || moreThanMinimum) && (skipMaximum || lessThanMaximum))
197-
pThis->QueueMission(Mission::Unload, true);
209+
if ((min < 0 || ammo >= min) && (max < 0 || ammo <= max))
210+
{
211+
if (TechnoExt::HasAmmoToDeploy(pThis))
212+
pThis->QueueMission(Mission::Unload, true);
213+
}
198214
}
199215

200216
// TODO : Merge into new AttachEffects

src/Ext/Techno/Body.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ bool TechnoExt::ConvertToType(FootClass* pThis, TechnoTypeClass* pToType)
317317
{
318318
// Fixed an issue where morphing could result in -1 health.
319319
double ratio = static_cast<double>(pToType->Strength) / pType->Strength;
320-
pThis->Health = static_cast<int>(oldHealth * ratio + 0.5);
320+
pThis->Health = static_cast<int>(oldHealth * ratio + 0.5);
321321

322322
auto const pTypeExt = TechnoExt::ExtMap.Find(static_cast<TechnoClass*>(pThis));
323323
pTypeExt->UpdateTypeData(pToType);
@@ -760,6 +760,40 @@ bool TechnoExt::CannotMove(UnitClass* pThis)
760760
return false;
761761
}
762762

763+
bool TechnoExt::HasAmmoToDeploy(TechnoClass* pThis)
764+
{
765+
const auto pTypeExt = TechnoExt::ExtMap.Find(pThis)->TypeExtData;
766+
767+
const int min = pTypeExt->Ammo_DeployUnlockMinimumAmount;
768+
const int max = pTypeExt->Ammo_DeployUnlockMaximumAmount;
769+
770+
if (min < 0 && max < 0)
771+
return true;
772+
773+
const int ammo = pThis->Ammo;
774+
775+
if ((min < 0 || ammo >= min) && (max < 0 || ammo <= max))
776+
return true;
777+
778+
return false;
779+
}
780+
781+
void TechnoExt::HandleOnDeployAmmoChange(TechnoClass* pThis, int maxAmmoOverride)
782+
{
783+
const auto pTypeExt = TechnoExt::ExtMap.Find(pThis)->TypeExtData;
784+
785+
if (const bool addOnDeploy = pTypeExt->Ammo_AddOnDeploy)
786+
{
787+
const int ammoCalc = std::max(pThis->Ammo + addOnDeploy, 0);
788+
int maxAmmo = pTypeExt->OwnerObject()->Ammo;
789+
790+
if (maxAmmoOverride >= 0)
791+
maxAmmo = maxAmmoOverride;
792+
793+
pThis->Ammo = std::min(maxAmmo, ammoCalc);
794+
}
795+
}
796+
763797
// =============================
764798
// load / save
765799

src/Ext/Techno/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ class TechnoExt
273273
static UnitTypeClass* GetUnitTypeExtra(UnitClass* pUnit);
274274
static AircraftTypeClass* GetAircraftTypeExtra(AircraftClass* pAircraft);
275275
static bool CannotMove(UnitClass* pThis);
276+
static bool HasAmmoToDeploy(TechnoClass* pThis);
277+
static void HandleOnDeployAmmoChange(TechnoClass* pThis, int maxAmmoOverride = -1);
276278

277279
// WeaponHelpers.cpp
278280
static int PickWeaponIndex(TechnoClass* pThis, TechnoClass* pTargetTechno, AbstractClass* pTarget, int weaponIndexOne, int weaponIndexTwo, bool allowFallback = true, bool allowAAFallback = true);

src/Ext/Techno/Hooks.Misc.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,22 @@ DEFINE_HOOK(0x730D1F, DeployCommandClass_Execute_VoiceDeploy, 0x5)
819819
}
820820

821821
#pragma endregion
822+
823+
824+
// Prevent subterranean units from deploying while underground.
825+
DEFINE_HOOK(0x73D6E6, UnitClass_Unload_Subterranean, 0x6)
826+
{
827+
enum { ReturnFromFunction = 0x73DFB0 };
828+
829+
GET(UnitClass*, pThis, ESI);
830+
831+
if (pThis->Type->Locomotor == LocomotionClass::CLSIDs::Tunnel)
832+
{
833+
auto const pLoco = static_cast<TunnelLocomotionClass*>(pThis->Locomotor.GetInterfacePtr());
834+
835+
if (pLoco->State != TunnelLocomotionClass::State::Idle)
836+
return ReturnFromFunction;
837+
}
838+
839+
return 0;
840+
}

src/Ext/Techno/Hooks.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,3 +1263,35 @@ DEFINE_HOOK(0x708FC0, TechnoClass_ResponseMove_Pickup, 0x5)
12631263

12641264
return 0;
12651265
}
1266+
1267+
// Handle disabling deploy action & cursor for vehicles and aircraft.
1268+
// Possible hook locations for other types in same function: Building: 0x700E3F, Infantry: 0x700E2C
1269+
DEFINE_HOOK(0x7010C1, TechnoClass_CanShowDeployCursor_UnitsAndAircraft, 0x5)
1270+
{
1271+
enum { DoNotAllowDeploy = 0x700DCE };
1272+
1273+
GET(FootClass*, pThis, ESI);
1274+
1275+
if (auto const pUnit = abstract_cast<UnitClass*>(pThis))
1276+
{
1277+
// Ammo-based deploy blocking.
1278+
if (!TechnoExt::HasAmmoToDeploy(pUnit))
1279+
return DoNotAllowDeploy;
1280+
1281+
// IsSimpleDeployer + type conversion
1282+
if (pUnit->Type->IsSimpleDeployer && AresFunctions::ConvertTypeTo)
1283+
{
1284+
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pUnit->Type);
1285+
1286+
if (auto const pTypeConvert = pTypeExt->Convert_Deploy)
1287+
{
1288+
auto const pCell = pUnit->GetCell();
1289+
1290+
if (!pCell->IsClearToMove(pTypeConvert->SpeedType, true, true, -1, pTypeConvert->MovementZone, -1, pCell->ContainsBridge()))
1291+
return DoNotAllowDeploy;
1292+
}
1293+
}
1294+
}
1295+
1296+
return 0;
1297+
}

src/Ext/Unit/Hooks.DeploysInto.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <Ext/TerrainType/Body.h>
55
#include <Ext/CaptureManager/Body.h>
66
#include <Ext/WarheadType/Body.h>
7+
#include <Ext/Building/Body.h>
78

89
static void TransferMindControlOnDeploy(TechnoClass* pTechnoFrom, TechnoClass* pTechnoTo)
910
{
@@ -250,4 +251,19 @@ DEFINE_HOOK(0x47C640, CellClass_CanThisExistHere_IgnoreSomething, 0x6)
250251
return CanExistHere; // Continue check the overlays .etc
251252
}
252253

254+
255+
DEFINE_HOOK(0x7396D2, UnitClass_TryToDeploy_Transfer, 0x5)
256+
{
257+
GET(UnitClass*, pUnit, EBP);
258+
GET(BuildingClass*, pStructure, EBX);
259+
260+
if (pUnit->Type->DeployToFire && pUnit->Target)
261+
pStructure->LastTarget = pUnit->Target;
262+
263+
const auto pStructureExt = BuildingExt::ExtMap.Find(pStructure);
264+
pStructureExt->DeployedTechno = true;
265+
266+
return 0;
267+
}
268+
253269
#pragma endregion

0 commit comments

Comments
 (0)