Skip to content

[Customize & New Feature]Targeting Optimizations #1364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,12 @@ This page lists all the individual contributions to the project by their author.
- Several attackmove related enhancement
- Fix the bug that `OpenToppedWarpDistance` is calculated incorrectly for building target
- Burst without delay
- Target scanning delay customization (code)
- Skip target scanning function calling for unarmed technos (code)
- Force techno targeting in distributed frames to improve performance
- **solar-III (凤九歌)**
- Target scanning delay customization (documentation)
- Skip target scanning function calling for unarmed technos (documentation)
- **tyuah8**:
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
- Destroyed unit leaves sensors bugfix
Expand Down
1 change: 1 addition & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Ext\Techno\Hooks.Targeting.cpp" />
<ClCompile Include="src\Ext\Infantry\Hooks.Firing.cpp" />
<ClCompile Include="src\Ext\TechnoType\Hooks.MultiWeapon.cpp" />
<ClCompile Include="src\Ext\Unit\Hooks.Firing.cpp" />
Expand Down
42 changes: 42 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Animations with `MakeInfantry` and `UseNormalLight=false` that are drawn in unit palette will now have cell lighting changes applied on them.
- Removed 0 damage effect on jumpjet infantries from `InfDeath=9` warhead.
- Fixed Nuke & Dominator Level lighting not applying to AircraftTypes.
- Skip target scanning function calling for unarmed technos.
- Projectiles created from `AirburstWeapon` now remember the WeaponType and can apply radiation etc.
- Fixed damaged aircraft not repairing on `UnitReload=true` docks unless they land on the dock first.
- Certain global tileset indices (`ShorePieces`, `WaterSet`, `CliffSet`, `WaterCliffs`, `WaterBridge`, `BridgeSet` and `WoodBridgeSet`) can now be toggled to be parsed for lunar theater by setting `[General] -> ApplyLunarFixes` to true in `lunarmd.ini`. Do note that enabling this without fixing f.ex `WoodBridgeTileSet` pointing to a tileset with `TilesInSet=0` will cause issues in-game.
Expand Down Expand Up @@ -1166,6 +1167,22 @@ ForbidParallelAIQueues.Building=no ; boolean
ForbidParallelAIQueues=false ; boolean
```

### Force techno targeting in distributed frames to improve performance

- When you create many technos in a same frame (i.e. starting the game with a campaign map that initially has a large number of technos), they will always scan for targets in a synchronous period, causing game lag. Increasing targeting delay alone will not make things better, as their targeting is still synchronized.
- It is now possible to force them to seek targets separately. When a techno spawns, it will generate a random number in \[0,15\]. If `DistributeTargetingFrame=true` is set, only when the current frame number is congruent with the technos own number under modulo 16, will it do targeting.
- You can use `DistributeTargetingFrame.AIOnly` to make it only work for AI (Players are not likely to have so many technos.)

In `rulesmd.ini`
```ini
[General]
DistributeTargetingFrame=false ; boolean
DistributeTargetingFrame.AIOnly=true ; boolean

[SOMETECHNO] ; TechnoType
DistributeTargetingFrame= ; boolean
```

### Iron Curtain & Force Shield effects on organics customization

- In vanilla game, when Iron Curtain is applied on `Organic=true` units like squids or infantry, they could only get killed instantly by `C4Warhead`. This behavior is now unhardcoded and can be set with `IronCurtain.EffectOnOrganics` globally and on per-TechnoType basis with `IronCurtain.Effect`. Following values are respected:
Expand Down Expand Up @@ -1349,6 +1366,31 @@ SubterraneanSpeed=-1 ; floating point value
`SubterraneanHeight` expects negative values to be used and may behave erratically if set to above -50.
```

### Target scanning delay optimization

- In vanilla, the game used `NormalTargetingDelay` and `GuardAreaTargetingDelay` to globally control the target searching intervals. Increasing these values would make units stupid, while decreasing them would cause game lag.
- Now, you can define them per techno, also allowing different values for AI and players. The default values are the same as those originally defined by the vanilla flags.
- You can also specific this delay for attack move mission. The default value is `NormalTargetingDelay`.

In `rulesmd.ini`:
```ini
[General]
AINormalTargetingDelay= ; integer, game frames
PlayerNormalTargetingDelay= ; integer, game frames
AIGuardAreaTargetingDelay= ; integer, game frames
PlayerGuardAreaTargetingDelay= ; integer, game frames
AIAttackMoveTargetingDelay= ; integer, game frames
PlayerAttackMoveTargetingDelay= ; integer, game frames

[SOMETECHNO] ; TechnoType
AINormalTargetingDelay= ; integer, game frames
PlayerNormalTargetingDelay= ; integer, game frames
AIGuardAreaTargetingDelay= ; integer, game frames
PlayerGuardAreaTargetingDelay= ; integer, game frames
AIAttackMoveTargetingDelay= ; integer, game frames
PlayerAttackMoveTargetingDelay= ; integer, game frames
```

### Voxel body multi-section shadows

- It is also now possible for vehicles and aircraft to display shadows for multiple sections of the voxel body at once, instead of just one section specified by `ShadowIndex`, by specifying the section indices in `ShadowIndices` (which defaults to `ShadowIndex`) in unit's `artmd.ini` entry.
Expand Down
3 changes: 3 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ New:
- [Linked superweapons](New-or-Enhanced-Logics.md#linked-superweapons) (by FS-21)
- [Delayed fire weapons](New-or-Enhanced-Logics.md#delayed-firing) (by Starkku)
- Burst without delay (by CrimRecya & TaranDahl)
- Skip target scanning function calling for unarmed technos (by TaranDahl and solar-III)
- Target scanning delay customization (by TaranDahl and solar-III)
- Force techno targeting in distributed frames to improve performance (by TaranDahl)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
17 changes: 17 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,15 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->AttackMove_IgnoreWeaponCheck.Read(exINI, GameStrings::General, "AttackMove.IgnoreWeaponCheck");
this->AttackMove_StopWhenTargetAcquired.Read(exINI, GameStrings::General, "AttackMove.StopWhenTargetAcquired");

this->AINormalTargetingDelay.Read(exINI, GameStrings::General, "AINormalTargetingDelay");
this->PlayerNormalTargetingDelay.Read(exINI, GameStrings::General, "PlayerNormalTargetingDelay");
this->AIGuardAreaTargetingDelay.Read(exINI, GameStrings::General, "AIGuardAreaTargetingDelay");
this->PlayerGuardAreaTargetingDelay.Read(exINI, GameStrings::General, "PlayerGuardAreaTargetingDelay");
this->AIAttackMoveTargetingDelay.Read(exINI, GameStrings::General, "AIAttackMoveTargetingDelay");
this->PlayerAttackMoveTargetingDelay.Read(exINI, GameStrings::General, "PlayerAttackMoveTargetingDelay");
this->DistributeTargetingFrame.Read(exINI, GameStrings::General, "DistributeTargetingFrame");
this->DistributeTargetingFrame_AIOnly.Read(exINI, GameStrings::General, "DistributeTargetingFrame.AIOnly");

// Section AITargetTypes
int itemsCount = pINI->GetKeyCount("AITargetTypes");
for (int i = 0; i < itemsCount; ++i)
Expand Down Expand Up @@ -513,6 +522,14 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->WarheadParticleAlphaImageIsLightFlash)
.Process(this->CombatLightDetailLevel)
.Process(this->LightFlashAlphaImageDetailLevel)
.Process(this->AINormalTargetingDelay)
.Process(this->PlayerNormalTargetingDelay)
.Process(this->AIGuardAreaTargetingDelay)
.Process(this->PlayerGuardAreaTargetingDelay)
.Process(this->AIAttackMoveTargetingDelay)
.Process(this->PlayerAttackMoveTargetingDelay)
.Process(this->DistributeTargetingFrame)
.Process(this->DistributeTargetingFrame_AIOnly)
.Process(this->BuildingTypeSelectable)
.Process(this->ProneSpeed_Crawls)
.Process(this->ProneSpeed_NoCrawls)
Expand Down
17 changes: 17 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,15 @@ class RulesExt
Valueable<int> CombatLightDetailLevel;
Valueable<int> LightFlashAlphaImageDetailLevel;

Nullable<int> AINormalTargetingDelay;
Nullable<int> PlayerNormalTargetingDelay;
Nullable<int> AIGuardAreaTargetingDelay;
Nullable<int> PlayerGuardAreaTargetingDelay;
Nullable<int> AIAttackMoveTargetingDelay;
Nullable<int> PlayerAttackMoveTargetingDelay;
Valueable<bool> DistributeTargetingFrame;
Valueable<bool> DistributeTargetingFrame_AIOnly;

Valueable<bool> BuildingWaypoints;
Valueable<bool> BuildingTypeSelectable;

Expand Down Expand Up @@ -401,6 +410,14 @@ class RulesExt
, WarheadParticleAlphaImageIsLightFlash { false }
, CombatLightDetailLevel { 0 }
, LightFlashAlphaImageDetailLevel { 0 }
, AINormalTargetingDelay {}
, PlayerNormalTargetingDelay {}
, AIGuardAreaTargetingDelay {}
, PlayerGuardAreaTargetingDelay {}
, AIAttackMoveTargetingDelay {}
, PlayerAttackMoveTargetingDelay {}
, DistributeTargetingFrame { false }
, DistributeTargetingFrame_AIOnly { true }
, BuildingWaypoints { false }
, BuildingTypeSelectable { false }
, ProneSpeed_Crawls { 0.67 }
Expand Down
44 changes: 44 additions & 0 deletions src/Ext/Techno/Hooks.Targeting.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "Body.h"

DEFINE_HOOK(0x6FA697, TechnoClass_Update_DontScanIfUnarmed, 0x6)
{
enum { SkipTargeting = 0x6FA6F5 };
GET(TechnoClass* const, pThis, ESI);
return pThis->IsArmed() ? 0 : SkipTargeting;
}

DEFINE_HOOK(0x70982C, TechnoClass_TargetAndEstimateDamage_TargetingDelay, 0x8)
{
enum { SkipGameCode = 0x70989C };

GET(TechnoClass* const, pThis, ESI);
GET(const int, frame, EAX);

pThis->unknown_4FC = frame;
int delay = ScenarioClass::Instance->Random.RandomRanged(0, 2);
const auto pTypeExt = TechnoExt::ExtMap.Find(pThis)->TypeExtData;

if (pThis->MegaMissionIsAttackMove())
{
delay += pThis->Owner->IsControlledByHuman()
? pTypeExt->PlayerAttackMoveTargetingDelay.Get(RulesExt::Global()->PlayerAttackMoveTargetingDelay.Get(RulesClass::Instance->NormalTargetingDelay))
: pTypeExt->AIAttackMoveTargetingDelay.Get(RulesExt::Global()->AIAttackMoveTargetingDelay.Get(RulesClass::Instance->NormalTargetingDelay));
}
else if (pThis->CurrentMission == Mission::Area_Guard)
{
delay += pThis->Owner->IsControlledByHuman()
? pTypeExt->PlayerGuardAreaTargetingDelay.Get(RulesExt::Global()->PlayerGuardAreaTargetingDelay.Get(RulesClass::Instance->GuardAreaTargetingDelay))
: pTypeExt->AIGuardAreaTargetingDelay.Get(RulesExt::Global()->AIGuardAreaTargetingDelay.Get(RulesClass::Instance->GuardAreaTargetingDelay));
}
else
{
delay += pThis->Owner->IsControlledByHuman()
? pTypeExt->PlayerNormalTargetingDelay.Get(RulesExt::Global()->PlayerNormalTargetingDelay.Get(RulesClass::Instance->NormalTargetingDelay))
: pTypeExt->AINormalTargetingDelay.Get(RulesExt::Global()->AINormalTargetingDelay.Get(RulesClass::Instance->NormalTargetingDelay));
}

R->ECX(delay);
R->EDX(frame);

return SkipGameCode;
}
13 changes: 10 additions & 3 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,19 +220,26 @@ DEFINE_HOOK(0x6F42F7, TechnoClass_Init, 0x2)
return 0;

auto const pExt = TechnoExt::ExtMap.Find(pThis);
pExt->TypeExtData = TechnoTypeExt::ExtMap.Find(pType);
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pType);
pExt->TypeExtData = pTypeExt;

pExt->CurrentShieldType = pExt->TypeExtData->ShieldType;
pExt->CurrentShieldType = pTypeExt->ShieldType;
pExt->InitializeAttachEffects();
pExt->InitializeDisplayInfo();
pExt->InitializeLaserTrails();

if (!pExt->AE.HasTint && !pExt->CurrentShieldType)
pExt->UpdateTintValues();

if (pExt->TypeExtData->Harvester_Counted)
if (pTypeExt->Harvester_Counted)
HouseExt::ExtMap.Find(pThis->Owner)->OwnedCountedHarvesters.push_back(pThis);

if ((pThis->Owner->IsControlledByHuman() || !RulesExt::Global()->DistributeTargetingFrame_AIOnly)
&& pTypeExt->DistributeTargetingFrame.Get(RulesExt::Global()->DistributeTargetingFrame))
{
pThis->TargetingTimer.Start(ScenarioClass::Instance->Random.RandomRanged(0, 15));
}

return 0;
}

Expand Down
17 changes: 17 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,15 @@ 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->AINormalTargetingDelay.Read(exINI, pSection, "AINormalTargetingDelay");
this->PlayerNormalTargetingDelay.Read(exINI, pSection, "PlayerNormalTargetingDelay");
this->AIGuardAreaTargetingDelay.Read(exINI, pSection, "AIGuardAreaTargetingDelay");
this->PlayerGuardAreaTargetingDelay.Read(exINI, pSection, "PlayerGuardAreaTargetingDelay");
this->AIAttackMoveTargetingDelay.Read(exINI, pSection, "AIAttackMoveTargetingDelay");
this->PlayerAttackMoveTargetingDelay.Read(exINI, pSection, "PlayerAttackMoveTargetingDelay");
this->DistributeTargetingFrame.Read(exINI, pSection, "DistributeTargetingFrame");

this->BunkerableAnyway.Read(exINI, pSection, "BunkerableAnyway");

this->DigitalDisplay_Health_FakeAtDisguise.Read(exINI, pSection, "DigitalDisplay.Health.FakeAtDisguise");
Expand Down Expand Up @@ -1438,6 +1447,14 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->Wake_Grapple)
.Process(this->Wake_Sinking)

.Process(this->AINormalTargetingDelay)
.Process(this->PlayerNormalTargetingDelay)
.Process(this->AIGuardAreaTargetingDelay)
.Process(this->PlayerGuardAreaTargetingDelay)
.Process(this->AIAttackMoveTargetingDelay)
.Process(this->PlayerAttackMoveTargetingDelay)
.Process(this->DistributeTargetingFrame)

.Process(this->DigitalDisplay_Health_FakeAtDisguise)

.Process(this->AttackMove_Aggressive)
Expand Down
16 changes: 16 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ class TechnoTypeExt
Nullable<AnimTypeClass*> Wake_Grapple;
Nullable<AnimTypeClass*> Wake_Sinking;

Nullable<int> AINormalTargetingDelay;
Nullable<int> PlayerNormalTargetingDelay;
Nullable<int> AIGuardAreaTargetingDelay;
Nullable<int> PlayerGuardAreaTargetingDelay;
Nullable<int> AIAttackMoveTargetingDelay;
Nullable<int> PlayerAttackMoveTargetingDelay;
Nullable<bool> DistributeTargetingFrame;

Nullable<bool> AttackMove_Aggressive;
Nullable<bool> AttackMove_UpdateTarget;

Expand Down Expand Up @@ -675,6 +683,14 @@ class TechnoTypeExt
, Wake_Grapple { }
, Wake_Sinking { }

, AINormalTargetingDelay {}
, PlayerNormalTargetingDelay {}
, AIGuardAreaTargetingDelay {}
, PlayerGuardAreaTargetingDelay {}
, AIAttackMoveTargetingDelay {}
, PlayerAttackMoveTargetingDelay {}
, DistributeTargetingFrame {}

, DigitalDisplay_Health_FakeAtDisguise { true }

, AttackMove_Aggressive {}
Expand Down