-
Notifications
You must be signed in to change notification settings - Fork 1
/
control.lua
200 lines (177 loc) · 6.32 KB
/
control.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
local util = require("util") -- from data\core\lualib\
local gui = require("gui")
local DataFrame = require("utils.DataFrame")
local migrations = require("migrations")
function player_init(player)
global.state[player.index] = {}
global.history_grouping[player.index] = {}
state_reset(global.state[player.index])
gui.regen(player)
end
function init()
global.state = {}
global.history = DataFrame:new()
global.history_grouping = {}
gui.init()
for _, player in pairs(game.players) do
player_init(player)
end
end
script.on_init(init)
script.on_load(function()
DataFrame:refresh(global.history)
end)
script.on_configuration_changed(function(configuration_changed_data)
local mod_data = configuration_changed_data.mod_changes['speedrun-trainer']
if (mod_data == nil or mod_data.old_version == nil) then
-- We don't care about vanilla saves, that's taken care by on_init
return
end
local old_major_str, old_minor_str, old_patch_str =
string.match(mod_data.old_version, "(%d+)%.(%d+)%.(%d+)")
local old_version = {
major = tonumber(old_major_str),
minor = tonumber(old_minor_str),
patch = tonumber(old_patch_str)
}
if old_version.major < 1 then
migrations["1.0.0"]()
end
for _, player in pairs(game.players) do
gui.regen(player)
end
end)
function state_reset(state)
state.waiting_for_events = false
state.running = false
state.tick_start = 0
state.tick_active = 0
state.mistakes = 0
state.entities = {}
state.entity_count = 0
state.starting_position = nil
end
script.on_event(defines.events.on_player_created, function(event)
if not global.state[event.player_index] then
player_init(game.get_player(event.player_index))
end
end)
function history_collect(player)
local state = global.state[player.index]
entry = util.merge({
{
player = player.name,
time = (state.tick_active - state.tick_start) / 60,
entities = table_size(state.entities),
mistakes = state.mistakes
},
gui.input_properties(player)
})
global.history:append(entry)
gui.render_history(player)
end
script.on_event(defines.events.on_gui_click, function(event)
local clicked_element = event.element
local state = global.state[event.player_index]
local gui_elements = global.gui_elements[event.player_index]
local history_grouping = global.history_grouping[event.player_index]
local player = game.get_player(event.player_index)
if clicked_element == gui_elements.button_start then
state_reset(state)
state.starting_position = player.position
state.waiting_for_events = true
elseif clicked_element == gui_elements.button_cancel then
state.running = false
elseif clicked_element == gui_elements.button_stop then
state.running = false
history_collect(player)
elseif clicked_element == gui_elements.button_reset then
local inventory = player.get_main_inventory()
for _, entity in pairs(state.entities) do
if entity.valid then
local items = entity.prototype.items_to_place_this
if items then
for _, item in pairs(items) do
inventory.insert(item)
end
end
entity.destroy()
end
end
player.teleport(state.starting_position)
state_reset(state)
elseif clicked_element == gui_elements.button_history then
gui.toggle_history(player)
elseif clicked_element == gui_elements.button_history_clear then
global.history:clear()
gui.render_history(player)
else
for property, checkbox in pairs(gui_elements.table_history_grouping) do
if clicked_element == checkbox then
if checkbox.state then
history_grouping[property.name] = property.name
else
history_grouping[property.name] = nil
end
gui.render_history(player)
break
end
end
end
gui.render_controls(player)
end)
script.on_event(defines.events.on_tick, function(event)
for _, player in pairs(game.players) do
gui.render_controls(player)
end
end)
script.on_event({
defines.events.on_built_entity,
defines.events.on_entity_settings_pasted,
defines.events.on_marked_for_deconstruction,
defines.events.on_marked_for_upgrade,
defines.events.on_picked_up_item,
defines.events.on_player_ammo_inventory_changed,
defines.events.on_player_armor_inventory_changed,
defines.events.on_player_changed_position,
defines.events.on_player_crafted_item,
defines.events.on_player_dropped_item,
defines.events.on_player_fast_transferred,
defines.events.on_player_main_inventory_changed,
defines.events.on_player_mined_entity,
defines.events.on_player_mined_item,
defines.events.on_player_mined_tile,
defines.events.on_player_rotated_entity,
defines.events.on_player_pipette
}, function(event)
if event.player_index == nil then
return
end
local state = global.state[event.player_index]
-- Other mods may cause one of these events before our on_player_created is called, e.g. the crash site cutscene
if not state then
player_init(game.get_player(event.player_index))
state = global.state[event.player_index]
end
if state.waiting_for_events then
state.waiting_for_events = false
state.running = true
state.tick_start = game.tick
end
-- NOT elseif! First entity placed does count!
if state.running then
state.tick_active = game.tick
if event.name == defines.events.on_player_mined_entity then
local entity = event.entity
if state.entities[entity.unit_number] then
state.mistakes = state.mistakes + 1
state.entities[entity.unit_number] = nil
state.entity_count = state.entity_count - 1
end
elseif event.name == defines.events.on_built_entity then
local entity = event.created_entity
state.entities[entity.unit_number] = entity
state.entity_count = state.entity_count + 1
end
end
end)