Skip to content

Commit 75b447a

Browse files
TaranDahlCoroniaCrimRecya
authored
Several attack move enhancement (#1730)
### Attack move - behavior when target acquired - Now you can make attacking moving units stop moving when they spot an enemy using `AttackMove.StopWhenTargetAcquired`. This is more like the attack move behavior in starcraft and warcraft. - This function is used to prevent units from charging forward and taking on more damage. - You can also make them move towards the spotted target using `AttackMove.PursuitTarget`. - This function is used for close range units like ZEP. In `rulesmd.ini`: ```ini [General] AttackMove.StopWhenTargetAcquired= ; boolean [SOMETECHNO] ; TechnoType AttackMove.StopWhenTargetAcquired= ; boolean, default to [General] -> AttackMove.StopWhenTargetAcquired if set, inverse of OpportunityFire otherwise. AttackMove.PursuitTarget= ; boolean ``` ```{note} 1. Many units would have stopped when they found an enemy. This behavior is independent of `AttackMove.StopWhenTargetAcquired`. 2. Some units (f.ex. jumpjets) will not fire correctly under the vanilla attack move. The exact reason is not clear, but this feature can fix this problem. 3. Jumpjets with `AttackMove.StopWhenTargetAcquired=true` will stop immediatly and not scatter to a cell. This is designed for practical reason. ``` ### Attack move - follow - Now you can have some units follow surrounding units when executing an attack move. The following behavior is equivalent to the behavior when using `ctrl + alt`. - Use `AttackMove.Follow.IncludeAir` to determine whether the follower will choose an air unit as a follow target. - This function should be useful for auxiliary units such as medics and repair drones. - We have made additional optimizations to the followed target selection algorithm to make this function more practical. In `rulesmd.ini`: ```ini [SOMETECHNO] ; TechnoType AttackMove.Follow=false ; boolean AttackMove.Follow.IncludeAir=false ; boolean ``` ### Attack move - without weapon - In vanilla, a unit without weapon is not allowed to attack move. Now you can disable this hardcoded behavior using `AttackMove.IgnoreWeaponCheck=true`. - Unarmed units of course cannot actually execute attack moves. This feature is to prevent the attack move pointer from being disabled when you select unarmed units and other units at the same time. In `rulesmd.ini`: ```ini [General] AttackMove.IgnoreWeaponCheck=false ; boolean ``` --------- Co-authored-by: Coronia <[email protected]> Co-authored-by: CrimRecya <[email protected]>
1 parent 6d70f9d commit 75b447a

File tree

13 files changed

+208
-3
lines changed

13 files changed

+208
-3
lines changed

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ This page lists all the individual contributions to the project by their author.
549549
- Customize whether `Crater=yes` animation would destroy tiberium
550550
- Targeting limitation for berzerk technos
551551
- Allows refineries to use multiple ActiveAnim simultaneously
552+
- Several attackmove related enhancement
552553
- **tyuah8**:
553554
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
554555
- Destroyed unit leaves sensors bugfix

docs/New-or-Enhanced-Logics.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,54 @@ AttackMove.Aggressive= ; boolean, default to [General] -> AttackMove.Agg
11711171
AttackMove.UpdateTarget= ; boolean, default to [General] -> AttackMove.UpdateTarget
11721172
```
11731173

1174+
### Attack move - behavior when target acquired
1175+
1176+
- Now you can make attack-moving units stop moving when they spot an enemy using `AttackMove.StopWhenTargetAcquired`. This is more like the attack move behavior in Starcraft and Warcraft.
1177+
- This feature is used to prevent units from charging forward and taking more damage during an attack move command.
1178+
- You can also make them keep chasing on the spotted target using `AttackMove.PursuitTarget`.
1179+
- This feature should be useful for close range units like ZEP.
1180+
1181+
1182+
In `rulesmd.ini`:
1183+
```ini
1184+
[General]
1185+
AttackMove.StopWhenTargetAcquired= ; boolean
1186+
1187+
[SOMETECHNO] ; TechnoType
1188+
AttackMove.StopWhenTargetAcquired= ; boolean, default to [General] -> AttackMove.StopWhenTargetAcquired if set, inverse of OpportunityFire otherwise.
1189+
AttackMove.PursuitTarget= ; boolean
1190+
```
1191+
1192+
```{note}
1193+
1. Many units would have stopped when they found an enemy during an attack move command already. This behavior is independent from `AttackMove.StopWhenTargetAcquired`.
1194+
2. Some units (f.ex. jumpjets) will not fire correctly under the vanilla attack move command. The exact reason is not clear, but this feature can fix this problem.
1195+
3. Jumpjets with `AttackMove.StopWhenTargetAcquired=true` will stop immediatly and not scatter to a cell. This is designed for practical reason.
1196+
```
1197+
1198+
### Attack move - follow
1199+
1200+
- Now you can have some units following surrounding units when executing an attack move command. The follow behavior is equivalent to the behavior of follow command (`ctrl + alt`).
1201+
- Use `AttackMove.Follow.IncludeAir` to determine whether the follower will follow an air unit.
1202+
- This feature should be useful for supportive units such as medics and repairers.
1203+
1204+
In `rulesmd.ini`:
1205+
```ini
1206+
[SOMETECHNO] ; TechnoType
1207+
AttackMove.Follow=false ; boolean
1208+
AttackMove.Follow.IncludeAir=false ; boolean
1209+
```
1210+
1211+
### Attack move - without weapon
1212+
1213+
- In vanilla, attack move command is not allowed to be given to units without weapons. Now you can disable this hardcoded behavior using `AttackMove.IgnoreWeaponCheck=true`.
1214+
- Unarmed units cannot actually execute attack move commands. This feature is to prevent the attack move pointer from being disabled when you select unarmed units and other units at the same time.
1215+
1216+
In `rulesmd.ini`:
1217+
```ini
1218+
[General]
1219+
AttackMove.IgnoreWeaponCheck=false ; boolean
1220+
```
1221+
11741222
### Aircraft spawner customizations
11751223

11761224
![image](_static/images/spawnrange-01.gif)

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ New:
407407
- [Allows refineries to use multiple ActiveAnim simultaneously](Fixed-or-Improved-Logics.md#allows-refineries-to-use-multiple-activeanim-simultaneously) (by TaranDahl)
408408
- Electric/RadBeam trail for laser tails (by NetsuNegi)
409409
- Add `DebrisMinimums` to keep the count of debris within a certain range (by CrimRecya)
410+
- Several attackmove related enhancement (by TaranDahl)
410411
411412
Vanilla fixes:
412413
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)

src/Ext/Rules/Body.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
269269
this->WarheadParticleAlphaImageIsLightFlash.Read(exINI, GameStrings::AudioVisual, "WarheadParticleAlphaImageIsLightFlash");
270270
this->CombatLightDetailLevel.Read(exINI, GameStrings::AudioVisual, "CombatLightDetailLevel");
271271
this->LightFlashAlphaImageDetailLevel.Read(exINI, GameStrings::AudioVisual, "LightFlashAlphaImageDetailLevel");
272-
273272
this->BuildingTypeSelectable.Read(exINI, GameStrings::General, "BuildingTypeSelectable");
274273

275274
this->ProneSpeed_Crawls.Read(exINI, GameStrings::General, "ProneSpeed.Crawls");
@@ -283,6 +282,9 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
283282

284283
this->BerzerkTargeting.Read(exINI, GameStrings::CombatDamage, "BerzerkTargeting");
285284

285+
this->AttackMove_IgnoreWeaponCheck.Read(exINI, GameStrings::General, "AttackMove.IgnoreWeaponCheck");
286+
this->AttackMove_StopWhenTargetAcquired.Read(exINI, GameStrings::General, "AttackMove.StopWhenTargetAcquired");
287+
286288
// Section AITargetTypes
287289
int itemsCount = pINI->GetKeyCount("AITargetTypes");
288290
for (int i = 0; i < itemsCount; ++i)
@@ -521,6 +523,8 @@ void RulesExt::ExtData::Serialize(T& Stm)
521523
.Process(this->TintColorIronCurtain)
522524
.Process(this->TintColorForceShield)
523525
.Process(this->TintColorBerserk)
526+
.Process(this->AttackMove_IgnoreWeaponCheck)
527+
.Process(this->AttackMove_StopWhenTargetAcquired)
524528
;
525529
}
526530

src/Ext/Rules/Body.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ class RulesExt
230230

231231
Valueable<AffectedHouse> BerzerkTargeting;
232232

233+
Valueable<bool> AttackMove_IgnoreWeaponCheck;
234+
Nullable<bool> AttackMove_StopWhenTargetAcquired;
235+
233236
// cache tint color
234237
int TintColorIronCurtain;
235238
int TintColorForceShield;
@@ -414,6 +417,9 @@ class RulesExt
414417
, TintColorIronCurtain { 0 }
415418
, TintColorForceShield { 0 }
416419
, TintColorBerserk { 0 }
420+
421+
, AttackMove_IgnoreWeaponCheck { false }
422+
, AttackMove_StopWhenTargetAcquired { }
417423
{ }
418424

419425
virtual ~ExtData() = default;

src/Ext/Techno/Body.Update.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ void TechnoExt::ExtData::OnEarlyUpdate()
4343
this->ApplyMindControlRangeLimit();
4444
this->UpdateRecountBurst();
4545
this->UpdateRearmInEMPState();
46+
47+
if (this->AttackMoveFollowerTempCount)
48+
{
49+
this->AttackMoveFollowerTempCount--;
50+
}
4651
}
4752

4853
void TechnoExt::ExtData::ApplyInterceptor()

src/Ext/Techno/Body.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ void TechnoExt::ExtData::Serialize(T& Stm)
652652
.Process(this->TintIntensityOwner)
653653
.Process(this->TintIntensityAllies)
654654
.Process(this->TintIntensityEnemies)
655+
.Process(this->AttackMoveFollowerTempCount)
655656
;
656657
}
657658

src/Ext/Techno/Body.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class TechnoExt
8282
int TintIntensityAllies;
8383
int TintIntensityEnemies;
8484

85+
int AttackMoveFollowerTempCount;
86+
8587
ExtData(TechnoClass* OwnerObject) : Extension<TechnoClass>(OwnerObject)
8688
, TypeExtData { nullptr }
8789
, Shield {}
@@ -134,6 +136,7 @@ class TechnoExt
134136
, TintIntensityOwner { 0 }
135137
, TintIntensityAllies { 0 }
136138
, TintIntensityEnemies { 0 }
139+
, AttackMoveFollowerTempCount { 0 }
137140
{ }
138141

139142
void OnEarlyUpdate();

src/Ext/Techno/Hooks.Firing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "Body.h"
1+
#include "Body.h"
22

33
#include <OverlayTypeClass.h>
44
#include <ScenarioClass.h>

src/Ext/Techno/Hooks.TargetEvaluation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,12 @@ DEFINE_HOOK(0x4DF3A0, FootClass_UpdateAttackMove_SelectNewTarget, 0x6)
187187

188188
const auto pExt = TechnoExt::ExtMap.Find(pThis);
189189

190-
if (pExt->TypeExtData->AttackMove_UpdateTarget.Get(RulesExt::Global()->AttackMove_UpdateTarget) && CheckAttackMoveCanResetTarget(pThis))
190+
if (pExt->TypeExtData->AttackMove_UpdateTarget.Get(RulesExt::Global()->AttackMove_UpdateTarget)
191+
&& CheckAttackMoveCanResetTarget(pThis))
191192
{
192193
pThis->Target = nullptr;
193194
pThis->HaveAttackMoveTarget = false;
195+
pExt->UpdateGattlingRateDownReset();
194196
}
195197

196198
return 0;

0 commit comments

Comments
 (0)