Character progression
This commit is contained in:
parent
4f543d7298
commit
b8f68df801
63
src/main.rs
63
src/main.rs
@ -81,6 +81,7 @@ struct Object {
|
||||
fighter: Option<Fighter>,
|
||||
ai: Option<Ai>,
|
||||
item: Option<Item>,
|
||||
always_visible: bool,
|
||||
}
|
||||
|
||||
impl Object {
|
||||
@ -96,6 +97,7 @@ impl Object {
|
||||
fighter: None,
|
||||
ai: None,
|
||||
item: None,
|
||||
always_visible: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +211,7 @@ struct Game {
|
||||
map: Map,
|
||||
messages: Messages,
|
||||
inventory: Vec<Object>,
|
||||
dungeon_level: u32,
|
||||
}
|
||||
|
||||
// A rectangle on the map, used to characterise a room.
|
||||
@ -394,6 +397,17 @@ fn handle_keys(tcod: &mut Tcod, game: &mut Game, objects: &mut Vec<Object>) -> P
|
||||
DidntTakeTurn
|
||||
}
|
||||
|
||||
(Key { code: Text, .. }, "<", true) => {
|
||||
// Go down stairs, if the player is on them
|
||||
let player_on_stairs = objects
|
||||
.iter()
|
||||
.any(|object| object.pos() == objects[PLAYER].pos() && object.name == "stairs");
|
||||
if player_on_stairs {
|
||||
next_level(tcod, game, objects);
|
||||
}
|
||||
DidntTakeTurn
|
||||
}
|
||||
|
||||
_ => DidntTakeTurn,
|
||||
}
|
||||
}
|
||||
@ -402,6 +416,11 @@ fn make_map(objects: &mut Vec<Object>) -> Map {
|
||||
// Fill the map with unblocked tiles
|
||||
let mut map = vec![vec![Tile::wall(); MAP_HEIGHT as usize]; MAP_WIDTH as usize];
|
||||
|
||||
// Player is the first element, remove everything else.
|
||||
// NOTE: works only when the player is the first object!
|
||||
assert_eq!(&objects[PLAYER] as *const _, &objects[0] as *const _);
|
||||
objects.truncate(1);
|
||||
|
||||
let mut rooms = vec![];
|
||||
|
||||
for _ in 0..MAX_ROOMS {
|
||||
@ -437,6 +456,12 @@ fn make_map(objects: &mut Vec<Object>) -> Map {
|
||||
}
|
||||
}
|
||||
|
||||
// Create stairs at the center of the last room
|
||||
let (last_room_x, last_room_y) = rooms[rooms.len() - 1].center();
|
||||
let mut stairs = Object::new(last_room_x, last_room_y, '<', "stairs", WHITE, false);
|
||||
stairs.always_visible = true;
|
||||
objects.push(stairs);
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
@ -515,7 +540,7 @@ fn place_objects(room: Rect, map: &Map, objects: &mut Vec<Object>) {
|
||||
// Only place it if the tile is note blocked
|
||||
if !is_blocked(x, y, map, objects) {
|
||||
let dice = rand::random::<f32>();
|
||||
let item = if dice < 0.7 {
|
||||
let mut item = if dice < 0.7 {
|
||||
// Create a healing potion (70% chance)
|
||||
let mut object = Object::new(x, y, '!', "healing potion", VIOLET, false);
|
||||
object.item = Some(Item::Heal);
|
||||
@ -537,6 +562,7 @@ fn place_objects(room: Rect, map: &Map, objects: &mut Vec<Object>) {
|
||||
object
|
||||
};
|
||||
|
||||
item.always_visible = true;
|
||||
objects.push(item);
|
||||
}
|
||||
}
|
||||
@ -1100,7 +1126,10 @@ fn render_all(tcod: &mut Tcod, game: &mut Game, objects: &[Object], fov_recomput
|
||||
// Only render objects in fov
|
||||
let mut to_draw: Vec<_> = objects
|
||||
.iter()
|
||||
.filter(|o| tcod.fov.is_in_fov(o.x, o.y))
|
||||
.filter(|o| {
|
||||
tcod.fov.is_in_fov(o.x, o.y)
|
||||
|| (o.always_visible && game.map[o.x as usize][o.y as usize].explored)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sort so that non-blocking objects are rendered behind blocking objects
|
||||
@ -1166,6 +1195,15 @@ fn render_all(tcod: &mut Tcod, game: &mut Game, objects: &[Object], fov_recomput
|
||||
DARKER_RED,
|
||||
);
|
||||
|
||||
// Display the current level
|
||||
tcod.panel.print_ex(
|
||||
1,
|
||||
3,
|
||||
BackgroundFlag::None,
|
||||
TextAlignment::Left,
|
||||
format!("Dungeon level: {}", game.dungeon_level),
|
||||
);
|
||||
|
||||
// Display names of objects under the mouse
|
||||
tcod.panel.set_default_foreground(LIGHT_GREY);
|
||||
tcod.panel.print_ex(
|
||||
@ -1235,6 +1273,7 @@ fn new_game(tcod: &mut Tcod) -> (Game, Vec<Object>) {
|
||||
map: make_map(&mut objects),
|
||||
messages: Messages::new(),
|
||||
inventory: vec![],
|
||||
dungeon_level: 1,
|
||||
};
|
||||
|
||||
initialise_fov(tcod, &game.map);
|
||||
@ -1365,6 +1404,26 @@ fn msgbox(text: &str, width: i32, root: &mut Root) {
|
||||
menu(text, options, width, root);
|
||||
}
|
||||
|
||||
// Advance to the next level
|
||||
fn next_level(tcod: &mut Tcod, game: &mut Game, objects: &mut Vec<Object>) {
|
||||
game.messages.add(
|
||||
"You take a moment to rest, and recover your strength.",
|
||||
VIOLET,
|
||||
);
|
||||
|
||||
let heal_hp = objects[PLAYER].fighter.map_or(0, |f| f.max_hp / 2);
|
||||
objects[PLAYER].heal(heal_hp);
|
||||
|
||||
game.messages.add(
|
||||
"After a rare moment of peace, you descend deeper into \
|
||||
the heart of the dungeon...",
|
||||
RED,
|
||||
);
|
||||
game.dungeon_level += 1;
|
||||
game.map = make_map(objects);
|
||||
initialise_fov(tcod, &game.map);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tcod::system::set_fps(FPS);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user