diff --git a/src/avatar.rs b/src/avatar.rs index 1b96a76..75ea8fa 100644 --- a/src/avatar.rs +++ b/src/avatar.rs @@ -1,28 +1,64 @@ -use crate::{AnimationFrames, Image, mock, Position}; +use crate::{AnimationFrames, Image, mock, Position, optional_data_line, ToBase36, from_base36}; /// avatar is a "sprite" in the game data but with a specific id #[derive(Debug, Eq, PartialEq)] pub struct Avatar { pub animation_frames: Vec, - pub room: String, /// room id + pub room_id: u64, pub position: Position, + pub colour_id: Option, +} + +impl Avatar { + fn room_position_line(&self) -> String { + format!("\nPOS {} {}", self.room_id.to_base36(), self.position.to_string()) + } + + fn colour_line(&self) -> String { + optional_data_line("COL", self.colour_id.as_ref()) + } } impl From for Avatar { fn from(string: String) -> Avatar { let string = string.replace("SPR A\n", ""); let mut lines: Vec<&str> = string.lines().collect(); - let room_pos = lines.pop().unwrap().replace("POS ", ""); - let room_pos: Vec<&str> = room_pos.split_whitespace().collect(); - let room = room_pos[0].to_string(); - let position = Position::from(room_pos[1].to_string()); + + let mut room_id: Option = None; + let mut position: Option = None; + let mut colour_id: Option = None; + + loop { + let last_line = lines.pop().unwrap(); + + if last_line.starts_with("POS") { + let room_pos = last_line.replace("POS ", ""); + let room_pos: Vec<&str> = room_pos.split_whitespace().collect(); + room_id = Some(from_base36(room_pos[0])); + + if room_pos.len() < 2 { + panic!("Bad room/position for avatar: {}", string); + } + + position = Some(Position::from(room_pos[1].to_string())); + } else if last_line.starts_with("COL") { + colour_id = Some(last_line.replace("COL ", "").parse().unwrap()); + } else { + lines.push(last_line); + break; + } + } + + let room_id = room_id.unwrap(); + let position = position.unwrap(); + let animation_frames: String = lines.join("\n"); - let animation_frames: Vec<&str> = animation_frames.split("\n>\n").collect(); + let animation_frames: Vec<&str> = animation_frames.split(">").collect(); let animation_frames: Vec = animation_frames.iter().map(|&frame| { Image::from(frame.to_string()) }).collect(); - Avatar { animation_frames, room, position } + Avatar { animation_frames, room_id, position , colour_id } } } @@ -30,10 +66,10 @@ impl ToString for Avatar { #[inline] fn to_string(&self) -> String { format!( - "SPR A\n{}\nPOS {} {}", + "SPR A\n{}{}{}", self.animation_frames.to_string(), - self.room, - self.position.to_string() + self.room_position_line(), + self.colour_line(), ) } }