Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
bleedingsourcesmanagerserver.c
Go to the documentation of this file.
1class BleedingSourcesManagerServer extends BleedingSourcesManagerBase
2{
3 const float TICK_INTERVAL_SEC = 3;
4 float m_Tick;
5 bool m_DisableBloodLoss = false;
6 ref array<int> m_DeleteList = new array<int>;
7
8 protected bool m_ProcessSourcesRemoval = false; //to avoid constant array counting
9
10 const int STORAGE_VERSION = 103;
11
13 {
14 return m_BleedingSourceZone.Get(GetSelectionNameFromBit(bit));
15 }
16
18 {
19 return STORAGE_VERSION;
20 }
21
22 void RequestDeletion(int bit)
23 {
24 if (m_DeleteList.Find(bit) == -1) //avoids multiple removal of the same bit/source
25 {
26 m_DeleteList.Insert(bit);
27 m_ProcessSourcesRemoval = true;
28 }
29 }
30
31 override protected void AddBleedingSource(int bit)
32 {
33 #ifdef DEVELOPER
34 if (m_Player && !m_Player.GetAllowDamage())//full invincibility prevents bleeding source creation
35 return;
36 #endif
37
38 m_Player.SetBleedingBits(m_Player.GetBleedingBits() | bit);
39 super.AddBleedingSource(bit);
40 m_Player.OnBleedingSourceAdded();
41 }
42
43 override protected bool RemoveBleedingSource(int bit)
44 {
45 if (super.RemoveBleedingSource(bit))
46 {
47 m_Player.OnBleedingSourceRemovedEx(m_Item);
48
49 float chanceToInfect;
50 if (m_Item)
51 {
52 chanceToInfect = m_Item.GetInfectionChance(0, CachedObjectsParams.PARAM1_BOOL);
53 }
54 else
55 {
56 chanceToInfect = PlayerConstants.BLEEDING_SOURCE_CLOSE_INFECTION_CHANCE;
57 }
58 float diceRoll = Math.RandomFloat01();
59 if (diceRoll < chanceToInfect)
60 {
61 m_Player.InsertAgent(eAgents.WOUND_AGENT);
62 }
63 }
64 else
65 {
66 ErrorEx("Failed to remove bleeding source:" + bit,ErrorExSeverity.INFO);
67 }
68
69 int inverse_bit_mask = ~bit;
70 m_Player.SetBleedingBits(m_Player.GetBleedingBits() & inverse_bit_mask);
71 m_Item = null;//reset, so that next call, if induced by self-healing, will have no item
72
73 return true;
74 }
75
77 {
78 int bleeding_sources_bits = m_Player.GetBleedingBits();
79 int rightmost_bit = bleeding_sources_bits & (-bleeding_sources_bits);
80
81 RemoveBleedingSource(rightmost_bit);
82 }
83
85 {
87 if (bit != 0)
89 }
90
96
98 {
99 int bleeding_sources_bits = m_Player.GetBleedingBits();
100
101 float highest_flow;
102 int highest_flow_bit;
103 int bit_offset;
104
105 for (int i = 0; i < BIT_INT_SIZE; ++i)
106 {
107 int bit = 1 << bit_offset;
108
109 if ((bit & bleeding_sources_bits) != 0)
110 {
112 if (meta)
113 {
114 if (meta.GetFlowModifier() > highest_flow)
115 {
116 highest_flow = meta.GetFlowModifier();
117 highest_flow_bit = bit;
118 //Print(meta.GetSelectionName());
119 }
120 }
121 }
122 bit_offset++;
123 }
124 return highest_flow_bit;
125 }
126
127 void OnTick(float delta_time)
128 {
129 m_Tick += delta_time;
130
131 if (m_ProcessSourcesRemoval)
132 {
133 while (m_DeleteList.Count() > 0)
134 {
135 RemoveBleedingSource(m_DeleteList.Get(0));
136 m_DeleteList.Remove(0);
137 }
138 m_ProcessSourcesRemoval = false;
139 }
140
141 if (m_Tick > TICK_INTERVAL_SEC)
142 {
143 float blood_scale = Math.InverseLerp(PlayerConstants.BLOOD_THRESHOLD_FATAL, PlayerConstants.BLEEDING_LOW_PRESSURE_BLOOD, m_Player.GetHealth("GlobalHealth", "Blood"));
144 blood_scale = Math.Clamp(blood_scale, PlayerConstants.BLEEDING_LOW_PRESSURE_MIN_MOD, 1);
145
146 for (int i = 0; i < m_BleedingSources.Count(); ++i)
147 {
148 m_BleedingSources.GetElement(i).OnUpdateServer(m_Tick, blood_scale, m_DisableBloodLoss);
149 }
150 m_Tick = 0;
151 }
152 }
153
155 {
156 for (int i = 0; i < m_BleedingSourceZone.Count(); ++i)
157 {
158 int bit = m_BleedingSourceZone.GetElement(i).GetBit();
159 if (CanAddBleedingSource(bit))
160 {
162 }
163 }
164 }
165
166 //damage must be to "Blood" healthType
167 void ProcessHit(float damage, EntityAI source, int component, string zone, string ammo, vector modelPos)
168 {
169 float dmg_max = m_Player.GetMaxHealth(zone, "Blood");
170 float bleed_threshold = GetGame().ConfigGetFloat("CfgAmmo " + ammo + " DamageApplied bleedThreshold");
171 string damageTypeString = GetGame().ConfigGetTextOut("CfgAmmo " + ammo + " DamageApplied type");
172 bleed_threshold = Math.Clamp(bleed_threshold,0,1);
173 float bleedingChance;
174 bool createBleedingSource = false;
175
176 // 'true' only when the damageTypeString is handled there
177 if (BleedChanceData.CalculateBleedChance(damageTypeString, damage, bleed_threshold,bleedingChance))
178 {
179 float roll = Math.RandomFloat01();
180 createBleedingSource = bleedingChance != 0 && bleedingChance >= roll;
181
182 #ifdef ENABLE_LOGGING
183 if (LogManager.IsBleedingChancesLogEnable())
184 {
185 Debug.BleedingChancesLog(roll.ToString(), "BleedingSourcesManagerServer" , "n/a", "bleeding random roll:");
186 }
187 #endif
188 }
189 else if (source && source.IsZombie())
190 {
191 int chance = Math.RandomInt(0,100);
192 if (chance <= damage)
193 {
194 createBleedingSource = true;
195 }
196 }
197 else if (damage > (dmg_max * (1 - bleed_threshold)))
198 {
199 createBleedingSource = true;
200 }
201
202 if (createBleedingSource)
203 {
204 #ifdef ENABLE_LOGGING
205 if (LogManager.IsBleedingChancesLogEnable())
206 {
207 Debug.BleedingChancesLog("true", "BleedingSourcesManagerServer" , "n/a", "Attempting to create bleeding source");
208 }
209 #endif
211 }
212 }
213
215 {
217
218 if (source >= m_BleedingSourceZone.Count() || !m_BleedingSourceZone.GetElement(source)) return;
219
220 int bit = m_BleedingSourceZone.GetElement(source).GetBit();
221
222 if (bit && CanAddBleedingSource(bit))
223 {
225 }
226 }
227
228 void SetBloodLoss(bool status)
229 {
230 m_DisableBloodLoss = status;
231 }
232
234 {
235 //int count = m_BleedingSources.Count();
236 int active_bits = m_Player.GetBleedingBits();
237 ctx.Write(active_bits);
238
239 int bit_offset = 0;
240 for (int i = 0; i < BIT_INT_SIZE; ++i)
241 {
242 int bit = 1 << bit_offset;
243 if ((bit & active_bits) != 0)
244 {
245 int active_time = GetBleedingSourceActiveTime(bit);
247
248 ctx.Write(active_time);
249 ctx.Write(type);
250 }
251 bit_offset++;
252 }
253 }
254
255 bool OnStoreLoad(ParamsReadContext ctx, int version)
256 {
257 int active_bits;
258 if (!ctx.Read(active_bits))
259 {
260 return false;
261 }
262
263 int bit_offset = 0;
264 for (int i = 0; i < BIT_INT_SIZE; ++i)
265 {
266 int bit = 1 << bit_offset;
267 if ((bit & active_bits) != 0 && CanAddBleedingSource(bit))
268 {
270 int active_time = 0;
271 if (!ctx.Read(active_time))
272 {
273 return false;
274 }
275 else
276 {
277 SetBleedingSourceActiveTime(bit,active_time);
278 }
279 if (version >= 121)//type was added in this version
280 {
282 if (!ctx.Read(type))
283 {
284 return false;
285 }
286 else
287 {
288 SetBleedingSourceType(bit,type);
289 }
290 }
291 }
292 bit_offset++;
293 }
294 return true;
295 }
296
297
299 {
300 if (m_Player && !m_Player.IsAlive())
302 }
303}
eBleedingSourceType
ItemBase m_Item
Definition actioninput.c:16
const int BIT_INT_SIZE
Definition bitarray.c:4
Static data of bleeding chance probabilities; currently used for melee only.
void OnStoreSave(ParamsWriteContext ctx)
eBleedingSourceType GetBleedingSourceType(int bit)
BleedingSourceZone GetBleedingSourceMeta(int bit)
void SetBleedingSourceActiveTime(int bit, int time)
void ProcessHit(float damage, EntityAI source, int component, string zone, string ammo, vector modelPos)
bool OnStoreLoad(ParamsReadContext ctx, int version)
void SetBleedingSourceType(int bit, eBleedingSourceType type)
void RemoveMostSignificantBleedingSourceEx(ItemBase item)
BleedingSourceZone GetBleedingSourceZone(int bit)
Definition debug.c:2
Definition enmath.c:7
Serialization general interface. Serializer API works with:
Definition serializer.c:56
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
eAgents
Definition eagents.c:3
proto native CGame GetGame()
ErrorExSeverity
Definition endebug.c:62
enum ShapeType ErrorEx
DayZPlayer m_Player
Definition hand_events.c:42
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
class ModifierDebugObj STORAGE_VERSION
float m_Tick