Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement nuke protect, fix move_items #229

Merged
merged 7 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/_file_loader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ return {
'modules.addons.report-jail',
'modules.addons.protection-jail',
'modules.addons.deconlog',
'modules.addons.nukeprotect',

--- Data
'modules.data.statistics',
Expand Down
3 changes: 2 additions & 1 deletion config/expcore/roles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ Roles.new_role('Regular','Reg')
'command/go-to-spawn',
'command/me',
'standard-decon',
'bypass-entity-protection'
'bypass-entity-protection',
'bypass-nukeprotect'
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours3 then
Expand Down
11 changes: 11 additions & 0 deletions config/nukeprotect.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
return {
ammo = {
["atomic-bomb"] = true
}, -- @setting ammo The items to not allow in the player's ammo inventory
armor = {}, -- @setting armor The items to not allow in the player's armor inventory
gun = {}, -- @setting gun The items to not allow in the player's gun inventory
main = {
["atomic-bomb"] = true
}, -- @setting main The items to not allow in the player's main inventory
ignore_permisison = "bypass-nukeprotect" -- @setting ignore_permisison The permission that nukeprotect will ignore
oof2win2 marked this conversation as resolved.
Show resolved Hide resolved
}
108 changes: 56 additions & 52 deletions expcore/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

local Colours = require 'utils.color_presets' --- @dep utils.color_presets
local Game = require 'utils.game' --- @dep utils.game
local Util = require 'util' --- @dep util

local Common = {}

Expand Down Expand Up @@ -538,62 +537,65 @@ end
--- Factorio.
-- @section factorio

--[[-- Moves items to the position and stores them in the closest entity of the type given
--[[-- Copies items to the position and stores them in the closest entity of the type given
-- Copies the items by prototype name, but keeps them in the original inventory
@tparam table items items which are to be added to the chests, ['name']=count
@tparam[opt=navies] LuaSurface surface the surface that the items will be moved to
@tparam[opt={0, 0}] table position the position that the items will be moved to {x=100, y=100}
@tparam table items items which are to be added to the chests, an array of LuaItemStack
@tparam[opt=navies] LuaSurface surface the surface that the items will be copied to
@tparam[opt={0, 0}] table position the position that the items will be copied to {x=100, y=100}
@tparam[opt=32] number radius the radius in which the items are allowed to be placed
@tparam[opt=iron-chest] string chest_type the chest type that the items should be moved into
@tparam[opt=iron-chest] string chest_type the chest type that the items should be copied into
@treturn LuaEntity the last chest that had items inserted into it

@usage-- Copy all the items in a players inventory and place them in chests at {0, 0}
move_items(game.player.get_main_inventory().get_contents())
copy_items_stack(game.player.get_main_inventory().get_contents())

]]
function Common.move_items(items, surface, position, radius, chest_type)
chest_type = chest_type or 'iron-chest'
surface = surface or game.surfaces[1]
if position and type(position) ~= 'table' then return end
if type(items) ~= 'table' then return end
-- Finds all entities of the given type
local p = position or {x=0, y=0}
local r = radius or 32
local entities = surface.find_entities_filtered{area={{p.x-r, p.y-r}, {p.x+r, p.y+r}}, name=chest_type} or {}
local count = #entities
local current = 1
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'}
table.insert(entities, chest)
count = count + 1
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then return make_new_chest() end
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current+1
if current > count then current = 1 end
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
-- Inserts the items into the chests
local last_chest
for item_name, item_count in pairs(items) do
local chest = next_chest{name=item_name, count=item_count}
if not chest then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item_name, surface.name, p.x, p.y)) end
Util.insert_safe(chest, {[item_name]=item_count})
last_chest = chest
end
return last_chest
function Common.copy_items_stack(items, surface, position, radius, chest_type)
chest_type = chest_type or 'iron-chest'
surface = surface or game.surfaces[1]
if position and type(position) ~= 'table' then return end
if type(items) ~= 'table' then return end
-- Finds all entities of the given type
local p = position or {x=0, y=0}
local r = radius or 32
local entities = surface.find_entities_filtered{area={{p.x-r, p.y-r}, {p.x+r, p.y+r}}, name=chest_type} or {}
local count = #entities
local current = 1
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'}
table.insert(entities, chest)
count = count + 1
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then return make_new_chest() end
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current+1
if current > count then current = 1 end
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
-- Inserts the items into the chests
local last_chest
for i=1,#items do
local item = items[i]
if item.valid_for_read then
local chest = next_chest(item)
if not chest or not chest.valid then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) end
chest.insert(item)
last_chest = chest
end
end
return last_chest
end

--[[-- Moves items to the position and stores them in the closest entity of the type given
Expand All @@ -606,7 +608,7 @@ end
@treturn LuaEntity the last chest that had items inserted into it

@usage-- Copy all the items in a players inventory and place them in chests at {0, 0}
move_items(game.player.get_main_inventory())
move_items_stack(game.player.get_main_inventory())

]]
function Common.move_items_stack(items, surface, position, radius, chest_type)
Expand Down Expand Up @@ -650,7 +652,9 @@ function Common.move_items_stack(items, surface, position, radius, chest_type)
if item.valid_for_read then
local chest = next_chest(item)
if not chest or not chest.valid then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) end
chest.insert(item)
local empty_stack = chest.get_inventory(defines.inventory.chest).find_empty_stack(item.name)
if not empty_stack then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) end
empty_stack.transfer_stack(item)
last_chest = chest
end
end
Expand Down
6 changes: 6 additions & 0 deletions locale/en/addons.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,9 @@ jail=__1__ was jailed because they were reported too many times. Please wait for

[protection-jail]
jail=__1__ was jailed because they removed too many protected entities. Please wait for a moderator.

[nukeprotect]
ammo=You cannot have __1__ in your ammo inventory, so it was placed into the chests at spawn.
armor=You cannot have __1__ in your armor inventory, so it was placed into the chests at spawn.
gun=You cannot have __1__ in your gun inventory, so it was placed into the chests at spawn.
main=You cannot have __1__ in your main inventory, so it was placed into the chests at spawn.
75 changes: 75 additions & 0 deletions modules/addons/nukeprotect.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
--- Disable new players from having certain items in their inventory, most commonly nukes
-- @addon Nukeprotect

local Event = require 'utils.event' --- @dep utils.event
local Roles = require 'expcore.roles' --- @dep expcore.roles
local config = require 'config.nukeprotect' --- @dep config.nukeprotect
local move_items_stack = _C.move_items_stack --- @dep expcore.common

Event.add(defines.events.on_player_ammo_inventory_changed, function(event)
oof2win2 marked this conversation as resolved.
Show resolved Hide resolved
local player = game.get_player(event.player_index)

-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end

local inv = player.get_inventory(defines.inventory.character_ammo)

for i = 1, #inv do
local item = inv[i]
if item.valid and item.valid_for_read and config.ammo[item.name] then
player.print({ "nukeprotect.ammo", { "item-name." .. item.name } })
move_items_stack({ item })
end
end
oof2win2 marked this conversation as resolved.
Show resolved Hide resolved
end)

Event.add(defines.events.on_player_armor_inventory_changed, function(event)
local player = game.get_player(event.player_index)

-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end

local inv = player.get_inventory(defines.inventory.character_armor)

for i = 1, #inv do
local item = inv[i]
if item.valid and item.valid_for_read and config.armor[item.name] then
player.print({ "nukeprotect.armor", { "item-name." .. item.name } })
move_items_stack({ item })
end
end
end)

Event.add(defines.events.on_player_gun_inventory_changed, function(event)
local player = game.get_player(event.player_index)

-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end

local inv = player.get_inventory(defines.inventory.character_guns)

for i = 1, #inv do
local item = inv[i]
if item.valid and item.valid_for_read and config.gun[item.name] then
player.print({ "nukeprotect.gun", { "item-name." .. item.name } })
move_items_stack({ item })
end
end
end)

Event.add(defines.events.on_player_main_inventory_changed, function(event)
local player = game.get_player(event.player_index)

-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end

local inv = player.get_inventory(defines.inventory.character_main)

for i = 1, #inv do
local item = inv[i]
if item.valid and item.valid_for_read and config.main[item.name] then
player.print({ "nukeprotect.main", { "item-name." .. item.name } })
move_items_stack({ item })
end
end
end)