/* Hurry Curry! - a game about cooking Copyright 2024 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use crate::sprite_renderer::SpriteRenderer; use hurrycurry_protocol::{glam::IVec2, TileIndex}; use sdl2::rect::{FRect, Rect}; use std::collections::HashMap; #[derive(Default)] pub struct Tilemap { tile_srcs: Vec<[Rect; 16]>, tiles: HashMap, } impl Tilemap { pub fn init(&mut self, tile_names: &[String], sprite_rects: &HashMap) { self.tile_srcs = tile_names .iter() .map(|name| { let fallback = sprite_rects .get(&format!("{name}+a")) .copied() .unwrap_or(Rect::new(0, 0, 0, 0)); [ sprite_rects.get(&format!("{name}+")), sprite_rects.get(&format!("{name}+w")), sprite_rects.get(&format!("{name}+e")), sprite_rects.get(&format!("{name}+we")), sprite_rects.get(&format!("{name}+n")), sprite_rects.get(&format!("{name}+wn")), sprite_rects.get(&format!("{name}+en")), sprite_rects.get(&format!("{name}+wen")), sprite_rects.get(&format!("{name}+s")), sprite_rects.get(&format!("{name}+ws")), sprite_rects.get(&format!("{name}+es")), sprite_rects.get(&format!("{name}+wes")), sprite_rects.get(&format!("{name}+ns")), sprite_rects.get(&format!("{name}+wns")), sprite_rects.get(&format!("{name}+ens")), sprite_rects.get(&format!("{name}+wens")), ] .map(|e| e.copied().unwrap_or(fallback)) }) .collect(); } pub fn set(&mut self, pos: IVec2, tile: Option, neighbors: [Option; 4]) { let Some(tile) = tile else { self.tiles.remove(&pos); return; }; let mut idx = 0; idx |= 0b0100 * (Some(tile) == neighbors[0]) as usize; idx |= 0b0001 * (Some(tile) == neighbors[1]) as usize; idx |= 0b1000 * (Some(tile) == neighbors[2]) as usize; idx |= 0b0010 * (Some(tile) == neighbors[3]) as usize; let src = self.tile_srcs[tile.0][idx]; self.tiles.insert( pos, ( src, FRect::new( pos.x as f32, pos.y as f32 + 1. - src.height() as f32 / 24., src.width() as f32 / 32., src.height() as f32 / 24., ), ), ); } pub fn draw(&self, ctx: &mut SpriteRenderer) { for &(src, dst) in self.tiles.values() { ctx.draw(((dst.y + dst.h) * 24.) as i32, src, dst); } } }