4 [
Attribute(
"SOUND_VEHICLE_REPAIR_PARTIAL",
desc:
"Sound effect played when heal is updated and not done. Broadcast to players. Leave empty if no sfx",
category:
"Heal/Repair Support Station")]
5 protected string m_sOnHealUpdateSoundEffectEventName;
7 [
Attribute(
desc:
"Sound effect played when Damage over Time is removed (Other than fire). Broadcast to players. Leave empty if no sfx",
category:
"Heal/Repair Support Station")]
8 protected string m_sOnDoTRemovedSoundEffectEventName;
10 protected ref SCR_AudioSourceConfiguration m_OnHealUpdateAudioSourceConfiguration;
11 protected ref SCR_AudioSourceConfiguration m_OnDoTRemovedAudioSourceConfiguration;
18 SCR_AudioSourceConfiguration CreateSoundAudioConfig(
string soundEventName)
25 SCR_AudioSourceConfiguration audioSourceConfiguration =
new SCR_AudioSourceConfiguration();
27 audioSourceConfiguration.m_sSoundEventName = soundEventName;
34 return audioSourceConfiguration;
39 SCR_AudioSourceConfiguration GetOnHealUpdateAudioConfig()
50 SCR_AudioSourceConfiguration GetOnDoTRemovedAudioConfig()
60 class SCR_BaseDamageHealSupportStationComponent : SCR_BaseSupportStationComponent
62 [
Attribute(
"500",
desc:
"Max damage healed each execute. If you hold the action it will heal each time the action ends",
category:
"Heal/Repair Support Station",
params:
"0.01 inf")]
63 protected float m_iDamageHealedEachExecution;
65 [
Attribute(
"100",
desc:
"Supply cost for ever 'Damage Healed Each Execution' damage healed. If the left over damage is less then it will of course be cheaper with a min value of 1",
category:
"Heal/Repair Support Station",
params:
"0 inf")]
66 protected int m_iSupplyCostDamageHealed;
68 [
Attribute(
"1",
desc:
"The max percentage that this support station can heal scaled. 1 == 100%, This is not calculated as a whole but for each hitZone. Aka if hitZone A is less than this percentage then the heal action can be executed even if total health is more than this %",
params:
"0.01 1",
category:
"Heal/Repair Support Station")]
69 protected float m_fMaxHealScaled;
72 [
Attribute(
"0.05",
desc:
"Hotfix: If server then this value is added on top of the m_fMaxHealScaled. This is because there is a potential desync of around 5% between client and server. EG: client can only heal up to 20% but server up to 25% so if client things the health is 19% and server things it is 21% the heal is still executed up to 25%",
params:
"0 0.10",
category:
"Heal/Repair Support Station")]
73 protected float m_fServerAddedMaxHealScaled;
75 [
Attribute(
desc:
"The DPS types that cost supplies to be healed/repaired. It will still remove the DPS effect even if it is not included here. It simply does not cost extra", uiwidget: UIWidgets.SearchComboBox, enums: ParamEnumArray.FromEnum(
EDamageType),
category:
"Heal/Repair Support Station")]
76 protected ref array<EDamageType> m_aDoTTypesHealed;
78 [
Attribute(
"100",
desc:
"Supplies needed to heal conditions such as bleeding. Ignored if 0 or m_aDoTTypesHealed is empty. Fire uses own supply calculation",
params:
"0 inf 1",
category:
"Heal/Repair Support Station")]
79 protected int m_iSuppliesPerDoTHealed;
81 [
Attribute(
ESupportStationReasonInvalid.HEAL_MAX_HEALABLE_HEALTH_REACHED_EMERGENCY.ToString(),
desc:
"Invalid reason when healing is done but full health not reached. For repair vehicle this is HEAL_MAX_HEALABLE_HEALTH_REACHED_FIELD for repair wrench only this is HEAL_MAX_HEALABLE_HEALTH_REACHED_EMERGENCY", uiwidget: UIWidgets.SearchComboBox, enums: ParamEnumArray.FromEnum(
ESupportStationReasonInvalid),
category:
"Heal/Repair Support Station")]
85 protected float m_fMaxDamageToHealSupplyCap = -1;
89 protected float GetMaxHealScaled()
91 if (m_fMaxHealScaled >= 1 || Replication.IsClient())
92 return m_fMaxHealScaled;
94 return Math.Clamp(m_fMaxHealScaled + m_fServerAddedMaxHealScaled, m_fMaxHealScaled, 1);
102 Debug.Error2(
"SCR_BaseDamageHealSupportStationComponent",
"'IsValid' fails as the damage heal support station is executed with a non SCR_BaseDamageHealSupportStationAction action! This is will break the support station!");
106 if (!super.IsValid(actionOwner, actionUser, action, actionPosition, reasonInvalid, supplyCost))
110 array<HitZone> hitZones = {};
113 if (activeDot == -1 && damageToHeal <= 0)
115 foreach (
HitZone hitzone : hitZones)
120 reasonInvalid = m_eMaxHealDone;
136 action.GetHitZonesToHeal(hitZones);
143 foreach (
HitZone hitZone : hitZones)
145 if (hitZone.GetDamageOverTime(DoT))
154 return Math.Clamp(action.GetActionDamageManager().GetHitZonesDamage(GetMaxHealScaled(), hitZones), 0, m_iDamageHealedEachExecution);
160 m_fMaxDamageToHealSupplyCap = -1;
166 array<HitZone> hitZones = {};
177 if (damageToHeal <= 0)
181 float damageHealCost = (damageToHeal / m_iDamageHealedEachExecution) * m_iSupplyCostDamageHealed;
188 m_fMaxDamageToHealSupplyCap = (m_iDamageHealedEachExecution / m_iSupplyCostDamageHealed) * availableSupplies;
189 return availableSupplies;
219 array<HitZone> hitZones = {};
220 float damageToHeal =
GetDamageOrStateToHeal(actionOwner, actionUser, damageHealAction, activeDoT, hitZones);
223 if (m_fMaxDamageToHealSupplyCap > 0 && m_fMaxDamageToHealSupplyCap < damageToHeal)
224 damageToHeal = m_fMaxDamageToHealSupplyCap;
231 FindEntityIds(actionOwner, actionUser, ownerId, userId, playerId);
238 foreach (
HitZone hitZone : hitZones)
240 hitZone.SetDamageOverTime(activeDoT, 0);
249 SCR_DamageManagerComponent damageManager = damageHealAction.GetActionDamageManager();
253 float maxHealScaled = GetMaxHealScaled();
256 damageManager.HealHitZones(damageToHeal,
true, maxHealScaled, hitZones);
259 if (damageManager.GetHitZonesDamage(maxHealScaled, hitZones) > 0)
266 if (maxHealScaled >= 1)
274 float healthScaled = damageHealAction.GetActionDamageManager().GetSingleHitZonesHealthScaled(hitZones);
287 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
290 IEntity actionOwner, actionUser;
296 ActionsManagerComponent actionManager = ActionsManagerComponent.Cast(actionOwner.FindComponent(ActionsManagerComponent));
322 PlaySoundEffect(classData.GetOnHealUpdateAudioConfig(), actionOwner, action);
335 SCR_DamageManagerComponent damageManager = SCR_DamageManagerComponent.GetDamageManager(actionOwner);
346 PlaySoundEffect(classData.GetOnDoTRemovedAudioConfig(), actionOwner, action);