From e56b1a26394dde87d8f93f980995e90ef3030765 Mon Sep 17 00:00:00 2001 From: Simon Brodtmann Date: Tue, 7 Jan 2025 23:06:31 +0100 Subject: [PATCH] Add class Technology --- cf-lib/data/Technology.lua | 162 +++++++++++++++++++++++++++++++++++++ cf-lib/util/table.lua | 6 +- 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 cf-lib/data/Technology.lua diff --git a/cf-lib/data/Technology.lua b/cf-lib/data/Technology.lua new file mode 100644 index 0000000..d1d1dbb --- /dev/null +++ b/cf-lib/data/Technology.lua @@ -0,0 +1,162 @@ +--- Utility class for a single technology +--- @class Technology +local Technology = {} + +local function prerequisiteName(prerequisite) + if type(prerequisite) == "table" and prerequisite.prototype then + return prerequisite.prototype.name + end + return prerequisite +end + +--- Pass a technology name or a technology table to get a Technology object +--- @param value string|table The name of the technology or the technology table +function Technology:new(value) + local name + local technology + + if type(value) == "string" then + name = value + technology = data.raw.technology[name] + elseif type(value) == "table" then + name = value.name + technology = value + end + + if not technology then + log("Technology not found: " .. name) + return nil + end + + local obj = { + prototype = technology + } + + setmetatable(obj, self) + self.__index = self + return obj +end + +--- Applies the technology to the game +function Technology:apply() + data:extend({ self.prototype }) +end + +--- Assigns data to the technology +--- Shorthand for table.assign(technology.prototype, data) +--- @param data table The data to assign +function Technology:assign(data) + table.assign(self.prototype, data) +end + +--- Sets the prerequisite for the technology +--- @param prerequisites table The names of the prerequisites +function Technology:setPrerequisites(prerequisites) + self.prototype.prerequisites = prerequisites +end + +--- Adds a prerequisite to the technology +--- @param prerequisite string|table The name of the prerequisite or the prerequisite Technology instance +function Technology:addPrerequisite(prerequisite) + local _prerequisite = prerequisiteName(prerequisite) + if (not table.contains(self.prototype.prerequisites, _prerequisite)) then + table.insert(self.prototype.prerequisites, _prerequisite) + end +end + +--- Adds multiple prerequisites to the technology +--- @param prerequisites table The names of the prerequisite or the prerequisite Technology instances +function Technology:addPrerequisites(prerequisites) + for _, prerequisite in pairs(prerequisites) do + local _prerequisite = prerequisiteName(prerequisite) + if (not table.contains(self.prototype.prerequisites, _prerequisite)) then + table.insert(self.prototype.prerequisites, _prerequisite) + end + end +end + +--- Replaces a prerequisite in a technology +--- @param old string|table The name of the old prerequisite or the prerequisite Technology instance +--- @param new string|table The name of the new prerequisite or the prerequisite Technology instance +function Technology:replacePrerequisite(old, new) + local _old = prerequisiteName(old) + local _new = prerequisiteName(new) + for i, prerequisite in pairs(self.prototype.prerequisites) do + if prerequisite == _old then + self.prototype.prerequisites[i] = _new + end + end +end + +--- Removes a prerequisite from the technology +--- @param prerequisite string|table The name of the prerequisite or the prerequisite Technology instance +function Technology:removePrerequisite(prerequisite) + local _prerequisite = prerequisiteName(prerequisite) + for i, techPrerequisite in pairs(self.prototype.prerequisites) do + if techPrerequisite == _prerequisite then + table.remove(self.prototype.prerequisites, i) + return + end + end +end + +--- Adds an ingredient to the technology +--- @param ingredientName string The name of the ingredient +--- @param amount? number The amount of the ingredient (default 1) +function Technology:addIngredient(ingredientName, amount) + self.prototype.unit = self.prototype.unit or { ingredients = {} } + self.prototype.unit.ingredients = self.prototype.unit.ingredients or {} + table.insert(self.prototype.unit.ingredients, { ingredientName, amount or 1 }) +end + +--- Adds a list of ingredients to the technology with the default amount of 1 +--- @param ingredientNames table The names of the ingredients +function Technology:addIngredients(ingredientNames) + for _, ingredientName in pairs(ingredientNames) do + self:addIngredient(ingredientName) + end +end + +--- Removes an existing ingredient by name +--- @param ingredientName string The name of the ingredient +function Technology:removeIngredient(ingredientName) + if self.prototype.unit and self.prototype.unit.ingredients then + for i, ingredient in pairs(self.prototype.unit.ingredients) do + if ingredient[1] == ingredientName then + self.prototype.unit.ingredients[i] = nil + end + end + end +end + +--- Adds a recipe unlock to the technology +--- @param recipeName string The name of the recipe to unlock +function Technology:addRecipe(recipeName) + table.insert(self.prototype.effects, { type = "unlock-recipe", recipe = recipeName }) +end + +--- Removes a recipe unlock from the technology +--- @param recipeName string The name of the recipe to remove +function Technology:removeRecipe(recipeName) + for i, effect in pairs(self.prototype.effects) do + if effect.type == "unlock-recipe" and effect.recipe == recipeName then + table.remove(self.prototype.effects, i) + return + end + end +end + +--- Clones the technology +--- @param name string The name of the new technology +--- @param clear? boolean If true, removes all effects and prerequisites from the technology (default false) +function Technology:clone(name, clear) + local clone = table.deepcopy(self.prototype) + clone.name = name + if (clear) then + clone.prerequisites = {} + clone.effects = {} + end + return Technology:new(clone) +end + +return Technology diff --git a/cf-lib/util/table.lua b/cf-lib/util/table.lua index c6a5f13..1cdfc11 100644 --- a/cf-lib/util/table.lua +++ b/cf-lib/util/table.lua @@ -60,7 +60,11 @@ function table.filter(target, predicate) local result = {} for k, v in pairs(target) do if predicate(v, k) then - result[k] = v + if type(k) == "number" then + table.insert(result, v) + else + result[k] = v + end end end return result