fix green bug
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -1632,9 +1632,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strafesnet_common"
|
name = "strafesnet_common"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||||
checksum = "c51de04816a98559f315d57b8a13a3bc010e2dc9bb033906a424ec8d56601731"
|
checksum = "1cc4c74ee1ba0c68431290db6f2573f208557a2bf63ec45c667d332de200d9f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
@@ -1661,9 +1661,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strafesnet_roblox_bot_file"
|
name = "strafesnet_roblox_bot_file"
|
||||||
version = "0.9.2"
|
version = "0.9.3"
|
||||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||||
checksum = "f3764f94fb71eba824aeabde808b490ef719331673f3f485c8b176895e4955dd"
|
checksum = "423d931e4f4f97406a86519a22172d1fc0d5b9d8c3b2d4553ae89b641bbd555c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"binrw",
|
"binrw",
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ strip = true
|
|||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
strafesnet_common = { version = "0.8.3", registry = "strafesnet" }
|
strafesnet_common = { version = "0.8.4", registry = "strafesnet" }
|
||||||
strafesnet_graphics = { version = "0.0.2", registry = "strafesnet" }
|
strafesnet_graphics = { version = "0.0.2", registry = "strafesnet" }
|
||||||
strafesnet_roblox_bot_file = { version = "0.9.2", registry = "strafesnet" }
|
strafesnet_roblox_bot_file = { version = "0.9.3", registry = "strafesnet" }
|
||||||
strafesnet_snf = { version = "0.3.2", registry = "strafesnet" }
|
strafesnet_snf = { version = "0.3.2", registry = "strafesnet" }
|
||||||
|
|||||||
@@ -20,19 +20,16 @@ pub struct PlaybackHead{
|
|||||||
timer:Timer<Scaled<SessionTimeInner,TimeInner>>,
|
timer:Timer<Scaled<SessionTimeInner,TimeInner>>,
|
||||||
state:PlaybackState,
|
state:PlaybackState,
|
||||||
}
|
}
|
||||||
const HEAD_NO_CRASH:Head={
|
|
||||||
let mut head=Head::new();
|
|
||||||
// push one output event so that output-1 doesn't underflow
|
|
||||||
head.push(EventType::Output);
|
|
||||||
head
|
|
||||||
};
|
|
||||||
impl PlaybackHead{
|
impl PlaybackHead{
|
||||||
pub fn new(time:SessionTime)->Self{
|
pub fn new(bot:&CompleteBot,time:SessionTime)->Self{
|
||||||
let timer=Timer::unpaused(time,Time::ZERO);
|
let timer=Timer::unpaused(time,Time::ZERO);
|
||||||
|
let head=Head::after_time(bot.timelines(),bot.time(Time::ZERO).into());
|
||||||
|
let mut state=PlaybackState::new();
|
||||||
|
state.process_head(bot.timelines(),&head);
|
||||||
Self{
|
Self{
|
||||||
head:HEAD_NO_CRASH,
|
head,
|
||||||
timer,
|
timer,
|
||||||
state:PlaybackState::new(),
|
state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub const fn state(&self)->&PlaybackState{
|
pub const fn state(&self)->&PlaybackState{
|
||||||
@@ -48,18 +45,11 @@ impl PlaybackHead{
|
|||||||
_=self.timer.set_paused(time,paused);
|
_=self.timer.set_paused(time,paused);
|
||||||
}
|
}
|
||||||
pub fn set_time(&mut self,bot:&CompleteBot,time:SessionTime,new_time:Time){
|
pub fn set_time(&mut self,bot:&CompleteBot,time:SessionTime,new_time:Time){
|
||||||
|
let new_time=new_time.rem_euclid(bot.duration().coerce());
|
||||||
self.timer.set_time(time,new_time);
|
self.timer.set_time(time,new_time);
|
||||||
// reset head
|
// reset head
|
||||||
self.head=Head::after_time(bot.timelines(),bot.time(new_time).into());
|
self.head=Head::after_time(bot.timelines(),bot.time(new_time).into());
|
||||||
|
|
||||||
// nudge indices as a hack to avoid oob index
|
|
||||||
if self.head.get_event_index(EventType::Output)==0{
|
|
||||||
self.head.push(EventType::Output);
|
|
||||||
}
|
|
||||||
if self.head.get_event_index(EventType::Output)==bot.timelines().output_events.len(){
|
|
||||||
self.head.set_event_index(EventType::Output,bot.timelines().output_events.len()-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state=PlaybackState::new();
|
self.state=PlaybackState::new();
|
||||||
self.state.process_head(bot.timelines(),&self.head);
|
self.state.process_head(bot.timelines(),&self.head);
|
||||||
}
|
}
|
||||||
@@ -90,8 +80,9 @@ impl PlaybackHead{
|
|||||||
},
|
},
|
||||||
None=>{
|
None=>{
|
||||||
//reset playback
|
//reset playback
|
||||||
self.head=HEAD_NO_CRASH;
|
self.head=Head::after_time(bot.timelines(),bot.time(Time::ZERO).into());
|
||||||
self.state=PlaybackState::new();
|
self.state=PlaybackState::new();
|
||||||
|
self.state.process_head(bot.timelines(),&self.head);
|
||||||
|
|
||||||
// hack to wind back timer offset without precise session timestamp
|
// hack to wind back timer offset without precise session timestamp
|
||||||
let (mut state,paused)=self.timer.clone().into_state();
|
let (mut state,paused)=self.timer.clone().into_state();
|
||||||
|
|||||||
@@ -28,58 +28,59 @@ fn speed_ratio(speed:i8)->strafesnet_common::integer::Ratio64{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Playback{
|
||||||
|
bot:CompleteBot,
|
||||||
|
playback_head:PlaybackHead,
|
||||||
|
playback_speed:i8,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PlayerWorker<'a>{
|
pub struct PlayerWorker<'a>{
|
||||||
surface:wgpu::Surface<'a>,
|
surface:wgpu::Surface<'a>,
|
||||||
graphics_thread:Graphics,
|
graphics_thread:Graphics,
|
||||||
bot:Option<CompleteBot>,
|
playback:Option<Playback>,
|
||||||
playback_head:PlaybackHead,
|
|
||||||
playback_speed:i8,
|
|
||||||
}
|
}
|
||||||
impl<'a> PlayerWorker<'a>{
|
impl<'a> PlayerWorker<'a>{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
surface:wgpu::Surface<'a>,
|
surface:wgpu::Surface<'a>,
|
||||||
graphics_thread:Graphics,
|
graphics_thread:Graphics,
|
||||||
)->Self{
|
)->Self{
|
||||||
let playback_head=PlaybackHead::new(SessionTime::ZERO);
|
|
||||||
Self{
|
Self{
|
||||||
surface,
|
surface,
|
||||||
graphics_thread,
|
graphics_thread,
|
||||||
bot:None,
|
playback:None,
|
||||||
playback_head,
|
|
||||||
playback_speed:0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn send(&mut self,ins:TimedInstruction<Instruction,SessionTime>){
|
pub fn send(&mut self,ins:TimedInstruction<Instruction,SessionTime>){
|
||||||
match ins.instruction{
|
match ins.instruction{
|
||||||
Instruction::SessionControl(SessionControlInstruction::SetPaused(paused))=>{
|
Instruction::SessionControl(SessionControlInstruction::SetPaused(paused))=>if let Some(playback)=&mut self.playback{
|
||||||
self.playback_head.set_paused(ins.time,paused);
|
playback.playback_head.set_paused(ins.time,paused);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::Restart)=>if let Some(bot)=&self.bot{
|
Instruction::SessionControl(SessionControlInstruction::Restart)=>if let Some(playback)=&mut self.playback{
|
||||||
self.playback_head.set_time(bot,ins.time,PlaybackTime::ZERO);
|
playback.playback_head.set_time(&playback.bot,ins.time,PlaybackTime::ZERO);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::SkipForward)=>if let Some(bot)=&self.bot{
|
Instruction::SessionControl(SessionControlInstruction::SkipForward)=>if let Some(playback)=&mut self.playback{
|
||||||
let head_time=self.playback_head.timer().clone().into_state().0.get_time(ins.time+SessionTime::from_secs(2));
|
let head_time=playback.playback_head.timer().clone().into_state().0.get_time(ins.time+SessionTime::from_secs(2));
|
||||||
self.playback_head.set_time(bot,ins.time,head_time);
|
playback.playback_head.set_time(&playback.bot,ins.time,head_time);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::SkipBack)=>if let Some(bot)=&self.bot{
|
Instruction::SessionControl(SessionControlInstruction::SkipBack)=>if let Some(playback)=&mut self.playback{
|
||||||
let head_time=self.playback_head.timer().clone().into_state().0.get_time(ins.time-SessionTime::from_secs(2));
|
let head_time=playback.playback_head.timer().clone().into_state().0.get_time(ins.time-SessionTime::from_secs(2));
|
||||||
self.playback_head.set_time(bot,ins.time,head_time);
|
playback.playback_head.set_time(&playback.bot,ins.time,head_time);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::DecreaseTimescale)=>{
|
Instruction::SessionControl(SessionControlInstruction::DecreaseTimescale)=>if let Some(playback)=&mut self.playback{
|
||||||
self.playback_speed=self.playback_speed.saturating_sub(1).max(-27);
|
playback.playback_speed=playback.playback_speed.saturating_sub(1).max(-27);
|
||||||
self.playback_head.set_scale(ins.time,speed_ratio(self.playback_speed));
|
playback.playback_head.set_scale(ins.time,speed_ratio(playback.playback_speed));
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::IncreaseTimescale)=>{
|
Instruction::SessionControl(SessionControlInstruction::IncreaseTimescale)=>if let Some(playback)=&mut self.playback{
|
||||||
self.playback_speed=self.playback_speed.saturating_add(1).min(27);
|
playback.playback_speed=playback.playback_speed.saturating_add(1).min(27);
|
||||||
self.playback_head.set_scale(ins.time,speed_ratio(self.playback_speed));
|
playback.playback_head.set_scale(ins.time,speed_ratio(playback.playback_speed));
|
||||||
},
|
},
|
||||||
Instruction::Render=>if let Some(bot)=&self.bot{
|
Instruction::Render=>if let Some(playback)=&mut self.playback{
|
||||||
self.playback_head.advance_time(bot,ins.time);
|
playback.playback_head.advance_time(&playback.bot,ins.time);
|
||||||
let (pos,angles)=self.playback_head.get_position_angles(bot,ins.time);
|
let (pos,angles)=playback.playback_head.get_position_angles(&playback.bot,ins.time);
|
||||||
self.graphics_thread.render(&self.surface,pos,angles);
|
self.graphics_thread.render(&self.surface,pos,angles);
|
||||||
},
|
},
|
||||||
Instruction::Resize(physical_size)=>{
|
Instruction::Resize(physical_size)=>if let Some(playback)=&self.playback{
|
||||||
let fov_y=self.playback_head.state().get_fov_y();
|
let fov_y=playback.playback_head.state().get_fov_y();
|
||||||
let fov_x=fov_y*physical_size.width as f64/physical_size.height as f64;
|
let fov_x=fov_y*physical_size.width as f64/physical_size.height as f64;
|
||||||
self.graphics_thread.resize(&self.surface,glam::uvec2(physical_size.width,physical_size.height),glam::vec2(fov_x as f32,fov_y as f32));
|
self.graphics_thread.resize(&self.surface,glam::uvec2(physical_size.width,physical_size.height),glam::vec2(fov_x as f32,fov_y as f32));
|
||||||
},
|
},
|
||||||
@@ -87,7 +88,13 @@ impl<'a> PlayerWorker<'a>{
|
|||||||
self.graphics_thread.change_map(&complete_map);
|
self.graphics_thread.change_map(&complete_map);
|
||||||
},
|
},
|
||||||
Instruction::LoadReplay(bot)=>{
|
Instruction::LoadReplay(bot)=>{
|
||||||
self.bot=Some(CompleteBot::new(bot));
|
let bot=CompleteBot::new(bot);
|
||||||
|
let playback_head=PlaybackHead::new(&bot,SessionTime::ZERO);
|
||||||
|
self.playback=Some(Playback{
|
||||||
|
bot,
|
||||||
|
playback_head,
|
||||||
|
playback_speed:0,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ pub struct PlaybackHead{
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl PlaybackHead{
|
impl PlaybackHead{
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(time:f64)->Result<Self,JsValue>{
|
pub fn new(bot:&CompleteBot,time:f64)->Result<Self,JsValue>{
|
||||||
let time=time::from_float(time).unwrap();
|
let time=time::from_float(time).unwrap();
|
||||||
Ok(Self{
|
Ok(Self{
|
||||||
head:head::PlaybackHead::new(time),
|
head:head::PlaybackHead::new(&bot.bot,time),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ const canvas = document.getElementById("viewport");
|
|||||||
const graphics = await setup_graphics(canvas);
|
const graphics = await setup_graphics(canvas);
|
||||||
const bot = new CompleteBot(new Uint8Array(await b.arrayBuffer()));
|
const bot = new CompleteBot(new Uint8Array(await b.arrayBuffer()));
|
||||||
const map = new CompleteMap(new Uint8Array(await m.arrayBuffer()));
|
const map = new CompleteMap(new Uint8Array(await m.arrayBuffer()));
|
||||||
const playback = new PlaybackHead(0);
|
const playback = new PlaybackHead(bot, 0);
|
||||||
|
|
||||||
// Initialize playback (fill playback state from bot)
|
|
||||||
playback.advance_time(bot, 0);
|
|
||||||
|
|
||||||
graphics.change_map(map);
|
graphics.change_map(map);
|
||||||
|
|
||||||
@@ -66,13 +63,15 @@ document.getElementById("control_pause").addEventListener("click", (e) => {
|
|||||||
});
|
});
|
||||||
document.getElementById("control_forward").addEventListener("click", (e) => {
|
document.getElementById("control_forward").addEventListener("click", (e) => {
|
||||||
const time_now = elapsed();
|
const time_now = elapsed();
|
||||||
const playback_time = playback.get_head_time(time_now) + playback.get_scale() * SEEK_DURATION;
|
const playback_time = playback.get_head_time(time_now);
|
||||||
playback.set_head_time(bot, time_now, playback_time);
|
const time_offset = playback.get_scale() * SEEK_DURATION;
|
||||||
|
playback.set_head_time(bot, time_now, playback_time + time_offset);
|
||||||
});
|
});
|
||||||
document.getElementById("control_backward").addEventListener("click", (e) => {
|
document.getElementById("control_backward").addEventListener("click", (e) => {
|
||||||
const time_now = elapsed();
|
const time_now = elapsed();
|
||||||
const playback_time = playback.get_head_time(time_now) + playback.get_scale() * SEEK_DURATION;
|
const playback_time = playback.get_head_time(time_now);
|
||||||
playback.set_head_time(bot, time_now, playback_time);
|
const time_offset = playback.get_scale() * SEEK_DURATION;
|
||||||
|
playback.set_head_time(bot, time_now, playback_time - time_offset);
|
||||||
});
|
});
|
||||||
document.getElementById("control_slower").addEventListener("click", (e) => {
|
document.getElementById("control_slower").addEventListener("click", (e) => {
|
||||||
set_scale((scale * 4) / 5);
|
set_scale((scale * 4) / 5);
|
||||||
|
|||||||
Reference in New Issue
Block a user