-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathadmin.lua
348 lines (297 loc) · 13.5 KB
/
admin.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
-- admin.lua
local admin = {}
-- Function to get all admin players
function admin.get_admin_players()
local admins = {}
for _, player in pairs(game.players) do
if player.admin then
table.insert(admins, player)
end
end
return admins
end
-- Track if the player is holding the custom deconstruction planner
global.player_holding_custom_planner = global.player_holding_custom_planner or {}
-- Function to give the player a deconstruction planner with special configuration
local landfill_tile_name = "landfill"
local function give_custom_deconstruction_planner(player)
-- Ensure the player has space in the cursor (hand)
if player.clear_cursor() then
-- Insert a deconstruction planner directly into the player's cursor (hand)
player.cursor_stack.set_stack("deconstruction-planner")
-- Configure the deconstruction planner to only target landfill tiles
local planner = player.cursor_stack
if planner and planner.is_deconstruction_item then
-- Set the tile filters to only target landfill
planner.tile_filters = {landfill_tile_name} -- Set to target only landfill tiles
planner.entity_filters = {} -- Clear
planner.tile_selection_mode = defines.deconstruction_item.tile_selection_mode.only
-- Mark that the player is holding the custom deconstruction planner
global.player_holding_custom_planner[player.index] = true
player.print("You have been given a custom deconstruction planner for removing landfill.")
else
player.print("Error: Couldn't configure the deconstruction planner.")
end
else
player.print("Error: You must have an empty cursor to receive the deconstruction planner.")
end
end
-- Event handler to detect when a player changes the item in their hand (cursor stack)
function admin.on_player_cursor_stack_changed(event)
local player = game.players[event.player_index]
-- Check if the player was holding the custom deconstruction planner
if global.player_holding_custom_planner[player.index] then
local cursor_stack = player.cursor_stack
-- If the player is no longer holding the custom deconstruction planner
if not cursor_stack.valid_for_read or cursor_stack.name ~= "deconstruction-planner" then
global.player_holding_custom_planner[player.index] = false
-- Try to delete the custom deconstruction planner from their inventory
local main_inventory = player.get_main_inventory()
if main_inventory then
for i = 1, #main_inventory do
local item = main_inventory[i]
if item and item.valid_for_read and item.name == "deconstruction-planner" then
-- Remove the deconstruction planner
main_inventory.remove(item)
player.print("The custom deconstruction planner has been removed.")
break
end
end
end
end
end
end
-- Function to create the top-left button for admins
function admin.create_top_left_button(player)
-- Ensure the player is an admin
if not player.admin then return end
-- If the button already exists, destroy it to avoid duplicate creation
if player.gui.top.admin_panel_button then
player.gui.top.admin_panel_button.destroy()
end
-- Create the top-left button
player.gui.top.add({
type = "button",
name = "admin_panel_button",
caption = "Admin Tools"
})
end
-- Event handler for when a player joins the game
function admin.on_player_joined(event)
local player = game.players[event.player_index]
admin.create_top_left_button(player)
end
-- Store the deconstruction event
function admin.store_deconstruction_event(player_name, area, surface)
-- Ensure the history exists
global.deconstruction_history = global.deconstruction_history or {}
-- Add the new deconstruction event to the history
table.insert(global.deconstruction_history, {
player_name = player_name,
area = area,
surface = surface
})
-- Limit the history to the last 20 entries
if #global.deconstruction_history > 20 then
table.remove(global.deconstruction_history, 1) -- Remove the oldest entry
end
end
-- Function to highlight a deconstruction area and render player's name
function admin.highlight_deconstruction_area(surface, area, player_name)
-- Ensure the surface is valid and check for left_top and right_bottom coordinates
if not surface or not surface.valid then
return
end
if area and area.left_top and area.right_bottom then
-- Define the color and duration for the rectangle highlight
local color = {r = 1, g = 0, b = 0, a = 0.5} -- Red with some transparency
local duration_ticks = 60 * 10 -- 10 seconds
-- Get all admin players
local admins = admin.get_admin_players()
-- Draw a rectangle around the deconstruction area visible only to admins
rendering.draw_rectangle({
color = color,
width = 4,
filled = false,
left_top = area.left_top,
right_bottom = area.right_bottom,
surface = surface,
players = admins, -- Show only to admins
time_to_live = duration_ticks -- Duration before it disappears
})
-- Draw the player's name at the top left of the deconstruction area with 50% transparency
rendering.draw_text({
text = player_name,
surface = surface,
target = area.left_top, -- Position the text at the top-left of the deconstruction area
color = {r = 1, g = 1, b = 1, a = 0.5}, -- White color with 50% transparency (alpha = 0.5)
scale = 1.5,
players = admins, -- Show only to admins
time_to_live = duration_ticks -- Duration before it disappears
})
end
end
-- Function to show the admin panel with buttons
function admin.show_admin_panel(player)
-- Ensure the player is an admin
if not player.admin then return end
-- Clear existing GUI elements if the panel is already open
if player.gui.center.admin_panel then
player.gui.center.admin_panel.destroy()
end
-- Create the admin panel
local frame = player.gui.center.add({
type = "frame",
name = "admin_panel",
direction = "vertical",
caption = "Admin Tools"
})
-- Add one button to display the last 20 deconstruction events
frame.add({
type = "button",
name = "show_last_20_decons",
caption = "Show Last 20 Deconstructions"
})
frame.add({
type = "button",
name = "remove_landfill",
caption = "Remove Landfill",
tooltip = "Removes up to 20 tiles of landfill with your next deconstruction planner use."
})
-- Add a button to execute the /admin command
frame.add({
type = "button",
name = "run_admin_command",
caption = "/admin info"
})
-- Add a close button
frame.add({
type = "button",
name = "close_admin_panel",
caption = "Close"
})
end
-- Function to handle GUI click events
function admin.on_gui_click(event)
local player = game.players[event.player_index]
-- Handle admin panel close button
if event.element.name == "close_admin_panel" then
if player.gui.center.admin_panel then
player.gui.center.admin_panel.destroy()
end
return
end
-- Handle showing last 20 deconstructions
if event.element.name == "show_last_20_decons" then
-- Loop through the last 20 deconstruction events and highlight each one
for _, decon_event in ipairs(global.deconstruction_history or {}) do
admin.highlight_deconstruction_area(decon_event.surface, decon_event.area, decon_event.player_name)
end
end
-- Handle removing landfill
if event.element.name == "remove_landfill" then
player.print("Use the deconstruction planner to remove up to 20 landfill tiles.")
give_custom_deconstruction_planner(player)
end
-- Handle executing /admin command
if event.element.name == "run_admin_command" then
game.players[event.player_index].print("You have to type /admin in the chat to execute the command.")
end
-- Handle clicking the top-left button to open the admin panel
if event.element.name == "admin_panel_button" then
admin.show_admin_panel(player)
end
end
-- Event handler for when a player uses the deconstruction planner
function admin.on_player_deconstructed_area(event)
local player = game.players[event.player_index]
local area = event.area
local surface = event.surface -- Use event.surface directly
-- Check if surface is valid before proceeding
if not surface or not surface.valid then
return
end
-- Store the deconstruction event (original logic)
admin.store_deconstruction_event(player.name, area, surface)
-- Check if the player is holding the custom deconstruction planner (for landfill removal)
if global.player_holding_custom_planner[player.index] then
local cursor_stack = player.cursor_stack
-- Check if the cursor stack contains the custom deconstruction planner (identified by its tile filter)
if cursor_stack.valid_for_read and cursor_stack.is_deconstruction_item then
if cursor_stack.tile_filters and cursor_stack.tile_filters[1] == "landfill" then
-- Track how many landfill tiles have been changed
local tiles_changed = 0
local max_tiles_to_change = 20
local tiles_to_replace = {}
-- Iterate over the selected area and find landfill tiles
for x = math.floor(area.left_top.x), math.ceil(area.right_bottom.x) do
for y = math.floor(area.left_top.y), math.ceil(area.right_bottom.y) do
local tile = surface.get_tile(x, y)
if tile.name == "landfill" and tiles_changed < max_tiles_to_change then
-- Replace landfill tile with water
table.insert(tiles_to_replace, {name = "water", position = {x, y}})
tiles_changed = tiles_changed + 1
end
-- Stop if we have changed 20 tiles
if tiles_changed >= max_tiles_to_change then
break
end
end
if tiles_changed >= max_tiles_to_change then
break
end
end
-- Replace the tiles on the surface
if #tiles_to_replace > 0 then
surface.set_tiles(tiles_to_replace)
game.print(string.format("[color=red]%s landfill tiles have been removed and replaced with water by %s.[/color]", tiles_changed, player.name))
else
player.print("No landfill tiles were found in the selected area.")
end
-- Remove the custom deconstruction planner from their hand
player.clear_cursor() -- Clears whatever is in their hand
-- Optionally, remove it from their inventory too
local main_inventory = player.get_main_inventory()
if main_inventory then
for i = 1, #main_inventory do
local item = main_inventory[i]
if item and item.valid_for_read and item.name == "deconstruction-planner" then
-- Check if the item has the correct tile filter (landfill)
if item.tile_filters and item.tile_filters[1] == "landfill" then
-- Remove the custom deconstruction planner from inventory
main_inventory.remove(item)
player.print("The custom deconstruction planner has been removed from your inventory.")
break
end
end
end
end
-- Mark that the player is no longer holding the custom planner
global.player_holding_custom_planner[player.index] = false
else
player.print("You're not holding the custom deconstruction planner.")
end
else
player.print("You're not holding any deconstruction planner.")
end
end
end
-- Command to give the player a custom deconstruction planner for landfill removal
commands.add_command("give_landfill_removal_planner", "Gives a deconstruction planner for landfill removal", function(cmd)
local player = game.players[cmd.player_index]
give_custom_deconstruction_planner(player)
end)
-- Add a command to open the admin panel
commands.add_command("open_admin_panel", "Open the admin panel", function(cmd)
local player = game.players[cmd.player_index]
admin.show_admin_panel(player)
end)
-- Library event integration
local lib = {}
lib.events = {
[defines.events.on_player_joined_game] = admin.on_player_joined,
[defines.events.on_gui_click] = admin.on_gui_click,
[defines.events.on_player_deconstructed_area] = admin.on_player_deconstructed_area,
[defines.events.on_player_cursor_stack_changed] = admin.on_player_cursor_stack_changed, -- Add this line
}
return lib