bugs ahoy and icons
This commit is contained in:
parent
4747bc7dec
commit
5b5de416e1
15
client/assets/icons/colour.lines.svg
Normal file
15
client/assets/icons/colour.lines.svg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1.375in" height="0.555556in"
|
||||||
|
viewBox="0 0 99 40">
|
||||||
|
<path id="Unnamed #8"
|
||||||
|
fill="none" stroke="black" stroke-width="1"
|
||||||
|
d="M 3.91,34.64
|
||||||
|
C 3.91,34.64 95.00,34.64 95.00,34.64M 3.91,25.09
|
||||||
|
C 3.91,25.09 95.00,25.09 95.00,25.09M 3.82,14.00
|
||||||
|
C 3.82,14.00 94.91,14.00 94.91,14.00M 3.91,4.00
|
||||||
|
C 3.91,4.00 95.00,4.00 95.00,4.00" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 624 B |
13
client/assets/icons/cross.svg
Normal file
13
client/assets/icons/cross.svg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1.38889in" height="0.555556in"
|
||||||
|
viewBox="0 0 100 40">
|
||||||
|
<path id="Path"
|
||||||
|
fill="none" stroke="black" stroke-width="1"
|
||||||
|
d="M 50.00,4.00
|
||||||
|
C 50.00,4.00 50.00,36.00 50.00,36.00M 4.00,20.00
|
||||||
|
C 4.00,20.00 96.00,20.00 96.00,20.00" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 505 B |
18
client/assets/icons/hourglass.lines.svg
Normal file
18
client/assets/icons/hourglass.lines.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1.375in" height="0.555556in"
|
||||||
|
viewBox="0 0 99 40">
|
||||||
|
<path id="Path #6"
|
||||||
|
fill="none" stroke="black" stroke-width="1"
|
||||||
|
d="M 4.00,35.00
|
||||||
|
C 4.00,35.00 95.00,35.00 95.00,35.00M 8.91,29.91
|
||||||
|
C 8.91,29.91 89.91,29.91 89.91,29.91M 14.91,24.91
|
||||||
|
C 14.91,24.91 85.00,25.00 85.00,25.00M 21.00,19.00
|
||||||
|
C 21.00,19.00 78.91,18.91 78.91,18.91M 15.09,14.18
|
||||||
|
C 15.09,14.18 85.00,14.09 85.00,14.09M 9.00,9.09
|
||||||
|
C 9.00,9.09 89.91,9.09 89.91,9.09M 4.00,4.09
|
||||||
|
C 4.00,4.09 94.91,4.09 94.91,4.09" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 803 B |
@ -412,8 +412,8 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.vbox-table td svg {
|
.vbox-table td svg {
|
||||||
stroke-width: 1.5px;
|
stroke-width: 2px;
|
||||||
height: 95%;
|
height: 96%;
|
||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -229,7 +229,7 @@ module.exports = {
|
|||||||
upgrades: 'combine with 2 red / blue / green',
|
upgrades: 'combine with 2 red / blue / green',
|
||||||
},
|
},
|
||||||
|
|
||||||
LifeI: {
|
GreenLifeI: {
|
||||||
description: 'Increases life',
|
description: 'Increases life',
|
||||||
colours: ['green'],
|
colours: ['green'],
|
||||||
thresholds: [5, 10, 20],
|
thresholds: [5, 10, 20],
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
|
|
||||||
module.exports = function triangle(classes) {
|
module.exports = function vboxColour(classes) {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 40" className={classes} >
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 40" className={classes} >
|
||||||
<path id="Unnamed"
|
<path id="Unnamed"
|
||||||
fill="none" strokeWidth="1px"
|
fill="none" strokeWidth="1px"
|
||||||
d="M 21.18,19.55
|
d="M 20,20
|
||||||
C 21.18,19.55 78.55,19.55 78.55,19.55M 85.00,14.00
|
C 20,20 80,20 80,20M 85.00,15.00
|
||||||
C 85.00,14.00 85.00,25.00 85.00,25.00
|
C 85.00,15.00 85.00,25.00 85.00,25.00
|
||||||
85.00,25.00 15.00,25.00 15.00,25.00
|
85.00,25.00 15.00,25.00 15.00,25.00
|
||||||
15.00,25.00 15.00,14.00 15.00,14.00
|
15.00,25.00 15.00,15.00 15.00,15.00
|
||||||
15.00,14.00 85.00,14.00 85.00,14.00 Z
|
15.00,15.00 85.00,15.00 85.00,15.00 Z
|
||||||
M 85.00,14.00
|
M 85.00,15.00
|
||||||
C 85.00,14.00 85.00,25.00 85.00,25.00
|
C 85.00,15.00 85.00,25.00 85.00,25.00
|
||||||
85.00,25.00 15.00,25.00 15.00,25.00
|
85.00,25.00 15.00,25.00 15.00,25.00
|
||||||
15.00,25.00 15.00,14.00 15.00,14.00
|
15.00,25.00 15.00,15.00 15.00,15.00
|
||||||
15.00,14.00 85.00,14.00 85.00,14.00 Z
|
15.00,15.00 85.00,15.00 85.00,15.00 Z
|
||||||
M 95.00,4.00
|
M 95.00,5.00
|
||||||
C 95.00,4.00 95.00,35.00 95.00,35.00
|
C 95.00,5.00 95.00,35.00 95.00,35.00
|
||||||
95.00,35.00 4.00,35.00 4.00,35.00
|
95.00,35.00 5.00,35.00 5.00,35.00
|
||||||
4.00,35.00 4.00,4.00 4.00,4.00
|
5.00,35.00 5.00,5.00 5.00,5.00
|
||||||
4.00,4.00 95.00,4.00 95.00,4.00 Z
|
5.00,5.00 95.00,5.00 95.00,5.00 Z
|
||||||
M 90.00,9.00
|
M 90.00,10.00
|
||||||
C 90.00,9.00 90.00,30.00 90.00,30.00
|
C 90.00,10.00 90.00,30.00 90.00,30.00
|
||||||
90.00,30.00 9.00,30.00 9.00,30.00
|
90.00,30.00 10.00,30.00 10.00,30.00
|
||||||
9.00,30.00 9.00,9.00 9.00,9.00
|
10.00,30.00 10.00,10.00 10.00,10.00
|
||||||
9.00,9.00 90.00,9.00 90.00,9.00 Z" />
|
10.00,10.00 90.00,10.00 90.00,10.00 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
@ -92,9 +92,9 @@ const SPECS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const COLOUR_ICONS = {
|
const COLOUR_ICONS = {
|
||||||
red: { colour: 'red', caption: 'red', svg: shapes.hexagon },
|
red: { colour: 'red', caption: 'red', svg: shapes.square },
|
||||||
blue: { colour: 'blue', caption: 'blue', svg: shapes.hexagon },
|
blue: { colour: 'blue', caption: 'blue', svg: shapes.square },
|
||||||
green: { colour: 'green', caption: 'green', svg: shapes.hexagon },
|
green: { colour: 'green', caption: 'green', svg: shapes.square },
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@ -270,7 +270,13 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (team_id, mob_id, target_id, s) in pve_skills {
|
for (team_id, mob_id, target_id, s) in pve_skills {
|
||||||
self.add_skill(team_id, mob_id, target_id, s).expect("unable to add pve mob skill");
|
match self.add_skill(team_id, mob_id, target_id, s) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
println!("{:?}", self.cryp_by_id(mob_id));
|
||||||
|
panic!("{:?} unable to add pve mob skill {:?}", e, s);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
|
|||||||
@ -59,7 +59,9 @@ impl Instance {
|
|||||||
self.players = iter::repeat_with(|| {
|
self.players = iter::repeat_with(|| {
|
||||||
let bot_id = Uuid::new_v4();
|
let bot_id = Uuid::new_v4();
|
||||||
let cryps = instance_mobs(bot_id);
|
let cryps = instance_mobs(bot_id);
|
||||||
Player::new(bot_id, self.id, &bot_id.to_string(), cryps).set_bot(true)
|
let mut p = Player::new(bot_id, self.id, &bot_id.to_string(), cryps).set_bot(true);
|
||||||
|
p.autobuy();
|
||||||
|
p
|
||||||
})
|
})
|
||||||
.take(15)
|
.take(15)
|
||||||
.collect::<Vec<Player>>();
|
.collect::<Vec<Player>>();
|
||||||
@ -199,16 +201,7 @@ impl Instance {
|
|||||||
fn bot_vbox_phase(&mut self) -> &mut Instance {
|
fn bot_vbox_phase(&mut self) -> &mut Instance {
|
||||||
for bot in self.players.iter_mut().filter(|p| p.bot) {
|
for bot in self.players.iter_mut().filter(|p| p.bot) {
|
||||||
bot.vbox.fill();
|
bot.vbox.fill();
|
||||||
|
bot.autobuy();
|
||||||
// paths for what to do
|
|
||||||
// use a spec
|
|
||||||
// craft a spec
|
|
||||||
// craft a skill
|
|
||||||
// check for cryps w/ no skills
|
|
||||||
// create a skill()
|
|
||||||
// find base
|
|
||||||
// pick 2 random colours
|
|
||||||
|
|
||||||
bot.set_ready(true);
|
bot.set_ready(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,6 +578,7 @@ mod tests {
|
|||||||
let player_account = Uuid::new_v4();
|
let player_account = Uuid::new_v4();
|
||||||
let cryps = instance_mobs(player_account);
|
let cryps = instance_mobs(player_account);
|
||||||
let mut player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true);
|
let mut player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true);
|
||||||
|
player.autobuy();
|
||||||
|
|
||||||
instance.add_player(player.clone());
|
instance.add_player(player.clone());
|
||||||
assert!(instance.can_start());
|
assert!(instance.can_start());
|
||||||
@ -605,4 +599,13 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(instance.rounds.len(), 3);
|
assert_eq!(instance.rounds.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn instance_bot_vbox_test() {
|
||||||
|
let mut instance = Instance::new();
|
||||||
|
let player_account = Uuid::new_v4();
|
||||||
|
let cryps = instance_mobs(player_account);
|
||||||
|
let mut player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -33,8 +33,8 @@ pub fn generate_mob() -> Cryp {
|
|||||||
pub fn instance_mobs(team_id: Uuid) -> Vec<Cryp> {
|
pub fn instance_mobs(team_id: Uuid) -> Vec<Cryp> {
|
||||||
iter::repeat_with(||
|
iter::repeat_with(||
|
||||||
generate_mob()
|
generate_mob()
|
||||||
.set_account(team_id)
|
.set_account(team_id))
|
||||||
.learn(Skill::Attack))
|
// .learn(Skill::Attack))
|
||||||
.take(3)
|
.take(3)
|
||||||
.collect::<Vec<Cryp>>()
|
.collect::<Vec<Cryp>>()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use rand::prelude::*;
|
||||||
|
|
||||||
use serde_cbor::{from_slice, to_vec};
|
use serde_cbor::{from_slice, to_vec};
|
||||||
|
|
||||||
@ -8,11 +9,13 @@ use failure::Error;
|
|||||||
use failure::err_msg;
|
use failure::err_msg;
|
||||||
|
|
||||||
use account::Account;
|
use account::Account;
|
||||||
use cryp::{Cryp, cryp_get};
|
use cryp::{Cryp, Colours, cryp_get};
|
||||||
use vbox::{Vbox};
|
use vbox::{Vbox, Var, VarEffect};
|
||||||
use rpc::{PlayerStateParams, PlayerCrypsSetParams};
|
use rpc::{PlayerStateParams, PlayerCrypsSetParams};
|
||||||
use instance::{instance_get, instance_update};
|
use instance::{instance_get, instance_update};
|
||||||
|
|
||||||
|
const DISCARD_COST: u16 = 5;
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
|
||||||
pub struct Score {
|
pub struct Score {
|
||||||
pub wins: u8,
|
pub wins: u8,
|
||||||
@ -74,6 +77,193 @@ impl Player {
|
|||||||
pub fn cryp_get(&mut self, id: Uuid) -> Result<&mut Cryp, Error> {
|
pub fn cryp_get(&mut self, id: Uuid) -> Result<&mut Cryp, Error> {
|
||||||
self.cryps.iter_mut().find(|c| c.id == id).ok_or(err_msg("cryp not found"))
|
self.cryps.iter_mut().find(|c| c.id == id).ok_or(err_msg("cryp not found"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn autobuy(&mut self) -> &mut Player {
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
|
// first check if any cryps have no skills
|
||||||
|
// if there is one find an item in vbox that gives a skill
|
||||||
|
while let Some(c) = self.cryps.iter().position(|c| c.skills.len() == 0) {
|
||||||
|
if let Some(s) = self.vbox.bound.iter().position(|v| v.into_skill().is_some()) {
|
||||||
|
let cryp_id = self.cryps[c].id;
|
||||||
|
self.vbox_apply(s, cryp_id).expect("could not apply");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
println!("no skills available...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// now keep buying and applying items cause whynot
|
||||||
|
// inb4 montecarlo gan
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let (target_cryp_i, target_cryp_id) = match self.cryps.iter().any(|c| c.skills.len() < 3) {
|
||||||
|
true => {
|
||||||
|
let mut target_cryp_i = 0;
|
||||||
|
for (j, c) in self.cryps.iter().enumerate() {
|
||||||
|
if c.skills.len() < self.cryps[target_cryp_i].skills.len() {
|
||||||
|
target_cryp_i = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(target_cryp_i, self.cryps[target_cryp_i].id)
|
||||||
|
},
|
||||||
|
false => {
|
||||||
|
let i = rng.gen_range(0, 3);
|
||||||
|
(i, self.cryps[i].id)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let needs_skills = self.cryps[target_cryp_i].skills.len() < 3;
|
||||||
|
let group_i = match needs_skills {
|
||||||
|
true => 1,
|
||||||
|
false => 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.vbox.bound.len() < 3 {
|
||||||
|
if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 {
|
||||||
|
// println!("insufficient balance");
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get 2 colours and something else
|
||||||
|
if self.vbox.free[0].len() < 2 {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
self.vbox_accept(0, 0).expect("could't accept colour 0");
|
||||||
|
self.vbox_accept(0, 0).expect("could't accept colour 1");
|
||||||
|
self.vbox_accept(group_i, 0).expect("could't accept group 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("{:?}", self.vbox.bound);
|
||||||
|
|
||||||
|
let skills = [Var::Attack, Var::Block, Var::Buff, Var::Debuff, Var::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"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// first 2 colours can be whatever
|
||||||
|
match self.vbox_combine(vec![0, 1, combo_i]) {
|
||||||
|
Ok(_) => {
|
||||||
|
// println!("refined {:?}", self.vbox.bound[self.vbox.bound.len() - 1]);
|
||||||
|
}
|
||||||
|
Err(e) => println!("{:?}", e),
|
||||||
|
};
|
||||||
|
|
||||||
|
let var_i = self.vbox.bound.len() - 1;
|
||||||
|
match self.vbox_apply(var_i, target_cryp_id) {
|
||||||
|
Ok(_) => {
|
||||||
|
// println!("{:?} improved", self.cryps[target_cryp_i].name);
|
||||||
|
},
|
||||||
|
Err(e) => println!("{:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_discard(&mut self) -> Result<&mut Player, Error> {
|
||||||
|
self.vbox.balance_sub(DISCARD_COST)?;
|
||||||
|
self.vbox.fill();
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_accept(&mut self, group: usize, index: usize) -> Result<&mut Player, Error> {
|
||||||
|
self.vbox.accept(group, index)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_combine(&mut self, indices: Vec<usize>) -> Result<&mut Player, Error> {
|
||||||
|
self.vbox.combine(indices)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_reclaim(&mut self, index: usize) -> Result<&mut Player, Error> {
|
||||||
|
self.vbox.reclaim(index)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_apply(&mut self, index: usize, cryp_id: Uuid) -> Result<&mut Player, Error> {
|
||||||
|
let var = self.vbox.bound.remove(index);
|
||||||
|
|
||||||
|
match var.effect() {
|
||||||
|
Some(VarEffect::Skill) => {
|
||||||
|
let skill = var.into_skill().ok_or(format_err!("var {:?} has no associated skill", var))?;
|
||||||
|
let cryp = self.cryp_get(cryp_id)?;
|
||||||
|
// done here because i teach them a tonne of skills for tests
|
||||||
|
let max_skills = 3;
|
||||||
|
if cryp.skills.len() >= max_skills {
|
||||||
|
return Err(format_err!("cryp at max skills ({:?})", max_skills));
|
||||||
|
}
|
||||||
|
|
||||||
|
if cryp.knows(skill) {
|
||||||
|
return Err(format_err!("cryp already knows skill ({:?})" , skill));
|
||||||
|
}
|
||||||
|
|
||||||
|
cryp.learn_mut(skill);
|
||||||
|
},
|
||||||
|
Some(VarEffect::Spec) => {
|
||||||
|
let spec = var.into_spec().ok_or(format_err!("var {:?} has no associated spec", var))?;
|
||||||
|
let cryp = self.cryp_get(cryp_id)?;
|
||||||
|
cryp.spec_add(spec)?;
|
||||||
|
|
||||||
|
},
|
||||||
|
None => return Err(err_msg("var has no effect on cryps")),
|
||||||
|
}
|
||||||
|
|
||||||
|
// now the var has been applied
|
||||||
|
// recalculate the stats of the whole team
|
||||||
|
let team_colours = self.cryps.iter().fold(Colours::new(), |tc, c| {
|
||||||
|
Colours {
|
||||||
|
red: tc.red + c.colours.red,
|
||||||
|
green: tc.green + c.colours.green,
|
||||||
|
blue: tc.blue + c.colours.blue
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for cryp in self.cryps.iter_mut() {
|
||||||
|
cryp.apply_modifiers(&team_colours);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vbox_unequip(&mut self, target: Var, cryp_id: Uuid) -> Result<&mut Player, Error> {
|
||||||
|
if self.vbox.bound.len() >= 9 {
|
||||||
|
return Err(err_msg("too many vars bound"));
|
||||||
|
}
|
||||||
|
|
||||||
|
match target.effect() {
|
||||||
|
Some(VarEffect::Skill) => {
|
||||||
|
let skill = target.into_skill().ok_or(format_err!("var {:?} has no associated skill", target))?;
|
||||||
|
let cryp = self.cryp_get(cryp_id)?;
|
||||||
|
cryp.forget(skill)?;
|
||||||
|
},
|
||||||
|
Some(VarEffect::Spec) => {
|
||||||
|
let spec = target.into_spec().ok_or(format_err!("var {:?} has no associated spec", target))?;
|
||||||
|
let cryp = self.cryp_get(cryp_id)?;
|
||||||
|
cryp.spec_remove(spec)?;
|
||||||
|
},
|
||||||
|
None => return Err(err_msg("var has no effect on cryps")),
|
||||||
|
}
|
||||||
|
|
||||||
|
// now the var has been applied
|
||||||
|
// recalculate the stats of the whole team
|
||||||
|
let team_colours = self.cryps.iter().fold(Colours::new(), |tc, c| {
|
||||||
|
Colours {
|
||||||
|
red: tc.red + c.colours.red,
|
||||||
|
green: tc.green + c.colours.green,
|
||||||
|
blue: tc.blue + c.colours.blue
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for cryp in self.cryps.iter_mut() {
|
||||||
|
cryp.apply_modifiers(&team_colours);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.vbox.bound.push(target);
|
||||||
|
self.vbox.bound.sort_unstable();
|
||||||
|
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn player_get(tx: &mut Transaction, account_id: Uuid, instance_id: Uuid) -> Result<Player, Error> {
|
pub fn player_get(tx: &mut Transaction, account_id: Uuid, instance_id: Uuid) -> Result<Player, Error> {
|
||||||
@ -191,3 +381,19 @@ pub fn player_mm_cryps_set(params: PlayerCrypsSetParams, tx: &mut Transaction, a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use mob::instance_mobs;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn player_bot_vbox_test() {
|
||||||
|
let player_account = Uuid::new_v4();
|
||||||
|
let cryps = instance_mobs(player_account);
|
||||||
|
let mut player = Player::new(player_account, Uuid::new_v4(), &"test".to_string(), cryps).set_bot(true);
|
||||||
|
|
||||||
|
player.autobuy();
|
||||||
|
println!("{:#?}", player);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1075,23 +1075,23 @@ fn silence(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn purge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
|
fn purge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
|
||||||
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
|
while let Some(i) = target.effects
|
||||||
if [Category::BlueBuff, Category::RedBuff].contains(&ce.effect.category()) {
|
.iter()
|
||||||
target.effects.remove(i);
|
.position(|ce| [Category::BlueBuff, Category::RedBuff].contains(&ce.effect.category())) {
|
||||||
|
let ce = target.effects.remove(i);
|
||||||
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
|
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn purify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
|
fn purify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
|
||||||
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
|
while let Some(i) = target.effects
|
||||||
if [Category::BlueDebuff, Category::RedDebuff].contains(&ce.effect.category()) {
|
.iter()
|
||||||
target.effects.remove(i);
|
.position(|ce| [Category::BlueDebuff, Category::RedDebuff].contains(&ce.effect.category())) {
|
||||||
|
let ce = target.effects.remove(i);
|
||||||
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
|
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,7 +101,7 @@ pub enum Var {
|
|||||||
TestSiphon,
|
TestSiphon,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VarEffect {
|
pub enum VarEffect {
|
||||||
Skill,
|
Skill,
|
||||||
Spec,
|
Spec,
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ impl Var {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effect(&self) -> Option<VarEffect> {
|
pub fn effect(&self) -> Option<VarEffect> {
|
||||||
if let Some(_skill) = self.into_skill() {
|
if let Some(_skill) = self.into_skill() {
|
||||||
return Some(VarEffect::Skill);
|
return Some(VarEffect::Skill);
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ impl Var {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_skill(&self) -> Option<Skill> {
|
pub fn into_skill(&self) -> Option<Skill> {
|
||||||
match self {
|
match self {
|
||||||
Var::Attack => Some(Skill::Attack),
|
Var::Attack => Some(Skill::Attack),
|
||||||
Var::Amplify => Some(Skill::Amplify),
|
Var::Amplify => Some(Skill::Amplify),
|
||||||
@ -215,7 +215,7 @@ impl Var {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_spec(&self) -> Option<Spec> {
|
pub fn into_spec(&self) -> Option<Spec> {
|
||||||
match *self {
|
match *self {
|
||||||
Var::Speed => Some(Spec::Speed),
|
Var::Speed => Some(Spec::Speed),
|
||||||
Var::RedSpeedI => Some(Spec::RedSpeedI),
|
Var::RedSpeedI => Some(Spec::RedSpeedI),
|
||||||
@ -255,6 +255,7 @@ impl From<Skill> for Var {
|
|||||||
Skill::Blast => Var::Blast,
|
Skill::Blast => Var::Blast,
|
||||||
Skill::Block => Var::Block,
|
Skill::Block => Var::Block,
|
||||||
Skill::Curse => Var::Curse,
|
Skill::Curse => Var::Curse,
|
||||||
|
Skill::Clutch => Var::Clutch,
|
||||||
Skill::Decay => Var::Decay,
|
Skill::Decay => Var::Decay,
|
||||||
Skill::Empower => Var::Empower,
|
Skill::Empower => Var::Empower,
|
||||||
Skill::Haste => Var::Haste,
|
Skill::Haste => Var::Haste,
|
||||||
@ -363,7 +364,7 @@ fn get_combos() -> Vec<Combo> {
|
|||||||
Combo { units: vec![Var::Attack, Var::Blue, Var::Blue], var: Var::Blast },
|
Combo { units: vec![Var::Attack, Var::Blue, Var::Blue], var: Var::Blast },
|
||||||
Combo { units: vec![Var::Attack, Var::Red, Var::Green], var: Var::Purify },
|
Combo { units: vec![Var::Attack, Var::Red, Var::Green], var: Var::Purify },
|
||||||
Combo { units: vec![Var::Attack, Var::Green, Var::Blue], var: Var::Decay },
|
Combo { units: vec![Var::Attack, Var::Green, Var::Blue], var: Var::Decay },
|
||||||
// Combo { units: vec![Var::Attack, Var::Red, Var::Blue], var: Var::Blast },
|
Combo { units: vec![Var::Attack, Var::Red, Var::Blue], var: Var::Blast }, // AAAAAAAAAAAAAAAAAA
|
||||||
|
|
||||||
Combo { units: vec![Var::Damage, Var::Red, Var::Red], var: Var::RedDamageI },
|
Combo { units: vec![Var::Damage, Var::Red, Var::Red], var: Var::RedDamageI },
|
||||||
Combo { units: vec![Var::Damage, Var::Green, Var::Green], var: Var::GreenDamageI },
|
Combo { units: vec![Var::Damage, Var::Green, Var::Green], var: Var::GreenDamageI },
|
||||||
@ -495,6 +496,7 @@ impl Vbox {
|
|||||||
|
|
||||||
// actually move
|
// actually move
|
||||||
self.bound.push(self.free[i].remove(j));
|
self.bound.push(self.free[i].remove(j));
|
||||||
|
self.bound.sort_unstable();
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
@ -535,118 +537,45 @@ impl Vbox {
|
|||||||
let combo = combos.iter().find(|c| c.units == input).ok_or(err_msg("not a combo"))?;
|
let combo = combos.iter().find(|c| c.units == input).ok_or(err_msg("not a combo"))?;
|
||||||
|
|
||||||
self.bound.push(combo.var);
|
self.bound.push(combo.var);
|
||||||
|
self.bound.sort_unstable();
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DISCARD_COST: u16 = 5;
|
|
||||||
|
|
||||||
pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
player.vbox.balance_sub(DISCARD_COST)?;
|
player.vbox_discard()?;
|
||||||
player.vbox.fill();
|
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
player.vbox.accept(params.group, params.index)?;
|
player.vbox_accept(params.group, params.index)?;
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
player.vbox.combine(params.indices)?;
|
player.vbox_combine(params.indices)?;
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_reclaim(params: VboxReclaimParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_reclaim(params: VboxReclaimParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
player.vbox.reclaim(params.index)?;
|
player.vbox_reclaim(params.index)?;
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
let var = player.vbox.bound.remove(params.index);
|
player.vbox_apply(params.index, params.cryp_id)?;
|
||||||
|
|
||||||
match var.effect() {
|
|
||||||
Some(VarEffect::Skill) => {
|
|
||||||
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 = 3;
|
|
||||||
if cryp.skills.len() >= max_skills {
|
|
||||||
return Err(format_err!("cryp at max skills ({:?})", max_skills));
|
|
||||||
}
|
|
||||||
|
|
||||||
cryp.learn_mut(skill);
|
|
||||||
},
|
|
||||||
Some(VarEffect::Spec) => {
|
|
||||||
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)?;
|
|
||||||
|
|
||||||
},
|
|
||||||
None => return Err(err_msg("var has no effect on cryps")),
|
|
||||||
}
|
|
||||||
|
|
||||||
// now the var has been applied
|
|
||||||
// recalculate the stats of the whole team
|
|
||||||
let team_colours = player.cryps.iter().fold(Colours::new(), |tc, c| {
|
|
||||||
Colours {
|
|
||||||
red: tc.red + c.colours.red,
|
|
||||||
green: tc.green + c.colours.green,
|
|
||||||
blue: tc.blue + c.colours.blue
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for cryp in player.cryps.iter_mut() {
|
|
||||||
cryp.apply_modifiers(&team_colours);
|
|
||||||
}
|
|
||||||
|
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_unequip(params: VboxUnequipParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
pub fn vbox_unequip(params: VboxUnequipParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||||
|
player.vbox_unequip(params.target, params.cryp_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")),
|
|
||||||
}
|
|
||||||
|
|
||||||
// now the var has been applied
|
|
||||||
// recalculate the stats of the whole team
|
|
||||||
let team_colours = player.cryps.iter().fold(Colours::new(), |tc, c| {
|
|
||||||
Colours {
|
|
||||||
red: tc.red + c.colours.red,
|
|
||||||
green: tc.green + c.colours.green,
|
|
||||||
blue: tc.blue + c.colours.blue
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for cryp in player.cryps.iter_mut() {
|
|
||||||
cryp.apply_modifiers(&team_colours);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.vbox.bound.push(params.target);
|
|
||||||
return player_update(tx, player, false);
|
return player_update(tx, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user