mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-30 20:41:41 +09:00
Added renderer and selection events
This commit is contained in:
@@ -3,13 +3,24 @@
|
|||||||
@commands Protection
|
@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 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 EntityProtection = require 'modules.control.protection' --- @dep modules.control.protection
|
||||||
local Selection = require 'modules.control.selection' --- @dep modules.control.selection
|
local Selection = require 'modules.control.selection' --- @dep modules.control.selection
|
||||||
|
|
||||||
local SelectionProtectEntity = 'ProtectEntity'
|
local SelectionProtectEntity = 'ProtectEntity'
|
||||||
local SelectionProtectArea = 'ProtectArea'
|
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
|
--- Test if a point is inside an aabb
|
||||||
local function aabb_point_enclosed(point, aabb)
|
local function aabb_point_enclosed(point, aabb)
|
||||||
return point.x >= aabb.left_top.x and point.y >= aabb.left_top.y
|
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
|
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
|
--- Toggles entity protection selection
|
||||||
-- @command protect-entity
|
-- @command protect-entity
|
||||||
Commands.new_command('protect-entity', 'Toggles entity protection selection, hold shift to remove protection')
|
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
|
--- When an area is selected to add protection to entities
|
||||||
Selection.on_selection(SelectionProtectEntity, function(event)
|
Selection.on_selection(SelectionProtectEntity, function(event)
|
||||||
|
local player = game.get_player(event.player_index)
|
||||||
for _, entity in ipairs(event.entities) do
|
for _, entity in ipairs(event.entities) do
|
||||||
EntityProtection.add_entity(entity)
|
EntityProtection.add_entity(entity)
|
||||||
|
show_protected_entity(player, entity)
|
||||||
end
|
end
|
||||||
return Commands.success{'expcom-protection.protected-entities', #event.entities}
|
return Commands.success{'expcom-protection.protected-entities', #event.entities}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- When an area is selected to remove protection from entities
|
--- When an area is selected to remove protection from entities
|
||||||
Selection.on_alt_selection(SelectionProtectEntity, function(event)
|
Selection.on_alt_selection(SelectionProtectEntity, function(event)
|
||||||
|
local player = game.get_player(event.player_index)
|
||||||
for _, entity in ipairs(event.entities) do
|
for _, entity in ipairs(event.entities) do
|
||||||
EntityProtection.remove_entity(entity)
|
EntityProtection.remove_entity(entity)
|
||||||
|
remove_render(player, get_entity_key(entity))
|
||||||
end
|
end
|
||||||
return Commands.success{'expcom-protection.unprotected-entities', #event.entities}
|
return Commands.success{'expcom-protection.unprotected-entities', #event.entities}
|
||||||
end)
|
end)
|
||||||
@@ -81,7 +148,9 @@ Selection.on_selection(SelectionProtectArea, function(event)
|
|||||||
return Commands.error{'expcom-protection.already-protected'}
|
return Commands.error{'expcom-protection.already-protected'}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local player = game.get_player(event.player_index)
|
||||||
EntityProtection.add_area(event.surface, area)
|
EntityProtection.add_area(event.surface, area)
|
||||||
|
show_protected_area(player, event.surface, area)
|
||||||
return Commands.success{'expcom-protection.protected-area'}
|
return Commands.success{'expcom-protection.protected-area'}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -89,14 +158,55 @@ end)
|
|||||||
Selection.on_alt_selection(SelectionProtectArea, function(event)
|
Selection.on_alt_selection(SelectionProtectArea, function(event)
|
||||||
local area = aabb_align_expand(event.area)
|
local area = aabb_align_expand(event.area)
|
||||||
local areas = EntityProtection.get_areas(event.surface)
|
local areas = EntityProtection.get_areas(event.surface)
|
||||||
|
local player = game.get_player(event.player_index)
|
||||||
for _, next_area in pairs(areas) do
|
for _, next_area in pairs(areas) do
|
||||||
if aabb_area_enclosed(next_area, area) then
|
if aabb_area_enclosed(next_area, area) then
|
||||||
EntityProtection.remove_area(event.surface, next_area)
|
EntityProtection.remove_area(event.surface, next_area)
|
||||||
Commands.print{'expcom-protection.unprotected-area'}
|
Commands.print{'expcom-protection.unprotected-area'}
|
||||||
|
remove_render(player, get_area_key(next_area))
|
||||||
end
|
end
|
||||||
end
|
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
|
--- When there is a repeat offence print it in chat
|
||||||
Event.add(EntityProtection.events.on_repeat_violation, function(event)
|
Event.add(EntityProtection.events.on_repeat_violation, function(event)
|
||||||
local player_name = format_chat_player_name(event.player_index)
|
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 Event = require 'utils.event' --- @dep utils.event
|
||||||
local config = require 'config.protection' --- @dep config.protection
|
local config = require 'config.protection' --- @dep config.protection
|
||||||
local EntityProtection = {
|
local EntityProtection = {
|
||||||
|
protected_entity_names = table.deep_copy(config.always_protected_names),
|
||||||
|
protected_entity_types = table.deep_copy(config.always_protected_types),
|
||||||
events = {
|
events = {
|
||||||
--- When a player mines a protected entity
|
--- When a player mines a protected entity
|
||||||
-- @event on_player_mined_protected
|
-- @event on_player_mined_protected
|
||||||
@@ -59,12 +61,12 @@ end)
|
|||||||
|
|
||||||
--- Get the key used in protected_entities
|
--- Get the key used in protected_entities
|
||||||
local function get_entity_key(entity)
|
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
|
end
|
||||||
|
|
||||||
--- Get the key used in protected_areas
|
--- Get the key used in protected_areas
|
||||||
local function get_area_key(area)
|
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
|
end
|
||||||
|
|
||||||
--- Check if an entity is always protected
|
--- Check if an entity is always protected
|
||||||
@@ -99,7 +101,7 @@ end
|
|||||||
|
|
||||||
--- Get all protected entities on a surface
|
--- Get all protected entities on a surface
|
||||||
function EntityProtection.get_entities(surface)
|
function EntityProtection.get_entities(surface)
|
||||||
return protected_entities[surface.index]
|
return protected_entities[surface.index] or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if an entity is protected
|
--- Check if an entity is protected
|
||||||
@@ -129,7 +131,7 @@ end
|
|||||||
|
|
||||||
--- Get all protected areas on a surface
|
--- Get all protected areas on a surface
|
||||||
function EntityProtection.get_areas(surface)
|
function EntityProtection.get_areas(surface)
|
||||||
return protected_areas[surface.index]
|
return protected_areas[surface.index] or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if an entity is protected
|
--- Check if an entity is protected
|
||||||
|
|||||||
@@ -6,7 +6,20 @@
|
|||||||
|
|
||||||
local Event = require 'utils.event' --- @dep utils.event
|
local Event = require 'utils.event' --- @dep utils.event
|
||||||
local Global = require 'utils.global' --- @dep utils.global
|
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' }
|
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 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
|
-- @tparam[opt=false] boolean single_use When true the selection will stop after first use
|
||||||
function Selection.start(player, selection_name, single_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 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] = {
|
selections[player.index] = {
|
||||||
name = selection_name,
|
name = selection_name,
|
||||||
arguments = { ... },
|
arguments = { ... },
|
||||||
@@ -31,6 +54,14 @@ function Selection.start(player, selection_name, single_use, ...)
|
|||||||
character = player.character
|
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
|
-- Give a selection tool if one is not in use
|
||||||
if player.cursor_stack.is_selection_tool then return end
|
if player.cursor_stack.is_selection_tool then return end
|
||||||
player.clear_cursor() -- Clear the current item
|
player.clear_cursor() -- Clear the current item
|
||||||
@@ -47,8 +78,17 @@ end
|
|||||||
function Selection.stop(player)
|
function Selection.stop(player)
|
||||||
if not selections[player.index] then return end
|
if not selections[player.index] then return end
|
||||||
local character = selections[player.index].character
|
local character = selections[player.index].character
|
||||||
|
local selection = selections[player.index].name
|
||||||
selections[player.index] = nil
|
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
|
-- Remove the selection tool
|
||||||
if player.cursor_stack.is_selection_tool then
|
if player.cursor_stack.is_selection_tool then
|
||||||
player.cursor_stack.clear()
|
player.cursor_stack.clear()
|
||||||
@@ -78,8 +118,8 @@ function Selection.is_selecting(player, selection_name)
|
|||||||
if not selections[player.index] then return false end
|
if not selections[player.index] then return false end
|
||||||
return selections[player.index].name == selection_name
|
return selections[player.index].name == selection_name
|
||||||
else
|
else
|
||||||
return player.cursor_stack.is_selection_tool
|
return player.cursor_stack.is_selection_tool
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Filter on_player_selected_area to this custom selection, appends the selection arguments
|
--- Filter on_player_selected_area to this custom selection, appends the selection arguments
|
||||||
|
|||||||
Reference in New Issue
Block a user