mirror of
https://codeberg.org/demostf/tf-demos-viewer.git
synced 2026-06-03 10:04:12 +02:00
ubered status
This commit is contained in:
parent
72027c010c
commit
32cb59264f
5 changed files with 45 additions and 56 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -541,12 +541,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tf-demo-parser"
|
name = "tf-demo-parser"
|
||||||
version = "0.5.1"
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ecbf06f08d668b350dce132a30888848306aebbf498fa6a5212ff65ba0a85dd2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitbuffer",
|
"bitbuffer",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"fnv",
|
"fnv",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"log",
|
||||||
"main_error",
|
"main_error",
|
||||||
"num-traits 0.2.19",
|
"num-traits 0.2.19",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
|
|
@ -561,7 +564,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tf-demos-viewer"
|
name = "tf-demos-viewer"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tf-demos-viewer"
|
name = "tf-demos-viewer"
|
||||||
description = "JS bindings for demo parser"
|
description = "JS bindings for demo parser"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
categories = ["wasm"]
|
categories = ["wasm"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
@ -26,7 +26,7 @@ wasm-bindgen = "0.2.96"
|
||||||
wee_alloc = { version = "0.4.2", optional = true }
|
wee_alloc = { version = "0.4.2", optional = true }
|
||||||
web-sys = { version = "0.3.22", features = ["console"] }
|
web-sys = { version = "0.3.22", features = ["console"] }
|
||||||
js-sys = "0.3.22"
|
js-sys = "0.3.22"
|
||||||
tf-demo-parser = { version = "0.5.1", path = "../tf-demo-parser" }
|
tf-demo-parser = "0.6.2"
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
serde_json = "1.0.133"
|
serde_json = "1.0.133"
|
||||||
|
|
||||||
|
|
|
||||||
8
flake.lock
generated
8
flake.lock
generated
|
|
@ -33,16 +33,16 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1732923073,
|
"lastModified": 1750880979,
|
||||||
"narHash": "sha256-OxrZizAeWllfavAj73qRlZirc7ig4gZdm2U+hgdAHk0=",
|
"narHash": "sha256-pzGtNlk34NLBylIgARHjUNjOhfwa0RmqdWZ2ZOFj0OU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d20209c9cb07495799ae423a305e31ef40d25edb",
|
"rev": "b639654086cba4ddd4ecb889a3c44635c89aa83f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"id": "nixpkgs",
|
||||||
"ref": "release-24.11",
|
"ref": "release-25.05",
|
||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
inputs = {
|
inputs = {
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils.url = "github:numtide/flake-utils";
|
||||||
naersk.url = "github:nix-community/naersk";
|
naersk.url = "github:nix-community/naersk";
|
||||||
nixpkgs.url = "nixpkgs/release-24.11";
|
nixpkgs.url = "nixpkgs/release-25.05";
|
||||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
80
src/state.rs
80
src/state.rs
|
|
@ -1,5 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tf_demo_parser::demo::data::game_state::{Projectile, ProjectileType};
|
use tf_demo_parser::demo::data::game_state::{PlayerCondition, Projectile, ProjectileType};
|
||||||
use tf_demo_parser::demo::data::DemoTick;
|
use tf_demo_parser::demo::data::DemoTick;
|
||||||
use tf_demo_parser::demo::gamevent::GameEvent;
|
use tf_demo_parser::demo::gamevent::GameEvent;
|
||||||
use tf_demo_parser::demo::header::Header;
|
use tf_demo_parser::demo::header::Header;
|
||||||
|
|
@ -74,6 +74,7 @@ impl ParsedDemo {
|
||||||
team: player.team,
|
team: player.team,
|
||||||
class: player.class,
|
class: player.class,
|
||||||
charge: player.charge,
|
charge: player.charge,
|
||||||
|
ubered: player.has_condition(PlayerCondition::Invulnerable),
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.players.get(index).is_none() {
|
if self.players.get(index).is_none() {
|
||||||
|
|
@ -164,6 +165,7 @@ pub struct PlayerState {
|
||||||
team: Team,
|
team: Team,
|
||||||
class: Class,
|
class: Class,
|
||||||
charge: u8,
|
charge: u8,
|
||||||
|
ubered: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlayerState {
|
impl PlayerState {
|
||||||
|
|
@ -182,9 +184,12 @@ impl PlayerState {
|
||||||
let y = pack_f32(self.position.y, world.boundary_min.y, world.boundary_max.y).to_le_bytes();
|
let y = pack_f32(self.position.y, world.boundary_min.y, world.boundary_max.y).to_le_bytes();
|
||||||
// 2 bits for team
|
// 2 bits for team
|
||||||
// 4 bits for class
|
// 4 bits for class
|
||||||
// 10 bits for health
|
// 9 bits for health
|
||||||
let team_class_health =
|
// 1 bit for ubered
|
||||||
((self.team as u16) << 14) + ((self.class as u16) << 10) + self.health;
|
let team_class_health = ((self.team as u16) << 14)
|
||||||
|
+ ((self.class as u16) << 10)
|
||||||
|
+ (self.health << 1)
|
||||||
|
+ (self.ubered as u16);
|
||||||
let combined_bytes = team_class_health.to_le_bytes();
|
let combined_bytes = team_class_health.to_le_bytes();
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
@ -217,7 +222,8 @@ impl PlayerState {
|
||||||
world.boundary_max.y,
|
world.boundary_max.y,
|
||||||
);
|
);
|
||||||
let team_class_health = u16::from_le_bytes([bytes[4], bytes[5]]);
|
let team_class_health = u16::from_le_bytes([bytes[4], bytes[5]]);
|
||||||
let health = team_class_health & 1023;
|
let ubered = (team_class_health & 1) == 1;
|
||||||
|
let health = (team_class_health >> 1) & 511;
|
||||||
let angle = Angle(bytes[6]);
|
let angle = Angle(bytes[6]);
|
||||||
let team = Team::new(team_class_health >> 14);
|
let team = Team::new(team_class_health >> 14);
|
||||||
let class = Class::new((team_class_health >> 10) & 15);
|
let class = Class::new((team_class_health >> 10) & 15);
|
||||||
|
|
@ -230,26 +236,31 @@ impl PlayerState {
|
||||||
team,
|
team,
|
||||||
class,
|
class,
|
||||||
charge,
|
charge,
|
||||||
|
ubered,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn get_world() -> World {
|
||||||
|
use tf_demo_parser::demo::vector::Vector;
|
||||||
|
let mut world = World::default();
|
||||||
|
world.boundary_max = Vector {
|
||||||
|
x: 10000.0,
|
||||||
|
y: 10000.0,
|
||||||
|
z: 100.0,
|
||||||
|
};
|
||||||
|
world.boundary_min = Vector {
|
||||||
|
x: -10000.0,
|
||||||
|
y: -10000.0,
|
||||||
|
z: -100.0,
|
||||||
|
};
|
||||||
|
world
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_player_packing() {
|
fn test_player_packing() {
|
||||||
use tf_demo_parser::demo::vector::Vector;
|
let world = get_world();
|
||||||
|
|
||||||
let world = World {
|
|
||||||
boundary_max: Vector {
|
|
||||||
x: 10000.0,
|
|
||||||
y: 10000.0,
|
|
||||||
z: 100.0,
|
|
||||||
},
|
|
||||||
boundary_min: Vector {
|
|
||||||
x: -10000.0,
|
|
||||||
y: -10000.0,
|
|
||||||
z: -100.0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = PlayerState {
|
let input = PlayerState {
|
||||||
position: VectorXY {
|
position: VectorXY {
|
||||||
|
|
@ -261,6 +272,7 @@ fn test_player_packing() {
|
||||||
team: Team::Blue,
|
team: Team::Blue,
|
||||||
class: Class::Demoman,
|
class: Class::Demoman,
|
||||||
charge: 7,
|
charge: 7,
|
||||||
|
ubered: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = input.pack(&world);
|
let bytes = input.pack(&world);
|
||||||
|
|
@ -436,20 +448,7 @@ impl BuildingState {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_building_packing() {
|
fn test_building_packing() {
|
||||||
use tf_demo_parser::demo::vector::Vector;
|
let world = get_world();
|
||||||
|
|
||||||
let world = World {
|
|
||||||
boundary_max: Vector {
|
|
||||||
x: 10000.0,
|
|
||||||
y: 10000.0,
|
|
||||||
z: 100.0,
|
|
||||||
},
|
|
||||||
boundary_min: Vector {
|
|
||||||
x: -10000.0,
|
|
||||||
y: -10000.0,
|
|
||||||
z: -100.0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = BuildingState {
|
let input = BuildingState {
|
||||||
position: VectorXY {
|
position: VectorXY {
|
||||||
|
|
@ -545,20 +544,7 @@ impl ProjectileState {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_projectile_packing() {
|
fn test_projectile_packing() {
|
||||||
use tf_demo_parser::demo::vector::Vector;
|
let world = get_world();
|
||||||
|
|
||||||
let world = World {
|
|
||||||
boundary_max: Vector {
|
|
||||||
x: 10000.0,
|
|
||||||
y: 10000.0,
|
|
||||||
z: 100.0,
|
|
||||||
},
|
|
||||||
boundary_min: Vector {
|
|
||||||
x: -10000.0,
|
|
||||||
y: -10000.0,
|
|
||||||
z: -100.0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = ProjectileState {
|
let input = ProjectileState {
|
||||||
position: VectorXY {
|
position: VectorXY {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue