334 lines
9.1 KiB
JavaScript
334 lines
9.1 KiB
JavaScript
const preact = require('preact');
|
|
const range = require('lodash/range');
|
|
const { connect } = require('preact-redux');
|
|
|
|
const shapes = require('./shapes');
|
|
const { convertItem } = require('./../utils');
|
|
const actions = require('../actions');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const {
|
|
ws,
|
|
instance,
|
|
player,
|
|
combiner,
|
|
reclaiming,
|
|
vboxHighlight,
|
|
itemInfo,
|
|
} = state;
|
|
|
|
function sendVboxDiscard() {
|
|
return ws.sendVboxDiscard(instance.id);
|
|
}
|
|
|
|
function sendVboxAccept(group, index) {
|
|
return ws.sendVboxAccept(instance.id, group, index);
|
|
}
|
|
|
|
function sendVboxCombine() {
|
|
return ws.sendVboxCombine(instance.id, combiner);
|
|
}
|
|
|
|
function sendVboxReclaim(i) {
|
|
return ws.sendVboxReclaim(instance.id, i);
|
|
}
|
|
|
|
return {
|
|
combiner,
|
|
instance,
|
|
player,
|
|
reclaiming,
|
|
sendVboxAccept,
|
|
sendVboxCombine,
|
|
sendVboxDiscard,
|
|
sendVboxReclaim,
|
|
vboxHighlight,
|
|
itemInfo,
|
|
};
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function setCombiner(c) {
|
|
return dispatch(actions.setCombiner(c));
|
|
}
|
|
|
|
function setReclaiming(v) {
|
|
return dispatch(actions.setReclaiming(v));
|
|
}
|
|
|
|
function setInfo(item) {
|
|
return dispatch(actions.setInfo(item));
|
|
}
|
|
|
|
function setVboxHighlight(v) {
|
|
return dispatch(actions.setVboxHighlight(v));
|
|
}
|
|
|
|
return {
|
|
setCombiner,
|
|
setReclaiming,
|
|
setInfo,
|
|
setVboxHighlight,
|
|
};
|
|
}
|
|
|
|
);
|
|
|
|
function Vbox(args) {
|
|
const {
|
|
combiner,
|
|
instance,
|
|
itemInfo,
|
|
player,
|
|
reclaiming,
|
|
sendVboxAccept,
|
|
sendVboxCombine,
|
|
sendVboxDiscard,
|
|
sendVboxReclaim,
|
|
vboxHighlight,
|
|
|
|
setCombiner,
|
|
setInfo,
|
|
setReclaiming,
|
|
setVboxHighlight,
|
|
} = args;
|
|
|
|
if (!player) return false;
|
|
const { vbox } = player;
|
|
|
|
// function setHighlight(type) {
|
|
// 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.item));
|
|
// return false;
|
|
// }
|
|
|
|
function combinerChange(newCombiner) {
|
|
setCombiner(newCombiner);
|
|
if (newCombiner.every(c => c === null)) return setVboxHighlight([]);
|
|
|
|
const combinerValues = newCombiner.map(cv => player.vbox.bound[cv]).filter(cv => cv);
|
|
|
|
const filteredCombos = itemInfo.combos
|
|
.filter(combo => combinerValues.every(u => combo.components.includes(u)));
|
|
|
|
const comboValues = itemInfo.items.filter(v => {
|
|
if (!filteredCombos.some(c => c.components.includes(v.item))) return false;
|
|
if (!['Red', 'Green', 'Blue'].includes(v.item) && combinerValues.includes(v.item)) return false;
|
|
return true;
|
|
});
|
|
|
|
return setVboxHighlight(comboValues.map(v => v.item));
|
|
}
|
|
|
|
//
|
|
// VBOX
|
|
//
|
|
const free = [];
|
|
for (let i = 0; i < 6; i++) {
|
|
free.push([vbox.free[0][i], vbox.free[1][i], vbox.free[2][i]]);
|
|
}
|
|
|
|
let vboxTimer;
|
|
const LONG_TOUCH_TIME = 500;
|
|
function vboxTouchStart(e, i, j) {
|
|
vboxTimer = (setTimeout(() => {
|
|
sendVboxAccept(j, i);
|
|
vboxTimer = null;
|
|
}, LONG_TOUCH_TIME));
|
|
return true;
|
|
}
|
|
|
|
function vboxTouchEnd(e, i, j) {
|
|
if (vboxTimer) {
|
|
clearTimeout(vboxTimer);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function vboxTouchMove(e) {
|
|
if (vboxTimer) clearTimeout(vboxTimer);
|
|
e.stopPropagation();
|
|
return true;
|
|
}
|
|
|
|
function vboxHover(e, v) {
|
|
if (v) {
|
|
setInfo(v);
|
|
e.stopPropagation();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const freeRows = free.map((row, i) => {
|
|
const cells = row.map((c, j) => {
|
|
const highlighted = c && vboxHighlight.includes(c);
|
|
|
|
return <td
|
|
key={j}
|
|
class={`${highlighted ? 'highlight' : ''}`}
|
|
onTouchStart={e => vboxTouchStart(e, i, j)}
|
|
onTouchEnd={e => vboxTouchEnd(e, i, j)}
|
|
onTouchMove={e => vboxTouchMove(e)}
|
|
|
|
// onClick={freeClick}
|
|
onDblClick={() => sendVboxAccept(j, i) }
|
|
onMouseOver={e => vboxHover(e, c)}
|
|
>
|
|
{convertItem(c)}
|
|
</td>;
|
|
});
|
|
|
|
return (
|
|
<tr key={i}>
|
|
{cells}
|
|
</tr>
|
|
);
|
|
});
|
|
|
|
//
|
|
// INVENTORY
|
|
//
|
|
function boundClick(e, i) {
|
|
const value = vbox.bound[i];
|
|
if (reclaiming && value) return sendVboxReclaim(i);
|
|
if (value) {
|
|
const insert = combiner.findIndex(j => j === null);
|
|
if (insert === -1) return combinerChange([i, null, null]);
|
|
combiner[insert] = i;
|
|
return combinerChange(combiner);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const boundTds = range(0, 9).map(i => {
|
|
const value = vbox.bound[i];
|
|
if (combiner.indexOf(i) > -1) {
|
|
return (
|
|
<td
|
|
key={i}>
|
|
|
|
</td>
|
|
);
|
|
}
|
|
|
|
const highlighted = value && vboxHighlight.includes(value);
|
|
|
|
return (
|
|
<td
|
|
key={i}
|
|
class={`${highlighted ? 'highlight' : ''}`}
|
|
onMouseOver={(e) => vboxHover(e, value)}
|
|
onClick={e => boundClick(e, i, highlighted) }>
|
|
{convertItem(value)}
|
|
</td>
|
|
);
|
|
});
|
|
|
|
const boundRows = [
|
|
<tr key={0} >
|
|
{boundTds[0]}
|
|
{boundTds[1]}
|
|
{boundTds[2]}
|
|
</tr>,
|
|
<tr key={1}>
|
|
{boundTds[3]}
|
|
{boundTds[4]}
|
|
{boundTds[5]}
|
|
</tr>,
|
|
<tr key={2}>
|
|
{boundTds[6]}
|
|
{boundTds[7]}
|
|
{boundTds[8]}
|
|
</tr>,
|
|
];
|
|
|
|
//
|
|
// COMBINER
|
|
//
|
|
function combinerRmv(i) {
|
|
combiner[i] = null;
|
|
return combinerChange(combiner);
|
|
}
|
|
const combinerElement = (
|
|
<table class="vbox-table">
|
|
<tbody>
|
|
<tr>
|
|
<td onClick={() => combinerRmv(0)}>
|
|
{combiner[0] !== null ? convertItem(vbox.bound[combiner[0]]) : shapes.vboxColour('gray')}
|
|
</td>
|
|
<td onClick={() => combinerRmv(1)}>
|
|
{combiner[1] !== null ? convertItem(vbox.bound[combiner[1]]) : shapes.vboxColour('gray')}
|
|
</td>
|
|
<td onClick={() => combinerRmv(2)}>
|
|
{convertItem(vbox.bound[combiner[2]])}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
);
|
|
|
|
//
|
|
// EVERYTHING
|
|
//
|
|
|
|
function reclaimClick(e) {
|
|
e.stopPropagation();
|
|
return setReclaiming(!reclaiming);
|
|
}
|
|
|
|
function hoverInfo(e, info) {
|
|
e.stopPropagation();
|
|
return setInfo(info);
|
|
}
|
|
|
|
const classes = `vbox`;
|
|
const reclaimClass = `vbox-btn reclaim ${reclaiming ? 'reclaiming' : ''}`;
|
|
|
|
return (
|
|
<div class={classes}>
|
|
<div class='vbox-box' onClick={() => setReclaiming(false)} onMouseOver={e => hoverInfo(e, 'vbox')} >
|
|
<div class="vbox-hdr">
|
|
<h3 onTouchStart={e => e.target.scrollIntoView(true)}>VBOX</h3>
|
|
<div class="bits" onMouseOver={e => hoverInfo(e, 'bits')} >{vbox.bits}b</div>
|
|
</div>
|
|
<button
|
|
onMouseOver={e => hoverInfo(e, 'reroll')}
|
|
onClick={() => sendVboxDiscard()}>
|
|
Reroll
|
|
</button>
|
|
<table class="vbox-table">
|
|
<tbody>
|
|
{freeRows}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class='vbox-inventory' onClick={() => setReclaiming(false)} onMouseOver={e => hoverInfo(e, 'inventory')} >
|
|
<h3 onTouchStart={e => e.target.scrollIntoView(true)}>INVENTORY</h3>
|
|
<button
|
|
class={reclaimClass}
|
|
onMouseOver={e => hoverInfo(e, 'reclaim')}
|
|
onClick={reclaimClick}>
|
|
reclaim
|
|
</button>
|
|
<table class="vbox-table">
|
|
<tbody>
|
|
{boundRows}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="vbox-combiner" onMouseOver={e => hoverInfo(e, 'combiner')} >
|
|
<h3 onTouchStart={e => e.target.scrollIntoView(true)}>I-COMBINATOR</h3>
|
|
<button
|
|
onMouseOver={e => hoverInfo(e, 'refine')}
|
|
onClick={() => sendVboxCombine()}>
|
|
refine
|
|
</button>
|
|
{combinerElement}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
module.exports = addState(Vbox);
|