Browse Source

cargo fmt

Getty Ritter 4 years ago
parent
commit
57b16ceca5

+ 13 - 13
chapter-07-damage/src/components.rs

@@ -1,8 +1,8 @@
 extern crate specs;
 use specs::prelude::*;
-extern crate specs_derive;
 extern crate rltk;
-use rltk::{RGB};
+extern crate specs_derive;
+use rltk::RGB;
 
 #[derive(Component)]
 pub struct Position {
@@ -16,15 +16,15 @@ pub struct Renderable {
     pub fg: RGB,
     pub bg: RGB,
 }
- 
+
 #[derive(Component, Debug)]
 pub struct Player {}
 
 #[derive(Component)]
 pub struct Viewshed {
-    pub visible_tiles : Vec<rltk::Point>,
-    pub range : i32,
-    pub dirty : bool
+    pub visible_tiles: Vec<rltk::Point>,
+    pub range: i32,
+    pub dirty: bool,
 }
 
 #[derive(Component, Debug)]
@@ -32,7 +32,7 @@ pub struct Monster {}
 
 #[derive(Component, Debug)]
 pub struct Name {
-    pub name : String
+    pub name: String,
 }
 
 #[derive(Component, Debug)]
@@ -40,18 +40,18 @@ pub struct BlocksTile {}
 
 #[derive(Component, Debug)]
 pub struct CombatStats {
-    pub max_hp : i32,
-    pub hp : i32,
-    pub defense : i32,
-    pub power : i32
+    pub max_hp: i32,
+    pub hp: i32,
+    pub defense: i32,
+    pub power: i32,
 }
 
 #[derive(Component, Debug)]
 pub struct WantsToMelee {
-    pub target : Entity
+    pub target: Entity,
 }
 
 #[derive(Component, Debug)]
 pub struct SufferDamage {
-    pub amount : i32
+    pub amount: i32,
 }

+ 13 - 11
chapter-07-damage/src/damage_system.rs

@@ -1,15 +1,17 @@
 extern crate specs;
-use specs::prelude::*;
-use super::{CombatStats, SufferDamage, Player};
+use super::{CombatStats, Player, SufferDamage};
 use rltk::console;
+use specs::prelude::*;
 
 pub struct DamageSystem {}
 
 impl<'a> System<'a> for DamageSystem {
-    type SystemData = ( WriteStorage<'a, CombatStats>,
-                        WriteStorage<'a, SufferDamage> );
+    type SystemData = (
+        WriteStorage<'a, CombatStats>,
+        WriteStorage<'a, SufferDamage>,
+    );
 
-    fn run(&mut self, data : Self::SystemData) {
+    fn run(&mut self, data: Self::SystemData) {
         let (mut stats, mut damage) = data;
 
         for (mut stats, damage) in (&mut stats, &damage).join() {
@@ -20,19 +22,19 @@ impl<'a> System<'a> for DamageSystem {
     }
 }
 
-pub fn delete_the_dead(ecs : &mut World) {
-    let mut dead : Vec<Entity> = Vec::new();
+pub fn delete_the_dead(ecs: &mut World) {
+    let mut dead: Vec<Entity> = Vec::new();
     // Using a scope to make the borrow checker happy
     {
         let combat_stats = ecs.read_storage::<CombatStats>();
         let players = ecs.read_storage::<Player>();
         let entities = ecs.entities();
         for (entity, stats) in (&entities, &combat_stats).join() {
-            if stats.hp < 1 { 
+            if stats.hp < 1 {
                 let player = players.get(entity);
                 match player {
                     None => dead.push(entity),
-                    Some(_) => console::log("You are dead")
+                    Some(_) => console::log("You are dead"),
                 }
             }
         }
@@ -40,5 +42,5 @@ pub fn delete_the_dead(ecs : &mut World) {
 
     for victim in dead {
         ecs.delete_entity(victim).expect("Unable to delete");
-    }    
-}
+    }
+}

+ 73 - 35
chapter-07-damage/src/main.rs

@@ -1,5 +1,5 @@
 extern crate rltk;
-use rltk::{Console, GameState, Rltk, RGB, Point};
+use rltk::{Console, GameState, Point, Rltk, RGB};
 extern crate specs;
 use specs::prelude::*;
 #[macro_use]
@@ -26,37 +26,42 @@ use damage_system::DamageSystem;
 rltk::add_wasm_support!();
 
 #[derive(PartialEq, Copy, Clone)]
-pub enum RunState { AwaitingInput, PreRun, PlayerTurn, MonsterTurn }
+pub enum RunState {
+    AwaitingInput,
+    PreRun,
+    PlayerTurn,
+    MonsterTurn,
+}
 
 pub struct State {
-    pub ecs: World
+    pub ecs: World,
 }
 
 impl State {
     fn run_systems(&mut self) {
-        let mut mapindex = MapIndexingSystem{};
+        let mut mapindex = MapIndexingSystem {};
         mapindex.run_now(&self.ecs);
-        let mut vis = VisibilitySystem{};
+        let mut vis = VisibilitySystem {};
         vis.run_now(&self.ecs);
-        let mut mob = MonsterAI{};
+        let mut mob = MonsterAI {};
         mob.run_now(&self.ecs);
-        let mut melee = MeleeCombatSystem{};
+        let mut melee = MeleeCombatSystem {};
         melee.run_now(&self.ecs);
-        let mut damage = DamageSystem{};
+        let mut damage = DamageSystem {};
         damage.run_now(&self.ecs);
         self.ecs.maintain();
     }
 }
 
 impl GameState for State {
-    fn tick(&mut self, ctx : &mut Rltk) {
+    fn tick(&mut self, ctx: &mut Rltk) {
         ctx.cls();
         let mut newrunstate;
         {
             let runstate = self.ecs.fetch::<RunState>();
             newrunstate = *runstate;
         }
-        
+
         match newrunstate {
             RunState::PreRun => {
                 self.run_systems();
@@ -89,16 +94,16 @@ impl GameState for State {
 
         for (pos, render) in (&positions, &renderables).join() {
             let idx = map.xy_idx(pos.x, pos.y);
-            if map.visible_tiles[idx] { ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph) }
+            if map.visible_tiles[idx] {
+                ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph)
+            }
         }
     }
 }
 
 fn main() {
     let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "resources");
-    let mut gs = State {
-        ecs: World::new(),
-    };
+    let mut gs = State { ecs: World::new() };
     gs.ecs.register::<Position>();
     gs.ecs.register::<Renderable>();
     gs.ecs.register::<Player>();
@@ -110,47 +115,80 @@ fn main() {
     gs.ecs.register::<WantsToMelee>();
     gs.ecs.register::<SufferDamage>();
 
-    let map : Map = Map::new_map_rooms_and_corridors();
+    let map: Map = Map::new_map_rooms_and_corridors();
     let (player_x, player_y) = map.rooms[0].center();
 
-    let player_entity = gs.ecs
+    let player_entity = gs
+        .ecs
         .create_entity()
-        .with(Position { x: player_x, y: player_y })
+        .with(Position {
+            x: player_x,
+            y: player_y,
+        })
         .with(Renderable {
             glyph: rltk::to_cp437('@'),
             fg: RGB::named(rltk::YELLOW),
             bg: RGB::named(rltk::BLACK),
         })
-        .with(Player{})
-        .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
-        .with(Name{name: "Player".to_string() })
-        .with(CombatStats{ max_hp: 30, hp: 30, defense: 2, power: 5 })
+        .with(Player {})
+        .with(Viewshed {
+            visible_tiles: Vec::new(),
+            range: 8,
+            dirty: true,
+        })
+        .with(Name {
+            name: "Player".to_string(),
+        })
+        .with(CombatStats {
+            max_hp: 30,
+            hp: 30,
+            defense: 2,
+            power: 5,
+        })
         .build();
 
     let mut rng = rltk::RandomNumberGenerator::new();
-    for (i,room) in map.rooms.iter().skip(1).enumerate() {
-        let (x,y) = room.center();
+    for (i, room) in map.rooms.iter().skip(1).enumerate() {
+        let (x, y) = room.center();
 
-        let glyph : u8;
-        let name : String;
+        let glyph: u8;
+        let name: String;
         let roll = rng.roll_dice(1, 2);
         match roll {
-            1 => { glyph = rltk::to_cp437('g'); name = "Goblin".to_string(); }
-            _ => { glyph = rltk::to_cp437('o'); name = "Orc".to_string(); }
+            1 => {
+                glyph = rltk::to_cp437('g');
+                name = "Goblin".to_string();
+            }
+            _ => {
+                glyph = rltk::to_cp437('o');
+                name = "Orc".to_string();
+            }
         }
 
-        gs.ecs.create_entity()
-            .with(Position{ x, y })
-            .with(Renderable{
+        gs.ecs
+            .create_entity()
+            .with(Position { x, y })
+            .with(Renderable {
                 glyph,
                 fg: RGB::named(rltk::RED),
                 bg: RGB::named(rltk::BLACK),
             })
-            .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
-            .with(Monster{})
-            .with(Name{ name: format!("{} #{}", &name, i) })
-            .with(BlocksTile{})
-            .with(CombatStats{ max_hp: 16, hp: 16, defense: 1, power: 4 })
+            .with(Viewshed {
+                visible_tiles: Vec::new(),
+                range: 8,
+                dirty: true,
+            })
+            .with(Monster {})
+            .with(Name {
+                name: format!("{} #{}", &name, i),
+            })
+            .with(BlocksTile {})
+            .with(CombatStats {
+                max_hp: 16,
+                hp: 16,
+                defense: 1,
+                power: 4,
+            })
             .build();
     }
 

+ 83 - 57
chapter-07-damage/src/map.rs

@@ -1,29 +1,30 @@
 extern crate rltk;
-use rltk::{ RGB, Rltk, Console, RandomNumberGenerator, BaseMap, Algorithm2D, Point };
-use super::{Rect};
+use super::Rect;
+use rltk::{Algorithm2D, BaseMap, Console, Point, RandomNumberGenerator, Rltk, RGB};
 use std::cmp::{max, min};
 extern crate specs;
 use specs::prelude::*;
 
-const MAPWIDTH : usize = 80;
-const MAPHEIGHT : usize = 43;
-const MAPCOUNT : usize = MAPHEIGHT * MAPWIDTH;
+const MAPWIDTH: usize = 80;
+const MAPHEIGHT: usize = 43;
+const MAPCOUNT: usize = MAPHEIGHT * MAPWIDTH;
 
 #[derive(PartialEq, Copy, Clone)]
 pub enum TileType {
-    Wall, Floor
+    Wall,
+    Floor,
 }
 
 #[derive(Default)]
 pub struct Map {
-    pub tiles : Vec<TileType>,
-    pub rooms : Vec<Rect>,
-    pub width : i32,
-    pub height : i32,
-    pub revealed_tiles : Vec<bool>,
-    pub visible_tiles : Vec<bool>,
-    pub blocked : Vec<bool>,
-    pub tile_content : Vec<Vec<Entity>>
+    pub tiles: Vec<TileType>,
+    pub rooms: Vec<Rect>,
+    pub width: i32,
+    pub height: i32,
+    pub revealed_tiles: Vec<bool>,
+    pub visible_tiles: Vec<bool>,
+    pub blocked: Vec<bool>,
+    pub tile_content: Vec<Vec<Entity>>,
 }
 
 impl Map {
@@ -31,17 +32,17 @@ impl Map {
         (y as usize * self.width as usize) + x as usize
     }
 
-    fn apply_room_to_map(&mut self, room : &Rect) {
-        for y in room.y1 +1 ..= room.y2 {
-            for x in room.x1 + 1 ..= room.x2 {
+    fn apply_room_to_map(&mut self, room: &Rect) {
+        for y in room.y1 + 1..=room.y2 {
+            for x in room.x1 + 1..=room.x2 {
                 let idx = self.xy_idx(x, y);
                 self.tiles[idx] = TileType::Floor;
             }
         }
     }
 
-    fn apply_horizontal_tunnel(&mut self, x1:i32, x2:i32, y:i32) {
-        for x in min(x1,x2) ..= max(x1,x2) {
+    fn apply_horizontal_tunnel(&mut self, x1: i32, x2: i32, y: i32) {
+        for x in min(x1, x2)..=max(x1, x2) {
             let idx = self.xy_idx(x, y);
             if idx > 0 && idx < self.width as usize * self.height as usize {
                 self.tiles[idx as usize] = TileType::Floor;
@@ -49,8 +50,8 @@ impl Map {
         }
     }
 
-    fn apply_vertical_tunnel(&mut self, y1:i32, y2:i32, x:i32) {
-        for y in min(y1,y2) ..= max(y1,y2) {
+    fn apply_vertical_tunnel(&mut self, y1: i32, y2: i32, x: i32) {
+        for y in min(y1, y2)..=max(y1, y2) {
             let idx = self.xy_idx(x, y);
             if idx > 0 && idx < self.width as usize * self.height as usize {
                 self.tiles[idx as usize] = TileType::Floor;
@@ -58,14 +59,16 @@ impl Map {
         }
     }
 
-    fn is_exit_valid(&self, x:i32, y:i32) -> bool {
-        if x < 1 || x > self.width-1 || y < 1 || y > self.height-1 { return false; }
+    fn is_exit_valid(&self, x: i32, y: i32) -> bool {
+        if x < 1 || x > self.width - 1 || y < 1 || y > self.height - 1 {
+            return false;
+        }
         let idx = (y * self.width) + x;
         !self.blocked[idx as usize]
     }
 
-    pub fn populate_blocked(&mut self) {        
-        for (i,tile) in self.tiles.iter_mut().enumerate() {
+    pub fn populate_blocked(&mut self) {
+        for (i, tile) in self.tiles.iter_mut().enumerate() {
             self.blocked[i] = *tile == TileType::Wall;
         }
     }
@@ -79,20 +82,20 @@ impl Map {
     /// Makes a new map using the algorithm from http://rogueliketutorials.com/tutorials/tcod/part-3/
     /// This gives a handful of random rooms and corridors joining them together.
     pub fn new_map_rooms_and_corridors() -> Map {
-        let mut map = Map{
-            tiles : vec![TileType::Wall; MAPCOUNT],
-            rooms : Vec::new(),
-            width : MAPWIDTH as i32,
+        let mut map = Map {
+            tiles: vec![TileType::Wall; MAPCOUNT],
+            rooms: Vec::new(),
+            width: MAPWIDTH as i32,
             height: MAPHEIGHT as i32,
-            revealed_tiles : vec![false; MAPCOUNT],
-            visible_tiles : vec![false; MAPCOUNT],
-            blocked : vec![false; MAPCOUNT],
-            tile_content : vec![Vec::new(); MAPCOUNT]
+            revealed_tiles: vec![false; MAPCOUNT],
+            visible_tiles: vec![false; MAPCOUNT],
+            blocked: vec![false; MAPCOUNT],
+            tile_content: vec![Vec::new(); MAPCOUNT],
         };
 
-        const MAX_ROOMS : i32 = 30;
-        const MIN_SIZE : i32 = 6;
-        const MAX_SIZE : i32 = 10;
+        const MAX_ROOMS: i32 = 30;
+        const MIN_SIZE: i32 = 6;
+        const MAX_SIZE: i32 = 10;
 
         let mut rng = RandomNumberGenerator::new();
 
@@ -104,15 +107,17 @@ impl Map {
             let new_room = Rect::new(x, y, w, h);
             let mut ok = true;
             for other_room in map.rooms.iter() {
-                if new_room.intersect(other_room) { ok = false }
+                if new_room.intersect(other_room) {
+                    ok = false
+                }
             }
             if ok {
                 map.apply_room_to_map(&new_room);
 
                 if !map.rooms.is_empty() {
                     let (new_x, new_y) = new_room.center();
-                    let (prev_x, prev_y) = map.rooms[map.rooms.len()-1].center();
-                    if rng.range(0,1) == 1 {
+                    let (prev_x, prev_y) = map.rooms[map.rooms.len() - 1].center();
+                    if rng.range(0, 1) == 1 {
                         map.apply_horizontal_tunnel(prev_x, new_x, prev_y);
                         map.apply_vertical_tunnel(prev_y, new_y, new_x);
                     } else {
@@ -130,31 +135,47 @@ impl Map {
 }
 
 impl BaseMap for Map {
-    fn is_opaque(&self, idx:i32) -> bool {
+    fn is_opaque(&self, idx: i32) -> bool {
         self.tiles[idx as usize] == TileType::Wall
     }
 
-    fn get_available_exits(&self, idx:i32) -> Vec<(i32, f32)> {
-        let mut exits : Vec<(i32, f32)> = Vec::new();
+    fn get_available_exits(&self, idx: i32) -> Vec<(i32, f32)> {
+        let mut exits: Vec<(i32, f32)> = Vec::new();
         let x = idx % self.width;
         let y = idx / self.width;
 
         // Cardinal directions
-        if self.is_exit_valid(x-1, y) { exits.push((idx-1, 1.0)) };
-        if self.is_exit_valid(x+1, y) { exits.push((idx+1, 1.0)) };
-        if self.is_exit_valid(x, y-1) { exits.push((idx-self.width, 1.0)) };
-        if self.is_exit_valid(x, y+1) { exits.push((idx+self.width, 1.0)) };
+        if self.is_exit_valid(x - 1, y) {
+            exits.push((idx - 1, 1.0))
+        };
+        if self.is_exit_valid(x + 1, y) {
+            exits.push((idx + 1, 1.0))
+        };
+        if self.is_exit_valid(x, y - 1) {
+            exits.push((idx - self.width, 1.0))
+        };
+        if self.is_exit_valid(x, y + 1) {
+            exits.push((idx + self.width, 1.0))
+        };
 
         // Diagonals
-        if self.is_exit_valid(x-1, y-1) { exits.push(((idx-self.width)-1, 1.45)); }
-        if self.is_exit_valid(x+1, y-1) { exits.push(((idx-self.width)+1, 1.45)); }
-        if self.is_exit_valid(x-1, y+1) { exits.push(((idx+self.width)-1, 1.45)); }
-        if self.is_exit_valid(x+1, y+1) { exits.push(((idx+self.width)+1, 1.45)); }
+        if self.is_exit_valid(x - 1, y - 1) {
+            exits.push(((idx - self.width) - 1, 1.45));
+        }
+        if self.is_exit_valid(x + 1, y - 1) {
+            exits.push(((idx - self.width) + 1, 1.45));
+        }
+        if self.is_exit_valid(x - 1, y + 1) {
+            exits.push(((idx + self.width) - 1, 1.45));
+        }
+        if self.is_exit_valid(x + 1, y + 1) {
+            exits.push(((idx + self.width) + 1, 1.45));
+        }
 
         exits
     }
 
-    fn get_pathing_distance(&self, idx1:i32, idx2:i32) -> f32 {
+    fn get_pathing_distance(&self, idx1: i32, idx2: i32) -> f32 {
         let p1 = Point::new(idx1 % self.width, idx1 / self.width);
         let p2 = Point::new(idx2 % self.width, idx2 / self.width);
         rltk::DistanceAlg::Pythagoras.distance2d(p1, p2)
@@ -166,17 +187,20 @@ impl Algorithm2D for Map {
         (pt.y * self.width) + pt.x
     }
 
-    fn index_to_point2d(&self, idx:i32) -> Point {
-        Point{ x: idx % self.width, y: idx / self.width }
+    fn index_to_point2d(&self, idx: i32) -> Point {
+        Point {
+            x: idx % self.width,
+            y: idx / self.width,
+        }
     }
 }
 
-pub fn draw_map(ecs: &World, ctx : &mut Rltk) {
+pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
     let map = ecs.fetch::<Map>();
 
     let mut y = 0;
     let mut x = 0;
-    for (idx,tile) in map.tiles.iter().enumerate() {
+    for (idx, tile) in map.tiles.iter().enumerate() {
         // Render a tile depending upon the tile type
 
         if map.revealed_tiles[idx] {
@@ -192,13 +216,15 @@ pub fn draw_map(ecs: &World, ctx : &mut Rltk) {
                     fg = RGB::from_f32(0., 1.0, 0.);
                 }
             }
-            if !map.visible_tiles[idx] { fg = fg.to_greyscale() }
+            if !map.visible_tiles[idx] {
+                fg = fg.to_greyscale()
+            }
             ctx.set(x, y, fg, RGB::from_f32(0., 0., 0.), glyph);
         }
 
         // Move the coordinates
         x += 1;
-        if x > MAPWIDTH as i32-1 {
+        if x > MAPWIDTH as i32 - 1 {
             x = 0;
             y += 1;
         }

+ 11 - 9
chapter-07-damage/src/map_indexing_system.rs

@@ -1,16 +1,18 @@
 extern crate specs;
+use super::{BlocksTile, Map, Position};
 use specs::prelude::*;
-use super::{Map, Position, BlocksTile};
 
 pub struct MapIndexingSystem {}
 
 impl<'a> System<'a> for MapIndexingSystem {
-    type SystemData = ( WriteExpect<'a, Map>,
-                        ReadStorage<'a, Position>,
-                        ReadStorage<'a, BlocksTile>,
-                        Entities<'a>,);
+    type SystemData = (
+        WriteExpect<'a, Map>,
+        ReadStorage<'a, Position>,
+        ReadStorage<'a, BlocksTile>,
+        Entities<'a>,
+    );
 
-    fn run(&mut self, data : Self::SystemData) {
+    fn run(&mut self, data: Self::SystemData) {
         let (mut map, position, blockers, entities) = data;
 
         map.populate_blocked();
@@ -19,14 +21,14 @@ impl<'a> System<'a> for MapIndexingSystem {
             let idx = map.xy_idx(position.x, position.y);
 
             // If they block, update the blocking list
-            let _p : Option<&BlocksTile> = blockers.get(entity);
+            let _p: Option<&BlocksTile> = blockers.get(entity);
             if let Some(_p) = _p {
                 map.blocked[idx] = true;
             }
-            
+
             // Push the entity to the appropriate index slot. It's a Copy
             // type, so we don't need to clone it (we want to avoid moving it out of the ECS!)
             map.tile_content[idx].push(entity);
         }
     }
-}
+}

+ 25 - 14
chapter-07-damage/src/melee_combat_system.rs

@@ -1,22 +1,25 @@
 extern crate specs;
-use specs::prelude::*;
-use super::{CombatStats, WantsToMelee, Name, SufferDamage};
+use super::{CombatStats, Name, SufferDamage, WantsToMelee};
 use rltk::console;
+use specs::prelude::*;
 
 pub struct MeleeCombatSystem {}
 
 impl<'a> System<'a> for MeleeCombatSystem {
-    type SystemData = ( Entities<'a>,
-                        WriteStorage<'a, WantsToMelee>,
-                        ReadStorage<'a, Name>,
-                        ReadStorage<'a, CombatStats>,
-                        WriteStorage<'a, SufferDamage>
-                      );
+    type SystemData = (
+        Entities<'a>,
+        WriteStorage<'a, WantsToMelee>,
+        ReadStorage<'a, Name>,
+        ReadStorage<'a, CombatStats>,
+        WriteStorage<'a, SufferDamage>,
+    );
 
-    fn run(&mut self, data : Self::SystemData) {
+    fn run(&mut self, data: Self::SystemData) {
         let (entities, mut wants_melee, names, combat_stats, mut inflict_damage) = data;
 
-        for (_entity, wants_melee, name, stats) in (&entities, &wants_melee, &names, &combat_stats).join() {
+        for (_entity, wants_melee, name, stats) in
+            (&entities, &wants_melee, &names, &combat_stats).join()
+        {
             if stats.hp > 0 {
                 let target_stats = combat_stats.get(wants_melee.target).unwrap();
                 if target_stats.hp > 0 {
@@ -25,10 +28,18 @@ impl<'a> System<'a> for MeleeCombatSystem {
                     let damage = i32::max(0, stats.power - target_stats.defense);
 
                     if damage == 0 {
-                        console::log(&format!("{} is unable to hurt {}", &name.name, &target_name.name));
+                        console::log(&format!(
+                            "{} is unable to hurt {}",
+                            &name.name, &target_name.name
+                        ));
                     } else {
-                        console::log(&format!("{} hits {}, for {} hp.", &name.name, &target_name.name, damage));
-                        inflict_damage.insert(wants_melee.target, SufferDamage{ amount: damage }).expect("Unable to do damage");
+                        console::log(&format!(
+                            "{} hits {}, for {} hp.",
+                            &name.name, &target_name.name, damage
+                        ));
+                        inflict_damage
+                            .insert(wants_melee.target, SufferDamage { amount: damage })
+                            .expect("Unable to do damage");
                     }
                 }
             }
@@ -36,4 +47,4 @@ impl<'a> System<'a> for MeleeCombatSystem {
 
         wants_melee.clear();
     }
-}
+}

+ 47 - 24
chapter-07-damage/src/monster_ai_system.rs

@@ -1,41 +1,64 @@
 extern crate specs;
+use super::{Map, Monster, Position, RunState, Viewshed, WantsToMelee};
 use specs::prelude::*;
-use super::{Viewshed, Monster, Map, Position, WantsToMelee, RunState};
 extern crate rltk;
-use rltk::{Point};
+use rltk::Point;
 
 pub struct MonsterAI {}
 
 impl<'a> System<'a> for MonsterAI {
     #[allow(clippy::type_complexity)]
-    type SystemData = ( WriteExpect<'a, Map>,
-                        ReadExpect<'a, Point>,
-                        ReadExpect<'a, Entity>,
-                        ReadExpect<'a, RunState>,
-                        Entities<'a>,
-                        WriteStorage<'a, Viewshed>, 
-                        ReadStorage<'a, Monster>,
-                        WriteStorage<'a, Position>,
-                        WriteStorage<'a, WantsToMelee>);
+    type SystemData = (
+        WriteExpect<'a, Map>,
+        ReadExpect<'a, Point>,
+        ReadExpect<'a, Entity>,
+        ReadExpect<'a, RunState>,
+        Entities<'a>,
+        WriteStorage<'a, Viewshed>,
+        ReadStorage<'a, Monster>,
+        WriteStorage<'a, Position>,
+        WriteStorage<'a, WantsToMelee>,
+    );
 
-    fn run(&mut self, data : Self::SystemData) {
-        let (mut map, player_pos, player_entity, runstate, entities, mut viewshed, monster, mut position, mut wants_to_melee) = data;
+    fn run(&mut self, data: Self::SystemData) {
+        let (
+            mut map,
+            player_pos,
+            player_entity,
+            runstate,
+            entities,
+            mut viewshed,
+            monster,
+            mut position,
+            mut wants_to_melee,
+        ) = data;
 
-        if *runstate != RunState::MonsterTurn { return; }
+        if *runstate != RunState::MonsterTurn {
+            return;
+        }
 
-        for (entity, mut viewshed,_monster,mut pos) in (&entities, &mut viewshed, &monster, &mut position).join() {
-            let distance = rltk::DistanceAlg::Pythagoras.distance2d(Point::new(pos.x, pos.y), *player_pos);
+        for (entity, mut viewshed, _monster, mut pos) in
+            (&entities, &mut viewshed, &monster, &mut position).join()
+        {
+            let distance =
+                rltk::DistanceAlg::Pythagoras.distance2d(Point::new(pos.x, pos.y), *player_pos);
             if distance < 1.5 {
-                wants_to_melee.insert(entity, WantsToMelee{ target: *player_entity }).expect("Unable to insert attack");
-            }
-            else if viewshed.visible_tiles.contains(&*player_pos) {
+                wants_to_melee
+                    .insert(
+                        entity,
+                        WantsToMelee {
+                            target: *player_entity,
+                        },
+                    )
+                    .expect("Unable to insert attack");
+            } else if viewshed.visible_tiles.contains(&*player_pos) {
                 // Path to the player
                 let path = rltk::a_star_search(
-                    map.xy_idx(pos.x, pos.y) as i32, 
-                    map.xy_idx(player_pos.x, player_pos.y) as i32, 
-                    &mut *map
+                    map.xy_idx(pos.x, pos.y) as i32,
+                    map.xy_idx(player_pos.x, player_pos.y) as i32,
+                    &mut *map,
                 );
-                if path.success && path.steps.len()>1 {
+                if path.success && path.steps.len() > 1 {
                     let mut idx = map.xy_idx(pos.x, pos.y);
                     map.blocked[idx] = false;
                     pos.x = path.steps[1] % map.width;
@@ -47,4 +70,4 @@ impl<'a> System<'a> for MonsterAI {
             }
         }
     }
-}
+}

+ 32 - 27
chapter-07-damage/src/player.rs

@@ -1,9 +1,9 @@
 extern crate rltk;
-use rltk::{VirtualKeyCode, Rltk, Point};
+use rltk::{Point, Rltk, VirtualKeyCode};
 extern crate specs;
+use super::{CombatStats, Map, Player, Position, RunState, State, Viewshed, WantsToMelee};
 use specs::prelude::*;
 use std::cmp::{max, min};
-use super::{Position, Player, Viewshed, State, Map, RunState, CombatStats, WantsToMelee};
 
 pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
     let mut positions = ecs.write_storage::<Position>();
@@ -14,19 +14,28 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
     let map = ecs.fetch::<Map>();
     let mut wants_to_melee = ecs.write_storage::<WantsToMelee>();
 
-    for (entity, _player, pos, viewshed) in (&entities, &players, &mut positions, &mut viewsheds).join() {
+    for (entity, _player, pos, viewshed) in
+        (&entities, &players, &mut positions, &mut viewsheds).join()
+    {
         let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
 
         for potential_target in map.tile_content[destination_idx].iter() {
             let target = combat_stats.get(*potential_target);
             if let Some(_target) = target {
-                wants_to_melee.insert(entity, WantsToMelee{ target: *potential_target }).expect("Add target failed");
+                wants_to_melee
+                    .insert(
+                        entity,
+                        WantsToMelee {
+                            target: *potential_target,
+                        },
+                    )
+                    .expect("Add target failed");
                 return;
             }
         }
 
         if !map.blocked[destination_idx] {
-            pos.x = min(79 , max(0, pos.x + delta_x));
+            pos.x = min(79, max(0, pos.x + delta_x));
             pos.y = min(49, max(0, pos.y + delta_y));
 
             viewshed.dirty = true;
@@ -40,38 +49,34 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
 pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
     // Player movement
     match ctx.key {
-        None => { return RunState::AwaitingInput } // Nothing happened
+        None => return RunState::AwaitingInput, // Nothing happened
         Some(key) => match key {
-            VirtualKeyCode::Left |
-            VirtualKeyCode::Numpad4 |
-            VirtualKeyCode::H => try_move_player(-1, 0, &mut gs.ecs),
+            VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H => {
+                try_move_player(-1, 0, &mut gs.ecs)
+            }
 
-            VirtualKeyCode::Right |
-            VirtualKeyCode::Numpad6 |
-            VirtualKeyCode::L => try_move_player(1, 0, &mut gs.ecs),
+            VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L => {
+                try_move_player(1, 0, &mut gs.ecs)
+            }
 
-            VirtualKeyCode::Up |
-            VirtualKeyCode::Numpad8 |
-            VirtualKeyCode::K => try_move_player(0, -1, &mut gs.ecs),
+            VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => {
+                try_move_player(0, -1, &mut gs.ecs)
+            }
 
-            VirtualKeyCode::Down |
-            VirtualKeyCode::Numpad2 |
-            VirtualKeyCode::J => try_move_player(0, 1, &mut gs.ecs),
+            VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => {
+                try_move_player(0, 1, &mut gs.ecs)
+            }
 
             // Diagonals
-            VirtualKeyCode::Numpad9 |
-            VirtualKeyCode::U => try_move_player(1, -1, &mut gs.ecs),
+            VirtualKeyCode::Numpad9 | VirtualKeyCode::U => try_move_player(1, -1, &mut gs.ecs),
 
-            VirtualKeyCode::Numpad7 |
-            VirtualKeyCode::Y => try_move_player(-1, -1, &mut gs.ecs),
+            VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => try_move_player(-1, -1, &mut gs.ecs),
 
-            VirtualKeyCode::Numpad3 |
-            VirtualKeyCode::N => try_move_player(1, 1, &mut gs.ecs),
+            VirtualKeyCode::Numpad3 | VirtualKeyCode::N => try_move_player(1, 1, &mut gs.ecs),
 
-            VirtualKeyCode::Numpad1 |
-            VirtualKeyCode::B => try_move_player(-1, 1, &mut gs.ecs),
+            VirtualKeyCode::Numpad1 | VirtualKeyCode::B => try_move_player(-1, 1, &mut gs.ecs),
 
-            _ => { return RunState::AwaitingInput }
+            _ => return RunState::AwaitingInput,
         },
     }
     RunState::PlayerTurn

+ 14 - 9
chapter-07-damage/src/rect.rs

@@ -1,21 +1,26 @@
 pub struct Rect {
-    pub x1 : i32,
-    pub x2 : i32,
-    pub y1 : i32,
-    pub y2 : i32
+    pub x1: i32,
+    pub x2: i32,
+    pub y1: i32,
+    pub y2: i32,
 }
 
 impl Rect {
-    pub fn new(x:i32, y: i32, w:i32, h:i32) -> Rect {
-        Rect{x1:x, y1:y, x2:x+w, y2:y+h}
+    pub fn new(x: i32, y: i32, w: i32, h: i32) -> Rect {
+        Rect {
+            x1: x,
+            y1: y,
+            x2: x + w,
+            y2: y + h,
+        }
     }
 
     // Returns true if this overlaps with other
-    pub fn intersect(&self, other:&Rect) -> bool {
+    pub fn intersect(&self, other: &Rect) -> bool {
         self.x1 <= other.x2 && self.x2 >= other.x1 && self.y1 <= other.y2 && self.y2 >= other.y1
     }
 
     pub fn center(&self) -> (i32, i32) {
-        ((self.x1 + self.x2)/2, (self.y1 + self.y2)/2)
+        ((self.x1 + self.x2) / 2, (self.y1 + self.y2) / 2)
     }
-}
+}

+ 17 - 12
chapter-07-damage/src/visibility_system.rs

@@ -1,30 +1,35 @@
 extern crate specs;
+use super::{Map, Player, Position, Viewshed};
 use specs::prelude::*;
-use super::{Viewshed, Position, Map, Player};
 extern crate rltk;
 use rltk::{field_of_view, Point};
 
 pub struct VisibilitySystem {}
 
 impl<'a> System<'a> for VisibilitySystem {
-    type SystemData = ( WriteExpect<'a, Map>,
-                        Entities<'a>,
-                        WriteStorage<'a, Viewshed>, 
-                        ReadStorage<'a, Position>,
-                        ReadStorage<'a, Player>);
+    type SystemData = (
+        WriteExpect<'a, Map>,
+        Entities<'a>,
+        WriteStorage<'a, Viewshed>,
+        ReadStorage<'a, Position>,
+        ReadStorage<'a, Player>,
+    );
 
-    fn run(&mut self, data : Self::SystemData) {
+    fn run(&mut self, data: Self::SystemData) {
         let (mut map, entities, mut viewshed, pos, player) = data;
 
-        for (ent,viewshed,pos) in (&entities, &mut viewshed, &pos).join() {
+        for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
             if viewshed.dirty {
                 viewshed.dirty = false;
-                viewshed.visible_tiles = field_of_view(Point::new(pos.x, pos.y), viewshed.range, &*map);
+                viewshed.visible_tiles =
+                    field_of_view(Point::new(pos.x, pos.y), viewshed.range, &*map);
 
                 // If this is the player, reveal what they can see
-                let _p : Option<&Player> = player.get(ent);
+                let _p: Option<&Player> = player.get(ent);
                 if let Some(_p) = _p {
-                    for t in map.visible_tiles.iter_mut() { *t = false };
+                    for t in map.visible_tiles.iter_mut() {
+                        *t = false
+                    }
                     for vis in viewshed.visible_tiles.iter() {
                         let idx = map.xy_idx(vis.x, vis.y);
                         map.revealed_tiles[idx] = true;
@@ -34,4 +39,4 @@ impl<'a> System<'a> for VisibilitySystem {
             }
         }
     }
-}
+}