Add ready rocket silo with custom GUI

This commit is contained in:
Simon Brodtmann 2025-01-26 16:06:55 +01:00
parent 0a795f5668
commit 51a61cd2e0
11 changed files with 441 additions and 98 deletions

View file

@ -0,0 +1,19 @@
local InitExisting = {}
-- Initialization for existing games
-- Don't send players to Lignumis but instead print a warning
InitExisting.on_init = function()
if game.tick == 0 then return end
storage.init = {}
for _, player in pairs(game.players) do
storage.init[player.index] = true
if player.physical_surface.name == "nauvis" then
storage.nauvis_visited = true
end
end
game.print { "", { "lignumis.start-new-game" } }
end
return InitExisting

View file

@ -0,0 +1,72 @@
local InitNew = {}
-- Initialization for new games
-- Send all players to Lignumis and clear Nauvis
-- Initialize the freeplay intro
local function init_intro()
if not remote.interfaces.freeplay then return end
-- Disable Nauvis intro
remote.call("freeplay", "set_disable_crashsite", true)
remote.call("freeplay", "set_skip_intro", true)
-- Replace yellow ammo with wood ammo
-- Wooden military does the same already
if not script.active_mods["wood-military"] then
local respawn_items = remote.call("freeplay", "get_respawn_items")
respawn_items["wood-darts-magazine"] = respawn_items["firearm-magazine"]
respawn_items["firearm-magazine"] = nil
remote.call("freeplay", "set_respawn_items", respawn_items)
local created_items = remote.call("freeplay", "get_created_items")
created_items["wood-darts-magazine"] = created_items["firearm-magazine"]
created_items["firearm-magazine"] = nil
remote.call("freeplay", "set_created_items", created_items)
end
end
-- Initialize space locations
-- Lock Nauvis, unlock Lignumis
local function init_space_locations()
local force = game.forces.player
force.technologies["planet-discovery-lignumis"].researched = true
if not force.technologies["planet-discovery-nauvis"].researched then
force.lock_space_location("nauvis")
end
end
-- Initialize Lignumis
local function init_lignumis()
storage.surface = game.planets["lignumis"].create_surface()
storage.surface.request_to_generate_chunks({ 0, 0 }, 3)
storage.surface.force_generate_chunk_requests()
storage.surface.daytime = 0.7
-- Chart starting area
local r = 200
local force = game.forces.player
local origin = force.get_spawn_position(storage.surface)
force.chart(storage.surface, { { origin.x - r, origin.y - r }, { origin.x + r, origin.y + r } })
end
-- Clear Nauvis surface as we start on Lignumis
local function clear_nauvis()
game.get_surface("nauvis").clear()
end
InitNew.on_init = function()
if game.tick > 0 then return end
init_intro()
init_space_locations()
init_lignumis()
clear_nauvis()
end
return InitNew

137
lignumis/scripts/init.lua Normal file
View file

@ -0,0 +1,137 @@
local crash_site = require("crash-site")
local util = require("util")
-- General initialization
local Init = {
events = {}
}
-- Migrate storage init as it was just a boolean before not supporting multiple players
local function migrate_0_9_6(event)
if storage.init and type(storage.init) == "boolean" then
storage.init = {
[event.player_index] = true
}
end
end
-- Initialize the player
-- Teleport to Lignumis and give some starting items
local function init_player(event)
local player = game.get_player(event.player_index)
if not player.character then return end
local surface = storage.surface or game.planets["lignumis"].surface
player.teleport(surface.find_non_colliding_position("character", { 0, 0 }, 0, 1), "lignumis")
player.character.destructible = false
local main_inventory = player.character.get_main_inventory()
-- Add some starting items to player inventory
main_inventory.insert({ name = "lumber", count = 8 })
end
-- Initialize the freeplay scenario
local function init_freeplay(event)
local player = game.get_player(event.player_index)
if not player or not remote.interfaces.freeplay then return end
local surface = storage.surface or game.planets["lignumis"].surface
storage.crashed_ship_items = remote.call("freeplay", "get_ship_items")
storage.crashed_debris_items = remote.call("freeplay", "get_debris_items")
storage.crashed_ship_parts = remote.call("freeplay", "get_ship_parts")
storage.starting_message = remote.call("freeplay", "get_custom_intro_message")
local ship_items = {
["burner-mining-drill"] = 1,
["burner-agricultural-tower"] = 2
}
local debris_items = {
["lumber"] = 8,
["wood-darts-magazine"] = 2
}
crash_site.create_crash_site(surface, { -5, -6 }, ship_items, debris_items,
table.deepcopy(storage.crashed_ship_parts))
util.remove_safe(player, storage.crashed_ship_items)
util.remove_safe(player, storage.crashed_debris_items)
player.character.get_main_inventory().sort_and_merge()
storage.crash_site_cutscene_active = true
crash_site.create_cutscene(player, { -5, -4 })
end
Init.events[defines.events.on_player_created] = function(event)
migrate_0_9_6(event)
storage.init = storage.init or {}
if storage.init[event.player_index] then return end
storage.init[event.player_index] = true
init_player(event)
init_freeplay(event)
end
-- Watch Nauvis being visited for the first time
Init.events[defines.events.on_player_changed_surface] = function(event)
local player = game.get_player(event.player_index)
if player and player.surface.name == "nauvis" then
storage.nauvis_visited = true
end
end
-- End intro and show starting message
Init.events[defines.events.on_cutscene_waypoint_reached] = function(event)
if not storage.crash_site_cutscene_active then return end
if not crash_site.is_crash_site_cutscene(event) then return end
local player = game.get_player(event.player_index)
player.exit_cutscene()
if storage.skip_intro then return end
local intro_message = storage.custom_intro_message or { "msg-intro-space-age" }
if game.is_multiplayer() then
player.print(intro_message)
else
game.show_message_dialog { text = intro_message }
end
end
-- Cancel intro
Init.events["crash-site-skip-cutscene"] = function(event)
if not storage.crash_site_cutscene_active then return end
if event.player_index ~= 1 then return end
local player = game.get_player(event.player_index)
if player.controller_type == defines.controllers.cutscene then
player.exit_cutscene()
end
end
Init.events[defines.events.on_cutscene_cancelled] = function(event)
if not storage.crash_site_cutscene_active then return end
if event.player_index ~= 1 then return end
storage.crash_site_cutscene_active = nil
local player = game.get_player(event.player_index)
if player.gui.screen.skip_cutscene_label then
player.gui.screen.skip_cutscene_label.destroy()
end
if player.character then
player.character.destructible = true
end
player.zoom = 1.5
end
return Init

View file

@ -0,0 +1,88 @@
local crash_site = require("crash-site")
-- Transition from Lignumis to Nauvis with the provisional rocket silo
local ToNauvis = {
events = {}
}
-- Chart the starting area for the player
local function chart_starting_area(surface, player)
local r = 200
local force = player.force
local origin = force.get_spawn_position(surface)
force.chart(surface, { { origin.x - r, origin.y - r }, { origin.x + r, origin.y + r } })
end
-- Initialize Nauvis
local function init_nauvis()
if storage.nauvis_visited then return end
local nauvis = game.planets["nauvis"].create_surface()
nauvis.request_to_generate_chunks({ 0, 0 }, 3)
nauvis.force_generate_chunk_requests()
nauvis.daytime = 0.7
end
-- Teleport player to Nauvis and show welcome message
local function teleport_player(player)
local nauvis = game.planets["nauvis"].surface
if player.surface.name == "lignumis" then
player.teleport(nauvis.find_non_colliding_position("character", { 0, 0 }, 0, 1), "nauvis")
chart_starting_area(nauvis, player)
player.print("Oh no, not again. But... Welcome to Nauvis!")
end
end
-- Initialize the Nauvis freeplay scenario
local function init_freeplay()
if not remote.interfaces.freeplay then return end
local nauvis = game.planets["nauvis"].surface
local ship_items = {
["burner-mining-drill"] = 2,
["stone-furnace"] = 2,
["burner-assembling-machine"] = 2,
["burner-agricultural-tower"] = 2,
["wood-lab"] = 2
}
local debris_items = { ["wood-darts-magazine"] = 20, ["wood"] = 20, ["lumber"] = 20 }
local crashed_ship_parts = remote.call("freeplay", "get_ship_parts")
crash_site.create_crash_site(nauvis, { -5, -6 }, ship_items, debris_items, table.deepcopy(crashed_ship_parts))
end
ToNauvis.events[defines.events.on_rocket_launched] = function(event)
if not event.rocket_silo.name == "provisional-rocket-silo" then return end
local rocket_entry
local rocket_entry_index
local player
for i, entry in pairs(storage.rocket_silos) do
if entry.real_silo == event.rocket_silo then
rocket_entry = entry
rocket_entry_index = i
player = game.get_player(entry.player)
break
end
end
init_nauvis()
teleport_player(player)
init_freeplay()
-- Give the player the content of the rocket
local inventory = player.get_main_inventory()
for _, item in pairs(rocket_entry.rocket_content) do
inventory.insert(item)
end
inventory.sort_and_merge()
table.remove(storage.rocket_silos, rocket_entry_index)
end
return ToNauvis

View file

@ -0,0 +1,147 @@
local RocketSilo = {
events = {}
}
-- Logic for provisional rocket silo with fake silo with inventory and custom launch GUI
local function build_gui(player, rocket_silo)
local anchor = {
gui = defines.relative_gui_type.container_gui,
names = { "provisional-rocket-silo-ready" },
position = defines.relative_gui_position.right
}
local launch_button = { type = "button", name = "provisional-rocket-silo-launch-button", caption = { "lignumis.provisional-rocket-silo-button" } }
local inventory = player.get_main_inventory()
launch_button.enabled = inventory.is_empty()
if not launch_button.enabled then
launch_button.tooltip = { "lignumis.provisional-rocket-silo-button-tooltip" }
end
storage.rocket_silo_guis = storage.rocket_silo_guis or {}
storage.rocket_silo_guis[player.index] = {
fake_silo = rocket_silo,
gui = gui.add(player.gui.relative, {
{
type = "frame",
name = "provisional-rocket-silo-relative-frame",
direction = "vertical",
anchor = anchor,
children = {
{ type = "label", style = "frame_title", caption = { "lignumis.provisional-rocket-silo-button" }, ignored_by_interaction = true },
{
type = "frame",
direction = "vertical",
style = "inside_shallow_frame_with_padding",
children = {
{
type = "flow",
direction = "vertical",
style = "inset_frame_container_vertical_flow",
children = {
{ type = "label", caption = { "lignumis.provisional-rocket-silo-description" } },
launch_button
}
}
}
}
}
}
})
}
end
local function on_gui_opened(event)
local entity = event.entity
if not entity or not entity.valid then return end
if entity.name ~= "provisional-rocket-silo-ready" then return end
local player = game.get_player(event.player_index)
if player.gui.relative["provisional-rocket-silo-relative-frame"] then
player.gui.relative["provisional-rocket-silo-relative-frame"].destroy()
end
build_gui(player, entity)
end
local function on_gui_closed(event)
local entity = event.entity
if not entity or not entity.valid then return end
if entity.name ~= "provisional-rocket-silo-ready" then return end
end
local function launch(event)
if event.element.name ~= "provisional-rocket-silo-launch-button" then return end
local player = game.get_player(event.player_index)
local fake_silo = storage.rocket_silo_guis[player.index].fake_silo
rocket_content = fake_silo.get_inventory(defines.inventory.chest).get_contents()
for _, entry in pairs(storage.rocket_silos) do
if entry.fake_silo == fake_silo then
entry.player = event.player_index
entry.rocket_content = rocket_content
fake_silo.destroy()
entry.real_silo.launch_rocket()
break
end
end
end
local function on_silo_mined(event)
if event.entity.name ~= "provisional-rocket-silo-ready" then return end
local fake_silo = event.entity
local player = game.get_player(event.player_index)
for i, entry in pairs(storage.rocket_silos) do
if entry.fake_silo == fake_silo then
player.mine_entity(entry.real_silo, true)
table.remove(storage.rocket_silos, i)
break
end
end
end
RocketSilo.on_init = function()
storage.rocket_silos = {}
storage.rocket_silo_guis = {}
end
RocketSilo.events[defines.events.on_script_trigger_effect] = function(event)
if event.effect_id ~= "provisional-rocket-ready" then return end
local lignumis = game.planets["lignumis"].surface
if event.surface_index ~= lignumis.index then return end
local real_silo = event.cause_entity
local fake_silo = real_silo.surface.create_entity({
name = "provisional-rocket-silo-ready",
position = real_silo.position,
force = real_silo.force,
create_build_effect_smoke = false,
})
storage.rocket_silos = storage.rocket_silos or {}
table.insert(storage.rocket_silos, {
real_silo = real_silo,
fake_silo = fake_silo
})
for _, player in pairs(real_silo.force.players) do
if player.selected == real_silo then
player.selected = fake_silo
end
end
end
RocketSilo.events[defines.events.on_gui_opened] = on_gui_opened
RocketSilo.events[defines.events.on_gui_closed] = on_gui_closed
RocketSilo.events[defines.events.on_gui_click] = launch
RocketSilo.events[defines.events.on_player_mined_entity] = on_silo_mined
return RocketSilo