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