summaryrefslogtreecommitdiff
path: root/pixel-client/src/tilemap.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-16 23:38:46 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-16 23:38:46 +0200
commit775b0148cec4329a6abb19d03220dc1d8a8b68c3 (patch)
tree9e715df1db4f23a9c3f1e9c07cf7e93e376b512f /pixel-client/src/tilemap.rs
parent3a358c6dd39aa78319549658adf1028cea61f643 (diff)
downloadhurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar
hurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar.bz2
hurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar.zst
rename pixel client
Diffstat (limited to 'pixel-client/src/tilemap.rs')
-rw-r--r--pixel-client/src/tilemap.rs117
1 files changed, 117 insertions, 0 deletions
diff --git a/pixel-client/src/tilemap.rs b/pixel-client/src/tilemap.rs
new file mode 100644
index 00000000..768f79ba
--- /dev/null
+++ b/pixel-client/src/tilemap.rs
@@ -0,0 +1,117 @@
+/*
+ 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 <https://www.gnu.org/licenses/>.
+
+*/
+use hurrycurry_protocol::{glam::IVec2, TileIndex};
+use log::warn;
+use sdl2::rect::Rect;
+use std::collections::{HashMap, HashSet};
+
+use crate::render::{
+ sprite::{Sprite, SpriteDraw},
+ SpriteRenderer,
+};
+
+#[derive(Default)]
+pub struct Tilemap {
+ connect_group_by_tile: Vec<Option<usize>>,
+ connect_members_by_group: Vec<HashSet<Option<TileIndex>>>,
+ tile_srcs: Vec<[Rect; 16]>,
+ tiles: HashMap<IVec2, SpriteDraw>,
+}
+
+impl Tilemap {
+ pub fn init(&mut self, tile_names: &[String], sprite_rects: &HashMap<String, Rect>) {
+ let tile_index = tile_names
+ .iter()
+ .enumerate()
+ .map(|(t, i)| (i.to_string(), t))
+ .collect::<HashMap<_, _>>();
+ self.connect_group_by_tile = vec![None; tile_names.len()];
+ self.connect_members_by_group = include_str!("../assets/connect.csv")
+ .lines()
+ .enumerate()
+ .map(|(gid, line)| {
+ line.split(",")
+ .flat_map(|tile| tile_index.get(tile).copied())
+ .map(|ti| {
+ self.connect_group_by_tile[ti] = Some(gid);
+ Some(TileIndex(ti))
+ })
+ .collect::<HashSet<_>>()
+ })
+ .collect::<Vec<_>>();
+
+ self.tile_srcs = tile_names
+ .iter()
+ .map(|name| {
+ let fallback = sprite_rects
+ .get(&format!("{name}+a"))
+ .copied()
+ .unwrap_or_else(|| {
+ warn!("no sprite for tile {name:?}");
+ 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<TileIndex>, neighbors: [Option<TileIndex>; 4]) {
+ let Some(tile) = tile else {
+ self.tiles.remove(&pos);
+ return;
+ };
+
+ let mut idx = 0;
+ if let Some(gid) = self.connect_group_by_tile[tile.0] {
+ let cgroup = &self.connect_members_by_group[gid];
+ idx |= 0b0100 * (cgroup.contains(&neighbors[0])) as usize;
+ idx |= 0b0001 * (cgroup.contains(&neighbors[1])) as usize;
+ idx |= 0b1000 * (cgroup.contains(&neighbors[2])) as usize;
+ idx |= 0b0010 * (cgroup.contains(&neighbors[3])) as usize;
+ }
+
+ let src = self.tile_srcs[tile.0][idx];
+ self.tiles
+ .insert(pos, Sprite::new_tile(src).at(pos.as_vec2()));
+ }
+
+ pub fn draw(&self, ctx: &mut SpriteRenderer) {
+ for &sprite in self.tiles.values() {
+ ctx.draw_world(sprite);
+ }
+ }
+}