parry -> counter

This commit is contained in:
ntr 2019-07-04 22:33:15 +10:00
parent 1a3260a359
commit 9b250d4b7d
14 changed files with 110 additions and 100 deletions

View File

@ -93,11 +93,11 @@ New skill `Hybrid`
- Heal
Changed multiplier 120% -> 130%
- Parry
- Counter
Changed duration 1T -> 2T
Changed cooldown 0T -> 2T
Now recharges 110% red damage as red life
Riposte multiplier reduced 100% -> 70%
CounterAttack multiplier reduced 100% -> 70%
- Siphon
Multiplier changed 30% -> 40%

View File

@ -96,7 +96,7 @@ RB - Invert
# Block Base #
RR - Parry
RR - Counter
GG - Reflect
BB - Electrify
RG - Intercept

View File

@ -56,7 +56,7 @@ In your player Construct #1 has `Strike`, Construct #2 has `Slay` and `Heal`, Co
- Buy 2 Basic Damage Spec (item)
- Combine 2 Red + 'Stun' -> Strangle
- Combine 2 Red + 'Block' -> Parry
- Combine 2 Red + 'Block' -> Counter
Construct #1 -> Give 'Stun' & 'Strangle' -> Strike, Stun, Strangle + 2 x Red Damage Spec (10R)
Construct #2 -> 'No change' -> Heal (2G)

View File

@ -80,27 +80,28 @@ const SKILLS = [
'BlastI',
'ChaosI',
'ClutchI',
'ElectrifyI',
'ElectrocuteI',
'ElectrocuteTickI',
'CounterAttackI',
'CounterI',
'CurseI',
'DecayI',
'DecayTickI',
'ElectrifyI',
'ElectrocuteI',
'ElectrocuteTickI',
'HasteI',
'HasteStrike',
'HatredI',
'HealI',
'HexI',
'HatredI',
'HostilityI',
'HybridBlast',
'HybridI',
'InterceptI',
'InvertI',
'ParryI',
'PurgeI',
'PurifyI',
'RechargeI',
'ReflectI',
'RiposteI',
'RuinI',
'ScatterI',
'SilenceI',
@ -110,7 +111,6 @@ const SKILLS = [
'SleepI',
'SnareI',
'StrikeI',
'InterceptI',
'ThrowI',
'TriageI',
'TriageTickI',

View File

@ -22,7 +22,7 @@ const Hex = require('./anims/hex');
const Hybrid = require('./anims/hybrid');
const Intercept = require('./anims/intercept');
const Invert = require('./anims/invert');
const Parry = require('./anims/parry');
const Counter = require('./anims/counter');
const Purify = require('./anims/purify');
const Recharge = require('./anims/recharge');
const Refl = require('./anims/reflect');
@ -150,7 +150,7 @@ function animations(props) {
case 'Electrify': return <Electrify />;
case 'Electrocute': return <Electrocute />;
case 'ElectrocuteTick': return <Electrocute />;
case 'Parry': return <Parry team={player} />;
case 'Counter': return <Counter team={player} />;
case 'Purify': return <Purify team={player} />;
case 'Recharge': return <Recharge team={player} />;
case 'Reflect': return <Refl team={player} />;

View File

@ -4,7 +4,7 @@ const anime = require('animejs').default;
const { TIMES } = require('../../constants');
class Parry extends Component {
class Counter extends Component {
constructor() {
super();
this.animations = [];
@ -15,25 +15,25 @@ class Parry extends Component {
<svg
class='skill-animation red'
version="1.1"
id="parry"
id="counter"
xmlns="http://www.w3.org/2000/svg"
style={{ transform: team ? 'rotate3d(1, 0, 0, 180deg)' : '' }}
viewBox="0 0 256 256">
<filter id='parryFilter'>
<filter id='counterFilter'>
<feTurbulence type="turbulence" baseFrequency="0" numOctaves="1" result="turbulence"></feTurbulence>
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="1" xChannelSelector="R" yChannelSelector="G"></feDisplacementMap>
</filter>
<polyline
points='128,168 80,240 176,240 128,168'
style={{ filter: 'url("#parryFilter")' }}
style={{ filter: 'url("#counterFilter")' }}
/>
<polyline
points='176,240 212,216 128,96 44,216 80,240'
style={{ filter: 'url("#parryFilter")' }}
style={{ filter: 'url("#counterFilter")' }}
/>
<polyline
points='212,216 248,192 128,24 8,192 44,216'
style={{ filter: 'url("#parryFilter")' }}
style={{ filter: 'url("#counterFilter")' }}
/>
</svg>
);
@ -41,7 +41,7 @@ class Parry extends Component {
componentDidMount() {
this.animations.push(anime({
targets: ['#parry'],
targets: ['#counter'],
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 },
@ -50,7 +50,7 @@ class Parry extends Component {
}));
this.animations.push(anime({
targets: ['#parry'],
targets: ['#counter'],
rotateX: 180,
delay: TIMES.TARGET_DELAY_MS * 2,
duration: TIMES.TARGET_DURATION_MS / 2,
@ -58,7 +58,7 @@ class Parry extends Component {
}));
this.animations.push(anime({
targets: ['#parryFilter feTurbulence', '#parryFilter feDisplacementMap'],
targets: ['#counterFilter feTurbulence', '#counterFilter feDisplacementMap'],
baseFrequency: 2,
scale: 10,
numOctaves: 5,
@ -80,4 +80,4 @@ class Parry extends Component {
}
}
module.exports = Parry;
module.exports = Counter;

View File

@ -48,8 +48,8 @@ class Intercept extends Component {
this.animations.push(anime({
targets: ['#intercept'],
transform: [
`scale(1) ${this.props.player ? 'rotate(180)' : ''}`,
`scale(3) ${this.props.player ? 'rotate(180)' : ''}`,
`scale(1 1) ${this.props.player ? 'rotate(180)' : ''}`,
`scale(30 3) ${this.props.player ? 'rotate(180)' : ''}`,
],
strokeWidth: 0,

View File

@ -1,6 +1,7 @@
const preact = require('preact');
const { Component } = require('preact');
const { connect } = require('preact-redux');
const anime = require('animejs').default;
const throttle = require('lodash/throttle');
@ -16,6 +17,7 @@ class TargetSvg extends Component {
this.onResize = throttle(() => {
const svg = document.getElementById('targeting');
const { width, height } = svg.getBoundingClientRect();
const path = document.querySelector('#targeting path');
this.setState({ width, height });
}, 500);
}
@ -104,6 +106,14 @@ class TargetSvg extends Component {
window.addEventListener('resize', this.onResize);
this.onResize();
setTimeout(this.onResize, 50);
// anime({
// targets: ['#targeting path'],
// strokeDashoffset: [anime.setDashoffset, 0],
// duration: 1000,
// easing: 'linear',
// loop: true,
// delay: anime.stagger(3000),
// });
}
componentWillUnmount() {

View File

@ -98,7 +98,7 @@ function testInstance(uuid) {
"cd": 2
},
{
"skill": "Parry",
"skill": "Counter",
"self_targeting": true,
"cd": 2
}
@ -1707,7 +1707,7 @@ function testInstance(uuid) {
"cd": null
},
{
"skill": "Parry",
"skill": "Counter",
"self_targeting": true,
"cd": 2
}
@ -4010,7 +4010,7 @@ function testInstance(uuid) {
"cd": null
},
{
"skill": "Parry",
"skill": "Counter",
"self_targeting": true,
"cd": 2
},

View File

@ -358,7 +358,7 @@ const removeTier = skill => {
if (skill.includes('Hybrid')) return 'Hybrid';
if (skill.includes('Amplify')) return 'Amplify';
if (skill.includes('Parry')) return 'Parry';
if (skill.includes('Counter')) return 'Counter';
if (skill.includes('Purify')) return 'Purify';
if (skill.includes('Electrify')) return 'Electrify';
if (skill.includes('Electrocute')) return 'Electrocute';

View File

@ -16,7 +16,7 @@ pub enum Effect {
Hex,
Hybrid,
Invert,
Parry,
Counter,
Purge,
Reflect,
Slow,
@ -66,7 +66,7 @@ pub enum Effect {
impl Effect {
pub fn immune(&self, skill: Skill) -> bool {
match self {
Effect::Parry => match skill {
Effect::Counter => match skill {
Skill::Attack => true,
Skill::Stun => true,
_ => skill.colours().contains(&Colour::Red)
@ -166,7 +166,7 @@ impl Effect {
Effect::Stun => Some(Colour::Red),
Effect::Block => Some(Colour::Green),
Effect::Buff => Some(Colour::Green),
Effect::Parry => Some(Colour::Green),
Effect::Counter => Some(Colour::Green),
Effect::Vulnerable => Some(Colour::Red),
Effect::Snare => Some(Colour::Red),
Effect::Clutch => Some(Colour::Green),

View File

@ -854,7 +854,7 @@ mod tests {
.learn(Skill::Stun)
.learn(Skill::Attack)
.learn(Skill::Block)
.learn(Skill::ParryI)
.learn(Skill::CounterI)
.learn(Skill::SiphonI)
.learn(Skill::AmplifyI)
.learn(Skill::Stun)
@ -866,7 +866,7 @@ mod tests {
.learn(Skill::Stun)
.learn(Skill::Attack)
.learn(Skill::Block)
.learn(Skill::ParryI)
.learn(Skill::CounterI)
.learn(Skill::SiphonI)
.learn(Skill::AmplifyI)
.learn(Skill::Stun)
@ -1074,7 +1074,7 @@ mod tests {
}
#[test]
fn parry_test() {
fn counter_test() {
let mut game = create_test_game();
let x_player = game.players[0].clone();
@ -1087,11 +1087,11 @@ mod tests {
game.construct_by_id(y_construct.id).unwrap().reduce_cooldowns();
}
while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::ParryI).is_some() {
while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::CounterI).is_some() {
game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns();
}
game.add_skill(x_player.id, x_construct.id, None, Skill::ParryI).unwrap();
game.add_skill(x_player.id, x_construct.id, None, Skill::CounterI).unwrap();
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Stun).unwrap();
game.player_ready(x_player.id).unwrap();
@ -1099,10 +1099,10 @@ mod tests {
game = game.resolve_phase_start();
// should not be stunned because of parry
// should not be stunned because of counter
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false);
// riposte
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (1024 - x_construct.red_power().pct(Skill::RiposteI.multiplier())));
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (1024 - x_construct.red_power().pct(Skill::CounterAttackI.multiplier())));
}
#[test]

View File

@ -130,9 +130,9 @@ pub enum Item {
InvertI,
InvertII,
InvertIII,
ParryI,
ParryII,
ParryIII,
CounterI,
CounterII,
CounterIII,
PurgeI,
PurgeII,
PurgeIII,
@ -335,9 +335,9 @@ impl Item {
Item::InvertI => Some(Skill::InvertI),
Item::InvertII => Some(Skill::InvertII),
Item::InvertIII => Some(Skill::InvertIII),
Item::ParryI => Some(Skill::ParryI),
Item::ParryII => Some(Skill::ParryII),
Item::ParryIII => Some(Skill::ParryIII),
Item::CounterI => Some(Skill::CounterI),
Item::CounterII => Some(Skill::CounterII),
Item::CounterIII => Some(Skill::CounterIII),
Item::PurgeI => Some(Skill::PurgeI),
Item::PurgeII => Some(Skill::PurgeII),
Item::PurgeIII => Some(Skill::PurgeIII),
@ -668,9 +668,9 @@ impl Item {
"Reverse healing into damage and damage into healing.
Any excess red or blue damage is converted into shield recharge."),
Item::ParryI |
Item::ParryII |
Item::ParryIII => format!("{} {:?}% red power and blocks red skills for {:?}T. {} {:?}% red power.",
Item::CounterI |
Item::CounterII |
Item::CounterIII => format!("{} {:?}% red power and blocks red skills for {:?}T. {} {:?}% red power.",
"Self targetting skill. Recharges RedLife for",
self.into_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration(),
@ -825,9 +825,9 @@ impl Item {
Item::InvertII => vec![Item::InvertI, Item::InvertI, Item::InvertI],
Item::InvertIII => vec![Item::InvertII, Item::InvertII, Item::InvertII],
Item::ParryI => vec![Item::Block, Item::Red, Item::Red],
Item::ParryII => vec![Item::ParryI, Item::ParryI, Item::ParryI],
Item::ParryIII => vec![Item::ParryII, Item::ParryII, Item::ParryII], // Add red recharge
Item::CounterI => vec![Item::Block, Item::Red, Item::Red],
Item::CounterII => vec![Item::CounterI, Item::CounterI, Item::CounterI],
Item::CounterIII => vec![Item::CounterII, Item::CounterII, Item::CounterII], // Add red recharge
Item::PurifyI => vec![Item::Block, Item::Green, Item::Green],
Item::PurifyII => vec![Item::PurifyI, Item::PurifyI, Item::PurifyI],
Item::PurifyIII => vec![Item::PurifyII, Item::PurifyII, Item::PurifyII],
@ -997,9 +997,9 @@ impl From<Skill> for Item {
Skill::InvertI => Item::InvertI,
Skill::InvertII => Item::InvertII,
Skill::InvertIII => Item::InvertIII,
Skill::ParryI => Item::ParryI,
Skill::ParryII => Item::ParryII,
Skill::ParryIII => Item::ParryIII,
Skill::CounterI => Item::CounterI,
Skill::CounterII => Item::CounterII,
Skill::CounterIII => Item::CounterIII,
Skill::PurgeI => Item::PurgeI,
Skill::PurgeII => Item::PurgeII,
Skill::PurgeIII => Item::PurgeIII,
@ -1065,9 +1065,9 @@ impl From<Skill> for Item {
Skill::HatredIII => Item::HostilityIII,
Skill::HasteStrike => Item::HasteI,
Skill::HybridBlast => Item::HybridI,
Skill::RiposteI => Item::ParryI,
Skill::RiposteII => Item::ParryII,
Skill::RiposteIII => Item::ParryIII,
Skill::CounterAttackI => Item::CounterI,
Skill::CounterAttackII => Item::CounterII,
Skill::CounterAttackIII => Item::CounterIII,
Skill::SiphonTickI => Item::SiphonI,
Skill::SiphonTickII => Item::SiphonII,
Skill::SiphonTickIII => Item::SiphonIII,
@ -1205,9 +1205,9 @@ pub fn get_combos() -> Vec<Combo> {
Combo { components: Item::InvertII.combo(), item: Item::InvertII },
Combo { components: Item::InvertIII.combo(), item: Item::InvertIII },
Combo { components: Item::ParryI.combo(), item: Item::ParryI },
Combo { components: Item::ParryII.combo(), item: Item::ParryII },
Combo { components: Item::ParryIII.combo(), item: Item::ParryIII },
Combo { components: Item::CounterI.combo(), item: Item::CounterI },
Combo { components: Item::CounterII.combo(), item: Item::CounterII },
Combo { components: Item::CounterIII.combo(), item: Item::CounterIII },
Combo { components: Item::PurifyI.combo(), item: Item::PurifyI },
Combo { components: Item::PurifyII.combo(), item: Item::PurifyII },
Combo { components: Item::PurifyIII.combo(), item: Item::PurifyIII },

View File

@ -188,9 +188,9 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut
Skill::InvertII |
Skill::InvertIII => invert(source, target, resolutions, skill),
Skill::ParryI |
Skill::ParryII |
Skill::ParryIII => parry(source, target, resolutions, skill),
Skill::CounterI |
Skill::CounterII |
Skill::CounterIII => counter(source, target, resolutions, skill),
Skill::PurgeI |
Skill::PurgeII |
@ -275,9 +275,9 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut
Skill::HatredII |
Skill::HatredIII => panic!("should only trigger from hatred"),
Skill::HybridBlast => panic!("should only trigger from hybrid"),
Skill::RiposteI |
Skill::RiposteII |
Skill::RiposteIII => panic!("should only trigger from parry"),
Skill::CounterAttackI |
Skill::CounterAttackII |
Skill::CounterAttackIII => panic!("should only trigger from counter"),
// Not used
@ -322,15 +322,15 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
}
},
Event::Immunity { skill: _, immunity } => match immunity.contains(&Effect::Parry) {
Event::Immunity { skill: _, immunity } => match immunity.contains(&Effect::Counter) {
true => {
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
.find(|e| e.effect == Effect::Parry).unwrap().clone();
.find(|e| e.effect == Effect::Counter).unwrap().clone();
match meta {
Some(EffectMeta::Skill(s)) => {
resolutions = riposte(&mut target, &mut source, resolutions, s);
},
_ => panic!("no parry skill"),
_ => panic!("no counter skill"),
};
},
@ -560,9 +560,9 @@ pub enum Skill {
InvertII,
InvertIII,
ParryI, // avoid all damage
ParryII,
ParryIII,
CounterI, // avoid all damage
CounterII,
CounterIII,
PurgeI,
PurgeII,
PurgeIII,
@ -579,9 +579,9 @@ pub enum Skill {
ReflectII,
ReflectIII,
RiposteI,
RiposteII,
RiposteIII,
CounterAttackI,
CounterAttackII,
CounterAttackIII,
RuinI,
RuinII,
@ -669,12 +669,12 @@ impl Skill {
Skill::ElectrocuteTickII => 100,
Skill::ElectrocuteTickIII => 130,
Skill::ParryI => 110,
Skill::ParryII => 145,
Skill::ParryIII => 200,
Skill::RiposteI => 70,
Skill::RiposteII => 95,
Skill::RiposteIII => 120,
Skill::CounterI => 110,
Skill::CounterII => 145,
Skill::CounterIII => 200,
Skill::CounterAttackI => 70,
Skill::CounterAttackII => 95,
Skill::CounterAttackIII => 120,
Skill::PurifyI => 45, //Green dmg (heal)
Skill::PurifyII => 70,
@ -812,12 +812,12 @@ impl Skill {
Skill::InvertII => vec![ConstructEffect {effect: Effect::Invert, duration: 3, meta: None, tick: None}],
Skill::InvertIII => vec![ConstructEffect {effect: Effect::Invert, duration: 4, meta: None, tick: None}],
Skill::ParryI => vec![ConstructEffect {effect: Effect::Parry, duration: 2,
meta: Some(EffectMeta::Skill(Skill::RiposteI)), tick: None}],
Skill::ParryII => vec![ConstructEffect {effect: Effect::Parry, duration: 2,
meta: Some(EffectMeta::Skill(Skill::RiposteII)), tick: None}],
Skill::ParryIII => vec![ConstructEffect {effect: Effect::Parry, duration: 2,
meta: Some(EffectMeta::Skill(Skill::RiposteIII)), tick: None}],
Skill::CounterI => vec![ConstructEffect {effect: Effect::Counter, duration: 2,
meta: Some(EffectMeta::Skill(Skill::CounterAttackI)), tick: None}],
Skill::CounterII => vec![ConstructEffect {effect: Effect::Counter, duration: 2,
meta: Some(EffectMeta::Skill(Skill::CounterAttackII)), tick: None}],
Skill::CounterIII => vec![ConstructEffect {effect: Effect::Counter, duration: 2,
meta: Some(EffectMeta::Skill(Skill::CounterAttackIII)), tick: None}],
Skill::ReflectI => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }],
Skill::ReflectII => vec![ConstructEffect {effect: Effect::Reflect, duration: 2, meta: None, tick: None }],
@ -895,9 +895,9 @@ impl Skill {
Skill::StrikeII => None,
Skill::StrikeIII => None,
Skill::Block => None, // reduce damage
Skill::ParryI |
Skill::ParryII |
Skill::ParryIII => Some(2), // avoid all damage
Skill::CounterI |
Skill::CounterII |
Skill::CounterIII => Some(2), // avoid all damage
Skill::SnareI => Some(2),
Skill::SnareII => Some(2),
@ -1020,9 +1020,9 @@ impl Skill {
// Trigger
Skill::HybridBlast |
Skill::HasteStrike |
Skill::RiposteI |
Skill::RiposteII |
Skill::RiposteIII | // parry
Skill::CounterAttackI |
Skill::CounterAttackII |
Skill::CounterAttackIII | // counter
Skill::ElectrocuteI |
Skill::ElectrocuteII |
Skill::ElectrocuteIII |
@ -1125,9 +1125,9 @@ impl Skill {
Skill::ClutchI |
Skill::ClutchII |
Skill::ClutchIII |
Skill::ParryI |
Skill::ParryII |
Skill::ParryIII => true,
Skill::CounterI |
Skill::CounterII |
Skill::CounterIII => true,
_ => false,
}
@ -1159,9 +1159,9 @@ impl Skill {
Skill::InvertI |
Skill::InvertII |
Skill::InvertIII |
Skill::ParryI |
Skill::ParryII |
Skill::ParryIII |
Skill::CounterI |
Skill::CounterII |
Skill::CounterIII |
Skill::PurifyI |
Skill::PurifyII |
Skill::PurifyIII |
@ -1318,7 +1318,7 @@ fn buff(source: &mut Construct, target: &mut Construct, mut results: Resolutions
return results;
}
fn parry(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
fn counter(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))