Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
pluginrecipesmanager.c
Go to the documentation of this file.
2 {
6 }
7 
8 const float ACCEPTABLE_DISTANCE = 5;
9 
10 const int SANITY_CHECK_ACCEPTABLE_RESULT = ERecipeSanityCheck.NOT_OWNED_BY_ANOTHER_LIVE_PLAYER | ERecipeSanityCheck.CLOSE_ENOUGH;
11 
12 class PluginRecipesManager extends PluginRecipesManagerBase
13 {
14  static ref map<string,ref CacheObject > m_RecipeCache = new map<string,ref CacheObject >;
15  static ref map<typename, bool> m_RecipesInitializedItem = new ref map<typename, bool>;
16 
17 
18  ref Timer m_TestTimer;
19  const int MAX_NUMBER_OF_RECIPES = GetMaxNumberOfRecipes();
20  const int MAX_CONCURENT_RECIPES = 128;
21  const int MAX_INGREDIENTS = 5;
22 
23  int m_RegRecipeIndex;
24  int m_ResolvedRecipes[MAX_CONCURENT_RECIPES];
25 
26  bool m_EnableDebugCrafting = false;
27  ItemBase m_Ingredients[MAX_INGREDIENTS];
28  int m_IngredientBitMask[MAX_INGREDIENTS];
29  int m_IngredientBitMaskSize[MAX_INGREDIENTS];
30 
31  int m_BitsResults[MAX_INGREDIENTS];
32 
33  ItemBase m_ingredient1[MAX_CONCURENT_RECIPES];
34  ItemBase m_ingredient2[MAX_CONCURENT_RECIPES];
35  ItemBase m_ingredient3[MAX_CONCURENT_RECIPES];
36 
37  ItemBase m_sortedIngredients[MAX_NUMBER_OF_INGREDIENTS];
38 
39  ref array<int> m_RecipesMatched = new array<int>;
40  ref array<string> m_CachedItems = new array<string>;
41 
42  ref array<ref RecipeBase> m_RecipeList = new array<ref RecipeBase>;//all recipes
43  static ref map<string, int> m_RecipeNamesList = new map<string, int>;//all recipes
44 
45  ref Timer myTimer1;
46 
47  static int GetMaxNumberOfRecipes()
48  {
49  return 2048;
50  }
51 
52  void PluginRecipesManager()
53  {
54 
55  CreateAllRecipes();
56  GenerateRecipeCache();
57 
58  myTimer1 = new Timer();
59  }
60 
61  void ~PluginRecipesManager()
62  {
63  }
64 
65 
66  bool IsEnableDebugCrafting()
67  {
68  return m_EnableDebugCrafting;
69  }
70 
71  void SetEnableDebugCrafting(bool enable)
72  {
73  m_EnableDebugCrafting = enable;
74  }
75 
76  string GetRecipeName(int recipe_id)
77  {
78  if (m_RecipeList[recipe_id])
79  return m_RecipeList[recipe_id].GetName();
80 
81  return "";
82  }
83 
84 
85  //will fill the map 'ids' with valid recipes for the 'item1' and 'item2' items, where the key is the recipe ID, and the value is the recipe name
86  int GetValidRecipes(ItemBase item1, ItemBase item2, array<int> ids, PlayerBase player)
87  {
88  if ( item1 == NULL || item2 == NULL )
89  {
90  if (ids) ids.Clear();
91  return 0;
92  }
93 
94  if ( ( item1.GetInventory().IsAttachment() && item1.GetHierarchyParent().DisassembleOnLastDetach() ) || ( item2.GetInventory().IsAttachment() && item2.GetHierarchyParent().DisassembleOnLastDetach() ) )
95  {
96  if (ids) ids.Clear();
97  return 0;
98  }
99  m_Ingredients[0] = item1;
100  m_Ingredients[1] = item2;
101 
102  return GetValidRecipesProper(2,m_Ingredients, ids, player);
103  }
104 
105  int GetValidRecipesProper(int num_of_items, ItemBase items[], array<int> ids, PlayerBase player)
106  {
107  if (ids) ids.Clear();
108  GetRecipeIntersection(num_of_items,items);
109  int numOfRecipes = SortIngredients(num_of_items,items,m_ResolvedRecipes);
110  //will return number of cached recipes for the 2 items being considered,
111  //and save their indexes in m_ResolvedRecipes, please note the m_ResolvedRecipes is a static array,
112  //and does not clear up with each query, so the number of recipes returned is critical to make sure we don't accidentally
113  //mix in some other indexes from previous queries(and obviously loop only as far as we have to)
114  //this also saves the ingredients in the correct assignment as ingredient 1/2 into m_ingredient1/m_ingredient2 arrays, these 3 arrays
115  //therefore provide you with information per each index with: recipeid,ingredient1,ingredient2
116  if ( numOfRecipes == 0 ) return 0;
117  int found = 0;
118  RecipeBase p_recipe = NULL;
119  for (int i = 0; i < numOfRecipes; i++)
120  {
121  p_recipe = m_RecipeList[m_ResolvedRecipes[i]];
122 
123  if ( p_recipe.CheckRecipe(m_ingredient1[i],m_ingredient2[i], player) == true )
124  {
125  if (ids) ids.Insert( p_recipe.GetID() );
126  found++;
127  }
128  }
129  return found;
130  }
131 
132 
133  float GetRecipeLengthInSecs(int recipe_id)
134  {
135  if ( m_RecipeList[recipe_id] ) return m_RecipeList[recipe_id].GetLengthInSecs();
136  return 0;
137  }
138 
139  float GetRecipeSpecialty(int recipe_id)
140  {
141  if ( m_RecipeList[recipe_id] ) return m_RecipeList[recipe_id].GetSpecialty();
142  return 0;
143  }
144 
145  bool GetIsInstaRecipe(int recipe_id)
146  {
147  if ( m_RecipeList[recipe_id] ) return m_RecipeList[recipe_id].IsInstaRecipe();
148  else return false;
149  }
150 
151  override void OnInit()
152  {
153  super.OnInit();
154  //ReadCacheFromFile(PATH_CACHE_FILE);//read the cache from a file
155  //GenerateHumanReadableRecipeList();
156  }
157 
158 
159  void CallbackGenerateCache()
160  {
161  Debug.Log("CallbackGenerateCache","recipes");
162  GenerateRecipeCache();
163  //SaveCacheToFile(PATH_CACHE_FILE);//generate the cache and save it to a file
164  //ReadCacheFromFile(PATH_CACHE_FILE);
165  }
166 
167  protected void GenerateRecipeCache()
168  {
169  GetGame().ProfilerStart("m_RecipeCache");
170 
171  //m_CacheBasesMap.Clear();
172  m_CachedItems.Clear();
173  PluginRecipesManager.m_RecipeCache.Clear();
174 
175  TStringArray all_config_paths = new TStringArray;
176 
177  all_config_paths.Insert(CFG_VEHICLESPATH);
178  all_config_paths.Insert(CFG_WEAPONSPATH);
179  all_config_paths.Insert(CFG_MAGAZINESPATH);
180  //Debug.Log("Got here 0","caching");
181  string config_path;
182  string child_name;
183  int scope;
184  TStringArray full_path = new TStringArray;
185  WalkRecipes();
186  for (int i = 0; i < all_config_paths.Count(); i++)
187  {
188  config_path = all_config_paths.Get(i);
189  int children_count = GetGame().ConfigGetChildrenCount(config_path);
190 
191  for (int x = 0; x < children_count; x++)
192  {
193  GetGame().ConfigGetChildName(config_path, x, child_name);
194  scope = GetGame().ConfigGetInt( config_path + " " + child_name + " scope" );
195 
196  if ( scope == 2 )
197  {
198  GetGame().ConfigGetFullPath(config_path +" "+ child_name,/*out*/ full_path);
199  MatchItems(full_path);
200  }
201  }
202  }
203  GetGame().ProfilerStop("m_RecipeCache");
204  }
205 
206  void WalkRecipes()
207  {
208  //Print("------------- WalkRecipes --------------");
209  for (int c = 0; c < m_RecipeList.Count(); c++)
210  {
211  RecipeBase recipe = m_RecipeList.Get(c);
212  if (recipe)
213  {
214  //Print(recipe.ClassName());
215  int recipe_id = recipe.GetID();
216  for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
217  {
218  array<string> list = recipe.m_Ingredients[i];
219 
220  for (int x = 0; x < list.Count(); x++)
221  {
222  string ingredient = list.Get(x);
223  int mask = Math.Pow(2,i);
224  CacheObject co = m_RecipeCache.Get(ingredient);
225 
226  if (!co)
227  {
228  co = new CacheObject;
229  m_RecipeCache.Insert(ingredient,co);
230  }
231  co.AddRecipe(recipe_id, mask);
232  }
233  }
234  }
235  }
236  }
237 
238 
239  // moved outside method to speed things up
240  ref array<int> m_RcpsArray;
241  string m_BaseName;
242  int m_RecipeID;
243  int item_mask;
244  int m_BaseMask;
245  string m_ItemName;
246  ref CacheObject m_CoItem;
247  ref CacheObject m_CoBase;
248 
249  //this will take the item class name and resolve it against all processed recipes
250  protected void MatchItems(TStringArray full_path)
251  {
252  m_ItemName = full_path.Get(0);
253  m_CoItem = m_RecipeCache.Get(m_ItemName);
254  //Print(m_ItemName);
255  if ( !m_CoItem )
256  {
257  m_CoItem = new CacheObject;
258  m_RecipeCache.Insert(m_ItemName,m_CoItem);
259  }
260  for (int i = 1; i < full_path.Count(); i++)
261  {
262  m_BaseName = full_path.Get(i);
263  m_CoBase = m_RecipeCache.Get(m_BaseName);
264  if ( m_CoBase )//resolve new base classes
265  {
266  m_RcpsArray = m_RecipeCache.Get(m_BaseName).GetRecipes();
267 
268  for ( int x = 0; x < m_RcpsArray.Count(); x++ )//base recipes
269  {
270  m_RecipeID = m_RcpsArray.Get(x);
271 
272  //item_mask = m_CoItem.GetMaskByRecipeID(m_RecipeID);
273  m_BaseMask = m_CoBase.GetMaskByRecipeID(m_RecipeID);
274 
275  m_CoItem.AddRecipe(m_RecipeID,m_BaseMask);
276  }
277  }
278  }
279 
280 
281  }
282 
283  void PerformRecipeServer(int id, ItemBase item_a,ItemBase item_b ,PlayerBase player)
284  {
285  m_Ingredients[0] = item_a;
286  m_Ingredients[1] = item_b;
287 
288  if ( !item_a || !item_b )
289  {
290  Error("PerformRecipeServer - one of the items null !!");
291  return;
292  }
293 
294  SortIngredientsInRecipe(id, 2,m_Ingredients, m_sortedIngredients);
295 
296  bool is_recipe_valid = CheckRecipe(id,m_sortedIngredients[0],m_sortedIngredients[1],player);
297  bool passed_sanity_check = RecipeSanityCheck(2,m_sortedIngredients,player);
298 
299  if ( !is_recipe_valid )
300  {
301  Error("PerformRecipeServer - recipe not valid !!");
302  return;
303  }
304  if ( !passed_sanity_check )
305  {
306  Error("PerformRecipeServer - recipe failed to pass sanity check !!");
307  return;
308  }
309  RecipeBase ptrRecipe = m_RecipeList[id];
310  ptrRecipe.PerformRecipe(m_sortedIngredients[0],m_sortedIngredients[1],player);
311  //player.RequestCraftingDisable();
312 
313  }
314 
315  void GenerateHumanReadableRecipeList()
316  {
317  FileHandle file = OpenFile("$profile:RecipeDump.txt", FileMode.WRITE);
318  if ( file == 0 )
319  {
320  //error message
321  PrintString("failed to open file RecipeDump");
322  return;
323  }
324  array<int> recipes = new array<int>;
325  for (int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
326  {
327  string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
328  CacheObject value = PluginRecipesManager.m_RecipeCache.GetElement(i);
329 
330  string line = key;
331  recipes.Clear();
332  recipes.InsertAll( value.GetRecipes() );
333 
334  //PrintString("Item: " + key);
335 
336  for (int x = 0; x < recipes.Count(); x++)
337  {
338  int recipe_id = recipes.Get(x);
339  string recipe_name = GetRecipeName(recipe_id);
340  line += "," +recipe_name;
341  }
342  FPrintln(file, line);
343  }
344  CloseFile(file);
345  }
346 
347  array<RecipeBase> GetRecipesForItem(string itemName)
348  {
349  CacheObject co = PluginRecipesManager.m_RecipeCache.Get(itemName);
350  array<int> ids = co.GetRecipes();
351 
352  array<RecipeBase> recipes = new array<RecipeBase>();
353  foreach (int recipeID : ids)
354  {
355  recipes.Insert(m_RecipeList[recipeID]);
356  }
357 
358  return recipes;
359  }
360 
361  protected bool RecipeSanityCheck(int num_of_ingredients, InventoryItemBase items[], PlayerBase player)
362  {
363  int check_results[MAX_INGREDIENTS];
364 
365  for (int i = 0; i < num_of_ingredients;i++)
366  {
367  ItemBase item = items[i];
368  Man item_owner_player = item.GetHierarchyRootPlayer();
369  vector item_pos = item.GetPosition();
370  vector player_pos = player.GetPosition();
371 
372  if (item_owner_player == player)
373  {
374  check_results[i] = check_results[i] | ERecipeSanityCheck.IS_IN_PLAYER_INVENTORY;
375  }
376 
377  if ( item_owner_player == NULL || item_owner_player == player || !item_owner_player.IsAlive() )
378  {
379  check_results[i] = check_results[i] | ERecipeSanityCheck.NOT_OWNED_BY_ANOTHER_LIVE_PLAYER;
380  }
381 
382  if ( vector.Distance(item_pos, player_pos ) < ACCEPTABLE_DISTANCE )
383  {
384  check_results[i] = check_results[i] | ERecipeSanityCheck.CLOSE_ENOUGH;
385  }
386  }
387  for (i = 0; i < num_of_ingredients;i++)
388  {
389  if ( !((check_results[i] & SANITY_CHECK_ACCEPTABLE_RESULT) == SANITY_CHECK_ACCEPTABLE_RESULT))
390  {
391  return false;
392  }
393  }
394  return true;
395  }
396 
397  override protected void RegisterRecipe(RecipeBase recipe)
398  {
399 
400  if ( m_RegRecipeIndex >= MAX_NUMBER_OF_RECIPES )
401  {
402  Error("Exceeded max. number of recipes, max set to: "+MAX_NUMBER_OF_RECIPES.ToString());
403  }
404 
405  m_RegRecipeIndex = m_RecipeList.Insert(recipe);
406  recipe.SetID(m_RegRecipeIndex);
407  m_RecipeNamesList.Insert(recipe.ClassName(), m_RegRecipeIndex);
408  //Print("RegisterRecipe: " +recipe.ClassName() + ", "+ m_RegRecipeIndex.ToString());
409  }
410 
411  override protected void UnregisterRecipe(string clasname)
412  {
413  int recipe_id = RecipeIDFromClassname(clasname);
414  //Print("UnregisterRecipe: " + recipe_id.ToString());
415  if (recipe_id != -1)
416  {
417  m_RecipeNamesList.Remove(clasname);
418  //Print(m_RecipeList[recipe_id]);
419  m_RecipeList[recipe_id] = null;
420  //Print(m_RecipeList[recipe_id]);
421  }
422  }
423 
424  static int RecipeIDFromClassname(string classname)
425  {
426  if (m_RecipeNamesList.Contains(classname))
427  return m_RecipeNamesList.Get(classname);
428  return -1;
429  }
430 
431  protected bool CheckRecipe(int id, ItemBase item1, ItemBase item2, PlayerBase player)//requires ordered items
432  {
433  RecipeBase p_recipe = m_RecipeList[id];
434  return p_recipe.CheckRecipe(item1,item2, player);
435  }
436 
437  protected void PrintCache()
438  {
439  for (int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
440  {
441  string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
442  CacheObject co = PluginRecipesManager.m_RecipeCache.GetElement(i);
443 
444  PrintString("Item: " + key);
445  co.DebugPrint();
446  PrintString("----------------");
447  }
448  }
450  protected bool SortIngredientsInRecipe(int id, int num_of_ingredients, ItemBase ingredients_unsorted[], ItemBase ingredients_sorted[] )
451  {
452  ClearResults();
453 
454  for (int i = 0; i < num_of_ingredients; i++)
455  {
456  CacheObject co_item = PluginRecipesManager.m_RecipeCache.Get( ingredients_unsorted[i].GetType() );
457  m_IngredientBitMask[i] = co_item.GetMaskByRecipeID(id);
458  m_IngredientBitMaskSize[i] = co_item.GetBitCountByRecipeID(id);
459  }
460 
461  bool result = ResolveIngredients(num_of_ingredients);
462 
463  if (result)
464  {
465  for (i = 0; i < num_of_ingredients; i++)
466  {
467  int index = Math.Log2( m_BitsResults[i]);
468  ingredients_sorted[index] = ingredients_unsorted[ i ];
469  }
470  }
471  //PrintResultMasks(num_of_ingredients);
472  return result;
473  }
474 
475  protected void ClearResults()
476  {
477  for (int i = 0; i < MAX_INGREDIENTS; i++)
478  {
479  m_BitsResults[i] = 0;
480  }
481 
482  }
483 
484  protected bool ResolveIngredients(int num_of_ingredients, int passes = 0)
485  {
486  int rightmost_bit;
487  int smallest = 99999;
488  int smallest_index = 0;
489 
490  for (int i = 0; i < num_of_ingredients; i++)
491  {
492  int count = m_IngredientBitMaskSize[i];
493  if ( count != 0 && count < smallest)
494  {
495  smallest = m_IngredientBitMaskSize[i];
496  smallest_index = i;
497  }
498  }
499 
500  rightmost_bit = m_IngredientBitMask[smallest_index] & (-m_IngredientBitMask[smallest_index]);
501  m_BitsResults[smallest_index] = m_BitsResults[smallest_index] | rightmost_bit;
502 
503  for (int x = 0; x < num_of_ingredients; x++)
504  {
505  m_IngredientBitMask[x] = ~rightmost_bit & m_IngredientBitMask[x];
506  m_IngredientBitMask[smallest_index] = 0;
507  m_IngredientBitMaskSize[smallest_index] = 0;
508  }
509 
510  // check validity
511  int check_sum_vertical = 0;
512 
513  for (int z = 0; z < num_of_ingredients; z++)
514  {
515  check_sum_vertical = check_sum_vertical | m_IngredientBitMask[z];//vertical sum
516  check_sum_vertical = check_sum_vertical | m_BitsResults[z];//vertical sum
517  if ((m_IngredientBitMask[z] | m_BitsResults[z]) == 0)
518  {
519  return false;//horizontal check
520  }
521  }
522 
523  if ( check_sum_vertical != (Math.Pow(2, num_of_ingredients) - 1)) return false;//vertical check
524 
525  passes++;
526 
527  if (passes < num_of_ingredients)
528  {
529  if ( !ResolveIngredients(num_of_ingredients, passes) ) return false;
530  }
531  return true;
532  }
533 
534 
535  protected void PrintResultMasks(int num)
536  {
537  for (int i = 0; i < num; i++)
538  {
539  Debug.Log("results mask("+i.ToString()+") = " +m_BitsResults[i].ToString() );
540  }
541  }
542 
544  protected int GetRecipeIntersection(int num_of_ingredients, ItemBase items[])
545  {
546  int count = 0;
547  int smallest = 9999;
548  int smallest_index = 0;
549  m_RecipesMatched.Clear();
550 
551  /*
552  m_Ingredients[0] = item_a;
553  m_Ingredients[1] = item_b;
554  */
555  //find the item with smallest number of recipes
556  CacheObject co_least_recipes;
557 
558  for (int i = 0; i < num_of_ingredients; i++)
559  {
560  CacheObject cobject = PluginRecipesManager.m_RecipeCache.Get( items[i].GetType() );
561  if (!cobject)
562  {
563  return 0;
564  }
565  if (cobject.GetNumberOfRecipes() < smallest)
566  {
567  smallest = cobject.GetNumberOfRecipes();
568  smallest_index = i;
569  co_least_recipes = cobject;
570  }
571  }
572 
573  //look for matches
574  array<int> recipes = co_least_recipes.GetRecipes();
575  for (int x = 0; x < recipes.Count(); x++)
576  {
577  int id = recipes.Get(x);
578  for (int z = 0; z < num_of_ingredients; z++)
579  {
580  if ( z!= smallest_index)
581  {
582  CacheObject cobject2 = PluginRecipesManager.m_RecipeCache.Get( items[z].GetType() );
583  if ( cobject2.IsContainRecipe(id) )
584  {
585  m_RecipesMatched.Insert(id);
586  count++;
587  }
588  }
589  }
590  }
591  return count;
592  }
593 
594  protected int SortIngredients(int num_of_ingredients, ItemBase items_unsorted[], int resolved_recipes[])
595  {
596  int count = 0;
597  for (int i = 0; i < m_RecipesMatched.Count() && i < MAX_CONCURENT_RECIPES; i++)
598  {
599  int recipe_id = m_RecipesMatched.Get(i);
600 
601  if (SortIngredientsInRecipe(recipe_id, num_of_ingredients, items_unsorted, m_sortedIngredients))//...and now we need to determine which item will be which ingredient number
602  {
603  resolved_recipes[count] = recipe_id;
604  m_ingredient1[count] = m_sortedIngredients[0];
605  m_ingredient2[count] = m_sortedIngredients[1];
606  //m_ingredient3[count] = m_sortedIngredients[2];
607  count++;
608  }
609  }
610  return count;
611  }
612 
613 
614  protected void CreateAllRecipes()
615  {
617  }
618 
619 
620  string GetSoundCategory(int recipeID, ItemBase item1, ItemBase item2)
621  {
622  ItemBase unsorted[2];
623  ItemBase sorted[2];
624 
625  unsorted[0] = item1;
626  unsorted[1] = item2;
627 
628  SortIngredientsInRecipe(recipeID, 2,unsorted, sorted);
629 
630  RecipeBase recipe = m_RecipeList[recipeID];
631  string soundCat = recipe.GetSoundCategory(0,sorted[0]);
632 
633  if (!soundCat)
634  {
635  soundCat = recipe.GetSoundCategory(1,sorted[1]);
636  }
637 
638  return soundCat;
639  }
640 
641 
642 
643 }
ItemBase
Definition: inventoryitem.c:730
RegisterRecipies
void RegisterRecipies()
Please do not delete commented recipes, they are usually commented out for a reason.
Definition: pluginrecipesmanagerbase.c:14
FPrintln
proto void FPrintln(FileHandle file, void var)
Write to file and add new line.
GetGame
proto native CGame GetGame()
CloseFile
proto void CloseFile(FileHandle file)
Close the File.
Error
void Error(string err)
Messagebox with error message.
Definition: endebug.c:90
OpenFile
proto FileHandle OpenFile(string name, FileMode mode)
Opens File.
ACCEPTABLE_DISTANCE
enum ERecipeSanityCheck ACCEPTABLE_DISTANCE
IS_IN_PLAYER_INVENTORY
@ IS_IN_PLAYER_INVENTORY
Definition: pluginrecipesmanager.c:3
m_RecipeID
WorldCraftActionReciveData m_RecipeID
TStringArray
array< string > TStringArray
Definition: enscript.c:685
SANITY_CHECK_ACCEPTABLE_RESULT
const int SANITY_CHECK_ACCEPTABLE_RESULT
Definition: pluginrecipesmanager.c:10
RegisterRecipe
class PokeHolesBarrel extends RecipeBase RegisterRecipe
RecipeBase
Definition: recipebase.c:4
FileMode
FileMode
Definition: ensystem.c:382
ERecipeSanityCheck
ERecipeSanityCheck
Definition: pluginrecipesmanager.c:1
m_ItemName
protected string m_ItemName
Definition: radialquickbarmenu.c:15
GetSoundCategory
string GetSoundCategory(ActionData action_data)
Definition: actionbase.c:989
PlayerBase
Definition: playerbaseclient.c:1
map
map
Definition: controlsxboxnew.c:3
vector
Definition: enconvert.c:105
CFG_VEHICLESPATH
const string CFG_VEHICLESPATH
Definition: constants.c:209
myTimer1
ref Timer myTimer1
Definition: pluginitemdiagnostic.c:46
PrintString
void PrintString(string s)
Helper for printing out string expression. Example: PrintString("Hello " + var);.
Definition: enscript.c:345
MAX_NUMBER_OF_INGREDIENTS
const int MAX_NUMBER_OF_INGREDIENTS
Definition: recipebase.c:1
CFG_MAGAZINESPATH
const string CFG_MAGAZINESPATH
Definition: constants.c:211
CFG_WEAPONSPATH
const string CFG_WEAPONSPATH
Definition: constants.c:210
CLOSE_ENOUGH
@ CLOSE_ENOUGH
Definition: pluginrecipesmanager.c:5
UnregisterRecipe
protected void UnregisterRecipe(string clasname)
array
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Definition: isboxcollidinggeometryproxyclasses.c:27
PluginRecipesManagerBase
Definition: pluginrecipesmanager.c:12
x
Icon x
NOT_OWNED_BY_ANOTHER_LIVE_PLAYER
@ NOT_OWNED_BY_ANOTHER_LIVE_PLAYER
Definition: pluginrecipesmanager.c:4
CacheObject
void CacheObject()
Definition: cacheobject.c:35
Debug
Definition: debug.c:13
FileHandle
int[] FileHandle
Definition: ensystem.c:390
OnInit
void OnInit()
Definition: aibehaviour.c:49
Timer
Definition: dayzplayerimplement.c:62
Math
Definition: enmath.c:6
GetType
override int GetType()
Definition: huddebugwincharagents.c:49