mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
222 lines
8.6 KiB
Lua
222 lines
8.6 KiB
Lua
--[[-- Commands Module - Protection
|
|
- Adds commands that can add and remove protection
|
|
@commands Protection
|
|
]]
|
|
|
|
local ExpUtil = require("modules/exp_util")
|
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
local Storage = require("modules/exp_util/storage")
|
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore.commands
|
|
local format_player_name = ExpUtil.format_player_name_locale --- @dep expcore.common
|
|
local EntityProtection = require("modules.exp_legacy.modules.control.protection") --- @dep modules.control.protection
|
|
local Selection = require("modules.exp_legacy.modules.control.selection") --- @dep modules.control.selection
|
|
|
|
local SelectionProtectEntity = "ProtectEntity"
|
|
local SelectionProtectArea = "ProtectArea"
|
|
|
|
local renders = {} -- Stores all renders for a player
|
|
Storage.register({
|
|
renders = renders,
|
|
}, function(tbl)
|
|
renders = tbl.renders
|
|
end)
|
|
|
|
--- Test if a point is inside an aabb
|
|
local function aabb_point_enclosed(point, aabb)
|
|
return point.x >= aabb.left_top.x and point.y >= aabb.left_top.y
|
|
and point.x <= aabb.right_bottom.x and point.y <= aabb.right_bottom.y
|
|
end
|
|
|
|
--- Test if an aabb is inside another aabb
|
|
local function aabb_area_enclosed(aabb_one, aabb_two)
|
|
return aabb_point_enclosed(aabb_one.left_top, aabb_two)
|
|
and aabb_point_enclosed(aabb_one.right_bottom, aabb_two)
|
|
end
|
|
|
|
--- Align an aabb to the grid by expanding it
|
|
local function aabb_align_expand(aabb)
|
|
return {
|
|
left_top = { x = math.floor(aabb.left_top.x), y = math.floor(aabb.left_top.y) },
|
|
right_bottom = { x = math.ceil(aabb.right_bottom.x), y = math.ceil(aabb.right_bottom.y) },
|
|
}
|
|
end
|
|
|
|
--- Get the key used in protected_entities
|
|
local function get_entity_key(entity)
|
|
return string.format("%i,%i", math.floor(entity.position.x), math.floor(entity.position.y))
|
|
end
|
|
|
|
--- Get the key used in protected_areas
|
|
local function get_area_key(area)
|
|
return string.format("%i,%i", math.floor(area.left_top.x), math.floor(area.left_top.y))
|
|
end
|
|
|
|
--- Show a protected entity to a player
|
|
local function show_protected_entity(player, entity)
|
|
local key = get_entity_key(entity)
|
|
if renders[player.index][key] then return end
|
|
local rb = entity.selection_box.right_bottom
|
|
local render_id = rendering.draw_sprite{
|
|
sprite = "utility/notification",
|
|
target = entity,
|
|
target_offset = {
|
|
(rb.x - entity.position.x) * 0.75,
|
|
(rb.y - entity.position.y) * 0.75,
|
|
},
|
|
x_scale = 2,
|
|
y_scale = 2,
|
|
surface = entity.surface,
|
|
players = { player },
|
|
}
|
|
renders[player.index][key] = render_id
|
|
end
|
|
|
|
--- Show a protected area to a player
|
|
local function show_protected_area(player, surface, area)
|
|
local key = get_area_key(area)
|
|
if renders[player.index][key] then return end
|
|
local render_id = rendering.draw_rectangle{
|
|
color = { 1, 1, 0, 0.5 },
|
|
filled = false,
|
|
width = 3,
|
|
left_top = area.left_top,
|
|
right_bottom = area.right_bottom,
|
|
surface = surface,
|
|
players = { player },
|
|
}
|
|
renders[player.index][key] = render_id
|
|
end
|
|
|
|
--- Remove a render object for a player
|
|
local function remove_render(player, key)
|
|
local render = renders[player.index][key] --[[@as LuaRenderObject]]
|
|
if render and render.valid then render.destroy() end
|
|
renders[player.index][key] = nil
|
|
end
|
|
|
|
--- Toggles entity protection selection
|
|
-- @command protect-entity
|
|
Commands.new_command("protect-entity", { "expcom-protection.description-pe" }, "Toggles entity protection selection, hold shift to remove protection")
|
|
:add_alias("pe")
|
|
:register(function(player)
|
|
if Selection.is_selecting(player, SelectionProtectEntity) then
|
|
Selection.stop(player)
|
|
else
|
|
Selection.start(player, SelectionProtectEntity)
|
|
return Commands.success{ "expcom-protection.entered-entity-selection" }
|
|
end
|
|
end)
|
|
|
|
--- Toggles area protection selection
|
|
-- @command protect-area
|
|
Commands.new_command("protect-area", { "expcom-protection.description-pa" }, "Toggles area protection selection, hold shift to remove protection")
|
|
:add_alias("pa")
|
|
:register(function(player)
|
|
if Selection.is_selecting(player, SelectionProtectArea) then
|
|
Selection.stop(player)
|
|
else
|
|
Selection.start(player, SelectionProtectArea)
|
|
return Commands.success{ "expcom-protection.entered-area-selection" }
|
|
end
|
|
end)
|
|
|
|
--- When an area is selected to add protection to entities
|
|
Selection.on_selection(SelectionProtectEntity, function(event)
|
|
local player = game.players[event.player_index]
|
|
for _, entity in ipairs(event.entities) do
|
|
EntityProtection.add_entity(entity)
|
|
show_protected_entity(player, entity)
|
|
end
|
|
|
|
player.print{ "expcom-protection.protected-entities", #event.entities }
|
|
end)
|
|
|
|
--- When an area is selected to remove protection from entities
|
|
Selection.on_alt_selection(SelectionProtectEntity, function(event)
|
|
local player = game.players[event.player_index]
|
|
for _, entity in ipairs(event.entities) do
|
|
EntityProtection.remove_entity(entity)
|
|
remove_render(player, get_entity_key(entity))
|
|
end
|
|
|
|
player.print{ "expcom-protection.unprotected-entities", #event.entities }
|
|
end)
|
|
|
|
--- When an area is selected to add protection to the area
|
|
Selection.on_selection(SelectionProtectArea, function(event)
|
|
local area = aabb_align_expand(event.area)
|
|
local areas = EntityProtection.get_areas(event.surface)
|
|
local player = game.players[event.player_index]
|
|
for _, next_area in pairs(areas) do
|
|
if aabb_area_enclosed(area, next_area) then
|
|
return player.print{ "expcom-protection.already-protected" }
|
|
end
|
|
end
|
|
|
|
EntityProtection.add_area(event.surface, area)
|
|
show_protected_area(player, event.surface, area)
|
|
player.print{ "expcom-protection.protected-area" }
|
|
end)
|
|
|
|
--- When an area is selected to remove protection from the area
|
|
Selection.on_alt_selection(SelectionProtectArea, function(event)
|
|
local area = aabb_align_expand(event.area)
|
|
local areas = EntityProtection.get_areas(event.surface)
|
|
local player = game.players[event.player_index]
|
|
for _, next_area in pairs(areas) do
|
|
if aabb_area_enclosed(next_area, area) then
|
|
EntityProtection.remove_area(event.surface, next_area)
|
|
player.print{ "expcom-protection.unprotected-area" }
|
|
remove_render(player, get_area_key(next_area))
|
|
end
|
|
end
|
|
end)
|
|
|
|
--- When selection starts show all protected entities and protected areas
|
|
Event.add(Selection.events.on_player_selection_start, function(event)
|
|
if event.selection ~= SelectionProtectEntity and event.selection ~= SelectionProtectArea then return end
|
|
local player = game.players[event.player_index]
|
|
local surface = player.surface
|
|
renders[player.index] = {}
|
|
-- Show protected entities
|
|
local entities = EntityProtection.get_entities(surface)
|
|
for _, entity in pairs(entities) do
|
|
show_protected_entity(player, entity)
|
|
end
|
|
|
|
-- Show always protected entities by name
|
|
if #EntityProtection.protected_entity_names > 0 then
|
|
for _, entity in pairs(surface.find_entities_filtered{ name = EntityProtection.protected_entity_names, force = player.force }) do
|
|
show_protected_entity(player, entity)
|
|
end
|
|
end
|
|
-- Show always protected entities by type
|
|
if #EntityProtection.protected_entity_types > 0 then
|
|
for _, entity in pairs(surface.find_entities_filtered{ type = EntityProtection.protected_entity_types, force = player.force }) do
|
|
show_protected_entity(player, entity)
|
|
end
|
|
end
|
|
-- Show protected areas
|
|
local areas = EntityProtection.get_areas(surface)
|
|
for _, area in pairs(areas) do
|
|
show_protected_area(player, surface, area)
|
|
end
|
|
end)
|
|
|
|
--- When selection ends hide protected entities and protected areas
|
|
Event.add(Selection.events.on_player_selection_end, function(event)
|
|
if event.selection ~= SelectionProtectEntity and event.selection ~= SelectionProtectArea then return end
|
|
for _, render in pairs(renders[event.player_index]) do
|
|
if render.valid then render.destroy() end
|
|
end
|
|
|
|
renders[event.player_index] = nil
|
|
end)
|
|
|
|
--- When there is a repeat offence print it in chat
|
|
Event.add(EntityProtection.events.on_repeat_violation, function(event)
|
|
local player_name = format_player_name(event.player_index)
|
|
Roles.print_to_roles_higher("Regular", { "expcom-protection.repeat-offence", player_name, event.entity.localised_name, event.entity.position.x, event.entity.position.y })
|
|
end)
|