local cr = {} cr.added = {} cr.index_map = {} cr.overrides = {} cr.new_sections = {} cr.deletions = {} local known_recipe = {} function print_dbg(text, ...) if true then -- printf( "workshop auto: | %s | "..text ,time_global(), ...) end end local function validate_recipe(craft_string) local t = str_explode(craft_string,",") if (#t == 6 or #t == 8 or #t == 10) then local tool = tonumber(t[1]) if tool < 0 or tool > 5 then print_dbg("Invalid tool %s! Must be 0-5", t[1]) return false end if not string.find(t[2], "recipe") then print_dbg("Invalid recipe %s!", t[2]) return false end for i=3,#t,2 do local item = t[i] local amt = tonumber(t[i+1]) if not ini_sys:section_exist(item) then print_dbg("Invalid component %s!", item) return false end if not amt or amt <= 0 then print_dbg("Invalid amount for component %s!", amt) return false end end return true else print_dbg("Invalid length of result table!") return false end end -- Add a new recipe to workshops. You can add as many recipes as you want for an item, the only caveat is you cannot add a recipe with an 'override' (more below). -- Arguments: -- index - Index page of the workshop item (analogous to what page it's on, e.g. 1-6 by default. More can be added with add_index) -- sec - Section of the item to be crafted -- recipe_string - Valid recipe string for the item. Needs to follow the format in craft.ltx e.g. "1, recipe_basic_0, broken_detector,1,prt_i_resistors,8,prt_i_transistors,7,prt_i_capacitors,8" -- returns true on success, false on failure with printed reason function add_new_recipe(index, sec, recipe_string) if index > 6 and not cr.new_sections[index] then return false end if not ini_sys:section_exist(sec) then return false end if not validate_recipe(recipe_string) then return false end if cr.overrides[sec] then print_dbg("Recipe %s already has an override recipe, returning", sec) return false end if not cr.added[sec] then cr.added[sec] = {} cr.index_map[sec] = index end local length = #cr.added[sec] cr.added[sec][length + 1] = recipe_string end -- Delete any existing recipes not added by autoinject (e.g. that were predefined in craft.ltx) function clear_existing_recipes(sec) if not ini_sys:section_exist(sec) then return false end if not cr.deletions[sec] then cr.deletions[sec] = true end return true end -- Specify a crafting recipe that will supersede all other crafting recipes for that item. Arguments similar to above. -- returns true on success, false on failure with printed reason function add_override_recipe(sec, recipe_string, index) if not ini_sys:section_exist(sec) then return false end if not validate_recipe(recipe_string) then return false end if cr.added[sec] then print_dbg("Recipe %s already has additive recipes, returning", sec) return false end if not index then index = 1 end cr.index_map[sec] = index cr.overrides[sec] = recipe_string return true end function remove_existing_recipes(sec) if cr.overrides[sec] then print_dbg("Recipe %s already has an override recipe, returning") return false end cr.overrides[sec] = "none" return true end -- Add a new page in the crafting menu. ID must be greater than 6. First-come, first-serve basis. function add_section(id, name) if id < 7 then print_dbg("Index already exists") return end if not cr.new_sections[id] then cr.new_sections[id] = name return true else print_dbg("Section already exists: %s", cr.new_sections[id]) return false end end -- to bypass encyclopedia function ui_workshop.UIWorkshopCraft:ListRecipes() -- Recipes showcase if is_empty(self.CC["recipe"].cell) then local inv, size_t = {}, 0 for recipe,_ in pairs(GetItemList("recipe")) do size_t = size_t + 1 inv[size_t] = recipe end self.CC["recipe"]:Reinit(inv) end -- Show/hide unlocked/locked recipes items for recipe,_ in pairs(GetItemList("recipe")) do local state = false print_dbg("Checking recipe %s", recipe) if ui_pda_encyclopedia_tab.is_unlocked_note("encyclopedia__notes_" .. recipe) or known_recipe[recipe] then state = true end self.recipes_items[recipe] = state end for idx,ci in pairs(self.CC["recipe"].cell) do if ci:IsShown() then if self.recipes_items[ci.section] then ci:Colorize("def") else ci:Colorize("hide") end end end end function ui_workshop.UIWorkshopCraft:LoadRecipes() -- Less parts on achievement local ach = 0 if (game_achievements.has_achievement("artificer_eagerness")) then ach = 1 end local ind = 1 local ini = itms_manager.ini_craft while ini:section_exist(tostring(ind)) do local ind_str = tostring(ind) local n = ini:line_count(ind_str) or 0 self.recipes[ind] = {} for i=0, n-1 do local result, id, value = ini:r_line(ind_str , i , "", "") if (id == "title") then self.recipes_type[ind] = value end id = string.sub(id,3) -- hijack and replace if cr.overrides[id] then print_dbg("UIWorkshop - Hijacking recipe for %s", id) local craft_string = cr.overrides[id] if craft_string then -- if craft_string ~= "override" then -- print_dbg("Craft recipe for %s is %s", id, craft_string) -- local t = str_explode(craft_string,",") -- add_recipe(self.recipes, ind, t, ach, id) -- end else local t = str_explode(value,",") add_recipe(self.recipes, ind, t, ach, id) end elseif cr.deletions[id] then -- do nothing lel elseif ini_sys:section_exist(id) then local t = str_explode(value,",") add_recipe(self.recipes, ind, t, ach, id) elseif (id ~= "tle") then printe("! UIWorkshopCraft:LoadRecipes() | section [%s] not found!",id) end end ind = ind + 1 end for k,v in pairs(cr.new_sections) do self.recipes_type[k] = v self.recipes[k] = {} end for section,craft_string in pairs(cr.overrides) do if craft_string ~= "override" then local index = cr.index_map[section] local t = str_explode(craft_string,",") add_recipe(self.recipes, index, t, ach, section) end end for section,recipes in pairs(cr.added) do local index = cr.index_map[section] for x,craft_string in pairs(recipes) do local t = str_explode(craft_string, ",") add_recipe(self.recipes, index, t, ach, section) end end for i=1,#self.recipes_type do local _itm = ui_workshop.list_element(i, self.recipes_type[i]) self.list_menu:AddExistingItem(_itm) end end function item_recipe.UIRecipe:LoadRecipes() local ini_craft = itms_manager.ini_craft -- Less parts on achievement local ach = 0 if (game_achievements.has_achievement("artificer_eagerness")) then ach = 1 end local ind = 1 while ini_craft:section_exist(tostring(ind)) do local ind_str = tostring(ind) local n = ini_craft:line_count(ind_str) or 0 for i=0, n-1 do local result, id, value = ini_craft:r_line(ind_str , i , "", "") id = string.sub(id,3) if cr.overrides[id] then print_dbg("UIWorkshop - Hijacking recipe for %s", id) local craft_string = cr.overrides[id] if craft_string then if craft_string ~= "override" then print_dbg("Craft recipe for %s is %s", id, craft_string) local t = str_explode(craft_string,",") add_recipe_ui(self.recipes, self.section ,self.toolkit, t, ach, id) end else local t = str_explode(value,",") add_recipe_ui(self.recipes, self.section ,self.toolkit, t, ach, id) end elseif ini_sys:section_exist(id) then local t = str_explode(value,",") add_recipe_ui(self.recipes, self.section ,self.toolkit, t, ach, id) elseif (id ~= "tle") then printe("! workshop_craft_ui:LoadRecipes() | section [%s] not found!",id) end end ind = ind + 1 end for section,recipes in pairs(cr.added) do local index = cr.index_map[section] for x,craft_string in pairs(recipes) do local t = str_explode(craft_string, ",") print_dbg("(Section %s) Adding for %s custom recipe %s", self.section, section, craft_string) add_recipe_ui(self.recipes, self.section ,self.toolkit, t, ach, section) end end end function item_recipe.func_recipe(obj) local sec = obj:section() print_dbg("intercept recipe %s", sec) if (not IsItem("recipe",sec)) then return end if (not ui_pda_encyclopedia_tab.is_unlocked_note("encyclopedia__notes_" .. sec)) then SendScriptCallback("actor_on_interaction", "notes", nil, sec) --alife_release(obj) else actor_menu.set_msg(1, game.translate_string("st_recipe_is_known"),3) end -- add to backup cache as well if not known_recipe[sec] then print_dbg("Adding %s to backup cache", sec) known_recipe[sec] = true end -- effect local hud = get_hud() if (hud) then hide_hud_inventory() end item_recipe.start(sec) end --recipes, workshop section, table of requirements, achievement, item section function add_recipe(recipes, ind, t, ach, id) if (#t == 6) or (#t == 8) or (#t == 10) then if not recipes[ind] then recipes[ind] = {} end local x = #recipes[ind] + 1 recipes[ind][x] = {} recipes[ind][x].sec = id recipes[ind][x].tool = tonumber(t[1]) or 1 recipes[ind][x].rsp = t[2] if t[3] and t[4] then -- support item 1 if ini_sys:section_exist(tostring(t[3])) then local amt = tonumber(t[4]) recipes[ind][x][1] = {tostring(t[3]), (amt > 4) and (amt - ach) or amt} else printe("! Workshop UI craft | componenet section [%s] not found for [%s] recipe!", tostring(t[3]), id) end end if t[5] and t[6] then -- support item 2 if ini_sys:section_exist(tostring(t[5])) then local amt = tonumber(t[6]) recipes[ind][x][2] = {tostring(t[5]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[5]), id) end end if t[7] and t[8] then -- support item 3 if ini_sys:section_exist(tostring(t[7])) then local amt = tonumber(t[8]) recipes[ind][x][3] = {tostring(t[7]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[7]), id) end end if t[9] and t[10] then -- support item 4 if ini_sys:section_exist(tostring(t[9])) then local amt = tonumber(t[10]) recipes[ind][x][4] = {tostring(t[9]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[9]), id) end end end end function add_recipe_ui(recipes, section, toolkit, t, ach, id) if ((#t == 6) or (#t == 8) or (#t == 10) )and (t[2] == section) then local x = #recipes + 1 recipes[x] = {} recipes[x].sec = id toolkit = ui_workshop.workshop_toolkits[tonumber(t[1]) or 1] if t[3] and t[4] then -- support item 1 if ini_sys:section_exist(tostring(t[3])) then local amt = tonumber(t[4]) recipes[x][1] = {tostring(t[3]), (amt > 4) and (amt - ach) or amt} else printe("! Workshop UI craft | componenet section [%s] not found for [%s] recipe!", tostring(t[3]), id) end end if t[5] and t[6] then -- support item 2 if ini_sys:section_exist(tostring(t[5])) then local amt = tonumber(t[6]) recipes[x][2] = {tostring(t[5]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[5]), id) end end if t[7] and t[8] then -- support item 3 if ini_sys:section_exist(tostring(t[7])) then local amt = tonumber(t[8]) recipes[x][3] = {tostring(t[7]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[7]), id) end end if t[9] and t[10] then -- support item 4 if ini_sys:section_exist(tostring(t[9])) then local amt = tonumber(t[10]) recipes[x][4] = {tostring(t[9]), (amt > 4) and (amt - ach) or amt} else printe("! UIWorkshopCraft:LoadRecipes() | componenet section [%s] not found for [%s] recipe!", tostring(t[9]), id) end end end end local function save_state(mdata) mdata.known_recipe = known_recipe end function load_state(mdata) known_recipe = mdata.known_recipe or {} end function on_game_start() RegisterScriptCallback("save_state",save_state) RegisterScriptCallback("load_state",load_state) end