221 lines
6.7 KiB
JavaScript
221 lines
6.7 KiB
JavaScript
const preact = require('preact');
|
|
const range = require('lodash/range');
|
|
|
|
const { ITEMS: { SKILLS, COLOURS, SPECS: SPEC_CONSTANT } } = require('./../constants');
|
|
const { COLOUR_ICONS, STATS, SPECS, convertVar, crypAvatar } = require('../utils');
|
|
const shapes = require('./shapes');
|
|
|
|
const InfoCryp = require('./info.cryp');
|
|
|
|
function Info(args) {
|
|
const {
|
|
activeCryp,
|
|
info,
|
|
combiner,
|
|
sendUnequip,
|
|
instance,
|
|
player,
|
|
vboxInfo,
|
|
vboxHidden,
|
|
} = args;
|
|
|
|
function CrypVar() {
|
|
if (!info) return false;
|
|
const [type, value] = info;
|
|
if (!type) return false;
|
|
|
|
let red = 0;
|
|
let blue = 0;
|
|
let green = 0;
|
|
player.cryps.forEach(cryp => {
|
|
red += cryp.colours.red;
|
|
blue += cryp.colours.blue;
|
|
green += cryp.colours.green;
|
|
});
|
|
const teamColours = { red, blue, green };
|
|
|
|
if (type === 'item') {
|
|
let itemDetails;
|
|
if (SKILLS[value]) {
|
|
itemDetails = SKILLS[value];
|
|
} else if (SPEC_CONSTANT[value]) {
|
|
itemDetails = SPEC_CONSTANT[value];
|
|
} else if (COLOURS[value]) {
|
|
itemDetails = COLOURS[value];
|
|
}
|
|
|
|
if (!itemDetails) {
|
|
return console.warn('UNHANLDED VAR', value);
|
|
}
|
|
return (
|
|
<div className="info-var">
|
|
{value} - {itemDetails.description}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (type === 'skill') {
|
|
const skillInfo = SKILLS[value.skill];
|
|
const description = skillInfo ? skillInfo.description : '?????';
|
|
return (
|
|
<div className="info-skill">
|
|
<div> {value.skill} </div>
|
|
<div> {description} </div>
|
|
<button onClick={() => sendUnequip(value.cryp.id, value.skill)}>
|
|
unequip
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (type === 'spec') {
|
|
const { spec } = value;
|
|
const breaks = SPEC_CONSTANT[value.spec].thresholds;
|
|
const colourReqs = SPEC_CONSTANT[spec].colours || [];
|
|
|
|
const thresholdEl = colourReqs.map((c, i) => {
|
|
const numIcons = Math.max(...breaks);
|
|
const dots = range(0, numIcons).map(j => {
|
|
const unmet = teamColours[c] < j + 1;
|
|
const caption = breaks.includes(j + 1)
|
|
? '+ x'
|
|
: '';
|
|
|
|
const reqClass = unmet
|
|
? 'unmet'
|
|
: '';
|
|
|
|
return (
|
|
<figure key={j} alt={c.colour} className={reqClass} >
|
|
{COLOUR_ICONS[c].svg(`stat-icon ${COLOUR_ICONS[c].colour}`)}
|
|
<figcaption>{caption}</figcaption>
|
|
</figure>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div key={i} className="spec-goals">
|
|
{dots}
|
|
</div>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div className="info-spec">
|
|
<div>
|
|
<div> {value.spec} </div>
|
|
<div> {SPEC_CONSTANT[value.spec].description} </div>
|
|
<div className="thresholds">
|
|
{thresholdEl}
|
|
</div>
|
|
</div>
|
|
<button onClick={() => sendUnequip(value.cryp.id, value.spec)}>
|
|
unequip
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
function playerRound(id) {
|
|
if (!instance.rounds.length) return null;
|
|
return instance.rounds[instance.rounds.length - 1].find(r => r.player_ids.includes(id));
|
|
}
|
|
|
|
function playerText(p) {
|
|
const round = playerRound(p.id);
|
|
if (!round) {
|
|
return p.ready
|
|
? 'ready'
|
|
: '';
|
|
}
|
|
|
|
if (round.finished) return 'finished';
|
|
if (round.game_id) return 'in game';
|
|
|
|
return p.ready
|
|
? 'ready'
|
|
: '';
|
|
}
|
|
|
|
function ScoreBoard() {
|
|
if (activeCryp || info[0]) return null;
|
|
|
|
const players = instance.players.map((p, i) => {
|
|
const pText = playerText(p);
|
|
return (
|
|
<tr key={i}
|
|
className={p.ready ? 'ready' : ''}>
|
|
<td>{p.name}</td>
|
|
<td>{p.score.wins} / {p.score.losses}</td>
|
|
<td>{pText}</td>
|
|
</tr>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<table>
|
|
<tbody>
|
|
{players}
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|
|
|
|
function Combos() {
|
|
if (!info[0]) return false;
|
|
if (activeCryp) return false;
|
|
if (!player) return false;
|
|
|
|
if (!(combiner.every(u => u === null))) {
|
|
const filteredCombos = vboxInfo.combos
|
|
.filter(combo => combiner.every(u => u === null
|
|
|| combo.units.includes(player.vbox.bound[u])));
|
|
if (filteredCombos.length > 6) return false;
|
|
return (
|
|
<table>
|
|
<tbody>
|
|
{filteredCombos.map((c, i) =>
|
|
<tr key={i} >
|
|
<td className="highlight" >{convertVar(c.var)}</td>
|
|
{c.units.map((u, j) => <td key={j}>{convertVar(u)}</td>)}
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|
|
const vboxCombos = vboxInfo.combos.filter(c => c.units.includes(info[1]));
|
|
if (vboxCombos.length > 6) return false;
|
|
return (
|
|
<table>
|
|
<tbody>
|
|
{vboxCombos.map((c, i) =>
|
|
<tr key={i} >
|
|
<td className="highlight" >{convertVar(c.var)}</td>
|
|
{c.units.map((u, j) => <td key={j} >{convertVar(u)}</td>)}
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|
|
|
|
// const beginningHdr = instance.phase === 'Lobby'
|
|
// ? <h2>game beginning...</h2>
|
|
// : null;
|
|
|
|
const classes = `instance-info ${vboxHidden ? '' : 'hidden'}`;
|
|
|
|
return (
|
|
<div className={classes} >
|
|
<CrypVar />
|
|
<Combos />
|
|
</div>
|
|
);
|
|
}
|
|
// <InfoCryp /> not required anymore
|
|
// <ScoreBoard /> Takes up too much space maybe a context switch
|
|
|
|
module.exports = Info;
|