summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/encyclopediae/default_encyclopedia.json29
-rw-r--r--content/encyclopediae/npcs.json2
-rw-r--r--content/maps/begin.json2
-rw-r--r--content/maps/smallview.json2
-rw-r--r--src/assemblage.rs5
-rw-r--r--src/componentwrapper.rs21
-rw-r--r--src/parameterexpression.rs3
-rw-r--r--src/room.rs7
-rw-r--r--src/systems/spawn.rs3
-rw-r--r--src/template.rs23
-rw-r--r--src/util.rs1
-rw-r--r--src/world.rs2
12 files changed, 69 insertions, 31 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index 2c88f45..25e3d32 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -7,14 +7,13 @@
],
"flags": ["Floor"]
},
- "homeportal": {
- "arguments": [["dedup_id", "string"], ["allowed", "list", ["list", []]], ["dedup_priority", "int", 0]],
- "extract": {"allowed": ["Whitelist", "allowed"], "dedup_priority": ["Dedup", "priority"]},
+ "_homeportal": {
+ "arguments": [["allowed", "list", ["list", []]]],
+ "extract": {"allowed": ["Whitelist", "allowed"]},
"components": [
["RoomExit", {"destination": "_home+{player}", "dest_pos": ""}],
["Interactable", {"typ": "visit", "arg": "_home+{player}"}],
- ["Whitelist", {"allowed": ["arg", "allowed"]}],
- ["Dedup", {"id": ["arg", "dedup_id"], "priority": ["arg", "dedup_priority"]}]
+ ["Whitelist", {"allowed": ["arg", "allowed"]}]
],
"flags": ["Floor"]
},
@@ -65,6 +64,23 @@
}]
]
},
+ "singleton": {
+ "arguments": [["ent", "template"], ["clan", "string", ""]],
+ "components": [
+ ["Spawner", {
+ "template": ["arg", "ent"],
+ "amount": 1,
+ "clan": ["arg", "clan"],
+ "radius": 0
+ }],
+ ["Timer", {
+ "delay": 999999999,
+ "spread": 0.0,
+ "trigger": "spawn",
+ "target_time": 0
+ }]
+ ]
+ },
"closeddoor": {
"sprite": "closeddoor",
"height": 2,
@@ -221,5 +237,8 @@
"sprite": "blueplayer"
}}
}
+ },
+ "templates": {
+ "homeportal": ["singleton", {"ent": {"type": "_homeportal"}}]
}
}
diff --git a/content/encyclopediae/npcs.json b/content/encyclopediae/npcs.json
index 02f13ad..592417c 100644
--- a/content/encyclopediae/npcs.json
+++ b/content/encyclopediae/npcs.json
@@ -68,7 +68,7 @@
["MonsterAI", {
"view_distance": 3,
"move_chance": 0.08,
- "homesickness": 0.1
+ "homesickness": 0.01
}],
["Movable", {"cooldown": 3}],
["Faction", {"faction": "neutral"}]
diff --git a/content/maps/begin.json b/content/maps/begin.json
index e01e866..d8f8efe 100644
--- a/content/maps/begin.json
+++ b/content/maps/begin.json
@@ -116,7 +116,7 @@
{"type": "img", "kwargs": {"sprite": "stairdown"}},
"floor"
],
- "r": ["grass", "rabbit"],
+ "r": ["grass", {"type": "singleton", "kwargs": {"ent": {"type": "rabbit"}}}],
"3": [{
"type": "portal",
"kwargs": {"destination": "smallview", "destpos": "begin"}
diff --git a/content/maps/smallview.json b/content/maps/smallview.json
index 49f48b4..3ddd9ac 100644
--- a/content/maps/smallview.json
+++ b/content/maps/smallview.json
@@ -61,7 +61,7 @@
"type": "portal",
"kwargs": {"destination": "town", "destpos": "gate"}
}, "floor"],
- "3": [{"type": "homeportal", "kwargs": {"dedup_id": "homeportal"}, "save": true}, "floor", {"type": "img", "kwargs": {"sprite": "portal", "height": 1.0}}],
+ "3": ["homeportal", "floor", {"type": "img", "kwargs": {"sprite": "portal", "height": 1.0}}],
"4": [{
"type": "portal",
"kwargs": {"destination": "room"}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index 80c10ab..82b25da 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -5,7 +5,7 @@ use crate::{
parameterexpression::ParameterExpression,
parameter::{Parameter, ParameterType},
componentwrapper::{ComponentWrapper, ComponentType},
- components::Serialise,
+ components::{Serialise, Clan},
Template,
Result as AnyResult,
aerr
@@ -76,6 +76,9 @@ impl Assemblage {
if template.should_save() && self.save {
components.push(ComponentWrapper::Serialise(Serialise{template: template.clone(), extract: self.extract.clone() }));
}
+ if let Some(clan) = &template.clan {
+ components.push(ComponentWrapper::Clan(Clan{name: clan.clone()}));
+ }
Ok(components)
}
}
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index 340d0c0..edcfee1 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -3,7 +3,6 @@ use std::collections::{HashMap, HashSet};
use serde::{Serialize, Deserialize};
use strum_macros::{EnumString, Display};
use specs::Builder;
-use rand::Rng;
use std::str::FromStr;
use crate::{
@@ -24,7 +23,8 @@ use crate::{
Template,
Pos,
Result,
- aerr
+ aerr,
+ errors
};
@@ -163,14 +163,8 @@ components!(all:
Spawner (amount: i64, clan: String, template: Template, radius: i64) {
Spawner{
amount: amount as usize,
- clan: Clan{name:
- if clan == "" {
- format!("$random({})", rand::thread_rng().gen::<u32>())
- } else {
- clan
- }
- },
- template: template.unsaved(),
+ clan: Clan{name: clan},
+ template: template,
saturated: false,
radius
}
@@ -230,6 +224,13 @@ components!(all:
}
};
Substitute (into: Template);
+ TriggerBox (triggers: Vec<String>) {
+ TriggerBox {
+ messages: triggers.iter().map(|s|
+ Trigger::from_str(s).map_err(|_|aerr!("invalid trigger name {}", s))
+ ).collect::<std::result::Result<Vec<Trigger>, std::boxed::Box<errors::AError>>>()?
+ }
+ };
);
diff --git a/src/parameterexpression.rs b/src/parameterexpression.rs
index b8d1cba..5a313f7 100644
--- a/src/parameterexpression.rs
+++ b/src/parameterexpression.rs
@@ -57,7 +57,8 @@ impl ParameterExpression {
.map(
|(k, v)|
Some((k.clone(), v.evaluate_(arguments, template, nesting+1)?)))
- .collect::<Option<HashMap<String, Parameter>>>()?
+ .collect::<Option<HashMap<String, Parameter>>>()?,
+ clan: None
}))
}
Self::Argument(argname) => {
diff --git a/src/room.rs b/src/room.rs
index db2171a..23545c0 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -31,7 +31,8 @@ use crate::{
Player,
Inventory,
Health,
- Removed
+ Removed,
+ Clan
},
Encyclopedia,
roomtemplate::RoomTemplate,
@@ -207,8 +208,9 @@ impl <'a, 'b>Room<'a, 'b> {
let entities = self.world.entities();
let positions = self.world.read_component::<Position>();
let serialisers = self.world.read_component::<Serialise>();
+ let clans = self.world.read_component::<Clan>();
let mut state = SaveState::new();
- for (entity, pos, serialiser) in (&entities, &positions, &serialisers).join() {
+ for (entity, pos, serialiser, clan) in (&entities, &positions, &serialisers, (&clans).maybe()).join() {
let mut template = serialiser.template.clone();
for (argument, component, member) in &serialiser.extract {
if let Some(parameter) = extract_parameter(*component, member.as_str(), &self.world, entity){
@@ -217,6 +219,7 @@ impl <'a, 'b>Room<'a, 'b> {
println!("failed to extract parameter {:?} from {:?}", member, component);
}
}
+ template.clan = clan.map(|c| c.name.clone());
state.changes.entry(pos.pos).or_insert_with(Vec::new).push(template);
}
state
diff --git a/src/systems/spawn.rs b/src/systems/spawn.rs
index f0a7aaa..284c2ab 100644
--- a/src/systems/spawn.rs
+++ b/src/systems/spawn.rs
@@ -49,6 +49,9 @@ impl <'a> System<'a> for Spawn {
}
let mut rng = rand::thread_rng();
for (entity, spawner, position, triggerbox) in (&entities, &mut spawners, &positions, &triggerboxes).join() {
+ if spawner.clan.name == "" {
+ spawner.clan.name = format!("$random({},{},{})", position.pos.x, position.pos.y, spawner.template.name.0);
+ }
if triggerbox.has_message(&[Trigger::Spawn]) {
if *clan_nums.get(&spawner.clan).unwrap_or(&0) < spawner.amount {
if spawner.saturated {
diff --git a/src/template.rs b/src/template.rs
index 5d753a1..1475d42 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -22,7 +22,9 @@ enum TemplateSave {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
kwargs: HashMap<String, Parameter>,
#[serde(default, skip_serializing_if = "Option::is_none")]
- save: Option<bool>
+ save: Option<bool>,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ clan: Option<String>
}
}
@@ -33,27 +35,29 @@ pub struct Template {
pub args: Vec<Parameter>,
pub kwargs: HashMap<String, Parameter>,
pub save: Option<bool>,
+ pub clan: Option<String>
}
impl From<TemplateSave> for Template {
fn from(ts: TemplateSave) -> Self {
match ts {
- TemplateSave::Name(name) => Self{name, args: Vec::new(), kwargs: HashMap::new(), save: None},
- TemplateSave::Full{name, args, kwargs, save} => Self{name, args, kwargs, save}
+ TemplateSave::Name(name) => Self{name, args: Vec::new(), kwargs: HashMap::new(), save: None, clan: None},
+ TemplateSave::Full{name, args, kwargs, save, clan} => Self{name, args, kwargs, save, clan}
}
}
}
impl Into<TemplateSave> for Template {
fn into(self) -> TemplateSave {
- if self.args.is_empty() && self.kwargs.is_empty() && self.save == None {
+ if self.args.is_empty() && self.kwargs.is_empty() && self.save == None && self.clan == None {
return TemplateSave::Name(self.name);
}
TemplateSave::Full {
name: self.name,
args: self.args,
kwargs: self.kwargs,
- save: self.save
+ save: self.save,
+ clan: self.clan
}
}
}
@@ -65,7 +69,8 @@ impl Template {
name: EntityType(name.to_string()),
args: Vec::new(),
kwargs,
- save: None
+ save: None,
+ clan: None
}
}
@@ -85,7 +90,8 @@ impl Template {
name: typ,
args: Vec::new(),
kwargs: HashMap::new(),
- save: None
+ save: None,
+ clan: None
}
}
@@ -100,6 +106,9 @@ impl Template {
if self.save == None {
self.save = other.save;
}
+ if self.clan == None {
+ self.clan = other.clan;
+ }
for (key, value) in other.kwargs {
self.kwargs.entry(key).or_insert(value);
}
diff --git a/src/util.rs b/src/util.rs
index 02c282c..4dc9402 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -38,7 +38,6 @@ pub fn write_file_safe<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) ->
}
-
#[macro_export]
macro_rules! hashmap {
( $($key:expr => $value:expr ),* ) => {{
diff --git a/src/world.rs b/src/world.rs
index b9af6df..24fe392 100644
--- a/src/world.rs
+++ b/src/world.rs
@@ -111,7 +111,7 @@ impl <'a, 'b>World<'a, 'b> {
fn try_add_loaded_player(&mut self, mut state: PlayerState, backups: &[Option<RoomId>]) -> Result<()> {
match self.add_loaded_player(state.clone()){
Err(MigrationError::RoomError(e)) => {
- println!("could not add player {:?} to room {:?}: {:?}", state.id, state.room, e);
+ println!("could not add player {:?} to room {:?}: {}", state.id, state.room, e);
if let Some((first, rest)) = backups.split_first(){
state.room = first.clone();
state.pos = RoomPos::Unknown;