Merge branch 'develop' into inventory

This commit is contained in:
ntr 2019-07-09 13:06:05 +10:00
commit 264d368351
10 changed files with 107 additions and 56 deletions

View File

@ -20,7 +20,7 @@ const store = createStore(
document.fonts.load('16pt "Jura"').then(() => { document.fonts.load('16pt "Jura"').then(() => {
const events = registerEvents(store); const events = registerEvents(store);
store.subscribe(() => console.log(store.getState())); // store.subscribe(() => console.log(store.getState()));
setupKeys(store); setupKeys(store);
const ws = createSocket(events); const ws = createSocket(events);

View File

@ -58,8 +58,8 @@ const colours = {
const { TIMES } = require('../constants'); const { TIMES } = require('../constants');
function animations(props) { function animations(props) {
const { game, account, resolution, player, construct } = props; const { game, account, resolution, player, construct, avatarAnimation, setAvatarAnimation } = props;
if (!resolution) return false; if (!resolution || resolution === 'clear') return false;
const [, event] = resolution.event; const [, event] = resolution.event;
if (!event || !event.skill) return false; if (!event || !event.skill) return false;
if (!resolution.target) return false; if (!resolution.target) return false;
@ -90,15 +90,9 @@ function animations(props) {
: otherTeamIds.findIndex(c => c === resolution.target.id); : otherTeamIds.findIndex(c => c === resolution.target.id);
const x = j - i; const x = j - i;
anime({ if (avatarAnimation.id !== resolution.id) {
targets: [document.getElementById(construct.id)], setAvatarAnimation({ id: resolution.id, animTargetId: construct.id, x, y });
translateY: y * 200, }
translateX: x * 200,
easing: 'easeInOutElastic',
direction: 'alternate',
duration: TIMES.SOURCE_DURATION_MS,
});
} }
const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds; const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
if (!((resolution.target.id === construct.id) if (!((resolution.target.id === construct.id)
@ -116,7 +110,7 @@ function animations(props) {
case 'Blast': return <Blast />; case 'Blast': return <Blast />;
case 'Siphon': return <Siphon />; case 'Siphon': return <Siphon />;
case 'SiphonTick': return <SiphonTick />; case 'SiphonTick': return <SiphonTick />;
case 'Strike': return <Strike colour={colours.red}/>; case 'Strike': return <Strike colour={colours.red} id={resolution.id}/>;
case 'Chaos': return <Chaos />; case 'Chaos': return <Chaos />;
case 'Slay': return <Slay />; case 'Slay': return <Slay />;
case 'Heal': return <Heal />; case 'Heal': return <Heal />;

View File

@ -55,7 +55,6 @@ class Strike extends Component {
<feGaussianBlur stdDeviation="4"/> <feGaussianBlur stdDeviation="4"/>
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="3" result="turbulence"/> <feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="3" result="turbulence"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="1" xChannelSelector="A" yChannelSelector="A"/> <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="1" xChannelSelector="A" yChannelSelector="A"/>
</filter> </filter>
{this.charges} {this.charges}
</svg> </svg>
@ -63,15 +62,6 @@ class Strike extends Component {
} }
componentDidMount() { componentDidMount() {
this.animations.push(anime({
targets: ['#strike'],
opacity: [
{ value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 },
{ value: 0, delay: TIMES.TARGET_DURATION_MS * 0.6, duration: TIMES.TARGET_DURATION_MS * 0.2 },
],
easing: 'easeInOutSine',
}));
if (!this.props.team) { if (!this.props.team) {
anime.set('#strike', { anime.set('#strike', {
rotate: Math.random() * 180 + 90, rotate: Math.random() * 180 + 90,
@ -81,15 +71,22 @@ class Strike extends Component {
rotate: Math.random() * 180 + 270, rotate: Math.random() * 180 + 270,
}); });
} }
anime.set('#strike', { anime.set('#strike', {
translateY: -200, translateY: -200,
translateX: 0, translateX: 0,
}); });
anime.set('#strikeFilter feDisplacementMap', {
scale: 1,
});
anime({ this.animations.push(anime({
targets: '#strike',
opacity: [
{ value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 },
{ value: 0, delay: TIMES.TARGET_DURATION_MS * 0.6, duration: TIMES.TARGET_DURATION_MS * 0.2 },
],
easing: 'easeInOutSine',
}));
this.animations.push(anime({
targets: '#strike', targets: '#strike',
translateY: 0, translateY: 0,
translateX: 0, translateX: 0,
@ -97,14 +94,14 @@ class Strike extends Component {
delay: TIMES.TARGET_DELAY_MS, delay: TIMES.TARGET_DELAY_MS,
duration: (TIMES.TARGET_DURATION_MS * 1 / 2), duration: (TIMES.TARGET_DURATION_MS * 1 / 2),
easing: 'easeInQuad', easing: 'easeInQuad',
}); }));
anime({ this.animations.push(anime({
targets: '#strikeFilter feDisplacementMap', targets: '#strikeFilter feDisplacementMap',
scale: 200, scale: 200,
loop: false, loop: false,
delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS * 1 / 4), delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS * 1 / 4),
easing: 'easeInQuad', easing: 'easeInQuad',
}); }));
} }
componentWillUnmount() { componentWillUnmount() {

View File

@ -1,8 +1,10 @@
const preact = require('preact'); const preact = require('preact');
const { Component } = require('preact'); const { Component } = require('preact');
const { connect } = require('preact-redux');
const anime = require('animejs').default; const anime = require('animejs').default;
const { TIMES } = require('../constants');
const genAvatar = name => { const genAvatar = name => {
let hash = 0; let hash = 0;
if (name.length === 0) return hash; if (name.length === 0) return hash;
@ -38,7 +40,20 @@ function clearAnimation(id) {
animations[id] = false; animations[id] = false;
} }
const addState = connect(
function receiveState(state) {
const { avatarAnimation } = state;
return { avatarAnimation };
}
);
class ConstructAvatar extends Component { class ConstructAvatar extends Component {
constructor() {
super();
this.animId = 0;
this.animations = [];
}
render() { render() {
return ( return (
<div <div
@ -50,7 +65,25 @@ class ConstructAvatar extends Component {
} }
componentDidMount() { componentDidMount() {
animateConstruct(this.props.id); this.idle = animateConstruct(this.props.id);
}
componentWillReceiveProps(nextProps) {
if (nextProps.avatarAnimation.id !== this.animId && nextProps.avatarAnimation.animTargetId === this.props.id) {
this.animId = nextProps.avatarAnimation.id;
this.idle.pause();
const anim = anime({
targets: [document.getElementById(this.props.id)],
translateY: nextProps.avatarAnimation.y * 200,
translateX: nextProps.avatarAnimation.x * 200,
easing: 'easeInOutElastic',
direction: 'alternate',
duration: TIMES.SOURCE_DURATION_MS,
});
anim.finished.then(this.idle.play);
}
// console.log(this.props);
// console.log(nextProps);
} }
componentWillUnmount() { componentWillUnmount() {
@ -81,6 +114,6 @@ class ConstructImg extends Component {
} }
module.exports = { module.exports = {
ConstructAvatar, ConstructAvatar: addState(ConstructAvatar),
ConstructImg, ConstructImg,
}; };

View File

@ -10,6 +10,9 @@ const shapes = require('./shapes');
const SkillBtn = require('./skill.btn'); const SkillBtn = require('./skill.btn');
const actions = require('../actions');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { const {
@ -18,6 +21,7 @@ const addState = connect(
account, account,
resolution, resolution,
activeSkill, activeSkill,
avatarAnimation,
} = state; } = state;
function selectSkillTarget(targetConstructId) { function selectSkillTarget(targetConstructId) {
@ -31,15 +35,26 @@ const addState = connect(
if (activeSkill && activeSkill.skill.self_targeting) { if (activeSkill && activeSkill.skill.self_targeting) {
ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill); ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill);
} }
return { return {
game, game,
account, account,
resolution, resolution,
activeSkill, activeSkill,
avatarAnimation,
selectSkillTarget, selectSkillTarget,
}; };
},
function receiveDispatch(dispatch) {
function setAvatarAnimation(c) {
return dispatch(actions.setAvatarAnimation(c));
} }
return {
setAvatarAnimation,
};
}
); );
@ -52,7 +67,8 @@ function GameConstruct(props) {
player, player,
resolution, resolution,
activeSkill, activeSkill,
setActiveConstruct, avatarAnimation,
setAvatarAnimation,
selectSkillTarget, selectSkillTarget,
} = props; } = props;
@ -77,8 +93,7 @@ function GameConstruct(props) {
const effects = construct.effects.length const effects = construct.effects.length
? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>) ? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
: <div>&nbsp;</div>; : <div>&nbsp;</div>;
const combatAnim = animations({ game, account, resolution, player, construct, avatarAnimation, setAvatarAnimation });
const combatAnim = animations({ game, account, resolution, player, construct });
const combatText = getCombatText(resolution, construct); const combatText = getCombatText(resolution, construct);
return ( return (
<div <div

View File

@ -81,23 +81,29 @@ class TargetSvg extends Component {
return <path d={path} />; return <path d={path} />;
} }
if (resolution === 'clear') return false;
const arrows = resolution if (!resolution) {
? null return (
: outgoing.map(getPath); <svg id="targeting"
viewBox={`0 0 ${width} ${height}`}
preserveAspectRatio="none"
class="targeting-arrows">
{outgoing.map(getPath)}
</svg>
);
}
let skill = ''; let skill = '';
if (resolution) {
if (resolution.event[1]) ([, { skill }] = resolution.event); if (resolution.event[1]) ([, { skill }] = resolution.event);
}
const resolutionText = resolution
? <text x={`${(width / 2) - 50}`} y={`${(height / 2) + 16}`} font-family="Jura" font-size="2em"> {skill} </text>
: null;
return ( return (
<svg id="targeting" viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="none" class="targeting-arrows"> <svg id="targeting" viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="none" class="targeting-arrows">
{arrows} <text
{resolutionText} x={`${(width / 2) - 50}`}
y={`${(height / 2) + 16}`}
font-family="Jura"
font-size="2em">
{skill}
</text>
</svg> </svg>
); );
} }

View File

@ -60,15 +60,17 @@ function registerEvents(store) {
// stop fetching the game state til animations are done // stop fetching the game state til animations are done
ws.clearGameStateTimeout(); ws.clearGameStateTimeout();
const newRes = game.resolved.slice(currentGame.resolved.length); const newRes = game.resolved.slice(currentGame.resolved.length);
let id = game.resolved.length - currentGame.resolved.length;
return eachSeries(newRes, (r, cb) => { return eachSeries(newRes, (r, cb) => {
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb(); if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
// Create sub events for combat animations // Create sub events for combat animations
const sequence = getCombatSequence(r); const sequence = getCombatSequence(r);
id += 1;
return eachSeries(sequence, (stages, sCb) => { return eachSeries(sequence, (stages, sCb) => {
const stagedR = Object.create(r); const stagedR = Object.create(r);
stagedR.sequence = sequence; stagedR.sequence = sequence;
stagedR.stages = stages; stagedR.stages = stages;
stagedR.id = id;
let timeout = 0; let timeout = 0;
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) { if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
timeout = TIMES.SOURCE_AND_TARGET_TOTAL_DURATION; timeout = TIMES.SOURCE_AND_TARGET_TOTAL_DURATION;
@ -80,11 +82,14 @@ function registerEvents(store) {
return setTimeout(sCb, timeout); return setTimeout(sCb, timeout);
}, err => { }, err => {
if (err) console.error(err); if (err) console.error(err);
// Finished this resolution // Clear the anim classes
return cb(); store.dispatch(actions.setResolution('clear'));
// Finished this resolution small delay for reset
return setTimeout(cb, 5);
}); });
}, err => { }, err => {
if (err) return console.error(err); if (err) return console.error(err);
store.dispatch(actions.setAvatarAnimation({ id: -1 }));
store.dispatch(actions.setResolution(null)); store.dispatch(actions.setResolution(null));
// stop skipping resolutions // stop skipping resolutions
store.dispatch(actions.setSkip(false)); store.dispatch(actions.setSkip(false));

View File

@ -15,6 +15,7 @@ module.exports = {
activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'), activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'),
activeItem: createReducer(null, 'SET_ACTIVE_VAR'), activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'), activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
avatarAnimation: createReducer({ id: -1 }, 'SET_AVATAR_ANIMATION'),
combiner: createReducer([null, null, null], 'SET_COMBINER'), combiner: createReducer([null, null, null], 'SET_COMBINER'),
constructs: createReducer([], 'SET_CONSTRUCTS'), constructs: createReducer([], 'SET_CONSTRUCTS'),
constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'), constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'),

View File

@ -74,7 +74,7 @@ const STATS = {
}; };
function eventClasses(game, account, resolution, construct) { function eventClasses(game, account, resolution, construct) {
if (!resolution) return ''; if (!resolution || resolution === 'clear') return '';
const postSkill = resolution.stages.includes('POST_SKILL'); const postSkill = resolution.stages.includes('POST_SKILL');
const source = construct.id === resolution.source.id; const source = construct.id === resolution.source.id;
const target = construct.id === resolution.target.id; const target = construct.id === resolution.target.id;
@ -176,7 +176,7 @@ function getCombatSequence(resolution) {
} }
function getCombatText(resolution, construct) { function getCombatText(resolution, construct) {
if (!resolution) return false; if (!resolution || resolution === 'clear') return false;
if (!resolution.stages.includes('POST_SKILL')) return false; if (!resolution.stages.includes('POST_SKILL')) return false;
if (construct.id !== resolution.target.id) return false; if (construct.id !== resolution.target.id) return false;

View File

@ -1259,7 +1259,7 @@ mod tests {
assert!(*duration == 1); assert!(*duration == 1);
true true
}, },
Event::Skill { skill: _ } => false, Event::AoeSkill { skill: _ } => false,
_ => panic!("ruin result not effect {:?}", event), _ => panic!("ruin result not effect {:?}", event),
} }
false => false, false => false,