Files
research-multipliers/data-final-fixes.lua

158 lines
5.2 KiB
Lua

local global_multiplier = settings.startup["global-multiplier"].value
local essential_research_multiplier = settings.startup["essential-research-multiplier"].value
local infinite_research_multiplier = settings.startup["infinite-research-multiplier"].value
local interplanetary_research_multiplier = settings.startup["interplanetary-research-multiplier"].value
local planet_discovery_research_multiplier = settings.startup["planet-discovery-research-multiplier"].value
local multiplier_mode = "override";
-- as defined by Factorio's technology tree; yes, some of this is redundant as they're trigger-based, but I would rather be technically correct
local essential_research = {
"automation-science-pack",
"logistic-science-pack",
"military-science-pack",
"chemical-science-pack",
"production-science-pack",
"utility-science-pack",
"rocket-silo",
"space-science-pack",
"planet-discovery-vulcanus",
"metallurgic-science-pack",
"planet-discovery-fulgora",
"electromagnetic-science-pack",
"planet-discovery-gleba",
"agricultural-science-pack",
"planet-discovery-aquilo",
"cryogenic-science-pack",
"promethium-science-pack",
};
-- used for 'pack' multiplier mode
local science_packs = {
"automation-science-pack",
"logistic-science-pack",
"military-science-pack",
"chemical-science-pack",
"production-science-pack",
"utility-science-pack",
"space-science-pack",
"metallurgic-science-pack",
"electromagnetic-science-pack",
"agricultural-science-pack",
"cryogenic-science-pack",
"promethium-science-pack",
}
-- used for detecting interplanetary research
local interplanetary_science_packs = {
"metallurgic-science-pack",
"electromagnetic-science-pack",
"agricultural-science-pack",
"cryogenic-science-pack",
"promethium-science-pack",
}
function is_essential_research(name)
for _, essential_name in pairs(essential_research) do
if (name == essential_name) then
return true;
end
end
return false;
end
-- infinite research generally has a finite number of defined 'levels', ones that don't have a formula. this function does not account for them.
function is_infinite_research(name)
return data.raw.technology[name].unit.count == nil;
end
function is_interplanetary_research(name)
return false;
end
function is_planet_discovery_research(name)
local start = string.find(name, "planet-discovery-", 1, true)
return start == 1;
end
function multiply(current, next)
if multiplier_mode == "override" then
return next;
elseif multiplier_mode == "multiply" then
return current * next;
elseif multiplier_mode == "add" then
return current + (next - 1);
end
end
for name, technology in pairs(data.raw.technology) do
-- skip trigger technology
if (technology.research_trigger ~= nil) then
goto continue;
end
-- default to the global multiplier
local multiplier = global_multiplier;
-- essential research
if (essential_research_multiplier ~= 1 and is_essential_research(name)) then
multiplier = multiply(multiplier, essential_research_multiplier);
end
-- infinite research
if (infinite_research_multiplier ~= 1 and is_infinite_research(name)) then
multiplier = multiply(multiplier, infinite_research_multiplier);
end
-- interplanetary research
if (interplanetary_research_multiplier ~= 1 and is_interplanetary_research(name)) then
multiplier = multiply(multiplier, interplanetary_research_multiplier);
end
-- planet discovery research
if (planet_discovery_research_multiplier ~= 1 and is_planet_discovery_research(name)) then
multiplier = multiply(multiplier, planet_discovery_research_multiplier);
end
-- TODO: science pack multiplier
-- debug printing
if (technology.unit) then
if (technology.unit.count ~= nil) then
log(name .. " : " .. technology.unit.count .. " -> x" .. multiplier)
else
log(name .. " : " .. '??' .. " -> x" .. multiplier)
end
end
-- TODO: Reduce multiplier precision to 3 decimal places
-- don't apply multiplier if it would do nothing
if (multiplier == 1) then
goto continue;
elseif (multiplier <= 0) then
log("Multiplier is less than 0, skipping " .. name .. " (" .. multiplier .. ")")
goto continue;
end
-- Multiplier has been calculated, apply it
if (technology.unit.count_formula) then
-- formula-based
if (multiplier < 1) then
-- if multiplier is less than 100%, we need to ensure the result is at least 1
-- MathExpression has a max() function for formulas
technology.unit.count_formula = 'max(1, ' .. technology.unit.count_formula .. ')*' .. multiplier
else
technology.unit.count_formula = '(' .. technology.unit.count_formula .. ')*' .. multiplier
end
else
-- simple count
if (multiplier < 1) then
technology.unit.count = math.max(math.ceil(technology.unit.count*multiplier), 1)
else
technology.unit.count = technology.unit.count*multiplier;
end
end
::continue::
end