fight monsters, collect artifacts
This commit is contained in:
		
							parent
							
								
									643f3b76f9
								
							
						
					
					
						commit
						8b21e179c2
					
				| @ -9,6 +9,7 @@ pub trait Artifact { | ||||
|     fn get_immutable_position(&self) -> &Position; | ||||
|     /// call to apply the effects of the artifact to the player
 | ||||
|     fn collect(&mut self, player: &mut Player); | ||||
|     fn was_collected(&self) -> bool; | ||||
| } | ||||
| 
 | ||||
| pub struct Chest { | ||||
| @ -36,6 +37,10 @@ impl Artifact for Chest { | ||||
|         player.retrieve_gold(self.gold); | ||||
|         self.gold = 0; | ||||
|     } | ||||
| 
 | ||||
|     fn was_collected(&self) -> bool { | ||||
|         self.gold == 0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Potion { | ||||
| @ -62,4 +67,8 @@ impl Artifact for Potion { | ||||
|         player.change_life(self.health.try_into().unwrap()); | ||||
|         self.health = 0; | ||||
|     } | ||||
| 
 | ||||
|     fn was_collected(&self) -> bool { | ||||
|         self.health == 0 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										99
									
								
								src/game.rs
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								src/game.rs
									
									
									
									
									
								
							| @ -1,3 +1,4 @@ | ||||
| use std::ops::Deref; | ||||
| use crate::artifacts::Artifact; | ||||
| use crate::level::{Level, StructureElement}; | ||||
| use crate::level_generator::LevelGenerator; | ||||
| @ -16,7 +17,7 @@ impl Game { | ||||
|     pub fn new(p: Player) -> Game { | ||||
|         let mut v: Vec<Level> = Vec::with_capacity(LEVELS); | ||||
|         for d in 0..LEVELS { | ||||
|             v.push(LevelGenerator::generate(d, d==0, d==LEVELS-1).render()); | ||||
|             v.push(LevelGenerator::generate(d, d == 0, d == LEVELS - 1).render()); | ||||
|         } | ||||
|         let mut g = Game { | ||||
|             player: p, | ||||
| @ -72,53 +73,77 @@ impl Game { | ||||
|         let level = &mut self.levels[player_level]; | ||||
|         level.get_element(new_x, new_y) | ||||
|     } | ||||
|     pub fn move_player(&mut self, mut dx: i16, mut dy: i16) { | ||||
| 
 | ||||
|     pub fn move_player(&mut self, mut dx: i16, mut dy: i16) -> (i16, i16) { | ||||
|         // verify the player can do the move
 | ||||
|         if !self.can_move(dx, dy) { | ||||
|             return; | ||||
|             return (-dx, -dy); | ||||
|         } | ||||
| 
 | ||||
|         let player_pos = &self.player.get_position(); | ||||
|         // // let new_x: i16 = player_pos.get_x() as i16 + dx;
 | ||||
|         // // let new_y: i16 = player_pos.get_y() as i16 + dy;
 | ||||
|         let mut player_level = player_pos.get_level(); | ||||
|         // // let level = &mut self.levels[player_level];
 | ||||
|         let element = self.next_element(dx, dy); | ||||
|         //
 | ||||
|         // // use stairs if walked onto one
 | ||||
|         match element { | ||||
|              (Some(e), None, None) => { | ||||
|                  match e { | ||||
|                      StructureElement::StairDown => { | ||||
|                          (dx, dy) = (0, 0); | ||||
|                          let (next_level, x, y) = self.next_start(); | ||||
|                          player_level = next_level; | ||||
|                          self.get_mutable_player().get_position().set(next_level, x, y); | ||||
|                      } | ||||
|                      StructureElement::StairUp => { | ||||
|                          (dx, dy) = (0, 0); | ||||
|                          let (next_level, x, y) = self.prev_end(); | ||||
|                          player_level = next_level; | ||||
|                          self.get_mutable_player().get_position().set(next_level, x, y); | ||||
|                      } | ||||
|                      _ => {} | ||||
|                  } | ||||
|              } | ||||
|              (_, _, _) => {} | ||||
|         let (structure, _, _) = self.next_element(dx, dy); | ||||
| 
 | ||||
|         // use stairs if walked onto one
 | ||||
|         match structure { | ||||
|             Some(e) => { | ||||
|                 match e { | ||||
|                     StructureElement::StairDown => { | ||||
|                         (dx, dy) = (0, 0); | ||||
|                         let (next_level, x, y) = self.next_start(); | ||||
|                         player_level = next_level; | ||||
|                         self.get_mutable_player().get_position().set(next_level, x, y); | ||||
|                     } | ||||
|                     StructureElement::StairUp => { | ||||
|                         (dx, dy) = (0, 0); | ||||
|                         let (next_level, x, y) = self.prev_end(); | ||||
|                         player_level = next_level; | ||||
|                         self.get_mutable_player().get_position().set(next_level, x, y); | ||||
|                     } | ||||
|                     _ => {} | ||||
|                 } | ||||
|             } | ||||
|             _ => {} | ||||
|         } | ||||
|         //
 | ||||
|         // // interact with monsters / artifacts
 | ||||
|         // match element {
 | ||||
|         //     (_, _, Some(a)) => {
 | ||||
|         //         // a.collect(&mut self.player);
 | ||||
|         //         // level.remove_artifact(&Position::new(player_level, new_x as usize, new_y as usize)).expect("Could not collect artifact");
 | ||||
|         //     }
 | ||||
|         //     (_, _, _) => {}
 | ||||
|         // }
 | ||||
| 
 | ||||
|         // update position and discover area on new position
 | ||||
|         let (new_x, new_y) = self.get_mutable_player().get_position().change(dx, dy); | ||||
|         self.get_mutable_level(player_level).discover(&Position::new(player_level, new_x, new_y)); | ||||
|         (-dx, -dy) | ||||
|     } | ||||
|     pub fn player_fights_monster(&mut self) -> bool { | ||||
|         let player_pos = &self.player.get_immutable_position(); | ||||
|         let player_level = player_pos.get_level(); | ||||
|         let level = &mut self.levels[player_level]; | ||||
|         let (_, m, _) = level.get_element(player_pos.get_x() as i16, player_pos.get_y() as i16); | ||||
|         match m { | ||||
|             None => {} | ||||
|             Some(m) => { | ||||
|                 // TODO fight the monster
 | ||||
|                 self.player.change_life(-1); | ||||
|                 m.decrease_life(1); | ||||
|                 return m.is_dead(); | ||||
|             } | ||||
|         }; | ||||
|         true | ||||
|     } | ||||
|     pub fn player_collects_artifact(&mut self) { | ||||
|         let player_pos = &self.player.get_immutable_position(); | ||||
|         let player_level = player_pos.get_level(); | ||||
|         let level = &mut self.levels[player_level]; | ||||
|         let (_, _, a) = level.get_element(player_pos.get_x() as i16, player_pos.get_y() as i16); | ||||
|         match a { | ||||
|             None => {} | ||||
|             Some(a) => { | ||||
|                 a.collect(&mut self.player); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     pub fn update_level(&mut self) { | ||||
|         let player_pos = &self.player.get_immutable_position(); | ||||
|         let player_level = player_pos.get_level(); | ||||
|         let level = &mut self.levels[player_level]; | ||||
|         level.update(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										19
									
								
								src/level.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/level.rs
									
									
									
									
									
								
							| @ -45,8 +45,8 @@ impl Level { | ||||
|             discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||
|             monsters: Vec::with_capacity(10), | ||||
|             artifacts: Vec::with_capacity(10), | ||||
|             start: (0,0), | ||||
|             end: (0,0), | ||||
|             start: (0, 0), | ||||
|             end: (0, 0), | ||||
|         } | ||||
|     } | ||||
|     pub fn get_element(&mut self, x: i16, y: i16) -> (Option<StructureElement>, Option<&mut Monster>, Option<&mut Box<(dyn Artifact + 'static)>>) { | ||||
| @ -172,6 +172,21 @@ impl Level { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn update(&mut self) { | ||||
|         for (index, a) in &mut self.artifacts.iter().enumerate() { | ||||
|             if a.was_collected() { | ||||
|                 self.artifacts.remove(index); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         for (index, m) in &mut self.monsters.iter().enumerate() { | ||||
|             if m.is_dead() { | ||||
|                 self.monsters.remove(index); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
|  | ||||
| @ -274,7 +274,7 @@ impl LevelGenerator { | ||||
|                     let t_x = left + room.offset_x + rng.gen_range(0..room.width); | ||||
|                     let t_y = top + room.offset_y + rng.gen_range(0..room.height); | ||||
|                     // TODO randomize enemies here
 | ||||
|                     enemies.push(Monster::new_with_position(10, Position::new(self.level, t_x, t_y))); | ||||
|                     enemies.push(Monster::new_with_position(2, Position::new(self.level, t_x, t_y))); | ||||
|                 } | ||||
| 
 | ||||
|                 if room.kind == RoomType::End || room.kind == RoomType::StairDown { | ||||
|  | ||||
							
								
								
									
										28
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ mod level_widget; | ||||
| mod level_generator; | ||||
| mod artifacts; | ||||
| mod monster; | ||||
| 
 | ||||
| //
 | ||||
| fn main() -> Result<()> { | ||||
|     let mut game = Game::new(Player::new(realname().as_str(), 10)); | ||||
| @ -56,7 +57,7 @@ fn main() -> Result<()> { | ||||
|                 width: level::LEVEL_WIDTH as u16, | ||||
|                 height: level::LEVEL_HEIGHT as u16, | ||||
|             }; | ||||
|             frame.render_stateful_widget(LevelWidget{}, map_area, &mut game); | ||||
|             frame.render_stateful_widget(LevelWidget {}, map_area, &mut game); | ||||
| 
 | ||||
|             let stats_area = Rect { | ||||
|                 x: area.x + 50, | ||||
| @ -81,17 +82,20 @@ fn main() -> Result<()> { | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { | ||||
|                     break; | ||||
|                 } | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Left { | ||||
|                     game.move_player(-1, 0); | ||||
|                 } | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Right { | ||||
|                     game.move_player(1, 0); | ||||
|                 } | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Up { | ||||
|                     game.move_player(0, -1); | ||||
|                 } | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Down { | ||||
|                     game.move_player(0, 1); | ||||
|                 if key.kind == KeyEventKind::Press { | ||||
|                     let new_pos = match key.code { | ||||
|                         KeyCode::Left => { game.move_player(-1, 0) } | ||||
|                         KeyCode::Right => { game.move_player(1, 0) } | ||||
|                         KeyCode::Up => { game.move_player(0, -1) } | ||||
|                         KeyCode::Down => { game.move_player(0, 1) } | ||||
|                         _ => { (0, 0) } | ||||
|                     }; | ||||
|                     if !game.player_fights_monster() { | ||||
|                         // player attacked monster but did not kill it
 | ||||
|                         game.move_player(new_pos.0, new_pos.1); | ||||
|                     } | ||||
|                     game.player_collects_artifact(); | ||||
|                     game.update_level(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user