summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components.rs11
-rw-r--r--src/componentwrapper.rs13
-rw-r--r--src/encyclopedia.rs12
-rw-r--r--src/main.rs7
-rw-r--r--src/parameter.rs2
-rw-r--r--src/resources.rs8
-rw-r--r--src/room.rs50
-rw-r--r--src/systems/controlinput.rs26
-rw-r--r--src/systems/create.rs51
-rw-r--r--src/systems/makefloor.rs35
-rw-r--r--src/systems/mod.rs4
-rw-r--r--src/systems/moving.rs24
-rw-r--r--src/systems/remove.rs27
-rw-r--r--src/systems/view.rs6
14 files changed, 198 insertions, 78 deletions
diff --git a/src/components.rs b/src/components.rs
index 34dbe97..5bd6ddd 100644
--- a/src/components.rs
+++ b/src/components.rs
@@ -45,6 +45,17 @@ pub struct Blocking;
pub struct Floor;
#[derive(Component, Debug, Clone)]
+pub struct New;
+
+#[derive(Component, Debug, Clone)]
+pub struct Removed;
+
+#[derive(Component, Debug, Clone)]
+pub struct Moved {
+ pub from: Pos
+}
+
+#[derive(Component, Debug, Clone)]
#[storage(HashMapStorage)]
pub struct Player {
pub name: String,
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index 8bf8552..e821b8b 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -1,9 +1,8 @@
use std::collections::HashMap;
-use specs::{Builder, EntityBuilder};
+use specs::{Builder, world::LazyBuilder};
use crate::components::{Visible, Blocking, Player, Floor};
-use crate::hashmap;
use crate::parameter::{Parameter, ParameterType};
@@ -20,7 +19,7 @@ macro_rules! components {
impl ComponentWrapper {
- pub fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a> {
+ pub fn build<'a>(&self, builder: LazyBuilder<'a>) -> LazyBuilder<'a> {
match self.clone() {
$(
Self::$comp(c) => builder.with(c),
@@ -28,11 +27,12 @@ macro_rules! components {
}
}
- pub fn load_component(comptype: ComponentType, mut parameters_: HashMap<&str, Parameter>) -> Option<Self> {
+ pub fn load_component(comptype: ComponentType, parameters_: HashMap<&str, Parameter>) -> Option<Self> {
match comptype {
$(
ComponentType::$comp => Some(Self::$comp({
+ #[allow(unused_mut)]
let mut $paramlist = parameters_;
$creation
})),
@@ -63,6 +63,7 @@ macro_rules! components {
match self {
$(
Self::$comp => {
+ #[allow(unused_mut)]
let mut h = HashMap::new();
$(
h.insert(stringify!($paramname), ParameterType::$paramtype);
@@ -82,8 +83,8 @@ components!(
height: parameters.remove("height")?.as_f64()?
}
};
- Blocking [] p {Blocking};
- Floor [] p {Floor};
+ Blocking [] _p {Blocking};
+ Floor [] _p {Floor};
Player [name: String] parameters {Player::new(parameters.remove("name")?.as_string()?)}
);
diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs
index 19d4297..5cdf90c 100644
--- a/src/encyclopedia.rs
+++ b/src/encyclopedia.rs
@@ -12,12 +12,6 @@ pub struct Encyclopedia {
impl Encyclopedia {
- pub fn new() -> Encyclopedia {
- Encyclopedia {
- items: HashMap::new()
- }
- }
-
pub fn from_json(val: Value) -> Result<Encyclopedia, &'static str> {
let mut items = HashMap::new();
for (k, v) in val.as_object().ok_or("encyclopedia not a json object")?.into_iter() {
@@ -26,12 +20,6 @@ impl Encyclopedia {
Ok(Encyclopedia{items})
}
- pub fn add_assemblage(&mut self, name: &str, assemblage: Assemblage) -> Result<(), &'static str> {
- //todo: what if name exists
- self.items.insert(name.to_string(), assemblage);
- Ok(())
- }
-
pub fn construct(&self, template: &Template) -> Result<Vec<ComponentWrapper>, &'static str> {
let assemblage = self.items.get(&template.name).ok_or("unknown assemblage name")?;
assemblage.instantiate(&template.args, &template.kwargs)
diff --git a/src/main.rs b/src/main.rs
index 65d744a..d2cfd13 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -38,20 +38,23 @@ use self::roomtemplate::RoomTemplate;
fn main() {
+ let mut servers: Vec<Box<dyn Server>> = Vec::new();
let addr = Path::new("\0rustifarm");
let unixserver = UnixServer::new(&addr).expect("binding unix server failed");
+ servers.push(Box::new(unixserver));
let addr = "127.0.0.1:1234".parse().unwrap();
let inetserver = TcpServer::new(&addr).expect("binding inet server failed");
+ servers.push(Box::new(inetserver));
-
- let servers: Vec<Box<dyn Server>> = vec![Box::new(unixserver), Box::new(inetserver)];
let mut gameserver = GameServer::new(servers);
let mut room = gen_room();
+ println!("asciifarm started");
+
loop {
let actions = gameserver.update();
diff --git a/src/parameter.rs b/src/parameter.rs
index 6d15e93..41137bb 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -11,6 +11,7 @@ pub enum Parameter {
impl Parameter {
+ #[allow(dead_code)]
pub fn string(string: &str) -> Self {
Self::String(string.to_string())
}
@@ -58,6 +59,7 @@ impl Parameter {
Some(self.as_str()?.to_string())
}
+ #[allow(dead_code)]
pub fn as_i64(&self) -> Option<i64> {
if let Self::Int(num) = self {
Some(*num)
diff --git a/src/resources.rs b/src/resources.rs
index bda745f..15d93c4 100644
--- a/src/resources.rs
+++ b/src/resources.rs
@@ -1,5 +1,5 @@
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use specs::Entity;
use super::pos::Pos;
@@ -7,6 +7,7 @@ use super::controls::Action;
// use super::oldassemblage::Assemblage;
use super::worldmessages::WorldMessage;
use super::template::Template;
+use crate::encyclopedia::Encyclopedia;
#[derive(Default)]
@@ -32,10 +33,11 @@ pub struct Spawn {
#[derive(Default)]
pub struct Ground {
- pub cells: HashMap<Pos, Vec<Entity>>
+ pub cells: HashMap<Pos, HashSet<Entity>>
}
#[derive(Default)]
pub struct NewEntities {
- pub templates: Vec<(Pos, Template)>
+ pub templates: Vec<(Pos, Template)>,
+ pub encyclopedia: Encyclopedia
}
diff --git a/src/room.rs b/src/room.rs
index dc7c849..84a1040 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -4,15 +4,12 @@ use std::collections::HashMap;
use specs::{
World,
WorldExt,
- Builder,
DispatcherBuilder,
- Dispatcher,
- Entity
+ Dispatcher
};
use super::controls::Action;
use super::pos::Pos;
-use super::components::Position;
use super::worldmessages::WorldMessage;
use super::resources::{
Size,
@@ -23,35 +20,38 @@ use super::resources::{
};
use super::systems::{
moving::Move,
- clearcontrols::ClearControllers,
makefloor::MakeFloor,
controlinput::ControlInput,
- view::View
+ view::View,
+ remove::Remove,
+ create::Create
};
-use super::componentwrapper::ComponentWrapper;
use crate::encyclopedia::Encyclopedia;
-use crate::template::Template;
use crate::roomtemplate::RoomTemplate;
pub struct Room<'a, 'b> {
world: World,
- dispatcher: Dispatcher<'a, 'b>,
- encyclopedia: Encyclopedia
+ dispatcher: Dispatcher<'a, 'b>
}
impl <'a, 'b>Room<'a, 'b> {
pub fn new(encyclopedia: Encyclopedia) -> Room<'a, 'b> {
let mut world = World::new();
+ world.insert(NewEntities{
+ templates: Vec::new(),
+ encyclopedia
+ });
let mut dispatcher = DispatcherBuilder::new()
.with(ControlInput, "controlinput", &[])
- .with(MakeFloor, "makefloor", &[])
+ .with(MakeFloor::default(), "makefloor", &[])
.with(Move, "move", &["makefloor", "controlinput"])
- .with(ClearControllers, "clearcontrollers", &["move"])
.with(View::default(), "view", &["move"])
+ .with(Create, "create", &["view", "controlinput"])
+ .with(Remove, "remove", &["view", "move"])
.build();
dispatcher.setup(&mut world);
@@ -59,8 +59,7 @@ impl <'a, 'b>Room<'a, 'b> {
Room {
world,
- dispatcher,
- encyclopedia
+ dispatcher
}
}
@@ -77,9 +76,7 @@ impl <'a, 'b>Room<'a, 'b> {
let y = (idx as i64) / width;
for template in templates {
- if let Err(msg) = self.add_entity(template, Pos{x, y}){
- println!("{}", msg);
- }
+ self.world.fetch_mut::<NewEntities>().templates.push((Pos{x, y}, template.clone()));
}
}
}
@@ -90,13 +87,6 @@ impl <'a, 'b>Room<'a, 'b> {
pub fn update(&mut self) {
self.dispatcher.dispatch(&mut self.world);
- let templates = self.world.remove::<NewEntities>().unwrap_or(NewEntities::default()).templates;
- self.world.insert(NewEntities::default());
- for (pos, template) in templates{
- if let Err(msg) = self.add_entity(&template, pos){
- println!("failed to add entity {:?}: {}", template, msg);
- }
- }
self.world.maintain();
}
@@ -104,18 +94,6 @@ impl <'a, 'b>Room<'a, 'b> {
self.world.fetch_mut::<Input>().actions = actions;
}
- pub fn add_entity(&mut self, template: &Template, pos: Pos) -> Result<Entity, &'static str> {
- let preentity = self.encyclopedia.construct(template)?;
- Ok(self.add_complist(&preentity, pos))
- }
-//
- pub fn add_complist(&mut self, template: &Vec<ComponentWrapper>, pos: Pos) -> Entity{
- let mut builder = self.world.create_entity();
- for comp in template {
- builder = comp.build(builder);
- }
- builder.with(Position::new(pos)).build()
- }
}
diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs
index 27ef5cf..0771b1e 100644
--- a/src/systems/controlinput.rs
+++ b/src/systems/controlinput.rs
@@ -11,7 +11,7 @@ use specs::{
Join
};
-use crate::components::{Controller, Player};
+use crate::components::{Controller, Player, Removed};
use crate::controls::{Control, Action};
use crate::resources::{Input, NewEntities, Spawn};
use crate::hashmap;
@@ -23,8 +23,26 @@ use crate::parameter::Parameter;
pub struct ControlInput;
impl <'a> System<'a> for ControlInput {
- type SystemData = (Entities<'a>, Read<'a, Input>, WriteStorage<'a, Controller>, ReadStorage<'a, Player>, Write<'a, NewEntities>, Read<'a, Spawn>);
- fn run(&mut self, (entities, input, mut controllers, players, mut new, spawn): Self::SystemData) {
+ type SystemData = (
+ Entities<'a>,
+ Read<'a, Input>,
+ WriteStorage<'a, Controller>,
+ ReadStorage<'a, Player>,
+ Write<'a, NewEntities>,
+ Read<'a, Spawn>,
+ WriteStorage<'a, Removed>
+ );
+ fn run(&mut self, (entities, input, mut controllers, players, mut new, spawn, mut removed): Self::SystemData) {
+ {
+ let mut ents = Vec::new();
+ for (ent, _controller) in (&*entities, &controllers).join() {
+ ents.push(ent);
+ }
+ for ent in ents {
+ controllers.remove(ent);
+ }
+ }
+
let mut playercontrols: HashMap<&str, Control> = HashMap::new();
let mut leaving = HashSet::new();
for action in &input.actions {
@@ -44,7 +62,7 @@ impl <'a> System<'a> for ControlInput {
let _ = controllers.insert(entity, Controller(control.clone()));
}
if leaving.contains(&player.name) {
- let _ = entities.delete(entity);
+ let _ = removed.insert(entity, Removed);
}
}
}
diff --git a/src/systems/create.rs b/src/systems/create.rs
new file mode 100644
index 0000000..35ef747
--- /dev/null
+++ b/src/systems/create.rs
@@ -0,0 +1,51 @@
+
+use specs::{
+ Read,
+ Write,
+ WriteStorage,
+ System,
+ Join,
+ Entities,
+ LazyUpdate,
+ Builder
+};
+
+use crate::components::{New, Position};
+use crate::resources::{NewEntities};
+
+
+
+pub struct Create;
+impl <'a> System<'a> for Create {
+ type SystemData = (
+ Entities<'a>,
+ Write<'a, NewEntities>,
+ Read<'a, LazyUpdate>,
+ WriteStorage<'a, New>
+ );
+
+ fn run(&mut self, (entities, mut new_entities, updater, mut new): Self::SystemData) {
+ {
+ let mut ents = Vec::new();
+ for (ent, _new) in (&entities, &new).join() {
+ ents.push(ent);
+ }
+ for ent in ents {
+ new.remove(ent);
+ }
+ }
+ for (pos, template) in &new_entities.templates {
+ let mut builder = updater.create_entity(&entities);
+ match new_entities.encyclopedia.construct(template) {
+ Ok(comps) => {
+ for comp in comps {
+ builder = comp.build(builder);
+ }
+ builder.with(Position::new(*pos)).with(New).build();
+ },
+ Err(msg) => {println!("{}", msg);}
+ }
+ }
+ new_entities.templates.clear();
+ }
+}
diff --git a/src/systems/makefloor.rs b/src/systems/makefloor.rs
index 8b550bc..74e4389 100644
--- a/src/systems/makefloor.rs
+++ b/src/systems/makefloor.rs
@@ -1,4 +1,5 @@
+use std::collections::HashSet;
use specs::{
ReadStorage,
@@ -8,20 +9,40 @@ use specs::{
Join
};
-use super::super::components::Position;
+use crate::components::{
+ Position,
+ New,
+ Moved,
+ Removed
+};
-use super::super::resources::{
+use crate::resources::{
Ground
};
+#[derive(Default)]
pub struct MakeFloor;
impl <'a> System<'a> for MakeFloor {
- type SystemData = (Entities<'a>, Write<'a, Ground>, ReadStorage<'a, Position>);
- fn run(&mut self, (entities, mut ground, positions): Self::SystemData) {
- ground.cells.clear();
- for (ent, pos) in (&entities, &positions).join() {
- ground.cells.entry(pos.pos).or_insert(Vec::new()).push(ent);
+ type SystemData = (
+ Entities<'a>,
+ Write<'a, Ground>,
+ ReadStorage<'a, Position>,
+ ReadStorage<'a, New>,
+ ReadStorage<'a, Moved>,
+ ReadStorage<'a, Removed>
+ );
+ fn run(&mut self, (entities, mut ground, positions, new, moved, removed): Self::SystemData) {
+ for (ent, pos, _new) in (&entities, &positions, &new).join() {
+ ground.cells.entry(pos.pos).or_insert(HashSet::new()).insert(ent);
+ }
+ for (ent, pos, mov) in (&entities, &positions, &moved).join() {
+ ground.cells.entry(pos.pos).or_insert(HashSet::new()).insert(ent);
+ ground.cells.get_mut(&mov.from).unwrap().remove(&ent);
+ }
+ for (ent, pos, _removed) in (&entities, &positions, &removed).join() {
+ ground.cells.get_mut(&pos.pos).unwrap().remove(&ent);
}
}
}
+
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index 0382e39..a4dd473 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -1,8 +1,10 @@
-pub mod clearcontrols;
+// pub mod clearcontrols;
pub mod controlinput;
pub mod makefloor;
pub mod moving;
pub mod view;
+pub mod remove;
+pub mod create;
diff --git a/src/systems/moving.rs b/src/systems/moving.rs
index 28c3d3f..35f73ea 100644
--- a/src/systems/moving.rs
+++ b/src/systems/moving.rs
@@ -1,5 +1,8 @@
+use std::collections::HashSet;
+
use specs::{
+ Entities,
ReadStorage,
WriteStorage,
Read,
@@ -13,7 +16,8 @@ use super::super::components::{
Controller,
Blocking,
Position,
- Floor
+ Floor,
+ Moved
};
use super::super::controls::{
@@ -30,22 +34,33 @@ use super::super::resources::{
pub struct Move;
impl <'a> System<'a> for Move {
type SystemData = (
+ Entities<'a>,
ReadStorage<'a, Controller>,
WriteStorage<'a, Position>,
Read<'a, Size>,
ReadStorage<'a, Blocking>,
Read<'a, Ground>,
ReadStorage<'a, Floor>,
+ WriteStorage<'a, Moved>
);
- fn run(&mut self, (controllers, mut positions, size, blocking, ground, floor): Self::SystemData) {
- for (controller, mut pos) in (&controllers, &mut positions.restrict_mut()).join(){
+ fn run(&mut self, (entities, controllers, mut positions, size, blocking, ground, floor, mut moved): Self::SystemData) {
+ {
+ let mut ents = Vec::new();
+ for (ent, _moved) in (&*entities, &moved).join() {
+ ents.push(ent);
+ }
+ for ent in ents {
+ moved.remove(ent);
+ }
+ }
+ for (ent, controller, mut pos) in (&entities, &controllers, &mut positions.restrict_mut()).join(){
match &controller.0 {
Control::Move(direction) => {
let newpos = (pos.get_unchecked().pos + direction.to_position()).clamp(Pos::new(0, 0), Pos::new(size.width - 1, size.height - 1));
let mut blocked = false;
let mut on_floor = false;
- for ent in ground.cells.get(&newpos).unwrap_or(&Vec::new()) {
+ for ent in ground.cells.get(&newpos).unwrap_or(&HashSet::new()) {
if blocking.get(*ent).is_some(){
blocked = true;
break;
@@ -57,6 +72,7 @@ impl <'a> System<'a> for Move {
if !blocked && on_floor {
let mut pos_mut = pos.get_mut_unchecked();
pos_mut.prev = Some(pos_mut.pos);
+ moved.insert(ent, Moved{from: pos_mut.pos}).expect("can't insert Moved");
pos_mut.pos = newpos.clone();
}
}
diff --git a/src/systems/remove.rs b/src/systems/remove.rs
new file mode 100644
index 0000000..2c531e2
--- /dev/null
+++ b/src/systems/remove.rs
@@ -0,0 +1,27 @@
+
+use specs::{
+ ReadStorage,
+ System,
+ Join,
+ Entities
+};
+
+use crate::components::{Removed};
+
+
+
+pub struct Remove;
+impl <'a> System<'a> for Remove {
+ type SystemData = (
+ Entities<'a>,
+ ReadStorage<'a, Removed>
+ );
+
+ fn run(&mut self, (entities, removals): Self::SystemData) {
+ for (ent, _) in (&*entities, &removals).join() {
+ if let Err(msg) = entities.delete(ent){
+ println!("{:?}", msg);
+ }
+ }
+ }
+}
diff --git a/src/systems/view.rs b/src/systems/view.rs
index fec5ee7..12b5f78 100644
--- a/src/systems/view.rs
+++ b/src/systems/view.rs
@@ -16,7 +16,7 @@ use specs::{
};
use super::super::pos::Pos;
-use super::super::components::{Visible, Player, Position};
+use super::super::components::{Visible, Player, Position, New};
use super::super::resources::{Size, Output};
use super::super::worldmessages::{WorldMessage, WorldUpdate, FieldMessage};
@@ -29,8 +29,8 @@ pub struct View {
}
impl <'a> System<'a> for View {
- type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Read<'a, Size>, WriteStorage<'a, Player>, Write<'a, Output>);
- fn run(&mut self, (positions, visible, size, mut players, mut output): Self::SystemData) {
+ type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Read<'a, Size>, WriteStorage<'a, Player>, Write<'a, Output>, ReadStorage<'a, New>);
+ fn run(&mut self, (positions, visible, size, mut players, mut output, _new): Self::SystemData) {
let mut cells: HashMap<Pos, Vec<Visible>> = HashMap::new();
for (pos, vis) in (&positions, &visible).join(){