barely functional
This commit is contained in:
commit
62ce8d20c4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/Cargo.lock
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "broken-data"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
133
src/equipment/comp.rs
Normal file
133
src/equipment/comp.rs
Normal file
|
@ -0,0 +1,133 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Comp {
|
||||
id: String, // Unique Item ID
|
||||
name: String, // Display Name
|
||||
slots: u8, // Spell slots, between 1 and 10
|
||||
mstorage: u8, // Spell storage, powers of 2, 16-128 (MiB)
|
||||
gstorage: u8, // Program storage, powers of 2, 8-32 (GiB)
|
||||
stat_mods: StatBlock, // Bufs/debufs
|
||||
flavor: String, // Flavortext
|
||||
description: String, // Description text
|
||||
}
|
||||
impl Comp {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: String::from("COMP_BLANK"),
|
||||
name: String::from("Basic DMD"),
|
||||
slots: 1,
|
||||
mstorage: 16,
|
||||
gstorage: 8,
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
flavor: String::from("A basic bitch digital magick device"),
|
||||
description: String::from(
|
||||
"One spell slot, 16MiB of spell storage, and 8GiB of program storage",
|
||||
),
|
||||
}
|
||||
}
|
||||
pub fn id(self) -> String {
|
||||
self.id
|
||||
}
|
||||
pub fn name(self) -> String {
|
||||
self.name
|
||||
}
|
||||
pub fn slots(self) -> u8 {
|
||||
self.slots
|
||||
}
|
||||
pub fn spell_storage(self) -> u8 {
|
||||
self.mstorage
|
||||
}
|
||||
pub fn program_storage(self) -> u8 {
|
||||
self.gstorage
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
pub fn description(self) -> String {
|
||||
self.description
|
||||
}
|
||||
pub fn flavor(self) -> String {
|
||||
self.flavor
|
||||
}
|
||||
|
||||
// Low teir gear
|
||||
pub fn cef_8080() -> Self {
|
||||
Self {
|
||||
id: String::from("COMP_CEF_8080"),
|
||||
name: String::from("CEF 8080"),
|
||||
slots: 1,
|
||||
mstorage: 16,
|
||||
gstorage: 8,
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
flavor: String::from("Mass produced garbage."),
|
||||
description: String::from(
|
||||
"One spell slot, 16MiB of spell storage, and 8GiB of program storage.",
|
||||
),
|
||||
}
|
||||
}
|
||||
pub fn chiba_e3() -> Self {
|
||||
let mut stat_mods = StatBlock::new_zero();
|
||||
stat_mods.set_intellect(1);
|
||||
Self {
|
||||
id: String::from("COMP_CHIBA_E3"),
|
||||
name: String::from("Chiba E3"),
|
||||
slots: 1,
|
||||
mstorage: 16,
|
||||
gstorage: 8,
|
||||
stat_mods,
|
||||
flavor: String::from("Handmade with love by Gideon Chiba, good luck out there trainee!"),
|
||||
description: String::from("+1 Intellect, 1 spell slot, 16MiB of spell storage, 8GiB of program storage."),
|
||||
}
|
||||
}
|
||||
pub fn spiceworks_v3() -> Self {
|
||||
let mut stat_mods = StatBlock::new_zero();
|
||||
stat_mods.set_magick(1);
|
||||
Self {
|
||||
id: String::from("COMP_SPICE_V3"),
|
||||
name: String::from("Spiceworks V3"),
|
||||
slots: 2,
|
||||
mstorage: 16,
|
||||
gstorage: 8,
|
||||
stat_mods,
|
||||
flavor: String::from("A heart is scratched into the side."),
|
||||
description: String::from("+1 Magick, 2 spell slots, 16MiB of spell storage, 8GiB of program storage."),
|
||||
}
|
||||
}
|
||||
|
||||
// Mid teir gear
|
||||
pub fn chiba_d35() -> Self {
|
||||
let mut mods = StatBlock::new_zero();
|
||||
mods.set_intellect(3);
|
||||
Self {
|
||||
id: String::from("COMP_CHIBA_D35"),
|
||||
name: String::from("Chiba D35"),
|
||||
slots: 6,
|
||||
mstorage: 64,
|
||||
gstorage: 16,
|
||||
stat_mods: mods,
|
||||
flavor: String::from("The hottest new offering from Gideon Chiba's handcrafted digital magick devices"),
|
||||
description: String::from("+3 Intellect, six spell slots, 64MiB of spell storage, and 16GiB of program storage"),
|
||||
}
|
||||
}
|
||||
pub fn cef_8081() -> Self {
|
||||
Self {
|
||||
id: String::from("COMP_CEF_8081"),
|
||||
name: String::from("CEF 8081"),
|
||||
slots: 5,
|
||||
mstorage: 128,
|
||||
gstorage: 16,
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
flavor: String::from("Mass produced garbage."),
|
||||
description: String::from("Five spell slots, 128MiB of spell storage, and 16GiB of program storage."),
|
||||
}
|
||||
}
|
||||
|
||||
// Gear Sets for AI unit generation
|
||||
pub fn low_level_opts() -> [Self; 3] {
|
||||
[Self::cef_8080(), Self::chiba_e3(), Self::spiceworks_v3()]
|
||||
}
|
||||
pub fn mid_level_opts() -> [Self; 2] {
|
||||
[Self::chiba_d35(), Self::cef_8081()]
|
||||
}
|
||||
}
|
66
src/equipment/gun.rs
Normal file
66
src/equipment/gun.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bullet {
|
||||
id: String,
|
||||
name: String,
|
||||
attack: u8,
|
||||
}
|
||||
impl Bullet {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: "BULLET_BLANK",
|
||||
name: "BLANK",
|
||||
attack: 0,
|
||||
}
|
||||
}
|
||||
pub fn id(self) -> String {
|
||||
self.id
|
||||
}
|
||||
pub fn name(self) -> String {
|
||||
self.name
|
||||
}
|
||||
pub fn attack(self) -> u8 {
|
||||
self.attack
|
||||
}
|
||||
|
||||
pub fn normal() -> Self {
|
||||
Self {
|
||||
id: "BULLET_NORMAL",
|
||||
name: "Normal Bullet",
|
||||
attack: 5,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Gun {
|
||||
id: String,
|
||||
name: String,
|
||||
stat_mods: StatBlock,
|
||||
attack: u8,
|
||||
bullets: Option<Bullet>,
|
||||
mag_size: u8,
|
||||
description: String,
|
||||
flavor: String,
|
||||
}
|
||||
impl Gun {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: String::from("GUN_WATER"),
|
||||
name: String::from("Water Gun"),
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
attack: 0,
|
||||
bullets: None,
|
||||
mag_size: 0,
|
||||
description: String::from("A cheap toy."),
|
||||
flavor: String::from("Don't walk into a gun fight with this."),
|
||||
}
|
||||
}
|
||||
pub fn attack(self) -> u8 {
|
||||
self.attack
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
}
|
18
src/equipment/hat.rs
Normal file
18
src/equipment/hat.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Hat {
|
||||
name: String,
|
||||
stat_mods: StatBlock,
|
||||
}
|
||||
impl Hat {
|
||||
pub fn new() -> Hat {
|
||||
Hat {
|
||||
name: String::from("Basic Hat"),
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
}
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
}
|
107
src/equipment/mod.rs
Normal file
107
src/equipment/mod.rs
Normal file
|
@ -0,0 +1,107 @@
|
|||
mod comp;
|
||||
mod gun;
|
||||
mod hat;
|
||||
mod pants;
|
||||
mod shirt;
|
||||
mod shoes;
|
||||
mod sword;
|
||||
|
||||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EquipmentBlock {
|
||||
sword: Option<sword::Sword>,
|
||||
gun: Option<gun::Gun>,
|
||||
comp: Option<comp::Comp>,
|
||||
head: Option<hat::Hat>,
|
||||
chest: Option<shirt::Shirt>,
|
||||
leg: Option<pants::Pants>,
|
||||
foot: Option<shoes::Shoes>,
|
||||
}
|
||||
impl EquipmentBlock {
|
||||
pub fn new() -> EquipmentBlock {
|
||||
EquipmentBlock {
|
||||
sword: None,
|
||||
gun: None,
|
||||
comp: None,
|
||||
head: None,
|
||||
chest: None,
|
||||
leg: None,
|
||||
foot: None,
|
||||
}
|
||||
}
|
||||
pub fn sword(self) -> Option<sword::Sword> {
|
||||
self.sword
|
||||
}
|
||||
pub fn gun(self) -> Option<gun::Gun> {
|
||||
self.gun
|
||||
}
|
||||
pub fn comp(self) -> Option<comp::Comp> {
|
||||
self.comp
|
||||
}
|
||||
pub fn hat(self) -> Option<hat::Hat> {
|
||||
self.head
|
||||
}
|
||||
pub fn shirt(self) -> Option<shirt::Shirt> {
|
||||
self.chest
|
||||
}
|
||||
pub fn pants(self) -> Option<pants::Pants> {
|
||||
self.leg
|
||||
}
|
||||
pub fn shoes(self) -> Option<shoes::Shoes> {
|
||||
self.foot
|
||||
}
|
||||
pub fn equip_sword(mut self, sword: sword::Sword) {
|
||||
self.sword = Some(sword);
|
||||
}
|
||||
pub fn equip_gun(mut self, gun: gun::Gun) {
|
||||
self.gun = Some(gun);
|
||||
}
|
||||
pub fn equip_comp(mut self, comp: comp::Comp) {
|
||||
self.comp = Some(comp);
|
||||
}
|
||||
pub fn equip_hat(mut self, hat: hat::Hat) {
|
||||
self.head = Some(hat);
|
||||
}
|
||||
pub fn equip_chest(mut self, shirt: shirt::Shirt) {
|
||||
self.chest = Some(shirt);
|
||||
}
|
||||
pub fn equip_pants(mut self, pants: pants::Pants) {
|
||||
self.leg = Some(pants);
|
||||
}
|
||||
pub fn equip_shoes(mut self, shoes: shoes::Shoes) {
|
||||
self.foot = Some(shoes);
|
||||
}
|
||||
pub fn unequip_sword(mut self) {
|
||||
self.sword = None;
|
||||
}
|
||||
pub fn unequip_gun(mut self) {
|
||||
self.gun = None;
|
||||
}
|
||||
pub fn unequip_comp(mut self) {
|
||||
self.comp = None;
|
||||
}
|
||||
pub fn unequip_hat(mut self) {
|
||||
self.head = None;
|
||||
}
|
||||
pub fn unequip_shirt(mut self) {
|
||||
self.chest = None;
|
||||
}
|
||||
pub fn unequip_pants(mut self) {
|
||||
self.leg = None;
|
||||
}
|
||||
pub fn unequip_shoes(mut self) {
|
||||
self.foot = None;
|
||||
}
|
||||
pub fn bonuses(self) -> StatBlock {
|
||||
let mut stats = StatBlock::new_zero();
|
||||
stats += self.sword.unwrap_or(sword::Sword::new()).stat_mods();
|
||||
stats += self.gun.uwrap_or(gun::Gun::new()).stat_mods();
|
||||
stats += self.comp.unwrap_or(comp::Comp::new()).stat_mods();
|
||||
stats += self.head.unwrap_or(hat::Hat::new()).stat_mods();
|
||||
stats += self.chest.unwrap_or(shirt::Shirt::new()).stat_mods();
|
||||
stats += self.leg.unwrap_or(pants::Pants::new()).stat_mods();
|
||||
stats += self.foot.unwrap_or(shoes::Shoes::new()).stat_mods();
|
||||
stats
|
||||
}
|
||||
}
|
18
src/equipment/pants.rs
Normal file
18
src/equipment/pants.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Pants {
|
||||
name: String,
|
||||
stat_mods: StatBlock,
|
||||
}
|
||||
impl Pants {
|
||||
pub fn new() -> Pants {
|
||||
Pants {
|
||||
name: String::from("Basic Pants"),
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
}
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
}
|
18
src/equipment/shirt.rs
Normal file
18
src/equipment/shirt.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Shirt {
|
||||
name: String,
|
||||
stat_mods: StatBlock,
|
||||
}
|
||||
impl Shirt {
|
||||
pub fn new() -> Shirt {
|
||||
Shirt {
|
||||
name: String::from("Basic Shirt"),
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
}
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
}
|
18
src/equipment/shoes.rs
Normal file
18
src/equipment/shoes.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Shoes {
|
||||
name: String,
|
||||
stat_mods: StatBlock,
|
||||
}
|
||||
impl Shoes {
|
||||
pub fn new() -> Shoes {
|
||||
Shoes {
|
||||
name: String::from("Basic Shoes"),
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
}
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
}
|
84
src/equipment/sword.rs
Normal file
84
src/equipment/sword.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use crate::statistics::StatBlock;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sword {
|
||||
id: String,
|
||||
name: String,
|
||||
damage: u8,
|
||||
stat_mods: StatBlock,
|
||||
flavor: String,
|
||||
description: String,
|
||||
}
|
||||
impl Sword {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: String::from("SWORD_BLANK"),
|
||||
name: String::from("Basic Sword"),
|
||||
damage: 1u8,
|
||||
stat_mods: StatBlock::new_zero(),
|
||||
flavor: String::from("A basic bitch sword. It is completely useless."),
|
||||
description: String::from("1 Attack Strength Sword. Literally the cheapest you can get."),
|
||||
}
|
||||
}
|
||||
pub fn id(self) -> String {
|
||||
self.id
|
||||
}
|
||||
pub fn name(self) -> String {
|
||||
self.name
|
||||
}
|
||||
pub fn damage(self) -> u8 {
|
||||
self.damage
|
||||
}
|
||||
pub fn stat_mods(self) -> StatBlock {
|
||||
self.stat_mods
|
||||
}
|
||||
pub fn flavor(self) -> String {
|
||||
self.flavor
|
||||
}
|
||||
pub fn description(self) -> String {
|
||||
self.description
|
||||
}
|
||||
pub fn set_id(&mut self, id: String) {
|
||||
self.id = id;
|
||||
}
|
||||
pub fn set_name(&mut self, name: String) {
|
||||
self.name = name;
|
||||
}
|
||||
pub fn set_damage(&mut self, damage: u8) {
|
||||
self.damage = damage;
|
||||
}
|
||||
pub fn set_stat_mods(&mut self, stat_mods: StatBlock) {
|
||||
self.stat_mods = stat_mods;
|
||||
}
|
||||
pub fn set_flavor(&mut self, flavor: String) {
|
||||
self.flavor = flavor;
|
||||
}
|
||||
pub fn set_description(&mut self, description: String) {
|
||||
self.description = description;
|
||||
}
|
||||
|
||||
pub fn sacred_blade() -> Self {
|
||||
let mut buf = StatBlock::new_zero();
|
||||
buf.set_strength(5);
|
||||
Self {
|
||||
id: String::from("SWORD_SACRED_BLADE"),
|
||||
name: String::from("Sacred Blade"),
|
||||
damage: 58u8,
|
||||
stat_mods: buf,
|
||||
flavor: String::from("Forged eons ago by master smiths and imbued with the magic of gods."),
|
||||
description: String::from("+5 Strength. 58 Attack. The sacred sword of a religious cult."),
|
||||
}
|
||||
}
|
||||
pub fn ceremonial_knife() -> Self {
|
||||
let mut buf = StatBlock::new_zero();
|
||||
buf.set_intellect(2);
|
||||
Self {
|
||||
id: String::from("SWORD_CEREMONIAL_KNIFE"),
|
||||
name: String::from("Ceremonial Knife"),
|
||||
damage: 27u8,
|
||||
stat_mods: buf,
|
||||
flavor: String::from("Used for sex parties, mostly."),
|
||||
description: String::from("+2 Intellect. 27 Attack. Used by wiccans during rites."),
|
||||
}
|
||||
}
|
||||
}
|
16
src/inventory.rs
Normal file
16
src/inventory.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use crate::equipment::{sword::Sword, gun::Gun, comp::Comp, hat::Hat, shirt::Shirt, pants::Pants, shoes::Shoes};
|
||||
|
||||
struct BagEquipment {
|
||||
swords: Option<Vec<Sword>>,
|
||||
guns: Option<Vec<Guns>>,
|
||||
comps: Option<Vec<Comp>>,
|
||||
hats: Option<Vec<Hat>>,
|
||||
shirts: Option<Vec<Shirt>>,
|
||||
pants: Option<Vec<Pants>>,
|
||||
shoes: Option<Vec<Shoes>>,
|
||||
}
|
||||
|
||||
struct Inventory {
|
||||
equipment: Option<BagEquipment>,
|
||||
|
||||
}
|
6
src/lib.rs
Normal file
6
src/lib.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
pub mod equipment;
|
||||
pub mod magic;
|
||||
pub mod statistics;
|
||||
pub mod unit;
|
||||
pub mod inventory;
|
||||
pub mod status;
|
1
src/magic.rs
Normal file
1
src/magic.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
148
src/statistics.rs
Normal file
148
src/statistics.rs
Normal file
|
@ -0,0 +1,148 @@
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct StatBlock {
|
||||
strength: i8, // determines physical attack power
|
||||
magick: i8, // determines magick attack power
|
||||
defense: i8, // determines damage reduction
|
||||
intellect: i8, // determines magick hit chance and evasion chance
|
||||
dexterity: i8, // determines physical hit chance and evasion chance
|
||||
agility: i8, // determines turn order
|
||||
vitality: i8, // determines HP/level
|
||||
}
|
||||
|
||||
impl std::ops::Add for StatBlock {
|
||||
type Output = Self;
|
||||
fn add(self, other: Self) -> Self {
|
||||
Self {
|
||||
strength: self.strength + other.strength,
|
||||
magick: self.magick + other.magick,
|
||||
defense: self.defense + other.defense,
|
||||
intellect: self.intellect + other.intellect,
|
||||
dexterity: self.dexterity + other.dexterity,
|
||||
agility: self.agility + other.agility,
|
||||
vitality: self.vitality + other.vitality,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign for StatBlock {
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
*self = Self {
|
||||
strength: self.strength + other.strength,
|
||||
magick: self.magick + other.magick,
|
||||
defense: self.defense + other.defense,
|
||||
intellect: self.intellect + other.intellect,
|
||||
dexterity: self.dexterity + other.dexterity,
|
||||
agility: self.agility + other.agility,
|
||||
vitality: self.vitality + other.vitality,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for StatBlock {
|
||||
type Output = Self;
|
||||
fn sub(self, other: Self) -> Self {
|
||||
Self {
|
||||
strength: self.strength - other.strength,
|
||||
magick: self.magick - other.magick,
|
||||
defense: self.defense - other.defense,
|
||||
intellect: self.intellect - other.intellect,
|
||||
dexterity: self.dexterity - other.dexterity,
|
||||
agility: self.agility - other.agility,
|
||||
vitality: self.vitality - other.vitality,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StatBlock {
|
||||
/// Generates a level 1 stat block
|
||||
pub fn new() -> StatBlock {
|
||||
StatBlock {
|
||||
strength: 3,
|
||||
magick: 3,
|
||||
defense: 3,
|
||||
intellect: 3,
|
||||
dexterity: 3,
|
||||
agility: 3,
|
||||
vitality: 3,
|
||||
}
|
||||
}
|
||||
/// Generates a null stat block
|
||||
pub fn new_zero() -> StatBlock {
|
||||
StatBlock {
|
||||
strength: 0,
|
||||
magick: 0,
|
||||
defense: 0,
|
||||
intellect: 0,
|
||||
dexterity: 0,
|
||||
agility: 0,
|
||||
vitality: 0,
|
||||
}
|
||||
}
|
||||
/// Generates a null stat block for use as the bonus_stat block
|
||||
pub fn new_bonus() -> StatBlock {
|
||||
StatBlock::new_zero()
|
||||
}
|
||||
pub fn strength(self) -> i8 {
|
||||
self.strength
|
||||
}
|
||||
pub fn magick(self) -> i8 {
|
||||
self.magick
|
||||
}
|
||||
pub fn defense(self) -> i8 {
|
||||
self.defense
|
||||
}
|
||||
pub fn intellect(self) -> i8 {
|
||||
self.intellect
|
||||
}
|
||||
pub fn dexterity(self) -> i8 {
|
||||
self.dexterity
|
||||
}
|
||||
pub fn agility(self) -> i8 {
|
||||
self.agility
|
||||
}
|
||||
pub fn vitality(self) -> i8 {
|
||||
self.vitality
|
||||
}
|
||||
pub fn set_strength(&mut self, strength: i8) {
|
||||
self.strength = strength;
|
||||
}
|
||||
pub fn set_magick(&mut self, magick: i8) {
|
||||
self.magick = magick;
|
||||
}
|
||||
pub fn set_defense(&mut self, defense: i8) {
|
||||
self.defense = defense;
|
||||
}
|
||||
pub fn set_intellect(&mut self, intellect: i8) {
|
||||
self.intellect = intellect;
|
||||
}
|
||||
pub fn set_dexterity(&mut self, dexterity: i8) {
|
||||
self.dexterity = dexterity;
|
||||
}
|
||||
pub fn set_agility(&mut self, agility: i8) {
|
||||
self.agility = agility;
|
||||
}
|
||||
pub fn set_vitality(&mut self, vitality: i8) {
|
||||
self.vitality = vitality;
|
||||
}
|
||||
pub fn add_strength(&mut self, count: i8) {
|
||||
self.strength = self.strength.saturating_add(count);
|
||||
}
|
||||
pub fn add_magick(&mut self, count: i8) {
|
||||
self.magick = self.magick.saturating_add(count);
|
||||
}
|
||||
pub fn add_defense(&mut self, count: i8) {
|
||||
self.defense = self.defense.saturating_add(count);
|
||||
}
|
||||
pub fn add_intellect(&mut self, count: i8) {
|
||||
self.intellect = self.intellect.saturating_add(count);
|
||||
}
|
||||
pub fn add_dexterity(&mut self, count: i8) {
|
||||
self.dexterity = self.dexterity.saturating_add(count);
|
||||
}
|
||||
pub fn add_agility(&mut self, count: i8) {
|
||||
self.agility = self.agility.saturating_add(count);
|
||||
}
|
||||
pub fn add_vitality(&mut self, count: i8) {
|
||||
self.vitality = self.vitality.saturating_add(count);
|
||||
}
|
||||
}
|
11
src/status.rs
Normal file
11
src/status.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Status {
|
||||
Poison, // hp slowly decreases
|
||||
Static, // chance to miss turn
|
||||
Freeze, // hp slowly decreases and chance to miss turn
|
||||
Burn, // hp slowly decreases and unable to cast magic
|
||||
Slow, // speed is halved
|
||||
Confuse, // chance to hit random target (self included)
|
||||
Stop, // miss turn
|
||||
Haste, // speed is doubled
|
||||
}
|
213
src/unit.rs
Normal file
213
src/unit.rs
Normal file
|
@ -0,0 +1,213 @@
|
|||
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),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue