bigass stat impl
This commit is contained in:
parent
b365a6c1f1
commit
9a5ecd4bd4
@ -116,15 +116,18 @@ impl ConstructEffect {
|
|||||||
pub enum Stat {
|
pub enum Stat {
|
||||||
RedLife,
|
RedLife,
|
||||||
RedPower,
|
RedPower,
|
||||||
RedDamageTaken,
|
RedDamageReceived,
|
||||||
|
RedHealingReceived,
|
||||||
|
|
||||||
GreenLife,
|
GreenLife,
|
||||||
GreenPower,
|
GreenPower,
|
||||||
GreenDamageTaken,
|
// GreenDamageReceived, // green damage is only applied by inverting healing
|
||||||
|
GreenHealingReceived,
|
||||||
|
|
||||||
BlueLife,
|
BlueLife,
|
||||||
BluePower,
|
BluePower,
|
||||||
BlueDamageTaken,
|
BlueDamageReceived,
|
||||||
|
BlueHealingReceived,
|
||||||
|
|
||||||
Speed,
|
Speed,
|
||||||
|
|
||||||
@ -483,61 +486,30 @@ impl Construct {
|
|||||||
// fixme put everything through this fn
|
// fixme put everything through this fn
|
||||||
pub fn stat(&self, stat: Stat) -> usize {
|
pub fn stat(&self, stat: Stat) -> usize {
|
||||||
match stat {
|
match stat {
|
||||||
Stat::RedLife => self.red_life(),
|
Stat::RedLife => self.red_life.value,
|
||||||
Stat::RedPower => self.red_power(),
|
Stat::RedPower => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||||
Stat::RedDamageTaken => unimplemented!(),
|
// Stat::RedDamageReceived => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||||
|
|
||||||
Stat::GreenLife => self.green_life(),
|
Stat::GreenLife => self.green_life.value,
|
||||||
Stat::GreenPower => self.green_power(),
|
Stat::GreenPower => self.modified_amount(self.red_power.value, Stat::GreenPower),
|
||||||
Stat::GreenDamageTaken => unimplemented!(),
|
// Stat::GreenDamageReceived => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||||
|
|
||||||
Stat::BlueLife => self.blue_life(),
|
Stat::BlueLife => self.blue_life.value,
|
||||||
Stat::BluePower => self.blue_power(),
|
Stat::BluePower => self.modified_amount(self.red_power.value, Stat::BluePower),
|
||||||
Stat::BlueDamageTaken => unimplemented!(),
|
// Stat::BlueDamageReceived => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||||
|
|
||||||
Stat::Speed => self.speed(),
|
Stat::Speed => self.modified_amount(self.speed.value, Stat::Speed),
|
||||||
|
|
||||||
Stat::Cooldowns => self.skills.iter().filter(|cs| cs.cd.is_some()).count(),
|
Stat::Cooldowns => self.skills.iter().filter(|cs| cs.cd.is_some()).count(),
|
||||||
Stat::Skills(colour) => self.skills.iter().filter(|cs| cs.skill.colours().contains(&colour)).count(),
|
Stat::Skills(colour) => self.skills.iter().filter(|cs| cs.skill.colours().contains(&colour)).count(),
|
||||||
Stat::EffectsCount => self.effects.len(),
|
Stat::EffectsCount => self.effects.len(),
|
||||||
|
|
||||||
|
_ => panic!("{:?} cannot be calculated without an amount", stat),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn red_power(&self) -> usize {
|
|
||||||
let red_power_mods = self.effects.iter()
|
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::RedPower))
|
|
||||||
.map(|e| (e.effect, e.meta))
|
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
let modified_red_power = red_power_mods.iter()
|
|
||||||
.fold(self.red_power.value, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
return modified_red_power;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blue_power(&self) -> usize {
|
|
||||||
let blue_power_mods = self.effects.iter()
|
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::BluePower))
|
|
||||||
.map(|e| (e.effect, e.meta))
|
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
let modified_blue_power = blue_power_mods.iter()
|
|
||||||
.fold(self.blue_power.value, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
return modified_blue_power;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn green_power(&self) -> usize {
|
|
||||||
let green_power_mods = self.effects.iter()
|
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::GreenPower))
|
|
||||||
.map(|e| (e.effect, e.meta))
|
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
let modified_green_power = green_power_mods.iter()
|
|
||||||
.fold(self.green_power.value, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
return modified_green_power;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn skill_speed(&self, s: Skill) -> usize {
|
pub fn skill_speed(&self, s: Skill) -> usize {
|
||||||
self.speed().saturating_mul(s.speed() as usize)
|
self.stat(Stat::Speed).saturating_mul(s.speed() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo complete with specs
|
// todo complete with specs
|
||||||
@ -545,43 +517,206 @@ impl Construct {
|
|||||||
s.aoe()
|
s.aoe()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn speed(&self) -> usize {
|
|
||||||
let speed_mods = self.effects.iter()
|
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::Speed))
|
|
||||||
.map(|e| (e.effect, e.meta))
|
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
let modified_speed = speed_mods.iter()
|
|
||||||
.fold(self.speed.value, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
return modified_speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn red_life(&self) -> usize {
|
|
||||||
self.red_life.value
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blue_life(&self) -> usize {
|
|
||||||
self.blue_life.value
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn green_life(&self) -> usize {
|
|
||||||
self.green_life.value
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_green_life(&mut self, amount: usize) {
|
fn reduce_green_life(&mut self, amount: usize) {
|
||||||
self.green_life.reduce(amount);
|
self.green_life.reduce(amount);
|
||||||
if self.affected(Effect::Sustain) && self.green_life() == 0 {
|
if self.affected(Effect::Sustain) && self.stat(Stat::GreenLife) == 0 {
|
||||||
self.green_life.value = 1;
|
self.green_life.value = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deal_green_damage(&mut self, amount: usize) -> Vec<Event> {
|
fn modified_amount(&self, amount: usize, modification: Stat) -> usize {
|
||||||
|
let mods = self.effects.iter()
|
||||||
|
.filter(|e| e.effect.modifications().contains(&modification))
|
||||||
|
.map(|e| (e.effect, e.meta))
|
||||||
|
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||||
|
|
||||||
|
return mods.iter()
|
||||||
|
.fold(amount, |acc, fx| fx.0.apply(acc, fx.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn damage(&mut self, amount: usize, colour: Colour) -> Vec<Event> {
|
||||||
|
match colour {
|
||||||
|
Colour::Red => self.deal_red_damage(amount),
|
||||||
|
Colour::Blue => self.deal_blue_damage(amount),
|
||||||
|
Colour::Green => panic!("green damage should be implemented as Action::Healing"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_red_damage(&mut self, amount: usize) -> Vec<Event> {
|
||||||
|
let mut events = vec![];
|
||||||
|
|
||||||
|
if self.is_ko() { return events; }
|
||||||
|
let construct = self.id;
|
||||||
|
|
||||||
|
let modified_power = self.modified_amount(amount, Stat::RedDamageReceived);
|
||||||
|
|
||||||
|
match self.affected(Effect::Invert) {
|
||||||
|
false => {
|
||||||
|
// calculate amount of damage red_life will not absorb
|
||||||
|
// eg 50 red_life 25 damage -> 0 remainder 25 mitigation
|
||||||
|
// 50 red_life 100 damage -> 50 remainder 50 mitigation
|
||||||
|
// 50 red_life 5 damage -> 0 remainder 5 mitigation
|
||||||
|
let remainder = modified_power.saturating_sub(self.red_life.value);
|
||||||
|
let mitigation = modified_power.saturating_sub(remainder);
|
||||||
|
|
||||||
|
// reduce red_life by mitigation amount
|
||||||
|
self.red_life.reduce(mitigation);
|
||||||
|
|
||||||
|
// deal remainder to green_life
|
||||||
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
|
self.reduce_green_life(remainder);
|
||||||
|
let delta = current_green_life - self.stat(Stat::GreenLife);
|
||||||
|
|
||||||
|
events.push(
|
||||||
|
Event::Damage {
|
||||||
|
construct,
|
||||||
|
amount: delta,
|
||||||
|
mitigation,
|
||||||
|
colour: Colour::Red,
|
||||||
|
display: EventConstruct::new(self),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if self.is_ko() {
|
||||||
|
events.push(Event::Ko { construct });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true => {
|
||||||
|
|
||||||
|
// 50/100 green life
|
||||||
|
// 0/100 red life
|
||||||
|
// 200 red dmg
|
||||||
|
//
|
||||||
|
// 50 green healing
|
||||||
|
// 100 red healing
|
||||||
|
// 50 red overhealing
|
||||||
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
|
self.green_life.increase(modified_power);
|
||||||
|
let new_green_life = self.green_life.value;
|
||||||
|
let green_healing = new_green_life - current_green_life;
|
||||||
|
|
||||||
|
let recharge = modified_power - green_healing;
|
||||||
|
let current_red_life = self.red_life.value;
|
||||||
|
self.red_life.increase(recharge);
|
||||||
|
let red_healing = self.red_life.value - current_red_life;
|
||||||
|
let overhealing = recharge - red_healing;
|
||||||
|
|
||||||
|
if green_healing > 0 {
|
||||||
|
events.push(
|
||||||
|
Event::Healing {
|
||||||
|
construct,
|
||||||
|
amount: green_healing,
|
||||||
|
overhealing: 0,
|
||||||
|
colour: Colour::Green
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if red_healing > 0 {
|
||||||
|
events.push(
|
||||||
|
Event::Healing {
|
||||||
|
construct,
|
||||||
|
amount: recharge,
|
||||||
|
overhealing,
|
||||||
|
colour: Colour::Blue
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_blue_damage(&mut self, amount: usize) -> Vec<Event> {
|
||||||
|
let mut events = vec![];
|
||||||
|
|
||||||
|
if self.is_ko() { return events; }
|
||||||
|
let construct = self.id;
|
||||||
|
|
||||||
|
let modified_power = self.modified_amount(amount, Stat::BlueDamageReceived);
|
||||||
|
|
||||||
|
match self.affected(Effect::Invert) {
|
||||||
|
false => {
|
||||||
|
let remainder = modified_power.saturating_sub(self.blue_life.value);
|
||||||
|
let mitigation = modified_power.saturating_sub(remainder);
|
||||||
|
|
||||||
|
// reduce blue_life by mitigation amount
|
||||||
|
self.blue_life.reduce(mitigation);
|
||||||
|
|
||||||
|
// deal remainder to green_life
|
||||||
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
|
self.reduce_green_life(remainder);
|
||||||
|
let delta = current_green_life - self.stat(Stat::GreenLife);
|
||||||
|
|
||||||
|
events.push(
|
||||||
|
Event::Damage {
|
||||||
|
construct,
|
||||||
|
amount: delta,
|
||||||
|
mitigation,
|
||||||
|
colour: Colour::Blue,
|
||||||
|
display: EventConstruct::new(self),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if self.is_ko() {
|
||||||
|
events.push(Event::Ko { construct });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true => {
|
||||||
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
|
self.green_life.increase(modified_power);
|
||||||
|
let new_green_life = self.green_life.value;
|
||||||
|
let green_healing = new_green_life - current_green_life;
|
||||||
|
|
||||||
|
let recharge = modified_power - green_healing;
|
||||||
|
let current_blue_life = self.blue_life.value;
|
||||||
|
self.blue_life.increase(recharge);
|
||||||
|
let blue_healing = self.blue_life.value - current_blue_life;
|
||||||
|
let overhealing = recharge - blue_healing;
|
||||||
|
|
||||||
|
if green_healing > 0 {
|
||||||
|
events.push(
|
||||||
|
Event::Healing {
|
||||||
|
construct,
|
||||||
|
amount: green_healing,
|
||||||
|
overhealing: 0,
|
||||||
|
colour: Colour::Green
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if blue_healing > 0 {
|
||||||
|
events.push(
|
||||||
|
Event::Healing {
|
||||||
|
construct,
|
||||||
|
amount: recharge,
|
||||||
|
overhealing,
|
||||||
|
colour: Colour::Blue
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn healing(&mut self, amount: usize, colour: Colour) -> Vec<Event> {
|
||||||
|
match colour {
|
||||||
|
Colour::Red => self.red_healing(amount),
|
||||||
|
Colour::Blue => self.blue_healing(amount),
|
||||||
|
Colour::Green => self.green_healing(amount),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn red_healing(&mut self, amount: usize) -> Vec<Event> {
|
||||||
let mut events = vec![];
|
let mut events = vec![];
|
||||||
if self.is_ko() { return events; }
|
if self.is_ko() { return events; }
|
||||||
let construct = self.id;
|
let construct = self.id;
|
||||||
|
|
||||||
let mods = self.effects.iter()
|
let mods = self.effects.iter()
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::GreenDamageTaken))
|
.filter(|e| e.effect.modifications().contains(&Stat::RedHealingReceived))
|
||||||
.map(|e| (e.effect, e.meta))
|
.map(|e| (e.effect, e.meta))
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||||
|
|
||||||
@ -590,7 +725,58 @@ impl Construct {
|
|||||||
|
|
||||||
match self.affected(Effect::Invert) {
|
match self.affected(Effect::Invert) {
|
||||||
false => {
|
false => {
|
||||||
let current_green_life = self.green_life();
|
let current_red_life = self.stat(Stat::RedLife);
|
||||||
|
self.red_life.increase(modified_power);
|
||||||
|
let new_red_life = self.red_life.value;
|
||||||
|
let healing = new_red_life - current_red_life;
|
||||||
|
let overhealing = modified_power - healing;
|
||||||
|
|
||||||
|
if healing != 0 {
|
||||||
|
events.push(Event::Healing { construct: self.id, amount: healing, overhealing, colour: Colour::Red });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true => {
|
||||||
|
// Recharge takes a red and blue amount so check for them
|
||||||
|
let red_remainder = modified_power.saturating_sub(self.red_life.value);
|
||||||
|
let red_mitigation = modified_power.saturating_sub(red_remainder);
|
||||||
|
|
||||||
|
// reduce red_life by mitigation amount
|
||||||
|
self.red_life.reduce(red_mitigation);
|
||||||
|
|
||||||
|
// deal remainder to green_life
|
||||||
|
let red_current_green_life = self.stat(Stat::GreenLife);
|
||||||
|
self.reduce_green_life(red_remainder);
|
||||||
|
let red_damage_amount = red_current_green_life - self.stat(Stat::GreenLife);
|
||||||
|
|
||||||
|
events.push(Event::Damage {
|
||||||
|
construct: self.id,
|
||||||
|
amount: red_damage_amount,
|
||||||
|
mitigation: red_mitigation,
|
||||||
|
colour: Colour::Red,
|
||||||
|
display: EventConstruct::new(self),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn green_healing(&mut self, amount: usize) -> Vec<Event> {
|
||||||
|
let mut events = vec![];
|
||||||
|
if self.is_ko() { return events; }
|
||||||
|
let construct = self.id;
|
||||||
|
|
||||||
|
let mods = self.effects.iter()
|
||||||
|
.filter(|e| e.effect.modifications().contains(&Stat::GreenHealingReceived))
|
||||||
|
.map(|e| (e.effect, e.meta))
|
||||||
|
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||||
|
|
||||||
|
let modified_power = mods.iter()
|
||||||
|
.fold(amount, |acc, fx| fx.0.apply(acc, fx.1));
|
||||||
|
|
||||||
|
match self.affected(Effect::Invert) {
|
||||||
|
false => {
|
||||||
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
self.green_life.increase(modified_power);
|
self.green_life.increase(modified_power);
|
||||||
let new_green_life = self.green_life.value;
|
let new_green_life = self.green_life.value;
|
||||||
|
|
||||||
@ -601,15 +787,14 @@ impl Construct {
|
|||||||
construct,
|
construct,
|
||||||
amount: healing,
|
amount: healing,
|
||||||
overhealing,
|
overhealing,
|
||||||
|
colour: Colour::Green,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
true => {
|
true => {
|
||||||
// events.push(Event::new(Event::Inversion { skill }));
|
|
||||||
|
|
||||||
// there is no green shield (yet)
|
// there is no green shield (yet)
|
||||||
let current_green_life = self.green_life();
|
let current_green_life = self.stat(Stat::GreenLife);
|
||||||
self.reduce_green_life(modified_power);
|
self.reduce_green_life(modified_power);
|
||||||
let delta = current_green_life - self.green_life();
|
let delta = current_green_life - self.stat(Stat::GreenLife);
|
||||||
|
|
||||||
events.push(Event::Damage {
|
events.push(Event::Damage {
|
||||||
construct,
|
construct,
|
||||||
@ -628,132 +813,13 @@ impl Construct {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn heal(&mut self, amount: usize, colour: Colour) -> Vec<Event> {
|
fn blue_healing(&mut self, amount: usize) -> Vec<Event> {
|
||||||
let mut events = vec![];
|
let mut events = vec![];
|
||||||
if self.is_ko() { return events; }
|
if self.is_ko() { return events; }
|
||||||
let construct = self.id;
|
let construct = self.id;
|
||||||
|
|
||||||
|
|
||||||
// match self.affected(Effect::Invert) {
|
|
||||||
// false => {
|
|
||||||
// let current_red_life = self.red_life();
|
|
||||||
// self.red_life.increase(red_amount);
|
|
||||||
// let new_red_life = self.red_life.value;
|
|
||||||
// let red = new_red_life - current_red_life;
|
|
||||||
|
|
||||||
// let current_blue_life = self.blue_life();
|
|
||||||
// self.blue_life.increase(blue_amount);
|
|
||||||
// let new_blue_life = self.blue_life.value;
|
|
||||||
// let blue = new_blue_life - current_blue_life;
|
|
||||||
|
|
||||||
// if red != 0 || blue != 0 {
|
|
||||||
// events.push(Event::Recharge { construct: self.id, red, blue });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// true => {
|
|
||||||
// // Recharge takes a red and blue amount so check for them
|
|
||||||
// if red_amount != 0 {
|
|
||||||
// let red_mods = self.effects.iter()
|
|
||||||
// .filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken))
|
|
||||||
// .map(|e| (e.effect, e.meta))
|
|
||||||
// .collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
// let red_modified_power = red_mods.iter()
|
|
||||||
// .fold(red_amount, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
|
|
||||||
// let red_remainder = red_modified_power.saturating_sub(self.red_life.value);
|
|
||||||
// let red_mitigation = red_modified_power.saturating_sub(red_remainder);
|
|
||||||
|
|
||||||
// // reduce red_life by mitigation amount
|
|
||||||
// self.red_life.reduce(red_mitigation);
|
|
||||||
|
|
||||||
// // deal remainder to green_life
|
|
||||||
// let red_current_green_life = self.green_life();
|
|
||||||
// self.reduce_green_life(red_remainder);
|
|
||||||
// let red_damage_amount = red_current_green_life - self.green_life();
|
|
||||||
|
|
||||||
// events.push(Event::Damage {
|
|
||||||
// construct: self.id,
|
|
||||||
// amount: red_damage_amount,
|
|
||||||
// mitigation: red_mitigation,
|
|
||||||
// colour: Colour::Red,
|
|
||||||
// display: EventConstruct::new(self),
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if blue_amount != 0 {
|
|
||||||
// let blue_mods = self.effects.iter()
|
|
||||||
// .filter(|e| e.effect.modifications().contains(&Stat::BlueDamageTaken))
|
|
||||||
// .map(|e| (e.effect, e.meta))
|
|
||||||
// .collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
// let blue_modified_power = blue_mods.iter()
|
|
||||||
// .fold(blue_amount, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
|
|
||||||
|
|
||||||
// let blue_remainder = blue_modified_power.saturating_sub(self.blue_life.value);
|
|
||||||
// let blue_mitigation = blue_modified_power.saturating_sub(blue_remainder);
|
|
||||||
|
|
||||||
// // reduce blue_life by mitigation amount
|
|
||||||
// self.blue_life.reduce(blue_mitigation);
|
|
||||||
|
|
||||||
// // deal remainder to green_life
|
|
||||||
// let blue_current_green_life = self.green_life();
|
|
||||||
// self.reduce_green_life(blue_remainder);
|
|
||||||
// let blue_damage_amount = blue_current_green_life - self.green_life();
|
|
||||||
|
|
||||||
// events.push(Event::Damage {
|
|
||||||
// construct: self.id,
|
|
||||||
// amount: blue_damage_amount,
|
|
||||||
// mitigation: blue_mitigation,
|
|
||||||
// colour: Colour::Blue,
|
|
||||||
// display: EventConstruct::new(self),
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// match colour {
|
|
||||||
// Colour::Red => {
|
|
||||||
|
|
||||||
// },
|
|
||||||
// Colour::Green => {
|
|
||||||
// let mods = self.effects.iter()
|
|
||||||
// .filter(|e| e.effect.modifications().contains(&Stat::GreenDamageTaken))
|
|
||||||
// .map(|e| (e.effect, e.meta))
|
|
||||||
// .collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
// let modified_power = mods.iter()
|
|
||||||
// .fold(amount, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
|
|
||||||
// let current_green_life = self.green_life();
|
|
||||||
// self.green_life.increase(modified_power);
|
|
||||||
// let new_green_life = self.green_life.value;
|
|
||||||
|
|
||||||
// let healing = new_green_life - current_green_life;
|
|
||||||
// let overhealing = modified_power - healing;
|
|
||||||
|
|
||||||
// events.push(Event::Healing {
|
|
||||||
// construct,
|
|
||||||
// amount: healing,
|
|
||||||
// overhealing,
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// Colour::Blue => {
|
|
||||||
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deal_red_damage(&mut self, amount: usize) -> Vec<Event> {
|
|
||||||
let mut events = vec![];
|
|
||||||
|
|
||||||
if self.is_ko() { return events; }
|
|
||||||
let construct = self.id;
|
|
||||||
|
|
||||||
let mods = self.effects.iter()
|
let mods = self.effects.iter()
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken))
|
.filter(|e| e.effect.modifications().contains(&Stat::BlueHealingReceived))
|
||||||
.map(|e| (e.effect, e.meta))
|
.map(|e| (e.effect, e.meta))
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||||
|
|
||||||
@ -762,128 +828,38 @@ impl Construct {
|
|||||||
|
|
||||||
match self.affected(Effect::Invert) {
|
match self.affected(Effect::Invert) {
|
||||||
false => {
|
false => {
|
||||||
// calculate amount of damage red_life will not absorb
|
let current_blue_life = self.stat(Stat::BlueLife);
|
||||||
// eg 50 red_life 25 damage -> 0 remainder 25 mitigation
|
self.blue_life.increase(modified_power);
|
||||||
// 50 red_life 100 damage -> 50 remainder 50 mitigation
|
let new_blue_life = self.blue_life.value;
|
||||||
// 50 red_life 5 damage -> 0 remainder 5 mitigation
|
let healing = new_blue_life - current_blue_life;
|
||||||
let remainder = modified_power.saturating_sub(self.red_life.value);
|
let overhealing = modified_power - healing;
|
||||||
let mitigation = modified_power.saturating_sub(remainder);
|
|
||||||
|
|
||||||
// reduce red_life by mitigation amount
|
if healing != 0 {
|
||||||
self.red_life.reduce(mitigation);
|
events.push(Event::Healing { construct: self.id, amount: healing, overhealing, colour: Colour::Red });
|
||||||
|
|
||||||
// deal remainder to green_life
|
|
||||||
let current_green_life = self.green_life();
|
|
||||||
self.reduce_green_life(remainder);
|
|
||||||
let delta = current_green_life - self.green_life();
|
|
||||||
|
|
||||||
events.push(
|
|
||||||
Event::Damage {
|
|
||||||
construct,
|
|
||||||
amount: delta,
|
|
||||||
mitigation,
|
|
||||||
colour: Colour::Red,
|
|
||||||
display: EventConstruct::new(self),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.is_ko() {
|
|
||||||
events.push(Event::Ko { construct });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
true => {
|
true => {
|
||||||
// events.push(Event::new(Event::Inversion { skill }));
|
// Recharge takes a red and blue amount so check for them
|
||||||
|
let blue_remainder = modified_power.saturating_sub(self.blue_life.value);
|
||||||
let current_green_life = self.green_life();
|
let blue_mitigation = modified_power.saturating_sub(blue_remainder);
|
||||||
self.green_life.increase(modified_power);
|
|
||||||
let new_green_life = self.green_life.value;
|
|
||||||
let healing = new_green_life - current_green_life;
|
|
||||||
let overhealing = modified_power - healing;
|
|
||||||
|
|
||||||
let current_life = self.red_life.value;
|
|
||||||
self.red_life.increase(overhealing);
|
|
||||||
let recharge = self.red_life.value - current_life;
|
|
||||||
|
|
||||||
if healing > 0 {
|
|
||||||
events.push(
|
|
||||||
Event::Healing {
|
|
||||||
construct,
|
|
||||||
amount: healing,
|
|
||||||
overhealing: overhealing - recharge,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if recharge > 0 {
|
|
||||||
events.push(Event::Recharge { construct, red: recharge, blue: 0 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deal_blue_damage(&mut self, amount: usize) -> Vec<Event> {
|
|
||||||
let mut events = vec![];
|
|
||||||
|
|
||||||
if self.is_ko() { return events; }
|
|
||||||
let construct = self.id;
|
|
||||||
|
|
||||||
let mods = self.effects.iter()
|
|
||||||
.filter(|e| e.effect.modifications().contains(&Stat::BlueDamageTaken))
|
|
||||||
.map(|e| (e.effect, e.meta))
|
|
||||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
|
||||||
|
|
||||||
let modified_power = mods.iter()
|
|
||||||
.fold(amount, |acc, fx| fx.0.apply(acc, fx.1));
|
|
||||||
|
|
||||||
match self.affected(Effect::Invert) {
|
|
||||||
false => {
|
|
||||||
let remainder = modified_power.saturating_sub(self.blue_life.value);
|
|
||||||
let mitigation = modified_power.saturating_sub(remainder);
|
|
||||||
|
|
||||||
// reduce blue_life by mitigation amount
|
// reduce blue_life by mitigation amount
|
||||||
self.blue_life.reduce(mitigation);
|
self.blue_life.reduce(blue_mitigation);
|
||||||
|
|
||||||
// deal remainder to green_life
|
// deal remainder to green_life
|
||||||
let current_green_life = self.green_life();
|
let blue_current_green_life = self.stat(Stat::GreenLife);
|
||||||
self.reduce_green_life(remainder);
|
self.reduce_green_life(blue_remainder);
|
||||||
let delta = current_green_life - self.green_life();
|
let blue_damage_amount = blue_current_green_life - self.stat(Stat::GreenLife);
|
||||||
|
|
||||||
events.push(Event::Damage {
|
events.push(Event::Damage {
|
||||||
construct,
|
construct: self.id,
|
||||||
amount: delta,
|
amount: blue_damage_amount,
|
||||||
mitigation,
|
mitigation: blue_mitigation,
|
||||||
colour: Colour::Blue,
|
colour: Colour::Red,
|
||||||
display: EventConstruct::new(self),
|
display: EventConstruct::new(self),
|
||||||
});
|
});
|
||||||
|
|
||||||
if self.is_ko() {
|
|
||||||
events.push(Event::Ko { construct });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
true => {
|
|
||||||
// events.push(Event::new(Event::Inversion { skill }));
|
|
||||||
|
|
||||||
let current_green_life = self.green_life();
|
|
||||||
self.green_life.increase(modified_power);
|
|
||||||
let new_green_life = self.green_life.value;
|
|
||||||
let healing = new_green_life - current_green_life;
|
|
||||||
let overhealing = modified_power - healing;
|
|
||||||
|
|
||||||
let current_life = self.blue_life.value;
|
|
||||||
self.blue_life.increase(overhealing);
|
|
||||||
let recharge = self.blue_life.value - current_life;
|
|
||||||
|
|
||||||
if healing > 0 {
|
|
||||||
events.push(Event::Healing { construct, amount: healing, overhealing });
|
|
||||||
}
|
|
||||||
|
|
||||||
if recharge > 0 {
|
|
||||||
events.push(Event::Recharge { construct, red: 0, blue: recharge });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,7 @@ impl Effect {
|
|||||||
pub fn modifications(&self) -> Vec<Stat> {
|
pub fn modifications(&self) -> Vec<Stat> {
|
||||||
match self {
|
match self {
|
||||||
// Bases
|
// Bases
|
||||||
Effect::Block => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken],
|
Effect::Block => vec![Stat::RedDamageReceived, Stat::BlueDamageReceived],
|
||||||
Effect::Buff => vec![Stat::BluePower, Stat::RedPower, Stat::Speed],
|
Effect::Buff => vec![Stat::BluePower, Stat::RedPower, Stat::Speed],
|
||||||
Effect::Slow => vec![Stat::Speed],
|
Effect::Slow => vec![Stat::Speed],
|
||||||
|
|
||||||
@ -112,10 +112,10 @@ impl Effect {
|
|||||||
Effect::Hybrid => vec![Stat::GreenPower],
|
Effect::Hybrid => vec![Stat::GreenPower],
|
||||||
|
|
||||||
// Damage taken changes
|
// Damage taken changes
|
||||||
Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken],
|
Effect::Curse => vec![Stat::RedDamageReceived, Stat::BlueDamageReceived],
|
||||||
Effect::Pure => vec![Stat::GreenDamageTaken], // increased green taken
|
Effect::Pure => vec![Stat::GreenHealingReceived], // increased green taken
|
||||||
Effect::Vulnerable => vec![Stat::RedDamageTaken],
|
Effect::Vulnerable => vec![Stat::RedDamageReceived],
|
||||||
Effect::Wither => vec![Stat::GreenDamageTaken], // reduced green taken
|
Effect::Wither => vec![Stat::GreenHealingReceived], // reduced green taken
|
||||||
|
|
||||||
// Speed
|
// Speed
|
||||||
Effect::Haste => vec![Stat::Speed],
|
Effect::Haste => vec![Stat::Speed],
|
||||||
|
|||||||
@ -587,7 +587,7 @@ impl Game {
|
|||||||
Value::ColourSkills { construct, colour, mult } =>
|
Value::ColourSkills { construct, colour, mult } =>
|
||||||
self.construct_by_id(*construct).unwrap().stat(Stat::Skills(*colour)).pct(*mult),
|
self.construct_by_id(*construct).unwrap().stat(Stat::Skills(*colour)).pct(*mult),
|
||||||
|
|
||||||
Value::DamageTaken { construct, colour, mult } =>
|
Value::DamageReceived { construct, colour, mult } =>
|
||||||
events.iter().fold(0, |dmg, e| match e {
|
events.iter().fold(0, |dmg, e| match e {
|
||||||
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } =>
|
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } =>
|
||||||
match *construct == *event_construct && *colour == *event_colour {
|
match *construct == *event_construct && *colour == *event_colour {
|
||||||
@ -620,17 +620,11 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn damage(&mut self, construct: Uuid, amount: usize, colour: Colour) -> Vec<Event> {
|
fn damage(&mut self, construct: Uuid, amount: usize, colour: Colour) -> Vec<Event> {
|
||||||
match colour {
|
self.construct_by_id(construct).unwrap().damage(amount, colour)
|
||||||
Colour::Red => self.construct_by_id(construct).unwrap().deal_red_damage(amount), // fixme unwrap
|
|
||||||
Colour::Green => self.construct_by_id(construct).unwrap().deal_green_damage(amount), // fixme unwrap
|
|
||||||
Colour::Blue => self.construct_by_id(construct).unwrap().deal_blue_damage(amount), // fixme unwrap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn heal(&mut self, construct: Uuid, value: usize, colour: Colour) -> Vec<Event> {
|
fn heal(&mut self, construct: Uuid, amount: usize, colour: Colour) -> Vec<Event> {
|
||||||
match colour {
|
self.construct_by_id(construct).unwrap().healing(amount, colour)
|
||||||
_ => self.construct_by_id(construct).unwrap().deal_red_damage(value) // fixme unwrap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effect(&mut self, construct: Uuid, effect: ConstructEffect) -> Vec<Event> {
|
fn effect(&mut self, construct: Uuid, effect: ConstructEffect) -> Vec<Event> {
|
||||||
@ -844,7 +838,7 @@ pub enum Value {
|
|||||||
ColourSkills { construct: Uuid, colour: Colour, mult: usize },
|
ColourSkills { construct: Uuid, colour: Colour, mult: usize },
|
||||||
Effects { construct: Uuid, mult: usize },
|
Effects { construct: Uuid, mult: usize },
|
||||||
Removals { construct: Uuid, mult: usize },
|
Removals { construct: Uuid, mult: usize },
|
||||||
DamageTaken { construct: Uuid, colour: Colour, mult: usize },
|
DamageReceived { construct: Uuid, colour: Colour, mult: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq)]
|
#[derive(Debug,Clone,PartialEq)]
|
||||||
@ -904,8 +898,7 @@ pub enum Event {
|
|||||||
Effect { construct: Uuid, effect: Effect, duration: u8, display: EventConstruct },
|
Effect { construct: Uuid, effect: Effect, duration: u8, display: EventConstruct },
|
||||||
Removal { construct: Uuid, effect: Effect, display: EventConstruct },
|
Removal { construct: Uuid, effect: Effect, display: EventConstruct },
|
||||||
|
|
||||||
Healing { construct: Uuid, amount: usize, overhealing: usize },
|
Healing { construct: Uuid, amount: usize, overhealing: usize, colour: Colour },
|
||||||
Recharge { construct: Uuid, red: usize, blue: usize },
|
|
||||||
Inversion { construct: Uuid },
|
Inversion { construct: Uuid },
|
||||||
Reflection { construct: Uuid },
|
Reflection { construct: Uuid },
|
||||||
Ko { construct: Uuid },
|
Ko { construct: Uuid },
|
||||||
@ -969,9 +962,9 @@ impl EventConstruct {
|
|||||||
pub fn new(construct: &Construct) -> EventConstruct {
|
pub fn new(construct: &Construct) -> EventConstruct {
|
||||||
EventConstruct {
|
EventConstruct {
|
||||||
id: construct.id,
|
id: construct.id,
|
||||||
red: construct.red_life(),
|
red: construct.stat(Stat::RedLife),
|
||||||
green: construct.green_life(),
|
green: construct.stat(Stat::GreenLife),
|
||||||
blue: construct.blue_life(),
|
blue: construct.stat(Stat::BlueLife),
|
||||||
effects: construct.effects.clone(),
|
effects: construct.effects.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -719,7 +719,7 @@ impl Cast {
|
|||||||
Action::Heal {
|
Action::Heal {
|
||||||
construct: self.target,
|
construct: self.target,
|
||||||
colour: Colour::Green,
|
colour: Colour::Green,
|
||||||
values: vec![Value::DamageTaken { construct: self.target, colour: Colour::Blue, mult: 100 }],
|
values: vec![Value::DamageReceived { construct: self.target, colour: Colour::Blue, mult: 100 }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ impl Cast {
|
|||||||
Action::Heal {
|
Action::Heal {
|
||||||
construct: self.target,
|
construct: self.target,
|
||||||
colour: Colour::Green,
|
colour: Colour::Green,
|
||||||
values: vec![Value::DamageTaken { construct: self.target, colour: Colour::Red, mult: 50 }],
|
values: vec![Value::DamageReceived { construct: self.target, colour: Colour::Red, mult: 50 }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user