From 34cfc19ae2447403ca67ac09923b4bb08bbf5154 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 4 Jul 2019 15:00:19 +1000 Subject: [PATCH 1/2] taunt / intercept --- CHANGELOG.md | 6 +- COMBOS.md | 2 +- NODES.md | 2 +- README.md | 2 +- client/src/animations.test.jsx | 2 +- client/src/components/animations.jsx | 5 +- client/src/components/anims/intercept.jsx | 94 ++++++++++++++++++++++ client/src/components/anims/red.circles.js | 81 +++++++++++++++++++ client/src/constants.jsx | 3 +- client/src/test.instance.js | 2 +- client/src/utils.jsx | 2 +- server/src/effect.rs | 4 +- server/src/game.rs | 10 +-- server/src/item.rs | 36 ++++----- server/src/player.rs | 4 +- server/src/skill.rs | 36 ++++----- 16 files changed, 234 insertions(+), 57 deletions(-) create mode 100644 client/src/components/anims/intercept.jsx create mode 100644 client/src/components/anims/red.circles.js diff --git a/CHANGELOG.md b/CHANGELOG.md index af961aa0..6429160b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,7 +109,7 @@ New skill `Hybrid` - Strike Change multipliers T1/T2/T3 (110/130/150 -> 90/110/130) -- Taunt +- Intercept Changed to Buff + RR (was Buff + RG) Now recharges 80% source red damage as red life to target @@ -170,9 +170,9 @@ New skill `Hybrid` Debuff duration increased 2T -> 3T - Switch clutch with taunt + Switch clutch with intercept Clutch now GR + Block (was GR + Buff) - Taunt now GR + Buff + Intercept now GR + Buff No longer self-target only diff --git a/COMBOS.md b/COMBOS.md index 20ccdddf..24232ec2 100644 --- a/COMBOS.md +++ b/COMBOS.md @@ -99,7 +99,7 @@ RB - Invert RR - Parry GG - Reflect BB - Electrify -RG - Taunt +RG - Intercept GB - Life `rename?` RB - Recharge diff --git a/NODES.md b/NODES.md index 076b466e..12ffc0fa 100644 --- a/NODES.md +++ b/NODES.md @@ -22,7 +22,7 @@ Uncommon `Increased damage over time` Rare `gain empower on KO` Rare `cannot be snared` Rare `cannot be silenced` -Rare `cannot be taunted` +Rare `cannot be intercepted` Rare `25% stun for attack` Rare `25% hex for blast` diff --git a/README.md b/README.md index 96116cc9..d32ffb94 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ their fear is a manifestation of the emotions and prejudices they have grown in * rally * physical damage * rend / expose - * taunt + * intercept * martial arts and combat * blocking * evasion and redirection diff --git a/client/src/animations.test.jsx b/client/src/animations.test.jsx index 702f06a4..7a36d1dd 100644 --- a/client/src/animations.test.jsx +++ b/client/src/animations.test.jsx @@ -110,7 +110,7 @@ const SKILLS = [ 'SleepI', 'SnareI', 'StrikeI', - 'TauntI', + 'InterceptI', 'ThrowI', 'TriageI', 'TriageTickI', diff --git a/client/src/components/animations.jsx b/client/src/components/animations.jsx index f4b1e76c..47e7a667 100644 --- a/client/src/components/animations.jsx +++ b/client/src/components/animations.jsx @@ -27,6 +27,7 @@ const Reflect = require('./anims/reflect'); const Chaos = require('./anims/chaos'); const Invert = require('./anims/invert'); const Slay = require('./anims/slay'); +const Intercept = require('./anims/intercept'); const Triage = require('./anims/triage'); const TriageTick = require('./anims/triage.tick'); const Siphon = require('./anims/siphon'); @@ -120,7 +121,7 @@ function animations(props) { case 'TriageTick': return ; case 'Scatter': return false; case 'Hybrid': return ; - case 'Taunt': return false; + case 'Intercept': return ; // Debuff base case 'Debuff': return ; @@ -146,7 +147,7 @@ function animations(props) { case 'Clutch': return false; case 'Electrify': return ; case 'Electrocute': return ; - case 'ElectrocuteTick': return false; + case 'ElectrocuteTick': return ; case 'Parry': return ; case 'Purify': return ; case 'Recharge': return ; diff --git a/client/src/components/anims/intercept.jsx b/client/src/components/anims/intercept.jsx new file mode 100644 index 00000000..4d844538 --- /dev/null +++ b/client/src/components/anims/intercept.jsx @@ -0,0 +1,94 @@ +const preact = require('preact'); +const { Component } = require('preact'); + +const anime = require('animejs').default; + +const { + TIMES, + COLOURS, +} = require('../../constants'); + +class Intercept extends Component { + constructor() { + super(); + this.animations = []; + } + + render() { + return ( + + + + + + + + + + + + ); + } + + componentDidMount() { + this.animations.push(anime({ + targets: ['#intercept'], + opacity: [ + { value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 }, + { value: 0, delay: TIMES.TARGET_DURATION_MS * 0.6, duration: TIMES.TARGET_DURATION_MS * 0.2 }, + ], + easing: 'easeInOutSine', + })); + + this.animations.push(anime({ + targets: ['#intercept'], + transform: [ + `scale(1) ${this.props.player ? 'rotate(180)' : ''}`, + `scale(3) ${this.props.player ? 'rotate(180)' : ''}`, + ], + strokeWidth: 0, + + delay: TIMES.TARGET_DELAY_MS, + duration: TIMES.TARGET_DURATION_MS, + easing: 'easeInSine', + // direction: 'reverse', + })); + + this.animations.push(anime({ + targets: ['#intercept rect'], + y: 96, + delay: TIMES.TARGET_DELAY_MS, + duration: TIMES.TARGET_DURATION_MS, + easing: 'easeInSine', + // direction: 'reverse', + })); + + this.animations.push(anime({ + targets: ['#interceptFilter feTurbulence', '#interceptFilter feDisplacementMap'], + baseFrequency: 2, + scale: 10, + numOctaves: 5, + easing: 'easeOutSine', + + delay: TIMES.TARGET_DELAY_MS, + duration: TIMES.TARGET_DURATION_MS, + })); + } + + // this is necessary because + // skipping / timing / unmounting race conditions + // can cause the animations to cut short, this will ensure the values are reset + // because preact will recycle all these components + componentWillUnmount() { + for (let i = this.animations.length - 1; i >= 0; i--) { + this.animations[i].reset(); + } + } +} + +module.exports = Intercept; diff --git a/client/src/components/anims/red.circles.js b/client/src/components/anims/red.circles.js new file mode 100644 index 00000000..7463afa3 --- /dev/null +++ b/client/src/components/anims/red.circles.js @@ -0,0 +1,81 @@ +const preact = require('preact'); +const { Component } = require('preact'); + +const anime = require('animejs').default; + +const { TIMES } = require('../../constants'); + +class Intercept extends Component { + constructor() { + super(); + this.animations = []; + } + + render({ player }) { + return ( + + + + + + + + + + + + ); + } + + componentDidMount() { + this.animations.push(anime({ + targets: ['#intercept'], + opacity: [ + { value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 }, + { value: 0, delay: TIMES.TARGET_DURATION_MS * 0.6, duration: TIMES.TARGET_DURATION_MS * 0.2 }, + ], + easing: 'easeInOutSine', + })); + + this.animations.push(anime({ + targets: ['#intercept'], + scale: 3, + strokeWidth: 0, + + delay: TIMES.TARGET_DELAY_MS, + duration: TIMES.TARGET_DURATION_MS, + easing: 'easeInOutCubic', + })); + + this.animations.push(anime({ + targets: ['#interceptFilter feTurbulence', '#interceptFilter feDisplacementMap'], + baseFrequency: 2, + scale: 10, + numOctaves: 5, + easing: 'easeOutSine', + + delay: TIMES.TARGET_DELAY_MS, + duration: TIMES.TARGET_DURATION_MS, + })); + } + + // this is necessary because + // skipping / timing / unmounting race conditions + // can cause the animations to cut short, this will ensure the values are reset + // because preact will recycle all these components + componentWillUnmount() { + for (let i = this.animations.length - 1; i >= 0; i--) { + this.animations[i].reset(); + } + } +} + +module.exports = Intercept; diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 3e6ff11b..3798d50e 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -3,7 +3,8 @@ 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_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; +const SOURCE_AND_TARGET_TOTAL_DURATION = 100000; module.exports = { TIMES: { diff --git a/client/src/test.instance.js b/client/src/test.instance.js index 88694d19..df9e7c21 100644 --- a/client/src/test.instance.js +++ b/client/src/test.instance.js @@ -1413,7 +1413,7 @@ function testInstance(uuid) { "cd": null }, { - "skill": "Taunt", + "skill": "Intercept", "self_targeting": false, "cd": 2 }, diff --git a/client/src/utils.jsx b/client/src/utils.jsx index c330c6c5..698ad096 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -349,7 +349,7 @@ const removeTier = skill => { if (skill.includes('Decay')) return 'Decay'; if (skill.includes('Invert')) return 'Invert'; - if (skill.includes('Taunt')) return 'Taunt'; + if (skill.includes('Intercept')) return 'Intercept'; if (skill.includes('Triage')) return 'Triage'; if (skill.includes('Scatter')) return 'Scatter'; if (skill.includes('Haste')) return 'Haste'; diff --git a/server/src/effect.rs b/server/src/effect.rs index a12d91ec..12ae9857 100644 --- a/server/src/effect.rs +++ b/server/src/effect.rs @@ -22,7 +22,7 @@ pub enum Effect { Slow, Snare, Stun, - Taunt, + Intercept, Vulnerable, Silence, Wither, // Reduce green dmg (healing) taken @@ -170,7 +170,7 @@ impl Effect { Effect::Vulnerable => Some(Colour::Red), Effect::Snare => Some(Colour::Red), Effect::Clutch => Some(Colour::Green), - Effect::Taunt => Some(Colour::Green), + Effect::Intercept => Some(Colour::Green), // magic Effect::Hex => Some(Colour::Blue), diff --git a/server/src/game.rs b/server/src/game.rs index 13956f07..a89de93f 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -389,7 +389,7 @@ impl Game { .find(|t| t.constructs.iter().any(|c| c.id == target_construct_id)) .unwrap(); - if let Some(t) = target_player.taunting() { + if let Some(t) = target_player.intercepting() { return vec![t.id]; } @@ -1271,7 +1271,7 @@ mod tests { } #[test] - fn taunt_test() { + fn intercept_test() { let mut game = create_2v2_test_game(); let i_player = game.players[0].clone(); @@ -1282,15 +1282,15 @@ mod tests { let x_construct = x_player.constructs[0].clone(); let y_construct = x_player.constructs[1].clone(); - game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::TauntI); + game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::InterceptI); - while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::TauntI).is_some() { + while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::InterceptI).is_some() { game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); } game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::TauntI).unwrap(); + game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::InterceptI).unwrap(); game.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap(); game.player_ready(i_player.id).unwrap(); diff --git a/server/src/item.rs b/server/src/item.rs index c8570494..428f8954 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -169,9 +169,9 @@ pub enum Item { SiphonI, SiphonII, SiphonIII, - TauntI, - TauntII, - TauntIII, + InterceptI, + InterceptII, + InterceptIII, ThrowI, ThrowII, ThrowIII, @@ -381,9 +381,9 @@ impl Item { Item::ClutchI => Some(Skill::ClutchI), Item::ClutchII => Some(Skill::ClutchII), Item::ClutchIII => Some(Skill::ClutchIII), - Item::TauntI => Some(Skill::TauntI), - Item::TauntII => Some(Skill::TauntII), - Item::TauntIII => Some(Skill::TauntIII), + Item::InterceptI => Some(Skill::InterceptI), + Item::InterceptII => Some(Skill::InterceptII), + Item::InterceptIII => Some(Skill::InterceptIII), Item::ThrowI => Some(Skill::ThrowI), Item::ThrowII => Some(Skill::ThrowII), Item::ThrowIII => Some(Skill::ThrowIII), @@ -761,9 +761,9 @@ impl Item { self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_duration()), - Item::TauntI | - Item::TauntII | - Item::TauntIII => format!("Taunt redirects skills against the team to target, lasts {:?}T.\ + Item::InterceptI | + Item::InterceptII | + Item::InterceptIII => format!("Intercept redirects skills against the team to target, lasts {:?}T.\ Recharges RedLife for {:?} RedPower.", self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().multiplier()), @@ -787,9 +787,9 @@ impl Item { fn combo(&self) -> Vec { match self { - Item::TauntI => vec![Item::Buff, Item::Red, Item::Red], - Item::TauntII => vec![Item::TauntI, Item::TauntI, Item::TauntI], - Item::TauntIII => vec![Item::TauntII, Item::TauntII, Item::TauntII], + Item::InterceptI => vec![Item::Buff, Item::Red, Item::Red], + Item::InterceptII => vec![Item::InterceptI, Item::InterceptI, Item::InterceptI], + Item::InterceptIII => vec![Item::InterceptII, Item::InterceptII, Item::InterceptII], Item::TriageI => vec![Item::Buff, Item::Green, Item::Green], Item::TriageII => vec![Item::TriageI, Item::TriageI, Item::TriageI], Item::TriageIII => vec![Item::TriageII, Item::TriageII, Item::TriageII], @@ -1040,9 +1040,9 @@ impl From for Item { Skill::StrikeII => Item::StrikeII, Skill::StrikeIII => Item::StrikeIII, Skill::Stun => Item::Stun, - Skill::TauntI => Item::TauntI, - Skill::TauntII => Item::TauntII, - Skill::TauntIII => Item::TauntIII, + Skill::InterceptI => Item::InterceptI, + Skill::InterceptII => Item::InterceptII, + Skill::InterceptIII => Item::InterceptIII, Skill::ThrowI => Item::ThrowI, Skill::ThrowII => Item::ThrowII, Skill::ThrowIII => Item::ThrowIII, @@ -1157,9 +1157,9 @@ pub struct Combo { pub fn get_combos() -> Vec { let mut combinations = vec![ - Combo { components: Item::TauntI.combo(), item: Item::TauntI }, - Combo { components: Item::TauntII.combo(), item: Item::TauntII }, - Combo { components: Item::TauntIII.combo(), item: Item::TauntIII }, + Combo { components: Item::InterceptI.combo(), item: Item::InterceptI }, + Combo { components: Item::InterceptII.combo(), item: Item::InterceptII }, + Combo { components: Item::InterceptIII.combo(), item: Item::InterceptIII }, Combo { components: Item::TriageI.combo(), item: Item::TriageI }, Combo { components: Item::TriageII.combo(), item: Item::TriageII }, diff --git a/server/src/player.rs b/server/src/player.rs index e44c7cbd..c3ca2aaa 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -281,9 +281,9 @@ impl Player { return required; } - pub fn taunting(&self) -> Option<&Construct> { + pub fn intercepting(&self) -> Option<&Construct> { self.constructs.iter() - .find(|c| c.affected(Effect::Taunt)) + .find(|c| c.affected(Effect::Intercept)) } pub fn construct_by_id(&mut self, id: Uuid) -> Option<&mut Construct> { diff --git a/server/src/skill.rs b/server/src/skill.rs index 36b6ebde..af425adf 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -243,9 +243,9 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut Skill::StrikeII | Skill::StrikeIII => strike(source, target, resolutions, skill), - Skill::TauntI | - Skill::TauntII | - Skill::TauntIII => taunt(source, target, resolutions, skill), + Skill::InterceptI | + Skill::InterceptII | + Skill::InterceptIII => intercept(source, target, resolutions, skill), Skill::ThrowI | Skill::ThrowII | @@ -618,9 +618,9 @@ pub enum Skill { StrikeII, StrikeIII, - TauntI, - TauntII, - TauntIII, + InterceptI, + InterceptII, + InterceptIII, ThrowI, // no damage stun, adds vulnerable ThrowII, @@ -714,9 +714,9 @@ impl Skill { Skill::ScatterI => 140, Skill::ScatterII => 200, Skill::ScatterIII => 300, - Skill::TauntI => 80, - Skill::TauntII => 110, - Skill::TauntIII => 150, + Skill::InterceptI => 80, + Skill::InterceptII => 110, + Skill::InterceptIII => 150, Skill::TriageTickI => 75, Skill::TriageTickII => 110, Skill::TriageTickIII => 140, @@ -869,9 +869,9 @@ impl Skill { meta: Some(EffectMeta::Skill(Skill::BashIII)), tick: None}], Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], - Skill::TauntI => vec![ConstructEffect {effect: Effect::Taunt, duration: 2, meta: None, tick: None}], - Skill::TauntII => vec![ConstructEffect {effect: Effect::Taunt, duration: 3, meta: None, tick: None}], - Skill::TauntIII => vec![ConstructEffect {effect: Effect::Taunt, duration: 4, meta: None, tick: None}], + Skill::InterceptI => vec![ConstructEffect {effect: Effect::Intercept, duration: 2, meta: None, tick: None}], + Skill::InterceptII => vec![ConstructEffect {effect: Effect::Intercept, duration: 3, meta: None, tick: None}], + Skill::InterceptIII => vec![ConstructEffect {effect: Effect::Intercept, duration: 4, meta: None, tick: None}], Skill::TriageI => vec![ConstructEffect {effect: Effect::Triage, duration: 2, meta: Some(EffectMeta::Skill(Skill::TriageTickI)), tick: None}], @@ -1001,9 +1001,9 @@ impl Skill { Skill::ClutchII => Some(2), Skill::ClutchIII => Some(3), - Skill::TauntI => Some(2), - Skill::TauntII => Some(2), - Skill::TauntIII => Some(2), + Skill::InterceptI => Some(2), + Skill::InterceptII => Some(2), + Skill::InterceptIII => Some(2), Skill::ElectrifyI =>Some(1), Skill::ElectrifyII =>Some(1), @@ -1287,12 +1287,12 @@ fn clutch(source: &mut Construct, target: &mut Construct, mut results: Resolutio return results; } -fn taunt(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { +fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { let red_amount = source.red_power().pct(skill.multiplier()); results.push(Resolution::new(source, target).event(target.recharge(skill, red_amount, 0))); - let taunt = skill.effect()[0]; - results.push(Resolution::new(source, target).event(target.add_effect(skill, taunt)).stages(LogStages::PostOnly)); + let intercept = skill.effect()[0]; + results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept)).stages(LogStages::PostOnly)); return results; } From d7b54f080cf9375dcb256cf69c37de8d2a49002e Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 4 Jul 2019 15:03:02 +1000 Subject: [PATCH 2/2] oops constant --- client/src/constants.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 3798d50e..3e6ff11b 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -3,8 +3,7 @@ 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_AND_TARGET_TOTAL_DURATION = 100000; +const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; module.exports = { TIMES: {