20 const int MAX_CONCURENT_RECIPES = 128;
21 const int MAX_INGREDIENTS = 5;
26 bool m_EnableDebugCrafting =
false;
73 m_EnableDebugCrafting = enable;
79 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].GetName();
87 if ( item1 == NULL || item2 == NULL )
98 m_Ingredients[0] = item1;
99 m_Ingredients[1] = item2;
106 if (ids) ids.Clear();
108 int numOfRecipes =
SortIngredients(num_of_items,items,m_ResolvedRecipes);
115 if ( numOfRecipes == 0 )
return 0;
118 for (
int i = 0; i < numOfRecipes; i++)
120 p_recipe = m_RecipeList[m_ResolvedRecipes[i]];
122 if ( p_recipe.
CheckRecipe(m_ingredient1[i],m_ingredient2[i], player) ==
true )
124 if (ids) ids.Insert( p_recipe.
GetID() );
134 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].GetLengthInSecs();
140 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].GetSpecialty();
146 if ( m_RecipeList[recipe_id] )
return m_RecipeList[recipe_id].IsInstaRecipe();
160 Debug.
Log(
"CallbackGenerateCache",
"recipes");
171 m_CachedItems.Clear();
172 PluginRecipesManager.m_RecipeCache.Clear();
185 for (
int i = 0; i < all_config_paths.Count(); i++)
187 config_path = all_config_paths.Get(i);
190 for (
int x = 0;
x < children_count;
x++)
208 for (
int c = 0; c < m_RecipeList.Count(); c++)
214 int recipe_id = recipe.
GetID();
219 for (
int x = 0;
x < list.Count();
x++)
221 string ingredient = list.Get(
x);
228 m_RecipeCache.Insert(ingredient,co);
230 co.AddRecipe(recipe_id, mask);
259 for (
int i = 1; i < full_path.Count(); i++)
261 m_BaseName = full_path.Get(i);
262 m_CoBase = m_RecipeCache.Get(m_BaseName);
265 m_RcpsArray = m_RecipeCache.Get(m_BaseName).GetRecipes();
267 for (
int x = 0;
x < m_RcpsArray.
Count();
x++ )
272 m_BaseMask = m_CoBase.GetMaskByRecipeID(
m_RecipeID);
284 m_Ingredients[0] = item_a;
285 m_Ingredients[1] = item_b;
287 if ( !item_a || !item_b )
289 Error(
"PerformRecipeServer - one of the items null !!");
295 bool is_recipe_valid =
CheckRecipe(
id,m_sortedIngredients[0],m_sortedIngredients[1],player);
298 if ( !is_recipe_valid )
300 Error(
"PerformRecipeServer - recipe not valid !!");
303 if ( !passed_sanity_check )
305 Error(
"PerformRecipeServer - recipe failed to pass sanity check !!");
309 ptrRecipe.
PerformRecipe(m_sortedIngredients[0],m_sortedIngredients[1],player);
324 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
326 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
327 CacheObject value = PluginRecipesManager.m_RecipeCache.GetElement(i);
331 recipes.InsertAll( value.GetRecipes() );
335 for (
int x = 0;
x < recipes.Count();
x++)
337 int recipe_id = recipes.Get(
x);
339 line +=
"," +recipe_name;
350 for (
int i = 0; i < num_of_ingredients;i++)
353 Man item_owner_player = item.GetHierarchyRootPlayer();
354 vector item_pos = item.GetPosition();
355 vector player_pos = player.GetPosition();
357 if (item_owner_player == player)
362 if ( item_owner_player == NULL || item_owner_player == player || !item_owner_player.IsAlive() )
364 check_results[i] = check_results[i] |
ERecipeSanityCheck.NOT_OWNED_BY_ANOTHER_LIVE_PLAYER;
372 for (i = 0; i < num_of_ingredients;i++)
385 if ( m_RegRecipeIndex >= MAX_NUMBER_OF_RECIPES )
387 Error(
"Exceeded max. number of recipes, max set to: "+MAX_NUMBER_OF_RECIPES.ToString());
390 m_RegRecipeIndex = m_RecipeList.Insert(recipe);
391 recipe.
SetID(m_RegRecipeIndex);
392 m_RecipeNamesList.Insert(recipe.ClassName(), m_RegRecipeIndex);
402 m_RecipeNamesList.Remove(clasname);
404 m_RecipeList[recipe_id] = null;
411 if (m_RecipeNamesList.Contains(classname))
412 return m_RecipeNamesList.Get(classname);
424 for (
int i = 0; i < PluginRecipesManager.m_RecipeCache.Count(); i++)
426 string key = PluginRecipesManager.m_RecipeCache.GetKey(i);
427 CacheObject co = PluginRecipesManager.m_RecipeCache.GetElement(i);
439 for (
int i = 0; i < num_of_ingredients; i++)
441 CacheObject co_item = PluginRecipesManager.m_RecipeCache.Get( ingredients_unsorted[i].
GetType() );
442 m_IngredientBitMask[i] = co_item.GetMaskByRecipeID(
id);
443 m_IngredientBitMaskSize[i] = co_item.GetBitCountByRecipeID(
id);
450 for (i = 0; i < num_of_ingredients; i++)
452 int index =
Math.
Log2( m_BitsResults[i]);
453 ingredients_sorted[index] = ingredients_unsorted[ i ];
464 m_BitsResults[i] = 0;
472 int smallest = 99999;
473 int smallest_index = 0;
475 for (
int i = 0; i < num_of_ingredients; i++)
477 int count = m_IngredientBitMaskSize[i];
478 if ( count != 0 && count < smallest)
480 smallest = m_IngredientBitMaskSize[i];
485 rightmost_bit = m_IngredientBitMask[smallest_index] & (-m_IngredientBitMask[smallest_index]);
486 m_BitsResults[smallest_index] = m_BitsResults[smallest_index] | rightmost_bit;
488 for (
int x = 0;
x < num_of_ingredients;
x++)
490 m_IngredientBitMask[
x] = ~rightmost_bit & m_IngredientBitMask[
x];
491 m_IngredientBitMask[smallest_index] = 0;
492 m_IngredientBitMaskSize[smallest_index] = 0;
496 int check_sum_vertical = 0;
498 for (
int z = 0; z < num_of_ingredients; z++)
500 check_sum_vertical = check_sum_vertical | m_IngredientBitMask[z];
501 check_sum_vertical = check_sum_vertical | m_BitsResults[z];
502 if ((m_IngredientBitMask[z] | m_BitsResults[z]) == 0)
508 if ( check_sum_vertical != (
Math.
Pow(2, num_of_ingredients) - 1))
return false;
512 if (passes < num_of_ingredients)
522 for (
int i = 0; i < num; i++)
524 Debug.
Log(
"results mask("+i.ToString()+
") = " +m_BitsResults[i].ToString() );
533 int smallest_index = 0;
534 m_RecipesMatched.Clear();
543 for (
int i = 0; i < num_of_ingredients; i++)
550 if (cobject.GetNumberOfRecipes() < smallest)
552 smallest = cobject.GetNumberOfRecipes();
554 co_least_recipes = cobject;
559 array<int> recipes = co_least_recipes.GetRecipes();
560 for (
int x = 0;
x < recipes.Count();
x++)
562 int id = recipes.Get(
x);
563 for (
int z = 0; z < num_of_ingredients; z++)
565 if ( z!= smallest_index)
568 if ( cobject2.IsContainRecipe(
id) )
570 m_RecipesMatched.Insert(
id);
582 for (
int i = 0; i < m_RecipesMatched.Count() && i < MAX_CONCURENT_RECIPES; i++)
584 int recipe_id = m_RecipesMatched.Get(i);
588 resolved_recipes[count] = recipe_id;
589 m_ingredient1[count] = m_sortedIngredients[0];
590 m_ingredient2[count] = m_sortedIngredients[1];
eBleedingSourceType GetType()
DetachActionData m_ItemName
WorldCraftActionReciveData m_RecipeID
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.
const int MAX_NUMBER_OF_INGREDIENTS
proto native int ConfigGetChildrenCount(string path)
Get count of subclasses in config class on path.
proto native void ProfilerStop(string name)
Use for profiling code from start to stop, they must match have same name, look wiki pages for more i...
proto native void ProfilerStart(string name)
Use for profiling code from start to stop, they must match have same name, look wiki pages for more i...
proto native int ConfigGetInt(string path)
Get int value from config on path.
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
proto native void ConfigGetFullPath(string path, out TStringArray full_path)
static void Log(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Prints debug message with normal prio.
override bool DisassembleOnLastDetach()
void ~PluginRecipesManager()
int GetValidRecipes(ItemBase item1, ItemBase item2, array< int > ids, PlayerBase player)
protected bool RecipeSanityCheck(int num_of_ingredients, InventoryItemBase items[], PlayerBase player)
protected void CreateAllRecipes()
const int MAX_INGREDIENTS
int GetValidRecipesProper(int num_of_items, ItemBase items[], array< int > ids, PlayerBase player)
protected void PrintResultMasks(int num)
protected void PrintCache()
const int MAX_CONCURENT_RECIPES
void PluginRecipesManager()
override protected void RegisterRecipe(RecipeBase recipe)
protected 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
void GenerateHumanReadableRecipeList()
bool m_EnableDebugCrafting
override protected void UnregisterRecipe(string clasname)
protected int GetRecipeIntersection(int num_of_ingredients, ItemBase items[])
fills an array with recipe IDs which 'item_a' and 'item_b' share
void PerformRecipeServer(int id, ItemBase item_a, ItemBase item_b, PlayerBase player)
protected void ClearResults()
bool IsEnableDebugCrafting()
float GetRecipeSpecialty(int recipe_id)
protected bool CheckRecipe(int id, ItemBase item1, ItemBase item2, PlayerBase player)
static int GetMaxNumberOfRecipes()
static int RecipeIDFromClassname(string classname)
ref array< int > m_RcpsArray
string GetRecipeName(int recipe_id)
protected void MatchItems(TStringArray full_path)
void SetEnableDebugCrafting(bool enable)
protected bool ResolveIngredients(int num_of_ingredients, int passes=0)
protected int SortIngredients(int num_of_ingredients, ItemBase items_unsorted[], int resolved_recipes[])
string GetSoundCategory(int recipeID, ItemBase item1, ItemBase item2)
bool GetIsInstaRecipe(int recipe_id)
void CallbackGenerateCache()
protected void GenerateRecipeCache()
float GetRecipeLengthInSecs(int recipe_id)
bool CheckRecipe(ItemBase item1, ItemBase item2, PlayerBase player)
string GetSoundCategory(int ingredientIndex, ItemBase item)
ref array< string > m_Ingredients[MAX_NUMBER_OF_INGREDIENTS]
void PerformRecipe(ItemBase item1, ItemBase item2, PlayerBase player)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
array< string > TStringArray
void PrintString(string s)
Helper for printing out string expression. Example: PrintString("Hello " + var);.
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.
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.