summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/mod.rs14
-rw-r--r--src/playerstate.rs1
-rw-r--r--src/pos.rs1
-rw-r--r--src/purgatory.rs10
-rw-r--r--src/resources/ground.rs30
-rw-r--r--src/room.rs36
-rw-r--r--src/systems/clear.rs19
-rw-r--r--src/systems/mod.rs4
-rw-r--r--src/systems/moving.rs21
-rw-r--r--src/systems/registernew.rs19
-rw-r--r--src/systems/remove.rs2
-rw-r--r--src/systems/view.rs36
-rw-r--r--todo.md6
13 files changed, 101 insertions, 98 deletions
diff --git a/src/components/mod.rs b/src/components/mod.rs
index b7e3875..1a590b2 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -33,7 +33,6 @@ use specs::{
DenseVecStorage,
VecStorage,
HashMapStorage,
- FlaggedStorage,
NullStorage,
Component,
Entity
@@ -50,7 +49,8 @@ use crate::{
Timestamp
};
-#[derive(Debug, Clone)]
+#[derive(Component, Debug, Clone)]
+#[storage(VecStorage)]
pub struct Position{
pub pos: Pos
}
@@ -60,19 +60,13 @@ impl Position {
}
}
-impl Component for Position {
- type Storage = FlaggedStorage<Self, VecStorage<Self>>;
-}
-
-#[derive(Debug, Clone)]
+#[derive(Component, Debug, Clone)]
+#[storage(VecStorage)]
pub struct Visible {
pub sprite: Sprite,
pub height: f64,
pub name: String
}
-impl Component for Visible {
- type Storage = FlaggedStorage<Self, VecStorage<Self>>;
-}
#[derive(Component, Debug)]
pub struct Controller {
diff --git a/src/playerstate.rs b/src/playerstate.rs
index f146cd2..f05332b 100644
--- a/src/playerstate.rs
+++ b/src/playerstate.rs
@@ -30,6 +30,7 @@ use crate::{
};
#[derive(Debug, Clone)]
+#[allow(dead_code)]
pub enum RoomPos {
Pos(Pos),
Name(String),
diff --git a/src/pos.rs b/src/pos.rs
index d95c6f7..0ea6435 100644
--- a/src/pos.rs
+++ b/src/pos.rs
@@ -18,6 +18,7 @@ impl Pos {
Pos {x, y}
}
+ #[allow(dead_code)]
pub fn clamp(self, smaller: Pos, larger: Pos) -> Pos {
Pos {
x: clamp(self.x, smaller.x, larger.x),
diff --git a/src/purgatory.rs b/src/purgatory.rs
index 04024db..e5803d0 100644
--- a/src/purgatory.rs
+++ b/src/purgatory.rs
@@ -11,9 +11,7 @@ use crate::{
roomtemplate::RoomTemplate,
systems::{
Move,
- RegisterNew,
ControlInput,
- View,
Remove,
Create,
Volate,
@@ -29,14 +27,12 @@ pub fn purgatory_id() -> RoomId {
pub fn create_purgatory<'a, 'b>(encyclopedia: &Encyclopedia) -> Room<'a, 'b> {
let dispatcher = DispatcherBuilder::new()
.with(Volate, "volate", &[])
- .with(RegisterNew::default(), "registernew", &[])
- .with(UpdateCooldowns, "cool_down", &["registernew"])
+ .with(UpdateCooldowns, "cool_down", &[])
.with(ControlInput, "controlinput", &["cool_down"])
.with(ControlAI, "controlai", &["cool_down"])
.with(Move, "move", &["controlinput", "controlai"])
- .with(View::default(), "view", &["move", "volate"])
- .with(Create, "create", &["view"])
- .with(Remove, "remove", &["view", "move"])
+ .with(Create, "create", &["move", "volate"])
+ .with(Remove, "remove", &["volate", "move"])
.build();
let mut room = Room::new(purgatory_id(), encyclopedia.clone(), dispatcher);
room.load_from_template(&RoomTemplate::from_json(&json!({
diff --git a/src/resources/ground.rs b/src/resources/ground.rs
index 8194a44..7411a15 100644
--- a/src/resources/ground.rs
+++ b/src/resources/ground.rs
@@ -8,27 +8,33 @@ use specs::{
};
use crate::{
- components::{Visible, Removed, Flags, Flag},
+ components::{Visible, Flags, Flag},
Pos
};
#[derive(Default)]
pub struct Ground {
- pub cells: HashMap<Pos, HashSet<Entity>>
+ pub cells: HashMap<Pos, HashSet<Entity>>,
+ pub changes: HashSet<Pos>
}
impl Ground {
- pub fn components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>, removals: &'a ReadStorage<Removed>) -> Vec<&'a C> {
- self.cells
- .get(&pos)
- .unwrap_or(&HashSet::new())
- .iter()
- .filter(|e| !removals.contains(**e))
- .filter_map(|e| component_type.get(*e))
- .collect()
+
+ pub fn insert(&mut self, pos: Pos, ent: Entity){
+ self.cells.entry(pos).or_insert_with(HashSet::new).insert(ent);
+ self.changes.insert(pos);
+ }
+
+ pub fn remove(&mut self, pos: &Pos, ent: Entity) -> bool{
+ if let Some(cell) = self.cells.get_mut(pos) {
+ self.changes.insert(*pos);
+ cell.remove(&ent)
+ } else {
+ false
+ }
}
- pub fn all_components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>) -> Vec<&'a C> {
+ pub fn components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>) -> Vec<&'a C> {
self.cells
.get(&pos)
.unwrap_or(&HashSet::new())
@@ -51,6 +57,6 @@ impl Ground {
}
pub fn flags_on<'a>(&self, pos: Pos, flags: &'a ReadStorage<Flags>) -> HashSet<Flag> {
- self.all_components_on::<Flags>(pos, flags).into_iter().fold(HashSet::new(), |a, b| &a | &b.0)
+ self.components_on::<Flags>(pos, flags).into_iter().fold(HashSet::new(), |a, b| &a | &b.0)
}
}
diff --git a/src/room.rs b/src/room.rs
index fa46d47..2b4fb7e 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -6,7 +6,6 @@ use specs::{
WorldExt,
DispatcherBuilder,
Dispatcher,
- Builder,
Join,
Entity
};
@@ -30,7 +29,6 @@ use crate::{
Player,
Inventory,
Health,
- New,
Removed
},
Encyclopedia,
@@ -66,17 +64,17 @@ use crate::{
Spawn,
Interact,
DropLoot,
- Growth
+ Growth,
+ Clear
}
};
pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
DispatcherBuilder::new()
.with(Volate, "volate", &[])
- .with(RegisterNew::default(), "registernew", &[])
- .with(Growth, "growth", &["registernew"])
- .with(UpdateCooldowns, "cool_down", &["registernew"])
- .with(Spawn, "spawn", &["registernew"])
+ .with(Growth, "growth", &[])
+ .with(UpdateCooldowns, "cool_down", &[])
+ .with(Spawn, "spawn", &[])
.with(ControlInput, "controlinput", &["cool_down"])
.with(ControlAI, "controlai", &["cool_down"])
.with(Take, "take", &["controlinput", "controlai"])
@@ -85,20 +83,20 @@ pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
.with(Move, "move", &["controlinput", "controlai"])
.with(Trapping, "trapping", &["move"])
.with(Fight, "fight", &["move"])
- .with(Heal, "heal", &["registernew"])
+ .with(Heal, "heal", &[])
.with(Attacking, "attacking", &["use", "trapping", "fight", "heal", "interact"])
.with(Die, "die", &["attacking"])
.with(DropLoot, "droploot", &["attacking"])
- .with(View::default(), "view", &["move", "attacking", "volate", "die"])
- .with(Migrate, "migrate", &["view"])
- .with(Create, "create", &["view", "spawn", "droploot", "growth"])
- .with(Remove, "remove", &["view", "move", "droploot"])
+ .with(Migrate, "migrate", &["move", "attacking", "volate", "die"])
+ .with(Create, "create", &["migrate", "spawn", "droploot", "growth"])
+ .with(Remove, "remove", &["migrate", "move", "droploot"])
.build()
}
pub struct Room<'a, 'b> {
world: World,
dispatcher: Dispatcher<'a, 'b>,
+ view_dispatcher: Dispatcher<'a, 'b>,
pub id: RoomId,
places: HashMap<String, Pos>
}
@@ -129,6 +127,11 @@ impl <'a, 'b>Room<'a, 'b> {
Room {
world,
dispatcher,
+ view_dispatcher: DispatcherBuilder::new()
+ .with(RegisterNew, "registernew", &[])
+ .with(View, "view", &["registernew"])
+ .with(Clear, "clear", &["view"])
+ .build(),
id,
places: HashMap::new()
}
@@ -170,6 +173,7 @@ impl <'a, 'b>Room<'a, 'b> {
self.world.fetch_mut::<Time>().time = timestamp;
self.dispatcher.dispatch(&self.world);
self.world.maintain();
+ self.view_dispatcher.dispatch(&self.world);
}
@@ -184,13 +188,7 @@ impl <'a, 'b>Room<'a, 'b> {
RoomPos::Pos(pos) => *pos,
RoomPos::Name(name) => *self.places.get(name).unwrap()
};
- let mut builder = self.world.create_entity();
- let ent = builder.entity;
- for comp in pre_player {
- builder = comp.build(builder);
- }
- builder.with(Position::new(spawn)).with(New).build();
- self.world.fetch_mut::<Players>().entities.insert(state.id.clone(), ent);
+ self.world.fetch_mut::<NewEntities>().to_build.push((spawn, pre_player));
}
pub fn remove_player(&mut self, id: &PlayerId) -> Result<PlayerState>{
diff --git a/src/systems/clear.rs b/src/systems/clear.rs
new file mode 100644
index 0000000..64588d3
--- /dev/null
+++ b/src/systems/clear.rs
@@ -0,0 +1,19 @@
+
+use specs::{
+ Write,
+ System
+};
+
+use crate::{
+ resources::Ground
+};
+
+pub struct Clear;
+impl <'a> System<'a> for Clear {
+ type SystemData =
+ Write<'a, Ground>;
+ fn run(&mut self, mut ground: Self::SystemData) {
+ ground.changes.clear();
+ }
+}
+
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index 318d5ee..3f990a7 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -20,6 +20,7 @@ mod spawn;
mod interact;
mod droploot;
mod growth;
+mod clear;
pub use self::{
controlinput::ControlInput,
@@ -42,5 +43,6 @@ pub use self::{
spawn::Spawn,
interact::Interact,
droploot::DropLoot,
- growth::Growth
+ growth::Growth,
+ clear::Clear
};
diff --git a/src/systems/moving.rs b/src/systems/moving.rs
index 6ecf040..ccd29d6 100644
--- a/src/systems/moving.rs
+++ b/src/systems/moving.rs
@@ -1,18 +1,14 @@
-use std::collections::HashSet;
-
use specs::{
Entities,
ReadStorage,
WriteStorage,
- Read,
System,
Join,
Write
};
use crate::{
- Pos,
components::{
Controller,
Position,
@@ -27,7 +23,6 @@ use crate::{
Control
},
resources::{
- Size,
Ground
},
};
@@ -39,7 +34,6 @@ impl <'a> System<'a> for Move {
Entities<'a>,
ReadStorage<'a, Controller>,
WriteStorage<'a, Position>,
- Read<'a, Size>,
ReadStorage<'a, Flags>,
Write<'a, Ground>,
WriteStorage<'a, Moved>,
@@ -48,20 +42,19 @@ impl <'a> System<'a> for Move {
WriteStorage<'a, ControlCooldown>
);
- fn run(&mut self, (entities, controllers, mut positions, size, flags, mut ground, mut moved, mut entered, movables, mut cooldowns): Self::SystemData) {
+ fn run(&mut self, (entities, controllers, mut positions, flags, mut ground, mut moved, mut entered, movables, mut cooldowns): Self::SystemData) {
moved.clear();
entered.clear();
- for (ent, controller, mut pos, movable) in (&entities, &controllers, &mut positions.restrict_mut(), &movables).join(){
+ for (ent, controller, mut position, movable) in (&entities, &controllers, &mut positions, &movables).join(){
match &controller.control {
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 newpos = position.pos + direction.to_position();
let ground_flags = ground.flags_on(newpos, &flags);
if !ground_flags.contains(&Flag::Blocking) && ground_flags.contains(&Flag::Floor) {
- let mut pos_mut = pos.get_mut_unchecked();
- moved.insert(ent, Moved{from: pos_mut.pos}).expect("can't insert Moved");
- ground.cells.get_mut(&pos_mut.pos).unwrap().remove(&ent);
- pos_mut.pos = newpos;
- ground.cells.entry(newpos).or_insert_with(HashSet::new).insert(ent);
+ moved.insert(ent, Moved{from: position.pos}).expect("can't insert Moved");
+ ground.remove(&position.pos, ent);
+ position.pos = newpos;
+ ground.insert(newpos, ent);
for ent in ground.cells.get(&newpos).unwrap() {
let _ = entered.insert(*ent, Entered);
}
diff --git a/src/systems/registernew.rs b/src/systems/registernew.rs
index c53309f..0091296 100644
--- a/src/systems/registernew.rs
+++ b/src/systems/registernew.rs
@@ -1,5 +1,4 @@
-use std::collections::HashSet;
use specs::{
ReadStorage,
@@ -11,26 +10,32 @@ use specs::{
use crate::components::{
Position,
- New
+ New,
+ Player
};
use crate::resources::{
- Ground
+ Ground,
+ Players
};
-#[derive(Default)]
pub struct RegisterNew;
impl <'a> System<'a> for RegisterNew {
type SystemData = (
Entities<'a>,
+ ReadStorage<'a, New>,
Write<'a, Ground>,
ReadStorage<'a, Position>,
- ReadStorage<'a, New>,
+ Write<'a, Players>,
+ ReadStorage<'a, Player>
);
- fn run(&mut self, (entities, mut ground, positions, new): Self::SystemData) {
+ fn run(&mut self, (entities, new, mut ground, positions, mut player_list, players): Self::SystemData) {
for (ent, pos, _new) in (&entities, &positions, &new).join() {
- ground.cells.entry(pos.pos).or_insert_with(HashSet::new).insert(ent);
+ ground.insert(pos.pos, ent);
+ }
+ for (ent, player, _new) in (&entities, &players, &new).join(){
+ player_list.entities.insert(player.id.clone(), ent);
}
}
}
diff --git a/src/systems/remove.rs b/src/systems/remove.rs
index b73a2fb..a228a32 100644
--- a/src/systems/remove.rs
+++ b/src/systems/remove.rs
@@ -26,7 +26,7 @@ impl <'a> System<'a> for Remove {
println!("{:?}", msg);
}
if let Some(position) = positions.get(ent) {
- ground.cells.get_mut(&position.pos).unwrap().remove(&ent);
+ ground.remove(&position.pos, ent);
}
}
}
diff --git a/src/systems/view.rs b/src/systems/view.rs
index 49338ac..4419203 100644
--- a/src/systems/view.rs
+++ b/src/systems/view.rs
@@ -1,5 +1,4 @@
-use std::collections::{HashSet};
use specs::{
ReadStorage,
@@ -14,12 +13,11 @@ use specs::{
use crate::{
Pos,
Sprite,
- components::{Visible, Player, Position, Inventory, New, Moved, Removed, Health, Ear},
+ components::{Visible, Player, Position, Inventory, New, Health, Ear},
resources::{Size, Output, Ground},
worldmessages::{WorldMessage, FieldMessage}
};
-#[derive(Default)]
pub struct View;
impl <'a> System<'a> for View {
@@ -33,37 +31,23 @@ impl <'a> System<'a> for View {
ReadStorage<'a, Player>,
Write<'a, Output>,
ReadStorage<'a, New>,
- ReadStorage<'a, Moved>,
- ReadStorage<'a, Removed>,
Read<'a, Ground>,
WriteStorage<'a, Ear>
);
- fn run(&mut self, (entities, positions, inventories, healths, visible, size, players, mut output, new, moved, removed, ground, mut ears): Self::SystemData) {
+ fn run(&mut self, (entities, positions, inventories, healths, visible, size, players, mut output, new, ground, mut ears): Self::SystemData) {
- let mut changed = HashSet::new();
- for (pos, _new) in (&positions, &new).join() {
- changed.insert(pos.pos);
- }
- for (pos, mov) in (&positions, &moved).join() {
- changed.insert(pos.pos);
- changed.insert(mov.from);
- }
- for (pos, _removed) in (&positions, &removed).join() {
- changed.insert(pos.pos);
- }
+ let changes: Vec<(Pos, Vec<Sprite>)> = ground.changes
+ .iter()
+ .map(|pos| (*pos, cell_sprites(ground.components_on(*pos, &visible))))
+ .collect();
-
- let has_changed: bool = !changed.is_empty();
- let mut changes: Vec<(Pos, Vec<Sprite>)> = Vec::new();
- for pos in changed {
- changes.push((pos, cell_sprites(ground.components_on(pos, &visible, &removed))));
- }
+ let has_changed: bool = !changes.is_empty();
output.output.clear();
for (ent, player, pos) in (&entities, &players, &positions).join() {
let mut updates = WorldMessage::default();
if new.get(ent).is_some() {
- let (values, mapping) = draw_room(&ground, (size.width, size.height), &visible, &removed);
+ let (values, mapping) = draw_room(&ground, (size.width, size.height), &visible);
let field = FieldMessage{
width: size.width,
height: size.height,
@@ -105,14 +89,14 @@ fn cell_sprites(mut visibles: Vec<&Visible>) -> Vec<Sprite> {
visibles.iter().map(|vis| vis.sprite.clone()).collect()
}
-fn draw_room(ground: &Read<Ground>, (width, height): (i64, i64), visible: &ReadStorage<Visible>, removals: &ReadStorage<Removed>) -> (Vec<usize>, Vec<Vec<Sprite>>){
+fn draw_room(ground: &Read<Ground>, (width, height): (i64, i64), visible: &ReadStorage<Visible>) -> (Vec<usize>, Vec<Vec<Sprite>>){
let size = width * height;
let mut values :Vec<usize> = Vec::with_capacity(size as usize);
let mut mapping: Vec<Vec<Sprite>> = Vec::new();
for y in 0..height {
for x in 0..width {
- let sprites: Vec<Sprite> = cell_sprites(ground.components_on(Pos{x, y}, visible, removals));
+ let sprites: Vec<Sprite> = cell_sprites(ground.components_on(Pos{x, y}, visible));
values.push(
match mapping.iter().position(|x| x == &sprites) {
Some(index) => {
diff --git a/todo.md b/todo.md
index 5ce886b..8c33302 100644
--- a/todo.md
+++ b/todo.md
@@ -3,9 +3,13 @@
- make readme
- more tests
+- parameterised interactions
+- trader
+- visitors
+- improved tutorial
+- port over rooms/saves
- timer resource?
- log world events to player
-- draw new entities
- relative room locations?
- improve error handling