movement depends on monster class now
This commit is contained in:
parent
0b08cb41c2
commit
efe531f6ce
|
@ -129,13 +129,7 @@ impl Level {
|
|||
}
|
||||
loop {
|
||||
// calculate the direction the monster will try to walk
|
||||
let (dx, dy) = match self.rng.gen_range(0..5) {
|
||||
1 => { (1, 0) }
|
||||
2 => { (-1, 0) }
|
||||
3 => { (0, 1) }
|
||||
4 => { (0, -1) }
|
||||
_ => { (0, 0) }
|
||||
};
|
||||
let (dx, dy) = self.monsters[index].get_next_move(&self, player.get_immutable_position());
|
||||
if self.can_monster_move(self.monsters[index].as_ref(), dx, dy) {
|
||||
let (new_x, new_y) = self.monsters[index].get_position().change(dx, dy);
|
||||
if player.get_immutable_position().get_x() == new_x && player.get_immutable_position().get_y() == new_y {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use ratatui::prelude::Color;
|
||||
|
||||
use crate::dungeon_slayer::MonsterStats;
|
||||
use crate::level::Level;
|
||||
use crate::position::{HasPosition, Position};
|
||||
use rand::Rng;
|
||||
|
||||
|
||||
pub trait Monster: HasPosition {
|
||||
fn get_name(&self) -> &str;
|
||||
|
@ -13,6 +16,7 @@ pub trait Monster: HasPosition {
|
|||
fn get_ticks_between_steps(&self) -> u128;
|
||||
fn get_defense(&self) -> u8;
|
||||
fn get_hit(&self) -> u8;
|
||||
fn get_next_move(&self, level: &Level, player_pos: &Position) -> (i16, i16);
|
||||
#[cfg(test)]
|
||||
fn get_life(&self) -> usize;
|
||||
}
|
||||
|
@ -30,6 +34,9 @@ macro_rules! default_monster {
|
|||
fn get_ticks_between_steps(&self) -> u128 { self.ticks_between_steps }
|
||||
fn get_defense(&self) -> u8 { self.monster_stats.defense }
|
||||
fn get_hit(&self) -> u8 { self.monster_stats.hit }
|
||||
fn get_next_move(&self, level: &Level, player_pos: &Position) -> (i16, i16) {
|
||||
self.calc_move(level, player_pos)
|
||||
}
|
||||
#[cfg(test)]
|
||||
fn get_life(&self) -> usize { self.life }
|
||||
}
|
||||
|
@ -90,6 +97,20 @@ impl crate::monster::LowerDaemon {
|
|||
monster_stats,
|
||||
}
|
||||
}
|
||||
|
||||
fn calc_move(&self, level: &Level, player_pos: &Position) -> (i16, i16) {
|
||||
let d = self.position.distance(player_pos);
|
||||
if d == 1 {
|
||||
return self.position.get_direction(player_pos);
|
||||
}
|
||||
match rand::thread_rng().gen_range(0..5) {
|
||||
1 => { (1, 0) }
|
||||
2 => { (-1, 0) }
|
||||
3 => { (0, 1) }
|
||||
4 => { (0, -1) }
|
||||
_ => { (0, 0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
default_monster!(LowerDaemon);
|
||||
|
||||
|
@ -139,6 +160,15 @@ impl Rat {
|
|||
monster_stats,
|
||||
}
|
||||
}
|
||||
fn calc_move(&self, level: &Level, player_pos: &Position) -> (i16, i16) {
|
||||
match rand::thread_rng().gen_range(0..5) {
|
||||
1 => { (1, 0) }
|
||||
2 => { (-1, 0) }
|
||||
3 => { (0, 1) }
|
||||
4 => { (0, -1) }
|
||||
_ => { (0, 0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
default_monster!(Rat);
|
||||
|
||||
|
@ -188,6 +218,15 @@ impl Orc {
|
|||
monster_stats,
|
||||
}
|
||||
}
|
||||
fn calc_move(&self, level: &Level, player_pos: &Position) -> (i16, i16) {
|
||||
match rand::thread_rng().gen_range(0..5) {
|
||||
1 => { (1, 0) }
|
||||
2 => { (-1, 0) }
|
||||
3 => { (0, 1) }
|
||||
4 => { (0, -1) }
|
||||
_ => { (0, 0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default_monster!(Orc);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::cmp::max;
|
||||
use std::cmp::{max, min};
|
||||
|
||||
/// describes an character (PC or NPC) in the dungeon that has a position.
|
||||
pub trait HasPosition {
|
||||
|
@ -43,6 +43,28 @@ impl Position {
|
|||
}
|
||||
|
||||
pub fn get_y(&self) -> usize { self.y }
|
||||
|
||||
/// calculate the distance to the other position using the manhattan metric
|
||||
pub fn distance(&self, other: &Self) -> usize {
|
||||
self.x.abs_diff(other.x) + self.y.abs_diff(other.y)
|
||||
}
|
||||
|
||||
/// get the direction (step size 1) towards the other position
|
||||
pub fn get_direction(&self, other: &Self) -> (i16, i16) {
|
||||
(
|
||||
max(min(other.x as i16 - self.x as i16, 1), -1),
|
||||
max(min(other.y as i16 - self.y as i16, 1), -1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_direction() {
|
||||
let p1 = Position::new(0, 10, 10);
|
||||
let p2 = Position::new(0, 8, 8);
|
||||
assert_eq!(p1.get_direction(&p2), (-1, -1));
|
||||
let p2 = Position::new(0, 11, 10);
|
||||
assert_eq!(p1.get_direction(&p2), (1, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue