display run duration
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
|
use strafesnet_roblox_bot_file::v0;
|
||||||
use strafesnet_common::physics::{Time as PhysicsTime};
|
use strafesnet_common::physics::{Time as PhysicsTime};
|
||||||
|
|
||||||
/// A loaded bot file.
|
/// A loaded bot file.
|
||||||
pub struct CompleteBot{
|
pub struct CompleteBot{
|
||||||
//Instructions
|
//Instructions
|
||||||
timelines:strafesnet_roblox_bot_file::v0::Block,
|
timelines:v0::Block,
|
||||||
time_base:PhysicsTime,
|
time_base:PhysicsTime,
|
||||||
duration:PhysicsTime,
|
duration:PhysicsTime,
|
||||||
}
|
}
|
||||||
@@ -11,8 +12,8 @@ impl CompleteBot{
|
|||||||
pub(crate) const CAMERA_OFFSET:glam::Vec3=glam::vec3(0.0,2.0,0.0);
|
pub(crate) const CAMERA_OFFSET:glam::Vec3=glam::vec3(0.0,2.0,0.0);
|
||||||
pub fn new(
|
pub fn new(
|
||||||
data:&[u8],
|
data:&[u8],
|
||||||
)->Result<Self,strafesnet_roblox_bot_file::v0::Error>{
|
)->Result<Self,v0::Error>{
|
||||||
let timelines=strafesnet_roblox_bot_file::v0::read_all_to_block(std::io::Cursor::new(data))?;
|
let timelines=v0::read_all_to_block(std::io::Cursor::new(data))?;
|
||||||
let first=timelines.output_events.first().unwrap();
|
let first=timelines.output_events.first().unwrap();
|
||||||
let last=timelines.output_events.last().unwrap();
|
let last=timelines.output_events.last().unwrap();
|
||||||
Ok(Self{
|
Ok(Self{
|
||||||
@@ -27,7 +28,21 @@ impl CompleteBot{
|
|||||||
pub const fn duration(&self)->PhysicsTime{
|
pub const fn duration(&self)->PhysicsTime{
|
||||||
self.duration
|
self.duration
|
||||||
}
|
}
|
||||||
pub const fn timelines(&self)->&strafesnet_roblox_bot_file::v0::Block{
|
pub const fn timelines(&self)->&v0::Block{
|
||||||
&self.timelines
|
&self.timelines
|
||||||
}
|
}
|
||||||
|
pub fn run_duration(&self,mode_id:v0::ModeID)->Option<PhysicsTime>{
|
||||||
|
let mut it=self.timelines.run_events.iter().rev();
|
||||||
|
let end=it.find_map(|event|match &event.event{
|
||||||
|
v0::RunEvent::Finish(run_start_event) if run_start_event.mode==mode_id=>Some(event.time),
|
||||||
|
_=>None,
|
||||||
|
})?;
|
||||||
|
let start=it.find_map(|event|match &event.event{
|
||||||
|
v0::RunEvent::Start(run_start_event) if run_start_event.mode==mode_id=>Some(event.time),
|
||||||
|
_=>None,
|
||||||
|
})?;
|
||||||
|
let start=crate::time::from_float(start).unwrap();
|
||||||
|
let end=crate::time::from_float(end).unwrap();
|
||||||
|
Some(end-start)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use wasm_bindgen::prelude::wasm_bindgen;
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
use strafesnet_roblox_bot_file::v0;
|
||||||
use strafesnet_roblox_bot_player::{bot,map,head,time,graphics};
|
use strafesnet_roblox_bot_player::{bot,map,head,time,graphics};
|
||||||
use strafesnet_graphics::setup;
|
use strafesnet_graphics::setup;
|
||||||
use strafesnet_common::physics::Time as PhysicsTime;
|
use strafesnet_common::physics::Time as PhysicsTime;
|
||||||
@@ -72,6 +73,11 @@ impl CompleteBot{
|
|||||||
pub fn duration(&self)->f64{
|
pub fn duration(&self)->f64{
|
||||||
self.bot.duration().get() as f64/PhysicsTime::ONE_SECOND.get() as f64
|
self.bot.duration().get() as f64/PhysicsTime::ONE_SECOND.get() as f64
|
||||||
}
|
}
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn run_duration(&self,mode_id:u32)->Option<f64>{
|
||||||
|
let mode=v0::ModeID(mode_id);
|
||||||
|
Some(self.bot.run_duration(mode)?.get() as f64/PhysicsTime::ONE_SECOND.get() as f64)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@@ -110,18 +116,18 @@ impl PlaybackHead{
|
|||||||
pub fn get_run_time(&self,bot:&CompleteBot,time:f64,mode_id:u32)->Option<f64>{
|
pub fn get_run_time(&self,bot:&CompleteBot,time:f64,mode_id:u32)->Option<f64>{
|
||||||
let time=time::from_float(time).unwrap();
|
let time=time::from_float(time).unwrap();
|
||||||
let time=self.head.time(&bot.bot,time);
|
let time=self.head.time(&bot.bot,time);
|
||||||
let mode=strafesnet_roblox_bot_file::v0::ModeID(mode_id);
|
let mode=v0::ModeID(mode_id);
|
||||||
let run_time=self.head.state().get_run(mode)?.time(time);
|
let run_time=self.head.state().get_run(mode)?.time(time);
|
||||||
Some(run_time.get() as f64/strafesnet_common::run::Time::ONE_SECOND.get() as f64)
|
Some(run_time.get() as f64/strafesnet_common::run::Time::ONE_SECOND.get() as f64)
|
||||||
}
|
}
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn is_run_in_progress(&self,mode_id:u32)->Option<bool>{
|
pub fn is_run_in_progress(&self,mode_id:u32)->Option<bool>{
|
||||||
let mode=strafesnet_roblox_bot_file::v0::ModeID(mode_id);
|
let mode=v0::ModeID(mode_id);
|
||||||
Some(self.head.state().get_run(mode)?.is_in_progress())
|
Some(self.head.state().get_run(mode)?.is_in_progress())
|
||||||
}
|
}
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn is_run_finished(&self,mode_id:u32)->Option<bool>{
|
pub fn is_run_finished(&self,mode_id:u32)->Option<bool>{
|
||||||
let mode=strafesnet_roblox_bot_file::v0::ModeID(mode_id);
|
let mode=v0::ModeID(mode_id);
|
||||||
Some(self.head.state().get_run(mode)?.is_finished())
|
Some(self.head.state().get_run(mode)?.is_finished())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,26 +23,32 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.hud {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column; /* stack vertically */
|
||||||
|
gap: 4px; /* space between timers */
|
||||||
|
}
|
||||||
|
|
||||||
|
.timer {
|
||||||
|
background: #000;
|
||||||
|
color: #fff;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script defer src="player.js" type="module"></script>
|
<script defer src="player.js" type="module"></script>
|
||||||
<script defer type="module" src="iframe-helper.js"></script>
|
<script defer type="module" src="iframe-helper.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="viewport"> </canvas>
|
<canvas id="viewport"> </canvas>
|
||||||
<div
|
<div class="hud">
|
||||||
id="timer"
|
<div id="duration" class="timer">00:00:00</div>
|
||||||
style="
|
<div id="timer" class="timer">00:00:00</div>
|
||||||
position: fixed;
|
|
||||||
bottom: 10px;
|
|
||||||
left: 10px;
|
|
||||||
background: #000;
|
|
||||||
color: #fff;
|
|
||||||
padding: 4px 8px;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
00:00:00
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ graphics.change_map(map);
|
|||||||
|
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
const timer = document.getElementById("timer");
|
const timer = document.getElementById("timer");
|
||||||
|
const duration = document.getElementById("duration");
|
||||||
const MODE_MAIN = 0;
|
const MODE_MAIN = 0;
|
||||||
|
|
||||||
function timer_text(t) {
|
function timer_text(t) {
|
||||||
@@ -31,6 +32,8 @@ function timer_text(t) {
|
|||||||
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${String(ms).padStart(3, "0")}`;
|
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${String(ms).padStart(3, "0")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duration.textContent = timer_text(bot.run_duration(MODE_MAIN));
|
||||||
|
|
||||||
function animate(now) {
|
function animate(now) {
|
||||||
const elapsedMs = now - startTime;
|
const elapsedMs = now - startTime;
|
||||||
const elapsedSec = elapsedMs / 1000; // wasm expects seconds
|
const elapsedSec = elapsedMs / 1000; // wasm expects seconds
|
||||||
|
|||||||
Reference in New Issue
Block a user