// use rand::prelude::*; use uuid::Uuid; use cryp::{Cryp, CrypSkill, CrypStat}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct Roll { pub base: u64, pub result: u64, } pub type Cooldown = Option; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum Skill { Attack, Block, Heal, Stun, Dodge, // used by tests, no cd, no dmg TestTouch, TestStun, TestBlock, } impl Skill { pub fn cd(&self) -> Cooldown { match self { Skill::Attack => None, Skill::Block => Some(1), Skill::Dodge => Some(1), Skill::Heal => Some(2), Skill::Stun => Some(2), Skill::TestTouch => None, Skill::TestStun => None, Skill::TestBlock => None, } } pub fn speed(&self) -> u8 { match self { Skill::Attack => 10, Skill::Block => 5, Skill::Dodge => 5, Skill::Heal => 2, Skill::Stun => 2, Skill::TestTouch => 10, Skill::TestStun => 2, Skill::TestBlock => 5, } } pub fn stat(&self, cryp: &Cryp) -> CrypStat { match self { Skill::Attack => cryp.str, Skill::Block => cryp.str, Skill::Stun => cryp.str, Skill::Dodge => cryp.agi, Skill::Heal => cryp.int, // test skills Skill::TestTouch => cryp.int, Skill::TestStun => cryp.str, Skill::TestBlock => cryp.str, } } pub fn duration(&self) -> u8 { match self { Skill::Dodge => 1, Skill::Stun => 2, Skill::Block => 1, Skill::TestBlock => 1, Skill::TestStun => 2, _ => panic!("{:?} does not have a duration", self), } } pub fn self_targeting(&self) -> bool { match self { Skill::Block => true, Skill::TestBlock => true, _ => false, } } pub fn castable(&self, cryp: &Cryp) -> bool { if cryp.is_stunned() { return false; } true } } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct Cast { pub id: Uuid, pub skill: Skill, pub source_team_id: Uuid, pub source_cryp_id: Uuid, pub target_cryp_id: Option, pub target_team_id: Uuid, pub roll: Option, } impl Cast { pub fn new(source_cryp_id: Uuid, source_team_id: Uuid, target_team_id: Option, skill: Skill) -> Cast { let (target_cryp_id, target_team_id) = match skill.self_targeting() { true => (Some(source_cryp_id), source_team_id), false => (None, target_team_id.unwrap()) }; return Cast { id: Uuid::new_v4(), source_cryp_id, source_team_id, target_cryp_id, target_team_id, skill, roll: None, }; } pub fn resolve(&mut self, cryp: &mut Cryp, target: &mut Cryp) -> &mut Cast { let roll = cryp.roll(self.skill); println!("{:?} -> {:?} -> {:?}", cryp.name, self.skill, target.name); match self.skill { // the real deal Skill::Stun => target.stun(roll), Skill::Attack => target.attack(roll), Skill::Block => target.block(roll), Skill::Heal => target, Skill::Dodge => target, // Test Skills Skill::TestStun => target.stun(roll), Skill::TestBlock => target.block(roll), Skill::TestTouch => target, }; // println!("{:?} gettin clapped for {:?}", target.name, roll.result); self.roll = Some(roll); self } pub fn set_target(&mut self, cryp_id: Uuid) -> &mut Cast { self.target_cryp_id = Some(cryp_id); self } pub fn used_cooldown(self) -> bool { let cs = CrypSkill::new(self.skill); return cs.cd.is_some(); } } // #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] // pub enum Skill { // Stoney, // Evasive, // } // impl Skill { // pub fn apply(&self, roll: Roll) -> Roll { // match self { // Skill::Stoney => stoney(self, roll), // Skill::Evasive => evasive(self, roll), // } // } // } // fn stoney(_s: &Skill, mut roll: Roll) -> Roll { // let effect = 0b11110000; // match roll.kind { // StatKind::Def => { // // println!("{:064b} | <- {:?}", effect, s); // roll.result = roll.result | effect; // roll // }, // _ => roll, // } // } // fn evasive(_s: &Skill, mut roll: Roll) -> Roll { // match roll.kind { // StatKind::Def => { // if roll.result.is_power_of_two() { // roll.result = u64::max_value() // } // roll // }, // _ => roll, // } // }