Skip to content

Commit

Permalink
Add ReflectDamage feature to AttachEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
Starkku committed Jul 23, 2024
1 parent a1539f5 commit ff3738e
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 3 deletions.
6 changes: 6 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ This page describes all the engine features that are either new and introduced b
- `Crit.AllowWarheads` can be used to list only Warheads that can benefit from this critical hit chance multiplier and `Crit.DisallowWarheads` weapons that are not allowed to, respectively.
- `RevengeWeapon` can be used to temporarily grant the specified weapon as a [revenge weapon](#revenge-weapon) for the attached object.
- `RevengeWeapon.AffectsHouses` customizes which houses can trigger the revenge weapon.
- `ReflectDamage` can be set to true to have any positive damage dealt to the object the effect is attached to be reflected back to the attacker. `ReflectDamage.Warhead` determines which Warhead is used to deal the damage, defaults to `[CombatDamage]`->`C4Warhead`. If `ReflectDamage.Warhead` is set to true, the Warhead is fully detonated instead of used to simply deal damage. `ReflectDamage.Multiplier` is a multiplier to the damage received and then reflected back.
- `DisableWeapons` can be used to disable ability to fire any and all weapons.
- On TechnoTypes with `OpenTopped=true`, `OpenTopped.CheckTransportDisableWeapons` can be set to true to make passengers not be able to fire out if transport's weapons are disabled by `DisableWeapons`.
- It is possible to set groups for attach effect types by defining strings in `Groups`.
Expand Down Expand Up @@ -108,6 +109,11 @@ Crit.AllowWarheads= ; list of WarheadTypes
Crit.DisallowWarheads= ; list of WarheadTypes
RevengeWeapon= ; WeaponType
RevengeWeapon.AffectsHouses=all ; list of Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
ReflectDamage=false ; boolean
ReflectDamage.Warhead= ; WarheadType
ReflectDamage.Warhead.Detonate=false ; WarheadType
ReflectDamage.Multiplier=1.0 ; floating point value, percents or absolute
ReflectDamage.AffectsHouses=all ; list of Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
DisableWeapons=false ; boolean
Groups= ; comma-separated list of strings (group IDs)

Expand Down
3 changes: 3 additions & 0 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ void TechnoExt::ExtData::RecalculateStatMultipliers()
bool forceDecloak = false;
bool disableWeapons = false;
bool hasTint = false;
bool reflectsDamage = false;

for (const auto& attachEffect : this->AttachedEffects)
{
Expand All @@ -927,6 +928,7 @@ void TechnoExt::ExtData::RecalculateStatMultipliers()
forceDecloak |= type->ForceDecloak;
disableWeapons |= type->DisableWeapons;
hasTint |= type->HasTint();
reflectsDamage |= type->ReflectDamage;
}

this->AE_FirepowerMultiplier = firepower;
Expand All @@ -937,6 +939,7 @@ void TechnoExt::ExtData::RecalculateStatMultipliers()
this->AE_ForceDecloak = forceDecloak;
this->AE_DisableWeapons = disableWeapons;
this->AE_HasTint = hasTint;
this->AE_ReflectDamage = reflectsDamage;

if (forceDecloak && pThis->CloakState == CloakState::Cloaked)
pThis->Uncloak(true);
Expand Down
1 change: 1 addition & 0 deletions src/Ext/Techno/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ void TechnoExt::ExtData::Serialize(T& Stm)
.Process(this->AE_ForceDecloak)
.Process(this->AE_DisableWeapons)
.Process(this->AE_HasTint)
.Process(this->AE_ReflectDamage)
.Process(this->FiringObstacleCell)
;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Techno/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class TechnoExt
bool AE_ForceDecloak;
bool AE_DisableWeapons;
bool AE_HasTint;
bool AE_ReflectDamage;

ExtData(TechnoClass* OwnerObject) : Extension<TechnoClass>(OwnerObject)
, TypeExtData { nullptr }
Expand Down Expand Up @@ -93,6 +94,7 @@ class TechnoExt
, AE_ForceDecloak { false }
, AE_DisableWeapons { false }
, AE_HasTint { false }
, AE_ReflectDamage { false }
, FiringObstacleCell {}
{ }

Expand Down
35 changes: 32 additions & 3 deletions src/Ext/Techno/Hooks.Shield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ DEFINE_HOOK(0x701900, TechnoClass_ReceiveDamage_Shield, 0x6)
GET(TechnoClass*, pThis, ECX);
LEA_STACK(args_ReceiveDamage*, args, 0x4);

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

int nDamageLeft = *args->Damage;

if (!args->IgnoreDefenses)
{
const auto pExt = TechnoExt::ExtMap.Find(pThis);

if (const auto pShieldData = pExt->Shield.get())
{
if (!pShieldData->IsActive())
return 0;

const int nDamageLeft = pShieldData->ReceiveDamage(args);
nDamageLeft = pShieldData->ReceiveDamage(args);

if (nDamageLeft >= 0)
{
*args->Damage = nDamageLeft;
Expand All @@ -39,6 +42,32 @@ DEFINE_HOOK(0x701900, TechnoClass_ReceiveDamage_Shield, 0x6)
RD::SkipLowDamageCheck = true;
}
}

if (pExt->AE_ReflectDamage && nDamageLeft > 0 && args->Attacker)
{
for (auto& attachEffect : pExt->AttachedEffects)
{
if (!attachEffect->IsActive())
continue;

auto const pType = attachEffect->GetType();

if (!pType->ReflectDamage)
continue;

int damage = static_cast<int>(nDamageLeft * pType->ReflectDamage_Multiplier);
auto const pWH = pType->ReflectDamage_Warhead.Get(RulesClass::Instance->C4Warhead);

if (EnumFunctions::CanTargetHouse(pType->ReflectDamage_AffectsHouses, pThis->Owner, args->SourceHouse))
{
if (pType->ReflectDamage_Warhead_Detonate)
WarheadTypeExt::DetonateAt(pWH, args->Attacker, pThis, damage, pThis->Owner);
else
args->Attacker->ReceiveDamage(&damage, 0, pWH, pThis, false, false, pThis->Owner);
}
}
}

return 0;
}

Expand Down
11 changes: 11 additions & 0 deletions src/New/Type/AttachEffectTypeClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ void AttachEffectTypeClass::LoadFromINI(CCINIClass* pINI)
this->RevengeWeapon.Read<true>(exINI, pSection, "RevengeWeapon");
this->RevengeWeapon_AffectsHouses.Read(exINI, pSection, "RevengeWeapon.AffectsHouses");

this->ReflectDamage.Read(exINI, pSection, "ReflectDamage");
this->ReflectDamage_Warhead.Read(exINI, pSection, "ReflectDamage.Warhead");
this->ReflectDamage_Warhead_Detonate.Read(exINI, pSection, "ReflectDamage.Warhead.Detonate");
this->ReflectDamage_Multiplier.Read(exINI, pSection, "ReflectDamage.Multiplier");
this->ReflectDamage_AffectsHouses.Read(exINI, pSection, "ReflectDamage.AffectsHouses");

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

// Groups
Expand Down Expand Up @@ -189,6 +195,11 @@ void AttachEffectTypeClass::Serialize(T& Stm)
.Process(this->Crit_DisallowWarheads)
.Process(this->RevengeWeapon)
.Process(this->RevengeWeapon_AffectsHouses)
.Process(this->ReflectDamage)
.Process(this->ReflectDamage_Warhead)
.Process(this->ReflectDamage_Warhead_Detonate)
.Process(this->ReflectDamage_Multiplier)
.Process(this->ReflectDamage_AffectsHouses)
.Process(this->DisableWeapons)
.Process(this->Groups)
;
Expand Down
10 changes: 10 additions & 0 deletions src/New/Type/AttachEffectTypeClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class AttachEffectTypeClass final : public Enumerable<AttachEffectTypeClass>
ValueableVector<WarheadTypeClass*> Crit_DisallowWarheads;
Valueable<WeaponTypeClass*> RevengeWeapon;
Valueable<AffectedHouse> RevengeWeapon_AffectsHouses;
Valueable<bool> ReflectDamage;
Nullable<WarheadTypeClass*> ReflectDamage_Warhead;
Valueable<bool> ReflectDamage_Warhead_Detonate;
Valueable<double> ReflectDamage_Multiplier;
Valueable<AffectedHouse> ReflectDamage_AffectsHouses;
Valueable<bool> DisableWeapons;

std::vector<std::string> Groups;
Expand Down Expand Up @@ -91,6 +96,11 @@ class AttachEffectTypeClass final : public Enumerable<AttachEffectTypeClass>
, Crit_DisallowWarheads {}
, RevengeWeapon {}
, RevengeWeapon_AffectsHouses{ AffectedHouse::All }
, ReflectDamage { false }
, ReflectDamage_Warhead {}
, ReflectDamage_Warhead_Detonate { false }
, ReflectDamage_Multiplier { 1.0 }
, ReflectDamage_AffectsHouses { AffectedHouse::All }
, DisableWeapons { false }
, Groups {}
{};
Expand Down

0 comments on commit ff3738e

Please sign in to comment.