mnml/client/src/scenes/combat.render.resolutions.js

148 lines
5.5 KiB
JavaScript

const { eachSeries } = require('async');
const CombatAnimations = require('./combat.animations');
const {
DELAYS: { ANIMATION_DURATION, MOVE_CREEP, DAMAGE_TICK },
POSITIONS: { COMBAT },
} = require('./constants');
function findResolutionCryps(scene, group, resolution, game) {
const sourceCryp = game.teams.find(t => t.cryps.find(c => c.id === resolution.source_cryp_id))
.cryps.find(c => c.id === resolution.source_cryp_id);
const sourceSpawn = group.children.entries.find(c => c.cryp.id === sourceCryp.id);
const targetCryp = game.teams.find(t => t.cryps.find(c => c.id === resolution.target_cryp_id))
.cryps.find(c => c.id === resolution.target_cryp_id);
const targetSpawn = group.children.entries.find(c => c.cryp.id === targetCryp.id);
return { sourceSpawn, targetSpawn };
}
function calculateTweenParams(sourceSpawn, targetSpawn, account) {
const tweenParams = (targets, centreSpot) => {
const enemy = targets.cryp.account !== account.id;
let x = centreSpot ? COMBAT.width() * 0.3 : targets.x;
x = (enemy && centreSpot) ? x + COMBAT.width() * 0.4 : x;
const y = centreSpot ? COMBAT.height() * 13.25 / 35 : targets.y;
const ease = 'Power1';
const duration = MOVE_CREEP;
return {
targets, x, y, ease, duration,
};
};
const moveSourceBattle = sourceSpawn.cryp.account !== targetSpawn.cryp.account
? tweenParams(sourceSpawn, true) : null;
const moveSourceOrig = sourceSpawn.cryp.account !== targetSpawn.cryp.account
? tweenParams(sourceSpawn, false) : null;
const moveTargetBattle = tweenParams(targetSpawn, true);
const moveTargetOrig = tweenParams(targetSpawn, false);
return {
moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig,
};
}
function animatePhase(scene, game, resolution, cb) {
// return early for disabled skills
if (resolution.resolution.disable.disabled) return cb();
const group = scene.scene.get('CombatCryps').cryps;
const animations = new CombatAnimations(scene);
const account = scene.registry.get('account');
// Find cryps, targets
const { sourceSpawn, targetSpawn } = findResolutionCryps(scene, group, resolution, game);
const {
moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig,
} = calculateTweenParams(sourceSpawn, targetSpawn, account);
const castParams = () => {
const x = (sourceSpawn === targetSpawn) ? moveTargetBattle.x : sourceSpawn.x;
const y = (sourceSpawn === targetSpawn) ? moveTargetBattle.y : sourceSpawn.y;
return { x, y };
};
const castLocation = castParams();
const { resolution: { results } } = resolution;
if (results.length === 0) return cb();
// Move cryps into position
if (moveSourceBattle) scene.tweens.add(moveSourceBattle);
scene.tweens.add(moveTargetBattle);
return scene.time.delayedCall(MOVE_CREEP, () => {
const isAlly = sourceSpawn.cryp.account === account.id;
// animate animation
animations.getSkill(resolution.skill, isAlly, castLocation);
// Target cryp takes damage
scene.time.delayedCall(ANIMATION_DURATION, () => {
eachSeries(results,
(result, tickCb) => {
// touch
if (!results.length) return tickCb();
const [resultType, values] = result;
if (resultType === 'Damage') {
targetSpawn.takeDamage(values);
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
return setTimeout(tickCb, DAMAGE_TICK);
}
if (resultType === 'Healing') {
targetSpawn.takeHealing(values.amount);
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
return setTimeout(tickCb, DAMAGE_TICK);
}
if (resultType === 'Effect') {
targetSpawn.effects.addEffect(values);
console.log('target has new effect', values.effect);
return setTimeout(tickCb, DAMAGE_TICK);
}
if (resultType === 'Removal') {
targetSpawn.effects.removeEffect(values.effect);
console.log('target effect removed', values.effect);
return setTimeout(tickCb, DAMAGE_TICK);
}
// unhandled result type
return tickCb();
},
(err) => {
// Move cryps back
if (moveSourceOrig) scene.tweens.add(moveSourceOrig);
scene.tweens.add(moveTargetOrig);
// all done
scene.time.delayedCall(MOVE_CREEP, () => {
animations.destroy(true);
return cb();
});
});
});
});
}
function renderResolutions(scene, game, resolutions) {
scene.registry.set('gamePhase', 'animating');
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
eachSeries(
resolutions,
(resolution, cb) => animatePhase(scene, game, resolution, cb),
(err) => {
if (err) return console.error(err);
scene.registry.set('gamePhase', 'Skill');
return true;
}
);
return true;
}
module.exports = renderResolutions;