mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Refactor legacy addons into Clusterio format (#413)
* 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
This commit is contained in:
181
exp_scenario/module/control/fast_deconstruction.lua
Normal file
181
exp_scenario/module/control/fast_deconstruction.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
--[[-- 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user