This commit is contained in:
ntr 2019-03-22 15:58:24 +11:00
parent 5dab6f621b
commit a65d62c86a
5 changed files with 167 additions and 49 deletions

View File

@ -34,6 +34,13 @@ change to ownership pattern
## SOON ## SOON
* vbox drops chances * vbox drops chances
* 50% spec, 25% colour etc * 50% spec, 25% colour etc
* rework damage and resolutions
deal_damage(colour)
resolutions.push(skill()).flatten()
overkill in logs
immunity resolution type
* confirm cryp without skill ready * confirm cryp without skill ready
* iconography * iconography
* aoe skills * aoe skills

View File

@ -297,6 +297,10 @@ impl Cryp {
self.effects.iter().any(|s| s.effect == Effect::Stun) self.effects.iter().any(|s| s.effect == Effect::Stun)
} }
pub fn is_inverted(&self) -> bool {
self.effects.iter().any(|s| s.effect == Effect::Invert)
}
pub fn available_skills(&self) -> Vec<&CrypSkill> { pub fn available_skills(&self) -> Vec<&CrypSkill> {
self.skills.iter() self.skills.iter()
.filter(|s| s.cd.is_none()) .filter(|s| s.cd.is_none())
@ -456,7 +460,7 @@ impl Cryp {
let immune = immunity.immune; let immune = immunity.immune;
if immune { if immune {
ResolutionResult::Healing { return ResolutionResult::Healing {
amount: 0, amount: 0,
overhealing: 0, overhealing: 0,
immunity: immunity.clone(), immunity: immunity.clone(),
@ -472,18 +476,34 @@ impl Cryp {
let modified_healing = healing_mods.iter().fold(amount, |acc, m| m.apply(acc)); let modified_healing = healing_mods.iter().fold(amount, |acc, m| m.apply(acc));
let current_hp = self.hp(); match self.is_inverted() {
self.hp.increase(modified_healing); false => {
let new_hp = self.hp.value; let current_hp = self.hp();
self.hp.increase(modified_healing);
let new_hp = self.hp.value;
let healing = new_hp - current_hp; let healing = new_hp - current_hp;
let overhealing = modified_healing - healing; let overhealing = modified_healing - healing;
return ResolutionResult::Healing { return ResolutionResult::Healing {
amount: healing, amount: healing,
overhealing, overhealing,
immunity, immunity,
}; };
},
true => {
// there is no green shield (yet)
self.hp.reduce(modified_healing);
return ResolutionResult::Inversion {
damage: modified_healing,
healing: 0,
recharge: 0,
category: Category::GreenDamage,
immunity,
};
}
}
} }
pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult { pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
@ -508,25 +528,48 @@ impl Cryp {
let modified_damage = red_damage_mods.iter().fold(amount, |acc, m| m.apply(acc)); let modified_damage = red_damage_mods.iter().fold(amount, |acc, m| m.apply(acc));
// calculate amount of damage red_shield will not absorb match self.is_inverted() {
// eg 50 red_shield 25 damage -> 0 remainder 25 mitigation false => {
// 50 red_shield 100 damage -> 50 remainder 50 mitigation // calculate amount of damage red_shield will not absorb
// 50 red_shield 5 damage -> 0 remainder 5 mitigation // eg 50 red_shield 25 damage -> 0 remainder 25 mitigation
let remainder = modified_damage.saturating_sub(self.red_shield.value); // 50 red_shield 100 damage -> 50 remainder 50 mitigation
let mitigation = modified_damage.saturating_sub(remainder); // 50 red_shield 5 damage -> 0 remainder 5 mitigation
let remainder = modified_damage.saturating_sub(self.red_shield.value);
let mitigation = modified_damage.saturating_sub(remainder);
// reduce red_shield by mitigation amount // reduce red_shield by mitigation amount
self.red_shield.reduce(mitigation); self.red_shield.reduce(mitigation);
// deal remainder to hp // deal remainder to hp
self.hp.reduce(remainder); self.hp.reduce(remainder);
return ResolutionResult::Damage { return ResolutionResult::Damage {
amount: remainder, amount: remainder,
mitigation, mitigation,
category: Category::RedDamage, category: Category::RedDamage,
immunity, immunity,
}; };
},
true => {
let current_hp = self.hp();
self.hp.increase(modified_damage);
let new_hp = self.hp.value;
let healing = new_hp - current_hp;
let overhealing = modified_damage - healing;
let current_shield = self.red_shield.value;
self.red_shield.increase(overhealing);
let recharge = self.red_shield.value - current_shield;
return ResolutionResult::Inversion {
damage: 0,
healing,
recharge,
immunity,
category: Category::RedDamage,
};
}
}
} }
pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult { pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
@ -548,20 +591,43 @@ impl Cryp {
.collect::<Vec<Effect>>(); .collect::<Vec<Effect>>();
// println!("{:?}", blue_damage_mods); // println!("{:?}", blue_damage_mods);
let modified_damage = blue_damage_mods.iter().fold(amount, |acc, m| m.apply(acc)); let modified_damage = blue_damage_mods.iter().fold(amount, |acc, m| m.apply(acc));
let remainder = modified_damage.saturating_sub(self.blue_shield.value);
let mitigation = modified_damage.saturating_sub(remainder);
self.blue_shield.reduce(mitigation); match self.is_inverted() {
self.hp.reduce(remainder); false => {
let remainder = modified_damage.saturating_sub(self.blue_shield.value);
let mitigation = modified_damage.saturating_sub(remainder);
return ResolutionResult::Damage { self.blue_shield.reduce(mitigation);
amount: remainder, self.hp.reduce(remainder);
mitigation,
category: Category::BlueDamage, return ResolutionResult::Damage {
immunity, amount: remainder,
}; mitigation,
category: Category::BlueDamage,
immunity,
};
},
true => {
let current_hp = self.hp();
self.hp.increase(modified_damage);
let new_hp = self.hp.value;
let healing = new_hp - current_hp;
let overhealing = modified_damage - healing;
let current_shield = self.blue_shield.value;
self.blue_shield.increase(overhealing);
let recharge = self.blue_shield.value - current_shield;
return ResolutionResult::Inversion {
damage: 0,
healing,
recharge,
immunity,
category: Category::BlueDamage,
};
}
}
} }
pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult { pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult {

View File

@ -382,6 +382,18 @@ impl Game {
cast.resolution.speed, source.name, cast.skill, target.name, amount, overhealing)), cast.resolution.speed, source.name, cast.skill, target.name, amount, overhealing)),
} }
}, },
ResolutionResult::Inversion { healing, damage, recharge, category: _, immunity } => {
match immunity.immune {
true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}",
cast.resolution.speed, source.name, cast.skill, target.name, immunity.effects)),
false => match *healing > 0 {
true => self.log.push(format!("[{:}] {:} {:?} {:} INVERTED {:} ({:} recharge)",
cast.resolution.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)),
}
}
},
ResolutionResult::Effect { effect, duration, immunity } => { ResolutionResult::Effect { effect, duration, immunity } => {
match immunity.immune { match immunity.immune {
true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}", true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}",

View File

@ -63,6 +63,7 @@ pub enum ResolutionResult {
Damage { amount: u64, mitigation: u64, category: Category , immunity: Immunity }, Damage { amount: u64, mitigation: u64, category: Category , immunity: Immunity },
Healing { amount: u64, overhealing: u64, immunity: Immunity }, Healing { amount: u64, overhealing: u64, immunity: Immunity },
Recharge { red: u64, blue: u64, immunity: Immunity }, Recharge { red: u64, blue: u64, immunity: Immunity },
Inversion { healing: u64, damage: u64, recharge: u64, category: Category, immunity: Immunity },
Effect { effect: Effect, duration: u8, immunity: Immunity }, Effect { effect: Effect, duration: u8, immunity: Immunity },
Removal { effect: Effect, immunity: Immunity }, Removal { effect: Effect, immunity: Immunity },
Evasion { skill: Skill, evasion_rating: u64 }, Evasion { skill: Skill, evasion_rating: u64 },
@ -305,6 +306,7 @@ pub enum Category {
BlueBuff, BlueBuff,
BlueTick, BlueTick,
Green, Green,
GreenDamage,
GreenBuff, GreenBuff,
Ko, Ko,
} }
@ -959,6 +961,37 @@ mod tests {
}; };
} }
#[test]
fn invert_test() {
let mut x = Cryp::new()
.named(&"muji".to_string());
let mut y = Cryp::new()
.named(&"camel".to_string());
// give red shield but reduce to 0
y.red_shield.force(64);
y.red_shield.reduce(64);
x.red_damage.force(256 + 64);
invert(&mut y.clone(), &mut y, Resolution::new(Skill::Invert));
assert!(y.is_inverted());
// heal should deal green damage
heal(&mut x, &mut y, Resolution::new(Skill::Heal));
assert!(y.hp() == 768);
// attack should heal and recharge red shield
let res = attack(&mut x, &mut y, Resolution::new(Skill::Attack));
assert!(y.hp() == 1024);
match res.results[0] {
ResolutionResult::Inversion { damage: _, healing: _, recharge, category: _, immunity: _ } => assert_eq!(recharge, 64),
_ => panic!("not inversion"),
};
}
#[test] #[test]
fn triage_test() { fn triage_test() {
let mut x = Cryp::new() let mut x = Cryp::new()

View File

@ -60,7 +60,7 @@ impl Spec {
let i_min = 32; let i_min = 32;
let i_max = 64; let i_max = 64;
fn apply_bonus(base: u64, colours: Vec<u8>, reqs: Vec<u8>, bonuses: Vec<u64>) -> u64 { fn apply_bonus(base: u64, colours: Vec<u8>, reqs: Vec<u8>, bonuses: Vec<u64>) -> u64 {
base + bonuses.iter().enumerate().fold(0, |acc, (i, b)| { base + bonuses.iter().enumerate().fold(0, |acc, (i, b)| {
acc + match (colours.iter().all(|colour| colour >= &reqs[i])) { acc + match (colours.iter().all(|colour| colour >= &reqs[i])) {
@ -72,27 +72,27 @@ impl Spec {
match *self { match *self {
Spec::RedDamageI => modified + { Spec::RedDamageI => modified + {
apply_bonus(base.pct(5), vec![team_colours.red], vec![5, 10, 20], apply_bonus(base.pct(5), vec![team_colours.red], vec![5, 10, 20],
vec![base.pct(5), base.pct(10), base.pct(20)]) vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
Spec::GreenDamageI => modified + { Spec::GreenDamageI => modified + {
apply_bonus(base.pct(5), vec![team_colours.green], vec![5, 10, 20], apply_bonus(base.pct(5), vec![team_colours.green], vec![5, 10, 20],
vec![base.pct(5), base.pct(10), base.pct(20)]) vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
Spec::BlueDamageI => modified + { Spec::BlueDamageI => modified + {
apply_bonus(base.pct(5), vec![team_colours.blue], vec![5, 10, 20], apply_bonus(base.pct(5), vec![team_colours.blue], vec![5, 10, 20],
vec![base.pct(5), base.pct(10), base.pct(20)]) vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
Spec::GRDI => modified + { Spec::GRDI => modified + {
apply_bonus(base.pct(5), vec![team_colours.green, team_colours.red], apply_bonus(base.pct(5), vec![team_colours.green, team_colours.red],
vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)]) vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
Spec::GBDI => modified + { Spec::GBDI => modified + {
apply_bonus(base.pct(5), vec![team_colours.green, team_colours.blue], apply_bonus(base.pct(5), vec![team_colours.green, team_colours.blue],
vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)]) vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
Spec::RBDI => modified + { Spec::RBDI => modified + {
apply_bonus(base.pct(5), vec![team_colours.red, team_colours.blue], apply_bonus(base.pct(5), vec![team_colours.red, team_colours.blue],
vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)]) vec![2, 5, 10], vec![base.pct(5), base.pct(10), base.pct(20)])
}, },
@ -109,20 +109,20 @@ impl Spec {
Spec::BlueShieldI => modified + { Spec::BlueShieldI => modified + {
let bonus = 10 * team_colours.blue as u64; let bonus = 10 * team_colours.blue as u64;
apply_bonus(bonus, vec![team_colours.blue], vec![5, 10, 20], vec![bonus, bonus * 2, bonus * 3]) apply_bonus(bonus, vec![team_colours.blue], vec![5, 10, 20], vec![bonus, bonus * 2, bonus * 3])
}, },
Spec::LRSI => modified + { Spec::LRSI => modified + {
let bonus = 5 * (team_colours.green + team_colours.red) as u64; let bonus = 5 * (team_colours.green + team_colours.red) as u64;
apply_bonus(bonus, vec![team_colours.green, team_colours.red], apply_bonus(bonus, vec![team_colours.green, team_colours.red],
vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3]) vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3])
}, },
Spec::LBSI => modified + { Spec::LBSI => modified + {
let bonus = 5 * (team_colours.green + team_colours.blue) as u64; let bonus = 5 * (team_colours.green + team_colours.blue) as u64;
apply_bonus(bonus, vec![team_colours.green, team_colours.blue], apply_bonus(bonus, vec![team_colours.green, team_colours.blue],
vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3]) vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3])
}, },
Spec::RBSI => modified + { Spec::RBSI => modified + {
let bonus = 5 * (team_colours.red + team_colours.blue) as u64; let bonus = 5 * (team_colours.red + team_colours.blue) as u64;
apply_bonus(bonus, vec![team_colours.red, team_colours.blue], apply_bonus(bonus, vec![team_colours.red, team_colours.blue],
vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3]) vec![2, 5, 10], vec![bonus, bonus * 2, bonus * 3])
}, },
} }