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;
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()
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 )
107 if (ids) ids.Clear();
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();
151 bool GetIsRepeatable(
int recipe_id)
153 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].IsRepeatable();
165 void CallbackGenerateCache()
167 Debug.Log(
"CallbackGenerateCache",
"recipes");
175 GetGame().ProfilerStart(
"m_RecipeCache");
178 m_CachedItems.Clear();
179 PluginRecipesManager.m_RecipeCache.Clear();
192 for (
int i = 0; i < all_config_paths.Count(); i++)
194 config_path = all_config_paths.Get(i);
195 int children_count =
GetGame().ConfigGetChildrenCount(config_path);
197 for (
int x = 0;
x < children_count;
x++)
199 GetGame().ConfigGetChildName(config_path,
x, child_name);
200 scope =
GetGame().ConfigGetInt( config_path +
" " + child_name +
" scope" );
204 GetGame().ConfigGetFullPath(config_path +
" "+ child_name, full_path);
209 GetGame().ProfilerStop(
"m_RecipeCache");
215 for (
int c = 0; c < m_RecipeList.Count(); c++)
221 int recipe_id = recipe.GetID();
226 for (
int x = 0;
x < list.Count();
x++)
228 string ingredient = list.Get(
x);
229 int mask =
Math.Pow(2,i);
235 m_RecipeCache.Insert(ingredient,co);
237 co.AddRecipe(recipe_id, mask);
266 for (
int i = 1; i < full_path.Count(); i++)
268 m_BaseName = full_path.Get(i);
269 m_CoBase = m_RecipeCache.Get(m_BaseName);
272 m_RcpsArray = m_RecipeCache.Get(m_BaseName).GetRecipes();
274 for (
int x = 0;
x < m_RcpsArray.Count();
x++ )
279 m_BaseMask = m_CoBase.GetMaskByRecipeID(
m_RecipeID);
291 if ( !itemA || !itemB )
301 bool result =
CheckRecipe(
id, m_sortedIngredients[0], m_sortedIngredients[1], player);
315 if ( !item_a || !item_b )
317 Error(
"PerformRecipeServer - one of the items null !!");
323 bool is_recipe_valid =
CheckRecipe(
id,m_sortedIngredients[0],m_sortedIngredients[1],player);
326 if ( !is_recipe_valid )
328 Error(
"PerformRecipeServer - recipe not valid !!");
331 if ( !passed_sanity_check )
333 Error(
"PerformRecipeServer - recipe failed to pass sanity check !!");
337 ptrRecipe.PerformRecipe(m_sortedIngredients[0],m_sortedIngredients[1],player);
344 set<string> testset =
new set<string>;
354 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
356 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
357 CacheObject value = PluginRecipesManager.m_RecipeCache.GetElement(i);
361 recipes.InsertAll( value.GetRecipes() );
365 for (
int x = 0;
x < recipes.Count();
x++)
367 int recipe_id = recipes.Get(
x);
368 string recipe_name = Widget.TranslateString(GetRecipeName(recipe_id));
369 testset.Insert(recipe_name);
371 line +=
"," +recipe_name;
378 foreach (
string st : testset)
388 CacheObject co = PluginRecipesManager.m_RecipeCache.Get(itemName);
392 foreach (
int recipeID : ids)
394 recipes.Insert(m_RecipeList[recipeID]);
402 int check_results[MAX_INGREDIENTS];
404 for (
int i = 0; i < num_of_ingredients;i++)
407 Man item_owner_player = item.GetHierarchyRootPlayer();
408 vector item_pos = item.GetPosition();
409 vector player_pos = player.GetPosition();
411 if (item_owner_player == player)
416 if ( item_owner_player == NULL || item_owner_player == player || !item_owner_player.IsAlive() )
418 check_results[i] = check_results[i] |
ERecipeSanityCheck.NOT_OWNED_BY_ANOTHER_LIVE_PLAYER;
426 for (i = 0; i < num_of_ingredients;i++)
439 if ( m_RegRecipeIndex >= MAX_NUMBER_OF_RECIPES )
441 Error(
"Exceeded max. number of recipes, max set to: "+MAX_NUMBER_OF_RECIPES.ToString());
444 m_RegRecipeIndex = m_RecipeList.Insert(recipe);
445 recipe.SetID(m_RegRecipeIndex);
446 m_RecipeNamesList.Insert(recipe.ClassName(), m_RegRecipeIndex);
456 m_RecipeNamesList.Remove(clasname);
458 m_RecipeList[recipe_id] = null;
465 if (m_RecipeNamesList.Contains(classname))
466 return m_RecipeNamesList.Get(classname);
473 return p_recipe.CheckRecipe(item1,item2, player);
478 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
480 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
481 CacheObject co = PluginRecipesManager.m_RecipeCache.GetElement(i);
493 for (
int i = 0; i < num_of_ingredients; i++)
495 CacheObject co_item = PluginRecipesManager.m_RecipeCache.Get( ingredients_unsorted[i].
GetType() );
496 m_IngredientBitMask[i] = co_item.GetMaskByRecipeID(
id);
497 m_IngredientBitMaskSize[i] = co_item.GetBitCountByRecipeID(
id);
504 for (i = 0; i < num_of_ingredients; i++)
506 int index =
Math.Log2( m_BitsResults[i]);
507 ingredients_sorted[index] = ingredients_unsorted[ i ];
516 for (
int i = 0; i < MAX_INGREDIENTS; i++)
518 m_BitsResults[i] = 0;
526 int smallest = 99999;
527 int smallest_index = 0;
529 for (
int i = 0; i < num_of_ingredients; i++)
531 int count = m_IngredientBitMaskSize[i];
532 if ( count != 0 && count < smallest)
534 smallest = m_IngredientBitMaskSize[i];
539 rightmost_bit = m_IngredientBitMask[smallest_index] & (-m_IngredientBitMask[smallest_index]);
540 m_BitsResults[smallest_index] = m_BitsResults[smallest_index] | rightmost_bit;
542 for (
int x = 0;
x < num_of_ingredients;
x++)
544 m_IngredientBitMask[
x] = ~rightmost_bit & m_IngredientBitMask[
x];
545 m_IngredientBitMask[smallest_index] = 0;
546 m_IngredientBitMaskSize[smallest_index] = 0;
550 int check_sum_vertical = 0;
552 for (
int z = 0; z < num_of_ingredients; z++)
554 check_sum_vertical = check_sum_vertical | m_IngredientBitMask[z];
555 check_sum_vertical = check_sum_vertical | m_BitsResults[z];
556 if ((m_IngredientBitMask[z] | m_BitsResults[z]) == 0)
562 if ( check_sum_vertical != (
Math.Pow(2, num_of_ingredients) - 1))
return false;
566 if (passes < num_of_ingredients)
576 for (
int i = 0; i < num; i++)
578 Debug.Log(
"results mask("+i.ToString()+
") = " +m_BitsResults[i].ToString() );
587 int smallest_index = 0;
588 m_RecipesMatched.Clear();
597 for (
int i = 0; i < num_of_ingredients; i++)
604 if (cobject.GetNumberOfRecipes() < smallest)
606 smallest = cobject.GetNumberOfRecipes();
608 co_least_recipes = cobject;
613 array<int> recipes = co_least_recipes.GetRecipes();
614 for (
int x = 0;
x < recipes.Count();
x++)
616 int id = recipes.Get(
x);
617 for (
int z = 0; z < num_of_ingredients; z++)
619 if ( z!= smallest_index)
622 if ( cobject2.IsContainRecipe(
id) )
624 m_RecipesMatched.Insert(
id);
636 for (
int i = 0; i < m_RecipesMatched.Count() && i < MAX_CONCURENT_RECIPES; i++)
638 int recipe_id = m_RecipesMatched.Get(i);
642 resolved_recipes[count] = recipe_id;
643 m_ingredient1[count] = m_sortedIngredients[0];
644 m_ingredient2[count] = m_sortedIngredients[1];
670 string soundCat = recipe.GetSoundCategory(0,sorted[0]);
674 soundCat = recipe.GetSoundCategory(1,sorted[1]);
683 return m_RecipeList[recipeID].GetRecipeAnimationInfo(player, mainItem, target);
688 return m_RecipeList[recipeID].GetAnimationCommandUID();
eBleedingSourceType GetType()
DetachActionData m_ItemName
WorldCraftActionReciveData m_RecipeID
override bool DisassembleOnLastDetach()
static int RecipeIDFromClassname(string classname)
void RegisterRecipe(RecipeBase recipe)
bool IsRecipePossibleToPerform(int id, ItemBase itemA, ItemBase itemB, PlayerBase player)
ref array< int > m_RcpsArray
void GenerateRecipeCache()
void GenerateHumanReadableRecipeList()
void UnregisterRecipe(string clasname)
bool ResolveIngredients(int num_of_ingredients, int passes=0)
void PerformRecipeServer(int id, ItemBase item_a, ItemBase item_b, PlayerBase player)
void PrintResultMasks(int num)
int GetAnimationCommandUID(int recipeID)
int GetRecipeIntersection(int num_of_ingredients, ItemBase items[])
fills an array with recipe IDs which 'item_a' and 'item_b' share
array< RecipeBase > GetRecipesForItem(string itemName)
bool CheckRecipe(int id, ItemBase item1, ItemBase item2, PlayerBase player)
bool RecipeSanityCheck(int num_of_ingredients, InventoryItemBase items[], PlayerBase player)
RecipeAnimationInfo GetRecipeAnimationInfo(int recipeID, PlayerBase player, ItemBase mainItem, ItemBase target)
string GetSoundCategory(int recipeID, ItemBase item1, ItemBase item2)
void MatchItems(TStringArray full_path)
bool SortIngredientsInRecipe(int id, int num_of_ingredients, ItemBase ingredients_unsorted[], ItemBase ingredients_sorted[])
sorts ingredients correctly as either first or second ingredient based on their masks
int SortIngredients(int num_of_ingredients, ItemBase items_unsorted[], int resolved_recipes[])
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
array< string > TStringArray
class array< Class T > PrintString
proto void CloseFile(FileHandle file)
Close the File.
proto FileHandle OpenFile(string name, FileMode mode)
Opens File.
proto void FPrintln(FileHandle file, void var)
Write to file and add new line.
void OnInit()
Callback for user defined initialization. Called for all suites during TestHarness....
const int SANITY_CHECK_ACCEPTABLE_RESULT
@ NOT_OWNED_BY_ANOTHER_LIVE_PLAYER
enum ERecipeSanityCheck ACCEPTABLE_DISTANCE
void RegisterRecipies()
Please do not delete commented recipes, they are usually commented out for a reason.
ref array< string > m_Ingredients[MAX_NUMBER_OF_INGREDIENTS]
const int MAX_NUMBER_OF_INGREDIENTS