Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
playerstomach.c
Go to the documentation of this file.
2 {
3  ref NutritionalProfile m_Profile;
4  float m_Amount;
5  int m_FoodStage;
6  //bool m_IsLiquid;
7  string m_ClassName;
8  int m_Agents;
9 
10  void StomachItem(string class_name, float amount, NutritionalProfile profile,int foodstage, int agents)
11  {
12  m_Amount = amount;
13  m_Profile = profile;
14  //m_IsLiquid = is_liquid;
15  m_FoodStage = foodstage;
16  m_ClassName = class_name;
17  m_Agents = agents;
18  }
19 
20  string GetClassName()
21  {
22  return m_ClassName;
23  }
24 
25  /*
26  void SetLiquid(bool is_liquid)
27  {
28  m_IsLiquid = is_liquid;
29  }
30 
31  bool IsLiquid()
32  {
33  return m_IsLiquid;
34  }*/
35 
36 
37 
38  int GetFoodStage()
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 
65 
66  // "digests" given amount, "outs" nutritional components, and returns 'true' if leads to complete item digestion(no amount left)
67  bool ProcessDigestion(float digestion_points, out float water, out float energy, out float toxicity, out float volume, out int agents, out float consumed_amount)
68  {
69  agents = m_Agents;
70  consumed_amount = GetNutritions(digestion_points, m_Profile, water, energy, toxicity );
71  m_Amount -= consumed_amount;
72  volume = m_Profile.GetFullnessIndex() * m_Amount;
73  return( m_Amount < 0.001 );
74  }
75 
76  float GetNutritions( float digestion_points, NutritionalProfile profile, out float water, out float energy, out float toxicity )
77  {
78  float energy_per_unit = profile.GetEnergy() / 100;
79  float water_per_unit = profile.GetWaterContent() / 100;
80  float toxicity_per_unit = profile.GetToxicity();
81  float digestability = profile.GetDigestibility();
82 
83  if(digestability == 0)//if undefined
84  {
85  digestability = 1;
86  }
87 
88  float consumed_quantity = digestion_points * digestability;
89 
90  if( m_Amount < consumed_quantity )
91  {
92  consumed_quantity = m_Amount;
93  }
94  if ( consumed_quantity > 0 )
95  {
96  water = consumed_quantity * water_per_unit;
97  energy = consumed_quantity * energy_per_unit;
98  toxicity = consumed_quantity * toxicity_per_unit;
99  }
100  return consumed_quantity;
101  }
102 }
103 
104 class PlayerStomach
105 {
106  const int DIGESTING_WATER = 1;
107  const int DIGESTING_ENERGY = 2;
108 
109  const int quantity_bit_offset = 16;
110  const int id_bit_offset = 4;//based on food stage count(+1 for safe measure)
111  static int CHECKSUM;
112  const float DIGESTION_POINTS = PlayerConstants.DIGESTION_SPEED;
113  const int ACCEPTABLE_QUANTITY_MAX = 32768;
115  static ref map<string, int> m_NamesToIDs = new map<string, int>;
116  static ref map<int, string> m_IDsToNames = new map<int, string>;
117  static const bool m_InitData = PlayerStomach.InitData();
119  int m_AgentTransferFilter;//bit mask that prevents agents set in the mask from passing to the player
124  const int STORAGE_VERSION = 106;
125 
126 
128  {
129  m_Player = player;
130  }
131 
133  {
134 
135  }
136 
137 
139  {
140  return m_StomachVolume;
141  }
142 
144  {
145  m_StomachContents.Clear();
146  m_StomachVolume = 0.0;
147  }
148 
149  void SetAgentTransferFilter(int filter_agents)
150  {
152  }
153 
155  {
156  return m_AgentTransferFilter;
157  }
158 
159  static void RegisterItem(string classname, int id)
160  {
161  int hash = classname.Hash();
162  CHECKSUM = CHECKSUM^hash; //xor hash vs current checksum
163 // Print(classname);
164 // Print(CHECKSUM);
165  m_NamesToIDs.Insert(classname, id);
166  m_IDsToNames.Insert(id, classname);
167  }
168 
169  static string GetClassnameFromID(int id)
170  {
171  return m_IDsToNames.Get(id);
172  }
173 
174  static int GetIDFromClassname(string name)
175  {
176  if(!m_NamesToIDs.Contains(name))
177  return -1;
178  return m_NamesToIDs.Get(name);
179  }
180 
181  static bool InitData()
182  {
183  TStringArray all_paths = new TStringArray;
184 
185  all_paths.Insert("CfgVehicles");
186  all_paths.Insert("cfgLiquidDefinitions");
187 
188  string config_path;
189  string child_name;
190  int scope;
191  string path;
192  int consumable_count;
193  for(int i = 0; i < all_paths.Count(); i++)
194  {
195  config_path = all_paths.Get(i);
196  int children_count = GetGame().ConfigGetChildrenCount(config_path);
197 
198  for(int x = 0; x < children_count; x++)
199  {
200  GetGame().ConfigGetChildName(config_path, x, child_name);
201  path = config_path + " " + child_name;
202  scope = GetGame().ConfigGetInt( config_path + " " + child_name + " scope" );
203  bool should_check = 1;
204  if( config_path == "CfgVehicles" && scope == 0)
205  {
206  should_check = 0;
207  }
208 
209  if ( should_check )
210  {
211  bool has_nutrition = GetGame().ConfigIsExisting(path + " Nutrition");
212  bool has_stages = GetGame().ConfigIsExisting(path + " Food");
213 
214  if(has_nutrition || has_stages)
215  {
216  //Print("child name:" + child_name);
217  RegisterItem(child_name, consumable_count);//consumable_count value serves as an unique ID for each item
218  consumable_count++;
219  }
220  }
221  }
222  }
223  //Print("consumable_count " + consumable_count);
224  return true;
225  }
226 
228  {
229  return STORAGE_VERSION;
230  }
231 
232  bool IsDigesting()
233  {
234  return (m_DigestingType != 0);
235  }
236 
238  {
239  return m_DigestingType;
240  }
241 
242 
243  void Update(float delta_time)
244  {
245  ProcessNutrients(delta_time);
246  }
247 
248  void ProcessNutrients(float delta_time)
249  {
250  StomachItem item;
251  int stomach_items_count = m_StomachContents.Count();
252  m_DigestingType = 0;
253  if(stomach_items_count == 0)
254  return;
255 
256  float digestion_points_per_item = (DIGESTION_POINTS / stomach_items_count) * delta_time;
257  m_StomachVolume = 0;//reset, it's accumulated with each pass
258  for(int i = 0; i < m_StomachContents.Count(); i ++)
259  {
260  item = m_StomachContents.Get(i);
261  float water, energy, toxicity, volume, consumed_amount;
262  int agents;
263  if(item.ProcessDigestion( digestion_points_per_item, water, energy, toxicity, volume, agents, consumed_amount ))
264  {
265  m_StomachContents.Remove(i);
266  i--;
267  }
268  m_StomachVolume += volume;
269  m_Player.GetStatEnergy().Add(energy);
270  m_Player.GetStatWater().Add(water);
271 
272  if(energy > 0)
273  {
275  }
276 
277  if(water > 0)
278  {
280  }
281 
282  DigestAgents(agents, consumed_amount);
283  }
284  }
285 
286 
287  void DigestAgents(int agents, float quantity)
288  {
289  if(!agents)
290  return;
291  agents = agents & (~m_AgentTransferFilter);//filter against the agent filter mask
292  int highest_bit = Math.Log2(agents) + 1;
293  for(int i = 0; i < highest_bit;i++)
294  {
295  int agent = (1 << i)& agents;
296  if( agent )
297  {
298  m_Player.m_AgentPool.DigestAgent(agent, quantity);
299  }
300  }
301  }
302 
303  void PrintUpdate()
304  {
305  Print("================================");
306  for(int i = 0; i < m_StomachContents.Count(); i++)
307  {
308  string itemname = m_StomachContents.Get(i).m_ClassName;
309  float amount = m_StomachContents.Get(i).GetAmount();
310  int food_stage = m_StomachContents.Get(i).GetFoodStage();
311  int agents = m_StomachContents.Get(i).m_Agents;
312  Print(">");
313  Print("itemname:" + itemname);
314  Print("amount:" + amount);
315  Print("food_stage:" + food_stage);
316  Print("agents:" + agents);
317  Print(">");
318  }
319  Print("m_StomachVolume:" + m_StomachVolume);
320  Print("================================");
321  }
322 
323  void AddToStomach(string class_name, float amount, int food_stage = 0, int agents = 0)
324  {
325  if (GetIDFromClassname(class_name) == -1)
326  return;
327  bool is_liquid;
328 
329  NutritionalProfile profile = Liquid.GetNutritionalProfileByName(class_name);
330  if(profile)
331  {
332  is_liquid = true;
333  }
334  else
335  {
336  profile = Edible_Base.GetNutritionalProfile(null,class_name, food_stage);
337  }
338 
339  if(profile)
340  {
341  // sanity checks start
342  if(amount > ACCEPTABLE_QUANTITY_MAX || amount < 0)
343  {
344  amount = 0;
345  }
346  if (food_stage < 0 || food_stage > ACCEPTABLE_FOODSTAGE_MAX)
347  {
348  food_stage = FoodStageType.RAW;
349  }
350  // sanity checks end
351 
352  agents = agents | profile.GetAgents();
353  bool found = false;
354  for(int i = 0; i < m_StomachContents.Count(); i++)
355  {
356  StomachItem stomach_item = m_StomachContents.Get(i);
357  if(stomach_item.GetClassName() == class_name )
358  {
359  if (is_liquid || stomach_item.GetFoodStage() == food_stage)
360  {
361  stomach_item.AddAmount(amount);
362  stomach_item.AddAgents(agents);
363  found = true;
364  }
365  }
366  }
367 
368  if(!found)
369  {
370  m_StomachContents.Insert(new StomachItem(class_name, amount, profile, food_stage, agents));
371  }
372  }
373  }
374 
376  {
377  ctx.Write( PlayerStomach.CHECKSUM );
378  ctx.Write( m_StomachContents.Count() );
379  StomachItem stomach_item;
380  for(int i = 0; i < m_StomachContents.Count();i++)
381  {
382  stomach_item = m_StomachContents.Get(i);
383  int id = PlayerStomach.GetIDFromClassname(stomach_item.m_ClassName);
384  //Print("SAVE id:" + id);
385  //Print("SAVE id_bit_offset:" + id_bit_offset);
386 
387  int write_result = stomach_item.m_FoodStage | ( id << id_bit_offset );
388  write_result = write_result | ((int)stomach_item.m_Amount << quantity_bit_offset);
389  ctx.Write( write_result );
390  ctx.Write( stomach_item.m_Agents );
391  //Print("SAVE write_result:" + write_result);
392  }
393  //Print("SAVE CHECKSUM:" + PlayerStomach.CHECKSUM);
394  }
395 
396  bool OnStoreLoad(ParamsReadContext ctx, int version)
397  {
398  int checksum, count;
399  if(!ctx.Read(checksum))
400  {
401  return false;
402  }
403 
404  if(!ctx.Read(count))
405  {
406  return false;
407  }
408  for(int i = 0; i < count; i++)
409  {
410  int value, agents;
411  if(!ctx.Read(value) )
412  {
413  return false;
414  }
415  if(!ctx.Read(agents) )
416  {
417  return false;
418  }
419  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
420  {
421  int amount = value >> quantity_bit_offset;//isolate amount bits
422  int id_mask = Math.Pow(2, quantity_bit_offset) - 1;
423  int id = (id_mask & value) >> id_bit_offset;//isolate id bits
424  int food_mask = Math.Pow(2, id_bit_offset) - 1;
425  int food_stage = value & food_mask;
426  //Print("LOAD value:" + value);
427  //Print("LOAD id:" + id);
428  //Print("LOAD id_bit_offset:" + id_bit_offset);
429  //Print("LOAD food_stage:" + food_stage);
430  string classname = GetClassnameFromID(id);
431  AddToStomach(classname, amount, food_stage, agents);
432  }
433  }
434  //Print("LOAD checksum:" + checksum);
435  if(checksum != CHECKSUM)
436  {
437  Print("Stomach checksum fail");
438  }
439  return true;
440  }
441 
443  {
444  int count = m_StomachContents.Count();
445  for(int i = 0; i < m_StomachContents.Count();i++)
446  {
447  int id = PlayerStomach.GetIDFromClassname(m_StomachContents.Get(i).m_ClassName);
448  int food_stage = m_StomachContents.Get(i).m_FoodStage;
449  int agents = m_StomachContents.Get(i).m_Agents;
450  float amount = m_StomachContents.Get(i).m_Amount;
451  Param4<int,int,int,float> p4 = new Param4<int,int,int,float>(id, food_stage, agents, amount);
452  object_out.Insert(p4);
453  }
454  Param1<float> p1 = new Param1<float>(m_StomachVolume);
455  object_out.Insert(p1);
456  return count;
457 
458  }
459 }
GetGame
proto native CGame GetGame()
GetStomachVolume
float GetStomachVolume()
Definition: playerstomach.c:138
TStringArray
array< string > TStringArray
Definition: enscript.c:685
GetStorageVersion
int GetStorageVersion()
Definition: playerstomach.c:227
GetDebugObject
int GetDebugObject(array< ref Param > object_out)
Definition: playerstomach.c:442
m_Digesting
bool m_Digesting
Definition: playerstomach.c:120
OnStoreLoad
bool OnStoreLoad(ParamsReadContext ctx, int version)
Definition: playerstomach.c:396
DigestAgents
void DigestAgents(int agents, float quantity)
Definition: playerstomach.c:287
ACCEPTABLE_QUANTITY_MAX
const int ACCEPTABLE_QUANTITY_MAX
Definition: playerstomach.c:113
Print
proto void Print(void var)
Prints content of variable to console/log.
PlayerStomach
void PlayerStomach(PlayerBase player)
Definition: playerstomach.c:127
ACCEPTABLE_FOODSTAGE_MAX
const int ACCEPTABLE_FOODSTAGE_MAX
Definition: playerstomach.c:114
GetDigestingType
int GetDigestingType()
Definition: playerstomach.c:237
SetAgentTransferFilter
void SetAgentTransferFilter(int filter_agents)
Definition: playerstomach.c:149
DIGESTING_WATER
class StomachItem DIGESTING_WATER
Serializer
Serialization general interface. Serializer API works with:
Definition: serializer.c:55
m_StomachVolume
float m_StomachVolume
Definition: playerstomach.c:123
PlayerBase
Definition: playerbaseclient.c:1
map
map
Definition: controlsxboxnew.c:3
PlayerConstants
Definition: playerconstants.c:1
AddToStomach
void AddToStomach(string class_name, float amount, int food_stage=0, int agents=0)
Definition: playerstomach.c:323
quantity_bit_offset
const int quantity_bit_offset
Definition: playerstomach.c:109
DIGESTION_POINTS
const float DIGESTION_POINTS
Definition: playerstomach.c:112
OnStoreSave
void OnStoreSave(ParamsWriteContext ctx)
Definition: playerstomach.c:375
DIGESTING_ENERGY
const int DIGESTING_ENERGY
Definition: playerstomach.c:107
id_bit_offset
const int id_bit_offset
Definition: playerstomach.c:110
class_name
class OptionSelectorMultistate extends OptionSelector class_name
FoodStageType
FoodStageType
Definition: foodstage.c:1
m_Agents
int m_Agents
Definition: actiongivebloodself.c:4
ClearContents
void ClearContents()
Definition: playerstomach.c:143
array
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Definition: isboxcollidinggeometryproxyclasses.c:27
m_AgentTransferFilter
int m_AgentTransferFilter
Definition: playerstomach.c:119
Update
void Update(float delta_time)
Definition: playerstomach.c:243
GetAgentTransferFilter
int GetAgentTransferFilter()
Definition: playerstomach.c:154
ProcessNutrients
void ProcessNutrients(float delta_time)
Definition: playerstomach.c:248
name
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
x
Icon x
IsDigesting
bool IsDigesting()
Definition: playerstomach.c:232
m_FoodStage
ref FoodStage m_FoodStage
Definition: edible_base.c:12
m_DigestingType
int m_DigestingType
Definition: playerstomach.c:121
NutritionalProfile
Definition: nutritionalprofile.c:1
int
Param3 int
~PlayerStomach
void ~PlayerStomach()
Definition: playerstomach.c:132
StomachItem
Definition: playerstomach.c:1
Liquid
Definition: liquid.c:1
Math
Definition: enmath.c:6
PrintUpdate
void PrintUpdate()
Definition: playerstomach.c:303
m_StomachContents
ref array< ref StomachItem > m_StomachContents
Definition: playerstomach.c:118
m_Player
PlayerBase m_Player
Definition: playerstomach.c:122
Edible_Base
Definition: bearsteakmeat.c:1
path
string path
Definition: optionselectormultistate.c:135
STORAGE_VERSION
const int STORAGE_VERSION
Definition: playerstomach.c:124