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>,
 | 
					  fighter: Option<Fighter>,
 | 
				
			||||||
  ai: Option<Ai>,
 | 
					  ai: Option<Ai>,
 | 
				
			||||||
  item: Option<Item>,
 | 
					  item: Option<Item>,
 | 
				
			||||||
 | 
					  always_visible: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Object {
 | 
					impl Object {
 | 
				
			||||||
@ -96,6 +97,7 @@ impl Object {
 | 
				
			|||||||
      fighter: None,
 | 
					      fighter: None,
 | 
				
			||||||
      ai: None,
 | 
					      ai: None,
 | 
				
			||||||
      item: None,
 | 
					      item: None,
 | 
				
			||||||
 | 
					      always_visible: false,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -209,6 +211,7 @@ struct Game {
 | 
				
			|||||||
  map: Map,
 | 
					  map: Map,
 | 
				
			||||||
  messages: Messages,
 | 
					  messages: Messages,
 | 
				
			||||||
  inventory: Vec<Object>,
 | 
					  inventory: Vec<Object>,
 | 
				
			||||||
 | 
					  dungeon_level: u32,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A rectangle on the map, used to characterise a room.
 | 
					// 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
 | 
					      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,
 | 
					    _ => DidntTakeTurn,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -402,6 +416,11 @@ fn make_map(objects: &mut Vec<Object>) -> Map {
 | 
				
			|||||||
  // Fill the map with unblocked tiles
 | 
					  // Fill the map with unblocked tiles
 | 
				
			||||||
  let mut map = vec![vec![Tile::wall(); MAP_HEIGHT as usize]; MAP_WIDTH as usize];
 | 
					  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![];
 | 
					  let mut rooms = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for _ in 0..MAX_ROOMS {
 | 
					  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
 | 
					  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
 | 
					    // Only place it if the tile is note blocked
 | 
				
			||||||
    if !is_blocked(x, y, map, objects) {
 | 
					    if !is_blocked(x, y, map, objects) {
 | 
				
			||||||
      let dice = rand::random::<f32>();
 | 
					      let dice = rand::random::<f32>();
 | 
				
			||||||
      let item = if dice < 0.7 {
 | 
					      let mut item = if dice < 0.7 {
 | 
				
			||||||
        // Create a healing potion (70% chance)
 | 
					        // Create a healing potion (70% chance)
 | 
				
			||||||
        let mut object = Object::new(x, y, '!', "healing potion", VIOLET, false);
 | 
					        let mut object = Object::new(x, y, '!', "healing potion", VIOLET, false);
 | 
				
			||||||
        object.item = Some(Item::Heal);
 | 
					        object.item = Some(Item::Heal);
 | 
				
			||||||
@ -537,6 +562,7 @@ fn place_objects(room: Rect, map: &Map, objects: &mut Vec<Object>) {
 | 
				
			|||||||
        object
 | 
					        object
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      item.always_visible = true;
 | 
				
			||||||
      objects.push(item);
 | 
					      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
 | 
					  // Only render objects in fov
 | 
				
			||||||
  let mut to_draw: Vec<_> = objects
 | 
					  let mut to_draw: Vec<_> = objects
 | 
				
			||||||
    .iter()
 | 
					    .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();
 | 
					    .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Sort so that non-blocking objects are rendered behind blocking objects
 | 
					  // 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,
 | 
					    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
 | 
					  // Display names of objects under the mouse
 | 
				
			||||||
  tcod.panel.set_default_foreground(LIGHT_GREY);
 | 
					  tcod.panel.set_default_foreground(LIGHT_GREY);
 | 
				
			||||||
  tcod.panel.print_ex(
 | 
					  tcod.panel.print_ex(
 | 
				
			||||||
@ -1235,6 +1273,7 @@ fn new_game(tcod: &mut Tcod) -> (Game, Vec<Object>) {
 | 
				
			|||||||
    map: make_map(&mut objects),
 | 
					    map: make_map(&mut objects),
 | 
				
			||||||
    messages: Messages::new(),
 | 
					    messages: Messages::new(),
 | 
				
			||||||
    inventory: vec![],
 | 
					    inventory: vec![],
 | 
				
			||||||
 | 
					    dungeon_level: 1,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initialise_fov(tcod, &game.map);
 | 
					  initialise_fov(tcod, &game.map);
 | 
				
			||||||
@ -1365,6 +1404,26 @@ fn msgbox(text: &str, width: i32, root: &mut Root) {
 | 
				
			|||||||
  menu(text, options, width, 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() {
 | 
					fn main() {
 | 
				
			||||||
  tcod::system::set_fps(FPS);
 | 
					  tcod::system::set_fps(FPS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user