z_mirror/MouseOverConstruction

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

Caleb HeuerIt just works!fb86312

insertion
3.3 KiB138 linesraw
1local construct = require("scripts.construct")
2local deconstruct = require("scripts.deconstruct")
3local insert = require("scripts.insert")
4local repair = require("scripts.repair")
5local upgrade = require("scripts.upgrade")
6
7--- @type Set<string>
8local ignored_entities = prototypes.mod_data["moc-ignored-entities"].data
9
10--- @param entity LuaEntity
11local function should_ignore_entity(entity)
12  local useful_name = ""
13  if entity.type == "entity-ghost" then
14    useful_name = entity.ghost_name
15  else
16    useful_name = entity.name
17  end
18  return ignored_entities[useful_name] or false
19end
20
21--- @param player LuaPlayer
22--- @param entity LuaEntity
23local function try_execute(player, entity)
24  if not storage.mouseover_active[player.index] then
25    return
26  end
27
28  if should_ignore_entity(entity) then
29    return
30  end
31
32  if not player.can_reach_entity(entity) then
33    storage.recheck_on_move[player.index] = true
34    return
35  end
36
37  local cursor_stack = player.cursor_stack
38  if not cursor_stack then
39    return
40  end
41
42  local is_empty = not cursor_stack.valid_for_read
43  local is_repair_tool = not is_empty and cursor_stack.type == "repair-tool"
44
45  local upgrade_prototype, upgrade_quality = entity.get_upgrade_target()
46  local entity_name, entity_quality = entity.name, entity.quality
47  if upgrade_prototype then
48    --- @cast upgrade_quality -?
49    entity_name = upgrade_prototype.name
50    entity_quality = upgrade_quality
51  elseif entity.type == "entity-ghost" then
52    entity_name = entity.ghost_name
53  end
54  local matches_selected = not is_empty
55    and cursor_stack.prototype.place_result
56    and cursor_stack.prototype.place_result.name == entity_name
57    and cursor_stack.quality == entity_quality
58
59  local should_execute = matches_selected or is_empty or is_repair_tool
60
61  if not should_execute then
62    return
63  end
64
65  if construct(player, entity) then
66    return
67  end
68
69  if insert(player, entity) then
70    return
71  end
72
73  if is_repair_tool and repair.start(player, entity) then
74    return
75  end
76
77  if upgrade(player, entity) then
78    return
79  end
80
81  deconstruct.start(player, entity)
82end
83
84--- @param e EventData.on_player_changed_position
85local function on_player_changed_position(e)
86  if not storage.recheck_on_move[e.player_index] then
87    return
88  end
89  storage.recheck_on_move[e.player_index] = nil
90
91  if not storage.mouseover_active[e.player_index] then
92    return
93  end
94
95  local player = game.get_player(e.player_index)
96  if not player then
97    return
98  end
99
100  local selected = player.selected
101  if not selected then
102    return
103  end
104
105  try_execute(player, selected)
106end
107
108--- @param e EventData.on_selected_entity_changed
109local function on_selected_entity_changed(e)
110  deconstruct.cancel(e.player_index)
111  repair.cancel(e.player_index)
112  storage.recheck_on_move[e.player_index] = nil
113
114  local player = game.get_player(e.player_index)
115  --- @cast player -?
116
117  local selected = player.selected
118  if not selected then
119    return
120  end
121
122  try_execute(player, selected)
123end
124
125--- @class orchestrator_handler : event_handler
126local orchestrator_handler = {}
127
128function orchestrator_handler.on_init()
129  --- @type Set<PlayerIndex>
130  storage.recheck_on_move = {}
131end
132
133orchestrator_handler.events = {
134  [defines.events.on_player_changed_position] = on_player_changed_position,
135  [defines.events.on_selected_entity_changed] = on_selected_entity_changed,
136}
137
138return orchestrator_handler