Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
55664e1
initial commit
Fryone Jul 30, 2023
6b6f924
Immunities (wip)
Fryone Aug 1, 2023
f00d0e6
Docs and fixes
Fryone Aug 1, 2023
3de494f
Merge branch 'develop' into fryone/owner_changer
Fryone Aug 2, 2023
0078e96
Merge branch 'develop' into fryone/owner_changer
Fryone Aug 5, 2023
9215933
Merge branch 'develop' into fryone/owner_changer
Fryone Aug 7, 2023
ddc364c
Merge branch 'develop' into fryone/owner_changer
Fryone Jan 7, 2024
aef9ebb
Merge branch 'develop' into fryone/owner_changer
Fryone Jan 21, 2024
053a3d0
Merge branch 'develop' into fryone/owner_changer
Fryone Feb 13, 2024
a01fd7d
Merge remote-tracking branch 'upstream/develop' into fryone/owner_cha…
Fryone Feb 23, 2024
723551e
Update YRpp
Fryone Feb 23, 2024
1770c6b
Update Detonate.cpp
Fryone Feb 23, 2024
30c3ee4
fix permamc anim not following target
Fryone Feb 24, 2024
0b51abf
updated logic
Fryone Feb 24, 2024
84a4a6c
Merge remote-tracking branch 'upstream/develop' into fryone/owner_cha…
Fryone Feb 27, 2024
75b58dc
Merge branch 'develop' into fryone/owner_changer
Coronia Dec 16, 2025
23e7605
fix mind control anim
Coronia Dec 16, 2025
4eeeff7
remove ChangeOwner.AffectElites
Coronia Dec 18, 2025
f05ebbf
Merge remote-tracking branch 'origin/develop' into fryone/owner_changer
Coronia Dec 18, 2025
e2d0c38
remove ChangeOwnerImmunities
Coronia Dec 18, 2025
66ba905
Merge branch 'fryone/owner_changer' of https://github.com/Fryone/Phob…
Fryone Dec 18, 2025
4541bac
Added timed control
Fryone Dec 20, 2025
e4593a7
update ChangeOwner.Duration
Coronia Dec 22, 2025
63125f9
Merge remote-tracking branch 'upstream/develop' into fryone/owner_cha…
Coronia Dec 22, 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 @@ -310,6 +310,7 @@ This page lists all the individual contributions to the project by their author.
- Sound entry on unit's creation
- Auto-deploy/Deploy block on ammo change
- Flashing Technos on selecting
- Change target Owner on warhead impact
- **ZivDero**
- Allow giving ownership of buildings to players in Skirmish and MP using <Player @ A-H>
- **Ares developers**
Expand Down
2 changes: 1 addition & 1 deletion YRpp
17 changes: 17 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,23 @@ In `rulesmd.ini`:
NotHuman.DeathSequence= ; integer (1 to 5)
```

### Change target Owner on impact

- Warheads can now change targets owner to warhead's owner.
- `IsOwnerChanger.SetAsMindControl` sets control as PermanentMindControl, uses `MindControlRingOffset` for anim, respects `ImmuneToPsionics`.
- `IsOwnerChanger.AffectElites` sets if elite veterancy units can be affected to owner change.
- `IsOwnerChanger.HealthThreshold` sets target minimal health percentage to have owner changed.

In `rulesmd.ini`:
```ini
[SOMEWARHEAD] ; Warhead
IsOwnerChanger = yes ; boolean
IsOwnerChanger.SetAsMindControl = no ; boolean
IsOwnerChanger.ControlAnim = SOMEANIM ; animation on target
IsOwnerChanger.AffectElites = yes ; boolean
IsOwnerChanger.HealthThreshold = 1.0 ; float
```

## Weapons

### AreaFire target customization
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,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)
- Change target Owner on warhead impact (by Fryone)
- In addition to `PlacementGrid.Translucency`, allow to set the transparency of the grid when PlacementPreview is enabled, using the `PlacementGrid.TranslucencyWithPreview` tag (by Belonit).
- Show briefing screen on singleplayer mission start (by Starkku)
- Allow setting mission par times and related messages in `missionmd.ini` (by Starkku)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class TechnoTypeExt
Nullable<Leptons> SpawnDistanceFromTarget;
Nullable<int> SpawnHeight;

NullableVector<int> ChangeOwnerImmunities;

struct LaserTrailDataEntry
{
ValueableIdx<LaserTrailTypeClass> idxType;
Expand Down Expand Up @@ -359,6 +361,8 @@ class TechnoTypeExt

, SpawnDistanceFromTarget {}
, SpawnHeight {}

, ChangeOwnerImmunities {}
{ }

virtual ~ExtData() = default;
Expand Down
11 changes: 11 additions & 0 deletions src/Ext/WarheadType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->DecloakDamagedTargets.Read(exINI, pSection, "DecloakDamagedTargets");
this->ShakeIsLocal.Read(exINI, pSection, "ShakeIsLocal");
this->ApplyModifiersOnNegativeDamage.Read(exINI, pSection, "ApplyModifiersOnNegativeDamage");
this->ChangeOwner.Read(exINI, pSection, "IsOwnerChanger");
this->ChangeOwner_MindControl.Read(exINI, pSection, "IsOwnerChanger.SetAsMindControl");
this->ChangeOwner_Anim.Read(exINI, pSection, "IsOwnerChanger.ControlAnim");
this->ChangeOwner_Threshold.Read(exINI, pSection, "IsOwnerChanger.HealthThreshold");
this->ChangeOwner_AffectElites.Read(exINI, pSection, "IsOwnerChanger.AffectElites");
Copy link

Choose a reason for hiding this comment

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

Ensure that the default values for ChangeOwner, ChangeOwner_MindControl, ChangeOwner_Anim, ChangeOwner_Threshold, and ChangeOwner_AffectElites are set appropriately in the constructor or elsewhere if not done so. This is crucial for maintaining predictable behavior when these properties are not explicitly defined in the INI files.


// Crits
this->Crit_Chance.Read(exINI, pSection, "Crit.Chance");
Expand Down Expand Up @@ -242,6 +247,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
|| this->Convert_Pairs.size() > 0
|| this->InflictLocomotor
|| this->RemoveInflictedLocomotor
|| this->ChangeOwner
);
}

Expand Down Expand Up @@ -270,6 +276,11 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm)
.Process(this->DecloakDamagedTargets)
.Process(this->ShakeIsLocal)
.Process(this->ApplyModifiersOnNegativeDamage)
.Process(this->ChangeOwner)
.Process(this->ChangeOwner_MindControl)
.Process(this->ChangeOwner_Anim)
.Process(this->ChangeOwner_Threshold)
.Process(this->ChangeOwner_AffectElites)

.Process(this->Crit_Chance)
.Process(this->Crit_ApplyChancePerTarget)
Expand Down
11 changes: 11 additions & 0 deletions src/Ext/WarheadType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class WarheadTypeExt
Valueable<bool> DecloakDamagedTargets;
Valueable<bool> ShakeIsLocal;
Valueable<bool> ApplyModifiersOnNegativeDamage;
Valueable<bool> ChangeOwner;
Valueable<bool> ChangeOwner_MindControl;
Nullable<AnimTypeClass*> ChangeOwner_Anim;
Valueable<double> ChangeOwner_Threshold;
Valueable<bool> ChangeOwner_AffectElites;

Valueable<double> Crit_Chance;
Valueable<bool> Crit_ApplyChancePerTarget;
Expand Down Expand Up @@ -155,6 +160,11 @@ class WarheadTypeExt
, DecloakDamagedTargets { true }
, ShakeIsLocal { false }
, ApplyModifiersOnNegativeDamage { false }
, ChangeOwner { false }
, ChangeOwner_MindControl { false }
, ChangeOwner_Anim {}
, ChangeOwner_Threshold { 1.0 }
, ChangeOwner_AffectElites { true }

, Crit_Chance { 0.0 }
, Crit_ApplyChancePerTarget { false }
Expand Down Expand Up @@ -250,6 +260,7 @@ class WarheadTypeExt
void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget);
void ApplyLocomotorInfliction(TechnoClass* pTarget);
void ApplyLocomotorInflictionReset(TechnoClass* pTarget);
void ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget);
Copy link

Choose a reason for hiding this comment

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

The addition of the ApplyOwnerChange method is crucial for implementing the new feature. It's important to ensure that this method is called at the appropriate places within the warhead detonation logic to apply the ownership change effects correctly. Additionally, consider adding error handling within this method to gracefully handle any potential issues that may arise during its execution, such as null references or invalid parameters.

Consider adding error handling within the ApplyOwnerChange method to ensure robustness.


public:
void Detonate(TechnoClass* pOwner, HouseClass* pHouse, BulletExt::ExtData* pBullet, CoordStruct coords);
Expand Down
59 changes: 59 additions & 0 deletions src/Ext/WarheadType/Detonate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass*
if (this->RemoveMindControl)
this->ApplyRemoveMindControl(pHouse, pTarget);

if (this->ChangeOwner)
this->ApplyOwnerChange(pHouse, pTarget);

if (this->Crit_Chance && (!this->Crit_SuppressWhenIntercepted || !bulletWasIntercepted))
this->ApplyCrit(pHouse, pTarget, pOwner);

Expand Down Expand Up @@ -250,6 +253,62 @@ void WarheadTypeExt::ExtData::ApplyRemoveDisguiseToInf(HouseClass* pHouse, Techn
}
}

void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget)
{
const auto pExt = TechnoExt::ExtMap.Find(pTarget);
auto armorType = pTarget->GetTechnoType()->Armor;

if (pExt->Shield && pExt->Shield->IsActive() && !pExt->Shield->CanBePenetrated(this->OwnerObject()))
armorType = pExt->Shield->GetArmorType();

const auto pOwnerAnimType = this->ChangeOwner_Anim.Get(nullptr);
const double ownerChangeHealthThreshold = this->ChangeOwner_Threshold;
const bool isMindControl = this->ChangeOwner_MindControl;
const bool doesAffectElites = this->ChangeOwner_AffectElites;
const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics;
const bool isBld = pTarget->What_Am_I() == AbstractType::Building;

bool isImmune = (isMindControl && targetImmuneToPsionics) || (pTarget->GetHealthPercentage() > ownerChangeHealthThreshold) || (!doesAffectElites && pTarget->Veterancy.IsElite());

if (!isImmune)
{
if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled()))
{
pTarget->SetOwningHouse(pHouse, true);
if (pOwnerAnimType)
{
CoordStruct OwningAnimLocation = pTarget->Location;
if (isMindControl)
if (isBld)
OwningAnimLocation.Z += pTarget->GetTechnoType()->Height * Unsorted::LevelHeight;
else
OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset;
if (auto pOwnerAnim = GameCreate<AnimClass>(pOwnerAnimType, OwningAnimLocation, 0, 1))
{
pOwnerAnim->Owner = pHouse;
if (isMindControl)
{
pTarget->MindControlRingAnim = pOwnerAnim;
pTarget->MindControlledByAUnit = true;
}
else
{
pOwnerAnim->Owner = pHouse;
}
pOwnerAnim->SetOwnerObject(pTarget);
if (isBld)
pOwnerAnim->ZAdjust = -1024;
}
}
else
{
if (isMindControl)
pTarget->MindControlledByAUnit = true;
}
}
}
}

void WarheadTypeExt::ExtData::ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner)
{
double dice;
Expand Down