OSP Code QoL Simple crafting

Users who are viewing this thread

Ive managed to do some simple crafting system for Warband 1.171/1.174

credits:
Lav and other for 1.166 Module Systems and commented header_operations, also for WRECK
Viking Conquest source code - I looked for reference and how things are done
Leonion - Trade Screen Replacer - same as above
kalaharn - posted idea of using troops as arrays somewhere on forum

known limitations
- max 6 ingredients
- all ingredients must be different
- if tools are taken both as ingredient and condition, only one tools are needed (and will be consumed)
- system doesnt care for modifiers, take first match, so accidentally can use some good item
- if too much recipes, scrolling can be uncomfortable
- you can read books while crafting, as it uses resting mechanism
- some operations that iterate on all troops can break something

How it works:
At the beginning of the game script store recipes and ingredients in organized arrays. Then you can call a presentation where there is shown all recipes or only those for which you have items in non-equipped equipment. If recipe is avaible to craft you can click on button and after confirmation ingredients will be taken, and result item will be given. You must then wait from 10 to 1 ingame hours (depends of engineering skill). While this time you cannot be attacked, but you cant do anything.
I think the system can be easily modified. Simple adding recipe is only filling some short code in script (i left template).
Recipes added by me are more for show possibilities rather than ingame immerse.

thumbnail

alternative link, cause sharing images from google s*cks
Code:
Rich (BB code):
#crafting
	[
		"auxillary_inv_array",
		"Auxillary Inventory Array",
		"Auxillary Inventory Array",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
	[
		"crafting_array",
		"Crafting Array",
		"Crafting Array",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
	[
		"crafting_recipes",
		"Crafting Recipes",
		"Crafting Recipes",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
	[
		"recipes_aux_overlays",
		"Here overlays ids",
		"from recipes container",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],	
	[
		"recipes_aux_items",
		"Here items ids",
		"from recipes container",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
	[
		"crafting_button_overlays",
		"Here overlays ids",
		"of craft buttons",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
	[
		"crafting_button_recipes",
		"Here recipes ids",
		"of craft buttons",
		tf_inactive,
		0,
		0,
		fac_no_faction,
		[],
		0,
		0,
		0,
		0,
		0
	],
Rich (BB code):
#for crafting presentation
from header_items import *
Rich (BB code):
#crafting presentation
	(
		"crafting",
		0,
		mesh_load_window,
		[
			(
				ti_on_presentation_load,
				[
					(presentation_set_duration, 999999),
					(set_fixed_point_multiplier, 1000),
					(str_clear, s1),
					(str_store_string, s1, "@Crafting"),
					(create_text_overlay, reg1, s1, tf_center_justify),
					(position_set_x, pos1, 500),
					(position_set_y, pos1, 700),
					(overlay_set_position, reg1, pos1),
					(overlay_set_text, reg1, s1),
					
					#equipment on right side
					(str_clear, s1),
					(str_store_string, s1, "@Inventory overview"),
					(create_text_overlay, reg1, s1, tf_center_justify),
					(position_set_x, pos1, 800),
					(position_set_y, pos1, 650),
					(overlay_set_position, reg1, pos1),
					(overlay_set_text, reg1, s1),
					
					#equipment auxillary data preparation
					(try_for_range, ":cur_pos", 0, 100),
						(troop_set_slot, "trp_auxillary_inv_array", ":cur_pos", 0),
						(troop_set_inventory_slot, "trp_auxillary_inv_array", ":cur_pos", 0),#use of 0, maybe can be -1 not sure
						#additional offset with bools to double check
						(store_add, ":cur_pos_plus_100", ":cur_pos", 100),
						(troop_set_slot, "trp_auxillary_inv_array", ":cur_pos_plus_100", 0),
					(try_end),
					
					
					#exit
					(create_button_overlay, "$g_crafting_presentation_back_button", "@Back"),
					(position_set_x, pos1, 200),
					(position_set_y, pos1, 50),
					(overlay_set_position, "$g_crafting_presentation_back_button", pos1),
					
					#show all recipes checkbox
					(create_check_box_overlay, "$g_crafting_show_all_recipes_checkbox", "mesh_checkbox_off", "mesh_checkbox_on"),
					(position_set_x, pos1, 300),
					(position_set_y, pos1, 650),
					(overlay_set_position, "$g_crafting_show_all_recipes_checkbox", pos1),
					(try_begin),#for case of uninitialized or something
						(eq, "$g_show_all_recipes", 0),
						(overlay_set_val, "$g_crafting_show_all_recipes_checkbox", 0),
					(else_try),
						(eq, "$g_show_all_recipes", 1),
						(overlay_set_val, "$g_crafting_show_all_recipes_checkbox", 1),
					(try_end),
					
					
					(str_clear, s1),
					(str_store_string, s1, "@Show all"),
					(create_text_overlay, reg1, s1, tf_center_justify),
					(position_set_x, pos1, 250),
					(position_set_y, pos1, 640),
					(overlay_set_position, reg1, pos1),
					(overlay_set_text, reg1, s1),
					
					
					#items
					
					#prepare player inventory data
					(troop_get_inventory_capacity, ":raw_inv_capacity", "trp_player"),
					#this one is not used, cause we can securely iterate of inventory and derivatives (always <=100)
					#(store_sub, "$g_crafting_presentation_inv_capacity", ":raw_inv_capacity", num_equipment_kinds),  ## !! header items !!
					
					#inv loop boundaries
					(assign, ":inv_loop_start", num_equipment_kinds),
					(assign, ":inv_loop_end", ":raw_inv_capacity"),

					
					#calculate container size
					#num_of_items/3+1 rows should be ok
					(assign, ":container_size_y", 0),
					(try_for_range, ":cur_inv_slot", ":inv_loop_start", ":inv_loop_end"),
						(troop_get_inventory_slot, ":item_in_slot", "trp_player", ":cur_inv_slot"),
						#skip empty slots
						(neq, ":item_in_slot", -1),
						(val_add, ":container_size_y", 1),
					(try_end),
					(val_div, ":container_size_y", 3),
					(val_add, ":container_size_y", 1),
					(val_mul, ":container_size_y", 100),
					
					#inventory items container
					(create_text_overlay, reg1, "@ ", tf_scrollable),
					(position_set_x, pos1, 670),
					(position_set_y, pos1, 100),
					(overlay_set_position, reg1, pos1),
					(position_set_x, pos1, 300),
					(position_set_y, pos1, 500),
					(overlay_set_area_size, reg1, pos1),
					
					(set_container_overlay, reg1),
						
					#auxillary loop variables
					(assign, ":row", 0),
					(assign, ":column", 0),
					(assign, ":item_counter", 0),

					#inventory_meshes_loop
					(try_for_range, ":cur_inv_slot", ":inv_loop_start", ":inv_loop_end"),
						(troop_get_inventory_slot, ":item_in_slot", "trp_player", ":cur_inv_slot"),
						#display only items, skip empty slots
						(neq, ":item_in_slot", -1),
						
						#counting mesh positions
						(store_mul, ":inv_mesh_x", ":column", 100),
						(store_mul, ":inv_mesh_y", ":row", 100),
						#cause going from top
						(store_sub, ":inv_mesh_y", ":container_size_y", ":inv_mesh_y"),
						
						(store_add, ":item_mesh_x", ":inv_mesh_x", 50),
						(store_add, ":item_mesh_y", ":inv_mesh_y", 50),
						
						
						#mesh inventory slot
						(create_mesh_overlay, reg1, mesh_inv_slot),
						(position_set_x, pos1, ":inv_mesh_x"),
						(position_set_y, pos1, ":inv_mesh_y"),
						(overlay_set_position, reg1, pos1),
						
						#mesh item
						(create_mesh_overlay_with_item_id, reg2, ":item_in_slot"),
						(position_set_x, pos2, ":item_mesh_x"),
						(position_set_y, pos2, ":item_mesh_y"),
						
						(overlay_set_position, reg2, pos2),
						
						#auxillary_table
						(troop_set_inventory_slot, "trp_auxillary_inv_array", ":item_counter", ":item_in_slot"),
						(store_add, ":additional_bool_check", ":item_counter", 100),
						#store id of overlay with specific item
						(troop_set_slot, "trp_auxillary_inv_array", ":item_counter", reg2),
						(troop_set_slot, "trp_auxillary_inv_array", ":additional_bool_check", 1),
						
						#auxillary variables incrementing
						(try_begin),
							(ge, ":column", 2),
							(assign, ":column", 0),
							(val_add, ":row", 1),
						(else_try),
							(val_add, ":column", 1),
						(try_end),
						
						(val_add, ":item_counter", 1),
						
					(try_end),
					
					(set_container_overlay, -1),
					
					#recipes on left side
					#calculate container size
					#num of recipes with 3 or less ingredients * 100 +
					#num of recipes with 4 or more ingredients * 200 +
					#(total num of recipes - 1)*10
					#should be enough
					(assign, ":recipes_container_size", 0),
					(try_for_range, ":cur_recipe", 0, "$g_total_number_or_recipes"),
						(store_mul, ":recipe_location", ":cur_recipe", 10),
						(troop_get_slot, ":num_of_ingredients_cur_recipe", "trp_crafting_recipes", ":recipe_location"),
						(try_begin),
							(ge, ":num_of_ingredients_cur_recipe", 4),
							(val_add, ":recipes_container_size", 200),
						(else_try),
							(val_add, ":recipes_container_size", 100),
						(try_end),
					(try_end),
					(store_sub, ":gaps", "$g_total_number_or_recipes", 1),
					(val_mul, ":gaps", 10),
					(val_add, ":recipes_container_size", ":gaps"),
					
					#recipes container
					(create_text_overlay, reg1, "@ ", tf_scrollable),
					(position_set_x, pos1, 30),
					(position_set_y, pos1, 100),
					(overlay_set_position, reg1, pos1),
					(position_set_x, pos1, 600),
					(position_set_y, pos1, 500),
					(overlay_set_area_size, reg1, pos1),
					
					(set_container_overlay, reg1),
					
					(assign, ":remaining_container_size_y", ":recipes_container_size"),
					
					(assign, "$g_total_num_of_items_overlays_in_recipes", 0),
					
					(assign, "$g_total_num_of_crafting_buttons", 0),
					
					#show recipes
					(try_for_range, ":cur_recipe", 0, "$g_total_number_or_recipes"),
						(assign, ":show_this_recipe", 0),
						(assign, ":can_craft", 0),#when all are shown
					
						(try_begin),
							#(eq, "$g_show_all_recipes", 0),for checking crafting possibiity also
							
							#check items for this recipe
							#(assign, ":has_items_check", 1),#this not needed, cause checking number of owned ingredients
							(store_mul, ":recipe_location", ":cur_recipe", 10),
							(troop_get_slot, ":num_of_ingredients", "trp_crafting_recipes", ":recipe_location"),
							
							#loop_boundaries
							(store_add, ":loop_start", ":recipe_location", 1),
							(store_add, ":loop_end", ":loop_start", ":num_of_ingredients"),
							
							(assign, ":ingredients_checked", 0),
							
							(try_for_range, ":i", ":loop_start", ":loop_end"),
								(troop_get_slot, ":cur_ingredient", "trp_crafting_recipes", ":i"),
								
								(assign, ":got_this_ingredient", 0),
								#check in not used inventory, use temp array
								(try_for_range, ":aux_pos", 0, 100),
									(troop_get_inventory_slot, ":cur_item", "trp_auxillary_inv_array", ":aux_pos"),
									(eq, ":cur_item", ":cur_ingredient"),
									(assign, ":got_this_ingredient", 1),
								(try_end),
								
								(eq, ":got_this_ingredient", 1),
								(val_add, ":ingredients_checked", 1),
								
							(try_end),
							
							(eq, ":ingredients_checked", ":num_of_ingredients"),#proceed
							#tools check
							#this can be simpler as tools cannot be equipped
							(store_add, ":tools_check_location", ":recipe_location", 7),
							(troop_get_slot, ":need_tools", "trp_crafting_recipes", ":tools_check_location"),
							(try_begin),
								(eq, ":need_tools", 1),#nested ifs composition!
								(try_begin),
									(player_has_item, "itm_tools"),
									(assign, ":show_this_recipe", 1),
								(else_try),#for a sake
									(assign, ":show_this_recipe", 0),
								(try_end),
							(else_try),
							#no need for tools
								(assign, ":show_this_recipe", 1),
							(try_end),
							
							#ability to craft when all recipes shown
							(assign, ":can_craft", ":show_this_recipe"),
							
						(try_end),
						
						#if show all recipes
						(try_begin),
							(eq, "$g_show_all_recipes", 1),
							(assign, ":show_this_recipe", 1),
						(try_end),
						
						#show this recipe
						(try_begin),#this can be not necessary
							(eq, ":show_this_recipe", 1),
							#num of ingredients
							#if more than 3 set aux offset
							#maybe some operations are doubled
							(store_mul, ":recipe_location", ":cur_recipe", 10),
							(troop_get_slot, ":num_of_ingredients", "trp_crafting_recipes", ":recipe_location"),
							(assign, ":aux_y_offset", 0),
							(try_begin),
								(ge, ":num_of_ingredients", 4),
								(assign, ":aux_y_offset", 50),
							(try_end),
							
							#loop auxillaries
							(assign, ":local_row", 0),
							(assign, ":local_column", 0),
							(assign, ":item_counter", 0),
							
							#show ingredients
							(try_for_range, ":cur_ingredient", 0, ":num_of_ingredients"),
								
								
								#counting this ingredient
								(store_add, ":this_ingredient_pos", ":recipe_location", ":cur_ingredient"),
								(val_add, ":this_ingredient_pos", 1),#loop from 0, ingredients from 1
								(troop_get_slot, ":item_in_slot", "trp_crafting_recipes", ":this_ingredient_pos"),
							
								#counting mesh positions
								(store_mul, ":inv_mesh_x", ":local_column", 100),
								(store_mul, ":inv_mesh_y", ":local_row", 100),
								#cause going from top
								(store_sub, ":inv_mesh_y", ":remaining_container_size_y", ":inv_mesh_y"),
								
								(store_add, ":item_mesh_x", ":inv_mesh_x", 50),
								(store_add, ":item_mesh_y", ":inv_mesh_y", 50),
							
								#mesh inventory slot
								(create_mesh_overlay, reg1, mesh_inv_slot),
								(position_set_x, pos1, ":inv_mesh_x"),
								(position_set_y, pos1, ":inv_mesh_y"),
								(overlay_set_position, reg1, pos1),
								
								#mesh item
								(create_mesh_overlay_with_item_id, reg2, ":item_in_slot"),
								(position_set_x, pos2, ":item_mesh_x"),
								(position_set_y, pos2, ":item_mesh_y"),
								
								(overlay_set_position, reg2, pos2),
								
								
								#auxillary variables incrementing
								(try_begin),
									(ge, ":local_column", 2),
									(assign, ":local_column", 0),
									(val_add, ":local_row", 1),
								(else_try),
									(val_add, ":local_column", 1),
								(try_end),
								
								#aux tables
								(troop_set_slot, "trp_recipes_aux_overlays", "$g_total_num_of_items_overlays_in_recipes", reg2),#before increment
								(troop_set_slot, "trp_recipes_aux_items", "$g_total_num_of_items_overlays_in_recipes", ":item_in_slot"),
								
								(val_add, "$g_total_num_of_items_overlays_in_recipes", 1),
								
							(try_end),
							
							#show result
							(store_sub, ":result_y", ":remaining_container_size_y", ":aux_y_offset"),
							(troop_get_slot, ":recipe_result", "trp_crafting_array", ":cur_recipe"),
							(assign, ":inv_mesh_x", 500),
							(assign, ":inv_mesh_y", ":result_y"),
							
							(store_add, ":item_mesh_x", ":inv_mesh_x", 50),
							(store_add, ":item_mesh_y", ":inv_mesh_y", 50),
							
							#mesh inventory slot
							(create_mesh_overlay, reg1, mesh_inv_slot),
							(position_set_x, pos1, ":inv_mesh_x"),
							(position_set_y, pos1, ":inv_mesh_y"),
							(overlay_set_position, reg1, pos1),
							
							#mesh item
							(create_mesh_overlay_with_item_id, reg2, ":recipe_result"),
							(position_set_x, pos2, ":item_mesh_x"),
							(position_set_y, pos2, ":item_mesh_y"),
							
							(overlay_set_position, reg2, pos2),
							
							#here also aux tables
							(troop_set_slot, "trp_recipes_aux_overlays", "$g_total_num_of_items_overlays_in_recipes", reg2),#before increment
							(troop_set_slot, "trp_recipes_aux_items", "$g_total_num_of_items_overlays_in_recipes", ":recipe_result"),
							
							(val_add, "$g_total_num_of_items_overlays_in_recipes", 1),
							
							#tools information
							(try_begin),
								(store_mul, ":recipe_location", ":cur_recipe", 10),
								(store_add, ":tools_check_location", ":recipe_location", 7),
								(troop_get_slot, ":need_tools", "trp_crafting_recipes", ":tools_check_location"),
								(eq, ":need_tools", 1),
								(str_clear, s1),
								(str_store_string, s1, "@Requires tools"),
								(create_text_overlay, reg0, s1, tf_scrollable),
								(position_set_x, pos1, 310),
								(store_sub, ":tools_y", ":result_y", 30),
								(position_set_y, pos1, ":tools_y"),
								(overlay_set_position, reg0, pos1),
								(position_set_x, pos1, 130),
								(position_set_y, pos1, 100),
								(overlay_set_area_size, reg0, pos1),
							(try_end),
							
							#craft buttons
							(try_begin),
								(eq, ":can_craft", 1),
								(create_button_overlay, reg1, "@Craft"),
								(position_set_x, pos1, 430),
								(store_add, ":craft_y", ":result_y", 40),
								(position_set_y, pos1, ":craft_y"),
								(overlay_set_position, reg1, pos1),
								
								(troop_set_slot, "trp_crafting_button_overlays", "$g_total_num_of_crafting_buttons", reg1),
								(troop_set_slot, "trp_crafting_button_recipes", "$g_total_num_of_crafting_buttons", ":cur_recipe"),
								
								(val_add, "$g_total_num_of_crafting_buttons", 1),
							(try_end),
							
							#offset for next recipe
							(try_begin),
								(ge, ":num_of_ingredients", 4),
								(val_sub, ":remaining_container_size_y", 200),
							(else_try),
								(val_sub, ":remaining_container_size_y", 100),
							(try_end),
							
						(try_end),
						
					#space between recipes
					(val_sub, ":remaining_container_size_y", 10),
						
					(try_end),
					
				]
			),
			
			(
				ti_on_presentation_event_state_change,
				[
					(store_trigger_param_1, ":object"),
					#(store_trigger_param_2, ":val"),#not used
					(try_begin),
						(eq, ":object", "$g_crafting_presentation_back_button"),
						(presentation_set_duration, 0),
						(jump_to_menu, "mnu_camp_action"),
					(else_try),
					
					#show all
						(eq, ":object", "$g_crafting_show_all_recipes_checkbox"),
						(try_begin),#this is made the complicated way i think
							(eq, "$g_show_all_recipes", 0),
							(assign, "$g_show_all_recipes", 1),
						(else_try),
							(eq, "$g_show_all_recipes", 1),
							(assign, "$g_show_all_recipes", 0),
						(try_end),
						(start_presentation, "prsnt_crafting"),
					(else_try),
					
						#craft buttons
						(try_for_range, ":i", 0, "$g_total_num_of_crafting_buttons"),
							(troop_get_slot, ":i_button", "trp_crafting_button_overlays", ":i"),
							(eq, ":object", ":i_button"),
							(troop_get_slot, "$g_choosen_crafting_id", "trp_crafting_button_recipes", ":i"),
							(presentation_set_duration, 0),
							(jump_to_menu, "mnu_crafting_confirm"),
						(try_end),
					(try_end),
					
					
					
				]
			),
			
			(
				ti_on_presentation_mouse_enter_leave,
				[
					(store_trigger_param_1, reg1), #overlay id
					(store_trigger_param_2, reg2), #enter or leave
					
					(try_begin),
						(eq, reg2, 0),
						(overlay_get_position, pos1, reg1),
						(assign, ":item_id", -1),
						
						#inv check loop
						(try_for_range, ":i", 0, 100),
							(troop_get_slot, ":slot_check", "trp_auxillary_inv_array", ":i"),
							(eq, ":slot_check", reg1), #overlay id match
							(store_add, ":aux_pos", ":i", 100),
							(troop_get_slot, ":is_item_additional_check", "trp_auxillary_inv_array", ":aux_pos"),
							(eq, ":is_item_additional_check", 1),
							(troop_get_inventory_slot, ":item_id", "trp_auxillary_inv_array", ":i"),
						(try_end),
						
						#recipes check loop
						(try_for_range, ":i", 0, "$g_total_num_of_items_overlays_in_recipes"),
							(troop_get_slot, ":slot_check", "trp_recipes_aux_overlays", ":i"),
							(eq, ":slot_check", reg1),
							(troop_get_slot, ":item_id", "trp_recipes_aux_items", ":i"),
						(try_end),
						
						(try_begin),#double check of item existence
							(ge, ":item_id", 1),
							(show_item_details, ":item_id", pos1, 100),
						(try_end),
						

					(else_try),
						(close_item_details),
					(try_end),
				]
			)
			
		]
	),
Rich (BB code):
#simple crafting
		(
			"go_to_crafting_menu",
			[],
			"Go to crafting menu",
			[
				(start_presentation, "prsnt_crafting"),
			],
		),
Rich (BB code):
#crafting confirm
#mnu_crafting_confirm
	(
		"crafting_confirm",
		mnf_disable_all_keys,
		"{s0}",
		"none",
		[
			#prepare strings
			(try_for_range, ":cur_global_string", 0, 17),#more than needed but im lazy
				(str_clear, ":cur_global_string"), 
			(try_end),
			
			(troop_get_slot, ":result_item", "trp_crafting_array", "$g_choosen_crafting_id"),
			(str_store_item_name, s7, ":result_item"),
			
			(store_mul, ":recipe_position", "$g_choosen_crafting_id", 10),
			(troop_get_slot, ":num_of_ingredients", "trp_crafting_recipes", ":recipe_position"),
			
			#thats how indexing works
			(store_add, ":loop_end", ":num_of_ingredients", 1),
			(try_for_range, ":ingredient_pos_in_recipe", 1, ":loop_end"),
				(store_add, ":ingredient_pos", ":ingredient_pos_in_recipe", ":recipe_position"),
				(troop_get_slot, ":ingredient_id", "trp_crafting_recipes", ":ingredient_pos"),
				(str_store_item_name, ":ingredient_pos_in_recipe", ":ingredient_id"),#global strings table 1-loop_end ?
				
				#insert commas heh - the last will not be used
				(try_begin),
					(neq, ":ingredient_pos_in_recipe", ":num_of_ingredients"),
					(store_add, ":commas_offset", ":ingredient_pos_in_recipe", 10),
					(str_store_string, ":commas_offset", "str_comma"),
				(try_end),
			(try_end),
			
			(store_skill_level, ":eng_lvl", "skl_engineer", "trp_player"),
			(store_sub, "$g_crafting_time", 10, ":eng_lvl"),
			(try_begin),
				(le, "$g_crafting_time", 0),
				(assign, "$g_crafting_time", 1),
			(try_end),
				(assign, reg0, "$g_crafting_time"),
			
			(str_store_string, s0, "str_want_to_craft_s7"),
			
		],
		[
			(
				"crafting_proceed",
				[],
				"Proceed",
				[
					#just operations cause condidtion checked earlier
					(store_mul, ":recipe_position", "$g_choosen_crafting_id", 10),
					(troop_get_slot, ":num_of_ingredients", "trp_crafting_recipes", ":recipe_position"),
					(store_add, ":loop_end", ":num_of_ingredients", 1),
					(try_for_range, ":ingredient_pos_in_recipe", 1, ":loop_end"),
						(store_add, ":ingredient_pos", ":ingredient_pos_in_recipe", ":recipe_position"),
						(troop_get_slot, ":ingredient_id", "trp_crafting_recipes", ":ingredient_pos"),
						(troop_remove_items, "trp_player", ":ingredient_id", 1),
					(try_end),
					
					(troop_get_slot, ":crafted_item", "trp_crafting_array", "$g_choosen_crafting_id"),
					(troop_add_items, "trp_player", ":crafted_item", 1),
					(change_screen_map),
					(rest_for_hours, "$g_crafting_time", 5, 0),
				],
			),
			
			(
				"back_to_crafting",
				[],
				"Go back",
				[
					(start_presentation, "prsnt_crafting"),
				],
			),
		],		
	),
Rich (BB code):
  #crafting
  ("want_to_craft_s7", "You want to craft {s7} using {s1}{s11}{s2}{s12}{s3}{s13}{s4}{s14}{s5}{s15}{s6}{s16}. This will take {reg0} hours."),
  ("comma", ", "),
Rich (BB code):
#crafting preparing
	(call_script, "script_fill_crafting_recipes"),
Rich (BB code):
#script_fill_crafting_recipes
#and some other crafting preparation
	(
		"fill_crafting_recipes",
		[
		
			#to presentation
			(assign, "$g_show_all_recipes", 0),
		
			#total number of recipes - global
			(assign, "$g_total_number_or_recipes", 7),
			#pre_fill_tables
			(try_for_range, ":cur_crafting", 0, "$g_total_number_or_recipes"),#total number of recipes or greater
				(troop_set_slot, "trp_crafting_array", ":cur_crafting", 0),
			(try_end),
			#for easy computation i set every creafting recipe has 10 (0-9) fields, which
			# 0 - number of items in recipe (say max 6)
			# 1 to 6 inclusive - ids of ingredients
			# 7 to 9 inclusive - other params, I use:
			# 7 - need tools in inventory
			(store_mul, ":crafting_recipes_table_size", "$g_total_number_or_recipes", 10),
			(try_for_range, ":i", 0, ":crafting_recipes_table_size"),
				(troop_set_slot, "trp_crafting_recipes", ":i", 0),
			(try_end),
			
			#here goes recipes !!! import module items
			#club = stick + stones
			#manual calculating values
			(troop_set_slot, "trp_crafting_array", 0, "itm_club"),
			(troop_set_slot, "trp_crafting_recipes", 0, 2), # 0*10
			(troop_set_slot, "trp_crafting_recipes", 1, "itm_wooden_stick"), # 0*10+1
			(troop_set_slot, "trp_crafting_recipes", 2, "itm_stones"), # 0*10+2
			
			#hatchet = staff + iron, needs tools
			#this auxilla variables must be recalculated for every recipe they are used
			(assign, ":recipe_id", 1),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":ingredient_2", ":recipe_location", 2),
			#ingredient_3 ...
			#tools
			(store_add, ":tools_location", ":recipe_location", 7),
			#fill calculated values
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_hatchet"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 2),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_staff"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "itm_iron"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1), #bool
			
			#fur coat = furs, needs tools
			(assign, ":recipe_id", 2),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":tools_location", ":recipe_location", 7),
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_fur_coat"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 1),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_furs"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1),
			
			#khergit_elite_armor = furs + wool + hides + linen + linen_tunic + ragged_outfit, needs tools
			(assign, ":recipe_id", 3),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":ingredient_2", ":recipe_location", 2),
			(store_add, ":ingredient_3", ":recipe_location", 3),
			(store_add, ":ingredient_4", ":recipe_location", 4),
			(store_add, ":ingredient_5", ":recipe_location", 5),
			(store_add, ":ingredient_6", ":recipe_location", 6),
			(store_add, ":tools_location", ":recipe_location", 7),
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_khergit_elite_armor"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 6),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_furs"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "itm_wool"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_3", "itm_raw_leather"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_4", "itm_linen"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_5", "itm_linen_tunic"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_6", "itm_ragged_outfit"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1),
			
			#sarranid_mail_shirt = mail_shirt + skirmicher_armor + dyes + linen + wool
			(assign, ":recipe_id", 4),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":ingredient_2", ":recipe_location", 2),
			(store_add, ":ingredient_3", ":recipe_location", 3),
			(store_add, ":ingredient_4", ":recipe_location", 4),
			(store_add, ":ingredient_5", ":recipe_location", 5),
			(store_add, ":tools_location", ":recipe_location", 7),
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_sarranid_mail_shirt"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 5),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_mail_shirt"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "itm_skirmisher_armor"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_3", "itm_raw_dyes"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_4", "itm_linen"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_5", "itm_wool"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 0),#or just delete this line
			
			#heavy_crossbow = tools + oil + furs + wooden_stick, needs tools (will also consume them)
			(assign, ":recipe_id", 5),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":ingredient_2", ":recipe_location", 2),
			(store_add, ":ingredient_3", ":recipe_location", 3),
			(store_add, ":ingredient_4", ":recipe_location", 4),
			(store_add, ":tools_location", ":recipe_location", 7),
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_heavy_crossbow"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 4),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_tools"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "itm_oil"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_3", "itm_furs"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_4", "itm_wooden_stick"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1),
			
			#siege_crossbow = heavy_crossbow + iron + stones, needs tools
			(assign, ":recipe_id", 6),
			(store_mul, ":recipe_location", ":recipe_id", 10),
			(store_add, ":ingredient_1", ":recipe_location", 1),
			(store_add, ":ingredient_2", ":recipe_location", 2),
			(store_add, ":ingredient_3", ":recipe_location", 3),
			(store_add, ":tools_location", ":recipe_location", 7),
			(troop_set_slot, "trp_crafting_array", ":recipe_id", "itm_sniper_crossbow"),
			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", 3),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "itm_heavy_crossbow"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "itm_iron"),
			(troop_set_slot, "trp_crafting_recipes", ":ingredient_3", "itm_stones"),
			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1),
			

#			#template
#			(assign, ":recipe_id", RECIPE_ID), #remember to increase g_total_number_of_recipes at the beginning of the script
#			(store_mul, ":recipe_location", ":recipe_id", 10),
#			(store_add, ":ingredient_1", ":recipe_location", 1),
#			(store_add, ":ingredient_2", ":recipe_location", 2),
#			(store_add, ":ingredient_3", ":recipe_location", 3),#DELETE UNNECESARY ENTRIES
#			(store_add, ":ingredient_4", ":recipe_location", 4),#THIS MUST BE RECALCULATED FOR EVERY SINGLE RECIPE
#			(store_add, ":ingredient_5", ":recipe_location", 5),
#			(store_add, ":ingredient_6", ":recipe_location", 6),
#			(store_add, ":tools_location", ":recipe_location", 7),
#			(troop_set_slot, "trp_crafting_array", ":recipe_id", "RESULT_ITEM"),
#			(troop_set_slot, "trp_crafting_recipes", ":recipe_location", NUMBER_OF_INGREDIENTS),
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_1", "INGREDIENT_ITEM_1"),
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_2", "INGREDIENT_ITEM_2"),
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_3", "INGREDIENT_ITEM_3"),#DELETE UNNECESARY ENTRIES
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_4", "INGREDIENT_ITEM_4"),
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_5", "INGREDIENT_ITEM_5"),
#			(troop_set_slot, "trp_crafting_recipes", ":ingredient_6", "INGREDIENT_ITEM_6"),
#			(troop_set_slot, "trp_crafting_recipes", ":tools_location", 1),#SET TO 0 OR DELETE IF DOESNT NEED TOOLS

			
		],
	),
As You can see I used some tricks to overcome Module System limitations. There are other ways to do this, some of them can be better. Also Im not sure but with using default compiler the compilation may be need to done twice for rebuilding ids.
Feel free to use it and modify.
 
Last edited:
I have been using this craft since you launched it, congratulations for the work. It serves me very well.
I copied a code from diplomacy "module_game_menus.py" (cheat_find_item_choose_this), and was able to put inside your code and now the engineer level affects the crafted item modifier.
The modification was:

Code:
            (
                "crafting_proceed",
                [],
                "Proceed",
                [
                    #just operations cause condidtion checked earlier
                    (store_mul, ":recipe_position", "$g_choosen_crafting_id", 10),
                    (troop_get_slot, ":num_of_ingredients", "trp_crafting_recipes", ":recipe_position"),
                    (store_add, ":loop_end", ":num_of_ingredients", 1),
                    (try_for_range, ":ingredient_pos_in_recipe", 1, ":loop_end"),
                        (store_add, ":ingredient_pos", ":ingredient_pos_in_recipe", ":recipe_position"),
                        (troop_get_slot, ":ingredient_id", "trp_crafting_recipes", ":ingredient_pos"),
                        (troop_remove_items, "trp_player", ":ingredient_id", 1),
                    (try_end),
               
                    (troop_get_slot, ":crafted_item", "trp_crafting_array", "$g_choosen_crafting_id"),
               
                   #test imod no item
                        (store_skill_level, ":eng_lvl", "skl_engineer", "trp_player"),
                        (try_begin),
                        (ge, ":eng_lvl", 10),
                            (item_get_type, ":i_type", ":crafted_item"),
                          (try_begin),
                            (eq, ":i_type", itp_type_horse),
                            (troop_add_item, "trp_player", ":crafted_item", imod_champion),
                          (else_try),
                            (is_between, ":i_type", itp_type_head_armor, itp_type_pistol),
                            (troop_add_item, "trp_player", ":crafted_item", imod_lordly),
                          (else_try),
                            (eq, ":i_type", itp_type_shield),
                            (troop_add_item, "trp_player", ":crafted_item", imod_reinforced),
                          (else_try),
                            (this_or_next|is_between, ":i_type", itp_type_one_handed_wpn, itp_type_goods),
                            (is_between, ":i_type", itp_type_pistol, itp_type_animal),
                            (troop_add_item, "trp_player", ":crafted_item", imod_masterwork),
                          (else_try),
                            (troop_add_item, "trp_player", ":crafted_item", imod_plain),
                          (try_end),
                        (else_try),
                        (ge, ":eng_lvl", 7),
                        (lt, ":eng_lvl", 10),
                          (item_get_type, ":i_type", ":crafted_item"),
                          (try_begin),
                            (eq, ":i_type", itp_type_horse),
                            (troop_add_item, "trp_player", ":crafted_item", imod_heavy),
                          (else_try),
                            (is_between, ":i_type", itp_type_head_armor, itp_type_pistol),
                            (troop_add_item, "trp_player", ":crafted_item", imod_reinforced),
                          (else_try),
                            (eq, ":i_type", itp_type_shield),
                            (troop_add_item, "trp_player", ":crafted_item", imod_thick),
                          (else_try),
                            (this_or_next|is_between, ":i_type", itp_type_one_handed_wpn, itp_type_goods),
                            (is_between, ":i_type", itp_type_pistol, itp_type_animal),
                            (troop_add_item, "trp_player", ":crafted_item", imod_balanced),
                          (else_try),
                            (troop_add_item, "trp_player", ":crafted_item", imod_thick),
                          (try_end),
                        (else_try),
                        (ge, ":eng_lvl", 4),
                        (lt, ":eng_lvl", 7),
                            (troop_add_item, "trp_player", ":crafted_item", imod_plain),
                        (else_try),
                        (lt, ":eng_lvl", 4),
                            (troop_add_item, "trp_player", ":crafted_item", 1),
                        (try_end),
                    (play_sound,"snd_hammer"),### BONUS, not required
                    # end test
                    #(troop_add_items, "trp_player", ":crafted_item", 1),
                    (change_screen_map),
                    (rest_for_hours, "$g_crafting_time", 5, 0),
                ],
            ),
My logic was the follow up:
skl_engineer < 4 = cracked items
7 < skl_engineer > 3 = no modifier
10 < skl_egineer > 7 = thick, balanced, reinforced, heavy
skl_egineer > 9 = masterwork, reinforced (shields), lordly, champion
I know they are redundances and this code can be improved for this situation, but, i'm not good with codes, however, its a beginning.

Sugestion:
Would be interesting to modify the item "tools" to "max_ammo(500)" and spend "x" of "max_ammo" according the chosen recipe. Of course, i have no idea how to do this.
 
Last edited:
Back
Top Bottom