diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-08 11:14:01 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-08 11:14:01 +0100 |
commit | b2145131ccde0a33b9840ac04c8b7d79e733ae12 (patch) | |
tree | 217f7bec5e5e8aed99c1af3135a8189b850d9f63 /client/src/world | |
parent | 1247f46149cbb3a21590573fdcef23e920d0addc (diff) | |
download | twclient-b2145131ccde0a33b9840ac04c8b7d79e733ae12.tar twclient-b2145131ccde0a33b9840ac04c8b7d79e733ae12.tar.bz2 twclient-b2145131ccde0a33b9840ac04c8b7d79e733ae12.tar.zst |
reset
Diffstat (limited to 'client/src/world')
-rw-r--r-- | client/src/world/helper.rs | 19 | ||||
-rw-r--r-- | client/src/world/map.rs | 158 | ||||
-rw-r--r-- | client/src/world/mod.rs | 34 | ||||
-rw-r--r-- | client/src/world/tee.rs | 167 |
4 files changed, 0 insertions, 378 deletions
diff --git a/client/src/world/helper.rs b/client/src/world/helper.rs deleted file mode 100644 index cb34a9f..0000000 --- a/client/src/world/helper.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::fmt::Display; - -#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] -#[repr(C)] -pub struct Color { - pub a: u8, - pub r: u8, - pub g: u8, - pub b: u8, -} - -impl Display for Color { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!( - "#{:02x}{:02x}{:02x}{:02x}", - self.r, self.g, self.b, self.a - )) - } -} diff --git a/client/src/world/map.rs b/client/src/world/map.rs deleted file mode 100644 index c8522b9..0000000 --- a/client/src/world/map.rs +++ /dev/null @@ -1,158 +0,0 @@ -use ::map as mapfile; -use anyhow::Error; -use common::{num::Cast, pretty, vec}; -use log::{info, log, warn}; -use ndarray::Array2; -use std::{ - collections::{hash_map, HashMap}, - fs::File, - mem, -}; - -pub use mapfile::format; -pub use mapfile::{ - format::Tile, - reader::{self, Color as BadColor, LayerTilemapType}, -}; - -use super::helper::Color; -pub const TILE_NUM: u32 = 16; - -pub struct Layer { - pub color: Color, - pub image: Option<usize>, - pub tiles: Array2<Tile>, - pub kind: LayerTilemapType, - pub offset: (i32, i32), -} - -pub struct Map { - pub layers: Vec<Layer>, - pub tilesets: HashMap<Option<usize>, Array2<Color>>, - pub name: String, - pub crc: i32, -} - -impl Map { - pub fn empty() -> Self { - Self { - layers: Vec::new(), - tilesets: HashMap::new(), - crc: 0, - name: String::from("twclient dummy map"), - } - } - - pub fn load(file: File, name: &str, crc: i32) -> Result<Self, Error> { - info!("loading map"); - let datafile = datafile::Reader::new(file).unwrap(); - let mut map = mapfile::Reader::from_datafile(datafile); - - let mut layers = vec![]; - for group_idx in map.group_indices() { - let group = map.group(group_idx).unwrap(); - - if group.parallax_x != 100 || group.parallax_y != 100 || group.clipping.is_some() { - warn!( - "skipping layer: {}: parallax_x:{} parallax_y:{} clipping:{:?}", - pretty::AlmostString::new(&group.name), - group.parallax_x, - group.parallax_y, - group.clipping, - ); - continue; - } - - for layer_idx in group.layer_indices { - info!("loading {}", pretty::AlmostString::new(&group.name)); - let layer = map.layer(layer_idx).unwrap(); - let tilemap = if let reader::LayerType::Tilemap(t) = layer.t { - t - } else { - warn!("non-tilemap layer skipped"); - continue; - }; - let normal = if let Some(n) = tilemap.type_.to_normal() { - n - } else { - warn!("non-normal layer skipped"); - continue; - }; - let tiles = map.layer_tiles(tilemap.tiles(normal.data)).unwrap(); - layers.push(Layer { - color: Color { - r: normal.color.red, - g: normal.color.green, - b: normal.color.blue, - a: normal.color.alpha, - }, - image: normal.image, - kind: tilemap.type_, - tiles, - offset: (group.offset_x, group.offset_y), - }); - } - } - - let mut tilesets = HashMap::new(); - for layer in &layers { - match tilesets.entry(layer.image) { - hash_map::Entry::Occupied(_) => {} - hash_map::Entry::Vacant(v) => { - let data = match layer.image { - None => Array2::from_elem( - (1, 1), - Color { - a: 255, - r: 255, - g: 0, - b: 255, - }, - ), - Some(image_idx) => { - let image = map.image(image_idx).unwrap(); - let height = image.height.usize(); - let width = image.width.usize(); - match image.data { - Some(d) => { - let data = map.image_data(d).unwrap(); - if data.len() % mem::size_of::<Color>() != 0 { - panic!("image shape invalid"); - } - let data: Vec<Color> = unsafe { vec::transmute(data) }; - Array2::from_shape_vec((height, width), data).unwrap() - } - None => { - warn!("layer with external tileset skipped"); - continue; - // let image_name = map.image_name(image.name)?; - // // WARN? Unknown external image - // // WARN! Wrong dimensions - // str::from_utf8(&image_name).ok() - // .and_then(sanitize) - // .map(&mut external_tileset_loader) - // .transpose()? - // .unwrap_or(None) - // .unwrap_or_else(|| Array2::from_elem((1, 1), Color::white())) - } - } - } - }; - v.insert(data); - } - } - } - - info!( - "{} layers + {} tilesets loaded", - layers.len(), - tilesets.len() - ); - Ok(Self { - tilesets, - layers, - crc, - name: String::from(name), - }) - } -} diff --git a/client/src/world/mod.rs b/client/src/world/mod.rs deleted file mode 100644 index 7b25a53..0000000 --- a/client/src/world/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -use self::{map::Map, tee::Tees}; -use crate::client::{helper::get_map_path, ClientMesgOut}; -use std::fs::File; - -pub mod helper; -pub mod map; -pub mod tee; - -pub use gamenet::enums; - -pub struct World { - pub map: Map, - pub tees: Tees, -} - -impl World { - pub fn new() -> Self { - Self { - map: Map::empty(), - tees: Tees::new(), - } - } - - pub fn update(&mut self, m: &ClientMesgOut) { - self.tees.update(m); - match m { - ClientMesgOut::MapChange { name, crc } => { - let file = File::open(get_map_path(name.as_str(), *crc)).unwrap(); - self.map = Map::load(file, name.as_str(), *crc).unwrap(); - } - _ => (), - } - } -} diff --git a/client/src/world/tee.rs b/client/src/world/tee.rs deleted file mode 100644 index 6b33f48..0000000 --- a/client/src/world/tee.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::{collections::BTreeMap, f32::consts::PI}; - -use super::helper::Color; -use crate::client::ClientMesgOut; -use gamenet::{ - enums::{Emote, Team, Weapon}, - SnapObj, -}; - -pub struct Tees { - pub inner: BTreeMap<u16, Tee>, -} - -pub struct Tee { - pub name: String, - pub skin: String, - pub clan: String, - - pub local: bool, - pub latency: i32, - pub score: i32, - - pub team: Team, - pub weapon: Weapon, - pub armor: i32, - pub ammo: i32, - pub emote: Emote, - pub attack_tick: i32, - - pub tick: i32, - pub angle: f32, - pub x: i32, - pub y: i32, - pub vel_x: i32, - pub vel_y: i32, - pub hook_x: i32, - pub hook_y: i32, - pub hook_dx: i32, - pub hook_dy: i32, - pub hook_player: i32, - pub hook_state: i32, - - pub color_feet: Color, - pub color_body: Color, - pub use_custom_colors: bool, - pub country: i32, -} - -impl Default for Tee { - fn default() -> Self { - Self { - x: Default::default(), - y: Default::default(), - local: false, - team: Team::Spectators, - latency: Default::default(), - score: Default::default(), - weapon: Weapon::Shotgun, - armor: Default::default(), - ammo: Default::default(), - attack_tick: Default::default(), - emote: Emote::Normal, - tick: Default::default(), - angle: Default::default(), - vel_x: Default::default(), - vel_y: Default::default(), - hook_x: Default::default(), - hook_y: Default::default(), - hook_dx: Default::default(), - hook_dy: Default::default(), - hook_player: Default::default(), - hook_state: Default::default(), - name: Default::default(), - skin: Default::default(), - clan: Default::default(), - color_feet: Color { - a: 0, - b: 0, - g: 0, - r: 0, - }, - color_body: Color { - a: 0, - b: 0, - g: 0, - r: 0, - }, - use_custom_colors: Default::default(), - country: Default::default(), - } - } -} - -impl Tees { - pub fn new() -> Self { - Self { - inner: BTreeMap::new(), - } - } - pub fn update(&mut self, m: &ClientMesgOut) { - match m { - ClientMesgOut::Snaps(s) => { - self.inner.clear(); - for (id, o) in s { - let e = self.inner.entry(*id).or_default(); - match o { - SnapObj::ClientInfo(o) => { - e.name = i32_to_string(o.name); - e.skin = i32_to_string(o.skin); - e.clan = i32_to_string(o.clan); - e.color_feet = unsafe { std::mem::transmute(o.color_feet) }; - e.color_body = unsafe { std::mem::transmute(o.color_body) }; - e.use_custom_colors = o.use_custom_color != 0 - } - SnapObj::PlayerInfo(o) => { - e.local = o.local == 1; - e.team = o.team; - e.latency = o.latency; - e.score = o.score; - } - SnapObj::Character(c) => { - e.ammo = c.ammo_count; - e.weapon = c.weapon; - e.emote = c.emote; - e.attack_tick = c.attack_tick; - - e.x = c.character_core.x; - e.y = c.character_core.y; - e.angle = c.character_core.angle as f32 / 1600.0 * 2.0 * PI; - e.vel_x = c.character_core.vel_x; - e.vel_y = c.character_core.vel_y; - - e.tick = c.character_core.tick; - e.hook_x = c.character_core.hook_x; - e.hook_y = c.character_core.hook_y; - e.hook_player = c.character_core.hooked_player; - e.hook_dx = c.character_core.hook_dx; - e.hook_dy = c.character_core.hook_dy; - e.hook_state = c.character_core.hook_state; - } - _ => (), - } - } - } - _ => {} - } - } - - pub fn local(&self) -> Option<&Tee> { - self.inner.values().find(|e| e.local) - } -} - -fn i32_to_string<const S: usize>(k: [i32; S]) -> String { - let mut bytes = vec![]; - for i in 0..S { - bytes.push(((((k[i]) >> 24) & 0xff) - 128) as u8); - bytes.push(((((k[i]) >> 16) & 0xff) - 128) as u8); - bytes.push(((((k[i]) >> 8) & 0xff) - 128) as u8); - bytes.push((((k[i]) & 0xff) - 128) as u8); - } - let len = bytes.iter().position(|e| *e == 0).unwrap_or(S); - while bytes.len() > len { - bytes.pop(); - } - String::from_utf8(bytes).unwrap() -} |