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.
151 lines
6.2 KiB
151 lines
6.2 KiB
local Beacon = {}
|
|
|
|
-- Note: supply_area_distance -- extends from edge of collision box
|
|
Beacon.affected_types = {"assembling-machine", "furnace", "lab", "mining-drill", "rocket-silo"}
|
|
|
|
function Beacon.get_beacon_prototypes()
|
|
if not Beacon.list_beacon_prototypes then
|
|
Beacon.list_beacon_prototypes = {}
|
|
for name, prototype in pairs(game.entity_prototypes) do
|
|
if prototype.type == "beacon" and prototype.supply_area_distance then
|
|
table.insert(Beacon.list_beacon_prototypes, prototype)
|
|
end
|
|
end
|
|
end
|
|
return Beacon.list_beacon_prototypes
|
|
end
|
|
|
|
function Beacon.get_max_beacon_range()
|
|
if not Beacon.max_beacon_range then
|
|
Beacon.max_beacon_range = 0
|
|
for _, prototype in pairs(Beacon.list_beacon_prototypes()) do
|
|
if prototype.supply_area_distance > Beacon.max_beacon_range then
|
|
Beacon.max_beacon_range = prototype.supply_area_distance
|
|
end
|
|
end
|
|
end
|
|
return Beacon.max_beacon_range
|
|
end
|
|
|
|
function Beacon.validate_entity(entity, ignore_count)
|
|
-- make sure not affected by more than 1 beacon
|
|
if (not entity.prototype.allowed_effects) or table_size(entity.prototype.allowed_effects) == 0
|
|
or (not entity.prototype.module_inventory_size) or entity.prototype.module_inventory_size == 0 then return end
|
|
local ignore = ignore_count and ignore_count or 0
|
|
local bounding_box = entity.bounding_box
|
|
local beacons = 0
|
|
for _, prototype in pairs(Beacon.get_beacon_prototypes()) do
|
|
local area = util.area_extend(bounding_box, prototype.supply_area_distance)
|
|
beacons = beacons + entity.surface.count_entities_filtered{type="beacon", name=prototype.name, area = area}
|
|
end
|
|
if beacons > 1 + ignore then
|
|
if entity.active == true then
|
|
entity.active = false
|
|
entity.surface.create_entity{
|
|
name = "flying-text",
|
|
position = entity.position,
|
|
text = {"space-exploration.beacon-overload"}
|
|
}
|
|
global.beacon_overloaded_entities = global.beacon_overloaded_entities or {}
|
|
global.beacon_overloaded_entities[entity.unit_number] = entity
|
|
|
|
global.beacon_overloaded_shapes = global.beacon_overloaded_shapes or {}
|
|
local shape_id = global.beacon_overloaded_shapes[entity.unit_number]
|
|
if shape_id and rendering.is_valid(shape_id) then rendering.destroy(shape_id) end -- shouldn't happen but best to check if other mods broke something
|
|
shape_id = rendering.draw_sprite{
|
|
sprite = "virtual-signal/"..mod_prefix.."beacon-overload",
|
|
surface = entity.surface,
|
|
target = entity,
|
|
x_scale = 1,
|
|
y_scale = 1,
|
|
target_offset = entity.prototype.alert_icon_shift
|
|
}
|
|
global.beacon_overloaded_shapes[entity.unit_number] = shape_id
|
|
end
|
|
else
|
|
-- TODO: add hook here so other things can cancel
|
|
if not entity.active then
|
|
global.beacon_overloaded_entities = global.beacon_overloaded_entities or {}
|
|
global.beacon_overloaded_shapes = global.beacon_overloaded_shapes or {}
|
|
local deactivated_by_beacons = false
|
|
for unit_number, overloaed_entity in pairs(global.beacon_overloaded_entities) do
|
|
if not overloaed_entity.valid then
|
|
global.beacon_overloaded_entities[unit_number] = nil
|
|
if global.beacon_overloaded_shapes[unit_number] then
|
|
local shape_id = global.beacon_overloaded_shapes[unit_number]
|
|
if rendering.is_valid(shape_id) then rendering.destroy(shape_id) end
|
|
global.beacon_overloaded_shapes[unit_number] = nil
|
|
end
|
|
elseif entity == overloaed_entity then
|
|
global.beacon_overloaded_entities[unit_number] = nil
|
|
if global.beacon_overloaded_shapes[unit_number] then
|
|
local shape_id = global.beacon_overloaded_shapes[unit_number]
|
|
if rendering.is_valid(shape_id) then rendering.destroy(shape_id) end
|
|
global.beacon_overloaded_shapes[unit_number] = nil
|
|
end
|
|
deactivated_by_beacons = true
|
|
end
|
|
end
|
|
if deactivated_by_beacons then
|
|
entity.active = true
|
|
entity.surface.create_entity{
|
|
name = "flying-text",
|
|
position = entity.position,
|
|
text = {"space-exploration.beacon-overload-ended"}
|
|
}
|
|
for interface, functions in pairs(remote.interfaces) do -- allow other mods to deactivate after
|
|
if interface ~= "space-exploration" and functions["on_entity_activated"] then
|
|
remote.call(interface, "on_entity_activated", {entity = entity, mod = "space-exploration"})
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Beacon.validate_beacon(entity, is_deconstructing)
|
|
local prototype = entity.prototype
|
|
local area = util.area_extend(entity.bounding_box, prototype.supply_area_distance)
|
|
local structures = entity.surface.find_entities_filtered{type = Beacon.affected_types, area = area}
|
|
local ignore = is_deconstructing and 1 or 0
|
|
for _, structure in pairs(structures) do
|
|
Beacon.validate_entity(structure, ignore)
|
|
end
|
|
end
|
|
|
|
function Beacon.on_entity_created(event)
|
|
local entity
|
|
if event.entity and event.entity.valid then
|
|
entity = event.entity
|
|
end
|
|
if event.created_entity and event.created_entity.valid then
|
|
entity = event.created_entity
|
|
end
|
|
if not entity then return end
|
|
if entity.type == "beacon" then
|
|
Beacon.validate_beacon(entity)
|
|
elseif util.table_contains(Beacon.affected_types, entity.type) then
|
|
Beacon.validate_entity(entity)
|
|
end
|
|
end
|
|
Event.addListener(defines.events.on_built_entity, Beacon.on_entity_created)
|
|
Event.addListener(defines.events.on_robot_built_entity, Beacon.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_built, Beacon.on_entity_created)
|
|
Event.addListener(defines.events.script_raised_revive, Beacon.on_entity_created)
|
|
|
|
function Beacon.on_entity_removed(event)
|
|
if event.entity and event.entity.valid then
|
|
if event.entity.type == "beacon" then
|
|
-- do validation but counting 1 beacon fewer
|
|
Beacon.validate_beacon(event.entity, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
Event.addListener(defines.events.on_player_mined_entity, Beacon.on_entity_removed)
|
|
Event.addListener(defines.events.on_robot_mined_entity, Beacon.on_entity_removed)
|
|
Event.addListener(defines.events.on_entity_died, Beacon.on_entity_removed)
|
|
Event.addListener(defines.events.script_raised_destroy, Beacon.on_entity_removed)
|
|
|
|
return Beacon
|
|
|