-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinput.lua
148 lines (135 loc) · 3.86 KB
/
input.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
local schemes = require("input_schemes")
local args = require("args")
local config = require("config")
local buttons
if not args.headless then
buttons = require("ui.screens.game.controls")
end
-- wrapper for game inputs to automate replay recording
local input = {
---@type Replay?
replay = nil,
is_done_replaying = false,
}
local recording = false
local input_state = {}
local time = 0
local replaying = false
local seed_index = 0
---starts recording all new inputs
function input.record_start()
input.replay_stop()
recording = true
time = 0
input_state = {}
end
---stops recording inputs
function input.record_stop()
recording = false
end
---start replaying the active replay
function input.replay_start()
input.record_stop()
replaying = true
time = 0
seed_index = 0
input_state = {}
input.is_done_replaying = false
end
function input.is_replaying()
return replaying
end
---save the next seed when recording or get the next seed when replaying
---@param seed number
---@return number
function input.next_seed(seed)
if recording then
input.replay:record_seed(seed)
return seed
elseif replaying then
seed_index = seed_index + 1
return input.replay.data.seeds[seed_index]
end
return seed
end
---stops replaying
function input.replay_stop()
replaying = false
input.is_done_replaying = true
end
---increments the timer for the input timestamps when recording and updates the input state when replaying
function input.update()
if recording then
time = time + 1
input.replay.input_tick_length = time
end
if replaying then
time = time + 1
input.is_done_replaying = time >= input.replay.input_tick_length
for key, state in input.replay:get_key_state_changes(time) do
input_state[key] = state
end
end
end
-- common keys used to get player actions
local mapping = {
lshift = "focus",
}
---gets the down state of any input (checks config for bindings, uses key if it doesn't exist)
---records changes if recording
---gets input state from replay if replaying
---@param input_name string
---@param add_ui_button boolean?
---@return boolean
function input.get(input_name, add_ui_button)
input_name = mapping[input_name] or input_name
if add_ui_button == nil then
add_ui_button = input_name ~= "left" and input_name ~= "right"
end
if args.headless or not config.get("in-game_buttons") then
add_ui_button = false
end
local inputs = config.get(input_name) or { {
ids = { input_name },
scheme = "keyboard",
} }
local ui_button
if add_ui_button then
ui_button = buttons.get(input_name)
if not ui_button then
ui_button = buttons.add(input_name)
end
ui_button.updated = true
end
local ret = false
for i = 1, #inputs do
local scheme = inputs[i]
for j = 1, #scheme.ids do
local key = scheme.scheme .. "_" .. scheme.ids[j]
if replaying then
local state = input_state[key] or false
if add_ui_button then
ui_button.real_input_state = state
end
return state
end
local state = schemes[scheme.scheme].is_down(scheme.ids[j])
if recording then
if input.replay == nil then
error("attempted to record input without active replay")
end
if input_state[key] ~= state then
input_state[key] = state
input.replay:record_input(key, state, time)
end
end
ret = ret or state
end
end
if add_ui_button then
ret = ui_button.ui_pressing or ret
ui_button.real_input_state = ret
end
return ret
end
return input