From bd517a1926391005de499ae12a2fdbc4a71dd6f2 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 19 Jul 2019 19:03:22 +1000 Subject: [PATCH] text back --- client/src/actions.jsx | 3 + client/src/animations.utils.jsx | 84 ++++++++++++++++++++++-- client/src/components/construct.jsx | 20 ++++++ client/src/components/game.construct.jsx | 32 ++++----- client/src/events.jsx | 15 ++++- client/src/reducers.jsx | 3 + client/src/utils.jsx | 74 ++------------------- 7 files changed, 137 insertions(+), 94 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 8b23cfa1..8eb1697f 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -1,8 +1,11 @@ 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 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 }); + export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value }); export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null }); export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) }); diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 49fe19ee..6a773ab8 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -85,22 +85,98 @@ 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; } - if (stages.includes('START_SKILL')) return TIMES.SOURCE_DURATION_MS; - if (stages.includes('END_SKILL')) return TIMES.TARGET_DURATION_MS; - if (stages.includes('POST_SKILL')) return TIMES.POST_SKILL_DURATION_MS; + let time = 0; - return 0; + 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 generateText() { + const [type, event] = resolution.event; + if (type === 'Ko') { + return 'KO!'; + } + + if (type === 'Disable') { + const { disable } = event; + return `${disable}`; + } + + if (type === 'Immunity') { + return 'IMMUNE'; + } + + if (type === 'Damage') { + const { mitigation, colour } = event; + let { amount } = event; + if (colour === 'Green') amount *= -1; + const mitigationText = mitigation + ? `(${mitigation})` + : ''; + return `${amount} ${mitigationText}`; + } + + if (type === 'Healing') { + const { amount, overhealing } = event; + return `${amount} (${overhealing} OH)`; + } + + if (type === 'Inversion') { + return 'INVERT'; + } + + if (type === 'Reflection') { + return 'REFLECT'; + } + + if (type === 'Effect') { + const { effect, duration } = event; + return `+ ${effect} ${duration}T`; + } + + if (type === 'Recharge') { + const { red, blue } = event; + return [`+${red}R ${blue}B`, '']; + } + + if (type === 'Removal') { + const { effect } = event; + return `-${effect}`; + } + + return false; + } + + return { + text: generateText(), + constructId: resolution.target.id, + }; } module.exports = { getObjects, getTime, getSequence, + getText, }; diff --git a/client/src/components/construct.jsx b/client/src/components/construct.jsx index 7cd8899d..6eb08e69 100644 --- a/client/src/components/construct.jsx +++ b/client/src/components/construct.jsx @@ -140,6 +140,26 @@ class ConstructAvatar extends Component { } } + +const addStateText = connect( + function receiveState(state) { + const { animText } = state; + return { animText }; + } +); + +function constructText(props) { + const { construct, animText } = props; + if (!construct || !animText) return false; + + const text = animText.constructId === construct.id + ? animText.text + : null; + + return
{text}
; +} + module.exports = { ConstructAvatar: addState(ConstructAvatar), + ConstructText: addStateText(constructText), }; diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 5e284e07..4569b4a1 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -3,8 +3,8 @@ const { Component } = require('preact'); const preact = require('preact'); const range = require('lodash/range'); -const { STATS, eventClasses, getCombatText } = require('../utils'); -const { ConstructAvatar } = require('./construct'); +const { STATS, eventClasses } = require('../utils'); +const { ConstructAvatar, ConstructText } = require('./construct'); const { ConstructAnimation } = require('./animations'); const shapes = require('./shapes'); @@ -20,9 +20,10 @@ const addState = connect( ws, game, account, - resolution, activeSkill, - avatarAnimation, + resolution, + + animText, } = state; function selectSkillTarget(targetConstructId) { @@ -40,22 +41,11 @@ const addState = connect( game, account, resolution, + animText, activeSkill, - avatarAnimation, selectSkillTarget, }; }, - - function receiveDispatch(dispatch) { - function setAvatarAnimation(source, target, id, animTargetId, type, params) { - return dispatch(actions.setAvatarAnimation({ source, target, id, animTargetId, type, params })); - } - - return { - setAvatarAnimation, - }; - } - ); @@ -72,9 +62,13 @@ class GameConstruct extends Component { account, construct, player, - resolution, activeSkill, selectSkillTarget, + + // todo remove dep + resolution, + + animText, } = this.props; const ko = construct.green_life.value === 0 ? 'ko' : ''; @@ -97,7 +91,7 @@ class GameConstruct extends Component { const effects = construct.effects.length ? construct.effects.map(c =>
{c.effect} - {c.duration}T
) :
 
; - const combatText = getCombatText(resolution, construct); + return (
selectSkillTarget(construct.id)} @@ -108,7 +102,7 @@ class GameConstruct extends Component {
{stats}
-
{combatText}
+
{effects}
); diff --git a/client/src/events.jsx b/client/src/events.jsx index 3843ea0c..074acd29 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -55,27 +55,36 @@ 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); const timeout = animations.getTime(sequence); const anims = animations.getObjects(r, sequence, game, account); + const text = animations.getText(r, sequence); - store.dispatch(actions.setAnimSource(anims.animSource)); - store.dispatch(actions.setAnimTarget(anims.animTarget)); + 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')) store.dispatch(actions.setAnimText(text)); return setTimeout(() => { store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); + store.dispatch(actions.setAnimText(null)); return setTimeout(cb, 50); - }, 3000); + }, timeout); }, err => { if (err) return console.error(err); // clear animation state store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); + store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimating(false)); + store.dispatch(actions.setSkip(false)); + store.dispatch(actions.setResolution(null)); + // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); ws.sendGameState(game.id); diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 9a36cccf..398e3721 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -15,9 +15,12 @@ module.exports = { activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'), activeItem: createReducer(null, 'SET_ACTIVE_VAR'), activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'), + animating: createReducer(false, 'SET_ANIMATING'), animSource: createReducer(null, 'SET_ANIM_SOURCE'), animTarget: createReducer(null, 'SET_ANIM_TARGET'), + animText: createReducer(null, 'SET_ANIM_TEXT'), + combiner: createReducer([null, null, null], 'SET_COMBINER'), constructs: createReducer([], 'SET_CONSTRUCTS'), constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'), diff --git a/client/src/utils.jsx b/client/src/utils.jsx index f50dc7a3..58340adf 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -86,8 +86,7 @@ const STATS = { }; function eventClasses(game, account, resolution, construct) { - if (!resolution || resolution === 'clear') return ''; - const postSkill = resolution.stages.includes('POST_SKILL'); + if (!resolution) return ''; const source = construct.id === resolution.source.id; const target = construct.id === resolution.target.id; // not involved at all. blur them @@ -113,7 +112,7 @@ function eventClasses(game, account, resolution, construct) { if (type === 'Damage') { const { colour } = event; - if (target && postSkill) { + if (target) { construct.green_life.value = resolution.target.green; if (colour === 'Red') { construct.red_life.value = resolution.target.red; @@ -131,7 +130,7 @@ function eventClasses(game, account, resolution, construct) { } if (type === 'Healing') { - if (target && postSkill) { + if (target) { construct.green_life.value = resolution.target.green; return 'green-damage'; } @@ -139,17 +138,17 @@ function eventClasses(game, account, resolution, construct) { if (type === 'Effect') { const { construct_effects: constructEffects } = event; - if (target && postSkill) construct.effects = constructEffects; + if (target) construct.effects = constructEffects; } if (type === 'Removal') { const { construct_effects: constructEffects } = event; - if (target && postSkill) construct.effects = constructEffects; + if (target) construct.effects = constructEffects; } if (type === 'Recharge') { const { red, blue } = event; - if (target && postSkill) { + if (target) { if (red > 0 && blue > 0) { construct.red_life.value = resolution.target.red; construct.blue_life.value = resolution.target.blue; @@ -169,66 +168,6 @@ function eventClasses(game, account, resolution, construct) { return ''; } -function getCombatText(resolution, construct) { - if (!resolution || resolution === 'clear') return false; - if (!resolution.stages.includes('POST_SKILL')) return false; - if (construct.id !== resolution.target.id) return false; - - const [type, event] = resolution.event; - if (type === 'Ko') { - return 'KO!'; - } - - if (type === 'Disable') { - const { disable } = event; - return `${disable}`; - } - - if (type === 'Immunity') { - return 'IMMUNE'; - } - - if (type === 'Damage') { - const { mitigation, colour } = event; - let { amount } = event; - if (colour === 'Green') amount *= -1; - const mitigationText = mitigation - ? `(${mitigation})` - : ''; - return `${amount} ${mitigationText}`; - } - - if (type === 'Healing') { - const { amount, overhealing } = event; - return `${amount} (${overhealing} OH)`; - } - - if (type === 'Inversion') { - return 'INVERT'; - } - - if (type === 'Reflection') { - return 'REFLECT'; - } - - if (type === 'Effect') { - const { effect, duration } = event; - return `+ ${effect} ${duration}T`; - } - - if (type === 'Recharge') { - const { red, blue } = event; - return [`+${red}R ${blue}B`, '']; - } - - if (type === 'Removal') { - const { effect } = event; - return `-${effect}`; - } - - return false; -} - function convertItem(v) { if (['Red', 'Green', 'Blue'].includes(v)) { return ( @@ -378,7 +317,6 @@ module.exports = { convertItem, numSort, eventClasses, - getCombatText, postData, errorToast, NULL_UUID,