-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfake_engine.lua
356 lines (322 loc) · 8.77 KB
/
fake_engine.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
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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
-- Set up the api we are using
---@class (exact) shot_ref
---@field state state
---@field num_of_cards_to_draw integer
---@diagnostic disable-next-line: unused-function
local function dbg_cards(pile)
for _, v in ipairs(pile) do
print(v.id)
end
end
---@diagnostic disable-next-line: unused-function, unused-local
local function dbg_wand()
print("discard")
dbg_cards(discarded)
print("hand")
dbg_cards(hand)
print("deck")
dbg_cards(deck)
end
---@param text_formatter text_formatter
---@param id string
local function bad_spell(text_formatter, id)
error(
text_formatter.colour_codes.RED
.. "Unknown spell "
.. text_formatter.colour_codes.RESET
.. '"'
.. text_formatter.colour_codes.GREEN
.. id
.. text_formatter.colour_codes.RESET
.. '"'
)
end
---@param text_formatter text_formatter
---@param id string
local function is_bad(text_formatter, id)
for _, v in ipairs(actions) do
if v.id == id then
return
end
end
bad_spell(text_formatter, id)
end
---@param id string
---@param charges integer?
---@param options options
---@param text_formatter text_formatter
local function easy_add(id, charges, options, text_formatter)
id = id:upper()
for _, v in ipairs(actions) do
if v.id:upper() == id then
if v.max_uses == nil then
charges = -1
elseif options.unlimited_spells and not v.never_unlimited then
charges = -1
elseif charges ~= nil then -- at this point we use the arg
elseif options.drained then
charges = 0
else
charges = v.max_uses
end
---@cast charges integer
_add_card_to_deck(id, 0, charges, true)
local card = deck[#deck]
---@diagnostic disable-next-line: missing-parameter, assign-type-mismatch, param-type-mismatch
card.action = card.action(card)
return
end
end
bad_spell(text_formatter, id)
end
---@class fake_engine
local M = {}
---@param options options
local function regenerate_translations(options)
-- print(ModTextFileGetContent("data/translations/common.csv"))
local actual_translations = {}
local tcsv = require("extra.tcsv")
local csv = tcsv.parse(ModTextFileGetContent("data/translations/common.csv"), "common.csv", false)
local csv_lang_row = nil
for k, v in ipairs(csv.langs) do
if v == options.language then
csv_lang_row = k + 1
end
end
for _, v in ipairs(csv.rows) do
actual_translations[v[1]] = v[csv_lang_row]
end
function GameTextGetTranslatedOrNot(text_or_key)
if text_or_key:sub(1, 1) == "$" then
return actual_translations[text_or_key:sub(2)] or text_or_key
end
return text_or_key
end
for _, v in ipairs(actions or {}) do
if options.language then
M.translations[v.id] = GameTextGetTranslatedOrNot(v.name)
--print(v.id, v.name, GameTextGetTranslatedOrNot(v.name))
--print(v.name:len())
end
end
end
M.mods_path = ""
M.data_path = ""
---@param options options
function M.make_fake_api(options)
package.path = package.path .. ";" .. M.data_path .. "?.lua;" .. M.mods_path .. "?.lua"
M.vfs = {
["data/translations/common.csv"] = assert(
assert(io.open(M.mods_path .. "data/translations/common.csv", "r")):read("*a")
),
}
local _print = print
require("meta.out")
print = _print
regenerate_translations(options)
local frame = math.floor(os.time() * 1000) % 2 ^ 16
function Random(a, b)
if not a and not b then
return math.random()
end
if not b then
b = a
a = 0
end
return math.floor(math.random() * (b - a + 1)) + a
end
local globals = {}
local append_map = {}
function GlobalsSetValue(key, value)
globals[key] = tostring(value)
end
function ModTextFileGetContent(filename)
local success, res = pcall(function()
if M.vfs[filename] then
return M.vfs[filename]
end
if filename:sub(1, 4) == "mods" then
return assert(assert(io.open(M.mods_path .. filename)):read("*a"))
end
return assert(assert(io.open(M.data_path .. filename)):read("*a"))
end)
if not success then
return ""
end
return res
end
function ModTextFileSetContent(filename, new_content)
M.vfs[filename] = new_content
if filename == "data/translations/common.csv" then
regenerate_translations(options)
end
end
function GlobalsGetValue(key, value)
return tostring(globals[key] or value)
end
function SetRandomSeed(x, y)
math.randomseed(x * 591.321 + y * 8541.123 + 124.545)
end
function GameGetFrameNum()
return frame
end
function ModLuaFileAppend(to, from)
append_map[to] = append_map[to] or {}
table.insert(append_map[to], from)
end
function dofile(file)
local res = { require(file:sub(1, file:len() - 4)) }
for _, v in ipairs(append_map[file] or {}) do
dofile(v)
end
return unpack(res)
end
dofile_once = dofile
dofile("data/scripts/gun/gun_enums.lua")
--[[function BeginProjectile(p)
print(p)
end]]
end
---@param text_formatter text_formatter
---@param options options
function M.initialise_engine(text_formatter, options)
dofile("data/scripts/gun/gun.lua")
local _create_shot = create_shot
function create_shot(...)
local uv = { _create_shot(...) }
local v = uv[1]
M.nodes_to_shot_ref[M.cur_parent] = v
M.shot_refs_to_nums[v] = { disp = M.cur_shot_num, real = M.cur_shot_num }
M.cur_shot_num = M.cur_shot_num + 1
-- v.state.wand_tree_initial_mana = mana
-- TODO: find a way to do this in a garunteed safe way
return unpack(uv)
end
function StartReload(reload_time)
M.reload_time = reload_time
end
--[[local _draw_shot = draw_shot
function draw_shot(...)
local v = { _draw_shot(...) }
local args = { ... }
local shot = args[1]
shot.state.wand_tree_mana = mana - shot.state.wand_tree_initial_mana
shot.state.wand_tree_initial_mana = nil
return unpack(v)
end]]
M.translations = {}
for _, v in ipairs(actions) do
text_formatter.ty_map[v.id] = v.type
local _a = v.action
v.action = function(clone, ...)
local new = function(...)
---@cast clone action
local old_node = M.cur_node
local new_node = { name = v.id, children = {}, index = clone.deck_index }
M.counts[v.id] = (M.counts[v.id] or 0) + 1
M.cur_node = new_node.children
M.cur_parent = new_node
table.insert(old_node, new_node)
local res = { _a(...) }
M.cur_node = old_node
return unpack(res)
end
if type(clone) == "table" then -- this is awful
---@diagnostic disable-next-line: return-type-mismatch
return new
end
clone = { deck_index = -1 }
return unpack({ new(...) })
end
end
regenerate_translations(options)
end
---@param options options
---@param text_formatter text_formatter
function M.evaluate(options, text_formatter)
---@type node
M.calls = { name = "Wand", children = {} }
M.nodes_to_shot_ref = {}
M.shot_refs_to_nums = {}
M.lines_to_shot_nums = {}
M.cur_shot_num = 1
M.counts = {}
_clear_deck(false)
for _, v in ipairs(options.spells) do
if type(v) == "string" then
easy_add(v, nil, options, text_formatter)
else
easy_add(v.name, v.count, options, text_formatter)
end
end
ConfigGun_ReadToLua(options.spells_per_cast, false, options.reload_time, 66)
_set_gun()
local data = require("data")
local arg_list = require("arg_list")
data.fire_rate_wait = options.cast_delay
local value = {}
for _, v in ipairs(arg_list) do
table.insert(value, data[v])
end
--[[local _handle = _handle_reload
_handle_reload = function()
print("reloaded")
print(reloading)
_handle()
end]]
mana = options.mana
GlobalsSetValue("GUN_ACTION_IF_HALF_STATUS", options.every_other and 1 or 0)
for i = 1, options.number_of_casts do
table.insert(M.calls.children, { name = "Cast #" .. i, children = {} })
ConfigGunActionInfo_ReadToLua(unpack(value))
_set_gun2()
M.cur_parent = M.calls.children[#M.calls.children]
local cur_root = M.cur_parent
M.cur_node = M.cur_parent.children
local old_mana = mana
_start_shot(mana)
for k, v in ipairs(options.always_casts) do
if type(v) == "table" then
v = v.name
end
---@cast v string
is_bad(text_formatter, v)
---@cast v string
--[[local s = "set_current_action"
local _c = _G[s]
_G[s] = function(...)
for _, v2 in ipairs({ ... }) do
print_table(v2)
end
_c(...)
end]]
local _clone_action = clone_action
clone_action = function(...)
local res = { _clone_action(...) }
local dest = ({ ... })[2]
local old_action = dest.action
dest.action = function(...)
local action_res = { old_action({ deck_index = -k })(...) }
return unpack(action_res)
end
clone_action = _clone_action
return unpack(res)
end
_play_permanent_card(v)
--_G[s] = _c
end
_draw_actions_for_shot(true)
--dbg_wand()
local delay = root_shot.state.fire_rate_wait
-- cursed nolla design.
_handle_reload()
if M.reload_time then
delay = math.max(delay, M.reload_time)
M.reload_time = nil
end
delay = math.max(delay, 1)
cur_root.extra = "Delay: " .. delay .. "f, ΔMana: " .. (old_mana - mana)
mana = mana + delay * options.mana_charge / 60
end
end
return M