This commit is contained in:
Mashy 2019-12-06 16:26:50 +10:00
parent 517b912c2e
commit 7afb6e30bd
3 changed files with 98 additions and 102 deletions

View File

@ -4,7 +4,7 @@ use rand::prelude::*;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use skill::{Skill, Cast, Disable, Event, EventVariant, EventConstruct}; use skill::{Skill, Cast, Disable, EventVariant, EventConstruct};
use game::{Colour}; use game::{Colour};
use effect::{Cooldown, Effect}; use effect::{Cooldown, Effect};
use spec::{Spec}; use spec::{Spec};
@ -415,7 +415,7 @@ impl Construct {
self self
} }
pub fn increase_cooldowns(&mut self, turns: usize) -> Vec<Event> { pub fn increase_cooldowns(&mut self, turns: usize) -> Vec<EventVariant> {
let mut events = vec![]; let mut events = vec![];
for skill in self.skills.iter_mut() { for skill in self.skills.iter_mut() {
@ -423,11 +423,11 @@ impl Construct {
match skill.cd { match skill.cd {
Some(cd) => { Some(cd) => {
skill.cd = Some(cd.saturating_add(turns)); skill.cd = Some(cd.saturating_add(turns));
events.push(Event::new(EventVariant::CooldownIncrease { turns, skill: skill.skill }, self.id)) events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill })
}, },
None => { None => {
skill.cd = Some(turns); skill.cd = Some(turns);
events.push(Event::new(EventVariant::CooldownIncrease { turns, skill: skill.skill }, self.id)) events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill })
}, },
} }
} }
@ -546,7 +546,7 @@ impl Construct {
} }
} }
pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec<Event> { pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec<EventVariant> {
let mut events = vec![]; let mut events = vec![];
if self.is_ko() { return events; } if self.is_ko() { return events; }
@ -565,7 +565,7 @@ impl Construct {
let blue = new_blue_life - current_blue_life; let blue = new_blue_life - current_blue_life;
if red != 0 || blue != 0 { if red != 0 || blue != 0 {
events.push(Event::new(EventVariant::Recharge { red, blue }, self.id)); events.push(EventVariant::Recharge { red, blue });
} }
}, },
true => { true => {
@ -591,12 +591,12 @@ impl Construct {
self.reduce_green_life(red_remainder); self.reduce_green_life(red_remainder);
let red_damage_amount = red_current_green_life - self.green_life(); let red_damage_amount = red_current_green_life - self.green_life();
events.push(Event::new(EventVariant::Damage { events.push(EventVariant::Damage {
amount: red_damage_amount, amount: red_damage_amount,
mitigation: red_mitigation, mitigation: red_mitigation,
colour: Colour::Red, colour: Colour::Red,
display: EventConstruct::new(self), display: EventConstruct::new(self),
}, self.id)); });
} }
if blue_amount != 0 { if blue_amount != 0 {
@ -620,19 +620,19 @@ impl Construct {
self.reduce_green_life(blue_remainder); self.reduce_green_life(blue_remainder);
let blue_damage_amount = blue_current_green_life - self.green_life(); let blue_damage_amount = blue_current_green_life - self.green_life();
events.push(Event::new(EventVariant::Damage { events.push(EventVariant::Damage {
amount: blue_damage_amount, amount: blue_damage_amount,
mitigation: blue_mitigation, mitigation: blue_mitigation,
colour: Colour::Blue, colour: Colour::Blue,
display: EventConstruct::new(self), display: EventConstruct::new(self),
}, self.id)); });
} }
} }
} }
return events; return events;
} }
pub fn deal_green_damage(&mut self, amount: usize) -> Vec<Event> { pub fn deal_green_damage(&mut self, amount: usize) -> Vec<EventVariant> {
let mut events = vec![]; let mut events = vec![];
if self.is_ko() { return events; } if self.is_ko() { return events; }
@ -653,10 +653,10 @@ impl Construct {
let healing = new_green_life - current_green_life; let healing = new_green_life - current_green_life;
let overhealing = modified_power - healing; let overhealing = modified_power - healing;
events.push(Event::new(EventVariant::Healing { events.push(EventVariant::Healing {
amount: healing, amount: healing,
overhealing, overhealing,
}, self.id)); });
}, },
true => { true => {
// events.push(Event::new(EventVariant::Inversion { skill })); // events.push(Event::new(EventVariant::Inversion { skill }));
@ -666,19 +666,19 @@ impl Construct {
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.green_life();
events.push(Event::new(EventVariant::Damage { events.push(EventVariant::Damage {
amount: delta, amount: delta,
mitigation: 0, mitigation: 0,
colour: Colour::Green, colour: Colour::Green,
display: EventConstruct::new(self), display: EventConstruct::new(self),
}, self.id)); });
} }
} }
return events; return events;
} }
pub fn deal_red_damage(&mut self, amount: usize) -> Vec<Event> { pub fn deal_red_damage(&mut self, amount: usize) -> Vec<EventVariant> {
let mut events = vec![]; let mut events = vec![];
if self.is_ko() { return events; } if self.is_ko() { return events; }
@ -708,17 +708,16 @@ impl Construct {
self.reduce_green_life(remainder); self.reduce_green_life(remainder);
let delta = current_green_life - self.green_life(); let delta = current_green_life - self.green_life();
events.push(Event::new( events.push(
EventVariant::Damage { EventVariant::Damage {
amount: delta, amount: delta,
mitigation, mitigation,
colour: Colour::Red, colour: Colour::Red,
display: EventConstruct::new(self), display: EventConstruct::new(self),
}, }
self.id );
));
if self.is_ko() { if self.is_ko() {
events.push(Event::new(EventVariant::Ko {}, self.id)); events.push(EventVariant::Ko {});
} }
}, },
true => { true => {
@ -735,16 +734,16 @@ impl Construct {
let recharge = self.red_life.value - current_life; let recharge = self.red_life.value - current_life;
if healing > 0 { if healing > 0 {
events.push(Event::new( events.push(
EventVariant::Healing{ EventVariant::Healing {
amount: healing, amount: healing,
overhealing: overhealing - recharge, overhealing: overhealing - recharge,
}, self.id }
)); );
} }
if recharge > 0 { if recharge > 0 {
events.push(Event::new(EventVariant::Recharge { red: recharge, blue: 0 }, self.id)); events.push(EventVariant::Recharge { red: recharge, blue: 0 });
} }
} }
}; };
@ -752,7 +751,7 @@ impl Construct {
return events; return events;
} }
pub fn deal_blue_damage(&mut self, amount: usize) -> Vec<Event> { pub fn deal_blue_damage(&mut self, amount: usize) -> Vec<EventVariant> {
let mut events = vec![]; let mut events = vec![];
if self.is_ko() { return events; } if self.is_ko() { return events; }
@ -778,12 +777,12 @@ impl Construct {
self.reduce_green_life(remainder); self.reduce_green_life(remainder);
let delta = current_green_life - self.green_life(); let delta = current_green_life - self.green_life();
events.push(Event::new(EventVariant::Damage { events.push(EventVariant::Damage {
amount: delta, amount: delta,
mitigation, mitigation,
colour: Colour::Blue, colour: Colour::Blue,
display: EventConstruct::new(self), display: EventConstruct::new(self),
}, self.id)); });
}, },
true => { true => {
// events.push(Event::new(EventVariant::Inversion { skill })); // events.push(Event::new(EventVariant::Inversion { skill }));
@ -799,17 +798,11 @@ impl Construct {
let recharge = self.blue_life.value - current_life; let recharge = self.blue_life.value - current_life;
if healing > 0 { if healing > 0 {
events.push( events.push(EventVariant::Healing { amount: healing, overhealing });
Event::new(EventVariant::Healing {
amount: healing,
overhealing,
},
self.id
));
} }
if recharge > 0 { if recharge > 0 {
events.push(Event::new(EventVariant::Recharge { red: 0, blue: recharge }, self.id)); events.push(EventVariant::Recharge { red: 0, blue: recharge });
} }
} }
}; };
@ -817,7 +810,7 @@ impl Construct {
return events; return events;
} }
pub fn add_effect(&mut self, effect: ConstructEffect) -> Vec<Event> { pub fn add_effect(&mut self, effect: ConstructEffect) -> Vec<EventVariant> {
if self.is_ko() { return vec![] } if self.is_ko() { return vec![] }
if self.affected(Effect::Banish) { panic!("banish immunity not fixt yet") } if self.affected(Effect::Banish) { panic!("banish immunity not fixt yet") }
@ -834,13 +827,11 @@ impl Construct {
} }
// todo modified durations cause of buffs // todo modified durations cause of buffs
let result = Event::new( let result = EventVariant::Effect {
EventVariant::Effect { effect: effect.effect,
effect: effect.effect, duration: effect.duration,
duration: effect.duration, display: EventConstruct::new(self)
display: EventConstruct::new(self), };
}, self.id
);
return vec![result]; return vec![result];
} }

View File

@ -40,11 +40,11 @@ pub enum Colour {
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum Action { pub enum Action {
Hit { construct: Uuid, skill: Skill }, Hit { cast: Cast },
HitCast { construct: Uuid, skill: Skill, source: Uuid }, HitCast { cast: Cast },
Damage { construct: Uuid, values: Vec<Value>, colour: Colour }, Damage { cast: Cast, construct: Uuid, values: Vec<Value>, colour: Colour },
Effect { construct: Uuid, effect: ConstructEffect }, Effect { cast: Cast, construct: Uuid, effect: ConstructEffect },
IncreaseCooldowns { construct: Uuid, turns: usize }, IncreaseCooldowns { cast: Cast, construct: Uuid, turns: usize },
// Recharge { skill: Skill, red: usize, blue: usize }, // Recharge { skill: Skill, red: usize, blue: usize },
} }
@ -493,7 +493,12 @@ impl Game {
self.skill_phase_start(r_animation_ms) self.skill_phase_start(r_animation_ms)
} }
fn event_add(&mut self, mut events: Vec<Event>) -> &mut Game { fn event_add(&mut self, event_variants: Vec<EventVariant>, cast: Cast) -> &mut Game {
let mut events = event_variants
.iter()
.map(|e| e.to_event(cast))
.collect();
self.events.last_mut().unwrap().append(&mut events); self.events.last_mut().unwrap().append(&mut events);
self self
} }
@ -501,45 +506,44 @@ impl Game {
pub fn actions(&mut self, actions: Vec<Action>) -> &mut Game { pub fn actions(&mut self, actions: Vec<Action>) -> &mut Game {
for action in actions { for action in actions {
match action { match action {
Action::Hit { construct, skill } => self.hit(construct, skill), Action::Hit { cast } => self.hit(cast),
Action::HitCast { construct, skill, source } => self.hit_cast(construct, skill, source), Action::HitCast { cast } => self.hit_cast(cast),
Action::Damage { construct, values, colour } => self.damage(construct, values, colour), Action::Damage { cast, construct, values, colour } => self.damage(cast, construct, values, colour),
Action::Effect { construct, effect } => self.effect(construct, effect), Action::Effect { cast, construct, effect } => self.effect(cast, construct, effect),
Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns), Action::IncreaseCooldowns { cast, construct, turns } => self.increase_cooldowns(cast, construct, turns),
}; };
} }
self self
} }
fn hit_cast(&mut self, construct: Uuid, skill: Skill, source: Uuid) -> &mut Game { fn hit_cast(&mut self, cast: Cast) -> &mut Game {
self.event_add(vec![Event::new(EventVariant::HitCast { skill: skill, source: source }, construct)]); self.event_add(vec![EventVariant::HitCast()], cast);
self self
} }
fn hit(&mut self, construct: Uuid, skill: Skill) -> &mut Game { fn hit(&mut self, cast: Cast) -> &mut Game {
self.event_add(vec![Event::new(EventVariant::Hit { skill: skill }, construct)]); self.event_add(vec![EventVariant::Hit()], cast);
self self
} }
fn damage(&mut self, construct: Uuid, values: Vec<Value>, colour: Colour) -> &mut Game { fn damage(&mut self, cast: Cast, construct: Uuid, values: Vec<Value>, colour: Colour) -> &mut Game {
let events = match colour { let events = match colour {
_ => self.construct_by_id(construct).unwrap().deal_red_damage(128) // fixme unwrap _ => self.construct_by_id(construct).unwrap().deal_red_damage(128) // fixme unwrap
}; };
self.event_add(events, cast);
self.event_add(events);
self self
} }
fn effect(&mut self, construct: Uuid, effect: ConstructEffect) -> &mut Game { fn effect(&mut self, cast: Cast, construct: Uuid, effect: ConstructEffect) -> &mut Game {
let events = self.construct_by_id(construct).unwrap().add_effect(effect); let events = self.construct_by_id(construct).unwrap().add_effect(effect);
self.event_add(events); self.event_add(events, cast);
self self
} }
fn increase_cooldowns(&mut self, construct: Uuid, turns: usize) -> &mut Game { fn increase_cooldowns(&mut self, cast: Cast, construct: Uuid, turns: usize) -> &mut Game {
let events = self.construct_by_id(construct).unwrap().increase_cooldowns(turns); let events = self.construct_by_id(construct).unwrap().increase_cooldowns(turns);
self.event_add(events); self.event_add(events, cast);
self self
} }

View File

@ -89,6 +89,10 @@ impl Cast {
}; };
} }
pub fn target(self) -> Uuid {
self.target
}
pub fn new_tick(source: &mut Construct, target: &mut Construct, skill: Skill) -> Cast { pub fn new_tick(source: &mut Construct, target: &mut Construct, skill: Skill) -> Cast {
Cast { Cast {
id: Uuid::new_v4(), id: Uuid::new_v4(),
@ -106,25 +110,28 @@ impl Cast {
pub fn actions(&self) -> Vec<Action> { pub fn actions(&self) -> Vec<Action> {
let mut actions = match self.skill.is_tick() { let mut actions = match self.skill.is_tick() {
false => vec![Action::HitCast { construct: self.target, skill: self.skill, source: self.source }], false => vec![Action::HitCast { cast: *self } ],
true => vec![Action::Hit { construct: self.target, skill: self.skill }] true => vec![Action::Hit { cast: *self } ]
}; };
let mut rest = match self.skill { let mut rest = match self.skill {
Skill::Amplify => vec![ Skill::Amplify => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)), tick: None }, effect: ConstructEffect { effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)), tick: None },
}, },
], ],
Skill::AmplifyPlus => vec![ Skill::AmplifyPlus => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)), tick: None }, effect: ConstructEffect { effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)), tick: None },
}, },
], ],
Skill::AmplifyPlusPlus => vec![ Skill::AmplifyPlusPlus => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)), tick: None }, effect: ConstructEffect { effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)), tick: None },
}, },
@ -132,6 +139,7 @@ impl Cast {
Skill::Attack => vec![ Skill::Attack => vec![
Action::Damage { Action::Damage {
cast: *self,
construct: self.target, construct: self.target,
colour: Colour::Red, colour: Colour::Red,
values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }], values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }],
@ -141,18 +149,21 @@ impl Cast {
Skill::Banish => vec![ Skill::Banish => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None }
} }
], ],
Skill::BanishPlus => vec![ Skill::BanishPlus => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None }
} }
], ],
Skill::BanishPlusPlus => vec![ Skill::BanishPlusPlus => vec![
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None } effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None, tick: None }
} }
@ -162,6 +173,7 @@ impl Cast {
Skill::BashPlus | Skill::BashPlus |
Skill::BashPlusPlus => vec![ Skill::BashPlusPlus => vec![
Action::Damage { Action::Damage {
cast: *self,
construct: self.target, construct: self.target,
colour: Colour::Red, colour: Colour::Red,
values: vec![ values: vec![
@ -170,10 +182,12 @@ impl Cast {
], ],
}, },
Action::Effect { Action::Effect {
cast: *self,
construct: self.target, construct: self.target,
effect: ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None } effect: ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None }
}, },
Action::IncreaseCooldowns { Action::IncreaseCooldowns {
cast: *self,
construct: self.target, construct: self.target,
turns: 1, turns: 1,
}, },
@ -183,6 +197,7 @@ impl Cast {
Skill::BlastPlus | Skill::BlastPlus |
Skill::BlastPlusPlus => vec![ Skill::BlastPlusPlus => vec![
Action::Damage { Action::Damage {
cast: *self,
construct: self.target, construct: self.target,
colour: Colour::Blue, colour: Colour::Blue,
values: vec![Value::Stat { construct: self.source, stat: Stat::BluePower, mult: self.skill.multiplier() }], values: vec![Value::Stat { construct: self.source, stat: Stat::BluePower, mult: self.skill.multiplier() }],
@ -193,6 +208,7 @@ impl Cast {
Skill::StrikePlus | Skill::StrikePlus |
Skill::StrikePlusPlus => vec![ Skill::StrikePlusPlus => vec![
Action::Damage { Action::Damage {
cast: *self,
construct: self.target, construct: self.target,
colour: Colour::Red, colour: Colour::Red,
values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }], values: vec![Value::Stat { construct: self.source, stat: Stat::RedPower, mult: self.skill.multiplier() }],
@ -211,32 +227,20 @@ pub type Disable = Vec<Effect>;
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub struct Event { pub struct Event {
pub target: Uuid, pub cast: Cast,
pub variant: EventVariant, pub variant: EventVariant,
pub delay: i64, pub delay: i64,
} }
impl Event { #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub fn new(variant: EventVariant, target: Uuid) -> Event {
let delay = variant.delay();
Event {
target,
variant,
delay,
}
}
}
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum EventVariant { pub enum EventVariant {
Hit { skill: Skill }, Hit (),
HitCast { skill: Skill, source: Uuid }, HitCast (),
Damage { amount: usize, mitigation: usize, colour: Colour, display: EventConstruct }, Damage { amount: usize, mitigation: usize, colour: Colour, display: EventConstruct },
Effect { effect: Effect, duration: u8, display: EventConstruct }, Effect { effect: Effect, duration: u8, display: EventConstruct },
Removal { effect: Option<Effect>, display: EventConstruct }, Removal { effect: Option<Effect>, display: EventConstruct },
Disable { disable: Disable },
Healing { amount: usize, overhealing: usize }, Healing { amount: usize, overhealing: usize },
Recharge { red: usize, blue: usize }, Recharge { red: usize, blue: usize },
Inversion { skill: Skill }, Inversion { skill: Skill },
@ -264,16 +268,25 @@ impl EventVariant {
let combat_text_overlap = 600; // overlap between animation and combat text let combat_text_overlap = 600; // overlap between animation and combat text
match self { match self {
EventVariant::Hit { skill: _ } => target_duration - combat_text_overlap, EventVariant::Hit() => target_duration - combat_text_overlap,
EventVariant::HitCast { skill: _, source: _ } => target_delay + target_duration - combat_text_overlap, EventVariant::HitCast() => target_delay + target_duration - combat_text_overlap,
_ => combat_text_delay, _ => combat_text_delay,
} }
} }
pub fn to_event(&self, cast: Cast) -> Event {
let delay = self.delay();
Event {
cast,
variant: *self,
delay,
}
}
} }
// used to show the progress of a construct // used to show the progress of a construct
// while the resolutions are animating // while the resolutions are animating
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub struct EventConstruct { pub struct EventConstruct {
pub id: Uuid, pub id: Uuid,
pub red: usize, pub red: usize,
@ -1555,19 +1568,7 @@ mod tests {
let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack); let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack);
let actions = cast.actions(); let actions = cast.actions();
match actions[0] {
Action::Hit { construct: _, skill } => {
assert_eq!(skill, Skill::Attack);
},
_ => panic!("{:?}", actions),
};
match actions[1] {
Action::Damage { construct: _, values: _, colour } => {
assert_eq!(colour, Colour::Red);
},
_ => panic!("{:?}", actions),
};
} }
// #[test] // #[test]