z_mirror/Tapeline

git clone https://git.raiguard.me/z_mirror/Tapeline

Caleb HeuerClean up data when a player is removedcae5ebf

revert-47-freeze-fix
3.7 KiB121 linesraw
1local flib_bounding_box = require("__flib__.bounding-box")
2
3--- @param settings TapeSettings
4--- @param tape Tape?
5--- @return string
6local function build_label(settings, tape)
7  local output = ""
8  if tape then
9    output = output
10      .. tostring(flib_bounding_box.width(tape.box))
11      .. "×"
12      .. tostring(flib_bounding_box.height(tape.box))
13      .. " | "
14  end
15  if settings.mode == "subgrid" then
16    return output .. "Subgrid mode | Size: " .. tostring(settings.subgrid_size)
17  else
18    return output .. "Split mode | # of splits: " .. tostring(settings.splits)
19  end
20end
21
22--- @param player LuaPlayer
23--- @return LuaItemStack?
24local function get_tool(player)
25  local cursor_stack = player.cursor_stack
26  if cursor_stack and cursor_stack.valid_for_read and cursor_stack.name == "tl-tool" then
27    return cursor_stack
28  end
29end
30
31--- @param player LuaPlayer
32--- @param tape Tape?
33local function set_tool(player, tape)
34  local cursor_stack = player.cursor_stack
35  if cursor_stack then
36    if not cursor_stack.valid_for_read or cursor_stack.name == "tl-tool" or player.clear_cursor() then
37      cursor_stack.set_stack({ name = "tl-tool", count = 10 })
38      local settings = tape and tape.settings or storage.player_settings[player.index]
39      cursor_stack.label = build_label(settings, tape)
40    end
41    if player.controller_type == defines.controllers.character and player.character_build_distance_bonus < 1000000 then
42      player.character_build_distance_bonus = player.character_build_distance_bonus + 1000000
43    end
44  end
45end
46
47--- @param e EventData.on_player_cursor_stack_changed
48local function on_player_cursor_stack_changed(e)
49  local player = game.get_player(e.player_index) --[[@as LuaPlayer]]
50  local player_tool = get_tool(player)
51  if player_tool and not storage.holding_tool[e.player_index] then
52    storage.holding_tool[player.index] = true
53    set_tool(player, storage.editing[e.player_index] or storage.drawing[e.player_index])
54  elseif not player_tool and storage.holding_tool[player.index] then
55    storage.holding_tool[player.index] = nil
56    if player.controller_type == defines.controllers.character and player.character_build_distance_bonus >= 1000000 then
57      player.character_build_distance_bonus = player.character_build_distance_bonus - 1000000
58    end
59  end
60end
61
62--- @param e EventData.on_built_entity
63local function on_built_entity(e)
64  local entity = e.entity
65  if not entity.valid then
66    return
67  end
68  local name = entity.name
69  if name == "entity-ghost" then
70    name = entity.ghost_name
71  end
72  if name ~= "tl-dummy-entity" then
73    return
74  end
75  local player = game.get_player(e.player_index)
76  if not player then
77    return
78  end
79  local tape = storage.editing[e.player_index] or storage.drawing[e.player_index]
80  if not tape then
81    return
82  end
83  set_tool(player, tape)
84end
85
86--- @param e EventData.on_player_selected_area|EventData.on_player_alt_selected_area
87local function on_player_selected_area(e)
88  if e.item ~= "tl-tool" then
89    return
90  end
91  local player = game.get_player(e.player_index)
92  if not player then
93    return
94  end
95  set_tool(player, storage.editing[e.player_index])
96end
97
98--- @param e EventData.on_player_removed
99local function on_player_removed(e)
100  storage.holding_tool[e.player_index] = nil
101end
102
103local tool = {}
104
105function tool.on_init()
106  --- @type table<uint, boolean>
107  storage.holding_tool = {}
108end
109
110tool.events = {
111  [defines.events.on_built_entity] = on_built_entity,
112  [defines.events.on_player_alt_selected_area] = on_player_selected_area,
113  [defines.events.on_player_cursor_stack_changed] = on_player_cursor_stack_changed,
114  [defines.events.on_player_selected_area] = on_player_selected_area,
115  [defines.events.on_player_removed] = on_player_removed,
116}
117
118tool.set = set_tool
119tool.get = get_tool
120
121return tool