recipebase.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. const int MAX_NUMBER_OF_INGREDIENTS = 2;
  2. const int MAXIMUM_RESULTS = 10;
  3. const float DEFAULT_SPAWN_DISTANCE = 0.6;
  4. class RecipeBase
  5. {
  6. string m_ItemsToCreate[MAXIMUM_RESULTS];
  7. ref array<string> m_Ingredients[MAX_NUMBER_OF_INGREDIENTS];
  8. ref array<string> m_SoundCategories[MAX_NUMBER_OF_INGREDIENTS];
  9. protected ref array<int> m_AnimationUIDs = new array<int>(); // used for overriding animation based on ingredient
  10. ItemBase m_Items[MAX_NUMBER_OF_INGREDIENTS];
  11. ItemBase m_IngredientsSorted[MAX_NUMBER_OF_INGREDIENTS]; //if the recipe is valid, this array will contain all ingredients sorted against the recipe ingredients
  12. ref array<ItemBase> m_IngredientsToBeDeleted = new array<ItemBase>;
  13. string m_Name;
  14. int m_ID;
  15. int m_NumberOfResults;
  16. int m_RecipeUID;
  17. float m_AnimationLength = 1;//animation length in relative time units
  18. float m_Specialty = 0;// value > 0 for roughness, value < 0 for precision
  19. bool m_IsInstaRecipe;//should this recipe be performed instantly without animation
  20. bool m_AnywhereInInventory;//is this recipe valid even when neither of the items is in hands
  21. float m_MinQuantityIngredient[MAX_NUMBER_OF_INGREDIENTS];
  22. float m_MaxQuantityIngredient[MAX_NUMBER_OF_INGREDIENTS];
  23. float m_MinDamageIngredient[MAX_NUMBER_OF_INGREDIENTS];
  24. float m_MaxDamageIngredient[MAX_NUMBER_OF_INGREDIENTS];
  25. bool m_IngredientUseSoftSkills[MAX_NUMBER_OF_INGREDIENTS];
  26. float m_IngredientAddHealth[MAX_NUMBER_OF_INGREDIENTS];
  27. float m_IngredientAddQuantity[MAX_NUMBER_OF_INGREDIENTS];
  28. float m_IngredientSetHealth[MAX_NUMBER_OF_INGREDIENTS];
  29. bool m_IngredientDestroy[MAX_NUMBER_OF_INGREDIENTS];
  30. bool m_ResultSetFullQuantity[MAXIMUM_RESULTS];
  31. float m_ResultSetQuantity[MAXIMUM_RESULTS];
  32. float m_ResultSetHealth[MAXIMUM_RESULTS];
  33. float m_ResultSpawnDistance[MAXIMUM_RESULTS];
  34. int m_ResultToInventory[MAXIMUM_RESULTS];
  35. int m_ResultInheritsHealth[MAXIMUM_RESULTS];
  36. int m_ResultInheritsColor[MAXIMUM_RESULTS];
  37. int m_ResultReplacesIngredient[MAXIMUM_RESULTS];
  38. bool m_ResultUseSoftSkills[MAXIMUM_RESULTS];
  39. void RecipeBase()
  40. {
  41. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  42. {
  43. m_Ingredients[i] = new array<string>;
  44. m_SoundCategories[i] = new array<string>;
  45. m_IngredientsSorted[i] = NULL;
  46. }
  47. for (i = 0; i < MAXIMUM_RESULTS; i++)
  48. {
  49. m_ResultSpawnDistance[i] = DEFAULT_SPAWN_DISTANCE;
  50. }
  51. m_NumberOfResults = 0;
  52. m_Name = "RecipeBase default name";
  53. m_RecipeUID = DayZPlayerConstants.CMD_ACTIONFB_CRAFTING;
  54. Init();
  55. }
  56. void Init();
  57. protected void SetAnimation (DayZPlayerConstants uid)
  58. {
  59. m_RecipeUID = uid;
  60. }
  61. float GetLengthInSecs()
  62. {
  63. return m_AnimationLength * CRAFTING_TIME_UNIT_SIZE;
  64. }
  65. float GetSpecialty()
  66. {
  67. return m_Specialty;
  68. }
  69. bool IsRecipeAnywhere()
  70. {
  71. return m_AnywhereInInventory;
  72. }
  73. bool IsRepeatable()
  74. {
  75. return false;
  76. }
  77. bool CheckIngredientMatch(ItemBase item1, ItemBase item2)
  78. {
  79. if (item1 == NULL || item2 == NULL) return false;
  80. m_Items[0] = item1;
  81. m_Items[1] = item2;
  82. bool found = false;
  83. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)//all ingredients
  84. {
  85. found = false;
  86. array<string> tempArray = m_Ingredients[i];
  87. for (int x = 0; x < tempArray.Count(); x++)//particular ingredient array
  88. {
  89. for (int z = 0; z < MAX_NUMBER_OF_INGREDIENTS; z++)
  90. {
  91. if (m_Items[z] != NULL)
  92. {
  93. ItemBase item = m_Items[z];
  94. if (tempArray.Get(x) == item.GetType() || GetGame().IsKindOf(item.GetType(),tempArray.Get(x)))
  95. {
  96. found = true;//we found a match
  97. //m_IngredientsSorted.Insert(item);
  98. m_IngredientsSorted[i] = item;
  99. m_Items[z] = NULL;
  100. }
  101. }
  102. if (found) break;//we found a match, no need to check the remaining ingredients
  103. }
  104. if (found) break;//we found a match, no need to check this m_Ingredient array
  105. }
  106. if (!found) return false;// no match within an m_Ingredient array, no reason to continue the search, recipe is invalid
  107. }
  108. if (found)
  109. {
  110. return true;
  111. }
  112. else
  113. {
  114. return false;
  115. }
  116. }
  117. void InsertIngredient(int index, string ingredient, DayZPlayerConstants uid = DayZPlayerConstants.CMD_ACTIONFB_CRAFTING)
  118. {
  119. InsertIngredientEx(index, ingredient, "", uid);
  120. }
  121. void InsertIngredientEx(int index, string ingredient, string soundCategory, DayZPlayerConstants uid = DayZPlayerConstants.CMD_ACTIONFB_CRAFTING)
  122. {
  123. array<string> ptr = m_Ingredients[index];
  124. ptr.Insert(ingredient);
  125. m_SoundCategories[index].Insert(soundCategory);
  126. if(index == 0)
  127. {
  128. m_AnimationUIDs.Insert(uid);
  129. }
  130. }
  131. void RemoveIngredient(int index, string ingredient)
  132. {
  133. array<string> ptr = m_Ingredients[index];
  134. for (int i = 0; i < ptr.Count(); i++)
  135. {
  136. if (ptr[i] == ingredient)
  137. {
  138. ptr.Remove(i);
  139. m_SoundCategories[index].Remove(i);
  140. return;
  141. }
  142. }
  143. }
  144. void AddResult(string item)
  145. {
  146. m_ItemsToCreate[m_NumberOfResults] = item;
  147. m_NumberOfResults++;
  148. }
  149. string GetName()
  150. {
  151. return m_Name;
  152. }
  153. bool IsInstaRecipe()
  154. {
  155. return m_IsInstaRecipe;
  156. }
  157. //spawns results in the world
  158. void SpawnItems(ItemBase ingredients[], PlayerBase player, array<ItemBase> spawned_objects)
  159. {
  160. spawned_objects.Clear();//just to make sure
  161. EntityAI object = NULL;
  162. for (int i = 0; i < m_NumberOfResults; i++)
  163. {
  164. string item_to_spawn = m_ItemsToCreate[i];
  165. if (m_ResultInheritsColor[i] != -1)
  166. {
  167. ItemBase item = ingredients[m_ResultInheritsColor[i]];
  168. string color = item.ConfigGetString("color");
  169. string new_class_name = m_ItemsToCreate[i] + color;
  170. item_to_spawn = new_class_name;
  171. }
  172. if (m_ResultToInventory[i] == -1)
  173. {
  174. Debug.Log(" = "+m_ResultToInventory[i].ToString(),"recipes");
  175. /*
  176. InventoryLocation inv_loc = new InventoryLocation;
  177. if (player.GetInventory().FindFirstFreeLocationForNewEntity(item_to_spawn, FindInventoryLocationType.ANY, inv_loc))
  178. {
  179. object = SpawnItemOnLocation(item_to_spawn, inv_loc, false);
  180. }
  181. */
  182. object = player.GetInventory().CreateInInventory(item_to_spawn);
  183. }
  184. else if (m_ResultToInventory[i] >= 0)
  185. {
  186. /*
  187. object = player.SpawnEntityOnGroundOnCursorDir(item_to_spawn, 0.5);
  188. ItemBase item_swap_with = ingredients[m_ResultToInventory[i]];
  189. player.SwapEntities(true, item_swap_with, EntityAI.Cast(object));
  190. */
  191. }
  192. //spawning in inventory failed, spawning on the ground instead.....
  193. if (!object)
  194. {
  195. object = player.SpawnEntityOnGroundRaycastDispersed(item_to_spawn,m_ResultSpawnDistance[i]);
  196. if (!object)
  197. Error("failed to spawn entity "+item_to_spawn+" , make sure the classname exists and item can be spawned");
  198. }
  199. spawned_objects.Insert(ItemBase.Cast(object));
  200. object = null;
  201. }
  202. }
  203. //applies final modifications to results
  204. void ApplyModificationsResults(ItemBase sorted[], array<ItemBase> results, ItemBase result, PlayerBase player)
  205. {
  206. float all_ingredients_health = 0;//this is used later in results
  207. float all_ingredients_health01 = 0;//combined damage % of ingredients
  208. int value_delta;
  209. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  210. {
  211. ItemBase ingrd = ItemBase.Cast(sorted[i]);
  212. all_ingredients_health += ingrd.GetHealth("", "");//accumulate health of all ingredients, used in results
  213. all_ingredients_health01 += ingrd.GetHealth01("", "");
  214. }
  215. //------------------- results ----------------------
  216. for (i = 0; i < m_NumberOfResults; i++)
  217. {
  218. ItemBase res = results.Get(i);
  219. if (!res)
  220. {
  221. continue;
  222. }
  223. if (res.IsItemBase())
  224. {
  225. value_delta = m_ResultSetQuantity[i];
  226. ItemBase resIb = ItemBase.Cast(res);
  227. if (!resIb.IsMagazine())//is not a magazine
  228. {
  229. if (m_ResultSetFullQuantity[i] == 1)//<------m_ResultSetFullQuantity
  230. {
  231. resIb.SetQuantityMax();
  232. }
  233. else if (value_delta != -1)//<------m_ResultSetQuantity
  234. {
  235. resIb.SetQuantity(value_delta);
  236. }
  237. }
  238. else//is magazine
  239. {
  240. Magazine mgzn = Magazine.Cast(resIb);
  241. if (m_ResultSetFullQuantity[i] == 1)//<------m_ResultSetFullQuantity
  242. {
  243. mgzn.ServerSetAmmoMax();
  244. }
  245. else if (value_delta != -1)//<------m_ResultSetQuantity
  246. {
  247. mgzn.ServerSetAmmoCount(value_delta);
  248. }
  249. }
  250. }
  251. if (m_ResultSetHealth[i] != -1)//<------m_ResultSetHealth
  252. {
  253. value_delta = m_ResultSetHealth[i];
  254. res.SetHealth("","",value_delta);
  255. }
  256. if (m_ResultInheritsHealth[i] != -1)//<------m_ResultInheritsHealth
  257. {
  258. if (m_ResultInheritsHealth[i] >= 0)
  259. {
  260. int ing_number = m_ResultInheritsHealth[i];
  261. ItemBase ing = sorted[ing_number];
  262. if (ing)
  263. {
  264. float ing_health01 = ing.GetHealth01("","");
  265. res.SetHealth("", "", ing_health01 * res.GetMaxHealth("",""));
  266. Debug.Log("Inheriting health from ingredient:"+m_ResultInheritsHealth[i].ToString(),"recipes");
  267. }
  268. }
  269. else if (m_ResultInheritsHealth[i] == -2)
  270. {
  271. float average_health01 = all_ingredients_health01 / MAX_NUMBER_OF_INGREDIENTS;
  272. res.SetHealth("", "", average_health01 * res.GetMaxHealth("",""));
  273. }
  274. }
  275. if (m_ResultReplacesIngredient[i] != -1)//<------ResultReplacesIngredient
  276. {
  277. if (m_ResultReplacesIngredient[i] > -1)
  278. {
  279. int ing_num = m_ResultReplacesIngredient[i];
  280. ItemBase ingr = sorted[ing_num];
  281. if (ingr)
  282. {
  283. MiscGameplayFunctions.TransferItemProperties(ingr, res);
  284. MiscGameplayFunctions.TransferInventory(ingr, res, player);
  285. }
  286. }
  287. }
  288. }
  289. }
  290. void DeleleIngredientsPass()
  291. {
  292. for (int i = 0; i < m_IngredientsToBeDeleted.Count(); i++)
  293. {
  294. ItemBase ingredient = m_IngredientsToBeDeleted.Get(i);
  295. ingredient.Delete();
  296. }
  297. m_IngredientsToBeDeleted.Clear();
  298. }
  299. //applies final modifications to ingredients
  300. void ApplyModificationsIngredients(ItemBase sorted[], PlayerBase player)
  301. {
  302. //---------------------- ingredients ----------------------
  303. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  304. {
  305. ItemBase ingredient = sorted[i];
  306. if (m_IngredientDestroy[i] == 1)//<------m_IngredientDestroy
  307. {
  308. if (ingredient) m_IngredientsToBeDeleted.Insert(ingredient);
  309. }
  310. else
  311. {
  312. if (m_IngredientAddHealth[i] != 0)//<------m_IngredientAddHealth
  313. {
  314. float health_delta = m_IngredientAddHealth[i];
  315. ingredient.AddHealth("","",health_delta);
  316. }
  317. else if (m_IngredientSetHealth[i] != -1)//<------m_IngredientSetHealth
  318. {
  319. float new_health = m_IngredientSetHealth[i];
  320. ingredient.SetHealth("","",new_health);
  321. }
  322. if (m_IngredientAddQuantity[i] != 0)//<------m_IngredientAddQuantity
  323. {
  324. float quantity_delta = m_IngredientAddQuantity[i];
  325. if (!ingredient.IsMagazine())
  326. {
  327. ItemBase obj = ingredient;
  328. bool isDestroyed = obj.AddQuantity(quantity_delta, true);
  329. if (isDestroyed)
  330. {
  331. continue;
  332. }
  333. }
  334. else
  335. {
  336. Magazine mag = Magazine.Cast(ingredient);
  337. int newQuantity = mag.GetAmmoCount() + quantity_delta;
  338. if (newQuantity <= 0)
  339. {
  340. if (mag) m_IngredientsToBeDeleted.Insert(mag);
  341. continue;
  342. }
  343. else
  344. {
  345. mag.ServerSetAmmoCount(newQuantity);
  346. }
  347. }
  348. }
  349. }
  350. }
  351. }
  352. //checks the recipe conditions
  353. bool CheckConditions(ItemBase sorted[])
  354. {
  355. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  356. {
  357. ItemBase ingredient = sorted[i];
  358. if (!ingredient.IsMagazine())
  359. {
  360. if (ingredient.GetQuantityMax() !=0 && m_MinQuantityIngredient[i] >= 0 && ingredient.GetQuantity() < m_MinQuantityIngredient[i])
  361. {
  362. //Debug.Log("Recipe condition check failing1: m_MinQuantityIngredient","recipes");
  363. return false;
  364. }
  365. if (m_MaxQuantityIngredient[i] >= 0 && ingredient.GetQuantity() > m_MaxQuantityIngredient[i])
  366. {
  367. //Debug.Log("Recipe condition check failing1: m_MaxQuantityIngredient","recipes");
  368. return false;
  369. }
  370. }
  371. else
  372. {
  373. Magazine mag1 = Magazine.Cast(ingredient);
  374. if (m_MinQuantityIngredient[i] >= 0 && mag1.GetAmmoCount() < m_MinQuantityIngredient[i])
  375. {
  376. //Debug.Log("Recipe condition check failing1: m_MinQuantityIngredient[0]","recipes");
  377. return false;
  378. }
  379. if (m_MaxQuantityIngredient[i] >= 0 && mag1.GetAmmoCount() > m_MaxQuantityIngredient[i])
  380. {
  381. //Debug.Log("Recipe condition check failing1: m_MaxQuantityIngredient[0]","recipes");
  382. return false;
  383. }
  384. }
  385. int dmg3 = ingredient.GetHealthLevel();
  386. if (m_MinDamageIngredient[i] >= 0 && ingredient.GetHealthLevel() < m_MinDamageIngredient[i])
  387. {
  388. int dmg = ingredient.GetHealthLevel();
  389. //Debug.Log("Recipe condition check failing1: m_MinDamageIngredient[0]","recipes");
  390. return false;
  391. }
  392. if (m_MaxDamageIngredient[i] >= 0 && ingredient.GetHealthLevel() > m_MaxDamageIngredient[i])
  393. {
  394. int dmg2 = ingredient.GetHealthLevel();
  395. //Debug.Log("Recipe condition check failing1: m_MaxDamageIngredient[0]","recipes");
  396. return false;
  397. }
  398. }
  399. return true;
  400. }
  401. //checks overall validity of this recipe
  402. bool CheckRecipe(ItemBase item1, ItemBase item2, PlayerBase player)
  403. {
  404. if (item1 == NULL || item2 == NULL)
  405. {
  406. Error("recipe invalid, at least one of the ingredients is NULL");
  407. return false;
  408. }
  409. ItemBase item_in_hand = player.GetItemInHands();
  410. if (!IsRecipeAnywhere() && (item1 != item_in_hand && item2 != item_in_hand))
  411. {
  412. return false;
  413. }
  414. m_IngredientsSorted[0] = item1;
  415. m_IngredientsSorted[1] = item2;
  416. if (CanDo(m_IngredientsSorted, player) && CheckConditions(m_IngredientsSorted))
  417. {
  418. return true;
  419. }
  420. return false;
  421. }
  422. protected void CheckIngredientAnimOverride()
  423. {
  424. array<string> tempArray = m_Ingredients[0];
  425. for ( int i; i < m_AnimationUIDs.Count(); i++ )
  426. {
  427. if (m_IngredientsSorted[0].ClassName() == tempArray[i] || m_IngredientsSorted[1].ClassName() == tempArray[i])
  428. SetAnimation(m_AnimationUIDs[i]);
  429. }
  430. }
  431. void OnSelectedRecipe(ItemBase item1, ItemBase item2, PlayerBase player)
  432. {
  433. if (item1 == NULL || item2 == NULL)
  434. {
  435. Error("CheckRecipe: recipe invalid, at least one of the ingredients is NULL");
  436. //Debug.Log("recipe invalid, at least one of the ingredients is NULL","recipes");
  437. return;
  438. }
  439. OnSelected(item1,item2,player);
  440. }
  441. void OnSelected(ItemBase item1, ItemBase item2, PlayerBase player)
  442. {
  443. }
  444. //performs this recipe
  445. void PerformRecipe(ItemBase item1, ItemBase item2, PlayerBase player)
  446. {
  447. if (item1 == NULL || item2 == NULL)
  448. {
  449. Error("PerformRecipe: recipe invalid, at least one of the ingredients is NULL");
  450. Debug.Log("PerformRecipe: at least one of the ingredients is NULL","recipes");
  451. }
  452. if (CheckRecipe(item1,item2,player))
  453. {
  454. array<ItemBase> spawned_objects = new array<ItemBase>;
  455. SpawnItems(m_IngredientsSorted, player,spawned_objects);
  456. ApplyModificationsResults(m_IngredientsSorted, spawned_objects, NULL, player);
  457. ApplyModificationsIngredients(m_IngredientsSorted, player);
  458. Do(m_IngredientsSorted, player, spawned_objects, m_Specialty);
  459. DeleleIngredientsPass();
  460. }
  461. else
  462. {
  463. Debug.Log("CheckRecipe failed on server","recipes");
  464. }
  465. }
  466. void ApplySoftSkillsSpecialty(PlayerBase player)
  467. {
  468. }
  469. bool CanDo(ItemBase ingredients[], PlayerBase player)
  470. {
  471. //Debug.Log("Called Can Do on a recipe id:" + m_ID.ToString(),"recipes");
  472. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  473. {
  474. if (ingredients[i].GetInventory() && ingredients[i].GetInventory().AttachmentCount() > 0)
  475. return false;
  476. }
  477. return true;
  478. }
  479. void Do(ItemBase ingredients[], PlayerBase player, array<ItemBase> results, float specialty_weight)
  480. {
  481. //Debug.Log("Called Do on a recipe id:" + m_ID.ToString(),"recipes");
  482. }
  483. int GetID()
  484. {
  485. return m_ID;
  486. }
  487. void SetID(int id)
  488. {
  489. m_ID = id;
  490. }
  491. void GetAllItems(array<string> items)
  492. {
  493. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  494. {
  495. array<string> ptr = m_Ingredients[i];
  496. for (int x = 0; x < ptr.Count(); x++)
  497. {
  498. items.Insert(ptr.Get(x));
  499. }
  500. }
  501. }
  502. string GetSoundCategory(int ingredientIndex, ItemBase item)
  503. {
  504. string itemType = item.GetType();
  505. array<string> ptr = m_Ingredients[ingredientIndex];
  506. for (int x = 0; x < ptr.Count(); x++)
  507. {
  508. if (GetGame().IsKindOf(itemType, ptr.Get(x)))
  509. {
  510. return m_SoundCategories[ingredientIndex].Get(x);
  511. }
  512. }
  513. return "";
  514. }
  515. bool IsItemInRecipe(string item)
  516. {
  517. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  518. {
  519. array<string> ptr = m_Ingredients[i];
  520. for (int x = 0; x < ptr.Count(); x++)
  521. {
  522. if (ptr.Get(x) == item) return true;
  523. }
  524. }
  525. return false;
  526. }
  527. //! returns a mask which marks ingredient positions for a given item in this recipe(for example mask of value 3 [....000011] means this item is both ingredient 1 and 2 in this recipe[from right to left])
  528. int GetIngredientMaskForItem(string item)
  529. {
  530. int mask = 0;
  531. for (int i = 0; i < MAX_NUMBER_OF_INGREDIENTS; i++)
  532. {
  533. array<string> ptr = m_Ingredients[i];
  534. for (int x = 0; x < ptr.Count(); x++)
  535. {
  536. if (ptr.Get(x) == item)
  537. {
  538. mask = ((int)Math.Pow(2, i)) | mask;
  539. }
  540. }
  541. }
  542. return mask;
  543. }
  544. int GetAnimationCommandUID()
  545. {
  546. if (m_AnimationUIDs.Count() > 0)
  547. CheckIngredientAnimOverride();
  548. return m_RecipeUID;
  549. }
  550. }