taunt / intercept

This commit is contained in:
ntr 2019-07-04 15:00:19 +10:00
parent 28abca3ed8
commit 34cfc19ae2
16 changed files with 234 additions and 57 deletions

View File

@ -109,7 +109,7 @@ New skill `Hybrid`
- Strike - Strike
Change multipliers T1/T2/T3 (110/130/150 -> 90/110/130) Change multipliers T1/T2/T3 (110/130/150 -> 90/110/130)
- Taunt - Intercept
Changed to Buff + RR (was Buff + RG) Changed to Buff + RR (was Buff + RG)
Now recharges 80% source red damage as red life to target Now recharges 80% source red damage as red life to target
@ -170,9 +170,9 @@ New skill `Hybrid`
Debuff duration increased 2T -> 3T Debuff duration increased 2T -> 3T
Switch clutch with taunt Switch clutch with intercept
Clutch now GR + Block (was GR + Buff) Clutch now GR + Block (was GR + Buff)
Taunt now GR + Buff Intercept now GR + Buff
No longer self-target only No longer self-target only

View File

@ -99,7 +99,7 @@ RB - Invert
RR - Parry RR - Parry
GG - Reflect GG - Reflect
BB - Electrify BB - Electrify
RG - Taunt RG - Intercept
GB - Life `rename?` GB - Life `rename?`
RB - Recharge RB - Recharge

View File

@ -22,7 +22,7 @@ Uncommon `Increased damage over time`
Rare `gain empower on KO` Rare `gain empower on KO`
Rare `cannot be snared` Rare `cannot be snared`
Rare `cannot be silenced` Rare `cannot be silenced`
Rare `cannot be taunted` Rare `cannot be intercepted`
Rare `25% stun for attack` Rare `25% stun for attack`
Rare `25% hex for blast` Rare `25% hex for blast`

View File

@ -46,7 +46,7 @@ their fear is a manifestation of the emotions and prejudices they have grown in
* rally * rally
* physical damage * physical damage
* rend / expose * rend / expose
* taunt * intercept
* martial arts and combat * martial arts and combat
* blocking * blocking
* evasion and redirection * evasion and redirection

View File

@ -110,7 +110,7 @@ const SKILLS = [
'SleepI', 'SleepI',
'SnareI', 'SnareI',
'StrikeI', 'StrikeI',
'TauntI', 'InterceptI',
'ThrowI', 'ThrowI',
'TriageI', 'TriageI',
'TriageTickI', 'TriageTickI',

View File

@ -27,6 +27,7 @@ const Reflect = require('./anims/reflect');
const Chaos = require('./anims/chaos'); const Chaos = require('./anims/chaos');
const Invert = require('./anims/invert'); const Invert = require('./anims/invert');
const Slay = require('./anims/slay'); const Slay = require('./anims/slay');
const Intercept = require('./anims/intercept');
const Triage = require('./anims/triage'); const Triage = require('./anims/triage');
const TriageTick = require('./anims/triage.tick'); const TriageTick = require('./anims/triage.tick');
const Siphon = require('./anims/siphon'); const Siphon = require('./anims/siphon');
@ -120,7 +121,7 @@ function animations(props) {
case 'TriageTick': return <TriageTick />; case 'TriageTick': return <TriageTick />;
case 'Scatter': return false; case 'Scatter': return false;
case 'Hybrid': return <Hybrid />; case 'Hybrid': return <Hybrid />;
case 'Taunt': return false; case 'Intercept': return <Intercept player={player} />;
// Debuff base // Debuff base
case 'Debuff': return <Debuff />; case 'Debuff': return <Debuff />;
@ -146,7 +147,7 @@ function animations(props) {
case 'Clutch': return false; case 'Clutch': return false;
case 'Electrify': return <Electrify />; case 'Electrify': return <Electrify />;
case 'Electrocute': return <Electrocute />; case 'Electrocute': return <Electrocute />;
case 'ElectrocuteTick': return false; case 'ElectrocuteTick': return <Electrocute />;
case 'Parry': return <Parry team={player} />; case 'Parry': return <Parry team={player} />;
case 'Purify': return <Purify team={player} />; case 'Purify': return <Purify team={player} />;
case 'Recharge': return <Recharge team={player} />; case 'Recharge': return <Recharge team={player} />;

View File

@ -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 (
<svg
class='skill-animation'
version="1.1"
id="intercept"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 128 128">
<filter id='interceptFilter'>
<feTurbulence type="turbulence" baseFrequency="0" numOctaves="1" result="turbulence"></feTurbulence>
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="1" xChannelSelector="R" yChannelSelector="G"></feDisplacementMap>
</filter>
<g filter="url(#interceptFilter)" stroke="none" fill={COLOURS.RED} >
<rect x='32' y="64" width="64" height="2" />
<rect x='48' y="32" width="32" height="2" />
<rect x='56' y="16" width="16" height="2" />
</g>
</svg>
);
}
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;

View File

@ -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 (
<svg
class='skill-animation red'
version="1.1"
id="intercept"
xmlns="http://www.w3.org/2000/svg"
style={{
transform: player ? 'rotate3d(1, 0, 0, 180deg)' : '',
}}
viewBox="0 0 128 128">
<filter id='interceptFilter'>
<feTurbulence type="turbulence" baseFrequency="0" numOctaves="1" result="turbulence"></feTurbulence>
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="1" xChannelSelector="R" yChannelSelector="G"></feDisplacementMap>
</filter>
<g filter="url(#interceptFilter)">
<circle cx="64" cy="128" r="48" />
<circle cx="64" cy="128" r="32" />
<circle cx="64" cy="128" r="16" />
</g>
</svg>
);
}
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;

View File

@ -3,7 +3,8 @@ const SOURCE_DURATION_MS = 1000;
const TARGET_DELAY_MS = 500; const TARGET_DELAY_MS = 500;
const TARGET_DURATION_MS = 1500; const TARGET_DURATION_MS = 1500;
const POST_SKILL_DURATION_MS = 1000; 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 = { module.exports = {
TIMES: { TIMES: {

View File

@ -1413,7 +1413,7 @@ function testInstance(uuid) {
"cd": null "cd": null
}, },
{ {
"skill": "Taunt", "skill": "Intercept",
"self_targeting": false, "self_targeting": false,
"cd": 2 "cd": 2
}, },

View File

@ -349,7 +349,7 @@ const removeTier = skill => {
if (skill.includes('Decay')) return 'Decay'; if (skill.includes('Decay')) return 'Decay';
if (skill.includes('Invert')) return 'Invert'; 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('Triage')) return 'Triage';
if (skill.includes('Scatter')) return 'Scatter'; if (skill.includes('Scatter')) return 'Scatter';
if (skill.includes('Haste')) return 'Haste'; if (skill.includes('Haste')) return 'Haste';

View File

@ -22,7 +22,7 @@ pub enum Effect {
Slow, Slow,
Snare, Snare,
Stun, Stun,
Taunt, Intercept,
Vulnerable, Vulnerable,
Silence, Silence,
Wither, // Reduce green dmg (healing) taken Wither, // Reduce green dmg (healing) taken
@ -170,7 +170,7 @@ impl Effect {
Effect::Vulnerable => Some(Colour::Red), Effect::Vulnerable => Some(Colour::Red),
Effect::Snare => Some(Colour::Red), Effect::Snare => Some(Colour::Red),
Effect::Clutch => Some(Colour::Green), Effect::Clutch => Some(Colour::Green),
Effect::Taunt => Some(Colour::Green), Effect::Intercept => Some(Colour::Green),
// magic // magic
Effect::Hex => Some(Colour::Blue), Effect::Hex => Some(Colour::Blue),

View File

@ -389,7 +389,7 @@ impl Game {
.find(|t| t.constructs.iter().any(|c| c.id == target_construct_id)) .find(|t| t.constructs.iter().any(|c| c.id == target_construct_id))
.unwrap(); .unwrap();
if let Some(t) = target_player.taunting() { if let Some(t) = target_player.intercepting() {
return vec![t.id]; return vec![t.id];
} }
@ -1271,7 +1271,7 @@ mod tests {
} }
#[test] #[test]
fn taunt_test() { fn intercept_test() {
let mut game = create_2v2_test_game(); let mut game = create_2v2_test_game();
let i_player = game.players[0].clone(); let i_player = game.players[0].clone();
@ -1282,15 +1282,15 @@ mod tests {
let x_construct = x_player.constructs[0].clone(); let x_construct = x_player.constructs[0].clone();
let y_construct = x_player.constructs[1].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.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, 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(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.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap();
game.player_ready(i_player.id).unwrap(); game.player_ready(i_player.id).unwrap();

View File

@ -169,9 +169,9 @@ pub enum Item {
SiphonI, SiphonI,
SiphonII, SiphonII,
SiphonIII, SiphonIII,
TauntI, InterceptI,
TauntII, InterceptII,
TauntIII, InterceptIII,
ThrowI, ThrowI,
ThrowII, ThrowII,
ThrowIII, ThrowIII,
@ -381,9 +381,9 @@ impl Item {
Item::ClutchI => Some(Skill::ClutchI), Item::ClutchI => Some(Skill::ClutchI),
Item::ClutchII => Some(Skill::ClutchII), Item::ClutchII => Some(Skill::ClutchII),
Item::ClutchIII => Some(Skill::ClutchIII), Item::ClutchIII => Some(Skill::ClutchIII),
Item::TauntI => Some(Skill::TauntI), Item::InterceptI => Some(Skill::InterceptI),
Item::TauntII => Some(Skill::TauntII), Item::InterceptII => Some(Skill::InterceptII),
Item::TauntIII => Some(Skill::TauntIII), Item::InterceptIII => Some(Skill::InterceptIII),
Item::ThrowI => Some(Skill::ThrowI), Item::ThrowI => Some(Skill::ThrowI),
Item::ThrowII => Some(Skill::ThrowII), Item::ThrowII => Some(Skill::ThrowII),
Item::ThrowIII => Some(Skill::ThrowIII), 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_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::TauntI | Item::InterceptI |
Item::TauntII | Item::InterceptII |
Item::TauntIII => format!("Taunt redirects skills against the team to target, lasts {:?}T.\ Item::InterceptIII => format!("Intercept redirects skills against the team to target, lasts {:?}T.\
Recharges RedLife for {:?} RedPower.", Recharges RedLife for {:?} RedPower.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
@ -787,9 +787,9 @@ impl Item {
fn combo(&self) -> Vec<Item> { fn combo(&self) -> Vec<Item> {
match self { match self {
Item::TauntI => vec![Item::Buff, Item::Red, Item::Red], Item::InterceptI => vec![Item::Buff, Item::Red, Item::Red],
Item::TauntII => vec![Item::TauntI, Item::TauntI, Item::TauntI], Item::InterceptII => vec![Item::InterceptI, Item::InterceptI, Item::InterceptI],
Item::TauntIII => vec![Item::TauntII, Item::TauntII, Item::TauntII], Item::InterceptIII => vec![Item::InterceptII, Item::InterceptII, Item::InterceptII],
Item::TriageI => vec![Item::Buff, Item::Green, Item::Green], Item::TriageI => vec![Item::Buff, Item::Green, Item::Green],
Item::TriageII => vec![Item::TriageI, Item::TriageI, Item::TriageI], Item::TriageII => vec![Item::TriageI, Item::TriageI, Item::TriageI],
Item::TriageIII => vec![Item::TriageII, Item::TriageII, Item::TriageII], Item::TriageIII => vec![Item::TriageII, Item::TriageII, Item::TriageII],
@ -1040,9 +1040,9 @@ impl From<Skill> for Item {
Skill::StrikeII => Item::StrikeII, Skill::StrikeII => Item::StrikeII,
Skill::StrikeIII => Item::StrikeIII, Skill::StrikeIII => Item::StrikeIII,
Skill::Stun => Item::Stun, Skill::Stun => Item::Stun,
Skill::TauntI => Item::TauntI, Skill::InterceptI => Item::InterceptI,
Skill::TauntII => Item::TauntII, Skill::InterceptII => Item::InterceptII,
Skill::TauntIII => Item::TauntIII, Skill::InterceptIII => Item::InterceptIII,
Skill::ThrowI => Item::ThrowI, Skill::ThrowI => Item::ThrowI,
Skill::ThrowII => Item::ThrowII, Skill::ThrowII => Item::ThrowII,
Skill::ThrowIII => Item::ThrowIII, Skill::ThrowIII => Item::ThrowIII,
@ -1157,9 +1157,9 @@ pub struct Combo {
pub fn get_combos() -> Vec<Combo> { pub fn get_combos() -> Vec<Combo> {
let mut combinations = vec![ let mut combinations = vec![
Combo { components: Item::TauntI.combo(), item: Item::TauntI }, Combo { components: Item::InterceptI.combo(), item: Item::InterceptI },
Combo { components: Item::TauntII.combo(), item: Item::TauntII }, Combo { components: Item::InterceptII.combo(), item: Item::InterceptII },
Combo { components: Item::TauntIII.combo(), item: Item::TauntIII }, Combo { components: Item::InterceptIII.combo(), item: Item::InterceptIII },
Combo { components: Item::TriageI.combo(), item: Item::TriageI }, Combo { components: Item::TriageI.combo(), item: Item::TriageI },
Combo { components: Item::TriageII.combo(), item: Item::TriageII }, Combo { components: Item::TriageII.combo(), item: Item::TriageII },

View File

@ -281,9 +281,9 @@ impl Player {
return required; return required;
} }
pub fn taunting(&self) -> Option<&Construct> { pub fn intercepting(&self) -> Option<&Construct> {
self.constructs.iter() 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> { pub fn construct_by_id(&mut self, id: Uuid) -> Option<&mut Construct> {

View File

@ -243,9 +243,9 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut
Skill::StrikeII | Skill::StrikeII |
Skill::StrikeIII => strike(source, target, resolutions, skill), Skill::StrikeIII => strike(source, target, resolutions, skill),
Skill::TauntI | Skill::InterceptI |
Skill::TauntII | Skill::InterceptII |
Skill::TauntIII => taunt(source, target, resolutions, skill), Skill::InterceptIII => intercept(source, target, resolutions, skill),
Skill::ThrowI | Skill::ThrowI |
Skill::ThrowII | Skill::ThrowII |
@ -618,9 +618,9 @@ pub enum Skill {
StrikeII, StrikeII,
StrikeIII, StrikeIII,
TauntI, InterceptI,
TauntII, InterceptII,
TauntIII, InterceptIII,
ThrowI, // no damage stun, adds vulnerable ThrowI, // no damage stun, adds vulnerable
ThrowII, ThrowII,
@ -714,9 +714,9 @@ impl Skill {
Skill::ScatterI => 140, Skill::ScatterI => 140,
Skill::ScatterII => 200, Skill::ScatterII => 200,
Skill::ScatterIII => 300, Skill::ScatterIII => 300,
Skill::TauntI => 80, Skill::InterceptI => 80,
Skill::TauntII => 110, Skill::InterceptII => 110,
Skill::TauntIII => 150, Skill::InterceptIII => 150,
Skill::TriageTickI => 75, Skill::TriageTickI => 75,
Skill::TriageTickII => 110, Skill::TriageTickII => 110,
Skill::TriageTickIII => 140, Skill::TriageTickIII => 140,
@ -869,9 +869,9 @@ impl Skill {
meta: Some(EffectMeta::Skill(Skill::BashIII)), tick: None}], meta: Some(EffectMeta::Skill(Skill::BashIII)), tick: None}],
Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, 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::InterceptI => vec![ConstructEffect {effect: Effect::Intercept, duration: 2, meta: None, tick: None}],
Skill::TauntII => vec![ConstructEffect {effect: Effect::Taunt, duration: 3, meta: None, tick: None}], Skill::InterceptII => vec![ConstructEffect {effect: Effect::Intercept, duration: 3, meta: None, tick: None}],
Skill::TauntIII => vec![ConstructEffect {effect: Effect::Taunt, duration: 4, 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, Skill::TriageI => vec![ConstructEffect {effect: Effect::Triage, duration: 2,
meta: Some(EffectMeta::Skill(Skill::TriageTickI)), tick: None}], meta: Some(EffectMeta::Skill(Skill::TriageTickI)), tick: None}],
@ -1001,9 +1001,9 @@ impl Skill {
Skill::ClutchII => Some(2), Skill::ClutchII => Some(2),
Skill::ClutchIII => Some(3), Skill::ClutchIII => Some(3),
Skill::TauntI => Some(2), Skill::InterceptI => Some(2),
Skill::TauntII => Some(2), Skill::InterceptII => Some(2),
Skill::TauntIII => Some(2), Skill::InterceptIII => Some(2),
Skill::ElectrifyI =>Some(1), Skill::ElectrifyI =>Some(1),
Skill::ElectrifyII =>Some(1), Skill::ElectrifyII =>Some(1),
@ -1287,12 +1287,12 @@ fn clutch(source: &mut Construct, target: &mut Construct, mut results: Resolutio
return results; 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()); let red_amount = source.red_power().pct(skill.multiplier());
results.push(Resolution::new(source, target).event(target.recharge(skill, red_amount, 0))); results.push(Resolution::new(source, target).event(target.recharge(skill, red_amount, 0)));
let taunt = skill.effect()[0]; let intercept = skill.effect()[0];
results.push(Resolution::new(source, target).event(target.add_effect(skill, taunt)).stages(LogStages::PostOnly)); results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept)).stages(LogStages::PostOnly));
return results; return results;
} }