object layer
This commit is contained in:
+24
-10
@@ -178,7 +178,8 @@ impl TryFrom<&str> for Archetype {
|
||||
match name {
|
||||
"empty" => Ok(Archetype::Empty),
|
||||
"wall" => Ok(Archetype::Wall),
|
||||
"object" => Ok(Archetype::Object),
|
||||
// "object" is intentionally absent: objects are not valid palette
|
||||
// entries in map files. They live in [[objects]] with their own glyph.
|
||||
_ => Err(format!("unknown archetype: {name}")),
|
||||
}
|
||||
}
|
||||
@@ -197,22 +198,28 @@ pub const ALL_ARCHETYPES: &[Archetype] = &[Archetype::Empty, Archetype::Wall, Ar
|
||||
/// tile. Objects are parsed from `[[objects]]` entries in `.toml` map files
|
||||
/// and stored on [`Board`].
|
||||
///
|
||||
/// Objects are rendered as an overlay on top of the board grid — the grid
|
||||
/// cell at `(x, y)` holds the background (floor) that is revealed if the
|
||||
/// object moves away. `glyph` is owned by the object itself and may be
|
||||
/// mutated by its Rhai script at runtime.
|
||||
///
|
||||
/// Script text lives in [`Board::scripts`]; this struct holds only the name
|
||||
/// used to look it up. Two `ObjectDef`s with the same `script_name` share
|
||||
/// source text but will run with independent Rhai scopes (independent local
|
||||
/// variables) when the scripting runtime is wired.
|
||||
/// source text but will run with independent Rhai scopes when the scripting
|
||||
/// runtime is wired.
|
||||
///
|
||||
/// **Not yet runtime-wired.** Objects are loaded and stored but their scripts
|
||||
/// are not yet executed. Scripting dispatch is a future feature.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct ObjectDef {
|
||||
/// Column of this object on the board (0-indexed).
|
||||
pub x: usize,
|
||||
/// Row of this object on the board (0-indexed).
|
||||
pub y: usize,
|
||||
/// 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,
|
||||
/// Name of the Rhai script in [`Board::scripts`] that drives this object.
|
||||
/// `None` means this object has no script yet.
|
||||
#[serde(default)]
|
||||
pub script_name: Option<String>,
|
||||
}
|
||||
|
||||
@@ -316,14 +323,21 @@ impl Board {
|
||||
&mut self.cells[y * self.width + x]
|
||||
}
|
||||
|
||||
/// Returns `true` if the archetype at `(x, y)` allows entities to pass through.
|
||||
/// Returns `true` if the cell at `(x, y)` allows entities to pass through.
|
||||
///
|
||||
/// 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 {
|
||||
let (_, arch) = self.get(x, y);
|
||||
// Derive passability from the archetype's behavior.
|
||||
// Object cells will need special handling here once scripts are wired.
|
||||
arch.behavior().passable
|
||||
// An object on this cell always blocks (until scripting overrides this).
|
||||
if self.object_at(x, y).is_some() {
|
||||
return false;
|
||||
}
|
||||
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> {
|
||||
self.objects.iter().position(|o| o.x == x && o.y == y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user