better scripting api
This commit is contained in:
+20
-5
@@ -1,10 +1,11 @@
|
||||
use crate::action::Action;
|
||||
use crate::log::LogLine;
|
||||
use crate::script::ScriptHost;
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use crate::board::Board;
|
||||
use crate::utils::{Action, Direction, ObjectId, Solid};
|
||||
use crate::utils::{Direction, ObjectId, ScriptArg, Solid};
|
||||
|
||||
/// How long a `say()` speech bubble stays on screen, in seconds.
|
||||
pub const SAY_DURATION: f64 = 3.0;
|
||||
@@ -105,17 +106,19 @@ impl GameState {
|
||||
}
|
||||
|
||||
/// Resolves the board queue: applies each promoted action to the board, then fires
|
||||
/// the `bump` hooks the moves triggered.
|
||||
/// the `bump` and `send` hooks the moves triggered.
|
||||
///
|
||||
/// Done in two phases so no `board_mut` borrow is held while `bump` scripts run
|
||||
/// Done in two phases so no `board_mut` borrow is held while scripts run
|
||||
/// (they read the board through its getters): phase A mutates the board and records
|
||||
/// `(bumped_object, bumper)` pairs; phase B fires the bumps after the borrow drops.
|
||||
/// `(bumped, bumper)` and `(send_target, fn_name, arg)` tuples; phase B fires the
|
||||
/// hooks after the borrow drops.
|
||||
fn resolve(&mut self) {
|
||||
let actions = self.scripts.take_board_queue();
|
||||
// Logs are collected here rather than pushed inline, since the board borrow
|
||||
// below also borrows `self`.
|
||||
let mut logs: Vec<LogLine> = Vec::new();
|
||||
let mut bumps: Vec<(ObjectId, i64)> = Vec::new();
|
||||
let mut sends: Vec<(ObjectId, String, Option<ScriptArg>)> = Vec::new();
|
||||
let mut new_bubbles: Vec<SpeechBubble> = Vec::new();
|
||||
{
|
||||
let mut board = self.board_mut();
|
||||
@@ -146,7 +149,16 @@ impl GameState {
|
||||
}),
|
||||
// Delays are consumed by ScriptHost::drain and never reach the board queue.
|
||||
Action::Delay(_) => {}
|
||||
|
||||
Action::SetColor { fg, bg } => {
|
||||
if let Some(obj) = board.objects.get_mut(&ba.source) {
|
||||
if let Some(c) = fg { obj.glyph.fg = c; }
|
||||
if let Some(c) = bg { obj.glyph.bg = c; }
|
||||
}
|
||||
}
|
||||
// Collected and fired after the board borrow drops, like bumps.
|
||||
Action::Send { target, fn_name, arg } => {
|
||||
sends.push((target, fn_name, arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,6 +171,9 @@ impl GameState {
|
||||
for (bumped, bumper) in bumps {
|
||||
self.scripts.run_bump(bumped, bumper);
|
||||
}
|
||||
for (target, fn_name, arg) in sends {
|
||||
self.scripts.run_send(target, &fn_name, arg);
|
||||
}
|
||||
self.drain_errors();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user