Skip to content

Commit 490a7df

Browse files
FlactineMetadoriusNetsuNegi
authored
Add veterancy-based target filtering for weapons and warheads (#2008)
This PR introduces **veterancy-based filtering** for both weapon targeting and warhead effect application. --- ## 1. Weapon target filtering by target veterancy Weapons can now restrict which targets they are allowed to attack based on the target’s veterancy level. This affects both weapon firing eligibility and weapon selection logic (except for special cases where weapon selection is fixed by the engine). ### New INI options: ```ini [SOMEWEAPON] ; WeaponType CanTargetVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all) ``` Targets whose veterancy is not included in the specified enumeration will not be considered valid targets for the weapon. --- ## 2. Warhead effect filtering by target veterancy Warheads can now conditionally apply their effects based on the target’s veterancy level. Unlike weapon filtering, this logic does **not** affect whether a weapon can fire, but instead determines whether the warhead’s effects will be applied after detonation. ### New INI options: ```ini [SOMEWARHEAD] ; WarheadType AffectsVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all) ``` * The warhead will only affect targets whose veterancy is explicitly listed in AffectsVeterancy. --- --- --- 本次更新新增了**基于目标等级(Veterancy)的筛选逻辑**,分别作用于**武器攻击判定**和**弹头效果生效判定**。 --- ## 1. 基于目标等级的武器筛选 武器现在可以根据目标单位的经验等级,决定是否允许对其进行攻击。 该逻辑不仅影响武器能否开火,也会影响武器选择流程(部分引擎强制固定选择的特殊情况除外)。 ### 新增 INI 选项(WeaponType): ```ini [SOMEWEAPON] ; 武器类型 CanTargetVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all) ``` 当目标的等级未被列入指定枚举时,武器将不会将其视为可攻击目标。 --- ## 2. 基于目标等级的弹头效果筛选 弹头现在可以根据目标单位的经验等级,决定爆炸后是否对其产生效果。 与武器筛选不同,此逻辑**不影响武器是否开火**,而是作用于爆炸结算阶段。 ### 新增 INI 选项: ```ini [SOMEWARHEAD] ; 弹头类型 AffectsVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all) ``` * 只有等级被列入指定枚举的目标才会受到弹头效果影响 --------- Co-authored-by: Kerbiter <crabiter@vivaldi.net> Co-authored-by: Netsu_Negi <71598172+NetsuNegi@users.noreply.github.com>
1 parent 15e75f2 commit 490a7df

18 files changed

Lines changed: 131 additions & 11 deletions

CREDITS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,9 @@ This page lists all the individual contributions to the project by their author.
678678
- **solar-III (凤九歌)**
679679
- Target scanning delay customization (documentation)
680680
- Skip target scanning function calling for unarmed technos (documentation)
681-
- **Flactine** - add target filtering options to attacheffect system
681+
- **Flactine**
682+
- Add target filtering options to attacheffect system
683+
- Add veterancy-based target filtering for weapons and warheads
682684
- **tyuah8**:
683685
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
684686
- Destroyed unit leaves sensors bugfix

docs/Fixed-or-Improved-Logics.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,7 @@ Conventional.IgnoreUnits=false ; boolean
23482348
### Customizable Warhead trigger conditions
23492349

23502350
- `AffectsBelowPercent` and `AffectsAbovePercent` can be used to set the health percentage thresholds that target needs to be below/equal and/or above of for the Warhead to detonate. If target has zero health left this check is bypassed.
2351+
- `AffectsVeterancy` sets the veterancy levels that allow the Warhead to detonate on the target.
23512352
- If set to `false`, `AffectsNeutral` makes the warhead can't damage or affect target that belongs to neutral house.
23522353
- 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`).
23532354

@@ -2356,6 +2357,7 @@ In `rulesmd.ini`:
23562357
[SOMEWARHEAD] ; WarheadType
23572358
AffectsBelowPercent=1.0 ; floating point value, percents or absolute
23582359
AffectsAbovePercent=0.0 ; floating point value, percents or absolute
2360+
AffectsVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all)
23592361
AffectsNeutral=true ; boolean
23602362
EffectsRequireVerses=false ; boolean
23612363
```

docs/New-or-Enhanced-Logics.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,11 +2992,12 @@ This function is only used as an additional scattering visual display, which is
29922992

29932993
In `rulesmd.ini`:
29942994
```ini
2995-
[SOMEWEAPON] ; WeaponType
2996-
CanTarget=all ; List of Affected Target Enumeration (none|land|water|empty|infantry|units|buildings|all)
2997-
CanTargetHouses=all ; List of Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
2998-
CanTarget.MaxHealth=1.0 ; floating point value, percents or absolute
2999-
CanTarget.MinHealth=0.0 ; floating point value, percents or absolute
2995+
[SOMEWEAPON] ; WeaponType
2996+
CanTarget=all ; List of Affected Target Enumeration (none|land|water|empty|infantry|units|buildings|all)
2997+
CanTargetHouses=all ; List of Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
2998+
CanTarget.MaxHealth=1.0 ; floating point value, percents or absolute
2999+
CanTarget.MinHealth=0.0 ; floating point value, percents or absolute
3000+
CanTargetVeterancy=all ; List of Affected Veterancy Enumeration (none|rookie|veteran|elite|all)
30003001
```
30013002

30023003
```{note}

docs/Whats-New.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ New:
518518
- [Attack non-threatening structures extensions](New-or-Enhanced-Logics.md#attack-non-threatening-structures-techno) (by FlyStar)
519519
- [Customize size for mind controlled unit](New-or-Enhanced-Logics.md#mind-control-enhancement) (by NetsuNegi)
520520
- [Deploy priority filtering](New-or-Enhanced-Logics.md#low-priority-for-deploy) (by Starkku)
521+
- [Weapon target filtering by target veterancy](New-or-Enhanced-Logics.md#weapon-targeting-filter) (by Flactine)
522+
- [Warhead effect filtering by target veterancy](Fixed-or-Improved-Logics.md#customizable-warhead-trigger-conditions) (by Flactine)
521523
522524
Vanilla fixes:
523525
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)

src/Ext/Bullet/Hooks.DetonateLogics.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ DEFINE_HOOK(0x4690D4, BulletClass_Logics_NewChecks, 0x6)
1919
if (auto const pTarget = abstract_cast<TechnoClass*>(pBullet->Target))
2020
{
2121
// Check if the WH should affect the techno target or skip it
22-
if (!pExt->IsHealthInThreshold(pTarget) || (!pExt->AffectsNeutral && pTarget->Owner->IsNeutral()))
22+
if (!pExt->IsHealthInThreshold(pTarget) || !pExt->IsVeterancyInThreshold(pTarget) || (!pExt->AffectsNeutral && pTarget->Owner->IsNeutral()))
2323
return GoToExtras;
2424
}
2525

@@ -382,7 +382,7 @@ DEFINE_HOOK(0x469AA4, BulletClass_Logics_Extras, 0x5)
382382
auto const pWHExt = WarheadTypeExt::ExtMap.Find(pWH);
383383
auto const pTarget = abstract_cast<TechnoClass*>(pThis->Target);
384384

385-
if (pTarget && !pWHExt->IsHealthInThreshold(pTarget))
385+
if (pTarget && !pWHExt->IsHealthInThreshold(pTarget) && !pWHExt->IsVeterancyInThreshold(pTarget))
386386
continue;
387387

388388
int damage = defaultDamage;
@@ -556,7 +556,8 @@ static bool IsAllowedSplitsTarget(TechnoClass* pSource, HouseClass* pOwner, Weap
556556
if (!EnumFunctions::CanTargetHouse(pWeaponExt->CanTargetHouses, pOwner, pTarget->Owner)
557557
|| !EnumFunctions::IsCellEligible(pTarget->GetCell(), pWeaponExt->CanTarget, true, true)
558558
|| !EnumFunctions::IsTechnoEligible(pTarget, pWeaponExt->CanTarget)
559-
|| !pWeaponExt->IsHealthInThreshold(pTarget))
559+
|| !pWeaponExt->IsHealthInThreshold(pTarget)
560+
|| !pWeaponExt->IsVeterancyInThreshold(pTarget))
560561
{
561562
return false;
562563
}

src/Ext/Bullet/Hooks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ DEFINE_HOOK(0x46A4FB, BulletClass_Shrapnel_Targeting, 0x6)
274274
if (!pWeaponExt->SkipWeaponPicking)
275275
{
276276
if (!EnumFunctions::CanTargetHouse(pWeaponExt->CanTargetHouses, pOwner, pTechno->Owner) || !EnumFunctions::IsTechnoEligible(pTechno, pWeaponExt->CanTarget)
277-
|| !pWeaponExt->IsHealthInThreshold(pTechno) || !pWeaponExt->HasRequiredAttachedEffects(pTechno, pSource))
277+
|| !pWeaponExt->IsHealthInThreshold(pTechno) || !pWeaponExt->IsVeterancyInThreshold(pTechno) || !pWeaponExt->HasRequiredAttachedEffects(pTechno, pSource))
278278
{
279279
return SkipObject;
280280
}

src/Ext/Techno/Body.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class TechnoExt
286286
static void CreateDelayedFireAnim(TechnoClass* pThis, AnimTypeClass* pAnimType, int weaponIndex, bool attach, bool center, bool removeOnNoDelay, bool onTurret, CoordStruct firingCoords);
287287
static bool HandleDelayedFireWithPauseSequence(TechnoClass* pThis, WeaponTypeClass* pWeapon, int weaponIndex, int frame, int firingFrame);
288288
static bool IsHealthInThreshold(TechnoClass* pObject, double min, double max);
289+
static bool IsVeterancyInThreshold(TechnoClass* pObject, double min, double max);
289290
static UnitTypeClass* GetUnitTypeExtra(UnitClass* pUnit, TechnoTypeExt::ExtData* pData);
290291
static AircraftTypeClass* GetAircraftTypeExtra(AircraftClass* pAircraft);
291292
static bool CannotMove(UnitClass* pThis);

src/Ext/Techno/Hooks.Firing.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ DEFINE_HOOK(0x6FC339, TechnoClass_CanFire, 0x6)
361361
if (!EnumFunctions::IsTechnoEligible(pTargetTechno, pWeaponExt->CanTarget)
362362
|| !EnumFunctions::CanTargetHouse(pWeaponExt->CanTargetHouses, pThis->Owner, pTargetTechno->Owner)
363363
|| !pWeaponExt->IsHealthInThreshold(pTargetTechno)
364+
|| !pWeaponExt->IsVeterancyInThreshold(pTargetTechno)
364365
|| !pWeaponExt->HasRequiredAttachedEffects(pTargetTechno, pThis))
365366
{
366367
return CannotFire;

src/Ext/Techno/Hooks.ReceiveDamage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ DEFINE_HOOK(0x701900, TechnoClass_ReceiveDamage_Shield, 0x6)
2121

2222
// AffectsAbove/BelowPercent & AffectsNeutral can ignore IgnoreDefenses like AffectsAllies/Enmies/Owner
2323
// They should be checked here to cover all cases that directly use ReceiveDamage to deal damage
24-
if (!pWHExt->IsHealthInThreshold(pThis) || (!pWHExt->AffectsNeutral && pThis->Owner->IsNeutral()))
24+
if (!pWHExt->IsHealthInThreshold(pThis) || !pWHExt->IsVeterancyInThreshold(pThis) || (!pWHExt->AffectsNeutral && pThis->Owner->IsNeutral()))
2525
{
2626
damage = 0;
2727
return 0;

src/Ext/Techno/WeaponHelpers.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ int TechnoExt::PickWeaponIndex(TechnoClass* pThis, TechnoClass* pTargetTechno, A
4040
if (!EnumFunctions::IsTechnoEligible(pTargetTechno, pSecondExt->CanTarget)
4141
|| !EnumFunctions::CanTargetHouse(pSecondExt->CanTargetHouses, pThis->Owner, pTargetTechno->Owner)
4242
|| !pSecondExt->IsHealthInThreshold(pTargetTechno)
43+
|| !pSecondExt->IsVeterancyInThreshold(pTargetTechno)
4344
|| !pSecondExt->HasRequiredAttachedEffects(pTargetTechno, pThis))
4445
{
4546
return weaponIndexOne;
@@ -70,6 +71,7 @@ int TechnoExt::PickWeaponIndex(TechnoClass* pThis, TechnoClass* pTargetTechno, A
7071
if (!EnumFunctions::IsTechnoEligible(pTargetTechno, pFirstExt->CanTarget)
7172
|| !EnumFunctions::CanTargetHouse(pFirstExt->CanTargetHouses, pThis->Owner, pTargetTechno->Owner)
7273
|| !pFirstExt->IsHealthInThreshold(pTargetTechno)
74+
|| !pFirstExt->IsVeterancyInThreshold(pTargetTechno)
7375
|| !firstAllowedAE)
7476
{
7577
return weaponIndexTwo;

0 commit comments

Comments
 (0)