refactoring FeelsAmazingMan

This commit is contained in:
Mashy 2019-11-25 16:54:51 +10:00
parent e3b27ae6b2
commit 490216fb01
13 changed files with 272 additions and 431 deletions

View File

@ -3,7 +3,7 @@
grid-area: vbox;
display: grid;
grid-template-rows: 3fr minmax(min-content, 2fr);
grid-template-columns: 1fr 4fr 6fr 17em; // =\
grid-template-columns: 1fr 4fr 6fr min-content;
grid-template-areas:
"store-hdr store info combos"
"stash-hdr stash combiner combos";
@ -217,7 +217,9 @@
display: grid;
grid-area: combos;
margin-left: 0.5em;
margin-right: 0.5em;
grid-template-rows: min-content min-content;
width: 15.5em;
grid-template-areas:
"comboHeader"
"comboList";

View File

@ -48,5 +48,8 @@ export const setTutorial = value => ({ type: 'SET_TUTORIAL', value });
export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value });
export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value });
export const setVboxCombiner = value => ({ type: 'SET_VBOX_COMBINER', value });
export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value });
export const setVboxInfo = value => ({ type: 'SET_VBOX_INFO', value });
export const setWs = value => ({ type: 'SET_WS', value });

View File

@ -8,7 +8,6 @@ const { createStore, combineReducers } = require('redux');
const { StripeProvider } = require('react-stripe-elements');
const reducers = require('./reducers');
const actions = require('./actions');
const setupKeys = require('./keyboard');
const createSocket = require('./socket');
const registerEvents = require('./events');

View File

@ -1,104 +1,44 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const countBy = require('lodash/countBy');
const addState = connect(
function receiveState(state) {
const {
ws,
itemInfo,
instance,
player,
vboxSelected,
} = state;
function sendVboxAccept(group, index) {
document.activeElement.blur();
return ws.sendVboxAccept(instance.id, group, index);
}
function sendVboxCombine() {
return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect);
}
return {
itemInfo,
player,
vboxSelected,
sendVboxAccept,
sendVboxCombine,
};
}
);
function Combiner(args) {
const {
// Variables that will change
vboxHighlight,
vbox,
vboxCombiner,
vboxSelected,
// Static
player,
itemInfo,
// functions
sendVboxAccept,
vboxBuySelected,
sendVboxCombine,
} = args;
const { vbox } = player;
const { stashSelect, storeSelect } = vboxSelected;
const vboxCombo = () => {
if (!(vboxHighlight && vboxHighlight.length === 0)) return false;
// The selected items can't be combined with additional items therefore valid combo
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 combinerCount = countBy(selectedItems, co => co);
const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => {
if (!combo.components.includes(c)) return false;
const comboCount = countBy(combo.components, co => co);
if (combinerCount[c] > comboCount[c]) return false;
return true;
}));
return comboItemObj.item;
};
const combinerCombo = vboxCombo();
function vboxBuySelected() {
if (!(storeSelect.length === 1 && stashSelect.length === 0)) return false;
document.activeElement.blur();
sendVboxAccept(storeSelect[0][0], storeSelect[0][1]);
return true;
}
let text = '';
let mouseEvent = false;
if (combinerCombo) {
const combinerComboText = combinerCombo.replace('Plus', '+');
if (vboxCombiner) {
const combinerComboText = vboxCombiner.replace('Plus', '+');
let bits = 0;
storeSelect.forEach(item => bits += item[0] + 1);
text = bits
? `Buy ${combinerComboText} ${bits}b`
: `Combine ${combinerComboText}`;
if (vbox.bits >= bits) mouseEvent = sendVboxCombine;
} else if (stashSelect.length === 0 && storeSelect.length === 1) {
const item = storeSelect[0];
text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`;
mouseEvent = vboxBuySelected;
} else {
return false;
}
return (
<button
class='combiner vbox-btn'
disabled={!mouseEvent}
disabled={bits > vbox.bits}
onClick={e => e.stopPropagation()}
onMouseDown={() => mouseEvent()}>
{text}
onMouseDown={sendVboxCombine}>
{bits ? `Buy ${combinerComboText} ${bits}b` : `Combine ${combinerComboText}`}
</button>
);
}
module.exports = addState(Combiner);
if (stashSelect.length === 0 && storeSelect.length === 1) {
const item = storeSelect[0];
return (
<button
class='combiner vbox-btn'
onClick={e => e.stopPropagation()}
onMouseDown={vboxBuySelected}>
{`Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`}
</button>
);
}
return false;
}
module.exports = Combiner;

View File

@ -1,112 +1,27 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const reactStringReplace = require('react-string-replace');
const countBy = require('lodash/countBy');
const { convertItem, removeTier } = require('../utils');
const shapes = require('./shapes');
const { convertItem } = require('../utils');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
info,
itemInfo,
itemUnequip,
instance,
player,
account,
tutorial,
vboxSelected,
} = state;
function sendVboxAccept(group, index) {
document.activeElement.blur();
return ws.sendVboxAccept(instance.id, group, index);
}
function sendVboxCombine() {
return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect);
}
return {
ws,
info,
itemInfo,
itemUnequip,
instance,
player,
account,
tutorial,
vboxSelected,
sendVboxAccept,
sendVboxCombine,
};
}
);
const addState = connect(({ info, itemInfo, instance, tutorial, vboxInfo }) =>
({ info, itemInfo, instance, tutorial, vboxInfo }));
function Combos(args) {
const {
// Variables that will change
info,
itemUnequip,
tutorial,
vboxHighlight,
vboxSelected,
vboxInfo,
// Static
player, // Only used for colour calcs which will be update if info changes
ws,
itemInfo,
instance, // Only used for instance id
instance, // Only used for tutorial check
// functions
sendVboxAccept,
sendVboxCombine,
setTutorialNull,
} = args;
const { comboItem } = this.state;
const { vbox } = player;
const { stashSelect, storeSelect } = vboxSelected;
const vboxCombo = () => {
if (!(vboxHighlight && vboxHighlight.length === 0)) return false;
// The selected items can't be combined with additional items therefore valid combo
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 combinerCount = countBy(selectedItems, co => co);
const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => {
if (!combo.components.includes(c)) return false;
const comboCount = countBy(combo.components, co => co);
if (combinerCount[c] > comboCount[c]) return false;
return true;
}));
return comboItemObj.item;
};
const combinerCombo = vboxCombo();
const checkVboxInfo = () => {
if (combinerCombo) return combinerCombo;
const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i])));
if (stashBase > -1) return vbox.bound[stashBase];
const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]])));
if (storeBase) return vbox.free[storeBase[0]][storeBase[1]];
if (stashSelect.length > 0) return vbox.bound[stashSelect[0]];
if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]];
return false;
};
let vboxInfo = false;
if (itemUnequip.length) [, vboxInfo] = itemUnequip;
else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo();
if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false;
if (!info && !vboxInfo) return false;
const comboInfo = vboxInfo || info;
const vboxCombos = itemInfo.combos.filter(c => c.components.includes(comboInfo));
if (vboxCombos.length > 6 || vboxCombos.length === 0) return false;
const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info));
if (vboxCombos.length > 6 || vboxCombos.length === 0) return <div class="combos"></div>;
const comboTable = vboxCombos.map((c, i) => {
const mouseOver = e => {
@ -126,14 +41,15 @@ function Combos(args) {
</div>
);
});
const comboList = comboTable.length > 0 ? <div class="combo-list">{comboTable}</div> : false;
return (
<div class="combos">
<div class="combo-header">
<h2>COMBOS</h2>
Combine colours and items.
</div>
{comboList}
<div class="combo-list">
{comboTable}
</div>
</div>
);
}

View File

@ -1,7 +1,5 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const countBy = require('lodash/countBy');
const forEach = require('lodash/forEach');
const actions = require('../actions');
@ -11,17 +9,23 @@ const StoreElement = require('./vbox.store');
const Combiner = require('./vbox.combiner');
const Combos = require('./vbox.combos');
const { setVboxState } = require('./vbox.utils');
const addState = connect(
function receiveState(state) {
const {
ws,
instance,
player,
vboxSelected,
info,
itemInfo,
itemUnequip,
tutorial,
vboxCombiner,
vboxHighlight,
vboxInfo,
vboxSelected,
} = state;
function sendVboxDiscard() {
@ -29,10 +33,15 @@ const addState = connect(
}
function sendVboxAccept(group, index) {
if (!(vboxSelected.storeSelect.length === 1 && vboxSelected.stashSelect.length === 0)) return false;
document.activeElement.blur();
return ws.sendVboxAccept(instance.id, group, index);
}
function sendVboxCombine() {
return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect);
}
function sendVboxReclaim(i) {
return ws.sendVboxReclaim(instance.id, i);
}
@ -42,17 +51,23 @@ const addState = connect(
}
return {
player,
instance,
info,
player,
sendVboxAccept,
sendVboxDiscard,
sendVboxReclaim,
vboxSelected,
itemInfo,
itemUnequip,
sendItemUnequip,
tutorial,
vboxCombiner,
vboxHighlight,
vboxInfo,
vboxSelected,
sendVboxAccept,
sendVboxCombine,
sendVboxDiscard,
sendVboxReclaim,
};
},
@ -61,55 +76,26 @@ const addState = connect(
return dispatch(actions.setInfo(item));
}
function setVboxSelected(v) {
function dispatchVboxSelect(v, state) {
setVboxState(dispatch, v, state);
dispatch(actions.setItemUnequip([]));
dispatch(actions.setVboxSelected(v));
return dispatch(actions.setVboxSelected(v));
}
return {
dispatchVboxSelect,
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.vboxHighlight !== this.props.vboxHighlight) return true;
if (newProps.player !== this.props.player) return true;
if (newProps.instance !== this.props.instance) return true;
return false;
@ -121,33 +107,33 @@ class Vbox extends preact.Component {
itemUnequip,
player,
tutorial,
vboxSelected,
instance,
vboxCombiner,
vboxHighlight,
vboxInfo,
vboxSelected,
// Static
itemInfo,
// Function Calls
dispatchVboxSelect,
sendItemUnequip,
sendVboxAccept,
sendVboxCombine,
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 setVboxSelected = v => dispatchVboxSelect(v, { itemInfo, itemUnequip, vbox });
const clearVboxSelected = () => setVboxSelected({ storeSelect: [], stashSelect: [] });
const vboxBuySelected = () => sendVboxAccept(storeSelect[0][0], storeSelect[0][1]);
const vboxHighlight = validVboxSelect(vbox, itemInfo, storeSelect, stashSelect);
//
// VBOX
//
function vboxHover(e, v) {
if (v) {
e.stopPropagation();
@ -157,17 +143,6 @@ class Vbox extends preact.Component {
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">
@ -233,37 +208,33 @@ class Vbox extends preact.Component {
clearVboxSelected = {clearVboxSelected}
setInfo = {setInfo}
setVboxSelected = {setVboxSelected}
storeSelect = {storeSelect}
stashSelect = {stashSelect}
storeSelect = {storeSelect}
vbox = {vbox}
vboxHighlight = {vboxHighlight}
vboxHover = {vboxHover}
/>
<StashElement
combinerChange = {combinerChange}
itemUnequip = {itemUnequip}
stashSelect = {stashSelect}
storeSelect = {storeSelect}
sendItemUnequip = {sendItemUnequip}
setInfo = {setInfo}
setVboxSelected = {setVboxSelected}
vbox = {vbox}
vboxBuySelected = {vboxBuySelected}
vboxHighlight = {vboxHighlight}
vboxHover = {vboxHover}
vboxSelecting = {vboxSelecting}
stashSelect = {stashSelect}
sendItemUnequip = {sendItemUnequip}
setInfo = {setInfo}
setVboxSelected = {setVboxSelected}
/>
<InfoContainer
vboxHighlight={vboxHighlight}
vboxBuySelected={vboxBuySelected}
/>
<Combiner
vboxHighlight={vboxHighlight}
vboxBuySelected={vboxBuySelected}
/>
<Combos
vboxHighlight={vboxHighlight}
vbox={vbox}
vboxCombiner={vboxCombiner}
vboxSelected={vboxSelected}
vboxBuySelected={vboxBuySelected}
sendVboxCombine={sendVboxCombine}
/>
<Combos />
<InfoContainer />
</div>
);
}

View File

@ -1,169 +1,33 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const reactStringReplace = require('react-string-replace');
const countBy = require('lodash/countBy');
const specThresholds = require('./vbox.info.thresholds');
const { INFO } = require('./../constants');
const { convertItem, removeTier } = require('../utils');
const { tutorialStage } = require('../tutorial.utils');
const shapes = require('./shapes');
const { genItemInfo } = require('./vbox.utils');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
info,
itemInfo,
itemUnequip,
instance,
player,
account,
tutorial,
vboxSelected,
} = state;
return {
ws,
info,
itemInfo,
itemUnequip,
instance,
player,
account,
tutorial,
vboxSelected,
};
},
function receiveDispatch(dispatch) {
function setTutorialNull() {
dispatch(actions.setTutorial(null));
}
function setInfo(info) {
dispatch(actions.setInfo(info));
}
return { setTutorialNull, setInfo };
}
);
const addState = connect(({ info, player, tutorial, vboxInfo, ws, itemInfo, instance }) =>
({ info, player, tutorial, vboxInfo, ws, itemInfo, instance }));
function Info(args) {
const {
// Variables that will change
info,
itemUnequip,
player,
tutorial,
vboxHighlight,
vboxSelected,
vboxInfo,
// Static
player, // Only used for colour calcs which will be update if info changes
ws,
itemInfo,
instance, // Only used for instance id
// functions
setTutorialNull,
instance,
} = args;
const { comboItem } = this.state;
const { vbox } = player;
const { stashSelect, storeSelect } = vboxSelected;
const vboxCombo = () => {
if (!(vboxHighlight && vboxHighlight.length === 0)) return false;
// The selected items can't be combined with additional items therefore valid combo
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 combinerCount = countBy(selectedItems, co => co);
const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => {
if (!combo.components.includes(c)) return false;
const comboCount = countBy(combo.components, co => co);
if (combinerCount[c] > comboCount[c]) return false;
return true;
}));
return comboItemObj.item;
};
const combinerCombo = vboxCombo();
const checkVboxInfo = () => {
if (combinerCombo) return combinerCombo;
const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i])));
if (stashBase > -1) return vbox.bound[stashBase];
const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]])));
if (storeBase) return vbox.free[storeBase[0]][storeBase[1]];
if (stashSelect.length > 0) return vbox.bound[stashSelect[0]];
if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]];
return false;
};
let vboxInfo = false;
if (itemUnequip.length) [, vboxInfo] = itemUnequip;
else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo();
if (tutorial) {
const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance);
const tutorialStageInfo = tutorialStage(tutorial, ws, instance);
if (tutorialStageInfo) return tutorialStageInfo;
}
function genItemInfo(item) {
const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item];
const isSkill = fullInfo.skill;
const isSpec = fullInfo.spec;
const itemDescription = () => {
const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/;
const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]());
return <div>{reactStringReplace(infoDescription, '\n', () => <br />)}</div>;
};
if (isSkill || isSpec) {
let infoName = fullInfo.item;
while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+');
// Prioritise the vbox info
if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info);
const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item));
let itemSourceInfo = itemSource.length && !isSpec
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
: false;
let header = null;
if (!itemSource.length) header = isSkill ? <h3> SKILL </h3> : <h3> SPEC </h3>;
if (itemSourceInfo) {
while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+');
const itemRegEx = /(Red|Blue|Green)/;
itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
}
const cooldown = isSkill && fullInfo.cooldown ? <div>{fullInfo.cooldown} Turn delay</div> : null;
const speed = isSkill
? <div> Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}% </div>
: null;
const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null;
return (
<div class={`info ${isSkill ? 'info-item' : 'info-item'}`}>
<h2>{infoName}</h2>
{header}
{itemSourceInfo}
{cooldown}
{itemDescription()}
{speed}
{thresholds}
</div>
);
}
return (
<div class="info info-item">
<h2>{fullInfo.item}</h2>
{itemDescription()}
</div>
);
}
const stateFullInfo = comboItem || vboxInfo;
if (stateFullInfo) return genItemInfo(stateFullInfo);
// check normal info state
if (!info) return false;
if (info.includes('constructName')) {
return (
@ -189,7 +53,7 @@ function Info(args) {
);
}
return genItemInfo(info);
return genItemInfo(info, itemInfo, player, info);
}
module.exports = addState(Info);

View File

@ -8,20 +8,20 @@ const { removeTier } = require('../utils');
function stashElement(props) {
const {
combinerChange,
itemUnequip,
sendItemUnequip,
setInfo,
setVboxSelected,
stashSelect,
storeSelect,
vbox,
vboxBuySelected,
vboxHighlight,
vboxHover,
vboxSelecting,
stashSelect,
sendItemUnequip,
setInfo,
setVboxSelected,
} = props;
const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0;
function stashClick(e) {
e.stopPropagation();
if (itemUnequip.length) return sendItemUnequip(itemUnequip);
@ -46,12 +46,13 @@ function stashElement(props) {
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v);
function onClick(type) {
function onClick(type, e) {
e.stopPropagation();
const combinerContainsIndex = stashSelect.indexOf(i) > -1;
// removing
if (combinerContainsIndex) {
if (type === 'click') {
return combinerChange(without(stashSelect, i));
return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) });
}
return true;
}
@ -61,9 +62,7 @@ function stashElement(props) {
return setVboxSelected({ storeSelect: [], stashSelect: [i] });
}
stashSelect.push(i);
// if (stashSelect.length === 3) setInfo(comboItem.item);
return combinerChange(stashSelect);
return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] });
}
const highlighted = stashSelect.indexOf(i) > -1;
@ -79,14 +78,14 @@ function stashElement(props) {
key={i}
draggable='true'
onDragStart={ev => {
onClick('drag');
onClick('drag', ev);
ev.dataTransfer.setData('text', '');
}}>
<button
class={classes}
onMouseOver={e => vboxHover(e, v)}
onClick={e => e.stopPropagation()}
onMouseDown={() => onClick('click')}>
onMouseDown={e => onClick('click', e)}>
{invObject}
</button>
</label>

View File

@ -0,0 +1,128 @@
const preact = require('preact');
const countBy = require('lodash/countBy');
const forEach = require('lodash/forEach');
const reactStringReplace = require('react-string-replace');
const actions = require('../actions');
const specThresholds = require('./vbox.info.thresholds');
const { INFO } = require('./../constants');
const { removeTier } = require('../utils');
const shapes = require('./shapes');
function setVboxState(dispatch, vboxSelected, state) {
const {
itemInfo,
itemUnequip,
vbox,
} = state;
const { storeSelect, stashSelect } = vboxSelected;
// default returns
let vboxCombiner = false;
let vboxHighlight = false;
if (!(storeSelect.length === 0 && stashSelect.length === 0)) {
vboxHighlight = [];
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) {
const fullCombo = combo.components.every(c => itemCount[c] === comboCount[c]);
if (fullCombo) vboxCombiner = combo.item;
forEach(buyCount, (value, key) => {
if (value > 0 && !vboxHighlight.includes(key)) {
vboxHighlight.push(key);
}
});
}
});
}
const vboxInfo = () => {
if (vboxCombiner) return vboxCombiner;
if (itemUnequip.length) return itemUnequip[1];
const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i])));
if (stashBase > -1) return vbox.bound[stashBase];
const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]])));
if (storeBase) return vbox.free[storeBase[0]][storeBase[1]];
if (stashSelect.length > 0) return vbox.bound[stashSelect[0]];
if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]];
return false;
};
dispatch(actions.setVboxInfo(vboxInfo()));
dispatch(actions.setVboxCombiner(vboxCombiner));
return dispatch(actions.setVboxHighlight(vboxHighlight));
}
function genItemInfo(item, itemInfo, player, info) {
const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item];
const isSkill = fullInfo.skill;
const isSpec = fullInfo.spec;
const itemDescription = () => {
const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/;
const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]());
return <div>{reactStringReplace(infoDescription, '\n', () => <br />)}</div>;
};
if (isSkill || isSpec) {
let infoName = fullInfo.item;
while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+');
const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item));
let itemSourceInfo = itemSource.length && !isSpec
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
: false;
let header = null;
if (!itemSource.length) header = isSkill ? <h3> SKILL </h3> : <h3> SPEC </h3>;
if (itemSourceInfo) {
while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+');
const itemRegEx = /(Red|Blue|Green)/;
itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
}
const cooldown = isSkill && fullInfo.cooldown ? <div>{fullInfo.cooldown} Turn delay</div> : null;
const speed = isSkill
? <div> Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}% </div>
: null;
const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null;
return (
<div class="info info-item">
<h2>{infoName}</h2>
{header}
{itemSourceInfo}
{cooldown}
{itemDescription()}
{speed}
{thresholds}
</div>
);
}
return (
<div class="info info-item">
<h2>{fullInfo.item}</h2>
{itemDescription()}
</div>
);
}
module.exports = { setVboxState, genItemInfo };

View File

@ -26,6 +26,12 @@ function registerEvents(store) {
return errorToast(msg);
}
function clearTutorial() {
store.dispatch(actions.setTutorial(null));
localStorage.setItem('tutorial-complete', true);
}
function setPing(ping) {
store.dispatch(actions.setPing(ping));
}
@ -182,6 +188,9 @@ function registerEvents(store) {
store.dispatch(actions.setActiveSkill(null));
store.dispatch(actions.setInfo(null));
store.dispatch(actions.setItemUnequip([]));
store.dispatch(actions.setItemUnequip([]));
store.dispatch(actions.setVboxCombiner(null));
store.dispatch(actions.setVboxHighlight(null));
store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] }));
}
@ -292,6 +301,9 @@ function registerEvents(store) {
startDemo();
}
// store.subscribe(setInfo);
// store.on('SET_INFO', setInfo);
// events.on('SET_PLAYER', setInstance);
// events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) {
@ -340,6 +352,7 @@ function registerEvents(store) {
clearInfo,
clearInstance,
clearMtxActive,
clearTutorial,
setAccount,
setAccountInstances,
setActiveItem,

View File

@ -57,6 +57,9 @@ module.exports = {
tutorialGame: createReducer(1, 'SET_TUTORIAL_GAME'),
vboxSelected: createReducer({ storeSelect: [], stashSelect: [] }, 'SET_VBOX_SELECTED'),
vboxCombiner: createReducer(null, 'SET_VBOX_COMBINER'),
vboxHighlight: createReducer(null, 'SET_VBOX_HIGHLIGHT'),
vboxInfo: createReducer(null, 'SET_VBOX_INFO'),
ws: createReducer(null, 'SET_WS'),
};

View File

@ -204,6 +204,11 @@ function createSocket(events) {
send(['SubscriptionState', {}]);
}
function clearTutorial(instanceId) {
events.clearTutorial();
sendInstanceState(instanceId);
}
// -------------
// Incoming
// -------------
@ -430,6 +435,8 @@ function createSocket(events) {
sendMtxBuy,
sendMtxConstructSpawn,
clearTutorial,
connect,
};
}

View File

@ -97,14 +97,10 @@ function tutorialVbox(player, store, tutorial) {
store.dispatch(actions.setTutorial(stage));
}
function tutorialStage(tutorial, ws, clearTutorial, instance) {
function tutorialStage(tutorial, ws, instance) {
if (!(instance.time_control === 'Practice' && instance.rounds.length === 1)) return false;
const exit = () => {
clearTutorial();
localStorage.setItem('tutorial-complete', true);
ws.sendInstanceState(instance.id);
};
const exit = () => ws.clearTutorial(instance.id);
const tutorialText = () => {
if (tutorial === 1) {