DayZ 1.24
Loading...
Searching...
No Matches
PlayerStomach.c
Go to the documentation of this file.
2{
4 float m_Amount;
6 //bool m_IsLiquid;
7 string m_ClassName;
9
10 void StomachItem(string class_name, float amount, NutritionalProfile profile, int foodstage, int agents)
11 {
12 m_Amount = amount;
14 //m_IsLiquid = is_liquid;
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
38 {
39 return m_FoodStage;
40 }
41
43 {
45 }
46
47 // returns grams or ml's of this item/liquid
48 float GetAmount()
49 {
50 return m_Amount;
51 }
52
53 // adds grams or ml's of this item/liquid
54 void AddAmount(float amount)
55 {
56 m_Amount += amount;
57 }
58
59 void AddAgents(int agents)
60 {
62 }
63
64
65 // "digests" given amount, "outs" nutritional components, and returns 'true' if leads to complete item digestion(no amount left)
66 bool ProcessDigestion(float digestion_points, out float water, out float energy, out float toxicity, out float volume, out int agents, out float consumed_amount)
67 {
71 volume = m_Profile.GetFullnessIndex() * m_Amount;
72 return (m_Amount < 0.001);
73 }
74
76 {
77 float energy_per_unit = profile.GetEnergy() / 100;
78 float water_per_unit = profile.GetWaterContent() / 100;
79 float toxicity_per_unit = profile.GetToxicity();
80 float digestability = profile.GetDigestibility();
81
82 if (digestability == 0) //if undefined
83 digestability = 1;
84
86
89 if (consumed_quantity > 0)
90 {
94 }
95 return consumed_quantity;
96 }
97}
98
99class PlayerStomach
100{
101 const int DIGESTING_WATER = 1;
102 const int DIGESTING_ENERGY = 2;
103
104 const int quantity_bit_offset = 16;
105 const int id_bit_offset = 4;//based on food stage count(+1 for safe measure)
106 static int CHECKSUM;
108 const int ACCEPTABLE_QUANTITY_MAX = 32768;
112 static const bool m_InitData = PlayerStomach.InitData();
114 int m_AgentTransferFilter;//bit mask that prevents agents set in the mask from passing to the player
119 const int STORAGE_VERSION = 106;
120
121
126
128 {
129
130 }
131
132
134 {
135 return m_StomachVolume;
136 }
137
139 {
140 m_StomachContents.Clear();
141 m_StomachVolume = 0.0;
142 }
143
148
150 {
152 }
153
154 static void RegisterItem(string classname, int id)
155 {
156 int hash = classname.Hash();
157 CHECKSUM = CHECKSUM ^ hash; //xor hash vs current checksum
158 // Print(classname);
159 // Print(CHECKSUM);
160 m_NamesToIDs.Insert(classname, id);
161 m_IDsToNames.Insert(id, classname);
162 }
163
164 static string GetClassnameFromID(int id)
165 {
166 return m_IDsToNames.Get(id);
167 }
168
169 static int GetIDFromClassname(string name)
170 {
171 if (!m_NamesToIDs.Contains(name))
172 return -1;
173 return m_NamesToIDs.Get(name);
174 }
175
176 static bool InitData()
177 {
179
180 all_paths.Insert("CfgVehicles");
181 all_paths.Insert("cfgLiquidDefinitions");
182
183 string config_path;
184 string child_name;
185 int scope;
186 string path;
188 for (int i = 0; i < all_paths.Count(); i++)
189 {
190 config_path = all_paths.Get(i);
191 int children_count = GetGame().ConfigGetChildrenCount(config_path);
192
193 for (int x = 0; x < children_count; x++)
194 {
195 GetGame().ConfigGetChildName(config_path, x, child_name);
196 path = config_path + " " + child_name;
197 scope = GetGame().ConfigGetInt(config_path + " " + child_name + " scope");
198 bool should_check = 1;
199 if (config_path == "CfgVehicles" && scope == 0)
200 should_check = 0;
201
202 if (should_check)
203 {
204 bool has_nutrition = GetGame().ConfigIsExisting(path + " Nutrition");
205 bool has_stages = GetGame().ConfigIsExisting(path + " Food");
206
208 {
209 //Print("child name:" + child_name);
210 RegisterItem(child_name, consumable_count);//consumable_count value serves as an unique ID for each item
212 }
213 }
214 }
215 }
216 //Print("consumable_count " + consumable_count);
217 return true;
218 }
219
221 {
222 return STORAGE_VERSION;
223 }
224
226 {
227 return (m_DigestingType != 0);
228 }
229
231 {
232 return m_DigestingType;
233 }
234
235
236 void Update(float delta_time)
237 {
239 }
240
242 {
245 m_DigestingType = 0;
246 if (stomach_items_count == 0)
247 return;
248
250 m_StomachVolume = 0;//reset, it's accumulated with each pass
251 for (int i = 0; i < m_StomachContents.Count(); i ++)
252 {
253 item = m_StomachContents.Get(i);
255 int agents;
257 {
258 m_StomachContents.Remove(i);
259 i--;
260 }
262 m_Player.GetStatEnergy().Add(energy);
263 m_Player.GetStatWater().Add(water);
264
265 if (energy > 0)
267
268 if (water > 0)
270
272 }
273 }
274
275
276 void DigestAgents(int agents, float quantity)
277 {
278 if (!agents)
279 return;
280 agents = agents & (~m_AgentTransferFilter);//filter against the agent filter mask
281 int highest_bit = Math.Log2(agents) + 1;
282 for (int i = 0; i < highest_bit; i++)
283 {
284 int agent = (1 << i)& agents;
285 if (agent)
286 m_Player.m_AgentPool.DigestAgent(agent, quantity);
287 }
288 }
289
291 {
292 Print("================================");
293 for (int i = 0; i < m_StomachContents.Count(); i++)
294 {
295 string itemname = m_StomachContents.Get(i).m_ClassName;
296 float amount = m_StomachContents.Get(i).GetAmount();
297 int food_stage = m_StomachContents.Get(i).GetFoodStage();
298 int agents = m_StomachContents.Get(i).m_Agents;
299 Print(">");
300 Print("itemname:" + itemname);
301 Print("amount:" + amount);
302 Print("food_stage:" + food_stage);
303 Print("agents:" + agents);
304 Print(">");
305 }
306 Print("m_StomachVolume:" + m_StomachVolume);
307 Print("================================");
308 }
309
310 void AddToStomach(string class_name, float amount, int food_stage = 0, int agents = 0)
311 {
313 return;
314 bool is_liquid;
315
317 if (profile)
318 is_liquid = true;
319 else
321
322 if (profile)
323 {
324 // sanity checks start
325 if (amount > ACCEPTABLE_QUANTITY_MAX || amount < 0)
326 amount = 0;
329 // sanity checks end
330
331 agents = agents | profile.GetAgents();
332 bool found = false;
333 for (int i = 0; i < m_StomachContents.Count(); i++)
334 {
336 if (stomach_item.GetClassName() == class_name)
337 {
338 if (is_liquid || stomach_item.GetFoodStage() == food_stage)
339 {
340 stomach_item.AddAmount(amount);
341 stomach_item.AddAgents(agents);
342 found = true;
343 }
344 }
345 }
346
347 if (!found)
349 }
350 }
351
353 {
354 ctx.Write(PlayerStomach.CHECKSUM);
355 ctx.Write(m_StomachContents.Count());
357 for (int i = 0; i < m_StomachContents.Count(); i++)
358 {
360 int id = PlayerStomach.GetIDFromClassname(stomach_item.m_ClassName);
361 //Print("SAVE id:" + id);
362 //Print("SAVE id_bit_offset:" + id_bit_offset);
363
364 int write_result = stomach_item.m_FoodStage | (id << id_bit_offset);
366 ctx.Write(write_result);
367 ctx.Write(stomach_item.m_Agents);
368 //Print("SAVE write_result:" + write_result);
369 }
370 //Print("SAVE CHECKSUM:" + PlayerStomach.CHECKSUM);
371 }
372
374 {
375 int checksum, count;
376 if (!ctx.Read(checksum))
377 return false;
378
379 if (!ctx.Read(count))
380 return false;
381 for (int i = 0; i < count; i++)
382 {
383 int value, agents;
384 if (!ctx.Read(value))
385 return false;
386 if (!ctx.Read(agents))
387 return false;
388 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
389 {
390 int amount = value >> quantity_bit_offset;//isolate amount bits
391 int id_mask = Math.Pow(2, quantity_bit_offset) - 1;
392 int id = (id_mask & value) >> id_bit_offset;//isolate id bits
393 int food_mask = Math.Pow(2, id_bit_offset) - 1;
394 int food_stage = value & food_mask;
395 //Print("LOAD value:" + value);
396 //Print("LOAD id:" + id);
397 //Print("LOAD id_bit_offset:" + id_bit_offset);
398 //Print("LOAD food_stage:" + food_stage);
399 string classname = GetClassnameFromID(id);
401 }
402 }
403 //Print("LOAD checksum:" + checksum);
404 if (checksum != CHECKSUM)
405 Print("Stomach checksum fail");
406 return true;
407 }
408
410 {
411 int count = m_StomachContents.Count();
412 for (int i = 0; i < m_StomachContents.Count(); i++)
413 {
414 int id = PlayerStomach.GetIDFromClassname(m_StomachContents.Get(i).m_ClassName);
415 int food_stage = m_StomachContents.Get(i).m_FoodStage;
416 int agents = m_StomachContents.Get(i).m_Agents;
417 float amount = m_StomachContents.Get(i).m_Amount;
419 object_out.Insert(p4);
420 }
422 object_out.Insert(p1);
423 return count;
424
425 }
426}
Param3 int
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
FoodStageType
Definition FoodStage.c:2
DayZPlayer m_Player
Definition Hand_Events.c:42
Icon x
void OnStoreSave(ParamsWriteContext ctx)
int GetStorageVersion()
const int STORAGE_VERSION
bool OnStoreLoad(ParamsReadContext ctx, int version)
class OptionSelectorMultistate extends OptionSelector class_name
int m_DigestingType
void PrintUpdate()
void AddToStomach(string class_name, float amount, int food_stage=0, int agents=0)
void ClearContents()
const int ACCEPTABLE_QUANTITY_MAX
const int ACCEPTABLE_FOODSTAGE_MAX
int GetAgentTransferFilter()
bool IsDigesting()
static ref map< int, string > m_IDsToNames
static int CHECKSUM
const float DIGESTION_POINTS
class StomachItem DIGESTING_WATER
const int quantity_bit_offset
void DigestAgents(int agents, float quantity)
int GetDebugObject(array< ref Param > object_out)
const int DIGESTING_ENERGY
bool m_Digesting
void ProcessNutrients(float delta_time)
static void RegisterItem(string classname, int id)
int GetDigestingType()
static string GetClassnameFromID(int id)
float GetStomachVolume()
void SetAgentTransferFilter(int filter_agents)
ref array< ref StomachItem > m_StomachContents
static bool InitData()
static const bool m_InitData
const int id_bit_offset
void ~PlayerStomach()
float m_StomachVolume
static int GetIDFromClassname(string name)
int m_AgentTransferFilter
static ref map< string, int > m_NamesToIDs
void PlayerStomach(PlayerBase player)
static NutritionalProfile GetNutritionalProfile(ItemBase item, string classname="", int food_stage=0)
Definition Liquid.c:2
static NutritionalProfile GetNutritionalProfileByName(string class_name)
Definition Liquid.c:210
Definition EnMath.c:7
static const float DIGESTION_SPEED
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
int GetFoodStage()
void SetFoodStage(int food_stage)
float GetNutritions(float digestion_points, NutritionalProfile profile, out float water, out float energy, out float toxicity)
ref NutritionalProfile m_Profile
float GetAmount()
string GetClassName()
bool ProcessDigestion(float digestion_points, out float water, out float energy, out float toxicity, out float volume, out int agents, out float consumed_amount)
void StomachItem(string class_name, float amount, NutritionalProfile profile, int foodstage, int agents)
string m_ClassName
void AddAmount(float amount)
void AddAgents(int agents)
proto native CGame GetGame()
proto void Print(void var)
Prints content of variable to console/log.
array< string > TStringArray
Definition EnScript.c:666
static proto float Log2(float x)
Returns the binary (base-2) logarithm of x.
static proto float Pow(float v, float power)
Return power of v ^ power.
proto native volatile void Update()