bigass stat impl
This commit is contained in:
parent
b365a6c1f1
commit
9a5ecd4bd4
@ -116,15 +116,18 @@ impl ConstructEffect {
|
||||
pub enum Stat {
|
||||
RedLife,
|
||||
RedPower,
|
||||
RedDamageTaken,
|
||||
RedDamageReceived,
|
||||
RedHealingReceived,
|
||||
|
||||
GreenLife,
|
||||
GreenPower,
|
||||
GreenDamageTaken,
|
||||
// GreenDamageReceived, // green damage is only applied by inverting healing
|
||||
GreenHealingReceived,
|
||||
|
||||
BlueLife,
|
||||
BluePower,
|
||||
BlueDamageTaken,
|
||||
BlueDamageReceived,
|
||||
BlueHealingReceived,
|
||||
|
||||
Speed,
|
||||
|
||||
@ -483,61 +486,30 @@ impl Construct {
|
||||
// fixme put everything through this fn
|
||||
pub fn stat(&self, stat: Stat) -> usize {
|
||||
match stat {
|
||||
Stat::RedLife => self.red_life(),
|
||||
Stat::RedPower => self.red_power(),
|
||||
Stat::RedDamageTaken => unimplemented!(),
|
||||
Stat::RedLife => self.red_life.value,
|
||||
Stat::RedPower => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||
// Stat::RedDamageReceived => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||
|
||||
Stat::GreenLife => self.green_life(),
|
||||
Stat::GreenPower => self.green_power(),
|
||||
Stat::GreenDamageTaken => unimplemented!(),
|
||||
Stat::GreenLife => self.green_life.value,
|
||||
Stat::GreenPower => self.modified_amount(self.red_power.value, Stat::GreenPower),
|
||||
// Stat::GreenDamageReceived => self.modified_amount(self.red_power.value, Stat::RedPower),
|
||||
|
||||
Stat::BlueLife => self.blue_life(),
|
||||
Stat::BluePower => self.blue_power(),
|
||||
Stat::BlueDamageTaken => unimplemented!(),
|
||||
Stat::BlueLife => self.blue_life.value,
|
||||
Stat::BluePower => self.modified_amount(self.red_power.value, Stat::BluePower),
|
||||
// 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::Skills(colour) => self.skills.iter().filter(|cs| cs.skill.colours().contains(&colour)).count(),
|
||||
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 {
|
||||
self.speed().saturating_mul(s.speed() as usize)
|
||||
self.stat(Stat::Speed).saturating_mul(s.speed() as usize)
|
||||
}
|
||||
|
||||
// todo complete with specs
|
||||
@ -545,43 +517,206 @@ impl Construct {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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![];
|
||||
if self.is_ko() { return events; }
|
||||
let construct = self.id;
|
||||
|
||||
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))
|
||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||
|
||||
@ -590,7 +725,58 @@ impl Construct {
|
||||
|
||||
match self.affected(Effect::Invert) {
|
||||
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);
|
||||
let new_green_life = self.green_life.value;
|
||||
|
||||
@ -601,15 +787,14 @@ impl Construct {
|
||||
construct,
|
||||
amount: healing,
|
||||
overhealing,
|
||||
colour: Colour::Green,
|
||||
});
|
||||
},
|
||||
true => {
|
||||
// events.push(Event::new(Event::Inversion { skill }));
|
||||
|
||||
// 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);
|
||||
let delta = current_green_life - self.green_life();
|
||||
let delta = current_green_life - self.stat(Stat::GreenLife);
|
||||
|
||||
events.push(Event::Damage {
|
||||
construct,
|
||||
@ -628,132 +813,13 @@ impl Construct {
|
||||
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![];
|
||||
if self.is_ko() { return events; }
|
||||
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()
|
||||
.filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken))
|
||||
.filter(|e| e.effect.modifications().contains(&Stat::BlueHealingReceived))
|
||||
.map(|e| (e.effect, e.meta))
|
||||
.collect::<Vec<(Effect, Option<EffectMeta>)>>();
|
||||
|
||||
@ -762,128 +828,38 @@ impl Construct {
|
||||
|
||||
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);
|
||||
let current_blue_life = self.stat(Stat::BlueLife);
|
||||
self.blue_life.increase(modified_power);
|
||||
let new_blue_life = self.blue_life.value;
|
||||
let healing = new_blue_life - current_blue_life;
|
||||
let overhealing = modified_power - healing;
|
||||
|
||||
// reduce red_life by mitigation amount
|
||||
self.red_life.reduce(mitigation);
|
||||
|
||||
// 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 });
|
||||
if healing != 0 {
|
||||
events.push(Event::Healing { construct: self.id, amount: healing, overhealing, colour: Colour::Red });
|
||||
}
|
||||
},
|
||||
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.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);
|
||||
// Recharge takes a red and blue amount so check for them
|
||||
let blue_remainder = modified_power.saturating_sub(self.blue_life.value);
|
||||
let blue_mitigation = modified_power.saturating_sub(blue_remainder);
|
||||
|
||||
// reduce blue_life by mitigation amount
|
||||
self.blue_life.reduce(mitigation);
|
||||
self.blue_life.reduce(blue_mitigation);
|
||||
|
||||
// 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();
|
||||
let blue_current_green_life = self.stat(Stat::GreenLife);
|
||||
self.reduce_green_life(blue_remainder);
|
||||
let blue_damage_amount = blue_current_green_life - self.stat(Stat::GreenLife);
|
||||
|
||||
events.push(Event::Damage {
|
||||
construct,
|
||||
amount: delta,
|
||||
mitigation,
|
||||
colour: Colour::Blue,
|
||||
construct: self.id,
|
||||
amount: blue_damage_amount,
|
||||
mitigation: blue_mitigation,
|
||||
colour: Colour::Red,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ impl Effect {
|
||||
pub fn modifications(&self) -> Vec<Stat> {
|
||||
match self {
|
||||
// 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::Slow => vec![Stat::Speed],
|
||||
|
||||
@ -112,10 +112,10 @@ impl Effect {
|
||||
Effect::Hybrid => vec![Stat::GreenPower],
|
||||
|
||||
// Damage taken changes
|
||||
Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken],
|
||||
Effect::Pure => vec![Stat::GreenDamageTaken], // increased green taken
|
||||
Effect::Vulnerable => vec![Stat::RedDamageTaken],
|
||||
Effect::Wither => vec![Stat::GreenDamageTaken], // reduced green taken
|
||||
Effect::Curse => vec![Stat::RedDamageReceived, Stat::BlueDamageReceived],
|
||||
Effect::Pure => vec![Stat::GreenHealingReceived], // increased green taken
|
||||
Effect::Vulnerable => vec![Stat::RedDamageReceived],
|
||||
Effect::Wither => vec![Stat::GreenHealingReceived], // reduced green taken
|
||||
|
||||
// Speed
|
||||
Effect::Haste => vec![Stat::Speed],
|
||||
|
||||
@ -587,7 +587,7 @@ impl Game {
|
||||
Value::ColourSkills { construct, colour, 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 {
|
||||
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } =>
|
||||
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> {
|
||||
match 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
|
||||
}
|
||||
self.construct_by_id(construct).unwrap().damage(amount, colour)
|
||||
}
|
||||
|
||||
fn heal(&mut self, construct: Uuid, value: usize, colour: Colour) -> Vec<Event> {
|
||||
match colour {
|
||||
_ => self.construct_by_id(construct).unwrap().deal_red_damage(value) // fixme unwrap
|
||||
}
|
||||
fn heal(&mut self, construct: Uuid, amount: usize, colour: Colour) -> Vec<Event> {
|
||||
self.construct_by_id(construct).unwrap().healing(amount, colour)
|
||||
}
|
||||
|
||||
fn effect(&mut self, construct: Uuid, effect: ConstructEffect) -> Vec<Event> {
|
||||
@ -844,7 +838,7 @@ pub enum Value {
|
||||
ColourSkills { construct: Uuid, colour: Colour, mult: usize },
|
||||
Effects { 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)]
|
||||
@ -904,8 +898,7 @@ pub enum Event {
|
||||
Effect { construct: Uuid, effect: Effect, duration: u8, display: EventConstruct },
|
||||
Removal { construct: Uuid, effect: Effect, display: EventConstruct },
|
||||
|
||||
Healing { construct: Uuid, amount: usize, overhealing: usize },
|
||||
Recharge { construct: Uuid, red: usize, blue: usize },
|
||||
Healing { construct: Uuid, amount: usize, overhealing: usize, colour: Colour },
|
||||
Inversion { construct: Uuid },
|
||||
Reflection { construct: Uuid },
|
||||
Ko { construct: Uuid },
|
||||
@ -969,9 +962,9 @@ impl EventConstruct {
|
||||
pub fn new(construct: &Construct) -> EventConstruct {
|
||||
EventConstruct {
|
||||
id: construct.id,
|
||||
red: construct.red_life(),
|
||||
green: construct.green_life(),
|
||||
blue: construct.blue_life(),
|
||||
red: construct.stat(Stat::RedLife),
|
||||
green: construct.stat(Stat::GreenLife),
|
||||
blue: construct.stat(Stat::BlueLife),
|
||||
effects: construct.effects.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -719,7 +719,7 @@ impl Cast {
|
||||
Action::Heal {
|
||||
construct: self.target,
|
||||
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 {
|
||||
construct: self.target,
|
||||
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