const preact = require('preact');
const reactStringReplace = require('react-string-replace');
const specThresholds = require('./info.thresholds');
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, newState) {
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;
if (newState.comboItem !== this.state.comboItem) return true;
return false;
}
componentDidUpdate(prevProps) {
// Catch case where mouse events don't properly clear state and info changed
if (prevProps.info !== this.props.info && this.state.comboItem) this.setState({ comboItem: null });
}
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;
const { comboItem } = this.state;
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 = comboItem
? itemInfo.items.find(i => i.item === comboItem) || INFO[comboItem]
: itemInfo.items.find(i => i.item === info) || INFO[info];
if (!fullInfo) return false;
const isSkill = fullInfo.skill;
const isSpec = fullInfo.spec;
const itemDescription = () => {
const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/;
const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]());
return {reactStringReplace(infoDescription, '\n', () =>
)}
;
};
if (isSkill || isSpec) {
let infoName = fullInfo.item;
while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+');
const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item));
let itemSourceInfo = itemSource.length && !isSpec
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
: false;
let header = null;
if (!itemSource.length) header = isSkill ? SKILL
: SPEC
;
if (itemSourceInfo) {
while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+');
const itemRegEx = /(Red|Blue|Green)/;
itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
}
const cooldown = isSkill && fullInfo.cooldown ? {fullInfo.cooldown} Turn delay
: null;
const speed = isSkill
? Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
: null;
const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null;
return (
{infoName} {fullInfo.cost}b
{header}
{itemSourceInfo}
{cooldown}
{itemDescription()}
{speed}
{thresholds}
);
}
const cost = fullInfo.cost ? `- ${fullInfo.cost}b` : false;
return (
{fullInfo.item} {cost}
{itemDescription()}
);
}
const Combos = () => {
if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false;
const generalNotes = (
General
You can preview combos by clicking the combined item when it appears in this section.
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;
const comboTable = vboxCombos.map((c, i) => {
const mouseOver = e => {
e.stopPropagation();
this.setState({ comboItem: c.item });
};
const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci)))
? [{convertItem(c.components[0])} {convertItem(c.components[1])}
,
{convertItem(c.components[2])}
]
: c.components.map((u, j) => {convertItem(u)}
);
return (
);
});
return (
{comboTable}
);
};
return (
this.setState({ comboItem: null })}>
);
}
}
module.exports = InfoComponent;