-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmap.rs
129 lines (118 loc) · 3.69 KB
/
map.rs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::constants::*;
use crate::player;
use std::fmt;
#[derive(Copy, Clone)]
pub enum Tile {
Floor,
Wall(u16),
Door { vertical: bool, lock: u16 },
}
pub enum Direction {
North,
East,
South,
West,
}
pub enum Actor {
Player(Direction),
Enemy, // TODO differentiate enemy types
Item, // TODO differentiate item types
DeadGuard,
PushWall,
}
#[derive(Debug, Clone)]
pub struct Map {
plane0: [[u16; MAP_HEIGHT]; MAP_WIDTH],
plane1: [[u16; MAP_HEIGHT]; MAP_WIDTH],
pub name: String,
}
impl Map {
pub fn new(
plane0: [[u16; MAP_HEIGHT]; MAP_WIDTH],
plane1: [[u16; MAP_HEIGHT]; MAP_WIDTH],
name: String,
) -> Self {
Self {
plane0,
plane1,
name,
}
}
pub fn tile_at(&self, x: u8, y: u8) -> Tile {
let tile = self.plane0[x as usize][y as usize];
match tile {
90 | 92 | 94 | 96 | 98 | 100 => Tile::Door {
vertical: true,
lock: (tile - 90) / 2,
},
91 | 93 | 95 | 97 | 99 | 101 => Tile::Door {
vertical: false,
lock: (tile - 91) / 2,
},
106 => Tile::Floor, // this one is actually an ambush tile, review if we need to do something with it
n if n < 107 => Tile::Wall(tile), // keep the tile number to find the proper texture
_ => Tile::Floor,
}
}
pub fn actor_at(&self, x: u8, y: u8) -> Option<Actor> {
match self.plane1[x as usize][y as usize] {
19 => Some(Actor::Player(Direction::North)),
20 => Some(Actor::Player(Direction::East)),
21 => Some(Actor::Player(Direction::South)),
22 => Some(Actor::Player(Direction::West)),
n if (23..=72).contains(&n) => Some(Actor::Item),
98 => Some(Actor::PushWall),
124 => Some(Actor::DeadGuard),
n if n >= 108 => Some(Actor::Enemy),
_ => None,
}
}
pub fn find_player(&self) -> player::Player {
let (player_x, player_y, player_dir) = self.find_player_start();
// TODO not sure why thse /3 and /2 are necessary
let player_x = (MAP_SCALE_W * (player_x as u32) + MAP_SCALE_W / 3) as f64;
let player_y = (MAP_SCALE_H * (player_y as u32) + MAP_SCALE_H / 2) as f64;
let player_angle = match player_dir {
Direction::North => ANGLE_UP,
Direction::East => ANGLE_RIGHT,
Direction::South => ANGLE_DOWN,
Direction::West => ANGLE_LEFT,
};
player::Player {
x: player_x,
y: player_y,
view_angle: player_angle,
move_angle: player_angle,
}
}
pub fn find_player_start(&self) -> (u8, u8, Direction) {
for x in 0..MAP_WIDTH as u8 {
for y in 0..MAP_HEIGHT as u8 {
if let Some(Actor::Player(direction)) = self.actor_at(x, y) {
return (x, y, direction);
}
}
}
panic!("Can't find the player in the map");
}
}
impl fmt::Display for Map {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for x in 0..MAP_WIDTH {
for y in 0..MAP_HEIGHT {
let word = self.plane0[x][y];
if word == 90 {
write!(f, "|").unwrap();
} else if word == 91 {
write!(f, "-").unwrap();
} else if word < 107 {
write!(f, "W").unwrap();
} else {
write!(f, " ").unwrap();
}
}
writeln!(f).unwrap();
}
Ok(())
}
}