189 lines
6.5 KiB
JavaScript
189 lines
6.5 KiB
JavaScript
const { connect } = require('preact-redux');
|
|
const { Component } = require('preact');
|
|
const preact = require('preact');
|
|
const range = require('lodash/range');
|
|
const reactStringReplace = require('react-string-replace');
|
|
|
|
const { STATS } = require('../utils');
|
|
const { ConstructAvatar, ConstructText } = require('./construct');
|
|
const shapes = require('./shapes');
|
|
const { INFO } = require('./../constants');
|
|
const actions = require('../actions');
|
|
|
|
const SkillBtn = require('./skill.btn');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const {
|
|
ws,
|
|
game,
|
|
account,
|
|
activeSkill,
|
|
animFocus,
|
|
animating,
|
|
animText,
|
|
gameSkillInfo,
|
|
itemInfo,
|
|
tutorialGame,
|
|
} = state;
|
|
|
|
function selectSkillTarget(targetConstructId) {
|
|
if (activeSkill) {
|
|
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return {
|
|
game,
|
|
account,
|
|
animating,
|
|
animFocus,
|
|
animText,
|
|
activeSkill,
|
|
selectSkillTarget,
|
|
gameSkillInfo,
|
|
itemInfo,
|
|
tutorialGame,
|
|
};
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function setGameEffectInfo(info) {
|
|
dispatch(actions.setGameEffectInfo(info));
|
|
}
|
|
|
|
function setTutorialGameClear(activeSkill, tutorialGame) {
|
|
if (activeSkill && tutorialGame) dispatch(actions.setTutorialGame(null));
|
|
}
|
|
|
|
return { setGameEffectInfo, setTutorialGameClear };
|
|
}
|
|
|
|
);
|
|
|
|
const eventClasses = (animating, animFocus, construct, postSkill) => {
|
|
if (!animating) return '';
|
|
if (!postSkill) {
|
|
if (animFocus.includes(construct.id)) return '';
|
|
return 'unfocus';
|
|
}
|
|
if (postSkill.constructId !== construct.id) {
|
|
if (animFocus.includes(construct.id)) return '';
|
|
return 'unfocus';
|
|
}
|
|
if (postSkill.effects) construct.effects = postSkill.effects;
|
|
construct.green_life.value = postSkill.life.green;
|
|
construct.red_life.value = postSkill.life.red;
|
|
construct.blue_life.value = postSkill.life.blue;
|
|
return postSkill.css;
|
|
};
|
|
|
|
class GameConstruct extends Component {
|
|
constructor() {
|
|
super();
|
|
this.resolvedLength = 0;
|
|
}
|
|
|
|
shouldComponentUpdate(newProps) {
|
|
if (newProps.activeSkill !== this.props.activeSkill) return true;
|
|
if (newProps.animFocus !== this.props.animFocus) return true;
|
|
if (newProps.animText !== this.props.animText) return true;
|
|
if (newProps.animating !== this.props.animating) return true;
|
|
if (newProps.construct !== this.props.construct) return true;
|
|
if (newProps.player !== this.props.player) return true;
|
|
if (newProps.tutorialGame !== this.props.tutorialGame) return true;
|
|
if (newProps.gameSkillInfo !== this.props.gameSkillInfo) return true;
|
|
return false;
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
// Changing state variables
|
|
activeSkill,
|
|
animFocus,
|
|
animText,
|
|
animating,
|
|
construct,
|
|
player,
|
|
tutorialGame,
|
|
gameSkillInfo,
|
|
// Constants
|
|
i,
|
|
itemInfo,
|
|
// Functions
|
|
selectSkillTarget,
|
|
setTutorialGameClear,
|
|
setGameEffectInfo,
|
|
} = this.props;
|
|
|
|
const koEvent = animText ? animText.text === 'KO!' && animText.constructId === construct.id : false;
|
|
const ko = construct.green_life.value === 0 && !koEvent ? 'ko' : '';
|
|
const classes = eventClasses(animating, animFocus, construct, animText);
|
|
|
|
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
|
<div key={j} alt={STATS[s].stat}>
|
|
{shapes[s]()}
|
|
<div class="max" >{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}</div>
|
|
<div class="value" >{construct[STATS[s].stat].value}</div>
|
|
</div>
|
|
));
|
|
|
|
const skills = range(0, 3)
|
|
.map(j => <SkillBtn key={j} construct={construct} i={j} j={i} animating={animating} />);
|
|
|
|
let crypSkills = <div></div>;
|
|
if (player) crypSkills = (<div class="skills"> {skills} </div>);
|
|
|
|
function hoverInfo(e, info) {
|
|
e.stopPropagation();
|
|
return setGameEffectInfo(info);
|
|
}
|
|
const effectBox = () => {
|
|
if (gameSkillInfo && gameSkillInfo.constructId === construct.id) {
|
|
const fullInfo = itemInfo.items.find(k => k.item === gameSkillInfo.skill) || INFO[gameSkillInfo.skill];
|
|
const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat)/;
|
|
const infoDescription = reactStringReplace(fullInfo.description, regEx, match => shapes[match]());
|
|
const speed = <span> Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}% </span>;
|
|
return (
|
|
<div class="skill-description">
|
|
<h2><span> {gameSkillInfo.skill} </span></h2>
|
|
<span>{infoDescription} </span> <br />
|
|
{speed}
|
|
</div>);
|
|
}
|
|
const effects = construct.effects.length
|
|
? construct.effects.map(c =>
|
|
<div key={c.effect}>
|
|
<span key={c.effect} onMouseOver={e => hoverInfo(e, c)}
|
|
onMouseOut={e => hoverInfo(e, null)}> {c.effect} - {c.duration}T
|
|
</span>
|
|
</div>)
|
|
: null;
|
|
return (<div class="effects"> {effects} </div>);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
onClick={() => {
|
|
selectSkillTarget(construct.id);
|
|
setTutorialGameClear(activeSkill, tutorialGame);
|
|
}}
|
|
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
|
class={`game-construct ${ko} ${classes}`} >
|
|
<div class="left">
|
|
{crypSkills}
|
|
{effectBox()}
|
|
</div>
|
|
<div class="right">
|
|
<div class="stats"> {stats} </div>
|
|
<ConstructAvatar construct={construct} />
|
|
<ConstructText construct={construct} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = addState(GameConstruct);
|