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

[Minor] Shield respawn anim and weapon #1381

Open
wants to merge 1 commit 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 @@ -358,6 +358,7 @@ This page lists all the individual contributions to the project by their author.
- **Ollerus**
- Build limit group enhancement
- Customizable rocker amplitude
- Shield respawn animation and weapon
- **handama** - AI script action to jump back to previous script
- **Ares developers**
- YRpp and Syringe which are used, save/load, project foundation and generally useful code from Ares
Expand Down
8 changes: 7 additions & 1 deletion docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ SelfHealing.RestartInCombat=true ; boolean
SelfHealing.RestartInCombatDelay=0 ; integer, game frames
Respawn=0.0 ; floating point value, percents or absolute
Respawn.Rate=0.0 ; floating point value, ingame minutes
Respawn.Anims= ; list of Animation
Respawn.Weapon= ; WeaponType
BracketDelta=0 ; integer - pixels
Pips=-1,-1,-1 ; integer, frames of pips.shp (zero-based) for Green, Yellow, Red
Pips.Building=-1,-1,-1 ; integer, frames of pips.shp (zero-based) for Green, Yellow, Red
Expand Down Expand Up @@ -330,6 +332,8 @@ Shield.Respawn.Duration=0 ; integer, game frames
Shield.Respawn.Amount=0.0 ; floating point value, percents or absolute
Shield.Respawn.Rate=-1.0 ; floating point value, ingame minutes
Shield.Respawn.RestartTimer=false ; boolean
Shield.Respawn.Anims= ; list of Animation
Shield.Respawn.Weapon= ; WeaponType
Shield.SelfHealing.Duration=0 ; integer, game frames
Shield.SelfHealing.Amount=0.0 ; floating point value, percents or absolute
Shield.SelfHealing.Rate=-1.0 ; floating point value, ingame minutes
Expand Down Expand Up @@ -366,6 +370,8 @@ Shield.InheritStateOnReplace=false ; boolean
- If you want shield recovers/respawns 1 HP per time, currently you need to set tag value to any number between 1 and 2, like `1.1`.
- If `SelfHealing.RestartInCombat` is set, self-healing timer pauses and then resumes after `SelfHealing.RestartInCombatDelay` frames have passed when the shield gets damaged.
- `SelfHealing.Rate` and `Respawn.Rate` respect the following settings: 0.0 instantly recovers the shield, other values determine the frequency of shield recovers/respawns in ingame minutes.
- `Respawn.Anims`, if set, will be played when the shield respawns. If more than one animation is listed, a random one is selected.
- `Respawn.Weapon`, if set, will be fired at the TechnoType once the shield respawns.
- `IdleAnim`, if set, will be played while the shield is intact. This animation is automatically set to loop indefinitely.
- `IdleAnim.ConditionYellow` and `IdleAnim.ConditionRed` can be used to set different animations for when shield health is at or below the percentage defined in `[AudioVisual]`->`ConditionYellow`/`ConditionRed`, respectively. If `IdleAnim.ConditionRed` is not set it falls back to `IdleAnim.ConditionYellow`, which in turn falls back to `IdleAnim`.
- `IdleAnimDamaged`, `IdleAnimDamaged.ConditionYellow` and `IdleAnimDamaged.ConditionRed` are used in an identical manner, but only when health of the object the shield is attached to is at or below `[AudioVisual]`->`ConditionYellow`. Follows similar fallback sequence to regular `IdleAnim` variants and if none are set, falls back to the regular `IdleAnim` or variants thereof.
Expand Down Expand Up @@ -402,7 +408,7 @@ Shield.InheritStateOnReplace=false ; boolean
- `Shield.PassPercent` overrides the `PassPercent` value set in the ShieldType that is being damaged.
- `Shield.ReceivedDamage.Minimum` & `Shield.ReceivedDamage.Maximum` override the values set in in the ShieldType that is being damaged.
- `Shield.ReceivedDamage.MinMultiplier` and `Shield.ReceivedDamage.MinMultiplier` are multipliers to the effective `Shield.ReceivedDamage.Minimum` and `Shield.ReceivedDamage.Maximum` respectively that are applied when the Warhead deals damage to a shield.
- `Shield.Respawn.Rate` & `Shield.Respawn.Amount` override ShieldType `Respawn.Rate` and `Respawn.Amount` for duration of `Shield.Respawn.Duration` amount of frames. Negative rate & zero or lower amount default to ShieldType values. If `Shield.Respawn.RestartTimer` is set, currently running shield respawn timer is reset, otherwise the timer's duration is adjusted in proportion to the new `Shield.Respawn.Rate` (e.g timer will be same percentage through before and after) without restarting the timer. If the effect expires while respawn timer is running, remaining time is adjusted to proportionally match ShieldType `Respawn.Rate`. Re-applying the effect resets the duration to `Shield.Respawn.Duration`
- `Shield.Respawn.Rate`, `Shield.Respawn.Amount`, `Shield.Respawn.Anims` and `Shield.Respawn.Weapon` override ShieldType `Respawn.Rate`, `Respawn.Amount`, `Respawn.Anims` and `Respawn.Weapon` for duration of `Shield.Respawn.Duration` amount of frames. Negative rate & zero or lower amount default to ShieldType values. If `Shield.Respawn.RestartTimer` is set, currently running shield respawn timer is reset, otherwise the timer's duration is adjusted in proportion to the new `Shield.Respawn.Rate` (e.g timer will be same percentage through before and after) without restarting the timer. If the effect expires while respawn timer is running, remaining time is adjusted to proportionally match ShieldType `Respawn.Rate`. Re-applying the effect resets the duration to `Shield.Respawn.Duration`
- `Shield.SelfHealing.Rate` & `Shield.SelfHealing.Amount` override ShieldType `SelfHealing.Rate` and `SelfHealing.Amount` for duration of `Shield.SelfHealing.Duration` amount of frames. Negative rate & zero or lower amount default to ShieldType values. If `Shield.SelfHealing.RestartTimer` is set, currently running self-healing timer is restarted, otherwise timer's duration is adjusted in proportion to the new `Shield.SelfHealing.Rate` (e.g timer will be same percentage through before and after) without restarting the timer. If the effect expires while self-healing timer is running, remaining time is adjusted to proportionally match ShieldType `SelfHealing.Rate`. Re-applying the effect resets the duration to `Shield.SelfHealing.Duration`.
- Additionally `Shield.SelfHealing.RestartInCombat` & `Shield.SelfHealing.RestartInCombatDelay` can be used to override ShieldType settings.
- `Shield.AffectTypes` allows listing which ShieldTypes can be affected by any of the effects listed above. If none are listed, all ShieldTypes are affected.
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ New:
- Nonprovocative Warheads (by Starkku)
- Option to restore `PowerSurplus` setting for AI (by Starkku)
- `FireOnce` infantry sequence reset toggle (by Starkku)
- Shield respawn animation and weapon (by Ollerus)

Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/WarheadType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->Shield_Respawn_Rate_InMinutes.Read(exINI, pSection, "Shield.Respawn.Rate");
this->Shield_Respawn_Rate = (int)(this->Shield_Respawn_Rate_InMinutes * 900);
this->Shield_Respawn_RestartTimer.Read(exINI, pSection, "Shield.Respawn.RestartTimer");
this->Shield_Respawn_Anims.Read(exINI, pSection, "Shield.Respawn.Anims");
this->Shield_Respawn_Weapon.Read(exINI, pSection, "Shield.Respawn.Weapon");
this->Shield_SelfHealing_Duration.Read(exINI, pSection, "Shield.SelfHealing.Duration");
this->Shield_SelfHealing_Amount.Read(exINI, pSection, "Shield.SelfHealing.Amount");
this->Shield_SelfHealing_Rate_InMinutes.Read(exINI, pSection, "Shield.SelfHealing.Rate");
Expand Down Expand Up @@ -423,6 +425,8 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm)
.Process(this->Shield_Respawn_Amount)
.Process(this->Shield_Respawn_Rate)
.Process(this->Shield_Respawn_RestartTimer)
.Process(this->Shield_Respawn_Anims)
.Process(this->Shield_Respawn_Weapon)
.Process(this->Shield_SelfHealing_Duration)
.Process(this->Shield_SelfHealing_Amount)
.Process(this->Shield_SelfHealing_Rate)
Expand Down
6 changes: 5 additions & 1 deletion src/Ext/WarheadType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class WarheadTypeExt
Nullable<double> Shield_Respawn_Amount;
Valueable<int> Shield_Respawn_Rate;
Valueable<bool> Shield_Respawn_RestartTimer;
ValueableVector<AnimTypeClass*> Shield_Respawn_Anims;
Nullable<WeaponTypeClass*> Shield_Respawn_Weapon;
Valueable<int> Shield_SelfHealing_Duration;
Nullable<double> Shield_SelfHealing_Amount;
Valueable<int> Shield_SelfHealing_Rate;
Expand Down Expand Up @@ -233,10 +235,12 @@ class WarheadTypeExt
, Shield_ReceivedDamage_MaxMultiplier { 1.0 }

, Shield_Respawn_Duration { 0 }
, Shield_Respawn_Amount { 0.0 }
, Shield_Respawn_Amount { }
, Shield_Respawn_Rate { -1 }
, Shield_Respawn_Rate_InMinutes { -1.0 }
, Shield_Respawn_RestartTimer { false }
, Shield_Respawn_Anims { }
, Shield_Respawn_Weapon { }
, Shield_SelfHealing_Duration { 0 }
, Shield_SelfHealing_Amount { }
, Shield_SelfHealing_Rate { -1 }
Expand Down
5 changes: 3 additions & 2 deletions src/Ext/WarheadType/Detonate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void WarheadTypeExt::ExtData::ApplyShieldModifiers(TechnoClass* pTarget, TechnoE
pTargetExt->Shield->SetHP((int)(shieldType->Strength * ratio));

if (pTargetExt->Shield->GetHP() == 0)
pTargetExt->Shield->SetRespawn(shieldType->Respawn_Rate, shieldType->Respawn, shieldType->Respawn_Rate, true);
pTargetExt->Shield->SetRespawn(shieldType->Respawn_Rate, shieldType->Respawn, shieldType->Respawn_Rate, true, shieldType->Respawn_Anims);
}
}
}
Expand All @@ -258,7 +258,8 @@ void WarheadTypeExt::ExtData::ApplyShieldModifiers(TechnoClass* pTarget, TechnoE
if (this->Shield_Respawn_Duration > 0 && isShieldTypeEligible(this->Shield_Respawn_Types.GetElements(this->Shield_AffectTypes)))
{
double amount = this->Shield_Respawn_Amount.Get(pTargetExt->Shield->GetType()->Respawn);
pTargetExt->Shield->SetRespawn(this->Shield_Respawn_Duration, amount, this->Shield_Respawn_Rate, this->Shield_Respawn_RestartTimer);
pTargetExt->Shield->SetRespawn(this->Shield_Respawn_Duration, amount, this->Shield_Respawn_Rate, this->Shield_Respawn_RestartTimer,
this->Shield_Respawn_Anims, this->Shield_Respawn_Weapon);
}

if (this->Shield_SelfHealing_Duration > 0 && isShieldTypeEligible(this->Shield_SelfHealing_Types.GetElements(this->Shield_AffectTypes)))
Expand Down
23 changes: 22 additions & 1 deletion src/New/Entity/ShieldClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ bool ShieldClass::Serialize(T& Stm)
.Process(this->SelfHealing_RestartInCombatDelay_Warhead)
.Process(this->Respawn_Warhead)
.Process(this->Respawn_Rate_Warhead)
.Process(this->Respawn_Anims_Warhead)
.Process(this->Respawn_Weapon_Warhead)
.Process(this->LastBreakFrame)
.Process(this->LastTechnoHealthRatio)
.Success();
Expand Down Expand Up @@ -711,6 +713,23 @@ void ShieldClass::RespawnShield()
double amount = timerWHModifier->InProgress() ? Respawn_Warhead : this->Type->Respawn;
this->HP = this->GetPercentageAmount(amount);
this->UpdateTint();
const auto pAnimList = timerWHModifier->InProgress() ? this->Respawn_Anims_Warhead : this->Type->Respawn_Anims;
const auto pWeapon = timerWHModifier->InProgress() ? this->Respawn_Weapon_Warhead : this->Type->Respawn_Weapon;

if (!pAnimList.empty())
{
if (const auto pAnimType = pAnimList[ScenarioClass::Instance->Random.RandomRanged(0, pAnimList.size() - 1)])
{
if (auto const pAnim = GameCreate<AnimClass>(pAnimType, this->Techno->Location))
{
pAnim->SetOwnerObject(this->Techno);
pAnim->Owner = this->Techno->Owner;
}
}
}

if (pWeapon)
TechnoExt::FireWeaponAtSelf(this->Techno, pWeapon);
}
else if (timerWHModifier->Completed() && timer->InProgress())
{
Expand All @@ -719,14 +738,16 @@ void ShieldClass::RespawnShield()
}
}

void ShieldClass::SetRespawn(int duration, double amount, int rate, bool resetTimer)
void ShieldClass::SetRespawn(int duration, double amount, int rate, bool resetTimer, std::vector<AnimTypeClass*> anim, WeaponTypeClass* weapon)
{
const auto timer = &this->Timers.Respawn;
const auto timerWHModifier = &this->Timers.Respawn_WHModifier;

bool modifierTimerInProgress = timerWHModifier->InProgress();
this->Respawn_Warhead = amount;
this->Respawn_Rate_Warhead = rate >= 0 ? rate : Type->Respawn_Rate;
this->Respawn_Anims_Warhead = anim;
this->Respawn_Weapon_Warhead = weapon ? weapon : Type->Respawn_Weapon;

timerWHModifier->Start(duration);

Expand Down
4 changes: 3 additions & 1 deletion src/New/Entity/ShieldClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ShieldClass
bool CanBePenetrated(WarheadTypeClass* pWarhead) const;
void BreakShield(AnimTypeClass* pBreakAnim = nullptr, WeaponTypeClass* pBreakWeapon = nullptr);

void SetRespawn(int duration, double amount, int rate, bool resetTimer);
void SetRespawn(int duration, double amount, int rate, bool resetTimer, std::vector<AnimTypeClass*> anim, WeaponTypeClass* weapon = nullptr);
void SetSelfHealing(int duration, double amount, int rate, bool restartInCombat, int restartInCombatDelay, bool resetTimer);
void KillAnim();
void AI_Temporal();
Expand Down Expand Up @@ -100,6 +100,8 @@ class ShieldClass
int SelfHealing_RestartInCombatDelay_Warhead;
double Respawn_Warhead;
int Respawn_Rate_Warhead;
std::vector<AnimTypeClass*> Respawn_Anims_Warhead;
WeaponTypeClass* Respawn_Weapon_Warhead;

int LastBreakFrame;
double LastTechnoHealthRatio;
Expand Down
4 changes: 4 additions & 0 deletions src/New/Type/ShieldTypeClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ void ShieldTypeClass::LoadFromINI(CCINIClass* pINI)
this->Powered.Read(exINI, pSection, "Powered");

this->Respawn.Read(exINI, pSection, "Respawn");
this->Respawn_Anims.Read(exINI, pSection, "Respawn.Anims");
this->Respawn_Weapon.Read(exINI, pSection, "Respawn.Weapon");
Nullable<double> Respawn_Rate__InMinutes;
Respawn_Rate__InMinutes.Read(exINI, pSection, "Respawn.Rate");
if (Respawn_Rate__InMinutes.isset())
Expand Down Expand Up @@ -109,6 +111,8 @@ void ShieldTypeClass::Serialize(T& Stm)
.Process(this->Powered)
.Process(this->Respawn)
.Process(this->Respawn_Rate)
.Process(this->Respawn_Anims)
.Process(this->Respawn_Weapon)
.Process(this->SelfHealing)
.Process(this->SelfHealing_Rate)
.Process(this->SelfHealing_RestartInCombat)
Expand Down
4 changes: 4 additions & 0 deletions src/New/Type/ShieldTypeClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ShieldTypeClass final : public Enumerable<ShieldTypeClass>
Valueable<bool> Powered;
Valueable<double> Respawn;
Valueable<int> Respawn_Rate;
ValueableVector<AnimTypeClass*> Respawn_Anims;
Valueable<WeaponTypeClass*> Respawn_Weapon;
Valueable<double> SelfHealing;
Valueable<int> SelfHealing_Rate;
Valueable<bool> SelfHealing_RestartInCombat;
Expand Down Expand Up @@ -67,6 +69,8 @@ class ShieldTypeClass final : public Enumerable<ShieldTypeClass>
, Powered { false }
, Respawn { 0.0 }
, Respawn_Rate { 0 }
, Respawn_Anims { }
, Respawn_Weapon { }
, SelfHealing { 0.0 }
, SelfHealing_Rate { 0 }
, SelfHealing_RestartInCombat { true }
Expand Down
Loading