Merge branch 'develop' of ssh://git.mnml.gg:40022/~/mnml into develop

This commit is contained in:
ntr 2019-11-07 16:12:32 +11:00
commit 1498c6677d
13 changed files with 315 additions and 245 deletions

View File

@ -2,7 +2,31 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [1.8.0] - 2019-10-31 ## [1.8.1] - 2019-11-07
# Changed
- Game phase
- Background for text overlapping with avatars in game phase (mobile)
- Fixed issue where effect text would show when not highlighted
- Invert
Now reverses recharge into damage
- Restrict
Changed cooldown from 2T -> 1T
Duration now 2T at all levels
- Ruin
Cooldown now 2T at all levels (down from 3T)
Now deals damage to each target (40/70/100)%
- Silence
Changed cooldown from 2T -> 1T
Duration now 2T at all levels
## [1.8.0] - 2019-11-06
# Added # Added
- Drag and drop for vbox interactions can be used instead of single click / double click - Drag and drop for vbox interactions can be used instead of single click / double click

View File

@ -8,15 +8,30 @@
* mobile info page * mobile info page
* Invert recharge
## SOON ## SOON
* supporter gold name in instance (anyone whos put any money into game)
* change cooldowns to delay & recharge * change cooldowns to delay & recharge
- delay is cooldown before skill can first be used - delay is cooldown before skill can first be used
- recharge is cooldown after using skill - recharge is cooldown after using skill
- every x speed reduces delay of skills - every x speed reduces delay of skills
* audio
* elo + leaderboards
* reconnect based on time delta
* ACP
* essential
## LATER
* theme toasts
* rework vecs into sets
* remove names so games/instances are copy
* consolidate game and instance
* combo rework * combo rework
- reduce number of items for creating t2/t3 items from 3 -> 2 - reduce number of items for creating t2/t3 items from 3 -> 2
- add lost complexity by adding skill spec items - add lost complexity by adding skill spec items
@ -27,21 +42,24 @@
- Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed) - Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed)
- Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life) - Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life)
* ACP * constants
* essential * (maybe) return of the combat log (last few events with condensed descriptions)
- click in to scroll
* audio * mnml tv
* treats
* susbcriber gold name in instance
* client animation bpm
* background colour changes depending on time of day
* rework vecs into sets * modules
* remove names so games/instances are copy * troll life -> dmg
* prince of peace
* bonus healing / no damage
* fuck magic
* empower on ko
*$$$* ## $$$
* Items
* instead of red noise, red and black bar gradient * instead of red noise, red and black bar gradient
* eth adapter * eth adapter
*sets*
* illusions * illusions
* vaporwave * vaporwave
* crop circles * crop circles
@ -51,38 +69,13 @@
* Aztec * Aztec
* youkai * youkai
* Industrial * Industrial
*CLIENT*
theme toasts
reconnect based on time delta
consolidate game and instance
* return of the combat log (last few events with condensed descriptions)
- click in to scroll
* elo + leaderboards
* reflect event stages (for animations)
* mnml tv
## LATER
* constants
* bot game grind
$$$
* Items
* Colour scheme * Colour scheme
* targeting highlight colour * targeting highlight colour
* number of constructs
* Highlight (dota) colour * Highlight (dota) colour
* fx colours + styles * fx colours + styles
* treats
* modules * client animation bpm
* troll life -> dmg * background colour changes depending on time of day
* prince of peace
* bonus healing / no damage
* fuck magic
* empower on ko
# Mechanics # Mechanics
* 10d chaos maths, not rock paper scissors * 10d chaos maths, not rock paper scissors

View File

@ -130,6 +130,9 @@
margin-bottom: 0.25em; margin-bottom: 0.25em;
text-align: center; text-align: center;
grid-area: name; grid-area: name;
span {
background-color: black;
}
} }
.skills { .skills {
@ -138,9 +141,15 @@
width: 100%; width: 100%;
height: 2em; height: 2em;
margin-right: 1em; margin-right: 1em;
span {
background-color: black;
}
} }
button.active { button.active {
background: #2c2c2c; background: #2c2c2c;
span {
background-color: #2c2c2c;
}
} }
} }
@ -151,6 +160,9 @@
width: 100%; width: 100%;
text-align: center; text-align: center;
font-size: 1.5em; font-size: 1.5em;
span {
background-color: black;
}
} }
.stats { .stats {
@ -232,6 +244,7 @@
padding-left: 1em; padding-left: 1em;
padding-right: 1em; padding-right: 1em;
text-align: center; text-align: center;
background-color: black;
svg { svg {
display: inline; display: inline;
height: 1em; height: 1em;

View File

@ -8,33 +8,33 @@ module.exports = {
Slay: () => 'red-green-border', Slay: () => 'red-green-border',
Siphon: () => 'blue-green-border', Siphon: () => 'blue-green-border',
// Stun // Stun
Link: () => 'blue-green-border',
Bash: () => 'red-border', Bash: () => 'red-border',
Sleep: () => 'green-border',
Ruin: () => 'blue-border', Ruin: () => 'blue-border',
Break: () => 'red-green-border', Sleep: () => 'green-border',
Banish: () => 'red-blue-border', Banish: () => 'red-blue-border',
Break: () => 'red-green-border',
Link: () => 'blue-green-border',
// Block // Block
Counter: () => 'red-border', Counter: () => 'red-border',
Purify: () => 'green-border',
Electrify: () => 'blue-border', Electrify: () => 'blue-border',
Purify: () => 'green-border',
Recharge: () => 'red-blue-border',
Sustain: () => 'red-green-border', Sustain: () => 'red-green-border',
Reflect: () => 'blue-green-border', Reflect: () => 'blue-green-border',
Recharge: () => 'blue-red-border',
// Buff // Buff
Intercept: () => 'red-border', Intercept: () => 'red-border',
Triage: () => 'green-border',
Haste: () => 'red-green-border',
Absorb: () => 'blue-border', Absorb: () => 'blue-border',
Hybrid: () => 'blue-green-border', Triage: () => 'green-border',
Amplify: () => 'red-blue-border', Amplify: () => 'red-blue-border',
Haste: () => 'red-green-border',
Hybrid: () => 'blue-green-border',
// Debuff // Debuff
Restrict: () => 'red-border', Restrict: () => 'red-border',
Purge: () => 'green-border',
Silence: () => 'blue-border', Silence: () => 'blue-border',
Purge: () => 'green-border',
Curse: () => 'red-blue-border',
Invert: () => 'red-green-border', Invert: () => 'red-green-border',
Decay: () => 'blue-green-border', Decay: () => 'blue-green-border',
Curse: () => 'red-blue-border',
// // Lifes Upgrades // // Lifes Upgrades
// LifeGG: () => 'green-border', // LifeGG: () => 'green-border',

View File

@ -111,7 +111,7 @@ function constructText(props) {
? animText.text ? animText.text
: construct.name; : construct.name;
return <h3 class={'name'}>{text}</h3>; return <h3 class={'name'}><span>{text}</span></h3>;
} }
module.exports = { module.exports = {

View File

@ -153,11 +153,11 @@ class GameConstruct extends Component {
} }
const effects = construct.effects.length const effects = construct.effects.length
? construct.effects.map(c => ? construct.effects.map(c =>
<div <div key={c.effect}>
key={c.effect} <span key={c.effect} onMouseOver={e => hoverInfo(e, c)}
onMouseOver={e => hoverInfo(e, c)} onMouseOut={e => hoverInfo(e, null)}> {c.effect} - {c.duration}T
onMouseOut={e => hoverInfo(e, null)} </span>
> {c.effect} - {c.duration}T</div>) </div>)
: null; : null;
return (<div class="effects"> {effects} </div>); return (<div class="effects"> {effects} </div>);
}; };

View File

@ -91,7 +91,7 @@ function Skill(props) {
onMouseOut={e => hoverInfo(e, null)} onMouseOut={e => hoverInfo(e, null)}
type="submit" type="submit"
onClick={onClick}> onClick={onClick}>
{s.skill} {cdText} <span>{s.skill} {cdText}</span>
</button> </button>
); );
} }

View File

@ -74,7 +74,7 @@ function registerEvents(store) {
// stop fetching the game state til animations are done // stop fetching the game state til animations are done
const newRes = game.resolved.slice(currentGame.resolved.length); const newRes = game.resolved.slice(currentGame.resolved.length);
return eachSeries(newRes, (r, cb) => { return eachSeries(newRes, (r, cb) => {
if (!r.event || r.stages === '') return cb(); if (!r.event) return cb();
const timeout = animations.getTime(r.stages); const timeout = animations.getTime(r.stages);
const anims = animations.getObjects(r, game, account); const anims = animations.getObjects(r, game, account);
const text = animations.getText(r); const text = animations.getText(r);

View File

@ -240,6 +240,8 @@ function convertItem(v) {
} }
function effectInfo(i) { function effectInfo(i) {
const hybridBlast = 25;
const hasteStrike = 30;
function multiplier(s) { // Update later to use server info in future function multiplier(s) { // Update later to use server info in future
if (s === 'CounterAttack') return 120; if (s === 'CounterAttack') return 120;
if (s === 'CounterAttack+') return 160; if (s === 'CounterAttack+') return 160;
@ -270,9 +272,9 @@ function effectInfo(i) {
case 'Buff': return `Increases construct RedPower BluePower SpeedStat by ${i.meta[1] - 100}%`; case 'Buff': return `Increases construct RedPower BluePower SpeedStat by ${i.meta[1] - 100}%`;
case 'Sustain': return 'Construct cannot be KO while active. Additionally provides immunity to disables'; case 'Sustain': return 'Construct cannot be KO while active. Additionally provides immunity to disables';
case 'Curse': return `Construct will take ${i.meta[1] - 100}% increased red and blue damage`; case 'Curse': return `Construct will take ${i.meta[1] - 100}% increased red and blue damage`;
case 'Haste': return `Construct has ${i.meta[1] - 100}% increased SpeedStat. Red attack skills will trigger a HasteStrike dealing 30% SpeedStat as red damage.`; case 'Haste': return `Construct has ${i.meta[1] - 100}% increased SpeedStat. Red attack skills will trigger a HasteStrike dealing ${hasteStrike}% SpeedStat as red damage.`;
case 'Hybrid': return `Construct has ${i.meta[1] - 100}% increased GreenPower. Blue attack skills will trigger a HybridBlast dealing 25% GreenPower as red damage.`; case 'Hybrid': return `Construct has ${i.meta[1] - 100}% increased GreenPower. Blue attack skills will trigger a HybridBlast dealing ${hybridBlast}% GreenPower as red damage.`;
case 'Invert': return 'Reverses damage and healing. Healing will damage this construct and damage will heal.'; case 'Invert': return 'Reverse healing/recharge into damage and damage into healing/recharge.';
case 'Counter': return `Red damage taken by this construct will trigger a CounterAttack. CounterAttack deals ${multiplier(i.meta[1])}% RedPower as red damage.`; case 'Counter': return `Red damage taken by this construct will trigger a CounterAttack. CounterAttack deals ${multiplier(i.meta[1])}% RedPower as red damage.`;
case 'Purge': return 'Disable construct from casting any green skills'; case 'Purge': return 'Disable construct from casting any green skills';
case 'Reflect': return 'Reflect blue skills back to caster'; case 'Reflect': return 'Reflect blue skills back to caster';

View File

@ -549,15 +549,17 @@ impl Construct {
} }
} }
pub fn recharge(&mut self, skill: Skill, red_amount: u64, blue_amount: u64) -> Event { pub fn recharge(&mut self, skill: Skill, red_amount: u64, blue_amount: u64) -> Vec<Event> {
let mut events = vec![];
// Should red type immunity block recharge??? // Should red type immunity block recharge???
if let Some(immunity) = self.immune(skill) { if let Some(immunity) = self.immune(skill) {
return Event::Immunity { events.push(Event::Immunity { skill, immunity });
skill, return events;
immunity,
};
} }
match self.affected(Effect::Invert) {
false => {
// Do we need inversion? // Do we need inversion?
let current_red_life = self.red_life(); let current_red_life = self.red_life();
self.red_life.increase(red_amount); self.red_life.increase(red_amount);
@ -569,7 +571,72 @@ impl Construct {
let new_blue_life = self.blue_life.value; let new_blue_life = self.blue_life.value;
let blue = new_blue_life - current_blue_life; let blue = new_blue_life - current_blue_life;
Event::Recharge { red, blue, skill } if red != 0 || blue != 0 {
events.push(Event::Recharge { red, blue, skill });
}
},
true => {
// Recharge takes a red and blue amount so check for them
if red_amount != 0 {
let red_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken))
.map(|e| (e.effect, e.meta))
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
let red_modified_power = red_mods.iter()
.fold(red_amount, |acc, fx| fx.0.apply(acc, fx.1));
let red_remainder = red_modified_power.saturating_sub(self.red_life.value);
let red_mitigation = red_modified_power.saturating_sub(red_remainder);
// reduce red_life by mitigation amount
self.red_life.reduce(red_mitigation);
// deal remainder to green_life
let red_current_green_life = self.green_life();
self.reduce_green_life(red_remainder);
let red_damage_amount = red_current_green_life - self.green_life();
events.push(Event::Damage {
skill,
amount: red_damage_amount,
mitigation: red_mitigation,
colour: Colour::Red
});
}
if blue_amount != 0 {
let blue_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::BlueDamageTaken))
.map(|e| (e.effect, e.meta))
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
let blue_modified_power = blue_mods.iter()
.fold(blue_amount, |acc, fx| fx.0.apply(acc, fx.1));
let blue_remainder = blue_modified_power.saturating_sub(self.blue_life.value);
let blue_mitigation = blue_modified_power.saturating_sub(blue_remainder);
// reduce blue_life by mitigation amount
self.blue_life.reduce(blue_mitigation);
// deal remainder to green_life
let blue_current_green_life = self.green_life();
self.reduce_green_life(blue_remainder);
let blue_damage_amount = blue_current_green_life - self.green_life();
events.push(Event::Damage {
skill,
amount: blue_damage_amount,
mitigation: blue_mitigation,
colour: Colour::Blue
});
}
}
}
return events;
} }
pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> Vec<Event> { pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> Vec<Event> {

View File

@ -1390,6 +1390,7 @@ mod tests {
true true
}, },
Event::AoeSkill { skill: _ } => false, Event::AoeSkill { skill: _ } => false,
Event::Damage { amount: _, mitigation: _, colour: _, skill: _ } => false,
_ => panic!("ruin result not effect {:?}", event), _ => panic!("ruin result not effect {:?}", event),
} }
false => false, false => false,
@ -1428,7 +1429,7 @@ mod tests {
game = game.resolve_phase_start(); game = game.resolve_phase_start();
assert!(game.resolved.len() == 5); assert!(game.resolved.len() == 4);
while let Some(r) = game.resolved.pop() { while let Some(r) = game.resolved.pop() {
let Resolution { source , target, event: _, stages: _ } = r; let Resolution { source , target, event: _, stages: _ } = r;
if [i_construct.id, j_construct.id].contains(&source.id) { if [i_construct.id, j_construct.id].contains(&source.id) {

View File

@ -807,8 +807,8 @@ impl Item {
Item::Invert| Item::Invert|
Item::InvertPlus | Item::InvertPlus |
Item::InvertPlusPlus => format!( Item::InvertPlusPlus => format!(
"Reverse healing into damage and damage into healing. "Reverse healing/recharge into damage and damage into healing/recharge.
Any excess red or blue damage is converted into shield recharge. Any excess red or blue damage is converted into shield recharge after healing.
Lasts {:?}T.", Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
@ -851,8 +851,10 @@ impl Item {
Item::Ruin| Item::Ruin|
Item::RuinPlus | Item::RuinPlus |
Item::RuinPlusPlus => format!( Item::RuinPlusPlus => format!(
"Team wide Stun for {:?}T. Stunned constructs are unable to cast skills.", "Team wide skill. Stun each construct for {:?}T.
self.into_skill().unwrap().effect()[0].get_duration()), Deal {:?}% BluePower as blue damage to each construct.",
self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().multiplier()),
Item::Link| Item::Link|
Item::LinkPlus | Item::LinkPlus |

View File

@ -433,8 +433,6 @@ pub enum EventStages {
EndOnly, // Skip Anim Skip EndOnly, // Skip Anim Skip
#[serde(rename = "POST_SKILL")] #[serde(rename = "POST_SKILL")]
PostOnly, // Skip Skip Anim PostOnly, // Skip Skip Anim
#[serde(rename = "")]
NoStages, // Skip Skip Skip
} }
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
@ -490,7 +488,6 @@ impl Resolution {
EventStages::EndPost => target_duration + post_skill, // Skip Anim Anim EventStages::EndPost => target_duration + post_skill, // Skip Anim Anim
EventStages::EndOnly => target_duration, // Skip Anim Skip EventStages::EndOnly => target_duration, // Skip Anim Skip
EventStages::PostOnly => post_skill, // Skip Skip Anim EventStages::PostOnly => post_skill, // Skip Skip Anim
EventStages::NoStages => 0, // Skip Skip Skip
} }
} }
} }
@ -829,13 +826,20 @@ impl Skill {
Skill::Link => 75, Skill::Link => 75,
Skill::LinkPlus => 100, Skill::LinkPlus => 100,
Skill::LinkPlusPlus => 150, Skill::LinkPlusPlus => 150,
Skill::Ruin => 40,
Skill::RuinPlus => 70,
Skill::RuinPlusPlus => 100,
// Debuff Base // Debuff Base
Skill::DecayTick => 33, Skill::DecayTick => 33,
Skill::DecayTickPlus => 45, Skill::DecayTickPlus => 45,
Skill::DecayTickPlusPlus => 70, Skill::DecayTickPlusPlus => 70,
Skill::Silence => 55, // Deals more per blue skill on target Skill::Silence => 55, // Deals more per blue skill on target
Skill::SilencePlus => 80, Skill::SilencePlus => 80,
Skill::SilencePlusPlus => 110, Skill::SilencePlusPlus => 110,
Skill::Restrict => 40, // Deals more per red skill on target Skill::Restrict => 40, // Deals more per red skill on target
Skill::RestrictPlus => 65, Skill::RestrictPlus => 65,
Skill::RestrictPlusPlus => 100, Skill::RestrictPlusPlus => 100,
@ -971,7 +975,7 @@ impl Skill {
Skill::Ruin => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], Skill::Ruin => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}],
Skill::RuinPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], Skill::RuinPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}],
Skill::RuinPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], Skill::RuinPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}],
Skill::Purge => vec![ConstructEffect {effect: Effect::Purge, duration: 2, meta: None, tick: None}], Skill::Purge => vec![ConstructEffect {effect: Effect::Purge, duration: 2, meta: None, tick: None}],
Skill::PurgePlus => vec![ConstructEffect {effect: Effect::Purge, duration: 3, meta: None, tick: None}], Skill::PurgePlus => vec![ConstructEffect {effect: Effect::Purge, duration: 3, meta: None, tick: None}],
@ -982,8 +986,8 @@ impl Skill {
Skill::LinkPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], Skill::LinkPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}],
Skill::Silence => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}], Skill::Silence => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}],
Skill::SilencePlus => vec![ConstructEffect {effect: Effect::Silence, duration: 3, meta: None, tick: None}], Skill::SilencePlus => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}],
Skill::SilencePlusPlus => vec![ConstructEffect {effect: Effect::Silence, duration: 4, meta: None, tick: None}], Skill::SilencePlusPlus => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}],
Skill::Siphon => vec![ConstructEffect {effect: Effect::Siphon, duration: 2, Skill::Siphon => vec![ConstructEffect {effect: Effect::Siphon, duration: 2,
meta: Some(EffectMeta::Skill(Skill::SiphonTick)), tick: None}], meta: Some(EffectMeta::Skill(Skill::SiphonTick)), tick: None}],
@ -997,8 +1001,8 @@ impl Skill {
Skill::SleepPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 4, meta: None, tick: None}], Skill::SleepPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 4, meta: None, tick: None}],
Skill::Restrict => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}], Skill::Restrict => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}],
Skill::RestrictPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 3, meta: None, tick: None}], Skill::RestrictPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}],
Skill::RestrictPlusPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 4, meta: None, tick: None}], Skill::RestrictPlusPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}],
Skill::Bash => vec![ConstructEffect {effect: Effect::Stun, duration: 2, Skill::Bash => vec![ConstructEffect {effect: Effect::Stun, duration: 2,
meta: Some(EffectMeta::Skill(Skill::Bash)), tick: None}], meta: Some(EffectMeta::Skill(Skill::Bash)), tick: None}],
@ -1027,24 +1031,25 @@ impl Skill {
pub fn base_cd(&self) -> Cooldown { pub fn base_cd(&self) -> Cooldown {
match self { match self {
Skill::Attack => None, Skill::Attack => None,
Skill::Debuff => Some(1), Skill::Block => None, // reduce damage
Skill::Buff => None, Skill::Buff => None,
Skill::Debuff => Some(1),
Skill::Stun => Some(2),
Skill::Strike=> None, Skill::Strike=> None,
Skill::StrikePlus => None, Skill::StrikePlus => None,
Skill::StrikePlusPlus => None, Skill::StrikePlusPlus => None,
Skill::Block => None, // reduce damage
Skill::Counter| Skill::Counter|
Skill::CounterPlus | Skill::CounterPlus |
Skill::CounterPlusPlus => None, // avoid all damage Skill::CounterPlusPlus => None, // avoid all damage
Skill::Restrict=> Some(2), Skill::Restrict |
Skill::RestrictPlus => Some(2), Skill::RestrictPlus |
Skill::RestrictPlusPlus => Some(2), Skill::RestrictPlusPlus => Some(2),
Skill::Stun => Some(2),
Skill::Bash=> Some(2), Skill::Bash |
Skill::BashPlus => Some(2), Skill::BashPlus |
Skill::BashPlusPlus => Some(2), Skill::BashPlusPlus => Some(2),
Skill::Heal=> None, Skill::Heal=> None,
@ -1055,27 +1060,28 @@ impl Skill {
Skill::TriagePlus => None, // hot Skill::TriagePlus => None, // hot
Skill::TriagePlusPlus => None, // hot Skill::TriagePlusPlus => None, // hot
Skill::Break=> Some(1), // no damage stun, adds vulnerable Skill::Break | // no damage stun, adds vulnerable
Skill::BreakPlus => Some(1), Skill::BreakPlus |
Skill::BreakPlusPlus => Some(1), Skill::BreakPlusPlus => Some(1),
Skill::Blast=> None, Skill::Blast |
Skill::BlastPlus => None, Skill::BlastPlus |
Skill::BlastPlusPlus => None, Skill::BlastPlusPlus => None,
Skill::Chaos=> None, Skill::Chaos |
Skill::ChaosPlus => None, Skill::ChaosPlus |
Skill::ChaosPlusPlus => None, Skill::ChaosPlusPlus => None,
Skill::Amplify=> Some(1), Skill::Amplify |
Skill::AmplifyPlus => Some(1), Skill::AmplifyPlus |
Skill::AmplifyPlusPlus => Some(1), Skill::AmplifyPlusPlus => Some(1),
Skill::Hybrid | Skill::Hybrid |
Skill::HybridPlus | Skill::HybridPlus |
Skill::HybridPlusPlus => Some(1), Skill::HybridPlusPlus => Some(1),
Skill::Invert=> Some(2), Skill::Invert |
Skill::InvertPlus => Some(2), Skill::InvertPlus |
Skill::InvertPlusPlus => Some(2), Skill::InvertPlusPlus => Some(2),
Skill::Decay => None, // dot Skill::Decay => None, // dot
@ -1086,52 +1092,52 @@ impl Skill {
Skill::SiphonPlus | Skill::SiphonPlus |
Skill::SiphonPlusPlus => None, Skill::SiphonPlusPlus => None,
Skill::Curse=> Some(1), Skill::Curse |
Skill::CursePlus => Some(1), Skill::CursePlus |
Skill::CursePlusPlus => Some(1), Skill::CursePlusPlus => Some(1),
Skill::Link=> Some(2), Skill::Link |
Skill::LinkPlus => Some(2), Skill::LinkPlus |
Skill::LinkPlusPlus => Some(2), Skill::LinkPlusPlus => Some(2),
Skill::Silence=> Some(2), Skill::Silence |
Skill::SilencePlus => Some(2), Skill::SilencePlus |
Skill::SilencePlusPlus => Some(2), Skill::SilencePlusPlus => Some(2),
Skill::Purify | Skill::Purify |
Skill::PurifyPlus | Skill::PurifyPlus |
Skill::PurifyPlusPlus => None, Skill::PurifyPlusPlus => None,
Skill::Purge=> Some(1), Skill::Purge |
Skill::PurgePlus => Some(1), Skill::PurgePlus |
Skill::PurgePlusPlus => Some(1), Skill::PurgePlusPlus => Some(1),
Skill::Banish | Skill::Banish |
Skill::BanishPlus | Skill::BanishPlus |
Skill::BanishPlusPlus => Some(1), Skill::BanishPlusPlus => Some(1),
Skill::Haste=> Some(1), Skill::Haste |
Skill::HastePlus => Some(1), Skill::HastePlus |
Skill::HastePlusPlus => Some(1), Skill::HastePlusPlus => Some(1),
Skill::Reflect | Skill::Reflect |
Skill::ReflectPlus | Skill::ReflectPlus |
Skill::ReflectPlusPlus => None, Skill::ReflectPlusPlus => None,
Skill::Recharge=> None, Skill::Recharge |
Skill::RechargePlus => None, Skill::RechargePlus |
Skill::RechargePlusPlus => None, Skill::RechargePlusPlus => None,
Skill::Ruin=> Some(3), Skill::Ruin |
Skill::RuinPlus => Some(2), Skill::RuinPlus |
Skill::RuinPlusPlus => Some(2), Skill::RuinPlusPlus => Some(2),
Skill::Slay=> None, Skill::Slay=> None,
Skill::SlayPlus => None, Skill::SlayPlus => None,
Skill::SlayPlusPlus => None, Skill::SlayPlusPlus => None,
Skill::Sleep=> Some(2), Skill::Sleep |
Skill::SleepPlus => Some(2), Skill::SleepPlus |
Skill::SleepPlusPlus => Some(2), Skill::SleepPlusPlus => Some(2),
Skill::Sustain | Skill::Sustain |
@ -1146,7 +1152,6 @@ impl Skill {
Skill::ElectrifyPlus | Skill::ElectrifyPlus |
Skill::ElectrifyPlusPlus => None, Skill::ElectrifyPlusPlus => None,
Skill::Absorb | Skill::Absorb |
Skill::AbsorbPlus | Skill::AbsorbPlus |
Skill::AbsorbPlusPlus => Some(1), Skill::AbsorbPlusPlus => Some(1),
@ -1212,7 +1217,6 @@ impl Skill {
Skill::SiphonTick | Skill::SiphonTick |
Skill::SiphonTickPlus | Skill::SiphonTickPlus |
Skill::SiphonTickPlusPlus | Skill::SiphonTickPlusPlus |
Skill::TriageTick | Skill::TriageTick |
Skill::TriageTickPlus | Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => true, Skill::TriageTickPlusPlus => true,
@ -1401,21 +1405,12 @@ 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 {
let red_amount = source.red_power().pct(skill.multiplier());
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])));
let e = target.recharge(skill, red_amount, 0);
let stages = match e {
Event::Recharge { red, blue, skill: _ } => {
if red > 0 || blue > 0 { EventStages::PostOnly }
else { EventStages::NoStages }
}
_ => {
warn!("no recharge event found {:?}", e);
EventStages::NoStages
}
};
results.push(Resolution::new(source, target).event(e).stages(stages)); let red_amount = source.red_power().pct(skill.multiplier());
target.recharge(skill, red_amount, 0)
.into_iter()
.for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
return results; return results;
} }
@ -1425,18 +1420,9 @@ fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolu
results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept))); results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept)));
let red_amount = source.red_power().pct(skill.multiplier()); let red_amount = source.red_power().pct(skill.multiplier());
let e = target.recharge(skill, red_amount, 0); target.recharge(skill, red_amount, 0)
let stages = match e { .into_iter()
Event::Recharge { red, blue, skill: _ } => { .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
if red > 0 || blue > 0 { EventStages::PostOnly }
else { EventStages::NoStages }
}
_ => {
warn!("no recharge event found {:?}", e);
EventStages::NoStages
}
};
results.push(Resolution::new(source, target).event(e).stages(stages));
return results; return results;
} }
@ -1684,6 +1670,11 @@ fn electrocute_tick(source: &mut Construct, target: &mut Construct, mut results:
} }
fn ruin(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn ruin(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
let amount = source.blue_power().pct(skill.multiplier());
target.deal_blue_damage(skill, amount)
.into_iter()
.for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
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()[0]))
.stages(EventStages::PostOnly)); .stages(EventStages::PostOnly));
@ -1693,18 +1684,9 @@ fn ruin(source: &mut Construct, target: &mut Construct, mut results: Resolutions
fn absorb(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn absorb(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])));
let blue_amount = source.blue_power().pct(skill.multiplier()); let blue_amount = source.blue_power().pct(skill.multiplier());
let e = target.recharge(skill, 0, blue_amount); target.recharge(skill, 0, blue_amount)
let stages = match e { .into_iter()
Event::Recharge { red, blue, skill: _ } => { .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
if red > 0 || blue > 0 { EventStages::PostOnly }
else { EventStages::NoStages }
}
_ => {
warn!("no recharge event found {:?}", e);
EventStages::NoStages
}
};
results.push(Resolution::new(source, target).event(e).stages(stages));
return results;; return results;;
} }
@ -1743,36 +1725,21 @@ fn reflect(source: &mut Construct, target: &mut Construct, mut results: Resoluti
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])));
let blue_amount = source.blue_power().pct(skill.multiplier()); let blue_amount = source.blue_power().pct(skill.multiplier());
let e = target.recharge(skill, 0, blue_amount); target.recharge(skill, 0, blue_amount)
let stages = match e { .into_iter()
Event::Recharge { red, blue, skill: _ } => { .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
if red > 0 || blue > 0 { EventStages::PostOnly }
else { EventStages::NoStages }
}
_ => {
warn!("no recharge event found {:?}", e);
EventStages::NoStages
}
};
results.push(Resolution::new(source, target).event(e).stages(stages));
return results;; return results;;
} }
fn recharge(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn recharge(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
results.push(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd));
let red_amount = source.red_power().pct(skill.multiplier()); let red_amount = source.red_power().pct(skill.multiplier());
let blue_amount = source.blue_power().pct(skill.multiplier()); let blue_amount = source.blue_power().pct(skill.multiplier());
let e = target.recharge(skill, red_amount, blue_amount); target.recharge(skill, red_amount, blue_amount)
let stages = match e { .into_iter()
Event::Recharge { red, blue, skill: _ } => { .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
if red > 0 || blue > 0 { EventStages::AllStages }
else { EventStages::StartEnd }
}
_ => {
warn!("no recharge event found {:?}", e);
EventStages::NoStages
}
};
results.push(Resolution::new(source, target).event(e).stages(stages));
return results; return results;
} }
@ -2183,6 +2150,7 @@ mod tests {
let mut results = recharge(&mut x, &mut y, vec![], Skill::Recharge); let mut results = recharge(&mut x, &mut y, vec![], Skill::Recharge);
results.remove(0);
let Resolution { source: _, target: _, event, stages: _ } = results.remove(0); let Resolution { source: _, target: _, event, stages: _ } = results.remove(0);
match event { match event {
Event::Recharge { red, blue, skill: _ } => { Event::Recharge { red, blue, skill: _ } => {