Fixed three script host bugs; scriptkey
This commit is contained in:
+42
-12
@@ -1,7 +1,8 @@
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::api::queue::ObjQueue;
|
||||
use crate::{Builtin, Direction};
|
||||
use crate::builtin::BUILTIN_SOURCES;
|
||||
use crate::floor::{Floor, FloorBiome};
|
||||
use crate::glyph::Glyph;
|
||||
use crate::object_def::ObjectDef;
|
||||
@@ -117,6 +118,38 @@ const fn default_as_below() -> DrawLayer {
|
||||
DrawLayer::Below
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Debug, Default)]
|
||||
pub enum ScriptKey {
|
||||
#[default]
|
||||
None,
|
||||
World(String),
|
||||
Builtin(&'static str),
|
||||
}
|
||||
|
||||
impl ScriptKey {
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
ScriptKey::None => "<none>",
|
||||
ScriptKey::World(name) => name.as_str(),
|
||||
ScriptKey::Builtin(name) => *name
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source<'a>(&self, sources: &'a HashMap<String, String>) -> Option<&'a str> {
|
||||
match self {
|
||||
ScriptKey::None => None,
|
||||
ScriptKey::World(name) => sources.get(name).map(String::as_str),
|
||||
key @ ScriptKey::Builtin(_) => BUILTIN_SOURCES.get(key).copied(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<String>> for ScriptKey {
|
||||
fn from(s: Option<String>) -> Self {
|
||||
s.map_or(Self::None, |s| Self::World(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// Everything an object-or-sensor needs to have a Rhai script attached.
|
||||
/// TODO clean this up some, especially the script_name-vs-builtin_script dichotomy
|
||||
#[derive(Clone, Default)]
|
||||
@@ -136,14 +169,13 @@ pub struct ScriptAttributes {
|
||||
/// or a synthetic `BUILTIN_*` name set when a script-backed archetype is
|
||||
/// expanded (see [`builtin_script`](ObjectDef::builtin_script)). `None` means
|
||||
/// this object has no script yet.
|
||||
pub script_name: Option<String>,
|
||||
pub script_name: ScriptKey,
|
||||
/// Embedded built-in script source, set when a script-backed archetype (e.g. a
|
||||
/// `pusher_*` or `gem`) is expanded into an object at load time (see
|
||||
/// [`crate::builtin_scripts`]). When set, this is the object's script *source*
|
||||
/// (its compile-key is the synthetic `BUILTIN_*` [`script_name`](ObjectDef::script_name)
|
||||
/// the same expansion assigns). Not part of the map file — it is regenerated
|
||||
/// from the archetype on load.
|
||||
pub builtin_script: Option<&'static str>,
|
||||
/// Open-ended string labels for this object. Serialized as a TOML array;
|
||||
/// not subject to any rate limit — mutations take effect immediately after
|
||||
/// the frame's action queue is drained.
|
||||
@@ -202,7 +234,7 @@ impl SensorSpec {
|
||||
optics: self.optics,
|
||||
name: self.name,
|
||||
tags: self.tags.into_iter().collect(),
|
||||
script_name: self.script,
|
||||
script_name: self.script.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@@ -234,8 +266,8 @@ pub trait Hookable {
|
||||
/// for an expanded built-in (so identical built-ins share one compiled AST,
|
||||
/// while the source still comes from `builtin_script`). `None` if the object has
|
||||
/// no script.
|
||||
fn script_key(&self) -> Option<&String> {
|
||||
self.scriptable().script_name.as_ref()
|
||||
fn script_key(&self) -> &ScriptKey {
|
||||
&self.scriptable().script_name
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,8 +378,7 @@ impl IntoTile for TileSpec {
|
||||
id: *next_object_id,
|
||||
glyph,
|
||||
optics,
|
||||
script_name: script,
|
||||
builtin_script: None,
|
||||
script_name: script.into(),
|
||||
tags: tags.into_iter().collect(),
|
||||
name,
|
||||
queue: ObjQueue::new(),
|
||||
@@ -365,8 +396,7 @@ impl IntoTile for TileSpec {
|
||||
id: *next_object_id,
|
||||
glyph: glyph.unwrap_or(builtin.default_glyph_for(variant)),
|
||||
optics: builtin.optics(),
|
||||
script_name: None,
|
||||
builtin_script: Some(builtin.script()),
|
||||
script_name: builtin.script(),
|
||||
tags: HashSet::from([format!("BUILTIN_{}", variant)]),
|
||||
name: None,
|
||||
queue: ObjQueue::new(),
|
||||
@@ -389,10 +419,10 @@ impl TileSpec {
|
||||
TileSpec::Builtin { kind: "wall".to_string(), glyph: None }
|
||||
}
|
||||
pub fn player() -> Self {
|
||||
TileSpec::Builtin { kind: "wall".to_string(), glyph: None }
|
||||
TileSpec::Player
|
||||
}
|
||||
pub fn krate() -> Self {
|
||||
TileSpec::Builtin { kind: "wall".to_string(), glyph: None }
|
||||
TileSpec::Builtin { kind: "crate".to_string(), glyph: None }
|
||||
}
|
||||
pub fn gem() -> Self {
|
||||
TileSpec::Builtin { kind: "gem".to_string(), glyph: None }
|
||||
|
||||
Reference in New Issue
Block a user