wip
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
use std::collections::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::api::queue::ObjQueue;
|
||||
use crate::glyph::Glyph;
|
||||
use crate::object_def::ObjectDef;
|
||||
use crate::utils::{Behavior, ObjectId, Pushable};
|
||||
|
||||
/// The various ways that a tile might respond to another tile trying to move on top of it
|
||||
#[derive(Serialize, Deserialize, PartialEq, Copy, Clone, Debug)]
|
||||
pub enum EnterResponse {
|
||||
/// Flat denial: don't let the move happen, block it.
|
||||
Block,
|
||||
/// Call the `grab` hook and then remove this object.
|
||||
/// TODO will do something different once inventory exists as a concept
|
||||
Grab,
|
||||
/// Attempt to exit the cell ourselves, the opposite direction. This of course recurses; if our move
|
||||
/// is denied then this is the same as a block.
|
||||
Push(Pushable),
|
||||
/// Call an `enter` hook and do something. The hook is responsible for resolving the conflict:
|
||||
/// placing the moving-object somewhere else, moving ourselves somewhere else, or whatever.
|
||||
/// It should return `true` or `false`: this return value is passed back up a `Push` chain to
|
||||
/// the original moving object, determining whether the moves should happen.
|
||||
/// Example: a teleporter moves anything that enters it to another spot, if it's unblocked. It
|
||||
/// will check if the target cell is open and move the object there if it is, returning true.
|
||||
/// If you push a crate into it, it returning true means you should move (into the space the crate
|
||||
/// left behind); it returning false means the crate wasn't teleported so your move is blocked
|
||||
/// also.
|
||||
/// The hook return value is only used for _other_ things in the chain: regardless of what's returned,
|
||||
/// the engine won't touch the crate or the teleporter; the hook is responsible for handling the
|
||||
/// actual collision. A teleporter that teleports the crate and returns false will leave an empty
|
||||
/// space behind (the player won't move into it because it returned false); a teleporter that
|
||||
/// returns true without teleporting the crate, the crate will be destroyed by the player moving
|
||||
/// on top of it.
|
||||
Hook,
|
||||
/// Swap places with whatever moved on top of you
|
||||
Swap,
|
||||
/// Get overwritten and destroyed by whatever moved on top of us. Right now, equivalent to `Grab`
|
||||
/// if the hook does nothing (but in the future `Grab` will have other builtin behavior)
|
||||
Squish
|
||||
}
|
||||
|
||||
impl From<Behavior> for EnterResponse {
|
||||
fn from(behavior: Behavior) -> EnterResponse {
|
||||
if behavior.grab {
|
||||
EnterResponse::Grab
|
||||
} else if behavior.pushable != Pushable::No {
|
||||
EnterResponse::Push(behavior.pushable)
|
||||
} else if behavior.solid {
|
||||
EnterResponse::Block
|
||||
} else {
|
||||
EnterResponse::Squish
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Where `Sensor`s are drawn, in relation to the grid:
|
||||
/// - `Above` is above everything, including the player. If the glyph has a nonzero tile, and it's
|
||||
/// visible / lit, it will be drawn.
|
||||
/// - `Below` is below the grid but above the floor. A nonzero-tile-glyph will be drawn only if
|
||||
/// there's not a grid-thing in the same cell.
|
||||
#[derive(Serialize, Deserialize, PartialEq, Copy, Clone, Debug)]
|
||||
#[serde(rename = "lowercase")]
|
||||
pub enum DrawLayer { Above, Below }
|
||||
|
||||
/// How a thing interacts with the lighting and visibility models
|
||||
#[derive(Serialize, Deserialize, PartialEq, Copy, Clone, Debug)]
|
||||
#[serde(rename = "lowercase")]
|
||||
pub struct Optics {
|
||||
/// Opaque things block field of view
|
||||
pub opaque: bool,
|
||||
/// The brightness (in number of cells' radius) of light this
|
||||
/// emits. It will emit light in the color of the foreground of its glyph.
|
||||
/// A cell is visible if:
|
||||
/// - the level isn't dark, in which case lighting isn't calculated
|
||||
/// - the cell is within the field of view
|
||||
/// - the cell is within the glow radius of at least one light source
|
||||
///
|
||||
/// Its color will be tinted by the light sources illuminating it.
|
||||
pub glow: u32,
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
pub struct Scripting {
|
||||
/// Compile-key of the Rhai script that drives this object: a name in
|
||||
/// [`World::scripts`](crate::world::World::scripts) for a hand-authored object,
|
||||
/// 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>,
|
||||
/// 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.
|
||||
pub tags: HashSet<String>,
|
||||
/// Optional unique human-readable name for this object. `None` if unnamed.
|
||||
/// Names are validated for uniqueness at map-load time; a duplicate name is
|
||||
/// cleared to `None` (the object survives but becomes anonymous).
|
||||
pub name: Option<String>,
|
||||
/// The output queue of actions for this object
|
||||
pub queue: ObjQueue,
|
||||
}
|
||||
|
||||
/// A `Sensor` is some kind of object that exists alongside the map: it's drawn on the board but can't
|
||||
/// affect board movement, as it doesn't live in the grid.
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Sensor {
|
||||
/// The unique ID of this sensor
|
||||
pub id: ObjectId,
|
||||
/// Where it is on the board: x coord
|
||||
pub x: usize,
|
||||
/// Where it is on the board: y coord
|
||||
pub y: usize,
|
||||
/// What it looks like
|
||||
pub glyph: Glyph,
|
||||
/// Sensors interact with FOV and lighting
|
||||
pub optics: Optics,
|
||||
/// Sensors have scripting ability
|
||||
#[serde(skip)]
|
||||
pub scripting: Scripting,
|
||||
}
|
||||
Reference in New Issue
Block a user