Divergent/mods/Zone Recycle Bin/gamedata/scripts/workshop_autoinject.script

401 lines
14 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
cr = {}
cr.added = {}
cr.index_map = {}
cr.overrides = {}
cr.new_sections = {}
cr.deletions = {}
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
WSLoadRecipes = ui_workshop.UIWorkshopCraft.LoadRecipes
function ui_workshop.UIWorkshopCraft:LoadRecipes()
if is_empty(cr.added) and is_empty(cr.overrides) then
WSLoadRecipes(self)
return
end
-- 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
UILoadRecipes = item_recipe.UIRecipe.LoadRecipes
function item_recipe.UIRecipe:LoadRecipes()
if is_empty(cr.added) and is_empty(cr.overrides) then
UILoadRecipes(self)
return
end
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
FuncRecipe = item_recipe.func_recipe
function item_recipe.func_recipe(obj)
local sec = obj:section()
-- 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
FuncRecipe(obj)
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
-- inject to ui
-- local craft_exist = itms_manager.ini_craft.section_exist
-- local craft_count = itms_manager.ini_craft.line_count
-- local craft_line = itms_manager.ini_craft.r_line
-- itms_manager.ini_craft.line_count = function(index)
-- end
function on_game_start()
RegisterScriptCallback("save_state",save_state)
RegisterScriptCallback("load_state",load_state)
end