From 33ad4db8f590b4d8207148daf4732c84a8f42a39 Mon Sep 17 00:00:00 2001
From: ntr
Date: Thu, 28 Nov 2019 15:43:48 +1000
Subject: [PATCH 1/6] server
---
server/src/instance.rs | 36 +++--
server/src/player.rs | 287 ++++++++++++++++++++++++++-------------
server/src/rpc.rs | 31 ++---
server/src/vbox.rs | 297 ++++++++++++++++++++++++++---------------
4 files changed, 419 insertions(+), 232 deletions(-)
diff --git a/server/src/instance.rs b/server/src/instance.rs
index c5ec9c04..0d052d08 100644
--- a/server/src/instance.rs
+++ b/server/src/instance.rs
@@ -15,7 +15,7 @@ use chrono::prelude::*;
use chrono::Duration;
use account::Account;
-use account;
+use vbox;
use player::{Player, Score, player_create};
@@ -466,35 +466,35 @@ impl Instance {
Ok(())
}
- pub fn vbox_discard(mut self, account: Uuid) -> Result {
+ pub fn vbox_refill(mut self, account: Uuid) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
- .vbox_discard()?;
+ .vbox_refill()?;
Ok(self)
}
- pub fn vbox_accept(mut self, account: Uuid, group: usize, index: usize, construct_id: Option) -> Result {
+ pub fn vbox_buy(mut self, account: Uuid, group: vbox::ItemType, index: String, construct_id: Option) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
- .vbox_accept(group, index, construct_id)?;
+ .vbox_buy(group, index, construct_id)?;
Ok(self)
}
- pub fn vbox_combine(mut self, account: Uuid, inv_indices: Vec, vbox_indices: Vec>) -> Result {
+ pub fn vbox_combine(mut self, account: Uuid, inv_indices: Vec, vbox_indices: vbox::VboxIndices) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
.vbox_combine(inv_indices, vbox_indices)?;
Ok(self)
}
- pub fn vbox_reclaim(mut self, account: Uuid, index: usize) -> Result {
+ pub fn vbox_refund(mut self, account: Uuid, index: String) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
- .vbox_reclaim(index)?;
+ .vbox_refund(index)?;
Ok(self)
}
- pub fn vbox_apply(mut self, account: Uuid, index: usize, construct_id: Uuid) -> Result {
+ pub fn vbox_apply(mut self, account: Uuid, index: String, construct_id: Uuid) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
.vbox_apply(index, construct_id)?;
@@ -834,19 +834,17 @@ mod tests {
fn instance_pve_test() {
let mut instance = Instance::new();
- let bot_player = bot_player();
- let bot = bot_player.id;
- instance.add_player(bot_player).unwrap();
+ let bot = bot_player();
+ let bot_one = bot.id;
+ instance.add_player(bot).unwrap();
- let player_account = Uuid::new_v4();
- let constructs = instance_mobs(player_account);
- let player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true);
-
- instance.add_player(player).expect("could not add player");
+ let bot = bot_player();
+ let bot_two = bot.id;
+ instance.add_player(bot).unwrap();
assert_eq!(instance.phase, InstancePhase::Lobby);
- instance.player_ready(player_account).unwrap();
- instance.player_ready(bot).unwrap();
+ instance.player_ready(bot_one).unwrap();
+ instance.player_ready(bot_two).unwrap();
assert_eq!(instance.phase, InstancePhase::Finished);
}
diff --git a/server/src/player.rs b/server/src/player.rs
index 6a0a5abd..9b1fbeca 100644
--- a/server/src/player.rs
+++ b/server/src/player.rs
@@ -1,3 +1,5 @@
+use std::collections::{HashMap};
+
use uuid::Uuid;
use rand::prelude::*;
@@ -9,7 +11,7 @@ use failure::err_msg;
use account;
use account::Account;
use construct::{Construct, Colours};
-use vbox::{Vbox};
+use vbox::{Vbox, ItemType, VboxIndices};
use item::{Item, ItemEffect};
use effect::{Effect};
@@ -155,124 +157,228 @@ impl Player {
pub fn autobuy(&mut self) -> &mut Player {
let mut rng = thread_rng();
- // first check if any constructs have no skills
- // if there is one find an item in vbox that gives a skill
- while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) {
- if let Some(s) = self.vbox.bound.iter().position(|v| v.into_skill().is_some()) {
- let construct_id = self.constructs[c].id;
- self.vbox_apply(s, construct_id).expect("could not apply");
+ // skill buying phase
+ while self.constructs.iter().any(|c| c.skills.len() < 3) {
+ // find the construct with the smallest number of skills
+ let construct_id = match self.constructs.iter().min_by_key(|c| c.skills.len()) {
+ None => panic!("no constructs in autobuy"),
+ Some(c) => c.id,
+ };
+
+ let i = self.vbox.stash.iter()
+ .find(|(_i, v)| v.into_skill().is_some())
+ .map(|(i, _v)| i.clone());
+
+ // got a skill in stash
+ if let Some(i) = i {
+ // AAAAAAAAAAAAAAAAAAAA
+ // there's a bad bug here where if this apply fails
+ // the item in question will be silently dropped
+ self.vbox_apply(i, construct_id).ok();
continue;
}
- info!("no skills available...");
- }
+ // need to buy one
+ else {
- // now keep buying and applying items cause whynot
- // inb4 montecarlo gan
+ // do we have any colours in store?
+ let colours = self.vbox.store[&ItemType::Colours].keys()
+ .cloned()
+ .collect::>();
- loop {
- let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) {
- true => {
- let mut target_construct_i = 0;
- for (j, c) in self.constructs.iter().enumerate() {
- if c.skills.len() < self.constructs[target_construct_i].skills.len() {
- target_construct_i = j;
+ // how about a base skill?
+ let base = match self.vbox.store[&ItemType::Skills].iter().next() {
+ Some(b) => Some(b.0.clone()),
+ None => None,
+ };
+
+ // if no: try to refill and start again
+ match colours.len() < 2 || base.is_none() {
+ true => match self.vbox_refill() {
+ Ok(_) => continue,
+ Err(_) => break, // give up
+ },
+ false => {
+ let mut vbox_items = HashMap::new();
+ vbox_items.insert(ItemType::Colours, colours);
+ vbox_items.insert(ItemType::Skills, vec![base.unwrap()]);
+
+ match self.vbox_combine(vec![], Some(vbox_items)) {
+ Ok(_) => continue,
+ Err(_) => break, // give up
}
}
- (target_construct_i, self.constructs[target_construct_i].id)
- },
- false => {
- let i = rng.gen_range(0, 3);
- (i, self.constructs[i].id)
- },
- };
-
- let needs_skills = self.constructs[target_construct_i].skills.len() < 3;
- let group_i = match needs_skills {
- true => 1,
- false => 2,
- };
-
-
- let num_colours = self.vbox.bound
- .iter()
- .filter(|v| [Item::Red, Item::Green, Item::Blue].contains(v))
- .count();
-
- if self.vbox.bound.len() < 3 || num_colours < 2 {
- if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 {
- // info!("insufficient balance");
- break;
}
-
- // get 2 colours and something else
- let free_colours = self.vbox.free[0].iter().fold(0, |count, item| {
- match item.is_some() {
- true => count + 1,
- false => count
- }
- });
- if free_colours < 2 {
- break;
- }
- self.bot_vbox_accept(0).expect("could't accept colour item");
- self.bot_vbox_accept(0).expect("could't accept colour item");
- self.bot_vbox_accept(group_i).expect("could't accept group item");
}
+ }
- // info!("{:?}", self.vbox.bound);
-
- let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun];
- let combo_i = match group_i {
- 1 => self.vbox.bound.iter().position(|v| skills.contains(v)).expect("no skill found"),
- 2 => self.vbox.bound.iter().position(|v| v.into_spec().is_some()).expect("no spec found"),
- _ => panic!("unknown group_i"),
+ // spec buying phase
+ while self.constructs.iter().any(|c| c.specs.len() < 3) {
+ // find the construct with the smallest number of skills
+ let construct_id = match self.constructs.iter().min_by_key(|c| c.specs.len()) {
+ None => panic!("no constructs in autobuy"),
+ Some(c) => c.id,
};
- // first 2 colours can be whatever
- self.vbox_combine(vec![0, 1, combo_i], vec![]).ok();
- let item_i = self.vbox.bound.len() - 1;
- self.vbox_apply(item_i, target_construct_id).ok();
+ let i = self.vbox.stash.iter()
+ .find(|(_i, v)| v.into_spec().is_some())
+ .map(|(i, _v)| i.clone());
+
+ // got a skill in stash
+ if let Some(i) = i {
+ // AAAAAAAAAAAAAAAAAAAA
+ // there's a bad bug here where if this apply fails
+ // the item in question will be silently dropped
+ self.vbox_apply(i, construct_id).ok();
+ continue;
+ }
+ // need to buy one
+ else {
+ // do we have any colours in store?
+ let colours = self.vbox.store[&ItemType::Colours].keys()
+ .cloned()
+ .collect::>();
+
+ // how about a base spec?
+ let base = match self.vbox.store[&ItemType::Specs].iter().next() {
+ Some(b) => Some(b.0.clone()),
+ None => None,
+ };
+
+ // if no: try to refill and start again
+ match colours.len() < 2 || base.is_none() {
+ true => match self.vbox_refill() {
+ Ok(_) => continue,
+ Err(_) => break, // give up
+ },
+ false => {
+ let mut vbox_items = HashMap::new();
+ vbox_items.insert(ItemType::Colours, colours);
+ vbox_items.insert(ItemType::Specs, vec![base.unwrap()]);
+
+ match self.vbox_combine(vec![], Some(vbox_items)) {
+ Ok(_) => continue,
+ Err(_) => break, // give up
+ }
+ }
+ }
+ }
}
+ // upgrading phase
+ // NYI
+
+ // // first check if any constructs have no skills
+ // // if there is one find an item in vbox that gives a skill
+ // while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) {
+ // if let Some(s) = self.vbox.stash.iter().position(|(i, v)| v.into_skill().is_some()) {
+ // let construct_id = self.constructs[c].id;
+ // self.vbox_apply(s, construct_id).expect("could not apply");
+ // continue;
+ // }
+ // info!("no skills available...");
+ // }
+
+ // // now keep buying and applying items cause whynot
+ // // inb4 montecarlo gan
+ // loop {
+ // let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) {
+ // true => {
+ // let mut target_construct_i = 0;
+ // for (j, c) in self.constructs.iter().enumerate() {
+ // if c.skills.len() < self.constructs[target_construct_i].skills.len() {
+ // target_construct_i = j;
+ // }
+ // }
+ // (target_construct_i, self.constructs[target_construct_i].id)
+ // },
+ // false => {
+ // let i = rng.gen_range(0, 3);
+ // (i, self.constructs[i].id)
+ // },
+ // };
+
+ // let needs_skills = self.constructs[target_construct_i].skills.len() < 3;
+ // let group_i = match needs_skills {
+ // true => 1,
+ // false => 2,
+ // };
+
+
+ // let num_colours = self.vbox.stash
+ // .iter()
+ // .filter(|(i, v)| [Item::Red, Item::Green, Item::Blue].contains(v))
+ // .count();
+
+ // if self.vbox.stash.len() < 3 || num_colours < 2 {
+ // if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 {
+ // // info!("insufficient balance");
+ // break;
+ // }
+
+ // // get 2 colours and something else
+ // let store_colours = self.vbox.store[&ItemType::Colours].len();
+ // if store_colours < 2 {
+ // break;
+ // }
+ // self.bot_vbox_accept(0).expect("could't accept colour item");
+ // self.bot_vbox_accept(0).expect("could't accept colour item");
+ // self.bot_vbox_accept(group_i).expect("could't accept group item");
+ // }
+
+ // // info!("{:?}", self.vbox.stash);
+
+ // let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun];
+ // let combo_i = match group_i {
+ // 1 => self.vbox.stash.iter().position(|v| skills.contains(v)).expect("no skill found"),
+ // 2 => self.vbox.stash.iter().position(|v| v.into_spec().is_some()).expect("no spec found"),
+ // _ => panic!("unknown group_i"),
+ // };
+
+ // // first 2 colours can be whatever
+ // self.vbox_combine(vec![0, 1, combo_i], vec![]).ok();
+ // let item_i = self.vbox.stash.len() - 1;
+ // self.vbox_apply(item_i, target_construct_id).ok();
+ // }
+
return self;
}
- pub fn vbox_discard(&mut self) -> Result<&mut Player, Error> {
+ pub fn vbox_refill(&mut self) -> Result<&mut Player, Error> {
self.vbox.balance_sub(DISCARD_COST)?;
self.vbox.fill();
Ok(self)
}
- pub fn bot_vbox_accept(&mut self, group: usize) -> Result<&mut Player, Error> {
- self.vbox.bot_accept(group)?;
+ pub fn bot_vbox_accept(&mut self, group: ItemType) -> Result<&mut Player, Error> {
+ let item = self.vbox.bot_buy(group)?;
+ self.vbox.stash_add(item, None)?;
Ok(self)
}
- pub fn vbox_accept(&mut self, group: usize, index: usize, construct_id: Option) -> Result<&mut Player, Error> {
- self.vbox.accept(group, index, construct_id)?;
- if construct_id.is_some() {
- let equip_index = self.vbox.bound.len() - 1;
- self.vbox_apply(equip_index, construct_id.expect("no construct"))?;
- }
+ pub fn vbox_buy(&mut self, group: ItemType, index: String, construct_id: Option) -> Result<&mut Player, Error> {
+ let item = self.vbox.buy(group, &index)?;
+
+ match construct_id {
+ Some(id) => { self.vbox_apply(index, id)?; },
+ None => { self.vbox.stash_add(item, None)?; },
+ };
+
Ok(self)
}
- pub fn vbox_combine(&mut self, inv_indices: Vec, vbox_indices: Vec>) -> Result<&mut Player, Error> {
+ pub fn vbox_combine(&mut self, inv_indices: Vec, vbox_indices: VboxIndices) -> Result<&mut Player, Error> {
self.vbox.combine(inv_indices, vbox_indices)?;
Ok(self)
}
- pub fn vbox_reclaim(&mut self, index: usize) -> Result<&mut Player, Error> {
- self.vbox.reclaim(index)?;
+ pub fn vbox_refund(&mut self, index: String) -> Result<&mut Player, Error> {
+ self.vbox.refund(index)?;
Ok(self)
}
- pub fn vbox_apply(&mut self, index: usize, construct_id: Uuid) -> Result<&mut Player, Error> {
- if self.vbox.bound.get(index).is_none() {
- return Err(format_err!("no item at index {:?}", index));
- }
-
- let item = self.vbox.bound.remove(index);
+ pub fn vbox_apply(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> {
+ let item = self.vbox.stash.remove(&index)
+ .ok_or(format_err!("no item at index {:?} {:?}", self.vbox.stash, index))?;
match item.effect() {
Some(ItemEffect::Skill) => {
@@ -317,8 +423,8 @@ impl Player {
}
pub fn vbox_unequip(&mut self, target: Item, construct_id: Uuid, target_construct_id: Option) -> Result<&mut Player, Error> {
- if self.vbox.bound.len() >= 9 && !target_construct_id.is_some() {
- return Err(err_msg("too many items bound"));
+ if self.vbox.stash.len() >= 9 && !target_construct_id.is_some() {
+ return Err(err_msg("too many items stash"));
}
match target.effect() {
@@ -349,13 +455,12 @@ impl Player {
construct.apply_modifiers(&player_colours);
}
- self.vbox.bound.push(target);
+ let equip_index = self.vbox.stash_add(target, None)?;
if target_construct_id.is_some() {
- let equip_index = self.vbox.bound.len() - 1;
self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?;
}
- // self.vbox.bound.sort_unstable();
+ // self.vbox.stash.sort_unstable();
Ok(self)
}
@@ -408,8 +513,8 @@ mod tests {
let player_account = Uuid::new_v4();
let constructs = instance_mobs(player_account);
let mut player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true);
- player.vbox.fill();
+ player.vbox.fill();
player.autobuy();
assert!(player.constructs.iter().all(|c| c.skills.len() >= 1));
diff --git a/server/src/rpc.rs b/server/src/rpc.rs
index bc0ba493..9f43a928 100644
--- a/server/src/rpc.rs
+++ b/server/src/rpc.rs
@@ -1,3 +1,4 @@
+use std::collections::HashMap;
use std::time::{Instant};
use std::thread::{spawn};
@@ -34,7 +35,7 @@ use mail::Email;
use pg::{Db};
use pg::{PgPool};
use skill::{Skill, dev_resolve, Resolutions};
-use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
+use vbox::{ItemType, vbox_buy, vbox_apply, vbox_refill, vbox_combine, vbox_refund, vbox_unequip};
use http::{AUTH_CLEAR, TOKEN_HEADER};
#[derive(Debug,Clone,Serialize)]
@@ -114,14 +115,14 @@ pub enum RpcRequest {
InstanceState { instance_id: Uuid },
InstanceChat { instance_id: Uuid, index: usize },
- VboxAccept { instance_id: Uuid, group: usize, index: usize },
- VboxAcceptEquip { instance_id: Uuid, group: usize, index: usize, construct_id: Uuid },
- VboxDiscard { instance_id: Uuid },
- VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Vec> },
- VboxApply { instance_id: Uuid, construct_id: Uuid, index: usize },
+ VboxBuy { instance_id: Uuid, group: ItemType, index: String },
+ VboxBuyEquip { instance_id: Uuid, group: ItemType, index: String, construct_id: Uuid },
+ VboxRefill { instance_id: Uuid },
+ VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Option>> },
+ VboxApply { instance_id: Uuid, construct_id: Uuid, index: String },
VboxUnequip { instance_id: Uuid, construct_id: Uuid, target: Item },
VboxUnequipApply { instance_id: Uuid, construct_id: Uuid, target: Item, target_construct_id: Uuid },
- VboxReclaim { instance_id: Uuid, index: usize },
+ VboxRefund { instance_id: Uuid, index: String },
}
struct Connection {
@@ -245,11 +246,11 @@ impl Connection {
RpcRequest::InstanceAbandon { instance_id } =>
Ok(instance_abandon(&mut tx, account, instance_id)?),
- RpcRequest::VboxAccept { instance_id, group, index } =>
- Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, None)?)),
+ RpcRequest::VboxBuy { instance_id, group, index } =>
+ Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, None)?)),
- RpcRequest::VboxAcceptEquip { instance_id, group, index, construct_id } =>
- Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, Some(construct_id))?)),
+ RpcRequest::VboxBuyEquip { instance_id, group, index, construct_id } =>
+ Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, Some(construct_id))?)),
RpcRequest::VboxApply { instance_id, construct_id, index } =>
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
@@ -257,11 +258,11 @@ impl Connection {
RpcRequest::VboxCombine { instance_id, inv_indices, vbox_indices } =>
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, inv_indices, vbox_indices)?)),
- RpcRequest::VboxDiscard { instance_id } =>
- Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
+ RpcRequest::VboxRefill { instance_id } =>
+ Ok(RpcMessage::InstanceState(vbox_refill(&mut tx, account, instance_id)?)),
- RpcRequest::VboxReclaim { instance_id, index } =>
- Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
+ RpcRequest::VboxRefund { instance_id, index } =>
+ Ok(RpcMessage::InstanceState(vbox_refund(&mut tx, account, instance_id, index)?)),
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, None)?)),
diff --git a/server/src/vbox.rs b/server/src/vbox.rs
index faf93fdc..e2507c74 100644
--- a/server/src/vbox.rs
+++ b/server/src/vbox.rs
@@ -1,8 +1,9 @@
use uuid::Uuid;
use std::iter;
+use std::collections::HashMap;
-// reclaims
+// refunds
use rand::prelude::*;
use rand::{thread_rng};
use rand::distributions::{WeightedIndex};
@@ -19,30 +20,48 @@ use construct::{Colours};
use item::*;
+pub type VboxIndices = Option>>;
+
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Vbox {
pub bits: usize,
- pub free: Vec>>,
- pub bound: Vec- ,
+ pub store: HashMap>,
+ pub stash: HashMap,
}
+#[derive(Debug,Copy,Clone,Serialize,Deserialize,Hash,PartialEq,Eq)]
pub enum ItemType {
Colours,
Skills,
Specs,
}
+const STORE_COLOURS_CAPACITY: usize = 6;
+const STORE_SKILLS_CAPACITY: usize = 3;
+const STORE_SPECS_CAPACITY: usize = 3;
+const STASH_CAPACITY: usize = 6;
+const STARTING_ATTACK_COUNT: usize = 3;
+
impl Vbox {
pub fn new() -> Vbox {
- let starting_items = vec![
- Item::Attack,
- Item::Attack,
- Item::Attack,
- ];
+ let mut colours: HashMap = HashMap::new();
+ let mut skills: HashMap = HashMap::new();
+ let mut specs: HashMap = HashMap::new();
+
+ let store = [
+ (ItemType::Colours, colours),
+ (ItemType::Skills, skills),
+ (ItemType::Colours, specs),
+ ].iter().cloned().collect();
+
+ let mut stash = HashMap::new();
+ for i in 0..STARTING_ATTACK_COUNT {
+ stash.insert(i.to_string(), Item::Attack);
+ }
Vbox {
- free: vec![vec![], vec![], vec![]],
- bound: starting_items,
+ store,
+ stash,
bits: 30,
}
}
@@ -65,103 +84,130 @@ impl Vbox {
pub fn fill(&mut self) -> &mut Vbox {
let mut rng = thread_rng();
- self.free = [ItemType::Colours, ItemType::Skills, ItemType::Specs].iter()
- .map(|item_type| {
- let items = match item_type {
- ItemType::Colours => vec![
- (Some(Item::Red), 1),
- (Some(Item::Green), 1),
- (Some(Item::Blue), 1),
- ],
- ItemType::Skills => vec![
- (Some(Item::Attack), 1),
- (Some(Item::Block), 1),
- (Some(Item::Buff), 1),
- (Some(Item::Debuff), 1),
- (Some(Item::Stun), 1),
- ],
- ItemType::Specs => vec![
- (Some(Item::Power), 1),
- (Some(Item::Life), 1),
- (Some(Item::Speed), 1),
- ],
- };
+ let colours = vec![
+ (Item::Red, 1),
+ (Item::Green, 1),
+ (Item::Blue, 1),
+ ];
+ let colour_dist = WeightedIndex::new(colours.iter().map(|item| item.1)).unwrap();
- let dist = WeightedIndex::new(items.iter().map(|item| item.1)).unwrap();
- iter::repeat_with(|| {
- items[dist.sample(&mut rng)].0}).take(match item_type {
- ItemType::Colours => 6,
- _ => 3,
- }).collect::>>()
- })
- .collect::>>>();
+ let skills = vec![
+ (Item::Attack, 1),
+ (Item::Block, 1),
+ (Item::Buff, 1),
+ (Item::Debuff, 1),
+ (Item::Stun, 1),
+ ];
+ let skill_dist = WeightedIndex::new(skills.iter().map(|item| item.1)).unwrap();
+
+ let specs = vec![
+ (Item::Power, 1),
+ (Item::Life, 1),
+ (Item::Speed, 1),
+ ];
+ let spec_dist = WeightedIndex::new(specs.iter().map(|item| item.1)).unwrap();
+
+ for item_type in [ItemType::Colours, ItemType::Skills, ItemType::Specs].iter() {
+ let (items, num, dist) = match item_type {
+ ItemType::Colours => (&colours, STORE_COLOURS_CAPACITY, &colour_dist),
+ ItemType::Skills => (&skills, STORE_SKILLS_CAPACITY, &skill_dist),
+ ItemType::Specs => (&specs, STORE_SPECS_CAPACITY, &spec_dist),
+ };
+
+ let drops = iter::repeat_with(|| items[dist.sample(&mut rng)].0)
+ .take(num)
+ .enumerate()
+ .map(|(i, item)| (i.to_string(), item))
+ .collect::>();
+
+ self.store.insert(*item_type, drops);
+ }
self
}
- pub fn accept(&mut self, i: usize, j: usize, construct_id: Option) -> Result<&mut Vbox, Error> {
- if self.bound.len() >= 6 && !construct_id.is_some() {
- return Err(err_msg("too many items bound"));
- }
-
+ pub fn buy(&mut self, item: ItemType, i: &String) -> Result
- {
// check item exists
- self.free
- .get(i).ok_or(format_err!("no item group at index {:?}", i))?
- .get(j).ok_or(format_err!("no item at index {:?}", j))?;
+ let selection = self.store
+ .get_mut(&item).ok_or(format_err!("no item group {:?}", item))?
+ .remove(i).ok_or(format_err!("no item at index {:?} {:}", item, i))?;
- // check can purchase
- let cost = match self.free[i][j] {
- None => 0,
- _ => self.free[i][j].unwrap().cost()
- };
- self.balance_sub(cost)?;
+ self.balance_sub(selection.cost())?;
- // actually move
- match self.free[i][j] {
- None => (),
- _ => self.bound.push(self.free[i][j].unwrap())
+ Ok(selection)
+ }
+
+ pub fn stash_add(&mut self, item: Item, index: Option<&String>) -> Result {
+ if self.stash.len() >= STASH_CAPACITY {
+ return Err(err_msg("stash full"));
}
- // self.bound.push(self.free[i][j].unwrap());
- self.free[i][j] = None;
- // self.bound.sort_unstable();
- Ok(self)
+ if let Some(index) = index {
+ if self.stash.contains_key(index) {
+ return Err(format_err!("slot occupied {:?}", index));
+ }
+ self.stash.insert(index.clone(), item);
+ return Ok(index.to_string());
+ }
+
+ for i in (0..STASH_CAPACITY).map(|i| i.to_string()) {
+ if !self.stash.contains_key(&i) {
+ self.stash.insert(i.clone(), item);
+ return Ok(i);
+ }
+ }
+
+ return Err(err_msg("stash full"));
}
- pub fn bot_accept(&mut self, i: usize) -> Result<&mut Vbox, Error> {
- let buy_index = self.free[i].iter().position(|item| item.is_some());
- self.accept(i, buy_index.expect("no valid buys"), None)
+ pub fn bot_buy(&mut self, item: ItemType) -> Result
- {
+ let buy_index = self.store[&item]
+ .keys()
+ .next()
+ .ok_or(format_err!("no item in group {:?}", item))?
+ .clone();
+
+ self.buy(item, &buy_index)
}
- pub fn reclaim(&mut self, i: usize) -> Result<&mut Vbox, Error> {
- self.bound.get(i).ok_or(format_err!("no item at index {:?}", i))?;
- let reclaimed = self.bound.remove(i);
- let refund = reclaimed.cost();
- // info!("reclaiming {:?} for {:?}", refund, reclaimed);
+ pub fn refund(&mut self, i: String) -> Result<&mut Vbox, Error> {
+ let refunded = self.stash.remove(&i)
+ .ok_or(format_err!("no item at index {:?} {:?}", self.stash, i))?;
+
+ let refund = refunded.cost();
+ // info!("refunding {:?} for {:?}", refund, refunded);
self.balance_add(refund);
Ok(self)
}
- pub fn combine(&mut self, mut inv_indices: Vec, vbox_indicies: Vec>) -> Result<&mut Vbox, Error> {
- if !inv_indices.iter().all(|i| self.bound.get(*i).is_some()) {
- return Err(err_msg("item missing index"));
- }
- // try to buy up the vbox indicies and add them to the inventory indicies for combining
- for vi in vbox_indicies.iter() {
- inv_indices.push(self.bound.len());
- self.accept(vi[0], vi[1], Some(Uuid::nil()))?;
- }
+ pub fn combine(&mut self, stash_indices: Vec, store_indices: Option>>) -> Result<&mut Vbox, Error> {
+ // find base item for index to insert into
+ let base_index = stash_indices.iter()
+ .find(|i| match self.stash.get(i.clone()) {
+ Some(item) => item.into_skill().is_some(),
+ None => false,
+ });
- // have to sort the indices and keep track of the iteration
- // because when removing the elements the array shifts
- inv_indices.sort_unstable();
- let mut input = inv_indices
+ let mut input = stash_indices
.iter()
- .enumerate()
- .map(|(i, index)| {
- self.bound.remove(index.saturating_sub(i))
- })
- .collect::>();
+ .map(|i| self.stash.remove(i)
+ .ok_or(format_err!("no item at index {:?} {:?}", self.stash, i)))
+ .collect::, Error>>()?;
+
+ if let Some(store_indices) = store_indices {
+ let mut purchased = store_indices.iter()
+ .map(|(g, list)|
+ list.iter()
+ .map(|i| self.buy(*g, i))
+ .collect::, Error>>()
+ )
+ .collect::>, Error>>()?
+ .into_iter()
+ .flatten()
+ .collect();
+
+ input.append(&mut purchased);
+ }
// sort the input to align with the combinations
// combos are sorted when created
@@ -169,40 +215,37 @@ impl Vbox {
let combos = get_combos();
let combo = combos.iter().find(|c| c.components == input).ok_or(err_msg("not a combo"))?;
- self.bound.push(combo.item);
- // self.bound.sort_unstable();
- if self.bound.len() > 6 {
- return Err(err_msg("too many items bound"));
- }
+ self.stash_add(combo.item, base_index)?;
+
Ok(self)
}
}
-pub fn vbox_discard(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result {
+pub fn vbox_refill(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result {
let instance = instance_get(tx, instance_id)?
- .vbox_discard(account.id)?;
+ .vbox_refill(account.id)?;
return instance_update(tx, instance);
}
-pub fn vbox_accept(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: usize, index: usize, construct_id: Option) -> Result {
+pub fn vbox_buy(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: ItemType, index: String, construct_id: Option) -> Result {
let instance = instance_get(tx, instance_id)?
- .vbox_accept(account.id, group, index, construct_id)?;
+ .vbox_buy(account.id, group, index, construct_id)?;
return instance_update(tx, instance);
}
-pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, inv_indices: Vec, vbox_indices: Vec>) -> Result {
+pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, stash_indices: Vec, vbox_indices: VboxIndices) -> Result {
let instance = instance_get(tx, instance_id)?
- .vbox_combine(account.id, inv_indices, vbox_indices)?;
+ .vbox_combine(account.id, stash_indices, vbox_indices)?;
return instance_update(tx, instance);
}
-pub fn vbox_reclaim(tx: &mut Transaction, account: &Account, instance_id: Uuid, index: usize) -> Result {
+pub fn vbox_refund(tx: &mut Transaction, account: &Account, instance_id: Uuid, index: String) -> Result {
let instance = instance_get(tx, instance_id)?
- .vbox_reclaim(account.id, index)?;
+ .vbox_refund(account.id, index)?;
return instance_update(tx, instance);
}
-pub fn vbox_apply(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, index: usize) -> Result {
+pub fn vbox_apply(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, index: String) -> Result {
let instance = instance_get(tx, instance_id)?
.vbox_apply(account.id, index, construct_id)?;
return instance_update(tx, instance);
@@ -221,9 +264,49 @@ mod tests {
#[test]
fn combine_test() {
let mut vbox = Vbox::new();
- vbox.bound = vec![Item::Attack, Item::Green, Item::Green];
- vbox.combine(vec![1,2,0], vec![]).unwrap();
- assert_eq!(vbox.bound[0], Item::Heal);
+ vbox.stash.insert(0.to_string(), Item::Attack);
+ vbox.stash.insert(1.to_string(), Item::Green);
+ vbox.stash.insert(2.to_string(), Item::Green);
+ vbox.combine(vec![0.to_string(), 1.to_string(), 2.to_string()], None).unwrap();
+ assert_eq!(vbox.stash["0"], Item::Heal);
+ }
+
+ #[test]
+ fn buy_test() {
+ let mut vbox = Vbox::new();
+ vbox.fill();
+
+ // cannot rebuy same
+ vbox.buy(ItemType::Skills, &0.to_string()).unwrap();
+ assert!(vbox.store[&ItemType::Skills].get(&0.to_string()).is_none());
+ assert!(vbox.buy(ItemType::Skills, &0.to_string()).is_err());
+ }
+
+ #[test]
+ fn capacity_test() {
+ let mut vbox = Vbox::new();
+ vbox.fill();
+ vbox.stash_add(Item::Red, None).unwrap();
+ vbox.stash_add(Item::Red, None).unwrap();
+ vbox.stash_add(Item::Red, None).unwrap();
+ assert!(vbox.stash_add(Item::Red, None).is_err());
+ }
+
+ #[test]
+ fn store_and_stash_combine_test() {
+ let mut vbox = Vbox::new();
+ vbox.fill();
+
+ let mut skill_combine_args = HashMap::new();
+ skill_combine_args.insert(ItemType::Colours, vec![0.to_string(), 1.to_string()]);
+ skill_combine_args.insert(ItemType::Skills, vec![0.to_string()]);
+
+ let mut spec_combine_args = HashMap::new();
+ spec_combine_args.insert(ItemType::Colours, vec![2.to_string(), 3.to_string()]);
+ spec_combine_args.insert(ItemType::Specs, vec![0.to_string()]);
+
+ vbox.combine(vec![], Some(skill_combine_args)).unwrap();
+ vbox.combine(vec![], Some(spec_combine_args)).unwrap();
}
#[test]
@@ -239,10 +322,10 @@ mod tests {
}
#[test]
- fn reclaim_test() {
+ fn refund_test() {
let mut vbox = Vbox::new();
- vbox.bound = vec![Item::Strike];
- vbox.reclaim(0).unwrap();
+ vbox.stash.insert(0.to_string(), Item::Strike);
+ vbox.refund(0.to_string()).unwrap();
assert_eq!(vbox.bits, 32);
}
From 4920821ec2a6e918a7441458ea16a48fba7f9345 Mon Sep 17 00:00:00 2001
From: ntr
Date: Thu, 28 Nov 2019 15:48:31 +1000
Subject: [PATCH 2/6] rm free and bound
---
client/src/components/instance.constructs.jsx | 6 +-
client/src/components/vbox.combiner.jsx | 2 +-
client/src/components/vbox.component.jsx | 2 +-
client/src/components/vbox.stash.jsx | 4 +-
client/src/components/vbox.store.jsx | 10 ++--
client/src/components/vbox.utils.jsx | 16 +++---
client/src/tutorial.utils.jsx | 56 +++++++++----------
7 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx
index c0a0b36d..3ed752b7 100644
--- a/client/src/components/instance.constructs.jsx
+++ b/client/src/components/instance.constructs.jsx
@@ -98,7 +98,7 @@ function Construct(props) {
const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => {
if (!itemEquip && itemEquip !== 0) return false;
if (!sk) return false;
- return sk.skill === vbox.bound[itemEquip];
+ return sk.skill === vbox.stash[itemEquip];
});
const tutorialDisableEquip = tutorialShouldDisableEquip(tutorial, iter, instance, construct);
function onClick(e) {
@@ -136,7 +136,7 @@ function Construct(props) {
return true;
}
- const equipping = skillList.includes(vbox.bound[itemEquip]) && !skill
+ const equipping = skillList.includes(vbox.stash[itemEquip]) && !skill
&& !tutorialDisableEquip && !duplicateSkill && i === construct.skills.length;
const border = () => {
if (!skill) return '';
@@ -169,7 +169,7 @@ function Construct(props) {
const s = construct.specs[i];
if (!s) {
- const equipping = specList.includes(vbox.bound[itemEquip]) && i === construct.specs.length;
+ const equipping = specList.includes(vbox.stash[itemEquip]) && i === construct.specs.length;
const classes = `${equipping ? 'equipping' : 'gray'} empty`;
return (
);
}
diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx
index f00e9b63..9d192b9c 100644
--- a/client/src/components/vbox.component.jsx
+++ b/client/src/components/vbox.component.jsx
@@ -161,7 +161,7 @@ class Vbox extends preact.Component {
function stashHdr() {
const refund = storeSelect.length === 0 && stashSelect.length === 1
- ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost
+ ? itemInfo.items.find(i => i.item === vbox.stash[stashSelect[0]]).cost
: 0;
const tutorialDisabled = tutorial && tutorial < 8
&& instance.time_control === 'Practice' && instance.rounds.length === 1;
diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx
index 97511443..cec94686 100644
--- a/client/src/components/vbox.stash.jsx
+++ b/client/src/components/vbox.stash.jsx
@@ -81,7 +81,7 @@ class stashElement extends preact.Component {
}
if (notValidCombo) {
- setInfo(vbox.bound[i]);
+ setInfo(vbox.stash[i]);
return setVboxSelected({ storeSelect: [], stashSelect: [i] });
}
@@ -123,7 +123,7 @@ class stashElement extends preact.Component {
onDragOver={ev => ev.preventDefault()}
onDrop={stashClick}
>
- {range(0, 6).map(i => stashBtn(vbox.bound[i], i))}
+ {range(0, 6).map(i => stashBtn(vbox.stash[i], i.toString()))}
);
}
diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx
index 9a168fc6..f4d1878c 100644
--- a/client/src/components/vbox.store.jsx
+++ b/client/src/components/vbox.store.jsx
@@ -32,7 +32,7 @@ class storeElement extends preact.Component {
const { storeSelect, stashSelect } = vboxSelected;
function availableBtn(v, group, index) {
- if (!v) return ;
+ if (!v) return ;
const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index);
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v);
@@ -63,7 +63,7 @@ class storeElement extends preact.Component {
const disabled = vbox.bits <= group;
return (
);
}
diff --git a/client/src/utils.jsx b/client/src/utils.jsx
index a14c684e..550c69e6 100644
--- a/client/src/utils.jsx
+++ b/client/src/utils.jsx
@@ -197,7 +197,7 @@ function postData(url = '/', data = {}) {
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, same-origin, *omit
headers: {
- Accept: 'application/json',
+ Buy: 'application/json',
'content-type': 'application/json',
},
redirect: 'error', // manual, *follow, error
diff --git a/server/src/vbox.rs b/server/src/vbox.rs
index e2507c74..fdfd1d3d 100644
--- a/server/src/vbox.rs
+++ b/server/src/vbox.rs
@@ -130,7 +130,7 @@ impl Vbox {
// check item exists
let selection = self.store
.get_mut(&item).ok_or(format_err!("no item group {:?}", item))?
- .remove(i).ok_or(format_err!("no item at index {:?} {:}", item, i))?;
+ .remove(i).ok_or(format_err!("no item at index {:?} {:}", self, i))?;
self.balance_sub(selection.cost())?;
From 91c82324e2e85ef44ffb8609813bf1defe819ca4 Mon Sep 17 00:00:00 2001
From: ntr
Date: Thu, 28 Nov 2019 16:31:37 +1000
Subject: [PATCH 5/6] clean up equipping api
---
client/src/socket.jsx | 2 +-
server/src/instance.rs | 2 +-
server/src/player.rs | 99 +++++++-----------------------------------
server/src/rpc.rs | 10 ++---
4 files changed, 20 insertions(+), 93 deletions(-)
diff --git a/client/src/socket.jsx b/client/src/socket.jsx
index ffe00b7d..a99fe130 100644
--- a/client/src/socket.jsx
+++ b/client/src/socket.jsx
@@ -84,7 +84,7 @@ function createSocket(events) {
}
function sendVboxBuyEquip(instanceId, group, index, constructId) {
- send(['VboxBuyEquip', { instance_id: instanceId, group, index, construct_id: constructId }]);
+ send(['VboxBuy', { instance_id: instanceId, group, index, construct_id: constructId }]);
events.clearInstance();
}
diff --git a/server/src/instance.rs b/server/src/instance.rs
index 0d052d08..65c17b65 100644
--- a/server/src/instance.rs
+++ b/server/src/instance.rs
@@ -497,7 +497,7 @@ impl Instance {
pub fn vbox_apply(mut self, account: Uuid, index: String, construct_id: Uuid) -> Result {
self.vbox_action_allowed(account)?;
self.account_player(account)?
- .vbox_apply(index, construct_id)?;
+ .vbox_equip(index, construct_id)?;
Ok(self)
}
diff --git a/server/src/player.rs b/server/src/player.rs
index 9b1fbeca..b0988a3a 100644
--- a/server/src/player.rs
+++ b/server/src/player.rs
@@ -174,7 +174,8 @@ impl Player {
// AAAAAAAAAAAAAAAAAAAA
// there's a bad bug here where if this apply fails
// the item in question will be silently dropped
- self.vbox_apply(i, construct_id).ok();
+ let item = self.vbox.stash.remove(&i).unwrap();
+ self.vbox_apply(item, construct_id).ok();
continue;
}
// need to buy one
@@ -228,7 +229,8 @@ impl Player {
// AAAAAAAAAAAAAAAAAAAA
// there's a bad bug here where if this apply fails
// the item in question will be silently dropped
- self.vbox_apply(i, construct_id).ok();
+ let item = self.vbox.stash.remove(&i).unwrap();
+ self.vbox_apply(item, construct_id).ok();
continue;
}
// need to buy one
@@ -267,79 +269,6 @@ impl Player {
// upgrading phase
// NYI
- // // first check if any constructs have no skills
- // // if there is one find an item in vbox that gives a skill
- // while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) {
- // if let Some(s) = self.vbox.stash.iter().position(|(i, v)| v.into_skill().is_some()) {
- // let construct_id = self.constructs[c].id;
- // self.vbox_apply(s, construct_id).expect("could not apply");
- // continue;
- // }
- // info!("no skills available...");
- // }
-
- // // now keep buying and applying items cause whynot
- // // inb4 montecarlo gan
- // loop {
- // let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) {
- // true => {
- // let mut target_construct_i = 0;
- // for (j, c) in self.constructs.iter().enumerate() {
- // if c.skills.len() < self.constructs[target_construct_i].skills.len() {
- // target_construct_i = j;
- // }
- // }
- // (target_construct_i, self.constructs[target_construct_i].id)
- // },
- // false => {
- // let i = rng.gen_range(0, 3);
- // (i, self.constructs[i].id)
- // },
- // };
-
- // let needs_skills = self.constructs[target_construct_i].skills.len() < 3;
- // let group_i = match needs_skills {
- // true => 1,
- // false => 2,
- // };
-
-
- // let num_colours = self.vbox.stash
- // .iter()
- // .filter(|(i, v)| [Item::Red, Item::Green, Item::Blue].contains(v))
- // .count();
-
- // if self.vbox.stash.len() < 3 || num_colours < 2 {
- // if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 {
- // // info!("insufficient balance");
- // break;
- // }
-
- // // get 2 colours and something else
- // let store_colours = self.vbox.store[&ItemType::Colours].len();
- // if store_colours < 2 {
- // break;
- // }
- // self.bot_vbox_accept(0).expect("could't accept colour item");
- // self.bot_vbox_accept(0).expect("could't accept colour item");
- // self.bot_vbox_accept(group_i).expect("could't accept group item");
- // }
-
- // // info!("{:?}", self.vbox.stash);
-
- // let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun];
- // let combo_i = match group_i {
- // 1 => self.vbox.stash.iter().position(|v| skills.contains(v)).expect("no skill found"),
- // 2 => self.vbox.stash.iter().position(|v| v.into_spec().is_some()).expect("no spec found"),
- // _ => panic!("unknown group_i"),
- // };
-
- // // first 2 colours can be whatever
- // self.vbox_combine(vec![0, 1, combo_i], vec![]).ok();
- // let item_i = self.vbox.stash.len() - 1;
- // self.vbox_apply(item_i, target_construct_id).ok();
- // }
-
return self;
}
@@ -359,7 +288,7 @@ impl Player {
let item = self.vbox.buy(group, &index)?;
match construct_id {
- Some(id) => { self.vbox_apply(index, id)?; },
+ Some(id) => { self.vbox_apply(item, id)?; },
None => { self.vbox.stash_add(item, None)?; },
};
@@ -376,10 +305,14 @@ impl Player {
Ok(self)
}
- pub fn vbox_apply(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> {
+ pub fn vbox_equip(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> {
let item = self.vbox.stash.remove(&index)
- .ok_or(format_err!("no item at index {:?} {:?}", self.vbox.stash, index))?;
+ .ok_or(format_err!("no item at index {:?} {:}", self, &index))?;
+ self.vbox_apply(item, construct_id)
+ }
+
+ pub fn vbox_apply(&mut self, item: Item, construct_id: Uuid) -> Result<&mut Player, Error> {
match item.effect() {
Some(ItemEffect::Skill) => {
let skill = item.into_skill().ok_or(format_err!("item {:?} has no associated skill", item))?;
@@ -455,12 +388,10 @@ impl Player {
construct.apply_modifiers(&player_colours);
}
- let equip_index = self.vbox.stash_add(target, None)?;
-
- if target_construct_id.is_some() {
- self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?;
- }
- // self.vbox.stash.sort_unstable();
+ match target_construct_id {
+ Some(cid) => { self.vbox_apply(target, cid)?; },
+ None => { self.vbox.stash_add(target, None)?; },
+ };
Ok(self)
}
diff --git a/server/src/rpc.rs b/server/src/rpc.rs
index 9f43a928..e27a62dd 100644
--- a/server/src/rpc.rs
+++ b/server/src/rpc.rs
@@ -115,8 +115,7 @@ pub enum RpcRequest {
InstanceState { instance_id: Uuid },
InstanceChat { instance_id: Uuid, index: usize },
- VboxBuy { instance_id: Uuid, group: ItemType, index: String },
- VboxBuyEquip { instance_id: Uuid, group: ItemType, index: String, construct_id: Uuid },
+ VboxBuy { instance_id: Uuid, group: ItemType, index: String, construct_id: Option },
VboxRefill { instance_id: Uuid },
VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Option>> },
VboxApply { instance_id: Uuid, construct_id: Uuid, index: String },
@@ -246,11 +245,8 @@ impl Connection {
RpcRequest::InstanceAbandon { instance_id } =>
Ok(instance_abandon(&mut tx, account, instance_id)?),
- RpcRequest::VboxBuy { instance_id, group, index } =>
- Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, None)?)),
-
- RpcRequest::VboxBuyEquip { instance_id, group, index, construct_id } =>
- Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, Some(construct_id))?)),
+ RpcRequest::VboxBuy { instance_id, group, index, construct_id } =>
+ Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, construct_id)?)),
RpcRequest::VboxApply { instance_id, construct_id, index } =>
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
From 11ec807ae23c9f6abd59caf6e0411968afe26ad4 Mon Sep 17 00:00:00 2001
From: ntr
Date: Thu, 28 Nov 2019 17:30:06 +1000
Subject: [PATCH 6/6] fix highlighting issues
---
client/src/actions.jsx | 2 +-
client/src/components/vbox.utils.jsx | 11 ++++++++---
client/src/keyboard.jsx | 1 +
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/client/src/actions.jsx b/client/src/actions.jsx
index 00b32e31..f6745548 100644
--- a/client/src/actions.jsx
+++ b/client/src/actions.jsx
@@ -49,7 +49,7 @@ export const setTeamSelect = value => ({ type: 'SET_TEAM_SELECT', value: Array.f
export const setTutorial = value => ({ type: 'SET_TUTORIAL', value });
export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value });
-export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value });
+export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value: Object.create(value) });
export const setVboxCombiner = value => ({ type: 'SET_VBOX_COMBINER', value });
export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value });
export const setVboxInfo = value => ({ type: 'SET_VBOX_INFO', value });
diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx
index e40a0b2e..030d308e 100644
--- a/client/src/components/vbox.utils.jsx
+++ b/client/src/components/vbox.utils.jsx
@@ -21,7 +21,7 @@ function setVboxState(dispatch, vboxSelected, state) {
let vboxCombiner = false;
let vboxHighlight = false;
- if (!(storeSelect.length === 0 && stashSelect.length === 0)) {
+ if (storeSelect.length || stashSelect.length) {
vboxHighlight = [];
const stashItems = stashSelect.map(j => vbox.stash[j]);
const shopItems = storeSelect.map(j => vbox.store[j[0]][j[1]]);
@@ -66,7 +66,7 @@ function setVboxState(dispatch, vboxSelected, state) {
dispatch(actions.setVboxInfo(vboxInfo()));
dispatch(actions.setVboxCombiner(vboxCombiner));
- dispatch(actions.setVboxHighlight(vboxHighlight));
+ dispatch(actions.setVboxHighlight(vboxHighlight.length ? vboxHighlight : null));
}
function genItemInfo(item, itemInfo, player) {
@@ -124,5 +124,10 @@ function genItemInfo(item, itemInfo, player) {
);
}
+function cost(group) {
+ if (group === 'Colours') return 1;
+ if (group === 'Skills') return 2;
+ if (group === 'Specs') return 3;
+};
-module.exports = { setVboxState, genItemInfo };
+module.exports = { setVboxState, genItemInfo, cost };
diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx
index 43d7343b..cca738f9 100644
--- a/client/src/keyboard.jsx
+++ b/client/src/keyboard.jsx
@@ -10,6 +10,7 @@ function setupKeys(store) {
key('esc', () => store.dispatch(actions.setInfo(null)));
key('esc', () => store.dispatch(actions.setItemUnequip([])));
key('esc', () => store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })));
+ key('esc', () => store.dispatch(actions.setVboxHighlight(null)));
key('esc', () => store.dispatch(actions.setMtxActive(null)));
}