From 64896cfb3aa589bfa9e923de5483aa0b73f6273f Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 22 Jul 2019 15:30:46 +1000 Subject: [PATCH] no longer set resolution, everything from event loop --- client/src/actions.jsx | 1 + client/src/animations.utils.jsx | 88 +++++++++++++++--------- client/src/components/game.construct.jsx | 37 +++++++--- client/src/constants.jsx | 6 +- client/src/events.jsx | 11 +-- client/src/reducers.jsx | 1 + client/src/utils.jsx | 85 ----------------------- 7 files changed, 91 insertions(+), 138 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 4f93f33d..910d3be5 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -2,6 +2,7 @@ export const setAccount = value => ({ type: 'SET_ACCOUNT', value }); export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value }); export const setAnimating = value => ({ type: 'SET_ANIMATING', value }); +export const setAnimFocus = value => ({ type: 'SET_ANIM_FOCUS', value }); export const setAnimSource = value => ({ type: 'SET_ANIM_SOURCE', value }); export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value }); export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value }); diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 70d4cc68..559de717 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -86,94 +86,116 @@ function getSequence(resolution) { } } -const SOURCE_DURATION_MS = 1000; -const TARGET_DELAY_MS = 500; -const TARGET_DURATION_MS = 1500; -const POST_SKILL_DELAY_MS = 2000; -const POST_SKILL_DURATION_MS = 1000; -const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS + POST_SKILL_DURATION_MS; - function getTime(stages) { - if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) { - return TIMES.SOURCE_AND_TARGET_TOTAL_DURATION; - } - let time = 0; - - if (stages.includes('START_SKILL')) time += TIMES.SOURCE_DURATION_MS; - if (stages.includes('END_SKILL')) time += TIMES.TARGET_DURATION_MS; + if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) { + time += TIMES.SOURCE_AND_TARGET_TOTAL_DURATION; + } else { + if (stages.includes('START_SKILL')) time += TIMES.SOURCE_DURATION_MS; + if (stages.includes('END_SKILL')) time += TIMES.TARGET_DURATION_MS; + } if (stages.includes('POST_SKILL')) time += TIMES.POST_SKILL_DURATION_MS; return time; } -function getText(resolution, sequence) { - if (!resolution) return { text: null, constructId: null }; - if (!sequence.includes('POST_SKILL')) return { text: null, constructId: null }; +function getFocusTargets(resolution, game) { + if (!resolution) return []; + if (!resolution.event) return []; + const [type] = resolution.event; + const source = resolution.source.id; + const target = resolution.target.id; - function generateText() { + if (type === 'AoeSkill') { + const targetTeam = game.players.find(t => t.constructs.find(c => c.id === target)); + const targetTeamIds = targetTeam.constructs.map(c => c.id); + if (source !== target) return targetTeamIds.push(source); + return targetTeamIds; + } + if (source !== target) return [source, target]; + return target; +} + +function getText(resolution, sequence) { + const nullText = { text: null, constructId: null, life: null }; + if (!resolution) return nullText; + if (!sequence.includes('POST_SKILL')) return nullText; + + function generatePostSkill() { const [type, event] = resolution.event; if (type === 'Ko') { - return 'KO!'; + return { text: 'KO!', css: 'ko' }; } if (type === 'Disable') { const { disable } = event; - return `${disable}`; + return { text: `${disable}`, css: '' }; } if (type === 'Immunity') { - return 'IMMUNE'; + return { text: 'IMMUNE', css: '' }; } if (type === 'Damage') { const { mitigation, colour } = event; let { amount } = event; - if (colour === 'Green') amount *= -1; + let css = ''; + if (colour === 'Green') { + css = 'green-damage'; + amount *= -1; + } + if (colour === 'Red') css = 'red-damage'; + if (colour === 'Blue') css = 'blue-damage'; + const mitigationText = mitigation ? `(${mitigation})` : ''; - return `${amount} ${mitigationText}`; + return { text: `${amount} ${mitigationText}`, css }; } if (type === 'Healing') { const { amount, overhealing } = event; - return `${amount} (${overhealing} OH)`; + return { text: `${amount} (${overhealing} OH)`, css: 'green-damage' }; } if (type === 'Inversion') { - return 'INVERT'; + return { text: 'INVERT', css: '' }; } if (type === 'Reflection') { - return 'REFLECT'; + return { text: 'REFLECT', css: '' }; } if (type === 'Effect') { - const { effect, duration } = event; - return `+ ${effect} ${duration}T`; + const { effect, duration, construct_effects: effects } = event; + return { text: `+ ${effect} ${duration}T`, css: '', effects }; } if (type === 'Recharge') { const { red, blue } = event; - return [`+${red}R ${blue}B`, '']; + return { text: [`+${red}R ${blue}B`, ''], css: '' }; } if (type === 'Removal') { - const { effect } = event; - return `-${effect}`; + const { effect, construct_effects: effects } = event; + return { text: `-${effect}`, css: '', effects }; } - return false; } + const { green, red, blue } = resolution.target; + const { text, css, effects } = generatePostSkill(); return { - text: generateText(), + css, + text, + effects, + life: { green, red, blue }, constructId: resolution.target.id, }; } module.exports = { + getFocusTargets, getObjects, getTime, getSequence, diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 41c30b8b..39c39cfc 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -3,7 +3,7 @@ const { Component } = require('preact'); const preact = require('preact'); const range = require('lodash/range'); -const { STATS, eventClasses } = require('../utils'); +const { STATS } = require('../utils'); const { ConstructAvatar, ConstructText } = require('./construct'); const { ConstructAnimation } = require('./animations'); const shapes = require('./shapes'); @@ -21,8 +21,9 @@ const addState = connect( game, account, activeSkill, + animFocus, resolution, - + animating, animText, } = state; @@ -41,13 +42,31 @@ const addState = connect( game, account, resolution, + animating, + animFocus, animText, activeSkill, selectSkillTarget, }; - }, + } ); +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() { @@ -58,21 +77,17 @@ class GameConstruct extends Component { render() { const { i, - game, - account, + animating, construct, player, activeSkill, selectSkillTarget, - - // todo remove dep - resolution, - + animFocus, animText, } = this.props; const ko = construct.green_life.value === 0 ? 'ko' : ''; - const classes = eventClasses(game, account, resolution, construct, animText); + const classes = eventClasses(animating, animFocus, construct, animText); const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
@@ -83,7 +98,7 @@ class GameConstruct extends Component { )); const skills = range(0, 3) - .map(j => ); + .map(j => ); let crypSkills =
 
; if (player) crypSkills = (
{skills}
); diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 7a9afb24..95160256 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -1,16 +1,14 @@ const SOURCE_DURATION_MS = 1000; const TARGET_DELAY_MS = 500; const TARGET_DURATION_MS = 1500; -const POST_SKILL_DELAY_MS = 2000; const POST_SKILL_DURATION_MS = 1000; -const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS + POST_SKILL_DURATION_MS; +const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; module.exports = { TIMES: { SOURCE_DURATION_MS, TARGET_DELAY_MS, TARGET_DURATION_MS, - POST_SKILL_DELAY_MS, POST_SKILL_DURATION_MS, SOURCE_AND_TARGET_TOTAL_DURATION, }, @@ -20,7 +18,7 @@ module.exports = { RED: '#a52a2a', BLUE: '#3498db', WHITE: '#f5f5f5', // whitesmoke - PURPLE: '#9355b5' // 6lack - that far cover + PURPLE: '#9355b5', // 6lack - that far cover }, INFO: { diff --git a/client/src/events.jsx b/client/src/events.jsx index 3aad7443..59fd62af 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -55,8 +55,6 @@ function registerEvents(store) { return eachSeries(newRes, (r, cb) => { if (['Disable', 'TargetKo'].includes(r.event[0])) return cb(); - store.dispatch(actions.setResolution(r)); - // convert server enum into anims keywords // todo make serersideonly const sequence = animations.getSequence(r); @@ -64,13 +62,15 @@ function registerEvents(store) { const anims = animations.getObjects(r, sequence, game, account); const text = animations.getText(r, sequence); + store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r))); + if (sequence.includes('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource)); if (sequence.includes('END_SKILL')) store.dispatch(actions.setAnimTarget(anims.animTarget)); if (sequence.includes('POST_SKILL')) { // timeout to prevent text classes from being added too soon setTimeout( () => store.dispatch(actions.setAnimText(text)), - timeout - 1000, + timeout - TIMES.POST_SKILL_DURATION_MS ); } @@ -78,9 +78,10 @@ function registerEvents(store) { store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimText(null)); - return cb(); + // We currently need another small timeout so that everything can properly dismount / unload + // Otherwise 3 x Attack on same target will only render the first time + return setTimeout(cb, 75); }, timeout); - }, err => { if (err) return console.error(err); // clear animation state diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 539c5473..123fa806 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -18,6 +18,7 @@ module.exports = { animating: createReducer(false, 'SET_ANIMATING'), animSource: createReducer(null, 'SET_ANIM_SOURCE'), + animFocus: createReducer(null, 'SET_ANIM_FOCUS'), animTarget: createReducer(null, 'SET_ANIM_TARGET'), animText: createReducer(null, 'SET_ANIM_TEXT'), diff --git a/client/src/utils.jsx b/client/src/utils.jsx index bb0717ab..7349ccf6 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -85,89 +85,6 @@ const STATS = { }, }; -function eventClasses(game, account, resolution, construct, postSkill) { - if (!resolution) return ''; - const source = construct.id === resolution.source.id; - const target = construct.id === resolution.target.id; - // not involved at all. blur them - const [type, event] = resolution.event; - - if (type === 'AoeSkill') { - const playerTeam = game.players.find(t => t.id === account.id); - const playerTeamIds = playerTeam.constructs.map(c => c.id); - const otherTeam = game.players.find(t => t.id !== account.id); - const otherTeamIds = otherTeam.constructs.map(c => c.id); - const targetIsPlayer = playerTeamIds.includes(resolution.target.id); - - const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds; - - if (targetTeam.includes(construct.id)) return ''; - } - - if (!(source || target)) return 'unfocus'; - - if (type === 'Ko') { - if (target) return 'ko'; - } - - if (type === 'Damage') { - const { colour } = event; - if (target) { - construct.green_life.value = resolution.target.green; - if (colour === 'Red') { - construct.red_life.value = resolution.target.red; - return 'red-damage'; - } - if (colour === 'Blue') { - construct.blue_life.value = resolution.target.blue; - return 'blue-damage'; - } - if (colour === 'Green') { - construct.green_life.value = resolution.target.green; - return 'green-damage'; - } - } - } - - if (type === 'Healing') { - if (target && postSkill) { - construct.green_life.value = resolution.target.green; - return 'green-damage'; - } - } - - if (type === 'Effect') { - const { construct_effects: constructEffects } = event; - if (target && postSkill) construct.effects = constructEffects; - } - - if (type === 'Removal') { - const { construct_effects: constructEffects } = event; - if (target && postSkill) construct.effects = constructEffects; - } - - if (type === 'Recharge') { - const { red, blue } = event; - if (target && postSkill) { - if (red > 0 && blue > 0) { - construct.red_life.value = resolution.target.red; - construct.blue_life.value = resolution.target.blue; - return 'purple-damage'; - } - if (red > 0) { - construct.red_life.value = resolution.target.red; - return 'red-damage'; - } - if (blue > 0) { - construct.blue_life.value = resolution.target.blue; - return 'blue-damage'; - } - } - } - - return ''; -} - const COLOURS = [ '#a52a2a', '#1FF01F', @@ -225,7 +142,6 @@ function randomPoints(numPoints, radius, dimensions) { } const removeTier = skill => { - if (skill.includes('SiphonTick')) return 'SiphonTick'; if (skill.includes('TriageTick')) return 'TriageTick'; if (skill.includes('DecayTick')) return 'DecayTick'; @@ -314,7 +230,6 @@ function convertItem(v) { module.exports = { stringSort, numSort, - eventClasses, postData, convertItem, errorToast,