diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 58a30438..f6c0c2ee 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -1,26 +1,27 @@ export const setAccount = value => ({ type: 'SET_ACCOUNT', value }); -export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value }); -export const setConstructDeleteId = value => ({ type: 'SET_CONSTRUCT_DELETE_ID', value }); -export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value }); -export const setSkip = value => ({ type: 'SET_SKIP', value }); -export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); -export const setInstances = value => ({ type: 'SET_INSTANCES', value }); -export const setNav = value => ({ type: 'SET_NAV', value }); -export const setShowNav = value => ({ type: 'SET_SHOW_NAV', value }); -export const setInstance = value => ({ type: 'SET_INSTANCE', value }); -export const setInstanceList = value => ({ type: 'SET_INSTANCE_LIST', value }); -export const setPing = value => ({ type: 'SET_PING', value }); -export const setPlayer = value => ({ type: 'SET_PLAYER', value }); -export const setGame = value => ({ type: 'SET_GAME', value }); -export const setResolution = value => ({ type: 'SET_RESOLUTION', value }); -export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value }); -export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) }); -export const setTeam = value => ({ type: 'SET_SELECTED_CONSTRUCTS', value: Array.from(value) }); export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null }); export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value }); export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value }); +export const setAvatarAnimation = value => ({ type: 'SET_AVATAR_ANIMATION', value }); +export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) }); +export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value }); +export const setConstructDeleteId = value => ({ type: 'SET_CONSTRUCT_DELETE_ID', value }); +export const setGame = value => ({ type: 'SET_GAME', value }); export const setInfo = value => ({ type: 'SET_INFO', value }); +export const setInstance = value => ({ type: 'SET_INSTANCE', value }); +export const setInstanceList = value => ({ type: 'SET_INSTANCE_LIST', value }); +export const setInstances = value => ({ type: 'SET_INSTANCES', value }); export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value }); +export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value }); export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value }); +export const setNav = value => ({ type: 'SET_NAV', value }); +export const setPing = value => ({ type: 'SET_PING', value }); +export const setPlayer = value => ({ type: 'SET_PLAYER', value }); export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value }); +export const setResolution = value => ({ type: 'SET_RESOLUTION', value }); +export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value }); +export const setShowNav = value => ({ type: 'SET_SHOW_NAV', value }); +export const setSkip = value => ({ type: 'SET_SKIP', value }); +export const setTeam = value => ({ type: 'SET_SELECTED_CONSTRUCTS', value: Array.from(value) }); +export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); export const setWs = value => ({ type: 'SET_WS', value }); diff --git a/client/src/app.jsx b/client/src/app.jsx index 9245495b..20586dc7 100644 --- a/client/src/app.jsx +++ b/client/src/app.jsx @@ -20,7 +20,7 @@ const store = createStore( document.fonts.load('16pt "Jura"').then(() => { const events = registerEvents(store); - store.subscribe(() => console.log(store.getState())); + // store.subscribe(() => console.log(store.getState())); setupKeys(store); const ws = createSocket(events); diff --git a/client/src/components/animations.jsx b/client/src/components/animations.jsx index 86f93010..564070fc 100644 --- a/client/src/components/animations.jsx +++ b/client/src/components/animations.jsx @@ -58,8 +58,8 @@ const colours = { const { TIMES } = require('../constants'); function animations(props) { - const { game, account, resolution, player, construct } = props; - if (!resolution) return false; + const { game, account, resolution, player, construct, avatarAnimation, setAvatarAnimation } = props; + if (!resolution || resolution === 'clear') return false; const [, event] = resolution.event; if (!event || !event.skill) return false; if (!resolution.target) return false; @@ -90,15 +90,9 @@ function animations(props) { : otherTeamIds.findIndex(c => c === resolution.target.id); const x = j - i; - anime({ - targets: [document.getElementById(construct.id)], - translateY: y * 200, - translateX: x * 200, - easing: 'easeInOutElastic', - direction: 'alternate', - duration: TIMES.SOURCE_DURATION_MS, - - }); + if (avatarAnimation.id !== resolution.id) { + setAvatarAnimation({ id: resolution.id, animTargetId: construct.id, x, y }); + } } const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds; if (!((resolution.target.id === construct.id) @@ -116,7 +110,7 @@ function animations(props) { case 'Blast': return ; case 'Siphon': return ; case 'SiphonTick': return ; - case 'Strike': return ; + case 'Strike': return ; case 'Chaos': return ; case 'Slay': return ; case 'Heal': return ; diff --git a/client/src/components/anims/strike.jsx b/client/src/components/anims/strike.jsx index 188cc043..3389f8ff 100644 --- a/client/src/components/anims/strike.jsx +++ b/client/src/components/anims/strike.jsx @@ -55,7 +55,6 @@ class Strike extends Component { - {this.charges} @@ -63,15 +62,6 @@ class Strike extends Component { } 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) { anime.set('#strike', { rotate: Math.random() * 180 + 90, @@ -81,15 +71,22 @@ class Strike extends Component { rotate: Math.random() * 180 + 270, }); } + anime.set('#strike', { translateY: -200, 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', translateY: 0, translateX: 0, @@ -97,14 +94,14 @@ class Strike extends Component { delay: TIMES.TARGET_DELAY_MS, duration: (TIMES.TARGET_DURATION_MS * 1 / 2), easing: 'easeInQuad', - }); - anime({ + })); + this.animations.push(anime({ targets: '#strikeFilter feDisplacementMap', scale: 200, loop: false, delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS * 1 / 4), easing: 'easeInQuad', - }); + })); } componentWillUnmount() { diff --git a/client/src/components/construct.jsx b/client/src/components/construct.jsx index 410c04d2..b70f0161 100644 --- a/client/src/components/construct.jsx +++ b/client/src/components/construct.jsx @@ -1,8 +1,10 @@ const preact = require('preact'); const { Component } = require('preact'); - +const { connect } = require('preact-redux'); const anime = require('animejs').default; +const { TIMES } = require('../constants'); + const genAvatar = name => { let hash = 0; if (name.length === 0) return hash; @@ -38,7 +40,20 @@ function clearAnimation(id) { animations[id] = false; } +const addState = connect( + function receiveState(state) { + const { avatarAnimation } = state; + return { avatarAnimation }; + } +); + class ConstructAvatar extends Component { + constructor() { + super(); + this.animId = 0; + this.animations = []; + } + render() { return (
{c.effect} - {c.duration}T
) :
 
; - - const combatAnim = animations({ game, account, resolution, player, construct }); + const combatAnim = animations({ game, account, resolution, player, construct, avatarAnimation, setAvatarAnimation }); const combatText = getCombatText(resolution, construct); return (
; } - - const arrows = resolution - ? null - : outgoing.map(getPath); + if (resolution === 'clear') return false; + if (!resolution) { + return ( + + {outgoing.map(getPath)} + + ); + } let skill = ''; - if (resolution) { - if (resolution.event[1]) ([, { skill }] = resolution.event); - } - const resolutionText = resolution - ? {skill} - : null; - + if (resolution.event[1]) ([, { skill }] = resolution.event); return ( - {arrows} - {resolutionText} + + {skill} + ); } diff --git a/client/src/events.jsx b/client/src/events.jsx index 25d0e76c..ec20bef3 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -60,15 +60,17 @@ function registerEvents(store) { // stop fetching the game state til animations are done ws.clearGameStateTimeout(); const newRes = game.resolved.slice(currentGame.resolved.length); + let id = game.resolved.length - currentGame.resolved.length; return eachSeries(newRes, (r, cb) => { if (['Disable', 'TargetKo'].includes(r.event[0])) return cb(); // Create sub events for combat animations const sequence = getCombatSequence(r); + id += 1; return eachSeries(sequence, (stages, sCb) => { const stagedR = Object.create(r); stagedR.sequence = sequence; stagedR.stages = stages; - + stagedR.id = id; let timeout = 0; if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) { timeout = TIMES.SOURCE_AND_TARGET_TOTAL_DURATION; @@ -80,11 +82,14 @@ function registerEvents(store) { return setTimeout(sCb, timeout); }, err => { if (err) console.error(err); - // Finished this resolution - return cb(); + // Clear the anim classes + store.dispatch(actions.setResolution('clear')); + // Finished this resolution small delay for reset + return setTimeout(cb, 5); }); }, err => { if (err) return console.error(err); + store.dispatch(actions.setAvatarAnimation({ id: -1 })); store.dispatch(actions.setResolution(null)); // stop skipping resolutions store.dispatch(actions.setSkip(false)); diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 2498963b..abd7ad03 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -15,6 +15,7 @@ module.exports = { activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'), activeItem: createReducer(null, 'SET_ACTIVE_VAR'), activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'), + avatarAnimation: createReducer({ id: -1 }, 'SET_AVATAR_ANIMATION'), combiner: createReducer([null, null, null], 'SET_COMBINER'), constructs: createReducer([], 'SET_CONSTRUCTS'), constructDeleteId: createReducer(null, 'SET_CONSTRUCT_DELETE_ID'), diff --git a/client/src/utils.jsx b/client/src/utils.jsx index c610f0dd..da74c26d 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -74,7 +74,7 @@ const STATS = { }; function eventClasses(game, account, resolution, construct) { - if (!resolution) return ''; + if (!resolution || resolution === 'clear') return ''; const postSkill = resolution.stages.includes('POST_SKILL'); const source = construct.id === resolution.source.id; const target = construct.id === resolution.target.id; @@ -176,7 +176,7 @@ function getCombatSequence(resolution) { } function getCombatText(resolution, construct) { - if (!resolution) return false; + if (!resolution || resolution === 'clear') return false; if (!resolution.stages.includes('POST_SKILL')) return false; if (construct.id !== resolution.target.id) return false;