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;
24 int m_ResolvedRecipes[MAX_CONCURENT_RECIPES];
26 bool m_EnableDebugCrafting =
false;
27 ItemBase m_Ingredients[MAX_INGREDIENTS];
28 int m_IngredientBitMask[MAX_INGREDIENTS];
29 int m_IngredientBitMaskSize[MAX_INGREDIENTS];
31 int m_BitsResults[MAX_INGREDIENTS];
33 ItemBase m_ingredient1[MAX_CONCURENT_RECIPES];
34 ItemBase m_ingredient2[MAX_CONCURENT_RECIPES];
35 ItemBase m_ingredient3[MAX_CONCURENT_RECIPES];
47 static int GetMaxNumberOfRecipes()
52 void PluginRecipesManager()
56 GenerateRecipeCache();
61 void ~PluginRecipesManager()
66 bool IsEnableDebugCrafting()
68 return m_EnableDebugCrafting;
71 void SetEnableDebugCrafting(
bool enable)
73 m_EnableDebugCrafting = enable;
76 string GetRecipeName(
int recipe_id)
78 if (m_RecipeList[recipe_id])
79 return m_RecipeList[recipe_id].GetName();
88 if ( item1 == NULL || item2 == NULL )
94 if ( ( item1.GetInventory().IsAttachment() && item1.GetHierarchyParent().DisassembleOnLastDetach() ) || ( item2.GetInventory().IsAttachment() && item2.GetHierarchyParent().DisassembleOnLastDetach() ) )
99 m_Ingredients[0] = item1;
100 m_Ingredients[1] = item2;
102 return GetValidRecipesProper(2,m_Ingredients, ids, player);
107 if (ids) ids.Clear();
108 GetRecipeIntersection(num_of_items,items);
109 int numOfRecipes = SortIngredients(num_of_items,items,m_ResolvedRecipes);
116 if ( numOfRecipes == 0 )
return 0;
119 for (
int i = 0; i < numOfRecipes; i++)
121 p_recipe = m_RecipeList[m_ResolvedRecipes[i]];
123 if ( p_recipe.CheckRecipe(m_ingredient1[i],m_ingredient2[i], player) ==
true )
125 if (ids) ids.Insert( p_recipe.GetID() );
133 float GetRecipeLengthInSecs(
int recipe_id)
135 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].GetLengthInSecs();
139 float GetRecipeSpecialty(
int recipe_id)
141 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].GetSpecialty();
145 bool GetIsInstaRecipe(
int recipe_id)
147 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].IsInstaRecipe();
159 void CallbackGenerateCache()
161 Debug.Log(
"CallbackGenerateCache",
"recipes");
162 GenerateRecipeCache();
167 protected void GenerateRecipeCache()
169 GetGame().ProfilerStart(
"m_RecipeCache");
172 m_CachedItems.Clear();
173 PluginRecipesManager.m_RecipeCache.Clear();
186 for (
int i = 0; i < all_config_paths.Count(); i++)
188 config_path = all_config_paths.Get(i);
189 int children_count =
GetGame().ConfigGetChildrenCount(config_path);
191 for (
int x = 0;
x < children_count;
x++)
193 GetGame().ConfigGetChildName(config_path,
x, child_name);
194 scope =
GetGame().ConfigGetInt( config_path +
" " + child_name +
" scope" );
198 GetGame().ConfigGetFullPath(config_path +
" "+ child_name, full_path);
199 MatchItems(full_path);
203 GetGame().ProfilerStop(
"m_RecipeCache");
209 for (
int c = 0; c < m_RecipeList.Count(); c++)
215 int recipe_id = recipe.GetID();
220 for (
int x = 0;
x < list.Count();
x++)
222 string ingredient = list.Get(
x);
223 int mask =
Math.Pow(2,i);
229 m_RecipeCache.Insert(ingredient,co);
231 co.AddRecipe(recipe_id, mask);
260 for (
int i = 1; i < full_path.Count(); i++)
262 m_BaseName = full_path.Get(i);
263 m_CoBase = m_RecipeCache.Get(m_BaseName);
266 m_RcpsArray = m_RecipeCache.Get(m_BaseName).GetRecipes();
268 for (
int x = 0;
x < m_RcpsArray.Count();
x++ )
273 m_BaseMask = m_CoBase.GetMaskByRecipeID(
m_RecipeID);
285 m_Ingredients[0] = item_a;
286 m_Ingredients[1] = item_b;
288 if ( !item_a || !item_b )
290 Error(
"PerformRecipeServer - one of the items null !!");
294 SortIngredientsInRecipe(
id, 2,m_Ingredients, m_sortedIngredients);
296 bool is_recipe_valid = CheckRecipe(
id,m_sortedIngredients[0],m_sortedIngredients[1],player);
297 bool passed_sanity_check = RecipeSanityCheck(2,m_sortedIngredients,player);
299 if ( !is_recipe_valid )
301 Error(
"PerformRecipeServer - recipe not valid !!");
304 if ( !passed_sanity_check )
306 Error(
"PerformRecipeServer - recipe failed to pass sanity check !!");
310 ptrRecipe.PerformRecipe(m_sortedIngredients[0],m_sortedIngredients[1],player);
315 void GenerateHumanReadableRecipeList()
325 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
327 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
328 CacheObject value = PluginRecipesManager.m_RecipeCache.GetElement(i);
332 recipes.InsertAll( value.GetRecipes() );
336 for (
int x = 0;
x < recipes.Count();
x++)
338 int recipe_id = recipes.Get(
x);
339 string recipe_name = GetRecipeName(recipe_id);
340 line +=
"," +recipe_name;
349 CacheObject co = PluginRecipesManager.m_RecipeCache.Get(itemName);
353 foreach (
int recipeID : ids)
355 recipes.Insert(m_RecipeList[recipeID]);
363 int check_results[MAX_INGREDIENTS];
365 for (
int i = 0; i < num_of_ingredients;i++)
368 Man item_owner_player = item.GetHierarchyRootPlayer();
369 vector item_pos = item.GetPosition();
370 vector player_pos = player.GetPosition();
372 if (item_owner_player == player)
377 if ( item_owner_player == NULL || item_owner_player == player || !item_owner_player.IsAlive() )
379 check_results[i] = check_results[i] |
ERecipeSanityCheck.NOT_OWNED_BY_ANOTHER_LIVE_PLAYER;
387 for (i = 0; i < num_of_ingredients;i++)
400 if ( m_RegRecipeIndex >= MAX_NUMBER_OF_RECIPES )
402 Error(
"Exceeded max. number of recipes, max set to: "+MAX_NUMBER_OF_RECIPES.ToString());
405 m_RegRecipeIndex = m_RecipeList.Insert(recipe);
406 recipe.SetID(m_RegRecipeIndex);
407 m_RecipeNamesList.Insert(recipe.ClassName(), m_RegRecipeIndex);
413 int recipe_id = RecipeIDFromClassname(clasname);
417 m_RecipeNamesList.Remove(clasname);
419 m_RecipeList[recipe_id] =
null;
424 static int RecipeIDFromClassname(
string classname)
426 if (m_RecipeNamesList.Contains(classname))
427 return m_RecipeNamesList.Get(classname);
434 return p_recipe.CheckRecipe(item1,item2, player);
437 protected void PrintCache()
439 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
441 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
442 CacheObject co = PluginRecipesManager.m_RecipeCache.GetElement(i);
450 protected bool SortIngredientsInRecipe(
int id,
int num_of_ingredients,
ItemBase ingredients_unsorted[],
ItemBase ingredients_sorted[] )
454 for (
int i = 0; i < num_of_ingredients; i++)
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);
461 bool result = ResolveIngredients(num_of_ingredients);
465 for (i = 0; i < num_of_ingredients; i++)
467 int index =
Math.Log2( m_BitsResults[i]);
468 ingredients_sorted[index] = ingredients_unsorted[ i ];
475 protected void ClearResults()
477 for (
int i = 0; i < MAX_INGREDIENTS; i++)
479 m_BitsResults[i] = 0;
484 protected bool ResolveIngredients(
int num_of_ingredients,
int passes = 0)
487 int smallest = 99999;
488 int smallest_index = 0;
490 for (
int i = 0; i < num_of_ingredients; i++)
492 int count = m_IngredientBitMaskSize[i];
493 if ( count != 0 && count < smallest)
495 smallest = m_IngredientBitMaskSize[i];
500 rightmost_bit = m_IngredientBitMask[smallest_index] & (-m_IngredientBitMask[smallest_index]);
501 m_BitsResults[smallest_index] = m_BitsResults[smallest_index] | rightmost_bit;
503 for (
int x = 0;
x < num_of_ingredients;
x++)
505 m_IngredientBitMask[
x] = ~rightmost_bit & m_IngredientBitMask[
x];
506 m_IngredientBitMask[smallest_index] = 0;
507 m_IngredientBitMaskSize[smallest_index] = 0;
511 int check_sum_vertical = 0;
513 for (
int z = 0; z < num_of_ingredients; z++)
515 check_sum_vertical = check_sum_vertical | m_IngredientBitMask[z];
516 check_sum_vertical = check_sum_vertical | m_BitsResults[z];
517 if ((m_IngredientBitMask[z] | m_BitsResults[z]) == 0)
523 if ( check_sum_vertical != (
Math.Pow(2, num_of_ingredients) - 1))
return false;
527 if (passes < num_of_ingredients)
529 if ( !ResolveIngredients(num_of_ingredients, passes) )
return false;
535 protected void PrintResultMasks(
int num)
537 for (
int i = 0; i < num; i++)
539 Debug.Log(
"results mask("+i.ToString()+
") = " +m_BitsResults[i].ToString() );
544 protected int GetRecipeIntersection(
int num_of_ingredients,
ItemBase items[])
548 int smallest_index = 0;
549 m_RecipesMatched.Clear();
558 for (
int i = 0; i < num_of_ingredients; i++)
565 if (cobject.GetNumberOfRecipes() < smallest)
567 smallest = cobject.GetNumberOfRecipes();
569 co_least_recipes = cobject;
574 array<int> recipes = co_least_recipes.GetRecipes();
575 for (
int x = 0;
x < recipes.Count();
x++)
577 int id = recipes.Get(
x);
578 for (
int z = 0; z < num_of_ingredients; z++)
580 if ( z!= smallest_index)
583 if ( cobject2.IsContainRecipe(
id) )
585 m_RecipesMatched.Insert(
id);
594 protected int SortIngredients(
int num_of_ingredients,
ItemBase items_unsorted[],
int resolved_recipes[])
597 for (
int i = 0; i < m_RecipesMatched.Count() && i < MAX_CONCURENT_RECIPES; i++)
599 int recipe_id = m_RecipesMatched.Get(i);
601 if (SortIngredientsInRecipe(recipe_id, num_of_ingredients, items_unsorted, m_sortedIngredients))
603 resolved_recipes[count] = recipe_id;
604 m_ingredient1[count] = m_sortedIngredients[0];
605 m_ingredient2[count] = m_sortedIngredients[1];
614 protected void CreateAllRecipes()
628 SortIngredientsInRecipe(recipeID, 2,unsorted, sorted);
631 string soundCat = recipe.GetSoundCategory(0,sorted[0]);
635 soundCat = recipe.GetSoundCategory(1,sorted[1]);