move item into its own mod

This commit is contained in:
ntr 2019-05-20 12:54:10 +10:00
parent 331844f904
commit b35909e231
20 changed files with 469 additions and 731 deletions

View File

@ -1,4 +1,4 @@
# vbox_info -> # item_info ->
combos [strike, [R R Attack]] combos [strike, [R R Attack]]
specs [spec [bonus amount, [r g b]] specs [spec [bonus amount, [r g b]]

View File

@ -4,8 +4,8 @@ export const setAccount = value => ({ type: SET_ACCOUNT, value });
export const SET_CRYPS = 'SET_CRYPS'; export const SET_CRYPS = 'SET_CRYPS';
export const setCryps = value => ({ type: SET_CRYPS, value }); export const setCryps = value => ({ type: SET_CRYPS, value });
export const SET_VBOX_INFO = 'SET_VBOX_INFO'; export const SET_ITEM_INFO = 'SET_ITEM_INFO';
export const setVboxInfo = value => ({ type: SET_VBOX_INFO, value }); export const setItemInfo = value => ({ type: SET_ITEM_INFO, value });
export const SET_SKIP = 'SET_SKIP'; export const SET_SKIP = 'SET_SKIP';
export const setSkip = value => ({ type: SET_SKIP, value }); export const setSkip = value => ({ type: SET_SKIP, value });

View File

@ -15,7 +15,7 @@ function Info(args) {
sendUnequip, sendUnequip,
instance, instance,
player, player,
vboxInfo, itemInfo,
vboxHidden, vboxHidden,
} = args; } = args;
@ -166,7 +166,7 @@ function Info(args) {
if (!player) return false; if (!player) return false;
if (!(combiner.every(u => u === null))) { if (!(combiner.every(u => u === null))) {
const filteredCombos = vboxInfo.combos const filteredCombos = itemInfo.combos
.filter(combo => combiner.every(u => u === null .filter(combo => combiner.every(u => u === null
|| combo.units.includes(player.vbox.bound[u]))); || combo.units.includes(player.vbox.bound[u])));
if (filteredCombos.length > 6) return false; if (filteredCombos.length > 6) return false;
@ -183,7 +183,7 @@ function Info(args) {
</table> </table>
); );
} }
const vboxCombos = vboxInfo.combos.filter(c => c.units.includes(info[1])); const vboxCombos = itemInfo.combos.filter(c => c.units.includes(info[1]));
if (vboxCombos.length > 6) return false; if (vboxCombos.length > 6) return false;
return ( return (
<table> <table>

View File

@ -11,7 +11,7 @@ const addState = connect(
info, info,
ws, ws,
instance, instance,
vboxInfo, itemInfo,
vboxHidden, vboxHidden,
player, player,
} = state; } = state;
@ -27,7 +27,7 @@ const addState = connect(
sendUnequip, sendUnequip,
instance, instance,
player, player,
vboxInfo, itemInfo,
vboxHidden, vboxHidden,
}; };
}, },

View File

@ -8,8 +8,8 @@ const shapes = require('./shapes');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { activeCryp, player, vboxInfo } = state; const { activeCryp, player, itemInfo } = state;
return { activeCryp, player, vboxInfo }; return { activeCryp, player, itemInfo };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -38,7 +38,7 @@ function InfoCryp(args) {
const { const {
activeCryp, activeCryp,
player, player,
vboxInfo, itemInfo,
setVboxHidden, setVboxHidden,
setInfo, setInfo,
@ -52,8 +52,8 @@ function InfoCryp(args) {
if (!cryp) return false; if (!cryp) return false;
function setHighlight(type) { function setHighlight(type) {
if (type === 'skill') return setVboxHighlight(vboxInfo.items.filter(v => v.skill).map(v => v.v)); if (type === 'skill') return setVboxHighlight(itemInfo.items.filter(v => v.skill).map(v => v.v));
if (type === 'spec') return setVboxHighlight(vboxInfo.items.filter(v => v.spec).map(v => v.v)); if (type === 'spec') return setVboxHighlight(itemInfo.items.filter(v => v.spec).map(v => v.v));
return false; return false;
} }

View File

@ -8,7 +8,7 @@ const actions = require('../actions');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { ws, instance, player, account, vboxHidden, vboxInfo, activeItem, activeCryp } = state; const { ws, instance, player, account, vboxHidden, itemInfo, activeItem, activeCryp } = state;
function sendInstanceReady() { function sendInstanceReady() {
return ws.sendInstanceReady(instance.id); return ws.sendInstanceReady(instance.id);
@ -18,7 +18,7 @@ const addState = connect(
return ws.sendVboxApply(instance.id, crypId, i); return ws.sendVboxApply(instance.id, crypId, i);
} }
return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, vboxInfo, activeItem, activeCryp }; return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, itemInfo, activeItem, activeCryp };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -57,12 +57,12 @@ function Cryp(props) {
setInfo, setInfo,
setActiveCryp, setActiveCryp,
setVboxHighlight, setVboxHighlight,
vboxInfo, itemInfo,
} = props; } = props;
function setHighlight(type) { function setHighlight(type) {
if (type === 'skill') return setVboxHighlight(vboxInfo.items.filter(v => v.skill).map(v => v.v)); if (type === 'skill') return setVboxHighlight(itemInfo.items.filter(v => v.skill).map(v => v.v));
if (type === 'spec') return setVboxHighlight(vboxInfo.items.filter(v => v.spec).map(v => v.v)); if (type === 'spec') return setVboxHighlight(itemInfo.items.filter(v => v.spec).map(v => v.v));
return false; return false;
} }
@ -74,8 +74,8 @@ function Cryp(props) {
} }
const { vbox } = player; const { vbox } = player;
const skillList = vboxInfo.items.filter(v => v.skill).map(v => v.v); const skillList = itemInfo.items.filter(v => v.skill).map(v => v.v);
const specList = vboxInfo.items.filter(v => v.spec).map(v => v.v); const specList = itemInfo.items.filter(v => v.spec).map(v => v.v);
const skills = range(0, 3).map(i => { const skills = range(0, 3).map(i => {
const skill = cryp.skills[i]; const skill = cryp.skills[i];
@ -194,7 +194,7 @@ function InstanceCryps(props) {
sendVboxApply, sendVboxApply,
vboxHidden, vboxHidden,
vboxInfo, itemInfo,
setVboxHighlight, setVboxHighlight,
} = props; } = props;
@ -202,7 +202,7 @@ function InstanceCryps(props) {
if (instance.phase === 'Lobby') return false; if (instance.phase === 'Lobby') return false;
const cryps = player.cryps.map((c, i) => Cryp({ const cryps = player.cryps.map((c, i) => Cryp({
activeCryp, activeItem, cryp: c, player, sendVboxApply, setInfo, setActiveCryp, vboxInfo, setVboxHighlight, activeCryp, activeItem, cryp: c, player, sendVboxApply, setInfo, setActiveCryp, itemInfo, setVboxHighlight,
})); }));
const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`; const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`;

View File

@ -7,13 +7,13 @@ const { convertItem, SPECS } = require('./../utils');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { player, vboxInfo, info, ws, instance } = state; const { player, itemInfo, info, ws, instance } = state;
function sendUnequip(crypId, item) { function sendUnequip(crypId, item) {
return ws.sendVboxUnequip(instance.id, crypId, item); return ws.sendVboxUnequip(instance.id, crypId, item);
} }
return { player, vboxInfo, info, sendUnequip }; return { player, itemInfo, info, sendUnequip };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -38,7 +38,7 @@ function Equipment(props) {
const { const {
player, player,
info, info,
vboxInfo, itemInfo,
sendUnequip, sendUnequip,
setInfo, setInfo,
setActiveItem, setActiveItem,
@ -70,8 +70,8 @@ function Equipment(props) {
const specClass = infoType === 'spec' ? 'specs highlight' : 'specs'; const specClass = infoType === 'spec' ? 'specs highlight' : 'specs';
// const classes = `right ${skill ? '' : 'action'}`; // const classes = `right ${skill ? '' : 'action'}`;
const skillList = vboxInfo.items.filter(v => v.skill).map(v => v.v); const skillList = itemInfo.items.filter(v => v.skill).map(v => v.v);
const specList = vboxInfo.items.filter(v => v.spec).map(v => v.v); const specList = itemInfo.items.filter(v => v.spec).map(v => v.v);
const skills = range(0, 9).map(i => { const skills = range(0, 9).map(i => {

View File

@ -26,7 +26,7 @@ function Vbox(args) {
vboxHidden, vboxHidden,
vboxHighlight, vboxHighlight,
setVboxHighlight, setVboxHighlight,
vboxInfo, itemInfo,
} = args; } = args;
if (!player) return false; if (!player) return false;
@ -39,10 +39,10 @@ function Vbox(args) {
const combinerValues = newCombiner.map(cv => player.vbox.bound[cv]).filter(cv => cv); const combinerValues = newCombiner.map(cv => player.vbox.bound[cv]).filter(cv => cv);
const filteredCombos = vboxInfo.combos const filteredCombos = itemInfo.combos
.filter(combo => combinerValues.every(u => combo.units.includes(u))); .filter(combo => combinerValues.every(u => combo.units.includes(u)));
const comboValues = vboxInfo.items.filter(v => { const comboValues = itemInfo.items.filter(v => {
if (!filteredCombos.some(c => c.units.includes(v.v))) return false; if (!filteredCombos.some(c => c.units.includes(v.v))) return false;
if (!['Red', 'Green', 'Blue'].includes(v.v) && combinerValues.includes(v.v)) return false; if (!['Red', 'Green', 'Blue'].includes(v.v) && combinerValues.includes(v.v)) return false;
return true; return true;

View File

@ -17,7 +17,7 @@ const addState = connect(
info, info,
vboxHidden, vboxHidden,
vboxHighlight, vboxHighlight,
vboxInfo, itemInfo,
} = state; } = state;
function sendVboxApply(i) { function sendVboxApply(i) {
@ -48,7 +48,7 @@ const addState = connect(
activeItem, activeItem,
activeCryp, activeCryp,
info, info,
vboxInfo, itemInfo,
vboxHidden, vboxHidden,
vboxHighlight, vboxHighlight,
sendVboxAccept, sendVboxAccept,

View File

@ -158,8 +158,8 @@ function registerEvents(store) {
console.log('EVENT ->', 'crypStatusUpdate', { id, skill, target }); console.log('EVENT ->', 'crypStatusUpdate', { id, skill, target });
} }
function setVboxInfo(v) { function setItemInfo(v) {
return store.dispatch(actions.setVboxInfo(v)); return store.dispatch(actions.setItemInfo(v));
} }
// events.on('SET_PLAYER', setInstance); // events.on('SET_PLAYER', setInstance);
@ -220,7 +220,7 @@ function registerEvents(store) {
setZone, setZone,
setPing, setPing,
setScores, setScores,
setVboxInfo, setItemInfo,
}; };
} }

View File

@ -33,6 +33,6 @@ module.exports = {
showLog: createReducer(false, actions.SET_SHOW_LOG), showLog: createReducer(false, actions.SET_SHOW_LOG),
vboxHidden: createReducer(false, actions.SET_VBOX_HIDDEN), vboxHidden: createReducer(false, actions.SET_VBOX_HIDDEN),
vboxHighlight: createReducer([], actions.SET_VBOX_HIGHLIGHT), vboxHighlight: createReducer([], actions.SET_VBOX_HIGHLIGHT),
vboxInfo: createReducer({ combos: [], items: [] }, actions.SET_VBOX_INFO), itemInfo: createReducer({ combos: [], items: [] }, actions.SET_VBOX_INFO),
ws: createReducer(null, actions.SET_WS), ws: createReducer(null, actions.SET_WS),
}; };

View File

@ -114,8 +114,8 @@ function createSocket(events) {
send({ method: 'player_vbox_reclaim', params: { instance_id: instanceId, index } }); send({ method: 'player_vbox_reclaim', params: { instance_id: instanceId, index } });
} }
function sendVboxInfo() { function sendItemInfo() {
send({ method: 'vbox_info', params: {} }); send({ method: 'item_info', params: {} });
} }
function sendGameSkill(gameId, crypId, targetCrypId, skill) { function sendGameSkill(gameId, crypId, targetCrypId, skill) {
@ -177,7 +177,7 @@ function createSocket(events) {
function accountInstanceList(res) { function accountInstanceList(res) {
const [struct, playerList] = res; const [struct, playerList] = res;
sendVboxInfo(); sendItemInfo();
events.setInstanceList(playerList); events.setInstanceList(playerList);
} }
@ -228,9 +228,9 @@ function createSocket(events) {
clearTimeout(instanceStateTimeout); clearTimeout(instanceStateTimeout);
} }
function vboxInfo(response) { function itemInfo(response) {
const [structName, info] = response; const [structName, info] = response;
events.setVboxInfo(info); events.setItemInfo(info);
} }
function pong() { function pong() {
@ -255,7 +255,7 @@ function createSocket(events) {
zone_state: zoneState, zone_state: zoneState,
zone_close: res => console.log(res), zone_close: res => console.log(res),
instance_state: instanceState, instance_state: instanceState,
vbox_info: vboxInfo, item_info: itemInfo,
pong, pong,
}; };
@ -367,7 +367,7 @@ function createSocket(events) {
sendVboxCombine, sendVboxCombine,
sendVboxDiscard, sendVboxDiscard,
sendVboxUnequip, sendVboxUnequip,
sendVboxInfo, sendItemInfo,
startInstanceStateTimeout, startInstanceStateTimeout,
startGameStateTimeout, startGameStateTimeout,
connect, connect,

View File

@ -11,7 +11,7 @@ use account::{Account};
use rpc::{CrypSpawnParams}; use rpc::{CrypSpawnParams};
use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, Event}; use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, Event};
use spec::{Spec}; use spec::{Spec};
use vbox::Item; use item::{Item};
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Colours { pub struct Colours {

View File

@ -18,8 +18,8 @@ use account::Account;
use player::{Player, player_create, player_get, player_global_update}; use player::{Player, player_create, player_get, player_global_update};
use cryp::{Cryp, cryp_get}; use cryp::{Cryp, cryp_get};
use mob::{instance_mobs}; use mob::{instance_mobs};
use game::{Game, Phase, game_get, game_write, game_instance_new}; use game::{Game, Phase, game_get, game_write};
use vbox::{Item}; use item::{Item};
use rpc::{RpcResult}; use rpc::{RpcResult};
use names::{name}; use names::{name};

View File

@ -1,266 +1,446 @@
use serde_cbor::{from_slice, to_vec}; use skill::{Skill};
use uuid::Uuid; use spec::{Spec};
use cryp::{Colours};
use postgres::transaction::Transaction; #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)]
use failure::Error; pub enum Item {
// colours
Blue,
Green,
Red,
// drops // base skills
use rand::prelude::*; Attack,
use rand::{thread_rng}; Block,
use rand::distributions::{LogNormal,WeightedIndex}; Stun,
Buff,
Debuff,
use account::Account; // specs
use rpc::{ItemUseParams}; // Base
use cryp::{Stat, cryp_get, cryp_write}; Damage,
use game::{GameMode}; Life,
use spec::{Spec, SpecType}; Speed,
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] // Lifes Upgrades
pub enum ItemAction { GreenLifeI,
RerollRedDamage, RedLifeI,
RerollBlueDamage, BlueLifeI,
RerollSpeed, GRLI,
RerollGreenLife, GBLI,
RerollRedLife, RBLI,
RerollBlueLife,
RerollEvasion,
SpecRedDamage5, // Damage Upgrades
SpecBlueDamage5, RedDamageI,
SpecRedLife5, BlueDamageI,
SpecBlueLife5, GreenDamageI,
SpecBlueEvasion5, GRDI,
GBDI,
RBDI,
// Speed Upgrades
RedSpeedI,
BlueSpeedI,
GreenSpeedI,
GRSpeedI,
GBSpeedI,
RBSpeedI,
Amplify,
Banish,
Blast,
Chaos,
Clutch,
Corrupt,
Curse,
Decay,
Hostility,
Haste,
Heal,
Hex,
Impurity,
Invert,
Parry,
Purge,
Purify,
Reflect,
Recharge,
Ruin,
Scatter,
Silence,
Slay,
Sleep,
Snare,
Strangle,
Strike,
StrikeII,
StrikeIII,
Siphon,
Taunt,
Throw,
Triage,
TestTouch,
TestStun,
TestBlock,
TestParry,
TestSiphon,
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum ItemEffect {
pub struct Item { Skill,
// mods: Vec<Mod>, Spec,
id: Uuid,
account: Uuid,
action: ItemAction,
} }
impl Item { impl Item {
pub fn new(action: ItemAction, account_id: Uuid) -> Item { pub fn colours(&self, count: &mut Colours) {
let id = Uuid::new_v4(); let combos = get_combos();
return Item { let combo = combos.iter().find(|c| c.item == *self);
id, match combo {
account: account_id, Some(c) => c.units.iter().for_each(|unit| match unit {
action, Item::Red => count.red += 1,
Item::Blue => count.blue += 1,
Item::Green => count.green += 1,
_ => {
let mut combo_count = Colours::new();
unit.colours(&mut combo_count);
count.red += combo_count.red;
count.blue += combo_count.blue;
count.green += combo_count.green;
}
}),
None => (),
}
}
pub fn cost(&self) -> u16 {
match self {
Item::Red => 1,
Item::Green => 1,
Item::Blue => 1,
Item::Attack => 2,
Item::Block => 2,
Item::Buff => 2,
Item::Debuff => 2,
Item::Stun => 2,
Item::Damage => 3,
Item::Life => 3,
Item::Speed => 3,
_ => {
let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self)
.unwrap_or_else(|| panic!("unable to find components for {:?}", self));
return combo.units.iter().fold(0, |acc, c| acc + c.cost());
},
}
}
pub fn speed(&self) -> u8 {
match self {
Item::Red => 3,
Item::Green => 2,
Item::Blue => 1,
Item::Attack => 1,
Item::Stun => 2,
Item::Block => 3,
Item::Buff => 4,
Item::Debuff => 4,
_ => {
let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self)
.unwrap_or_else(|| panic!("unable to find components for {:?}", self));
return combo.units.iter().fold(0, |acc, c| acc + c.speed());
},
}
}
pub fn effect(&self) -> Option<ItemEffect> {
if let Some(_skill) = self.into_skill() {
return Some(ItemEffect::Skill);
}
if let Some(_spec) = self.into_spec() {
return Some(ItemEffect::Spec);
}
return None;
}
pub fn into_skill(&self) -> Option<Skill> {
match self {
Item::Attack => Some(Skill::Attack),
Item::Amplify => Some(Skill::Amplify),
Item::Banish => Some(Skill::Banish),
Item::Blast => Some(Skill::Blast),
Item::Block => Some(Skill::Block),
Item::Chaos => Some(Skill::Chaos),
Item::Curse => Some(Skill::Curse),
Item::Debuff => Some(Skill::Debuff),
Item::Decay => Some(Skill::Decay),
Item::Haste => Some(Skill::Haste),
Item::Heal => Some(Skill::Heal),
Item::Hex => Some(Skill::Hex),
Item::Hostility => Some(Skill::Hostility),
Item::Impurity => Some(Skill::Impurity),
Item::Invert => Some(Skill::Invert),
Item::Parry => Some(Skill::Parry),
Item::Purge => Some(Skill::Purge),
Item::Purify => Some(Skill::Purify),
Item::Recharge => Some(Skill::Recharge),
Item::Reflect => Some(Skill::Reflect),
Item::Ruin => Some(Skill::Ruin),
Item::Scatter => Some(Skill::Scatter),
Item::Silence => Some(Skill::Silence),
Item::Slay => Some(Skill::Slay),
Item::Sleep => Some(Skill::Sleep),
Item::Siphon => Some(Skill::Siphon),
Item::Snare => Some(Skill::Snare),
Item::Strangle => Some(Skill::Strangle),
Item::Stun => Some(Skill::Stun),
Item::Strike => Some(Skill::Strike),
Item::StrikeII => Some(Skill::StrikeII),
Item::StrikeIII => Some(Skill::StrikeIII),
Item::Clutch => Some(Skill::Clutch),
Item::Taunt => Some(Skill::Taunt),
Item::Throw => Some(Skill::Throw),
Item::Corrupt => Some(Skill::Corrupt),
Item::Triage => Some(Skill::Triage),
_ => None,
}
}
pub fn into_spec(&self) -> Option<Spec> {
match *self {
Item::Speed => Some(Spec::Speed),
Item::RedSpeedI => Some(Spec::RedSpeedI),
Item::BlueSpeedI => Some(Spec::BlueSpeedI),
Item::GreenSpeedI => Some(Spec::GreenSpeedI),
Item::GRSpeedI => Some(Spec::GRSpeedI),
Item::GBSpeedI => Some(Spec::GBSpeedI),
Item::RBSpeedI => Some(Spec::RBSpeedI),
Item::Damage => Some(Spec::Damage),
Item::RedDamageI => Some(Spec::RedDamageI),
Item::BlueDamageI => Some(Spec::BlueDamageI),
Item::GreenDamageI => Some(Spec::GreenDamageI),
Item::GRDI => Some(Spec::GRDI),
Item::GBDI => Some(Spec::GBDI),
Item::RBDI => Some(Spec::RBDI),
Item::Life => Some(Spec::Life),
Item::GRLI => Some(Spec::GRLI),
Item::GBLI => Some(Spec::GBLI),
Item::RBLI => Some(Spec::RBLI),
Item::GreenLifeI => Some(Spec::GreenLifeI),
Item::RedLifeI => Some(Spec::RedLifeI),
Item::BlueLifeI => Some(Spec::BlueLifeI),
_ => None,
}
}
}
impl From<Skill> for Item {
fn from(skill: Skill) -> Item {
match skill {
Skill::Amplify => Item::Amplify,
Skill::Attack => Item::Attack,
Skill::Banish => Item::Banish,
Skill::Blast => Item::Blast,
Skill::Block => Item::Block,
Skill::Chaos => Item::Chaos,
Skill::Curse => Item::Curse,
Skill::Clutch => Item::Clutch,
Skill::Decay => Item::Decay,
Skill::Debuff => Item::Debuff,
Skill::Haste => Item::Haste,
Skill::Hostility => Item::Hostility,
Skill::Heal => Item::Heal,
Skill::Hex => Item::Hex,
Skill::Impurity => Item::Impurity,
Skill::Invert => Item::Invert,
Skill::Parry => Item::Parry,
Skill::Purge => Item::Purge,
Skill::Purify => Item::Purify,
Skill::Recharge => Item::Recharge,
Skill::Reflect => Item::Reflect,
Skill::Ruin => Item::Ruin,
Skill::Scatter => Item::Scatter,
Skill::Silence => Item::Silence,
Skill::Siphon => Item::Siphon,
Skill::Slay => Item::Slay,
Skill::Sleep => Item::Sleep,
Skill::Snare => Item::Snare,
Skill::Strangle => Item::Strangle,
Skill::Strike => Item::Strike,
Skill::StrikeII => Item::StrikeII,
Skill::StrikeIII => Item::StrikeIII,
Skill::Stun => Item::Stun,
Skill::Taunt => Item::Taunt,
Skill::Throw => Item::Throw,
Skill::Triage => Item::Triage,
Skill::Corrupt => Item::Corrupt,
Skill::TestTouch => Item::TestTouch,
Skill::TestStun => Item::TestStun,
Skill::TestBlock => Item::TestBlock,
Skill::TestParry => Item::TestParry,
Skill::TestSiphon => Item::TestSiphon,
_ => panic!("{:?} not implemented as a item", skill),
}
}
}
impl From<Spec> for Item {
fn from(spec: Spec) -> Item {
match spec {
Spec::Speed => Item::Speed,
Spec::RedSpeedI => Item::RedSpeedI,
Spec::BlueSpeedI => Item::BlueSpeedI,
Spec::GreenSpeedI => Item::GreenSpeedI,
Spec::GRSpeedI => Item::GRSpeedI,
Spec::GBSpeedI => Item::GBSpeedI,
Spec::RBSpeedI => Item::RBSpeedI,
Spec::Damage => Item::Damage,
Spec::RedDamageI => Item::RedDamageI,
Spec::BlueDamageI => Item::BlueDamageI,
Spec::GreenDamageI => Item::GreenDamageI,
Spec::GRDI => Item::GRDI,
Spec::GBDI => Item::GBDI,
Spec::RBDI => Item::RBDI,
Spec::Life => Item::Life,
Spec::GRLI => Item::GRLI,
Spec::GBLI => Item::GBLI,
Spec::RBLI => Item::RBLI,
Spec::GreenLifeI => Item::GreenLifeI,
Spec::RedLifeI => Item::RedLifeI,
Spec::BlueLifeI => Item::BlueLifeI,
// _ => panic!("{:?} not implemented as a item", spec),
}
}
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Combo {
pub item: Item,
pub units: Vec<Item>,
}
pub fn get_combos() -> Vec<Combo> {
let mut combinations = vec![
Combo { units: vec![Item::Buff, Item::Red, Item::Red], item: Item::Taunt },
Combo { units: vec![Item::Buff, Item::Green, Item::Green], item: Item::Triage },
Combo { units: vec![Item::Buff, Item::Blue, Item::Blue], item: Item::Scatter }, //To be impl
Combo { units: vec![Item::Buff, Item::Red, Item::Green], item: Item::Haste },
Combo { units: vec![Item::Buff, Item::Green, Item::Blue], item: Item::Impurity },
Combo { units: vec![Item::Buff, Item::Red, Item::Blue], item: Item::Amplify }, // Some flavour
Combo { units: vec![Item::Debuff, Item::Red, Item::Red], item: Item::Snare },
Combo { units: vec![Item::Debuff, Item::Green, Item::Green], item: Item::Purge }, // Needs flavour
Combo { units: vec![Item::Debuff, Item::Blue, Item::Blue], item: Item::Silence },
Combo { units: vec![Item::Debuff, Item::Red, Item::Green], item: Item::Curse }, // To be reworked
Combo { units: vec![Item::Debuff, Item::Green, Item::Blue], item: Item::Decay },
Combo { units: vec![Item::Debuff, Item::Red, Item::Blue], item: Item::Invert },
Combo { units: vec![Item::Block, Item::Red, Item::Red], item: Item::Parry }, // Add red recharge
Combo { units: vec![Item::Block, Item::Green, Item::Green], item: Item::Purify },
Combo { units: vec![Item::Block, Item::Blue, Item::Blue], item: Item::Corrupt },
Combo { units: vec![Item::Block, Item::Red, Item::Green], item: Item::Clutch },
Combo { units: vec![Item::Block, Item::Green, Item::Blue], item: Item::Reflect },
Combo { units: vec![Item::Block, Item::Red, Item::Blue], item: Item::Recharge },
Combo { units: vec![Item::Stun, Item::Red, Item::Red], item: Item::Strangle },
Combo { units: vec![Item::Stun, Item::Green, Item::Green], item: Item::Sleep },
Combo { units: vec![Item::Stun, Item::Blue, Item::Blue], item: Item::Ruin },
Combo { units: vec![Item::Stun, Item::Red, Item::Green], item: Item::Throw },
Combo { units: vec![Item::Stun, Item::Green, Item::Blue], item: Item::Hex },
Combo { units: vec![Item::Stun, Item::Red, Item::Blue], item: Item::Banish },
Combo { units: vec![Item::Attack, Item::Red, Item::Red], item: Item::Strike },
Combo { units: vec![Item::Strike, Item::Strike, Item::Strike], item: Item::StrikeII },
Combo { units: vec![Item::StrikeII, Item::StrikeII, Item::StrikeII], item: Item::StrikeIII },
Combo { units: vec![Item::Attack, Item::Green, Item::Green], item: Item::Heal },
Combo { units: vec![Item::Attack, Item::Blue, Item::Blue], item: Item::Blast },
Combo { units: vec![Item::Attack, Item::Red, Item::Green], item: Item::Slay },
Combo { units: vec![Item::Attack, Item::Green, Item::Blue], item: Item::Siphon },
Combo { units: vec![Item::Attack, Item::Red, Item::Blue], item: Item::Chaos },
Combo { units: vec![Item::Damage, Item::Red, Item::Red], item: Item::RedDamageI },
Combo { units: vec![Item::Damage, Item::Green, Item::Green], item: Item::GreenDamageI },
Combo { units: vec![Item::Damage, Item::Blue, Item::Blue], item: Item::BlueDamageI },
Combo { units: vec![Item::Damage, Item::Red, Item::Green], item: Item::GRDI },
Combo { units: vec![Item::Damage, Item::Green, Item::Blue], item: Item::GBDI },
Combo { units: vec![Item::Damage, Item::Red, Item::Blue], item: Item::RBDI },
Combo { units: vec![Item::Life, Item::Red, Item::Red], item: Item::RedLifeI },
Combo { units: vec![Item::Life, Item::Green, Item::Green], item: Item::GreenLifeI },
Combo { units: vec![Item::Life, Item::Blue, Item::Blue], item: Item::BlueLifeI },
Combo { units: vec![Item::Life, Item::Red, Item::Green], item: Item::GRLI },
Combo { units: vec![Item::Life, Item::Green, Item::Blue], item: Item::GBLI },
Combo { units: vec![Item::Life, Item::Red, Item::Blue], item: Item::RBLI },
Combo { units: vec![Item::Speed, Item::Red, Item::Red], item: Item::RedSpeedI },
Combo { units: vec![Item::Speed, Item::Green, Item::Green], item: Item::GreenSpeedI },
Combo { units: vec![Item::Speed, Item::Blue, Item::Blue], item: Item::BlueSpeedI },
Combo { units: vec![Item::Speed, Item::Red, Item::Green], item: Item::GRSpeedI },
Combo { units: vec![Item::Speed, Item::Green, Item::Blue], item: Item::GBSpeedI },
Combo { units: vec![Item::Speed, Item::Red, Item::Blue], item: Item::RBSpeedI },
];
combinations.iter_mut().for_each(|set| set.units.sort_unstable());
return combinations;
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ItemInfo {
pub v: Item,
pub spec: bool,
pub skill: bool,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ItemInfoCtr {
pub combos: Vec<Combo>,
pub items: Vec<ItemInfo>,
}
pub fn item_info() -> ItemInfoCtr {
let combos = get_combos();
let mut items = combos
.into_iter()
.flat_map(|mut c| {
c.units.push(c.item);
c.units
})
.collect::<Vec<Item>>();
items.sort_unstable();
items.dedup();
let items = items
.into_iter()
.map(|v| ItemInfo {
v,
spec: v.into_spec().is_some(),
skill: v.into_skill().is_some(),
})
.collect::<Vec<ItemInfo>>();
let combos = get_combos();
return ItemInfoCtr {
combos,
items,
}; };
}
fn apply(&mut self, tx: &mut Transaction, target: Uuid) -> Result<(), Error> {
match self.action {
ItemAction::RerollGreenLife => reroll(self, tx, target, Stat::GreenLife),
ItemAction::RerollRedDamage => reroll(self, tx, target, Stat::RedDamage),
ItemAction::RerollBlueDamage => reroll(self, tx, target, Stat::BlueDamage),
ItemAction::RerollSpeed => reroll(self, tx, target, Stat::Speed),
ItemAction::RerollRedLife => reroll(self, tx, target, Stat::RedLife),
ItemAction::RerollBlueLife => reroll(self, tx, target, Stat::BlueLife),
ItemAction::RerollEvasion => reroll(self, tx, target, Stat::Evasion),
ItemAction::SpecRedDamage5 => spec_add(self, tx, target, SpecType::RedDamage5),
ItemAction::SpecBlueDamage5 => spec_add(self, tx, target, SpecType::BlueDamage5),
_ => unimplemented!(),
}
}
} }
fn spec_add(item: &mut Item, tx: &mut Transaction, target: Uuid, spec_type: SpecType) -> Result<(), Error> {
let mut cryp = cryp_get(tx, target, item.account)?;
let spec = Spec::new(spec_type);
cryp.spec_add(spec)?;
cryp_write(cryp, tx)?;
return Ok(());
}
fn reroll(item: &mut Item, tx: &mut Transaction, target: Uuid, stat: Stat) -> Result<(), Error> {
let mut cryp = cryp_get(tx, target, item.account)?;
cryp.roll_stat(stat);
cryp_write(cryp, tx)?;
return Ok(());
}
fn mode_drops(mode: GameMode) -> Vec<(ItemAction, usize)> {
match mode {
GameMode::Normal => vec![
(ItemAction::RerollGreenLife, 1),
(ItemAction::RerollRedDamage, 1),
(ItemAction::RerollBlueDamage, 1),
],
GameMode::Pvp => vec![
(ItemAction::RerollSpeed, 1),
],
GameMode::Zone3v2Attack |
GameMode::Zone2v2Caster |
GameMode::Zone3v3MeleeMiniboss => vec![
(ItemAction::RerollEvasion, 1),
(ItemAction::RerollRedLife, 1),
(ItemAction::RerollBlueLife, 1),
],
GameMode::Zone3v3HealerBoss => vec![
(ItemAction::RerollSpeed, 1),
],
// _ => vec![
// (ItemAction::RerollGreenLife, 1),
// (ItemAction::RerollRedDamage, 1),
// (ItemAction::RerollBlueDamage, 1),
// (ItemAction::RerollSpeed, 1),
// (ItemAction::RerollRedLife, 1),
// (ItemAction::RerollBlueLife, 1),
// (ItemAction::RerollEvasion, 1),
// ],
}
}
pub fn item_drop(tx: &mut Transaction, account_id: Uuid, mode: GameMode) -> Result<(), Error> {
let mut rng = thread_rng();
let log_normal = LogNormal::new(1.0, 1.0);
let num_drops = log_normal.sample(&mut rng).floor() as u16;
let actions = mode_drops(mode);
info!("{:?} drops", num_drops);
for _i in 0..num_drops {
let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
let kind = actions[dist.sample(&mut rng)].0;
let item = Item::new(kind, account_id);
info!("{:?} dropped {:?}", account_id, item);
item_create(item, tx, account_id)?;
}
Ok(())
}
pub fn item_create(item: Item, tx: &mut Transaction, account_id: Uuid) -> Result<Item, Error> {
let item_bytes = to_vec(&item)?;
let query = "
INSERT INTO items (id, account, data)
VALUES ($1, $2, $3)
RETURNING id, account, data;
";
let result = tx
.query(query, &[&item.id, &account_id, &item_bytes])?;
result.iter().next().expect("no row returned");
return Ok(item);
}
pub fn item_use(params: ItemUseParams, tx: &mut Transaction, account: &Account) -> Result<(), Error> {
let query = "
SELECT data
FROM items
WHERE id = $1
AND account = $2
FOR UPDATE;
";
let result = tx
.query(query, &[&params.item, &account.id])?;
let returned = result.iter().next().expect("no row returned");
let item_bytes: Vec<u8> = returned.get(0);
let mut item = from_slice::<Item>(&item_bytes)?;
item.apply(tx, params.target)?;
item_delete(tx, params.item)?;
return Ok(());
}
pub fn item_delete(tx: &mut Transaction, id: Uuid) -> Result<(), Error> {
let query = "
DELETE
FROM items
WHERE id = $1;
";
let result = tx
.execute(query, &[&id])?;
if result != 1 {
return Err(format_err!("unable to delete item {:?}", id));
}
// info!("item deleted {:?}", id);
return Ok(());
}
pub fn items_list(tx: &mut Transaction, account: &Account) -> Result<Vec<Item>, Error> {
let query = "
SELECT data, id
FROM items
WHERE account = $1;
";
let result = tx
.query(query, &[&account.id])?;
let mut items = vec![];
for row in result.into_iter() {
let item_bytes: Vec<u8> = row.get(0);
let id = row.get(1);
match from_slice::<Item>(&item_bytes) {
Ok(i) => items.push(i),
Err(_e) => {
item_delete(tx, id)?;
}
};
}
return Ok(items);
}
// # max damage potion
// name
// "MapMonstersCurseEffectOnSelfFinal3": {
// "adds_tags": [],
// "domain": "area",
// "generation_type": "prefix",
// "generation_weights": [],
// "grants_buff": {},
// "grants_effect": {},
// "group": "MapHexproof",
// "is_essence_only": false,
// "name": "Hexwarded",
// "required_level": 1,
// "spawn_weights": [
// {
// "tag": "top_tier_map",
// "weight": 0
// },
// {
// "tag": "default",
// "weight": 0
// }
// ],
// "stats": [
// {
// "id": "map_item_drop_quantity_+%",
// "max": 15,
// "min": 15
// },
// {
// "id": "map_item_drop_rarity_+%",
// "max": 8,
// "min": 8
// },
// {
// "id": "map_monsters_curse_effect_on_self_+%_final",
// "max": -60,
// "min": -60
// }
// ]
// },

View File

@ -17,17 +17,18 @@ extern crate serde_cbor;
extern crate fern; extern crate fern;
#[macro_use] extern crate log; #[macro_use] extern crate log;
mod account;
mod cryp; mod cryp;
mod game; mod game;
mod instance;
mod item;
mod mob;
mod names;
mod net; mod net;
mod player;
mod rpc;
mod skill; mod skill;
mod spec; mod spec;
mod names;
mod rpc;
mod account;
mod instance;
mod player;
mod mob;
mod util; mod util;
mod vbox; mod vbox;
mod warden; mod warden;

View File

@ -10,9 +10,10 @@ use failure::err_msg;
use account::Account; use account::Account;
use cryp::{Cryp, Colours, cryp_get}; use cryp::{Cryp, Colours, cryp_get};
use vbox::{Vbox, Item, ItemEffect}; use vbox::{Vbox};
use item::{Item, ItemEffect};
use rpc::{PlayerCrypsSetParams}; use rpc::{PlayerCrypsSetParams};
use instance::{Instance, instance_get, instance_update}; use instance::{Instance};
use skill::{Effect}; use skill::{Effect};
const DISCARD_COST: u16 = 5; const DISCARD_COST: u16 = 5;

View File

@ -19,11 +19,11 @@ use cryp::{Cryp, cryp_spawn};
use game::{Game, game_state, game_skill, game_ready}; use game::{Game, game_state, game_skill, game_ready};
use account::{Account, account_create, account_login, account_from_token, account_cryps, account_instances}; use account::{Account, account_create, account_login, account_from_token, account_cryps, account_instances};
use skill::{Skill}; use skill::{Skill};
// use zone::{Zone, zone_create, zone_join, zone_close};
use spec::{Spec}; use spec::{Spec};
use player::{Score, player_mm_cryps_set}; use player::{Score, player_mm_cryps_set};
use instance::{Instance, instance_state, instance_new, instance_ready, instance_join}; use instance::{Instance, instance_state, instance_new, instance_ready, instance_join};
use vbox::{Item, VboxInfo, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip, vbox_info}; use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
use item::{Item, ItemInfoCtr, item_info};
pub struct Rpc; pub struct Rpc;
@ -97,7 +97,7 @@ impl Rpc {
"player_vbox_reclaim" => Rpc::player_vbox_reclaim(data, &mut tx, account.unwrap(), client), "player_vbox_reclaim" => Rpc::player_vbox_reclaim(data, &mut tx, account.unwrap(), client),
"player_vbox_unequip" => Rpc::player_vbox_unequip(data, &mut tx, account.unwrap(), client), "player_vbox_unequip" => Rpc::player_vbox_unequip(data, &mut tx, account.unwrap(), client),
"vbox_info" => Ok(RpcResponse { method: "vbox_info".to_string(), params: RpcResult::VboxInfo(vbox_info()) }), "item_info" => Ok(RpcResponse { method: "item_info".to_string(), params: RpcResult::ItemInfo(item_info()) }),
_ => Err(format_err!("unknown method - {:?}", v.method)), _ => Err(format_err!("unknown method - {:?}", v.method)),
}; };
@ -405,7 +405,7 @@ pub enum RpcResult {
Account(Account), Account(Account),
CrypList(Vec<Cryp>), CrypList(Vec<Cryp>),
GameState(Game), GameState(Game),
VboxInfo(VboxInfo), ItemInfo(ItemInfoCtr),
InstanceScores(Vec<(String, Score)>), InstanceScores(Vec<(String, Score)>),
// ZoneState(Zone), // ZoneState(Zone),
// ZoneClose(()), // ZoneClose(()),

View File

@ -3,7 +3,7 @@ use uuid::Uuid;
use util::{IntPct}; use util::{IntPct};
use cryp::{Cryp, CrypEffect, EffectMeta, Stat}; use cryp::{Cryp, CrypEffect, EffectMeta, Stat};
use vbox::{Item}; use item::{Item};
use game::{Game}; use game::{Game};

View File

@ -1,5 +1,4 @@
use std::iter; use std::iter;
use uuid::Uuid;
// reclaims // reclaims
use rand::prelude::*; use rand::prelude::*;
@ -13,453 +12,10 @@ use failure::err_msg;
use account::Account; use account::Account;
use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxReclaimParams, VboxUnequipParams}; use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxReclaimParams, VboxUnequipParams};
use skill::{Skill};
use spec::{Spec};
use instance::{Instance, instance_get, instance_update}; use instance::{Instance, instance_get, instance_update};
use cryp::{Colours}; use cryp::{Colours};
#[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] use item::*;
pub enum Item {
// colours
Blue,
Green,
Red,
// base skills
Attack,
Block,
Stun,
Buff,
Debuff,
// specs
// Base
Damage,
Life,
Speed,
// Lifes Upgrades
GreenLifeI,
RedLifeI,
BlueLifeI,
GRLI,
GBLI,
RBLI,
// Damage Upgrades
RedDamageI,
BlueDamageI,
GreenDamageI,
GRDI,
GBDI,
RBDI,
// Speed Upgrades
RedSpeedI,
BlueSpeedI,
GreenSpeedI,
GRSpeedI,
GBSpeedI,
RBSpeedI,
Amplify,
Banish,
Blast,
Chaos,
Clutch,
Corrupt,
Curse,
Decay,
Hostility,
Haste,
Heal,
Hex,
Impurity,
Invert,
Parry,
Purge,
Purify,
Reflect,
Recharge,
Ruin,
Scatter,
Silence,
Slay,
Sleep,
Snare,
Strangle,
Strike,
StrikeII,
StrikeIII,
Siphon,
Taunt,
Throw,
Triage,
TestTouch,
TestStun,
TestBlock,
TestParry,
TestSiphon,
}
pub enum ItemEffect {
Skill,
Spec,
}
impl Item {
pub fn colours(&self, count: &mut Colours) {
let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self);
match combo {
Some(c) => c.units.iter().for_each(|unit| match unit {
Item::Red => count.red += 1,
Item::Blue => count.blue += 1,
Item::Green => count.green += 1,
_ => {
let mut combo_count = Colours::new();
unit.colours(&mut combo_count);
count.red += combo_count.red;
count.blue += combo_count.blue;
count.green += combo_count.green;
}
}),
None => (),
}
}
fn cost(&self) -> u16 {
match self {
Item::Red => 1,
Item::Green => 1,
Item::Blue => 1,
Item::Attack => 2,
Item::Block => 2,
Item::Buff => 2,
Item::Debuff => 2,
Item::Stun => 2,
Item::Damage => 3,
Item::Life => 3,
Item::Speed => 3,
_ => {
let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self)
.unwrap_or_else(|| panic!("unable to find components for {:?}", self));
return combo.units.iter().fold(0, |acc, c| acc + c.cost());
},
}
}
pub fn speed(&self) -> u8 {
match self {
Item::Red => 3,
Item::Green => 2,
Item::Blue => 1,
Item::Attack => 1,
Item::Stun => 2,
Item::Block => 3,
Item::Buff => 4,
Item::Debuff => 4,
_ => {
let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self)
.unwrap_or_else(|| panic!("unable to find components for {:?}", self));
return combo.units.iter().fold(0, |acc, c| acc + c.speed());
},
}
}
pub fn effect(&self) -> Option<ItemEffect> {
if let Some(_skill) = self.into_skill() {
return Some(ItemEffect::Skill);
}
if let Some(_spec) = self.into_spec() {
return Some(ItemEffect::Spec);
}
return None;
}
pub fn into_skill(&self) -> Option<Skill> {
match self {
Item::Attack => Some(Skill::Attack),
Item::Amplify => Some(Skill::Amplify),
Item::Banish => Some(Skill::Banish),
Item::Blast => Some(Skill::Blast),
Item::Block => Some(Skill::Block),
Item::Chaos => Some(Skill::Chaos),
Item::Curse => Some(Skill::Curse),
Item::Debuff => Some(Skill::Debuff),
Item::Decay => Some(Skill::Decay),
Item::Haste => Some(Skill::Haste),
Item::Heal => Some(Skill::Heal),
Item::Hex => Some(Skill::Hex),
Item::Hostility => Some(Skill::Hostility),
Item::Impurity => Some(Skill::Impurity),
Item::Invert => Some(Skill::Invert),
Item::Parry => Some(Skill::Parry),
Item::Purge => Some(Skill::Purge),
Item::Purify => Some(Skill::Purify),
Item::Recharge => Some(Skill::Recharge),
Item::Reflect => Some(Skill::Reflect),
Item::Ruin => Some(Skill::Ruin),
Item::Scatter => Some(Skill::Scatter),
Item::Silence => Some(Skill::Silence),
Item::Slay => Some(Skill::Slay),
Item::Sleep => Some(Skill::Sleep),
Item::Siphon => Some(Skill::Siphon),
Item::Snare => Some(Skill::Snare),
Item::Strangle => Some(Skill::Strangle),
Item::Stun => Some(Skill::Stun),
Item::Strike => Some(Skill::Strike),
Item::StrikeII => Some(Skill::StrikeII),
Item::StrikeIII => Some(Skill::StrikeIII),
Item::Clutch => Some(Skill::Clutch),
Item::Taunt => Some(Skill::Taunt),
Item::Throw => Some(Skill::Throw),
Item::Corrupt => Some(Skill::Corrupt),
Item::Triage => Some(Skill::Triage),
_ => None,
}
}
pub fn into_spec(&self) -> Option<Spec> {
match *self {
Item::Speed => Some(Spec::Speed),
Item::RedSpeedI => Some(Spec::RedSpeedI),
Item::BlueSpeedI => Some(Spec::BlueSpeedI),
Item::GreenSpeedI => Some(Spec::GreenSpeedI),
Item::GRSpeedI => Some(Spec::GRSpeedI),
Item::GBSpeedI => Some(Spec::GBSpeedI),
Item::RBSpeedI => Some(Spec::RBSpeedI),
Item::Damage => Some(Spec::Damage),
Item::RedDamageI => Some(Spec::RedDamageI),
Item::BlueDamageI => Some(Spec::BlueDamageI),
Item::GreenDamageI => Some(Spec::GreenDamageI),
Item::GRDI => Some(Spec::GRDI),
Item::GBDI => Some(Spec::GBDI),
Item::RBDI => Some(Spec::RBDI),
Item::Life => Some(Spec::Life),
Item::GRLI => Some(Spec::GRLI),
Item::GBLI => Some(Spec::GBLI),
Item::RBLI => Some(Spec::RBLI),
Item::GreenLifeI => Some(Spec::GreenLifeI),
Item::RedLifeI => Some(Spec::RedLifeI),
Item::BlueLifeI => Some(Spec::BlueLifeI),
_ => None,
}
}
}
impl From<Skill> for Item {
fn from(skill: Skill) -> Item {
match skill {
Skill::Amplify => Item::Amplify,
Skill::Attack => Item::Attack,
Skill::Banish => Item::Banish,
Skill::Blast => Item::Blast,
Skill::Block => Item::Block,
Skill::Chaos => Item::Chaos,
Skill::Curse => Item::Curse,
Skill::Clutch => Item::Clutch,
Skill::Decay => Item::Decay,
Skill::Debuff => Item::Debuff,
Skill::Haste => Item::Haste,
Skill::Hostility => Item::Hostility,
Skill::Heal => Item::Heal,
Skill::Hex => Item::Hex,
Skill::Impurity => Item::Impurity,
Skill::Invert => Item::Invert,
Skill::Parry => Item::Parry,
Skill::Purge => Item::Purge,
Skill::Purify => Item::Purify,
Skill::Recharge => Item::Recharge,
Skill::Reflect => Item::Reflect,
Skill::Ruin => Item::Ruin,
Skill::Scatter => Item::Scatter,
Skill::Silence => Item::Silence,
Skill::Siphon => Item::Siphon,
Skill::Slay => Item::Slay,
Skill::Sleep => Item::Sleep,
Skill::Snare => Item::Snare,
Skill::Strangle => Item::Strangle,
Skill::Strike => Item::Strike,
Skill::StrikeII => Item::StrikeII,
Skill::StrikeIII => Item::StrikeIII,
Skill::Stun => Item::Stun,
Skill::Taunt => Item::Taunt,
Skill::Throw => Item::Throw,
Skill::Triage => Item::Triage,
Skill::Corrupt => Item::Corrupt,
Skill::TestTouch => Item::TestTouch,
Skill::TestStun => Item::TestStun,
Skill::TestBlock => Item::TestBlock,
Skill::TestParry => Item::TestParry,
Skill::TestSiphon => Item::TestSiphon,
_ => panic!("{:?} not implemented as a item", skill),
}
}
}
impl From<Spec> for Item {
fn from(spec: Spec) -> Item {
match spec {
Spec::Speed => Item::Speed,
Spec::RedSpeedI => Item::RedSpeedI,
Spec::BlueSpeedI => Item::BlueSpeedI,
Spec::GreenSpeedI => Item::GreenSpeedI,
Spec::GRSpeedI => Item::GRSpeedI,
Spec::GBSpeedI => Item::GBSpeedI,
Spec::RBSpeedI => Item::RBSpeedI,
Spec::Damage => Item::Damage,
Spec::RedDamageI => Item::RedDamageI,
Spec::BlueDamageI => Item::BlueDamageI,
Spec::GreenDamageI => Item::GreenDamageI,
Spec::GRDI => Item::GRDI,
Spec::GBDI => Item::GBDI,
Spec::RBDI => Item::RBDI,
Spec::Life => Item::Life,
Spec::GRLI => Item::GRLI,
Spec::GBLI => Item::GBLI,
Spec::RBLI => Item::RBLI,
Spec::GreenLifeI => Item::GreenLifeI,
Spec::RedLifeI => Item::RedLifeI,
Spec::BlueLifeI => Item::BlueLifeI,
// _ => panic!("{:?} not implemented as a item", spec),
}
}
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Combo {
item: Item,
units: Vec<Item>,
}
fn get_combos() -> Vec<Combo> {
let mut combinations = vec![
Combo { units: vec![Item::Buff, Item::Red, Item::Red], item: Item::Taunt },
Combo { units: vec![Item::Buff, Item::Green, Item::Green], item: Item::Triage },
Combo { units: vec![Item::Buff, Item::Blue, Item::Blue], item: Item::Scatter }, //To be impl
Combo { units: vec![Item::Buff, Item::Red, Item::Green], item: Item::Haste },
Combo { units: vec![Item::Buff, Item::Green, Item::Blue], item: Item::Impurity },
Combo { units: vec![Item::Buff, Item::Red, Item::Blue], item: Item::Amplify }, // Some flavour
Combo { units: vec![Item::Debuff, Item::Red, Item::Red], item: Item::Snare },
Combo { units: vec![Item::Debuff, Item::Green, Item::Green], item: Item::Purge }, // Needs flavour
Combo { units: vec![Item::Debuff, Item::Blue, Item::Blue], item: Item::Silence },
Combo { units: vec![Item::Debuff, Item::Red, Item::Green], item: Item::Curse }, // To be reworked
Combo { units: vec![Item::Debuff, Item::Green, Item::Blue], item: Item::Decay },
Combo { units: vec![Item::Debuff, Item::Red, Item::Blue], item: Item::Invert },
Combo { units: vec![Item::Block, Item::Red, Item::Red], item: Item::Parry }, // Add red recharge
Combo { units: vec![Item::Block, Item::Green, Item::Green], item: Item::Purify },
Combo { units: vec![Item::Block, Item::Blue, Item::Blue], item: Item::Corrupt },
Combo { units: vec![Item::Block, Item::Red, Item::Green], item: Item::Clutch },
Combo { units: vec![Item::Block, Item::Green, Item::Blue], item: Item::Reflect },
Combo { units: vec![Item::Block, Item::Red, Item::Blue], item: Item::Recharge },
Combo { units: vec![Item::Stun, Item::Red, Item::Red], item: Item::Strangle },
Combo { units: vec![Item::Stun, Item::Green, Item::Green], item: Item::Sleep },
Combo { units: vec![Item::Stun, Item::Blue, Item::Blue], item: Item::Ruin },
Combo { units: vec![Item::Stun, Item::Red, Item::Green], item: Item::Throw },
Combo { units: vec![Item::Stun, Item::Green, Item::Blue], item: Item::Hex },
Combo { units: vec![Item::Stun, Item::Red, Item::Blue], item: Item::Banish },
Combo { units: vec![Item::Attack, Item::Red, Item::Red], item: Item::Strike },
Combo { units: vec![Item::Strike, Item::Strike, Item::Strike], item: Item::StrikeII },
Combo { units: vec![Item::StrikeII, Item::StrikeII, Item::StrikeII], item: Item::StrikeIII },
Combo { units: vec![Item::Attack, Item::Green, Item::Green], item: Item::Heal },
Combo { units: vec![Item::Attack, Item::Blue, Item::Blue], item: Item::Blast },
Combo { units: vec![Item::Attack, Item::Red, Item::Green], item: Item::Slay },
Combo { units: vec![Item::Attack, Item::Green, Item::Blue], item: Item::Siphon },
Combo { units: vec![Item::Attack, Item::Red, Item::Blue], item: Item::Chaos },
Combo { units: vec![Item::Damage, Item::Red, Item::Red], item: Item::RedDamageI },
Combo { units: vec![Item::Damage, Item::Green, Item::Green], item: Item::GreenDamageI },
Combo { units: vec![Item::Damage, Item::Blue, Item::Blue], item: Item::BlueDamageI },
Combo { units: vec![Item::Damage, Item::Red, Item::Green], item: Item::GRDI },
Combo { units: vec![Item::Damage, Item::Green, Item::Blue], item: Item::GBDI },
Combo { units: vec![Item::Damage, Item::Red, Item::Blue], item: Item::RBDI },
Combo { units: vec![Item::Life, Item::Red, Item::Red], item: Item::RedLifeI },
Combo { units: vec![Item::Life, Item::Green, Item::Green], item: Item::GreenLifeI },
Combo { units: vec![Item::Life, Item::Blue, Item::Blue], item: Item::BlueLifeI },
Combo { units: vec![Item::Life, Item::Red, Item::Green], item: Item::GRLI },
Combo { units: vec![Item::Life, Item::Green, Item::Blue], item: Item::GBLI },
Combo { units: vec![Item::Life, Item::Red, Item::Blue], item: Item::RBLI },
Combo { units: vec![Item::Speed, Item::Red, Item::Red], item: Item::RedSpeedI },
Combo { units: vec![Item::Speed, Item::Green, Item::Green], item: Item::GreenSpeedI },
Combo { units: vec![Item::Speed, Item::Blue, Item::Blue], item: Item::BlueSpeedI },
Combo { units: vec![Item::Speed, Item::Red, Item::Green], item: Item::GRSpeedI },
Combo { units: vec![Item::Speed, Item::Green, Item::Blue], item: Item::GBSpeedI },
Combo { units: vec![Item::Speed, Item::Red, Item::Blue], item: Item::RBSpeedI },
];
combinations.iter_mut().for_each(|set| set.units.sort_unstable());
return combinations;
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ItemInfo {
pub v: Item,
pub spec: bool,
pub skill: bool,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxInfo {
pub combos: Vec<Combo>,
pub items: Vec<ItemInfo>,
}
pub fn vbox_info() -> VboxInfo {
let combos = get_combos();
let mut items = combos
.into_iter()
.flat_map(|mut c| {
c.units.push(c.item);
c.units
})
.collect::<Vec<Item>>();
items.sort_unstable();
items.dedup();
let items = items
.into_iter()
.map(|v| ItemInfo {
v,
spec: v.into_spec().is_some(),
skill: v.into_skill().is_some(),
})
.collect::<Vec<ItemInfo>>();
let combos = get_combos();
return VboxInfo {
combos,
items,
};
}
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Vbox { pub struct Vbox {
@ -677,7 +233,7 @@ mod tests {
} }
// #[test] // #[test]
// fn vbox_info_test() { // fn item_info_test() {
// info!("{:#?}", vbox_info()); // info!("{:#?}", item_info());
// } // }
} }