const preact = require('preact'); const range = require('lodash/range'); const reactStringReplace = require('react-string-replace'); const { INFO } = require('./../constants'); const { convertItem, removeTier } = require('../utils'); const { tutorialStage } = require('../tutorial.utils'); const shapes = require('./shapes'); class InfoComponent extends preact.Component { shouldComponentUpdate(newProps) { if (newProps.tutorial !== this.props.tutorial) return true; // We don't care about info during tutorial if (newProps.tutorial && this.props.instance.time_control === 'Practice' && this.props.instance.rounds.length === 1) return false; if (newProps.info !== this.props.info) return true; return false; } render(args) { const { // Variables that will change info, tutorial, // Static player, // Only used for colour calcs which will be update if info changes ws, itemInfo, instance, // Only used for instance id // functions setInfo, setTutorialNull, } = args; function Info() { if (tutorial) { const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); if (tutorialStageInfo) return tutorialStageInfo; } if (!info) return false; if (info.includes('constructName')) { return (

{info.replace('constructName ', '')}

This is the name of your construct.
Names are randomly generated and are purely cosmetic.
You can change change your construct name in the reshape tab outside of games.

); } if (info.includes('constructAvatar')) { return (

{info.replace('constructAvatar ', '')}

This is your construct avatar.
Avatars are randomly generated and are purely cosmetic.
You can change your construct avatar in the reshape tab outside of games.

); } const fullInfo = itemInfo.items.find(i => i.item === info) || INFO[info]; if (!fullInfo) return false; const isSkill = fullInfo.skill; const isSpec = fullInfo.spec; if (isSkill) { const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat)/; const infoDescription = reactStringReplace(fullInfo.description, regEx, match => shapes[match]()); const itemSource = itemInfo.combos.filter(c => c.item === removeTier(info)); const itemSourceInfo = itemSource.length ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` : false; const itemRegEx = /(Red|Blue|Green)/; const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); const speed =
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
; const cooldown = fullInfo.cooldown ? `${fullInfo.cooldown} Turn delay` : null; return (

{fullInfo.item} {fullInfo.cost}b

SKILL

{itemSourceDescription}
{cooldown}
{infoDescription}
{speed}
); } if (isSpec) { let red = 0; let blue = 0; let green = 0; player.constructs.forEach(construct => { red += construct.colours.red; blue += construct.colours.blue; green += construct.colours.green; }); const teamColours = { red, blue, green }; const colourReqs = fullInfo.values.bonuses || []; const thresholds = colourReqs.map((bonus, i) => { const colours = ['red', 'green', 'blue']; const colourGoals = { red: [], green: [], blue: [], }; const overFlow = []; colours.forEach(c => { const colourReq = bonus.req[c]; if (colourReqs === 0) return false; const start = i === 0 ? 0 : colourReqs[i - 1].req[c]; const dots = range(start, colourReq).map(j => { const unmet = teamColours[c] < j + 1; const reqClass = unmet ? 'unmet' : ''; if (j - start > 4) { overFlow.push(
{shapes.vboxColour(c)}
); } else { colourGoals[c].push(
{shapes.vboxColour(c)}
); } return true; }); return dots; }); const reqsMet = colours.every(c => teamColours[c] >= bonus.req[c]); const reqClass = reqsMet ? '' : 'unmet'; const goals = colours.map((c, j) => { if (colourGoals[c].length) { return (
{colourGoals[c]}
); } return false; }); const bonusObj = info.includes('Life') ?
+ {bonus.bonus}
:
+ {bonus.bonus}%
; const overFlowObj = overFlow.length ?
{overFlow}
: null; return (
{goals} {overFlowObj} {bonusObj}
); }); const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat)/; const infoDescription = reactStringReplace(fullInfo.description, regEx, match => shapes[match]()); const itemSource = itemInfo.combos.filter(c => c.item === info); let itemSourceInfo = itemSource.length ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` : false; const itemRegEx = /(Red|Blue|Green)/; if (itemSourceInfo) { while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); } const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); let infoText = info; while (infoText.includes('Plus')) infoText = infoText.replace('Plus', '+'); return (

{infoText} {fullInfo.cost}b

SPEC

{itemSourceDescription}
{infoDescription}
{thresholds}
); } const cost = fullInfo.cost ? `- ${fullInfo.cost}b` : false; return (

{fullInfo.item} {cost}

{fullInfo.description}
); } function Combos() { if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; const generalNotes = (

General

You can preview combos by clicking them when they appear in this section.
Reclaim can be used to sell items in the inventory.
Click the READY button to start the GAME PHASE.

); if (!player) return generalNotes; if (!info) return generalNotes; const vboxCombos = itemInfo.combos.filter(c => c.components.includes(info)); if (vboxCombos.length > 6 || vboxCombos.length === 0) return generalNotes; return ( {vboxCombos.map((c, i) => {c.components.map((u, j) => )} )}
setInfo(c.item)} >{convertItem(c.item)}{convertItem(u)}
); } return (
); } } module.exports = InfoComponent;