Move passable and opaque into objectdef

This commit is contained in:
2026-05-30 21:22:36 -05:00
parent a0d21bde20
commit 0241cd2a8d
5 changed files with 59 additions and 25 deletions
+27 -19
View File
@@ -72,7 +72,7 @@ pub struct FontSpec {
///
/// For scripted objects (`Archetype::Object`), the behavior will eventually be
/// determined by the Rhai script rather than this struct. See the Object variant
/// for details.
/// for details. (TODO fix this comment)
#[derive(Copy, Clone, Debug)]
pub struct Behavior {
/// Whether an entity can walk through this cell.
@@ -104,8 +104,6 @@ pub enum Archetype {
Empty,
/// A solid wall; impassable and opaque.
Wall,
/// A scripted object. Behavior defaults to impassable until script-driven.
Object,
/// Sentinel for map files that reference an unknown archetype name.
/// Renders as a yellow `?` on red to make the error visible in-game.
ErrorBlock,
@@ -125,10 +123,6 @@ impl Archetype {
passable: false,
opaque: true,
},
Archetype::Object => Behavior {
passable: false,
opaque: false,
},
Archetype::ErrorBlock => Behavior {
passable: false,
opaque: true,
@@ -141,7 +135,6 @@ impl Archetype {
match self {
Archetype::Empty => "empty",
Archetype::Wall => "wall",
Archetype::Object => "object",
Archetype::ErrorBlock => "error_block",
}
}
@@ -162,11 +155,6 @@ impl Archetype {
fg: Rgba8 { r: 0x80, g: 0x80, b: 0x80, a: 255 },
bg: Rgba8 { r: 0x60, g: 0x60, b: 0x60, a: 255 },
},
Archetype::Object => Glyph {
tile: 63,
fg: Rgba8 { r: 255, g: 255, b: 0, a: 255 }, // yellow
bg: Rgba8 { r: 0, g: 0, b: 0, a: 255 },
},
// Visually distinct so malformed map files are immediately obvious.
Archetype::ErrorBlock => Glyph {
tile: 63,
@@ -199,7 +187,7 @@ impl TryFrom<&str> for Archetype {
///
/// `ErrorBlock` is excluded — it is a sentinel for load errors, not a valid
/// editing choice.
pub const ALL_ARCHETYPES: &[Archetype] = &[Archetype::Empty, Archetype::Wall, Archetype::Object];
pub const ALL_ARCHETYPES: &[Archetype] = &[Archetype::Empty, Archetype::Wall];
/// A scripted object placed on the board, loaded from a map file.
///
@@ -228,11 +216,25 @@ pub struct ObjectDef {
/// Visual representation of this object. Owned by the object (not derived
/// from the grid cell), so scripts can change tile, fg, and bg at runtime.
pub glyph: Glyph,
/// Whether the object blocks movement, of players or other objects
pub passable: bool,
/// Whether the object blocks line of sight / FOV for the player
pub opaque: bool,
/// Name of the Rhai script in [`Board::scripts`] that drives this object.
/// `None` means this object has no script yet.
pub script_name: Option<String>,
}
impl ObjectDef {
pub fn default_glyph() -> Glyph {
Glyph {
tile: 63,
fg: Rgba8 { r: 255, g: 255, b: 0, a: 255 }, // yellow
bg: Rgba8 { r: 0, g: 0, b: 0, a: 255 },
}
}
}
/// A portal that teleports the player to a named entry point on another board.
///
/// Portals are loaded from `[[portals]]` entries in `.toml` map files and
@@ -345,17 +347,23 @@ impl Board {
/// Objects block movement before the grid cell archetype is consulted.
/// Panics if `x` or `y` are out of bounds.
pub fn is_passable(&self, x: usize, y: usize) -> bool {
// An object on this cell always blocks (until scripting overrides this).
if self.object_at(x, y).is_some() {
return false;
// An object on this cell blocks if it's unpassable
if let Some(obj) = self.object_at(x, y) && !obj.passable {
false
} else {
self.get(x, y).1.behavior().passable
}
self.get(x, y).1.behavior().passable
}
/// Returns the index into [`Board::objects`] of the object at `(x, y)`, if any.
pub fn object_at(&self, x: usize, y: usize) -> Option<usize> {
pub fn object_index_at(&self, x: usize, y: usize) -> Option<usize> {
self.objects.iter().position(|o| o.x == x && o.y == y)
}
/// Returns a borrow of the actual object at `(x, y)` if any
pub fn object_at(&self, x: usize, y: usize) -> Option<&ObjectDef> {
self.object_index_at(x, y).map(|idx| &self.objects[idx])
}
}
/// Holds the active game board and provides game-logic operations.