Added radar disabling between surface radars in range
This commit is contained in:
parent
0e9e38509e
commit
88f5211ddb
@ -31,6 +31,8 @@ script.on_event(defines.events.on_built_entity, function(event)
|
||||
radar.on_built_entity(event)
|
||||
base.on_built_entity(event)
|
||||
end)
|
||||
script.on_event(defines.events.on_robot_built_entity, radar.on_built_entity)
|
||||
script.on_nth_tick(60, radar.on_jam_tick)
|
||||
script.on_event(defines.events.on_entity_died, base.on_entity_died)
|
||||
script.on_event(defines.events.on_player_died, base.on_player_died)
|
||||
script.on_event(defines.events.on_pre_player_mined_item, base.on_pre_player_mined_item)
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
local radar = require("radar")
|
||||
|
||||
local drop_zone = {}
|
||||
|
||||
function drop_zone.teleport_to_planet(player, surface)
|
||||
@ -64,15 +66,10 @@ function drop_zone.on_player_selected_area(event)
|
||||
if not player.force.is_chunk_charted(surface, {math.floor(pos.x / 32), math.floor(pos.y / 32)}) then
|
||||
player.print("Cannot lock drop zone: area is not scanned!")
|
||||
else
|
||||
for _, jammer in pairs(surface.find_entities_filtered{
|
||||
area = {{pos.x - 120, pos.y - 120}, {pos.x + 120, pos.y + 120}},
|
||||
type = "radar"
|
||||
}) do
|
||||
if jammer.force ~= player.force and jammer.force.name ~= "neutral" then
|
||||
player.print("Cannot lock drop zone: area is jammed by an enemy!")
|
||||
if player.cursor_stack then player.cursor_stack.clear() end
|
||||
return
|
||||
end
|
||||
if radar.sector_jammed(surface, pos, player.force) then
|
||||
player.print("Cannot lock drop zone: area is jammed by an enemy!")
|
||||
if player.cursor_stack then player.cursor_stack.clear() end
|
||||
return
|
||||
end
|
||||
storage.player_targets[player.force.name .. "_" .. surface.name] = {position = pos}
|
||||
player.print("Drop Zone LOCKED for " .. surface.name .. " at [" .. math.floor(pos.x) .. ", " .. math.floor(pos.y) .. "]")
|
||||
|
||||
92
radar.lua
92
radar.lua
@ -3,6 +3,36 @@ local radar = {}
|
||||
local GRID_SIZE = 16
|
||||
local MAX_RADIUS = 3200
|
||||
|
||||
local function powered(entity)
|
||||
return entity.energy > 0
|
||||
end
|
||||
|
||||
-- Half-size of the square active-vision footprint, matching what the entity reveals on the map.
|
||||
local function vision_half_size(entity)
|
||||
if entity.type == "radar" then
|
||||
return (entity.prototype.max_distance_of_nearby_sector_revealed or 3) * 32
|
||||
end
|
||||
local cell = entity.logistic_cell
|
||||
return cell and cell.construction_radius or 0
|
||||
end
|
||||
|
||||
local function enemy_vision(entity, force)
|
||||
return entity.force ~= force and entity.force.name ~= "neutral"
|
||||
end
|
||||
|
||||
local function sector_jammed(surface, position, force)
|
||||
for _, source in pairs(surface.find_entities_filtered{type = {"radar", "roboport"}}) do
|
||||
if source.active and powered(source) and enemy_vision(source, force) then
|
||||
local half = vision_half_size(source)
|
||||
if math.abs(position.x - source.position.x) <= half and math.abs(position.y - source.position.y) <= half then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
radar.sector_jammed = sector_jammed
|
||||
|
||||
local function scan_orbit(entity, planet_name)
|
||||
local surface = game.planets[planet_name] and game.planets[planet_name].surface
|
||||
if not surface then return end
|
||||
@ -15,16 +45,7 @@ local function scan_orbit(entity, planet_name)
|
||||
|
||||
local state = storage.grid_pos[scan_key]
|
||||
local position = {x = state.x, y = state.y}
|
||||
local blocked = false
|
||||
for _, jammer in pairs(surface.find_entities_filtered{
|
||||
area = {{position.x - 120, position.y - 120}, {position.x + 120, position.y + 120}},
|
||||
type = "radar"
|
||||
}) do
|
||||
if jammer.force ~= entity.force and jammer.force.name ~= "neutral" then
|
||||
blocked = true
|
||||
break
|
||||
end
|
||||
end
|
||||
local blocked = sector_jammed(surface, position, entity.force)
|
||||
|
||||
local scan_range = 1
|
||||
if not blocked then
|
||||
@ -79,28 +100,57 @@ function radar.on_orbital_scan_tick()
|
||||
end
|
||||
end
|
||||
|
||||
-- Powered overlapping enemy vision squares jam each other. The engine cannot
|
||||
-- darken only the overlap, so an overlapped radar is disabled entirely until
|
||||
-- the other side dies, loses power, or moves out of range. Roboports count as
|
||||
-- vision sources but are never disabled themselves.
|
||||
function radar.on_jam_tick()
|
||||
storage.jammed_entities = storage.jammed_entities or {}
|
||||
for unit_number, entity in pairs(storage.jammed_entities) do
|
||||
if entity.valid then entity.active = true end
|
||||
storage.jammed_entities[unit_number] = nil
|
||||
end
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
if not surface.platform then
|
||||
local sources = {}
|
||||
for _, entity in pairs(surface.find_entities_filtered{type = {"radar", "roboport"}}) do
|
||||
if entity.valid and entity.active and powered(entity) then sources[#sources + 1] = entity end
|
||||
end
|
||||
for i = 1, #sources do
|
||||
for j = i + 1, #sources do
|
||||
local a, b = sources[i], sources[j]
|
||||
if enemy_vision(a, b.force) then
|
||||
local reach = vision_half_size(a) + vision_half_size(b)
|
||||
if math.abs(a.position.x - b.position.x) <= reach and math.abs(a.position.y - b.position.y) <= reach then
|
||||
for _, entity in pairs({a, b}) do
|
||||
if entity.type == "radar" then
|
||||
entity.active = false
|
||||
storage.jammed_entities[entity.unit_number] = entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function radar.on_built_entity(event)
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) or entity.type ~= "radar" or entity.surface.platform then return end
|
||||
|
||||
local jammer_force, jammer_pos, jammer_radius = entity.force, entity.position, 120
|
||||
-- A fresh vision source jams any enemy drop-zone lock inside its footprint.
|
||||
local jammer_force, jammer_pos = entity.force, entity.position
|
||||
local jammer_half = vision_half_size(entity)
|
||||
for _, enemy_force in pairs(game.forces) do
|
||||
if enemy_force.name ~= jammer_force.name and enemy_force.name ~= "neutral" then
|
||||
local min_x = math.floor((jammer_pos.x - jammer_radius) / 32)
|
||||
local min_y = math.floor((jammer_pos.y - jammer_radius) / 32)
|
||||
local max_x = math.ceil((jammer_pos.x + jammer_radius) / 32)
|
||||
local max_y = math.ceil((jammer_pos.y + jammer_radius) / 32)
|
||||
for x = min_x, max_x do
|
||||
for y = min_y, max_y do enemy_force.unchart_chunk({x = x, y = y}, entity.surface) end
|
||||
end
|
||||
|
||||
storage.player_targets = storage.player_targets or {}
|
||||
local key = enemy_force.name .. "_" .. entity.surface.name
|
||||
local target = storage.player_targets[key]
|
||||
if target then
|
||||
local dx, dy = math.abs(target.position.x - jammer_pos.x), math.abs(target.position.y - jammer_pos.y)
|
||||
-- Jam the same reach on each axis, rather than a circular radius.
|
||||
if dx <= jammer_radius and dy <= jammer_radius then
|
||||
if dx <= jammer_half and dy <= jammer_half then
|
||||
storage.player_targets[key] = nil
|
||||
local message = "[color=red][JAMMER] Your drop zone at [" .. math.floor(target.position.x)
|
||||
.. ", " .. math.floor(target.position.y) .. "] on " .. entity.surface.name
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user