fusion-lab/data.lua

Wed, 02 Jul 2025 14:28:57 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Wed, 02 Jul 2025 14:28:57 +0300
changeset 10
101603241531
permissions
-rw-r--r--

Add fusion lab (currently v1.2.3)

local fluoro_heat_exchanger_icons = {
	{icon = data.raw.boiler['heat-exchanger'].icon},
	{
		icon = data.raw.fluid['fluoroketone-cold'].icon,
		scale = 0.3,
		shift = {-8, -8},
	},
}

data:extend{
	{
		type = "item",
		name = "fusion-lab",
		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,
		place_result = "fusion-lab",
		weight = 200 * kg,
		stack_size = 5,
		default_import_location = "aquilo"
	},
	{
		type = "recipe",
		name = "fusion-lab",
		category = data.raw.recipe['fusion-reactor'].category,
		subgroup = data.raw.recipe.lab.subgroup,
		order = "x[fusion-lab]",
		enabled = false,
		energy_required = data.raw.recipe.biolab.energy_required,
		ingredients =
		{
			{type = "item", name = "lab", amount = 1},
			{type = "item", name = "refined-concrete", amount = 25},
			{type = "item", name = "tungsten-plate", amount = 50},
			{type = "item", name = "holmium-plate", amount = 50},
			{type = "item", name = "quantum-processor", amount = 50},
		},
		results = {
			{type = "item", name = "fusion-lab", amount = 1},
		},
		surface_conditions = table.deepcopy(data.raw.recipe['fusion-reactor'].surface_conditions),
		allow_productivity = false,
	},
	{
		type = "lab",
		name = "fusion-lab",
		selection_priority = 100,
		icon = "__fusion-lab__/graphics/icons/photometric-lab-icon.png",
		flags = {"placeable-player", "player-creation"},
		minable = {mining_time = 0.2, result = "fusion-lab"},
		max_health = 350,
		corpse = "cargo-bay-remnants",
		dying_explosion = "lab-explosion",
		collision_box = data.raw.lab.biolab.collision_box, -- 5×5
		selection_box = data.raw.lab.biolab.selection_box, -- 5×5
		damaged_trigger_effect = data.raw.lab.lab.damaged_trigger_effect,
		surface_conditions = table.deepcopy(data.raw.container['steel-chest'].surface_conditions),
		on_animation =
		{
			layers =
			{
				util.sprite_load("__fusion-lab__/graphics/entity/fusion-lab/photometric-lab-hr-shadow", {
					frame_count = 1,
					scale = 0.5,
					repeat_count = 80,
					animation_speed = 0.4,
					draw_as_shadow = true,
				}),
				util.sprite_load("__fusion-lab__/graphics/entity/fusion-lab/photometric-lab-hr-animation", {
					frame_count = 80,
					animation_speed = 0.4,
					scale = 0.5
				}),
				util.sprite_load("__fusion-lab__/graphics/entity/fusion-lab/photometric-lab-hr-emission", {
					frame_count = 80,
					animation_speed = 0.4,
					scale = 0.5,
					blend_mode = "additive",
					draw_as_glow = true,
				}),
			}
		},
		off_animation =
		{
			layers =
			{
				util.sprite_load("__fusion-lab__/graphics/entity/fusion-lab/photometric-lab-hr-shadow", {
					frame_count = 1,
					scale = 0.5,
					repeat_count = 80,
					animation_speed = 0.4,
					draw_as_shadow = true,
				}),
				util.sprite_load("__fusion-lab__/graphics/entity/fusion-lab/photometric-lab-hr-animation", {
					frame_count = 80,
					animation_speed = 0.4,
					scale = 0.5
				}),
			}
		},
		working_sound =
		{
			-- 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,
			},
			fade_in_ticks = 4,
			fade_out_ticks = 20,
			sound_accents =
			{
				{sound = {filename = "__space-age__/sound/entity/foundry/foundry-slide-open.ogg", volume = 0.65, audible_distance_modifier = 0.3}, frame = 3},
				{sound = {filename = "__space-age__/sound/entity/foundry/foundry-slide-close.ogg", volume = 0.65, audible_distance_modifier = 0.3}, frame = 34},
				{sound = {variations = sound_variations("__quality__/sound/recycler/recycler-mechanic", 3, 0.85), audible_distance_modifier = 0.3}, frame = 16},
				{sound = {variations = sound_variations("__quality__/sound/recycler/recycler-mechanic", 3, 0.85), audible_distance_modifier = 0.3}, frame = 41},
				{sound = {variations = sound_variations("__quality__/sound/recycler/recycler-jaw-shut", 3, 0.35), audible_distance_modifier = 0.3}, frame = 24},
				{sound = {variations = sound_variations("__quality__/sound/recycler/recycler-jaw-shut", 3, 0.45), audible_distance_modifier = 0.3}, frame = 64},
				{sound = {variations = sound_variations("__space-age__/sound/entity/electromagnetic-plant/emp-electric", 5, 0.5), audible_distance_modifier = 0.4, }, frame = 6 - 5},
				{sound = {variations = sound_variations("__space-age__/sound/entity/electromagnetic-plant/emp-electric", 5, 0.5), audible_distance_modifier = 0.4, }, frame = 56 - 5},
				{sound = {filename = "__space-age__/sound/entity/tesla-turret/tesla-turret-rotation-stop.ogg", volume = 0.8, audible_distance_modifier = 0.6}, frame = 8},
				{sound = {filename = "__space-age__/sound/entity/tesla-turret/tesla-turret-rotation-stop.ogg", volume = 0.8, audible_distance_modifier = 0.6}, frame = 44},
				{sound = {variations = sound_variations("__space-age__/sound/entity/biolab/biolab-beaker", 7, 0.95), audible_distance_modifier = 0.6}, frame = 20},
			},
			max_sounds_per_prototype = 2
		},
		impact_category = "glass",
		open_sound = { filename = "__base__/sound/open-close/lab-open.ogg", volume = 0.6 },
		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,
		inputs = table.deepcopy(data.raw.lab.biolab.inputs),
		science_pack_drain_rate_percent = settings.startup["fusion-lab-drain-rate-percent"].value,
		icons_positioning = data.raw.lab.biolab.icons_positioning,
	},
	{
		type = "heat-interface",
		name = "fusion-lab-heat-interface",
		icon = "__base__/graphics/icons/heat-interface.png",
		flags = {"placeable-player", "not-on-map", "not-flammable", "not-blueprintable", "not-deconstructable"},
		placeable_by = {item = "fusion-lab", count = 1},
		collision_mask = {layers={}},
		selection_priority = 150,
		hidden = true,
		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
		open_sound = data.raw["fusion-reactor"]["fusion-reactor"].open_sound,
		close_sound = data.raw["fusion-reactor"]["fusion-reactor"].close_sound,
		heat_buffer =
		{
			max_temperature = 1000,
			specific_heat = "1MJ",
			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},
			}
		},
		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",
		name = "fluoro-heat-exchanger",
		icons = fluoro_heat_exchanger_icons,
		subgroup = "energy",
		order = "f[nuclear-energy]-d[fluoro-heat-exchanger]",
		inventory_move_sound = data.raw.item["heat-exchanger"].inventory_move_sound,
		pick_sound = data.raw.item["heat-exchanger"].pick_sound,
		drop_sound = data.raw.item["heat-exchanger"].drop_sound,
		place_result = "fluoro-heat-exchanger",
		stack_size = 50,
		weight = 40*kg,
		random_tint_color = data.raw.item["heat-exchanger"].random_tint_color,
	},
	{
		type = "technology",
		name = "fusion-lab",
		icon = "__fusion-lab__/graphics/technology/fusion-lab.png",
		icon_size = 256,
		effects =
		{
			{
				type = "unlock-recipe",
				recipe = "fusion-lab"
			},
			{
				type = "unlock-recipe",
				recipe = "fluoro-heat-exchanger"
			},
		},
		prerequisites = {"fusion-reactor"},
		unit =
		{
			count_formula = "1000",
			ingredients = table.deepcopy(data.raw.technology["fusion-reactor"].unit.ingredients),
			time = 60
		}
	},
	{
		type = "recipe",
		name = "fluoro-heat-exchanger",
		category = "crafting",
		subgroup = data.raw.recipe["heat-exchanger"].subgroup,
		order = "zzz[fluoro-heat-exchanger]",
		enabled = false,
		energy_required = data.raw.recipe["heat-exchanger"].energy_required,
		ingredients = data.raw.recipe["heat-exchanger"].ingredients,
		results = {
			{type = "item", name = "fluoro-heat-exchanger", amount = 1},
		},
		allow_productivity = false,
	},
}

local fluoro_heat_exchanger = table.deepcopy(data.raw.boiler["heat-exchanger"])
fluoro_heat_exchanger.name = "fluoro-heat-exchanger"
fluoro_heat_exchanger.icon = nil
fluoro_heat_exchanger.icons = fluoro_heat_exchanger_icons
fluoro_heat_exchanger.fluid_box.filter = "fluoroketone-cold"
fluoro_heat_exchanger.output_fluid_box.filter = "fluoroketone-hot"
fluoro_heat_exchanger.minable.result = "fluoro-heat-exchanger"
fluoro_heat_exchanger.energy_source.min_working_temperature = 180
fluoro_heat_exchanger.target_temperature = 180
data:extend{fluoro_heat_exchanger}

local smoke_source = table.deepcopy(data.raw["particle-source"]["nuclear-smouldering-smoke-source"])
smoke_source.name = "fusion-lab-smoke-source"
smoke_source.time_before_start = 0
smoke_source.time_before_start_deviation = 0
smoke_source.time_to_live = 31
smoke_source.time_to_live_deviation = 0
smoke_source.height = 0.8
smoke_source.smoke[1].frequency = 0.5
data:extend{smoke_source}

-- TODO: replace the fusion-lab-heat-interface with this, once I figure out how
-- to change its "consumption" (i.e. power output) during runtime...
--[[
local void_reactor = table.deepcopy(data.raw.reactor['nuclear-reactor'])
void_reactor.name = "void-reactor"
void_reactor.energy_source = {type = "void"}
void_reactor.minable = nil
void_reactor.consumption = "660kW"
void_reactor.neighbour_bonus = 0
void_reactor.surface_conditions = nil
void_reactor.picture = nil
void_reactor.light = nil
void_reactor.working_light_picture = nil
data:extend{void_reactor}
]]--

local fusion_lab_menu_simulation = {
    checkboard = false,
    save = '__fusion-lab__/menu-simulations/menu-simulation-fusion-lab.zip',
    length = 60 * 14,
    init =
    [[
      local sim_planet = game.surfaces.fulgora
      local logo = sim_planet.find_entities_filtered{name = "factorio-logo-11tiles", limit = 1}[1]
      logo.destructible = false
      local center = {logo.position.x, logo.position.y+9.75}
      game.simulation.camera_surface_index = sim_planet.index
      game.simulation.camera_position = center
      game.simulation.camera_zoom = 1
      game.tick_paused = false
      require("__fusion-lab__.menu-simulations.menu-simulation-fusion-lab")
    ]]
  }

-- data.raw["utility-constants"]["default"].main_menu_simulations = {}
data.raw["utility-constants"]["default"].main_menu_simulations["fusion-lab"] = fusion_lab_menu_simulation

mercurial