-
Notifications
You must be signed in to change notification settings - Fork 8
IConfigurableRecipe
The IConfigurableRecipe
is an Interface implementation.
It allows you to make your Recipe an Overridable Recipe to allow either:
- Other Modders
- Server Owners
To customize your Recipes for your items.
Not only that, you can use them to allow items from other mods to be used in your recipes allowing for greater extensions and mod connections. More Info on that in the IRecipeOverride
Documentation
The implementation of the IConfigurableRecipe
can be used with both RecipeFamily
and Recipe
depending on the situation.
Below is the Implementation of the IConfigurableRecipe
in both cases:
The implementation uses a specific data structure and is setup in a specific way for it to be able to work.
Working with the implementation will be confusing to start with as it is not a normal implementation of the recipe setup.
static RecipeDefaultModel Defaults => new()
{
// Defaults required to create recipes, but not overridable
ModelType = typeof(MyRecipe).Name,
Assembly = typeof(MyRecipe).AssemblyQualifiedName,
HiddenName = "My Item Recipe",
LocalizableName = Localizer.DoStr("My Item Recipe"),
RequiredSkillType = typeof(SomeSkill),
RequiredSkillLevel = 0,
SpeedImprovementTalents = new Type[] {
typeof(SomeFocusedSpeedTalent),
typeof(SomeParallelSpeedTalent) },
// RecipeModel (Will be overrideable)
IngredientList = new()
{
new EMIngredient("PlasticItem", false, 15),
new EMIngredient("GoldBarItem", false, 8),
new EMIngredient("Lumber", true, 7)
},
ProductList = new()
{
new EMCraftable("MyItem"),
},
BaseExperienceOnCraft = 1,
BaseLabor = 250,
LaborIsStatic = false,
BaseCraftTime = 1,
CraftTimeIsStatic = false,
CraftingStation = "CraftingTableItem",
EnableRecipe = true,
};
Here is each component broken down and explained:
ModelType
:
The Model type refers to the recipe itself *Required
Assembly
:
The Assembly Refers to the assembly its located in *Required
HiddenName
:
The Hidden Name is the Internal Referencing Name Used
LocalizableName
:
Is the display name used to display in the tables ( Also used for translations )
RequiredSkillType
:
Required Skill for crafting
RequiredSkillLevel
:
Required Skill level for crafting
SpeedImprovementTalents
:
Craft Time Modifiers
The list of ingredients used to make the item,
- Param 1 is the Item as a string! This is important!!
- Param 2 is "Is this a tag or not" false = not a tag, true = is a tag.
- Param 3 is How many of this item is needed
- Param 4 Is "Should the required amount change with modifiers"
The List of all items for the output
- Param 1 is the Item for output as a string! This is Important!!
- Param 2 is how many items to give back, Default is 1 and does not need to be included unless you wish to give more then 1 item
BaseExperienceOnCraft
:
The Experience Modifier on top of their total skill value ( 1 is default )
BaseLabor
:
The Base amount of labor required
LaborIsStatic
:
Labor can be affected by skill level, use true if you are not using a skill
BaseCraftTime
:
How long it takes to make this item
CraftTimeIsStatic
:
Can the timer be altered by the talents, false = yes, true = no
CraftingStation
:
Crafting Station it is to be made at, MUST be a string and MUST be the Item not the Object!
- If it is the object IE: WorkbenchObject it will throw errors
- Must be WorkbenchItem in order to function
EnableRecipe
:
EnableRecipe is a toggle option to enable or disable a recipe so it can be used or not, it is our way of removing a recipe in a compiled mod, by default this is set to true but adds the option in the config file to enable or disable the recipe
These are the values that are required when using this on the RecipeFamily Recipe.
Anything Marked with an Asterixis (*) is Required
[RequiresSkill(typeof(Skill), level)] *
public class Recipe : RecipeFamily, IConfigurableRecipe
{
static RecipeDefaultModel Defaults => new()
{
ModelType = typeof(Recipe).Name, *
Assembly = typeof(Recipe).AssemblyQualifiedName, *
HiddenName = "Item Name", *
LocalizableName = Localizer.DoStr("Item Name"), *
IngredientList = new()
{
new EMIngredient("Item", false, 8) *
},
ProductList = new()
{
new EMCraftable("Item", 3), *
},
BaseExperienceOnCraft = 1,
BaseLabor = 50, *
LaborIsStatic = false, *
BaseCraftTime = 1, *
CraftTimeIsStatic = false, *
CraftingStation = "Item", *
RequiredSkillType = typeof(Skill),
RequiredSkillLevel = 4,
IngredientImprovementTalents = typeof(LavishResourcesTalent),
SpeedImprovementTalents = new Type[] { typeof(ParallelSpeedTalent), typeof(FocusedSpeedTalent) },
};
static Recipe() { EMRecipeResolver.AddDefaults(Defaults); } *
public Recipe()
{
this.Recipes = EMRecipeResolver.Obj.ResolveRecipe(this); *
this.LaborInCalories = EMRecipeResolver.Obj.ResolveLabor(this); *
this.CraftMinutes = EMRecipeResolver.Obj.ResolveCraftMinutes(this); *
this.ExperienceOnCraft = EMRecipeResolver.Obj.ResolveExperience(this); *
this.Initialize(Defaults.LocalizableName, GetType()); *
CraftingComponent.AddRecipe(EMRecipeResolver.Obj.ResolveStation(this), this); *
}
}
Now here you will see some new things:
- The Static Constructer
- The Constructor
The static constructor adds the defaults to the Recipe Resolver ready to be read
The Constructor Initalizes everything ready to be used in game
Both Must be setup the way you see above
Recipe is used for Variants, it is implemented the same way but the constructors are different
Here is an example:
[RequiresSkill(typeof(Skill), 1)]
public partial class Recipe : Recipe, IConfigurableRecipe
{
static RecipeDefaultModel Defaults => new()
{
ModelType = typeof(Recipe).Name,
Assembly = typeof(Recipe).AssemblyQualifiedName,
HiddenName = "Display Name",
LocalizableName = Localizer.DoStr("Display Name"),
IngredientList = new()
{
new EMIngredient("Item", false, 6, true),
},
ProductList = new()
{
new EMCraftable("Item", 6),
},
CraftingStation = "Item",
};
static Recipe() { EMRecipeResolver.AddDefaults(Defaults); }
public Recipe()
{
CraftingComponent.AddTagProduct(EMRecipeResolver.Obj.ResolveStation(this), typeof(ParentRecipe), EMRecipeResolver.Obj.ResolveRecipe(this).First());
}
}
If you know how to make Recipe Variants this will be somewhat familiar.
In the Public Constructer we use the recipe resolver to attach to the correct table, then we reference the parent recipe, then we attach our recipe.
Recipe Variants don't override the craft time or skills so that is not needed as it inherits it from the parent recipe.
The EMIngredient is our Version of the IngredientElement()
This uses this setup:
EMIngredient(string item: "", bool isTag: false, int amount: 1, bool isStatic: false)
We have to use strings here because this is how we find the Items before anything is initialized in order to override the Recipes or make them be able to be overridden.
We use true
or false
for the isTag to check if we should be looking for a tag or an item.
The other 2 are pretty standard.
Amount is how many of this item is required to make the end product ( in whole numbers only )
IsStatic is should the amount of items required be affected by modules, skill modifiers or talent modifiers:
- false ( which is default ) means yes it can be affected by modifiers.
- true means it can not be affected by modifiers.
The EMProduct is pretty much the same as CraftingElement<>()
This uses this setup:
EMProduct(string item: "", int amount: 1)
However here we use a string as well because we are looking for things before they are initialized
We use the amount to say how many we are giving when the recipe has finished crafting