214 lines
6.3 KiB
JavaScript
214 lines
6.3 KiB
JavaScript
const { connect } = require('preact-redux');
|
|
const preact = require('preact');
|
|
const range = require('lodash/range');
|
|
|
|
const shapes = require('./shapes');
|
|
const { SPECS, STATS, crypAvatar } = require('../utils');
|
|
const actions = require('../actions');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const { ws, instance, player, account, vboxHidden, vboxInfo, activeVar } = state;
|
|
|
|
function sendInstanceReady() {
|
|
return ws.sendInstanceReady(instance.id);
|
|
}
|
|
|
|
function sendVboxApply(crypId, i) {
|
|
return ws.sendVboxApply(instance.id, crypId, i);
|
|
}
|
|
|
|
return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, vboxInfo, activeVar };
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function quit() {
|
|
dispatch(actions.setInstance(null));
|
|
}
|
|
|
|
function setInfo(item, value) {
|
|
dispatch(actions.setInfo([item, value]));
|
|
}
|
|
|
|
function setActiveCryp(value) {
|
|
dispatch(actions.setActiveCryp(value));
|
|
}
|
|
|
|
function clearInfo() {
|
|
return dispatch(actions.setInfo([]));
|
|
}
|
|
|
|
function setVboxHighlight(v) {
|
|
dispatch(actions.setVboxHighlight(v));
|
|
}
|
|
|
|
return { quit, clearInfo, setInfo, setActiveCryp, setVboxHighlight };
|
|
}
|
|
|
|
);
|
|
|
|
function Cryp(props) {
|
|
const {
|
|
activeVar,
|
|
cryp,
|
|
player,
|
|
sendVboxApply,
|
|
setInfo,
|
|
setActiveCryp,
|
|
setVboxHighlight,
|
|
vboxInfo,
|
|
} = props;
|
|
|
|
function setHighlight(type) {
|
|
if (type === 'skill') return setVboxHighlight(vboxInfo.vars.filter(v => v.skill).map(v => v.v));
|
|
if (type === 'spec') return setVboxHighlight(vboxInfo.vars.filter(v => v.spec).map(v => v.v));
|
|
return false;
|
|
}
|
|
|
|
function onClick(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
|
|
return setActiveCryp(cryp);
|
|
}
|
|
|
|
const { vbox } = player;
|
|
const skillList = vboxInfo.vars.filter(v => v.skill).map(v => v.v);
|
|
const specList = vboxInfo.vars.filter(v => v.spec).map(v => v.v);
|
|
|
|
const skills = range(0, 3).map(i => {
|
|
const skill = cryp.skills[i];
|
|
const s = skill
|
|
? skill.skill
|
|
: (<span className="gray">+</span>);
|
|
|
|
function skillClick(e) {
|
|
if (!skill && activeVar !== null) return sendVboxApply(cryp.id, activeVar);
|
|
if (!skill) setHighlight('skill');
|
|
else setInfo('skill', { skill: skill.skill, cryp });
|
|
e.stopPropagation();
|
|
return setActiveCryp(cryp);
|
|
}
|
|
|
|
const action = skill ? '' : 'action';
|
|
const equip = skillList.includes(vbox.bound[activeVar]) && !skill ? 'equip' : '';
|
|
const classes = `right ${action} ${equip}`;
|
|
return (
|
|
<button key={i} className={classes} onClick={skillClick} >{s}</button>
|
|
);
|
|
});
|
|
|
|
const specs = range(0, 6).map(i => {
|
|
const s = cryp.specs[i];
|
|
|
|
function blankSpecClick(e) {
|
|
e.stopPropagation();
|
|
if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
|
|
setHighlight('spec');
|
|
return setActiveCryp(cryp);
|
|
}
|
|
|
|
if (!s) {
|
|
const equip = specList.includes(vbox.bound[activeVar]) ? 'equip-spec' : 'gray';
|
|
return (
|
|
<figure key={i} onClick={blankSpecClick} className={equip} >
|
|
{shapes.diamond(`stat-icon ${equip}`)}
|
|
<figcaption>+</figcaption>
|
|
</figure>
|
|
);
|
|
}
|
|
|
|
function specClick(e) {
|
|
e.stopPropagation();
|
|
setActiveCryp(cryp);
|
|
setInfo('spec', { spec: s, cryp });
|
|
}
|
|
|
|
return (
|
|
<figure key={i} onClick={specClick}>
|
|
{SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)}
|
|
<figcaption>{SPECS[s].caption}</figcaption>
|
|
</figure>
|
|
);
|
|
});
|
|
|
|
const stats = Object.values(STATS).map(s => (
|
|
<figure key={s.stat} alt={s.stat} className={s.stat}>
|
|
{s.svg(`stat-icon ${s.colour} stat`)}
|
|
<figcaption>{cryp[s.stat].value}</figcaption>
|
|
</figure>
|
|
));
|
|
|
|
// const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green;
|
|
// const colours = mapValues(cryp.colours, c => {
|
|
// if (cTotal === 0) return 245;
|
|
// return Math.floor(c / cTotal * 255);
|
|
// });
|
|
// const alpha = cTotal === 0 ? 1 : 0.75;
|
|
// const thickness = total => {
|
|
// if (total < 3) return 1;
|
|
// if (total < 6) return 2;
|
|
// if (total < 9) return 3;
|
|
// return 4;
|
|
// };
|
|
// const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` };
|
|
return (
|
|
<div key={cryp.id} className="instance-cryp" onClick={onClick} >
|
|
{crypAvatar(cryp.name)}
|
|
<h2 className="name" >{cryp.name}</h2>
|
|
<div className="skills">
|
|
{skills}
|
|
</div>
|
|
<div className="specs">
|
|
{specs}
|
|
</div>
|
|
<div className="stats">
|
|
<div className="damage-label label">
|
|
Damage
|
|
</div>
|
|
<div className="speed-label label">
|
|
Speed
|
|
</div>
|
|
<div className="life-label label">
|
|
Life
|
|
</div>
|
|
<div className="icons">
|
|
{stats}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function InstanceCryps(props) {
|
|
const {
|
|
activeVar,
|
|
player,
|
|
instance,
|
|
// clearInfo,
|
|
setInfo,
|
|
setActiveCryp,
|
|
|
|
sendVboxApply,
|
|
vboxHidden,
|
|
vboxInfo,
|
|
setVboxHighlight,
|
|
} = props;
|
|
|
|
if (!player) return false;
|
|
if (instance.phase === 'Lobby') return false;
|
|
|
|
const cryps = player.cryps.map((c, i) => Cryp({
|
|
activeVar, cryp: c, player, sendVboxApply, setInfo, setActiveCryp, vboxInfo, setVboxHighlight,
|
|
}));
|
|
|
|
const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`;
|
|
return (
|
|
<div className={classes} onClick={() => setActiveCryp(null)}>
|
|
{cryps}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
module.exports = addState(InstanceCryps);
|