From 2761f4cb2cbaff5b5c97133ffa7bd9911539de25 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 13:57:33 -0700 Subject: [PATCH 1/8] add pass/fail returns to technology meta functions --- lib/metas/technology.lua | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/metas/technology.lua b/lib/metas/technology.lua index 8961856..057484f 100644 --- a/lib/metas/technology.lua +++ b/lib/metas/technology.lua @@ -39,7 +39,7 @@ metas.add_prereq = function(self, prereq_technology_name) local prereq_technology = data.raw.technology[prereq_technology_name] if not prereq_technology then log("WARNING @ \'" .. self.name .. "\':add_prereq(): Technology " .. prereq_technology_name .. " does not exist") - return self + return self, false -- add prereq failed end if not self.prerequisites then @@ -48,35 +48,46 @@ metas.add_prereq = function(self, prereq_technology_name) for _, prereq in pairs(self.prerequisites) do if prereq == prereq_technology_name then - return + return self, true -- should it be true? false? its already in the tech end end self.prerequisites[#self.prerequisites + 1] = prereq_technology_name - return self + return self, true -- add prereq succeeds end metas.remove_prereq = function(self, prereq_technology_name) if not self.prerequisites then - return self + return self, true -- should it be true? false? end - self.prerequisites = table.filter(self.prerequisites, function(prereq) return prereq ~= prereq_technology_name end) + for i, prereq in pairs(self.prerequisites) do + if prereq == prereq_technology_name then + table.remove(self.prerequisites, i) + return self, true -- remove prereq succeeds + end + end - return self + return self, false -- remove prereq fails end metas.remove_pack = function(self, science_pack_name) if not self.unit then - return self + return self, true -- should it be true? false? end - self.unit.ingredients = table.filter(self.unit.ingredients, function(ingredient) return ingredient[1] ~= science_pack_name end) + for i, ingredient in pairs(self.unit.ingredients) do + if ingredient[1] == science_pack_name then + table.remove(self.unit.ingredients, i) + return self, true -- remove pack succeeds + end + end - return self + return self, false -- remove pack fails end +-- possible to add the same pack twice, should probably check for that metas.add_pack = function(self, science_pack_name) if self.research_trigger then error("WARNING @ \'" .. self.name .. "\':add_pack(): Attempted to add science packs to technology with research_trigger.") @@ -88,7 +99,7 @@ metas.add_pack = function(self, science_pack_name) table.insert(self.unit.ingredients, {science_pack_name, 1}) - return self + return self, true -- always succeeds end return metas From 24b60a541046c3929de4515ad440d3d286792f83 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 14:59:02 -0700 Subject: [PATCH 2/8] annotations --- lib/metas/technology.lua | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/metas/technology.lua b/lib/metas/technology.lua index 057484f..78fdbad 100644 --- a/lib/metas/technology.lua +++ b/lib/metas/technology.lua @@ -35,6 +35,10 @@ metas.standardize = function(self) return self end +---@param self table +---@param prereq_technology_name string +---@return table self +---@return boolean success metas.add_prereq = function(self, prereq_technology_name) local prereq_technology = data.raw.technology[prereq_technology_name] if not prereq_technology then @@ -57,6 +61,10 @@ metas.add_prereq = function(self, prereq_technology_name) return self, true -- add prereq succeeds end +---@param self table +---@param prereq_technology_name string +---@return table self +---@return boolean success metas.remove_prereq = function(self, prereq_technology_name) if not self.prerequisites then return self, true -- should it be true? false? @@ -72,6 +80,10 @@ metas.remove_prereq = function(self, prereq_technology_name) return self, false -- remove prereq fails end +---@param self table +---@param science_pack_name string +---@return table self +---@return boolean success metas.remove_pack = function(self, science_pack_name) if not self.unit then return self, true -- should it be true? false? @@ -88,6 +100,10 @@ metas.remove_pack = function(self, science_pack_name) end -- possible to add the same pack twice, should probably check for that +---@param self table +---@param science_pack_name string +---@return table self +---@return boolean success metas.add_pack = function(self, science_pack_name) if self.research_trigger then error("WARNING @ \'" .. self.name .. "\':add_pack(): Attempted to add science packs to technology with research_trigger.") @@ -97,9 +113,15 @@ metas.add_pack = function(self, science_pack_name) self.unit = {ingredients = {}} end + for _, ingredient in pairs(self.unit.ingredients) do + if ingredient[1] == science_pack_name then + return self, true -- add pack fails, it already exists + end + end + table.insert(self.unit.ingredients, {science_pack_name, 1}) - return self, true -- always succeeds + return self, true -- add pack succeeds end return metas From 98036f79452fa5ed0c3b144d3f51efae09c8a576 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 15:30:25 -0700 Subject: [PATCH 3/8] add RECIPE().clear_results --- lib/metas/recipe.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/metas/recipe.lua b/lib/metas/recipe.lua index 86ada2e..0525e1a 100644 --- a/lib/metas/recipe.lua +++ b/lib/metas/recipe.lua @@ -272,7 +272,12 @@ end metas.clear_ingredients = function(self) self.ingredients = {} - return self + return self, true -- impossible to fail +end + +metas.clear_results = function(self) + self.ingredients = {} + return self, true -- impossible to fail end metas.multiply_result_amount = function(self, result_name, percent) From 7c1ce9010b427d10fb58724c7a49988638e1d506 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 15:33:06 -0700 Subject: [PATCH 4/8] formatting --- lib/metas/technology.lua | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/metas/technology.lua b/lib/metas/technology.lua index 78fdbad..018516a 100644 --- a/lib/metas/technology.lua +++ b/lib/metas/technology.lua @@ -46,9 +46,7 @@ metas.add_prereq = function(self, prereq_technology_name) return self, false -- add prereq failed end - if not self.prerequisites then - self.prerequisites = {} - end + self.prerequisites = self.prerequisites or {} for _, prereq in pairs(self.prerequisites) do if prereq == prereq_technology_name then @@ -90,10 +88,10 @@ metas.remove_pack = function(self, science_pack_name) end for i, ingredient in pairs(self.unit.ingredients) do - if ingredient[1] == science_pack_name then - table.remove(self.unit.ingredients, i) - return self, true -- remove pack succeeds - end + if ingredient[1] == science_pack_name then + table.remove(self.unit.ingredients, i) + return self, true -- remove pack succeeds + end end return self, false -- remove pack fails @@ -109,14 +107,12 @@ metas.add_pack = function(self, science_pack_name) error("WARNING @ \'" .. self.name .. "\':add_pack(): Attempted to add science packs to technology with research_trigger.") end - if not self.unit then - self.unit = {ingredients = {}} - end + self.unit = self.unit or {ingredients = {}} for _, ingredient in pairs(self.unit.ingredients) do - if ingredient[1] == science_pack_name then - return self, true -- add pack fails, it already exists - end + if ingredient[1] == science_pack_name then + return self, true -- add pack fails, it already exists + end end table.insert(self.unit.ingredients, {science_pack_name, 1}) From f19254496bac7ee6feac40068954cc6d71851f1d Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 16:01:56 -0700 Subject: [PATCH 5/8] recipe metas, and a few bugfixes --- lib/metas/recipe.lua | 207 ++++++++++++++++++++++++++++++++----------- 1 file changed, 154 insertions(+), 53 deletions(-) diff --git a/lib/metas/recipe.lua b/lib/metas/recipe.lua index 0525e1a..e1c2af8 100644 --- a/lib/metas/recipe.lua +++ b/lib/metas/recipe.lua @@ -81,60 +81,84 @@ py.allow_productivity = function(recipe_names) end end +---@param self table +---@param technology_name string|table +---@return table self +---@return boolean success metas.add_unlock = function(self, technology_name) if type(technology_name) == "table" then + local success = true for _, tech in pairs(technology_name) do - self:add_unlock(tech) + _, this_success = self:add_unlock(tech) + success = success and this_success -- if any addition fails, the whole check fails end - return self + return self, success end local technology = data.raw.technology[technology_name] if not technology then log("WARNING @ \'" .. self.name .. "\':add_unlock(): Technology " .. technology_name .. " does not exist") - return self + return self, false -- fails, tech does not exist end - if not technology.effects then - technology.effects = {} + technology.effects = technology.effects or {} + + -- skip adding unlocks twice + for _, effect in pairs(technology.effects) do + if effect.type == "unlock-recipe" and effect.recipe == self.name then + return self, false -- fails, already in tech + end end table_insert(technology.effects, {type = "unlock-recipe", recipe = self.name}) self.enabled = false - return self + return self, true end +---@param self table +---@param technology_name string|table +---@return table self +---@return boolean success metas.remove_unlock = function(self, technology_name) if type(technology_name) == "table" then + local success = true for _, tech in pairs(technology_name) do - self:remove_unlock(tech) + local _, this_success = self:remove_unlock(tech) + success = success and this_success end - return self + return self, success -- if any removal fails, the whole check fails end local technology = data.raw.technology[technology_name] if not technology then log("WARNING @ \'" .. self.name .. "\':remove_unlock(): Technology " .. technology_name .. " does not exist") - return self + return self, false -- fails, tech does not exist + elseif not technology.effects then + return self, false -- tech effects do not exist end - if not technology.effects then - return self + for i, effect in pairs(technology.effects) do + if effect.recipe == self.name then + table.remove(technology.effects, i) + return self, true -- successfully removed recipe from tech + end end - technology.effects = table.filter(technology.effects, function(effect) - return effect.recipe ~= self.name - end) - - return self + return self, false -- recipe not part of tech end +---@param self table +---@param technology_old string|table +---@param technology_new string|table +---@return table self +---@return boolean success metas.replace_unlock = function(self, technology_old, technology_new) - self:remove_unlock(technology_old):add_unlock(technology_new) + local _, success_remove = self:remove_unlock(technology_old) + local _, success_add = self:add_unlock(technology_new) - return self + return self, success_remove and success_add -- fails if either fails end do @@ -144,7 +168,7 @@ do if type == "string" then if not FLUID[new] and not ITEM[new] and not unsafe then log("WARNING @ \'" .. recipe.name .. "\':replace_ingredient(): Ingredient " .. new .. " does not exist") - return + return false end for _, ingredient in pairs(ingredients_or_results) do if ingredient.name == old then @@ -164,7 +188,7 @@ do new = table.deepcopy(new) if not FLUID[new.name] and not ITEM[new.name] and not unsafe then log("WARNING @ \'" .. recipe.name .. "\':replace_ingredient(): Ingredient " .. new.name .. " does not exist") - return + return false end for k, ingredient in pairs(ingredients_or_results) do if ingredient.name == old then @@ -172,39 +196,68 @@ do end end end + return true -- must have been a success! cant early return on success because of possible repeated results end + ---@param self table + ---@param old_ingredient string + ---@param new_ingredient string|table + ---@param new_amount? int + ---@return table self + ---@return boolean success metas.replace_ingredient = function(self, old_ingredient, new_ingredient, new_amount) self:standardize() - replacement_helper(self, self.ingredients, old_ingredient, new_ingredient, new_amount, false) - return self + local success = replacement_helper(self, self.ingredients, old_ingredient, new_ingredient, new_amount, false) + return self, success end + ---@param self table + ---@param old_ingredient string + ---@param new_ingredient string|table + ---@param new_amount? int + ---@return table self + ---@return boolean success metas.replace_ingredient_unsafe = function(self, old_ingredient, new_ingredient, new_amount) self:standardize() - replacement_helper(self, self.ingredients, old_ingredient, new_ingredient, new_amount, true) - return self + local success = replacement_helper(self, self.ingredients, old_ingredient, new_ingredient, new_amount, true) + return self, success end + ---@param self table + ---@param old_result string + ---@param new_result string|table + ---@param new_amount? int + ---@return table self + ---@return boolean success metas.replace_result = function(self, old_result, new_result, new_amount) self:standardize() - replacement_helper(self, self.results, old_result, new_result, new_amount, false) + local success = replacement_helper(self, self.results, old_result, new_result, new_amount, false) if self.main_product == old_result then self.main_product = type(new_result) == "string" and new_result or new_result[1] or new_result.name end - return self + return self, success end + ---@param self table + ---@param old_result string + ---@param new_result string|table + ---@param new_amount? int + ---@return table self + ---@return boolean success metas.replace_result_unsafe = function(self, old_result, new_result, new_amount) self:standardize() - replacement_helper(self, self.results, old_result, new_result, new_amount, true) + local success = replacement_helper(self, self.results, old_result, new_result, new_amount, true) if self.main_product == old_result then self.main_product = type(new_result) == "string" and new_result or new_result[1] or new_result.name end - return self + return self, success end end +---@param self table +---@param ingredient data.IngredientPrototype +---@return table self +---@return boolean success metas.add_ingredient_unsafe = function(self, ingredient) self:standardize() -- Ensure that this ingredient does not already exist in this recipe. @@ -213,8 +266,8 @@ metas.add_ingredient_unsafe = function(self, ingredient) if existing.name == ingredient.name and existing.type == ingredient.type then if existing.amount and ingredient.amount then existing.amount = existing.amount + ingredient.amount - existing.ignored_by_productivity = (existing.ignored_by_productivity or 0) + (ingredient.ignored_by_productivity or 0) - return self + existing.ignored_by_stats = (existing.ignored_by_stats or 0) + (ingredient.ignored_by_stats or 0) + return self, true end end end @@ -224,25 +277,37 @@ metas.add_ingredient_unsafe = function(self, ingredient) end table_insert(self.ingredients, ingredient) - return self + return self, true end +---@param self table +---@param ingredient data.IngredientPrototype +---@return table self +---@return boolean success metas.add_ingredient = function(self, ingredient) self:standardize() if not FLUID[ingredient.name] and not ITEM[ingredient.name] then log("WARNING @ \'" .. self.name .. "\':add_ingredient(): Ingredient " .. ingredient.name .. " does not exist") - return self + return self, false end return metas.add_ingredient_unsafe(self, ingredient) end +---@param self table +---@param result data.ProductPrototype +---@return table self +---@return boolean success metas.add_result = function(self, result) self:standardize() table_insert(self.results, result) - return self + return self, true end +---@param self table +---@param ingredient_name string +---@return table self +---@return int amount_removed metas.remove_ingredient = function(self, ingredient_name) self:standardize() local amount_removed = 0 @@ -256,6 +321,10 @@ metas.remove_ingredient = function(self, ingredient_name) return self, amount_removed end +---@param self table +---@param result_name string +---@return table self +---@return int amount_removed metas.remove_result = function(self, result_name) self:standardize() local amount_removed = 0 @@ -280,6 +349,11 @@ metas.clear_results = function(self) return self, true -- impossible to fail end +---@param self table +---@param result_name string +---@param percent float +---@return table self +---@return boolean success metas.multiply_result_amount = function(self, result_name, percent) self:standardize() @@ -289,18 +363,23 @@ metas.multiply_result_amount = function(self, result_name, percent) result.amount = math.ceil(amount * percent) if result.amount == 0 then self:remove_result(result_name) - return + return self, true -- successful multiply end result.amount_min = nil result.amount_max = nil - return self + return self, true -- successful multiply end end log("WARNING @ \'" .. self.name .. "\':multiply_result_amount(): Result " .. result_name .. " not found") - return self + return self, false -- could not find result end +---@param self table +---@param ingredient_name string +---@param percent float +---@return table self +---@return boolean success metas.multiply_ingredient_amount = function(self, ingredient_name, percent) self:standardize() @@ -309,72 +388,94 @@ metas.multiply_ingredient_amount = function(self, ingredient_name, percent) ingredient.amount = math.ceil(ingredient.amount * percent) if ingredient.amount == 0 then self:remove_ingredient(ingredient_name) - return + return self, true -- successful multiply end - return self + return self, true -- successful multiply end end log("WARNING @ \'" .. self.name .. "\':multiply_ingredient_amount(): Ingredient " .. ingredient_name .. " not found") - return self + return self, false -- could not find ingredient end +---@param self table +---@param result_name string +---@param increase int +---@return table self +---@return boolean success metas.add_result_amount = function(self, result_name, increase) self:standardize() for _, result in pairs(self.results) do if result.name == result_name then result.amount = result.amount + increase - if result.amount == 0 then + if result.amount <= 0 then self:remove_result(result_name) - return + return self, true -- successful addition end - return self + return self, true -- successful addition end end log("WARNING @ \'" .. self.name .. "\':add_result_amount(): Result " .. result_name .. " not found") - return self + return self, false -- could not find result end +---@param self table +---@param ingredient_name string +---@param increase int +---@return table self +---@return boolean success metas.add_ingredient_amount = function(self, ingredient_name, increase) self:standardize() for _, ingredient in pairs(self.ingredients) do if ingredient.name == ingredient_name then ingredient.amount = ingredient.amount + increase - if ingredient.amount == 0 then + if ingredient.amount <= 0 then self:remove_ingredient(ingredient_name) - return + return self, true -- successful addition end - return self + return self, true -- successful addition end end log("WARNING @ \'" .. self.name .. "\':add_ingredient_amount(): Ingredient " .. ingredient_name .. " not found") - return self + return self, false -- could not find ingredient end +---@param self table +---@param result_name string +---@param amount int +---@return table self +---@return boolean success metas.set_result_amount = function(self, result_name, amount) - self:replace_result(result_name, result_name, amount) - return self + return self:replace_result(result_name, result_name, amount) end +---@param self table +---@param ingredient_name string +---@param amount int +---@return table self +---@return boolean success metas.set_ingredient_amount = function(self, ingredient_name, amount) - self:replace_ingredient(ingredient_name, ingredient_name, amount) - return self + return self:replace_ingredient(ingredient_name, ingredient_name, amount) end +---@param self table +---@param category_name string +---@return table self +---@return boolean success metas.change_category = function(self, category_name) self:standardize() if data.raw["recipe-category"][category_name] then self.category = category_name + return self, true -- successful set else log("WARNING @ \'" .. self.name .. "\':change_category(): Category " .. category_name .. " not found") + return self, false -- category does not exist end - - return self end --- Get the prototype for the main_product using the same logic the game uses. From ccc8167f389426aad44bfb1e60d3fa582eb3bbf5 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 16:07:53 -0700 Subject: [PATCH 6/8] item metas --- lib/metas/item.lua | 38 +++++++++++++++++++++++++++++++------- lib/metas/recipe.lua | 6 +++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/metas/item.lua b/lib/metas/item.lua index 4f9a1fc..b78d52a 100644 --- a/lib/metas/item.lua +++ b/lib/metas/item.lua @@ -36,20 +36,39 @@ ITEM = setmetatable({}, { local metas = {} +---@param self table +---@param flag string +---@return table self +---@return boolean success metas.add_flag = function(self, flag) - if not self.flags then self.flags = {} end + self.flags = self.flags or {} + for _, f in pairs(self.flags) do + if f == flag then + return self, false -- flag already exists + end + end table.insert(self.flags, flag) - return self + return self, true -- flag added end +---@param self table +---@param flag string +---@return table self +---@return boolean success metas.remove_flag = function(self, flag) - if not self.flags then return self end + if not self.flags then return self, false end for i, f in pairs(self.flags) do - if f == flag then table.remove(self.flags, i) end + if f == flag then + table.remove(self.flags, i) + return self, true -- flag found and removed + end end - return self + return self, false -- could not find flag end +---@param self table +---@param flag string +---@return boolean has_flag metas.has_flag = function(self, flag) if not self.flags then return false end for _, f in pairs(self.flags) do @@ -82,8 +101,13 @@ py.spoil_triggers = { end } +---@param self table +---@param spoil_result string|table +---@param spoil_ticks int +---@return table self +---@return boolean success metas.spoil = function(self, spoil_result, spoil_ticks) - if not feature_flags.spoiling then return end + if not feature_flags.spoiling then return self, false end -- spoilage is off if not spoil_ticks then error("No spoil ticks provided for item " .. self.name) end if type(spoil_result) == "string" then @@ -96,7 +120,7 @@ metas.spoil = function(self, spoil_result, spoil_ticks) self.spoil_ticks = spoil_ticks - return self + return self, true end return metas diff --git a/lib/metas/recipe.lua b/lib/metas/recipe.lua index e1c2af8..639eeae 100644 --- a/lib/metas/recipe.lua +++ b/lib/metas/recipe.lua @@ -105,9 +105,9 @@ metas.add_unlock = function(self, technology_name) -- skip adding unlocks twice for _, effect in pairs(technology.effects) do - if effect.type == "unlock-recipe" and effect.recipe == self.name then - return self, false -- fails, already in tech - end + if effect.type == "unlock-recipe" and effect.recipe == self.name then + return self, false -- fails, already in tech + end end table_insert(technology.effects, {type = "unlock-recipe", recipe = self.name}) From 415b122f8eb433464789669c8a7f2436859dd0a6 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 16:11:57 -0700 Subject: [PATCH 7/8] entity metas --- lib/metas/entity.lua | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/metas/entity.lua b/lib/metas/entity.lua index bb6d0a6..b94edd7 100644 --- a/lib/metas/entity.lua +++ b/lib/metas/entity.lua @@ -57,20 +57,39 @@ metas.standardize = function(self) return self end +---@param self table +---@param flag string +---@return table self +---@return boolean success metas.add_flag = function(self, flag) - if not self.flags then self.flags = {} end + self.flags = self.flags or {} + for _, f in pairs(self.flags) do + if f == flag then + return self, false -- flag already exists + end + end table.insert(self.flags, flag) - return self + return self, true -- flag added end +---@param self table +---@param flag string +---@return table self +---@return boolean success metas.remove_flag = function(self, flag) - if not self.flags then return self end + if not self.flags then return self, false end for i, f in pairs(self.flags) do - if f == flag then table.remove(self.flags, i) end + if f == flag then + table.remove(self.flags, i) + return self, true -- flag found and removed + end end - return self + return self, false -- could not find flag end +---@param self table +---@param flag string +---@return boolean has_flag metas.has_flag = function(self, flag) if not self.flags then return false end for _, f in pairs(self.flags) do From 32d782106646ede3bbd1173f84a04135621968e6 Mon Sep 17 00:00:00 2001 From: protocol-1903 Date: Sun, 7 Dec 2025 23:44:44 -0700 Subject: [PATCH 8/8] make luals hate me less --- lib/metas/entity.lua | 20 +++--- lib/metas/fluid.lua | 1 + lib/metas/item.lua | 24 +++---- lib/metas/recipe.lua | 142 ++++++++++++++++++++------------------- lib/metas/technology.lua | 19 +++--- lib/metas/tile.lua | 1 + 6 files changed, 105 insertions(+), 102 deletions(-) diff --git a/lib/metas/entity.lua b/lib/metas/entity.lua index b94edd7..32e4681 100644 --- a/lib/metas/entity.lua +++ b/lib/metas/entity.lua @@ -1,12 +1,12 @@ local collision_mask_util = require "__core__/lualib/collision-mask-util" +local entity_types = defines.prototypes.entity + ---@class data.EntityPrototype ----@field public standardize fun(self: data.EntityPrototype): data.EntityPrototype ----@field public add_flag fun(self: data.EntityPrototype, flag: string): data.EntityPrototype ----@field public remove_flag fun(self: data.EntityPrototype, flag: string): data.EntityPrototype +---@field public standardize fun(self: data.EntityPrototype): data.EntityPrototype, boolean +---@field public add_flag fun(self: data.EntityPrototype, flag: string): data.EntityPrototype, boolean +---@field public remove_flag fun(self: data.EntityPrototype, flag: string): data.EntityPrototype, boolean ---@field public has_flag fun(self: data.EntityPrototype, flag: string): boolean - -local entity_types = defines.prototypes.entity ENTITY = setmetatable({}, { ---@param entity data.EntityPrototype __call = function(self, entity) @@ -57,9 +57,9 @@ metas.standardize = function(self) return self end ----@param self table +---@param self data.EntityPrototype ---@param flag string ----@return table self +---@return data.EntityPrototype self ---@return boolean success metas.add_flag = function(self, flag) self.flags = self.flags or {} @@ -72,9 +72,9 @@ metas.add_flag = function(self, flag) return self, true -- flag added end ----@param self table +---@param self data.EntityPrototype ---@param flag string ----@return table self +---@return data.EntityPrototype self ---@return boolean success metas.remove_flag = function(self, flag) if not self.flags then return self, false end @@ -87,7 +87,7 @@ metas.remove_flag = function(self, flag) return self, false -- could not find flag end ----@param self table +---@param self data.EntityPrototype ---@param flag string ---@return boolean has_flag metas.has_flag = function(self, flag) diff --git a/lib/metas/fluid.lua b/lib/metas/fluid.lua index 186d03b..84452d3 100644 --- a/lib/metas/fluid.lua +++ b/lib/metas/fluid.lua @@ -1,3 +1,4 @@ +---@class data.FluidPrototype FLUID = setmetatable(data.raw.fluid, { ---@param fluid data.FluidPrototype __call = function(self, fluid) diff --git a/lib/metas/item.lua b/lib/metas/item.lua index b78d52a..ef12629 100644 --- a/lib/metas/item.lua +++ b/lib/metas/item.lua @@ -1,10 +1,10 @@ +local item_prototypes = defines.prototypes.item + ---@class data.ItemPrototype ----@field public add_flag fun(self: data.ItemPrototype, flag: string): data.ItemPrototype ----@field public remove_flag fun(self: data.ItemPrototype, flag: string): data.ItemPrototype +---@field public add_flag fun(self: data.ItemPrototype, flag: string): data.ItemPrototype, boolean +---@field public remove_flag fun(self: data.ItemPrototype, flag: string): data.ItemPrototype, boolean ---@field public has_flag fun(self: data.ItemPrototype, flag: string): boolean ----@field public spoil fun(self: data.ItemPrototype, spoil_result: (string | table), spoil_ticks: number): data.ItemPrototype - -local item_prototypes = defines.prototypes.item +---@field public spoil fun(self: data.ItemPrototype, spoil_result: (string | table), spoil_ticks: number): data.ItemPrototype, boolean ITEM = setmetatable({}, { ---@param item data.ItemPrototype __call = function(self, item) @@ -36,9 +36,9 @@ ITEM = setmetatable({}, { local metas = {} ----@param self table +---@param self data.ItemPrototype ---@param flag string ----@return table self +---@return data.ItemPrototype self ---@return boolean success metas.add_flag = function(self, flag) self.flags = self.flags or {} @@ -51,9 +51,9 @@ metas.add_flag = function(self, flag) return self, true -- flag added end ----@param self table +---@param self data.ItemPrototype ---@param flag string ----@return table self +---@return data.ItemPrototype self ---@return boolean success metas.remove_flag = function(self, flag) if not self.flags then return self, false end @@ -66,7 +66,7 @@ metas.remove_flag = function(self, flag) return self, false -- could not find flag end ----@param self table +---@param self data.ItemPrototype ---@param flag string ---@return boolean has_flag metas.has_flag = function(self, flag) @@ -101,8 +101,8 @@ py.spoil_triggers = { end } ----@param self table ----@param spoil_result string|table +---@param self data.ItemPrototype +---@param spoil_result string|data.SpoilToTriggerResult ---@param spoil_ticks int ---@return table self ---@return boolean success diff --git a/lib/metas/recipe.lua b/lib/metas/recipe.lua index 639eeae..c6f9cd9 100644 --- a/lib/metas/recipe.lua +++ b/lib/metas/recipe.lua @@ -2,32 +2,31 @@ local table_insert = table.insert --unsafe functions overrides protections for ingredient/result existence +local metas = {} + ---@class data.RecipePrototype ---@field public standardize fun(self: data.RecipePrototype): data.RecipePrototype ----@field public add_unlock fun(self: data.RecipePrototype, technology_name: string | string[]): data.RecipePrototype ----@field public remove_unlock fun(self: data.RecipePrototype, technology_name: string | string[]): data.RecipePrototype ----@field public replace_unlock fun(self: data.RecipePrototype, technology_old: string | string[], technology_new: string | string[]): data.RecipePrototype ----@field public replace_ingredient fun(self: data.RecipePrototype, old_ingredient: string, new_ingredient: string | data.IngredientPrototype, new_amount: integer?): data.RecipePrototype ----@field public replace_ingredient_unsafe fun(self: data.RecipePrototype, old_ingredient: string, new_ingredient: string | data.IngredientPrototype, new_amount: integer?): data.RecipePrototype ----@field public add_ingredient fun(self: data.RecipePrototype, ingredient: data.IngredientPrototype): data.RecipePrototype ----@field public add_ingredient_unsafe fun(self: data.RecipePrototype, ingredient: data.IngredientPrototype): data.RecipePrototype +---@field public add_unlock fun(self: data.RecipePrototype, technology_name: string | string[]): data.RecipePrototype, boolean +---@field public remove_unlock fun(self: data.RecipePrototype, technology_name: string | string[]): data.RecipePrototype, boolean +---@field public replace_unlock fun(self: data.RecipePrototype, technology_old: string | string[], technology_new: string | string[]): data.RecipePrototype, boolean +---@field public replace_ingredient fun(self: data.RecipePrototype, old_ingredient: string, new_ingredient: string | data.IngredientPrototype, new_amount: integer?): data.RecipePrototype, boolean +---@field public replace_ingredient_unsafe fun(self: data.RecipePrototype, old_ingredient: string, new_ingredient: string | data.IngredientPrototype, new_amount: integer?): data.RecipePrototype, boolean +---@field public add_ingredient fun(self: data.RecipePrototype, ingredient: data.IngredientPrototype): data.RecipePrototype, boolean +---@field public add_ingredient_unsafe fun(self: data.RecipePrototype, ingredient: data.IngredientPrototype): data.RecipePrototype, boolean ---@field public remove_ingredient fun(self: data.RecipePrototype, ingredient_name: string): data.RecipePrototype, integer ----@field public replace_result fun(self: data.RecipePrototype, old_result: string, new_result: string | data.ProductPrototype, new_amount: integer?): data.RecipePrototype ----@field public replace_result_unsafe fun(self: data.RecipePrototype, old_result: string, new_result: string | data.ProductPrototype, new_amount: integer?): data.RecipePrototype ----@field public add_result fun(self: data.RecipePrototype, result: data.ProductPrototype): data.RecipePrototype ----@field public remove_result fun(self: data.RecipePrototype, result_name: string): data.RecipePrototype ----@field public clear_ingredients fun(self: data.RecipePrototype): data.RecipePrototype ----@field public multiply_result_amount fun(self: data.RecipePrototype, result_name: string, percent: number): data.RecipePrototype ----@field public multiply_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, percent: number): data.RecipePrototype ----@field public add_result_amount fun(self: data.RecipePrototype, result_name: string, increase: number): data.RecipePrototype ----@field public add_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, increase: number): data.RecipePrototype ----@field public set_result_amount fun(self: data.RecipePrototype, result_name: string, amount: number): data.RecipePrototype ----@field public set_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, amount: number): data.RecipePrototype +---@field public replace_result fun(self: data.RecipePrototype, old_result: string, new_result: string | data.ProductPrototype, new_amount: integer?): data.RecipePrototype, boolean +---@field public replace_result_unsafe fun(self: data.RecipePrototype, old_result: string, new_result: string | data.ProductPrototype, new_amount: integer?): data.RecipePrototype, boolean +---@field public add_result fun(self: data.RecipePrototype, result: data.ProductPrototype): data.RecipePrototype, boolean +---@field public remove_result fun(self: data.RecipePrototype, result_name: string): data.RecipePrototype, integer +---@field public clear_ingredients fun(self: data.RecipePrototype): data.RecipePrototype, boolean +---@field public multiply_result_amount fun(self: data.RecipePrototype, result_name: string, percent: number): data.RecipePrototype, boolean +---@field public multiply_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, percent: number): data.RecipePrototype, boolean +---@field public add_result_amount fun(self: data.RecipePrototype, result_name: string, increase: number): data.RecipePrototype, boolean +---@field public add_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, increase: number): data.RecipePrototype, boolean +---@field public set_result_amount fun(self: data.RecipePrototype, result_name: string, amount: number): data.RecipePrototype, boolean +---@field public set_ingredient_amount fun(self: data.RecipePrototype, ingredient_name: string, amount: number): data.RecipePrototype, boolean ---@field public get_main_product fun(self: data.RecipePrototype, allow_multi_product: boolean?): LuaItemPrototype?|LuaFluidPrototype? ----@field public get_icons fun(self: data.RecipePrototype): data.IconData - -local metas = {} - +---@field public get_icons fun(self: data.RecipePrototype): data.IconData[] RECIPE = setmetatable(data.raw.recipe, { ---@param recipe data.RecipePrototype __call = function(self, recipe) @@ -81,15 +80,15 @@ py.allow_productivity = function(recipe_names) end end ----@param self table ----@param technology_name string|table ----@return table self +---@param self data.RecipePrototype +---@param technology_name string|string[] +---@return data.RecipePrototype self ---@return boolean success metas.add_unlock = function(self, technology_name) if type(technology_name) == "table" then local success = true for _, tech in pairs(technology_name) do - _, this_success = self:add_unlock(tech) + local _, this_success = self:add_unlock(tech) success = success and this_success -- if any addition fails, the whole check fails end return self, success @@ -117,9 +116,9 @@ metas.add_unlock = function(self, technology_name) return self, true end ----@param self table ----@param technology_name string|table ----@return table self +---@param self data.RecipePrototype +---@param technology_name string|string[] +---@return data.RecipePrototype self ---@return boolean success metas.remove_unlock = function(self, technology_name) if type(technology_name) == "table" then @@ -149,10 +148,10 @@ metas.remove_unlock = function(self, technology_name) return self, false -- recipe not part of tech end ----@param self table ----@param technology_old string|table ----@param technology_new string|table ----@return table self +---@param self data.RecipePrototype +---@param technology_old string|string[] +---@param technology_new string|string[] +---@return data.RecipePrototype self ---@return boolean success metas.replace_unlock = function(self, technology_old, technology_new) local _, success_remove = self:remove_unlock(technology_old) @@ -199,11 +198,11 @@ do return true -- must have been a success! cant early return on success because of possible repeated results end - ---@param self table + ---@param self data.RecipePrototype ---@param old_ingredient string - ---@param new_ingredient string|table + ---@param new_ingredient string|data.IngredientPrototype ---@param new_amount? int - ---@return table self + ---@return data.RecipePrototype self ---@return boolean success metas.replace_ingredient = function(self, old_ingredient, new_ingredient, new_amount) self:standardize() @@ -211,11 +210,11 @@ do return self, success end - ---@param self table + ---@param self data.RecipePrototype ---@param old_ingredient string - ---@param new_ingredient string|table + ---@param new_ingredient string|data.IngredientPrototype ---@param new_amount? int - ---@return table self + ---@return data.RecipePrototype self ---@return boolean success metas.replace_ingredient_unsafe = function(self, old_ingredient, new_ingredient, new_amount) self:standardize() @@ -223,11 +222,11 @@ do return self, success end - ---@param self table + ---@param self data.RecipePrototype ---@param old_result string - ---@param new_result string|table + ---@param new_result string|data.ProductPrototype ---@param new_amount? int - ---@return table self + ---@return data.RecipePrototype self ---@return boolean success metas.replace_result = function(self, old_result, new_result, new_amount) self:standardize() @@ -238,11 +237,11 @@ do return self, success end - ---@param self table + ---@param self data.RecipePrototype ---@param old_result string - ---@param new_result string|table + ---@param new_result string|data.ProductPrototype ---@param new_amount? int - ---@return table self + ---@return data.RecipePrototype self ---@return boolean success metas.replace_result_unsafe = function(self, old_result, new_result, new_amount) self:standardize() @@ -254,9 +253,9 @@ do end end ----@param self table +---@param self data.RecipePrototype ---@param ingredient data.IngredientPrototype ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.add_ingredient_unsafe = function(self, ingredient) self:standardize() @@ -280,9 +279,9 @@ metas.add_ingredient_unsafe = function(self, ingredient) return self, true end ----@param self table +---@param self data.RecipePrototype ---@param ingredient data.IngredientPrototype ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.add_ingredient = function(self, ingredient) self:standardize() @@ -294,9 +293,9 @@ metas.add_ingredient = function(self, ingredient) return metas.add_ingredient_unsafe(self, ingredient) end ----@param self table +---@param self data.RecipePrototype ---@param result data.ProductPrototype ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.add_result = function(self, result) self:standardize() @@ -304,9 +303,9 @@ metas.add_result = function(self, result) return self, true end ----@param self table +---@param self data.RecipePrototype ---@param ingredient_name string ----@return table self +---@return data.RecipePrototype self ---@return int amount_removed metas.remove_ingredient = function(self, ingredient_name) self:standardize() @@ -321,9 +320,9 @@ metas.remove_ingredient = function(self, ingredient_name) return self, amount_removed end ----@param self table +---@param self data.RecipePrototype ---@param result_name string ----@return table self +---@return data.RecipePrototype self ---@return int amount_removed metas.remove_result = function(self, result_name) self:standardize() @@ -349,10 +348,10 @@ metas.clear_results = function(self) return self, true -- impossible to fail end ----@param self table +---@param self data.RecipePrototype ---@param result_name string ---@param percent float ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.multiply_result_amount = function(self, result_name, percent) self:standardize() @@ -375,10 +374,10 @@ metas.multiply_result_amount = function(self, result_name, percent) return self, false -- could not find result end ----@param self table +---@param self data.RecipePrototype ---@param ingredient_name string ---@param percent float ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.multiply_ingredient_amount = function(self, ingredient_name, percent) self:standardize() @@ -398,10 +397,10 @@ metas.multiply_ingredient_amount = function(self, ingredient_name, percent) return self, false -- could not find ingredient end ----@param self table +---@param self data.RecipePrototype ---@param result_name string ---@param increase int ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.add_result_amount = function(self, result_name, increase) self:standardize() @@ -421,10 +420,10 @@ metas.add_result_amount = function(self, result_name, increase) return self, false -- could not find result end ----@param self table +---@param self data.RecipePrototype ---@param ingredient_name string ---@param increase int ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.add_ingredient_amount = function(self, ingredient_name, increase) self:standardize() @@ -444,27 +443,27 @@ metas.add_ingredient_amount = function(self, ingredient_name, increase) return self, false -- could not find ingredient end ----@param self table +---@param self data.RecipePrototype ---@param result_name string ---@param amount int ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.set_result_amount = function(self, result_name, amount) return self:replace_result(result_name, result_name, amount) end ----@param self table +---@param self data.RecipePrototype ---@param ingredient_name string ---@param amount int ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.set_ingredient_amount = function(self, ingredient_name, amount) return self:replace_ingredient(ingredient_name, ingredient_name, amount) end ----@param self table +---@param self data.RecipePrototype ---@param category_name string ----@return table self +---@return data.RecipePrototype self ---@return boolean success metas.change_category = function(self, category_name) self:standardize() @@ -481,6 +480,9 @@ end --- Get the prototype for the main_product using the same logic the game uses. --- Set allow_multi_product to take the *first* result (not game behavior) instead of failing when a recipe has no main_product set but has multiple results. ---
Check https://lua-api.factorio.com/latest/prototypes/RecipePrototype.html#main_product for more details +---@param self data.RecipePrototype +---@param allow_multi_product boolean +---@return data.ItemPrototype|data.FluidPrototype metas.get_main_product = function(self, allow_multi_product) self:standardize() local target, target_type = self.main_product, "item" @@ -536,6 +538,8 @@ end --- Returns the icons table a recipe would use (i.e. using the item icon if the recipe prototype has no .icons/.icon set). --- May error on malformed prototypes. ---
Check https://lua-api.factorio.com/latest/prototypes/RecipePrototype.html#icon for more details. +---@param self data.RecipePrototype +---@return data.IconData[] metas.get_icons = function(self) local icon = icons(self) if icon then return icon end diff --git a/lib/metas/technology.lua b/lib/metas/technology.lua index 018516a..e6f26d0 100644 --- a/lib/metas/technology.lua +++ b/lib/metas/technology.lua @@ -4,8 +4,6 @@ ---@field public remove_prereq fun(self, prereq_technology_name: string): data.TechnologyPrototype ---@field public remove_pack fun(self, science_pack_name: string): data.TechnologyPrototype ---@field public add_pack fun(self, science_pack_name: string): data.TechnologyPrototype ----@field dependencies string[] - TECHNOLOGY = setmetatable(data.raw.technology, { ---@param technology data.TechnologyPrototype __call = function(self, technology) @@ -29,15 +27,14 @@ metas.standardize = function(self) if not self.unit and not self.research_trigger then self.unit = {ingredients = {}} end self.prerequisites = self.prerequisites or {} - self.dependencies = self.dependencies or {} self.effects = self.effects or {} return self end ----@param self table +---@param self data.TechnologyPrototype ---@param prereq_technology_name string ----@return table self +---@return data.TechnologyPrototype self ---@return boolean success metas.add_prereq = function(self, prereq_technology_name) local prereq_technology = data.raw.technology[prereq_technology_name] @@ -59,9 +56,9 @@ metas.add_prereq = function(self, prereq_technology_name) return self, true -- add prereq succeeds end ----@param self table +---@param self data.TechnologyPrototype ---@param prereq_technology_name string ----@return table self +---@return data.TechnologyPrototype self ---@return boolean success metas.remove_prereq = function(self, prereq_technology_name) if not self.prerequisites then @@ -78,9 +75,9 @@ metas.remove_prereq = function(self, prereq_technology_name) return self, false -- remove prereq fails end ----@param self table +---@param self data.TechnologyPrototype ---@param science_pack_name string ----@return table self +---@return data.TechnologyPrototype self ---@return boolean success metas.remove_pack = function(self, science_pack_name) if not self.unit then @@ -98,9 +95,9 @@ metas.remove_pack = function(self, science_pack_name) end -- possible to add the same pack twice, should probably check for that ----@param self table +---@param self data.TechnologyPrototype ---@param science_pack_name string ----@return table self +---@return data.TechnologyPrototype self ---@return boolean success metas.add_pack = function(self, science_pack_name) if self.research_trigger then diff --git a/lib/metas/tile.lua b/lib/metas/tile.lua index 78be897..6a9d935 100644 --- a/lib/metas/tile.lua +++ b/lib/metas/tile.lua @@ -1,3 +1,4 @@ +---@class data.TilePrototype TILE = setmetatable(data.raw.tile, { ---@param tile data.TilePrototype __call = function(self, tile)