summaryrefslogtreecommitdiff
path: root/dungeon/src/entity.rs
blob: 02184a98ab28c1439674b2d810d45fe0b889c929 (plain)
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
//! 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,
	/// An item (not in an inventory) on the floor of the dungeon
	Item(Item),
}

/// 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,
	/// 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};
	///
	/// let pos = Pos::new(0, 0).unwrap();
	/// let dir = Direction::North;
	/// let kind = EntityKind::Player;
	/// let health = Some(10);
	/// let entity = Entity::new(pos, dir, kind, health);
	/// ```
	#[must_use]
	pub const fn new(
		pos: Pos,
		dir: Direction,
		kind: EntityKind,
		health: Option<u32>,
	) -> Self {
		let fpos = FPos::from_pos(pos);
		Self {
			pos,
			fpos,
			dir,
			kind,
			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 health = Some(PLAYER_FULL_HEALTH);
		Self::new(pos, dir, kind, health)
	}
}

/// 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)
	}
}