Skip to content
Open
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
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,7 @@ This page lists all the individual contributions to the project by their author.
- Fix an issue where units recruited by a team with `AreTeamMembersRecruitable=false` cannot be recruited even if they have been liberated by that team
- Global default value for `DefaultToGuardArea`
- Weapon range finding in cylinder
- Allow the unit to stop immediately if the target enters the range during ApproachTarget
- **solar-III (凤九歌)**
- Target scanning delay customization (documentation)
- Skip target scanning function calling for unarmed technos (documentation)
Expand Down
11 changes: 11 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,17 @@ SubterraneanSpeed=-1 ; floating point value
`SubterraneanHeight` expects negative values to be used and may behave erratically if set to above -50.
```

### Stop immediately if the target enters the range during ApproachTarget

- In vanilla, the ApproachTarget will simply exit and do nothing if the target is in range. This will cause your units to approach the target unnecessarily.
- Now you can change this behavior by the following flag.

In `rulesmd.ini`:
```ini
[General]
ApproachTarget.StopWhenInRange=false ; boolean
```

### 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.
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ Vanilla fixes:
- Fixed the bug where selected technos would lose their selection if their regular mind control was replaced with permanent mind control or with the control from the Psychic Dominator superweapon (by NetsuNegi)
- Fixed an issue that retaliation will make the unit keep switching among multiple targets with the same amount of threat (by TaranDahl)
- Fixed the issue where units recruited by a team with `AreTeamMembersRecruitable=false` cannot be recruited even if they have been liberated by that team (by TaranDahl)
- Allow the unit to stop immediately if the target enters the range during ApproachTarget (by TaranDahl)

Phobos fixes:
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi)
Expand Down
5 changes: 3 additions & 2 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->AllowBerzerkOnAllies.Read(exINI, GameStrings::CombatDamage, "AllowBerzerkOnAllies");

this->AttackMove_IgnoreWeaponCheck.Read(exINI, GameStrings::General, "AttackMove.IgnoreWeaponCheck");
this->AttackMove_StopWhenTargetAcquired.Read(exINI, GameStrings::General, "AttackMove.StopWhenTargetAcquired");

this->Parasite_GrappleAnim.Read(exINI, GameStrings::AudioVisual, "Parasite.GrappleAnim");

Expand Down Expand Up @@ -363,6 +362,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->AIParadropMission.Read(exINI, GameStrings::General, "AIParadropMission");

this->CylinderRangefinding.Read(exINI, GameStrings::General, "CylinderRangefinding");

this->ApproachTarget_StopWhenInRange.Read(exINI, GameStrings::General, "ApproachTarget.StopWhenInRange");

// Section AITargetTypes
int itemsCount = pINI->GetKeyCount("AITargetTypes");
Expand Down Expand Up @@ -640,7 +641,6 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->TintColorForceShield)
.Process(this->TintColorBerserk)
.Process(this->AttackMove_IgnoreWeaponCheck)
.Process(this->AttackMove_StopWhenTargetAcquired)
.Process(this->Parasite_GrappleAnim)
.Process(this->InfantryAutoDeploy)
.Process(this->AdjacentWallDamage)
Expand All @@ -663,6 +663,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->AIParadropMission)
.Process(this->DefaultToGuardArea)
.Process(this->CylinderRangefinding)
.Process(this->ApproachTarget_StopWhenInRange)
;
}

Expand Down
8 changes: 5 additions & 3 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once

#include <RulesClass.h>
#include <Utilities/Container.h>
Expand Down Expand Up @@ -272,7 +272,6 @@ class RulesExt
Valueable<bool> AllowBerzerkOnAllies;

Valueable<bool> AttackMove_IgnoreWeaponCheck;
Nullable<bool> AttackMove_StopWhenTargetAcquired;

NullableIdx<AnimTypeClass> Parasite_GrappleAnim;

Expand Down Expand Up @@ -314,6 +313,8 @@ class RulesExt

Valueable<bool> CylinderRangefinding;

Valueable<bool> ApproachTarget_StopWhenInRange;

ExtData(RulesClass* OwnerObject) : Extension<RulesClass>(OwnerObject)
, Storage_TiberiumIndex { -1 }
, HarvesterDumpAmount { 0.0f }
Expand Down Expand Up @@ -534,7 +535,6 @@ class RulesExt
, TintColorBerserk { 0 }

, AttackMove_IgnoreWeaponCheck { false }
, AttackMove_StopWhenTargetAcquired { }

, Parasite_GrappleAnim {}
, InfantryAutoDeploy { false }
Expand Down Expand Up @@ -570,6 +570,8 @@ class RulesExt
, DefaultToGuardArea { false }

, CylinderRangefinding { false }

, ApproachTarget_StopWhenInRange { false }
{ }

virtual ~ExtData() = default;
Expand Down
28 changes: 27 additions & 1 deletion src/Ext/Techno/Hooks.Firing.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Body.h"
#include "Body.h"

#include <Ext/Anim/Body.h>
#include <Ext/Building/Body.h>
Expand Down Expand Up @@ -1149,3 +1149,29 @@ DEFINE_HOOK(0x6F755A, TechnoClass_IsCloseEnough_CylinderRangefinding, 0x7)
R->EAX(pCoord->X);
return (cylinder || pThis->WhatAmI() == AbstractType::Aircraft) ? 0x6F75B2 : 0x6F7568;
}

DEFINE_HOOK(0x4D5A34, FootClass_ApproachTarget_StopWhenInRange, 0x6)
{
GET_STACK(bool, closeEnough, STACK_OFFSET(0x158, -0x146));

if (RulesExt::Global()->ApproachTarget_StopWhenInRange && closeEnough)
{
GET(FootClass*, pThis, EBX);
if (auto const pJumpjetLoco = locomotion_cast<JumpjetLocomotionClass*>(pThis->Locomotor))
{
auto const crd = pThis->GetCoords();
pJumpjetLoco->DestinationCoords.X = crd.X;
pJumpjetLoco->DestinationCoords.Y = crd.Y;
pJumpjetLoco->CurrentSpeed = 0;
pJumpjetLoco->MaxSpeed = 0;
pJumpjetLoco->State = JumpjetLocomotionClass::State::Hovering;
pThis->AbortMotion();
}
else
{
pThis->SetDestination(nullptr, true);
}
}

return 0;
}
49 changes: 0 additions & 49 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,55 +1039,6 @@ DEFINE_HOOK(0x519FEC, InfantryClass_UpdatePosition_EngineerRepair, 0xA)

#pragma region AttackMove

DEFINE_HOOK(0x4DF410, FootClass_UpdateAttackMove_TargetAcquired, 0x6)
{
GET(FootClass* const, pThis, ESI);

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

if (pThis->IsCloseEnoughToAttack(pThis->Target)
&& pTypeExt->AttackMove_StopWhenTargetAcquired.Get(RulesExt::Global()->AttackMove_StopWhenTargetAcquired.Get(!pTypeExt->OwnerObject()->OpportunityFire)))
{
if (auto const pJumpjetLoco = locomotion_cast<JumpjetLocomotionClass*>(pThis->Locomotor))
{
auto const crd = pThis->GetCoords();
pJumpjetLoco->DestinationCoords.X = crd.X;
pJumpjetLoco->DestinationCoords.Y = crd.Y;
pJumpjetLoco->CurrentSpeed = 0;
pJumpjetLoco->MaxSpeed = 0;
pJumpjetLoco->State = JumpjetLocomotionClass::State::Hovering;
pThis->AbortMotion();
}
else
{
pThis->StopMoving();
pThis->AbortMotion();
}
}

if (pTypeExt->AttackMove_PursuitTarget)
pThis->SetDestination(pThis->Target, true);

return 0;
}

DEFINE_HOOK(0x4DF4DB, TechnoClass_RefreshMegaMission_CheckMissionFix, 0xA)
{
enum { ClearMegaMission = 0x4DF4F9, ContinueMegaMission = 0x4DF4CF };

GET(FootClass* const, pThis, ESI);

auto const pTypeExt = TechnoExt::ExtMap.Find(pThis)->TypeExtData;
auto const mission = pThis->GetCurrentMission();
const bool stopWhenTargetAcquired = pTypeExt->AttackMove_StopWhenTargetAcquired.Get(RulesExt::Global()->AttackMove_StopWhenTargetAcquired.Get(!pTypeExt->OwnerObject()->OpportunityFire));
bool clearMegaMission = mission != Mission::Guard;

if (stopWhenTargetAcquired && clearMegaMission)
clearMegaMission = !(mission == Mission::Move && pThis->MegaDestination && pThis->DistanceFrom(pThis->MegaDestination) > 256);

return clearMegaMission ? ClearMegaMission : ContinueMegaMission;
}

DEFINE_HOOK(0x711E90, TechnoTypeClass_CanAttackMove_IgnoreWeapon, 0x6)
{
enum { SkipGameCode = 0x711E9A };
Expand Down
4 changes: 0 additions & 4 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,6 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->AttackMove_Follow.Read(exINI, pSection, "AttackMove.Follow");
this->AttackMove_Follow_IncludeAir.Read(exINI, pSection, "AttackMove.Follow.IncludeAir");
this->AttackMove_Follow_IfMindControlIsFull.Read(exINI, pSection, "AttackMove.Follow.IfMindControlIsFull");
this->AttackMove_StopWhenTargetAcquired.Read(exINI, pSection, "AttackMove.StopWhenTargetAcquired");
this->AttackMove_PursuitTarget.Read(exINI, pSection, "AttackMove.PursuitTarget");

this->Ammo_AutoConvertMinimumAmount.Read(exINI, pSection, "Ammo.AutoConvertMinimumAmount");
this->Ammo_AutoConvertMaximumAmount.Read(exINI, pSection, "Ammo.AutoConvertMaximumAmount");
Expand Down Expand Up @@ -1814,8 +1812,6 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->AttackMove_Follow)
.Process(this->AttackMove_Follow_IncludeAir)
.Process(this->AttackMove_Follow_IfMindControlIsFull)
.Process(this->AttackMove_StopWhenTargetAcquired)
.Process(this->AttackMove_PursuitTarget)

.Process(this->MultiWeapon)
.Process(this->MultiWeapon_IsSecondary)
Expand Down
4 changes: 0 additions & 4 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,6 @@ class TechnoTypeExt
Valueable<bool> AttackMove_Follow;
Valueable<bool> AttackMove_Follow_IncludeAir;
Valueable<bool> AttackMove_Follow_IfMindControlIsFull;
Nullable<bool> AttackMove_StopWhenTargetAcquired;
Valueable<bool> AttackMove_PursuitTarget;

Valueable<bool> MultiWeapon;
ValueableVector<bool> MultiWeapon_IsSecondary;
Expand Down Expand Up @@ -866,8 +864,6 @@ class TechnoTypeExt
, AttackMove_Follow { false }
, AttackMove_Follow_IncludeAir { false }
, AttackMove_Follow_IfMindControlIsFull { false }
, AttackMove_StopWhenTargetAcquired { }
, AttackMove_PursuitTarget { false }

, MultiWeapon { false }
, MultiWeapon_IsSecondary {}
Expand Down
1 change: 1 addition & 0 deletions src/Utilities/TemplateDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <VoxClass.h>
#include <CRT.h>
#include <LocomotionClass.h>
#include <JumpjetLocomotionClass.h>
#include <Locomotion/TestLocomotionClass.h>

namespace detail
Expand Down