rework counter & sustain, update logs and tests
This commit is contained in:
parent
f9d36fce63
commit
aa3b9badef
48
CHANGELOG.md
48
CHANGELOG.md
@ -7,7 +7,39 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### Fixed
|
### Fixed
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
## [In Progress]
|
## [0.1.4 2019-09-17]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
Removed self targetting, all skills can be used on any target
|
||||||
|
|
||||||
|
`Reflect` No cooldown, 1T duration
|
||||||
|
`Purify` No cooldown
|
||||||
|
`Recharge` No cooldown
|
||||||
|
|
||||||
|
`Link` reworked ->
|
||||||
|
Stuns caster for 3/2/1T
|
||||||
|
If target has higher green life than caster:
|
||||||
|
Deal blue damage to target equal to difference between green life
|
||||||
|
Heal with green damage to source equal to difference between green life
|
||||||
|
|
||||||
|
`Counter` effect no longer applies immunities
|
||||||
|
Counter no cooldown
|
||||||
|
Counter applies for 1T
|
||||||
|
Counter skill now applies block at 40% / 60% / 80% reduction for 1T
|
||||||
|
Counter no longer recharges red life
|
||||||
|
|
||||||
|
`Electrify`
|
||||||
|
No Cooldown
|
||||||
|
Duration -> 1T
|
||||||
|
Electrocute duration now 2/3/4T
|
||||||
|
|
||||||
|
`Sustain`
|
||||||
|
Now has 1T cooldown at all levels
|
||||||
|
Has 1T duration at all levels
|
||||||
|
Now recharges red life to target (120 / 150 / 230)%
|
||||||
|
|
||||||
|
|
||||||
|
## [0.1.3 2019-??-??]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@ -20,20 +52,6 @@ Added `Buff` as a skill
|
|||||||
|
|
||||||
`Sustain` now grants immunity to disables.
|
`Sustain` now grants immunity to disables.
|
||||||
|
|
||||||
*BALANCE*
|
|
||||||
- purify
|
|
||||||
- 1 effect from all constructs at level 2
|
|
||||||
- removes all effects from all constructs at l3
|
|
||||||
|
|
||||||
- invert
|
|
||||||
- fx for buffs when applied to enemies
|
|
||||||
- invert + haste -> doubles all cooldowns
|
|
||||||
|
|
||||||
var / skill info rpc
|
|
||||||
thresholds / bonuses
|
|
||||||
sell cost
|
|
||||||
etc
|
|
||||||
|
|
||||||
## [0.1.2] - 2019-05-07
|
## [0.1.2] - 2019-05-07
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
* fuck magic
|
* fuck magic
|
||||||
* empower on ko
|
* empower on ko
|
||||||
|
|
||||||
|
var / skill info rpc -> sell cost / cooldown
|
||||||
* rework vecs into sets
|
* rework vecs into sets
|
||||||
* remove names so games/instances are copy
|
* remove names so games/instances are copy
|
||||||
|
|
||||||
|
|||||||
@ -64,11 +64,6 @@ pub enum Effect {
|
|||||||
impl Effect {
|
impl Effect {
|
||||||
pub fn immune(&self, skill: Skill) -> bool {
|
pub fn immune(&self, skill: Skill) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Effect::Counter => match skill {
|
|
||||||
Skill::Attack => true,
|
|
||||||
Skill::Stun => true,
|
|
||||||
_ => skill.colours().contains(&Colour::Red)
|
|
||||||
},
|
|
||||||
Effect::Banish => true,
|
Effect::Banish => true,
|
||||||
Effect::Sustain => [
|
Effect::Sustain => [
|
||||||
Skill::Stun,
|
Skill::Stun,
|
||||||
|
|||||||
@ -1172,14 +1172,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Counter).unwrap();
|
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Counter).unwrap();
|
||||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Stun).unwrap();
|
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||||
|
|
||||||
game.player_ready(x_player.id).unwrap();
|
game.player_ready(x_player.id).unwrap();
|
||||||
game.player_ready(y_player.id).unwrap();
|
game.player_ready(y_player.id).unwrap();
|
||||||
|
|
||||||
game = game.resolve_phase_start();
|
game = game.resolve_phase_start();
|
||||||
|
|
||||||
// should not be stunned because of counter
|
// don't get stunned but not really stunning ¯\_(ツ)_/¯
|
||||||
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false);
|
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false);
|
||||||
// riposte
|
// riposte
|
||||||
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (
|
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (
|
||||||
@ -1209,8 +1209,8 @@ mod tests {
|
|||||||
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Electrify).unwrap();
|
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Electrify).unwrap();
|
||||||
game.player_ready(x_player.id).unwrap();
|
game.player_ready(x_player.id).unwrap();
|
||||||
game.player_ready(y_player.id).unwrap();
|
game.player_ready(y_player.id).unwrap();
|
||||||
game = game.resolve_phase_start();
|
// game = game.resolve_phase_start();
|
||||||
assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Electric));
|
// assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Electric));
|
||||||
|
|
||||||
// attack and receive debuff
|
// attack and receive debuff
|
||||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||||
|
|||||||
@ -315,21 +315,17 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
|
|||||||
_ => panic!("no absorb skill"),
|
_ => panic!("no absorb skill"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
Event::Immunity { skill: _, immunity } => match immunity.contains(&Effect::Counter) {
|
if target.affected(Effect::Counter) {
|
||||||
true => {
|
|
||||||
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
|
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
|
||||||
.find(|e| e.effect == Effect::Counter).unwrap().clone();
|
.find(|e| e.effect == Effect::Counter).unwrap().clone();
|
||||||
match meta {
|
match meta {
|
||||||
Some(EffectMeta::Skill(s)) => {
|
Some(EffectMeta::Skill(s)) => {
|
||||||
resolutions = riposte(&mut target, &mut source, resolutions, s);
|
resolutions = counter_attack(&mut target, &mut source, resolutions, s);
|
||||||
},
|
},
|
||||||
_ => panic!("no counter skill"),
|
_ => panic!("no counter skill"),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
},
|
|
||||||
false => (),
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
@ -747,9 +743,6 @@ impl Skill {
|
|||||||
Skill::ElectrocuteTickPlus => 100,
|
Skill::ElectrocuteTickPlus => 100,
|
||||||
Skill::ElectrocuteTickPlusPlus => 130,
|
Skill::ElectrocuteTickPlusPlus => 130,
|
||||||
|
|
||||||
Skill::Counter=> 110,
|
|
||||||
Skill::CounterPlus => 145,
|
|
||||||
Skill::CounterPlusPlus => 200,
|
|
||||||
Skill::CounterAttack=> 70,
|
Skill::CounterAttack=> 70,
|
||||||
Skill::CounterAttackPlus => 95,
|
Skill::CounterAttackPlus => 95,
|
||||||
Skill::CounterAttackPlusPlus => 120,
|
Skill::CounterAttackPlusPlus => 120,
|
||||||
@ -758,14 +751,18 @@ impl Skill {
|
|||||||
Skill::PurifyPlus => 70,
|
Skill::PurifyPlus => 70,
|
||||||
Skill::PurifyPlusPlus => 105,
|
Skill::PurifyPlusPlus => 105,
|
||||||
|
|
||||||
Skill::Reflect=> 45, //restore blue life (heal)
|
Skill::Reflect=> 45, //Recharge blue life (heal)
|
||||||
Skill::ReflectPlus => 70,
|
Skill::ReflectPlus => 70,
|
||||||
Skill::ReflectPlusPlus => 100,
|
Skill::ReflectPlusPlus => 100,
|
||||||
|
|
||||||
Skill::Recharge=> 85, //restore red and blue life (heal)
|
Skill::Recharge=> 85, //Recharge red and blue life (heal)
|
||||||
Skill::RechargePlus => 130,
|
Skill::RechargePlus => 130,
|
||||||
Skill::RechargePlusPlus => 200,
|
Skill::RechargePlusPlus => 200,
|
||||||
|
|
||||||
|
Skill::Sustain => 120, // Recharge red life (heal)
|
||||||
|
Skill::SustainPlus => 150,
|
||||||
|
Skill::SustainPlusPlus => 230,
|
||||||
|
|
||||||
// Stun Base
|
// Stun Base
|
||||||
Skill::Sleep=> 240, //Green dmg (heal)
|
Skill::Sleep=> 240, //Green dmg (heal)
|
||||||
Skill::SleepPlus => 300,
|
Skill::SleepPlus => 300,
|
||||||
@ -891,11 +888,17 @@ impl Skill {
|
|||||||
Skill::InvertPlusPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 4, meta: None, tick: None}],
|
Skill::InvertPlusPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 4, meta: None, tick: None}],
|
||||||
|
|
||||||
Skill::Counter => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
Skill::Counter => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::CounterAttack)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::CounterAttack)), tick: None},
|
||||||
|
ConstructEffect {effect: Effect::Block, duration: 1,
|
||||||
|
meta: Some(EffectMeta::Multiplier(60)), tick: None}],
|
||||||
Skill::CounterPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
Skill::CounterPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::CounterAttackPlus)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::CounterAttackPlus)), tick: None},
|
||||||
|
ConstructEffect {effect: Effect::Block, duration: 1,
|
||||||
|
meta: Some(EffectMeta::Multiplier(40)), tick: None}],
|
||||||
Skill::CounterPlusPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
Skill::CounterPlusPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::CounterAttackPlusPlus)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::CounterAttackPlusPlus)), tick: None},
|
||||||
|
ConstructEffect {effect: Effect::Block, duration: 1,
|
||||||
|
meta: Some(EffectMeta::Multiplier(20)), tick: None}],
|
||||||
|
|
||||||
Skill::Reflect => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }],
|
Skill::Reflect => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }],
|
||||||
Skill::ReflectPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }],
|
Skill::ReflectPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }],
|
||||||
@ -1076,7 +1079,7 @@ impl Skill {
|
|||||||
|
|
||||||
Skill::Sustain |
|
Skill::Sustain |
|
||||||
Skill::SustainPlus |
|
Skill::SustainPlus |
|
||||||
Skill::SustainPlusPlus => None,
|
Skill::SustainPlusPlus => Some(1),
|
||||||
|
|
||||||
Skill::Intercept=> Some(2),
|
Skill::Intercept=> Some(2),
|
||||||
Skill::InterceptPlus => Some(2),
|
Skill::InterceptPlus => Some(2),
|
||||||
@ -1341,8 +1344,14 @@ fn sleep(source: &mut Construct, target: &mut Construct, mut results: Resolution
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
||||||
skill.effect().into_iter()
|
let red_amount = source.red_power().pct(skill.multiplier());
|
||||||
.for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e)))));
|
results.push(Resolution::new(source, target)
|
||||||
|
.event(target.recharge(skill, red_amount, 0)));
|
||||||
|
|
||||||
|
results.push(Resolution::new(source, target)
|
||||||
|
.event(target.add_effect(skill, skill.effect()[0]))
|
||||||
|
.stages(EventStages::PostOnly));
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1378,19 +1387,17 @@ fn buff(source: &mut Construct, target: &mut Construct, mut results: Resolutions
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn counter(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)
|
results.push(Resolution::new(source, target)
|
||||||
.event(target.recharge(skill, red_amount, 0))
|
.event(target.add_effect(skill, skill.effect()[0])));
|
||||||
.stages(EventStages::StartEnd));
|
|
||||||
|
|
||||||
results.push(Resolution::new(source, target)
|
results.push(Resolution::new(source, target)
|
||||||
.event(target.add_effect(skill, skill.effect()[0]))
|
.event(target.add_effect(skill, skill.effect()[1]))
|
||||||
.stages(EventStages::PostOnly));
|
.stages(EventStages::PostOnly));
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn riposte(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
fn counter_attack(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
||||||
let amount = source.red_power().pct(skill.multiplier());
|
let amount = source.red_power().pct(skill.multiplier());
|
||||||
target.deal_red_damage(skill, amount)
|
target.deal_red_damage(skill, amount)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -1821,7 +1828,7 @@ mod tests {
|
|||||||
sustain(&mut y.clone(), &mut y, vec![], Skill::Sustain);
|
sustain(&mut y.clone(), &mut y, vec![], Skill::Sustain);
|
||||||
assert!(y.affected(Effect::Sustain));
|
assert!(y.affected(Effect::Sustain));
|
||||||
|
|
||||||
let mut results = blast(&mut x, &mut y, vec![], Skill::Blast);
|
let mut results = ruin(&mut x, &mut y, vec![], Skill::Ruin);
|
||||||
let Resolution { source: _, target: _, event, stages: _ } = results.remove(0);
|
let Resolution { source: _, target: _, event, stages: _ } = results.remove(0);
|
||||||
match event {
|
match event {
|
||||||
Event::Immunity { skill: _, immunity } => assert!(immunity.contains(&Effect::Sustain)),
|
Event::Immunity { skill: _, immunity } => assert!(immunity.contains(&Effect::Sustain)),
|
||||||
@ -2056,8 +2063,8 @@ mod tests {
|
|||||||
.learn(Skill::HealPlus);
|
.learn(Skill::HealPlus);
|
||||||
|
|
||||||
purge(&mut x, &mut y, vec![], Skill::Purge);
|
purge(&mut x, &mut y, vec![], Skill::Purge);
|
||||||
// current turn + 2 turns at lvl 1
|
// 2 turns at lvl 1
|
||||||
assert!(y.effects.iter().any(|e| e.effect == Effect::Purge && e.duration == 3));
|
assert!(y.effects.iter().any(|e| e.effect == Effect::Purge && e.duration == 2));
|
||||||
assert!(y.disabled(Skill::Heal).is_some());
|
assert!(y.disabled(Skill::Heal).is_some());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user