implemented taking damage and dying

This commit is contained in:
Christopher
2023-03-01 15:36:42 +13:00
parent 4b326547e4
commit b56819aadf
4 changed files with 79 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
use crate::model::{Galaxy, Pos, SectorStatus, COURSES}; use crate::model::{Galaxy, Pos, SectorStatus, COURSES, Quadrant};
pub fn short_range_scan(model: &Galaxy) { pub fn short_range_scan(model: &Galaxy) {
let quadrant = &model.quadrants[model.enterprise.quadrant.as_index()]; let quadrant = &model.quadrants[model.enterprise.quadrant.as_index()];

View File

@@ -2,6 +2,8 @@ use std::{io::{stdin, stdout, Write}, process::exit, str::FromStr};
use model::Galaxy; use model::Galaxy;
use crate::model::Condition;
mod model; mod model;
mod commands; mod commands;
@@ -10,7 +12,7 @@ fn main() {
.expect("Error setting Ctrl-C handler"); .expect("Error setting Ctrl-C handler");
let mut galaxy = Galaxy::generate_new(); let mut galaxy = Galaxy::generate_new();
// init options, starting state and notes // todo: init options, starting state and notes
commands::short_range_scan(&galaxy); commands::short_range_scan(&galaxy);
loop { loop {
@@ -19,6 +21,14 @@ fn main() {
"NAV" => gather_dir_and_speed_then_move(&mut galaxy), "NAV" => gather_dir_and_speed_then_move(&mut galaxy),
_ => print_command_help() _ => print_command_help()
} }
if galaxy.enterprise.condition == Condition::Destroyed { // todo: also check if stranded
println!("Is is stardate {}.
There were {} Klingon battle cruisers left at
the end of your mission.
", galaxy.stardate, galaxy.remaining_klingons());
break;
}
} }
} }
@@ -37,6 +47,21 @@ fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy) {
return; return;
} }
let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()];
for k in 0..quadrant.klingons.len() {
let new_sector = quadrant.find_empty_sector();
quadrant.klingons[k].sector = new_sector;
}
// todo: check if enterprise is protected by a starbase
for k in 0..quadrant.klingons.len() {
quadrant.klingons[k].fire_on(&mut galaxy.enterprise);
}
if galaxy.enterprise.condition == Condition::Destroyed {
return;
}
commands::move_enterprise(course.unwrap(), speed.unwrap(), galaxy); commands::move_enterprise(course.unwrap(), speed.unwrap(), galaxy);
} }

View File

@@ -15,7 +15,21 @@ pub struct Quadrant {
} }
pub struct Klingon { pub struct Klingon {
pub sector: Pos pub sector: Pos,
energy: f32
}
impl Klingon {
pub fn fire_on(&mut self, enterprise: &mut Enterprise) {
let mut rng = rand::thread_rng();
let attack_strength = rng.gen::<f32>();
let dist_to_enterprise = self.sector.abs_diff(enterprise.sector) as f32;
let hit_strength = self.energy * (2.0 + attack_strength) / dist_to_enterprise;
self.energy /= 3.0 + attack_strength;
enterprise.take_hit(self.sector, hit_strength as u16);
}
} }
pub struct Enterprise { pub struct Enterprise {
@@ -26,10 +40,30 @@ pub struct Enterprise {
pub total_energy: u16, pub total_energy: u16,
pub shields: u16, pub shields: u16,
} }
impl Enterprise {
fn take_hit(&mut self, sector: Pos, hit_strength: u16) {
if self.condition == Condition::Destroyed {
return;
}
#[derive(Debug)] println!("{hit_strength} unit hit on Enterprise from sector {sector}");
// absorb into shields
if self.shields <= 0 {
println!("The Enterprise has been destroyed. The Federation will be conquered.");
self.condition = Condition::Destroyed;
}
// report shields
// take damage if strength is greater than 20
}
}
#[derive(PartialEq, Debug)]
pub enum Condition { pub enum Condition {
Green, Yellow, Red Green, Yellow, Red,
Destroyed,
} }
#[derive(PartialEq, Clone, Copy, Debug)] #[derive(PartialEq, Clone, Copy, Debug)]
@@ -39,6 +73,10 @@ impl Pos {
pub fn as_index(&self) -> usize { pub fn as_index(&self) -> usize {
(self.0 * 8 + self.1).into() (self.0 * 8 + self.1).into()
} }
fn abs_diff(&self, other: Pos) -> u8 {
self.0.abs_diff(other.0) + self.1.abs_diff(other.1)
}
} }
impl Mul<u8> for Pos { impl Mul<u8> for Pos {
@@ -128,7 +166,7 @@ impl Galaxy {
_ => 0 _ => 0
}; };
for _ in 0..klingon_count { for _ in 0..klingon_count {
quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector() }); quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector(), energy: rng.gen_range(100..=300) as f32 });
} }
result.push(quadrant); result.push(quadrant);
@@ -162,7 +200,7 @@ impl Quadrant {
klingons.into_iter().find(|k| &k.sector == sector).is_some() klingons.into_iter().find(|k| &k.sector == sector).is_some()
} }
fn find_empty_sector(&self) -> Pos { pub fn find_empty_sector(&self) -> Pos {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
loop { loop {
let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8)); let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8));

View File

@@ -2,6 +2,11 @@
Started after movement and display of stats was finished (no energy management or collision detection or anything). Started after movement and display of stats was finished (no energy management or collision detection or anything).
- [ ] stop before hitting an object - [x] klingon movement
- [x] klingon firing, game over etc
- [ ] remove energy on move - [ ] remove energy on move
- [ ] klingon movement - [ ] shields
- [ ] stranded...
- [ ] stop before hitting an object
- when moving across a sector, the enterprise should stop before it runs into something
- the current move is a jump, which makes this problematic. would need to rewrite it