diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index c74185fd..38da27d5 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -86,7 +86,7 @@ function getSequence(resolution) { case 'EndPost': return ['END_SKILL', 'POST_SKILL']; case 'EndOnly': return ['END_SKILL']; case 'PostOnly': return ['POST_SKILL']; - case 'None': return []; + case 'NoStages': return []; default: return ['START_SKILL', 'END_SKILL', 'POST_SKILL']; } } diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx index 12c308a5..f4f778e1 100644 --- a/client/src/components/game.ctrl.jsx +++ b/client/src/components/game.ctrl.jsx @@ -10,11 +10,13 @@ const GameCtrlTopButtons = require('./game.ctrl.btns.top'); const addState = connect( function receiveState(state) { const { + animating, game, account, } = state; return { + animating, game, account, }; @@ -23,6 +25,7 @@ const addState = connect( function Controls(args) { const { + animating, account, game, } = args; @@ -31,10 +34,10 @@ function Controls(args) { const opponent = game.players.find(t => t.id !== account.id); const player = game.players.find(t => t.id === account.id); - const zero = Date.parse(game.phase_start); - const now = Date.now(); + const now = animating ? zero : Date.now(); const end = Date.parse(game.phase_end); + const timerPct = game.phase_end ? ((now - zero) / (end - zero) * 100) : 100; diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 849d9162..97199bb5 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -1,10 +1,10 @@ const preact = require('preact'); -const SOURCE_DURATION_MS = 1000; -const TARGET_DELAY_MS = 500; -const TARGET_DURATION_MS = 1500; -const POST_SKILL_DURATION_MS = 1000; -const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; +const SOURCE_DURATION_MS = 1000; // Time for SOURCE ONLY +const TARGET_DELAY_MS = 500; // Used for Source + Target +const TARGET_DURATION_MS = 1500; // Time for TARGET ONLY +const POST_SKILL_DURATION_MS = 1000; // Time for all POST +const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; // SOURCE + TARGET time module.exports = { TIMES: { diff --git a/client/src/events.jsx b/client/src/events.jsx index 5b9aba1f..6bc39110 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -82,10 +82,14 @@ function registerEvents(store) { } if (sequence.includes('POST_SKILL') && text) { // timeout to prevent text classes from being added too soon - setTimeout( - () => store.dispatch(actions.setAnimText(text)), - timeout - TIMES.POST_SKILL_DURATION_MS - ); + if (timeout === TIMES.POST_SKILL_DURATION_MS) { + store.dispatch(actions.setAnimText(text)); + } else { + setTimeout( + () => store.dispatch(actions.setAnimText(text)), + timeout - TIMES.POST_SKILL_DURATION_MS + ); + } } return setTimeout(() => { store.dispatch(actions.setAnimSkill(null)); diff --git a/server/src/game.rs b/server/src/game.rs index b96d15ad..8c1f2389 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -161,14 +161,12 @@ impl Game { self.skill_phase_start(0) } - fn skill_phase_start(mut self, num_resolutions: usize) -> Game { - let resolution_animation_ms = num_resolutions as i64 * 2500; - + fn skill_phase_start(mut self, resolution_time: i64) -> Game { self.phase_start = Utc::now() - .checked_add_signed(Duration::milliseconds(resolution_animation_ms)) + .checked_add_signed(Duration::milliseconds(resolution_time)) .expect("could not set phase start"); - self.phase_end = self.time_control.game_phase_end(resolution_animation_ms); + self.phase_end = self.time_control.game_phase_end(resolution_time); for player in self.players.iter_mut() { if player.skills_required() == 0 { @@ -428,13 +426,12 @@ impl Game { // temp vec of this round's resolving skills // because need to check cooldown use before pushing them into the complete list let mut casts = vec![]; - let mut turn_events = 0; - + let mut resolution_delay = 0; while let Some(cast) = self.stack.pop() { // info!("{:} casts ", cast); let mut resolutions = resolution_steps(&cast, &mut self); - turn_events += resolutions.len(); + resolution_delay = resolutions.iter().fold(resolution_delay, |acc, r| acc + r.clone().get_delay()); self.resolved.append(&mut resolutions); // while let Some(resolution) = resolutions.pop() { @@ -460,7 +457,7 @@ impl Game { return self.finish() } - self.skill_phase_start(turn_events) + self.skill_phase_start(resolution_delay) } fn progress_durations(&mut self, resolved: &Vec) -> &mut Game { diff --git a/server/src/skill.rs b/server/src/skill.rs index 44cead79..968eb91f 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -415,7 +415,7 @@ pub enum EventStages { EndPost, // Skip Anim Anim EndOnly, // Skip Anim Skip PostOnly, // Skip Skip Anim - None, // Skip Skip Skip + NoStages, // Skip Skip Skip } #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] @@ -455,6 +455,25 @@ impl Resolution { self.stages = s; self } + + pub fn get_delay(self) -> i64 { + let source_duration = 1000; // Time for SOURCE ONLY + let target_delay = 500; // Used for Source + Target + let target_duration = 1500; // Time for TARGET ONLY + let post_skill = 1000; // Time for all POST + let source_and_target_total = target_delay + target_duration; // SOURCE + TARGET time + + match self.stages { + EventStages::AllStages => source_and_target_total + post_skill, // Anim Anim Anim + EventStages::StartEnd => source_and_target_total, // Anim Anim Skip + EventStages::StartPost => source_duration + post_skill, // Anim Skip Anim + EventStages::StartOnly => source_duration, // Anim Skip Skip + EventStages::EndPost => target_duration + post_skill, // Skip Anim Anim + EventStages::EndOnly => target_duration, // Skip Anim Skip + EventStages::PostOnly => post_skill, // Skip Skip Anim + EventStages::NoStages => 0, // Skip Skip Skip + } + } } @@ -1363,7 +1382,7 @@ fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resoluti let stages = match e { Event::Recharge { red, blue, skill: _ } => { if red > 0 || blue > 0 { EventStages::PostOnly } - else { EventStages::None } + else { EventStages::NoStages } } _ => panic!("not recharge") }; @@ -1382,7 +1401,7 @@ fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolu let stages = match e { Event::Recharge { red, blue, skill: _ } => { if red > 0 || blue > 0 { EventStages::PostOnly } - else { EventStages::None } + else { EventStages::NoStages } } _ => panic!("not recharge") }; @@ -1606,7 +1625,7 @@ fn electrocute(source: &mut Construct, target: &mut Construct, mut results: Reso let electrocute = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); results.push(Resolution::new(source, target) .event(target.add_effect(skill, electrocute)) - .stages(EventStages::EndPost)); + .stages(EventStages::PostOnly)); match skip_tick { @@ -1674,7 +1693,7 @@ fn reflect(source: &mut Construct, target: &mut Construct, mut results: Resoluti let stages = match e { Event::Recharge { red, blue, skill: _ } => { if red > 0 || blue > 0 { EventStages::PostOnly } - else { EventStages::None } + else { EventStages::NoStages } } _ => panic!("not recharge") };