You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
12 KiB
336 lines
12 KiB
local Landingpad = {}
|
|
|
|
-- constants
|
|
Landingpad.name_rocket_landing_pad = mod_prefix.."rocket-landing-pad"
|
|
Landingpad.name_rocket_landing_pad_settings = mod_prefix.."rocket-landing-pad-settings"
|
|
|
|
---@class LandingPad All data necessary to maintain the state of a delivery cannon
|
|
|
|
--- Gets the Landingpad for this unit_number
|
|
---@param unit_number number
|
|
function Landingpad.from_unit_number (unit_number)
|
|
if not unit_number then Log.trace("Landingpad.from_unit_number: invalid unit_number: nil") return end
|
|
unit_number = tonumber(unit_number)
|
|
-- NOTE: only supports container as the entity
|
|
if global.rocket_landing_pads[unit_number] then
|
|
return global.rocket_landing_pads[unit_number]
|
|
else
|
|
Log.trace("Landingpad.from_unit_number: invalid unit_number: " .. unit_number)
|
|
end
|
|
end
|
|
|
|
--- Gets the Landingpad for this entity
|
|
---@param entity LuaEntity
|
|
function Landingpad.from_entity (entity)
|
|
if not(entity and entity.valid) then
|
|
Log.trace("Landingpad.from_entity: invalid entity")
|
|
return
|
|
end
|
|
-- NOTE: only suppors container as the entity
|
|
return Landingpad.from_unit_number(entity.unit_number)
|
|
end
|
|
|
|
-- returns the available struct
|
|
function Landingpad.get_force_landing_pads_availability(force_name, landing_pad_name)
|
|
|
|
local empty_landing_pads = {}
|
|
local filled_landing_pads = {}
|
|
local blocked_landing_pads = {}
|
|
|
|
if global.forces[force_name] and global.forces[force_name].rocket_landing_pad_names and global.forces[force_name].rocket_landing_pad_names[landing_pad_name] then
|
|
local landing_pads = global.forces[force_name].rocket_landing_pad_names[landing_pad_name]
|
|
|
|
for _, landing_pad in pairs(landing_pads) do
|
|
if landing_pad.container and landing_pad.container.valid then
|
|
if landing_pad.inbound_rocket then
|
|
table.insert(blocked_landing_pads, landing_pad)
|
|
elseif landing_pad.container.get_inventory(defines.inventory.chest).is_empty() then
|
|
table.insert(empty_landing_pads, landing_pad)
|
|
else
|
|
table.insert(filled_landing_pads, landing_pad)
|
|
end
|
|
else
|
|
Landingpad.destroy(landing_pad)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
return {
|
|
empty_landing_pads = empty_landing_pads,
|
|
filled_landing_pads = filled_landing_pads,
|
|
blocked_landing_pads = blocked_landing_pads,
|
|
}
|
|
|
|
end
|
|
|
|
-- returns the available struct
|
|
function Landingpad.get_zone_landing_pads_availability(force_name, zone, landing_pad_name)
|
|
|
|
local empty_landing_pads = {}
|
|
local filled_landing_pads = {}
|
|
local blocked_landing_pads = {}
|
|
|
|
local zone_assets = Zone.get_force_assets(force_name, zone.index)
|
|
if zone_assets.rocket_landing_pad_names and zone_assets.rocket_landing_pad_names[landing_pad_name] then
|
|
local landing_pads = zone_assets.rocket_landing_pad_names[landing_pad_name]
|
|
|
|
|
|
for _, landing_pad in pairs(landing_pads) do
|
|
if landing_pad.container and landing_pad.container.valid then
|
|
if landing_pad.inbound_rocket then
|
|
table.insert(blocked_landing_pads, landing_pad)
|
|
elseif landing_pad.container.get_inventory(defines.inventory.chest).is_empty() then
|
|
table.insert(empty_landing_pads, landing_pad)
|
|
else
|
|
table.insert(filled_landing_pads, landing_pad)
|
|
end
|
|
else
|
|
Landingpad.destroy(landing_pad)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
return {
|
|
empty_landing_pads = empty_landing_pads,
|
|
filled_landing_pads = filled_landing_pads,
|
|
blocked_landing_pads = blocked_landing_pads,
|
|
}
|
|
|
|
end
|
|
|
|
function Landingpad.on_entity_created(event)
|
|
local entity = util.get_entity_from_event(event)
|
|
|
|
if not entity then return end
|
|
if entity.name == Landingpad.name_rocket_landing_pad then
|
|
local zone = Zone.from_surface(entity.surface)
|
|
if not zone then
|
|
return cancel_entity_creation(entity, event.player_index, {"space-exploration.construction-denied"})
|
|
end
|
|
local fn = entity.force.name
|
|
|
|
local default_name = zone.name .. " Landing Pad"
|
|
|
|
local struct = {
|
|
type = Landingpad.name_rocket_landing_pad,
|
|
valid = true,
|
|
force_name = fn,
|
|
unit_number = entity.unit_number,
|
|
container = entity,
|
|
name = default_name,
|
|
zone = zone
|
|
}
|
|
global.rocket_landing_pads = global.rocket_landing_pads or {}
|
|
global.rocket_landing_pads[entity.unit_number] = struct
|
|
|
|
Landingpad.name(struct) -- assigns to zone_assets
|
|
|
|
-- set settings
|
|
local tags = util.get_tags_from_event(event, Landingpad.serialize)
|
|
if tags then
|
|
Landingpad.deserialize(entity, tags)
|
|
end
|
|
|
|
if event.player_index and game.players[event.player_index] and game.players[event.player_index].connected then
|
|
LandingpadGUI.gui_open(game.players[event.player_index], struct)
|
|
end
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_entity_cloned, Landingpad.on_entity_created)
|
|
Event.addListener(defines.events.on_built_entity, Landingpad.on_entity_created)
|
|
Event.addListener(defines.events.on_robot_built_entity, Landingpad.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_built, Landingpad.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_revive, Landingpad.on_entity_created)
|
|
|
|
function Landingpad.remove_struct_from_tables(struct)
|
|
|
|
-- force
|
|
local force_data = global.forces[struct.force_name]
|
|
force_data.rocket_landing_pad_names = force_data.rocket_landing_pad_names or {}
|
|
local force_type_table = force_data.rocket_landing_pad_names
|
|
|
|
if not force_type_table[struct.name] then return end
|
|
force_type_table[struct.name][struct.unit_number] = nil
|
|
local count_remaining = 0
|
|
for _, remaining in pairs(force_type_table[struct.name]) do
|
|
count_remaining = count_remaining + 1
|
|
end
|
|
if count_remaining == 0 then
|
|
force_type_table[struct.name] = nil
|
|
end
|
|
|
|
-- zone
|
|
local zone_assets = Zone.get_force_assets(struct.force_name, struct.zone.index)
|
|
zone_assets.rocket_landing_pad_names = zone_assets.rocket_landing_pad_names or {}
|
|
local zone_type_table = zone_assets.rocket_landing_pad_names
|
|
|
|
if not zone_type_table[struct.name] then return end
|
|
zone_type_table[struct.name][struct.unit_number] = nil
|
|
local count_remaining = 0
|
|
for _, remaining in pairs(zone_type_table[struct.name]) do
|
|
count_remaining = count_remaining + 1
|
|
end
|
|
if count_remaining == 0 then
|
|
zone_type_table[struct.name] = nil
|
|
end
|
|
|
|
end
|
|
|
|
function Landingpad.destroy_sub(struct, key)
|
|
if struct[key] and struct[key].valid then
|
|
struct[key].destroy()
|
|
struct[key] = nil
|
|
end
|
|
end
|
|
|
|
function Landingpad.destroy(struct)
|
|
if not struct then
|
|
Log.trace("Landingpad.destroy: no struct")
|
|
return
|
|
end
|
|
struct.valid = false
|
|
Landingpad.destroy_sub(struct, 'container')
|
|
|
|
Landingpad.remove_struct_from_tables(struct)
|
|
global.rocket_landing_pads[struct.unit_number] = nil
|
|
|
|
-- if a player has this gui open then close it
|
|
local gui_name = LandingpadGUI.name_rocket_landing_pad_gui_root
|
|
for _, player in pairs(game.connected_players) do
|
|
local root = player.gui.relative[gui_name]
|
|
if root and root.tags and root.tags.unit_number == struct.unit_number then
|
|
player.gui.relative[gui_name].destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
function Landingpad.name(struct, new_name)
|
|
struct.name = (new_name or struct.name)
|
|
|
|
-- force
|
|
local force_data = global.forces[struct.force_name]
|
|
force_data.rocket_landing_pad_names = force_data.rocket_landing_pad_names or {}
|
|
local force_type_table = force_data.rocket_landing_pad_names
|
|
|
|
force_type_table[struct.name] = force_type_table[struct.name] or {}
|
|
force_type_table[struct.name][struct.unit_number] = struct
|
|
|
|
local zone_assets = Zone.get_force_assets(struct.force_name, struct.zone.index)
|
|
zone_assets.rocket_landing_pad_names = zone_assets.rocket_landing_pad_names or {}
|
|
local zone_type_table = zone_assets.rocket_landing_pad_names
|
|
|
|
zone_type_table[struct.name] = zone_type_table[struct.name] or {}
|
|
zone_type_table[struct.name][struct.unit_number] = struct
|
|
end
|
|
|
|
function Landingpad.rename(struct, new_name)
|
|
local old_name = struct.name
|
|
Landingpad.remove_struct_from_tables(struct)
|
|
Landingpad.name(struct, new_name)
|
|
end
|
|
|
|
function Landingpad.dropdown_list_zone_landing_pad_names(force_name, zone, current)
|
|
local selected_index
|
|
local list = {} -- names with optional [count]
|
|
local values = {} -- raw names
|
|
table.insert(list, {"space-exploration.none_general_vicinity"})
|
|
table.insert(values, "") -- not sure if nil would work
|
|
|
|
if zone and zone.type ~= "spaceship" then
|
|
local zone_assets = Zone.get_force_assets(force_name, zone.index)
|
|
for name, sites in pairs(zone_assets["rocket_landing_pad_names"]) do
|
|
local count = 0
|
|
for _, struct in pairs(sites) do
|
|
count = count + 1
|
|
end
|
|
if count == 1 then
|
|
table.insert(list, name)
|
|
table.insert(values, name)
|
|
if name == current then selected_index = #list end
|
|
elseif count > 1 then
|
|
table.insert(list, name .. " ["..count.."]")
|
|
table.insert(values, name)
|
|
if name == current then selected_index = #list end
|
|
end
|
|
end
|
|
end
|
|
return list, (selected_index or 1), values
|
|
end
|
|
|
|
function Landingpad.dropdown_list_force_landing_pad_names(force_name, current)
|
|
local selected_index
|
|
local list = {} -- names with optional [count]
|
|
local values = {} -- raw names
|
|
table.insert(list, {"space-exploration.none_cannot_launch"})
|
|
table.insert(values, "") -- not sure if nil would work
|
|
|
|
local force_data = global.forces[force_name]
|
|
if force_data.rocket_landing_pad_names then
|
|
for name, sites in pairs(force_data.rocket_landing_pad_names) do
|
|
local count = 0
|
|
for _, struct in pairs(sites) do
|
|
count = count + 1
|
|
end
|
|
if count == 1 then
|
|
table.insert(list, name)
|
|
table.insert(values, name)
|
|
if name == current then selected_index = #list end
|
|
elseif count > 1 then
|
|
table.insert(list, name .. " ["..count.."]")
|
|
table.insert(values, name)
|
|
if name == current then selected_index = #list end
|
|
end
|
|
end
|
|
end
|
|
return list, (selected_index or 1), values
|
|
end
|
|
|
|
function Landingpad.on_entity_removed(event)
|
|
local entity = event.entity
|
|
if entity and entity.valid and entity.name == Landingpad.name_rocket_landing_pad then
|
|
Landingpad.destroy(Landingpad.from_entity(entity))
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_entity_died, Landingpad.on_entity_removed)
|
|
Event.addListener(defines.events.on_robot_mined_entity, Landingpad.on_entity_removed)
|
|
Event.addListener(defines.events.on_player_mined_entity, Landingpad.on_entity_removed)
|
|
Event.addListener(defines.events.script_raised_destroy, Landingpad.on_entity_removed)
|
|
|
|
function Landingpad.serialize(entity)
|
|
local landing_pad = Landingpad.from_entity(entity)
|
|
if landing_pad then
|
|
local tags = {}
|
|
tags.name = landing_pad.name
|
|
return tags
|
|
end
|
|
end
|
|
|
|
function Landingpad.deserialize(entity, tags)
|
|
local landing_pad = Landingpad.from_entity(entity)
|
|
if landing_pad then
|
|
Landingpad.rename(landing_pad, tags.name)
|
|
end
|
|
end
|
|
|
|
--- Handles the player creating a blueprint by setting tags to store the state of landing pads
|
|
---@param event any
|
|
function Landingpad.on_player_setup_blueprint(event)
|
|
util.setup_blueprint(event, Landingpad.name_rocket_landing_pad, Landingpad.serialize)
|
|
end
|
|
Event.addListener(defines.events.on_player_setup_blueprint, Landingpad.on_player_setup_blueprint)
|
|
|
|
--- Handles the player copy/pasting settings between landing pads
|
|
---@param event any
|
|
function Landingpad.on_entity_settings_pasted(event)
|
|
util.settings_pasted(event, Landingpad.name_rocket_landing_pad, Landingpad.serialize, Landingpad.deserialize)
|
|
end
|
|
Event.addListener(defines.events.on_entity_settings_pasted, Landingpad.on_entity_settings_pasted)
|
|
|
|
function Landingpad.on_init(event)
|
|
global.rocket_landing_pads = {} -- all landing pads sorted by struct[unit_unumber]
|
|
end
|
|
Event.addListener("on_init", Landingpad.on_init, true)
|
|
|
|
return Landingpad
|
|
|