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
* vbox drops chances
* 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
* iconography
* aoe skills

View File

@ -297,6 +297,10 @@ impl Cryp {
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> {
self.skills.iter()
.filter(|s| s.cd.is_none())
@ -456,7 +460,7 @@ impl Cryp {
let immune = immunity.immune;
if immune {
ResolutionResult::Healing {
return ResolutionResult::Healing {
amount: 0,
overhealing: 0,
immunity: immunity.clone(),
@ -472,18 +476,34 @@ impl Cryp {
let modified_healing = healing_mods.iter().fold(amount, |acc, m| m.apply(acc));
let current_hp = self.hp();
self.hp.increase(modified_healing);
let new_hp = self.hp.value;
match self.is_inverted() {
false => {
let current_hp = self.hp();
self.hp.increase(modified_healing);
let new_hp = self.hp.value;
let healing = new_hp - current_hp;
let overhealing = modified_healing - healing;
let healing = new_hp - current_hp;
let overhealing = modified_healing - healing;
return ResolutionResult::Healing {
amount: healing,
overhealing,
immunity,
};
return ResolutionResult::Healing {
amount: healing,
overhealing,
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 {
@ -508,25 +528,48 @@ impl Cryp {
let modified_damage = red_damage_mods.iter().fold(amount, |acc, m| m.apply(acc));
// calculate amount of damage red_shield will not absorb
// eg 50 red_shield 25 damage -> 0 remainder 25 mitigation
// 50 red_shield 100 damage -> 50 remainder 50 mitigation
// 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);
match self.is_inverted() {
false => {
// calculate amount of damage red_shield will not absorb
// eg 50 red_shield 25 damage -> 0 remainder 25 mitigation
// 50 red_shield 100 damage -> 50 remainder 50 mitigation
// 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
self.red_shield.reduce(mitigation);
// reduce red_shield by mitigation amount
self.red_shield.reduce(mitigation);
// deal remainder to hp
self.hp.reduce(remainder);
// deal remainder to hp
self.hp.reduce(remainder);
return ResolutionResult::Damage {
amount: remainder,
mitigation,
category: Category::RedDamage,
immunity,
};
return ResolutionResult::Damage {
amount: remainder,
mitigation,
category: Category::RedDamage,
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 {
@ -548,20 +591,43 @@ impl Cryp {
.collect::<Vec<Effect>>();
// println!("{:?}", blue_damage_mods);
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);
self.hp.reduce(remainder);
match self.is_inverted() {
false => {
let remainder = modified_damage.saturating_sub(self.blue_shield.value);
let mitigation = modified_damage.saturating_sub(remainder);
return ResolutionResult::Damage {
amount: remainder,
mitigation,
category: Category::BlueDamage,
immunity,
};
self.blue_shield.reduce(mitigation);
self.hp.reduce(remainder);
return ResolutionResult::Damage {
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 {

View File

@ -382,6 +382,18 @@ impl Game {
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 } => {
match immunity.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 },
Healing { amount: u64, overhealing: 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 },
Removal { effect: Effect, immunity: Immunity },
Evasion { skill: Skill, evasion_rating: u64 },
@ -305,6 +306,7 @@ pub enum Category {
BlueBuff,
BlueTick,
Green,
GreenDamage,
GreenBuff,
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]
fn triage_test() {
let mut x = Cryp::new()

View File

@ -60,7 +60,7 @@ impl Spec {
let i_min = 32;
let i_max = 64;
fn apply_bonus(base: u64, colours: Vec<u8>, reqs: Vec<u8>, bonuses: Vec<u64>) -> u64 {
base + bonuses.iter().enumerate().fold(0, |acc, (i, b)| {
acc + match (colours.iter().all(|colour| colour >= &reqs[i])) {
@ -72,27 +72,27 @@ impl Spec {
match *self {
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)])
},
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)])
},
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)])
},
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)])
},
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)])
},
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)])
},
@ -109,20 +109,20 @@ impl Spec {
Spec::BlueShieldI => modified + {
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])
},
},
Spec::LRSI => modified + {
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])
},
Spec::LBSI => modified + {
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])
},
Spec::RBSI => modified + {
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])
},
}