another one

This commit is contained in:
ntr 2019-03-25 13:45:23 +11:00
parent aa2832f4d8
commit c3beed3690
3 changed files with 215 additions and 172 deletions

View File

@ -9,7 +9,7 @@ use failure::err_msg;
use account::{Account};
use rpc::{CrypSpawnParams};
use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, ResolutionResult};
use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, Event};
use spec::{Spec};
use game::{Log};
use vbox::Var;
@ -449,9 +449,9 @@ impl Cryp {
}
}
pub fn recharge(&mut self) -> ResolutionResult {
pub fn recharge(&mut self) -> Event {
if let Some(immunity) = self.immune(Skill::Recharge) {
return ResolutionResult::Immunity {
return Event::Immunity {
immunity,
};
}
@ -462,12 +462,12 @@ impl Cryp {
let blue = self.blue_shield.max.saturating_sub(self.blue_shield.value);
self.blue_shield.value = self.blue_shield.max;
ResolutionResult::Recharge { red, blue }
Event::Recharge { red, blue }
}
pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> Event {
if let Some(immunity) = self.immune(skill) {
return ResolutionResult::Immunity {
return Event::Immunity {
immunity,
};
}
@ -490,7 +490,7 @@ impl Cryp {
let healing = new_hp - current_hp;
let overhealing = modified_healing - healing;
return ResolutionResult::Healing {
return Event::Healing {
amount: healing,
overhealing,
};
@ -501,7 +501,7 @@ impl Cryp {
self.reduce_hp(modified_healing);
let delta = current_hp - self.hp();
return ResolutionResult::Inversion {
return Event::Inversion {
damage: delta,
healing: 0,
recharge: 0,
@ -511,9 +511,9 @@ impl Cryp {
}
}
pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> Event {
if let Some(immunity) = self.immune(skill) {
return ResolutionResult::Immunity {
return Event::Immunity {
immunity,
};
}
@ -544,7 +544,7 @@ impl Cryp {
self.reduce_hp(remainder);
let delta = current_hp - self.hp();
return ResolutionResult::Damage {
return Event::Damage {
amount: delta,
mitigation,
category: Category::RedDamage,
@ -561,7 +561,7 @@ impl Cryp {
self.red_shield.increase(overhealing);
let recharge = self.red_shield.value - current_shield;
return ResolutionResult::Inversion {
return Event::Inversion {
damage: 0,
healing,
recharge,
@ -571,9 +571,9 @@ impl Cryp {
}
}
pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> Event {
if let Some(immunity) = self.immune(skill) {
return ResolutionResult::Immunity {
return Event::Immunity {
immunity,
};
}
@ -597,7 +597,7 @@ impl Cryp {
self.reduce_hp(remainder);
let delta = current_hp - self.hp();
return ResolutionResult::Damage {
return Event::Damage {
amount: delta,
mitigation,
category: Category::BlueDamage,
@ -614,7 +614,7 @@ impl Cryp {
self.blue_shield.increase(overhealing);
let recharge = self.blue_shield.value - current_shield;
return ResolutionResult::Inversion {
return Event::Inversion {
damage: 0,
healing,
recharge,
@ -624,15 +624,15 @@ impl Cryp {
}
}
pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult {
pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> Event {
if let Some(immunity) = self.immune(skill) {
return ResolutionResult::Immunity {
return Event::Immunity {
immunity,
};
}
// todo modified durations cause of buffs
let result = ResolutionResult::Effect {
let result = Event::Effect {
effect: effect.effect,
duration: effect.effect.duration(),
};
@ -643,7 +643,7 @@ impl Cryp {
return result;
}
pub fn evade(&self, skill: Skill) -> Option<ResolutionResult> {
pub fn evade(&self, skill: Skill) -> Option<Event> {
if self.evasion.value == 0 {
return None;
}
@ -655,7 +655,7 @@ impl Cryp {
println!("{:} < {:?}", roll, evasion_rating);
match roll < evasion_rating {
true => Some(ResolutionResult::Evasion {
true => Some(Event::Evasion {
skill,
evasion_rating: evasion_rating,
}),

View File

@ -10,7 +10,7 @@ use failure::err_msg;
use account::Account;
use rpc::{GameStateParams, GameSkillParams};
use cryp::{Cryp};
use skill::{Skill, Cast, ResolutionResult};
use skill::{Skill, Cast, Resolution, Event};
use player::{Player};
use instance::{instance_game_finished, global_game_finished};
@ -168,6 +168,17 @@ impl Game {
}
}
pub fn cryp_name(&mut self, id: Uuid) -> String {
match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == id)) {
Some(team) => {
let cryp = team.cryps.iter_mut().find(|c| c.id == id).expect("cryp not in team");
return cryp.name.clone();
}
None => panic!("{:?} not in game", id),
}
}
fn all_cryps(&self) -> Vec<Cryp> {
self.teams.clone()
.into_iter()
@ -361,56 +372,61 @@ impl Game {
self.resolve_skills()
}
fn log_resolution(&mut self, cast: &Cast) -> &mut Game {
let source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone();
let target = self.cryp_by_id(cast.target_cryp_id).unwrap().clone();
// remove names from the cast
// put them in teh result
// just add the results to the resolved vec
// try remove casts altogether
for result in cast.resolution.results.iter() {
match result {
ResolutionResult::Disable { disable } =>
fn log_resolution(&mut self, cast: &Cast) -> &mut Game {
for resolution in cast.resolutions.iter() {
let Resolution { source, target, event } = resolution;
match event {
Event::Disable { disable } =>
self.log.push(format!("{:} {:?} {:} disabled {:?}",
source.name, cast.skill, target.name, disable)),
ResolutionResult::Immunity { immunity } =>
Event::Immunity { immunity } =>
self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}",
cast.resolution.speed, source.name, cast.skill, target.name, immunity)),
cast.speed, source.name, cast.skill, target.name, immunity)),
ResolutionResult::TargetKo =>
Event::TargetKo =>
self.log.push(format!("[{:}] {:} {:?} {:} - KO",
cast.resolution.speed, source.name, cast.skill, target.name)),
cast.speed, source.name, cast.skill, target.name)),
ResolutionResult::Damage { amount, mitigation, category: _ } =>
Event::Damage { amount, mitigation, category: _ } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)",
cast.resolution.speed, source.name, cast.skill, target.name, amount, mitigation)),
cast.speed, source.name, cast.skill, target.name, amount, mitigation)),
ResolutionResult::Healing { amount, overhealing } =>
Event::Healing { amount, overhealing } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:}OH)",
cast.resolution.speed, source.name, cast.skill, target.name, amount, overhealing)),
cast.speed, source.name, cast.skill, target.name, amount, overhealing)),
ResolutionResult::Inversion { healing, damage, recharge, category: _ } => {
Event::Inversion { healing, damage, recharge, category: _ } => {
match *healing > 0 {
true => self.log.push(format!("[{:}] {:} {:?} {:} INVERTED {:} ({:} recharge)",
cast.resolution.speed, source.name, cast.skill, target.name, healing, recharge)),
cast.speed, source.name, cast.skill, target.name, healing, recharge)),
false => self.log.push(format!("[{:}] {:} {:?} {:} INVERTED {:}",
cast.resolution.speed, source.name, cast.skill, target.name, damage)),
cast.speed, source.name, cast.skill, target.name, damage)),
}
},
ResolutionResult::Effect { effect, duration } =>
Event::Effect { effect, duration } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:?} {:}T",
cast.resolution.speed, source.name, cast.skill, target.name, effect, duration)),
cast.speed, source.name, cast.skill, target.name, effect, duration)),
ResolutionResult::Removal { effect } =>
Event::Removal { effect } =>
self.log.push(format!("[{:}] {:?} removed {:} {:?}",
cast.resolution.speed, source.name, target.name, effect)),
cast.speed, source.name, target.name, effect)),
ResolutionResult::Recharge { red, blue } =>
Event::Recharge { red, blue } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:}R {:}B",
cast.resolution.speed, source.name, cast.skill, target.name, red, blue)),
cast.speed, source.name, cast.skill, target.name, red, blue)),
ResolutionResult::Evasion { skill: _, evasion_rating } =>
Event::Evasion { skill: _, evasion_rating } =>
self.log.push(format!("[{:}] {:} {:?} {:} evaded ({:}%)",
cast.resolution.speed, source.name, cast.skill, target.name, evasion_rating)),
cast.speed, source.name, cast.skill, target.name, evasion_rating)),
Event::Incomplete => panic!("incomplete resolution {:?}", resolution),
}
}

View File

@ -8,11 +8,12 @@ use game::{Game};
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub struct Cast {
pub id: Uuid,
pub skill: Skill,
pub source_team_id: Uuid,
pub source_cryp_id: Uuid,
pub target_cryp_id: Uuid,
pub resolution: Resolution,
pub skill: Skill,
pub speed: u64,
pub resolutions: Resolutions,
}
impl Cast {
@ -23,7 +24,8 @@ impl Cast {
source_team_id,
target_cryp_id,
skill,
resolution: Resolution::new(skill),
speed: 0,
resolutions: vec![],
};
}
@ -34,7 +36,7 @@ impl Cast {
pub fn finalise(&mut self, game: &mut Game) -> &mut Cast {
let mut results = vec![];
let mut source = game.cryp_by_id(self.source_cryp_id).unwrap().clone();
self.resolution.speed = source.skill_speed(self.skill);
self.speed = source.skill_speed(self.skill);
let targets = match source.skill_is_aoe(self.skill) {
true => game.cryp_aoe_targets(self.target_cryp_id),
@ -47,7 +49,7 @@ impl Cast {
results.append(&mut self.skill.resolve(&mut source, target));
}
self.resolution.results = results;
self.resolutions = results;
self
}
@ -60,7 +62,36 @@ pub type Disable = Vec<Effect>;
pub type Immunity = Vec<Effect>;
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum ResolutionResult {
pub struct LogCryp {
pub id: Uuid,
pub name: String,
}
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub struct Resolution {
pub source: LogCryp,
pub target: LogCryp,
pub event: Event,
}
impl Resolution {
fn new(source: &Cryp, target: &Cryp) -> Resolution {
Resolution {
source: LogCryp { id: source.id, name: source.name.clone() },
target: LogCryp { id: target.id, name: target.name.clone() },
event: Event::Incomplete,
}
}
fn event(mut self, e: Event) -> Resolution {
self.event = e;
self
}
}
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum Event {
TargetKo,
Disable { disable: Disable },
Immunity { immunity: Immunity },
@ -71,21 +102,11 @@ pub enum ResolutionResult {
Effect { effect: Effect, duration: u8 },
Removal { effect: Effect },
Evasion { skill: Skill, evasion_rating: u64 },
Incomplete,
}
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub struct Resolution {
pub skill: Skill,
pub speed: u64,
pub results: Vec<ResolutionResult>,
}
impl Resolution {
fn new(skill: Skill) -> Resolution {
Resolution { skill, results: vec![], speed: 0 }
}
}
type Resolutions = Vec<Resolution>;
pub type Cooldown = Option<u8>;
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -579,14 +600,14 @@ impl Skill {
}
}
pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp) -> Vec<ResolutionResult> {
pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp) -> Resolutions {
let mut rng = thread_rng();
let _base: u64 = rng.gen();
let mut results = vec![];
if let Some(disable) = source.disabled(*self) {
results.push(ResolutionResult::Disable { disable });
results.push(Resolution::new(source, target).event(Event::Disable { disable }));
return results;
}
@ -594,14 +615,14 @@ impl Skill {
// true => {
// if let Some(evasion) = target.evade(*self) {
// results.push(evasion);
// return resolution;
// return Event;
// }
// },
// false => (),
// }
if target.is_ko() {
results.push(ResolutionResult::TargetKo);
results.push(Resolution::new(source, target).event(Event::TargetKo));
return results;
}
@ -687,197 +708,198 @@ impl Skill {
}
}
fn attack(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.red_damage();
results.push(target.deal_red_damage(Skill::Attack, amount));
fn attack(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.red_damage();
results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::Attack, amount)));
return results;
}
fn stun(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn stun(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
results.push(target.add_effect(Skill::Stun, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Stun, effect)));
return results;
}
fn clutch(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn clutch(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Clutch, duration: Effect::Clutch.duration(), tick: None };
results.push(target.add_effect(Skill::Clutch, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Clutch, effect)));
return results;
}
fn throw(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn throw(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let stun = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Effect::Vulnerable.duration(), tick: None };
results.push(target.add_effect(Skill::Throw, stun));
results.push(target.add_effect(Skill::Throw, vulnerable));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Throw, stun)));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Throw, vulnerable)));
return results;
}
fn strangle(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn strangle(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let target_stun = CrypEffect {
effect: Effect::Strangle,
duration: Effect::Strangle.duration(),
tick: Some(Cast::new_tick(cryp, target, Skill::StrangleTick))
tick: Some(Cast::new_tick(source, target, Skill::StrangleTick))
};
let attacker_immunity = CrypEffect { effect: Effect::Strangling, duration: Effect::Strangling.duration(), tick: None };
results.push(target.add_effect(Skill::Strangle, target_stun));
results.push(cryp.add_effect(Skill::Strangle, attacker_immunity));
return strangle_tick(cryp, target, results);
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Strangle, target_stun)));
results.push(Resolution::new(source, source).event(source.add_effect(Skill::Strangle, attacker_immunity)));
return strangle_tick(source, target, results);
}
fn strangle_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.red_damage();
results.push(target.deal_red_damage(Skill::StrangleTick, amount));
fn strangle_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.red_damage();
results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::StrangleTick, amount)));
// remove immunity if target ko
if target.is_ko() {
let i = cryp.effects
let i = source.effects
.iter()
.position(|e| e.effect == Effect::Strangling)
.expect("no strangling on cryp");
cryp.effects.remove(i);
source.effects.remove(i);
results.push(Resolution::new(source, source).event(Event::Removal { effect: Effect::Strangling }));
}
return results;
}
fn block(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn block(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let block = CrypEffect { effect: Effect::Block, duration: Effect::Block.duration(), tick: None };
results.push(target.add_effect(Skill::Block, block));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Block, block)));
return results;
}
fn parry(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn parry(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Parry, duration: Effect::Parry.duration(), tick: None };
results.push(target.add_effect(Skill::Parry, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Parry, effect)));
return results;
}
fn snare(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let snare = CrypEffect { effect: Effect::Snare, duration: Effect::Snare.duration(), tick: None };
results.push(target.add_effect(Skill::Snare, snare));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Snare, snare)));
return results;
}
fn empower(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn empower(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let empower = CrypEffect { effect: Effect::Empower, duration: Effect::Empower.duration(), tick: None };
results.push(target.add_effect(Skill::Empower, empower));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Empower, empower)));
return results;
}
fn heal(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.green_damage();
results.push(target.deal_green_damage(Skill::Heal, amount));
fn heal(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.green_damage();
results.push(Resolution::new(source, target).event(target.deal_green_damage(Skill::Heal, amount)));
return results;
}
fn triage(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn triage(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect {
effect: Effect::Triage,
duration: Effect::Triage.duration(),
tick: Some(Cast::new_tick(cryp, target, Skill::TriageTick)),
tick: Some(Cast::new_tick(source, target, Skill::TriageTick)),
};
results.push(target.add_effect(Skill::Triage, effect));
return triage_tick(cryp, target, results);
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Triage, effect)));
return triage_tick(source, target, results);
}
fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.blue_damage().wrapping_div(2);
results.push(target.deal_green_damage(Skill::TriageTick, amount));
fn triage_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.green_damage().wrapping_div(2);
results.push(Resolution::new(source, target).event(target.deal_green_damage(Skill::TriageTick, amount)));
return results;
}
fn blast(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.blue_damage();
results.push(target.deal_blue_damage(Skill::Blast, amount));
fn blast(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.blue_damage();
results.push(Resolution::new(source, target).event(target.deal_blue_damage(Skill::Blast, amount)));
return results;
}
fn amplify(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn amplify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amplify = CrypEffect { effect: Effect::Amplify, duration: Effect::Amplify.duration(), tick: None };
results.push(target.add_effect(Skill::Amplify, amplify));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Amplify, amplify)));
return results;;
}
fn haste(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn haste(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Haste, duration: Effect::Haste.duration(), tick: None };
results.push(target.add_effect(Skill::Haste, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Haste, effect)));
return results;;
}
fn slow(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn slow(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Slow, duration: Effect::Slow.duration(), tick: None };
results.push(target.add_effect(Skill::Slow, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Slow, effect)));
return results;;
}
fn decay(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn decay(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let decay = CrypEffect {
effect: Effect::Decay,
duration: Effect::Decay.duration(),
tick: Some(Cast::new_tick(cryp, target, Skill::DecayTick)),
tick: Some(Cast::new_tick(source, target, Skill::DecayTick)),
};
results.push(target.add_effect(Skill::Decay, decay));
return decay_tick(cryp, target, results);
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Decay, decay)));
return decay_tick(source, target, results);
}
fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.blue_damage();
results.push(target.deal_blue_damage(Skill::DecayTick, amount));
fn decay_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.blue_damage();
results.push(Resolution::new(source, target).event(target.deal_blue_damage(Skill::DecayTick, amount)));
return results;
}
fn hex(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn hex(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let hex = CrypEffect { effect: Effect::Hex, duration: Effect::Hex.duration(), tick: None };
results.push(target.add_effect(Skill::Hex, hex));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Hex, hex)));
return results;;
}
fn curse(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn curse(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let curse = CrypEffect { effect: Effect::Curse, duration: Effect::Curse.duration(), tick: None };
results.push(target.add_effect(Skill::Curse, curse));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Curse, curse)));
return results;;
}
fn invert(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn invert(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Invert, duration: Effect::Invert.duration(), tick: None };
results.push(target.add_effect(Skill::Invert, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Invert, effect)));
return results;;
}
fn reflect(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn reflect(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Reflect, duration: Effect::Reflect.duration(), tick: None };
results.push(target.add_effect(Skill::Reflect, effect));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Reflect, effect)));
return results;;
}
fn recharge(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
results.push(target.recharge());
fn recharge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
results.push(Resolution::new(source, target).event(target.recharge()));
return results;
}
fn siphon(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn siphon(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let siphon = CrypEffect {
effect: Effect::Siphon,
duration: Effect::Siphon.duration(),
tick: Some(Cast::new_tick(cryp, target, Skill::SiphonTick)),
tick: Some(Cast::new_tick(source, target, Skill::SiphonTick)),
};
results.push(target.add_effect(Skill::Siphon, siphon));
return siphon_tick(cryp, target, results);
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Siphon, siphon)));
return siphon_tick(source, target, results);
}
fn siphon_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let amount = cryp.blue_damage();
fn siphon_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.blue_damage();
let siphon_damage = target.deal_blue_damage(Skill::SiphonTick, amount);
results.push(siphon_damage.clone());
results.push(Resolution::new(source, target).event(siphon_damage.clone()));
match siphon_damage {
ResolutionResult::Damage { amount, mitigation: _, category: _, } => {
results.push(cryp.deal_green_damage(Skill::Heal, amount));
Event::Damage { amount, mitigation: _, category: _, } => {
results.push(Resolution::new(source, source).event(source.deal_green_damage(Skill::Heal, amount)));
},
_ => panic!("siphon tick damage not dealt {:?}", siphon_damage),
}
@ -885,49 +907,49 @@ fn siphon_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionRe
return results;
}
fn shield(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn shield(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let shield = CrypEffect { effect: Effect::Shield, duration: Effect::Shield.duration(), tick: None };
results.push(target.add_effect(Skill::Shield, shield));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Shield, shield)));
return results;
}
fn silence(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn silence(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let silence = CrypEffect { effect: Effect::Silence, duration: Effect::Silence.duration(), tick: None };
results.push(target.add_effect(Skill::Silence, silence));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Silence, silence)));
return results;
}
fn purge(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn purge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
if ce.effect.category() == Category::BlueBuff {
target.effects.remove(i);
results.push(ResolutionResult::Removal { effect: ce.effect });
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
}
}
return results;
}
fn purify(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn purify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
if ce.effect.category() == Category::BlueDebuff {
target.effects.remove(i);
results.push(ResolutionResult::Removal { effect: ce.effect });
results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect }));
}
}
return results;
}
fn banish(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
fn banish(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let banish = CrypEffect { effect: Effect::Banish, duration: Effect::Banish.duration(), tick: None };
results.push(target.add_effect(Skill::Banish, banish));
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Banish, banish)));
return results;
}
fn strike(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec<ResolutionResult>) -> Vec<ResolutionResult> {
let _amount = cryp.red_damage();
results.push(target.deal_red_damage(Skill::Attack, u64::max_value()));
fn strike(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let _amount = source.red_damage();
results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::Attack, u64::max_value())));
return results;
}
@ -984,10 +1006,11 @@ mod tests {
block(&mut y.clone(), &mut y, vec![]);
assert!(y.effects.iter().any(|e| e.effect == Effect::Block));
let results = attack(&mut x, &mut y, vec![]);
let mut results = attack(&mut x, &mut y, vec![]);
match results[0] {
ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 50),
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 50),
_ => panic!("not damage"),
};
}
@ -1005,11 +1028,12 @@ mod tests {
clutch(&mut y.clone(), &mut y, vec![]);
assert!(y.is_clutch());
let results = attack(&mut x, &mut y, vec![]);
let mut results = attack(&mut x, &mut y, vec![]);
assert!(y.hp() == 1);
match results[0] {
ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 1023),
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 1023),
_ => panic!("not damage"),
};
}
@ -1035,11 +1059,12 @@ mod tests {
assert!(y.hp() == 768);
// attack should heal and recharge red shield
let results = attack(&mut x, &mut y, vec![]);
let mut results = attack(&mut x, &mut y, vec![]);
assert!(y.hp() == 1024);
match results[0] {
ResolutionResult::Inversion { damage: _, healing: _, recharge, category: _ } => assert_eq!(recharge, 64),
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Inversion { damage: _, healing: _, recharge, category: _ } => assert_eq!(recharge, 64),
_ => panic!("not inversion"),
};
}
@ -1055,12 +1080,13 @@ mod tests {
reflect(&mut y.clone(), &mut y, vec![]);
assert!(y.is_reflecting());
let results = Skill::Attack.resolve(&mut x, &mut y);
let mut results = Skill::Attack.resolve(&mut x, &mut y);
assert!(x.hp() == 768);
match results[0] {
ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 256),
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 256),
_ => panic!("not damage"),
};
}
@ -1083,7 +1109,7 @@ mod tests {
y.deal_red_damage(Skill::Attack, 5);
let prev_hp = y.hp();
let results = triage(&mut x, &mut y, vec![]);
let _results = triage(&mut x, &mut y, vec![]);
assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
assert!(y.hp() > prev_hp);
@ -1103,10 +1129,11 @@ mod tests {
y.deal_red_damage(Skill::Attack, 5);
y.deal_blue_damage(Skill::Blast, 5);
let results = recharge(&mut x, &mut y, vec![]);
let mut results = recharge(&mut x, &mut y, vec![]);
match results[0] {
ResolutionResult::Recharge { red, blue } => {
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Recharge { red, blue } => {
assert!(red == 5);
assert!(blue == 5);
}