1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
extern crate rand;
use character::rand::Rng;
extern crate pathfinding;
use self::pathfinding::astar;
use constants::Orders;
use location::Location;
#[derive(Clone)]
pub struct Character {
pub symbol : char,
pub color : u8,
pub order : u8,
pub location : Location,
pub needs_path : bool,
desired_location : Option<Location>,
path : Option<Vec<Location>>,
}
impl Character {
pub fn new(symbol : char, color : u8, location : Location) -> Character {
Character {
symbol : symbol,
color : color,
order : Orders::Wander as u8,
location : location,
needs_path : false,
desired_location : None,
path : None,
}
}
pub fn action(&mut self, free_spaces : Vec<(Location,usize)>) {
if self.order == Orders::Wander as u8 {
self.needs_path == false;
self.wander(free_spaces);
}
else if self.order == Orders::Move as u8 {
self.move_along_path(free_spaces);
}
}
pub fn calculate_path(&mut self, impassable : Vec<(Location, usize)>) {
match self.desired_location {
None => self.order = Orders::Wander as u8,
Some(target) => {
let location = self.location;
let result = astar(&location,
|l| l.neighbours(impassable.clone()),
|l| l.distance(&target),
|l| *l == target);
let mut result = result.expect("No way to get to target.").0;
result.reverse();
result.pop();
self.path = Some(result);
}
}
}
pub fn give_destination(&mut self, destination : Location) {
self.desired_location = Some(destination);
self.order = Orders::Move as u8;
}
fn wander(&mut self, free_spaces : Vec<(Location, usize)>) {
let direction = rand::thread_rng().gen_range(0, free_spaces.len());
self.location = free_spaces[direction].0;
}
fn move_along_path(&mut self, free_spaces : Vec<(Location, usize)>) {
let mut moved = false;
match self.path {
None => self.needs_path = true,
Some(ref mut calculated_path) => {
self.needs_path = false;
if calculated_path.len() > 0 {
let next_location = calculated_path.pop().unwrap();
for free_space in free_spaces {
if next_location == free_space.0 {
self.location = next_location;
moved = true;
}
}
}
else {
self.desired_location = None;
self.order = Orders::Wander as u8;
}
}
}
if !moved {
self.path = None;
}
}
}
|