ubered status

This commit is contained in:
Robin Appelman 2025-06-26 00:42:43 +02:00
commit 32cb59264f
5 changed files with 45 additions and 56 deletions

7
Cargo.lock generated
View file

@ -541,12 +541,15 @@ dependencies = [
[[package]]
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 = [
"bitbuffer",
"enumflags2",
"fnv",
"itertools",
"log",
"main_error",
"num-traits 0.2.19",
"num_enum",
@ -561,7 +564,7 @@ dependencies = [
[[package]]
name = "tf-demos-viewer"
version = "0.2.1"
version = "0.2.2"
dependencies = [
"js-sys",
"serde",

View file

@ -1,7 +1,7 @@
[package]
name = "tf-demos-viewer"
description = "JS bindings for demo parser"
version = "0.2.1"
version = "0.2.2"
authors = ["Robin Appelman <robin@icewind.nl>"]
categories = ["wasm"]
edition = "2021"
@ -26,7 +26,7 @@ wasm-bindgen = "0.2.96"
wee_alloc = { version = "0.4.2", optional = true }
web-sys = { version = "0.3.22", features = ["console"] }
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_json = "1.0.133"

8
flake.lock generated
View file

@ -33,16 +33,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1732923073,
"narHash": "sha256-OxrZizAeWllfavAj73qRlZirc7ig4gZdm2U+hgdAHk0=",
"lastModified": 1750880979,
"narHash": "sha256-pzGtNlk34NLBylIgARHjUNjOhfwa0RmqdWZ2ZOFj0OU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d20209c9cb07495799ae423a305e31ef40d25edb",
"rev": "b639654086cba4ddd4ecb889a3c44635c89aa83f",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "release-24.11",
"ref": "release-25.05",
"type": "indirect"
}
},

View file

@ -2,7 +2,7 @@
inputs = {
utils.url = "github:numtide/flake-utils";
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";
};

View file

@ -1,5 +1,5 @@
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::gamevent::GameEvent;
use tf_demo_parser::demo::header::Header;
@ -74,6 +74,7 @@ impl ParsedDemo {
team: player.team,
class: player.class,
charge: player.charge,
ubered: player.has_condition(PlayerCondition::Invulnerable),
};
if self.players.get(index).is_none() {
@ -164,6 +165,7 @@ pub struct PlayerState {
team: Team,
class: Class,
charge: u8,
ubered: bool,
}
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();
// 2 bits for team
// 4 bits for class
// 10 bits for health
let team_class_health =
((self.team as u16) << 14) + ((self.class as u16) << 10) + self.health;
// 9 bits for health
// 1 bit for ubered
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();
[
@ -217,7 +222,8 @@ impl PlayerState {
world.boundary_max.y,
);
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 team = Team::new(team_class_health >> 14);
let class = Class::new((team_class_health >> 10) & 15);
@ -230,26 +236,31 @@ impl PlayerState {
team,
class,
charge,
ubered,
}
}
}
#[test]
fn test_player_packing() {
#[cfg(test)]
fn get_world() -> World {
use tf_demo_parser::demo::vector::Vector;
let world = World {
boundary_max: Vector {
let mut world = World::default();
world.boundary_max = Vector {
x: 10000.0,
y: 10000.0,
z: 100.0,
},
boundary_min: Vector {
};
world.boundary_min = Vector {
x: -10000.0,
y: -10000.0,
z: -100.0,
},
};
world
}
#[test]
fn test_player_packing() {
let world = get_world();
let input = PlayerState {
position: VectorXY {
@ -261,6 +272,7 @@ fn test_player_packing() {
team: Team::Blue,
class: Class::Demoman,
charge: 7,
ubered: false,
};
let bytes = input.pack(&world);
@ -436,20 +448,7 @@ impl BuildingState {
#[test]
fn test_building_packing() {
use tf_demo_parser::demo::vector::Vector;
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 world = get_world();
let input = BuildingState {
position: VectorXY {
@ -545,20 +544,7 @@ impl ProjectileState {
#[test]
fn test_projectile_packing() {
use tf_demo_parser::demo::vector::Vector;
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 world = get_world();
let input = ProjectileState {
position: VectorXY {