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.
555 lines
24 KiB
555 lines
24 KiB
local DeliveryCannon = {}
|
|
|
|
DeliveryCannon.variants = {
|
|
["logistic"] = {
|
|
name = mod_prefix.."delivery-cannon",
|
|
name_energy_interface = mod_prefix.."delivery-cannon-energy-interface",
|
|
name_beam = mod_prefix.."delivery-cannon-beam",
|
|
beam_offset = {x = -0.5, y = -5},
|
|
name_capsule = mod_prefix.."delivery-cannon-capsule",
|
|
name_capsule_projectile = mod_prefix.."delivery-cannon-capsule-projectile",
|
|
energy_per_delta_v = 50000,
|
|
},
|
|
["weapon"] = {
|
|
name = mod_prefix.."delivery-cannon-weapon",
|
|
name_energy_interface = mod_prefix.."delivery-cannon-weapon-energy-interface",
|
|
name_beam = mod_prefix.."delivery-cannon-weapon-beam",
|
|
beam_offset = {x = -1, y = -5},
|
|
name_capsule = mod_prefix.."delivery-cannon-weapon-capsule",
|
|
name_capsule_projectile = mod_prefix.."delivery-cannon-weapon-capsule-projectile",
|
|
energy_per_delta_v = 500000,
|
|
}
|
|
}
|
|
|
|
DeliveryCannon.name_delivery_cannon_chest = mod_prefix.."delivery-cannon-chest"
|
|
|
|
DeliveryCannon.name_delivery_cannon_capsule_shadow = mod_prefix.."delivery-cannon-capsule-shadow"
|
|
DeliveryCannon.name_delivery_cannon_capsule_explosion = mod_prefix.."delivery-cannon-capsule-explosion"
|
|
|
|
DeliveryCannon.name_delivery_cannon_targeter = mod_prefix.."delivery-cannon-targeter"
|
|
DeliveryCannon.name_target_activity_type = "delivery-cannon-target"
|
|
|
|
DeliveryCannon.capsule_fall_altitude = 100
|
|
DeliveryCannon.capsule_fall_time = 2 * 60
|
|
|
|
DeliveryCannon.name_event_copy_entity_settings = mod_prefix.."copy-entity-settings"
|
|
|
|
---@class DeliveryCannon All data necessary to maintain the state of a delivery cannon
|
|
|
|
--- Gets the DeliveryCannon for this unit_number
|
|
---@param unit_number number
|
|
function DeliveryCannon.from_unit_number (unit_number)
|
|
if not unit_number then Log.trace("DeliveryCannon.from_unit_number: invalid unit_number: nil") return end
|
|
unit_number = tonumber(unit_number)
|
|
-- NOTE: only supports container as the entity
|
|
if global.delivery_cannons[unit_number] then
|
|
return global.delivery_cannons[unit_number]
|
|
else
|
|
Log.trace("DeliveryCannon.from_unit_number: invalid unit_number: " .. unit_number)
|
|
end
|
|
end
|
|
|
|
--- Gets the DeliveryCannon for this entity
|
|
---@param entity LuaEntity
|
|
function DeliveryCannon.from_entity (entity)
|
|
if not(entity and entity.valid) then
|
|
Log.trace("DeliveryCannon.from_entity: invalid entity")
|
|
return
|
|
end
|
|
-- NOTE: only supports container as the entity
|
|
return DeliveryCannon.from_unit_number(entity.unit_number)
|
|
end
|
|
|
|
--- Computes the cost to launch a delivery cannon
|
|
---@param origin Zone launch zone
|
|
---@param destination Zone destination zone
|
|
function DeliveryCannon.get_delta_v(origin, destination)
|
|
if origin and destination then
|
|
return Zone.get_launch_delta_v(origin) + Zone.get_travel_delta_v(origin, destination)
|
|
end
|
|
end
|
|
|
|
--- Get the coordinate the delivery cannon is targetting
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.get_coordinate(delivery_cannon)
|
|
if delivery_cannon.destination and delivery_cannon.destination.coordinate then
|
|
return delivery_cannon.destination.coordinate
|
|
end
|
|
return nil
|
|
end
|
|
|
|
--- Does the delivery cannon have a destination set
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.has_destination(delivery_cannon)
|
|
return delivery_cannon and delivery_cannon.destination and delivery_cannon.destination.coordinate and delivery_cannon.destination.zone
|
|
end
|
|
|
|
--- Returns if this delivery cannon is valid
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.is_valid(delivery_cannon)
|
|
return delivery_cannon and delivery_cannon.main and delivery_cannon.main.valid
|
|
and delivery_cannon.energy_interface and delivery_cannon.energy_interface.valid
|
|
end
|
|
|
|
--- Returns if this delivery cannon can fire
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.can_fire(delivery_cannon)
|
|
return delivery_cannon and (not delivery_cannon.is_off)
|
|
and delivery_cannon.energy and delivery_cannon.required_energy
|
|
and delivery_cannon.energy >= delivery_cannon.required_energy
|
|
end
|
|
|
|
--- Gets the stack that this delivery cannon is ready to fire
|
|
---@param delivery_cannon any
|
|
function DeliveryCannon.get_stack(delivery_cannon)
|
|
if not delivery_cannon then return end
|
|
local recipe = delivery_cannon.main.get_recipe()
|
|
if not recipe then return end
|
|
if string.find(recipe.name, "se-delivery-cannon-weapon-pack-", 1, true) then
|
|
local ammo_name = Util.replace(recipe.name, "se-delivery-cannon-weapon-pack-", "")
|
|
local ammo = game.item_prototypes[ammo_name]
|
|
if ammo then
|
|
return {name = ammo_name, count = 1}
|
|
end
|
|
else
|
|
for _, ingredient in pairs(recipe.ingredients) do
|
|
if ingredient.name ~= DeliveryCannon.variants[delivery_cannon.variant].name_capsule then
|
|
local stack = ingredient
|
|
stack.count = stack.amount or stack.count
|
|
return stack
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Displays a message that the delivery cannon projectile was destroyed by an opposing force
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
---@param defence_data any info about the destruction
|
|
---@param target_zone Zone the zone the delivery cannon was firing at
|
|
function DeliveryCannon.display_destroyed_projectile_message(delivery_cannon, defence_data, target_zone)
|
|
game.forces[delivery_cannon.force_name].print({"space-exploration.delivery_cannon_canister_destroyed_by", delivery_cannon.zone.name, target_zone.name})
|
|
for force_name, shots_fired in pairs(defence_data) do
|
|
game.forces[force_name].print({"space-exploration.delivery_cannon_defended_canister", target_zone.name, shots_fired.defence_shots, shots_fired.point_defence_shots})
|
|
end
|
|
end
|
|
|
|
--- Displays a message that the delivery cannon projectile was not destroyed by an opposing force
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
---@param defence_data any info about the (failed) destruction
|
|
---@param target_zone Zone the zone the delivery cannon was firing at
|
|
function DeliveryCannon.display_not_destroyed_projectile_message(delivery_cannon, defence_data, target_zone)
|
|
for force_name, shots_fired in pairs(defence_data) do
|
|
game.forces[force_name].print({"space-exploration.delivery_cannon_defended_canister_failed", target_zone.name, shots_fired.defence_shots, shots_fired.point_defence_shots})
|
|
end
|
|
end
|
|
|
|
--- Picks a new target for a delivery cannon
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
---@param target_zone Zone the zone to pick a target from
|
|
---@param target_surface LuaSurface the surface to pick a target from
|
|
function DeliveryCannon.pick_new_target(delivery_cannon, target_zone, target_surface)
|
|
local random_chunk = target_surface.get_random_chunk()
|
|
local position = {x = (random_chunk.x + math.random()) * 32, y = (random_chunk.y + math.random()) * 32}
|
|
if target_zone.radius and Util.vector_length(position) > target_zone.radius then
|
|
position = Util.vector_set_length(position, target_zone.radius * math.random())
|
|
end
|
|
if math.random() < 0.99 then
|
|
local enemy = find_enemy(game.forces[delivery_cannon.force_name], target_surface, position)
|
|
if enemy then
|
|
position = enemy.position
|
|
end
|
|
end
|
|
delivery_cannon.destination.coordinate = position
|
|
end
|
|
|
|
--- Adds a delivery cannon to the zone assets
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.add_delivery_cannon_to_table(delivery_cannon)
|
|
local type_table = DeliveryCannon.get_delivery_cannon_type_table(delivery_cannon)
|
|
type_table[delivery_cannon.unit_number] = delivery_cannon
|
|
end
|
|
|
|
--- Gets the delivery cannon zone assets
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.get_delivery_cannon_type_table(delivery_cannon)
|
|
local zone_assets = Zone.get_force_assets(delivery_cannon.force_name, delivery_cannon.zone.index)
|
|
zone_assets.delivery_cannons = zone_assets.delivery_cannons or {}
|
|
return zone_assets.delivery_cannons
|
|
end
|
|
|
|
--- Removes a delivery cannon from the zone assets
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.remove_delivery_cannon_from_table(delivery_cannon)
|
|
local type_table = DeliveryCannon.get_delivery_cannon_type_table(delivery_cannon)
|
|
if not type_table[delivery_cannon.unit_number] then return end
|
|
type_table[delivery_cannon.unit_number] = nil
|
|
end
|
|
|
|
--- Fires a delivery cannon if it's ready to fire
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.attempt_fire(delivery_cannon)
|
|
-- only fire cannons that are valid, have a valid destination, and have enough energy to fire at that destination
|
|
if not DeliveryCannon.is_valid(delivery_cannon) then DeliveryCannon.destroy(delivery_cannon) return end
|
|
if not DeliveryCannon.has_destination(delivery_cannon) then return end
|
|
delivery_cannon.energy = delivery_cannon.energy_interface.energy
|
|
if not delivery_cannon.required_energy then
|
|
delivery_cannon.required_energy = DeliveryCannon.variants[delivery_cannon.variant].energy_per_delta_v * DeliveryCannon.get_delta_v(delivery_cannon.zone, delivery_cannon.destination.zone)
|
|
end
|
|
if not DeliveryCannon.can_fire(delivery_cannon) then return end
|
|
|
|
-- only fire cannons with a valid payload ready
|
|
local cannon_inv = delivery_cannon.main.get_output_inventory()
|
|
delivery_cannon.payload_name = nil
|
|
delivery_cannon.payload_count = 0
|
|
for name, count in pairs(cannon_inv.get_contents()) do -- should only be 1
|
|
delivery_cannon.payload_name = name
|
|
delivery_cannon.payload_count = count
|
|
end
|
|
if not (delivery_cannon.payload_count > 0) then return end
|
|
|
|
-- fire the cannon
|
|
local target_zone = delivery_cannon.destination.zone
|
|
local target_surface = Zone.get_make_surface(target_zone)
|
|
local target_position = DeliveryCannon.get_coordinate(delivery_cannon)
|
|
if delivery_cannon.force_name then game.forces[delivery_cannon.force_name].chart(target_surface, Util.position_to_area(target_position, 64)) end
|
|
local stack = DeliveryCannon.get_stack(delivery_cannon)
|
|
if not stack then error("Delivery Cannon tried to fire invalid stack") return end
|
|
cannon_inv.remove({name=delivery_cannon.payload_name, count=1})
|
|
delivery_cannon.energy_interface.energy = delivery_cannon.energy_interface.energy - delivery_cannon.required_energy
|
|
delivery_cannon.main.surface.create_entity{
|
|
name = DeliveryCannon.variants[delivery_cannon.variant].name_beam,
|
|
position = Util.vectors_add(delivery_cannon.main.position, DeliveryCannon.variants[delivery_cannon.variant].beam_offset ),
|
|
target = Util.vectors_add(delivery_cannon.main.position, {x = 0, y = -100})
|
|
}
|
|
|
|
-- give opposing force's meteor defence a chance to destroy the projectile
|
|
local payload = {
|
|
variant = delivery_cannon.variant,
|
|
stack = stack,
|
|
target_zone = target_zone,
|
|
target_position = target_position,
|
|
force_name = delivery_cannon.force_name,
|
|
eta = game.tick + DeliveryCannon.capsule_fall_time,
|
|
health = 1
|
|
}
|
|
local defence_data = Meteor.defence_vs_projectile(payload)
|
|
if payload.health <= 0 then DeliveryCannon.display_destroyed_projectile_message(delivery_cannon, defence_data, target_zone) return end
|
|
|
|
-- the projectile went through
|
|
DeliveryCannon.display_not_destroyed_projectile_message(delivery_cannon, defence_data, target_zone)
|
|
global.delivery_cannon_payloads = global.delivery_cannon_payloads or {}
|
|
table.insert(global.delivery_cannon_payloads, payload)
|
|
|
|
local projectile_start_position = Util.vectors_add(target_position, {x = 0, y = -DeliveryCannon.capsule_fall_altitude})
|
|
local shadow_start_position = Util.vectors_add(target_position, {x = DeliveryCannon.capsule_fall_altitude, y = 0})
|
|
target_surface.create_entity{
|
|
name = DeliveryCannon.variants[delivery_cannon.variant].name_capsule_projectile,
|
|
position = projectile_start_position,
|
|
target = target_position,
|
|
force = delivery_cannon.force_name,
|
|
speed = DeliveryCannon.capsule_fall_altitude/DeliveryCannon.capsule_fall_time
|
|
}
|
|
target_surface.create_entity{
|
|
name = DeliveryCannon.name_delivery_cannon_capsule_shadow,
|
|
position = shadow_start_position,
|
|
target = target_position,
|
|
force = delivery_cannon.force_name,
|
|
speed = DeliveryCannon.capsule_fall_altitude/DeliveryCannon.capsule_fall_time
|
|
}
|
|
target_surface.request_to_generate_chunks(projectile_start_position)
|
|
target_surface.request_to_generate_chunks(shadow_start_position)
|
|
target_surface.request_to_generate_chunks(target_position)
|
|
|
|
-- select a new target if it automatic mode
|
|
if delivery_cannon.auto_select_targets then
|
|
DeliveryCannon.pick_new_target(delivery_cannon, target_zone, target_surface)
|
|
end
|
|
end
|
|
|
|
--- Performs the effect of a payload landing
|
|
--- If there is a delivery chest at the landing location, try to insert the payload item,
|
|
--- otherwise causes an explosion at the target and spills the items on the ground
|
|
---@param payload any the payload that is landing
|
|
function DeliveryCannon.do_payload_effect(payload)
|
|
local surface = Zone.get_make_surface(payload.target_zone)
|
|
local spill = payload.stack.count
|
|
local chest = surface.find_entity(DeliveryCannon.name_delivery_cannon_chest, payload.target_position)
|
|
if chest then
|
|
spill = spill - chest.insert(payload.stack)
|
|
end
|
|
if spill > 0 then
|
|
|
|
surface.create_entity{
|
|
name = DeliveryCannon.name_delivery_cannon_capsule_explosion,
|
|
position = payload.target_position,
|
|
force = payload.force_name
|
|
}
|
|
if payload.stack.name == "explosives" then -- double damage
|
|
surface.create_entity{
|
|
name = DeliveryCannon.name_delivery_cannon_capsule_explosion,
|
|
position = payload.target_position,
|
|
force = payload.force_name
|
|
}
|
|
end
|
|
|
|
local proto = game.item_prototypes[payload.stack.name]
|
|
local projectiles = {}
|
|
if proto.type == "ammo" then
|
|
local ammo_type = proto.get_ammo_type()
|
|
for _, action in pairs(ammo_type.action) do
|
|
for _, action_delivery in pairs(action.action_delivery) do
|
|
if action_delivery.type == "projectile" or action_delivery.type == "artillery" then
|
|
projectiles[action_delivery.projectile] = (projectiles[action_delivery.projectile] or 0) + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if proto.type == "capsule" then
|
|
local ammo_type = proto.capsule_action.attack_parameters.ammo_type
|
|
for _, action in pairs(ammo_type.action) do
|
|
for _, action_delivery in pairs(action.action_delivery) do
|
|
if action_delivery.type == "projectile" or action_delivery.type == "artillery" then
|
|
projectiles[action_delivery.projectile] = (projectiles[action_delivery.projectile] or 0) + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local no_items = false
|
|
for projectile_name, projectile_count in pairs(projectiles) do
|
|
no_items = true
|
|
surface.create_entity{
|
|
name = projectile_name,
|
|
position = payload.target_position,
|
|
target = payload.target_position,
|
|
speed = 0.1,
|
|
force = payload.force_name
|
|
}
|
|
end
|
|
if not no_items then
|
|
local spill_stack = table.deepcopy(payload.stack)
|
|
spill_stack.count = math.ceil(spill/4)
|
|
surface.spill_item_stack(payload.target_position, spill_stack, true, payload.force_name, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Updates all delivery cannons, potentially firing them or updating their guis
|
|
--- Checks are done infrequently, but still frequently enough that the cannon will never
|
|
--- get backed up while assembling at full speed
|
|
--- Updates all delivery cannons payloads, causing their effect when they hit
|
|
---@param delivery_cannon DeliveryCannon delivery cannon data
|
|
function DeliveryCannon.on_tick()
|
|
-- fire cannons
|
|
for _, delivery_cannon in pairs(global.delivery_cannons) do
|
|
if (game.tick + delivery_cannon.unit_number) % 60 == 0 then
|
|
DeliveryCannon.attempt_fire(delivery_cannon)
|
|
end
|
|
end
|
|
|
|
-- update guis
|
|
if game.tick % 60 == 0 then
|
|
for _, player in pairs(game.connected_players) do
|
|
DeliveryCannonGUI.gui_update(player)
|
|
end
|
|
end
|
|
|
|
-- process payloads
|
|
if global.delivery_cannon_payloads then
|
|
for i = #global.delivery_cannon_payloads, 1, -1 do
|
|
local payload = global.delivery_cannon_payloads[i]
|
|
if payload then
|
|
if game.tick >= payload.eta then
|
|
DeliveryCannon.do_payload_effect(payload)
|
|
table.remove(global.delivery_cannon_payloads, i)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_tick, DeliveryCannon.on_tick)
|
|
|
|
--- When the player selects an area using the targeter, set the delivery cannon to target that location
|
|
---@param event any
|
|
function DeliveryCannon.on_player_selected_area(event)
|
|
if (event.item == DeliveryCannon.name_delivery_cannon_targeter) then
|
|
local player = game.players[event.player_index]
|
|
local playerdata = get_make_playerdata(player)
|
|
if playerdata.remote_view_activity and playerdata.remote_view_activity.type == DeliveryCannon.name_target_activity_type then
|
|
local delivery_cannon = playerdata.remote_view_activity.delivery_cannon
|
|
if delivery_cannon.main and delivery_cannon.main.valid then
|
|
delivery_cannon.destination.coordinate = {
|
|
x = (event.area.left_top.x + event.area.right_bottom.x) / 2,
|
|
y = (event.area.left_top.y + event.area.right_bottom.y) / 2
|
|
}
|
|
delivery_cannon.destination.zone = Zone.from_surface(player.surface)
|
|
player.print({"space-exploration.delivery-cannon-coordinates-set", math.floor(delivery_cannon.destination.coordinate.x), math.floor(delivery_cannon.destination.coordinate.y)})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_player_selected_area, DeliveryCannon.on_player_selected_area)
|
|
|
|
function DeliveryCannon.on_entity_created(event)
|
|
local entity = util.get_entity_from_event(event)
|
|
|
|
if not entity then return end
|
|
if entity.name == DeliveryCannon.variants["logistic"].name or entity.name == DeliveryCannon.variants["weapon"].name then
|
|
if not RemoteView.is_unlocked_force(entity.force.name) then
|
|
return cancel_entity_creation(entity, event.player_index, {"space-exploration.generic-requires-satellite"})
|
|
end
|
|
local force_name = entity.force.name
|
|
|
|
local zone = Zone.from_surface(entity.surface)
|
|
|
|
if not zone then
|
|
return cancel_entity_creation(entity, event.player_index, {"space-exploration.invalid_launch_location"})
|
|
end
|
|
|
|
local delivery_cannon = {
|
|
type = entity.name,
|
|
variant = entity.name == DeliveryCannon.variants["logistic"].name and "logistic" or "weapon",
|
|
valid = true,
|
|
force_name = force_name,
|
|
unit_number = entity.unit_number,
|
|
main = entity,
|
|
zone = zone,
|
|
is_off = true,
|
|
destination = {
|
|
zone = nil
|
|
},
|
|
launch_status = -1
|
|
}
|
|
|
|
global.delivery_cannons[entity.unit_number] = delivery_cannon
|
|
Log.trace("DeliveryCannon: delivery_cannon added")
|
|
|
|
DeliveryCannon.add_delivery_cannon_to_table(delivery_cannon) -- assigns to zone_assets
|
|
|
|
-- spawn energy interface
|
|
delivery_cannon.energy_interface = util.find_entity_or_revive_ghost(entity.surface, DeliveryCannon.variants[delivery_cannon.variant].name_energy_interface, entity.position)
|
|
if not delivery_cannon.energy_interface then
|
|
delivery_cannon. energy_interface = entity.surface.create_entity{
|
|
name = DeliveryCannon.variants[delivery_cannon.variant].name_energy_interface,
|
|
force = entity.force,
|
|
position = {entity.position.x, entity.position.y}
|
|
}
|
|
end
|
|
delivery_cannon.energy_interface.destructible = false
|
|
|
|
-- set settings
|
|
local tags = util.get_tags_from_event(event, DeliveryCannon.serialize)
|
|
if tags then
|
|
DeliveryCannon.deserialize(entity, tags)
|
|
end
|
|
|
|
if event.player_index and game.players[event.player_index] and game.players[event.player_index].connected then
|
|
DeliveryCannonGUI.gui_open(game.players[event.player_index], delivery_cannon)
|
|
end
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_entity_cloned, DeliveryCannon.on_entity_created)
|
|
Event.addListener(defines.events.on_built_entity, DeliveryCannon.on_entity_created)
|
|
Event.addListener(defines.events.on_robot_built_entity, DeliveryCannon.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_built, DeliveryCannon.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_revive, DeliveryCannon.on_entity_created)
|
|
|
|
function DeliveryCannon.destroy_sub(delivery_cannon, key)
|
|
if delivery_cannon[key] and delivery_cannon[key].valid then
|
|
delivery_cannon[key].destroy()
|
|
delivery_cannon[key] = nil
|
|
end
|
|
end
|
|
|
|
function DeliveryCannon.destroy(delivery_cannon, player_index)
|
|
if not delivery_cannon then
|
|
Log.trace("delivery_cannon_destroy: no delivery_cannon")
|
|
return
|
|
end
|
|
|
|
delivery_cannon.valid = false
|
|
|
|
DeliveryCannon.destroy_sub(delivery_cannon, 'main')
|
|
DeliveryCannon.destroy_sub(delivery_cannon, 'energy_interface')
|
|
|
|
DeliveryCannon.remove_delivery_cannon_from_table(delivery_cannon)
|
|
global.delivery_cannons[delivery_cannon.unit_number] = nil
|
|
|
|
-- if a player has this gui open then close it
|
|
local gui_name = DeliveryCannonGUI.name_delivery_cannon_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 == delivery_cannon.unit_number then
|
|
root.destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
function DeliveryCannon.on_entity_removed(event)
|
|
local entity = event.entity
|
|
if entity and entity.valid and
|
|
(entity.name == DeliveryCannon.variants["logistic"].name or entity.name == DeliveryCannon.variants["weapon"].name) then
|
|
DeliveryCannon.destroy(DeliveryCannon.from_entity(entity), event.player_index )
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_entity_died, DeliveryCannon.on_entity_removed)
|
|
Event.addListener(defines.events.on_robot_mined_entity, DeliveryCannon.on_entity_removed)
|
|
Event.addListener(defines.events.on_player_mined_entity, DeliveryCannon.on_entity_removed)
|
|
Event.addListener(defines.events.script_raised_destroy, DeliveryCannon.on_entity_removed)
|
|
|
|
function DeliveryCannon.serialize(entity)
|
|
local delivery_cannon = DeliveryCannon.from_entity(entity)
|
|
if delivery_cannon then
|
|
local tags = {}
|
|
if delivery_cannon.destination then
|
|
tags.destination = {
|
|
coordinate = delivery_cannon.destination.coordinate,
|
|
zone_name = delivery_cannon.destination.zone and delivery_cannon.destination.zone.name
|
|
}
|
|
end
|
|
tags.is_off = delivery_cannon.is_off
|
|
tags.auto_select_targets = delivery_cannon.auto_select_targets
|
|
return tags
|
|
end
|
|
end
|
|
|
|
function DeliveryCannon.deserialize(entity, tags)
|
|
local delivery_cannon = DeliveryCannon.from_entity(entity)
|
|
if delivery_cannon then
|
|
if tags.destination then
|
|
delivery_cannon.destination = {
|
|
coordinate = table.deepcopy(tags.destination.coordinate),
|
|
zone = Zone.from_name(tags.destination.zone_name)
|
|
}
|
|
end
|
|
delivery_cannon.is_off = tags.is_off
|
|
delivery_cannon.auto_select_targets = tags.auto_select_targets
|
|
end
|
|
end
|
|
|
|
--- Handles the player creating a blueprint by setting tags to store the state of delivery cannons
|
|
---@param event any
|
|
function DeliveryCannon.on_player_setup_blueprint(event)
|
|
util.setup_blueprint(event, {DeliveryCannon.variants["logistic"].name, DeliveryCannon.variants["weapon"].name}, DeliveryCannon.serialize)
|
|
end
|
|
Event.addListener(defines.events.on_player_setup_blueprint, DeliveryCannon.on_player_setup_blueprint)
|
|
|
|
--- Handles the player copy/pasting settings between delivery cannons
|
|
---@param event any
|
|
function DeliveryCannon.on_entity_settings_pasted(event)
|
|
util.settings_pasted(event, {DeliveryCannon.variants["logistic"].name, DeliveryCannon.variants["weapon"].name}, DeliveryCannon.serialize, DeliveryCannon.deserialize,
|
|
function(entity, player_index)
|
|
local delivery_cannon = DeliveryCannon.from_entity(entity)
|
|
local player = game.players[player_index]
|
|
if delivery_cannon and delivery_cannon.destination and delivery_cannon.destination.coordinate then
|
|
player.print({"space-exploration.delivery-cannon-coordinates-pasted", math.floor(delivery_cannon.destination.coordinate.x), math.floor(delivery_cannon.destination.coordinate.y)})
|
|
end
|
|
end)
|
|
end
|
|
Event.addListener(defines.events.on_entity_settings_pasted, DeliveryCannon.on_entity_settings_pasted)
|
|
|
|
function DeliveryCannon.on_init(event)
|
|
global.delivery_cannons = {}
|
|
end
|
|
Event.addListener("on_init", DeliveryCannon.on_init, true)
|
|
|
|
return DeliveryCannon
|
|
|