Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 82 additions & 2 deletions autotech.lua
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ function auto_tech:set_tech_unit()
local exponent = self.configuration.tech_cost_exponent
local victory_node = self.technology_nodes:find_technology_node(self.dependency_graph.victory_node)
local max_depth = victory_node.depth - 1
local depths_of_science_packs = {}

if max_depth <= 0 then
error("victory technology has a depth of " .. max_depth .. "\n" .. serpent.block(victory_node))
Expand All @@ -390,20 +391,99 @@ function auto_tech:set_tech_unit()
error()
end

-- get the depths of all science packs on the tech tree, assuming non-progression military science
self.technology_nodes:for_all_nodes(function(technology_node)
local factorio_tech = technology_node.object_node.object
local science_pack_unlocked_by_this_tech = data.raw.tool[technology_node.object_node.object.name]
if science_pack_unlocked_by_this_tech then
if factorio_tech.name ~= "military-science-pack" then
depths_of_science_packs[#depths_of_science_packs + 1] = technology_node.depth
if verbose_logging then
log("Depth of a new science pack tech is " .. technology_node.depth)
end
return
end
if verbose_logging then
log("Depth of a military science pack tech is " .. technology_node.depth .. ". it will be ignored as a non-progression pack.")
end
end
end)



-- sort the table of depths from lowest to highest
table.sort(depths_of_science_packs)
if verbose_logging then
for _, pack_depth in pairs(depths_of_science_packs) do
log("Depth of a new science pack tech is " .. pack_depth)
end
end

local number_of_initial_trigger_techs = 0
-- count the amount of trigger techs leading to the initial science pack
for i = 1, math.min(#self.technology_nodes_array, depths_of_science_packs[1] + 1) do
local node = self.technology_nodes_array[i]
if not node.object_node.object.research_trigger then
break
end
if verbose_logging then
log(node.printable_name .. " is the new latest trigger tech")
end
number_of_initial_trigger_techs = node.depth + 1
end
if verbose_logging then
log("Number of initial trigger techs is " .. number_of_initial_trigger_techs)
end


self.technology_nodes:for_all_nodes(function(technology_node)
local factorio_tech = technology_node.object_node.object
if factorio_tech.research_trigger then return end
factorio_tech.unit = factorio_tech.unit or {}
local depth_percent = (technology_node.depth / max_depth)

-- get the relative depth of the technology compared to the science pack, as a percentage
local relative_depth_percent = -1
local absolute_depth_in_science_tier = technology_node.depth
for i = #depths_of_science_packs, 2, -1 do -- work from largest to smallest, end at 2 as we won't be adjusting automation tech costs
local current_tier_depth = depths_of_science_packs[i] + 1 -- Add one as we want the first tech, not the science pack
if technology_node.depth >= current_tier_depth then
local next_tier_depth = depths_of_science_packs[i + 1] or max_depth
local length_of_science_tier = next_tier_depth - current_tier_depth
absolute_depth_in_science_tier = absolute_depth_in_science_tier - current_tier_depth
relative_depth_percent = (technology_node.depth - current_tier_depth) / length_of_science_tier -- aka relative depth in science tier
break
end
end

local depth_percent = ((technology_node.depth - number_of_initial_trigger_techs) / (max_depth - number_of_initial_trigger_techs))
factorio_tech.unit.count = start + (victory - start) * (depth_percent ^ exponent)

if factorio_tech.unit.count == math.huge then
error(depth_percent .. "\n" .. serpent.block(factorio_tech) .. serpent.block(self.configuration))
end
if verbose_logging then
log("Technology " .. factorio_tech.name .. " has a depth of " .. technology_node.depth .. ". Calculated science pack cost is " .. factorio_tech.unit.count)
log(table.concat{
"Technology ",
factorio_tech.name,
" has a depth of ",
technology_node.depth,
", absolute depth from last science pack of ",
absolute_depth_in_science_tier,
" and a relative depth in the science tier of ",
relative_depth_percent,
". Calculated science pack cost is ",
factorio_tech.unit.count
})
end
if relative_depth_percent >= 0 then
if absolute_depth_in_science_tier < technology_node.depth then
factorio_tech.unit.count = factorio_tech.unit.count * (0.5 * (1.0 - relative_depth_percent) + relative_depth_percent) -- linear scaling between 0.5 and full cost across the science tier
end
end
factorio_tech.unit.count = math.max(cost_rounding(factorio_tech.unit.count), 1)
if verbose_logging then
log("Technology " .. factorio_tech.name .. " has the reduced and rounded cost of " .. factorio_tech.unit.count)
end

local final_multiplier = self.configuration.tech_cost_additional_multipliers[factorio_tech.name]
if final_multiplier then
Expand Down