diff --git a/client/src/scenes/statsheet.js b/client/src/scenes/statsheet.js index 7ce92ee8..a34fbcc1 100644 --- a/client/src/scenes/statsheet.js +++ b/client/src/scenes/statsheet.js @@ -52,10 +52,16 @@ class StatSheet extends Phaser.Scene { create(cryp) { this.registry.events.on('changedata', this.updateData, this); + const ws = this.registry.get('ws'); + + const player = this.registry.get('player'); + if (!player) return false; + const { vbox } = player; + this.cryp = cryp; const del = this.add.existing(new DeleteHitBox(this, X + WIDTH * 0.7, Y + HEIGHT * 0.6)); - this.add.text(del.getCenter().x, del.getCenter().y, 'Unlearn', TEXT.HEADER) + this.add.text(del.getCenter().x, del.getCenter().y, 'unequip', TEXT.HEADER) .setOrigin(0.5, 0.5); this.add.text(X, Y, cryp.name, TEXT.HEADER); @@ -116,7 +122,7 @@ class StatSheet extends Phaser.Scene { if (hitBox) { hitBox.itemDeselect(); // add socket function for unlearn here - console.log(`delete: ${item.item}`); + ws.sendVboxUnequip(vbox.instance, cryp.id, item.item); } return true; }); diff --git a/client/src/socket.js b/client/src/socket.js index 1f49f710..b2ec0ad9 100644 --- a/client/src/socket.js +++ b/client/src/socket.js @@ -101,6 +101,10 @@ function createSocket(events) { send({ method: 'player_vbox_apply', params: { instance_id: instanceId, cryp_id: crypId, index } }); } + function sendVboxUnequip(instanceId, crypId, target) { + send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, cryp_id: crypId, target } }); + } + function sendVboxDiscard(instanceId) { send({ method: 'player_vbox_discard', params: { instance_id: instanceId } }); } @@ -311,6 +315,7 @@ function createSocket(events) { sendVboxReclaim, sendVboxCombine, sendVboxDiscard, + sendVboxUnequip, connect, }; } diff --git a/server/src/account.rs b/server/src/account.rs index 4b10d6fe..02d3cdce 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -9,10 +9,7 @@ use postgres::transaction::Transaction; use rpc::{AccountCreateParams, AccountLoginParams}; -use cryp::{Cryp, CrypRecover, cryp_write, cryp_recover}; -use game::Game; -// use zone::{Zone, zone_delete}; -use skill::{Skill}; +use cryp::{Cryp, cryp_recover}; use player::{Player, player_delete}; use failure::Error; @@ -180,61 +177,6 @@ pub fn account_cryps(tx: &mut Transaction, account: &Account) -> Result Result, Error> { - let query = " - SELECT games.data - FROM players join games - ON (players.game = games.id) - WHERE account = $1; - "; - - let result = tx - .query(query, &[&account.id])?; - - let games: Result, _> = result.iter().map(|row| { - let cryp_bytes: Vec = row.get(0); - from_slice::(&cryp_bytes) - }).collect(); - - // catch any errors - if games.is_err() { - return Err(err_msg("could not deserialize a game")); - } - - // now unwrap is safe - return Ok(games.unwrap()); - -} - -// pub fn account_zone(tx: &mut Transaction, account: &Account) -> Result { -// let query = " -// SELECT * -// FROM zones -// WHERE account = $1 -// AND active = true; -// "; - -// let result = tx -// .query(query, &[&account.id])?; - -// let returned = match result.iter().next() { -// Some(row) => row, -// None => return Err(err_msg("no active zone")), -// }; - -// // tells from_slice to cast into a cryp -// let bytes: Vec = returned.get("data"); -// let zone = match from_slice::(&bytes) { -// Ok(z) => z, -// Err(_) => { -// zone_delete(tx, returned.get("id"))?; -// return Err(err_msg("invalid zone removed")) -// }, -// }; - -// return Ok(zone); -// } - pub fn account_players(tx: &mut Transaction, account: &Account) -> Result, Error> { let query = " SELECT data, id diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 5fcfc49c..70c130ff 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -8,7 +8,7 @@ use failure::Error; use failure::err_msg; use account::{Account}; -use rpc::{CrypSpawnParams, CrypLearnParams, CrypForgetParams, CrypUnspecParams}; +use rpc::{CrypSpawnParams}; use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, ResolutionResult}; use spec::{Spec}; use game::{Log}; @@ -185,7 +185,7 @@ impl Cryp { self } - pub fn forget(mut self, skill: Skill) -> Result { + 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); @@ -623,7 +623,6 @@ 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(); @@ -646,31 +645,6 @@ 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)?; - return cryp_write(cryp, tx); -} - pub fn cryp_write(cryp: Cryp, tx: &mut Transaction) -> Result { let cryp_bytes = to_vec(&cryp)?; diff --git a/server/src/game.rs b/server/src/game.rs index 87d1a741..fbd48d11 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -134,10 +134,6 @@ impl Game { self } - fn already_joined(&self, team_id: Uuid) -> bool { - self.teams.iter().any(|t| t.id == team_id) - } - pub fn team_add(&mut self, team: Team) -> Result<&mut Game, Error> { if self.teams.len() == self.team_num { return Err(err_msg("maximum number of teams")); diff --git a/server/src/player.rs b/server/src/player.rs index 898a8d3c..cc683790 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -11,7 +11,7 @@ use account::Account; use cryp::{Cryp, cryp_get}; use vbox::{Vbox}; use rpc::{PlayerStateParams, PlayerCrypsSetParams}; -use instance::{Instance, instance_get, instance_update}; +use instance::{instance_get, instance_update}; #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Score { diff --git a/server/src/rpc.rs b/server/src/rpc.rs index a48a188a..cb9f0eb3 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -23,7 +23,7 @@ use skill::{Skill}; use spec::{Spec}; use player::{player_state, player_cryps_set, Player}; use instance::{instance_join, instance_ready}; -use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim}; +use vbox::{Var, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip}; pub struct Rpc; @@ -84,9 +84,10 @@ impl Rpc { "player_cryps_set" => Rpc::player_cryps_set(data, &mut tx, account.unwrap(), client), "player_vbox_accept" => Rpc::player_vbox_accept(data, &mut tx, account.unwrap(), client), "player_vbox_apply" => Rpc::player_vbox_apply(data, &mut tx, account.unwrap(), client), - "player_vbox_reclaim" => Rpc::player_vbox_reclaim(data, &mut tx, account.unwrap(), client), "player_vbox_combine" => Rpc::player_vbox_combine(data, &mut tx, account.unwrap(), client), "player_vbox_discard" => Rpc::player_vbox_discard(data, &mut tx, account.unwrap(), client), + "player_vbox_reclaim" => Rpc::player_vbox_reclaim(data, &mut tx, account.unwrap(), client), + "player_vbox_unequip" => Rpc::player_vbox_unequip(data, &mut tx, account.unwrap(), client), _ => Err(format_err!("unknown method - {:?}", v.method)), }; @@ -365,6 +366,23 @@ impl Rpc { return Ok(response); } + fn player_vbox_unequip(data: Vec, tx: &mut Transaction, account: Account, client: &mut WebSocket) -> Result { + let msg = from_slice::(&data).or(Err(err_msg("invalid params")))?; + + let response = RpcResponse { + method: "player_state".to_string(), + params: RpcResult::PlayerState(vbox_unequip(msg.params, tx, &account)?) + }; + + Rpc::send_msg(client, RpcResponse { + method: "account_cryps".to_string(), + params: RpcResult::CrypList(account_cryps(tx, &account)?) + })?; + + return Ok(response); + } + + } #[derive(Debug,Clone,Serialize,Deserialize)] @@ -632,6 +650,19 @@ pub struct VboxApplyParams { pub index: usize, } +#[derive(Debug,Clone,Serialize,Deserialize)] +struct VboxUnequipMsg { + method: String, + params: VboxUnequipParams, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct VboxUnequipParams { + pub instance_id: Uuid, + pub cryp_id: Uuid, + pub target: Var, +} + #[derive(Debug,Clone,Serialize,Deserialize)] struct VboxReclaimMsg { method: String, diff --git a/server/src/skill.rs b/server/src/skill.rs index 08c4e29c..a106c217 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -46,12 +46,6 @@ pub struct Immunity { pub effects: Vec } -impl Immunity { - fn new() -> Immunity { - Immunity { immune: false, effects: vec![] } - } -} - #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Disable { pub disabled: bool, @@ -322,23 +316,11 @@ pub enum Skill { Parry, // avoid all damage Snare, - Paralyse, - Strangle, // physical dot and disable Strike, Stun, // Evade, // actively evade - - // ----------------- - // Technology - // ----------------- - Replicate, - Swarm, - Orbit, - Repair, - Scan, // track? - // ----------------- // Nonviolence // ----------------- @@ -346,9 +328,6 @@ pub enum Skill { Triage, // hot TriageTick, Throw, // no damage stun, adds vulnerable - Charm, - Calm, - Rez, // Sleep, // Nightmare, @@ -363,29 +342,21 @@ pub enum Skill { Siphon, SiphonTick, Curse, - Plague, // aoe dot - Ruin, // aoe // ----------------- // Purity // ----------------- Empower, - Slay, Shield, Silence, - Inquiry, Purify, Purge, - // Precision, // ----------------- // Chaos // ----------------- Banish, Hex, - Fear, - Taunt, - Pause, // speed slow Haste, Slow, @@ -410,21 +381,13 @@ impl Skill { Skill::Parry => None, // avoid all damage Skill::Snare => Some(1), - Skill::Paralyse => Some(1), - Skill::Strangle => Some(2), - // Strangle Skill::Stun => Some(1), // ----------------- // Technology // ----------------- - Skill::Replicate => None, - Skill::Swarm => Some(2), - Skill::Orbit => Some(1), - Skill::Repair => None, - Skill::Scan => Some(1), // track? // ----------------- // Preservation @@ -433,9 +396,6 @@ impl Skill { Skill::Triage => None, // hot Skill::TriageTick => None, Skill::Throw => Some(1), // no damage stun, adds vulnerable - Skill::Charm => Some(1), - Skill::Calm => None, - Skill::Rez => Some(2), // ----------------- // Destruction @@ -447,18 +407,13 @@ impl Skill { Skill::Siphon => Some(1), Skill::SiphonTick => None, Skill::Curse => Some(1), - Skill::Plague => Some(1), // aoe dot - Skill::Ruin => Some(2), // aoe // ----------------- // Purity // ----------------- - // Skill::Precision => None, Skill::Empower => Some(1), - Skill::Slay => None, Skill::Shield => None, Skill::Silence => Some(1), - Skill::Inquiry => Some(1), Skill::Purify => None, Skill::Purge => None, @@ -467,9 +422,6 @@ impl Skill { // ----------------- Skill::Banish => Some(1), Skill::Hex => None, - Skill::Fear => None, - Skill::Taunt => Some(1), - Skill::Pause => Some(1), // speed slow Skill::Haste => None, Skill::Slow => None, @@ -496,21 +448,13 @@ impl Skill { Skill::Parry => Category::Red, // avoid all damage Skill::Snare => Category::Red, - Skill::Paralyse => Category::Red, - Skill::Strangle => Category::Red, - // Strangle Skill::Stun => Category::Red, // ----------------- // Technology // ----------------- - Skill::Replicate => Category::Red, - Skill::Swarm => Category::Red, - Skill::Orbit => Category::Red, - Skill::Repair => Category::Red, - Skill::Scan => Category::Red, // track? // ----------------- // Preservation @@ -519,9 +463,6 @@ impl Skill { Skill::Triage => Category::Blue, // hot Skill::TriageTick => Category::BlueTick, // hot Skill::Throw => Category::Red, // no damage stun, adds vulnerable - Skill::Charm => Category::Blue, - Skill::Calm => Category::Red, - Skill::Rez => Category::Blue, // ----------------- // Destruction @@ -533,18 +474,13 @@ impl Skill { Skill::Siphon => Category::Blue, Skill::SiphonTick => Category::BlueTick, // hot Skill::Curse => Category::Blue, - Skill::Plague => Category::Blue, // aoe dot - Skill::Ruin => Category::Blue, // aoe // ----------------- // Purity // ----------------- - // Skill::Precision => 1, Skill::Empower => Category::Red, - Skill::Slay => Category::Red, Skill::Shield => Category::Blue, Skill::Silence => Category::Blue, - Skill::Inquiry => Category::Blue, Skill::Purify => Category::Blue, Skill::Purge => Category::Blue, @@ -553,9 +489,6 @@ impl Skill { // ----------------- Skill::Banish => Category::Blue, Skill::Hex => Category::Blue, - Skill::Fear => Category::Blue, - Skill::Taunt => Category::Blue, - Skill::Pause => Category::Blue, // extend durations // Skill::Lag => 2, // Skill::Haste => Category::Blue, Skill::Slow => Category::Blue, @@ -593,8 +526,6 @@ impl Skill { // fast phys combat Skill::Attack => 5, Skill::Strike => 10, - Skill::Paralyse => 5, - Skill::Strangle => 5, Skill::Banish => 5, Skill::Blast => 5, Skill::Decay => 5, // dot @@ -602,7 +533,6 @@ impl Skill { // magic combat trickery Skill::Triage => 3, // hot Skill::Slow => 3, - Skill::Fear => 2, Skill::Amplify => 3, Skill::Curse => 3, Skill::Empower => 3, @@ -613,8 +543,6 @@ impl Skill { Skill::Siphon => 2, Skill::SiphonTick => 2, // hot Skill::Hex => 2, - Skill::Pause => 2, // extend durations - Skill::Plague => 2, // aoe dot Skill::Silence => 2, Skill::Stun => 2, Skill::Throw => 2, // no damage stun, adds vulnerable @@ -625,20 +553,7 @@ impl Skill { Skill::Purge => 1, // unimplemented - // Skill::Precision => 1, // Skill::Lag => 2, // - Skill::Taunt => 10, - Skill::Ruin => 3, // aoe - Skill::Slay => 1, - Skill::Charm => 2, - Skill::Calm => 2, - Skill::Inquiry => 2, - Skill::Rez => 4, - Skill::Replicate => 1, - Skill::Swarm => 3, - Skill::Orbit => 2, - Skill::Repair => 1, - Skill::Scan => 2, // track? // ----------------- // Test @@ -687,19 +602,12 @@ impl Skill { Skill::Parry => parry(source, target, resolution), Skill::Snare => snare(source, target, resolution), // TODO prevent physical moves - Skill::Paralyse => panic!("nyi"), // no physical moves - Skill::Strangle => panic!("nyi"), // no physical moves Skill::Stun => stun(source, target, resolution), // ----------------- // Technology // ----------------- - Skill::Replicate => panic!("nyi"), - Skill::Swarm => panic!("nyi"), - Skill::Orbit => panic!("nyi"), - Skill::Repair => panic!("nyi"), - Skill::Scan => panic!("nyi"), // track? // ----------------- // Preservation @@ -708,9 +616,6 @@ impl Skill { Skill::Triage => triage(source, target, resolution), // hot Skill::TriageTick => triage_tick(source, target, resolution), // hot Skill::Throw => throw(source, target, resolution), // no damage stun, adds vulnerable - Skill::Charm => panic!("nyi"), // target casts random spell on teammate - Skill::Calm => panic!("nyi"), // physical fear, taunt removal - Skill::Rez => panic!("nyi"), // ----------------- // Destruction @@ -722,18 +627,13 @@ impl Skill { Skill::Siphon => siphon(source, target, resolution), Skill::SiphonTick => siphon_tick(source, target, resolution), // hot Skill::Curse => curse(source, target, resolution), - Skill::Plague => panic!("nyi"), // dot that spreads every turn - Skill::Ruin => panic!("nyi"), // aoe version of blast // ----------------- // Purity // ----------------- - // Skill::Precision => panic!("nyi"), Skill::Empower => empower(source, target, resolution), // increased phys damage - Skill::Slay => panic!("nyi"), // phys damage mult by target magic damage Skill::Shield => shield(source, target, resolution), // target is immune to magic damage and fx Skill::Silence => silence(source, target, resolution), // target cannot cast spells - Skill::Inquiry => panic!("nyi"), // Skill::Purify => purify(source, target, resolution), // dispel all debuffs Skill::Purge => purge(source, target, resolution), // dispel all buffs @@ -742,9 +642,6 @@ impl Skill { // ----------------- Skill::Banish => banish(source, target, resolution), // TODO prevent all actions Skill::Hex => hex(source, target, resolution), // todo prevent casting - Skill::Fear => panic!("nyi"), // cast random spell on self - Skill::Taunt => panic!("nyi"), // target forced to attack - Skill::Pause => panic!("nyi"), // speed slow Skill::Haste => haste(source, target, resolution), // speed slow Skill::Slow => slow(source, target, resolution), // speed slow @@ -775,7 +672,6 @@ impl Skill { Skill::Triage | Skill::Empower | Skill::Purify | - Skill::Calm | Skill::Parry | Skill::Block => true, _ => false, @@ -935,7 +831,7 @@ fn siphon_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) - resolution.results.push(siphon_damage.clone()); match siphon_damage { - ResolutionResult::Damage { amount, mitigation, category: _, immunity } => { + ResolutionResult::Damage { amount, mitigation: _, category: _, immunity } => { if !immunity.immune { resolution.results.push(cryp.heal(Skill::Heal, amount)); } @@ -997,7 +893,7 @@ fn banish(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Re } fn strike(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { - let amount = cryp.red_damage(); + let _amount = cryp.red_damage(); resolution.results.push(target.deal_red_damage(Skill::Attack, u64::max_value())); return resolution; } @@ -1149,3 +1045,93 @@ mod tests { assert!(!x.effects.iter().any(|e| e.effect == Effect::Decay)); } } + + + + + + +// pub enum Skill { +// Attack, + +// // ----------------- +// // Nature +// // ----------------- +// Block, // reduce damage +// Parry, // avoid all damage +// Snare, + +// Paralyse, + +// Strangle, // physical dot and disable +// Strike, +// Stun, +// // Evade, // actively evade + + +// // ----------------- +// // Technology +// // ----------------- +// Replicate, +// Swarm, +// Orbit, +// Repair, +// Scan, // track? + +// // ----------------- +// // Nonviolence +// // ----------------- +// Heal, +// Triage, // hot +// TriageTick, +// Throw, // no damage stun, adds vulnerable +// Charm, +// Calm, +// Rez, + +// // Sleep, +// // Nightmare, + +// // ------------------- +// // Destruction +// // ------------------- +// Blast, +// Amplify, +// Decay, // dot +// DecayTick, // dot +// Siphon, +// SiphonTick, +// Curse, +// Plague, // aoe dot +// Ruin, // aoe + +// // ----------------- +// // Purity +// // ----------------- +// Empower, +// Slay, +// Shield, +// Silence, +// Inquiry, +// Purify, +// Purge, +// // Precision, + +// // ----------------- +// // Chaos +// // ----------------- +// Banish, +// Hex, +// Fear, +// Taunt, +// Pause, // speed slow +// Haste, +// Slow, + +// // used by tests, no cd, no damage +// TestTouch, +// TestStun, +// TestBlock, +// TestParry, +// TestSiphon, +// } diff --git a/server/src/vbox.rs b/server/src/vbox.rs index b3a9ffa2..1f7251d0 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -12,7 +12,7 @@ use failure::Error; use failure::err_msg; use account::Account; -use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxReclaimParams}; +use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxReclaimParams, VboxUnequipParams}; use skill::{Skill}; use spec::{Spec}; use player::{Player, player_get, player_update}; @@ -107,17 +107,18 @@ impl Var { } fn effect(&self) -> Option { - if let Some(_skill) = self.skill() { + if let Some(_skill) = self.into_skill() { return Some(VarEffect::Skill); } - if let Some(_spec) = self.spec() { + if let Some(_spec) = self.into_spec() { return Some(VarEffect::Spec); } return None; } - fn skill(&self) -> Option { + fn into_skill(&self) -> Option { match self { + Var::Attack => Some(Skill::Attack), Var::Amplify => Some(Skill::Amplify), Var::Banish => Some(Skill::Banish), Var::Blast => Some(Skill::Blast), @@ -130,13 +131,13 @@ impl Var { Var::Purge => Some(Skill::Purge), Var::Purify => Some(Skill::Purify), // Var::Reflect => Some(Skill::Reflect), - Var::Ruin => Some(Skill::Ruin), + // Var::Ruin => Some(Skill::Ruin), Var::Shield => Some(Skill::Shield), Var::Silence => Some(Skill::Silence), - Var::Slay => Some(Skill::Slay), + // Var::Slay => Some(Skill::Slay), Var::Slow => Some(Skill::Slow), Var::Snare => Some(Skill::Snare), - Var::Strangle => Some(Skill::Strangle), + // Var::Strangle => Some(Skill::Strangle), Var::Strike => Some(Skill::Strike), // Var::Clutch => Some(Skill::Clutch), // Var::Taunt => Some(Skill::Taunt), @@ -147,7 +148,7 @@ impl Var { } } - fn spec(&self) -> Option { + fn into_spec(&self) -> Option { match *self { Var::Speed => Some(Spec::SpeedI), @@ -167,6 +168,56 @@ impl Var { } } +impl From for Var { + fn from(skill: Skill) -> Var { + match skill { + Skill::Amplify => Var::Amplify, + Skill::Attack => Var::Attack, + Skill::Banish => Var::Banish, + Skill::Blast => Var::Blast, + Skill::Block => Var::Block, + Skill::Curse => Var::Curse, + Skill::Empower => Var::Empower, + Skill::Haste => Var::Haste, + Skill::Heal => Var::Heal, + Skill::Hex => Var::Hex, + Skill::Parry => Var::Parry, + Skill::Purge => Var::Purge, + Skill::Purify => Var::Purify, + Skill::Shield => Var::Shield, + Skill::Silence => Var::Silence, + Skill::Siphon => Var::Siphon, + Skill::Slow => Var::Slow, + Skill::Snare => Var::Snare, + Skill::Strike => Var::Strike, + Skill::Stun => Var::Stun, + Skill::Throw => Var::Throw, + Skill::Triage => Var::Triage, + _ => panic!("{:?} not implemented as a var", skill), + } + } +} + +impl From for Var { + fn from(spec: Spec) -> Var { + match spec { + Spec::SpeedI => Var::Speed, + + Spec::RedDamageI => Var::RedDamageI, + Spec::BlueDamageI => Var::BlueDamageI, + Spec::GreenDamageI => Var::GreenDamageI, + + Spec::LifeI => Var::LifeI, + Spec::LRSI => Var::LRSI, + Spec::LBSI => Var::LBSI, + Spec::RBSI => Var::RBSI, + Spec::RedShieldI => Var::RedShieldI, + Spec::BlueShieldI => Var::BlueShieldI, + // _ => panic!("{:?} not implemented as a var", spec), + } + } +} + struct Combo { var: Var, units: Vec, @@ -414,7 +465,7 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou match var.effect() { Some(VarEffect::Skill) => { - let skill = var.skill().ok_or(format_err!("var {:?} has no associated skill", var))?; + let skill = var.into_skill().ok_or(format_err!("var {:?} has no associated skill", var))?; let cryp = player.cryp_get(params.cryp_id)?; // done here because i teach them a tonne of skills for tests let max_skills = 4; @@ -425,7 +476,7 @@ 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 spec = var.into_spec().ok_or(format_err!("var {:?} has no associated spec", var))?; let cryp = player.cryp_get(params.cryp_id)?; cryp.spec_add(spec)?; @@ -436,6 +487,32 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou return player_update(tx, player, false); } +pub fn vbox_unequip(params: VboxUnequipParams, tx: &mut Transaction, account: &Account) -> Result { + let mut player = player_get(tx, account.id, params.instance_id)?; + + if player.vbox.bound.len() >= 9 { + return Err(err_msg("too many vars bound")); + } + + println!("{:?}", params); + + match params.target.effect() { + Some(VarEffect::Skill) => { + let skill = params.target.into_skill().ok_or(format_err!("var {:?} has no associated skill", params.target))?; + let cryp = player.cryp_get(params.cryp_id)?; + cryp.forget(skill)?; + }, + Some(VarEffect::Spec) => { + let spec = params.target.into_spec().ok_or(format_err!("var {:?} has no associated spec", params.target))?; + let cryp = player.cryp_get(params.cryp_id)?; + cryp.spec_remove(spec)?; + }, + None => return Err(err_msg("var has no effect on cryps")), + } + + player.vbox.bound.push(params.target); + return player_update(tx, player, false); +} #[cfg(test)] mod tests {