214 lines
6.3 KiB
Rust
214 lines
6.3 KiB
Rust
use crate::equipment::EquipmentBlock;
|
|
use crate::statistics::StatBlock;
|
|
use crate::status::Status;
|
|
use rand::seq::SliceRandom;
|
|
use rand::Rng;
|
|
|
|
const MASC_NAMES: &'static [&'static str] = &["Antonio", "Brandon", "Charles", "Denzel", "Edgar"];
|
|
const FEMME_NAMES: &'static [&'static str] = &["Alice", "Bethany", "Cynthia", "Dawn", "Elizabeth"];
|
|
const NEUTR_NAMES: &'static [&'static str] = &["Aspen", "Blake", "Charlie", "Dekota", "Emery"];
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum Gender {
|
|
Man,
|
|
Woman,
|
|
Nonbinary,
|
|
DemiGirl,
|
|
DemiBoy,
|
|
NoGender,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Unit {
|
|
name: String,
|
|
level: u8,
|
|
exp: u32,
|
|
status: Option<(Option<Status>,Option<Status>)>,
|
|
gender: Gender,
|
|
base_stats: StatBlock,
|
|
hp: u16,
|
|
jel: u8,
|
|
jel_total: u8,
|
|
is_monster: bool,
|
|
equipment: Option<EquipmentBlock>,
|
|
}
|
|
|
|
impl Unit {
|
|
pub fn new() -> Unit {
|
|
let mut rng = rand::thread_rng();
|
|
let j = rng.gen_range(10..26);
|
|
Unit {
|
|
name: String::from("Basic Unit"),
|
|
level: 1,
|
|
exp: 0,
|
|
status: None,
|
|
gender: Gender::NoGender,
|
|
base_stats: StatBlock::new(),
|
|
hp: 18,
|
|
jel: j,
|
|
jel_total: j,
|
|
is_monster: true,
|
|
equipment: None,
|
|
}
|
|
}
|
|
pub fn name(self) -> String {
|
|
self.name
|
|
}
|
|
pub fn level(self) -> u8 {
|
|
self.level
|
|
}
|
|
pub fn gender(self) -> Gender {
|
|
self.gender
|
|
}
|
|
pub fn stats(self) -> StatBlock {
|
|
self.base_stats + self.stat_bonus()
|
|
}
|
|
pub fn base_stats(self) -> StatBlock {
|
|
self.base_stats
|
|
}
|
|
pub fn stat_bonus(self) -> StatBlock {
|
|
match self.equipment() {
|
|
Some(e) => e.bonuses(),
|
|
None => StatBlock::new_zero(),
|
|
}
|
|
}
|
|
pub fn hp(self) -> u16 {
|
|
self.hp
|
|
}
|
|
pub fn hp_max(self) -> u16 {
|
|
u16::from(
|
|
18u16
|
|
+ (u16::from(self.level)
|
|
* u16::from(0u8.wrapping_add_signed(self.stats().vitality()))),
|
|
)
|
|
}
|
|
pub fn jel(self) -> u8 {
|
|
self.jel
|
|
}
|
|
pub fn jel_total(self) -> u8 {
|
|
self.jel_total
|
|
}
|
|
pub fn is_monster(self) -> bool {
|
|
self.is_monster
|
|
}
|
|
pub fn equipment(self) -> Option<EquipmentBlock> {
|
|
if self.is_monster {
|
|
return None;
|
|
}
|
|
self.equipment
|
|
}
|
|
|
|
pub fn generate_gender() -> Gender {
|
|
let gender_variants = [
|
|
Gender::Man,
|
|
Gender::Woman,
|
|
Gender::Nonbinary,
|
|
Gender::DemiGirl,
|
|
Gender::DemiBoy,
|
|
];
|
|
match gender_variants.choose(&mut rand::thread_rng()) {
|
|
Some(g) => g.to_owned(),
|
|
None => Gender::NoGender,
|
|
}
|
|
}
|
|
pub fn generate_name(g: &Gender) -> String {
|
|
let names = match g {
|
|
Gender::Man => MASC_NAMES.to_vec(),
|
|
Gender::Woman => FEMME_NAMES.to_vec(),
|
|
Gender::Nonbinary => NEUTR_NAMES.to_vec(),
|
|
Gender::DemiGirl => [FEMME_NAMES, NEUTR_NAMES].concat(),
|
|
Gender::DemiBoy => [MASC_NAMES, NEUTR_NAMES].concat(),
|
|
Gender::NoGender => [MASC_NAMES, FEMME_NAMES, NEUTR_NAMES].concat(),
|
|
_ => return String::from("MISSINGNO"),
|
|
};
|
|
match names.choose(&mut rand::thread_rng()) {
|
|
Some(n) => String::from(n.clone()),
|
|
None => String::from("MISSINGNO"),
|
|
}
|
|
}
|
|
|
|
pub fn human_battle_maniac(lv: u8) -> Unit {
|
|
let mut rng = rand::thread_rng();
|
|
let mut j = rng.gen_range(10..26);
|
|
if lv > 20 {
|
|
j += rng.gen_range(10..26);
|
|
}
|
|
let g = Unit::generate_gender();
|
|
let n = format!("Battle Maniac {}", Unit::generate_name(&g)); // Excuse me, but may I
|
|
// borrow your gender for a
|
|
// moment?
|
|
let mut sb = StatBlock::new();
|
|
for _i in 0..lv {
|
|
match rng.gen_range(0..4) {
|
|
0 => sb.add_strength(1),
|
|
1 => sb.add_defense(1),
|
|
2 => sb.add_vitality(1),
|
|
3 => sb.add_intellect(1),
|
|
_ => {
|
|
eprintln!("ERROR! human_battle_maniac() stat assign out of bounds!");
|
|
sb.add_vitality(1);
|
|
},
|
|
};
|
|
}
|
|
let mut equip = EquipmentBlock::new();
|
|
|
|
//TODO: create equipment and equipment allocation algorithm
|
|
Unit {
|
|
name: n,
|
|
level: lv,
|
|
exp: 0, //TODO!! Fix this
|
|
status: None,
|
|
gender: g,
|
|
base_stats: sb.clone(),
|
|
hp: u16::from(
|
|
18u16 + (u16::from(lv) * u16::from(0u8.wrapping_add_signed(sb.vitality()))),
|
|
),
|
|
jel: j,
|
|
jel_total: j,
|
|
is_monster: false,
|
|
equipment: Some(equip),
|
|
}
|
|
}
|
|
pub fn human_street_samurai(lv: u8) -> Unit {
|
|
let mut rng = rand::thread_rng();
|
|
let mut j = rng.gen_range(10..26);
|
|
if rng.gen_range(0..100) < 25 && lv > 20 {
|
|
j += rng.gen_range(10..26);
|
|
}
|
|
let g = Unit::generate_gender();
|
|
let n = format!("Street Samurai {}", Unit::generate_name(&g));
|
|
|
|
let mut sb = StatBlock::new();
|
|
for _i in 0..lv {
|
|
match rng.gen_range(0..4) {
|
|
0 => sb.add_strength(1),
|
|
1 => sb.add_defense(1),
|
|
2 => sb.add_vitality(1),
|
|
3 => sb.add_agility(1),
|
|
_ => {
|
|
eprintln!("ERROR! human_street_samurai() stat assign out of bounds!");
|
|
sb.add_vitality(1);
|
|
},
|
|
};
|
|
}
|
|
let mut equip = EquipmentBlock::new();
|
|
//TODO: create equipment and equipment allocation algorithm
|
|
|
|
Unit {
|
|
name: n,
|
|
level: lv,
|
|
exp: 0, //TODO!! fix this
|
|
status: None,
|
|
gender: g,
|
|
base_stats: sb.clone(),
|
|
hp: u16::from(
|
|
18u16 + (u16::from(lv) * u16::from(0u8.wrapping_add_signed(sb.vitality()))),
|
|
),
|
|
jel: j,
|
|
jel_total: j,
|
|
is_monster: false,
|
|
equipment: Some(equip),
|
|
}
|
|
}
|
|
}
|