291 lines
9.4 KiB
JavaScript
291 lines
9.4 KiB
JavaScript
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
|
|
: (<span class="gray">SKILL</span>);
|
|
|
|
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 (
|
|
<label onDragStart={ev => {
|
|
ev.dataTransfer.setData('text', '');
|
|
skillClick(ev);
|
|
}} key={i} draggable={skill} onDragEnd={() => setItemUnequip([])}>
|
|
<button
|
|
key={i}
|
|
disabled={!skill && !equipping}
|
|
class={classes}
|
|
onClick={skillClick}
|
|
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
|
{s}
|
|
</button>
|
|
</label>
|
|
);
|
|
});
|
|
|
|
const colours = () => {
|
|
return (
|
|
<div class="colours" onMouseOver={e => hoverInfo(e, 'constructSpecs')} >
|
|
<div> {shapes.Red()} {construct.colours.red} </div>
|
|
<div> {shapes.Blue()} {construct.colours.blue} </div>
|
|
<div> {shapes.Green()} {construct.colours.green} </div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const offensiveStats = Object.keys(OFFENSE).map(s => {
|
|
const stat = OFFENSE[s];
|
|
|
|
const info = (s === 'SpeedStat' && 'speedStat')
|
|
|| (s.includes('Power') && 'powerStat');
|
|
return <div key={stat.stat}
|
|
alt={stat.stat}
|
|
class={stat.stat}
|
|
onMouseOver={e => hoverInfo(e, info)} >
|
|
{shapes[s]()}
|
|
<div>{construct[stat.stat].value}</div>
|
|
</div>;
|
|
});
|
|
|
|
const defensiveStats = Object.keys(DEFENSE).map(s => {
|
|
const stat = DEFENSE[s];
|
|
|
|
const info = (s.includes('Life') && 'lifeStat');
|
|
return <div key={stat.stat}
|
|
alt={stat.stat}
|
|
class={stat.stat}
|
|
onMouseOver={e => hoverInfo(e, info)} >
|
|
{shapes[s]()}
|
|
<div>{construct[stat.stat].value}</div>
|
|
</div>;
|
|
});
|
|
|
|
const classes = 'instance-construct';
|
|
const avatarMouseOver = e => hoverInfo(e, `constructAvatar ${construct.name}`);
|
|
return (
|
|
<div key={construct.id} class={classes} onClick={onClick} onDragOver={ev => ev.preventDefault()} onDrop={onClick}>
|
|
<ConstructAvatar construct={construct} mouseOver={avatarMouseOver}/>
|
|
<h2 class="name" onMouseOver={e => hoverInfo(e, `constructName ${construct.name}`)}>{construct.name}</h2>
|
|
<div class="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
|
|
{skills}
|
|
</div>
|
|
{colours()}
|
|
<div class="offStats">
|
|
{offensiveStats}
|
|
</div>
|
|
<div class="defStats">
|
|
{defensiveStats}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
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 (
|
|
<div class='construct-list'>
|
|
{constructs}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = addState(InstanceConstructs);
|