Skip to content

Commit fc7d6a4

Browse files
MetadoriusFS-21
andauthored
Warhead activation target health thresholds (#1398)
### Customizable Warhead trigger conditions - It is now possible to make warheads only trigger when target's HP is above and/or below certain percentage. - Both conditions need to evaluate to true in order for the warhead to trigger. In `rulesmd.ini`: ```ini [SOMEWARHEAD] ; WarheadType AffectsAbovePercent=0.0 ; floating point value, percents or absolute AffectsBelowPercent=1.0 ; floating point value, percents or absolute ``` --------- Co-authored-by: FS-21 <[email protected]>
1 parent fea4401 commit fc7d6a4

File tree

8 files changed

+72
-10
lines changed

8 files changed

+72
-10
lines changed

CREDITS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ This page lists all the individual contributions to the project by their author.
4848
- Ability to disable shadow for debris & meteor animations
4949
- Voxel light source position customization
5050
- `UseFixedVoxelLighting`
51+
- Warhead activation target health thresholds
5152
- **Uranusian (Thrifinesma)**:
5253
- Mind Control enhancement
5354
- Custom warhead splash list
@@ -144,6 +145,7 @@ This page lists all the individual contributions to the project by their author.
144145
- Map Events 604 & 605 for checking if a specific Techno enters in a cell
145146
- Warhead that can not kill
146147
- `Pips.HideIfNoStrength` and `SelfHealing.EnabledBy` additions for shields
148+
- Warhead activation target health thresholds enhancements
147149
- **Starkku**:
148150
- Misc. minor bugfixes & improvements
149151
- AI script actions:

docs/Fixed-or-Improved-Logics.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,6 +1846,20 @@ Rocker.AmplitudeMultiplier=1.0 ; floating point value, multiplier
18461846
Rocker.AmplitudeOverride= ; integer
18471847
```
18481848

1849+
### Customizable Warhead trigger conditions
1850+
1851+
- It is now possible to make warheads only trigger when target's HP is above and/or below certain percentage.
1852+
- Both conditions need to evaluate to true in order for the warhead to trigger.
1853+
- If set to `false`, `EffectsRequireVerses` makes the Phobos-introduced warhead effects trigger even if it can't damage the target because of it's current ArmorType (e.g. 0% in `Verses`).
1854+
1855+
In `rulesmd.ini`:
1856+
```ini
1857+
[SOMEWARHEAD] ; WarheadType
1858+
AffectsAbovePercent=0.0 ; floating point value, percents or absolute
1859+
AffectsBelowPercent=1.0 ; floating point value, percents or absolute
1860+
EffectsRequireVerses=false ; boolean
1861+
```
1862+
18491863
### Customizable Warhead animation behaviour
18501864

18511865
- It is possible to make game play random animation from `AnimList` by setting `AnimList.PickRandom` to true. The result is similar to what `EMEffect=true` produces, however it comes with no side-effects (`EMEffect=true` prevents `Inviso=true` projectiles from snapping on targets, making them miss moving targets).

docs/New-or-Enhanced-Logics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1877,7 +1877,7 @@ FireUp.ResetInRetarget=true ; boolean
18771877
All new Warhead effects
18781878
- Can be used with `CellSpread` and Ares' GenericWarhead superweapon where applicable.
18791879
- Cannot be used with `MindControl.Permanent=yes` of Ares.
1880-
- Respect `Verses` where applicable unless `EffectsRequireVerses` is set to false. If target has an active shield, its armor type is used instead unless warhead can penetrate the shield.
1880+
- Respect `Verses` where applicable unless `EffectsRequireVerses` is set to `false`. If target has an active shield, its armor type is used instead unless warhead can penetrate the shield.
18811881
```
18821882

18831883
### Break Mind Control on impact

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ New:
599599
- Draw visual effects for airburst weapons (by CrimRecya)
600600
- Unit `Speed` setting now accepts floating point values (by Starkku)
601601
- `Strafing` is now disabled by default when using `Trajectory` (by CrimRecya)
602+
- Warhead activation target health thresholds (by FS-21, Kerbiter)
602603
603604
Vanilla fixes:
604605
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)

src/Ext/Bullet/Hooks.DetonateLogics.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,27 @@
1111
#include <AircraftClass.h>
1212
#include <TacticalClass.h>
1313

14-
DEFINE_HOOK(0x4690D4, BulletClass_Logics_ScreenShake, 0x6)
14+
DEFINE_HOOK(0x4690D4, BulletClass_Logics_NewChecks, 0x6)
1515
{
16-
enum { SkipShaking = 0x469130 };
16+
enum { SkipShaking = 0x469130, GoToExtras = 0x469AA4 };
1717

18+
GET(BulletClass*, pBullet, ESI);
1819
GET(WarheadTypeClass*, pWarhead, EAX);
1920
GET_BASE(CoordStruct*, pCoords, 0x8);
2021

21-
auto const pWHExt = WarheadTypeExt::ExtMap.Find(pWarhead);
22+
auto const pExt = WarheadTypeExt::ExtMap.Find(pWarhead);
23+
24+
if (auto pTarget = abstract_cast<TechnoClass*>(pBullet->Target))
25+
{
26+
// Check if the WH should affect the techno target or skip it
27+
if (!pExt->IsHealthInThreshold(pTarget) && pBullet->Owner != pBullet->Target)
28+
return GoToExtras;
29+
}
30+
31+
// Check for ScreenShake
2232
auto&& [_, visible] = TacticalClass::Instance->CoordsToClient(*pCoords);
2333

24-
if (pWHExt->ShakeIsLocal && !visible)
34+
if (pExt->ShakeIsLocal && !visible)
2535
return SkipShaking;
2636

2737
return 0;
@@ -312,6 +322,13 @@ DEFINE_HOOK(0x469AA4, BulletClass_Logics_Extras, 0x5)
312322
auto const pWH = pWeaponExt->ExtraWarheads[i];
313323
int damage = defaultDamage;
314324
size_t size = pWeaponExt->ExtraWarheads_DamageOverrides.size();
325+
auto const pWHExt = WarheadTypeExt::ExtMap.Find(pWH);
326+
327+
if (auto const pTarget = abstract_cast<TechnoClass*>(pThis->Target))
328+
{
329+
if (!pWHExt->IsHealthInThreshold(pTarget))
330+
continue;
331+
}
315332

316333
if (size > i)
317334
damage = pWeaponExt->ExtraWarheads_DamageOverrides[i];

src/Ext/RadSite/Body.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ void RadSiteExt::ExtData::Initialize()
1616
bool RadSiteExt::ExtData::ApplyRadiationDamage(TechnoClass* pTarget, int& damage)
1717
{
1818
const auto pWarhead = this->Type->GetWarhead();
19+
const auto pWHExt = WarheadTypeExt::ExtMap.Find(pWarhead);
20+
21+
if (!pWHExt->IsHealthInThreshold(pTarget))
22+
return false;
1923

2024
if (!this->Type->GetWarheadDetonate())
2125
{
@@ -25,14 +29,9 @@ bool RadSiteExt::ExtData::ApplyRadiationDamage(TechnoClass* pTarget, int& damage
2529
else
2630
{
2731
if (this->Type->GetWarheadDetonateFull())
28-
{
2932
WarheadTypeExt::DetonateAt(pWarhead, pTarget, this->RadInvoker, damage, this->RadHouse);
30-
}
3133
else
32-
{
33-
const auto pWHExt = WarheadTypeExt::ExtMap.Find(pWarhead);
3434
pWHExt->DamageAreaWithTarget(pTarget->GetCoords(), damage, this->RadInvoker, pWarhead, true, this->RadHouse, pTarget);
35-
}
3635

3736
if (!pTarget->IsAlive)
3837
return false;

src/Ext/WarheadType/Body.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,25 @@ bool WarheadTypeExt::ExtData::CanAffectTarget(TechnoClass* pTarget) const
3535
if (!pTarget)
3636
return false;
3737

38+
if (!IsHealthInThreshold(pTarget))
39+
return false;
40+
3841
if (!this->EffectsRequireVerses)
3942
return true;
4043

4144
return GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), pTarget) != 0.0;
4245
}
4346

47+
bool WarheadTypeExt::ExtData::IsHealthInThreshold(TechnoClass* pTarget) const
48+
{
49+
// Check if the WH should affect the techno target or skip it
50+
double hp = pTarget->GetHealthPercentage();
51+
bool hpBelowPercent = hp <= this->AffectsBelowPercent;
52+
bool hpAbovePercent = hp > this->AffectsAbovePercent;
53+
54+
return hpBelowPercent && hpAbovePercent;
55+
}
56+
4457
// Checks if Warhead can affect target that might or might be currently invulnerable.
4558
bool WarheadTypeExt::ExtData::CanAffectInvulnerable(TechnoClass* pTarget) const
4659
{
@@ -274,6 +287,12 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
274287

275288
this->AirstrikeTargets.Read(exINI, pSection, "AirstrikeTargets");
276289

290+
this->AffectsAbovePercent.Read(exINI, pSection, "AffectsAbovePercent");
291+
this->AffectsBelowPercent.Read(exINI, pSection, "AffectsBelowPercent");
292+
293+
if (this->AffectsAbovePercent > this->AffectsBelowPercent)
294+
Debug::Log("[Developer warning][%s] AffectsAbovePercent is bigger than AffectsBelowPercent, the warhead will never activate!\n", pSection);
295+
277296
// Convert.From & Convert.To
278297
TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All);
279298

@@ -493,6 +512,9 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm)
493512
.Process(this->SuppressReflectDamage_Types)
494513
.Process(this->SuppressReflectDamage_Groups)
495514

515+
.Process(this->AffectsAbovePercent)
516+
.Process(this->AffectsBelowPercent)
517+
496518
.Process(this->InflictLocomotor)
497519
.Process(this->RemoveInflictedLocomotor)
498520

src/Ext/WarheadType/Body.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ class WarheadTypeExt
177177

178178
Valueable<AffectedTarget> AirstrikeTargets;
179179

180+
Valueable<double> AffectsAbovePercent;
181+
Valueable<double> AffectsBelowPercent;
182+
180183
// Ares tags
181184
// http://ares-developers.github.io/Ares-docs/new/warheads/general.html
182185
Valueable<bool> AffectsEnemies;
@@ -352,6 +355,9 @@ class WarheadTypeExt
352355

353356
, AirstrikeTargets { AffectedTarget::Building }
354357

358+
, AffectsAbovePercent { 0.0 }
359+
, AffectsBelowPercent { 1.0 }
360+
355361
, AffectsEnemies { true }
356362
, AffectsOwner {}
357363
, EffectsRequireVerses { true }
@@ -386,6 +392,7 @@ class WarheadTypeExt
386392
bool CanAffectTarget(TechnoClass* pTarget) const;
387393
bool CanAffectInvulnerable(TechnoClass* pTarget) const;
388394
bool EligibleForFullMapDetonation(TechnoClass* pTechno, HouseClass* pOwner) const;
395+
bool IsHealthInThreshold(TechnoClass* pTarget) const;
389396

390397
virtual ~ExtData() = default;
391398
virtual void LoadFromINIFile(CCINIClass* pINI) override;

0 commit comments

Comments
 (0)