const { connect } = require('preact-redux'); const preact = require('preact'); const range = require('lodash/range'); const buttons = require('./buttons'); const shapes = require('./shapes'); const { OFFENSE, DEFENSE } = require('../utils'); const { ConstructAvatar } = require('./construct'); const actions = require('../actions'); const { removeTier } = require('../utils'); const { tutorialConstructDisplay, tutorialShouldDisableEquip } = require('../tutorial.utils.jsx'); const addState = connect( function receiveState(state) { const { ws, instance, player, account, itemInfo, itemUnequip, vboxSelected, tutorial, } = state; function sendVboxBuyEquip(constructId) { return ws.sendVboxBuyEquip(instance.id, vboxSelected.storeSelect[0][0], vboxSelected.storeSelect[0][1], constructId); } function sendVboxApply(constructId, i) { return ws.sendVboxApply(instance.id, constructId, i); } function sendVboxUnequipApply(targetConstructId) { return ws.sendVboxUnequipApply(instance.id, itemUnequip[0], itemUnequip[1], targetConstructId); } return { instance, player, account, sendVboxBuyEquip, sendVboxUnequipApply, sendVboxApply, itemInfo, itemUnequip, vboxSelected, tutorial, }; }, function receiveDispatch(dispatch) { function quit() { dispatch(actions.setInstance(null)); } function setInfo(item) { dispatch(actions.setInfo(item)); } function setItemUnequip(v) { const info = v.length ? v[1] : null; dispatch(actions.setVboxInfo(info)); dispatch(actions.setVboxCombiner(null)); dispatch(actions.setVboxHighlight(false)); dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); return dispatch(actions.setItemUnequip(v)); } return { quit, setInfo, setItemUnequip }; } ); function Construct(props) { const { // Changing state variables construct, iter, itemUnequip, instance, player, vboxSelected, tutorial, // Static Info itemInfo, // Function Calls sendVboxApply, sendVboxBuyEquip, sendVboxUnequipApply, setItemUnequip, setInfo, } = props; const { vbox } = player; const itemEquip = vboxSelected.storeSelect.length === 0 && vboxSelected.stashSelect.length === 1 ? vboxSelected.stashSelect[0] : -1; const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => { if (!itemEquip && itemEquip !== 0) return false; if (!sk) return false; return sk.skill === vbox.stash[itemEquip]; }); const tutorialDisableEquip = tutorialShouldDisableEquip(tutorial, iter, instance, construct); function onClick(e) { e.stopPropagation(); e.preventDefault(); if (duplicateSkill || tutorialDisableEquip) return true; if (itemEquip !== -1) return sendVboxApply(construct.id, itemEquip); if (vboxSelected.storeSelect.length === 1) return sendVboxBuyEquip(construct.id); if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id); setItemUnequip([]); return true; } function hoverInfo(e, info) { e.stopPropagation(); if (!info) return false; if (vboxSelected.storeSelect.length || vboxSelected.stashSelect.length) return false; return setInfo(info); } 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, 1).map(i => { const skill = construct.skills[i]; const s = skill ? skill.skill : (SKILL); function skillClick(e) { if (!skill) return false; e.stopPropagation(); if (itemUnequip.length && itemUnequip[0] === construct.id && skill.skill === itemUnequip[1] && i === itemUnequip[2]) return setItemUnequip([]); setItemUnequip([construct.id, skill.skill, i]); return true; } const equipping = skillList.includes(vbox.stash[itemEquip]) && !skill && !tutorialDisableEquip && !duplicateSkill && i === construct.skills.length; const border = () => { if (!skill) return ''; const borderFn = buttons[removeTier(skill.skill)]; if (!borderFn) return ''; return borderFn(); }; const highlight = itemUnequip[0] === construct.id && itemUnequip[1] === s ? 'highlight' : ''; const classes = `${highlight} ${equipping ? 'equipping' : ''} ${!skill ? 'empty' : ''} ${border()}`; return ( ); }); const specs = range(0, 0).map(i => { const s = construct.specs[i]; if (!s) { const equipping = specList.includes(vbox.stash[itemEquip]) && i === construct.specs.length; const classes = `${equipping ? 'equipping' : 'gray'} empty`; return ( ); } function specClick(e) { if (!s) return false; e.stopPropagation(); if (itemUnequip.length && itemUnequip[0] === construct.id && itemUnequip[1] === s && i === itemUnequip[2]) return setItemUnequip([]); return setItemUnequip([construct.id, s, i]); } const highlight = itemUnequip[0] === construct.id && itemUnequip[1] === s && i === itemUnequip[2]; return ( ); }); const offensiveStats = Object.keys(OFFENSE).map(s => { const stat = OFFENSE[s]; const info = (s === 'SpeedStat' && 'speedStat') || (s.includes('Power') && 'powerStat'); return
hoverInfo(e, info)} > {shapes[s]()}
{construct[stat.stat].value}
; }); const defensiveStats = Object.keys(DEFENSE).map(s => { const stat = DEFENSE[s]; const info = (s.includes('Life') && 'lifeStat'); return
hoverInfo(e, info)} > {shapes[s]()}
{construct[stat.stat].value}
; }); const classes = 'instance-construct'; const avatarMouseOver = e => hoverInfo(e, `constructAvatar ${construct.name}`); return (
ev.preventDefault()} onDrop={onClick}>

hoverInfo(e, `constructName ${construct.name}`)}>{construct.name}

hoverInfo(e, 'constructSkills')} > {skills}
hoverInfo(e, 'constructSpecs')} > {specs}
{offensiveStats}
{defensiveStats}
); } class InstanceConstructs extends preact.Component { shouldComponentUpdate(newProps) { if (newProps.itemUnequip !== this.props.itemUnequip) return true; if (newProps.tutorial !== this.props.tutorial) return true; // JSON or Array objects if (newProps.player !== this.props.player) return true; if (newProps.instance !== this.props.instance) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true; return false; } render(props) { const { // Changing state variables itemUnequip, instance, player, tutorial, vboxSelected, // Static data itemInfo, // Function calls setInfo, sendVboxApply, sendVboxBuyEquip, sendVboxUnequipApply, setItemUnequip, } = props; if (!player) return false; if (instance.phase === 'Lobby') return false; const constructs = range(0, 3).map(i => { const tutorialConstruct = tutorialConstructDisplay(player, instance, tutorial, i); if (tutorialConstruct) return (tutorialConstruct); return Construct({ iter: i, construct: player.constructs[i], itemUnequip, instance, setItemUnequip, player, sendVboxApply, sendVboxBuyEquip, sendVboxUnequipApply, setInfo, itemInfo, vboxSelected, tutorial, }); }); return (
{constructs}
); } } module.exports = addState(InstanceConstructs);