Skip to content

[Minor] GainSelfHealFromPlayerControl/Allies #1581

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

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
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 @@ -454,6 +454,7 @@ This page lists all the individual contributions to the project by their author.
- Fire weapon when Warhead kills something
- Promotion animation deglobalization
- Forcing specific weapon by range
- Allowed player's self-healing effects to be benefited by allied or `PlayerControl=true` houses
- **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes
- **handama** - AI script action to `16005 Jump Back To Previous Script`
- **TaranDahl (航味麻酱)**:
Expand Down
4 changes: 4 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,8 @@ AlternateFLH.OnTurret=true ; boolean

- It is now possible to set a global cap for the effects of `InfantryGainSelfHeal` and `UnitsGainSelfHeal` by setting `InfantryGainSelfHealCap` & `UnitsGainSelfHealCap` under `[General]`, respectively.
- Whether or not `MultiplayPassive=true` houses benefit from these effects can be controlled via `GainSelfHealAllowMultiplayPassive`.
- In campaign, whether or not these effects for player can be benefited by houses with `PlayerControl=true` can be controlled via `GainSelfHealFromPlayerControl`.
- Whether or not these effects can be benefited by allied houses can be controlled via `GainSelfHealFromAllies`.
- It is also possible to change the pip frames displayed from `pips.shp` individually for infantry, units and buildings by setting the frames for infantry & unit self-healing on `Pips.SelfHeal.Infantry/Units/Buildings` under `[AudioVisual]`, respectively.
- `Pips.SelfHeal.Infantry/Units/Buildings.Offset` can be used to customize the pixel offsets for the displayed pips, individually for infantry, units and buildings.
- Whether or not a TechnoType benefits from effects of `InfantryGainSelfHeal` or `UnitsGainSelfHeal` buildings or neither can now be controlled by setting `SelfHealGainType`.
Expand All @@ -716,6 +718,8 @@ In `rulesmd.ini`:
InfantryGainSelfHealCap= ; integer, maximum amount of InfantryGainSelfHeal that can be in effect at once, must be 1 or higher
UnitsGainSelfHealCap= ; integer, maximum amount of UnitsGainSelfHeal that can be in effect at once, must be 1 or higher
GainSelfHealAllowMultiplayPassive=true ; boolean
GainSelfHealFromPlayerControl=false ; boolean
GainSelfHealFromAllies=false ; boolean

[AudioVisual]
Pips.SelfHeal.Infantry=13,20 ; integer, frames of pips.shp for infantry & unit-self healing pips, respectively
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ New:
- [Removed dependency on `blowfish.dll`](Miscellanous.md#blowfish-dependency) (by ZivDero)
- [Warhead that can not kill](New-or-Enhanced-Logics.md#warhead-that-cannot-kill) (by FS-21)
- [Customize parasite culling targets](Fixed-or-Improved-Logics.md#customizing-parasite-culling-targets) (by NetsuNegi)
- Allowed player's self-healing effects to be benefited by allied or `PlayerControl=true` houses (by Ollerus)

Vanilla fixes:
- Prevent the units with locomotors that cause problems from entering the tank bunker (by TaranDahl)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->InfantryGainSelfHealCap.Read(exINI, GameStrings::General, "InfantryGainSelfHealCap");
this->UnitsGainSelfHealCap.Read(exINI, GameStrings::General, "UnitsGainSelfHealCap");
this->GainSelfHealAllowMultiplayPassive.Read(exINI, GameStrings::General, "GainSelfHealAllowMultiplayPassive");
this->GainSelfHealFromPlayerControl.Read(exINI, GameStrings::General, "GainSelfHealFromPlayerControl");
this->GainSelfHealFromAllies.Read(exINI, GameStrings::General, "GainSelfHealFromAllies");
this->EnemyInsignia.Read(exINI, GameStrings::General, "EnemyInsignia");
this->DisguiseBlinkingVisibility.Read(exINI, GameStrings::General, "DisguiseBlinkingVisibility");
this->ChronoSparkleDisplayDelay.Read(exINI, GameStrings::General, "ChronoSparkleDisplayDelay");
Expand Down Expand Up @@ -322,6 +324,8 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->InfantryGainSelfHealCap)
.Process(this->UnitsGainSelfHealCap)
.Process(this->GainSelfHealAllowMultiplayPassive)
.Process(this->GainSelfHealFromPlayerControl)
.Process(this->GainSelfHealFromAllies)
.Process(this->EnemyInsignia)
.Process(this->DisguiseBlinkingVisibility)
.Process(this->ChronoSparkleDisplayDelay)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class RulesExt
Nullable<int> InfantryGainSelfHealCap;
Nullable<int> UnitsGainSelfHealCap;
Valueable<bool> GainSelfHealAllowMultiplayPassive;
Valueable<bool> GainSelfHealFromPlayerControl;
Valueable<bool> GainSelfHealFromAllies;
Valueable<bool> EnemyInsignia;
Valueable<AffectedHouse> DisguiseBlinkingVisibility;
Valueable<int> ChronoSparkleDisplayDelay;
Expand Down Expand Up @@ -212,6 +214,8 @@ class RulesExt
, InfantryGainSelfHealCap {}
, UnitsGainSelfHealCap {}
, GainSelfHealAllowMultiplayPassive { true }
, GainSelfHealFromPlayerControl { false }
, GainSelfHealFromAllies { false }
, EnemyInsignia { true }
, DisguiseBlinkingVisibility { AffectedHouse::Owner }
, ChronoSparkleDisplayDelay { 24 }
Expand Down
71 changes: 51 additions & 20 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// methods used in TechnoClass_AI hooks or anything similar
#include "Body.h"

#include <SessionClass.h>
#include <SpawnManagerClass.h>
#include <ParticleSystemClass.h>

Expand Down Expand Up @@ -686,33 +687,63 @@ void TechnoExt::ApplyGainedSelfHeal(TechnoClass* pThis)
if (selfHealType == SelfHealGainType::NoHeal)
return;

bool applyHeal = false;
if ((selfHealType == SelfHealGainType::Infantry)
? (Unsorted::CurrentFrame % RulesClass::Instance->SelfHealInfantryFrames)
: (Unsorted::CurrentFrame % RulesClass::Instance->SelfHealUnitFrames))
{
return;
}

int amount = 0;

if (selfHealType == SelfHealGainType::Infantry)
{
int count = RulesExt::Global()->InfantryGainSelfHealCap.isset() ?
std::min(std::max(RulesExt::Global()->InfantryGainSelfHealCap.Get(), 1), pThis->Owner->InfantrySelfHeal) :
pThis->Owner->InfantrySelfHeal;
auto countSelfHealing = [pThis](const bool infantryHeal)
{
auto const pOwner = pThis->Owner;
const bool hasCap = infantryHeal ? RulesExt::Global()->InfantryGainSelfHealCap.isset() : RulesExt::Global()->UnitsGainSelfHealCap.isset();
const int cap = infantryHeal ? RulesExt::Global()->InfantryGainSelfHealCap.Get() : RulesExt::Global()->UnitsGainSelfHealCap.Get();
int count = std::max(infantryHeal ? pOwner->InfantrySelfHeal : pOwner->UnitsSelfHeal, 1);

amount = RulesClass::Instance->SelfHealInfantryAmount * count;
if (hasCap && count >= cap)
{
count = cap;
return count;
}

if (!(Unsorted::CurrentFrame % RulesClass::Instance->SelfHealInfantryFrames) && amount)
applyHeal = true;
}
else
{
int count = RulesExt::Global()->UnitsGainSelfHealCap.isset() ?
std::min(std::max(RulesExt::Global()->UnitsGainSelfHealCap.Get(), 1), pThis->Owner->UnitsSelfHeal) :
pThis->Owner->UnitsSelfHeal;
const bool allowPlayerControl = RulesExt::Global()->GainSelfHealFromPlayerControl && SessionClass::IsCampaign();
const bool allowAlliesInCampaign = RulesExt::Global()->GainSelfHealFromAllies && SessionClass::IsCampaign();
const bool allowAlliesDefault = RulesExt::Global()->GainSelfHealFromAllies && !SessionClass::IsCampaign();

if (allowPlayerControl || allowAlliesInCampaign || allowAlliesDefault)
{
for (auto pHouse : HouseClass::Array)
{
if (pHouse == pOwner)
continue;

amount = RulesClass::Instance->SelfHealUnitAmount * count;
if ((allowPlayerControl && pHouse->IsControlledByCurrentPlayer())
|| (allowAlliesInCampaign && !pHouse->IsControlledByCurrentPlayer() && pHouse->IsAlliedWith(pOwner))
|| (allowAlliesDefault && pHouse->IsAlliedWith(pOwner)))
{
count += infantryHeal ? pHouse->InfantrySelfHeal : pHouse->UnitsSelfHeal;

if (!(Unsorted::CurrentFrame % RulesClass::Instance->SelfHealUnitFrames) && amount)
applyHeal = true;
}
if (hasCap && count >= cap)
{
count = cap;
return count;
}
}
}
}

return count;
};

if (selfHealType == SelfHealGainType::Infantry)
amount = RulesClass::Instance->SelfHealInfantryAmount * countSelfHealing(true);
else
amount = RulesClass::Instance->SelfHealUnitAmount * countSelfHealing(false);

if (applyHeal && amount)
if (amount)
{
if (amount >= healthDeficit)
amount = healthDeficit;
Expand Down
36 changes: 34 additions & 2 deletions src/Ext/Techno/Body.Visuals.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Body.h"

#include <SessionClass.h>
#include <TacticalClass.h>
#include <SpawnManagerClass.h>

Expand All @@ -26,13 +27,44 @@ void TechnoExt::DrawSelfHealPips(TechnoClass* pThis, Point2D* pLocation, Rectang
if (pThis->WhatAmI() == AbstractType::Infantry || (pThis->GetTechnoType()->Organic && pThis->WhatAmI() == AbstractType::Unit))
isOrganic = true;

if (pThis->Owner->InfantrySelfHeal > 0 && (hasInfantrySelfHeal || (isOrganic && !hasUnitSelfHeal)))
auto hasSelfHeal = [pThis](const bool infantryHeal)
{
auto const pOwner = pThis->Owner;

if (infantryHeal ? pOwner->InfantrySelfHeal > 0 : pOwner->UnitsSelfHeal > 0)
return true;

const bool allowPlayerControl = RulesExt::Global()->GainSelfHealFromPlayerControl && SessionClass::IsCampaign();
const bool allowAlliesInCampaign = RulesExt::Global()->GainSelfHealFromAllies && SessionClass::IsCampaign();
const bool allowAlliesDefault = RulesExt::Global()->GainSelfHealFromAllies && !SessionClass::IsCampaign();

if (allowPlayerControl || allowAlliesInCampaign || allowAlliesDefault)
{
for (auto pHouse : HouseClass::Array)
{
if (pHouse == pOwner)
continue;

if ((allowPlayerControl && pHouse->IsControlledByCurrentPlayer())
|| (allowAlliesInCampaign && !pHouse->IsControlledByCurrentPlayer() && pHouse->IsAlliedWith(pOwner))
|| (allowAlliesDefault && pHouse->IsAlliedWith(pOwner)))
{
if (infantryHeal ? pHouse->InfantrySelfHeal > 0 : pHouse->UnitsSelfHeal > 0)
return true;
}
}
}

return false;
};

if ((hasInfantrySelfHeal || (isOrganic && !hasUnitSelfHeal)) && hasSelfHeal(true))
{
drawPip = true;
selfHealFrames = RulesClass::Instance->SelfHealInfantryFrames;
isInfantryHeal = true;
}
else if (pThis->Owner->UnitsSelfHeal > 0 && (hasUnitSelfHeal || (pThis->WhatAmI() == AbstractType::Unit && !isOrganic)))
else if ((hasUnitSelfHeal || (pThis->WhatAmI() == AbstractType::Unit && !isOrganic)) && hasSelfHeal(false))
{
drawPip = true;
selfHealFrames = RulesClass::Instance->SelfHealUnitFrames;
Expand Down