diff --git a/core/src/construct.rs b/core/src/construct.rs index 02beb0e9..6b7ecb26 100644 --- a/core/src/construct.rs +++ b/core/src/construct.rs @@ -4,7 +4,7 @@ use rand::prelude::*; use failure::Error; use failure::err_msg; -use skill::{Skill, Cast, Immunity, Disable, EventVariant}; +use skill::{Skill, Cast, Immunity, Disable, Event, EventVariant}; use game::{Colour}; use effect::{Cooldown, Effect}; use spec::{Spec}; @@ -549,7 +549,7 @@ impl Construct { // Should red type immunity block recharge??? if let Some(immunity) = self.immune(skill) { if !self.is_ko() { - events.push(EventVariant::Immunity { skill, immunity }); + events.push(Event::new(EventVariant::Immunity { skill, immunity }, self)); } return events; } @@ -568,7 +568,7 @@ impl Construct { let blue = new_blue_life - current_blue_life; if red != 0 || blue != 0 { - events.push(EventVariant::Recharge { red, blue, skill }); + events.push(Event::new(EventVariant::Recharge { red, blue, skill }, self)); } }, true => { @@ -594,12 +594,12 @@ impl Construct { self.reduce_green_life(red_remainder); let red_damage_amount = red_current_green_life - self.green_life(); - events.push(EventVariant::Damage { + events.push(Event::new(EventVariant::Damage { skill, amount: red_damage_amount, mitigation: red_mitigation, colour: Colour::Red - }); + }, self)); } if blue_amount != 0 { @@ -623,12 +623,12 @@ impl Construct { self.reduce_green_life(blue_remainder); let blue_damage_amount = blue_current_green_life - self.green_life(); - events.push(EventVariant::Damage { + events.push(Event::new(EventVariant::Damage { skill, amount: blue_damage_amount, mitigation: blue_mitigation, colour: Colour::Blue - }); + }, self)); } } } @@ -639,7 +639,7 @@ impl Construct { let mut events = vec![]; if let Some(immunity) = self.immune(skill) { if !self.is_ko() { - events.push(EventVariant::Immunity { skill, immunity }); + events.push(Event::new(EventVariant::Immunity { skill, immunity }, self)); } return events; } @@ -661,38 +661,38 @@ impl Construct { let healing = new_green_life - current_green_life; let overhealing = modified_power - healing; - events.push(EventVariant::Healing { + events.push(Event::new(EventVariant::Healing { skill, amount: healing, overhealing, - }); + }, self)); }, true => { - // events.push(EventVariant::Inversion { skill }); + // events.push(Event::new(EventVariant::Inversion { skill })); // there is no green shield (yet) let current_green_life = self.green_life(); self.reduce_green_life(modified_power); let delta = current_green_life - self.green_life(); - events.push(EventVariant::Damage { + events.push(Event::new(EventVariant::Damage { skill, amount: delta, mitigation: 0, colour: Colour::Green, - }); + }, self)); } } return events; } - pub fn deal_red_damage(&mut self, skill: Skill, amount: usize) -> Vec { + pub fn deal_red_damage(&mut self, skill: Skill, amount: usize) -> Vec { let mut events = vec![]; if let Some(immunity) = self.immune(skill) { if !self.is_ko() { - events.push(EventVariant::Immunity { skill, immunity }); + events.push(Event::new(EventVariant::Immunity { skill, immunity }, self)); } return events; } @@ -722,15 +722,18 @@ impl Construct { self.reduce_green_life(remainder); let delta = current_green_life - self.green_life(); - events.push(EventVariant::Damage { - skill, - amount: delta, - mitigation, - colour: Colour::Red, - }); + events.push(Event::new( + EventVariant::Damage { + skill, + amount: delta, + mitigation, + colour: Colour::Red, + }, + self + )); }, true => { - // events.push(EventVariant::Inversion { skill }); + // events.push(Event::new(EventVariant::Inversion { skill })); let current_green_life = self.green_life(); self.green_life.increase(modified_power); @@ -743,15 +746,17 @@ impl Construct { let recharge = self.red_life.value - current_life; if healing > 0 { - events.push(EventVariant::Healing { - skill, - amount: healing, - overhealing: overhealing - recharge, - }); + events.push(Event::new( + EventVariant::Healing{ + skill, + amount: healing, + overhealing: overhealing - recharge, + }, self + )); } if recharge > 0 { - events.push(EventVariant::Recharge { red: recharge, blue: 0, skill }); + events.push(Event::new(EventVariant::Recharge { red: recharge, blue: 0, skill }, self)); } } }; @@ -764,7 +769,7 @@ impl Construct { if let Some(immunity) = self.immune(skill) { if !self.is_ko() { - events.push(EventVariant::Immunity { skill, immunity }); + events.push(Event::new(EventVariant::Immunity { skill, immunity }, self)); } return events; } @@ -790,15 +795,15 @@ impl Construct { self.reduce_green_life(remainder); let delta = current_green_life - self.green_life(); - events.push(EventVariant::Damage { + events.push(Event::new(EventVariant::Damage { skill, amount: delta, mitigation, colour: Colour::Blue, - }); + }, self)); }, true => { - // events.push(EventVariant::Inversion { skill }); + // events.push(Event::new(EventVariant::Inversion { skill })); let current_green_life = self.green_life(); self.green_life.increase(modified_power); @@ -811,15 +816,18 @@ impl Construct { let recharge = self.blue_life.value - current_life; if healing > 0 { - events.push(EventVariant::Healing { - skill, - amount: healing, - overhealing, - }); + events.push( + Event::new(EventVariant::Healing { + skill, + amount: healing, + overhealing, + }, + self + )); } if recharge > 0 { - events.push(EventVariant::Recharge { red: 0, blue: recharge, skill }); + events.push(Event::new(EventVariant::Recharge { red: 0, blue: recharge, skill }, self)); } } }; @@ -829,10 +837,11 @@ impl Construct { pub fn add_effect(&mut self, skill: Skill, effect: ConstructEffect) -> Event { if let Some(immunity) = self.immune(skill) { - return EventVariant::Immunity { - skill, - immunity, - }; + return Event::new( + EventVariant::Immunity{ + skill, + immunity, + }, self); } if let Some(p) = self.effects.iter().position(|ce| ce.effect == effect.effect) { @@ -847,12 +856,14 @@ impl Construct { } // todo modified durations cause of buffs - let result = EventVariant::Effect { - effect: effect.effect, - duration: effect.duration, - construct_effects: self.effects.clone(), - skill, - }; + let result = Event::new( + EventVariant::Effect { + effect: effect.effect, + duration: effect.duration, + construct_effects: self.effects.clone(), + skill, + }, self + ); return result; } diff --git a/core/src/game.rs b/core/src/game.rs index 6ed1673a..28a2ca8d 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -10,7 +10,7 @@ use failure::Error; use failure::err_msg; use construct::{Construct, Stat}; -use skill::{Skill, Cast, Resolution, Event, resolve}; +use skill::{Skill, Cast, Event, resolve}; use effect::{Effect}; use player::{Player}; use instance::{TimeControl}; @@ -53,7 +53,7 @@ pub struct Game { pub players: Vec, pub phase: Phase, pub stack: Vec, - pub resolutions: Vec>, + pub resolutions: Vec>, pub instance: Option, time_control: TimeControl, phase_start: DateTime, @@ -489,7 +489,7 @@ impl Game { self.skill_phase_start(r_animation_ms) } - fn resolution_add(&mut self, mut resolutions: Vec) -> &mut Game { + fn resolution_add(&mut self, mut resolutions: Vec) -> &mut Game { self.resolutions.last_mut().unwrap().append(&mut resolutions); self } @@ -505,9 +505,8 @@ impl Game { } fn damage(&mut self, construct: Uuid, skill: Skill, values: Vec, colour: Colour) -> &mut Game { - let target = self.construct_by_id(construct).unwrap(); let resolutions = match colour { - _ => target.deal_red_damage(skill, 128) // fixme unwrap + _ => self.construct_by_id(construct).unwrap().deal_red_damage(skill, 128) // fixme unwrap }; self.resolution_add(resolutions); @@ -535,8 +534,8 @@ impl Game { self } - // fn log_resolution(&mut self, speed: usize, resolution: &Resolution) -> &mut Game { - // let Resolution { source, target, event, stages: _ } = resolution; + // fn log_resolution(&mut self, speed: usize, resolution: &Event) -> &mut Game { + // let Event { source, target, event, stages: _ } = resolution; // match event { // Event::Ko { skill: _ }=> // self.log.push(format!("{:} KO!", target.name)), @@ -1033,13 +1032,13 @@ mod tests { // // game = game.resolve_phase_start(); // // assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Link)); - // // let Resolution { source: _, target: _, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); + // // let Event { source: _, target: _, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); // // match event { // // Event::Effect { effect, skill: _, duration: _, construct_effects: _ } => assert_eq!(effect, Effect::Link), // // _ => panic!("not siphon"), // // }; - // // let Resolution { source: _, target: _, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); + // // let Event { source: _, target: _, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); // // match event { // // Event::Recharge { red: _, blue: _, skill: _ } => (), // // _ => panic!("link result was not recharge"), @@ -1051,7 +1050,7 @@ mod tests { // // game.player_ready(y_player.id).unwrap(); // // game = game.resolve_phase_start(); - // // let Resolution { source: _, target, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); + // // let Event { source: _, target, event, stages: _ } = game.resolutions.last.unwrap().pop().unwrap(); // // assert_eq!(target.id, y_construct.id); // // match event { // // Event::Damage { amount, skill: _, mitigation: _, colour: _} => @@ -1125,7 +1124,7 @@ mod tests { // .last().unwrap() // .into_iter() // .filter(|r| { - // let Resolution { source, target: _, event, stages: _ } = r; + // let Event { source, target: _, event, stages: _ } = r; // match source.id == x_construct.id { // true => match event { // Event::Effect { effect, duration, skill: _, construct_effects: _ } => { @@ -1175,7 +1174,7 @@ mod tests { // assert!(game.resolutions.len() == 4); // while let Some(r) = game.resolutions.last().unwrap().pop() { - // let Resolution { source , target, event: _, stages: _ } = r; + // let Event { source , target, event: _, stages: _ } = r; // if [i_construct.id, j_construct.id].contains(&source.id) { // assert!(target.id == x_construct.id); // } @@ -1264,7 +1263,7 @@ mod tests { // game = game.resolve_phase_start(); // assert!(game.construct_by_id(y_construct.id).unwrap().affected(Effect::Decay)); - // let Resolution { source: _, target: _, event, stages: _ } = game.resolutions.last().unwrap().pop().unwrap(); + // let Event { source: _, target: _, event, stages: _ } = game.resolutions.last().unwrap().pop().unwrap(); // match event { // Event::Damage { amount: _, skill, mitigation: _, colour: _ } => assert_eq!(skill, Skill::DecayTick), // _ => panic!("not decay"), @@ -1278,7 +1277,7 @@ mod tests { // game.player_ready(y_player.id).unwrap(); // game = game.resolve_phase_start(); - // while let Some(Resolution { source: _, target: _, event, stages: _ }) = game.resolutions.last().unwrap().pop() { + // while let Some(Event { source: _, target: _, event, stages: _ }) = game.resolutions.last().unwrap().pop() { // match event { // Event::Damage { amount: _, skill: _, mitigation: _, colour: _ } => // panic!("{:?} damage event", event), @@ -1298,7 +1297,7 @@ mod tests { // game.player_ready(y_player.id).unwrap(); // game = game.resolve_phase_start(); - // while let Some(Resolution { source: _, target: _, event, stages: _ }) = game.resolutions.last().unwrap().pop() { + // while let Some(Event { source: _, target: _, event, stages: _ }) = game.resolutions.last().unwrap().pop() { // match event { // Event::Damage { amount: _, skill: _, mitigation: _, colour: _ } => // panic!("{:#?} {:#?} damage event", game.resolutions, event), @@ -1323,10 +1322,7 @@ mod tests { let player_id = game.players[0].id; let source = game.players[0].constructs[0].id; let target = game.players[1].constructs[0].id; - println!("{:?}", game); game.add_skill(player_id, source, target, Skill::Attack).unwrap(); game = game.resolve_phase_start(); - - println!("{:?}", game.resolutions.last().unwrap()); } } diff --git a/core/src/skill.rs b/core/src/skill.rs index 7c96a778..d44ba780 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -16,7 +16,7 @@ use effect::{Effect, Cooldown}; // let mut b = Construct::new(); // b.id = b_id; // if skill.aoe() { // Send an aoe skill event for anims -// game.event(Resolution::new(&a, &b).event(Event::AoeSkill { skill }).stages(EventStages::StartEnd)); +// game.event(Event::new(&a, &b).event(Event::AoeSkill { skill }).stages(EventStages::StartEnd)); // } // return cast_actions(skill, &mut a, &mut b, resolutions); // } @@ -57,7 +57,7 @@ pub fn resolve(game: &mut Game, cast: Cast) { // let source = game.construct_by_id(cast.source).unwrap().clone(); // if skill.aoe() { // Send an aoe skill event for anims - // game.event(Resolution::new(&source, + // game.event(Event::new(&source, // &game.construct_by_id(cast.target).unwrap().clone()).event(Event::AoeSkill { skill }).stages(EventStages::StartEnd)); // } @@ -67,352 +67,6 @@ pub fn resolve(game: &mut Game, cast: Cast) { } -pub fn cast_actions(cast: Cast) -> Vec { - match cast.skill { - _ => vec![ - Action::Damage { - construct: cast.target, - skill: Skill::Attack, - colour: Colour::Red, - values: vec![Value::Stat { construct: cast.source, stat: Stat::RedPower, mult: Skill::Attack.multiplier() }], - }], - } - - // Skill::Strike => game.event( - // Event::Damage { - // colour: Colour::Red, - // amount: SkillPower { construct: cast.source, skill: Skill::Strike } - // }, - // Event::LifeSteal { - // amount: CastDamage { id: cast.id, colour: Colour::Red, target: cast.source }, - // }, - // ), - - // Skill::Attack => game.event(Event::Damage { - // colour: Colour::Red, - // amount: Stat { construct: cast.source, stat: Stat::RedPower, pct: ATTACK_RED_POWER_PCT } - // }), - - - // Skill::Bash => game.event(Event::Damage { - // colour: Colour::Red, - // amounts: vec![ - // Stat { construct: cast.source, stat: Stat::RedPower, pct: ATTACK_RED_POWER_PCT }, - // Cooldowns { construct: cast.source }, - // ], - // }) - - // // we clone the current state of the target and source - // // so we can modify them during the resolution - // // no more than 1 mutable ref allowed on game - - // let mut source = game.construct_by_id(cast.source).unwrap().clone(); - // let mut target = game.construct_by_id(target_id).unwrap().clone(); - - // // bail out on ticks that have been removed - // if skill.is_tick() && target.effects.iter().find(|ce| match ce.tick { - // Some(t) => t.id == cast.id, - // None => false, - // }).is_none() { - // return; - // } - - // if let Some(_disable) = source.disabled(skill) { - // game.event(Resolution::new(source, target).event(Event::Disable { disable, skill }).stages(EventStages::PostOnly)); - // return; - // } - - // if target.is_ko() { - // game.event(Resolution::new(source, target).event(Event::TargetKo { skill }).stages(EventStages::PostOnly)); - // return; - // } - - // if target.affected(Effect::Reflect) && skill.colours().contains(&Colour::Blue) && !skill.is_tick() { - // // guard against overflow - // if source.affected(Effect::Reflect) { - // } - // game.event(Resolution::new(source, target).event(Event::Reflection { skill })); - // return cast_actions(skill, &mut source.clone(), source, resolutions); - // } - - - // // haste_strike_check(game) - - // if source.affected(Effect::Haste) { - // match skill { - // Skill::Slay | - // Skill::SlayPlus | - // Skill::SlayPlusPlus | - // Skill::Chaos | - // Skill::ChaosPlus | - // Skill::ChaosPlusPlus | - // Skill::Strike | - // Skill::StrikePlus | - // Skill::StrikePlusPlus => { - // let amount = source.speed().pct(Skill::HasteStrike.multiplier()); - // target.deal_red_damage(Skill::HasteStrike, amount) - // .into_iter() - // .for_each(|e| game.event(Resolution::new(source, target).event(e))); - // }, - // _ => (), - // } - // } - - // if source.affected(Effect::Hybrid) { - // match skill { - // Skill::Blast| - // Skill::BlastPlus | - // Skill::BlastPlusPlus | - // Skill::Chaos | - // Skill::ChaosPlus | - // Skill::ChaosPlusPlus | - // Skill::Siphon | - // Skill::SiphonPlus | - // Skill::SiphonPlusPlus => { - // let amount = source.green_power().pct(Skill::HybridBlast.multiplier()); - // target.deal_blue_damage(Skill::HybridBlast, amount) - // .into_iter() - // .for_each(|e| game.event(Resolution::new(source, target).event(e))); - // }, - // _ => (), - // } - // } - - // match self.category() == EffectCategory::Red { - // true => { - // if let Some(evasion) = target.evade(*self) { - // game.event(evasion); - // return Event; - // } - // }, - // false => (), - // } - - // match skill { - // Skill::Amplify| - // Skill::AmplifyPlus | - // Skill::AmplifyPlusPlus => amplify(game, skill), - - // Skill::Banish| - // Skill::BanishPlus | - // Skill::BanishPlusPlus => banish(game, skill), - - // Skill::Bash| - // Skill::BashPlus | - // Skill::BashPlusPlus => bash(game, skill), - - // Skill::Blast| - // Skill::BlastPlus | - // Skill::BlastPlusPlus => blast(game, skill), - - // Skill::Chaos| - // Skill::ChaosPlus | - // Skill::ChaosPlusPlus => chaos(game, skill), - - // Skill::Sustain| - // Skill::SustainPlus | - // Skill::SustainPlusPlus => sustain(game, skill), - - // Skill::Electrify| - // Skill::ElectrifyPlus | - // Skill::ElectrifyPlusPlus => electrify(game, skill), - // Skill::ElectrocuteTick| - // Skill::ElectrocuteTickPlus | - // Skill::ElectrocuteTickPlusPlus => electrocute_tick(game, skill), - - // Skill::Curse| - // Skill::CursePlus | - // Skill::CursePlusPlus => curse(game, skill), - - // Skill::Decay| - // Skill::DecayPlus | - // Skill::DecayPlusPlus => decay(game, skill), - // Skill::DecayTick| - // Skill::DecayTickPlus | - // Skill::DecayTickPlusPlus => decay_tick(game, skill), - - // Skill::Haste| - // Skill::HastePlus | - // Skill::HastePlusPlus => haste(game, skill), - - // Skill::Heal| - // Skill::HealPlus | - // Skill::HealPlusPlus => heal(game, skill), - - // Skill::Absorb| - // Skill::AbsorbPlus | - // Skill::AbsorbPlusPlus => absorb(game, skill), - - // Skill::Hybrid| - // Skill::HybridPlus | - // Skill::HybridPlusPlus => hybrid(game, skill), - - // Skill::Invert| - // Skill::InvertPlus | - // Skill::InvertPlusPlus => invert(game, skill), - - // Skill::Counter| - // Skill::CounterPlus | - // Skill::CounterPlusPlus => counter(game, skill), - - // Skill::Purge| - // Skill::PurgePlus | - // Skill::PurgePlusPlus => purge(game, skill), - - // Skill::Purify| - // Skill::PurifyPlus | - // Skill::PurifyPlusPlus => purify(game, skill), - - // Skill::Recharge| - // Skill::RechargePlus | - // Skill::RechargePlusPlus => recharge(game, skill), - - // Skill::Reflect| - // Skill::ReflectPlus | - // Skill::ReflectPlusPlus => reflect(game, skill), - - // Skill::Ruin| - // Skill::RuinPlus | - // Skill::RuinPlusPlus => ruin(game, skill), - - // Skill::Link| - // Skill::LinkPlus | - // Skill::LinkPlusPlus => link(game, skill), - - // Skill::Silence| - // Skill::SilencePlus | - // Skill::SilencePlusPlus => silence(game, skill), - - // Skill::Siphon| - // Skill::SiphonPlus | - // Skill::SiphonPlusPlus => siphon(game, skill), - // Skill::SiphonTick| - // Skill::SiphonTickPlus | - // Skill::SiphonTickPlusPlus => siphon_tick(game, skill), - - // Skill::Slay| - // Skill::SlayPlus | - // Skill::SlayPlusPlus => slay(game, skill), - - // Skill::Sleep| - // Skill::SleepPlus | - // Skill::SleepPlusPlus => sleep(game, skill), - - // Skill::Restrict| - // Skill::RestrictPlus | - // Skill::RestrictPlusPlus => restrict(game, skill), - - // Skill::Strike| - // Skill::StrikePlus | - // Skill::StrikePlusPlus => strike(game, skill), - - // Skill::Intercept| - // Skill::InterceptPlus | - // Skill::InterceptPlusPlus => intercept(game, skill), - - // Skill::Break| - // Skill::BreakPlus | - // Skill::BreakPlusPlus => break_(game, skill), - - // Skill::Triage| - // Skill::TriagePlus | - // Skill::TriagePlusPlus => triage(game, skill), - - // Skill::TriageTick| - // Skill::TriageTickPlus | - // Skill::TriageTickPlusPlus => triage_tick(game, skill), - - // // Base Skills - // Skill::Attack => attack(game, skill), - // Skill::Block => block(game, skill), - // Skill::Buff => buff(game, skill), - // Skill::Debuff => debuff(game, skill), - // Skill::Stun => stun(game, skill), - - // // Triggered - // Skill::Electrocute | - // Skill::ElectrocutePlus | - // Skill::ElectrocutePlusPlus => panic!("should only trigger from electrify hit"), - // Skill::HasteStrike => panic!("should only trigger from haste"), - // Skill::Absorption| - // Skill::AbsorptionPlus | - // Skill::AbsorptionPlusPlus => panic!("should only trigger from absorb"), - // Skill::HybridBlast => panic!("should only trigger from hybrid"), - // Skill::CounterAttack| - // Skill::CounterAttackPlus | - // Skill::CounterAttackPlusPlus => panic!("should only trigger from counter"), - - - // // Not used - // }; - - // for Resolution { source: event_source, target: event_target, event, stages: _ } in resolutions.clone() { - // let mut source = game.construct_by_id(event_source.id).unwrap().clone(); - // let mut target = game.construct_by_id(event_target.id).unwrap().clone(); - - // match event { - // Event::Damage { amount, skill, mitigation, colour: c } => { - // if target.affected(Effect::Electric) && !skill.is_tick() { - // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() - // .find(|e| e.effect == Effect::Electric).unwrap().clone(); - // match meta { - // Some(EffectMeta::Skill(s)) => { - // // Gurad against reflect overflow - // if !(source.affected(Effect::Reflect) && target.affected(Effect::Reflect)) { - // // Check reflect don't bother if electrocute is procing on death - // if source.affected(Effect::Reflect) && !target.is_ko() { - // game.event(Resolution::new(&target, &source) - // .event(Event::Reflection { skill: s }).stages(EventStages::EndPost)); - // electrocute(&mut source, &mut target, resolutions, s); - // } else { - // electrocute(&mut target, &mut source, resolutions, s); - // } - // } - // }, - // _ => panic!("no electrify skill"), - // }; - // } - - // if target.affected(Effect::Absorb) && !target.is_ko() { - // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() - // .find(|e| e.effect == Effect::Absorb).unwrap().clone(); - // match meta { - // Some(EffectMeta::Skill(s)) => { - // absorption(&mut source, &mut target, resolutions, skill, amount + mitigation, s); - // }, - // _ => panic!("no absorb skill"), - // }; - // } - // if c == Colour::Red { - // if target.affected(Effect::Counter) && !target.is_ko() { - // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() - // .find(|e| e.effect == Effect::Counter).unwrap().clone(); - // match meta { - // Some(EffectMeta::Skill(s)) => { - // counter_attack(&mut target, &mut source, resolutions, s); - // }, - // _ => panic!("no counter skill"), - // }; - // } - // } - - // if target.is_ko() && event_target.green == 0 { - // // Make sure target ko is from this event - // target.effects.clear(); - // game.event(Resolution::new(&source, &target).event(Event::Ko()).stages(EventStages::PostOnly)); - // } - // }, - // _ => (), - // }; - - - // game.update_construct(&mut source); - // game.update_construct(&mut target); - // }; -} - - - #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct Cast { pub id: Uuid, @@ -455,18 +109,18 @@ pub type Disable = Vec; pub type Immunity = Vec; #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] -pub struct Resolution { +pub struct Event { pub target: EventConstruct, pub variant: EventVariant, pub stages: EventStages, pub delay: i64, } -impl Resolution { - pub fn new(target: &Construct, variant: EventVariant) -> Resolution { +impl Event { + pub fn new(variant: EventVariant, target: &Construct) -> Event { let stages = variant.stages(); - Resolution { + Event { target: EventConstruct { id: target.id, red: target.red_life(), @@ -474,8 +128,8 @@ impl Resolution { blue: target.blue_life(), }, variant, - stages: stages, delay: stages.delay(), + stages: stages, } } } @@ -551,7 +205,7 @@ pub struct EventConstruct { pub blue: usize, } -#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum EventStages { #[serde(rename = "START_SKILL END_SKILL POST_SKILL")] AllStages, // Anim Anim Anim @@ -1410,24 +1064,63 @@ impl Skill { } } +pub fn cast_actions(cast: Cast) -> Vec { + match cast.skill { -// fn strike(source: &mut Construct, target: &mut Construct, skill: Skill) { -// let amount = source.red_power().pct(skill.multiplier()); -// target.deal_red_damage(skill, amount) -// .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e))); + Skill::Amplify => vec![ + Action::Effect { + construct: cast.target, + skill: cast.skill, + effect: ConstructEffect {effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)), tick: None }, + }, + ], + Skill::AmplifyPlus => vec![ + Action::Effect { + construct: cast.target, + skill: cast.skill, + effect: ConstructEffect {effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)), tick: None }, + }, + ], + Skill::AmplifyPlusPlus => vec![ + Action::Effect { + construct: cast.target, + skill: cast.skill, + effect: ConstructEffect {effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)), tick: None }, + }, + ], + // fn amplify(source: &mut Construct, target: &mut Construct, skill: Skill) { +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } -// fn stun(source: &mut Construct, target: &mut Construct, skill: Skill) { -// skill.effect().into_iter() -// .for_each(|e| (game.event(Resolution::new(source, target).event(target.add_effect(skill, e))))); + Skill::Attack => vec![ + Action::Damage { + construct: cast.target, + skill: cast.skill, + colour: Colour::Red, + values: vec![Value::Stat { construct: cast.source, stat: Stat::RedPower, mult: cast.skill.multiplier() }], + }, + ], -// } + Skill::Strike | + Skill::StrikePlus | + Skill::StrikePlusPlus => vec![ + Action::Damage { + construct: cast.target, + skill: cast.skill, + colour: Colour::Red, + values: vec![Value::Stat { construct: cast.source, stat: Stat::RedPower, mult: cast.skill.multiplier() }], + }, + ], + + _ => unimplemented!() + } + +} // fn bash(source: &mut Construct, target: &mut Construct, skill: Skill) { // skill.effect().into_iter() -// .for_each(|e| (game.event(Resolution::new(source, target).event(target.add_effect(skill, e))))); +// .for_each(|e| (game.event(Event::new(source, target).event(target.add_effect(skill, e))))); // if resolutions.iter().any(|r| match r.event { // Event::Effect { effect, skill: effect_skill, duration: _, construct_effects: _ } @@ -1449,7 +1142,7 @@ impl Skill { // let amount = source.red_power().pct(skill.multiplier().pct(100 + 45usize.saturating_mul(cds))); // target.deal_red_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // } @@ -1457,55 +1150,55 @@ impl Skill { // fn sleep(source: &mut Construct, target: &mut Construct, skill: Skill) { // skill.effect().into_iter() -// .for_each(|e| (game.event(Resolution::new(source, target).event(target.add_effect(skill, e))))); +// .for_each(|e| (game.event(Event::new(source, target).event(target.add_effect(skill, e))))); // let amount = source.green_power().pct(skill.multiplier()); // target.deal_green_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn sustain(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // let red_amount = source.red_power().pct(skill.multiplier()); // target.recharge(skill, red_amount, 0) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn intercept(source: &mut Construct, target: &mut Construct, skill: Skill) { // let intercept = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, intercept))); +// game.event(Event::new(source, target).event(target.add_effect(skill, intercept))); // let red_amount = source.red_power().pct(skill.multiplier()); // target.recharge(skill, red_amount, 0) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn break_(source: &mut Construct, target: &mut Construct, skill: Skill) { // let stun = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, stun))); +// game.event(Event::new(source, target).event(target.add_effect(skill, stun))); // let vuln = skill.effect()[1]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, vuln)).stages(EventStages::PostOnly)); +// game.event(Event::new(source, target).event(target.add_effect(skill, vuln)).stages(EventStages::PostOnly)); // } // fn block(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn buff(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(skill, skill.effect()[0]))); // } // fn counter(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(skill, skill.effect()[0]))); // } @@ -1514,13 +1207,13 @@ impl Skill { // let amount = source.red_power().pct(skill.multiplier()); // target.deal_red_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e))); +// .for_each(|e| game.event(Event::new(source, target).event(e))); // } // fn restrict(source: &mut Construct, target: &mut Construct, skill: Skill) { // skill.effect().into_iter() -// .for_each(|e| (game.event(Resolution::new(source, target).event(target.add_effect(skill, e))))); +// .for_each(|e| (game.event(Event::new(source, target).event(target.add_effect(skill, e))))); // let s_multi = target.skills // .iter() @@ -1532,7 +1225,7 @@ impl Skill { // let amount = source.red_power().pct(skill.multiplier()).pct(s_multi); // target.deal_red_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } @@ -1544,13 +1237,13 @@ impl Skill { // for e in slay_events { // match e { // Event::Damage { amount, mitigation: _, colour: _, skill: _ } => { -// game.event(Resolution::new(source, target).event(e)); +// game.event(Event::new(source, target).event(e)); // let heal = source.deal_green_damage(skill, amount.pct(50)); // for h in heal { -// game.event(Resolution::new(source, source).event(h).stages(EventStages::PostOnly)); +// game.event(Event::new(source, source).event(h).stages(EventStages::PostOnly)); // }; // }, -// _ => game.event(Resolution::new(source, target).event(e)), +// _ => game.event(Event::new(source, target).event(e)), // } // } @@ -1560,7 +1253,7 @@ impl Skill { // let amount = source.green_power().pct(skill.multiplier()); // target.deal_green_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e))); +// .for_each(|e| game.event(Event::new(source, target).event(e))); // } // fn triage(source: &mut Construct, target: &mut Construct, skill: Skill) { @@ -1577,7 +1270,7 @@ impl Skill { // _ => panic!("no triage tick skill"), // }; // let triage = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); -// game.event(Resolution::new(source, target).event(target.add_effect(skill, triage))); +// game.event(Event::new(source, target).event(target.add_effect(skill, triage))); // match skip_tick { // false => return triage_tick(source, target, resolutions, tick_skill) @@ -1588,7 +1281,7 @@ impl Skill { // let amount = source.green_power().pct(skill.multiplier()); // target.deal_green_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::EndPost))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::EndPost))); // } // fn chaos(source: &mut Construct, target: &mut Construct, skill: Skill) { @@ -1597,37 +1290,37 @@ impl Skill { // let amount = source.blue_power().pct(skill.multiplier()).pct(b_rng); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e))); +// .for_each(|e| game.event(Event::new(source, target).event(e))); // let r_rng: usize = rng.gen_range(100, 130); // let amount = source.red_power().pct(skill.multiplier()).pct(r_rng); // target.deal_red_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn blast(source: &mut Construct, target: &mut Construct, skill: Skill) { // let amount = source.blue_power().pct(skill.multiplier()); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e))); +// .for_each(|e| game.event(Event::new(source, target).event(e))); // } // fn amplify(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn haste(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn debuff(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn decay(source: &mut Construct, target: &mut Construct, skill: Skill) { // let wither = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, wither))); +// game.event(Event::new(source, target).event(target.add_effect(skill, wither))); // let skip_tick = target.effects.iter().any(|e| { // match e.effect { @@ -1641,7 +1334,7 @@ impl Skill { // _ => panic!("no decay tick skill"), // }; // let decay = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(skill, decay)) // .stages(EventStages::PostOnly)); @@ -1654,14 +1347,14 @@ impl Skill { // let amount = source.blue_power().pct(skill.multiplier()); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::EndPost))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::EndPost))); // } // // electrify is the buff effect // // when attacked it runs electrocute and applies a debuff // fn electrify(source: &mut Construct, target: &mut Construct, skill: Skill) { // let electrify = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, electrify))); +// game.event(Event::new(source, target).event(target.add_effect(skill, electrify))); // } // fn electrocute(source: &mut Construct, target: &mut Construct, skill: Skill) { @@ -1671,7 +1364,7 @@ impl Skill { // match electric { // Some(eff) => { // let ce = source.effects.remove(eff); -// game.event(Resolution::new(source, source) +// game.event(Event::new(source, source) // .event(Event::Removal { skill, effect: Some(ce.effect), construct_effects: source.effects.clone() }) // .stages(EventStages::PostOnly)); // } @@ -1692,7 +1385,7 @@ impl Skill { // } // }); // let electrocute = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(skill, electrocute)) // .stages(EventStages::PostOnly)); @@ -1706,72 +1399,72 @@ impl Skill { // let amount = source.blue_power().pct(skill.multiplier()); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::EndPost))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::EndPost))); // } // fn ruin(source: &mut Construct, target: &mut Construct, skill: Skill) { // let amount = source.blue_power().pct(skill.multiplier()); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(skill, skill.effect()[0])) // .stages(EventStages::PostOnly)); // } // fn absorb(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // let blue_amount = source.blue_power().pct(skill.multiplier()); // target.recharge(skill, 0, blue_amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn absorption(source: &mut Construct, target: &mut Construct, reflect_skill: Skill, amount: usize, skill: Skill) { // let absorb = skill.effect()[0].set_meta(EffectMeta::AddedDamage(amount)); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(target.add_effect(reflect_skill, absorb)) // .stages(EventStages::PostOnly)); // let absorb_index = target.effects.iter().position(|e| e.effect == Effect::Absorb).expect("No absorb"); // let ce = target.effects.remove(absorb_index); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(Event::Removal { skill, effect: Some(ce.effect), construct_effects: target.effects.clone() }) // .stages(EventStages::PostOnly)); // } // fn curse(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn hybrid(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn invert(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // } // fn reflect(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // let blue_amount = source.blue_power().pct(skill.multiplier()); // target.recharge(skill, 0, blue_amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn recharge(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); +// game.event(Event::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); // let red_amount = source.red_power().pct(skill.multiplier()); // let blue_amount = source.blue_power().pct(skill.multiplier()); // target.recharge(skill, red_amount, blue_amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } @@ -1789,7 +1482,7 @@ impl Skill { // _ => panic!("no siphon tick skill"), // }; // let siphon = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); -// game.event(Resolution::new(source, target).event(target.add_effect(skill, siphon))); +// game.event(Event::new(source, target).event(target.add_effect(skill, siphon))); // match skip_tick { // false => return siphon_tick(source, target, resolutions, tick_skill) @@ -1803,30 +1496,30 @@ impl Skill { // for e in siphon_events { // match e { // Event::Damage { amount, mitigation: _, colour: _, skill: _ } => { -// game.event(Resolution::new(source, target).event(e).stages(EventStages::EndPost)); +// game.event(Event::new(source, target).event(e).stages(EventStages::EndPost)); // let heal = source.deal_green_damage(skill, amount); // for h in heal { -// game.event(Resolution::new(source, source).event(h).stages(EventStages::PostOnly)); +// game.event(Event::new(source, source).event(h).stages(EventStages::PostOnly)); // }; // }, -// _ => game.event(Resolution::new(source, target).event(e).stages(EventStages::EndPost)), +// _ => game.event(Event::new(source, target).event(e).stages(EventStages::EndPost)), // } // } // } // fn link(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // let amount = source.blue_power().pct(skill.multiplier().saturating_mul(target.effects.len() as usize)); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn silence(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); // let s_multi = target.skills // .iter() @@ -1838,43 +1531,43 @@ impl Skill { // let amount = source.blue_power().pct(skill.multiplier()).pct(s_multi); // target.deal_blue_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // fn purge(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); +// game.event(Event::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); // if target.effects.len() > 0 { // target.effects.clear(); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(Event::Removal { skill, effect: None, construct_effects: target.effects.clone() }) // .stages(EventStages::PostOnly)); // } // let effect = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); +// game.event(Event::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); // } // fn purify(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); +// game.event(Event::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); // if target.effects.len() > 0 { // let amount = source.green_power().pct(skill.multiplier().saturating_mul(target.effects.len() as usize)); // target.effects.clear(); -// game.event(Resolution::new(source, target) +// game.event(Event::new(source, target) // .event(Event::Removal { skill, effect: None, construct_effects: target.effects.clone() }) // .stages(EventStages::PostOnly)); // target.deal_green_damage(skill, amount) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // let effect = skill.effect()[0]; -// game.event(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); +// game.event(Event::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); // } // fn banish(source: &mut Construct, target: &mut Construct, skill: Skill) { -// game.event(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); +// game.event(Event::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); // let red_damage = target.red_life().pct(skill.multiplier()); // let blue_damage = target.blue_life().pct(skill.multiplier()); @@ -1882,16 +1575,16 @@ impl Skill { // if red_damage > 0 { // target.deal_red_damage(skill, red_damage) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } // if blue_damage > 0 { // target.deal_blue_damage(skill, blue_damage) // .into_iter() -// .for_each(|e| game.event(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); +// .for_each(|e| game.event(Event::new(source, target).event(e).stages(EventStages::PostOnly))); // } -// game.event(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly)); +// game.event(Event::new(source, target).event(target.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly)); // } // #[cfg(test)] @@ -1956,7 +1649,7 @@ mod tests { // attack(&mut x, &mut y, vec![], Skill::Attack); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Damage { amount, mitigation: _, colour: _, skill: _ } => // assert!(amount < x.red_power().pct(Skill::Attack.multiplier())), @@ -1979,7 +1672,7 @@ mod tests { // assert!(y.affected(Effect::Sustain)); // ruin(&mut x, &mut y, vec![], Skill::Ruin); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Immunity { skill: _, immunity } => assert!(immunity.contains(&Effect::Sustain)), // _ => panic!("not immune cluthc"), @@ -1988,7 +1681,7 @@ mod tests { // attack(&mut x, &mut y, vec![], Skill::Attack); // assert!(y.green_life() == 1); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert_eq!(amount, 1023), // _ => panic!("not damage"), @@ -2049,13 +1742,13 @@ mod tests { // assert!(x.green_life() < 1024); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Reflection { skill } => assert_eq!(skill, Skill::Blast), // _ => panic!("not reflection"), // }; - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert!(amount > 0), // _ => panic!("not damage"), @@ -2081,20 +1774,20 @@ mod tests { // assert!(y.affected(Effect::Siphon)); // assert!(x.green_life() == (512 + 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier()))); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Effect { effect, skill: _, duration: _, construct_effects: _ } => assert_eq!(effect, Effect::Siphon), // _ => panic!("not siphon"), // }; - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Damage { amount, skill: _, mitigation: _, colour: _} => assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier()) // + 220.pct(Skill::SiphonTick.multiplier())), // _ => panic!("not damage siphon"), // }; - // let Resolution { source: _, target, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target, event, stages: _ } = resolutions.remove(0); // match event { // Event::Healing { amount, skill: _, overhealing: _ } => { // assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier())); @@ -2145,7 +1838,7 @@ mod tests { // recharge(&mut x, &mut y, vec![], Skill::Recharge); // resolutions.remove(0); - // let Resolution { source: _, target: _, event, stages: _ } = resolutions.remove(0); + // let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0); // match event { // Event::Recharge { red, blue, skill: _ } => { // assert!(red == 5); @@ -2222,3 +1915,336 @@ mod tests { // assert!(y.disabled(Skill::Heal).is_some()); // } } + + + // Skill::Strike => game.event( + // Event::Damage { + // colour: Colour::Red, + // amount: SkillPower { construct: cast.source, skill: Skill::Strike } + // }, + // Event::LifeSteal { + // amount: CastDamage { id: cast.id, colour: Colour::Red, target: cast.source }, + // }, + // ), + + // Skill::Attack => game.event(Event::Damage { + // colour: Colour::Red, + // amount: Stat { construct: cast.source, stat: Stat::RedPower, pct: ATTACK_RED_POWER_PCT } + // }), + + + // Skill::Bash => game.event(Event::Damage { + // colour: Colour::Red, + // amounts: vec![ + // Stat { construct: cast.source, stat: Stat::RedPower, pct: ATTACK_RED_POWER_PCT }, + // Cooldowns { construct: cast.source }, + // ], + // }) + + // // we clone the current state of the target and source + // // so we can modify them during the resolution + // // no more than 1 mutable ref allowed on game + + // let mut source = game.construct_by_id(cast.source).unwrap().clone(); + // let mut target = game.construct_by_id(target_id).unwrap().clone(); + + // // bail out on ticks that have been removed + // if skill.is_tick() && target.effects.iter().find(|ce| match ce.tick { + // Some(t) => t.id == cast.id, + // None => false, + // }).is_none() { + // return; + // } + + // if let Some(_disable) = source.disabled(skill) { + // game.event(Event::new(source, target).event(Event::Disable { disable, skill }).stages(EventStages::PostOnly)); + // return; + // } + + // if target.is_ko() { + // game.event(Event::new(source, target).event(Event::TargetKo { skill }).stages(EventStages::PostOnly)); + // return; + // } + + // if target.affected(Effect::Reflect) && skill.colours().contains(&Colour::Blue) && !skill.is_tick() { + // // guard against overflow + // if source.affected(Effect::Reflect) { + // } + // game.event(Event::new(source, target).event(Event::Reflection { skill })); + // return cast_actions(skill, &mut source.clone(), source, resolutions); + // } + + + // // haste_strike_check(game) + + // if source.affected(Effect::Haste) { + // match skill { + // Skill::Slay | + // Skill::SlayPlus | + // Skill::SlayPlusPlus | + // Skill::Chaos | + // Skill::ChaosPlus | + // Skill::ChaosPlusPlus | + // Skill::Strike | + // Skill::StrikePlus | + // Skill::StrikePlusPlus => { + // let amount = source.speed().pct(Skill::HasteStrike.multiplier()); + // target.deal_red_damage(Skill::HasteStrike, amount) + // .into_iter() + // .for_each(|e| game.event(Event::new(source, target).event(e))); + // }, + // _ => (), + // } + // } + + // if source.affected(Effect::Hybrid) { + // match skill { + // Skill::Blast| + // Skill::BlastPlus | + // Skill::BlastPlusPlus | + // Skill::Chaos | + // Skill::ChaosPlus | + // Skill::ChaosPlusPlus | + // Skill::Siphon | + // Skill::SiphonPlus | + // Skill::SiphonPlusPlus => { + // let amount = source.green_power().pct(Skill::HybridBlast.multiplier()); + // target.deal_blue_damage(Skill::HybridBlast, amount) + // .into_iter() + // .for_each(|e| game.event(Event::new(source, target).event(e))); + // }, + // _ => (), + // } + // } + + // match self.category() == EffectCategory::Red { + // true => { + // if let Some(evasion) = target.evade(*self) { + // game.event(evasion); + // return Event; + // } + // }, + // false => (), + // } + + // match skill { + // Skill::Amplify| + // Skill::AmplifyPlus | + // Skill::AmplifyPlusPlus => amplify(game, skill), + + // Skill::Banish| + // Skill::BanishPlus | + // Skill::BanishPlusPlus => banish(game, skill), + + // Skill::Bash| + // Skill::BashPlus | + // Skill::BashPlusPlus => bash(game, skill), + + // Skill::Blast| + // Skill::BlastPlus | + // Skill::BlastPlusPlus => blast(game, skill), + + // Skill::Chaos| + // Skill::ChaosPlus | + // Skill::ChaosPlusPlus => chaos(game, skill), + + // Skill::Sustain| + // Skill::SustainPlus | + // Skill::SustainPlusPlus => sustain(game, skill), + + // Skill::Electrify| + // Skill::ElectrifyPlus | + // Skill::ElectrifyPlusPlus => electrify(game, skill), + // Skill::ElectrocuteTick| + // Skill::ElectrocuteTickPlus | + // Skill::ElectrocuteTickPlusPlus => electrocute_tick(game, skill), + + // Skill::Curse| + // Skill::CursePlus | + // Skill::CursePlusPlus => curse(game, skill), + + // Skill::Decay| + // Skill::DecayPlus | + // Skill::DecayPlusPlus => decay(game, skill), + // Skill::DecayTick| + // Skill::DecayTickPlus | + // Skill::DecayTickPlusPlus => decay_tick(game, skill), + + // Skill::Haste| + // Skill::HastePlus | + // Skill::HastePlusPlus => haste(game, skill), + + // Skill::Heal| + // Skill::HealPlus | + // Skill::HealPlusPlus => heal(game, skill), + + // Skill::Absorb| + // Skill::AbsorbPlus | + // Skill::AbsorbPlusPlus => absorb(game, skill), + + // Skill::Hybrid| + // Skill::HybridPlus | + // Skill::HybridPlusPlus => hybrid(game, skill), + + // Skill::Invert| + // Skill::InvertPlus | + // Skill::InvertPlusPlus => invert(game, skill), + + // Skill::Counter| + // Skill::CounterPlus | + // Skill::CounterPlusPlus => counter(game, skill), + + // Skill::Purge| + // Skill::PurgePlus | + // Skill::PurgePlusPlus => purge(game, skill), + + // Skill::Purify| + // Skill::PurifyPlus | + // Skill::PurifyPlusPlus => purify(game, skill), + + // Skill::Recharge| + // Skill::RechargePlus | + // Skill::RechargePlusPlus => recharge(game, skill), + + // Skill::Reflect| + // Skill::ReflectPlus | + // Skill::ReflectPlusPlus => reflect(game, skill), + + // Skill::Ruin| + // Skill::RuinPlus | + // Skill::RuinPlusPlus => ruin(game, skill), + + // Skill::Link| + // Skill::LinkPlus | + // Skill::LinkPlusPlus => link(game, skill), + + // Skill::Silence| + // Skill::SilencePlus | + // Skill::SilencePlusPlus => silence(game, skill), + + // Skill::Siphon| + // Skill::SiphonPlus | + // Skill::SiphonPlusPlus => siphon(game, skill), + // Skill::SiphonTick| + // Skill::SiphonTickPlus | + // Skill::SiphonTickPlusPlus => siphon_tick(game, skill), + + // Skill::Slay| + // Skill::SlayPlus | + // Skill::SlayPlusPlus => slay(game, skill), + + // Skill::Sleep| + // Skill::SleepPlus | + // Skill::SleepPlusPlus => sleep(game, skill), + + // Skill::Restrict| + // Skill::RestrictPlus | + // Skill::RestrictPlusPlus => restrict(game, skill), + + // Skill::Strike| + // Skill::StrikePlus | + // Skill::StrikePlusPlus => strike(game, skill), + + // Skill::Intercept| + // Skill::InterceptPlus | + // Skill::InterceptPlusPlus => intercept(game, skill), + + // Skill::Break| + // Skill::BreakPlus | + // Skill::BreakPlusPlus => break_(game, skill), + + // Skill::Triage| + // Skill::TriagePlus | + // Skill::TriagePlusPlus => triage(game, skill), + + // Skill::TriageTick| + // Skill::TriageTickPlus | + // Skill::TriageTickPlusPlus => triage_tick(game, skill), + + // // Base Skills + // Skill::Attack => attack(game, skill), + // Skill::Block => block(game, skill), + // Skill::Buff => buff(game, skill), + // Skill::Debuff => debuff(game, skill), + // Skill::Stun => stun(game, skill), + + // // Triggered + // Skill::Electrocute | + // Skill::ElectrocutePlus | + // Skill::ElectrocutePlusPlus => panic!("should only trigger from electrify hit"), + // Skill::HasteStrike => panic!("should only trigger from haste"), + // Skill::Absorption| + // Skill::AbsorptionPlus | + // Skill::AbsorptionPlusPlus => panic!("should only trigger from absorb"), + // Skill::HybridBlast => panic!("should only trigger from hybrid"), + // Skill::CounterAttack| + // Skill::CounterAttackPlus | + // Skill::CounterAttackPlusPlus => panic!("should only trigger from counter"), + + + // // Not used + // }; + + // for Event { source: event_source, target: event_target, event, stages: _ } in resolutions.clone() { + // let mut source = game.construct_by_id(event_source.id).unwrap().clone(); + // let mut target = game.construct_by_id(event_target.id).unwrap().clone(); + + // match event { + // Event::Damage { amount, skill, mitigation, colour: c } => { + // if target.affected(Effect::Electric) && !skill.is_tick() { + // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() + // .find(|e| e.effect == Effect::Electric).unwrap().clone(); + // match meta { + // Some(EffectMeta::Skill(s)) => { + // // Gurad against reflect overflow + // if !(source.affected(Effect::Reflect) && target.affected(Effect::Reflect)) { + // // Check reflect don't bother if electrocute is procing on death + // if source.affected(Effect::Reflect) && !target.is_ko() { + // game.event(Event::new(&target, &source) + // .event(Event::Reflection { skill: s }).stages(EventStages::EndPost)); + // electrocute(&mut source, &mut target, resolutions, s); + // } else { + // electrocute(&mut target, &mut source, resolutions, s); + // } + // } + // }, + // _ => panic!("no electrify skill"), + // }; + // } + + // if target.affected(Effect::Absorb) && !target.is_ko() { + // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() + // .find(|e| e.effect == Effect::Absorb).unwrap().clone(); + // match meta { + // Some(EffectMeta::Skill(s)) => { + // absorption(&mut source, &mut target, resolutions, skill, amount + mitigation, s); + // }, + // _ => panic!("no absorb skill"), + // }; + // } + // if c == Colour::Red { + // if target.affected(Effect::Counter) && !target.is_ko() { + // let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() + // .find(|e| e.effect == Effect::Counter).unwrap().clone(); + // match meta { + // Some(EffectMeta::Skill(s)) => { + // counter_attack(&mut target, &mut source, resolutions, s); + // }, + // _ => panic!("no counter skill"), + // }; + // } + // } + + // if target.is_ko() && event_target.green == 0 { + // // Make sure target ko is from this event + // target.effects.clear(); + // game.event(Event::new(&source, &target).event(Event::Ko()).stages(EventStages::PostOnly)); + // } + // }, + // _ => (), + // }; + + + // game.update_construct(&mut source); + // game.update_construct(&mut target); + // };