diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 2d0007bb..72bbd25d 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -11,10 +11,6 @@ ## NOW combo specs -fix global matchmaking - -startup checks - scoreboard constants diff --git a/server/src/cryp.rs b/server/src/cryp.rs index f9957733..69ef1de7 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -100,7 +100,7 @@ impl CrypStat { // self.recalculate(specs) // } - pub fn recalculate(&mut self, specs: &Vec) -> &mut CrypStat { + pub fn recalculate(&mut self, specs: &Vec, team_colours: &Colours) -> &mut CrypStat { let specs = specs .iter() .filter(|s| s.affects().contains(&self.stat)) @@ -109,7 +109,7 @@ impl CrypStat { // applied with fold because it can be zeroed or multiplied // but still needs access to the base amount - let value = specs.iter().fold(self.base, |acc, s| s.apply(acc, self.base)); + let value = specs.iter().fold(self.base, |acc, s| s.apply(acc, self.base, team_colours)); self.value = value; self.max = value; @@ -149,6 +149,7 @@ pub struct Cryp { pub red_shield: CrypStat, pub blue_shield: CrypStat, pub blue_damage: CrypStat, + pub green_damage: CrypStat, pub speed: CrypStat, pub hp: CrypStat, pub evasion: CrypStat, @@ -170,8 +171,9 @@ impl Cryp { red_shield: CrypStat { base: 0, value: 0, max: 0, stat: Stat::RedShield }, blue_damage: CrypStat { base: 256, value: 256, max: 256, stat: Stat::BlueDamage }, blue_shield: CrypStat { base: 0, value: 0, max: 0, stat: Stat::BlueShield }, - speed: CrypStat { base: 128, value: 128, max: 128, stat: Stat::Speed }, + green_damage: CrypStat { base: 256, value: 256, max: 256, stat: Stat::GreenDamage }, hp: CrypStat { base: 1024, value: 1024, max: 1024, stat: Stat::Hp }, + speed: CrypStat { base: 128, value: 128, max: 128, stat: Stat::Speed }, evasion: CrypStat { base: 0, value: 0, max: 0, stat: Stat::Evasion }, skills: vec![], effects: vec![], @@ -200,15 +202,14 @@ impl Cryp { pub fn learn_mut(&mut self, s: Skill) -> &mut Cryp { self.skills.push(CrypSkill::new(s)); - self.colours = Colours::from_cryp(&self); - self + self.calculate_colours() } pub fn forget(&mut self, skill: Skill) -> Result<&mut Cryp, Error> { match self.skills.iter().position(|s| s.skill == skill) { Some(i) => { self.skills.remove(i); - return Ok(self); + return Ok(self.calculate_colours()); }, None => Err(format_err!("{:?} does not know {:?}", self.name, skill)), } @@ -216,7 +217,7 @@ impl Cryp { pub fn spec_add(&mut self, spec: Spec) -> Result<&mut Cryp, Error> { self.specs.push(spec); - return Ok(self.recalculate_stats()); + return Ok(self.calculate_colours()); } pub fn spec_remove(&mut self, spec: Spec) -> Result<&mut Cryp, Error> { @@ -225,23 +226,25 @@ impl Cryp { None => return Err(err_msg("spec not found")), }; - Ok(self.recalculate_stats()) + Ok(self.calculate_colours()) } + fn calculate_colours(&mut self) -> &mut Cryp { + self.colours = Colours::from_cryp(&self); + self + } - fn recalculate_stats(&mut self) -> &mut Cryp { + pub fn apply_modifiers(&mut self, team_colours: &Colours) -> &mut Cryp { self.specs.sort_unstable(); - // recalculate the colours for the spec bonuses - self.colours = Colours::from_cryp(&self); - - self.red_damage.recalculate(&self.specs); - self.red_shield.recalculate(&self.specs); - self.blue_damage.recalculate(&self.specs); - self.blue_shield.recalculate(&self.specs); - self.evasion.recalculate(&self.specs); - self.speed.recalculate(&self.specs); - self.hp.recalculate(&self.specs); + self.red_damage.recalculate(&self.specs, team_colours); + self.red_shield.recalculate(&self.specs, team_colours); + self.blue_damage.recalculate(&self.specs, team_colours); + self.blue_shield.recalculate(&self.specs, team_colours); + self.evasion.recalculate(&self.specs, team_colours); + self.speed.recalculate(&self.specs, team_colours); + self.green_damage.recalculate(&self.specs, team_colours); + self.hp.recalculate(&self.specs, team_colours); self } @@ -393,6 +396,17 @@ impl Cryp { return modified_blue_damage; } + pub fn green_damage(&self) -> u64 { + let green_damage_mods = self.effects.iter() + .filter(|e| e.effect.modifications().contains(&Stat::GreenDamage)) + .map(|cryp_effect| cryp_effect.effect) + .collect::>(); + + let modified_green_damage = green_damage_mods.iter().fold(self.green_damage.value, |acc, m| m.apply(acc)); + return modified_green_damage; + } + + pub fn skill_speed(&self, s: Skill) -> u64 { self.speed().saturating_mul(s.speed() as u64) } @@ -648,7 +662,7 @@ pub fn cryp_recover(cryp_bytes: Vec, tx: &mut Transaction) -> Result R } fn heal(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { - let amount = cryp.blue_damage(); + let amount = cryp.green_damage(); resolution.results.push(target.heal(Skill::Heal, amount)); return resolution; } diff --git a/server/src/spec.rs b/server/src/spec.rs index fccec9e4..c0960df4 100644 --- a/server/src/spec.rs +++ b/server/src/spec.rs @@ -1,6 +1,6 @@ use rand::prelude::*; -use cryp::{Stat}; +use cryp::{Stat, Colours}; #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] pub enum Spec { @@ -20,6 +20,16 @@ pub enum Spec { BlueDamageI, } +pub trait IntPct { + fn pct(self, pct: u64) -> u64; +} + +impl IntPct for u64 { + fn pct(self, pct: u64) -> u64 { + self * pct / 100 + } +} + impl Spec { pub fn affects(&self) -> Vec { match *self { @@ -39,25 +49,40 @@ impl Spec { } } - pub fn apply(&self, modified: u64, base: u64) -> u64 { + pub fn apply(&self, modified: u64, base: u64, team_colours: &Colours) -> u64 { let mut rng = thread_rng(); let i_min = 32; let i_max = 64; match *self { - Spec::RedDamageI => modified + (base * 5 / 100), - Spec::GreenDamageI => modified + (base * 5 / 100), - Spec::BlueDamageI => modified + (base * 5 / 100), + Spec::RedDamageI => modified + match team_colours.red { + 0...5 => base.pct(5), + 6...10 => base.pct(10), + 11...15 => base.pct(15), + _ => base.pct(20) + }, + Spec::GreenDamageI => modified + match team_colours.green { + 0...5 => base.pct(5), + 6...10 => base.pct(10), + 11...15 => base.pct(15), + _ => base.pct(20) + }, + Spec::BlueDamageI => modified + match team_colours.blue { + 0...5 => base.pct(5), + 6...10 => base.pct(10), + 11...15 => base.pct(15), + _ => base.pct(20) + }, - Spec::SpeedI => modified + (base * 5 / 100), + Spec::SpeedI => modified + base.pct(5), - Spec::LifeI => modified + (base * 5 / 100), + Spec::LifeI => modified + base.pct(5), Spec::RedShieldI => modified + rng.gen_range(i_min, i_max), Spec::BlueShieldI => modified + rng.gen_range(i_min, i_max), - Spec::LRSI => modified + (base * 5 / 100), - Spec::LBSI => modified + (base * 5 / 100), - Spec::RBSI => modified + (base * 5 / 100), + Spec::LRSI => modified + base.pct(5), + Spec::LBSI => modified + base.pct(5), + Spec::RBSI => modified + base.pct(5), } } diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 8e0eaecc..be4bc528 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -516,6 +516,20 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou None => return Err(err_msg("var has no effect on cryps")), } + // now the var has been applied + // recalculate the stats of the whole team + let team_colours = player.cryps.iter().fold(Colours::new(), |tc, c| { + Colours { + red: tc.red + c.colours.red, + green: tc.green + c.colours.green, + blue: tc.blue + c.colours.blue + } + }); + + for cryp in player.cryps.iter_mut() { + cryp.apply_modifiers(&team_colours); + } + return player_update(tx, player, false); }