dotzuki_engine/tile_meta.rs
1use std::fmt::Debug;
2use std::hash::Hash;
3
4/// Describes how a tile interacts with entities on the overworld map.
5///
6/// This is used by the movement and collision systems to determine
7/// whether the player or NPCs can walk on a tile, trigger special
8/// behaviour (ledges, grass encounters, doors), or are blocked.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum CollisionType {
11 /// The tile can be walked on freely.
12 Passable,
13
14 /// The tile blocks all movement.
15 Impassable,
16
17 /// A ledge tile that allows jumping down.
18 ///
19 /// The `direction` field indicates which direction the player
20 /// faces when jumping (e.g., 0 = down).
21 Ledge {
22 /// Direction the player faces when jumping the ledge.
23 direction: u8,
24 },
25
26 /// A counter tile that the player can interact with from behind.
27 Counter,
28
29 /// Tall grass where wild monster encounters can occur.
30 ///
31 /// When `Some(id)`, specifies a special grass tile ID for
32 /// encounter calculations. When `None`, uses the default
33 /// encounter rate.
34 Grass(Option<u8>),
35
36 /// Water tile that requires Surf to traverse.
37 Water,
38
39 /// A warp tile that triggers a map transition.
40 Warp,
41
42 /// A door tile that can be entered.
43 Door,
44}
45
46/// Marker trait for tile metadata identifiers.
47///
48/// Implementations are typically lightweight enums or numeric IDs
49/// representing a specific set of tile collision data (e.g.,
50/// a tileset's collision table).
51pub trait TileMetaTrait: Copy + Eq + Hash + Debug + 'static {}
52
53/// Provides collision and terrain metadata for tiles in a given tileset.
54///
55/// The engine queries this trait whenever an entity attempts to move
56/// onto a tile, to determine whether the movement is valid and what
57/// special behaviour (if any) should trigger.
58pub trait TileMetadata<T: TileMetaTrait> {
59 /// Returns `true` if a tile with the given ID in the given tileset
60 /// can be walked on freely.
61 fn is_passable(&self, tileset: T, tile_id: u8) -> bool;
62
63 /// Returns the full `CollisionType` for a tile.
64 fn collision_type(&self, tileset: T, tile_id: u8) -> CollisionType;
65
66 /// Returns `true` if the tile is a ledge.
67 fn is_ledge(&self, tileset: T, tile_id: u8) -> bool;
68
69 /// Returns `true` if the tile is a counter.
70 fn is_counter(&self, tileset: T, tile_id: u8) -> bool;
71
72 /// Returns `true` if the tile is tall grass.
73 fn is_grass(&self, tileset: T, tile_id: u8) -> bool;
74
75 /// Returns the special grass tile ID for encounter calculations,
76 /// or `None` if the default encounter rate should be used.
77 fn get_grass_tile(&self, tileset: T) -> Option<u8>;
78}