forked from tburrows13/RemoteConfiguration
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontrol.lua
More file actions
340 lines (303 loc) · 12.1 KB
/
Copy pathcontrol.lua
File metadata and controls
340 lines (303 loc) · 12.1 KB
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
local RecipeChange = require "__RemoteConfiguration__/recipe-change"
-- These entity types can be opened remotely anyway
local entity_type_blacklist = {
["locomotive"] = true,
["train-stop"] = true,
["electric-pole"] = true,
}
local function increase_range(player)
if player.character and player.character_reach_distance_bonus < 200000 then
player.character_reach_distance_bonus = player.character_reach_distance_bonus + 200000
end
end
local function reset_range(player)
if not player.character then return end
while player.character_reach_distance_bonus >= 200000 do
player.character_reach_distance_bonus = player.character_reach_distance_bonus - 200000
end
end
local function can_reach_entity(player, entity)
-- Check if player can reach entity disregarding whatever reach bonus we have given the player
if not player.character then return true end
local reach_distance_bonus = player.character_reach_distance_bonus
reset_range(player)
local can_reach = player.can_reach_entity(entity)
player.character_reach_distance_bonus = reach_distance_bonus
return can_reach
end
local function is_out_of_range_gui_open(player)
local opened = player.opened
if opened and player.opened_gui_type == defines.gui_type.entity and not can_reach_entity(player, opened) then
return true
end
return false
end
local wires = {["red-wire"] = true, ["green-wire"] = true, ["copper-cable"] = true}
local function is_holding_wire(player)
local cursor_stack = player.cursor_stack
if cursor_stack and cursor_stack.valid_for_read then
return wires[cursor_stack.name]
end
end
script.on_event("rc-open-gui",
function(event)
local player = game.get_player(event.player_index)
local cursor_stack = player.cursor_stack
if (cursor_stack and cursor_stack.valid_for_read) or player.cursor_ghost then return end
local selected = player.selected
if selected then
if entity_type_blacklist[selected.type] then return end
reset_player(player) -- Ensures that can_reach_entity is accurate, not needed any more?
local out_of_reach = not can_reach_entity(player, selected)
local map_mode = player.render_mode == defines.render_mode.chart_zoomed_in
if out_of_reach or map_mode then
player.opened = nil -- Triggers on_gui_closed before we open the GUI we care about
if out_of_reach then
increase_range(player)
player.permission_group = game.permissions.get_group("Remote Configuration GUI opened")
end
player.opened = selected
if player.opened_gui_type == defines.gui_type.entity then
RecipeChange.on_remote_gui_opened(player)
else
-- Opening GUI failed
reset_player(player)
end
end
end
end
)
function reset_player(player)
player.permission_group = game.permissions.get_group("Default")
reset_range(player)
end
script.on_event(defines.events.on_gui_closed,
function(event)
local player = game.get_player(event.player_index)
RecipeChange.on_gui_closed(player)
if is_holding_wire(player) then return end
reset_player(player)
end
)
-- Allows wires to be fast-transfered or placed in chests when close, but not when far away
local function recalculate_wire_permissions(event)
local player = game.get_player(event.player_index)
if not is_holding_wire(player) then return end
local opened = player.opened
if player.selected and can_reach_entity(player, player.selected) then
reset_player(player)
elseif player.opened_self or (opened and player.opened_gui_type == defines.gui_type.entity and can_reach_entity(player, opened)) then
reset_player(player)
else
increase_range(player)
player.permission_group = game.permissions.get_group("Remote Configuration GUI opened")
end
end
script.on_event(defines.events.on_player_changed_position, recalculate_wire_permissions)
script.on_event(defines.events.on_selected_entity_changed, recalculate_wire_permissions)
script.on_event(defines.events.on_gui_opened, recalculate_wire_permissions)
script.on_event(defines.events.on_player_cursor_stack_changed,
function(event)
local player = game.get_player(event.player_index)
if is_holding_wire(player) then
recalculate_wire_permissions(event)
else
if not is_out_of_range_gui_open(player) then
reset_player(player)
end
end
end
)
script.on_event("rc-paste-entity-settings",
function(event)
local player = game.get_player(event.player_index)
local cursor_stack = player.cursor_stack
if (cursor_stack and cursor_stack.valid_for_read) or player.cursor_ghost then return end
local selected = player.selected
if not selected then return end
local in_reach = can_reach_entity(player, selected)
if in_reach then return end -- Let vanilla handle this
local entity_copy_source = player.entity_copy_source
if not entity_copy_source then return end
removed_items = selected.copy_settings(entity_copy_source, player)
local surface = selected.surface
local position = selected.position
local force = player.force
for name, count in pairs(removed_items) do
surface.spill_item_stack(
position,
{name = name, count = count},
true, -- enabled_looted
force, -- force for deconstruction
false -- allow_on_belts
)
end
end
)
function is_cheating(player)
if
player.cheat_mode
and not (player.controller_type == defines.controllers.god and script.active_mods["space-exploration"])
then
return true
end
return player.controller_type == defines.controllers.editor
end
function set_cursor(player, item)
local inventory = player.get_main_inventory()
if not inventory then
return false
end
local cursor_stack = player.cursor_stack
if not cursor_stack or not player.clear_cursor() then
return false
end
local inventory_stack, stack_index = inventory.find_item_stack(item)
if not inventory_stack or not stack_index then
local stack_size = game.item_prototypes[item].stack_size
if is_cheating(player) and inventory.can_insert({ name = item, count = stack_size }) then
inventory.insert({ name = item, count = stack_size })
inventory_stack, stack_index = inventory.find_item_stack(item)
else
player.cursor_ghost = item
return true
end
end
--- @cast inventory_stack LuaItemStack
--- @cast stack_index uint
if not cursor_stack.transfer_stack(inventory_stack) then
return false
end
local inventory_def
if player.controller_type == defines.controllers.character then
inventory_def = defines.inventory.character_main
elseif player.controller_type == defines.controllers.editor then
inventory_def = defines.inventory.editor_main
elseif player.controller_type == defines.controllers.god then
inventory_def = defines.inventory.god_main
end
player.hand_location = { inventory = inventory_def, slot = stack_index }
return true
end
local function remote_build(event)
local player = game.get_player(event.player_index)
if player.render_mode == defines.render_mode.game then
-- Try and put the real item back in the cursor
local cursor_ghost = player.cursor_ghost
if not cursor_ghost then return end
local main_inventory = player.get_main_inventory()
if not main_inventory then
return
end
local count = main_inventory.get_item_count(cursor_ghost.name)
if count == 0 then
return
end
set_cursor(player, cursor_ghost.name)
else
local cursor_stack = player.cursor_stack
if not (cursor_stack and cursor_stack.valid_for_read) then return end
if not cursor_stack.prototype.place_result then return end
local cursor_stack_name = cursor_stack.name
if player.clear_cursor() then
player.cursor_ghost = cursor_stack_name
end
end
end
script.on_event("rc-build", remote_build)
local direction_modifiers = {
["straight-rail"] = 0, -- 0 means ignore
["curved-rail"] = 0,
["rail-signal"] = 0,
["rail-chain-signal"] = 0,
["generator"] = 0,
["burner-generator"] = 0,
["assembling-machine"] = -1, -- -1 means rotate immediately
["splitter"] = 4,
["underground-belt"] = 4,
["pipe-to-ground"] = 4,
["pump"] = 4,
}
local function remote_rotate(event, direction)
local player = game.get_player(event.player_index)
local cursor_stack = player.cursor_stack
if (cursor_stack and cursor_stack.valid_for_read) or player.cursor_ghost then return end
local selected = player.selected
if not selected then return end
if can_reach_entity(player, selected) then return end -- Let vanilla handle this
if not selected.supports_direction then return end
local current_direction = selected.get_upgrade_direction()
if not current_direction then current_direction = selected.direction end
local direction_modifier = direction_modifiers[selected.type] or 2
if direction_modifier == 0 then return end
if direction_modifier == -1 then
local next_direction = (current_direction + 2 * direction) % 8
selected.direction = next_direction
else
local next_direction = (current_direction + direction * direction_modifier) % 8
if next_direction == selected.direction and selected.get_upgrade_target() and selected.get_upgrade_target().name == selected.name then
selected.cancel_upgrade(player.force, player)
else
selected.order_upgrade{force = player.force, target = selected, player = player, direction = next_direction}
end
end
end
script.on_event("rc-rotate", function(event) remote_rotate(event, 1) end)
script.on_event("rc-reverse-rotate", function(event) remote_rotate(event, -1) end)
local function remote_mine(event)
local player = game.get_player(event.player_index)
local selected = player.selected
if not selected then return end
if can_reach_entity(player, selected) then return end -- Let vanilla handle this
selected.order_deconstruction(player.force, player)
end
script.on_event("rc-mine", remote_mine)
local function remote_cancel_deconstruct(event)
local player = game.get_player(event.player_index)
local selected = player.selected
if not selected then return end
selected.cancel_deconstruction(player.force, player)
end
script.on_event("rc-shift-right-click", remote_cancel_deconstruct)
local function create_permission_group(config_changed_data)
local permissions = game.permissions
if config_changed_data then
-- in on_configuration_changed
if config_changed_data.mod_changes and config_changed_data.mod_changes["RemoteConfiguration"] then
for _, player in pairs(game.players) do
reset_player(player)
player.opened = nil
end
end
if permissions.get_group("Remote Configuration GUI opened") then
permissions.get_group("Remote Configuration GUI opened").destroy()
end
end
if permissions.get_group("Remote Configuration GUI opened") then
return
end
local group = permissions.create_group("Remote Configuration GUI opened")
if not group then
log("Group not created!!!")
game.print("[Remote Configuration] Group not created, please report!")
return
end
group.set_allows_action(defines.input_action.begin_mining, false)
group.set_allows_action(defines.input_action.begin_mining_terrain, false)
group.set_allows_action(defines.input_action.build, false)
group.set_allows_action(defines.input_action.build_rail, false)
group.set_allows_action(defines.input_action.build_terrain, false)
group.set_allows_action(defines.input_action.cursor_split, false)
group.set_allows_action(defines.input_action.cursor_transfer, false)
group.set_allows_action(defines.input_action.fast_entity_split, false)
group.set_allows_action(defines.input_action.fast_entity_transfer, false)
group.set_allows_action(defines.input_action.inventory_split, false)
group.set_allows_action(defines.input_action.inventory_transfer, false)
group.set_allows_action(defines.input_action.place_equipment, false)
group.set_allows_action(defines.input_action.stack_split, false)
group.set_allows_action(defines.input_action.stack_transfer, false)
group.set_allows_action(defines.input_action.take_equipment, false)
group.set_allows_action(defines.input_action.paste_entity_settings, false)
end
script.on_init(create_permission_group)
script.on_configuration_changed(create_permission_group)