Skip to main content

thedes_domain/
player.rs

1use serde::{Deserialize, Serialize};
2use thedes_geometry::orientation::Direction;
3use thiserror::Error;
4
5use crate::{
6    geometry::CoordPair,
7    stat::{Stat, StatValue},
8};
9
10#[derive(Debug, Error)]
11pub enum InvalidPlayerHp {
12    #[error("Player HP {0} is too big")]
13    TooBig(u8),
14}
15
16#[derive(Debug, Error)]
17pub enum InitError {
18    #[error("Player pointer position would overflow")]
19    Overflow,
20}
21
22#[derive(
23    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
24)]
25pub struct PlayerPosition {
26    head: CoordPair,
27    facing: Direction,
28}
29
30impl PlayerPosition {
31    pub fn new(head: CoordPair, facing: Direction) -> Result<Self, InitError> {
32        if head.checked_move_unit(facing).is_none() {
33            Err(InitError::Overflow)?
34        }
35        Ok(Self { head, facing })
36    }
37
38    pub fn head(&self) -> CoordPair {
39        self.head
40    }
41
42    pub(crate) fn set_head(&mut self, new_head: CoordPair) {
43        self.head = new_head;
44    }
45
46    pub fn facing(&self) -> Direction {
47        self.facing
48    }
49
50    pub(crate) fn face(&mut self, direction: Direction) {
51        self.facing = direction;
52    }
53
54    pub fn pointer(&self) -> CoordPair {
55        self.head.move_unit(self.facing)
56    }
57
58    pub fn contains(&self, point: CoordPair) -> bool {
59        self.head() == point || self.pointer() == point
60    }
61}
62
63#[derive(
64    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
65)]
66pub struct Player {
67    position: PlayerPosition,
68    hp: Stat,
69}
70
71impl Player {
72    pub const DEFAULT_HP: Stat = Stat::new(80, 80);
73
74    pub fn new(position: PlayerPosition, hp: Stat) -> Self {
75        Self { position, hp }
76    }
77
78    pub fn position(&self) -> &PlayerPosition {
79        &self.position
80    }
81
82    pub(crate) fn position_mut(&mut self) -> &mut PlayerPosition {
83        &mut self.position
84    }
85
86    pub fn hp(&self) -> Stat {
87        self.hp
88    }
89
90    pub fn damage(&mut self, amount: StatValue) {
91        self.hp.decrease_value(amount);
92    }
93
94    pub fn heal(&mut self, amount: StatValue) {
95        self.hp.increase_value(amount);
96    }
97}