mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
* Refactor custom start * Refactor afk kick * Fix use of assert get player * Refactor chat popup * Refactor chat auto reply * Refactor help bubbles * Refactor damage popups * Refactor death markers * Refactor deconstruction log * Remove FAGC logging * Refactor discord alerts * Refactor insert pickup * Refactor inventory clear * Refactor extra logging * Refactor nuke protection * Refactor pollution grading * Refactor protection jail * Refactor report jail * Refactor mine depletion * Refactor degrading tiles * Refactor station auto name * Refactor spawn area * Refactor fast deconstruction * Bug Fixes
182 lines
5.6 KiB
Lua
182 lines
5.6 KiB
Lua
--[[-- Control - Fast Deconstruction
|
|
Makes trees which are marked for decon "decay" quickly to allow faster building
|
|
]]
|
|
|
|
local Gui = require("modules/exp_gui")
|
|
local Async = require("modules/exp_util/async")
|
|
local Roles = require("modules.exp_legacy.expcore.roles")
|
|
|
|
local PlayerData = require("modules.exp_legacy.expcore.player_data")
|
|
local HasEnabledDecon = PlayerData.Settings:combine("HasEnabledDecon")
|
|
HasEnabledDecon:set_default(false)
|
|
|
|
local random = math.random
|
|
local floor = math.floor
|
|
local min = math.min
|
|
|
|
--- @class TreeDeconCache
|
|
--- @field tick number The tick this cache is valid
|
|
--- @field player_index number
|
|
--- @field player LuaPlayer
|
|
--- @field force LuaForce
|
|
--- @field trees LuaEntity[]
|
|
--- @field tree_count number
|
|
--- @field permission "fast" | "allow" | "disallow"
|
|
--- @field task Async.AsyncReturn
|
|
|
|
local cache --- @type TreeDeconCache?
|
|
|
|
local remove_trees_async =
|
|
Async.register(function(task_data)
|
|
--- @cast task_data TreeDeconCache
|
|
if task_data.tree_count == 0 then
|
|
return Async.status.complete()
|
|
end
|
|
|
|
local head = task_data.tree_count
|
|
local trees = task_data.trees
|
|
|
|
local max_remove = floor(head / 100) + 1
|
|
local remove_count = min(random(0, max_remove), head)
|
|
for i = 1, remove_count do
|
|
local index = random(1, head)
|
|
local entity = trees[index]
|
|
trees[index] = trees[head]
|
|
head = head - 1
|
|
|
|
if entity and entity.valid then
|
|
entity.destroy()
|
|
end
|
|
end
|
|
|
|
task_data.tree_count = head
|
|
return Async.status.continue(task_data)
|
|
end)
|
|
|
|
--- Check the permission the player has
|
|
--- @param player LuaPlayer
|
|
--- @return "fast" | "allow" | "disallow"
|
|
local function get_permission(player)
|
|
if Roles.player_allowed(player, "fast-tree-decon") then
|
|
return HasEnabledDecon:get(player) and "fast" or "allow"
|
|
elseif Roles.player_allowed(player, "standard-decon") then
|
|
return "allow"
|
|
else
|
|
return "disallow"
|
|
end
|
|
end
|
|
|
|
--- Return or build the cache for a player
|
|
--- @param player_index number
|
|
--- @return TreeDeconCache
|
|
local function get_player_cache(player_index)
|
|
-- Return the current cache if it is valid
|
|
if cache and cache.tick == game.tick and cache.player_index == player_index then
|
|
return cache
|
|
end
|
|
|
|
-- Create a new cache if the previous on is in use
|
|
if not cache or cache.task and not cache.task.completed then
|
|
cache = {} --[[@as any]]
|
|
end
|
|
|
|
local player = assert(game.get_player(player_index))
|
|
cache.tick = game.tick
|
|
cache.player_index = player_index
|
|
cache.player = player
|
|
cache.force = player.force --[[ @as LuaForce ]]
|
|
cache.tree_count = 0
|
|
cache.trees = {}
|
|
cache.permission = get_permission(player)
|
|
cache.task = remove_trees_async:start_soon(cache)
|
|
|
|
return cache
|
|
end
|
|
|
|
-- Left menu button to toggle between fast decon and normal decon marking
|
|
Gui.toolbar.create_button{
|
|
name = "toggle-tree-decon",
|
|
sprite = "entity/tree-01",
|
|
tooltip = { "exp_fast-decon.tooltip-main" },
|
|
auto_toggle = true,
|
|
visible = function(player, _)
|
|
return Roles.player_allowed(player, "fast-tree-decon")
|
|
end
|
|
}:on_click(function(def, player, element)
|
|
local state = Gui.toolbar.get_button_toggled_state(def, player)
|
|
HasEnabledDecon:set(player, state)
|
|
player.print{ "exp_fast-decon.chat-toggle", state and { "exp_fast-decon.chat-enabled" } or { "exp_fast-decon.chat-disabled" } }
|
|
end)
|
|
|
|
-- Add trees to queue when marked, only allows simple entities and for players with role permission
|
|
--- @param event EventData.on_marked_for_deconstruction
|
|
local function on_marked_for_deconstruction(event)
|
|
-- Check player and entity are valid
|
|
local entity = event.entity
|
|
local player_index = event.player_index
|
|
if not player_index or not entity.valid then
|
|
return
|
|
end
|
|
|
|
-- If it has a last user then either do nothing or cancel decon
|
|
local last_user = entity.last_user
|
|
local player_cache = get_player_cache(player_index)
|
|
if last_user then
|
|
if player_cache.permission == "disallow" then
|
|
entity.cancel_deconstruction(player_cache.force)
|
|
end
|
|
return
|
|
end
|
|
|
|
-- Allow fast decon on no last user and not cliff
|
|
if player_cache.permission == "fast" and entity.type ~= "cliff" then
|
|
local head = player_cache.tree_count + 1
|
|
player_cache.tree_count = head
|
|
player_cache.trees[head] = entity
|
|
end
|
|
end
|
|
|
|
--- Clear trees when hit with a car
|
|
--- @param event EventData.on_entity_damaged
|
|
local function on_entity_damaged(event)
|
|
-- Check it was an impact from a force
|
|
if not (event.damage_type.name == "impact" and event.force) then
|
|
return
|
|
end
|
|
|
|
-- Check the entity hit was a tree or rock
|
|
if not (event.entity.type == "tree" or event.entity.type == "simple-entity") then
|
|
return
|
|
end
|
|
|
|
-- Check the case was a car
|
|
if (not event.cause) or (event.cause.type ~= "car") then
|
|
return
|
|
end
|
|
|
|
-- Get a valid player as the driver
|
|
local driver = event.cause.get_driver()
|
|
if not driver then return end
|
|
if driver.object_name ~= "LuaPlayer" then
|
|
driver = driver.player
|
|
if not driver then return end
|
|
end
|
|
|
|
-- Mark the entity to be removed
|
|
local allow = get_player_cache(driver.index)
|
|
if allow == "fast" and HasEnabledDecon:get(driver) then
|
|
event.entity.destroy()
|
|
else
|
|
event.entity.order_deconstruction(event.force, driver)
|
|
end
|
|
end
|
|
|
|
local e = defines.events
|
|
|
|
return {
|
|
events = {
|
|
[e.on_entity_damaged] = on_entity_damaged,
|
|
[e.on_marked_for_deconstruction] = on_marked_for_deconstruction,
|
|
}
|
|
}
|