From 7afb6e30bdda6f60e40ad8aebc19917377a6a168 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 6 Dec 2019 16:26:50 +1000 Subject: [PATCH 1/6] wip --- core/src/construct.rs | 83 +++++++++++++++++++------------------------ core/src/game.rs | 48 +++++++++++++------------ core/src/skill.rs | 69 +++++++++++++++++------------------ 3 files changed, 98 insertions(+), 102 deletions(-) diff --git a/core/src/construct.rs b/core/src/construct.rs index f8a3efbf..937a377f 100644 --- a/core/src/construct.rs +++ b/core/src/construct.rs @@ -4,7 +4,7 @@ use rand::prelude::*; use failure::Error; use failure::err_msg; -use skill::{Skill, Cast, Disable, Event, EventVariant, EventConstruct}; +use skill::{Skill, Cast, Disable, EventVariant, EventConstruct}; use game::{Colour}; use effect::{Cooldown, Effect}; use spec::{Spec}; @@ -415,7 +415,7 @@ impl Construct { self } - pub fn increase_cooldowns(&mut self, turns: usize) -> Vec { + pub fn increase_cooldowns(&mut self, turns: usize) -> Vec { let mut events = vec![]; for skill in self.skills.iter_mut() { @@ -423,11 +423,11 @@ impl Construct { match skill.cd { Some(cd) => { skill.cd = Some(cd.saturating_add(turns)); - events.push(Event::new(EventVariant::CooldownIncrease { turns, skill: skill.skill }, self.id)) + events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill }) }, None => { skill.cd = Some(turns); - events.push(Event::new(EventVariant::CooldownIncrease { turns, skill: skill.skill }, self.id)) + events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill }) }, } } @@ -546,7 +546,7 @@ impl Construct { } } - pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec { + pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec { let mut events = vec![]; if self.is_ko() { return events; } @@ -565,7 +565,7 @@ impl Construct { let blue = new_blue_life - current_blue_life; if red != 0 || blue != 0 { - events.push(Event::new(EventVariant::Recharge { red, blue }, self.id)); + events.push(EventVariant::Recharge { red, blue }); } }, true => { @@ -591,12 +591,12 @@ impl Construct { self.reduce_green_life(red_remainder); let red_damage_amount = red_current_green_life - self.green_life(); - events.push(Event::new(EventVariant::Damage { + events.push(EventVariant::Damage { amount: red_damage_amount, mitigation: red_mitigation, colour: Colour::Red, display: EventConstruct::new(self), - }, self.id)); + }); } if blue_amount != 0 { @@ -620,19 +620,19 @@ impl Construct { self.reduce_green_life(blue_remainder); let blue_damage_amount = blue_current_green_life - self.green_life(); - events.push(Event::new(EventVariant::Damage { + events.push(EventVariant::Damage { amount: blue_damage_amount, mitigation: blue_mitigation, colour: Colour::Blue, display: EventConstruct::new(self), - }, self.id)); + }); } } } return events; } - pub fn deal_green_damage(&mut self, amount: usize) -> Vec { + pub fn deal_green_damage(&mut self, amount: usize) -> Vec { let mut events = vec![]; if self.is_ko() { return events; } @@ -653,10 +653,10 @@ impl Construct { let healing = new_green_life - current_green_life; let overhealing = modified_power - healing; - events.push(Event::new(EventVariant::Healing { + events.push(EventVariant::Healing { amount: healing, overhealing, - }, self.id)); + }); }, true => { // events.push(Event::new(EventVariant::Inversion { skill })); @@ -666,19 +666,19 @@ impl Construct { self.reduce_green_life(modified_power); let delta = current_green_life - self.green_life(); - events.push(Event::new(EventVariant::Damage { + events.push(EventVariant::Damage { amount: delta, mitigation: 0, colour: Colour::Green, display: EventConstruct::new(self), - }, self.id)); + }); } } return events; } - pub fn deal_red_damage(&mut self, amount: usize) -> Vec { + pub fn deal_red_damage(&mut self, amount: usize) -> Vec { let mut events = vec![]; if self.is_ko() { return events; } @@ -708,17 +708,16 @@ impl Construct { self.reduce_green_life(remainder); let delta = current_green_life - self.green_life(); - events.push(Event::new( + events.push( EventVariant::Damage { amount: delta, mitigation, colour: Colour::Red, display: EventConstruct::new(self), - }, - self.id - )); + } + ); if self.is_ko() { - events.push(Event::new(EventVariant::Ko {}, self.id)); + events.push(EventVariant::Ko {}); } }, true => { @@ -735,16 +734,16 @@ impl Construct { let recharge = self.red_life.value - current_life; if healing > 0 { - events.push(Event::new( - EventVariant::Healing{ + events.push( + EventVariant::Healing { amount: healing, overhealing: overhealing - recharge, - }, self.id - )); + } + ); } if recharge > 0 { - events.push(Event::new(EventVariant::Recharge { red: recharge, blue: 0 }, self.id)); + events.push(EventVariant::Recharge { red: recharge, blue: 0 }); } } }; @@ -752,7 +751,7 @@ impl Construct { return events; } - pub fn deal_blue_damage(&mut self, amount: usize) -> Vec { + pub fn deal_blue_damage(&mut self, amount: usize) -> Vec { let mut events = vec![]; if self.is_ko() { return events; } @@ -778,12 +777,12 @@ impl Construct { self.reduce_green_life(remainder); let delta = current_green_life - self.green_life(); - events.push(Event::new(EventVariant::Damage { + events.push(EventVariant::Damage { amount: delta, mitigation, colour: Colour::Blue, - display: EventConstruct::new(self), - }, self.id)); + display: EventConstruct::new(self), + }); }, true => { // events.push(Event::new(EventVariant::Inversion { skill })); @@ -799,17 +798,11 @@ impl Construct { let recharge = self.blue_life.value - current_life; if healing > 0 { - events.push( - Event::new(EventVariant::Healing { - amount: healing, - overhealing, - }, - self.id - )); + events.push(EventVariant::Healing { amount: healing, overhealing }); } if recharge > 0 { - events.push(Event::new(EventVariant::Recharge { red: 0, blue: recharge }, self.id)); + events.push(EventVariant::Recharge { red: 0, blue: recharge }); } } }; @@ -817,7 +810,7 @@ impl Construct { return events; } - pub fn add_effect(&mut self, effect: ConstructEffect) -> Vec { + pub fn add_effect(&mut self, effect: ConstructEffect) -> Vec { if self.is_ko() { return vec![] } if self.affected(Effect::Banish) { panic!("banish immunity not fixt yet") } @@ -834,13 +827,11 @@ impl Construct { } // todo modified durations cause of buffs - let result = Event::new( - EventVariant::Effect { - effect: effect.effect, - duration: effect.duration, - display: EventConstruct::new(self), - }, self.id - ); + let result = EventVariant::Effect { + effect: effect.effect, + duration: effect.duration, + display: EventConstruct::new(self) + }; return vec![result]; } diff --git a/core/src/game.rs b/core/src/game.rs index 9258c2e0..effe4285 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -40,11 +40,11 @@ pub enum Colour { #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub enum Action { - Hit { construct: Uuid, skill: Skill }, - HitCast { construct: Uuid, skill: Skill, source: Uuid }, - Damage { construct: Uuid, values: Vec, colour: Colour }, - Effect { construct: Uuid, effect: ConstructEffect }, - IncreaseCooldowns { construct: Uuid, turns: usize }, + Hit { cast: Cast }, + HitCast { cast: Cast }, + Damage { cast: Cast, construct: Uuid, values: Vec, colour: Colour }, + Effect { cast: Cast, construct: Uuid, effect: ConstructEffect }, + IncreaseCooldowns { cast: Cast, construct: Uuid, turns: usize }, // Recharge { skill: Skill, red: usize, blue: usize }, } @@ -493,7 +493,12 @@ impl Game { self.skill_phase_start(r_animation_ms) } - fn event_add(&mut self, mut events: Vec) -> &mut Game { + fn event_add(&mut self, event_variants: Vec, cast: Cast) -> &mut Game { + let mut events = event_variants + .iter() + .map(|e| e.to_event(cast)) + .collect(); + self.events.last_mut().unwrap().append(&mut events); self } @@ -501,45 +506,44 @@ impl Game { pub fn actions(&mut self, actions: Vec) -> &mut Game { for action in actions { match action { - Action::Hit { construct, skill } => self.hit(construct, skill), - Action::HitCast { construct, skill, source } => self.hit_cast(construct, skill, source), - Action::Damage { construct, values, colour } => self.damage(construct, values, colour), - Action::Effect { construct, effect } => self.effect(construct, effect), - Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns), + Action::Hit { cast } => self.hit(cast), + Action::HitCast { cast } => self.hit_cast(cast), + Action::Damage { cast, construct, values, colour } => self.damage(cast, construct, values, colour), + Action::Effect { cast, construct, effect } => self.effect(cast, construct, effect), + Action::IncreaseCooldowns { cast, construct, turns } => self.increase_cooldowns(cast, construct, turns), }; } self } - fn hit_cast(&mut self, construct: Uuid, skill: Skill, source: Uuid) -> &mut Game { - self.event_add(vec![Event::new(EventVariant::HitCast { skill: skill, source: source }, construct)]); + fn hit_cast(&mut self, cast: Cast) -> &mut Game { + self.event_add(vec![EventVariant::HitCast()], cast); self } - fn hit(&mut self, construct: Uuid, skill: Skill) -> &mut Game { - self.event_add(vec![Event::new(EventVariant::Hit { skill: skill }, construct)]); + fn hit(&mut self, cast: Cast) -> &mut Game { + self.event_add(vec![EventVariant::Hit()], cast); self } - fn damage(&mut self, construct: Uuid, values: Vec, colour: Colour) -> &mut Game { + fn damage(&mut self, cast: Cast, construct: Uuid, values: Vec, colour: Colour) -> &mut Game { let events = match colour { _ => self.construct_by_id(construct).unwrap().deal_red_damage(128) // fixme unwrap }; - - self.event_add(events); + self.event_add(events, cast); self } - fn effect(&mut self, construct: Uuid, effect: ConstructEffect) -> &mut Game { + fn effect(&mut self, cast: Cast, construct: Uuid, effect: ConstructEffect) -> &mut Game { let events = self.construct_by_id(construct).unwrap().add_effect(effect); - self.event_add(events); + self.event_add(events, cast); self } - fn increase_cooldowns(&mut self, construct: Uuid, turns: usize) -> &mut Game { + fn increase_cooldowns(&mut self, cast: Cast, construct: Uuid, turns: usize) -> &mut Game { let events = self.construct_by_id(construct).unwrap().increase_cooldowns(turns); - self.event_add(events); + self.event_add(events, cast); self } diff --git a/core/src/skill.rs b/core/src/skill.rs index a0282286..298c762f 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -89,6 +89,10 @@ impl Cast { }; } + pub fn target(self) -> Uuid { + self.target + } + pub fn new_tick(source: &mut Construct, target: &mut Construct, skill: Skill) -> Cast { Cast { id: Uuid::new_v4(), @@ -106,25 +110,28 @@ impl Cast { pub fn actions(&self) -> Vec { let mut actions = match self.skill.is_tick() { - false => vec![Action::HitCast { construct: self.target, skill: self.skill, source: self.source }], - true => vec![Action::Hit { construct: self.target, skill: self.skill }] + false => vec![Action::HitCast { cast: *self } ], + true => vec![Action::Hit { cast: *self } ] }; let mut rest = match self.skill { Skill::Amplify => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)), tick: None }, }, ], Skill::AmplifyPlus => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)), tick: None }, }, ], Skill::AmplifyPlusPlus => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)), tick: None }, }, @@ -132,6 +139,7 @@ impl Cast { Skill::Attack => vec![ Action::Damage { + cast: *self, construct: self.target, colour: Colour::Red, values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }], @@ -141,18 +149,21 @@ impl Cast { Skill::Banish => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } } ], Skill::BanishPlus => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } } ], Skill::BanishPlusPlus => vec![ Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } } @@ -162,6 +173,7 @@ impl Cast { Skill::BashPlus | Skill::BashPlusPlus => vec![ Action::Damage { + cast: *self, construct: self.target, colour: Colour::Red, values: vec![ @@ -170,10 +182,12 @@ impl Cast { ], }, Action::Effect { + cast: *self, construct: self.target, effect: ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None } }, Action::IncreaseCooldowns { + cast: *self, construct: self.target, turns: 1, }, @@ -183,6 +197,7 @@ impl Cast { Skill::BlastPlus | Skill::BlastPlusPlus => vec![ Action::Damage { + cast: *self, construct: self.target, colour: Colour::Blue, values: vec![Value::Stat { construct: self.source, stat: Stat::BluePower, mult: self.skill.multiplier() }], @@ -193,6 +208,7 @@ impl Cast { Skill::StrikePlus | Skill::StrikePlusPlus => vec![ Action::Damage { + cast: *self, construct: self.target, colour: Colour::Red, values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }], @@ -211,32 +227,20 @@ pub type Disable = Vec; #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Event { - pub target: Uuid, + pub cast: Cast, pub variant: EventVariant, pub delay: i64, } -impl Event { - pub fn new(variant: EventVariant, target: Uuid) -> Event { - let delay = variant.delay(); - Event { - target, - variant, - delay, - } - } -} - -#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum EventVariant { - Hit { skill: Skill }, - HitCast { skill: Skill, source: Uuid }, + Hit (), + HitCast (), Damage { amount: usize, mitigation: usize, colour: Colour, display: EventConstruct }, Effect { effect: Effect, duration: u8, display: EventConstruct }, Removal { effect: Option, display: EventConstruct }, - Disable { disable: Disable }, Healing { amount: usize, overhealing: usize }, Recharge { red: usize, blue: usize }, Inversion { skill: Skill }, @@ -264,16 +268,25 @@ impl EventVariant { let combat_text_overlap = 600; // overlap between animation and combat text match self { - EventVariant::Hit { skill: _ } => target_duration - combat_text_overlap, - EventVariant::HitCast { skill: _, source: _ } => target_delay + target_duration - combat_text_overlap, + EventVariant::Hit() => target_duration - combat_text_overlap, + EventVariant::HitCast() => target_delay + target_duration - combat_text_overlap, _ => combat_text_delay, } } + + pub fn to_event(&self, cast: Cast) -> Event { + let delay = self.delay(); + Event { + cast, + variant: *self, + delay, + } + } } // used to show the progress of a construct // while the resolutions are animating -#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct EventConstruct { pub id: Uuid, pub red: usize, @@ -1555,19 +1568,7 @@ mod tests { let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack); let actions = cast.actions(); - match actions[0] { - Action::Hit { construct: _, skill } => { - assert_eq!(skill, Skill::Attack); - }, - _ => panic!("{:?}", actions), - }; - - match actions[1] { - Action::Damage { construct: _, values: _, colour } => { - assert_eq!(colour, Colour::Red); - }, - _ => panic!("{:?}", actions), - }; + } // #[test] From a6f654fac1de769480ea6d065517748bcfd198e6 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 6 Dec 2019 18:09:11 +1000 Subject: [PATCH 2/6] send cast in event, split up cast and hit --- client/src/animations.utils.jsx | 85 +++++++++---------- client/src/components/anims/attack.jsx | 6 +- .../components/game.construct.anim.text.jsx | 12 +-- .../components/game.construct.effect.box.jsx | 9 +- client/src/components/game.construct.life.jsx | 9 +- client/src/events.jsx | 29 +++---- core/src/construct.rs | 27 ++++-- core/src/game.rs | 8 +- core/src/skill.rs | 78 +++++++++++------ 9 files changed, 144 insertions(+), 119 deletions(-) diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index abd1cb0d..248d3517 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -1,71 +1,66 @@ -function getObjects(resolution, game, account) { - const [type, event] = resolution.variant; - +const direction = (game, account, source, target) => { 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 sourceIsPlayer = playerTeamIds.includes(event.source); - const targetIsPlayer = playerTeamIds.includes(resolution.target); - - const targetting = () => { - if (type === 'AoeSkill') { - if (targetIsPlayer) return playerTeamIds; - return otherTeamIds; - } - return [resolution.target]; - }; + const sourceIsPlayer = playerTeamIds.includes(source); + const targetIsPlayer = playerTeamIds.includes(target); const sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer); let y = 0; if (!sameTeam) y = targetIsPlayer ? 1 : -1; const i = sourceIsPlayer - ? playerTeamIds.findIndex(c => c === event.source) - : otherTeamIds.findIndex(c => c === event.source); + ? playerTeamIds.findIndex(c => c === source) + : otherTeamIds.findIndex(c => c === source); const j = targetIsPlayer - ? playerTeamIds.findIndex(c => c === resolution.target) - : otherTeamIds.findIndex(c => c === resolution.target); + ? playerTeamIds.findIndex(c => c === target) + : otherTeamIds.findIndex(c => c === target); const x = j - i; - const direction = { x, y }; - // const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds; + return { x, y }; +}; - const getFocusTargets = () => { - if (type === 'HitCast') { - const { source } = event; - const { target } = resolution; - if (source !== target) return [source, target]; - return [target]; - } - if (type === 'AoeSkill') { - if (targetIsPlayer) return playerTeamIds; - return otherTeamIds; - } - return [resolution.target]; - }; +function getAnimSource(resolution, game, account) { + const { source, target } = resolution.cast; const animSource = { animation: 'sourceCast', - constructId: event.source, - direction, + constructId: source, + direction: direction(game, account, source, target), }; + return animSource; +} +function getAnimTarget(resolution, game, account) { + const { source, target, skill } = resolution.cast; + const player = resolution.cast.player === account; const animTarget = { - skill: event.skill, - constructId: targetting(), - player: playerTeamIds.includes(resolution.target), - direction, + constructId: resolution.cast.target, + player, + direction: direction(game, account, source, target), + skill, }; - return { - animSource, - animTarget, - focusTargets: getFocusTargets(), - skill: event.skill, - }; + return animTarget; +} + +function getFocusTargets(resolution, game, account) { + if (resolution.variant[1] === 'AoeHit') { + 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); + if (resolution.cast.player === account) return playerTeamIds; + return otherTeamIds; + } + + const { source, target } = resolution.cast; + return [source, target]; } module.exports = { - getObjects, + getAnimSource, + getAnimTarget, + getFocusTargets, }; diff --git a/client/src/components/anims/attack.jsx b/client/src/components/anims/attack.jsx index 65756c1f..0f5dd317 100644 --- a/client/src/components/anims/attack.jsx +++ b/client/src/components/anims/attack.jsx @@ -46,8 +46,8 @@ class Attack extends Component { y: [400, 200], height: [100, 10, 0], width: [12, 5, 0], - delay: () => anime.random(TIMES.TARGET_DELAY_MS, TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS / 2), - duration: TIMES.TARGET_DURATION_MS, + delay: () => anime.random(0, TIMES.TARGET_DURATION_MS / 4), + duration: TIMES.TARGET_DURATION_MS * 5 / 4, })); } @@ -59,9 +59,7 @@ class Attack extends Component { for (let i = this.animations.length - 1; i >= 0; i--) { this.animations[i].reset(); } - this.props.animCb && this.props.animCb(); } - } module.exports = addState(Attack); diff --git a/client/src/components/game.construct.anim.text.jsx b/client/src/components/game.construct.anim.text.jsx index ad39219d..b54d9cd1 100644 --- a/client/src/components/game.construct.anim.text.jsx +++ b/client/src/components/game.construct.anim.text.jsx @@ -7,7 +7,7 @@ const shapes = require('./shapes'); const { removeTier } = require('../utils'); const { TIMES } = require('./../constants'); -const addState = connect(({ animText, animSkill, itemInfo }) => ({ animText, animSkill, itemInfo })); +const addState = connect(({ animText, itemInfo }) => ({ animText, itemInfo })); class AnimText extends preact.Component { shouldComponentUpdate(newProps) { @@ -17,7 +17,7 @@ class AnimText extends preact.Component { componentDidUpdate(prevProps) { const { animText, construct } = this.props; - if (animText && animText !== prevProps.animText && animText.target === construct.id) { + if (animText && animText !== prevProps.animText && animText.variant[1].target === construct.id) { anime({ targets: '.combat-text', top: '40%', @@ -28,10 +28,10 @@ class AnimText extends preact.Component { } render() { - const { construct, animText, animSkill, itemInfo } = this.props; - if (animText && animText.target === construct.id) { + const { construct, animText, itemInfo } = this.props; + if (animText && animText.variant[1].target === construct.id) { const itemSourceDescription = () => { - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animSkill)); + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.cast.skill)); const itemSourceInfo = itemSource.length ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` : false; @@ -82,7 +82,7 @@ class AnimText extends preact.Component { return (
-

{animSkill}

+

{animText.cast.skill}

{itemSourceDescription()} {generateAnimText()}
diff --git a/client/src/components/game.construct.effect.box.jsx b/client/src/components/game.construct.effect.box.jsx index a6215475..598c2ae8 100644 --- a/client/src/components/game.construct.effect.box.jsx +++ b/client/src/components/game.construct.effect.box.jsx @@ -21,11 +21,10 @@ const addState = connect( class GameConstructEffects extends preact.Component { shouldComponentUpdate(newProps) { - if (newProps.animText !== this.props.animText) { - if (newProps.animText && newProps.animText.constructId === this.props.construct.id) { - const [type] = newProps.animText.variant; - if (type === 'Effect' || type === 'Removal') return true; - } + if (newProps.animText && newProps.animText !== this.props.animText) { + const [type, info] = newProps.animText.variant; + if (info.target === this.props.construct.id + && (type === 'Effect' || type === 'Removal')) return true; } if (newProps.construct !== this.props.construct) return true; return false; diff --git a/client/src/components/game.construct.life.jsx b/client/src/components/game.construct.life.jsx index 680f657c..fe2f76a1 100644 --- a/client/src/components/game.construct.life.jsx +++ b/client/src/components/game.construct.life.jsx @@ -7,11 +7,10 @@ const addState = connect(({ animText }) => ({ animText })); class GameConstructLife extends preact.Component { shouldComponentUpdate(newProps) { - if (newProps.animText !== this.props.animText) { - if (newProps.animText && newProps.animText.target === this.props.construct.id) { - const [type] = newProps.animText.variant; - if (type === 'Damage' || type === 'Healing' || type === 'Recharge') return true; - } + if (newProps.animText && newProps.animText !== this.props.animText) { + const [type, info] = newProps.animText.variant; + if (info.target === this.props.construct.id + && (type === 'Damage' || type === 'Healing' || type === 'Recharge')) return true; } if (newProps.construct !== this.props.construct) return true; return false; diff --git a/client/src/events.jsx b/client/src/events.jsx index ca91776d..ba78e4d2 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -5,7 +5,7 @@ const eachSeries = require('async/eachSeries'); const sample = require('lodash/sample'); const actions = require('./actions'); -const animations = require('./animations.utils'); +const { getAnimSource, getAnimTarget, getFocusTargets } = require('./animations.utils'); const { infoToast, errorToast } = require('./utils'); const { tutorialVbox } = require('./tutorial.utils'); const { TIMES } = require('./constants'); @@ -90,24 +90,19 @@ function registerEvents(store) { const newRes = game.events[currentGame.events.length]; return eachSeries(newRes, (r, cb) => { const timeout = r.delay; + const focusTargets = getFocusTargets(r, game, account); + store.dispatch(actions.setAnimFocus(focusTargets)); - if (r.variant[0].includes('Hit')) { - let animTimeOut = TIMES.TARGET_DURATION_MS; - const anims = animations.getObjects(r, game, account); - - if (r.variant[0] === 'HitCast') { - animTimeOut += TIMES.TARGET_DELAY_MS; - store.dispatch(actions.setAnimSource(anims.animSource)); - } - - store.dispatch(actions.setAnimFocus(anims.focusTargets)); - store.dispatch(actions.setAnimSkill(anims.skill)); - store.dispatch(actions.setAnimTarget(anims.animTarget)); + if (r.variant[0] === 'Cast') { + const animSource = getAnimSource(r, game, account); + store.dispatch(actions.setAnimSource(animSource)); store.dispatch(actions.setAnimText(null)); - setTimeout(() => { - store.dispatch(actions.setAnimSource(null)); - store.dispatch(actions.setAnimTarget(null)); - }, animTimeOut); + setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS); + } else if (r.variant[0].includes('Hit')) { + const animTarget = getAnimTarget(r, game, account); + store.dispatch(actions.setAnimTarget(animTarget)); + store.dispatch(actions.setAnimText(null)); + setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS); } else { store.dispatch(actions.setAnimText(r)); } diff --git a/core/src/construct.rs b/core/src/construct.rs index 937a377f..84f1b9e2 100644 --- a/core/src/construct.rs +++ b/core/src/construct.rs @@ -423,11 +423,11 @@ impl Construct { match skill.cd { Some(cd) => { skill.cd = Some(cd.saturating_add(turns)); - events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill }) + events.push(EventVariant::CooldownIncrease { target: self.id, turns }) }, None => { skill.cd = Some(turns); - events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill }) + events.push(EventVariant::CooldownIncrease { target: self.id, turns }) }, } } @@ -548,7 +548,7 @@ impl Construct { pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec { let mut events = vec![]; - + let target = self.id; if self.is_ko() { return events; } match self.affected(Effect::Invert) { @@ -565,7 +565,7 @@ impl Construct { let blue = new_blue_life - current_blue_life; if red != 0 || blue != 0 { - events.push(EventVariant::Recharge { red, blue }); + events.push(EventVariant::Recharge { target, red, blue }); } }, true => { @@ -592,6 +592,7 @@ impl Construct { let red_damage_amount = red_current_green_life - self.green_life(); events.push(EventVariant::Damage { + target, amount: red_damage_amount, mitigation: red_mitigation, colour: Colour::Red, @@ -621,6 +622,7 @@ impl Construct { let blue_damage_amount = blue_current_green_life - self.green_life(); events.push(EventVariant::Damage { + target, amount: blue_damage_amount, mitigation: blue_mitigation, colour: Colour::Blue, @@ -635,6 +637,7 @@ impl Construct { pub fn deal_green_damage(&mut self, amount: usize) -> Vec { let mut events = vec![]; if self.is_ko() { return events; } + let target = self.id; let mods = self.effects.iter() .filter(|e| e.effect.modifications().contains(&Stat::GreenDamageTaken)) @@ -654,6 +657,7 @@ impl Construct { let overhealing = modified_power - healing; events.push(EventVariant::Healing { + target, amount: healing, overhealing, }); @@ -667,6 +671,7 @@ impl Construct { let delta = current_green_life - self.green_life(); events.push(EventVariant::Damage { + target, amount: delta, mitigation: 0, colour: Colour::Green, @@ -682,6 +687,7 @@ impl Construct { let mut events = vec![]; if self.is_ko() { return events; } + let target = self.id; let mods = self.effects.iter() .filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken)) @@ -710,6 +716,7 @@ impl Construct { events.push( EventVariant::Damage { + target, amount: delta, mitigation, colour: Colour::Red, @@ -717,7 +724,7 @@ impl Construct { } ); if self.is_ko() { - events.push(EventVariant::Ko {}); + events.push(EventVariant::Ko { target }); } }, true => { @@ -736,6 +743,7 @@ impl Construct { if healing > 0 { events.push( EventVariant::Healing { + target, amount: healing, overhealing: overhealing - recharge, } @@ -743,7 +751,7 @@ impl Construct { } if recharge > 0 { - events.push(EventVariant::Recharge { red: recharge, blue: 0 }); + events.push(EventVariant::Recharge { target, red: recharge, blue: 0 }); } } }; @@ -755,6 +763,7 @@ impl Construct { let mut events = vec![]; if self.is_ko() { return events; } + let target = self.id; let mods = self.effects.iter() .filter(|e| e.effect.modifications().contains(&Stat::BlueDamageTaken)) @@ -778,6 +787,7 @@ impl Construct { let delta = current_green_life - self.green_life(); events.push(EventVariant::Damage { + target, amount: delta, mitigation, colour: Colour::Blue, @@ -798,11 +808,11 @@ impl Construct { let recharge = self.blue_life.value - current_life; if healing > 0 { - events.push(EventVariant::Healing { amount: healing, overhealing }); + events.push(EventVariant::Healing { target, amount: healing, overhealing }); } if recharge > 0 { - events.push(EventVariant::Recharge { red: 0, blue: recharge }); + events.push(EventVariant::Recharge { target, red: 0, blue: recharge }); } } }; @@ -828,6 +838,7 @@ impl Construct { // todo modified durations cause of buffs let result = EventVariant::Effect { + target: self.id, effect: effect.effect, duration: effect.duration, display: EventConstruct::new(self) diff --git a/core/src/game.rs b/core/src/game.rs index effe4285..f351a70d 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -41,7 +41,7 @@ pub enum Colour { #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub enum Action { Hit { cast: Cast }, - HitCast { cast: Cast }, + Cast { cast: Cast }, Damage { cast: Cast, construct: Uuid, values: Vec, colour: Colour }, Effect { cast: Cast, construct: Uuid, effect: ConstructEffect }, IncreaseCooldowns { cast: Cast, construct: Uuid, turns: usize }, @@ -507,7 +507,7 @@ impl Game { for action in actions { match action { Action::Hit { cast } => self.hit(cast), - Action::HitCast { cast } => self.hit_cast(cast), + Action::Cast { cast } => self.cast(cast), Action::Damage { cast, construct, values, colour } => self.damage(cast, construct, values, colour), Action::Effect { cast, construct, effect } => self.effect(cast, construct, effect), Action::IncreaseCooldowns { cast, construct, turns } => self.increase_cooldowns(cast, construct, turns), @@ -517,8 +517,8 @@ impl Game { self } - fn hit_cast(&mut self, cast: Cast) -> &mut Game { - self.event_add(vec![EventVariant::HitCast()], cast); + fn cast(&mut self, cast: Cast) -> &mut Game { + self.event_add(vec![EventVariant::Cast()], cast); self } diff --git a/core/src/skill.rs b/core/src/skill.rs index 298c762f..a8b1db8f 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -109,10 +109,13 @@ impl Cast { } pub fn actions(&self) -> Vec { - let mut actions = match self.skill.is_tick() { - false => vec![Action::HitCast { cast: *self } ], - true => vec![Action::Hit { cast: *self } ] - }; + let mut actions = vec![]; + + if self.skill.cast_animation() { + actions.push(Action::Cast { cast: *self }); + } + + actions.push(Action::Hit { cast: *self }); let mut rest = match self.skill { Skill::Amplify => vec![ @@ -234,29 +237,23 @@ pub struct Event { #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum EventVariant { + Cast (), Hit (), - HitCast (), + HitAoe (), - Damage { amount: usize, mitigation: usize, colour: Colour, display: EventConstruct }, - Effect { effect: Effect, duration: u8, display: EventConstruct }, - Removal { effect: Option, display: EventConstruct }, + Damage { target: Uuid, amount: usize, mitigation: usize, colour: Colour, display: EventConstruct }, + Effect { target: Uuid, effect: Effect, duration: u8, display: EventConstruct }, + Removal { target: Uuid, effect: Option, display: EventConstruct }, - Healing { amount: usize, overhealing: usize }, - Recharge { red: usize, blue: usize }, - Inversion { skill: Skill }, - Reflection { skill: Skill }, - AoeSkill { skill: Skill }, - Skill { skill: Skill }, - TargetKo { skill: Skill }, - // skill not necessary but makes it neater as all events are arrays in js - Ko (), + Healing { target: Uuid, amount: usize, overhealing: usize }, + Recharge { target: Uuid, red: usize, blue: usize }, + Inversion { target: Uuid }, + Reflection { target: Uuid }, + Ko { target: Uuid }, + + CooldownIncrease { target: Uuid, turns: usize }, + CooldownDecrease { target: Uuid, turns: usize }, Forfeit (), - Incomplete (), - // not used - Evasion { skill: Skill, evasion_rating: usize }, - - CooldownIncrease { turns: usize, skill: Skill }, - CooldownDecrease { turns: usize, skill: Skill }, } impl EventVariant { @@ -269,7 +266,7 @@ impl EventVariant { match self { EventVariant::Hit() => target_duration - combat_text_overlap, - EventVariant::HitCast() => target_delay + target_duration - combat_text_overlap, + EventVariant::Cast() => target_delay, _ => combat_text_delay, } } @@ -1053,6 +1050,24 @@ impl Skill { } } + pub fn cast_animation(&self) -> bool { + match self { + Skill::ElectrocuteTick | + Skill::ElectrocuteTickPlus | + Skill::ElectrocuteTickPlusPlus | + Skill::DecayTick | + Skill::DecayTickPlus | + Skill::DecayTickPlusPlus | + Skill::SiphonTick | + Skill::SiphonTickPlus | + Skill::SiphonTickPlusPlus | + Skill::TriageTick | + Skill::TriageTickPlus | + Skill::TriageTickPlusPlus => false, + _ => true + } + } + pub fn defensive(&self) -> bool { match self { Skill::Amplify| @@ -1568,7 +1583,20 @@ mod tests { let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack); let actions = cast.actions(); - + match actions[0] { + Action::Hit { cast } => { + assert_eq!(cast.skill, Skill::Attack); + }, + _ => panic!("{:?}", actions), + }; + + match actions[1] { + Action::Damage { cast: _, construct: _, values: _, colour } => { + assert_eq!(colour, Colour::Red); + }, + _ => panic!("{:?}", actions), + }; + } // #[test] From 261ab1d48b982dcaeb167f8b351e8f57be437a86 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 6 Dec 2019 20:24:14 +1000 Subject: [PATCH 3/6] calculate direction server side --- client/src/animations.utils.jsx | 56 ++++++++++----------------------- client/src/events.jsx | 4 +-- core/src/game.rs | 31 ++++++++++++++++-- core/src/skill.rs | 11 ++++--- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 248d3517..e0cc1bdb 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -1,52 +1,30 @@ -const direction = (game, account, source, target) => { - 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 sourceIsPlayer = playerTeamIds.includes(source); - const targetIsPlayer = playerTeamIds.includes(target); +function getAnimSource(resolution, account) { + const { player } = resolution.cast; + const { x, y, target } = resolution.variant[1]; + const animY = y && player === account.id ? -1 : y; - const sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer); - let y = 0; - if (!sameTeam) y = targetIsPlayer ? 1 : -1; - - const i = sourceIsPlayer - ? playerTeamIds.findIndex(c => c === source) - : otherTeamIds.findIndex(c => c === source); - - const j = targetIsPlayer - ? playerTeamIds.findIndex(c => c === target) - : otherTeamIds.findIndex(c => c === target); - const x = j - i; - return { x, y }; -}; - - -function getAnimSource(resolution, game, account) { - const { source, target } = resolution.cast; - const animSource = { + return { animation: 'sourceCast', - constructId: source, - direction: direction(game, account, source, target), + constructId: target, + direction: { x, y: animY }, }; - return animSource; } -function getAnimTarget(resolution, game, account) { - const { source, target, skill } = resolution.cast; - const player = resolution.cast.player === account; - const animTarget = { - constructId: resolution.cast.target, - player, - direction: direction(game, account, source, target), +function getAnimTarget(resolution, account) { + const { player, skill } = resolution.cast; + const { x, y, target } = resolution.variant[1]; + const animY = y && player === account.id ? -1 : y; + const isPlayer = player === account.id; + return { + constructId: target, + player: isPlayer, skill, + direction: { x, y: animY }, }; - - return animTarget; } function getFocusTargets(resolution, game, account) { - if (resolution.variant[1] === 'AoeHit') { + if (resolution.variant[1] === 'HitAoe') { 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); diff --git a/client/src/events.jsx b/client/src/events.jsx index ba78e4d2..84753cec 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -94,12 +94,12 @@ function registerEvents(store) { store.dispatch(actions.setAnimFocus(focusTargets)); if (r.variant[0] === 'Cast') { - const animSource = getAnimSource(r, game, account); + const animSource = getAnimSource(r, account); store.dispatch(actions.setAnimSource(animSource)); store.dispatch(actions.setAnimText(null)); setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS); } else if (r.variant[0].includes('Hit')) { - const animTarget = getAnimTarget(r, game, account); + const animTarget = getAnimTarget(r, account); store.dispatch(actions.setAnimTarget(animTarget)); store.dispatch(actions.setAnimText(null)); setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS); diff --git a/core/src/game.rs b/core/src/game.rs index f351a70d..f07bce57 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -517,13 +517,40 @@ impl Game { self } + fn direction(&mut self, cast: Cast) -> (i8, i8) { + let i = self.players.iter() + .find(|t| t.constructs.iter().any(|c| c.id == cast.source)) + .unwrap().constructs + .iter() + .position(|c| c.id == cast.source) + .unwrap() as i8; + + let j = self.players.iter() + .find(|t| t.constructs.iter().any(|c| c.id == cast.target)) + .unwrap().constructs + .iter() + .position(|c| c.id == cast.target) + .unwrap() as i8; + let x = j - i; + + let target = self.construct_by_id(cast.target).unwrap(); + // is the caster player account same as target player account side of screen + let y = match cast.player == target.account { + true => 0, + false => 1 + }; + (x, y) + } + fn cast(&mut self, cast: Cast) -> &mut Game { - self.event_add(vec![EventVariant::Cast()], cast); + let (x, y) = self.direction(cast); + self.event_add(vec![EventVariant::Cast { target: cast.source, x, y, player: cast.player }], cast); self } fn hit(&mut self, cast: Cast) -> &mut Game { - self.event_add(vec![EventVariant::Hit()], cast); + let (x, y) = self.direction(cast); + self.event_add(vec![EventVariant::Hit { target: cast.target, x, y, player: cast.player }], cast); self } diff --git a/core/src/skill.rs b/core/src/skill.rs index a8b1db8f..58313f43 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -237,9 +237,9 @@ pub struct Event { #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum EventVariant { - Cast (), - Hit (), - HitAoe (), + Cast { target: Uuid, player: Uuid, x: i8, y: i8 }, + Hit { target: Uuid, player: Uuid, x: i8, y: i8 }, + HitAoe { target: Uuid }, Damage { target: Uuid, amount: usize, mitigation: usize, colour: Colour, display: EventConstruct }, Effect { target: Uuid, effect: Effect, duration: u8, display: EventConstruct }, @@ -265,8 +265,9 @@ impl EventVariant { let combat_text_overlap = 600; // overlap between animation and combat text match self { - EventVariant::Hit() => target_duration - combat_text_overlap, - EventVariant::Cast() => target_delay, + EventVariant::Cast { target: _, x: _, y: _, player: _ } => target_delay, + EventVariant::Hit { target: _, x: _, y: _, player: _ } | + EventVariant::HitAoe { target: _ } => target_duration - combat_text_overlap, _ => combat_text_delay, } } From b405608510fc9ba6be58714b4d10e852dbae17b7 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 6 Dec 2019 20:50:47 +1000 Subject: [PATCH 4/6] set animfocus server side --- client/src/animations.utils.jsx | 15 --------------- client/src/events.jsx | 7 ++++--- core/src/skill.rs | 7 +++++++ 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index e0cc1bdb..630d6b99 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -23,22 +23,7 @@ function getAnimTarget(resolution, account) { }; } -function getFocusTargets(resolution, game, account) { - if (resolution.variant[1] === 'HitAoe') { - 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); - if (resolution.cast.player === account) return playerTeamIds; - return otherTeamIds; - } - - const { source, target } = resolution.cast; - return [source, target]; -} - module.exports = { getAnimSource, getAnimTarget, - getFocusTargets, }; diff --git a/client/src/events.jsx b/client/src/events.jsx index 84753cec..9ca8026d 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -5,7 +5,7 @@ const eachSeries = require('async/eachSeries'); const sample = require('lodash/sample'); const actions = require('./actions'); -const { getAnimSource, getAnimTarget, getFocusTargets } = require('./animations.utils'); +const { getAnimSource, getAnimTarget } = require('./animations.utils'); const { infoToast, errorToast } = require('./utils'); const { tutorialVbox } = require('./tutorial.utils'); const { TIMES } = require('./constants'); @@ -90,18 +90,19 @@ function registerEvents(store) { const newRes = game.events[currentGame.events.length]; return eachSeries(newRes, (r, cb) => { const timeout = r.delay; - const focusTargets = getFocusTargets(r, game, account); - store.dispatch(actions.setAnimFocus(focusTargets)); + store.dispatch(actions.setAnimFocus(r.focus)); if (r.variant[0] === 'Cast') { const animSource = getAnimSource(r, account); store.dispatch(actions.setAnimSource(animSource)); store.dispatch(actions.setAnimText(null)); + setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS); } else if (r.variant[0].includes('Hit')) { const animTarget = getAnimTarget(r, account); store.dispatch(actions.setAnimTarget(animTarget)); store.dispatch(actions.setAnimText(null)); + setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS); } else { store.dispatch(actions.setAnimText(r)); diff --git a/core/src/skill.rs b/core/src/skill.rs index 58313f43..f1dfc78f 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -231,6 +231,7 @@ pub type Disable = Vec; #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Event { pub cast: Cast, + pub focus: Vec, pub variant: EventVariant, pub delay: i64, } @@ -274,8 +275,14 @@ impl EventVariant { pub fn to_event(&self, cast: Cast) -> Event { let delay = self.delay(); + let focus = match self { + EventVariant::HitAoe { target: _ } => vec![cast.source, cast.target], // some tricky multi target here l8r + _ => vec![cast.source, cast.target], + }; + Event { cast, + focus, variant: *self, delay, } From 22ac2b502ebb5a26dba34152a2b59e4ebb4f6513 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 7 Dec 2019 01:31:11 +1000 Subject: [PATCH 5/6] clean up anim functions --- client/src/animations.utils.jsx | 73 +++++++++++++++++++++++---------- client/src/events.jsx | 30 ++------------ 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 630d6b99..5220f3c7 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -1,29 +1,58 @@ -function getAnimSource(resolution, account) { - const { player } = resolution.cast; - const { x, y, target } = resolution.variant[1]; - const animY = y && player === account.id ? -1 : y; +const actions = require('./actions'); +const { TIMES } = require('./constants'); - return { - animation: 'sourceCast', - constructId: target, - direction: { x, y: animY }, - }; +function setAnimations(r, store, account) { + store.dispatch(actions.setAnimFocus(r.focus)); + + if (r.variant[0] === 'Cast') { + store.dispatch(actions.setAnimText(null)); + + const { player } = r.cast; + const { x, y, target } = r.variant[1]; + const animY = y && player === account.id ? -1 : y; + const animSource = { + animation: 'sourceCast', + constructId: target, + direction: { x, y: animY }, + }; + store.dispatch(actions.setAnimSource(animSource)); + + return setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS); + } + + if (r.variant[0].includes('Hit')) { + store.dispatch(actions.setAnimText(null)); + + const { player, skill } = r.cast; + const { x, y, target } = r.variant[1]; + const animY = y && player === account.id ? -1 : y; + const isPlayer = player === account.id; + const animTarget = { + constructId: target, + player: isPlayer, + skill, + direction: { x, y: animY }, + }; + store.dispatch(actions.setAnimTarget(animTarget)); + + return setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS); + } + + return store.dispatch(actions.setAnimText(r)); } -function getAnimTarget(resolution, account) { - const { player, skill } = resolution.cast; - const { x, y, target } = resolution.variant[1]; - const animY = y && player === account.id ? -1 : y; - const isPlayer = player === account.id; - return { - constructId: target, - player: isPlayer, - skill, - direction: { x, y: animY }, - }; +function clearAnimations(store) { + store.dispatch(actions.setAnimSkill(null)); + store.dispatch(actions.setAnimSource(null)); + store.dispatch(actions.setAnimTarget(null)); + store.dispatch(actions.setAnimText(null)); + store.dispatch(actions.setAnimating(false)); + store.dispatch(actions.setGameEffectInfo(null)); + store.dispatch(actions.setAnimFocus(null)); } + module.exports = { - getAnimSource, - getAnimTarget, + setAnimations, + clearAnimations, }; diff --git a/client/src/events.jsx b/client/src/events.jsx index 9ca8026d..57491079 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -5,10 +5,9 @@ const eachSeries = require('async/eachSeries'); const sample = require('lodash/sample'); const actions = require('./actions'); -const { getAnimSource, getAnimTarget } = require('./animations.utils'); +const { setAnimations, clearAnimations } = require('./animations.utils'); const { infoToast, errorToast } = require('./utils'); const { tutorialVbox } = require('./tutorial.utils'); -const { TIMES } = require('./constants'); function registerEvents(store) { function notify(msg) { @@ -90,34 +89,11 @@ function registerEvents(store) { const newRes = game.events[currentGame.events.length]; return eachSeries(newRes, (r, cb) => { const timeout = r.delay; - store.dispatch(actions.setAnimFocus(r.focus)); - - if (r.variant[0] === 'Cast') { - const animSource = getAnimSource(r, account); - store.dispatch(actions.setAnimSource(animSource)); - store.dispatch(actions.setAnimText(null)); - - setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS); - } else if (r.variant[0].includes('Hit')) { - const animTarget = getAnimTarget(r, account); - store.dispatch(actions.setAnimTarget(animTarget)); - store.dispatch(actions.setAnimText(null)); - - setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS); - } else { - store.dispatch(actions.setAnimText(r)); - } + setAnimations(r, store, account); return setTimeout(cb, timeout); }, err => { if (err) return console.error(err); - // clear animation state - store.dispatch(actions.setAnimSkill(null)); - store.dispatch(actions.setAnimSource(null)); - store.dispatch(actions.setAnimTarget(null)); - store.dispatch(actions.setAnimText(null)); - store.dispatch(actions.setAnimating(false)); - store.dispatch(actions.setGameEffectInfo(null)); - store.dispatch(actions.setAnimFocus(null)); + clearAnimations(store); // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); ws.sendGameState(game.id); From e8b725c7bb41dbec02685243b1217c209cca08a6 Mon Sep 17 00:00:00 2001 From: ntr Date: Sat, 7 Dec 2019 10:17:44 +1000 Subject: [PATCH 6/6] len --- client/src/events.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/events.jsx b/client/src/events.jsx index 57491079..5230b256 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -86,7 +86,7 @@ function registerEvents(store) { store.dispatch(actions.setAnimating(true)); store.dispatch(actions.setGameSkillInfo(null)); // stop fetching the game state til animations are done - const newRes = game.events[currentGame.events.length]; + const newRes = game.events[game.events.length - 1]; return eachSeries(newRes, (r, cb) => { const timeout = r.delay; setAnimations(r, store, account);