Skip to content

Commit 1b66c76

Browse files
committed
feat: add inventory and power-ups
1 parent dbd656d commit 1b66c76

File tree

6 files changed

+276
-100
lines changed

6 files changed

+276
-100
lines changed

books/hands-on-rust/dungeoncrawl/src/components.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use std::collections::HashSet;
2-
31
pub use crate::prelude::*;
2+
use std::collections::HashSet;
43

54
#[derive(Clone, Copy, Debug, PartialEq)]
65
pub struct Render {
7-
pub color: ColorPair,
8-
pub glyph: FontCharType,
6+
pub color : ColorPair,
7+
pub glyph : FontCharType
98
}
109

1110
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -20,46 +19,64 @@ pub struct Item;
2019
#[derive(Clone, Copy, Debug, PartialEq)]
2120
pub struct AmuletOfYala;
2221

22+
#[derive(Clone, Copy, Debug, PartialEq)]
23+
pub struct ProvidesHealing{
24+
pub amount: i32
25+
}
26+
27+
#[derive(Clone, Copy, Debug, PartialEq)]
28+
pub struct ProvidesDungeonMap;
29+
2330
#[derive(Clone, Copy, Debug, PartialEq)]
2431
pub struct MovingRandomly;
2532

2633
#[derive(Clone, Copy, Debug, PartialEq)]
2734
pub struct ChasingPlayer;
2835

36+
2937
#[derive(Clone, Copy, Debug, PartialEq)]
3038
pub struct WantsToMove {
31-
pub entity: Entity,
32-
pub destination: Point,
39+
pub entity : Entity,
40+
pub destination : Point
3341
}
3442

3543
#[derive(Clone, Copy, Debug, PartialEq)]
3644
pub struct WantsToAttack {
37-
pub attacker: Entity,
38-
pub victim: Entity,
45+
pub attacker : Entity,
46+
pub victim : Entity
3947
}
4048

4149
#[derive(Clone, Copy, Debug, PartialEq)]
4250
pub struct Health {
4351
pub current: i32,
44-
pub max: i32,
52+
pub max: i32
4553
}
4654

4755
#[derive(Clone, PartialEq)]
4856
pub struct Name(pub String);
4957

58+
#[derive(Clone, PartialEq)]
59+
pub struct Carried(pub Entity);
60+
61+
#[derive(Clone, Copy, Debug, PartialEq)]
62+
pub struct ActivateItem {
63+
pub used_by : Entity,
64+
pub item : Entity
65+
}
66+
5067
#[derive(Clone, Debug, PartialEq)]
51-
pub struct FieldOfView {
52-
pub visible_tiles: HashSet<Point>,
68+
pub struct FieldOfView{
69+
pub visible_tiles : HashSet<Point>,
5370
pub radius: i32,
54-
pub is_dirty: bool,
71+
pub is_dirty: bool
5572
}
5673

5774
impl FieldOfView {
5875
pub fn new(radius: i32) -> Self {
59-
Self {
76+
Self{
6077
visible_tiles: HashSet::new(),
6178
radius,
62-
is_dirty: true,
79+
is_dirty: true
6380
}
6481
}
6582

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,55 @@
11
use crate::prelude::*;
22

3-
pub fn spawn_player(ecs: &mut World, pos: Point) {
4-
ecs.push((
5-
Player,
6-
pos,
7-
Render {
8-
color: ColorPair::new(WHITE, BLACK),
9-
glyph: to_cp437('@'),
10-
},
11-
Health {
12-
current: 10,
13-
max: 10,
14-
},
15-
FieldOfView::new(8),
16-
));
17-
}
18-
19-
pub fn spawn_monster(ecs: &mut World, rng: &mut RandomNumberGenerator, pos: Point) {
20-
let (hp, name, glyph) = match rng.roll_dice(1, 10) {
3+
pub fn spawn_player(ecs : &mut World, pos : Point) {
4+
ecs.push(
5+
(Player,
6+
pos,
7+
Render{
8+
color: ColorPair::new(WHITE, BLACK),
9+
glyph : to_cp437('@')
10+
},
11+
Health{ current: 10, max: 10 },
12+
FieldOfView::new(8)
13+
)
14+
);
15+
}
16+
17+
pub fn spawn_entity(
18+
ecs: &mut World,
19+
rng: &mut RandomNumberGenerator,
20+
pos: Point
21+
) {
22+
let roll = rng.roll_dice(1, 6);
23+
match roll {
24+
1 => spawn_healing_potion(ecs, pos),
25+
2 => spawn_magic_mapper(ecs, pos),
26+
_ => spawn_monster(ecs, rng, pos)
27+
}
28+
}
29+
30+
pub fn spawn_monster(
31+
ecs: &mut World,
32+
rng: &mut RandomNumberGenerator,
33+
pos : Point
34+
) {
35+
let (hp, name, glyph) = match rng.roll_dice(1,10) {
2136
1..=8 => goblin(),
22-
_ => orc(),
37+
_ => orc()
2338
};
2439

25-
ecs.push((
26-
Enemy,
27-
pos,
28-
Render {
29-
color: ColorPair::new(WHITE, BLACK),
30-
glyph,
31-
},
32-
ChasingPlayer {},
33-
Health {
34-
current: hp,
35-
max: hp,
36-
},
37-
Name(name),
38-
FieldOfView::new(6),
39-
));
40+
ecs.push(
41+
(Enemy,
42+
pos,
43+
Render{
44+
color: ColorPair::new(WHITE, BLACK),
45+
glyph,
46+
},
47+
ChasingPlayer{},
48+
Health{current: hp, max: hp},
49+
Name(name),
50+
FieldOfView::new(6)
51+
)
52+
);
4053
}
4154

4255
fn goblin() -> (i32, String, FontCharType) {
@@ -47,15 +60,43 @@ fn orc() -> (i32, String, FontCharType) {
4760
(2, "Orc".to_string(), to_cp437('o'))
4861
}
4962

50-
pub fn spawn_amulet_of_yala(ecs: &mut World, pos: Point) {
51-
ecs.push((
52-
Item,
53-
AmuletOfYala,
54-
pos,
55-
Render {
56-
color: ColorPair::new(WHITE, BLACK),
57-
glyph: to_cp437('|'),
58-
},
59-
Name("Amulet of Yala".to_string()),
60-
));
63+
pub fn spawn_amulet_of_yala(ecs : &mut World, pos : Point) {
64+
ecs.push(
65+
(Item, AmuletOfYala,
66+
pos,
67+
Render{
68+
color: ColorPair::new(WHITE, BLACK),
69+
glyph : to_cp437('|')
70+
},
71+
Name("Amulet of Yala".to_string())
72+
)
73+
);
74+
}
75+
76+
pub fn spawn_healing_potion(ecs: &mut World, pos: Point) {
77+
ecs.push(
78+
(Item,
79+
pos,
80+
Render{
81+
color: ColorPair::new(WHITE, BLACK),
82+
glyph : to_cp437('!')
83+
},
84+
Name("Healing Potion".to_string()),
85+
ProvidesHealing{amount: 6}
86+
)
87+
);
88+
}
89+
90+
pub fn spawn_magic_mapper(ecs: &mut World, pos: Point) {
91+
ecs.push(
92+
(Item,
93+
pos,
94+
Render{
95+
color: ColorPair::new(WHITE, BLACK),
96+
glyph : to_cp437('{')
97+
},
98+
Name("Dungeon Map".to_string()),
99+
ProvidesDungeonMap{}
100+
)
101+
);
61102
}

books/hands-on-rust/dungeoncrawl/src/systems/hud.rs

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,58 @@ use crate::prelude::*;
33
#[system]
44
#[read_component(Health)]
55
#[read_component(Player)]
6+
#[read_component(Item)]
7+
#[read_component(Carried)]
8+
#[read_component(Name)]
69
pub fn hud(ecs: &SubWorld) {
710
let mut health_query = <&Health>::query().filter(component::<Player>());
8-
let player_health = health_query.iter(ecs).nth(0).unwrap();
9-
let mut draw_batch = DrawBatch::new();
11+
let player_health = health_query
12+
.iter(ecs)
13+
.nth(0)
14+
.unwrap();
1015

16+
let mut draw_batch = DrawBatch::new();
1117
draw_batch.target(2);
12-
draw_batch.print_centered(1, "Explore the Dungeon. Cursor keys to move.");
18+
draw_batch.print_centered(1,
19+
"Explore the Dungeon. Cursor keys to move.");
1320
draw_batch.bar_horizontal(
1421
Point::zero(),
15-
SCREEN_WIDTH * 2,
22+
SCREEN_WIDTH*2,
1623
player_health.current,
1724
player_health.max,
18-
ColorPair::new(RED, BLACK),
25+
ColorPair::new(RED, BLACK)
1926
);
2027
draw_batch.print_color_centered(
2128
0,
22-
format!(
23-
" Health: {} / {} ",
24-
player_health.current, player_health.max
29+
format!(" Health: {} / {} ",
30+
player_health.current,
31+
player_health.max
2532
),
26-
ColorPair::new(WHITE, RED),
33+
ColorPair::new(WHITE, RED)
2734
);
35+
36+
let player = <(Entity, &Player)>::query()
37+
.iter(ecs)
38+
.find_map(|(entity, _player)| Some(*entity))
39+
.unwrap();
40+
let mut item_query = <(&Item, &Name, &Carried)>::query();
41+
let mut y = 3;
42+
item_query
43+
.iter(ecs)
44+
.filter(|(_, _, carried)| carried.0 == player)
45+
.for_each(|(_, name, _)| {
46+
draw_batch.print(
47+
Point::new(3, y),
48+
format!("{} : {}", y-2, &name.0)
49+
);
50+
y += 1;
51+
}
52+
);
53+
if y > 3 {
54+
draw_batch.print_color(Point::new(3, 2), "Items carried",
55+
ColorPair::new(YELLOW, BLACK)
56+
);
57+
}
58+
2859
draw_batch.submit(10000).expect("Batch error");
2960
}

books/hands-on-rust/dungeoncrawl/src/systems/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
use crate::prelude::*;
22

3-
mod chasing;
4-
mod combat;
5-
mod end_turn;
6-
mod entity_render;
7-
mod hud;
83
mod map_render;
9-
mod movement;
4+
mod entity_render;
105
mod player_input;
116
mod random_move;
7+
mod chasing;
8+
mod end_turn;
9+
mod movement;
10+
mod hud;
1211
mod tooltips;
12+
mod combat;
1313
mod fov;
14+
mod use_items;
1415

1516
pub fn build_input_scheduler() -> Schedule {
1617
Schedule::builder()
@@ -26,6 +27,7 @@ pub fn build_input_scheduler() -> Schedule {
2627

2728
pub fn build_player_scheduler() -> Schedule {
2829
Schedule::builder()
30+
.add_system(use_items::use_items_system())
2931
.add_system(combat::combat_system())
3032
.flush()
3133
.add_system(movement::movement_system())
@@ -44,6 +46,7 @@ pub fn build_monster_scheduler() -> Schedule {
4446
.add_system(random_move::random_move_system())
4547
.add_system(chasing::chasing_system())
4648
.flush()
49+
.add_system(use_items::use_items_system())
4750
.add_system(combat::combat_system())
4851
.flush()
4952
.add_system(movement::movement_system())

0 commit comments

Comments
 (0)