mnml/server/src/skill.rs
2018-10-30 16:44:10 +11:00

201 lines
4.8 KiB
Rust
Executable File

// 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<u8>;
#[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<Uuid>,
pub target_team_id: Uuid,
pub roll: Option<Roll>,
}
impl Cast {
pub fn new(source_cryp_id: Uuid, source_team_id: Uuid, target_team_id: Option<Uuid>, 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,
// }
// }