equip kinda wip

This commit is contained in:
ntr 2019-05-20 16:26:54 +10:00
parent b35909e231
commit be022b3de8
22 changed files with 284 additions and 384 deletions

View File

@ -481,7 +481,7 @@ main .top {
/*box-shadow: inset -0.5em 0 0 0 forestgreen;*/ /*box-shadow: inset -0.5em 0 0 0 forestgreen;*/
} }
.ready { .ready, .instance-btn.ready {
color: forestgreen; color: forestgreen;
border-color: forestgreen; border-color: forestgreen;
box-shadow: inset -0.5em 0 0 0 forestgreen; box-shadow: inset -0.5em 0 0 0 forestgreen;

View File

@ -1,65 +1,24 @@
export const SET_ACCOUNT = 'SET_ACCOUNT'; export const setAccount = value => ({ type: 'SET_ACCOUNT', value });
export const setAccount = value => ({ type: SET_ACCOUNT, value }); export const setCryps = value => ({ type: 'SET_CRYPS', value });
export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
export const SET_CRYPS = 'SET_CRYPS'; export const setSkip = value => ({ type: 'SET_SKIP', value });
export const setCryps = value => ({ type: SET_CRYPS, value }); export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value });
export const setVboxHidden = value => ({ type: 'SET_VBOX_HIDDEN', value });
export const SET_ITEM_INFO = 'SET_ITEM_INFO'; export const setInstances = value => ({ type: 'SET_INSTANCES', value });
export const setItemInfo = value => ({ type: SET_ITEM_INFO, value }); export const setNav = value => ({ type: 'SET_NAV', value });
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
export const SET_SKIP = 'SET_SKIP'; export const setPlayer = value => ({ type: 'SET_PLAYER', value });
export const setSkip = value => ({ type: SET_SKIP, value }); export const setPing = value => ({ type: 'SET_PING', value });
export const setGame = value => ({ type: 'SET_GAME', value });
export const SET_VBOX_HIGHLIGHT = 'SET_VBOX_HIGHLIGHT'; export const setResolution = value => ({ type: 'SET_RESOLUTION', value });
export const setVboxHighlight = value => ({ type: SET_VBOX_HIGHLIGHT, value }); export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value });
export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) });
export const SET_VBOX_HIDDEN = 'SET_VBOX_HIDDEN'; export const setTeam = value => ({ type: 'SET_SELECTED_CRYPS', value: Array.from(value) });
export const setVboxHidden = value => ({ type: SET_VBOX_HIDDEN, value }); export const setActiveSkill = (crypId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: crypId ? { crypId, skill } : null });
export const setActiveCryp = value => ({ type: 'SET_ACTIVE_CRYP', value });
export const SET_INSTANCES = 'SET_INSTANCES'; export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value });
export const setInstances = value => ({ type: SET_INSTANCES, value }); export const setInfo = value => ({ type: 'SET_INFO', value });
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
export const SET_NAV = 'SET_NAV'; export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
export const setNav = value => ({ type: SET_NAV, value }); export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value });
export const setWs = value => ({ type: 'SET_WS', value });
export const SET_INSTANCE = 'SET_INSTANCE';
export const setInstance = value => ({ type: SET_INSTANCE, value });
export const SET_PLAYER = 'SET_PLAYER';
export const setPlayer = value => ({ type: SET_PLAYER, value });
export const SET_PING = 'SET_PING';
export const setPing = value => ({ type: SET_PING, value });
export const SET_GAME = 'SET_GAME';
export const setGame = value => ({ type: SET_GAME, value });
export const SET_RESOLUTION = 'SET_RESOLUTION';
export const setResolution = value => ({ type: SET_RESOLUTION, value });
export const SET_SHOW_LOG = 'SET_SHOW_LOG';
export const setShowLog = value => ({ type: SET_SHOW_LOG, value });
export const SET_COMBINER = 'SET_COMBINER';
export const setCombiner = value => ({ type: SET_COMBINER, value: Array.from(value) });
export const SET_SELECTED_CRYPS = 'SET_SELECTED_CRYPS';
export const setTeam = value => ({ type: SET_SELECTED_CRYPS, value: Array.from(value) });
export const SET_ACTIVE_SKILL = 'SET_ACTIVE_SKILL';
export const setActiveSkill = (crypId, skill) => ({ type: SET_ACTIVE_SKILL, value: crypId ? { crypId, skill } : null });
export const SET_ACTIVE_CRYP = 'SET_ACTIVE_CRYP';
export const setActiveCryp = value => ({ type: SET_ACTIVE_CRYP, value });
export const SET_ACTIVE_VAR = 'SET_ACTIVE_VAR';
export const setActiveItem = value => ({ type: SET_ACTIVE_VAR, value });
export const SET_INFO = 'SET_INFO';
export const setInfo = value => ({ type: SET_INFO, value });
export const SET_RECLAIMING = 'SET_RECLAIMING';
export const setReclaiming = value => ({ type: SET_RECLAIMING, value });
export const SET_WS = 'SET_WS';
export const setWs = value => ({ type: SET_WS, value });

View File

@ -55,14 +55,19 @@ function GamePanel(props) {
return sendGameReady(); return sendGameReady();
} }
const otherTeams = game.players.filter(t => t.id !== account.id);
const playerTeam = game.players.find(t => t.id === account.id);
let actionText = 'Ready'; let actionText = 'Ready';
let actionStyles = 'instance-btn instance-ui-btn right';
if (game.phase === 'Finish') actionText = 'Done'; if (game.phase === 'Finish') actionText = 'Done';
if (resolution) actionText = 'Skip'; if (resolution) actionText = 'Skip';
if (actionText === 'Ready' && playerTeam.ready) actionStyles += ' ready';
const header = ( const header = (
<div className="top"> <div className="top">
<button <button
className="instance-btn instance-ui-btn right" className={actionStyles}
onClick={() => actionClick()}> onClick={() => actionClick()}>
{actionText} {actionText}
</button> </button>
@ -75,8 +80,6 @@ function GamePanel(props) {
return null; return null;
} }
const otherTeams = game.players.filter(t => t.id !== account.id);
const playerTeam = game.players.find(t => t.id === account.id);
const zero = Date.parse(game.phase_end) - (1000 * 60); const zero = Date.parse(game.phase_end) - (1000 * 60);
const now = Date.now(); const now = Date.now();

View File

@ -12,8 +12,8 @@ function pingColour(ping) {
function renderHeader(args) { function renderHeader(args) {
const { account, ping } = args; const { account, ping } = args;
const accountStatus = account ? const accountStatus = account
(<div className="header-status"> ? (<div className="header-status">
<h1 className="header-username">{account.name}</h1> <h1 className="header-username">{account.name}</h1>
{saw(pingColour(ping))} {saw(pingColour(ping))}
<div className="ping-text">{ping}ms</div> <div className="ping-text">{ping}ms</div>

View File

@ -5,24 +5,27 @@ const { ITEMS: { SKILLS, COLOURS, SPECS: SPEC_CONSTANT } } = require('./../const
const { COLOUR_ICONS, STATS, SPECS, convertItem, crypAvatar } = require('../utils'); const { COLOUR_ICONS, STATS, SPECS, convertItem, crypAvatar } = require('../utils');
const shapes = require('./shapes'); const shapes = require('./shapes');
const InfoCryp = require('./info.cryp');
function Info(args) { function Info(args) {
const { const {
activeCryp, activeCryp,
info, info,
infoCryp,
itemInfo,
combiner, combiner,
sendUnequip, sendUnequip,
instance, instance,
player, player,
itemInfo,
vboxHidden, vboxHidden,
} = args; } = args;
function CrypItem() { function CrypItem() {
if (!info) return false; if (!info) return false;
const [type, value] = info; const fullInfo = itemInfo.items.find(i => i.item === info);
if (!type) return false; if (!fullInfo) return false;
const isSkill = fullInfo.skill;
const isSpec = fullInfo.spec;
let red = 0; let red = 0;
let blue = 0; let blue = 0;
@ -34,44 +37,23 @@ function Info(args) {
}); });
const teamColours = { red, blue, green }; const teamColours = { red, blue, green };
if (type === 'item') { const unequipBtn = activeCryp
let itemDetails; ? <button onClick={() => sendUnequip(activeCryp.id, info)}>unequip</button>
if (SKILLS[value]) { : null;
itemDetails = SKILLS[value];
} else if (SPEC_CONSTANT[value]) {
itemDetails = SPEC_CONSTANT[value];
} else if (COLOURS[value]) {
itemDetails = COLOURS[value];
}
if (!itemDetails) { if (isSkill) {
return console.warn('UNHANLDED VAR', value);
}
return (
<div className="info-item">
{value} - {itemDetails.description}
</div>
);
}
if (type === 'skill') {
const skillInfo = SKILLS[value.skill];
const description = skillInfo ? skillInfo.description : '?????';
return ( return (
<div className="info-skill"> <div className="info-skill">
<div> {value.skill} </div> <div>{fullInfo.item}</div>
<div> {description} </div> <div>{fullInfo.description}</div>
<button onClick={() => sendUnequip(value.cryp.id, value.skill)}> {unequipBtn}
unequip
</button>
</div> </div>
); );
} }
if (type === 'spec') { if (isSpec) {
const { spec } = value; const breaks = SPEC_CONSTANT[info].thresholds;
const breaks = SPEC_CONSTANT[value.spec].thresholds; const colourReqs = SPEC_CONSTANT[info].colours || [];
const colourReqs = SPEC_CONSTANT[spec].colours || [];
const thresholdEl = colourReqs.map((c, i) => { const thresholdEl = colourReqs.map((c, i) => {
const numIcons = Math.max(...breaks); const numIcons = Math.max(...breaks);
@ -102,17 +84,21 @@ function Info(args) {
return ( return (
<div className="info-spec"> <div className="info-spec">
<div> {value.spec} </div> <div>{info}</div>
<div> {SPEC_CONSTANT[value.spec].description} </div> <div>{fullInfo.description}</div>
<div className="thresholds"> <div className="thresholds">
{thresholdEl} {thresholdEl}
</div> </div>
<button onClick={() => sendUnequip(value.cryp.id, value.spec)}> {unequipBtn}
unequip
</button>
</div> </div>
); );
} }
return (
<div className="info-item">
{fullInfo.item} - {fullInfo.description}
</div>
);
} }
function playerRound(id) { function playerRound(id) {
@ -161,7 +147,7 @@ function Info(args) {
} }
function Combos() { function Combos() {
if (!info[0]) return false; if (info) return false;
if (activeCryp) return false; if (activeCryp) return false;
if (!player) return false; if (!player) return false;
@ -183,7 +169,7 @@ function Info(args) {
</table> </table>
); );
} }
const vboxCombos = itemInfo.combos.filter(c => c.units.includes(info[1])); const vboxCombos = itemInfo.combos.filter(c => c.units.includes(info));
if (vboxCombos.length > 6) return false; if (vboxCombos.length > 6) return false;
return ( return (
<table> <table>
@ -212,7 +198,7 @@ function Info(args) {
</div> </div>
); );
} }
// <InfoCryp /> not required anymore
// <ScoreBoard /> Takes up too much space maybe a context switch // <ScoreBoard /> Takes up too much space maybe a context switch
module.exports = Info; module.exports = Info;

View File

@ -1,134 +0,0 @@
const preact = require('preact');
const range = require('lodash/range');
const { connect } = require('preact-redux');
const actions = require('../actions');
const { STATS, SPECS, crypAvatar } = require('../utils');
const shapes = require('./shapes');
const addState = connect(
function receiveState(state) {
const { activeCryp, player, itemInfo } = state;
return { activeCryp, player, itemInfo };
},
function receiveDispatch(dispatch) {
function setInfo(item, value) {
dispatch(actions.setInfo([item, value]));
}
function setActiveCryp(value) {
dispatch(actions.setActiveCryp(value));
}
function setVboxHidden(value) {
dispatch(actions.setVboxHidden(value));
}
function setVboxHighlight(v) {
dispatch(actions.setVboxHighlight(v));
}
return { setInfo, setActiveCryp, setVboxHidden, setVboxHighlight };
}
);
function InfoCryp(args) {
const {
activeCryp,
player,
itemInfo,
setVboxHidden,
setInfo,
setActiveCryp,
setVboxHighlight,
} = args;
if (!activeCryp) return false;
const cryp = player.cryps.find(c => c.id === activeCryp.id);
if (!cryp) return false;
function setHighlight(type) {
if (type === 'skill') return setVboxHighlight(itemInfo.items.filter(v => v.skill).map(v => v.v));
if (type === 'spec') return setVboxHighlight(itemInfo.items.filter(v => v.spec).map(v => v.v));
return false;
}
// onClick={() => setInfo('skill', { skill: s, cryp })}
const skills = range(0, 3).map(i => {
const skill = cryp.skills[i];
function skillClick(e) {
if (!skill) {
setVboxHidden(false);
setHighlight('skill');
} else setInfo('skill', { skill: skill.skill, cryp });
e.stopPropagation();
return setActiveCryp(cryp);
}
const s = cryp.skills[i]
? cryp.skills[i].skill
: (<span>&nbsp;</span>);
return <button key={i} alt={s} onClick={skillClick} >{s}</button>;
});
const stats = Object.values(STATS).map((s, j) => (
<figure key={j} alt={s.stat} className={s.stat}>
{s.svg(`stat-icon ${s.colour}`)}
<figcaption>{cryp[s.stat].value}</figcaption>
</figure>
));
const specs = range(0, 6).map(i => {
const s = cryp.specs[i];
function blankSpecClick(e) {
e.stopPropagation();
setActiveCryp(cryp);
setHighlight('spec');
setVboxHidden(true);
}
if (!s) {
return (
<figure key={i} className="gray" onClick={blankSpecClick}>
{shapes.diamond('stat-icon gray')}
<figcaption>&nbsp;</figcaption>
</figure>
);
}
function specClick(e) {
e.stopPropagation();
setActiveCryp(cryp);
setInfo('spec', { spec: s, cryp });
}
return (
<figure key={i} onClick={specClick}>
{SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)}
<figcaption>{SPECS[s].caption}</figcaption>
</figure>
);
});
return (
<div className="info-cryp">
<div className="stats">
{stats}
</div>
<div className="specs">
{specs}
</div>
<div className="skills">
{skills}
</div>
</div>
);
}
module.exports = addState(InfoCryp);

View File

@ -9,11 +9,7 @@ function InstanceComponent(args) {
const { const {
instance, instance,
player, player,
quit,
sendInstanceReady, sendInstanceReady,
vboxHidden,
setVboxHidden,
} = args; } = args;
if (!instance) return false; if (!instance) return false;

View File

@ -6,43 +6,14 @@ const Instance = require('./instance.component');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { ws, instance, player, account, activeItem, vboxHidden } = state; const { ws, instance, player } = state;
function sendInstanceReady() { function sendInstanceReady() {
return ws.sendInstanceReady(instance.id); return ws.sendInstanceReady(instance.id);
} }
function sendVboxApply(crypId, i) { return { instance, player, sendInstanceReady };
return ws.sendVboxApply(instance.id, crypId, i);
}
return { instance, player, account, sendInstanceReady, sendVboxApply, activeItem, vboxHidden };
}, },
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setInstance(null));
}
function setInfo(item, value) {
dispatch(actions.setInfo([item, value]));
}
function setVboxHidden(v) {
dispatch(actions.setVboxHidden(v));
}
function setActiveCryp(value) {
dispatch(actions.setActiveCryp(value));
}
function clearInfo() {
return dispatch(actions.setInfo([]));
}
return { quit, clearInfo, setInfo, setVboxHidden, setActiveCryp };
}
); );
module.exports = addState(Instance); module.exports = addState(Instance);

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, itemInfo, activeItem, activeCryp } = state; const { ws, instance, player, account, vboxHidden, itemInfo, itemEquip, 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, itemInfo, activeItem, activeCryp }; return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, itemInfo, itemEquip, activeCryp };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -26,8 +26,8 @@ const addState = connect(
dispatch(actions.setInstance(null)); dispatch(actions.setInstance(null));
} }
function setInfo(item, value) { function setInfo(item) {
dispatch(actions.setInfo([item, value])); dispatch(actions.setInfo(item));
} }
function setActiveCryp(value) { function setActiveCryp(value) {
@ -35,14 +35,22 @@ const addState = connect(
} }
function clearInfo() { function clearInfo() {
return dispatch(actions.setInfo([])); return dispatch(actions.setInfo(null));
} }
function setVboxHighlight(v) { function setVboxHighlight(v) {
dispatch(actions.setVboxHighlight(v)); dispatch(actions.setVboxHighlight(v));
} }
return { quit, clearInfo, setInfo, setActiveCryp, setVboxHighlight }; function setItemEquip(v) {
return dispatch(actions.setItemEquip(v));
}
function setItemUnequip(v) {
return dispatch(actions.setItemUnequip(v));
}
return { quit, clearInfo, setInfo, setActiveCryp, setItemUnequip, setItemEquip, setVboxHighlight };
} }
); );
@ -50,32 +58,34 @@ const addState = connect(
function Cryp(props) { function Cryp(props) {
const { const {
activeCryp, activeCryp,
activeItem, itemEquip,
cryp, cryp,
player, player,
sendVboxApply, sendVboxApply,
setInfo,
setActiveCryp, setActiveCryp,
setItemUnequip,
setItemEquip,
setVboxHighlight, setVboxHighlight,
itemInfo, itemInfo,
} = props; } = props;
function setHighlight(type) { function setHighlight(type) {
if (type === 'skill') return setVboxHighlight(itemInfo.items.filter(v => v.skill).map(v => v.v)); if (type === 'skill') return setVboxHighlight(itemInfo.items.filter(v => v.skill).map(v => v.item));
if (type === 'spec') return setVboxHighlight(itemInfo.items.filter(v => v.spec).map(v => v.v)); if (type === 'spec') return setVboxHighlight(itemInfo.items.filter(v => v.spec).map(v => v.item));
return false; return false;
} }
function onClick(e) { function onClick(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
if (activeItem !== null) sendVboxApply(cryp.id, activeItem); if (itemEquip !== null) sendVboxApply(cryp.id, itemEquip);
setItemEquip(null);
return setActiveCryp(cryp); return setActiveCryp(cryp);
} }
const { vbox } = player; const { vbox } = player;
const skillList = itemInfo.items.filter(v => v.skill).map(v => v.v); const skillList = itemInfo.items.filter(v => v.skill).map(v => v.item);
const specList = itemInfo.items.filter(v => v.spec).map(v => v.v); const specList = itemInfo.items.filter(v => v.spec).map(v => v.item);
const skills = range(0, 3).map(i => { const skills = range(0, 3).map(i => {
const skill = cryp.skills[i]; const skill = cryp.skills[i];
@ -84,15 +94,15 @@ function Cryp(props) {
: (<span className="gray">+</span>); : (<span className="gray">+</span>);
function skillClick(e) { function skillClick(e) {
if (!skill && activeItem !== null) return sendVboxApply(cryp.id, activeItem); if (!skill) return false;
if (!skill) setHighlight('skill'); setItemUnequip(skill.skill);
else setInfo('skill', { skill: skill.skill, cryp }); setActiveCryp(cryp);
e.stopPropagation(); e.stopPropagation();
return setActiveCryp(cryp); return true;
} }
const action = skill ? '' : 'action'; const action = skill ? '' : 'action';
const equip = skillList.includes(vbox.bound[activeItem]) && !skill ? 'equip' : ''; const equip = skillList.includes(vbox.bound[itemEquip]) && !skill ? 'equip' : '';
const classes = `right ${action} ${equip}`; const classes = `right ${action} ${equip}`;
return ( return (
<button key={i} className={classes} onClick={skillClick} >{s}</button> <button key={i} className={classes} onClick={skillClick} >{s}</button>
@ -104,13 +114,13 @@ function Cryp(props) {
function blankSpecClick(e) { function blankSpecClick(e) {
e.stopPropagation(); e.stopPropagation();
if (activeItem !== null) return sendVboxApply(cryp.id, activeItem); if (itemEquip !== null) return sendVboxApply(cryp.id, itemEquip);
setHighlight('spec'); setHighlight('spec');
return setActiveCryp(cryp); return setActiveCryp(cryp);
} }
if (!s) { if (!s) {
const equip = specList.includes(vbox.bound[activeItem]) ? 'equip-spec' : 'gray'; const equip = specList.includes(vbox.bound[itemEquip]) ? 'equip-spec' : 'gray';
return ( return (
<figure key={i} onClick={blankSpecClick} className={equip} > <figure key={i} onClick={blankSpecClick} className={equip} >
{shapes.diamond(`stat-icon ${equip}`)} {shapes.diamond(`stat-icon ${equip}`)}
@ -120,8 +130,8 @@ function Cryp(props) {
function specClick(e) { function specClick(e) {
e.stopPropagation(); e.stopPropagation();
setItemUnequip(s);
setActiveCryp(cryp); setActiveCryp(cryp);
setInfo('spec', { spec: s, cryp });
} }
return ( return (
@ -185,7 +195,7 @@ function Cryp(props) {
function InstanceCryps(props) { function InstanceCryps(props) {
const { const {
activeCryp, activeCryp,
activeItem, itemEquip,
player, player,
instance, instance,
// clearInfo, // clearInfo,
@ -196,13 +206,25 @@ function InstanceCryps(props) {
vboxHidden, vboxHidden,
itemInfo, itemInfo,
setVboxHighlight, setVboxHighlight,
setItemUnequip,
setItemEquip,
} = props; } = props;
if (!player) return false; if (!player) return false;
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, itemInfo, setVboxHighlight, activeCryp,
itemEquip,
setItemUnequip,
setItemEquip,
cryp: c,
player,
sendVboxApply,
setInfo,
setActiveCryp,
itemInfo,
setVboxHighlight,
})); }));
const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`; const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`;

View File

@ -7,29 +7,33 @@ const { convertItem, SPECS } = require('./../utils');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { player, itemInfo, info, ws, instance } = state; const { player, activeCryp, itemInfo, info, ws, instance, itemUnequip } = 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, itemInfo, info, sendUnequip }; return { player, itemInfo, info, sendUnequip, activeCryp, itemUnequip };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
function setInfo(item, value) { function setInfo(item) {
dispatch(actions.setInfo([item, value])); dispatch(actions.setInfo(item));
} }
function clearInfo() { function clearInfo() {
return dispatch(actions.setInfo([])); return dispatch(actions.setInfo(null));
} }
function setActiveItem(v) { function setItemEquip(v) {
return dispatch(actions.setActiveItem(v)); return dispatch(actions.setItemEquip(v));
} }
return { setInfo, setActiveItem, clearInfo }; function setItemUnequip(v) {
return dispatch(actions.setItemUnequip(v));
}
return { setInfo, setItemEquip, setItemUnequip, clearInfo };
} }
); );
@ -37,48 +41,47 @@ const addState = connect(
function Equipment(props) { function Equipment(props) {
const { const {
player, player,
info,
itemUnequip,
setItemEquip,
setItemUnequip,
activeCryp,
itemInfo, itemInfo,
sendUnequip, sendUnequip,
setInfo,
setActiveItem,
} = props; } = props;
const { vbox } = player; const { vbox } = player;
const infoType = info ? info[0] : false;
const infoValue = info ? info[1] : false; const fullInfo = itemInfo.items.find(i => i.item === itemUnequip);
const isSkill = fullInfo && fullInfo.skill;
const isSpec = fullInfo && fullInfo.spec;
function boundClick(e, i) { function boundClick(e, i) {
const value = vbox.bound[i]; const value = vbox.bound[i];
setInfo('item', value); setItemEquip(i);
setActiveItem(i);
return false; return false;
} }
function skillUnequip(e) { function unequipClick(e) {
e.stopPropagation(); e.stopPropagation();
if (infoType === 'skill') sendUnequip(infoValue.cryp.id, infoValue.skill); if (!itemUnequip) return false;
return true; if (!activeCryp) return false;
setItemUnequip(null);
return sendUnequip(activeCryp.id, itemUnequip);
} }
function specUnequip(e) { const skillClass = isSkill ? 'skills highlight' : 'skills';
e.stopPropagation(); const specClass = isSpec ? 'specs highlight' : 'specs';
if (infoType === 'spec') sendUnequip(infoValue.cryp.id, infoValue.spec);
return true;
}
const skillClass = infoType === 'skill' ? 'skills highlight' : 'skills';
const specClass = infoType === 'spec' ? 'specs highlight' : 'specs';
// const classes = `right ${skill ? '' : 'action'}`;
const skillList = itemInfo.items.filter(v => v.skill).map(v => v.v);
const specList = itemInfo.items.filter(v => v.spec).map(v => v.v);
const skillList = itemInfo.items.filter(v => v.skill).map(v => v.item);
const specList = itemInfo.items.filter(v => v.spec).map(v => v.item);
const skills = range(0, 9).map(i => { const skills = range(0, 9).map(i => {
const item = convertItem(vbox.bound[i]); const item = convertItem(vbox.bound[i]);
if (skillList.includes(item)) { if (skillList.includes(item)) {
return ( return (
<button key={i} className={''} onClick={e => boundClick(e, i)}> <button key={i} onClick={e => boundClick(e, i)}>
{item} {item}
</button> </button>
); );
@ -99,13 +102,13 @@ function Equipment(props) {
return ( return (
<div className="equip" > <div className="equip" >
<div className={skillClass} onClick={e => skillUnequip(e)}> <div className={skillClass} onClick={e => unequipClick(e)}>
<h3>Skills</h3> <h3>Skills</h3>
<div className ="items"> <div className ="items">
{skills} {skills}
</div> </div>
</div> </div>
<div className={specClass} onClick={e => specUnequip(e)}> <div className={specClass} onClick={e => unequipClick(e)}>
<h3>Specs</h3> <h3>Specs</h3>
<div className ="items"> <div className ="items">
{specs} {specs}

View File

@ -80,7 +80,8 @@ function Nav(args) {
<h2>Team</h2> <h2>Team</h2>
{teamElements} {teamElements}
<h2>Instances</h2> <h2>Instances</h2>
<button onClick={() => navTo('list')}>Join</button> <button onClick={() => navTo('team')}>1. Select Team</button>
<button onClick={() => navTo('list')}>2. Join</button>
<hr /> <hr />
{joined} {joined}
<h2>Hax</h2> <h2>Hax</h2>

View File

@ -113,7 +113,7 @@ function Team(args) {
disabled={team.some(c => !c)} disabled={team.some(c => !c)}
className="instance-btn instance-ui-btn right" className="instance-btn instance-ui-btn right"
onClick={() => navToList()}> onClick={() => navToList()}>
Join an Instance Join Instance
</button> </button>
</div> </div>
); );

View File

@ -89,7 +89,7 @@ function Vbox(args) {
function freeClick() { function freeClick() {
if (c) { if (c) {
setActiveCryp(null); setActiveCryp(null);
return setInfo('item', c); return setInfo(c);
} }
return false; return false;
} }
@ -129,7 +129,7 @@ function Vbox(args) {
const insert = combiner.findIndex(j => j === null); const insert = combiner.findIndex(j => j === null);
if (insert === -1) return combinerChange([i, null, null]); if (insert === -1) return combinerChange([i, null, null]);
combiner[insert] = i; combiner[insert] = i;
setInfo('item', value); setInfo(value);
setActiveCryp(null); setActiveCryp(null);
return combinerChange(combiner); return combinerChange(combiner);
} }

View File

@ -68,8 +68,8 @@ const addState = connect(
return dispatch(actions.setReclaiming(v)); return dispatch(actions.setReclaiming(v));
} }
function setInfo(type, info) { function setInfo(item) {
return dispatch(actions.setInfo([type, info])); return dispatch(actions.setInfo(item));
} }
function setActiveCryp(v) { function setActiveCryp(v) {
@ -81,7 +81,7 @@ const addState = connect(
} }
function showTeam() { function showTeam() {
dispatch(actions.setInfo([null, null])); dispatch(actions.setInfo(null));
dispatch(actions.setVboxHidden(true)); dispatch(actions.setVboxHidden(true));
return true; return true;
} }

View File

@ -116,8 +116,9 @@ function registerEvents(store) {
store.dispatch(actions.setActiveItem(v)); store.dispatch(actions.setActiveItem(v));
} }
function clearInfo(info) { function clearInfo() {
store.dispatch(actions.setInfo([])); store.dispatch(actions.setInfo(null));
store.dispatch(actions.setActiveCryp(null));
console.log('event clear item'); console.log('event clear item');
} }

View File

@ -8,7 +8,9 @@ function setupKeys(store) {
key('esc', () => store.dispatch(actions.setReclaiming(false))); key('esc', () => store.dispatch(actions.setReclaiming(false)));
key('esc', () => store.dispatch(actions.setActiveSkill(null))); key('esc', () => store.dispatch(actions.setActiveSkill(null)));
key('esc', () => store.dispatch(actions.setActiveCryp(null))); key('esc', () => store.dispatch(actions.setActiveCryp(null)));
key('esc', () => store.dispatch(actions.setInfo([null, null]))); key('esc', () => store.dispatch(actions.setInfo(null)));
key('esc', () => store.dispatch(actions.setItemEquip(null)));
key('esc', () => store.dispatch(actions.setItemUnequip(null)));
key('esc', () => store.dispatch(actions.setVboxHighlight([]))); key('esc', () => store.dispatch(actions.setVboxHighlight([])));
} }

View File

@ -1,5 +1,3 @@
const actions = require('./actions');
function createReducer(defaultState, actionType) { function createReducer(defaultState, actionType) {
return function reducer(state = defaultState, action) { return function reducer(state = defaultState, action) {
switch (action.type) { switch (action.type) {
@ -13,26 +11,28 @@ function createReducer(defaultState, actionType) {
/* eslint-disable key-spacing */ /* eslint-disable key-spacing */
module.exports = { module.exports = {
account: createReducer(null, actions.SET_ACCOUNT), account: createReducer(null, 'SET_ACCOUNT'),
activeCryp: createReducer(null, actions.SET_ACTIVE_CRYP), activeCryp: createReducer(null, 'SET_ACTIVE_CRYP'),
activeSkill: createReducer(null, actions.SET_ACTIVE_SKILL), activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
activeItem: createReducer(null, actions.SET_ACTIVE_VAR), activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
combiner: createReducer([null, null, null], actions.SET_COMBINER), combiner: createReducer([null, null, null], 'SET_COMBINER'),
cryps: createReducer([], actions.SET_CRYPS), cryps: createReducer([], 'SET_CRYPS'),
game: createReducer(null, actions.SET_GAME), game: createReducer(null, 'SET_GAME'),
info: createReducer([null, null], actions.SET_INFO), info: createReducer(null, 'SET_INFO'),
instance: createReducer(null, actions.SET_INSTANCE), itemEquip: createReducer(null, 'SET_ITEM_EQUIP'),
instances: createReducer([], actions.SET_INSTANCES), itemUnequip: createReducer(null, 'SET_ITEM_UNEQUIP'),
skip: createReducer(false, actions.SET_SKIP), instance: createReducer(null, 'SET_INSTANCE'),
nav: createReducer(null, actions.SET_NAV), instances: createReducer([], 'SET_INSTANCES'),
ping: createReducer(null, actions.SET_PING), skip: createReducer(false, 'SET_SKIP'),
player: createReducer(null, actions.SET_PLAYER), nav: createReducer(null, 'SET_NAV'),
reclaiming: createReducer(false, actions.SET_RECLAIMING), ping: createReducer(null, 'SET_PING'),
resolution: createReducer(null, actions.SET_RESOLUTION), player: createReducer(null, 'SET_PLAYER'),
team: createReducer([null, null, null], actions.SET_SELECTED_CRYPS), reclaiming: createReducer(false, 'SET_RECLAIMING'),
showLog: createReducer(false, actions.SET_SHOW_LOG), resolution: createReducer(null, 'SET_RESOLUTION'),
vboxHidden: createReducer(false, actions.SET_VBOX_HIDDEN), team: createReducer([null, null, null], 'SET_SELECTED_CRYPS'),
vboxHighlight: createReducer([], actions.SET_VBOX_HIGHLIGHT), showLog: createReducer(false, 'SET_SHOW_LOG'),
itemInfo: createReducer({ combos: [], items: [] }, actions.SET_VBOX_INFO), vboxHidden: createReducer(false, 'SET_VBOX_HIDDEN'),
ws: createReducer(null, actions.SET_WS), vboxHighlight: createReducer([], 'SET_VBOX_HIGHLIGHT'),
itemInfo: createReducer({ combos: [], items: [] }, 'SET_ITEM_INFO'),
ws: createReducer(null, 'SET_WS'),
}; };

View File

@ -177,7 +177,6 @@ function createSocket(events) {
function accountInstanceList(res) { function accountInstanceList(res) {
const [struct, playerList] = res; const [struct, playerList] = res;
sendItemInfo();
events.setInstanceList(playerList); events.setInstanceList(playerList);
} }
@ -309,6 +308,7 @@ function createSocket(events) {
events.setAccount(account); events.setAccount(account);
sendAccountInstances(); sendAccountInstances();
sendAccountCryps(); sendAccountCryps();
sendItemInfo();
} }
sendPing(); sendPing();

View File

@ -242,6 +242,88 @@ impl Item {
_ => None, _ => None,
} }
} }
pub fn into_description(&self) -> String {
match self {
// colours
Item::Blue => format!("Combine with skills and specs to create upgraded items. \n Deterrents and destruction."),
Item::Green => format!("Combine with skills and specs to create upgraded items.\n Protection and trickery."),
Item::Red => format!("Combine with skills and specs to create upgraded items. \n Speed and chaos."),
// base skills
Item::Attack => format!("Deal {:?}% RedDamage", self.into_skill().unwrap().multiplier()),
Item::Block => format!("description"),
Item::Stun => format!("description"),
Item::Buff => format!("description"),
Item::Debuff => format!("description"),
// specs
// Base
Item::Damage => format!("description"),
Item::Life => format!("description"),
Item::Speed => format!("description"),
// Lifes Upgrades
Item::GreenLifeI => format!("description"),
Item::RedLifeI => format!("description"),
Item::BlueLifeI => format!("description"),
Item::GRLI => format!("description"),
Item::GBLI => format!("description"),
Item::RBLI => format!("description"),
// Damage Upgrades
Item::RedDamageI => format!("description"),
Item::BlueDamageI => format!("description"),
Item::GreenDamageI => format!("description"),
Item::GRDI => format!("description"),
Item::GBDI => format!("description"),
Item::RBDI => format!("description"),
// Speed Upgrades
Item::RedSpeedI => format!("description"),
Item::BlueSpeedI => format!("description"),
Item::GreenSpeedI => format!("description"),
Item::GRSpeedI => format!("description"),
Item::GBSpeedI => format!("description"),
Item::RBSpeedI => format!("description"),
Item::Amplify => format!("description"),
Item::Banish => format!("description"),
Item::Blast => format!("description"),
Item::Chaos => format!("description"),
Item::Clutch => format!("description"),
Item::Corrupt => format!("description"),
Item::Curse => format!("description"),
Item::Decay => format!("description"),
Item::Hostility => format!("description"),
Item::Haste => format!("description"),
Item::Heal => format!("description"),
Item::Hex => format!("description"),
Item::Impurity => format!("description"),
Item::Invert => format!("description"),
Item::Parry => format!("description"),
Item::Purge => format!("description"),
Item::Purify => format!("description"),
Item::Reflect => format!("description"),
Item::Recharge => format!("description"),
Item::Ruin => format!("description"),
Item::Scatter => format!("description"),
Item::Silence => format!("description"),
Item::Slay => format!("description"),
Item::Sleep => format!("description"),
Item::Snare => format!("description"),
Item::Strangle => format!("description"),
Item::Strike => format!("description"),
Item::StrikeII => format!("description"),
Item::StrikeIII => format!("description"),
Item::Siphon => format!("description"),
Item::Taunt => format!("description"),
Item::Throw => format!("description"),
Item::Triage => format!("description"),
_ => format!("..."),
}
}
} }
impl From<Skill> for Item { impl From<Skill> for Item {
@ -403,9 +485,10 @@ pub fn get_combos() -> Vec<Combo> {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ItemInfo { pub struct ItemInfo {
pub v: Item, pub item: Item,
pub spec: bool, pub spec: bool,
pub skill: bool, pub skill: bool,
pub description: String,
} }
@ -431,9 +514,10 @@ pub fn item_info() -> ItemInfoCtr {
let items = items let items = items
.into_iter() .into_iter()
.map(|v| ItemInfo { .map(|v| ItemInfo {
v, item: v,
spec: v.into_spec().is_some(), spec: v.into_spec().is_some(),
skill: v.into_skill().is_some(), skill: v.into_skill().is_some(),
description: v.into_description(),
}) })
.collect::<Vec<ItemInfo>>(); .collect::<Vec<ItemInfo>>();

View File

@ -76,14 +76,14 @@ fn print_panic_payload(ctx: &str, payload: &(Any + Send + 'static)) {
} }
pub fn start() { pub fn start() {
panic::set_hook(Box::new(|panic_info| { // panic::set_hook(Box::new(|panic_info| {
print_panic_payload("set_hook", panic_info.payload()); // print_panic_payload("set_hook", panic_info.payload());
if let Some(location) = panic_info.location() { // if let Some(location) = panic_info.location() {
info!("LOCATION: {}:{}", location.file(), location.line()); // info!("LOCATION: {}:{}", location.file(), location.line());
} else { // } else {
info!("NO LOCATION INFORMATION"); // info!("NO LOCATION INFORMATION");
} // }
})); // }));
let database_url = env::var("DATABASE_URL") let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set"); .expect("DATABASE_URL must be set");

View File

@ -189,6 +189,10 @@ impl Player {
} }
pub fn vbox_apply(&mut self, index: usize, cryp_id: Uuid) -> Result<&mut Player, Error> { pub fn vbox_apply(&mut self, index: usize, cryp_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); let item = self.vbox.bound.remove(index);
match item.effect() { match item.effect() {

View File

@ -499,6 +499,8 @@ impl Effect {
Effect::Ruin => Category::Debuff, Effect::Ruin => Category::Debuff,
Effect::Curse => Category::Debuff, Effect::Curse => Category::Debuff,
Effect::Banish => Category::Debuff, // todo randomise Effect::Banish => Category::Debuff, // todo randomise
// Effect::Banish => rng.gen_bool(0.5),
Effect::Slow => Category::Debuff, Effect::Slow => Category::Debuff,
Effect::Haste => Category::Buff, Effect::Haste => Category::Buff,
Effect::Hatred => Category::Buff, Effect::Hatred => Category::Buff,