overlord_event_system/behaviors/combat/
fight_start.rs1use essences::combat_origin::CombatEventOrigin;
15use essences::fight_breakdown::CombatSource;
16use essences::fighting::ActiveFight;
17
18use crate::behaviors::{BehaviorKind, BehaviorMeta, BehaviorRegistry};
19use crate::event::OverlordEvent;
20use crate::mechanics::content_lookups::ContentLookups;
21use crate::mechanics::fight::{self, NativeSink};
22use crate::state::OverlordState;
23
24pub struct FightStartCtx<'a> {
29 pub fight: &'a ActiveFight,
30 pub state: &'a OverlordState,
31 pub lookups: &'a ContentLookups,
32}
33
34pub type FightStartFn = fn(&FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>>;
36
37pub fn init_fight_self(ctx: &FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>> {
41 let mut sink = NativeSink::default();
42 fight::init_fight(
43 &mut sink,
44 ctx.lookups,
45 ctx.fight,
46 ctx.state,
47 ctx.fight.fight_id,
48 )
49 .map_err(|e| anyhow::anyhow!("init_fight: {e}"))?;
50 Ok(sink.events)
51}
52
53pub fn init_fight_self_static_buff(ctx: &FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>> {
58 let mut events = init_fight_self(ctx)?;
59 events.push(OverlordEvent::EntityIncrAttribute {
60 entity_id: ctx.fight.player_id,
61 attribute: "static".to_string(),
62 delta: 1,
63 });
64 if let Some(party_player_id) = ctx.fight.party_player_id {
65 events.push(OverlordEvent::EntityIncrAttribute {
66 entity_id: party_player_id,
67 attribute: "static".to_string(),
68 delta: 1,
69 });
70 }
71 Ok(events)
72}
73
74pub fn noop(_ctx: &FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>> {
78 Ok(vec![])
79}
80
81pub fn damage_first_entity_5(ctx: &FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>> {
86 let Some(entity) = ctx.fight.entities.first() else {
87 return Ok(vec![]);
88 };
89 Ok(vec![OverlordEvent::Damage {
90 by_entity_id: None,
91 entity_id: entity.id,
92 damage: 5,
93 damage_data: crate::event::CustomEventData::default(),
94 origin: CombatEventOrigin::Core,
95 source: CombatSource::Other,
96 }])
97}
98
99pub fn apply_spawn_on_death_to_player(ctx: &FightStartCtx) -> anyhow::Result<Vec<OverlordEvent>> {
104 Ok(vec![OverlordEvent::EntityApplyEffect {
105 entity_id: ctx.fight.player_id,
106 effect_id: uuid::Uuid::parse_str("39f135d2-b930-42a7-abfa-f1ec49f3cc00")?,
107 origin: CombatEventOrigin::Core,
108 }])
109}
110
111pub fn register(registry: &mut BehaviorRegistry) {
113 registry.register_fight_start(
114 BehaviorMeta {
115 name: "noop".to_string(),
116 category: BehaviorKind::FightStart,
117 title: "Пустой start_behavior".to_string(),
118 description: "Эквивалент пустого start_behavior — не создаёт событий.".to_string(),
119 },
120 noop,
121 );
122 registry.register_fight_start(
123 BehaviorMeta {
124 name: "damage_first_entity_5".to_string(),
125 category: BehaviorKind::FightStart,
126 title: "Урон 5 по первой сущности (тест)".to_string(),
127 description: "Damage(Fight.entities[0], 5) — порт test fight start_behavior."
128 .to_string(),
129 },
130 damage_first_entity_5,
131 );
132 registry.register_fight_start(
133 BehaviorMeta {
134 name: "apply_spawn_on_death_to_player".to_string(),
135 category: BehaviorKind::FightStart,
136 title: "Эффект spawn-on-death на игрока (тест)".to_string(),
137 description: "ApplyEffect(Fight.player_id, 39f135d2) — порт test fight start_behavior."
138 .to_string(),
139 },
140 apply_spawn_on_death_to_player,
141 );
142 registry.register_fight_start(
143 BehaviorMeta {
144 name: "init_fight_self".to_string(),
145 category: BehaviorKind::FightStart,
146 title: "Инициализация боя".to_string(),
147 description: "Порт start_behavior `ctx.init_fight(State, <self id>)` — \
148 стартовые события боя через init_fight (без RNG)."
149 .to_string(),
150 },
151 init_fight_self,
152 );
153 registry.register_fight_start(
154 BehaviorMeta {
155 name: "init_fight_self_static_buff".to_string(),
156 category: BehaviorKind::FightStart,
157 title: "Инициализация боя + static-бафф".to_string(),
158 description: "Порт init_fight + push EntityIncrAttribute(player, \"static\", 1) \
159 и того же для party_player_id, если он есть."
160 .to_string(),
161 },
162 init_fight_self_static_buff,
163 );
164}