fusion-lab/control.lua

changeset 10
101603241531
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fusion-lab/control.lua	Wed Jul 02 14:28:57 2025 +0300
@@ -0,0 +1,159 @@
+local function init_storage()
+	if storage.fusion_labs == nil
+	then
+		storage.fusion_labs = {}
+		local num_labs = 0
+		for _, surface in pairs(game.surfaces)
+		do
+			for _, lab in pairs(surface.find_entities_filtered{name="fusion-lab"})
+			do
+				if lab.valid
+				then
+				num_labs = num_labs + 1
+					local heat_interfaces = surface.find_entities_filtered{
+						name='fusion-lab-heat-interface',
+						position=lab.position,
+						limit = 1,
+					}
+					local heat_interface
+					if #heat_interfaces == 0
+					then
+						heat_interfaces = {lab.surface.create_entity{
+							name='fusion-lab-heat-interface',
+							position=lab.position,
+							force=lab.force,
+						}}
+						heat_interfaces[1].temperature = 15
+						heat_interfaces[1].destructible = false
+					end
+					storage.fusion_labs[lab] = {
+						heat_interface = heat_interfaces[1],
+					}
+				end
+			end
+		end
+	end
+end
+
+local function cleanup_labs()
+	local new_storage_fusion_labs = {}
+	for lab, lab_info in pairs(storage.fusion_labs)
+	do
+		if lab.valid
+		then
+			new_storage_fusion_labs[lab] = lab_info
+		end
+	end
+	storage.fusion_labs = new_storage_fusion_labs
+end
+
+script.on_nth_tick(31, function(event)
+	init_storage()
+	local need_cleanup = false
+	for lab, lab_info in pairs(storage.fusion_labs)
+	do
+		if not lab.valid
+		then
+			need_cleanup = true
+		elseif lab.status == defines.entity_status.working
+		then
+			local heat_interface = lab_info.heat_interface
+			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
+			-- to conveniently radiate exactly half of that energy rate.
+			--
+			-- The 0.341 here is 31/60*0.66 = 0.341 degrees of heat increase
+			-- every 31 ticks, for 0.66 ℃/sec. it's written out as 0.341 to
+			-- avoid potential floating point rounding errors.
+			heat_interface.temperature = heat_interface.temperature + (1 + lab.consumption_bonus) * 0.341
+			if heat_interface.temperature > 600
+			then
+				lab.surface.create_entity{
+					name = 'fusion-lab-smoke-source',
+					position={lab.position.x + 3.5 * (math.random() - 0.5), lab.position.y + 3.5 * (math.random() - 0.5)},
+					force=lab.force,
+				}
+			end
+			if heat_interface.temperature > 710.0
+			then
+				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,
+				}
+			end
+			--[[
+			if heat_interface.temperature > 750.0
+			then
+				lab.die()
+			end
+			]]--
+		end
+	end
+	if need_cleanup
+	then
+		cleanup_labs()
+	end
+end)
+
+
+script.on_event(defines.events.on_entity_died, function(event)
+	local lab = event.entity
+	-- we can't rely on storage here
+	local heat_interfaces = lab.surface.find_entities_filtered{
+		name='fusion-lab-heat-interface',
+		position=lab.position,
+		limit = 1,
+	}
+	if #heat_interfaces > 0
+	then
+		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}}
+			do
+				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,
+				}
+			end
+		end
+		heat_interface.destroy()
+	end
+end, {{filter="name", name="fusion-lab"}})
+
+local function on_fusion_lab_mined(event)
+	init_storage()
+	local entity = event.entity
+	for _, heat_interface in pairs(entity.surface.find_entities_filtered{
+			name='fusion-lab-heat-interface',
+			position = entity.position
+		})
+	do
+		heat_interface.destroy()
+	end
+end
+
+local function on_fusion_lab_built(event)
+	init_storage()
+	local lab = event.entity
+	heat_interface = lab.surface.create_entity{
+		name='fusion-lab-heat-interface',
+		position=lab.position,
+		force=lab.force,
+	}
+	heat_interface.temperature = 15
+	heat_interface.destructible = false
+	storage.fusion_labs[lab] = {heat_interface = heat_interface}
+end
+
+script.on_event(defines.events.on_player_mined_entity, on_fusion_lab_mined, {{filter="name", name="fusion-lab"}})
+script.on_event(defines.events.on_robot_mined_entity, on_fusion_lab_mined, {{filter="name", name="fusion-lab"}})
+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"}})

mercurial