diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 5cc5248e..1f7d47f9 100755 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -9,7 +9,6 @@ use failure::err_msg; use account::Account; use rpc::{CrypSpawnParams}; -use game::{Log}; use skill::{Skill, Cooldown, Effect}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -53,15 +52,21 @@ pub struct CrypStat { } impl CrypStat { - fn set(&mut self, v: u64) -> &CrypStat { + pub fn set(&mut self, v: u64) -> &CrypStat { self.value = v; self } - pub fn reduce(&mut self, dmg: u64) -> &mut CrypStat { - self.value = self.value.saturating_sub(dmg); + pub fn reduce(&mut self, amt: u64) -> &mut CrypStat { + self.value = self.value.saturating_sub(amt); self } + + pub fn increase(&mut self, amt: u64) -> &mut CrypStat { + self.value = self.value.saturating_add(amt); + self + } + } #[derive(Debug,Clone,Serialize,Deserialize)] diff --git a/server/src/game.rs b/server/src/game.rs index d0dd47bd..a7f4a521 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -229,9 +229,10 @@ impl Game { } let skill = Cast::new(source_cryp_id, team_id, target_team_id, skill); + let skill_id = skill.id; self.stack.push(skill); - return Ok(skill.id); + return Ok(skill_id); } fn skill_phase_finished(&self) -> bool { @@ -355,15 +356,16 @@ impl Game { let mut source = self.cryp_by_id(skill.source_cryp_id).unwrap().clone(); let mut target = self.cryp_by_id(skill.target_cryp_id.unwrap()).unwrap().clone(); - self.log.push(format!("{:?} uses {:?} on {:?}", source.name, skill.skill, target.name)); - let resolution = skill.set_resolution(&mut source, &mut target, &mut self.log); - self.resolved.push(resolution.clone()); + // self.log.push(format!("{:?} uses {:?} on {:?}", source.name, skill.skill, target.name)); + skill.set_resolution(&mut source, &mut target); + self.log.push(skill.resolution.text.clone()); + self.resolved.push(skill.clone()); self.update_cryp(&mut source); self.update_cryp(&mut target); - return resolution.clone(); + return skill.clone(); }).collect::>(); // now Resolve has all been assigned @@ -836,9 +838,6 @@ mod tests { let _y_block_id = game.add_skill(y_team.id, y_cryp.id, None, Skill::Block).unwrap(); game.target_phase_start(); - // game.add_target(x_team.id, x_cryp.id, y_block_id).unwrap(); - // game.add_target(y_team.id, y_cryp.id, x_block_id).unwrap(); - // game.resolve_phase_start(); assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_some()); assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_some()); @@ -876,5 +875,4 @@ mod tests { assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false); println!("{:#?}", game.log); } - } diff --git a/server/src/skill.rs b/server/src/skill.rs index 1bbfad12..b20ef700 100755 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -1,10 +1,10 @@ -use rand::prelude::*; +use rand::{thread_rng, Rng}; use uuid::Uuid; -use game::{Log}; +// use game::{Log}; use cryp::{Cryp, CrypEffect}; -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Cast { pub id: Uuid, pub skill: Skill, @@ -12,7 +12,7 @@ pub struct Cast { pub source_cryp_id: Uuid, pub target_cryp_id: Option, pub target_team_id: Uuid, - pub resolution: Option, + pub resolution: Resolution, } impl Cast { @@ -30,12 +30,12 @@ impl Cast { target_cryp_id, target_team_id, skill, - resolution: None, + resolution: Resolution { base: 0, result: None, text: String::new() }, }; } - pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> &mut Cast { - self.resolution = Some(self.skill.resolve(cryp, target, log)); + pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp) -> &mut Cast { + self.resolution = self.skill.resolve(cryp, target); self } @@ -44,15 +44,16 @@ impl Cast { self } - pub fn used_cooldown(self) -> bool { + pub fn used_cooldown(&self) -> bool { return self.skill.cd().is_some(); } } -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Resolution { pub base: u64, pub result: Option, + pub text: String, } pub type Cooldown = Option; @@ -118,11 +119,11 @@ pub enum Skill { Paralyse, - // Strangle + Strangle, // physical dot and disable Stun, - Dodge, - Evasion, // additional layer of dmg avoidance + Evade, // actively evade + Evasion, // adds evasion to cryp // ----------------- @@ -194,11 +195,12 @@ impl Skill { Skill::Snare => Some(2), Skill::Paralyse => Some(3), + Skill::Strangle => Some(3), // Strangle Skill::Stun => Some(1), - Skill::Dodge => Some(2), + Skill::Evade => Some(2), Skill::Evasion => Some(3), // additional layer of dmg avoidance // ----------------- @@ -268,11 +270,12 @@ impl Skill { // Nature // ----------------- Skill::Block => 10, // reduce dmg - Skill::Dodge => 10, + Skill::Evade => 10, Skill::Parry => 10, // avoid all dmg Skill::Snare => 10, Skill::Paralyse => 5, + Skill::Strangle => 5, // Strangle @@ -338,11 +341,11 @@ impl Skill { } } - pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let mut rng = thread_rng(); let base: u64 = rng.gen(); - let mut res = Resolution { base, result: None }; + let mut res = Resolution { base, result: None, text: String::new() }; // println!("{:?}'s stats", self.name); // println!("{:064b} <- finalised", roll.result); @@ -355,21 +358,19 @@ impl Skill { // return Some(roll); match self { - Skill::Attack => { - target.hp.reduce(cryp.phys_dmg.value); - }, + Skill::Attack => attack(cryp, target, &mut res), // ----------------- // Nature // ----------------- - Skill::Block => block(cryp, target, log), - Skill::Dodge => panic!("nyi"), + Skill::Block => block(cryp, target, &mut res), + Skill::Evade => panic!("nyi"), // Skill::Parry => panic!("nyi"), // avoid all dmg Skill::Snare => panic!("nyi"), - Skill::Paralyse => panic!("nyi"), - // Strangle + Skill::Paralyse => panic!("nyi"), // no physical moves + Skill::Strangle => panic!("nyi"), // no physical moves - Skill::Stun => stun(cryp, target, log), + Skill::Stun => stun(cryp, target, &mut res), Skill::Evasion => panic!("nyi"), // additional layer of dmg avoidance // ----------------- @@ -384,7 +385,7 @@ impl Skill { // ----------------- // Preservation // ----------------- - Skill::Heal => panic!("nyi"), + Skill::Heal => heal(cryp, target, &mut res), Skill::Triage => panic!("nyi"), // hot Skill::Throw => panic!("nyi"), // no dmg stun, adds vulnerable Skill::Charm => panic!("nyi"), @@ -426,8 +427,8 @@ impl Skill { // Test // ----------------- Skill::TestTouch => (), - Skill::TestStun => stun(cryp, target, log), - Skill::TestBlock => block(cryp, target, log), + Skill::TestStun => stun(cryp, target, &mut res), + Skill::TestBlock => block(cryp, target, &mut res), }; return res; @@ -435,7 +436,7 @@ impl Skill { pub fn duration(&self) -> u8 { match self { - Skill::Dodge => 1, + Skill::Evade => 1, Skill::Stun => 2, Skill::Block => 1, @@ -461,20 +462,64 @@ impl Skill { } } -fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn attack(cryp: &mut Cryp, target: &mut Cryp, res: &mut Resolution) { + res.text = format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, cryp.phys_dmg); + target.hp.reduce(cryp.phys_dmg.value); +} + +fn stun(cryp: &mut Cryp, target: &mut Cryp, res: &mut Resolution) { if !target.effects.iter().any(|e| e.effect.prevents(Skill::Stun)) { let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration() }; target.effects.push(stun); - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration)); + res.text = format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration); } else { - log.push(format!("{:?} blocks.", target.name)); + res.text = format!("{:?} blocks.", target.name); } } -fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn block(_cryp: &mut Cryp, target: &mut Cryp, res: &mut Resolution) { let effect = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration() }; target.effects.push(effect); - log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration)); + res.text = format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration); +} + +fn heal(cryp: &mut Cryp, target: &mut Cryp, res: &mut Resolution) { + let new_hp = *[ + target.hp.value.saturating_add(cryp.spell_dmg.value), + target.stamina.value + ].iter().min().unwrap(); + + let healing = new_hp.saturating_sub(target.hp.value); + let overhealing = target.hp.value.saturating_add(cryp.phys_dmg.value).saturating_sub(target.stamina.value); + target.hp.value = new_hp; + res.text = format!("{:?} -> {:?} | Heal for {:?} ({:?}OH)", cryp.name, target.name, healing, overhealing); +} + +#[cfg(test)] +mod tests { + use skill::*; + + #[test] + fn heal_test() { + let mut x = Cryp::new() + .named(&"muji".to_string()) + .level(8) + .learn(Skill::Heal) + .create(); + + let mut y = Cryp::new() + .named(&"camel".to_string()) + .level(8) + .learn(Skill::Heal) + .create(); + + x.hp.reduce(5); + + let mut resolution = Resolution { base: 0, result: None, text: String::new() }; + heal(&mut y, &mut x, &mut resolution); + + println!("{:?}", resolution); + } } // #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]