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 @@ -498,6 +498,7 @@ This page lists all the individual contributions to the project by their author.
- Damaged unit image changes
- `VoiceDeploy` through hot-key/command bar fix
- Damaged aircraft image changes
- Change target Owner on warhead impact
- **ZivDero**:
- Re-enable the Veinhole Monster and Weeds from TS
- Recreate the weed-charging of SWs like the TS Chemical Missile
Expand Down
14 changes: 14 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2298,6 +2298,20 @@ ImmuneToCrit=false ; boolean
If you set `Crit.Warhead` to the same Warhead it is defined on, or create a chain of Warheads with it that loops back to the first one there is a possibility for the game to get stuck in a loop and freeze or crash afterwards.
```

### Change target Owner on impact

- Warheads can now change targets owner to warhead's owner.
- `ChangeOwner.SetAsMindControl` makes the effect work like permanent mind control, which respects `ImmuneToPsionics`.
- `ChangeOwner.MindControlAnim` determines the mind control anim of this effect, which respects `MindControlRingOffset`.

In `rulesmd.ini`:
```ini
[SOMEWARHEAD] ; WarheadType
ChangeOwner=false ; boolean
ChangeOwner.SetAsMindControl=false ; boolean
ChangeOwner.MindControlAnim= ; Animation
```

### Convert TechnoType on impact

![image](_static/images/convertwh.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 @@ -469,6 +469,7 @@ New:
- [CellSpread damage check if victim is in air or on floor](New-or-Enhanced-Logics.md#cellspread-enhancement) (by TaranDahl)
- OpenTopped range bonus and damage multiplier customization for passengers (by Ollerus)
- AutoDeath upon ownership change (by Ollerus)
- Change target Owner on warhead impact (by Fryone)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
9 changes: 9 additions & 0 deletions src/Ext/WarheadType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)

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

this->ChangeOwner.Read(exINI, pSection, "ChangeOwner");
this->ChangeOwner_SetAsMindControl.Read(exINI, pSection, "ChangeOwner.SetAsMindControl");
this->ChangeOwner_MindControlAnim.Read(exINI, pSection, "ChangeOwner.MindControlAnim");

// Convert.From & Convert.To
TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All);

Expand Down Expand Up @@ -359,6 +363,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
|| this->Convert_Pairs.size() > 0
|| this->InflictLocomotor
|| this->RemoveInflictedLocomotor
|| this->ChangeOwner
|| this->AttachEffects.AttachTypes.size() > 0
|| this->AttachEffects.RemoveTypes.size() > 0
|| this->AttachEffects.RemoveGroups.size() > 0
Expand Down Expand Up @@ -599,6 +604,10 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm)

.Process(this->AnimZAdjust)

.Process(this->ChangeOwner)
.Process(this->ChangeOwner_SetAsMindControl)
.Process(this->ChangeOwner_MindControlAnim)

// Ares tags
.Process(this->AffectsEnemies)
.Process(this->AffectsOwner)
Expand Down
10 changes: 10 additions & 0 deletions src/Ext/WarheadType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ class WarheadTypeExt

Nullable<int> AnimZAdjust;

Valueable<bool> ChangeOwner;
Valueable<bool> ChangeOwner_SetAsMindControl;
Nullable<AnimTypeClass*> ChangeOwner_MindControlAnim;

// Ares tags
// http://ares-developers.github.io/Ares-docs/new/warheads/general.html
Valueable<bool> AffectsEnemies;
Expand Down Expand Up @@ -446,11 +450,17 @@ class WarheadTypeExt
, PlayAnimAboveSurface { false }

, AnimZAdjust {}

, ChangeOwner { false }
, ChangeOwner_SetAsMindControl { false }
, ChangeOwner_MindControlAnim {}
{ }

void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget);
void ApplyLocomotorInfliction(TechnoClass* pTarget);
void ApplyLocomotorInflictionReset(TechnoClass* pTarget);
void ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget);

public:
bool CanTargetHouse(HouseClass* pHouse, TechnoClass* pTechno) const;
bool CanAffectTarget(TechnoClass* pTarget) const;
Expand Down
41 changes: 40 additions & 1 deletion src/Ext/WarheadType/Detonate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,13 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass*
if (!this->CanTargetHouse(pHouse, pTarget) || !this->CanAffectTarget(pTarget))
return;

// Put this at first since it can change the target's house
// Put these at first since they can change the target's house
if (this->RemoveMindControl)
pHouse = this->ApplyRemoveMindControl(pHouse, pTarget);

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

// These can change the target's techno types
if (this->Convert_Pairs.size() > 0)
this->ApplyConvert(pHouse, pTarget);
Expand Down Expand Up @@ -469,6 +472,42 @@ HouseClass* WarheadTypeExt::ExtData::ApplyRemoveMindControl(HouseClass* pHouse,
return pHouse;
}

void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget)
{
const bool isMindControl = this->ChangeOwner_SetAsMindControl;
const bool isImmune = (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) || pTarget->IsMindControlled();

if (!isImmune)
{
pTarget->SetOwningHouse(pHouse, true);

if (isMindControl)
{
pTarget->MindControlledByAUnit = true;

if (const auto pAnimType = this->ChangeOwner_MindControlAnim.Get())
{
CoordStruct location = pTarget->Location;
const bool isBld = pTarget->What_Am_I() == AbstractType::Building;

if (isBld)
location.Z += static_cast<BuildingClass*>(pTarget)->Type->Height * Unsorted::LevelHeight;
else
location.Z += pTarget->GetTechnoType()->MindControlRingOffset;

if (const auto pOwnerAnim = GameCreate<AnimClass>(pAnimType, location))
{
pTarget->MindControlRingAnim = pOwnerAnim;
pOwnerAnim->SetOwnerObject(pTarget);

if (isBld)
pOwnerAnim->ZAdjust = -1024;
}
}
}
}
}

void WarheadTypeExt::ExtData::ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner)
{
const double dice = this->Crit_ApplyChancePerTarget ? ScenarioClass::Instance->Random.RandomDouble() : this->Crit_RandomBuffer;
Expand Down