use macros to create monsters
This commit is contained in:
@@ -12,7 +12,7 @@ use rand::Rng;
|
||||
|
||||
use crate::artifacts::{Artifact, Chest, Potion};
|
||||
use crate::level::{Level, StructureElement};
|
||||
use crate::monster::{create_monster_by_type, Monster, Orc, Rat, Snake};
|
||||
use crate::monster::{create_monster_by_type, Monster, MonsterTypes, Orc, Rat, Snake};
|
||||
use crate::position::Position;
|
||||
|
||||
pub const ROOMS_VERTICAL: usize = 7;
|
||||
@@ -268,11 +268,12 @@ impl LevelGenerator {
|
||||
|
||||
let t = [
|
||||
// level 0
|
||||
HashMap::from([("Rat", 1..=100)]),
|
||||
HashMap::from([(MonsterTypes::Rat, 1..=100)]),
|
||||
// level 1
|
||||
// HashMap::from([("Rat", 1..=50), ("Snake", 51..=100)]),
|
||||
// // level 2
|
||||
// HashMap::from([("Rat", 1..=40)]),
|
||||
HashMap::from([(MonsterTypes::Rat, 1..=50), (MonsterTypes::Snake, 51..=100)]),
|
||||
// level 2
|
||||
HashMap::from([(MonsterTypes::Orc, 1..=100)]),
|
||||
HashMap::from([(MonsterTypes::Skeleton, 1..=100)]),
|
||||
];
|
||||
if level < t.len() {
|
||||
for (mtype, range) in &t[level] {
|
||||
|
||||
152
src/monster.rs
152
src/monster.rs
@@ -1,10 +1,10 @@
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use crate::position::{HasPosition, Position};
|
||||
use macros::CreateMonsters;
|
||||
use rand::Rng;
|
||||
use ratatui::prelude::Color;
|
||||
|
||||
use crate::position::{HasPosition, Position};
|
||||
|
||||
pub trait Monster: HasPosition {
|
||||
fn get_name(&self) -> &str;
|
||||
fn is_dead(&self) -> bool;
|
||||
@@ -18,99 +18,77 @@ pub trait Monster: HasPosition {
|
||||
fn damage(&self) -> usize;
|
||||
}
|
||||
|
||||
#[derive(CreateMonsters, PartialEq, Eq, Hash)]
|
||||
pub enum MonsterTypes {
|
||||
Rat,
|
||||
Orc,
|
||||
Snake,
|
||||
Skeleton,
|
||||
}
|
||||
|
||||
macro_rules! create_monster {
|
||||
($($t:ident),+ $(,)?) => ($(
|
||||
pub struct $t {
|
||||
name: String,
|
||||
life: usize,
|
||||
position: Position,
|
||||
symbol: String,
|
||||
color: Color,
|
||||
experience_gain: usize,
|
||||
ticks_between_steps: u128,
|
||||
damage_range: RangeInclusive<usize>,
|
||||
}
|
||||
impl Monster for $t {
|
||||
fn get_name(&self) -> &str { &self.name }
|
||||
fn is_dead(&self) -> bool { self.life <= 0 }
|
||||
fn get_experience_gain(&self) -> usize { self.experience_gain }
|
||||
fn get_representation(&self) -> (&str, Color) { (&self.symbol, self.color) }
|
||||
fn decrease_life(&mut self, by: usize) {
|
||||
self.life = self.life.saturating_sub(by);
|
||||
}
|
||||
fn get_ticks_between_steps(&self) -> u128 { self.ticks_between_steps }
|
||||
fn damage(&self) -> usize { rand::thread_rng().gen_range(self.damage_range.clone()) }
|
||||
|
||||
#[cfg(test)]
|
||||
fn get_life(&self) -> usize { self.life }
|
||||
}
|
||||
impl HasPosition for $t {
|
||||
fn get_position(&mut self) -> &mut Position {
|
||||
&mut self.position
|
||||
}
|
||||
fn get_immutable_position(&self) -> &Position {
|
||||
&self.position
|
||||
($t:ident $(, $k:ident : $v:expr)*$(,)?) => (
|
||||
impl $t {
|
||||
pub fn new_with_position(position: Position) -> Self {
|
||||
Self {
|
||||
position,
|
||||
$($k: $v,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
)+)
|
||||
)
|
||||
}
|
||||
|
||||
impl Rat {
|
||||
pub fn new_with_position(position: Position) -> Self {
|
||||
Self {
|
||||
name: "rat".to_string(),
|
||||
life: 2,
|
||||
position,
|
||||
symbol: String::from("R"),
|
||||
color: Color::Black,
|
||||
experience_gain: 5,
|
||||
ticks_between_steps: 5,
|
||||
damage_range: 1..=2,
|
||||
}
|
||||
}
|
||||
}
|
||||
create_monster!(Rat);
|
||||
create_monster!(
|
||||
Rat,
|
||||
name:"rat".to_string(),
|
||||
life: 2,
|
||||
symbol: String::from("R"),
|
||||
color: Color::Black,
|
||||
experience_gain: 5,
|
||||
ticks_between_steps: 5,
|
||||
damage_range: 1..=2,
|
||||
);
|
||||
|
||||
impl Orc {
|
||||
pub fn new_with_position(position: Position) -> Self {
|
||||
Self {
|
||||
name: "orc".to_string(),
|
||||
life: 4,
|
||||
position,
|
||||
symbol: String::from("O"),
|
||||
color: Color::DarkGray,
|
||||
experience_gain: 10,
|
||||
ticks_between_steps: 10,
|
||||
damage_range: 2..=3,
|
||||
}
|
||||
}
|
||||
}
|
||||
create_monster!(Orc);
|
||||
create_monster!(
|
||||
Orc,
|
||||
name: "orc".to_string(),
|
||||
life: 4,
|
||||
symbol: String::from("O"),
|
||||
color: Color::DarkGray,
|
||||
experience_gain: 10,
|
||||
ticks_between_steps: 10,
|
||||
damage_range: 2..=3,
|
||||
);
|
||||
|
||||
impl Snake {
|
||||
pub fn new_with_position(position: Position) -> Self {
|
||||
Self {
|
||||
name: "snake".to_string(),
|
||||
life: 3,
|
||||
position,
|
||||
symbol: String::from("S"),
|
||||
color: Color::DarkGray,
|
||||
experience_gain: 10,
|
||||
ticks_between_steps: 20,
|
||||
damage_range: 1..=4,
|
||||
}
|
||||
}
|
||||
}
|
||||
create_monster!(Snake);
|
||||
create_monster!(
|
||||
Snake,
|
||||
name: "snake".to_string(),
|
||||
life: 3,
|
||||
symbol: String::from("s"),
|
||||
color: Color::Black,
|
||||
experience_gain: 10,
|
||||
ticks_between_steps: 20,
|
||||
damage_range: 1..=4,
|
||||
);
|
||||
|
||||
pub fn create_monster_by_type(mtype: &str, position: Position) -> Box<dyn Monster> {
|
||||
match mtype {
|
||||
"Rat" => Box::new(Rat::new_with_position(position)),
|
||||
"Orc" => Box::new(Orc::new_with_position(position)),
|
||||
"Snake" => Box::new(Snake::new_with_position(position)),
|
||||
&_ => {
|
||||
panic!("Unknown species: {}", mtype)
|
||||
}
|
||||
create_monster!(
|
||||
Skeleton,
|
||||
name: "skeleton".to_string(),
|
||||
life: 3,
|
||||
symbol: String::from("S"),
|
||||
color: Color::DarkGray,
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user