mnml/client/src/components/game.construct.jsx
2020-01-19 12:31:08 +10:00

111 lines
3.7 KiB
JavaScript

const preact = require('preact');
const { connect } = require('preact-redux');
const range = require('lodash/range');
const { ConstructAvatar, ConstructName } = require('./construct');
const SkillBtn = require('./game.construct.skill.btn');
const ConstructAnimationText = require('./game.construct.anim.text');
const ConstructLife = require('./game.construct.life');
const ConstructEffectBox = require('./game.construct.effect.box');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
authenticated,
activeSkill,
animFocus,
resolution,
} = state;
function selectSkillTarget(targetConstructId) {
if (activeSkill) {
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
}
return false;
}
return {
game,
authenticated,
activeSkill,
animFocus,
resolution,
selectSkillTarget,
};
}
);
class GameConstruct extends preact.Component {
shouldComponentUpdate(newProps) {
if (newProps.activeSkill !== this.props.activeSkill) return true;
if (newProps.animFocus !== this.props.animFocus) return true;
if (newProps.construct !== this.props.construct) return true;
if (newProps.resolution && newProps.resolution !== this.props.resolution) {
const [type, variant] = newProps.resolution.event;
if (variant.construct === this.props.construct.id && type === 'Ko') return true;
}
return false;
}
render() {
const {
// Changing state variables
authenticated,
game,
activeSkill,
animFocus,
resolution,
selectSkillTarget,
construct,
player,
} = this.props;
// construct green_life comes from game state and won't update during animations
// treat the construct as ko for the remainder of the anims if ko event occurs
const ko = construct.green_life.value === 0 || this.ko ? 'ko' : '';
const koEvent = () => {
if (resolution) {
const [type, variant] = resolution.event;
if (variant.construct === construct.id && type === 'Ko') {
this.ko = true;
return 'ko-transition';
}
}
return '';
};
const unfocus = animFocus && !animFocus.includes(construct.id) ? 'unfocus' : '';
const targeted = game.stack.find(c => c.target === construct.id);
const highlight = !authenticated && !targeted && activeSkill ? 'highlight' : '';
const crypSkills = player
? <div class="skills"> {range(0, 3).map(j => <SkillBtn key={j} construct={construct} i={j} />)} </div>
: <div></div>;
return (
<div
onClick={() => selectSkillTarget(construct.id)}
style={ activeSkill ? { cursor: 'pointer' } : {}}
class={`game-construct ${ko} ${koEvent()} ${unfocus} ${highlight}`}>
<div class="left">
{crypSkills}
<ConstructEffectBox construct={construct} />
</div>
<div class="right">
<ConstructLife construct={construct} />
<ConstructAvatar construct={construct} />
<ConstructName construct={construct} />
<ConstructAnimationText construct={construct} />
</div>
</div>
);
}
}
module.exports = addState(GameConstruct);