205 lines
4.0 KiB
Rust
Executable File
205 lines
4.0 KiB
Rust
Executable File
use uuid::Uuid;
|
|
use rand::prelude::*;
|
|
use serde_cbor::*;
|
|
|
|
use rpc::{GenerateParams};
|
|
use skill::{Skill};
|
|
|
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
|
pub enum StatKind {
|
|
Dmg,
|
|
Def,
|
|
Hp,
|
|
Stam,
|
|
}
|
|
|
|
#[derive(Debug,Clone)]
|
|
pub struct Roll {
|
|
pub base: u64,
|
|
pub result: u64,
|
|
pub kind: StatKind,
|
|
}
|
|
|
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
|
pub struct Stat {
|
|
pub value: u64,
|
|
pub kind: StatKind,
|
|
}
|
|
|
|
impl Stat {
|
|
fn set(&mut self, v: u64) -> &Stat {
|
|
self.value = v;
|
|
self
|
|
}
|
|
|
|
fn roll(&self, c: &Cryp) -> Roll {
|
|
let mut rng = thread_rng();
|
|
let base: u64 = rng.gen();
|
|
|
|
let mut roll = Roll { kind: self.kind, base, result: base };
|
|
|
|
println!("{:?}", self.kind);
|
|
println!("{:064b} <- base roll", base);
|
|
|
|
// apply skills
|
|
roll = c.skills.iter().fold(roll, |roll, s| s.apply(roll));
|
|
|
|
// finally combine with stat
|
|
println!("{:064b} <- finalised", roll.result);
|
|
roll.result = roll.result & self.value;
|
|
|
|
println!("{:064b} & <- attribute roll", self.value);
|
|
println!("{:064b} = {:?}", roll.result, roll.result);
|
|
println!("");
|
|
|
|
return roll;
|
|
}
|
|
|
|
fn reduce(&mut self, dmg: u64) -> &mut Stat {
|
|
self.value = self.value.saturating_sub(dmg);
|
|
self
|
|
}
|
|
}
|
|
|
|
pub struct Turn {
|
|
pub dmg: Roll,
|
|
pub def: Roll,
|
|
}
|
|
|
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
|
pub struct Cryp {
|
|
pub id: Uuid,
|
|
// todo
|
|
// make attributes hold this value
|
|
pub dmg: Stat,
|
|
pub def: Stat,
|
|
pub stam: Stat,
|
|
pub hp: Stat,
|
|
pub xp: u64,
|
|
pub lvl: u8,
|
|
pub skills: Vec<Skill>,
|
|
pub name: String,
|
|
}
|
|
|
|
fn check_lvl(lvl: u8) -> u8 {
|
|
if lvl > 64 { return 64; }
|
|
return lvl;
|
|
}
|
|
|
|
impl Cryp {
|
|
pub fn new() -> Cryp {
|
|
let id = Uuid::new_v4();
|
|
return Cryp {
|
|
id,
|
|
dmg: Stat { value: 0, kind: StatKind::Dmg },
|
|
def: Stat { value: 0, kind: StatKind::Def },
|
|
stam: Stat { value: 0, kind: StatKind::Stam },
|
|
hp: Stat { value: 0, kind: StatKind::Hp },
|
|
lvl: 0,
|
|
xp: 0,
|
|
skills: vec![],
|
|
name: String::new()
|
|
};
|
|
}
|
|
|
|
pub fn named(mut self, name: String) -> Cryp {
|
|
self.name = name.clone();
|
|
self
|
|
}
|
|
|
|
pub fn level(mut self, lvl: u8) -> Cryp {
|
|
self.lvl = check_lvl(lvl);
|
|
self
|
|
}
|
|
|
|
pub fn learn(mut self, s: Skill) -> Cryp {
|
|
self.skills.push(s);
|
|
self
|
|
}
|
|
|
|
pub fn add_xp(mut self) -> Cryp {
|
|
self.xp = self.xp.saturating_add(1);
|
|
if self.xp.is_power_of_two() {
|
|
return self.level_up();
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn level_up(mut self) -> Cryp {
|
|
self.lvl = self.lvl.saturating_add(1);
|
|
self.create()
|
|
}
|
|
|
|
pub fn turn(&self) -> Turn {
|
|
// println!("{:?}'s turn:", c.name);
|
|
let dmg = self.dmg.roll(self);
|
|
let def = self.def.roll(self);
|
|
|
|
return Turn { dmg, def }
|
|
}
|
|
|
|
pub fn create(mut self) -> Cryp {
|
|
let mut rng = thread_rng();
|
|
let max = match self.lvl == 64 {
|
|
true => u64::max_value(),
|
|
false => 2_u64.pow(self.lvl.into()),
|
|
};
|
|
|
|
self.xp = max;
|
|
|
|
self.dmg.set(rng.gen_range(1, max));
|
|
self.def.set(rng.gen_range(1, max));
|
|
self.stam.set(rng.gen_range(1, max));
|
|
self.hp.set(self.stam.value);
|
|
self
|
|
}
|
|
|
|
pub fn assign_dmg(&mut self, opp: &Cryp, plr_t: &Turn, opp_t: &Turn) -> &mut Cryp {
|
|
let final_dmg = opp_t.dmg.result.saturating_sub(plr_t.def.result);
|
|
let blocked = opp_t.dmg.result.saturating_sub(final_dmg);
|
|
|
|
self.hp.reduce(final_dmg);
|
|
|
|
println!("{:?} deals {:?} dmg to {:?} ({:?} blocked / {:?} hp remaining)"
|
|
,opp.name
|
|
,final_dmg
|
|
,self.name
|
|
,blocked
|
|
,self.hp.value);
|
|
|
|
self
|
|
}
|
|
|
|
pub fn is_ko(&self) -> bool {
|
|
self.hp.value == 0
|
|
}
|
|
|
|
}
|
|
|
|
pub fn generate(params: GenerateParams) -> Cryp {
|
|
Cryp::new()
|
|
.named("hatchling".to_string())
|
|
.level(params.level)
|
|
.learn(Skill::Stoney)
|
|
.create()
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use cryp::*;
|
|
use skill::*;
|
|
|
|
#[test]
|
|
fn create_cryp_test() {
|
|
let max_level = Cryp::new()
|
|
.named("hatchling".to_string())
|
|
.level(64)
|
|
.learn(Skill::Stoney)
|
|
.create();
|
|
|
|
assert_eq!(max_level.lvl, 64);
|
|
return;
|
|
}
|
|
}
|