make monsters more like players
This commit is contained in:
parent
c0d51f501f
commit
2098bedabe
13
src/game.rs
13
src/game.rs
|
@ -80,19 +80,8 @@ impl Game {
|
||||||
/// limitation as walls.
|
/// limitation as walls.
|
||||||
fn can_move(&mut self, dx: i16, dy: i16) -> bool {
|
fn can_move(&mut self, dx: i16, dy: i16) -> bool {
|
||||||
let player_pos = &self.player.get_position();
|
let player_pos = &self.player.get_position();
|
||||||
let new_x: i16 = player_pos.get_x() as i16 + dx;
|
|
||||||
let new_y: i16 = player_pos.get_y() as i16 + dy;
|
|
||||||
let level = &mut self.levels[player_pos.get_level()];
|
let level = &mut self.levels[player_pos.get_level()];
|
||||||
match level.get_element(new_x, new_y) {
|
level.can_player_move(&self.player, dx, dy)
|
||||||
(None, _, _) => { return false; }
|
|
||||||
(Some(t), _, _) => {
|
|
||||||
match t {
|
|
||||||
StructureElement::Wall => { return false; }
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
/// returns the position (as tuple) of the next level's start point.
|
/// returns the position (as tuple) of the next level's start point.
|
||||||
fn next_start(&self) -> (usize, usize, usize) {
|
fn next_start(&self) -> (usize, usize, usize) {
|
||||||
|
|
111
src/level.rs
111
src/level.rs
|
@ -6,7 +6,7 @@ use crate::artifacts::Artifact;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::monster::{Orc, Rat};
|
use crate::monster::{Orc, Rat};
|
||||||
use crate::monster::Monster;
|
use crate::monster::Monster;
|
||||||
#[cfg(test)]
|
use crate::player::Player;
|
||||||
use crate::position::HasPosition;
|
use crate::position::HasPosition;
|
||||||
use crate::position::Position;
|
use crate::position::Position;
|
||||||
|
|
||||||
|
@ -37,24 +37,6 @@ pub struct Level {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
#[cfg(test)]
|
|
||||||
pub fn new(level: usize) -> Level {
|
|
||||||
let mut s = [[StructureElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH];
|
|
||||||
for x in 2..LEVEL_WIDTH - 2 {
|
|
||||||
for y in 2..LEVEL_HEIGHT - 2 {
|
|
||||||
s[x][y] = StructureElement::Floor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Level {
|
|
||||||
level,
|
|
||||||
structure: s,
|
|
||||||
discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
|
||||||
monsters: Vec::with_capacity(10),
|
|
||||||
artifacts: Vec::with_capacity(10),
|
|
||||||
start: (0, 0),
|
|
||||||
end: (0, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get_element(&mut self, x: i16, y: i16) -> (Option<StructureElement>, Option<&mut Box<(dyn Monster + 'static)>>, Option<&mut Box<(dyn Artifact + 'static)>>) {
|
pub fn get_element(&mut self, x: i16, y: i16) -> (Option<StructureElement>, Option<&mut Box<(dyn Monster + 'static)>>, Option<&mut Box<(dyn Artifact + 'static)>>) {
|
||||||
if x < 0 || y < 0 {
|
if x < 0 || y < 0 {
|
||||||
return (None, None, None);
|
return (None, None, None);
|
||||||
|
@ -82,33 +64,6 @@ impl Level {
|
||||||
}
|
}
|
||||||
(Some(self.structure[x][y]), res_m, res_a)
|
(Some(self.structure[x][y]), res_m, res_a)
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
|
||||||
pub fn add_monster(&mut self, mut monster: impl Monster + 'static) -> Result<(), String> {
|
|
||||||
if self.level != monster.get_position().get_level() {
|
|
||||||
return Err("Wrong Level".to_string());
|
|
||||||
}
|
|
||||||
for m in &mut self.monsters {
|
|
||||||
if m.get_position() == monster.get_position() {
|
|
||||||
return Err("Position already used".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.monsters.push(Box::new(monster));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub fn add_artifact(&mut self, artifact: impl Artifact + 'static) -> Result<(), String> {
|
|
||||||
if self.level != artifact.get_immutable_position().get_level() {
|
|
||||||
return Err("Wrong Level".to_string());
|
|
||||||
}
|
|
||||||
for a in &mut self.artifacts {
|
|
||||||
if a.get_immutable_position() == artifact.get_immutable_position() {
|
|
||||||
return Err("Position already used".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.artifacts.push(Box::new(artifact));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
/// discover the area with in the level around the given position
|
/// discover the area with in the level around the given position
|
||||||
pub fn discover(&mut self, pos: &Position) {
|
pub fn discover(&mut self, pos: &Position) {
|
||||||
let x = pos.get_x();
|
let x = pos.get_x();
|
||||||
|
@ -153,7 +108,6 @@ impl Level {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
for (index, a) in &mut self.artifacts.iter().enumerate() {
|
for (index, a) in &mut self.artifacts.iter().enumerate() {
|
||||||
if a.was_collected() {
|
if a.was_collected() {
|
||||||
|
@ -167,6 +121,69 @@ impl Level {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for index in 0..self.monsters.len() {
|
||||||
|
if self.can_monster_move(self.monsters[index].as_ref(), 0, 1) {
|
||||||
|
self.monsters[index].get_position().change(0, 1);
|
||||||
|
} else if self.can_monster_move(self.monsters[index].as_ref(), 0, -1) {
|
||||||
|
self.monsters[index].get_position().change(0, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn can_monster_move(&self, agent: &dyn Monster, dx: i16, dy: i16) -> bool {
|
||||||
|
let agent_pos = agent.get_immutable_position();
|
||||||
|
let new_x: usize = (agent_pos.get_x() as i16 + dx) as usize;
|
||||||
|
let new_y: usize = (agent_pos.get_y() as i16 + dy) as usize;
|
||||||
|
self.structure[new_x][new_y] != StructureElement::Wall
|
||||||
|
}
|
||||||
|
pub fn can_player_move(&self, agent: &Player, dx: i16, dy: i16) -> bool {
|
||||||
|
let agent_pos = agent.get_immutable_position();
|
||||||
|
let new_x: usize = (agent_pos.get_x() as i16 + dx) as usize;
|
||||||
|
let new_y: usize = (agent_pos.get_y() as i16 + dy) as usize;
|
||||||
|
self.structure[new_x][new_y] != StructureElement::Wall
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn new(level: usize) -> Level {
|
||||||
|
let mut s = [[StructureElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH];
|
||||||
|
for x in 2..LEVEL_WIDTH - 2 {
|
||||||
|
for y in 2..LEVEL_HEIGHT - 2 {
|
||||||
|
s[x][y] = StructureElement::Floor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Level {
|
||||||
|
level,
|
||||||
|
structure: s,
|
||||||
|
discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||||
|
monsters: Vec::with_capacity(10),
|
||||||
|
artifacts: Vec::with_capacity(10),
|
||||||
|
start: (0, 0),
|
||||||
|
end: (0, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn add_monster(&mut self, mut monster: impl Monster + 'static) -> Result<(), String> {
|
||||||
|
if self.level != monster.get_position().get_level() {
|
||||||
|
return Err("Wrong Level".to_string());
|
||||||
|
}
|
||||||
|
for m in &mut self.monsters {
|
||||||
|
if m.get_position() == monster.get_position() {
|
||||||
|
return Err("Position already used".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.monsters.push(Box::new(monster));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn add_artifact(&mut self, artifact: impl Artifact + 'static) -> Result<(), String> {
|
||||||
|
if self.level != artifact.get_immutable_position().get_level() {
|
||||||
|
return Err("Wrong Level".to_string());
|
||||||
|
}
|
||||||
|
for a in &mut self.artifacts {
|
||||||
|
if a.get_immutable_position() == artifact.get_immutable_position() {
|
||||||
|
return Err("Position already used".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.artifacts.push(Box::new(artifact));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ fn main() -> Result<()> {
|
||||||
stats_area,
|
stats_area,
|
||||||
);
|
);
|
||||||
})?;
|
})?;
|
||||||
if event::poll(std::time::Duration::from_millis(16))? {
|
if event::poll(std::time::Duration::from_millis(100))? {
|
||||||
if let event::Event::Key(key) = event::read()? {
|
if let event::Event::Key(key) = event::read()? {
|
||||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||||
break;
|
break;
|
||||||
|
@ -114,14 +114,14 @@ fn main() -> Result<()> {
|
||||||
game.move_player(new_pos.0, new_pos.1);
|
game.move_player(new_pos.0, new_pos.1);
|
||||||
}
|
}
|
||||||
game.player_collects_artifact();
|
game.player_collects_artifact();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
game.update_level();
|
game.update_level();
|
||||||
if game.get_game_state() != GameState::RUNNING {
|
if game.get_game_state() != GameState::RUNNING {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loop {
|
loop {
|
||||||
let _ = terminal.draw(|frame| {
|
let _ = terminal.draw(|frame| {
|
||||||
let mut area = frame.size();
|
let mut area = frame.size();
|
||||||
|
|
Loading…
Reference in New Issue