267 lines
8.6 KiB
JavaScript
267 lines
8.6 KiB
JavaScript
const preact = require('preact');
|
|
const { connect } = require('preact-redux');
|
|
const countBy = require('lodash/countBy');
|
|
const forEach = require('lodash/forEach');
|
|
|
|
const actions = require('../actions');
|
|
|
|
const InfoContainer = require('./info.container');
|
|
const StashElement = require('./vbox.stash');
|
|
const StoreElement = require('./vbox.store');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const {
|
|
ws,
|
|
instance,
|
|
player,
|
|
vboxSelected,
|
|
info,
|
|
itemInfo,
|
|
itemUnequip,
|
|
tutorial,
|
|
} = state;
|
|
|
|
function sendVboxDiscard() {
|
|
return ws.sendVboxDiscard(instance.id);
|
|
}
|
|
|
|
function sendVboxAccept(group, index) {
|
|
document.activeElement.blur();
|
|
return ws.sendVboxAccept(instance.id, group, index);
|
|
}
|
|
|
|
function sendVboxReclaim(i) {
|
|
return ws.sendVboxReclaim(instance.id, i);
|
|
}
|
|
|
|
function sendItemUnequip([constructId, item]) {
|
|
return ws.sendVboxUnequip(instance.id, constructId, item);
|
|
}
|
|
|
|
return {
|
|
instance,
|
|
info,
|
|
player,
|
|
sendVboxAccept,
|
|
sendVboxDiscard,
|
|
sendVboxReclaim,
|
|
vboxSelected,
|
|
itemInfo,
|
|
itemUnequip,
|
|
sendItemUnequip,
|
|
tutorial,
|
|
};
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function setInfo(item) {
|
|
return dispatch(actions.setInfo(item));
|
|
}
|
|
|
|
function setVboxSelected(v) {
|
|
dispatch(actions.setItemUnequip([]));
|
|
dispatch(actions.setVboxSelected(v));
|
|
return dispatch(actions.setVboxSelected(v));
|
|
}
|
|
|
|
return {
|
|
setInfo,
|
|
setVboxSelected,
|
|
};
|
|
}
|
|
);
|
|
|
|
function validVboxSelect(vbox, itemInfo, storeSelect, stashSelect) {
|
|
if (storeSelect.length === 0 && stashSelect.length === 0) return false;
|
|
|
|
const validSelects = [];
|
|
|
|
const stashItems = stashSelect.map(j => vbox.bound[j]);
|
|
const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]);
|
|
|
|
const selectedItems = stashItems.concat(shopItems);
|
|
const itemCount = countBy(selectedItems, co => co);
|
|
|
|
itemInfo.combos.forEach(combo => {
|
|
const comboCount = countBy(combo.components, co => co);
|
|
const buyCount = countBy(combo.components, co => co);
|
|
const valid = selectedItems.every(c => {
|
|
if (!combo.components.includes(c)) return false;
|
|
if (itemCount[c] > comboCount[c]) return false;
|
|
buyCount[c] -= 1;
|
|
return true;
|
|
});
|
|
if (valid) {
|
|
forEach(buyCount, (value, key) => {
|
|
if (value > 0 && !validSelects.includes(key)) validSelects.push(key);
|
|
});
|
|
}
|
|
});
|
|
|
|
return validSelects;
|
|
}
|
|
|
|
class Vbox extends preact.Component {
|
|
shouldComponentUpdate(newProps) {
|
|
// Single variable props
|
|
if (newProps.itemUnequip !== this.props.itemUnequip) return true;
|
|
if (newProps.tutorial !== this.props.tutorial) return true;
|
|
if (newProps.vboxSelected !== this.props.vboxSelected) return true;
|
|
if (newProps.player !== this.props.player) return true;
|
|
if (newProps.instance !== this.props.instance) return true;
|
|
return false;
|
|
}
|
|
|
|
render(args) {
|
|
const {
|
|
// Changing state variables
|
|
itemUnequip,
|
|
player,
|
|
tutorial,
|
|
vboxSelected,
|
|
instance,
|
|
|
|
// Static
|
|
itemInfo,
|
|
// Function Calls
|
|
sendItemUnequip,
|
|
sendVboxAccept,
|
|
sendVboxDiscard,
|
|
sendVboxReclaim,
|
|
setVboxSelected,
|
|
setInfo,
|
|
} = args;
|
|
|
|
if (!player) return false;
|
|
const { vbox } = player;
|
|
const { storeSelect, stashSelect } = vboxSelected;
|
|
const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0;
|
|
|
|
function combinerChange(newStashSelect) {
|
|
return setVboxSelected({ storeSelect, stashSelect: newStashSelect });
|
|
}
|
|
|
|
const vboxHighlight = validVboxSelect(vbox, itemInfo, storeSelect, stashSelect);
|
|
//
|
|
// VBOX
|
|
//
|
|
function vboxHover(e, v) {
|
|
if (v) {
|
|
e.stopPropagation();
|
|
if (storeSelect.find(c => c[0])) return true; // There is a base skill or spec selected in the vbox
|
|
if (stashSelect.length !== 0) {
|
|
const base = stashSelect.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c]));
|
|
if (base || base === 0) return true;
|
|
}
|
|
setInfo(v);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function clearVboxSelected() {
|
|
setVboxSelected({ storeSelect: [], stashSelect: [] });
|
|
}
|
|
|
|
function vboxBuySelected() {
|
|
if (!vboxSelecting) return false;
|
|
document.activeElement.blur();
|
|
sendVboxAccept(storeSelect[0][0], storeSelect[0][1]);
|
|
return true;
|
|
}
|
|
|
|
function storeHdr() {
|
|
return (
|
|
<div class="store-hdr">
|
|
<h3
|
|
onTouchStart={e => e.target.scrollIntoView(true)}
|
|
onMouseOver={e => vboxHover(e, 'store')}> STORE
|
|
</h3>
|
|
<div class={`bits ${vbox.bits < 3 ? 'red' : false}`} onMouseOver={e => vboxHover(e, 'bits')}>
|
|
<h1> {vbox.bits}b </h1>
|
|
</div>
|
|
<button
|
|
class='vbox-btn'
|
|
onMouseOver={e => vboxHover(e, 'refill')}
|
|
disabled={vbox.bits < 2
|
|
|| (tutorial && tutorial < 7
|
|
&& instance.time_control === 'Practice' && instance.rounds.length === 1)
|
|
}
|
|
onClick={e => e.stopPropagation()}
|
|
onMouseDown={() => sendVboxDiscard()}>
|
|
refill <br />
|
|
2b
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function stashHdr() {
|
|
const refund = storeSelect.length === 0 && stashSelect.length === 1
|
|
? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost
|
|
: 0;
|
|
const tutorialDisabled = tutorial && tutorial < 8
|
|
&& instance.time_control === 'Practice' && instance.rounds.length === 1;
|
|
const refundBtn = (
|
|
<button
|
|
disabled={tutorialDisabled || !refund}
|
|
class='vbox-btn'
|
|
onClick={e => e.stopPropagation()}
|
|
onMouseDown={e => {
|
|
e.stopPropagation();
|
|
sendVboxReclaim(vboxSelected.stashSelect[0]);
|
|
}}>
|
|
refund <br />
|
|
{refund}b
|
|
</button>
|
|
);
|
|
|
|
return (
|
|
<div class='stash-hdr'>
|
|
<h3 onTouchStart={e => e.target.scrollIntoView(true)}
|
|
onMouseOver={e => vboxHover(e, 'stash')}> STASH
|
|
</h3>
|
|
{refundBtn}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// EVERYTHING
|
|
return (
|
|
<div class='vbox'>
|
|
{storeHdr()}
|
|
{stashHdr()}
|
|
<InfoContainer
|
|
vboxHighlight={vboxHighlight}
|
|
vboxBuySelected={vboxBuySelected}
|
|
/>
|
|
<StoreElement
|
|
clearVboxSelected = {clearVboxSelected}
|
|
setInfo = {setInfo}
|
|
setVboxSelected = {setVboxSelected}
|
|
storeSelect = {storeSelect}
|
|
stashSelect = {stashSelect}
|
|
vbox = {vbox}
|
|
vboxHighlight = {vboxHighlight}
|
|
vboxHover = {vboxHover}
|
|
/>
|
|
<StashElement
|
|
combinerChange = {combinerChange}
|
|
itemUnequip = {itemUnequip}
|
|
vbox = {vbox}
|
|
vboxBuySelected = {vboxBuySelected}
|
|
vboxHighlight = {vboxHighlight}
|
|
vboxHover = {vboxHover}
|
|
vboxSelecting = {vboxSelecting}
|
|
stashSelect = {stashSelect}
|
|
sendItemUnequip = {sendItemUnequip}
|
|
setInfo = {setInfo}
|
|
setVboxSelected = {setVboxSelected}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = addState(Vbox);
|