builtin macro
This commit is contained in:
+17
-18
@@ -6,7 +6,6 @@ use crate::object_def::ObjectDef;
|
||||
use crate::utils::Direction;
|
||||
use crate::utils::{Behavior, ObjectId, Player, PortalDef, Pushable, RegistryValue, Solid};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use crate::builtin_scripts::archetype_script_key;
|
||||
|
||||
/// The complete state of one game board (a single room or screen).
|
||||
///
|
||||
@@ -499,14 +498,14 @@ impl Board {
|
||||
/// the normal load path, so this is only needed for the in-memory path. Cells
|
||||
/// already loaded as objects are untouched, so it is safe to call more than once.
|
||||
pub fn expand_builtin_archetypes(&mut self) {
|
||||
use crate::builtin_scripts::{archetype_script, builtin_tag};
|
||||
use crate::builtin_scripts::builtin_tag;
|
||||
// Collect first: the loop below mutates both layers and the object map.
|
||||
let mut found: Vec<(usize, usize, usize, Glyph, Archetype)> = Vec::new();
|
||||
for z in 0..self.layers.len() {
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
let (glyph, arch) = *self.get(z, x, y);
|
||||
if archetype_script(arch).is_some() {
|
||||
if matches!(arch, Archetype::Builtin(_, _)) {
|
||||
found.push((z, x, y, glyph, arch));
|
||||
}
|
||||
}
|
||||
@@ -516,20 +515,25 @@ impl Board {
|
||||
// Vacate the terrain cell (revealing any floor beneath), then spawn the
|
||||
// object — mirroring `resolve_entry`'s object template.
|
||||
*self.get_mut(z, x, y) = (Glyph::transparent(), Archetype::Empty);
|
||||
let b = arch.behavior();
|
||||
let Archetype::Builtin(b, _alias) = arch else { continue };
|
||||
let beh = b.behavior();
|
||||
let mut obj = ObjectDef::new(x, y);
|
||||
obj.z = z;
|
||||
obj.glyph = glyph;
|
||||
obj.solid = b.solid;
|
||||
obj.opaque = b.opaque;
|
||||
obj.solid = beh.solid;
|
||||
obj.opaque = beh.opaque;
|
||||
// Carry the archetype's pushability/grab onto the object (pushers and
|
||||
// spinners are Pushable::No, so they stay unpushable; gems are pushable
|
||||
// and grabbable).
|
||||
obj.pushable = b.pushable != crate::utils::Pushable::No;
|
||||
obj.grab = b.grab;
|
||||
obj.builtin_script = archetype_script(arch);
|
||||
obj.script_name = archetype_script_key(arch).map(|s| s.to_owned());
|
||||
obj.tags.insert(builtin_tag(arch));
|
||||
obj.pushable = beh.pushable != crate::utils::Pushable::No;
|
||||
obj.grab = beh.grab;
|
||||
obj.builtin_script = Some(b.script());
|
||||
// The compile-cache key and the BUILTIN_* tag are both derived from the
|
||||
// alias (e.g. "BUILTIN_pusher_east"), so each alias gets its own cached
|
||||
// AST — a tiny bit less sharing than before, but the source is identical.
|
||||
let tag = builtin_tag(arch);
|
||||
obj.script_name = Some(tag.clone());
|
||||
obj.tags.insert(tag);
|
||||
self.add_object(obj);
|
||||
}
|
||||
}
|
||||
@@ -614,7 +618,7 @@ impl Board {
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::Board;
|
||||
use crate::archetype::{Archetype, SpinDirection};
|
||||
use crate::archetype::{Archetype, Builtin};
|
||||
use crate::glyph::Glyph;
|
||||
use crate::layer::Layer;
|
||||
use crate::object_def::ObjectDef;
|
||||
@@ -963,12 +967,7 @@ pub(crate) mod tests {
|
||||
#[test]
|
||||
fn expand_builtin_archetypes_replaces_a_spinner_cell_with_an_object() {
|
||||
let mut board = open_board(3, 1, (2, 0), vec![]);
|
||||
stamp(
|
||||
&mut board,
|
||||
0,
|
||||
0,
|
||||
Archetype::Spinner(SpinDirection::Clockwise),
|
||||
);
|
||||
stamp(&mut board, 0, 0, Archetype::Builtin(Builtin::Spinner, "spinner_cw"));
|
||||
board.expand_builtin_archetypes();
|
||||
|
||||
// The terrain cell is vacated and a scripted object takes its place.
|
||||
|
||||
Reference in New Issue
Block a user