mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Added renderer and selection events
This commit is contained in:
@@ -3,13 +3,24 @@
|
||||
@commands Protection
|
||||
]]
|
||||
|
||||
local Event = require 'utils.event' --- @dep utils.event
|
||||
local Global = require 'utils.global' --- @dep utils.global
|
||||
local Roles = require 'expcore.roles' --- @dep expcore.roles
|
||||
local Commands = require 'expcore.commands' --- @dep expcore.commands
|
||||
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
|
||||
local EntityProtection = require 'modules.control.protection' --- @dep modules.control.protection
|
||||
local Selection = require 'modules.control.selection' --- @dep modules.control.selection
|
||||
|
||||
local SelectionProtectEntity = 'ProtectEntity'
|
||||
local SelectionProtectArea = 'ProtectArea'
|
||||
|
||||
local renders = {} -- Stores all renders for a player
|
||||
Global.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
|
||||
@@ -30,6 +41,58 @@ local function aabb_align_expand(aabb)
|
||||
}
|
||||
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.8,
|
||||
(rb.y-entity.position.y)*0.8
|
||||
},
|
||||
surface = entity.surface,
|
||||
players = { player }
|
||||
}
|
||||
renders[player.index][key] = render_id
|
||||
end
|
||||
|
||||
--- Show a protected are 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]
|
||||
if render and rendering.is_valid(render) then rendering.destroy(render) end
|
||||
renders[player.index][key] = nil
|
||||
end
|
||||
|
||||
--- Toggles entity protection selection
|
||||
-- @command protect-entity
|
||||
Commands.new_command('protect-entity', 'Toggles entity protection selection, hold shift to remove protection')
|
||||
@@ -58,16 +121,20 @@ end)
|
||||
|
||||
--- When an area is selected to add protection to entities
|
||||
Selection.on_selection(SelectionProtectEntity, function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
for _, entity in ipairs(event.entities) do
|
||||
EntityProtection.add_entity(entity)
|
||||
show_protected_entity(player, entity)
|
||||
end
|
||||
return Commands.success{'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.get_player(event.player_index)
|
||||
for _, entity in ipairs(event.entities) do
|
||||
EntityProtection.remove_entity(entity)
|
||||
remove_render(player, get_entity_key(entity))
|
||||
end
|
||||
return Commands.success{'expcom-protection.unprotected-entities', #event.entities}
|
||||
end)
|
||||
@@ -81,7 +148,9 @@ Selection.on_selection(SelectionProtectArea, function(event)
|
||||
return Commands.error{'expcom-protection.already-protected'}
|
||||
end
|
||||
end
|
||||
local player = game.get_player(event.player_index)
|
||||
EntityProtection.add_area(event.surface, area)
|
||||
show_protected_area(player, event.surface, area)
|
||||
return Commands.success{'expcom-protection.protected-area'}
|
||||
end)
|
||||
|
||||
@@ -89,14 +158,55 @@ end)
|
||||
Selection.on_alt_selection(SelectionProtectArea, function(event)
|
||||
local area = aabb_align_expand(event.area)
|
||||
local areas = EntityProtection.get_areas(event.surface)
|
||||
local player = game.get_player(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)
|
||||
Commands.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.get_player(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 show hide protected entities on screen 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 _, id in pairs(renders[event.player_index]) do
|
||||
if rendering.is_valid(id) then rendering.destroy(id) 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_chat_player_name(event.player_index)
|
||||
|
||||
@@ -8,6 +8,8 @@ local Global = require 'utils.global' --- @dep utils.global
|
||||
local Event = require 'utils.event' --- @dep utils.event
|
||||
local config = require 'config.protection' --- @dep config.protection
|
||||
local EntityProtection = {
|
||||
protected_entity_names = table.deep_copy(config.always_protected_names),
|
||||
protected_entity_types = table.deep_copy(config.always_protected_types),
|
||||
events = {
|
||||
--- When a player mines a protected entity
|
||||
-- @event on_player_mined_protected
|
||||
@@ -59,12 +61,12 @@ end)
|
||||
|
||||
--- Get the key used in protected_entities
|
||||
local function get_entity_key(entity)
|
||||
return string.format('%i,%i', entity.position.x, entity.position.y)
|
||||
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', area.left_top.x, area.left_top.y)
|
||||
return string.format('%i,%i', math.floor(area.left_top.x), math.floor(area.left_top.y))
|
||||
end
|
||||
|
||||
--- Check if an entity is always protected
|
||||
@@ -99,7 +101,7 @@ end
|
||||
|
||||
--- Get all protected entities on a surface
|
||||
function EntityProtection.get_entities(surface)
|
||||
return protected_entities[surface.index]
|
||||
return protected_entities[surface.index] or {}
|
||||
end
|
||||
|
||||
--- Check if an entity is protected
|
||||
@@ -129,7 +131,7 @@ end
|
||||
|
||||
--- Get all protected areas on a surface
|
||||
function EntityProtection.get_areas(surface)
|
||||
return protected_areas[surface.index]
|
||||
return protected_areas[surface.index] or {}
|
||||
end
|
||||
|
||||
--- Check if an entity is protected
|
||||
|
||||
@@ -6,7 +6,20 @@
|
||||
|
||||
local Event = require 'utils.event' --- @dep utils.event
|
||||
local Global = require 'utils.global' --- @dep utils.global
|
||||
local Selection = {}
|
||||
local Selection = {
|
||||
events = {
|
||||
--- When a player enterers selection mode
|
||||
-- @event on_player_selection_start
|
||||
-- @tparam number player_index the player index of the player who entered selection mode
|
||||
-- @tparam string selection the name of the selection being made
|
||||
on_player_selection_start = script.generate_event_name(),
|
||||
--- When a player leaves selection mode
|
||||
-- @event on_player_selection_end
|
||||
-- @tparam number player_index the player index of the player who left selection mode
|
||||
-- @tparam string selection the name of the selection which ended
|
||||
on_player_selection_end = script.generate_event_name(),
|
||||
}
|
||||
}
|
||||
|
||||
local selection_tool = { name='selection-tool' }
|
||||
|
||||
@@ -22,8 +35,18 @@ end)
|
||||
-- @tparam string selection_name The name of the selection to start, used with on_selection
|
||||
-- @tparam[opt=false] boolean single_use When true the selection will stop after first use
|
||||
function Selection.start(player, selection_name, single_use, ...)
|
||||
-- Assign the arguments if the player is valid
|
||||
if not player or not player.valid then return end
|
||||
if selections[player.index] then
|
||||
-- Raise the end event if a selection was already in progress
|
||||
script.raise_event(Selection.events.on_player_selection_end, {
|
||||
name = Selection.events.on_player_selection_end,
|
||||
tick = game.tick,
|
||||
player_index = player.index,
|
||||
selection = selections[player.index].name
|
||||
})
|
||||
end
|
||||
|
||||
-- Set the selection data
|
||||
selections[player.index] = {
|
||||
name = selection_name,
|
||||
arguments = { ... },
|
||||
@@ -31,6 +54,14 @@ function Selection.start(player, selection_name, single_use, ...)
|
||||
character = player.character
|
||||
}
|
||||
|
||||
-- Raise the event
|
||||
script.raise_event(Selection.events.on_player_selection_start, {
|
||||
name = Selection.events.on_player_selection_start,
|
||||
tick = game.tick,
|
||||
player_index = player.index,
|
||||
selection = selection_name
|
||||
})
|
||||
|
||||
-- Give a selection tool if one is not in use
|
||||
if player.cursor_stack.is_selection_tool then return end
|
||||
player.clear_cursor() -- Clear the current item
|
||||
@@ -47,8 +78,17 @@ end
|
||||
function Selection.stop(player)
|
||||
if not selections[player.index] then return end
|
||||
local character = selections[player.index].character
|
||||
local selection = selections[player.index].name
|
||||
selections[player.index] = nil
|
||||
|
||||
-- Raise the event
|
||||
script.raise_event(Selection.events.on_player_selection_end, {
|
||||
name = Selection.events.on_player_selection_end,
|
||||
tick = game.tick,
|
||||
player_index = player.index,
|
||||
selection = selection
|
||||
})
|
||||
|
||||
-- Remove the selection tool
|
||||
if player.cursor_stack.is_selection_tool then
|
||||
player.cursor_stack.clear()
|
||||
@@ -78,8 +118,8 @@ function Selection.is_selecting(player, selection_name)
|
||||
if not selections[player.index] then return false end
|
||||
return selections[player.index].name == selection_name
|
||||
else
|
||||
return player.cursor_stack.is_selection_tool
|
||||
end
|
||||
return player.cursor_stack.is_selection_tool
|
||||
end
|
||||
end
|
||||
|
||||
--- Filter on_player_selected_area to this custom selection, appends the selection arguments
|
||||
|
||||
Reference in New Issue
Block a user