use ratatui::style::Color; use crate::player::Player; use crate::position::Position; pub trait Artifact { //! An artifact that can be collected by the player fn get_representation(&self) -> (&str, Color); /// get the position of the artifact in the level fn get_immutable_position(&self) -> &Position; /// call to apply the effects of the artifact to the player fn collect(&mut self, player: &mut Player, messages: &mut Vec); /// returns if the artifact was collected and can be removed from the level fn was_collected(&self) -> bool; } pub struct Chest { /// a chest that contains some gold position: Position, gold: usize, } impl Chest { pub fn new(position: Position) -> Self { let level = position.get_level(); Self { position, // TODO maybe randomize this? gold: (level + 1) * 10, } } } impl Artifact for Chest { fn get_representation(&self) -> (&str, Color) { ("C", Color::Blue) } fn get_immutable_position(&self) -> &Position { &self.position } fn collect(&mut self, player: &mut Player, messages: &mut Vec) { player.retrieve_gold(self.gold); messages.insert(0, format!("opened chest and collected {} gold.", self.gold).to_string()); self.gold = 0; } fn was_collected(&self) -> bool { self.gold == 0 } } pub struct Potion { /// a potion that restores some health position: Position, health: usize, } impl Potion { pub fn new(position: Position) -> Self { Self { position, health: 5, } } } impl Artifact for Potion { fn get_representation(&self) -> (&str, Color) { ("P", Color::Green) } fn get_immutable_position(&self) -> &Position { &self.position } fn collect(&mut self, player: &mut Player, messages: &mut Vec) { // only consume potion of the player can gain at least one health point if !player.is_healthy() { let old = player.get_life(); player.change_life(self.health.try_into().unwrap()); let new = player.get_life(); messages.insert(0, format!("picked up potion and gained {} hp.", new - old).to_string()); self.health = 0; } else { messages.insert(0, "not using the potion because you're healthy.".to_string()); } } fn was_collected(&self) -> bool { self.health == 0 } }