Forum Discussion

tastytourist's avatar
9 years ago

Menu categories (or category-like workarounds) for picker interactions?

So there are several different people making custom foods now, and while for the pie menu interactions like "Serve Breakfast" and so on, it works fine to add all sorts of recipes to it by using the same pie_menu_category, there is no (direct) way to do that for the picker interaction ("Cook") -- but when everyone needs to make their own menu lists, that might lead to a little bit of cluttering sooner or later.

From PickerSuperInteraction:
Spoiler
        








Is there any sort of alternative approach that would add new recipes to an existing picker menu? Putting everything in pie menus -- possibly with new "Cook / Serve" pie menus for stuff that should be available anytime (not at set hours) -- does not exactly reduce clutter either .. and without a picker, one would need a whole set of additional pie menus to be able to cook the "family size" group meals as well.

I only have the scripts from ages ago here, but I have a feeling the recipe list is generated on the fly whenever the active sim tries to acess it (is that correct?), so trying to add on to that by way of a script might not be a good idea performance-wise. Or am I overly concerned here?

From crafting_interactions.py
    @flexmethod
def picker_rows_gen(cls, inst, target, context, crafter=DEFAULT, order_count=1, recipe_ingredients_map=None, **kwargs):
if crafter is DEFAULT:
crafter = context.sim
candidate_ingredients = cls._get_ingredient_candidates(crafter)
recipe_list = []
if inst is not None:
inst._choice_enumeration_strategy.build_choice_list(inst)
recipe_list = inst._choice_enumeration_strategy.choices
else:
recipe_list = cls.recipes
if recipe_ingredients_map is None:
recipe_ingredients_map = {}
for recipe in recipe_list:
adjusted_ingredient_price = 0
enable_recipe = True
ingredient_display_list = []
if recipe.use_ingredients is not None:
recipe_ingredients_map = []
ingredients_used = {}
ingredients_found_count = 0
ingredients_needed_count = 0
has_required_ingredients = True
for tuned_ingredient_factory in recipe.sorted_ingredient_requirements:
ingredient_requirement = tuned_ingredient_factory()
ingredient_requirement.attempt_satisfy_ingredients(candidate_ingredients, ingredients_used)
ingredients_found_count += ingredient_requirement.count_satisfied
ingredients_needed_count += ingredient_requirement.count_required
ingredient_display_list.append(ingredient_requirement.get_display_data())
recipe_ingredients_map.append(ingredient_requirement)
if recipe.use_ingredients.all_ingredients_required and ingredients_found_count < ingredients_needed_count:
enable_recipe = False
has_required_ingredients = False
if ingredients_needed_count:
adjusted_ingredient_price = (ingredients_needed_count - ingredients_found_count)/ingredients_needed_count
is_order_interaction = issubclass(cls, StartCraftingOrderSuperInteraction)
price = recipe.get_price(is_order_interaction, adjusted_ingredient_price)*order_count
recipe_test_result = CraftingProcess.recipe_test(target, context, recipe, crafter, price)
while recipe_test_result.visible:
if recipe_test_result.errors:
if len(recipe_test_result.errors) > 1:
localized_error_string = LocalizationHelperTuning.get_bulleted_list(None, *recipe_test_result.errors)
else:
localized_error_string = recipe_test_result.errors
description = cls.create_unavailable_recipe_description(localized_error_string)
tooltip = lambda *_, **__: cls.create_unavailable_recipe_description(localized_error_string)
else:
description = recipe.recipe_description(crafter)
if recipe.use_ingredients is not None:
tooltip_ingredients =
ingredients_list_string = LocalizationHelperTuning.get_bulleted_list(None, *tooltip_ingredients)
if recipe.use_ingredients.all_ingredients_required:
tooltip = functools.partial(IngredientTuning.REQUIRED_INGREDIENT_LIST_STRING, ingredients_list_string)
description = IngredientTuning.REQUIRED_INGREDIENT_LIST_STRING(ingredients_list_string)
else:
tooltip = functools.partial(IngredientTuning.OPTIONAL_INGREDIENT_LIST_STRING, ingredients_list_string)
else:
tooltip = functools.partial(recipe.recipe_description, crafter)
if recipe.has_final_product_definition:
recipe_icon = IconInfoData(icon_resource=recipe.icon_override, obj_def_id=recipe.final_product_definition_id, obj_geo_hash=recipe.final_product_geo_hash, obj_material_hash=recipe.final_product_material_hash)
else:
recipe_icon = IconInfoData(recipe.icon_override)
row = RecipePickerRow(name=recipe.get_recipe_name(crafter), price=price, icon=recipe.icon_override, row_description=description, row_tooltip=tooltip, skill_level=recipe.required_skill_level, is_enable=enable_recipe & recipe_test_result.enabled, linked_recipe=recipe.base_recipe, display_name=recipe.get_recipe_picker_name(crafter), icon_info=recipe_icon, tag=recipe, ingredients=ingredient_display_list, price_with_ingredients=price, pie_menu_influence_by_active_mood=recipe_test_result.influence_by_active_mood, mtx_id=recipe.entitlement)
yield row
if inst is not None:
inst._recipe_ingredients_map = recipe_ingredients_map

def _setup_dialog(self, dialog, crafter=DEFAULT, order_count=1, **kwargs):
crafter = self.sim if crafter is DEFAULT else crafter
dialog.set_target_sim(crafter)
for row in self.picker_rows_gen(self.target, self.context, crafter=crafter, order_count=order_count, **kwargs):
dialog.add_row(row)


If there's no way to access the same list individually, we could still do a sort of compiled version so it would not be the end of the world -- I just wanted to doublecheck first if anyone can think of a better approach.
  • It should be enough to add your new recipes to the "recipes" field of the appropriate StartCraftingSuperInteraction (e.g. fridge_Cook). You are likely to get mod conflicts, so you might want to use the script-based injector to modify that tuning in Python.
  • "SimGuruEugi;14500548" wrote:
    You are likely to get mod conflicts, so you might want to use the script-based injector to modify that tuning in Python.


    Yes, that's why I was asking -- overriding that whole thing is not feasible because conflicts, so how else can I add on to the recipe list? That is not really clear to me .. to me the above code looks like it's what generates the picker lists for absolutely everything, not just cooking recipes, so I can't just go and tack on a bunch of cooking recipes at the end there.

    graycurse (who I don't think has an account here) said recently that he was looking at the same thing, maybe we can get that figured out =).