1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
//! The `entity` module contains structures of all entities including players and enimies.
use crate::{Direction, FPos, Pos, const_pos};
/// `PLAYER_FULL_HEALTH` is the starting health of the player entity
pub const PLAYER_FULL_HEALTH: u32 = 10;
/// `PLAYER_INVENTORY_SIZE` is the maximum size of the inventory
pub const PLAYER_INVENTORY_SIZE: usize = 5;
/// The `Item` type represents any item an entity may be using
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Item {
Potion { heal: u32 },
Weapon { atack: u32 },
Armor { defense: u32 },
}
/// The `EntityKind` represents what kind of entity this is.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum EntityKind {
/// The main player
Player,
Enemy,
/// An item (not in an inventory) on the floor of the dungeon
Item(Item),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EntityMoveSpeed {
Slow,
Medium,
Fast,
}
impl EntityMoveSpeed {
/// Returns value in tiles/second
pub fn value(&self) -> f32 {
match &self {
Self::Slow => 1.,
Self::Medium => 2.,
Self::Fast => 3.,
}
}
}
/// The `Entity` kind represents the main player, or any other
/// ai autonomous character that can move freely across the
/// dungeon.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Entity {
/// The fixed grid position of the entity
pub pos: Pos,
/// The floating (real) current position of the entity
pub fpos: FPos,
/// Which direction this entity is facing
pub dir: Direction,
/// Which kind this entity is (along with entity kind specific data)
pub kind: EntityKind,
/// Move speed of this entity
pub move_speed: EntityMoveSpeed,
/// The amount of health this entity has (None if this Entity does not use health)
pub health: Option<u32>,
}
impl Entity {
/// Creates a new `Entity` at a given `Pos`, `Direction`, and `EntityKind`.
///
/// # Examples
///
/// ```
/// use dungeon::{Pos, Direction, Entity, EntityKind, EntityMoveSpeed};
///
/// let pos = Pos::new(0, 0).unwrap();
/// let dir = Direction::North;
/// let kind = EntityKind::Player;
/// let health = Some(10);
/// let move_speed = EntityMoveSpeed::Medium;
/// let entity = Entity::new(pos, dir, kind, move_speed, health);
/// ```
#[must_use]
pub const fn new(
pos: Pos,
dir: Direction,
kind: EntityKind,
move_speed: EntityMoveSpeed,
health: Option<u32>,
) -> Self {
let fpos = FPos::from_pos(pos);
Self {
pos,
fpos,
dir,
kind,
move_speed,
health,
}
}
/// Creates the Player version of the `Entity`
///
/// # Examples
///
/// ```
/// use dungeon::{Pos, Entity};
///
/// let pos = Pos::new(0, 0).unwrap();
/// let player = Entity::player(pos);
/// ```
#[must_use]
pub const fn player(pos: Pos) -> Self {
let dir = Direction::East;
let kind = EntityKind::Player;
let move_speed = EntityMoveSpeed::Medium;
let health = Some(PLAYER_FULL_HEALTH);
Self::new(pos, dir, kind, move_speed, health)
}
/// Creates an Enemy version of the `Entity`
///
/// # Examples
///
/// ```
/// use dungeon::{Pos, Entity, EntityMoveSpeed};
///
/// let pos = Pos::new(0, 0).unwrap();
/// let move_speed = EntityMoveSpeed::Medium;
/// let health = 8;
/// let enemy = Entity::enemy(pos, move_speed, health);
/// ```
#[must_use]
pub const fn enemy(pos: Pos, move_speed: EntityMoveSpeed, health: u32) -> Self {
let dir = Direction::East;
let kind = EntityKind::Enemy;
Self::new(pos, dir, kind, move_speed, Some(health))
}
pub fn move_by_dir(&mut self, dir: Direction, delta_time: f32) {
if let Some(fp) = self.fpos.step_by(dir, delta_time * self.move_speed.value()) {
// TODO: collision
self.fpos = fp;
}
}
}
/// The `Player` type represents the main player entity
#[derive(Clone, Debug, PartialEq)]
pub struct Player {
pub entity: Entity,
pub inventory: Vec<Item>,
}
impl Player {
/// Instantiates the game player at a given `Pos`
///
/// # Examples
///
/// ```
/// use dungeon::{Pos, Player};
///
/// let pos = Pos::new(1, 2).unwrap();
/// let player = Player::new(pos);
/// ```
pub fn new(pos: Pos) -> Self {
let entity = Entity::player(pos);
let inventory = vec![];
Self { entity, inventory }
}
}
impl Default for Player {
fn default() -> Self {
let pos = const_pos!(1, 1);
Self::new(pos)
}
}
|