265 lines
7.1 KiB
JavaScript
265 lines
7.1 KiB
JavaScript
const { connect } = require('preact-redux');
|
|
const preact = require('preact');
|
|
const range = require('lodash/range');
|
|
|
|
const shapes = require('./shapes');
|
|
const { STATS, instanceConstruct } = require('../utils');
|
|
const actions = require('../actions');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const { ws, instance, player, account, itemInfo, itemEquip, activeConstruct } = state;
|
|
|
|
function sendInstanceReady() {
|
|
return ws.sendInstanceReady(instance.id);
|
|
}
|
|
|
|
function sendVboxApply(constructId, i) {
|
|
return ws.sendVboxApply(instance.id, constructId, i);
|
|
}
|
|
|
|
function sendUnequip(constructId, item) {
|
|
return ws.sendVboxUnequip(instance.id, constructId, item);
|
|
}
|
|
|
|
return {
|
|
instance,
|
|
player,
|
|
account,
|
|
sendInstanceReady,
|
|
sendVboxApply,
|
|
itemInfo,
|
|
itemEquip,
|
|
activeConstruct,
|
|
sendUnequip,
|
|
};
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function quit() {
|
|
dispatch(actions.setInstance(null));
|
|
}
|
|
|
|
function setInfo(item) {
|
|
dispatch(actions.setInfo(item));
|
|
}
|
|
|
|
function setActiveConstruct(value) {
|
|
dispatch(actions.setActiveConstruct(value));
|
|
}
|
|
|
|
function clearInfo() {
|
|
return dispatch(actions.setInfo(null));
|
|
}
|
|
|
|
function setItemEquip(v) {
|
|
return dispatch(actions.setItemEquip(v));
|
|
}
|
|
|
|
function setItemUnequip(v) {
|
|
return dispatch(actions.setItemUnequip(v));
|
|
}
|
|
|
|
return { quit, clearInfo, setInfo, setActiveConstruct, setItemUnequip, setItemEquip };
|
|
}
|
|
|
|
);
|
|
|
|
function Construct(props) {
|
|
const {
|
|
activeConstruct,
|
|
itemEquip,
|
|
construct,
|
|
player,
|
|
sendVboxApply,
|
|
setActiveConstruct,
|
|
setItemUnequip,
|
|
setItemEquip,
|
|
itemInfo,
|
|
setInfo,
|
|
sendUnequip,
|
|
} = props;
|
|
|
|
function onClick(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
if (itemEquip !== null) sendVboxApply(construct.id, itemEquip);
|
|
setItemEquip(null);
|
|
return setActiveConstruct(construct);
|
|
}
|
|
|
|
function hoverInfo(e, info) {
|
|
if (!info) return false;
|
|
e.stopPropagation();
|
|
return setInfo(info);
|
|
}
|
|
|
|
const { vbox } = player;
|
|
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, 3).map(i => {
|
|
const skill = construct.skills[i];
|
|
const s = skill
|
|
? skill.skill
|
|
: (<span className="gray">+</span>);
|
|
|
|
function skillClick(e) {
|
|
if (!skill) return false;
|
|
setItemUnequip(skill.skill);
|
|
setActiveConstruct(construct);
|
|
e.stopPropagation();
|
|
return true;
|
|
}
|
|
|
|
function skillDblClick(e) {
|
|
if (!skill) return false;
|
|
sendUnequip(construct.id, skill.skill);
|
|
setActiveConstruct(null);
|
|
setItemUnequip(null);
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
return true;
|
|
}
|
|
|
|
// const action = skill ? '' : 'action';
|
|
const equip = skillList.includes(vbox.bound[itemEquip]) && !skill ? 'equipping' : '';
|
|
const classes = `${equip}`;
|
|
return (
|
|
<button
|
|
key={i}
|
|
disabled={!skill && !itemEquip}
|
|
className={classes}
|
|
onClick={skillClick}
|
|
onDblClick={skillDblClick}
|
|
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
|
{s}
|
|
</button>
|
|
);
|
|
});
|
|
|
|
const specs = range(0, 6).map(i => {
|
|
const s = construct.specs[i];
|
|
|
|
if (!s) {
|
|
const equip = specList.includes(vbox.bound[itemEquip]) ? 'equip-spec' : 'gray';
|
|
return (
|
|
<figure key={i} className={equip} >
|
|
{shapes.diamond(equip)}
|
|
<figcaption> </figcaption>
|
|
</figure>
|
|
);
|
|
}
|
|
|
|
const specInfo = itemInfo.items.find(i => i.item === s);
|
|
|
|
function specClick(e) {
|
|
e.stopPropagation();
|
|
setItemUnequip(s);
|
|
setActiveConstruct(construct);
|
|
}
|
|
|
|
function specDblClick(e) {
|
|
sendUnequip(construct.id, s);
|
|
setActiveConstruct(null);
|
|
setItemUnequip(null);
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
return true;
|
|
}
|
|
|
|
|
|
return (
|
|
<figure
|
|
key={i}
|
|
onClick={specClick}
|
|
onDblClick={specDblClick}
|
|
onMouseOver={e => hoverInfo(e, s)} >
|
|
{shapes[s]()}
|
|
<figcaption>{s}</figcaption>
|
|
</figure>
|
|
);
|
|
});
|
|
|
|
const stats = Object.keys(STATS).map(s => {
|
|
const stat = STATS[s];
|
|
|
|
const info = (s === 'Speed' && 'Speed')
|
|
|| (s.includes('Power') && 'Power')
|
|
|| (s.includes('Life') && 'Life');
|
|
|
|
return <figure key={stat.stat}
|
|
alt={stat.stat}
|
|
className={stat.stat}
|
|
onMouseOver={e => hoverInfo(e, info)} >
|
|
{shapes[s]()}
|
|
<figcaption>{construct[stat.stat].value}</figcaption>
|
|
</figure>;
|
|
});
|
|
|
|
const activeId = activeConstruct ? activeConstruct.id : false;
|
|
const constructClass = activeId === construct.id ? 'instance-construct-active' : 'instance-construct';
|
|
|
|
return (
|
|
<div key={construct.id} className={constructClass} onClick={onClick} >
|
|
{instanceConstruct(construct.name, construct.id)}
|
|
<h2 className="name" >{construct.name}</h2>
|
|
<div className="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
|
|
{skills}
|
|
</div>
|
|
<div className="specs" onMouseOver={e => hoverInfo(e, 'constructSpecs')} >
|
|
{specs}
|
|
</div>
|
|
<div className="stats">
|
|
{stats}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function InstanceConstructs(props) {
|
|
const {
|
|
activeConstruct,
|
|
itemEquip,
|
|
player,
|
|
instance,
|
|
// clearInfo,
|
|
setInfo,
|
|
setActiveConstruct,
|
|
|
|
sendVboxApply,
|
|
itemInfo,
|
|
setVboxHighlight,
|
|
setItemUnequip,
|
|
setItemEquip,
|
|
sendUnequip,
|
|
} = props;
|
|
|
|
if (!player) return false;
|
|
if (instance.phase === 'Lobby') return false;
|
|
|
|
const constructs = player.constructs.map((c, i) => Construct({
|
|
construct: c,
|
|
activeConstruct,
|
|
itemEquip,
|
|
setItemUnequip,
|
|
setItemEquip,
|
|
player,
|
|
sendVboxApply,
|
|
setInfo,
|
|
setActiveConstruct,
|
|
itemInfo,
|
|
setVboxHighlight,
|
|
sendUnequip,
|
|
}));
|
|
|
|
const classes = `construct-list`;
|
|
return (
|
|
<div className={classes} onClick={() => setActiveConstruct(null)}>
|
|
{constructs}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
module.exports = addState(InstanceConstructs);
|