mirror of
https://github.com/notwa/mm
synced 2024-11-04 22:29:02 -08:00
200 lines
4.6 KiB
Lua
Executable file
200 lines
4.6 KiB
Lua
Executable file
-- movement speed testing
|
|
-- for Majora's Mask:
|
|
-- go to the fairy's fountain in clock town as human link and run this script.
|
|
-- for Ocarina of Time:
|
|
-- go to the Temple of Time as a child and run this script.
|
|
|
|
require "addrs"
|
|
|
|
local length = 70 -- in frames
|
|
local print_each = true
|
|
|
|
local tests = {
|
|
optimal_roll = {
|
|
[ 1]={ Y=127},
|
|
[ 2]={Z=true, Y=127, A=true},
|
|
[17]={Z=true, Y=127},
|
|
[18]={Z=true, Y=127, A=true},
|
|
[33]={goto=17},
|
|
},
|
|
|
|
mash_roll = {
|
|
[ 1]={ Y=127},
|
|
[ 2]={Z=true, Y=127, A=true},
|
|
[13]={Z=true, Y=127},
|
|
[14]={Z=true, Y=127, A=true},
|
|
[25]={goto=13},
|
|
},
|
|
|
|
sidehop = {
|
|
[ 1]={ X=127},
|
|
[ 2]={Z=true},
|
|
[ 8]={Z=true, X=-127, A=true},
|
|
[ 9]={Z=true, X=-127},
|
|
[15]={goto=8},
|
|
},
|
|
|
|
quick_turnaround = {
|
|
[1]={Z=true},
|
|
[2]={},
|
|
[5]={ Y=-127},
|
|
[6]={Z=true, Y=-127},
|
|
},
|
|
|
|
backwalk = {
|
|
[1]={ Y=-127},
|
|
[2]={Z=true},
|
|
[8]={Z=true, Y=-127},
|
|
},
|
|
|
|
walk = {
|
|
[1]={Y=127},
|
|
},
|
|
|
|
inverse_backwalk = {
|
|
[1]={Z=true, Y=127},
|
|
[4]={},
|
|
[7]={ Y=-127},
|
|
[8]={Z=true, Y=127},
|
|
},
|
|
}
|
|
|
|
local link = addrs.link_actor
|
|
|
|
local pos = mm and {2400, 20, 375} or {-200, -40, 2330}
|
|
local angle = 180
|
|
|
|
local fn = 'data/lua movement test.State'
|
|
|
|
function pythag(x, y)
|
|
return math.sqrt(x*x + y*y)
|
|
end
|
|
|
|
function reset_stick()
|
|
joypad.setanalog({["X Axis"]=false, ["Y Axis"]=false}, 1)
|
|
end
|
|
|
|
function find_displacement()
|
|
local x = link.x()
|
|
local y = link.z() -- FIXME
|
|
return pythag(pos[1] - x, pos[2] - y)
|
|
end
|
|
|
|
function setup()
|
|
client.unpause()
|
|
for _=1, 2 do
|
|
reset_stick()
|
|
local angle = (angle/360*65536) % 65536
|
|
--link.angle_old(angle_old)
|
|
link.angle(angle)
|
|
link.x(pos[1])
|
|
link.y(pos[2])
|
|
link.z(pos[3])
|
|
link.x_copy(pos[1])
|
|
link.y_copy(pos[2])
|
|
link.z_copy(pos[3])
|
|
for i=1, 3*21 do
|
|
emu.frameadvance()
|
|
joypad.set({A=i % 4 > 0, Z=i > 9 and i <= 12}, 1)
|
|
end
|
|
end
|
|
savestate.save(fn)
|
|
end
|
|
|
|
function reload()
|
|
savestate.load(fn)
|
|
end
|
|
|
|
function finish()
|
|
reset_stick()
|
|
client.pause()
|
|
end
|
|
|
|
function preprocess(inputs)
|
|
for f, j in pairs(inputs) do
|
|
if type(f) == 'number' then
|
|
j['Start'] = j['S']
|
|
j['C Down'] = j['CD']
|
|
j['C Left'] = j['CL']
|
|
j['C Right'] = j['CR']
|
|
j['C Up'] = j['CU']
|
|
j['X Axis'] = j['X']
|
|
j['Y Axis'] = j['Y']
|
|
end
|
|
end
|
|
end
|
|
|
|
function test_inputs(name, inputs, length)
|
|
preprocess(inputs)
|
|
reload()
|
|
local to = length or inputs.length
|
|
local frame = 0
|
|
local latest, action
|
|
for _=1, to do
|
|
frame = frame + 1
|
|
for _=1, 10 do -- limit number of goto's to follow
|
|
latest = 0
|
|
action = nil
|
|
for f, j in pairs(inputs) do
|
|
if type(f) == 'number' and frame >= f and f > latest then
|
|
latest = f
|
|
action = j
|
|
end
|
|
end
|
|
if action == nil or type(action.goto) ~= 'number' then
|
|
break
|
|
else
|
|
frame = action.goto
|
|
end
|
|
end
|
|
if action ~= nil then
|
|
for _=1, 3 do
|
|
joypad.setanalog(action, 1)
|
|
joypad.set(action, 1)
|
|
emu.frameadvance()
|
|
end
|
|
end
|
|
reset_stick()
|
|
end
|
|
return x
|
|
end
|
|
|
|
function run_tests(length)
|
|
setup()
|
|
|
|
local fmt = '%20s: %10.5f'
|
|
local spd_fmt = '%20.5f units/frame'
|
|
print('# testing')
|
|
|
|
if tests['testme'] ~= nil then
|
|
local key = 'testme'
|
|
local x = test_inputs(key, tests[key], length)
|
|
local distance = find_displacement()
|
|
print(fmt:format(key, distance))
|
|
print(spd_fmt:format(distance/length))
|
|
else
|
|
local furthest = nil
|
|
local distance = 0
|
|
for k, v in pairs(tests) do
|
|
local x = test_inputs(k, v, length)
|
|
local new_distance = find_displacement()
|
|
if print_each then
|
|
print(fmt:format(k, new_distance))
|
|
end
|
|
if new_distance > distance then
|
|
furthest = k
|
|
distance = new_distance
|
|
end
|
|
end
|
|
if furthest ~= nil then
|
|
print()
|
|
print(('## and the winner for %i frames is...'):format(length))
|
|
print(fmt:format(furthest, distance))
|
|
print(spd_fmt:format(distance/length))
|
|
end
|
|
end
|
|
print()
|
|
finish()
|
|
end
|
|
|
|
run_tests(length)
|