diff options
-rw-r--r-- | client/src/world/helper.rs | 1 | ||||
-rw-r--r-- | client/src/world/map.rs | 26 | ||||
-rw-r--r-- | client/src/world/mod.rs | 4 | ||||
-rw-r--r-- | client/src/world/tee.rs | 5 | ||||
-rw-r--r-- | renderer/src/main.rs | 4 | ||||
-rw-r--r-- | renderer/src/map.rs | 15 | ||||
-rw-r--r-- | renderer/src/tee.rs | 112 |
7 files changed, 132 insertions, 35 deletions
diff --git a/client/src/world/helper.rs b/client/src/world/helper.rs index fab452a..cb34a9f 100644 --- a/client/src/world/helper.rs +++ b/client/src/world/helper.rs @@ -1,6 +1,7 @@ use std::fmt::Display; #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[repr(C)] pub struct Color { pub a: u8, pub r: u8, diff --git a/client/src/world/map.rs b/client/src/world/map.rs index c72bfa9..c6355f2 100644 --- a/client/src/world/map.rs +++ b/client/src/world/map.rs @@ -23,11 +23,14 @@ pub struct Layer { 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 { @@ -35,10 +38,12 @@ impl Map { Self { layers: Vec::new(), tilesets: HashMap::new(), + crc: 0, + name: String::from("twclient dummy map"), } } - pub fn load(file: File) -> Result<Self, Error> { + 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); @@ -47,17 +52,10 @@ impl Map { for group_idx in map.group_indices() { let group = map.group(group_idx).unwrap(); - if group.parallax_x != 100 - || group.parallax_y != 100 - || group.offset_x != 0 - || group.offset_y != 0 - || group.clipping.is_some() - { + if group.parallax_x != 100 || group.parallax_y != 100 || group.clipping.is_some() { warn!( - "skipping layer: {}: off_x:{} off_y:{} parallax_x:{} parallax_y:{} clipping:{:?}", + "skipping layer: {}: parallax_x:{} parallax_y:{} clipping:{:?}", pretty::AlmostString::new(&group.name), - group.offset_x, - group.offset_y, group.parallax_x, group.parallax_y, group.clipping, @@ -88,6 +86,7 @@ impl Map { image: normal.image, kind: tilemap.type_, tiles, + offset: (group.offset_x, group.offset_y), }); } } @@ -146,6 +145,11 @@ impl Map { layers.len(), tilesets.len() ); - Ok(Self { tilesets, layers }) + Ok(Self { + tilesets, + layers, + crc, + name: String::from(name), + }) } } diff --git a/client/src/world/mod.rs b/client/src/world/mod.rs index 8a16016..7b25a53 100644 --- a/client/src/world/mod.rs +++ b/client/src/world/mod.rs @@ -2,9 +2,9 @@ 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 mod helper; pub use gamenet::enums; @@ -26,7 +26,7 @@ impl World { match m { ClientMesgOut::MapChange { name, crc } => { let file = File::open(get_map_path(name.as_str(), *crc)).unwrap(); - self.map = Map::load(file).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 index 5458fe6..6b33f48 100644 --- a/client/src/world/tee.rs +++ b/client/src/world/tee.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, f32::consts::PI}; use super::helper::Color; use crate::client::ClientMesgOut; @@ -28,7 +28,7 @@ pub struct Tee { pub attack_tick: i32, pub tick: i32, - pub angle: i32, + pub angle: f32, pub x: i32, pub y: i32, pub vel_x: i32, @@ -126,6 +126,7 @@ impl Tees { 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; diff --git a/renderer/src/main.rs b/renderer/src/main.rs index 985a717..9716393 100644 --- a/renderer/src/main.rs +++ b/renderer/src/main.rs @@ -172,10 +172,10 @@ fn main() { if !repeat { match k { VirtualKeyCode::A => { - renderer.input.direction += sk * -1; + renderer.input.direction -= sk; } VirtualKeyCode::D => { - renderer.input.direction += sk * 1; + renderer.input.direction += sk; } VirtualKeyCode::Space => { renderer.input.jump = sa; diff --git a/renderer/src/map.rs b/renderer/src/map.rs index a1e8d94..5b657d4 100644 --- a/renderer/src/map.rs +++ b/renderer/src/map.rs @@ -29,18 +29,18 @@ impl MapRenderer { for (key, t) in &world.map.tilesets { for layer in world.map.layers.iter().filter(|l| l.image == *key) { let tint = layer.color; - let mut bytes: Vec<u8> = Vec::with_capacity(t.dim().0 * t.dim().1 * 4); info!( "loading tileset: (texture: {:?}, tint: {}) => {:?}", key, tint, t.dim() ); + let mut bytes: Vec<u8> = Vec::with_capacity(t.dim().0 * t.dim().1 * 4); for ((_x, _y), c) in t.indexed_iter() { - bytes.push((c.r as u32 * tint.r as u32) as u8); - bytes.push((c.g as u32 * tint.g as u32) as u8); - bytes.push((c.b as u32 * tint.b as u32) as u8); - bytes.push((c.a as u32 * tint.a as u32) as u8); + bytes.push((c.r as u32/* * tint.r as u32*/) as u8); + bytes.push((c.g as u32/* * tint.g as u32*/) as u8); + bytes.push((c.b as u32/* * tint.b as u32*/) as u8); + bytes.push((c.a as u32/* * tint.a as u32*/) as u8); } let d = skia_safe::Data::new_copy(&bytes); let v = skia_safe::Image::from_raster_data( @@ -98,7 +98,10 @@ impl MapRenderer { let layer_x = layer_x.try_into().unwrap_or(0); let layer_y = layer_y.try_into().unwrap_or(0); - let tile = match l.tiles.get((layer_y, layer_x)) { + let tile = match l.tiles.get(( + ((layer_y as i32) + l.offset.1) as usize, + ((layer_y as i32) + l.offset.0) as usize, + )) { Some(t) => t, None => continue, }; diff --git a/renderer/src/tee.rs b/renderer/src/tee.rs index d796f5e..8e8e3ba 100644 --- a/renderer/src/tee.rs +++ b/renderer/src/tee.rs @@ -6,8 +6,11 @@ use skia_safe::{ }; use twclient::world::{tee::Tee, World}; -const TEE_COLL_RADIUS: f32 = 16.0; +// const TEE_COLL_RADIUS: f32 = 16.0; const TEE_REND_RADIUS: f32 = 32.0; +const TEE_EYE_ROTATION_RADIUS: f32 = 8.0; +const TEE_EYE_SIZE: f32 = 12.0; +const TEE_EYE_DISTANCE: f32 = 8.0; pub struct TeeRenderer { skins: BTreeMap<String, Image>, @@ -59,16 +62,19 @@ impl TeeRenderer { }; canvas.draw_image_rect( - skin_texture, - Some(( - &Rect { - top: 16.0, - left: 16.0, - right: 96.0, - bottom: 96.0, - }, - SrcRectConstraint::Strict, - )), + &skin_texture, + Some((&SKIN_BODY_SHADOW, SrcRectConstraint::Strict)), + Rect { + top: -TEE_REND_RADIUS, + left: -TEE_REND_RADIUS, + right: TEE_REND_RADIUS, + bottom: TEE_REND_RADIUS, + }, + &tee_paint, + ); + canvas.draw_image_rect( + &skin_texture, + Some((&SKIN_BODY, SrcRectConstraint::Strict)), Rect { top: -TEE_REND_RADIUS, left: -TEE_REND_RADIUS, @@ -78,6 +84,62 @@ impl TeeRenderer { &tee_paint, ); + { + canvas.save(); + // println!("{}", tee.angle); + canvas.translate(( + tee.angle.cos() * TEE_EYE_ROTATION_RADIUS, + tee.angle.sin() * TEE_EYE_ROTATION_RADIUS, + )); + + canvas.draw_image_rect( + &skin_texture, + Some((&SKIN_EYE_NORMAL, SrcRectConstraint::Strict)), + Rect { + top: -TEE_EYE_SIZE, + left: -TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + right: TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + bottom: TEE_EYE_SIZE, + }, + &tee_paint, + ); + { + canvas.save(); + canvas.scale((-1.0, 1.0)); + canvas.draw_image_rect( + &skin_texture, + Some((&SKIN_EYE_NORMAL, SrcRectConstraint::Strict)), + Rect { + top: -TEE_EYE_SIZE, + left: -TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + right: TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + bottom: TEE_EYE_SIZE, + }, + &tee_paint, + ); + canvas.restore(); + } + + canvas.restore(); + } + { + canvas.save(); + + canvas.draw_image_rect( + &skin_texture, + Some((&SKIN_FOOT, SrcRectConstraint::Strict)), + Rect { + top: -TEE_EYE_SIZE, + left: -TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + right: TEE_EYE_SIZE - TEE_EYE_DISTANCE / 2.0, + bottom: TEE_EYE_SIZE, + }, + &tee_paint, + ); + + canvas.restore(); + } + canvas.draw_str_align( tee.name.as_str(), (origin.x, origin.y - 20.0), @@ -88,7 +150,8 @@ impl TeeRenderer { } pub fn load_skin(_name: &str) -> Option<Image> { - let path = "/usr/share/ddnet/data/skins/default.png"; + // let path = "/usr/share/ddnet/data/skins/limekitty.png"; + let path = "/home/muffin/.teeworlds/downloadedskins/limekittygirl.png"; let mut file = File::open(path).unwrap(); let mut data = Vec::new(); file.read_to_end(&mut data).unwrap(); @@ -96,3 +159,28 @@ impl TeeRenderer { Image::from_encoded(data) } } + +const SKIN_BODY: Rect = Rect { + top: 0.0, + left: 0.0, + right: 96.0, + bottom: 96.0, +}; +const SKIN_BODY_SHADOW: Rect = Rect { + top: 0.0, + left: 96.0, + right: 192.0, + bottom: 96.0, +}; +const SKIN_FOOT: Rect = Rect { + left: 196.0, + right: 256.0, + top: 32.0, + bottom: 64.0, +}; +const SKIN_EYE_NORMAL: Rect = Rect { + left: 64.0, + right: 96.0, + top: 96.0, + bottom: 128.0, +}; |