mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-25 10:44:41 +01:00
Plugins: trick events (trick_started, trick_landed, line_broken) and reskate.score.current
- With events.tricks a plugin hears the local skater's tricks: trick_started (where), trick_landed (points, multiplier, where it started and landed, how long it took) and line_broken (a slam or a wipeout); reskate.score.current() is the score HUD's line, multiplier and whether a trick is going on. Without the permission the events cannot be registered. - The score HUD is read into the trick watch (Extension/Skater/score_hud.h, trick_watch.h) on the client tick only while a running plugin has events.tricks; a new level starts a new line. plugins::start takes the image base for it. - reskate-test has a tricks module (skipped until a trick lands) and ptest trick, which waits 30 s for one and prints what its events said; reskate-hostile has trick-loop. Not yet checked against real tricks in game.
This commit is contained in:
1 parent
373c141381
commit
f37abef426
13 files changed
+333
-15
No files matched your search
@@ -73,6 +73,11 @@ attack("raycast-flood", "keeps running: refused past 64 raycasts a tick", functi
|
||||
for i = 1, 100000 do reskate.world.raycast(vector.create(0, 100, 0), vector.create(0, -100, 0)) end
|
||||
end)
|
||||
|
||||
attack("trick-loop", "stopped at the next trick landed", function()
|
||||
reskate.on("trick_landed", function() while true do end end)
|
||||
reskate.console.print("hostile: now land a trick")
|
||||
end)
|
||||
|
||||
-- Each returns true when that way out worked.
|
||||
local escapes = {
|
||||
{"io", function() return io ~= nil end},
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
"api": 1,
|
||||
"entry": "plugin/main.lua",
|
||||
"side": "client",
|
||||
"permissions": ["console", "skater.read", "skater.teleport", "world.raycast"]
|
||||
"permissions": ["console", "skater.read", "skater.teleport", "world.raycast", "events.tricks"]
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
local h = require("harness")
|
||||
local t = h.module("tricks")
|
||||
|
||||
-- What the trick events said so far, and `ptest trick` waiting for one.
|
||||
local seen = {started = 0, landed = 0, broken = 0}
|
||||
local last_landed = nil
|
||||
local waiting_until = nil
|
||||
|
||||
local function shown(v)
|
||||
return string.format("(%.1f, %.1f, %.1f)", v.x, v.y, v.z)
|
||||
end
|
||||
|
||||
reskate.on("trick_started", function(e)
|
||||
seen.started += 1
|
||||
if waiting_until then reskate.console.print("ptest trick: started at " .. shown(e.at)) end
|
||||
end)
|
||||
reskate.on("trick_landed", function(e)
|
||||
seen.landed += 1
|
||||
last_landed = e
|
||||
if waiting_until then
|
||||
waiting_until = nil
|
||||
reskate.console.print(string.format("ptest trick: landed %.0f points at x%.1f in %.0f ms, from %s to %s",
|
||||
e.points, e.multiplier, e.ms, shown(e.started_at), shown(e.landed_at)))
|
||||
end
|
||||
end)
|
||||
reskate.on("line_broken", function(e)
|
||||
seen.broken += 1
|
||||
if waiting_until then reskate.console.print("ptest trick: the line broke: " .. e.reason) end
|
||||
end)
|
||||
reskate.on("tick", function()
|
||||
if waiting_until and reskate.time.now() > waiting_until then
|
||||
waiting_until = nil
|
||||
reskate.console.print("ptest trick: no trick landed in 30 s")
|
||||
end
|
||||
end)
|
||||
|
||||
-- By hand: ptest trick, then land a trick within 30 s.
|
||||
reskate.console.command("ptest trick", "Waits 30 s for a trick and prints what the trick events say", function()
|
||||
waiting_until = reskate.time.now() + 30000
|
||||
reskate.console.print("ptest trick: land a trick")
|
||||
end)
|
||||
|
||||
t.check("a trick event needs a function", function()
|
||||
h.refused(reskate.on, "trick_landed", 5)
|
||||
end)
|
||||
t.check("score.current is nil without a score HUD, else the line", function()
|
||||
local s = reskate.score.current()
|
||||
if s == nil then return h.skip("no score HUD (in the menu, or on foot)") end
|
||||
assert(type(s.line) == "number" and s.line >= 0, "line " .. tostring(s.line))
|
||||
assert(type(s.multiplier) == "number" and s.multiplier >= 0, "multiplier " .. tostring(s.multiplier))
|
||||
assert(type(s.in_trick) == "boolean")
|
||||
end)
|
||||
t.check("a landed trick says its points, multiplier, places and time", function()
|
||||
if last_landed == nil then return h.skip("no trick landed since it loaded") end
|
||||
local e = last_landed
|
||||
assert(e.points >= 0 and e.multiplier >= 0 and e.ms >= 0, "points, multiplier, ms")
|
||||
assert(typeof(e.started_at) == "vector" and typeof(e.landed_at) == "vector", "places are vectors")
|
||||
assert(vector.magnitude(e.landed_at - e.started_at) < 200, "it went more than 200 m in one trick")
|
||||
end)
|
||||
t.check("tricks land after they start", function()
|
||||
if seen.landed == 0 then return h.skip("no trick landed since it loaded") end
|
||||
assert(seen.started >= seen.landed, seen.started .. " started, " .. seen.landed .. " landed")
|
||||
end)
|
||||
@@ -2,7 +2,7 @@
|
||||
-- `ptest <module>` for one (`ptest list` names them). Each API ReSkate adds gets a module here.
|
||||
local harness = require("harness")
|
||||
|
||||
for _, name in {"base", "time", "level", "package", "json", "require", "console", "storage", "sandbox", "skater"} do
|
||||
for _, name in {"base", "time", "level", "package", "json", "require", "console", "storage", "sandbox", "skater", "tricks"} do
|
||||
require("checks/" .. name)
|
||||
end
|
||||
|
||||
|
||||
Reference in new issue
Block a user