diff --git a/src/plugins/action.rs b/src/plugins/action.rs index 0d1b7bdfa..76eff1b52 100644 --- a/src/plugins/action.rs +++ b/src/plugins/action.rs @@ -105,7 +105,7 @@ impl ActionPlugin { let t = GameTimer::get().play_head(); world.get_resource::().and_then(|d| { d.events.iter().rev().find_map(|(ts, e)| match t >= *ts { - true => Some((*e, t - *ts)), + true => Some((e.clone(), t - *ts)), false => None, }) }) diff --git a/src/plugins/battle.rs b/src/plugins/battle.rs index 8d154982c..a7db905aa 100644 --- a/src/plugins/battle.rs +++ b/src/plugins/battle.rs @@ -1,4 +1,5 @@ use bevy_egui::egui::Align2; +use event::Event; use crate::module_bindings::ArenaRun; @@ -66,7 +67,8 @@ impl BattlePlugin { UnitPlugin::translate_to_slots(world); GameTimer::get().insert_to_end(); ActionPlugin::spin(world)?; - Event::BattleStart.send(world).spin(world)?; + Event::BattleStart.send(world); + ActionPlugin::spin(world)?; loop { if let Some((left, right)) = Self::get_strikers(world) { Self::run_strike(left, right, world)?; @@ -126,16 +128,20 @@ impl BattlePlugin { Self::strike(left, right, world)?; Self::after_strike(left, right, world)?; Self::fatigue(world)?; - Event::TurnEnd.send(world).spin(world)?; + Event::TurnEnd.send(world); + ActionPlugin::spin(world)?; ActionPlugin::spin(world)?; Ok(()) } fn before_strike(left: Entity, right: Entity, world: &mut World) -> Result<()> { debug!("Before strike {left:?} {right:?}"); - Event::TurnStart.send(world).spin(world)?; - Event::BeforeStrike(left, right).send(world).spin(world)?; - Event::BeforeStrike(right, left).send(world).spin(world)?; + Event::TurnStart.send(world); + ActionPlugin::spin(world)?; + Event::BeforeStrike(left, right).send(world); + ActionPlugin::spin(world)?; + Event::BeforeStrike(right, left).send(world); + ActionPlugin::spin(world)?; if Self::stricker_death_check(left, right, world) { return Ok(()); } @@ -188,8 +194,10 @@ impl BattlePlugin { GameTimer::get().to_batch_start(); } GameTimer::get().insert_to_end().end_batch(); - Event::AfterStrike(left, right).send(world).spin(world)?; - Event::AfterStrike(right, left).send(world).spin(world)?; + Event::AfterStrike(left, right).send(world); + ActionPlugin::spin(world)?; + Event::AfterStrike(right, left).send(world); + ActionPlugin::spin(world)?; Ok(()) } diff --git a/src/resourses/context.rs b/src/resourses/context.rs index d878db11f..c74281ecf 100644 --- a/src/resourses/context.rs +++ b/src/resourses/context.rs @@ -45,7 +45,7 @@ impl ContextLayer { } pub fn get_event(&self) -> Option { match self { - ContextLayer::Event(entity, ..) => Some(*entity), + ContextLayer::Event(event, ..) => Some(event.clone()), _ => None, } } diff --git a/src/resourses/effect.rs b/src/resourses/effect.rs index a19ada853..f4335f267 100644 --- a/src/resourses/effect.rs +++ b/src/resourses/effect.rs @@ -12,7 +12,6 @@ pub enum Effect { Debug(Expression), Text(Expression), Damage(Option), - AoeFaction(Expression, Box), WithTarget(Expression, Box), WithOwner(Expression, Box), List(Vec>), @@ -46,12 +45,12 @@ impl Effect { .context("Can't find ATK")?, }; debug!("Damage {} {target:?}", value.to_string()); - Event::IncomingDamage { + let event = Event::IncomingDamage { owner: target, value: value.get_int()?, - } - .send_with_context(context.clone(), world) - .map(&mut value, world); + }; + event.clone().send_with_context(context.clone(), world); + event.map(&mut value, world); debug!("Value after map {value:?}"); let value = value.get_int()?; if value > 0 { @@ -112,25 +111,19 @@ impl Effect { .take(), world, )?; - { - let mut context = context - .clone() - .set_var(VarName::Color, VarValue::Color(color)) - .take(); - - context.set_var( - VarName::Charges, - VarValue::Int( - context - .get_var(VarName::Level, world) - .map(|v| v.get_int().unwrap()) - .unwrap_or(1) - + *base, - ), - ); - ActionPlugin::action_push_front(effect, context, world); - } + let mut context = context + .clone() + .set_var(VarName::Color, VarValue::Color(color)) + .take(); + let charges = context + .get_var(VarName::Level, world) + .map(|v| v.get_int().unwrap()) + .unwrap_or(1) + + *base; + context.set_var(VarName::Charges, VarValue::Int(charges)); + Event::UseAbility(ability.to_owned()).send_with_context(context.clone(), world); + ActionPlugin::action_push_front(effect, context, world); } Effect::Summon(name) => { let mut unit = Pools::get_summon(name, world) @@ -150,33 +143,25 @@ impl Effect { unit.atk += extra_atk; let color = Pools::get_color_by_name(name, world)?; - TextColumn::add( - context.owner(), - &format!("Summon {name}"), - color.c32(), - world, - )?; - { - let mut context = context - .clone() - .set_var(VarName::Color, VarValue::Color(color)) - .take(); - if context.get_var(VarName::Charges, world).is_none() { - context.set_var( - VarName::Charges, - context - .get_var(VarName::Level, world) - .unwrap_or(VarValue::Int(1)), - ); - } - let faction = context.get_faction(world)?; - let parent = - TeamPlugin::find_entity(faction, world).context("Team not found")?; - let entity = unit.unpack(parent, None, world); - UnitPlugin::fill_slot_gaps(faction, world); - UnitPlugin::translate_to_slots(world); - Event::Summon(entity).send_with_context(context.clone(), world); + + let mut context = context + .clone() + .set_var(VarName::Color, VarValue::Color(color)) + .take(); + if context.get_var(VarName::Charges, world).is_none() { + context.set_var( + VarName::Charges, + context + .get_var(VarName::Level, world) + .unwrap_or(VarValue::Int(1)), + ); } + let faction = context.get_faction(world)?; + let parent = TeamPlugin::find_entity(faction, world).context("Team not found")?; + let entity = unit.unpack(parent, None, world); + UnitPlugin::fill_slot_gaps(faction, world); + UnitPlugin::translate_to_slots(world); + Event::Summon(entity).send_with_context(context.clone(), world); } Effect::AddStatus(status) => { let charges = context @@ -231,13 +216,6 @@ impl Effect { ActionPlugin::action_push_front(effect.deref().clone(), context.clone(), world); } } - Effect::AoeFaction(faction, effect) => { - for unit in UnitPlugin::collect_faction(faction.get_faction(context, world)?, world) - { - let context = context.clone().set_target(unit, world).take(); - ActionPlugin::action_push_front(effect.deref().clone(), context, world); - } - } Effect::Text(text) => { let text = text.get_string(context, world)?; TextColumn::add(context.owner(), &text, Color::PINK.c32(), world)?; @@ -400,8 +378,7 @@ impl Effect { | Effect::StateAddVar(..) | Effect::AbilityStateAddVar(..) | Effect::SendEvent(..) => default(), - Effect::AoeFaction(_, e) - | Effect::WithTarget(_, e) + Effect::WithTarget(_, e) | Effect::Repeat(_, e) | Effect::WithOwner(_, e) | Effect::WithVar(_, _, e) => vec![e], @@ -432,8 +409,7 @@ impl EditorNodeGenerator for Effect { fn show_extra(&mut self, path: &str, context: &Context, world: &mut World, ui: &mut Ui) { match self { - Effect::AoeFaction(_, _) - | Effect::WithTarget(_, _) + Effect::WithTarget(_, _) | Effect::WithOwner(_, _) | Effect::Noop | Effect::Kill @@ -622,10 +598,7 @@ impl EditorNodeGenerator for Effect { show_node(e, format!("{path}:e"), connect_pos, context, ui, world); } } - Effect::AoeFaction(e, eff) - | Effect::WithTarget(e, eff) - | Effect::WithOwner(e, eff) - | Effect::Repeat(e, eff) => { + Effect::WithTarget(e, eff) | Effect::WithOwner(e, eff) | Effect::Repeat(e, eff) => { ui.vertical(|ui| { ui.horizontal(|ui| { show_node(e, format!("{path}:e"), connect_pos, context, ui, world); @@ -764,7 +737,7 @@ impl std::fmt::Display for Effect { .and_then(|x| Some(x.to_string())) .unwrap_or_default() ), - Effect::WithOwner(x, e) | Effect::WithTarget(x, e) | Effect::AoeFaction(x, e) => { + Effect::WithOwner(x, e) | Effect::WithTarget(x, e) => { write!(f, "{} ({x}, {e})", self.as_ref()) } Effect::List(list) | Effect::ListSpread(list) => write!( diff --git a/src/resourses/event.rs b/src/resourses/event.rs index 436cde0ae..b5ef9e6d8 100644 --- a/src/resourses/event.rs +++ b/src/resourses/event.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, Display, PartialEq, Eq, Serialize, Deserialize, Default, Clone, Copy)] +#[derive(Debug, Display, PartialEq, Eq, Serialize, Deserialize, Default, Clone)] pub enum Event { IncomingDamage { owner: Entity, @@ -32,13 +32,14 @@ pub enum Event { target: Entity, }, Summon(Entity), + UseAbility(String), } impl Event { - pub fn send_with_context(self, mut context: Context, world: &mut World) -> Self { + pub fn send_with_context(self, mut context: Context, world: &mut World) { debug!("Send event {self:?}"); - context.set_event(self); - ActionPlugin::register_event(self, world); + context.set_event(self.clone()); + ActionPlugin::register_event(self.clone(), world); let units = match &self { Event::DamageTaken { owner, value } | Event::IncomingDamage { owner, value } => { context.set_var(VarName::Value, VarValue::Int(*value)); @@ -48,12 +49,13 @@ impl Event { | Event::TurnStart | Event::TurnEnd | Event::Death(..) - | Event::Summon(..) => { + | Event::Summon(..) + | Event::UseAbility(..) => { let mut units = UnitPlugin::collect_all(world); units.sort_by_key(|e| VarState::get(*e, world).get_int(VarName::Slot).unwrap()); - match self { + match &self { Event::Death(e) | Event::Summon(e) => { - context.set_target(e, world); + context.set_target(*e, world); } _ => {} }; @@ -90,10 +92,9 @@ impl Event { world, ); } - self } - pub fn send(self, world: &mut World) -> Self { + pub fn send(self, world: &mut World) { self.send_with_context(Context::new_empty(), world) } @@ -120,8 +121,4 @@ impl Event { } self } - - pub fn spin(self, world: &mut World) -> Result { - ActionPlugin::spin(world) - } } diff --git a/src/resourses/mod.rs b/src/resourses/mod.rs index f5e79a636..5efce618f 100644 --- a/src/resourses/mod.rs +++ b/src/resourses/mod.rs @@ -39,6 +39,5 @@ pub use pools::*; pub use status_library::*; pub use test_scenarios::*; pub use trigger::*; -pub use unit_card::*; pub use vars::*; pub use vfx::*; diff --git a/src/resourses/trigger.rs b/src/resourses/trigger.rs index 687ca1195..b8d4839c1 100644 --- a/src/resourses/trigger.rs +++ b/src/resourses/trigger.rs @@ -37,6 +37,7 @@ pub enum FireTrigger { List(Vec>), Period(usize, usize, Box), OnceAfter(i32, Box), + UnitUsedAbility(String), AfterIncomingDamage, AfterDamageTaken, AfterDamageDealt, @@ -76,6 +77,10 @@ impl FireTrigger { .eq(&UnitPlugin::get_faction(context.owner(), world)), _ => false, }, + FireTrigger::UnitUsedAbility(name) => match event { + Event::UseAbility(e) => e.eq(name), + _ => false, + }, FireTrigger::BeforeDeath => match event { Event::Death(dead) => dead.eq(&context.owner()), _ => false, @@ -134,7 +139,8 @@ impl EditorNodeGenerator for FireTrigger { | FireTrigger::AnyDeath | FireTrigger::AllySummon | FireTrigger::BeforeDeath - | FireTrigger::AfterKill => hex_color!("#80D8FF"), + | FireTrigger::AfterKill + | FireTrigger::UnitUsedAbility(..) => hex_color!("#80D8FF"), FireTrigger::Period(..) | FireTrigger::OnceAfter(..) => hex_color!("#18FFFF"), FireTrigger::List(_) => hex_color!("#FFEB3B"), } @@ -189,11 +195,12 @@ impl EditorNodeGenerator for FireTrigger { | FireTrigger::AnyDeath | FireTrigger::AllySummon | FireTrigger::BeforeDeath - | FireTrigger::AfterKill => default(), + | FireTrigger::AfterKill + | FireTrigger::UnitUsedAbility(..) => default(), } } - fn show_extra(&mut self, _: &str, _: &Context, _: &mut World, ui: &mut Ui) { + fn show_extra(&mut self, path: &str, _: &Context, world: &mut World, ui: &mut Ui) { match self { FireTrigger::List(list) => { if ui.button("CLEAR").clicked() { @@ -206,6 +213,16 @@ impl EditorNodeGenerator for FireTrigger { FireTrigger::OnceAfter(delay, _) => { DragValue::new(delay).ui(ui); } + FireTrigger::UnitUsedAbility(name) => { + ComboBox::from_id_source(&path) + .selected_text(name.to_owned()) + .show_ui(ui, |ui| { + for option in Pools::get(world).abilities.keys().sorted() { + let text = option.to_string(); + ui.selectable_value(name, option.to_owned(), text); + } + }); + } FireTrigger::Noop | FireTrigger::AfterIncomingDamage | FireTrigger::AfterDamageTaken @@ -419,6 +436,12 @@ impl std::fmt::Display for FireTrigger { FireTrigger::OnceAfter(delay, trigger) => { write!(f, "Once in {delay} {trigger}") } + FireTrigger::UnitUsedAbility(name) => write!( + f, + "{} [{}]", + self.as_ref().to_case(convert_case::Case::Lower), + name + ), } } }