Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PoisonDamageEffect.c
Go to the documentation of this file.
2{
3 protected bool m_bIsDecaying;
4 protected float m_fLocalDPSValue;
5
6 // Delay in ms between next hit sound playback
7 protected static const int SOUND_COOLDOWN = 1500;
8 protected const int CRITICAL_DMG_THRESHOLD = 4;
9 protected const int MAX_DMG_VALUE = 100;
10
11 //------------------------------------------------------------------------------------------------
12 protected override void HandleConsequences(SCR_ExtendedDamageManagerComponent dmgManager, DamageEffectEvaluator evaluator)
13 {
14 super.HandleConsequences(dmgManager, evaluator);
15
16 evaluator.HandleEffectConsequences(this, dmgManager);
17 }
18
19 //------------------------------------------------------------------------------------------------
20 override bool HijackDamageEffect(SCR_ExtendedDamageManagerComponent dmgManager)
21 {
22 // same as with bleeding, this should prevent us from regenerating
23 dmgManager.TerminateDamageEffectsOfType(SCR_PhysicalHitZonesRegenDamageEffect);
24
25 array<ref SCR_PersistentDamageEffect> damageEffects = {};
26 dmgManager.FindAllDamageEffectsOfTypeOnHitZone(SCR_PoisonDamageEffect, GetAffectedHitZone(), damageEffects);
27
28 SCR_PoisonDamageEffect poisonEffect;
29 IEntity instigatorEnt = GetInstigator().GetInstigatorEntity();
30
31 int otherMaxDuration;
32 const int thisMaxDuration = GetMaxDuration();
33 foreach (SCR_PersistentDamageEffect dmgEffect : damageEffects)
34 {
35 poisonEffect = SCR_PoisonDamageEffect.Cast(dmgEffect);
36 if (!poisonEffect || poisonEffect == this)
37 continue;
38
39 if (poisonEffect.GetInstigator().GetInstigatorEntity() != instigatorEnt)
40 continue;
41
42 // combine same effects from the same entity
43 poisonEffect.SetDPS(poisonEffect.GetDPS() + GetDPS());
44
45 // is that effect supposed to end at some point?
46 otherMaxDuration = poisonEffect.GetMaxDuration();
47 if (otherMaxDuration > 0)
48 {
49 if (thisMaxDuration > 0)
50 poisonEffect.SetMaxDuration(otherMaxDuration + thisMaxDuration); // if both of us are meant to expire, then lets combine that time
51 else
52 poisonEffect.SetMaxDuration(0); // if this new effect is not supposed to expire, then we make that old one not expire
53
54 poisonEffect.ApplyEffect(dmgManager);
55 }
56
57 return true;
58 }
59
60 return false;
61 }
62
63 //------------------------------------------------------------------------------------------------
64 override /*static*/ bool UseBatchProcessing()
65 {
66 return true;
67 }
68
69 //------------------------------------------------------------------------------------------------
70 override /*static*/ void BatchData(inout SCR_BatchedDamageEffects batchedDataContainer, notnull SCR_PersistentDamageEffect effect)
71 {
72 if (!batchedDataContainer)
73 {
74 batchedDataContainer = new SCR_BatchedPoisonDamageEffects(effect.GetCustomDamageValue());
75 return;
76 }
77
78 SCR_BatchedPoisonDamageEffects poisonBatch = SCR_BatchedPoisonDamageEffects.Cast(batchedDataContainer);
79 if (!poisonBatch)
80 return;
81
82 poisonBatch.m_fDamageValue += effect.GetCustomDamageValue();
83 poisonBatch.m_iNumberOfEffects++;
84 }
85
86 //------------------------------------------------------------------------------------------------
87 override /*static*/ void BatchProcessing(notnull SCR_ExtendedDamageManagerComponent dmgManager, notnull SCR_BatchedDamageEffects batchedDataContainer, bool isAuthority)
88 {
89 if (!isAuthority)
90 return;
91
93 if (!characterDamageMgr)
94 return;
95
96 SCR_BatchedPoisonDamageEffects poisonBatchData = SCR_BatchedPoisonDamageEffects.Cast(batchedDataContainer);
97 if (!poisonBatchData)
98 return;
99
100 WorldTimestamp currentTs = dmgManager.GetOwner().GetWorld().GetTimestamp();
101 if (!poisonBatchData.m_NextSoundEventTime)
102 {
103 poisonBatchData.m_NextSoundEventTime = currentTs.PlusMilliseconds(SOUND_COOLDOWN);
104 return;
105 }
106
107 if (poisonBatchData.m_NextSoundEventTime.Greater(currentTs))
108 return;
109
110 poisonBatchData.m_NextSoundEventTime = currentTs.PlusMilliseconds(SOUND_COOLDOWN);
111 characterDamageMgr.SynchronizedSoundEvent(Type());
112 }
113
114 //------------------------------------------------------------------------------------------------
115 override bool ExecuteSynchronizedSoundPlayback(notnull SCR_ExtendedDamageManagerComponent dmgManager)
116 {
118 if (!characterDamageMgr)
119 return false;
120
121 float damageValue = m_fLocalDPSValue;
122 bool decaying = m_bIsDecaying;
123 SCR_BatchedPoisonDamageEffects batchedData = SCR_BatchedPoisonDamageEffects.Cast(SCR_DamageSufferingSystem.GetInstance().GetBatchedDataOfType(dmgManager, Type()));
124 if (batchedData)
125 {
126 damageValue = batchedData.m_fDamageValue;
127 decaying = decaying && batchedData.m_iNumberOfEffects < 2;
128 }
129
130 characterDamageMgr.SoundHit(damageValue > CRITICAL_DMG_THRESHOLD && !decaying, EDamageType.INCENDIARY);
131 return true;
132 }
133
134 //------------------------------------------------------------------------------------------------
135 override void OnEffectAdded(SCR_ExtendedDamageManagerComponent dmgManager)
136 {
137 m_fLocalDPSValue = GetDPS();
139 SCR_DamageSufferingSystem.GetInstance().RegisterEffect(dmgManager, this);
141 if (!poisonScreenEffect)
142 return;
143
144 poisonScreenEffect.OnDamageEffectAdded(this);
145 }
146
147 //------------------------------------------------------------------------------------------------
148 override void OnEffectRemoved(SCR_ExtendedDamageManagerComponent dmgManager)
149 {
151 SCR_DamageSufferingSystem.GetInstance().UnregisterEffect(dmgManager, this);
153 if (!poisonScreenEffect)
154 return;
155
156 poisonScreenEffect.OnDamageEffectRemoved(this);
157
159 if (!characterDamageMgr)
160 return;
161
162 characterDamageMgr.RegenPhysicalHitZones();
163 }
164
165 //------------------------------------------------------------------------------------------------
169 BaseInfoDisplay GetScreenEffect(notnull SCR_ExtendedDamageManagerComponent dmgManager, typename effectType)
170 {
171 ChimeraCharacter character = ChimeraCharacter.Cast(dmgManager.GetOwner());
172 if (!character)
173 return null;
174
176 return null;
177
178 PlayerController controller = GetGame().GetPlayerController();
179 if (!controller)
180 return null;
181
182 SCR_HUDManagerComponent hudMgr = SCR_HUDManagerComponent.Cast(controller.FindComponent(SCR_HUDManagerComponent));
183 if (!hudMgr)
184 return null;
185
186 array<BaseInfoDisplay> outInfoDisplays = {};
187 hudMgr.GetInfoDisplays(outInfoDisplays);
188 SCR_ScreenEffectsManager screenEffectsDisplay;
189 foreach (BaseInfoDisplay display : outInfoDisplays)
190 {
191 if (!display)
192 continue;
193
194 screenEffectsDisplay = SCR_ScreenEffectsManager.Cast(display);
195 if (!screenEffectsDisplay)
196 continue;
197
198 return screenEffectsDisplay.GetEffect(effectType);
199 }
200
201 return null;
202 }
203
204 //------------------------------------------------------------------------------------------------
205 override float GetCustomDamageValue()
206 {
207 return m_fLocalDPSValue;
208 }
209
210 //------------------------------------------------------------------------------------------------
211 override void RecalculateDPS(float timeSlice, notnull SCR_ExtendedDamageManagerComponent dmgManager)
212 {
213 const SCR_CharacterDamageManagerComponent characterDmgManager = SCR_CharacterDamageManagerComponent.Cast(dmgManager);
214
215 int decayFactor = 1;
216 if (m_bIsDecaying)
217 decayFactor = -1;//if it shouldnt expire then we are constantly exposed to the source of the poison
218
219 m_fLocalDPSValue = Math.Clamp(GetDPS() * (1 + decayFactor * characterDmgManager.GetPoisonBuildupFactor() * timeSlice), 0, MAX_DMG_VALUE);
220 SetDPS(m_fLocalDPSValue); // poison buildup
221 }
222
223 //------------------------------------------------------------------------------------------------
224 protected override void EOnFrame(float timeSlice, SCR_ExtendedDamageManagerComponent dmgManager)
225 {
226 timeSlice = GetAccurateTimeSlice(timeSlice);
227
228 const bool decaying = GetMaxDuration() != 0;
229 if (decaying != m_bIsDecaying)
230 {
231 m_bIsDecaying = decaying;
232 ApplyEffect(dmgManager);
233 }
234
235 DotDamageEffectTimerToken token = UpdateTimer(timeSlice, dmgManager);
236 DealCustomDot(GetAffectedHitZone(), m_fLocalDPSValue * timeSlice, token, dmgManager);
237 }
238
239 //------------------------------------------------------------------------------------------------
240 override bool SaveApplyEffect(ScriptBitWriter w)
241 {
242 const int remainingTime = Math.Ceil(GetMaxDuration() - GetCurrentDuration());
243
244 bool decaying = remainingTime > 0;
245 w.WriteBool(decaying);
246 if (decaying)
247 w.WriteInt(remainingTime);
248
249 w.WriteFloat01(GetDPS() * 0.01); // divide by MAX_DMG_VALUE to compress it to the 0-1 range
250 return true;
251 }
252
253 //------------------------------------------------------------------------------------------------
255 {
256 r.ReadBool(m_bIsDecaying);
257 int remainingTime;
258 if (m_bIsDecaying)
259 r.ReadInt(remainingTime);
260
261 SetMaxDuration(remainingTime); // always set it, as 0 means that this is not going expire
262
263 r.ReadFloat01(m_fLocalDPSValue);
264 m_fLocalDPSValue *= MAX_DMG_VALUE; // uncompress from 0-1
265 SetDPS(m_fLocalDPSValue);
266
267 return true;
268 }
269}
ArmaReforgerScripted GetGame()
Definition game.c:1398
int Type
Definition Math.c:13
void SoundHit(bool critical, EDamageType damageType)
static IEntity GetLocalControlledEntity()
override void BatchData(inout SCR_BatchedDamageEffects batchedDataContainer, notnull SCR_PersistentDamageEffect effect)
BaseInfoDisplay GetScreenEffect(notnull SCR_ExtendedDamageManagerComponent dmgManager, typename effectType)
override bool HijackDamageEffect(SCR_ExtendedDamageManagerComponent dmgManager)
override bool ExecuteSynchronizedSoundPlayback(notnull SCR_ExtendedDamageManagerComponent dmgManager)
override void RecalculateDPS(float timeSlice, notnull SCR_ExtendedDamageManagerComponent dmgManager)
override void BatchProcessing(notnull SCR_ExtendedDamageManagerComponent dmgManager, notnull SCR_BatchedDamageEffects batchedDataContainer, bool isAuthority)
override float GetCustomDamageValue()
override bool LoadApplyEffect(ScriptBitReader r)
override bool SaveApplyEffect(ScriptBitWriter w)
override void OnEffectRemoved(SCR_ExtendedDamageManagerComponent dmgManager)
override void EOnFrame(float timeSlice, SCR_ExtendedDamageManagerComponent dmgManager)
override void HandleConsequences(SCR_ExtendedDamageManagerComponent dmgManager, DamageEffectEvaluator evaluator)
override void OnEffectAdded(SCR_ExtendedDamageManagerComponent dmgManager)
void OnDamageEffectRemoved(notnull DotDamageEffect dmgEffect)
void OnDamageEffectAdded(notnull DotDamageEffect dmgEffect, bool updateVisuals=true)
BaseInfoDisplay GetEffect(typename effectType)
Return the effect is it exist.
EDamageType
Definition EDamageType.c:13
BaseProjectileComponentClass GameComponentClass GetInstigator()