text back

This commit is contained in:
ntr 2019-07-19 19:03:22 +10:00
parent c94fc46f34
commit bd517a1926
7 changed files with 137 additions and 94 deletions

View File

@ -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) });

View File

@ -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,
};

View File

@ -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 <div class={'combat-text'}>{text}</div>;
}
module.exports = {
ConstructAvatar: addState(ConstructAvatar),
ConstructText: addStateText(constructText),
};

View File

@ -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 => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
: <div>&nbsp;</div>;
const combatText = getCombatText(resolution, construct);
return (
<div
onClick={() => selectSkillTarget(construct.id)}
@ -108,7 +102,7 @@ class GameConstruct extends Component {
<div class="stats"> {stats} </div>
<ConstructAvatar construct={construct} />
<ConstructAnimation construct={construct} />
<div class={'combat-text'}> {combatText} </div>
<ConstructText construct={construct} />
<div class="effects"> {effects} </div>
</div>
);

View File

@ -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);

View File

@ -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'),

View File

@ -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,