object tags
This commit is contained in:
+59
-4
@@ -51,6 +51,9 @@ pub enum Action {
|
||||
SetTile(u32),
|
||||
/// Append a plain (uncolored) line to the game log.
|
||||
Log(LogLine),
|
||||
/// Add (`present = true`) or remove (`present = false`) `tag` on `target`.
|
||||
/// Zero-cost; applied by [`crate::game::GameState`] after the action batch.
|
||||
SetTag { target: ObjectId, tag: String, present: bool },
|
||||
}
|
||||
|
||||
impl Action {
|
||||
@@ -61,7 +64,7 @@ impl Action {
|
||||
pub fn time_cost(&self) -> f64 {
|
||||
match self {
|
||||
Action::Move(_) => MOVE_COST,
|
||||
Action::SetTile(_) | Action::Log(_) => 0.0,
|
||||
Action::SetTile(_) | Action::Log(_) | Action::SetTag { .. } => 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,7 +241,7 @@ impl ScriptHost {
|
||||
objects.push(ObjectRuntime {
|
||||
object_id: id,
|
||||
script_name: name.clone(),
|
||||
scope: new_object_scope(board_cell, &queue),
|
||||
scope: new_object_scope(board_cell, &queue, id),
|
||||
output_queue: queue,
|
||||
ready_timer: 0.0,
|
||||
});
|
||||
@@ -422,6 +425,38 @@ fn register_read_api(engine: &mut Engine, board: &BoardRef, board_queue: &BoardQ
|
||||
engine.register_fn("blocked", move |ctx: NativeCallContext, dir: Direction| {
|
||||
is_blocked(&b, &bq, source_of(&ctx), dir)
|
||||
});
|
||||
|
||||
// has_tag(s) -> bool: does the calling object have this tag?
|
||||
let b = board.clone();
|
||||
engine.register_fn("has_tag", move |ctx: NativeCallContext, tag: ImmutableString| {
|
||||
let src = source_of(&ctx);
|
||||
b.borrow().objects.get(&src).map_or(false, |o| o.tags.contains(tag.as_str()))
|
||||
});
|
||||
|
||||
// get_tags() -> Array of strings: the calling object's current tag set.
|
||||
let b = board.clone();
|
||||
engine.register_fn("get_tags", move |ctx: NativeCallContext| -> rhai::Array {
|
||||
let src = source_of(&ctx);
|
||||
b.borrow()
|
||||
.objects
|
||||
.get(&src)
|
||||
.map(|o| o.tags.iter().map(|t| rhai::Dynamic::from(t.clone())).collect())
|
||||
.unwrap_or_default()
|
||||
});
|
||||
|
||||
// objects_with_tag(s) -> Array of i64: ids of all objects carrying the tag.
|
||||
let b = board.clone();
|
||||
engine.register_fn(
|
||||
"objects_with_tag",
|
||||
move |_ctx: NativeCallContext, tag: ImmutableString| -> rhai::Array {
|
||||
b.borrow()
|
||||
.objects
|
||||
.iter()
|
||||
.filter(|(_, o)| o.tags.contains(tag.as_str()))
|
||||
.map(|(&id, _)| rhai::Dynamic::from(id as i64))
|
||||
.collect()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Whether the object at `source` would bump something by moving in `dir`.
|
||||
@@ -489,6 +524,24 @@ fn register_write_api(engine: &mut Engine, queues: &QueueMap) {
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
// set_tag(target_id, tag, present): add (true) or remove (false) a tag on any object.
|
||||
// Use MY_ID as target_id to mutate the calling object's own tags.
|
||||
let q = queues.clone();
|
||||
engine.register_fn(
|
||||
"set_tag",
|
||||
move |ctx: NativeCallContext, target: i64, tag: ImmutableString, present: bool| {
|
||||
emit(
|
||||
&q,
|
||||
source_of(&ctx),
|
||||
Action::SetTag {
|
||||
target: target as ObjectId,
|
||||
tag: tag.to_string(),
|
||||
present,
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Registers the `Queue` object: a handle to an object's output queue with `length()`
|
||||
@@ -519,8 +572,9 @@ fn source_of(ctx: &NativeCallContext) -> ObjectId {
|
||||
}
|
||||
|
||||
/// Builds a fresh per-object scope, seeded with the read-only `Board` view, this
|
||||
/// object's `Queue`, and the four direction constants (`North`/`South`/`East`/`West`).
|
||||
fn new_object_scope(board: &BoardRef, queue: &ObjQueue) -> Scope<'static> {
|
||||
/// object's `Queue`, the four direction constants, and `MY_ID` (the object's own
|
||||
/// stable [`ObjectId`] as `i64`, for use with `set_tag` and similar calls).
|
||||
fn new_object_scope(board: &BoardRef, queue: &ObjQueue, object_id: ObjectId) -> Scope<'static> {
|
||||
let mut scope = Scope::new();
|
||||
scope.push_constant("Board", board.clone());
|
||||
scope.push_constant("Queue", queue.clone());
|
||||
@@ -528,5 +582,6 @@ fn new_object_scope(board: &BoardRef, queue: &ObjQueue) -> Scope<'static> {
|
||||
scope.push_constant("South", Direction::South);
|
||||
scope.push_constant("East", Direction::East);
|
||||
scope.push_constant("West", Direction::West);
|
||||
scope.push_constant("MY_ID", object_id as i64);
|
||||
scope
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user