From c2fe8f779e23b8b3df416670d3ab7f059e38cb04 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 14 Mar 2019 23:40:06 +1100 Subject: [PATCH 1/3] use balance to purchase --- client/src/scenes/item.list.js | 6 ++-- server/src/vbox.rs | 51 +++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/client/src/scenes/item.list.js b/client/src/scenes/item.list.js index c66d859e..98a90fd2 100644 --- a/client/src/scenes/item.list.js +++ b/client/src/scenes/item.list.js @@ -152,9 +152,9 @@ class ItemList extends Phaser.Scene { drawInventory(graphics); drawVbox(graphics); - this.add.text(X + WIDTH * 0.1, Y, 'Inventory', TEXT.HEADER); - this.add.text(X + WIDTH * 0.47, Y, 'Combiner', TEXT.HEADER); - this.add.text(X + WIDTH * 0.35, Y + HEIGHT / 2, 'Varibox', TEXT.HEADER); + this.add.text(X + WIDTH * 0.1, Y, 'inventory', TEXT.HEADER); + this.add.text(X + WIDTH * 0.47, Y, 'iCombinator', TEXT.HEADER); + this.add.text(X + WIDTH * 0.35, Y + HEIGHT / 2, `vBox - ${vbox.bits}b`, TEXT.HEADER); const reroll = this.add .rectangle(WIDTH * 0.01, Y + HEIGHT * 0.775, ITEM_WIDTH * 1.25, ITEM_HEIGHT * 1.25, 0x222222) diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 6e6db1db..01b8d6ac 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -96,6 +96,26 @@ impl Var { } } + fn cost(&self) -> Result { + match self { + Var::Red => Ok(1), + Var::Green => Ok(1), + Var::Blue => Ok(1), + + Var::Attack => Ok(2), + Var::Block => Ok(2), + Var::Buff => Ok(2), + Var::Debuff => Ok(2), + Var::Stun => Ok(2), + + Var::Damage => Ok(3), + Var::Hp => Ok(3), + Var::Speed => Ok(3), + + _ => Err(err_msg("var not purchasable")), + } + } + fn effect(&self) -> Option { if let Some(_skill) = self.skill() { return Some(VarEffect::Skill); @@ -170,7 +190,7 @@ enum ColourCode { #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Vbox { pub id: Uuid, - pub balance: u16, + pub bits: u16, pub free: Vec>, pub bound: Vec, pub instance: Uuid, @@ -197,7 +217,7 @@ impl Vbox { instance: instance_id, free: vec![], bound: starting_items, - balance: 9, + bits: 9, }; vbox.fill(); @@ -205,6 +225,21 @@ impl Vbox { return vbox; } + pub fn balance_sub(&mut self, amount: u16) -> Result<&mut Vbox, Error> { + let new_balance = self.bits + .checked_sub(amount) + .ok_or(format_err!("insufficient balance: {:?}", self.bits))?; + + self.bits = new_balance; + + Ok(self) + } + + pub fn balance_add(&mut self, amount: u16) -> &mut Vbox { + self.bits = self.bits.saturating_add(amount); + self + } + pub fn fill(&mut self) -> &mut Vbox { let colours = vec![ (Var::Red, 1), @@ -248,10 +283,16 @@ impl Vbox { return Err(err_msg("too many vars bound")); } + // check item exists self.free .get(i).ok_or(format_err!("no var group at index {:?}", i))? .get(j).ok_or(format_err!("no var at index {:?}", j))?; + // check can purchase + let cost = self.free[i][j].cost()?; + self.balance_sub(cost)?; + + // actually move self.bound.push(self.free[i].remove(j)); Ok(self) @@ -259,8 +300,10 @@ impl Vbox { pub fn drop(&mut self, i: usize) -> Result<&mut Vbox, Error> { self.bound.get(i).ok_or(format_err!("no var at index {:?}", i))?; - self.bound.remove(i); - // balance update + let dropped = self.bound.remove(i); + + // calculate total cost + // self.balance_add(dropped.cost()?); Ok(self) } From 42b35f9d8cc4910389c70a8a02ce2c973324abe6 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 15 Mar 2019 12:51:30 +1100 Subject: [PATCH 2/3] player names --- server/WORKLOG.md | 7 +++++-- server/src/instance.rs | 6 +++--- server/src/player.rs | 7 ++++--- server/src/vbox.rs | 5 ++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/server/WORKLOG.md b/server/WORKLOG.md index b6a7f6a4..f0e32ed4 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -9,11 +9,14 @@ # WORK WORK ## NOW -cost system for items - be able to reclaim skills / specs from cryp +be able to reclaim skills / specs from cryp combo specs randomise skill speed +scoreboard + +constants + round system for games join instance is pve? diff --git a/server/src/instance.rs b/server/src/instance.rs index bba1b5ed..da16a67e 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -58,7 +58,7 @@ impl Instance { self.players = iter::repeat_with(|| { let bot_id = Uuid::new_v4(); let cryps = instance_mobs(bot_id); - Player::new(bot_id, self.id, cryps).set_bot(true) + Player::new(bot_id, self.id, &bot_id.to_string(), cryps).set_bot(true) }) .take(15) .collect::>(); @@ -400,7 +400,7 @@ pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account: return Err(format_err!("incorrect team size. ({:})", 3)); } - let mut player = Player::new(account.id, instance.id, cryps); + let mut player = Player::new(account.id, instance.id, &account.name, cryps); player.vbox.fill(); let player = player_create(tx, player, account)?; @@ -515,7 +515,7 @@ mod tests { let player_id = Uuid::new_v4(); let cryps = instance_mobs(player_id); - let player = Player::new(player_id, instance.id, cryps).set_bot(true); + let player = Player::new(player_id, instance.id, &"test".to_string(), cryps).set_bot(true); instance.add_player(player); assert!(instance.can_start()); diff --git a/server/src/player.rs b/server/src/player.rs index c2efdb9d..898a8d3c 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -24,7 +24,7 @@ pub struct Player { pub id: Uuid, pub instance: Uuid, pub account: Uuid, - // name: String, + pub name: String, pub vbox: Vbox, pub score: Score, pub cryps: Vec, @@ -33,11 +33,12 @@ pub struct Player { } impl Player { - pub fn new(account: Uuid, instance: Uuid, cryps: Vec) -> Player { + pub fn new(account: Uuid, instance: Uuid, name: &String, cryps: Vec) -> Player { Player { id: Uuid::new_v4(), account, instance, + name: name.clone(), vbox: Vbox::new(account, instance), score: Score { wins: 0, losses: 0 }, cryps, @@ -179,7 +180,7 @@ pub fn player_cryps_set(params: PlayerCrypsSetParams, tx: &mut Transaction, acco player_update(tx, p, false) }, Err(_) => { - return player_create(tx, Player::new(account.id, Uuid::nil(), cryps), &account) + return player_create(tx, Player::new(account.id, Uuid::nil(), &account.name, cryps), &account) } } } diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 01b8d6ac..733f3fa8 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -217,7 +217,7 @@ impl Vbox { instance: instance_id, free: vec![], bound: starting_items, - bits: 9, + bits: 18, }; vbox.fill(); @@ -426,8 +426,11 @@ impl Vbox { } } +const DISCARD_COST: u16 = 5; + pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result { let mut player = player_get(tx, account.id, params.instance_id)?; + player.vbox.balance_sub(DISCARD_COST)?; player.vbox.fill(); return player_update(tx, player, false); } From 2321450139e1fc6ed726d16ebb86f9b5d16500e8 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 15 Mar 2019 14:57:45 +1100 Subject: [PATCH 3/3] refunds --- server/src/instance.rs | 4 +- server/src/vbox.rs | 243 ++++++++++++++++++----------------------- 2 files changed, 109 insertions(+), 138 deletions(-) diff --git a/server/src/instance.rs b/server/src/instance.rs index da16a67e..dcb0eb16 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -212,7 +212,7 @@ impl Instance { .iter() .filter(|p| round.player_ids.contains(&p.id) && p.bot) .count() == 2 { - println!("should play a game between {:?}", round.player_ids); + // println!("should play a game between {:?}", round.player_ids); let a = self.players.clone().into_iter().find(|p| p.id == round.player_ids[0]).unwrap(); let b = self.players.clone().into_iter().find(|p| p.id == round.player_ids[1]).unwrap(); @@ -529,7 +529,7 @@ mod tests { assert!(instance.vbox_phase_finished()); instance.games_phase_start(); - println!("{:#?}", instance); + // println!("{:#?}", instance); assert!(instance.games_phase_finished()); } diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 733f3fa8..dc9921ef 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -17,7 +17,7 @@ use skill::{Skill}; use spec::{Spec}; use player::{Player, player_get, player_update}; -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] pub enum Var { // colours Blue, @@ -81,38 +81,28 @@ enum VarEffect { } impl Var { - fn is_base(&self) -> bool { + fn cost(&self) -> u16 { match self { - Var::Attack | - Var::Block | - Var::Stun | - Var::Debuff | - Var::Buff => true, + Var::Red => 1, + Var::Green => 1, + Var::Blue => 1, - Var::Hp | - Var::Damage => true, + Var::Attack => 2, + Var::Block => 2, + Var::Buff => 2, + Var::Debuff => 2, + Var::Stun => 2, - _ => false, - } - } + Var::Damage => 3, + Var::Hp => 3, + Var::Speed => 3, - fn cost(&self) -> Result { - match self { - Var::Red => Ok(1), - Var::Green => Ok(1), - Var::Blue => Ok(1), - - Var::Attack => Ok(2), - Var::Block => Ok(2), - Var::Buff => Ok(2), - Var::Debuff => Ok(2), - Var::Stun => Ok(2), - - Var::Damage => Ok(3), - Var::Hp => Ok(3), - Var::Speed => Ok(3), - - _ => Err(err_msg("var not purchasable")), + _ => { + let combos = get_combos(); + let combo = combos.iter().find(|c| c.1 == *self) + .unwrap_or_else(|| panic!("unable to find components for {:?}", self)); + return combo.0.iter().fold(0, |acc, c| acc + c.cost()); + }, } } @@ -177,14 +167,61 @@ impl Var { } } -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] -enum ColourCode { - RR, - GG, - BB, - RG, - BR, - GB, +fn get_combos() -> Vec<(Vec, Var)> { + let mut combinations = vec![ + (vec![Var::Attack, Var::Red, Var::Red] , Var::Strike ), + (vec![Var::Attack, Var::Green, Var::Green] , Var::Heal ), + (vec![Var::Attack, Var::Blue, Var::Blue] , Var::Blast ), + (vec![Var::Attack, Var::Red, Var::Green] , Var::Strike ), + (vec![Var::Attack, Var::Green, Var::Blue] , Var::Heal ), + (vec![Var::Attack, Var::Red, Var::Blue] , Var::Blast ), + + (vec![Var::Block, Var::Red, Var::Red] , Var::Parry ), + (vec![Var::Block, Var::Green, Var::Green] , Var::Reflect ), + (vec![Var::Block, Var::Blue, Var::Blue] , Var::Toxic ), + (vec![Var::Block, Var::Red, Var::Green] , Var::Taunt ), + (vec![Var::Block, Var::Green, Var::Blue] , Var::Shield ), + // (vec![Var::Block, Var::Red, Var::Blue] , Var::Blast), + + (vec![Var::Buff, Var::Red, Var::Red] , Var::Empower), + (vec![Var::Buff, Var::Green, Var::Green] , Var::Triage), + (vec![Var::Buff, Var::Blue, Var::Blue] , Var::Amplify), + (vec![Var::Buff, Var::Red, Var::Green] , Var::Clutch), + // (vec![Var::Buff, Var::Green, Var::Blue] , Var::Heal), + (vec![Var::Buff, Var::Red, Var::Blue] , Var::Haste), + + (vec![Var::Debuff, Var::Red, Var::Red] , Var::Snare), + (vec![Var::Debuff, Var::Green, Var::Green] , Var::Purge), + (vec![Var::Debuff, Var::Blue, Var::Blue] , Var::Curse), + // (vec![Var::Debuff, Var::Red, Var::Green] , Var::Siphon), + (vec![Var::Debuff, Var::Green, Var::Blue] , Var::Siphon), + (vec![Var::Debuff, Var::Red, Var::Blue] , Var::Slow), + + (vec![Var::Stun, Var::Red, Var::Red] , Var::Strangle), + (vec![Var::Stun, Var::Green, Var::Green] , Var::Throw), + (vec![Var::Stun, Var::Blue, Var::Blue] , Var::Ruin), + // (vec![Var::Stun, Var::Red, Var::Green] , Var::Strike), + (vec![Var::Stun, Var::Green, Var::Blue] , Var::Silence), + (vec![Var::Stun, Var::Red, Var::Blue] , Var::Hex), + + (vec![Var::Damage, Var::Red, Var::Red] , Var::RedDamageI), + (vec![Var::Damage, Var::Green, Var::Green] , Var::GreenDamageI), + (vec![Var::Damage, Var::Blue, Var::Blue] , Var::BlueDamageI), + // (vec![Var::Damage, Var::Red, Var::Green] , Var::Strike), + // (vec![Var::Damage, Var::Green, Var::Blue] , Var::Silence), + // (vec![Var::Damage, Var::Red, Var::Blue] , Var::Hex), + + (vec![Var::Hp, Var::Red, Var::Red] , Var::RedShieldI), + (vec![Var::Hp, Var::Green, Var::Green] , Var::LifeI), + (vec![Var::Hp, Var::Blue, Var::Blue] , Var::BlueShieldI), + (vec![Var::Hp, Var::Red, Var::Green] , Var::LRSI), + (vec![Var::Hp, Var::Green, Var::Blue] , Var::LBSI), + (vec![Var::Hp, Var::Red, Var::Blue] , Var::RBSI), + ]; + + combinations.iter_mut().for_each(|set| set.0.sort_unstable()); + + return combinations; } #[derive(Debug,Clone,Serialize,Deserialize)] @@ -289,7 +326,7 @@ impl Vbox { .get(j).ok_or(format_err!("no var at index {:?}", j))?; // check can purchase - let cost = self.free[i][j].cost()?; + let cost = self.free[i][j].cost(); self.balance_sub(cost)?; // actually move @@ -301,9 +338,9 @@ impl Vbox { pub fn drop(&mut self, i: usize) -> Result<&mut Vbox, Error> { self.bound.get(i).ok_or(format_err!("no var at index {:?}", i))?; let dropped = self.bound.remove(i); - - // calculate total cost - // self.balance_add(dropped.cost()?); + let refund = dropped.cost(); + println!("refunding {:?} for {:?}", refund, dropped); + self.balance_add(refund); Ok(self) } @@ -318,8 +355,8 @@ impl Vbox { // have to sort the indices and keep track of the iteration // because when removing the elements the array shifts - indices.sort(); - let mut vars = indices + indices.sort_unstable(); + let mut input = indices .iter() .enumerate() .map(|(i, index)| { @@ -327,100 +364,13 @@ impl Vbox { }) .collect::>(); - let base_index = vars - .iter() - .position(|v| v.is_base()) - .ok_or(err_msg("no base item selected"))?; + // sort the input to align with the combinations + // combos are sorted when created + input.sort_unstable(); + let combos = get_combos(); + let combo = combos.iter().find(|c| c.0 == input).ok_or(err_msg("not a combo"))?; - let base = vars.remove(base_index); - - // fold colours into RGB - let colours = vars - .iter() - .fold([0, 0, 0], |mut acc, c| { - match c { - Var::Red => acc[0] += 1, - Var::Green => acc[1] += 1, - Var::Blue => acc[2] += 1, - _ => (), - }; - acc - }); - - let colour_code = match colours { - [2,0,0] => ColourCode::RR, - [0,2,0] => ColourCode::GG, - [0,0,2] => ColourCode::BB, - [1,1,0] => ColourCode::RG, - [0,1,1] => ColourCode::GB, - [1,0,1] => ColourCode::BR, - _ => return Err(err_msg("not a combo")), - }; - - let new = match base { - Var::Attack => match colour_code { - ColourCode::RR => Var::Strike, - ColourCode::GG => Var::Heal, - ColourCode::BB => Var::Blast, - ColourCode::RG => Var::Slay, // - ColourCode::GB => return Err(err_msg("unhandled skill combo")), - ColourCode::BR => Var::Banish, // - }, - Var::Block => match colour_code { - ColourCode::RR => Var::Parry, - ColourCode::GG => Var::Reflect, - ColourCode::BB => Var::Toxic, - ColourCode::RG => Var::Taunt, - ColourCode::GB => Var::Shield, - ColourCode::BR => return Err(err_msg("unhandled skill combo")), - }, - Var::Buff => match colour_code { - ColourCode::RR => Var::Empower, - ColourCode::GG => Var::Triage, - ColourCode::BB => Var::Amplify, - ColourCode::RG => Var::Clutch, - ColourCode::GB => return Err(err_msg("unhandled skill combo")), - ColourCode::BR => Var::Haste, - }, - Var::Debuff => match colour_code { - ColourCode::RR => Var::Snare, - ColourCode::GG => Var::Purge, - ColourCode::BB => Var::Curse, - ColourCode::RG => return Err(err_msg("unhandled skill combo")), - ColourCode::GB => Var::Siphon, - ColourCode::BR => Var::Slow, - }, - Var::Stun => match colour_code { - ColourCode::RR => Var::Strangle, - ColourCode::GG => Var::Throw, - ColourCode::BB => Var::Ruin, - ColourCode::RG => return Err(err_msg("unhandled skill combo")), - ColourCode::GB => Var::Silence, - ColourCode::BR => Var::Hex, - }, - - // SPECS - Var::Damage => match colour_code { - ColourCode::RR => Var::RedDamageI, - ColourCode::GG => Var::GreenDamageI, - ColourCode::BB => Var::BlueDamageI, - ColourCode::RG => return Err(err_msg("unhandled skill combo")), - ColourCode::GB => return Err(err_msg("unhandled skill combo")), - ColourCode::BR => return Err(err_msg("unhandled skill combo")), - }, - Var::Hp => match colour_code { - ColourCode::RR => Var::RedShieldI, - ColourCode::GG => Var::LifeI, - ColourCode::BB => Var::BlueShieldI, - ColourCode::RG => Var::LRSI, - ColourCode::GB => Var::LBSI, - ColourCode::BR => Var::RBSI, - }, - - _ => panic!("wrong base {:?}", base), - }; - - self.bound.push(new); + self.bound.push(combo.1); Ok(self) } @@ -493,4 +443,25 @@ mod tests { vbox.combine(vec![1,2,0]).unwrap(); assert_eq!(vbox.bound[0], Var::Heal); } + + #[test] + fn combos_test() { + let mut input = vec![Var::Green, Var::Attack, Var::Green]; + let combos = get_combos(); + + // sort input so they align + input.sort_unstable(); + + let combo = combos.iter().find(|c| c.0 == input); + assert!(combo.is_some()); + } + + #[test] + fn drop_test() { + let mut vbox = Vbox::new(Uuid::new_v4(), Uuid::new_v4()); + vbox.bound = vec![Var::Strike]; + vbox.drop(0).unwrap(); + assert_eq!(vbox.bits, 22); + } + } \ No newline at end of file