DayZ 1.27
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
PlayerStomach.c
См. документацию.
2{
4 float m_Amount;
6 //bool m_IsLiquid;
7 string m_ClassName;
9 protected float m_Temperature;
10
11 void StomachItem(string class_name, float amount, NutritionalProfile profile,int foodstage, int agents, float temperature)
12 {
13 m_Amount = amount;
14 m_Profile = profile;
15 //m_IsLiquid = is_liquid;
16 m_FoodStage = foodstage;
18 m_Agents = agents;
19 m_Temperature = temperature;
20 }
21
22 string GetClassName()
23 {
24 return m_ClassName;
25 }
26
27 /*
28 void SetLiquid(bool is_liquid)
29 {
30 m_IsLiquid = is_liquid;
31 }
32
33 bool IsLiquid()
34 {
35 return m_IsLiquid;
36 }*/
37
39 {
40 return m_FoodStage;
41 }
42
43 void SetFoodStage(int food_stage)
44 {
45 m_FoodStage = food_stage;
46 }
47
48 // returns grams or ml's of this item/liquid
49 float GetAmount()
50 {
51 return m_Amount;
52 }
53
54 // adds grams or ml's of this item/liquid
55 void AddAmount(float amount)
56 {
57 m_Amount += amount;
58 }
59
60 void AddAgents(int agents)
61 {
62 m_Agents = m_Agents | agents;
63 }
64
66 {
67 return m_Temperature;
68 }
69
70 // adjust temperature based on the fraction of the new amount compared to the original amount
71 void AddTemperature(float temperature, float fraction)
72 {
73 float currentTempFraction = (1 - 1/fraction) * m_Temperature;
74 float newTempFraction = (1/fraction) * temperature;
75
76 m_Temperature = currentTempFraction + newTempFraction;
77 }
78
79
80 // "digests" given amount, "outs" nutritional components, and returns 'true' if leads to complete item digestion(no amount left)
81 bool ProcessDigestion(float digestion_points, out float water, out float energy, out float toxicity, out float volume, out int agents, out float consumed_amount)
82 {
83 agents = m_Agents;
84 consumed_amount = GetNutritions(digestion_points, m_Profile, water, energy, toxicity);
85 m_Amount -= consumed_amount;
86 volume = m_Profile.GetFullnessIndex() * m_Amount;
87 return(m_Amount < 0.001);
88 }
89
90 float GetNutritions(float digestion_points, NutritionalProfile profile, out float water, out float energy, out float toxicity)
91 {
92 float energy_per_unit = profile.GetEnergy() / 100;
93 float water_per_unit = profile.GetWaterContent() / 100;
94 float toxicity_per_unit = profile.GetToxicity();
95 float digestability = profile.GetDigestibility();
96
97 if (digestability == 0)//if undefined
98 {
99 digestability = 1;
100 }
101
102 float consumed_quantity = digestion_points * digestability;
103
104 if (m_Amount < consumed_quantity)
105 {
106 consumed_quantity = m_Amount;
107 }
108 if (consumed_quantity > 0)
109 {
110 water = consumed_quantity * water_per_unit;
111 energy = consumed_quantity * energy_per_unit;
112 toxicity = consumed_quantity * toxicity_per_unit;
113 }
114 return consumed_quantity;
115 }
116}
117
118class PlayerStomach
119{
120 const int DIGESTING_WATER = 1;
121 const int DIGESTING_ENERGY = 2;
122
123 const int quantity_bit_offset = 16;
124 const int id_bit_offset = 4;//based on food stage count(+1 for safe measure)
125 static int CHECKSUM;
127 const int ACCEPTABLE_QUANTITY_MAX = 32768;
131 static const bool m_InitData = PlayerStomach.InitData();
133 int m_AgentTransferFilter;//bit mask that prevents agents set in the mask from passing to the player
138 protected float m_StomachTemperature;
139 const int STORAGE_VERSION = 106;
140
141
143 {
144 m_Player = player;
145 }
146
147
149 {
150 return m_StomachVolume;
151 }
152
154 {
156 }
157
159 {
160 m_StomachContents.Clear();
161 m_StomachVolume = 0.0;
163 }
164
165 // Reduce content of the stomach by provided percentage
166 void ReduceContents(float percent)
167 {
168 percent = Math.Clamp(percent, 0, 100);
169 float reduction = percent * 0.01;
170
171 foreach (StomachItem item : m_StomachContents)
172 {
173 item.AddAmount( -(item.GetAmount() * reduction) );
174 }
175
176 m_StomachVolume -= m_StomachVolume * reduction;
177 }
178
179 void SetAgentTransferFilter(int filter_agents)
180 {
182 }
183
185 {
187 }
188
189 static void RegisterItem(string classname, int id)
190 {
191 int hash = classname.Hash();
192 CHECKSUM = CHECKSUM^hash; //xor hash vs current checksum
193 m_NamesToIDs.Insert(classname, id);
194 m_IDsToNames.Insert(id, classname);
195 }
196
197 static string GetClassnameFromID(int id)
198 {
199 return m_IDsToNames.Get(id);
200 }
201
202 static int GetIDFromClassname(string name)
203 {
204 if (!m_NamesToIDs.Contains(name))
205 return -1;
206 return m_NamesToIDs.Get(name);
207 }
208
209 static bool InitData()
210 {
211 TStringArray all_paths = new TStringArray;
212
213 all_paths.Insert("CfgVehicles");
214 all_paths.Insert("cfgLiquidDefinitions");
215
216 string config_path;
217 string child_name;
218 int scope;
219 string path;
220 int consumable_count;
221 for(int i = 0; i < all_paths.Count(); i++)
222 {
223 config_path = all_paths.Get(i);
224 int children_count = GetGame().ConfigGetChildrenCount(config_path);
225
226 for(int x = 0; x < children_count; x++)
227 {
228 GetGame().ConfigGetChildName(config_path, x, child_name);
229 path = config_path + " " + child_name;
230 scope = GetGame().ConfigGetInt(config_path + " " + child_name + " scope");
231 bool should_check = 1;
232 if (config_path == "CfgVehicles" && scope == 0)
233 {
234 should_check = 0;
235 }
236
237 if (should_check)
238 {
239 bool has_nutrition = GetGame().ConfigIsExisting(path + " Nutrition");
240 bool has_stages = GetGame().ConfigIsExisting(path + " Food");
241
242 if (has_nutrition || has_stages)
243 {
244 //Print("child name:" + child_name);
245 RegisterItem(child_name, consumable_count);//consumable_count value serves as an unique ID for each item
246 consumable_count++;
247 }
248 }
249 }
250 }
251 //Print("consumable_count " + consumable_count);
252 return true;
253 }
254
256 {
257 return STORAGE_VERSION;
258 }
259
261 {
262 return (m_DigestingType != 0);
263 }
264
266 {
267 return m_DigestingType;
268 }
269
271 {
273
274 int stomachItemsCount = m_StomachContents.Count();
275 if (stomachItemsCount == 0)
276 return;
277
278 StomachItem item;
279
280 for (int i = 0; i < stomachItemsCount; i++)
281 {
282 item = m_StomachContents[i];
284 }
285
286 m_StomachTemperature = m_StomachTemperature / stomachItemsCount;
287 }
288
289 void Update(float delta_time)
290 {
291 ProcessNutrients(delta_time);
292 }
293
294 void ProcessNutrients(float delta_time)
295 {
296 m_DigestingType = 0;
297
298 StomachItem item;
299 int stomachItemsCount = m_StomachContents.Count();
300 if (stomachItemsCount == 0)
301 return;
302
303 float digestionPointsPerItem = (DIGESTION_POINTS / stomachItemsCount) * delta_time;
304 m_StomachVolume = 0;//reset, it's accumulated with each pass
305 for (int i = stomachItemsCount - 1; i >= 0; i--)
306 {
307 item = m_StomachContents[i];
308 float water, energy, toxicity, volume, consumedAmount;
309 int agents;
310
311 if (item.ProcessDigestion(digestionPointsPerItem, water, energy, toxicity, volume, agents, consumedAmount))
312 {
313 m_StomachContents.Remove(i);
315 }
316
317 m_StomachVolume += volume;
318 m_Player.GetStatEnergy().Add(energy);
319 m_Player.GetStatWater().Add(water);
320
321 if (energy > 0)
323
324 if (water > 0)
326
328 float amountOfAgents = item.m_Profile.m_AgentsPerDigest;
329 if (amountOfAgents == 0)
330 amountOfAgents = consumedAmount;
331
333 if ((item.m_Agents & eAgents.FOOD_POISON) == eAgents.FOOD_POISON && m_Player.HasBloodyHands())
334 amountOfAgents = Math.Max(amountOfAgents, PlayerConstants.BLOODY_HANDS_FOOD_POISON_AGENT_INCREMENT);
335
336 DigestAgents(agents, amountOfAgents);
337 }
338 }
339
340 void DigestAgents(int agents, float quantity)
341 {
342 if (!agents)
343 return;
344
345 agents = agents & (~m_AgentTransferFilter);//filter against the agent filter mask
346 int highestBit = Math.Log2(agents) + 1;
347 for (int i = 0; i < highestBit; ++i)
348 {
349 int agent = (1 << i)& agents;
350 if (agent)
351 {
353 if (rndPct != 0)
354 quantity += quantity * rndPct;
355 m_Player.m_AgentPool.DigestAgent(agent, quantity);
356 }
357 }
358 }
359
361 {
362 float amountByAgent = 0.0;
363 foreach (StomachItem item : m_StomachContents)
364 {
365 if ((item.m_Agents & agent) == agent)
366 amountByAgent += item.m_Amount;
367 }
368
369 return amountByAgent;
370 }
371
373 {
374 float amount = GetVolumeContainingAgent(agent);
375 if (amount > 0.0)
376 return Math.InverseLerp(0.0, GetStomachVolume(), amount);
377
378 return 0.0;
379 }
380
382 {
383 Print("================================");
384 for(int i = 0; i < m_StomachContents.Count(); i++)
385 {
386 string itemname = m_StomachContents.Get(i).m_ClassName;
387 float amount = m_StomachContents.Get(i).GetAmount();
388 int food_stage = m_StomachContents.Get(i).GetFoodStage();
389 int agents = m_StomachContents.Get(i).m_Agents;
390 Print(">");
391 Print("itemname:" + itemname);
392 Print("amount:" + amount);
393 Print("food_stage:" + food_stage);
394 Print("agents:" + agents);
395 Print(">");
396 }
397 Print("m_StomachVolume:" + m_StomachVolume);
398 Print("================================");
399 }
400
401 void AddToStomach(string class_name, float amount, int food_stage = 0, int agents = 0, float temperature = 0)
402 {
404 return;
405
406 NutritionalProfile profile = Liquid.GetNutritionalProfileByName(class_name);
407 if (!profile)
408 profile = Edible_Base.GetNutritionalProfile(null, class_name, food_stage);
409
410 if (profile)
411 {
412 // sanity checks start
413 if (amount > ACCEPTABLE_QUANTITY_MAX || amount < 0)
414 amount = 0;
415
416 if (food_stage < 0 || food_stage > ACCEPTABLE_FOODSTAGE_MAX)
417 food_stage = FoodStageType.RAW;
418 // sanity checks end
419
420 agents = agents | profile.GetAgents();
421 bool found = false;
422 int count = m_StomachContents.Count();
423 for(int i = 0; i < count; i++)
424 {
425 StomachItem stomachItem = m_StomachContents.Get(i);
426 if (stomachItem.GetClassName() == class_name && stomachItem.m_Agents == agents)
427 {
428 if (profile.IsLiquid() || stomachItem.GetFoodStage() == food_stage)
429 {
430 float fraction = 1;
431 if (amount != 0)
432 fraction = (stomachItem.m_Amount + amount) / amount;
433
434 stomachItem.AddTemperature(temperature, fraction);
435 stomachItem.AddAmount(amount);
436 stomachItem.AddAgents(agents); //nutrition profile agents
437 found = true;
438 }
439 }
440 }
441
442 if (!found)
443 m_StomachContents.Insert(new StomachItem(class_name, amount, profile, food_stage, agents, temperature));
444
446 }
447 }
448
450 {
451 ctx.Write(PlayerStomach.CHECKSUM);
452 ctx.Write(m_StomachContents.Count());
453 StomachItem stomachItem;
454 for(int i = 0; i < m_StomachContents.Count();i++)
455 {
456 stomachItem = m_StomachContents.Get(i);
457 int id = PlayerStomach.GetIDFromClassname(stomachItem.m_ClassName);
458 //Print("SAVE id:" + id);
459 //Print("SAVE id_bit_offset:" + id_bit_offset);
460
461 int writeResult = stomachItem.m_FoodStage | (id << id_bit_offset);
462 writeResult = writeResult | ((int)stomachItem.m_Amount << quantity_bit_offset);
463 ctx.Write(writeResult);
464 ctx.Write(stomachItem.m_Agents);
465 ctx.Write((int)stomachItem.GetTemperature());
466 //Print("SAVE writeResult:" + writeResult);
467 }
468 //Print("SAVE CHECKSUM:" + PlayerStomach.CHECKSUM);
469 }
470
471 bool OnStoreLoad(ParamsReadContext ctx, int version)
472 {
473 int checksum, count;
474 if (!ctx.Read(checksum))
475 {
476 return false;
477 }
478
479 if (!ctx.Read(count))
480 {
481 return false;
482 }
483 for (int i = 0; i < count; ++i)
484 {
485 int value, agents, temperature;
486 if (!ctx.Read(value))
487 return false;
488
489 if (!ctx.Read(agents))
490 return false;
491
492 if (version >= 140 && !ctx.Read(temperature))
493 return false;
494
495 if (checksum == CHECKSUM)//if checksum matches, add to stomach, otherwise throw the data away but go through the de-serialization to keep the stream intact
496 {
497 int amount = value >> quantity_bit_offset;//isolate amount bits
498 int id_mask = Math.Pow(2, quantity_bit_offset) - 1;
499 int id = (id_mask & value) >> id_bit_offset;//isolate id bits
500 int food_mask = Math.Pow(2, id_bit_offset) - 1;
501 int food_stage = value & food_mask;
502 //Print("LOAD value:" + value);
503 //Print("LOAD id:" + id);
504 //Print("LOAD id_bit_offset:" + id_bit_offset);
505 //Print("LOAD food_stage:" + food_stage);
506 string classname = GetClassnameFromID(id);
507 AddToStomach(classname, amount, food_stage, agents, temperature);
508 }
509 }
510 //Print("LOAD checksum:" + checksum);
511 if (checksum != CHECKSUM)
512 {
513 Print("Stomach checksum fail");
514 }
515 return true;
516 }
517
519 {
520 int count = m_StomachContents.Count();
521 for(int i = 0; i < m_StomachContents.Count();i++)
522 {
523 int id = PlayerStomach.GetIDFromClassname(m_StomachContents.Get(i).m_ClassName);
524 int food_stage = m_StomachContents.Get(i).m_FoodStage;
525 int agents = m_StomachContents.Get(i).m_Agents;
526 float amount = m_StomachContents.Get(i).m_Amount;
527 float temperature = m_StomachContents.Get(i).GetTemperature();
528 Param5<int,int,int,float,float> p5 = new Param5<int,int,int,float,float>(id, food_stage, agents, amount, temperature);
529 object_out.Insert(p5);
530 }
531 Param1<float> p1 = new Param1<float>(m_StomachVolume);
532 object_out.Insert(p1);
533 Param1<float> paramTemp = new Param1<float>(m_StomachTemperature);
534 object_out.Insert(paramTemp);
535 return count;
536
537 }
538}
Param3 int
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
map
Определения ControlsXboxNew.c:4
eAgents
Определения EAgents.c:3
FoodStageType
Определения FoodStage.c:2
DayZPlayer m_Player
Определения Hand_Events.c:42
Icon x
void OnStoreSave(ParamsWriteContext ctx)
Определения ModifiersManager.c:229
int GetStorageVersion()
Определения ModifiersManager.c:170
class ModifierDebugObj STORAGE_VERSION
bool OnStoreLoad(ParamsReadContext ctx, int version)
Определения ModifiersManager.c:265
string path
Определения OptionSelectorMultistate.c:142
class OptionSelectorMultistate extends OptionSelector class_name
int m_DigestingType
Определения PlayerStomach.c:135
void AddToStomach(string class_name, float amount, int food_stage=0, int agents=0, float temperature=0)
Определения PlayerStomach.c:401
void PrintUpdate()
Определения PlayerStomach.c:381
float GetVolumeContainingAgent01(eAgents agent)
Определения PlayerStomach.c:372
void ClearContents()
Определения PlayerStomach.c:158
void ReduceContents(float percent)
Определения PlayerStomach.c:166
const int ACCEPTABLE_QUANTITY_MAX
Определения PlayerStomach.c:127
void UpdateStomachTemperature()
Определения PlayerStomach.c:270
const int ACCEPTABLE_FOODSTAGE_MAX
Определения PlayerStomach.c:128
int GetAgentTransferFilter()
Определения PlayerStomach.c:184
bool IsDigesting()
Определения PlayerStomach.c:260
float GetStomachTemperature()
Определения PlayerStomach.c:153
static ref map< int, string > m_IDsToNames
Определения PlayerStomach.c:130
static int CHECKSUM
Определения PlayerStomach.c:125
const float DIGESTION_POINTS
Определения PlayerStomach.c:126
class StomachItem DIGESTING_WATER
const int quantity_bit_offset
Определения PlayerStomach.c:123
void DigestAgents(int agents, float quantity)
Определения PlayerStomach.c:340
int GetDebugObject(array< ref Param > object_out)
Определения PlayerStomach.c:518
const int DIGESTING_ENERGY
Определения PlayerStomach.c:121
bool m_Digesting
Определения PlayerStomach.c:134
void ProcessNutrients(float delta_time)
Определения PlayerStomach.c:294
static void RegisterItem(string classname, int id)
Определения PlayerStomach.c:189
int GetDigestingType()
Определения PlayerStomach.c:265
static string GetClassnameFromID(int id)
Определения PlayerStomach.c:197
float m_StomachTemperature
Определения PlayerStomach.c:138
float GetStomachVolume()
Определения PlayerStomach.c:148
void SetAgentTransferFilter(int filter_agents)
Определения PlayerStomach.c:179
ref array< ref StomachItem > m_StomachContents
Определения PlayerStomach.c:132
static bool InitData()
Определения PlayerStomach.c:209
static const bool m_InitData
Определения PlayerStomach.c:131
const int id_bit_offset
Определения PlayerStomach.c:124
float m_StomachVolume
Определения PlayerStomach.c:137
float GetVolumeContainingAgent(eAgents agent)
Определения PlayerStomach.c:360
static int GetIDFromClassname(string name)
Определения PlayerStomach.c:202
int m_AgentTransferFilter
Определения PlayerStomach.c:133
static ref map< string, int > m_NamesToIDs
Определения PlayerStomach.c:129
void PlayerStomach(PlayerBase player)
Определения PlayerStomach.c:142
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
proto native bool ConfigIsExisting(string path)
proto native int ConfigGetInt(string path)
Get int value from config on path.
proto native int ConfigGetChildrenCount(string path)
Get count of subclasses in config class on path.
static NutritionalProfile GetNutritionalProfile(ItemBase item, string classname="", int food_stage=0)
Определения Edible_Base.c:513
Определения Edible_Base.c:2
Определения EnMath.c:7
bool IsLiquid()
Определения NutritionalProfile.c:47
float GetDigestibility()
Определения NutritionalProfile.c:77
float GetWaterContent()
Определения NutritionalProfile.c:57
int GetAgents()
Определения NutritionalProfile.c:32
float GetEnergy()
Определения NutritionalProfile.c:52
float GetToxicity()
Определения NutritionalProfile.c:72
float m_AgentsPerDigest
Определения NutritionalProfile.c:12
Определения PlayerBaseClient.c:2
static const float STOMACH_DIGEST_AGENT_RANDOM_MIN
Определения PlayerConstants.c:67
static const float STOMACH_DIGEST_AGENT_RANDOM_MAX
Percents of agents count <-1.0; 1.0>
Определения PlayerConstants.c:68
static const float BLOODY_HANDS_FOOD_POISON_AGENT_INCREMENT
Определения PlayerConstants.c:265
static const float DIGESTION_SPEED
Определения PlayerConstants.c:61
Определения PlayerConstants.c:2
proto bool Write(void value_out)
proto bool Read(void value_in)
int GetFoodStage()
Определения PlayerStomach.c:38
void SetFoodStage(int food_stage)
Определения PlayerStomach.c:43
float m_Temperature
Определения PlayerStomach.c:9
float GetNutritions(float digestion_points, NutritionalProfile profile, out float water, out float energy, out float toxicity)
Определения PlayerStomach.c:90
void StomachItem(string class_name, float amount, NutritionalProfile profile, int foodstage, int agents, float temperature)
Определения PlayerStomach.c:11
ref NutritionalProfile m_Profile
Определения PlayerStomach.c:3
float GetAmount()
Определения PlayerStomach.c:49
string GetClassName()
Определения PlayerStomach.c:22
bool ProcessDigestion(float digestion_points, out float water, out float energy, out float toxicity, out float volume, out int agents, out float consumed_amount)
Определения PlayerStomach.c:81
int m_Agents
Определения PlayerStomach.c:8
void AddTemperature(float temperature, float fraction)
Определения PlayerStomach.c:71
int m_FoodStage
Определения PlayerStomach.c:5
float m_Amount
Определения PlayerStomach.c:4
string m_ClassName
Определения PlayerStomach.c:7
void AddAmount(float amount)
Определения PlayerStomach.c:55
void AddAgents(int agents)
Определения PlayerStomach.c:60
float GetTemperature()
Определения PlayerStomach.c:65
Определения PlayerStomach.c:2
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Serializer ParamsReadContext
Определения gameplay.c:15
proto native CGame GetGame()
Serializer ParamsWriteContext
Определения gameplay.c:16
proto void Print(void var)
Prints content of variable to console/log.
array< string > TStringArray
Определения EnScript.c:685
static proto float Max(float x, float y)
Returns bigger of two given values.
static float RandomFloatInclusive(float min, float max)
Returns a random float number between and min [inclusive] and max [inclusive].
Определения EnMath.c:106
static proto float Log2(float x)
Returns the binary (base-2) logarithm of x.
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.
static proto float InverseLerp(float a, float b, float value)
Calculates the linear value that produces the interpolant value within the range [a,...
static proto float Pow(float v, float power)
Return power of v ^ power.
proto native int Hash()
Returns hash of string.
proto native volatile void Update()
Определения PlayerSoundManager.c:125