use crate::{
actions::{Action, Direction},
floor::Tile,
};
use std::cell::RefCell;
pub struct Warrior {
level: usize,
ahead: Vec<Tile>,
behind: Vec<Tile>,
health: i32,
facing: Direction,
action: RefCell<Option<Action>>,
warnings: RefCell<Vec<String>>,
}
impl Warrior {
pub fn new(
level: usize,
ahead: Vec<Tile>,
behind: Vec<Tile>,
health: i32,
facing: Direction,
) -> Warrior {
Warrior {
level,
ahead,
behind,
health,
facing,
action: RefCell::new(None),
warnings: RefCell::new(Vec::new()),
}
}
pub fn walk(&self) {
self.perform_walk(Direction::Forward);
}
pub fn walk_toward(&self, direction: Direction) {
if self.level < 6 {
panic!("You have not yet learned `walk_toward`! Perhaps you meant `walk`?")
}
self.perform_walk(direction);
}
fn perform_walk(&self, direction: Direction) {
self.perform(Action::Walk(direction));
}
pub fn check(&self) -> Tile {
if self.level < 2 {
panic!("You have not yet learned `check`!");
}
self.perform_check(Direction::Forward)
}
pub fn check_toward(&self, direction: Direction) -> Tile {
if self.level < 6 {
panic!("You have not yet learned `check_toward`! Perhaps you meant `check`?")
}
self.perform_check(direction)
}
fn perform_check(&self, direction: Direction) -> Tile {
match direction {
Direction::Forward => match self.ahead.first() {
Some(tile) => *tile,
None => Tile::Wall,
},
Direction::Backward => match self.behind.first() {
Some(tile) => *tile,
None => Tile::Wall,
},
}
}
pub fn look(&self) -> &Vec<Tile> {
if self.level < 8 {
panic!("You have not yet learned `look`!")
}
self.look_toward(Direction::Forward)
}
pub fn look_toward(&self, direction: Direction) -> &Vec<Tile> {
if self.level < 8 {
panic!("You have not yet learned `look_toward`!")
}
match direction {
Direction::Forward => &self.ahead,
Direction::Backward => &self.behind,
}
}
pub fn attack(&self) {
if self.level < 2 {
panic!("You have not yet learned `attack`!");
}
self.perform_attack(Direction::Forward);
}
pub fn attack_toward(&self, direction: Direction) {
if self.level < 6 {
panic!("You have not yet learned `attack_toward`! Perhaps you meant `attack`?")
}
self.perform_attack(direction);
}
fn perform_attack(&self, direction: Direction) {
self.perform(Action::Attack(direction));
}
pub fn health(&self) -> i32 {
if self.level < 3 {
panic!("You have not yet learned `health`!");
}
self.health
}
pub fn rest(&self) {
if self.level < 3 {
panic!("You have not yet learned `rest`!");
}
self.perform(Action::Rest);
}
pub fn rescue(&self) {
if self.level < 5 {
panic!("You have not yet learned `rescue`!");
}
self.perform_rescue(Direction::Forward);
}
pub fn rescue_toward(&self, direction: Direction) {
if self.level < 6 {
panic!("You have not yet learned `rescue_toward`! Perhaps you meant `rescue`?")
}
self.perform_rescue(direction);
}
fn perform_rescue(&self, direction: Direction) {
self.perform(Action::Rescue(direction));
}
pub fn pivot(&self) {
if self.level < 7 {
panic!("You have not yet learned `pivot`!")
}
let direction = match self.facing {
Direction::Forward => Direction::Backward,
Direction::Backward => Direction::Forward,
};
self.perform(Action::Pivot(direction));
}
pub fn shoot(&self) {
if self.level < 8 {
panic!("You have not yet learned `shoot`!")
}
self.shoot_toward(Direction::Forward);
}
pub fn shoot_toward(&self, direction: Direction) {
if self.level < 8 {
panic!("You have not yet learned `shoot_toward`!")
}
self.perform(Action::Shoot(direction));
}
pub fn action(&self) -> Option<Action> {
*self.action.borrow()
}
fn perform(&self, action: Action) {
if let Some(prev) = *self.action.borrow() {
let warnings = &mut *self.warnings.borrow_mut();
warnings.push(format!("WARNING: Already performed action: {:?}", prev));
warnings.push(format!(
"WARNING: Unable to perform additional action: {:?}",
action
));
return;
}
*self.action.borrow_mut() = Some(action);
}
pub fn warnings(&self) -> Vec<String> {
let warnings = &*self.warnings.borrow();
warnings.clone()
}
}