no longer set resolution, everything from event loop

This commit is contained in:
Mashy 2019-07-22 15:30:46 +10:00
parent b04ae8a8d4
commit 64896cfb3a
7 changed files with 91 additions and 138 deletions

View File

@ -2,6 +2,7 @@ export const setAccount = value => ({ type: 'SET_ACCOUNT', value });
export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value }); export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value });
export const setAnimating = value => ({ type: 'SET_ANIMATING', 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 setAnimSource = value => ({ type: 'SET_ANIM_SOURCE', value });
export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value }); export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value });
export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value }); export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value });

View File

@ -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) { function getTime(stages) {
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
return TIMES.SOURCE_AND_TARGET_TOTAL_DURATION;
}
let time = 0; let time = 0;
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
if (stages.includes('START_SKILL')) time += TIMES.SOURCE_DURATION_MS; time += TIMES.SOURCE_AND_TARGET_TOTAL_DURATION;
if (stages.includes('END_SKILL')) time += TIMES.TARGET_DURATION_MS; } 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; if (stages.includes('POST_SKILL')) time += TIMES.POST_SKILL_DURATION_MS;
return time; return time;
} }
function getText(resolution, sequence) { function getFocusTargets(resolution, game) {
if (!resolution) return { text: null, constructId: null }; if (!resolution) return [];
if (!sequence.includes('POST_SKILL')) return { text: null, constructId: null }; 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; const [type, event] = resolution.event;
if (type === 'Ko') { if (type === 'Ko') {
return 'KO!'; return { text: 'KO!', css: 'ko' };
} }
if (type === 'Disable') { if (type === 'Disable') {
const { disable } = event; const { disable } = event;
return `${disable}`; return { text: `${disable}`, css: '' };
} }
if (type === 'Immunity') { if (type === 'Immunity') {
return 'IMMUNE'; return { text: 'IMMUNE', css: '' };
} }
if (type === 'Damage') { if (type === 'Damage') {
const { mitigation, colour } = event; const { mitigation, colour } = event;
let { amount } = 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 const mitigationText = mitigation
? `(${mitigation})` ? `(${mitigation})`
: ''; : '';
return `${amount} ${mitigationText}`; return { text: `${amount} ${mitigationText}`, css };
} }
if (type === 'Healing') { if (type === 'Healing') {
const { amount, overhealing } = event; const { amount, overhealing } = event;
return `${amount} (${overhealing} OH)`; return { text: `${amount} (${overhealing} OH)`, css: 'green-damage' };
} }
if (type === 'Inversion') { if (type === 'Inversion') {
return 'INVERT'; return { text: 'INVERT', css: '' };
} }
if (type === 'Reflection') { if (type === 'Reflection') {
return 'REFLECT'; return { text: 'REFLECT', css: '' };
} }
if (type === 'Effect') { if (type === 'Effect') {
const { effect, duration } = event; const { effect, duration, construct_effects: effects } = event;
return `+ ${effect} ${duration}T`; return { text: `+ ${effect} ${duration}T`, css: '', effects };
} }
if (type === 'Recharge') { if (type === 'Recharge') {
const { red, blue } = event; const { red, blue } = event;
return [`+${red}R ${blue}B`, '']; return { text: [`+${red}R ${blue}B`, ''], css: '' };
} }
if (type === 'Removal') { if (type === 'Removal') {
const { effect } = event; const { effect, construct_effects: effects } = event;
return `-${effect}`; return { text: `-${effect}`, css: '', effects };
} }
return false; return false;
} }
const { green, red, blue } = resolution.target;
const { text, css, effects } = generatePostSkill();
return { return {
text: generateText(), css,
text,
effects,
life: { green, red, blue },
constructId: resolution.target.id, constructId: resolution.target.id,
}; };
} }
module.exports = { module.exports = {
getFocusTargets,
getObjects, getObjects,
getTime, getTime,
getSequence, getSequence,

View File

@ -3,7 +3,7 @@ const { Component } = require('preact');
const preact = require('preact'); const preact = require('preact');
const range = require('lodash/range'); const range = require('lodash/range');
const { STATS, eventClasses } = require('../utils'); const { STATS } = require('../utils');
const { ConstructAvatar, ConstructText } = require('./construct'); const { ConstructAvatar, ConstructText } = require('./construct');
const { ConstructAnimation } = require('./animations'); const { ConstructAnimation } = require('./animations');
const shapes = require('./shapes'); const shapes = require('./shapes');
@ -21,8 +21,9 @@ const addState = connect(
game, game,
account, account,
activeSkill, activeSkill,
animFocus,
resolution, resolution,
animating,
animText, animText,
} = state; } = state;
@ -41,13 +42,31 @@ const addState = connect(
game, game,
account, account,
resolution, resolution,
animating,
animFocus,
animText, animText,
activeSkill, activeSkill,
selectSkillTarget, 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 { class GameConstruct extends Component {
constructor() { constructor() {
@ -58,21 +77,17 @@ class GameConstruct extends Component {
render() { render() {
const { const {
i, i,
game, animating,
account,
construct, construct,
player, player,
activeSkill, activeSkill,
selectSkillTarget, selectSkillTarget,
animFocus,
// todo remove dep
resolution,
animText, animText,
} = this.props; } = this.props;
const ko = construct.green_life.value === 0 ? 'ko' : ''; 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) => ( const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
<div key={j} alt={STATS[s].stat}> <div key={j} alt={STATS[s].stat}>
@ -83,7 +98,7 @@ class GameConstruct extends Component {
)); ));
const skills = range(0, 3) const skills = range(0, 3)
.map(j => <SkillBtn key={j} construct={construct} i={j} j={i} />); .map(j => <SkillBtn key={j} construct={construct} i={j} j={i} animating={animating} />);
let crypSkills = <div> &nbsp; </div>; let crypSkills = <div> &nbsp; </div>;
if (player) crypSkills = (<div class="skills"> {skills} </div>); if (player) crypSkills = (<div class="skills"> {skills} </div>);

View File

@ -1,16 +1,14 @@
const SOURCE_DURATION_MS = 1000; const SOURCE_DURATION_MS = 1000;
const TARGET_DELAY_MS = 500; const TARGET_DELAY_MS = 500;
const TARGET_DURATION_MS = 1500; const TARGET_DURATION_MS = 1500;
const POST_SKILL_DELAY_MS = 2000;
const POST_SKILL_DURATION_MS = 1000; 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 = { module.exports = {
TIMES: { TIMES: {
SOURCE_DURATION_MS, SOURCE_DURATION_MS,
TARGET_DELAY_MS, TARGET_DELAY_MS,
TARGET_DURATION_MS, TARGET_DURATION_MS,
POST_SKILL_DELAY_MS,
POST_SKILL_DURATION_MS, POST_SKILL_DURATION_MS,
SOURCE_AND_TARGET_TOTAL_DURATION, SOURCE_AND_TARGET_TOTAL_DURATION,
}, },
@ -20,7 +18,7 @@ module.exports = {
RED: '#a52a2a', RED: '#a52a2a',
BLUE: '#3498db', BLUE: '#3498db',
WHITE: '#f5f5f5', // whitesmoke WHITE: '#f5f5f5', // whitesmoke
PURPLE: '#9355b5' // 6lack - that far cover PURPLE: '#9355b5', // 6lack - that far cover
}, },
INFO: { INFO: {

View File

@ -55,8 +55,6 @@ function registerEvents(store) {
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();
store.dispatch(actions.setResolution(r));
// convert server enum into anims keywords // convert server enum into anims keywords
// todo make serersideonly // todo make serersideonly
const sequence = animations.getSequence(r); const sequence = animations.getSequence(r);
@ -64,13 +62,15 @@ function registerEvents(store) {
const anims = animations.getObjects(r, sequence, game, account); const anims = animations.getObjects(r, sequence, game, account);
const text = animations.getText(r, sequence); 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('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource));
if (sequence.includes('END_SKILL')) store.dispatch(actions.setAnimTarget(anims.animTarget)); if (sequence.includes('END_SKILL')) store.dispatch(actions.setAnimTarget(anims.animTarget));
if (sequence.includes('POST_SKILL')) { if (sequence.includes('POST_SKILL')) {
// timeout to prevent text classes from being added too soon // timeout to prevent text classes from being added too soon
setTimeout( setTimeout(
() => store.dispatch(actions.setAnimText(text)), () => 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.setAnimSource(null));
store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimTarget(null));
store.dispatch(actions.setAnimText(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); }, timeout);
}, err => { }, err => {
if (err) return console.error(err); if (err) return console.error(err);
// clear animation state // clear animation state

View File

@ -18,6 +18,7 @@ module.exports = {
animating: createReducer(false, 'SET_ANIMATING'), animating: createReducer(false, 'SET_ANIMATING'),
animSource: createReducer(null, 'SET_ANIM_SOURCE'), animSource: createReducer(null, 'SET_ANIM_SOURCE'),
animFocus: createReducer(null, 'SET_ANIM_FOCUS'),
animTarget: createReducer(null, 'SET_ANIM_TARGET'), animTarget: createReducer(null, 'SET_ANIM_TARGET'),
animText: createReducer(null, 'SET_ANIM_TEXT'), animText: createReducer(null, 'SET_ANIM_TEXT'),

View File

@ -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 = [ const COLOURS = [
'#a52a2a', '#a52a2a',
'#1FF01F', '#1FF01F',
@ -225,7 +142,6 @@ function randomPoints(numPoints, radius, dimensions) {
} }
const removeTier = skill => { const removeTier = skill => {
if (skill.includes('SiphonTick')) return 'SiphonTick'; if (skill.includes('SiphonTick')) return 'SiphonTick';
if (skill.includes('TriageTick')) return 'TriageTick'; if (skill.includes('TriageTick')) return 'TriageTick';
if (skill.includes('DecayTick')) return 'DecayTick'; if (skill.includes('DecayTick')) return 'DecayTick';
@ -314,7 +230,6 @@ function convertItem(v) {
module.exports = { module.exports = {
stringSort, stringSort,
numSort, numSort,
eventClasses,
postData, postData,
convertItem, convertItem,
errorToast, errorToast,