Wed, 27 Aug 2025 10:26:12 +0300
Lots of stuff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/aqs_util.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,187 @@ +---@class AqsScienceArgs +---@field count? int +---@field count_formula? string +---@field time int + +--- @param args AqsScienceArgs +--- @return data.TechnologyUnit +function red_science(args) + return { + count = args.count, + count_formula = args.count_formula, + time = args.time, + ingredients = { + {"automation-science-pack", 1}, + }, + } +end + +--- @param args AqsScienceArgs +function green_science(args) + local x = red_science(args) + table.insert(x.ingredients, {"logistic-science-pack", 1}) + return x +end + +--- @param args AqsScienceArgs +function blue_science(args) + local x = green_science(args) + table.insert(x.ingredients, {"chemical-science-pack", 1}) + return x +end + +--- @param args AqsScienceArgs +function cryo_science(args) + local x = blue_science(args) + table.insert(x.ingredients, {"cryogenic-science-pack", 1}) + return x +end + +---@return data.ItemIngredientPrototype +function item(name, amount) + return {type="item", name=name, amount=amount or 1} +end + +---@return data.FluidIngredientPrototype +function fluid(name, amount) + return {type = "fluid", name = name, amount = amount} +end + +---@param technology data.TechnologyPrototype +---@param x string +function remove_recipe_effect(technology, x) + ---@type (data.Modifier)[] + local list2 = {} + for k, v in pairs(technology.effects) + do + if v.type ~= "unlock-recipe" or v.recipe ~= x + then + table.insert(list2, v) + end + end + technology.effects = list2 +end + +---@param technology data.TechnologyPrototype +---@param x data.Modifier +function remove_effect(technology, x) + ---@type (data.Modifier)[] + local list2 = {} + for _, technology_effect in pairs(technology.effects or {}) + do + local match = true + for key, value in pairs(x) + do + if technology_effect[key] ~= value + then + match = false + break + end + end + if not match + then + table.insert(list2, technology_effect) + end + end + technology.effects = list2 +end + +---@param recipe_name string +---@return data.UnlockRecipeModifier +function unlock_recipe(recipe_name) + return {type = "unlock-recipe", recipe = recipe_name} +end + +---@param recipe_name string +---@return data.ChangeRecipeProductivityModifier +function recipe_productivity(recipe_name) + return { + type = "change-recipe-productivity", + recipe = recipe_name, + change = 0.1, + } +end + +---@alias SciencePack "automation-science-pack"|"logistic-science-pack"|"chemical-science-pack"|"production-science-pack"|"utility-science-pack"|"metallurgic-science-pack"|"nuclear-science-pack"|"electromagnetic-science-pack"|"cryogenic-science-pack"|"promethium-science-pack"|"agricultural-science-pack" + +---@param technology data.TechnologyPrototype +---@param x SciencePack +function is_in_unit(technology, x) + print(technology.name) + if technology.unit + then + for k,v in pairs(technology.unit.ingredients) + do + if v[1] == x + then + return true + end + end + end + return false +end + +---@param technology data.TechnologyPrototype +---@param x string +---@param y string +function replace_in_prerequisites(technology, x, y) + if technology.prerequisites ~= nil + then + for k, v in pairs(technology.prerequisites) + do + if technology.prerequisites[k] == x + then + technology.prerequisites[k] = y + break + end + end + end +end + +---@param technology data.TechnologyPrototype +---@param x SciencePack +---@param y SciencePack +function replace_in_unit(technology, x, y) + if technology.unit + then + technology.unit = table.deepcopy(technology.unit) + for k,v in pairs(technology.unit.ingredients) + do + if v[1] == x + then + v[1] = y + break + end + end + end + replace_in_prerequisites(technology, x, y) +end + +---@param technology data.TechnologyPrototype +---@param x SciencePack +function delete_from_unit(technology, x) + if technology.unit + then + local new_ingredients = {} + for k,v in pairs(technology.unit.ingredients) + do + if v[1] ~= x + then + table.insert(new_ingredients, v) + end + end + technology.unit.ingredients = new_ingredients + end + if technology.prerequisites ~= nil + then + local new_prerequisites = {} + for k, v in pairs(technology.prerequisites) + do + if v ~= x + then + table.insert(new_prerequisites, v) + end + end + technology.prerequisites = new_prerequisites + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/data-updates.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,203 @@ +require("aqs_util") + +data.raw.recipe["refinery"].ingredients = { + item("steel-plate", 10), + item("low-density-structure", 5), + item("processing-unit", 5), + fluid("fluorine", 1000), + item("promethium-asteroid-chunk", 10), +} + +local function rename(arr, a, b) + arr[b] = arr[a] + arr[a] = nil + arr[b].name = b +end + +--rename(data.raw["recipe"], "promethium-chunk-submerging", "promethium-emulsion") +data.raw["recipe"]["promethium-chunk-submerging"].ingredients = { + item("promethium-asteroid-chunk", 1), + fluid("ammonia", 300), + fluid("fluorine", 300), +} +data.raw["recipe"]["promethium-chunk-submerging"].icon = "__aquilo-start__/graphics/icons/promethium-chunk-submerging.png" +data.raw["fluid"]["promethium-emulsion"].icon = "__aquilo-start__/graphics/icons/promethium-emulsion.png" +data.raw["fluid"]["promethium-emulsion"].base_color = {r=0.44, g=0.09, b=0.14} +data.raw["fluid"]["promethium-emulsion"].flow_color = {r=0.84, g=0.24, b=0.49} +data.raw["fluid"]["promethium-emulsion"].visualization_color = {r=0.84, g=0.24, b=0.49} +data.raw["recipe"]["promethium-chunk-melting"].hidden = true + +data.raw.recipe["cryogenic-plant"].ingredients = { + item("lithium-plate", 20), + item("processing-unit", 20), + item("heat-conduit", 50), + item("refined-concrete", 40) +} + +data.raw["technology"]["cryogenic-plant"].unit = blue_science{count = 200, time = 30} +data.raw["technology"]["cryogenic-plant"].research_trigger = nil +data.raw["technology"]["cryogenic-plant"].prerequisites = {"lithium-processing-2", "concrete", "processing-unit"} + +data.raw.furnace["refinery"].effect_receiver.base_effect.quality = 4 -- 40% +data.raw.technology["refinery"].unit = cryo_science{count = 500, time = 30} +data.raw.technology["refinery"].prerequisites = { + "processing-unit", + "low-density-structure", + "cryogenic-science-pack", +} + +data.raw["recipe"]["lithium"].ingredients = { + fluid("lithium-brine", 10), + fluid("ammonia", 10), +} +data.raw.recipe["lithium"].results[1].amount = 1 +data.raw["technology"]["flare-stack-fluid-venting-tech"].unit = red_science{count = 20, time = 30,} +data.raw.tile["ice-platform"].mined_sound = table.deepcopy(data.raw["simple-entity"]["lithium-iceberg-huge"].mined_sound) + +remove_recipe_effect(data.raw["technology"]["lithium-processing"], "lithium") +remove_recipe_effect(data.raw["technology"]["cryogenic-plant"], "fluoroketone") +remove_recipe_effect(data.raw["technology"]["cryogenic-plant"], "fluoroketone-cooling") + +data.raw["technology"]["cryogenic-science-pack"].prerequisites = {"lithium-processing-2", "fluorine-processing"} +data.raw["technology"]["foundation"].prerequisites = {"cryogenic-science-pack", "metallurgic-science-pack", "agricultural-science-pack", "electromagnetic-science-pack"} + +data.raw["technology"]["landfill"].unit = nil +data.raw["technology"]["landfill"].research_trigger = { + type = "mine-entity", + entity = "stone", +} +data.raw["technology"]["landfill"].prerequisites = {"space-platform-thruster"} +data.raw["technology"]["planet-discovery-gleba"].prerequisites = {"space-platform-thruster"} +data.raw["technology"]["agriculture"].prerequisites = {"planet-discovery-gleba", "landfill"} + +data.raw["technology"]["quantum-processor"].prerequisites = { + "cryogenic-science-pack", + "metallurgic-science-pack", + "agricultural-science-pack", + "nuclear-science-pack", + "electromagnetic-science-pack"} +data.raw["technology"]["foundation"].prerequisites = {"rail-support-foundations", "agricultural-science-pack", "cryogenic-science-pack", "nuclear-science-pack", "electromagnetic-science-pack"} + +if data.raw["technology"]["freezing"] +then + data.raw["technology"]["freezing"].unit = cryo_science{count = 100, time = 30} + data.raw["technology"]["freezing"].prerequisites = {"cryogenic-science-pack"} +end + +if data.raw["technology"]["spoilables-processing"] +then + data.raw["technology"]["spoilables-processing"].unit = cryo_science{count = 250, time = 30} + data.raw["technology"]["spoilables-processing"].prerequisites = {"planet-discovery-gleba", "freezing"} +end + +local exclude_from_cryo = { + ["nuclear-fuel-reprocessing"] = 1, + ["elevated-rail"] = 1, +} + +-- Replace production science pack with cryo science +for technology_name, technology in pairs(data.raw["technology"]) +do + if technology.unit + then + local has_production = is_in_unit(technology, "production-science-pack") + local has_cryo = is_in_unit(technology, "cryogenic-science-pack") + if has_production and (has_cryo or exclude_from_cryo[technology.name]) + then + delete_from_unit(technology, "production-science-pack") + else + replace_in_unit(technology, "production-science-pack", "cryogenic-science-pack") + end + end +end + +table.insert(data.raw["technology"]["elevated-rail"].prerequisites, "chemical-science-pack") +table.insert(data.raw["technology"]["planet-discovery-fulgora"].prerequisites, "elevated-rail") +data.raw["technology"]["automated_bridges"].hidden = true +data.raw["tool"]["cryogenic-science-pack"].order = "e[cryogenic-science-pack]" + +for _, lab in pairs(data.raw["lab"]) +do + local new_inputs = {} + for _, input in pairs(lab.inputs) + do + if input ~= "production-science-pack" + then + table.insert(new_inputs, input) + end + end + lab.inputs = new_inputs +end + +data.raw["tool"]["production-science-pack"].hidden = true +data.raw["technology"]["production-science-pack"].hidden = true + +for _, recipe in pairs(data.raw["recipe"]) +do + if (#(recipe.results or {}) == 1 and recipe.results[1].name == "production-science-pack") + or ((recipe.main_product or "") == "production-science-pack") + then + recipe.hidden = true + end +end + +table.insert(data.raw["technology"]["planet-discovery-fulgora"], "elevated-rail") +data.raw["technology"]["induction-technology1"].prerequisites = {"battery", "modular-armor"} +data.raw["technology"]["battery-equipment"].prerequisites = {"induction-technology1"} +for _, tech in pairs(data.raw["technology"]) +do + replace_in_prerequisites(tech, "solar-panel-equipment", "battery-equipment") +end + +data.raw["electric-pole"]["wire-buoy"].supply_area_distance = 3 +data.raw["technology"]["epic-quality"].prerequisites = { + "electromagnetic-science-pack", + "utility-science-pack", + "cryogenic-science-pack" +} +data.raw["technology"]["epic-quality"].unit.ingredients = { + {"automation-science-pack", 1}, + {"logistic-science-pack", 1}, + {"chemical-science-pack", 1}, + {"space-science-pack", 1}, + {"cryogenic-science-pack", 1}, + {"utility-science-pack", 1}, + {"electromagnetic-science-pack", 1}, +} +data.raw["technology"]["legendary-quality"].prerequisites = { + "epic-quality", + "metallurgic-science-pack", + "agricultural-science-pack", + "nuclear-science-pack" +} + +data.raw.technology["steam-power"].prerequisites = {"fluid-handling"} +data.raw.technology["steam-power"].unit = red_science{count = 20, time = 30} +remove_effect(data.raw["technology"]["steam-power"], unlock_recipe "burner-crusher") +remove_effect(data.raw["technology"]["steam-power"], unlock_recipe "sand") +table.insert(data.raw["technology"]["crude-asteroid-crushing"].effects, unlock_recipe "burner-crusher") +table.insert(data.raw["technology"]["crude-asteroid-crushing"].effects, unlock_recipe "sand") + +remove_effect(data.raw["technology"]["steam-power"], unlock_recipe "pipe") +remove_effect(data.raw["technology"]["steam-power"], unlock_recipe "pipe-to-ground") +table.insert(data.raw["technology"]["steel-processing"].effects, unlock_recipe "pipe") +data.raw["technology"]["electronics"].prerequisites = {"crude-asteroid-crushing"} +data.raw["technology"]["steel-processing"].prerequisites = {"crude-asteroid-crushing"} +data.raw["technology"]["promethium-thermals"].prerequisites = {"lithium-processing", "steel-processing"} +data.raw["technology"]["automation-science-pack"].prerequisites = {"steel-processing", "electronics", "promethium-thermals"} + +table.insert(data.raw["technology"]["oil-gathering"].effects, unlock_recipe "pipe-to-ground") + +data.raw.recipe["metallic-asteroid-crushing"].category = "crushing" +data.raw.recipe["carbonic-asteroid-crushing"].category = "crushing" +data.raw.recipe["oxide-asteroid-crushing"].category = "crushing" +data.raw.recipe["crude-metallic-asteroid-crushing"].category = "basic-crushing" +data.raw.recipe["crude-carbonic-asteroid-crushing"].category = "basic-crushing" + +local electric_drill = data.raw["mining-drill"]["electric-mining-drill"] +for _, crusher_name in pairs{"crusher", "burner-crusher"} +do + local crusher = data.raw["assembling-machine"][crusher_name] or data.raw["furnace"][crusher_name] + crusher.open_sound = electric_drill.open_sound + crusher.close_sound = electric_drill.close_sound +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/data.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,82 @@ +require("aqs_util") + +local function item_productivity_icon(name) + local icons = util.technology_icon_constant_recipe_productivity(name) + icons[1].icon_size = 64 + return icons +end + +---@type data.TechnologyPrototype[] +local new_techs = { + { + type = "technology", + name = "lithium-processing-2", + prerequisites = {"oil-gathering", "lithium-processing"}, + research_trigger = { + type = "mine-entity", + entity = "lithium-brine", + }, + icon = table.deepcopy(data.raw.technology["lithium-processing"].icon), + icon_size = data.raw.technology["lithium-processing"].icon_size, + + effects = {unlock_recipe "lithium"} + }, { + type = "technology", + name = "fluorine-processing", + prerequisites = {"cryogenic-plant"}, + research_trigger = { + type = "mine-entity", + entity = "fluorine-vent" + }, + icon = table.deepcopy(data.raw.fluid["fluorine"].icon), + icon_size = data.raw.fluid["fluorine"].icon_size, + effects = {unlock_recipe "fluoroketone", unlock_recipe "fluoroketone-cooling"} + }, { + type = "technology", + name = "ice-platform-productivity", + effects = {recipe_productivity "ice-platform"}, + prerequisites = {"fluid-handling"}, + icons = util.technology_icon_constant_recipe_productivity "__aquilo-start__/graphics/technology/ice-platform-productivity.png", + unit = red_science{ + count = 50, + time = 20, + }, + upgrade = true, + }, { + type = "technology", + name = "ice-platform-productivity-2", + effects = {recipe_productivity "ice-platform"}, + prerequisites = {"ice-platform-productivity", "logistic-science-pack"}, + icons = util.technology_icon_constant_recipe_productivity "__aquilo-start__/graphics/technology/ice-platform-productivity.png", + unit = green_science{ + count = 100, + time = 20, + }, + upgrade = true, + }, { + type = "technology", + name = "ice-platform-productivity-3", + effects = {recipe_productivity "ice-platform"}, + prerequisites = {"ice-platform-productivity-2", "chemical-science-pack"}, + icons = util.technology_icon_constant_recipe_productivity "__aquilo-start__/graphics/technology/ice-platform-productivity.png", + unit = blue_science{ + count = 200, + time = 30, + }, + upgrade = true, + }, { + type = "technology", + name = "ice-platform-productivity-4", + effects = {recipe_productivity "ice-platform"}, + prerequisites = {"ice-platform-productivity-3", "cryogenic-science-pack"}, + icons = util.technology_icon_constant_recipe_productivity "__aquilo-start__/graphics/technology/ice-platform-productivity.png", + unit = cryo_science{ + count_formula = "1.5^L * 100", + time = 60, + }, + max_level = 30, + upgrade = true, + }, +} + +data:extend(new_techs) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/info.json Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,21 @@ +{ + "name": "aquilo-start", + "author": "teemu", + "version": "0.0.0", + "description": "(Modpack+balancing) Crash land on Aquilo and freeze to death or maybe crush asteroids and survive", + "dependencies": [ + "base", + "space-age", + "dw-frozen-reaches", + "any-planet-start", + "atan-nuclear-science", + "cargo-ships", + "promethium-quality", + "Flare Stack", + "classic-mining-drill", + "SetDefaultImportPlanet", + "InductionChargingRevamp"], + "space_travel_required": true, + "title": "Aquilo start", + "factorio_version": "2.0" +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/locale/en/aquilo-start.cfg Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,2 @@ +[technology-name] +ice-platform-productivity=Ice platform productivity \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aquilo-start/settings.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,7 @@ +data.raw["string-setting"]["aps-planet"].allowed_values = {"aquilo"} +data.raw["string-setting"]["aps-planet"].default_value = "aquilo" +data.raw["string-setting"]["aps-planet"].hidden = true +data.raw["int-setting"]["heat-conduit"].allowed_values = {10} +data.raw["int-setting"]["heat-conduit"].default_value = 10 +data.raw["bool-setting"]["stirling-generator-lithium"].forced_value = true +data.raw["string-setting"]["SetDefaultImportPlanet-planet"].default_value = "aquilo" \ No newline at end of file
--- a/fusion-lab/control.lua Wed Jul 23 16:08:55 2025 +0300 +++ b/fusion-lab/control.lua Wed Aug 27 10:26:12 2025 +0300 @@ -1,3 +1,15 @@ +---@class FusionLabStorageData +---@field heat_interface LuaEntity heat buffer shadowing this entity + +---@class FusionLabStorage +---@field fusion_labs table<LuaEntity, FusionLabStorageData>? +storage = {} + +---@param heat_interface LuaEntity +local function init_heat_interface(heat_interface) + heat_interface.custom_status = {diode=defines.entity_status_diode.green, label={"entity-status.normal"}} +end + local function init_storage() if storage.fusion_labs == nil then @@ -25,6 +37,8 @@ }} heat_interfaces[1].temperature = 15 heat_interfaces[1].destructible = false + heat_interfaces[1].active = false + init_heat_interface(heat_interfaces[1]) end storage.fusion_labs[lab] = { heat_interface = heat_interfaces[1], @@ -37,7 +51,7 @@ local function cleanup_labs() local new_storage_fusion_labs = {} - for lab, lab_info in pairs(storage.fusion_labs) + for lab, lab_info in pairs(storage.fusion_labs or {}) do if lab.valid then @@ -50,7 +64,7 @@ script.on_nth_tick(31, function(event) init_storage() local need_cleanup = false - for lab, lab_info in pairs(storage.fusion_labs) + for lab, lab_info in pairs(storage.fusion_labs or {}) do if not lab.valid then @@ -58,6 +72,16 @@ elseif lab.status == defines.entity_status.working then local heat_interface = lab_info.heat_interface + + if not heat_interface.valid + then + -- (╯°□°)╯︵ ┻━┻ + game.print("[Fusion lab] Heat interface data corrupt, rebuilding") + storage.fusion_labs = nil + init_storage() + return + end + lab.minable = (heat_interface.temperature <= 900) -- A cryogenic plant cooling hot fluoroketone voids 1320kW -- of heat energy, so the fusion lab with no modules just happens @@ -80,30 +104,40 @@ lab.surface.create_entity{ name = 'crash-site-fire-flame', position={lab.position.x + 3.5 * (math.random() - 0.5), lab.position.y + 3.5 * (math.random() - 0.5)}, - force=game.forces.enemy, + force=game.forces.neutral, } end - --[[ - if heat_interface.temperature > 750.0 - then - lab.die() - end - ]]-- end end if need_cleanup then cleanup_labs() end + for _, player in pairs(game.players) + do + if player.gui.relative.fusion_lab_gui and player.opened and player.opened.name == "fusion-lab" + then + for lab, lab_info in pairs(storage.fusion_labs) + do + if lab == player.opened + then + local heat_interface = lab_info.heat_interface + local gui = player.gui.relative.fusion_lab_gui + gui.heat.value = heat_interface.temperature / 700 + gui.heat.caption = {"format-degrees", string.format("%.2f", heat_interface.temperature)} + end + end + end + end end) - script.on_event(defines.events.on_entity_died, function(event) local lab = event.entity - -- we can't rely on storage here + event.entity.force = game.forces.neutral + -- we can't rely on storage here; search for the heat interface on the map local heat_interfaces = lab.surface.find_entities_filtered{ - name='fusion-lab-heat-interface', - position=lab.position, + name = 'fusion-lab-heat-interface', + position = lab.position, limit = 1, } if #heat_interfaces > 0 @@ -111,14 +145,26 @@ local heat_interface = heat_interfaces[1] if heat_interface.temperature > 700 then - for _, ofs in pairs{{0, 0}, {5, 0}, {-5, 0}, {0, 5}, {0, -5}, {1.5, 1.5}, {-1.5, 1.5}, {-1.5, -1.5}, {1.5, -1.5}} + for _, ofs in pairs{ + {0, 0}, + {5, 0}, + {-5, 0}, + {0, 5}, + {0, -5}, + {1.5, 1.5}, + {-1.5, 1.5}, + {-1.5, -1.5}, + {1.5, -1.5}} do - local pos = {x = lab.position.x + ofs[1], y = lab.position.y + ofs[2]} + local pos = { + x = lab.position.x + ofs[1], + y = lab.position.y + ofs[2]} lab.surface.create_entity{ name = 'artillery-projectile', position = pos, target = pos, - force = game.forces.enemy, + force = game.forces.neutral, + cause = event.entity, } end end @@ -126,9 +172,10 @@ end end, {{filter="name", name="fusion-lab"}}) +---@param event EventData local function on_fusion_lab_mined(event) init_storage() - local entity = event.entity + local entity = event.entity ---@type LuaEntity for _, heat_interface in pairs(entity.surface.find_entities_filtered{ name='fusion-lab-heat-interface', position = entity.position @@ -148,6 +195,7 @@ } heat_interface.temperature = 15 heat_interface.destructible = false + heat_interface.active = false storage.fusion_labs[lab] = {heat_interface = heat_interface} end @@ -156,4 +204,4 @@ script.on_event(defines.events.on_space_platform_mined_entity, on_fusion_lab_mined, {{filter="name", name="fusion-lab"}}) script.on_event(defines.events.on_built_entity, on_fusion_lab_built, {{filter="name", name="fusion-lab"}}) script.on_event(defines.events.on_robot_built_entity, on_fusion_lab_built, {{filter="name", name="fusion-lab"}}) -script.on_event(defines.events.on_space_platform_built_entity, on_fusion_lab_built, {{filter="name", name="fusion-lab"}}) +script.on_event(defines.events.on_space_platform_built_entity, on_fusion_lab_built, {{filter="name", name="fusion-lab"}}) \ No newline at end of file
--- a/fusion-lab/data-updates.lua Wed Jul 23 16:08:55 2025 +0300 +++ b/fusion-lab/data-updates.lua Wed Aug 27 10:26:12 2025 +0300 @@ -14,4 +14,4 @@ result.temperature = 180 end end -end +end \ No newline at end of file
--- a/fusion-lab/data.lua Wed Jul 23 16:08:55 2025 +0300 +++ b/fusion-lab/data.lua Wed Aug 27 10:26:12 2025 +0300 @@ -7,6 +7,8 @@ }, } +local nuclear_reactor = data.raw.reactor["nuclear-reactor"] + data:extend{ { type = "item", @@ -14,9 +16,9 @@ icon = "__fusion-lab__/graphics/icons/photometric-lab-icon.png", subgroup = "production-machine", order = "z[lab]b[fusion-lab]", - inventory_move_sound = data.raw.lab.lab.inventory_move_sound, - pick_sound = data.raw.item["fusion-reactor"].pick_sound, - drop_sound = data.raw.item["fusion-reactor"].drop_sound, + inventory_move_sound = table.deepcopy(data.raw.item.lab.inventory_move_sound), + pick_sound = table.deepcopy(data.raw.item.lab.pick_sound), + drop_sound = table.deepcopy(data.raw.item.lab.drop_sound), place_result = "fusion-lab", weight = 200 * kg, stack_size = 5, @@ -106,7 +108,6 @@ -- it's a space age ensemble! sound = { - -- filename = "__space-age__/sound/entity/fusion/fusion-reactor.ogg", filename = "__space-age__/sound/entity/tesla-turret/tesla-turret-rotation-loop.ogg", volume = 0.65, max_sounds_per_prototype = 2, @@ -134,59 +135,54 @@ close_sound = { filename = "__base__/sound/open-close/lab-close.ogg", volume = 0.6 }, energy_source = table.deepcopy(data.raw['fusion-reactor']['fusion-reactor'].burner), energy_usage = "1MW", - researching_speed = settings.startup["fusion-lab-researching-speed"].value, - module_slots = settings.startup["fusion-lab-module-slots"].value, + researching_speed = tonumber(settings.startup["fusion-lab-researching-speed"].value), + module_slots = tonumber(settings.startup["fusion-lab-module-slots"].value), inputs = table.deepcopy(data.raw.lab.biolab.inputs), - science_pack_drain_rate_percent = settings.startup["fusion-lab-drain-rate-percent"].value, + science_pack_drain_rate_percent = tonumber(settings.startup["fusion-lab-drain-rate-percent"].value), icons_positioning = data.raw.lab.biolab.icons_positioning, }, { - type = "heat-interface", + type = "reactor", name = "fusion-lab-heat-interface", icon = "__base__/graphics/icons/heat-interface.png", - flags = {"placeable-player", "not-on-map", "not-flammable", "not-blueprintable", "not-deconstructable"}, + flags = { + "placeable-player", + "not-on-map", + "not-flammable", + "not-blueprintable", + "not-deconstructable", + "no-automated-item-insertion", + }, placeable_by = {item = "fusion-lab", count = 1}, collision_mask = {layers={}}, selection_priority = 150, hidden = true, + energy_source = {type="void"}, + consumption = "0.001W", factoriopedia_alternative = "fusion-lab", max_health = 200, corpse = "small-remnants", - collision_box = data.raw.lab.biolab.collision_box, -- 5×5 - selection_box = data.raw.lab.lab.selection_box, -- 3×3 - gui_mode = "none", -- all, none, admins + collision_box = table.deepcopy(data.raw.lab.biolab.collision_box), + selection_box = {{-2.5, 0.5}, {-0.5, 2.5}}, open_sound = data.raw["fusion-reactor"]["fusion-reactor"].open_sound, close_sound = data.raw["fusion-reactor"]["fusion-reactor"].close_sound, + lower_layer_picture = table.deepcopy(nuclear_reactor.lower_layer_picture), + heat_lower_layer_picture = table.deepcopy(nuclear_reactor.heat_lower_layer_picture), + connection_patches_connected = table.deepcopy(nuclear_reactor.connection_patches_connected), + connection_patches_disconnected = table.deepcopy(nuclear_reactor.connection_patches_disconnected), + heat_connection_patches_connected = table.deepcopy(nuclear_reactor.heat_connection_patches_connected), + heat_connection_patches_disconnected = table.deepcopy(nuclear_reactor.heat_connection_patches_disconnected), + --circuit_connector = table.deepcopy(data.raw["rocket-silo"]["rocket-silo"].circuit_connector), + circuit_wire_max_distance = nuclear_reactor.circuit_wire_max_distance, heat_buffer = { max_temperature = 1000, - specific_heat = "1MJ", + specific_heat = "10MJ", max_transfer = "1GW", default_temperature = 15, min_working_temperature = 15, - pipe_covers = data.raw.boiler["heat-exchanger"].energy_source.pipe_covers, - heat_pipe_covers = data.raw.boiler["heat-exchanger"].energy_source.heat_pipe_covers, - connections = - { - {position = { 2, -2}, direction = defines.direction.north}, - {position = {-2, -2}, direction = defines.direction.north}, - {position = { 2, 2}, direction = defines.direction.south}, - {position = {-2, 2}, direction = defines.direction.south}, - {position = { 2, -2}, direction = defines.direction.east}, - {position = { 2, 2}, direction = defines.direction.east}, - {position = {-2, -2}, direction = defines.direction.west}, - {position = {-2, 2}, direction = defines.direction.west}, - } + connections = table.deepcopy(nuclear_reactor.heat_buffer.connections), }, - picture = - { - filename = "__base__/graphics/entity/nuclear-reactor/reactor-pipes.png", - height = 316, - width = 320, - scale = 0.5, - flags = {"no-crop"}, - shift = util.by_pixel(-1, -5) - } }, { type = "item",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/no-productivity-modules/data-final-fixes.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,184 @@ +---@param technology data.TechnologyPrototype +---@param x string +function remove_recipe_effect(technology, x) + ---@type (data.Modifier)[] + local list2 = {} + for k, v in pairs(technology.effects or {}) + do + if v.type ~= "unlock-recipe" or v.recipe ~= x + then + table.insert(list2, v) + end + end + technology.effects = list2 +end + +---@param technology data.TechnologyPrototype +---@param x data.Modifier +function remove_effect(technology, x) + ---@type (data.Modifier)[] + local list2 = {} + for _, technology_effect in pairs(technology.effects or {}) + do + local match = true + for key, value in pairs(x) + do + if technology_effect[key] ~= value + then + match = false + break + end + end + if not match + then + table.insert(list2, technology_effect) + end + end + technology.effects = list2 +end + +---@param technology data.TechnologyPrototype +---@param x string +function remove_prerequisite(technology, x) + if technology.prerequisites + then + local new_prerequisites = {} + local changed = false + for k, v in pairs(technology.prerequisites) + do + if v == x + then + changed = true + else + table.insert(new_prerequisites, v) + end + end + if changed + then + technology.prerequisites = new_prerequisites + end + end +end + +---@param recipe data.RecipePrototype +---@param ingredient_to_remove string +local function remove_ingredient(recipe, ingredient_to_remove) + local changed = false + local new_ingredients = {} + for _, ingredient in pairs(recipe.ingredients or {}) + do + if ingredient.name == ingredient_to_remove + then + changed = true + else + table.insert(new_ingredients, ingredient) + end + end + if changed + then + recipe.ingredients = new_ingredients + end +end + +local removed_technologies = {} + +---@param recipe data.RecipePrototype +local function recipe_results_in(recipe, x) + for _, result in pairs(recipe.results or {}) + do + if result.name == x + then + return true + end + end + return false +end + +---@param effect_name string +---@param effect_value number +local function is_effect_banned(effect_name, effect_value) + if effect_name == "consumption" + then + if effect_value > 0 + then + return settings.startup["banned-module-effect-consumption-increase"].value + else + return settings.startup["banned-module-effect-consumption-decrease"].value + end + else + return settings.startup["banned-module-effect-"..effect_name].value + end +end + +for _, module in pairs(data.raw["module"]) +do + local new_effects = {} + local changed = false + local empty = true + for effect_name, effect_value in pairs(module.effect) + do + if is_effect_banned(effect_name, effect_value) + then + changed = true + else + new_effects[effect_name] = effect_value + empty = false + end + end + if changed + then + if not empty + then + module.effect = new_effects + else + data.raw["module"][module.name].hidden = true + for _, technology in pairs(data.raw["technology"]) + do + if technology.effects + then + remove_recipe_effect(technology, module.name) + if #technology.effects == 0 + then + technology.hidden = true + log("Npm: removed technology "..technology.name) + table.insert(removed_technologies, technology.name) + end + end + end + for _, recipe in pairs(data.raw["recipe"]) + do + if recipe_results_in(recipe, module.name) + then + recipe.hidden = true + end + remove_ingredient(recipe, module.name) + end + end + end +end + +if settings.startup["banned-module-effect-quality"].value +then + ---@type data.UnlockQualityModifier + local unlock_uncommon = {type = "unlock-quality", quality = "uncommon"} + ---@type data.UnlockQualityModifier + local unlock_rare = {type = "unlock-quality", quality = "rare"} + if mods["quality"] + then + remove_effect(data.raw["technology"]["quality-module"], unlock_uncommon) + remove_effect(data.raw["technology"]["quality-module"], unlock_rare) + end + if mods["promethium-quality"] + then + table.insert(data.raw["technology"]["refinery"].effects, unlock_uncommon) + table.insert(data.raw["technology"]["refinery"].effects, unlock_rare) + end +end + +for _, technology in pairs(data.raw["technology"]) +do + for _, removed_tech in pairs(removed_technologies) + do + remove_prerequisite(technology, removed_tech) + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/no-productivity-modules/info.json Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,8 @@ +{ + "name": "no-productivity-modules", + "author": "teemu", + "version": "0.0.0", + "dependencies": ["base", "(?) quality", "(?) promethium-quality"], + "factorio_version": "2.0", + "title": "Ban modules" +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/no-productivity-modules/locale/en/ban-modules.cfg Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,7 @@ +[mod-setting-name] +banned-module-effect-speed=Ban modules from affecting machine speed +banned-module-effect-consumption-increase=Ban modules from increasing energy consumption +banned-module-effect-consumption-decrease=Ban modules from decreasing energy consumption +banned-module-effect-pollution=Ban modules from affecting pollution +banned-module-effect-productivity=Ban modules from affecting productivity bonus +banned-module-effect-quality=Ban modules from affecting quality \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/no-productivity-modules/settings.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,17 @@ +for _, effect in pairs{ + "consumption-increase", + "consumption-decrease", + "speed", + "productivity", + "pollution", + "quality"} +do + data:extend({ + { + type = "bool-setting", + name = "banned-module-effect-"..effect, + setting_type = "startup", + default_value = true + } + }) +end \ No newline at end of file
--- a/place-sounds/control.lua Wed Jul 23 16:08:55 2025 +0300 +++ b/place-sounds/control.lua Wed Aug 27 10:26:12 2025 +0300 @@ -1,43 +1,57 @@ -script.on_event(defines.events.on_built_entity, function(event) - local sound_path = "entity-close/"..event.entity.name +---@param entity LuaEntity +local function should_play_entity_sounds(entity) + return not (entity.type == "electric-pole" or entity.type == "wall" or entity.name == "stone-furnace") +end + +---@param entity LuaEntity +---@param sound_path SoundPath +local function try_play_sound(entity, sound_path, position) if helpers.is_valid_sound_path(sound_path) then - event.entity.surface.play_sound{ + entity.surface.play_sound{ path=sound_path, - position=game.players[event.player_index].position, + position=entity.position, } + return true + else + return false end +end + +local function play_drop_sounds(entity, position) + if not (should_play_entity_sounds(entity) and try_play_sound(entity, "entity-close/"..entity.name)) + then + try_play_sound(entity, "item-drop/"..entity.name) + end +end + +local function play_mined_sounds(entity, position) + if not (should_play_entity_sounds(entity) and try_play_sound(entity, "entity-open/"..entity.name, position)) + then + try_play_sound(entity, "item-pick/"..entity.name, position) + end +end + +script.on_event(defines.events.on_built_entity, function(event) + play_drop_sounds(event.entity, game.players[event.player_index].position) end) script.on_event(defines.events.on_robot_built_entity, function(event) - local sound_path = "entity-close/"..event.entity.name - if helpers.is_valid_sound_path(sound_path) - then - event.entity.surface.play_sound{ - path=sound_path, - position=event.entity.position, - } - end + play_drop_sounds(event.entity, event.entity.position) +end) + +script.on_event(defines.events.on_space_platform_built_entity, function(event) + play_drop_sounds(event.entity, event.entity.position) end) script.on_event(defines.events.on_player_mined_entity, function(event) - local sound_path = "entity-open/"..event.entity.name - if helpers.is_valid_sound_path(sound_path) - then - event.entity.surface.play_sound{ - path=sound_path, - position=game.players[event.player_index].position, - } - end + play_mined_sounds(event.entity, game.players[event.player_index].position) end) script.on_event(defines.events.on_robot_mined_entity, function(event) - local sound_path = "entity-open/"..event.entity.name - if helpers.is_valid_sound_path(sound_path) - then - event.entity.surface.play_sound{ - path=sound_path, - position=event.entity.position, - } - end + play_mined_sounds(event.entity, event.entity.position) end) + +script.on_event(defines.events.on_space_platform_mined_entity, function(event) + play_mined_sounds(event.entity, event.entity.position) +end)
--- a/place-sounds/data-final-fixes.lua Wed Jul 23 16:08:55 2025 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ ----@class entity EntityPrototype ----@class item ItemPrototype -local function copy_item_sounds_to_entity(item, entity) - entity.open_sound = table.deepcopy(item.pick_sound) - entity.close_sound = table.deepcopy(item.drop_sound) -end - --- prevent metallic machine sounds when placing power poles -local sounds = require("__base__.prototypes.entity.sounds") -for _, electric_pole in pairs(data.raw["electric-pole"]) -do - electric_pole.open_sound = sounds.electric_large_open - electric_pole.close_sound = sounds.electric_large_close -end - --- prevent metallic machine sounds when placing stuff made of bricks -copy_item_sounds_to_entity(data.raw.item["stone-furnace"], data.raw.furnace["stone-furnace"]) -copy_item_sounds_to_entity(data.raw.item["stone-wall"], data.raw.wall["stone-wall"])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/science-extra-trigger-techs/data-final-fixes.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,16 @@ +for _, tech in pairs(data.raw["technology"]) +do + for k, v in pairs(tech.prerequisites or {}) + do + local replacement = data.raw["technology"][v]["_science_extra_trigger_technology"] + if replacement and tech.name ~= replacement + then + tech.prerequisites[k] = replacement + end + end +end + +for _, tech in pairs(data.raw["technology"]) +do + tech["_science_extra_trigger_technology"] = nil +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/science-extra-trigger-techs/data-updates.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,82 @@ +---@type table<string, int> +local min_science_requirements = {} + +-- Extract tech tier from the name +-- e.g. "military-3" => 3 +---@param name string +local function tech_level(name) + local a, b = string.find(name, "-%d+$") + if a == nil + then + return nil + else + return tonumber(string.sub(name, a+1, b)) + end +end + +for _, technology in pairs(data.raw["technology"]) +do + if technology.unit + then + local prerequisites = {} + for _, prereq in pairs(technology.prerequisites or {}) + do + prerequisites[prereq] = 1 + end + local unit_count = 50 + if technology.unit.count + then + unit_count = technology.unit.count + elseif technology.unit.count_formula + then + local level = tech_level(technology.name) or 1 + unit_count = math.max(1, helpers.evaluate_expression(technology.unit.count_formula, {l = level, L = level})) + end + for _, ing in pairs(technology.unit.ingredients or {}) + do + if prerequisites[ing[1]] + then + local count = math.min(500, ing[2] * unit_count / 5) + if not min_science_requirements[ing[1]] + then + min_science_requirements[ing[1]] = count + else + min_science_requirements[ing[1]] = math.min(min_science_requirements[ing[1]], count) + end + end + end + end +end + +for _, technology in pairs(data.raw["technology"]) +do + local science_pack = nil + for _, effect in pairs(technology.effects or {}) + do + if effect.type == "unlock-recipe" and min_science_requirements[effect.recipe] + then + science_pack = effect.recipe + break + end + end + if science_pack ~= nil + then + ---@type data.TechnologyPrototype + local trigger_tech = { + type = "technology", + name = technology.name.."-2", + research_trigger = { + type = "craft-item", + item = science_pack, + count = math.min(500, min_science_requirements[science_pack]), + }, + icon = technology.icon, + icons = technology.icons, + icon_size = technology.icon_size, + prerequisites = {technology.name}, + upgrade = true, + } + technology["_science_extra_trigger_technology"] = technology.name.."-2" + data:extend{trigger_tech} + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/science-extra-trigger-techs/info.json Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,9 @@ +{ + "name": "science-extra-trigger-techs", + "title": "Don't queue science packs not yet crafted", + "author": "teemu", + "factorio_version": "2.0", + "dependencies": ["base"], + "version": "1.0.2", + "description": "Prevents adding technologies to research queue before actually crafting their science packs." +}
--- a/show-buildable/data-updates.lua Wed Jul 23 16:08:55 2025 +0300 +++ b/show-buildable/data-updates.lua Wed Aug 27 10:26:12 2025 +0300 @@ -34,6 +34,7 @@ new_entity.circuit_connector = nil new_entity.next_upgrade = nil new_entity.fast_replaceable_group = nil + new_entity.hidden = true mangle_fluid_box(new_entity.fluid_box) for _, fluid_box in pairs (new_entity.fluid_boxes or {}) do
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voidblock-nauvis-icon/data-updates.lua Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,4 @@ +data.raw.planet["nauvis"].starmap_icon = "__voidblock-nauvis-icon__/graphics/icons/starmap-planet-nauvis.png" +data.raw.planet["nauvis"].starmap_icon_size = 512 +data.raw.planet["nauvis"].icon = "__voidblock-nauvis-icon__/graphics/icons/nauvis.png" +data.raw.planet["nauvis"].icon_size = 64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voidblock-nauvis-icon/info.json Wed Aug 27 10:26:12 2025 +0300 @@ -0,0 +1,9 @@ +{ + "author": "teemu", + "name": "voidblock-nauvis-icon", + "title": "Void Block purple planet icon", + "version": "1.0.0", + "dependencies": ["base", "VoidBlock"], + "description": "Replaces the Nauvis planet icon with a purple one to fit VoidBlock", + "factorio_version": "2.0" +} \ No newline at end of file