diff --git a/84_Super_Star_Trek/rust/src/commands.rs b/84_Super_Star_Trek/rust/src/commands.rs index 20e694e0..52ca5daf 100644 --- a/84_Super_Star_Trek/rust/src/commands.rs +++ b/84_Super_Star_Trek/rust/src/commands.rs @@ -1,9 +1,9 @@ use rand::Rng; -use crate::{model::{Galaxy, Pos, COURSES, EndPosition, self, Enterprise, systems}, view, input}; +use crate::{model::{Galaxy, Pos, COURSES, EndPosition, self, Enterprise, systems}, view, input::{self, prompt_value, param_or_prompt_value}}; pub fn perform_short_range_scan(galaxy: &Galaxy) { - if galaxy.enterprise.damaged.contains_key(model::systems::SHORT_RANGE_SCAN) { + if galaxy.enterprise.damaged.contains_key(systems::SHORT_RANGE_SCAN) { view::scanners_out(); return; } @@ -13,7 +13,7 @@ pub fn perform_short_range_scan(galaxy: &Galaxy) { pub fn get_amount_and_set_shields(galaxy: &mut Galaxy, provided: Vec) { - if galaxy.enterprise.damaged.contains_key(model::systems::SHIELD_CONTROL) { + if galaxy.enterprise.damaged.contains_key(systems::SHIELD_CONTROL) { view::inoperable(&systems::name_for(systems::SHIELD_CONTROL)); return; } @@ -47,7 +47,7 @@ pub fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy, provided: Vec let course = course.unwrap(); let mut max_warp = 8.0; - if galaxy.enterprise.damaged.contains_key(model::systems::WARP_ENGINES) { + if galaxy.enterprise.damaged.contains_key(systems::WARP_ENGINES) { max_warp = 0.2; } @@ -204,7 +204,7 @@ fn move_klingons_and_fire(galaxy: &mut Galaxy) { } pub fn display_damage_control(enterprise: &Enterprise) { - if enterprise.damaged.contains_key(model::systems::DAMAGE_CONTROL) { + if enterprise.damaged.contains_key(systems::DAMAGE_CONTROL) { view::inoperable(&systems::name_for(systems::DAMAGE_CONTROL)); return; } @@ -218,7 +218,7 @@ pub fn display_damage_control(enterprise: &Enterprise) { } pub fn perform_long_range_scan(galaxy: &mut Galaxy) { - if galaxy.enterprise.damaged.contains_key(model::systems::LONG_RANGE_SCAN) { + if galaxy.enterprise.damaged.contains_key(systems::LONG_RANGE_SCAN) { view::inoperable(&systems::name_for(systems::LONG_RANGE_SCAN)); return; } @@ -230,7 +230,7 @@ pub fn perform_long_range_scan(galaxy: &mut Galaxy) { } pub fn access_computer(galaxy: &Galaxy, provided: Vec) { - if galaxy.enterprise.damaged.contains_key(model::systems::COMPUTER) { + if galaxy.enterprise.damaged.contains_key(systems::COMPUTER) { view::inoperable(&systems::name_for(systems::COMPUTER)); return; } @@ -251,4 +251,52 @@ pub fn access_computer(galaxy: &Galaxy, provided: Vec) { 5 => view::galaxy_region_map(), _ => todo!() // todo implement others } +} + +pub fn get_power_and_fire_phasers(galaxy: &mut Galaxy, provided: Vec) { + if galaxy.enterprise.damaged.contains_key(systems::PHASERS) { + view::inoperable(&systems::name_for(systems::PHASERS)); + return; + } + + let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; + if quadrant.klingons.len() == 0 { + view::no_local_enemies(); + return; + } + + let computer_damaged = galaxy.enterprise.damaged.contains_key(systems::COMPUTER); + if computer_damaged { + view::computer_accuracy_issue(); + } + + let available_energy = galaxy.enterprise.total_energy - galaxy.enterprise.shields; + view::phasers_locked(available_energy); + let mut power: f32; + loop { + let setting = param_or_prompt_value(&provided, 0, "Number of units to fire", 0, available_energy); + if setting.is_some() { + power = setting.unwrap() as f32; + break; + } + } + + if power == 0.0 { + return; + } + + galaxy.enterprise.total_energy -= power as u16; + + let mut rng = rand::thread_rng(); + if computer_damaged { + power *= rng.gen::(); + } + + let per_enemy = power / quadrant.klingons.len() as f32; + + // fire on each klingon + + for klingon in &mut quadrant.klingons { + klingon.fire_on(&mut galaxy.enterprise) + } } \ No newline at end of file diff --git a/84_Super_Star_Trek/rust/src/main.rs b/84_Super_Star_Trek/rust/src/main.rs index 4b809b97..1bd1d652 100644 --- a/84_Super_Star_Trek/rust/src/main.rs +++ b/84_Super_Star_Trek/rust/src/main.rs @@ -1,6 +1,6 @@ use std::process::exit; -use model::Galaxy; +use model::{Galaxy, systems}; mod input; mod model; @@ -26,12 +26,13 @@ fn main() { continue; } match command[0].to_uppercase().as_str() { // order is weird because i built it in this order :) - model::systems::SHORT_RANGE_SCAN => commands::perform_short_range_scan(&galaxy), - model::systems::WARP_ENGINES => commands::gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()), - model::systems::SHIELD_CONTROL => commands::get_amount_and_set_shields(&mut galaxy, command[1..].into()), - model::systems::DAMAGE_CONTROL => commands::display_damage_control(&galaxy.enterprise), - model::systems::LONG_RANGE_SCAN => commands::perform_long_range_scan(&mut galaxy), - model::systems::COMPUTER => commands::access_computer(&galaxy, command[1..].into()), + systems::SHORT_RANGE_SCAN => commands::perform_short_range_scan(&galaxy), + systems::WARP_ENGINES => commands::gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()), + systems::SHIELD_CONTROL => commands::get_amount_and_set_shields(&mut galaxy, command[1..].into()), + systems::DAMAGE_CONTROL => commands::display_damage_control(&galaxy.enterprise), + systems::LONG_RANGE_SCAN => commands::perform_long_range_scan(&mut galaxy), + systems::COMPUTER => commands::access_computer(&galaxy, command[1..].into()), + systems::PHASERS => commands::get_power_and_fire_phasers(&mut galaxy, command[1..].into()), _ => view::print_command_help() } diff --git a/84_Super_Star_Trek/rust/src/model.rs b/84_Super_Star_Trek/rust/src/model.rs index 9bb386f1..dbd23522 100644 --- a/84_Super_Star_Trek/rust/src/model.rs +++ b/84_Super_Star_Trek/rust/src/model.rs @@ -25,6 +25,8 @@ pub struct Klingon { impl Klingon { pub fn fire_on(&mut self, enterprise: &mut Enterprise) { + // todo check if enterprise is protected + let mut rng = rand::thread_rng(); let attack_strength = rng.gen::(); let dist_to_enterprise = self.sector.abs_diff(enterprise.sector) as f32; @@ -112,9 +114,10 @@ pub mod systems { pub const DAMAGE_CONTROL: &str = "DAM"; pub const LONG_RANGE_SCAN: &str = "LRS"; pub const COMPUTER: &str = "COM"; + pub const PHASERS: &str = "PHA"; - pub const KEYS: [&str; 6] = [ - SHORT_RANGE_SCAN, WARP_ENGINES, SHIELD_CONTROL, DAMAGE_CONTROL, LONG_RANGE_SCAN, COMPUTER + pub const KEYS: [&str; 7] = [ + SHORT_RANGE_SCAN, WARP_ENGINES, SHIELD_CONTROL, DAMAGE_CONTROL, LONG_RANGE_SCAN, COMPUTER, PHASERS ]; pub fn name_for(key: &str) -> String { @@ -125,6 +128,7 @@ pub mod systems { DAMAGE_CONTROL => "Damage Control".into(), LONG_RANGE_SCAN => "Long Range Scanners".into(), COMPUTER => "Library-Computer".into(), + PHASERS => "Phaser Control".into(), _ => "Unknown".into() } } diff --git a/84_Super_Star_Trek/rust/src/view.rs b/84_Super_Star_Trek/rust/src/view.rs index fec5434c..1c904958 100644 --- a/84_Super_Star_Trek/rust/src/view.rs +++ b/84_Super_Star_Trek/rust/src/view.rs @@ -425,3 +425,17 @@ pub(crate) fn galaxy_scanned_map(galaxy: &Galaxy) { "\n ----- ----- ----- ----- ----- ----- ----- -----") } } + +pub fn no_local_enemies() { + println!( +"Science Officer Spock reports, 'Sensors show no enemy ships + in this quadrant'") +} + +pub fn computer_accuracy_issue() { + println!("Computer failure hampers accuracy") +} + +pub fn phasers_locked(available_energy: u16) { + println!("Phasers locked on target; Energy available = {available_energy} units") +} diff --git a/84_Super_Star_Trek/rust/tasks.md b/84_Super_Star_Trek/rust/tasks.md index 46ba7d6a..8f5b3bab 100644 --- a/84_Super_Star_Trek/rust/tasks.md +++ b/84_Super_Star_Trek/rust/tasks.md @@ -22,12 +22,14 @@ Started after movement and display of stats was finished (no energy management o - also, movement courses could be floats, according to the instructions, allowing for more precise movement and aiming - [x] better command reading - support entering multiple values on a line (e.g. nav 3 0.1) - [ ] starbases - - [ ] repair + - [ ] proximity detection for docking + - [ ] repair on damage control + - [ ] protection from shots - [ ] weapons - [ ] phasers - [ ] torpedoes - [ ] computer - - [ ] 0 - output of all short and long range scans (requires tracking if a system has been scanned) + - [x] 0 - output of all short and long range scans (requires tracking if a system has been scanned) - [ ] 1 - klingons, starbases, stardate and damage control - [ ] 2 - photon torpedo data: direction and distance to all local klingons - [ ] 3 - starbase distance and dir locally