Skip to content
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

Burst projectile retargeting #1073

Open
wants to merge 41 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
dc865b2
First commit
FS-21 Jun 1, 2023
1506095
Merge branch 'develop' into feature/burst-retarget
FS-21 Jun 1, 2023
60cbebf
Added docs
FS-21 Jun 1, 2023
82dbb40
Removed comments
FS-21 Jun 1, 2023
9d7b854
Tweak
FS-21 Jun 4, 2023
ba2e450
v2.0 and tag rename
FS-21 Sep 4, 2023
a364fe9
Small changes
FS-21 Sep 4, 2023
ef93c81
Merge branch 'develop' into feature/burst-retarget
FS-21 Sep 22, 2023
1ea2d23
Point to latest YRpp
FS-21 Sep 22, 2023
2fd3455
Merge branch 'develop' into feature/burst-retarget
FS-21 Sep 25, 2023
ab1cb83
Fixes
FS-21 Oct 3, 2023
24b2cc1
tweak
FS-21 Oct 6, 2023
6f85473
tweak
FS-21 Oct 6, 2023
68296f9
Fix crash
FS-21 Oct 6, 2023
da32f58
tweak
FS-21 Oct 7, 2023
ea7d0e3
Merge branch 'develop' into feature/burst-retarget
FS-21 Nov 9, 2023
f32981b
Moved IsUnitAvailable() in TechnoExt
FS-21 Nov 11, 2023
d9e8c2a
tweaks
FS-21 Nov 11, 2023
12ffb72
Changed name of GetRandomTarget()
FS-21 Nov 11, 2023
54f327e
Tweaks based on feedback
FS-21 Nov 16, 2023
f83e32f
Merge remote-tracking branch 'origin/develop' into feature/burst-reta…
FS-21 Mar 10, 2024
24e0606
Merge remote-tracking branch 'origin/develop' into feature/burst-reta…
FS-21 Mar 10, 2024
9336b6c
fixed weird merge
FS-21 Mar 11, 2024
d84a418
Merge branch 'develop' into feature/burst-retarget
FS-21 Mar 12, 2024
1692452
Fix crashes
FS-21 Mar 23, 2024
d4d841c
Merge branch 'develop' into feature/burst-retarget
FS-21 Apr 27, 2024
e4a625b
Fix crashes
FS-21 Apr 29, 2024
a6ea99a
Merge branch 'develop' into feature/burst-retarget
FS-21 Aug 30, 2024
bb09eb0
Fix crash
FS-21 Aug 30, 2024
5677163
Merge branch 'develop' into feature/burst-retarget
FS-21 Aug 30, 2024
6d1ff8a
Merge branch 'develop' into feature/burst-retarget
FS-21 Oct 27, 2024
9f560b9
Merge branch 'develop' into feature/burst-retarget
FS-21 Oct 28, 2024
fac6454
Moved code into new files
FS-21 Oct 29, 2024
d32236f
Moving more code
FS-21 Oct 29, 2024
5ba91ae
Code rewrite
FS-21 Nov 1, 2024
f56ad67
Merge branch 'develop' into feature/burst-retarget
FS-21 Nov 1, 2024
c18b3c2
small fix
FS-21 Nov 1, 2024
8b60ea7
small doc fix
FS-21 Nov 1, 2024
32fc883
Small changes
FS-21 Feb 18, 2025
edb5977
tweak
FS-21 Feb 19, 2025
93e7fdd
tweak
FS-21 Feb 20, 2025
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 @@ -128,6 +128,7 @@ This page lists all the individual contributions to the project by their author.
- Shared ammo logic
- Customizable FLH when infantry is prone or deployed
- Initial strength for cloned infantry
- `Burst.Retarget` for projectile retargeting
- **Starkku**:
- Misc. minor bugfixes & improvements
- AI script actions:
Expand Down
2 changes: 1 addition & 1 deletion YRpp
Submodule YRpp updated 1 files
+2 −2 TechnoClass.h
16 changes: 16 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,22 @@ ExtraWarheads= ; list of WarheadTypes
ExtraWarheads.DamageOverrides= ; list of integers
```

### Projectile's random target
- The firer will pick targets randomly.
- Works with missiles (no splits, airbusts, etc), cannons, lasers & spawners.
- A valid techno is required for trigger the logic.
- `OmniFire=yes` will make selectable any targets around the firer, limited by the weapon range.
- `OmniFire=no` will force the firer to pick targets in an area composed by the firer's weapon range around the original target intersected with the firer's weapon range around the firer.
- `RandomTarget.Spawners.MultipleTargets=true` gives each spawner it's own target.
- This logic should be used only in one weapon of the object.

In `rulesmd.ini`:
```ini
[SOMEWEAPON] ; WeaponType
RandomTarget=0.0 ; double or percentage
RandomTarget.Spawners.MultipleTargets=false ; boolean
```

### Feedback weapon

![image](_static/images/feedbackweapon.gif)
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ New:
- Customizable straight trajectory detonation & snap distance and pass-through option (by Starkku)
- Airstrike & spy plane fixed spawn distance & height (by Starkku)
- Allow enabling application of `Verses` and `PercentAtMax` for negative damage (by Starkku)
- `Burst.Retarget` for assigning a new target in each projectile (by FS-21)

Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
21 changes: 4 additions & 17 deletions src/Ext/Script/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void ScriptExt::Mission_Gather_NearTheLeader(TeamClass* pTeam, int countdown = -
// Find the Leader
pLeaderUnit = pExt->TeamLeader;

if (!IsUnitAvailable(pLeaderUnit, true))
if (!TechnoExt::IsUnitAvailable(pLeaderUnit, true))
{
pLeaderUnit = FindTheTeamLeader(pTeam);
pExt->TeamLeader = pLeaderUnit;
Expand Down Expand Up @@ -452,7 +452,7 @@ void ScriptExt::Mission_Gather_NearTheLeader(TeamClass* pTeam, int countdown = -
// Check if units are around the leader
for (auto pUnit = pTeam->FirstUnit; pUnit; pUnit = pUnit->NextTeamMember)
{
if (!IsUnitAvailable(pUnit, true))
if (!TechnoExt::IsUnitAvailable(pUnit, true))
{
auto pTypeUnit = pUnit->GetTechnoType();

Expand Down Expand Up @@ -750,7 +750,7 @@ bool ScriptExt::MoveMissionEndStatus(TeamClass* pTeam, TechnoClass* pFocus, Foot
// Team already have a focused target
for (auto pUnit = pTeam->FirstUnit; pUnit; pUnit = pUnit->NextTeamMember)
{
if (IsUnitAvailable(pUnit, true)
if (TechnoExt::IsUnitAvailable(pUnit, true)
&& !pUnit->TemporalTargetingMe
&& !pUnit->BeingWarpedOut)
{
Expand Down Expand Up @@ -1082,7 +1082,7 @@ FootClass* ScriptExt::FindTheTeamLeader(TeamClass* pTeam)
// Find the Leader or promote a new one
for (auto pUnit = pTeam->FirstUnit; pUnit; pUnit = pUnit->NextTeamMember)
{
if (!IsUnitAvailable(pUnit, true) || !(pUnit->IsInitiated || pUnit->WhatAmI() == AbstractType::Aircraft))
if (!TechnoExt::IsUnitAvailable(pUnit, true) || !(pUnit->IsInitiated || pUnit->WhatAmI() == AbstractType::Aircraft))
continue;

// The team Leader will be used for selecting targets, if there are living Team Members then always exists 1 Leader.
Expand Down Expand Up @@ -1276,19 +1276,6 @@ void ScriptExt::ChronoshiftTeamToTarget(TeamClass* pTeam, TechnoClass* pTeamLead
return;
}

bool ScriptExt::IsUnitAvailable(TechnoClass* pTechno, bool checkIfInTransportOrAbsorbed)
{
if (!pTechno)
return false;

bool isAvailable = pTechno->IsAlive && pTechno->Health > 0 && !pTechno->InLimbo && pTechno->IsOnMap;

if (checkIfInTransportOrAbsorbed)
isAvailable &= !pTechno->Absorbed && !pTechno->Transporter;

return isAvailable;
}

void ScriptExt::Log(const char* pFormat, ...)
{
va_list args;
Expand Down
1 change: 0 additions & 1 deletion src/Ext/Script/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ class ScriptExt
static void VariableOperationHandler(TeamClass* pTeam, int nVariable, int Number);
template<bool IsSrcGlobal, bool IsGlobal, class _Pr>
static void VariableBinaryOperationHandler(TeamClass* pTeam, int nVariable, int nVarToOperate);
static bool IsUnitAvailable(TechnoClass* pTechno, bool checkIfInTransportOrAbsorbed);
static void Log(const char* pFormat, ...);

// Mission.Attack.cpp
Expand Down
14 changes: 7 additions & 7 deletions src/Ext/Script/Mission.Attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void ScriptExt::Mission_Attack(TeamClass* pTeam, bool repeatAction = true, int c

pFocus = abstract_cast<TechnoClass*>(pTeam->Focus);

if (!IsUnitAvailable(pFocus, true))
if (!TechnoExt::IsUnitAvailable(pFocus, true))
{
pTeam->Focus = nullptr;
pFocus = nullptr;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for TechnoExt::IsUnitAvailable(pFocus, true) is correct, but the subsequent nulling of pTeam->Focus and pFocus should be inside the if block. The current placement outside the block will null the focus regardless of whether pFocus is available or not, which is likely unintended.

	if (!TechnoExt::IsUnitAvailable(pFocus, true))
	{
-		pTeam->Focus = nullptr;
-		pFocus = nullptr;
+		pTeam->Focus = nullptr;
+		pFocus = nullptr;
	}

Commitable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
pFocus = abstract_cast<TechnoClass*>(pTeam->Focus);
if (!IsUnitAvailable(pFocus, true))
if (!TechnoExt::IsUnitAvailable(pFocus, true))
{
pTeam->Focus = nullptr;
pFocus = nullptr;
pFocus = abstract_cast<TechnoClass*>(pTeam->Focus);
if (!TechnoExt::IsUnitAvailable(pFocus, true))
{
pTeam->Focus = nullptr;
pFocus = nullptr;
}

Expand Down Expand Up @@ -114,7 +114,7 @@ void ScriptExt::Mission_Attack(TeamClass* pTeam, bool repeatAction = true, int c

for (auto pFoot = pTeam->FirstUnit; pFoot; pFoot = pFoot->NextTeamMember)
{
if (IsUnitAvailable(pFoot, true))
if (TechnoExt::IsUnitAvailable(pFoot, true))
{
auto const pTechnoType = pFoot->GetTechnoType();

Expand Down Expand Up @@ -142,7 +142,7 @@ void ScriptExt::Mission_Attack(TeamClass* pTeam, bool repeatAction = true, int c
// Find the Leader
pLeaderUnit = pTeamData->TeamLeader;

if (!IsUnitAvailable(pLeaderUnit, true))
if (!TechnoExt::IsUnitAvailable(pLeaderUnit, true))
{
pLeaderUnit = FindTheTeamLeader(pTeam);
pTeamData->TeamLeader = pLeaderUnit;
Expand Down Expand Up @@ -298,7 +298,7 @@ void ScriptExt::Mission_Attack(TeamClass* pTeam, bool repeatAction = true, int c
bool isAirOK = pFocus->IsInAir() && leaderWeaponsHaveAA;
bool isGroundOK = !pFocus->IsInAir() && leaderWeaponsHaveAG;

if (IsUnitAvailable(pFocus, true)
if (TechnoExt::IsUnitAvailable(pFocus, true)
&& !pFocus->GetTechnoType()->Immune
&& (isAirOK || isGroundOK)
&& (!pLeaderUnit->Owner->IsAlliedWith(pFocus) || IsUnitMindControlledFriendly(pLeaderUnit->Owner, pFocus)))
Expand All @@ -309,7 +309,7 @@ void ScriptExt::Mission_Attack(TeamClass* pTeam, bool repeatAction = true, int c
{
auto const pTechnoType = pFoot->GetTechnoType();

if (IsUnitAvailable(pFoot, true))
if (TechnoExt::IsUnitAvailable(pFoot, true))
{
// Aircraft case 1
if ((pFoot->WhatAmI() == AbstractType::Aircraft
Expand Down Expand Up @@ -485,7 +485,7 @@ TechnoClass* ScriptExt::GreatestThreat(TechnoClass* pTechno, int method, int cal
continue;

if (object != pTechno
&& IsUnitAvailable(object, true)
&& TechnoExt::IsUnitAvailable(object, true)
&& !objectType->Immune
&& !object->TemporalTargetingMe
&& !object->BeingWarpedOut
Expand Down Expand Up @@ -1167,7 +1167,7 @@ void ScriptExt::Mission_Attack_List1Random(TeamClass* pTeam, bool repeatAction,
auto const pFirstUnit = pTeam->FirstUnit;

if (pTechnoType == objectFromList
&& IsUnitAvailable(pTechno, true)
&& TechnoExt::IsUnitAvailable(pTechno, true)
&& (!pFirstUnit->Owner->IsAlliedWith(pTechno) || IsUnitMindControlledFriendly(pFirstUnit->Owner, pTechno)))
{
validIndexes.push_back(j);
Expand Down
8 changes: 4 additions & 4 deletions src/Ext/Script/Mission.Move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ScriptExt::Mission_Move(TeamClass* pTeam, int calcThreatMode = 0, bool pick
// Find the Leader
pLeaderUnit = pTeamData->TeamLeader;

if (!IsUnitAvailable(pLeaderUnit, true))
if (!TechnoExt::IsUnitAvailable(pLeaderUnit, true))
{
pLeaderUnit = FindTheTeamLeader(pTeam);
pTeamData->TeamLeader = pLeaderUnit;
Expand Down Expand Up @@ -125,7 +125,7 @@ void ScriptExt::Mission_Move(TeamClass* pTeam, int calcThreatMode = 0, bool pick

auto const pTechnoType = pFoot->GetTechnoType();

if (IsUnitAvailable(pFoot, true))
if (TechnoExt::IsUnitAvailable(pFoot, true))
{
if (pTechnoType->Underwater && pTechnoType->LandTargeting == LandTargetingType::Land_Not_OK && selectedTarget->GetCell()->LandType != LandType::Water) // Land not OK for the Naval unit
{
Expand Down Expand Up @@ -264,7 +264,7 @@ TechnoClass* ScriptExt::FindBestObject(TechnoClass* pTechno, int method, int cal
}

if (object != pTechno
&& IsUnitAvailable(object, true)
&& TechnoExt::IsUnitAvailable(object, true)
&& ((pickAllies && pTechno->Owner->IsAlliedWith(object))
|| (!pickAllies && !pTechno->Owner->IsAlliedWith(object))))
{
Expand Down Expand Up @@ -407,7 +407,7 @@ void ScriptExt::Mission_Move_List1Random(TeamClass* pTeam, int calcThreatMode, b
auto objectFromList = objectsList[j];

if (pTechnoType == objectFromList
&& IsUnitAvailable(pTechno, true)
&& TechnoExt::IsUnitAvailable(pTechno, true)
&& ((pickAllies
&& pTeam->FirstUnit->Owner->IsAlliedWith(pTechno))
|| (!pickAllies
Expand Down
47 changes: 47 additions & 0 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <Ext/Anim/Body.h>
#include <Ext/Bullet/Body.h>
#include <Ext/House/Body.h>
#include <Ext/Script/Body.h>
#include <Utilities/EnumFunctions.h>
#include <Utilities/AresFunctions.h>

Expand Down Expand Up @@ -719,3 +720,49 @@ void TechnoExt::UpdateSharedAmmo(TechnoClass* pThis)
}
}
}

void TechnoExt::ExtData::UpdateRandomTargets()
{
auto const pThis = this->OwnerObject();
if (!pThis)
return;

const auto pExt = TechnoExt::ExtMap.Find(pThis);
if (!pExt)
return;

if (pThis->Target
&& pThis->SpawnManager
&& pExt->CurrentRandomTarget
&& IsUnitAvailable(static_cast<TechnoClass*>(pExt->CurrentRandomTarget), true))
{
for (auto pSpawn : pThis->SpawnManager->SpawnedNodes)
{
if (!pSpawn->Unit)
continue;

auto pSpawnExt = TechnoExt::ExtMap.Find(pSpawn->Unit);
if (!pSpawnExt)
continue;

if (!pSpawnExt->CurrentRandomTarget)
{
pSpawnExt->CurrentRandomTarget = TechnoExt::FindRandomTarget(pThis);
pSpawn->Unit->Target = pSpawnExt->CurrentRandomTarget;
}
else if (pSpawn->Status == SpawnNodeStatus::Preparing && pSpawn->Unit->IsInAir())
{
if (!pSpawn->Unit->Target && pSpawnExt->CurrentRandomTarget)
pSpawn->Unit->Target = pSpawnExt->CurrentRandomTarget;
}
}
}

if (pExt->OriginalTarget && !pThis->Target && IsUnitAvailable(static_cast<TechnoClass*>(pExt->OriginalTarget), true) && !pThis->IsInAir())
{
if (pExt->CurrentRandomTarget && IsUnitAvailable(pExt->CurrentRandomTarget, true))
pThis->SetTarget(pExt->CurrentRandomTarget);
else
pThis->SetTarget(pExt->OriginalTarget);
}
}
Loading