mnml/client/src/components/instance.cryps.jsx
2019-05-18 00:11:15 +10:00

217 lines
6.5 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, activeCryp } = 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, activeCryp };
},
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 {
activeCryp,
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) 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}`)}
</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 activeId = activeCryp ? activeCryp.id : false;
const crypClass = activeId === cryp.id ? 'instance-cryp-active' : 'instance-cryp';
// 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={crypClass} 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 {
activeCryp,
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({
activeCryp, 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);