use comfy::{ draw_rect_outline, draw_sprite, error, random_i32, vec2, EngineContext, HashSet, Vec2, GREEN, RED, WHITE }; use crate::game; use super::{furniture::Furniture, grid::Grid}; pub const SCALE: f32 = 4.0; #[derive(Debug, PartialEq)] enum RoomType { Kitchen, Bath, Toilett, LivingRoom, SleepingRoom } type Tile = (Vec2, Vec2, Furniture); //(pos, size, furniture) #[derive(Debug)] pub struct Room { room_type: RoomType, pub size: (u8, u8), //(width, height) pub grid: Grid, furnitures: Vec } impl RoomType { pub fn random() -> Self { match random_i32(0, 4) { 0 => RoomType::Kitchen, 1 => RoomType::Bath, 2 => RoomType::Toilett, 3 => RoomType::LivingRoom, 4 => RoomType::SleepingRoom, _ => panic!("Somehow you where unlucky and got a random number out of range") } } } impl Room { pub fn new(ctx: &mut EngineContext<'_>) -> Self { let room_type = RoomType::random(); let size = Self::random_size(&room_type); let furnitures = Self::random_room_furniture(&room_type, size, ctx); Room { room_type, size, grid: Self::create_grid(size.0, size.1), furnitures } } fn random_size(room_type: &RoomType) -> (u8, u8) { //Kitchen + Living Room 5-8 //Bath + sleepingroom 4-6 //Toilet 2-3 match room_type { RoomType::Kitchen | RoomType::LivingRoom => (random_i32(5, 8) as u8, 3), RoomType::Bath | RoomType::SleepingRoom => (random_i32(4, 6) as u8, 3), RoomType::Toilett => (random_i32(2, 3) as u8, 3) } } fn random_room_furniture(room_type: &RoomType, size: (u8, u8), ctx: &mut EngineContext<'_>) -> Vec { let mut furnitures = Vec::new(); let width = size.0; match room_type { RoomType::Kitchen => { furnitures.push(( vec2(0.0, 0.0), vec2(1.0, 2.0), Furniture::new("kitchen", "fridge", ctx) )); furnitures.push(( vec2(1.0, 0.0), vec2(1.0, 1.0), Furniture::new("kitchen", "dishwasher", ctx) )); furnitures.push(( vec2(1.0, 1.0), vec2(0.75, 0.75), Furniture::new("kitchen", "blender", ctx) )); } _ => {} } furnitures } fn create_grid(width: u8, height: u8) -> Grid { error!("START GRID CREATION!"); let left_border = width as f32 / 2.0; let lower_border = height as f32 / 2.0; //Lower Cable let lower_cable_y = height as f32 / 6.0; let mut current_x = -0.5; let mut nodes = Vec::new(); let max_offset = ((width / 2) as i32).max(1); while current_x < width as f32 { nodes.push(vec2( (current_x - left_border) * SCALE, (lower_cable_y - lower_border) * SCALE )); current_x += random_i32(1, max_offset) as f32; } current_x = width as f32 + 0.5; nodes.push(vec2( (current_x - left_border) * SCALE, (lower_cable_y - lower_border) * SCALE )); let mut connections = Vec::new(); for i in 1 .. nodes.len() { connections.push((i - 1, i)); } //Lamps let upper_cable_y = height as f32 - 0.25; let max_lamps = (width as f32 / 2.5).round() as i32; let lamp_amount = random_i32(1, max_lamps + 1); let node_indices: HashSet = (0 .. lamp_amount) .map(|_| random_i32(1, nodes.len() as i32 - 1) as usize) .collect(); let last_lower_node_index = nodes.len(); for (i, index) in node_indices.iter().enumerate() { nodes.push(vec2( nodes.get(*index).unwrap().x, (upper_cable_y - lower_border) * SCALE )); connections.push((*index, last_lower_node_index + i)); } Grid::new(nodes, connections) } pub fn draw(&self) { let (width, height) = self.size; draw_rect_outline( vec2(0.0, 0.0), vec2(width as f32 * SCALE, height as f32 * SCALE), 0.3, RED, game::ZLayer::MapMax.into() ); for (pos, size, furniture) in &self.furnitures { let mut pos = *pos - vec2(width as f32 / 2.0, height as f32 / 2.0); pos += *size * 0.5; if let Some(texture) = furniture.get_human_texture_handle() { draw_sprite( texture, pos * SCALE, WHITE, game::ZLayer::MapMax.into(), *size * SCALE ); } else { draw_rect_outline( pos * SCALE, *size * SCALE, 0.3, GREEN, game::ZLayer::MapMax.into() ); } } self.grid.draw(); } }