el_diablo/src/monster.rs

132 lines
3.3 KiB
Rust
Raw Normal View History

2024-10-20 22:12:28 +02:00
use std::ops::RangeInclusive;
2024-10-25 07:21:34 +02:00
use crate::position::{HasPosition, Position};
use macros::CreateMonsters;
2024-10-20 22:12:28 +02:00
use rand::Rng;
2023-12-18 16:11:19 +01:00
use ratatui::prelude::Color;
2023-12-25 13:47:15 +01:00
pub trait Monster: HasPosition {
2023-12-31 15:59:52 +01:00
fn get_name(&self) -> &str;
2023-12-18 16:11:19 +01:00
fn is_dead(&self) -> bool;
fn get_representation(&self) -> (&str, Color);
fn decrease_life(&mut self, by: usize);
2023-12-25 13:47:15 +01:00
// fn get_immutable_position(&self) -> &Position;
2023-12-22 20:10:30 +01:00
fn get_experience_gain(&self) -> usize;
2023-12-26 19:11:41 +01:00
fn get_ticks_between_steps(&self) -> u128;
2023-12-18 16:11:19 +01:00
#[cfg(test)]
fn get_life(&self) -> usize;
2024-10-20 22:12:28 +02:00
fn damage(&self) -> usize;
2023-12-18 16:11:19 +01:00
}
#[derive(CreateMonsters, PartialEq, Eq, Hash, Clone, Copy)]
2024-10-25 07:21:34 +02:00
pub enum MonsterTypes {
Rat,
Orc,
Snake,
Skeleton,
Spider,
2024-10-25 07:21:34 +02:00
}
2023-12-26 19:11:41 +01:00
2024-10-25 07:21:34 +02:00
macro_rules! create_monster {
($t:ident $(, $k:ident : $v:expr)*$(,)?) => (
impl $t {
pub fn new_with_position(position: Position) -> Self {
Self {
position,
$($k: $v,)*
}
2023-12-25 13:47:15 +01:00
}
2023-12-18 16:11:19 +01:00
}
2024-10-25 07:21:34 +02:00
)
2023-12-18 16:11:19 +01:00
}
2024-10-25 07:21:34 +02:00
create_monster!(
Rat,
name:"rat".to_string(),
life: 2,
symbol: String::from("r"),
2024-10-31 22:39:11 +01:00
color: Color::White,
2024-10-25 07:21:34 +02:00
experience_gain: 5,
ticks_between_steps: 5,
damage_range: 1..=2,
);
2023-12-18 16:11:19 +01:00
create_monster!(
Spider,
name:"spider".to_string(),
life: 3,
symbol: String::from("s"),
2024-11-01 08:49:12 +01:00
color: Color::Yellow,
experience_gain: 7,
ticks_between_steps: 7,
damage_range: 2..=3,
);
2024-10-25 07:21:34 +02:00
create_monster!(
Orc,
name: "orc".to_string(),
life: 4,
symbol: String::from("O"),
2024-10-31 22:39:11 +01:00
color: Color::Gray,
2024-10-25 07:21:34 +02:00
experience_gain: 10,
ticks_between_steps: 10,
damage_range: 2..=3,
);
2023-11-27 19:21:10 +01:00
2024-10-25 07:21:34 +02:00
create_monster!(
Snake,
name: "snake".to_string(),
life: 3,
symbol: String::from("s"),
2024-10-31 22:39:11 +01:00
color: Color::White,
2024-10-25 07:21:34 +02:00
experience_gain: 10,
ticks_between_steps: 20,
damage_range: 1..=4,
);
2023-12-18 16:11:19 +01:00
2024-10-25 07:21:34 +02:00
create_monster!(
Skeleton,
name: "skeleton".to_string(),
life: 3,
symbol: String::from("S"),
2024-10-31 22:39:11 +01:00
color: Color::Gray,
2024-10-25 07:21:34 +02:00
experience_gain: 20,
ticks_between_steps: 10,
damage_range: 1..=5,
);
pub fn create_monster_by_type(monster_type: &MonsterTypes, position: Position) -> Box<dyn Monster> {
match monster_type {
MonsterTypes::Rat => Box::new(Rat::new_with_position(position)),
MonsterTypes::Orc => Box::new(Orc::new_with_position(position)),
MonsterTypes::Snake => Box::new(Snake::new_with_position(position)),
MonsterTypes::Skeleton => Box::new(Skeleton::new_with_position(position)),
MonsterTypes::Spider => Box::new(Spider::new_with_position(position)),
2024-10-24 08:57:52 +02:00
}
}
2023-11-27 19:21:10 +01:00
#[test]
fn monsters_can_move() {
2023-12-31 15:59:52 +01:00
let mut m = Rat::new_with_position(Position::new(0, 0, 0));
2023-11-27 19:21:10 +01:00
assert_eq!(m.get_position(), &Position::new(0, 0, 0));
m.get_position().change(1, 2);
assert_eq!(m.get_position(), &Position::new(0, 1, 2));
m.get_position().change(2, 1);
assert_eq!(m.get_position(), &Position::new(0, 3, 3));
m.get_position().set(1, 2, 3);
m.get_position().change(2, 1);
assert_eq!(m.get_position(), &Position::new(1, 4, 4));
}
#[test]
fn monsters_can_die() {
2023-12-31 15:59:52 +01:00
let mut m = Rat::new_with_position(Position::new(0, 0, 0));
2023-11-27 19:21:10 +01:00
assert_eq!(m.get_life(), 2);
assert_eq!(m.is_dead(), false);
m.decrease_life(1);
assert_eq!(m.get_life(), 1);
m.decrease_life(2);
assert_eq!(m.get_life(), 0);
assert_eq!(m.is_dead(), true);
2024-10-20 14:59:20 +02:00
}