diff --git a/server/WORKLOG.md b/server/WORKLOG.md index da7dd6b2..f0e32ed4 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -9,19 +9,18 @@ # WORK WORK ## NOW - +be able to reclaim skills / specs from cryp combo specs - -standardise cryps randomise skill speed -generate svgs - scoreboard constants round system for games + join instance + is pve? + add cryps to player level bots every round buy out vbox find any combos diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 7cf905e2..5fcfc49c 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -10,8 +10,8 @@ use failure::err_msg; use account::{Account}; use rpc::{CrypSpawnParams, CrypLearnParams, CrypForgetParams, CrypUnspecParams}; use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, ResolutionResult}; +use spec::{Spec}; use game::{Log}; -use vbox::{Var}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct CrypSkill { @@ -64,17 +64,17 @@ pub struct CrypStat { } impl CrypStat { - pub fn set(&mut self, v: u64, specs: &Vec) -> &mut CrypStat { + pub fn set(&mut self, v: u64, specs: &Vec) -> &mut CrypStat { self.base = v; self.recalculate(specs) } - pub fn recalculate(&mut self, specs: &Vec) -> &mut CrypStat { + pub fn recalculate(&mut self, specs: &Vec) -> &mut CrypStat { let specs = specs .iter() .filter(|s| s.affects().contains(&self.stat)) .map(|s| *s) - .collect::>(); + .collect::>(); // applied with fold because it can be zeroed or multiplied // but still needs access to the base amount @@ -127,7 +127,7 @@ pub struct Cryp { pub lvl: u8, pub skills: Vec, pub effects: Vec, - pub specs: Vec, + pub specs: Vec, pub name: String, pub ko_logged: bool, } @@ -250,20 +250,18 @@ impl Cryp { self } - pub fn spec_add(&mut self, spec: Var) -> Result<&mut Cryp, Error> { + pub fn spec_add(&mut self, spec: Spec) -> Result<&mut Cryp, Error> { self.specs.push(spec); return Ok(self.recalculate_stats()); } - pub fn spec_remove(&mut self, spec: Var) -> Result { - let spec = match self.specs.iter().position(|s| *s == spec) { + pub fn spec_remove(&mut self, spec: Spec) -> Result<&mut Cryp, Error> { + match self.specs.iter().position(|s| *s == spec) { Some(p) => self.specs.remove(p), None => return Err(err_msg("spec not found")), }; - self.recalculate_stats(); - - Ok(spec) + Ok(self.recalculate_stats()) } @@ -625,6 +623,7 @@ pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result Result { let cryp = Cryp::new() .named(¶ms.name) + .learn(Skill::Attack) .level(1) .set_account(account.id) .create(); @@ -647,6 +646,25 @@ pub fn cryp_spawn(params: CrypSpawnParams, tx: &mut Transaction, account: &Accou return Ok(cryp); } +pub fn cryp_learn(params: CrypLearnParams, tx: &mut Transaction, account: &Account) -> Result { + let mut cryp = cryp_get(tx, params.id, account.id)?; + + // done here because i teach them a tonne of skills for tests + let max_skills = 4; + if cryp.skills.len() >= max_skills { + return Err(format_err!("cryp at max skills ({:?})", max_skills)); + } + + cryp = cryp.learn(params.skill); + return cryp_write(cryp, tx); +} + +pub fn cryp_forget(params: CrypForgetParams, tx: &mut Transaction, account: &Account) -> Result { + let mut cryp = cryp_get(tx, params.id, account.id)?; + cryp = cryp.forget(params.skill)?; + return cryp_write(cryp, tx); +} + pub fn cryp_unspec(params: CrypUnspecParams, tx: &mut Transaction, account: &Account) -> Result { let mut cryp = cryp_get(tx, params.id, account.id)?; cryp.spec_remove(params.spec)?; diff --git a/server/src/main.rs b/server/src/main.rs index e8ce946d..9b43995c 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -22,6 +22,7 @@ mod cryp; mod game; mod net; mod skill; +mod spec; // mod passives; mod rpc; mod account; diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 8561814e..a48a188a 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -20,9 +20,10 @@ use game::{Game, game_state, game_pve, game_skill}; use account::{Account, account_create, account_login, account_from_token, account_cryps, account_players}; use skill::{Skill}; // use zone::{Zone, zone_create, zone_join, zone_close}; +use spec::{Spec}; use player::{player_state, player_cryps_set, Player}; use instance::{instance_join, instance_ready}; -use vbox::{Var, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim}; +use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim}; pub struct Rpc; @@ -432,7 +433,7 @@ struct CrypForgetMsg { #[derive(Debug,Clone,Serialize,Deserialize)] pub struct CrypUnspecParams { pub id: Uuid, - pub spec: Var, + pub spec: Spec, } #[derive(Debug,Clone,Serialize,Deserialize)] diff --git a/server/src/spec.rs b/server/src/spec.rs new file mode 100644 index 00000000..fccec9e4 --- /dev/null +++ b/server/src/spec.rs @@ -0,0 +1,64 @@ +use rand::prelude::*; + +use cryp::{Stat}; + +#[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] +pub enum Spec { + SpeedI, + + // Pure redShield has to come first as it applies the base amount + // that is multiplied + LifeI, + RedShieldI, + BlueShieldI, + LRSI, + LBSI, + RBSI, + + RedDamageI, + GreenDamageI, + BlueDamageI, +} + +impl Spec { + pub fn affects(&self) -> Vec { + match *self { + Spec::RedDamageI => vec![Stat::RedDamage], + Spec::GreenDamageI => vec![Stat::GreenDamage], + Spec::BlueDamageI => vec![Stat::BlueDamage], + + Spec::SpeedI => vec![Stat::Speed], + + Spec::RedShieldI => vec![Stat::RedShield], + Spec::BlueShieldI => vec![Stat::BlueShield], + Spec::LifeI => vec![Stat::Hp], + Spec::LRSI => vec![Stat::Hp, Stat::RedShield], + Spec::LBSI => vec![Stat::Hp, Stat::BlueShield], + Spec::RBSI => vec![Stat::BlueShield, Stat::RedShield], + + } + } + + pub fn apply(&self, modified: u64, base: u64) -> 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::SpeedI => modified + (base * 5 / 100), + + Spec::LifeI => modified + (base * 5 / 100), + 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), + } + } + +} diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 93d0a936..b3a9ffa2 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -14,8 +14,8 @@ use failure::err_msg; use account::Account; use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxReclaimParams}; use skill::{Skill}; +use spec::{Spec}; use player::{Player, player_get, player_update}; -use cryp::{Stat}; #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] pub enum Var { @@ -110,7 +110,7 @@ impl Var { if let Some(_skill) = self.skill() { return Some(VarEffect::Skill); } - if self.spec() { + if let Some(_spec) = self.spec() { return Some(VarEffect::Spec); } return None; @@ -147,63 +147,22 @@ impl Var { } } - fn spec(&self) -> bool { + fn spec(&self) -> Option { match *self { - Var::Speed => true, + Var::Speed => Some(Spec::SpeedI), - Var::RedDamageI => true, - Var::BlueDamageI => true, - Var::GreenDamageI => true, + Var::RedDamageI => Some(Spec::RedDamageI), + Var::BlueDamageI => Some(Spec::BlueDamageI), + Var::GreenDamageI => Some(Spec::GreenDamageI), - Var::LifeI => true, - Var::LRSI => true, - Var::LBSI => true, - Var::RBSI => true, - Var::RedShieldI => true, - Var::BlueShieldI => true, + Var::LifeI => Some(Spec::LifeI), + Var::LRSI => Some(Spec::LRSI), + Var::LBSI => Some(Spec::LBSI), + Var::RBSI => Some(Spec::RBSI), + Var::RedShieldI => Some(Spec::RedShieldI), + Var::BlueShieldI => Some(Spec::BlueShieldI), - _ => false, - } - } - - pub fn affects(&self) -> Vec { - match self { - Var::RedDamageI => vec![Stat::RedDamage], - Var::GreenDamageI => vec![Stat::GreenDamage], - Var::BlueDamageI => vec![Stat::BlueDamage], - - Var::Speed => vec![Stat::Speed], - - Var::RedShieldI => vec![Stat::RedShield], - Var::BlueShieldI => vec![Stat::BlueShield], - Var::LifeI => vec![Stat::Hp], - Var::LRSI => vec![Stat::Hp, Stat::RedShield], - Var::LBSI => vec![Stat::Hp, Stat::BlueShield], - Var::RBSI => vec![Stat::BlueShield, Stat::RedShield], - _ => panic!("{:?} is not a spec item", self), - } - } - - pub fn apply(&self, modified: u64, base: u64) -> u64 { - let mut rng = thread_rng(); - - let i_min = 32; - let i_max = 64; - - match self { - Var::RedDamageI => modified + (base * 5 / 100), - Var::GreenDamageI => modified + (base * 5 / 100), - Var::BlueDamageI => modified + (base * 5 / 100), - - Var::Speed => modified + (base * 5 / 100), - - Var::LifeI => modified + (base * 5 / 100), - Var::RedShieldI => modified + rng.gen_range(i_min, i_max), - Var::BlueShieldI => modified + rng.gen_range(i_min, i_max), - Var::LRSI => modified + (base * 5 / 100), - Var::LBSI => modified + (base * 5 / 100), - Var::RBSI => modified + (base * 5 / 100), - _ => panic!("{:?} is not a spec item", self), + _ => None, } } } @@ -466,8 +425,9 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou cryp.learn_mut(skill); }, Some(VarEffect::Spec) => { + let spec = var.spec().ok_or(format_err!("var {:?} has no associated spec", var))?; let cryp = player.cryp_get(params.cryp_id)?; - cryp.spec_add(var)?; + cryp.spec_add(spec)?; }, None => return Err(err_msg("var has no effect on cryps")),