refactor game.construct
This commit is contained in:
parent
8e90e6e0e3
commit
af654cffc2
73
client/src/components/game.construct.anim.text.jsx
Normal file
73
client/src/components/game.construct.anim.text.jsx
Normal file
@ -0,0 +1,73 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const anime = require('animejs').default;
|
||||
const reactStringReplace = require('react-string-replace');
|
||||
|
||||
const shapes = require('./shapes');
|
||||
const { removeTier } = require('../utils');
|
||||
const { TIMES } = require('./../constants');
|
||||
|
||||
const addState = connect(({ animText, itemInfo }) => ({ animText, itemInfo }));
|
||||
|
||||
class AnimText extends preact.Component {
|
||||
shouldComponentUpdate(newProps) {
|
||||
if (newProps.animText !== this.props.animText) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { animText, construct } = this.props;
|
||||
if (animText && animText !== prevProps.animText && animText.constructId === construct.id) {
|
||||
anime({
|
||||
targets: '.combat-text',
|
||||
top: '40%',
|
||||
duration: TIMES.POST_SKILL_DURATION_MS - 500,
|
||||
easing: 'easeOutQuad',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render(props) {
|
||||
const { construct, animText, itemInfo } = props;
|
||||
if (animText && animText.constructId === construct.id) {
|
||||
const itemSourceDescription = () => {
|
||||
const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.skill));
|
||||
const itemSourceInfo = itemSource.length
|
||||
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
|
||||
: false;
|
||||
const itemRegEx = /(Red|Blue|Green)/;
|
||||
return reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
|
||||
};
|
||||
|
||||
const animationTextHtml = () => {
|
||||
// monkaW hack to make red / blue recharge work nicely
|
||||
if (animText.css === 'rb') {
|
||||
const text = animText.text.split(' ');
|
||||
return (
|
||||
<h1>
|
||||
<span class="red">{text[0]}</span>
|
||||
<span class="blue">{text[1]}</span>
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h1 class={animText.css}>
|
||||
<span>{animText.text}</span>
|
||||
</h1>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div class="combat-text">
|
||||
<h2><span>{animText.skill}</span></h2>
|
||||
<span>{itemSourceDescription()}</span>
|
||||
{animationTextHtml()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = addState(AnimText);
|
||||
72
client/src/components/game.construct.effect.box.jsx
Normal file
72
client/src/components/game.construct.effect.box.jsx
Normal file
@ -0,0 +1,72 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const reactStringReplace = require('react-string-replace');
|
||||
|
||||
const actions = require('../actions');
|
||||
const shapes = require('./shapes');
|
||||
const { INFO } = require('./../constants');
|
||||
|
||||
const addState = connect(
|
||||
({ animText, itemInfo, gameSkillInfo }) => ({ animText, itemInfo, gameSkillInfo }),
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setGameEffectInfo(info) {
|
||||
dispatch(actions.setGameEffectInfo(info));
|
||||
}
|
||||
|
||||
return { setGameEffectInfo };
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
class GameConstructEffects extends preact.Component {
|
||||
shouldComponentUpdate(newProps) {
|
||||
if (newProps.animText !== this.props.animText) {
|
||||
if (newProps.animText && newProps.animText.constructId === this.props.construct.id) return true;
|
||||
}
|
||||
if (newProps.construct !== this.props.construct) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
animText,
|
||||
construct,
|
||||
gameSkillInfo,
|
||||
setGameEffectInfo,
|
||||
itemInfo,
|
||||
} = this.props;
|
||||
|
||||
function hoverInfo(e, info) {
|
||||
e.stopPropagation();
|
||||
return setGameEffectInfo(info);
|
||||
}
|
||||
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 = animText && animText.constructId === construct.id && animText.effects
|
||||
? animText.effects
|
||||
: construct.effects;
|
||||
const renderEffects = effects.length
|
||||
? 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"> {renderEffects} </div>);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = addState(GameConstructEffects);
|
||||
@ -1,94 +1,23 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const anime = require('animejs').default;
|
||||
const range = require('lodash/range');
|
||||
const reactStringReplace = require('react-string-replace');
|
||||
|
||||
const { STATS, removeTier } = require('../utils');
|
||||
const { ConstructAvatar, ConstructText } = require('./construct');
|
||||
const shapes = require('./shapes');
|
||||
const { INFO, TIMES } = require('./../constants');
|
||||
const actions = require('../actions');
|
||||
|
||||
const SkillBtn = require('./skill.btn');
|
||||
|
||||
const addStateText = connect(({ animText, itemInfo }) => ({ animText, itemInfo }));
|
||||
|
||||
class combatText extends preact.Component {
|
||||
shouldComponentUpdate(newProps) {
|
||||
if (newProps.animText !== this.props.animText) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { animText, construct } = this.props;
|
||||
if (animText && animText !== prevProps.animText && animText.constructId === construct.id) {
|
||||
anime({
|
||||
targets: '.combat-text',
|
||||
top: '40%',
|
||||
duration: TIMES.POST_SKILL_DURATION_MS - 500,
|
||||
easing: 'easeOutQuad',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render(props) {
|
||||
const { construct, animText, itemInfo } = props;
|
||||
if (animText && animText.constructId === construct.id) {
|
||||
const itemSourceDescription = () => {
|
||||
const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.skill));
|
||||
const itemSourceInfo = itemSource.length
|
||||
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
|
||||
: false;
|
||||
const itemRegEx = /(Red|Blue|Green)/;
|
||||
return reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
|
||||
};
|
||||
|
||||
const animationTextHtml = () => {
|
||||
// monkaW hack to make red / blue recharge work nicely
|
||||
if (animText.css === 'rb') {
|
||||
const text = animText.text.split(' ');
|
||||
return (
|
||||
<h1>
|
||||
<span class="red">{text[0]}</span>
|
||||
<span class="blue">{text[1]}</span>
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h1 class={animText.css}>
|
||||
<span>{animText.text}</span>
|
||||
</h1>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div class="combat-text">
|
||||
<h2><span>{animText.skill}</span></h2>
|
||||
<span>{itemSourceDescription()}</span>
|
||||
{animationTextHtml()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const ConstructAnimationText = addStateText(combatText);
|
||||
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,
|
||||
account,
|
||||
|
||||
activeSkill,
|
||||
animFocus,
|
||||
animating,
|
||||
animText,
|
||||
gameSkillInfo,
|
||||
itemInfo,
|
||||
} = state;
|
||||
|
||||
function selectSkillTarget(targetConstructId) {
|
||||
@ -99,59 +28,20 @@ const addState = connect(
|
||||
}
|
||||
|
||||
return {
|
||||
game,
|
||||
account,
|
||||
animating,
|
||||
activeSkill,
|
||||
animFocus,
|
||||
animText,
|
||||
activeSkill,
|
||||
selectSkillTarget,
|
||||
gameSkillInfo,
|
||||
itemInfo,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setGameEffectInfo(info) {
|
||||
dispatch(actions.setGameEffectInfo(info));
|
||||
}
|
||||
|
||||
return { setGameEffectInfo };
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
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 preact.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.gameSkillInfo !== this.props.gameSkillInfo) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -161,78 +51,36 @@ class GameConstruct extends preact.Component {
|
||||
activeSkill,
|
||||
animFocus,
|
||||
animText,
|
||||
animating,
|
||||
selectSkillTarget,
|
||||
construct,
|
||||
player,
|
||||
gameSkillInfo,
|
||||
// Constants
|
||||
i,
|
||||
itemInfo,
|
||||
// Functions
|
||||
selectSkillTarget,
|
||||
setGameEffectInfo,
|
||||
} = this.props;
|
||||
|
||||
const koEvent = animText ? animText.text === 'KO!' && animText.constructId === construct.id : false;
|
||||
const koEvent = animText && animText.text === 'KO!' && animText.constructId === construct.id;
|
||||
const ko = construct.green_life.value === 0 && !koEvent ? 'ko' : '';
|
||||
const classes = eventClasses(animating, animFocus, construct, animText);
|
||||
const cssClass = ['ko-transition', 'unfocus'].includes(classes) ? classes : null;
|
||||
|
||||
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>);
|
||||
const cssClass = () => {
|
||||
if (koEvent) return 'ko-transition';
|
||||
if (animFocus && !animFocus.includes(construct.id)) return 'unfocus';
|
||||
return '';
|
||||
};
|
||||
|
||||
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);
|
||||
}}
|
||||
onClick={() => selectSkillTarget(construct.id)}
|
||||
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
||||
class={`game-construct ${ko} ${cssClass}`}>
|
||||
class={`game-construct ${ko} ${cssClass()}`}>
|
||||
<div class="left">
|
||||
{crypSkills}
|
||||
{effectBox()}
|
||||
<ConstructEffectBox construct={construct} />
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="stats"> {stats} </div>
|
||||
<ConstructLife construct={construct} />
|
||||
<ConstructAvatar construct={construct} />
|
||||
<ConstructText construct={construct} />
|
||||
<ConstructAnimationText construct={construct} />
|
||||
|
||||
44
client/src/components/game.construct.life.jsx
Normal file
44
client/src/components/game.construct.life.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const shapes = require('./shapes');
|
||||
|
||||
const addState = connect(({ animText }) => ({ animText }));
|
||||
|
||||
class GameConstructLife extends preact.Component {
|
||||
shouldComponentUpdate(newProps) {
|
||||
if (newProps.animText !== this.props.animText) {
|
||||
if (newProps.animText && newProps.animText.constructId === this.props.construct.id) return true;
|
||||
}
|
||||
if (newProps.construct !== this.props.construct) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { construct, animText } = this.props;
|
||||
// this will be cleaner in new update
|
||||
const updateLife = animText && animText.constructId === construct.id;
|
||||
const redLife = updateLife ? animText.life.red : construct.red_life.value;
|
||||
const greenLife = updateLife ? animText.life.green : construct.green_life.value;
|
||||
const blueLife = updateLife ? animText.life.blue : construct.blue_life.value;
|
||||
|
||||
return (
|
||||
<div class="stats">
|
||||
<div>
|
||||
{shapes.RedLife()}
|
||||
<div class="max" >{redLife} / {construct.red_life.max}</div>
|
||||
</div>
|
||||
<div>
|
||||
{shapes.GreenLife()}
|
||||
<div class="max" >{greenLife} / {construct.green_life.max}</div>
|
||||
</div>
|
||||
<div>
|
||||
{shapes.BlueLife()}
|
||||
<div class="max" >{blueLife} / {construct.blue_life.max}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = addState(GameConstructLife);
|
||||
@ -10,11 +10,13 @@ const addState = connect(
|
||||
const {
|
||||
activeSkill,
|
||||
game,
|
||||
animating,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
activeSkill,
|
||||
game,
|
||||
animating,
|
||||
};
|
||||
},
|
||||
|
||||
@ -138,7 +138,7 @@ function registerEvents(store) {
|
||||
store.dispatch(actions.setAnimText(null));
|
||||
store.dispatch(actions.setAnimating(false));
|
||||
store.dispatch(actions.setGameEffectInfo(null));
|
||||
|
||||
store.dispatch(actions.setAnimFocus(null));
|
||||
// set the game state so resolutions don't fire twice
|
||||
store.dispatch(actions.setGame(game));
|
||||
ws.sendGameState(game.id);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user