pub struct OverlordLogic { /* private fields */ }Implementations§
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_equip_ability( &self, slot_id: u64, ability_id: AbilityId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_unequip_ability( &self, slot_id: AbilitySlotId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_equip_abilities( &self, equipped_abilities: EquippedAbilities, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn make_cast_effect_action( &self, entity_id: EntityId, effect_id: EffectId, ) -> EntityAction
pub fn make_start_cast_ability_action( &self, by_entity_id: EntityId, ability_id: AbilityId, ) -> EntityAction
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn handle_equip_artifact(
&self,
template_id: ArtifactTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_equip_artifact( &self, template_id: ArtifactTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Wears one artifact. Exactly one is worn at a time, so this is also the unequip path: the previously worn artifact keeps paying its ownership bonus and loses only its World Law.
Putting on ART-03 Halfway Bell moves the flip bar under charge the
player may already hold, so the persistent gauge is re-denominated here
against the new bar. Without it, the next gain would find an accumulator
past its threshold and zero it — an equip would silently burn up to a
full gauge.
Sourcepub fn handle_insert_artifact_stone(
&self,
template_id: ArtifactStoneTemplateId,
socket: ArtifactSocketSlot,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_insert_artifact_stone( &self, template_id: ArtifactStoneTemplateId, socket: ArtifactSocketSlot, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Puts an artifact stone into one of the six sockets.
Two gates, both from config: the stone’s catalog entry names the only socket it fits, and the unlock schedule says whether that socket is open at the player’s chapter. The right-hand (Law) column is scheduled past the end of the campaign, so it is this same check — not a missing socket — that keeps it shut.
Sourcepub fn handle_set_artifact_stone_law_target(
&self,
template_id: ArtifactStoneTemplateId,
law_template_id: Option<LawTemplateId>,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_artifact_stone_law_target( &self, template_id: ArtifactStoneTemplateId, law_template_id: Option<LawTemplateId>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Points a right-column stone at the law it acts on, or clears the choice.
Three gates, and the third is the interesting one:
- the stone is in the catalog and sits in a Law socket — an Aspect stone has no law to choose;
- the law is in the catalog;
- the law is slotted on a core. A law off the core does nothing, so
pointing a stone at one would create a reference that has to be
cleaned up later; refusing here plus clearing on
UnslotLaw(the monolith’sunslot) is what makes “no dangling reference” true from both ends.
Deliberately NOT checked: that the law’s side matches the socket. The Law sockets are Visible / Hidden / Bridge, and visible-versus-hidden is a PHASE, not a side — the same law is the visible one while its side is up and the hidden one while it is down. Every slotted law is therefore a legal target for every Law socket, and the half of the fight a stone speaks in is decided by the flip (post-merge plan §8).
Sourcepub fn handle_remove_artifact_stone(
&self,
template_id: ArtifactStoneTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_remove_artifact_stone( &self, template_id: ArtifactStoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Takes a stone out of its socket. The stone keeps its level, its copies and its chosen law, so re-socketing restores exactly what it was.
Losing BL-01 Extra Span also gives back the bridge it paid for
(crate::mechanics::cores::prune_bridges_over_budget) — otherwise the
stone is a one-way ratchet. This is the artifact-side mirror of
UnslotLaw clearing the stone targets that pointed at the law it
unslotted: each side cleans up the other’s dangling half.
Sourcepub fn handle_upgrade_artifact_stone(
&self,
template_id: ArtifactStoneTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_upgrade_artifact_stone( &self, template_id: ArtifactStoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Raises one artifact stone by one level, paid for in raw copies.
The rule itself came whole with the first copy; a level only scales the magnitude (design §3), which is why nothing here consults the rule.
Sourcepub fn handle_upgrade_artifact(
&self,
template_id: ArtifactTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_upgrade_artifact( &self, template_id: ArtifactTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Raises one artifact by one level and spends the configured raw-copy rung.
Ownership and cap are checked before consulting the GameConfig ladder; the collection then atomically checks copies, spends them, and raises the level. Every refusal returns the unmodified state.
Sourcepub fn handle_player_new_artifacts(
&self,
artifacts: &[ArtifactTemplateId],
artifact_stones: &[ArtifactStoneTemplateId],
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_player_new_artifacts( &self, artifacts: &[ArtifactTemplateId], artifact_stones: &[ArtifactStoneTemplateId], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Banks granted artifacts and artifact stones.
An artifact duplicate banks one copy, including at the level cap. A stone duplicate likewise banks a copy. Neither grant path upgrades.
A template that is not in the catalog is skipped and logged rather than stored: a dangling id would sit in the collection forever with no name, no rule and no way to remove it.
Sourcepub fn roll_artifact_stone_drop(
&self,
rng: &mut StdRng,
chance: f64,
chapter_level: i64,
) -> Option<EventPluginized<OverlordEvent, OverlordState>>
pub fn roll_artifact_stone_drop( &self, rng: &mut StdRng, chance: f64, chapter_level: i64, ) -> Option<EventPluginized<OverlordEvent, OverlordState>>
BAL-031 faucet: one artifact stone from a campaign mob, a chapter boss or a cleared dungeon (the caller supplies the leg’s signed chance).
Deliberately a different faucet from the artifacts themselves (design §5), so the two collections never compete for one drop. The pick is uniform over the stones of the socket families the player’s chapter has already made usable — before the first socket (ch91) the pool is empty and nothing drops, after the last (ch191) it is all 29.
Sourcepub fn missing_socket_artifact_stones(
game_config: &GameConfig,
chapter: i64,
collection: &ArtifactCollection,
) -> Vec<Uuid>
pub fn missing_socket_artifact_stones( game_config: &GameConfig, chapter: i64, collection: &ArtifactCollection, ) -> Vec<Uuid>
BAL-031: the guaranteed compatible L1 stones the character’s chapter owes but the collection cannot serve. Each newly-usable socket family (ch91/111/131/151/171/191) guarantees ONE stone of its family; a family the player already owns any stone of needs nothing. Granting the result converges, so the check is safe on every chapter advance and on connect.
Sourcepub fn apply_artifact_aspects(
&mut self,
state: &mut OverlordState,
events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>,
event: &OverlordEvent,
)
pub fn apply_artifact_aspects( &mut self, state: &mut OverlordState, events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>, event: &OverlordEvent, )
The two Aspect rules that hang off the fight rather than off a trigger:
«Теневой круг» on the heartbeat and the Flip pair on GlobalFlip.
Runs from apply_success_hooks, like the stone triggers, for the same
reason: the events it reacts to are properties of the event, not of which
arm handled them.
A build with no artifact leaves through the first early return having touched no state at all.
Sourcepub fn handle_fire_artifact_effect(
&mut self,
owner_id: EntityId,
effect_template_id: Uuid,
effect_level: i64,
share_permyriad: i64,
artifact_stone_id: ArtifactStoneTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_fire_artifact_effect( &mut self, owner_id: EntityId, effect_template_id: Uuid, effect_level: i64, share_permyriad: i64, artifact_stone_id: ArtifactStoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Runs the deferred half of FA-05 Staggered Entrance.
The readings are taken now, not carried from the flip: the nearest enemy half a second later may be a different one, and a fight that ended in between leaves nothing to run against — in which case the event quietly does nothing.
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_enable_auto_chest( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_disable_auto_chest( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_enable_auto_chest_filter( &self, filter_id: AutoChestFilterId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_disable_auto_chest_filter( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_enable_auto_chest_power_compare( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_disable_auto_chest_power_compare( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_update_auto_chest_batch_size( &self, batch_size: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_new_auto_chest_filter( &self, filter: AutoChestFilter, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_update_auto_chest_filter( &self, updated_filter: AutoChestFilter, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_remove_auto_chest_filter( &self, filter_id: AutoChestFilterId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_add_bundle_group( &self, bundle_ids: &[BundleId], source: CurrencySource, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn handle_set_arena_world_side(
&self,
side: WorldSide,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_arena_world_side( &self, side: WorldSide, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Arena world switch (select-opponent screen): the side this player STARTS arena fights on — both as the attacker and as the snapshot opponent in other players’ fights. Only meaningful once the flip is unlocked; before that there is no switch to set.
pub fn is_battle_active(&self, state: &OverlordState) -> bool
pub fn handle_prepare_fight( &mut self, prepare_fight_type: PrepareFightType, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_start_fight( &mut self, event: OverlordEvent, fight_id: Uuid, rand_gen: StdRng, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn get_prepare_fight_delay( &self, is_win: bool, chapter: &Chapter, state: &OverlordState, ) -> u64
pub fn get_end_fight_delay(&self, fight_id: FightTemplateId) -> u64
pub fn handle_afk_rewards_gating_unlocked( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sourcepub fn handle_end_fight(
&mut self,
fight_id: Uuid,
is_win: bool,
pvp_state: Option<&PVPState>,
rand_gen: StdRng,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_end_fight( &mut self, fight_id: Uuid, is_win: bool, pvp_state: Option<&PVPState>, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
rand_gen is threaded in for the placeholder artifact-stone drop on a
cleared dungeon; nothing else in the end-of-fight pipeline rolls.
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_run_cheat( &mut self, cheat: &Cheat, current_tick: u64, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_spawn_entity( &mut self, id: EntityId, entity_template_id: EntityTemplateId, position: Coordinates, team: EntityTeam, has_big_hp_bar: bool, entity_attributes: EntityAttributes, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_start_move( &mut self, entity_id: Uuid, to: Coordinates, duration_ticks: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_move_progress( &self, entity_id: Uuid, to: Coordinates, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_end_move( &self, entity_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_stun( &mut self, entity_id: Uuid, duration_ticks: u64, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_cancel_cast_with_cooldown( &mut self, entity_id: Uuid, ability_id: Uuid, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_add_ability_cooldown( &mut self, entity_id: Uuid, ability_id: Uuid, delta_ticks: i64, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_incr_attribute( &mut self, entity_id: Uuid, attribute: &str, delta: i64, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_apply_effect( &mut self, entity_id: Uuid, effect_id: Uuid, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_cast_effect( &mut self, entity_id: Uuid, effect_id: Uuid, caller_event: Option<Box<OverlordEvent>>, rand_gen: StdRng, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_start_cast_ability( &mut self, _event: OverlordEvent, by_entity_id: Uuid, ability_id: AbilityId, rand_gen: StdRng, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sourcepub fn handle_derived_ability_strike(
&mut self,
by_entity_id: Uuid,
to_entity_id: Uuid,
ability_id: AbilityId,
level: i64,
payload_permille: i64,
source_paid_mana_x100: i64,
rand_gen: StdRng,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_derived_ability_strike( &mut self, by_entity_id: Uuid, to_entity_id: Uuid, ability_id: AbilityId, level: i64, payload_permille: i64, source_paid_mana_x100: i64, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
A derived copy of an ability’s payload (Repeat / Pulse). Re-resolves the ability’s numbers with the caster’s stones, scales them by the copy’s share and lands them.
It is NOT a cast: no on_cast, no mana, no cooldown, no pet charge and
no further shape expansion — a copy never copies itself, which is the
whole of the anti-recursion rule. What it IS, per BAL-019, is real
combat output: the hit is Core, so the laws, equipment triggers and pet
facets downstream of it react exactly as they would to the original,
and it carries the source cast’s final paid Mana price so a
Mana-conditioned reaction judges it by that cast. The damage itself is
tagged derived.
pub fn handle_cast_ability( &mut self, _event: OverlordEvent, by_entity_id: Uuid, to_entity_id: Uuid, ability_id: AbilityId, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_start_cast_projectile( &mut self, _event: OverlordEvent, by_entity_id: Uuid, to_entity_id: Uuid, projectile_id: Uuid, level: i64, source: CombatSource, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_cast_projectile( &mut self, _event: OverlordEvent, by_entity_id: Uuid, to_entity_id: Uuid, projectile_id: Uuid, level: i64, projectile_data: &CustomEventData, source: CombatSource, rand_gen: StdRng, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_player_death( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_entity_death( &mut self, entity_id: Uuid, reward: Vec<CurrencyUnit>, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_heal( &mut self, by_entity_id: Option<EntityId>, entity_id: Uuid, heal: u64, source: CombatSource, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_damage( &mut self, by_entity_id: Option<Uuid>, entity_id: Uuid, damage: u64, damage_data: &CustomEventData, source: CombatSource, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_fight_progress( &mut self, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_max_hp( &mut self, entity_id: EntityId, new_max_hp: u64, new_hp: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_send_gift( &self, receiver_id: Uuid, config_gift_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_new_gift( &self, new_gift: Gift, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_accept_gift( &self, gift_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn pre_event(&mut self, event: &OverlordEvent, current_tick: u64)
pub fn pre_event(&mut self, event: &OverlordEvent, current_tick: u64)
Per-event pre-amble: stamps the combat clock so relative schedule
calls made anywhere in the dispatch resolve against the current tick,
and records the currency source label for the next compute_fields
diff. Called by handle_event and by the monolith’s merged
(logic + persistence) arms, which bypass this dispatch.
Sourcepub fn dispatch_origin(&self) -> CombatEventOrigin
pub fn dispatch_origin(&self) -> CombatEventOrigin
Provenance of the dispatch in progress. Anything this dispatch queues on
an entity’s action queue must be stamped with it, because the queue
drains on a later tick, long after post_event disarmed the scope.
Two kinds of queue entry deliberately do not take this mark and stay
Core: an ability’s cooldown re-arm and a charge-driven pet ult. Both are
the entity’s own cadence — the same metronome ticks with or without a
modifier — so marking them would turn every later swing into a
modifier’s product and switch triggers off for the rest of the fight.
See essences::entity::EntityActionsQueue::push_start_cast_replacing.
Sourcepub fn post_event(
&mut self,
result: &mut EventHandleResult<OverlordEvent, OverlordState>,
)
pub fn post_event( &mut self, result: &mut EventHandleResult<OverlordEvent, OverlordState>, )
Closing half of the provenance pre-amble: disarms the clock and restamps everything this dispatch is handing back.
Must run at the end of every dispatch that called
OverlordLogic::pre_event — this one included, plus the monolith’s
merged (logic + persistence) arms, which replicate the wrapper without
going through handle_event.
The restamp only ever upgrades to a non-Core mark, so an event a
modifier already marked cannot be reset by a later Core dispatch. Events
that carry no provenance (SpawnEntity, FightProgress, the flip) are
left alone by set_origin — see
crate::event::OverlordEvent::carried_origin for why those are
boundaries rather than gaps, and
OverlordLogic::dispatch_origin for the delayed hop through the
entity action queue.
Sourcepub fn fight_breakdown(
&self,
is_win: bool,
duration_ticks: u64,
) -> Option<FightBreakdown>
pub fn fight_breakdown( &self, is_win: bool, duration_ticks: u64, ) -> Option<FightBreakdown>
The breakdown accumulated for the fight in progress, as a summary.
The live path does not need this — handle_end_fight drains the
accumulator into OverlordState::last_fight_breakdown. It exists for
crate::fight::FightEngine, which deliberately does NOT process
EndFight (progression side effects must not run inside a simulation)
and so would otherwise have no way to read what its fight produced.
Sourcepub fn arm_fight_seed(&mut self, seed: Seed)
pub fn arm_fight_seed(&mut self, seed: Seed)
Hand the next PrepareFight{PVPFight} the seed of the precalculation
whose outcome was persisted, so the live fight reproduces it.
Sourcepub fn event_rng(&self, driver_rng: StdRng) -> StdRng
pub fn event_rng(&self, driver_rng: StdRng) -> StdRng
RNG for the event pre_event was just called with: the fight’s own
stream for fight-scoped events of a seeded fight, otherwise the driver’s.
Must be called after pre_event and exactly once per dispatched event —
pre_event is what advances the fight’s draw counter.
Sourcepub fn is_fight_scoped(event: &OverlordEvent) -> bool
pub fn is_fight_scoped(event: &OverlordEvent) -> bool
Whether an event belongs to the fight’s own random stream.
The membership rule is an invariant, not a taste call: an event belongs here iff only fight machinery can produce it. Admitting an event that a non-fight cascade can also emit desyncs the counter — the live loop would bump on an interleaved tap that the precalculation never saw, and every roll after it diverges. Omitting an event the fight does emit desyncs it the other way.
EndFight is deliberately absent: FightEngine takes the outcome from
it without dispatching it (fight::FightEngine::try_finish), so bumping
on it would count in the live loop only.
Sourcepub fn effect_subscription_events(
&self,
event: &OverlordEvent,
state: &OverlordState,
) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
pub fn effect_subscription_events( &self, event: &OverlordEvent, state: &OverlordState, ) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
Effect events_subscribe scan: when a fight is active, effects applied
to entities can react to any event by casting. The returned events are
appended to the handling result’s events (after the success hooks).
Sourcepub fn apply_success_hooks(
&mut self,
state: &mut OverlordState,
events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>,
event: &OverlordEvent,
)
pub fn apply_success_hooks( &mut self, state: &mut OverlordState, events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>, event: &OverlordEvent, )
Cross-cutting success hooks: quest progress, offer triggers, Trigger Stone fires, law reactions and the artifact’s flip/heartbeat Aspect rules. Runs for every successfully handled event, both here and in the monolith’s merged arms.
Stone triggers hang off this hook rather than off the combat arms on
purpose: the surface they react to
(crate::event::OverlordEvent::is_core_combat_event) is a property of
the event, not of which arm handled it, and a merged arm added later for
one of those events would otherwise silently switch the mechanic off.
&mut self for the fight clock the timed effects schedule their expiry
on.
pub fn handle_event( &mut self, event: &OverlordEvent, state: OverlordState, rand_gen: StdRng, current_tick: u64, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sourcepub fn fight_clock_now(&self) -> u64
pub fn fight_clock_now(&self) -> u64
Where the fight clock currently stands. The loop that drives a fight
owns the clock; this is the read a caller needs to ask
Self::collect_due_scheduled for a point in the future.
pub fn collect_due_scheduled(&mut self, current_tick: u64) -> Vec<OverlordEvent>
pub fn compute_fields( &self, state: &mut OverlordState, prev_state: &OverlordState, ) -> Vec<OverlordEvent>
Source§impl OverlordLogic
impl OverlordLogic
pub fn new( game_config: SharedGameConfig, behaviors: Arc<BehaviorRegistry>, frontend: bool, ) -> Self
Sourcepub fn set_last_currency_source(&mut self, source: Option<CurrencySource>)
pub fn set_last_currency_source(&mut self, source: Option<CurrencySource>)
Sets the source label used by log_currency_change_metrics for the next
compute_fields diff. Use when state mutations happen outside the normal
CurrencyIncrease / CurrencyDecrease event flow (e.g., starter bundle
seeding on character creation).
Sourcepub fn set_game_config(&mut self, game_config: SharedGameConfig)
pub fn set_game_config(&mut self, game_config: SharedGameConfig)
Swaps the config this logic reads from. Locale-translated configs only differ in localized strings, so swapping mid-session is safe — used by the backend to switch a connection to the user’s localized GameConfig once their language is known after auth.
pub fn handle_set_custom_value( &self, key: String, value: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_new_character_level( &self, level: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_noop( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_fight_content_loading( &self, fight_id: Uuid, loading: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_tutorial_step_completed( &self, step_number: i16, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn compute_character_level( &self, state: &mut OverlordState, ) -> Vec<OverlordEvent>
pub fn get_quest_progress( &self, character_state: &CharacterState, active_fight: &Option<ActiveFight>, quest: &QuestInstance, progress_script_native: Option<&str>, trigger_event: &OverlordEvent, game_config: &GameConfig, ) -> Result<i64>
pub fn handle_currency_increase( &self, currencies: &[CurrencyUnit], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_currency_decrease( &self, currencies: &[CurrencyUnit], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sourcepub fn currency_increase(
currencies: &[CurrencyUnit],
currency_source: CurrencySource,
) -> EventPluginized<OverlordEvent, OverlordState>
pub fn currency_increase( currencies: &[CurrencyUnit], currency_source: CurrencySource, ) -> EventPluginized<OverlordEvent, OverlordState>
Creates a CurrencyIncrease event. The actual state mutation happens when the
event is processed by the handler — callers don’t need to mutate state manually.
Sourcepub fn currency_decrease(
state: &OverlordState,
currencies: &[CurrencyUnit],
currency_consumer: CurrencyConsumer,
) -> Option<EventPluginized<OverlordEvent, OverlordState>>
pub fn currency_decrease( state: &OverlordState, currencies: &[CurrencyUnit], currency_consumer: CurrencyConsumer, ) -> Option<EventPluginized<OverlordEvent, OverlordState>>
Creates a CurrencyDecrease event after validating sufficient balance.
Returns None if the player doesn’t have enough currency.
The actual state mutation happens when the event is processed by the handler.
pub fn handle_show_bird( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_bird_shown( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_rate_us_shown( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn handle_plinko_ball_dropped(
&self,
item_id: Uuid,
path: &[PlinkoDirection],
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_plinko_ball_dropped( &self, item_id: Uuid, path: &[PlinkoDirection], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Начисляет постоянные прибавки к статам за колышки, задетые шариком.
Колышки выводятся из пути детерминированно (pins_touched_by_path),
поэтому один и тот же путь всегда даёт один и тот же набор колышков.
Прибавки складываются в character_state.plinko_pin_bonuses, откуда
их подхватывает общий агрегатор атрибутов — тем же путём, что таланты
и статуя, так что бонус попадает и в бой, и в отображаемые статы, и в
Power.
pub fn handle_open_item_case( &self, batch_size: i64, rng: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_auto_chest_open_item_case( &self, batch_size: i64, rng: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_player_new_items( &self, items: &[Item], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_player_equip_item( &self, item_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_sell_item( &self, item_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_enable_auto_sell( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_disable_auto_sell( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_gear_override_enabled( &self, item_type: ItemType, enabled: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_enable_case_upgrade_pop_up( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_disable_case_upgrade_pop_up( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn apply_law_pre_cast(
&mut self,
state: &mut OverlordState,
caster_id: EntityId,
ability_id: AbilityId,
target_id: EntityId,
) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
pub fn apply_law_pre_cast( &mut self, state: &mut OverlordState, caster_id: EntityId, ability_id: AbilityId, target_id: EntityId, ) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
Laws whose condition is decided by the cast itself, evaluated BEFORE the cast resolves so an effect can change the very action that triggered it.
Returns the events the laws produced; the caller prepends them to the
cast’s own output. Attribute arms are written straight onto the entity
instead of going through an event, because mechanics::fight::attack
reads them off the caster snapshot the ability script is about to be
handed — an event would land one action too late.
A non-Core cast (a derived repeat, anything a modifier produced) returns immediately: that is the anti-loop boundary for the pre-cast conditions.
Sourcepub fn apply_law_reactions(
&mut self,
state: &mut OverlordState,
events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>,
event: &OverlordEvent,
)
pub fn apply_law_reactions( &mut self, state: &mut OverlordState, events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>, event: &OverlordEvent, )
Laws whose condition is an outcome. Runs from apply_success_hooks, so
the state it reads is the one the outcome actually produced.
Sourcepub fn apply_flip_to_laws(
&mut self,
state: &mut OverlordState,
entity_id: EntityId,
from_side: WorldSide,
to_side: WorldSide,
) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
pub fn apply_flip_to_laws( &mut self, state: &mut OverlordState, entity_id: EntityId, from_side: WorldSide, to_side: WorldSide, ) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
One completed flip, in the order plan §3 prescribes:
- the charge is delivered to the receiving law and starts amplifying it;
- the charge is zeroed;
- the “phase started” laws (
RL-12,FL-11) fire — already amplified.
Entity-local: any combatant that flips gets its own laws re-folded, so a PvP opponent’s inactive half stops contributing on their flip exactly as the hero’s does.
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_reset_offers( &self, new_offers: &[Offer], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn handle_global_flip(
&mut self,
entity_id: EntityId,
from_side: WorldSide,
to_side: WorldSide,
revision: u64,
rng: &mut StdRng,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_global_flip( &mut self, entity_id: EntityId, from_side: WorldSide, to_side: WorldSide, revision: u64, rng: &mut StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Dispatch arm for GlobalFlip, in BOTH paths.
Order is the acceptance criterion, not a preference: roll and resolve the Team Die of the incoming side, then hand the flip to the law layer, which delivers bridge charge and fires the phase-start laws.
Sourcepub fn roll_team_die_on_fight_start(
&mut self,
state: &mut OverlordState,
rng: &mut StdRng,
) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
pub fn roll_team_die_on_fight_start( &mut self, state: &mut OverlordState, rng: &mut StdRng, ) -> Vec<EventPluginized<OverlordEvent, OverlordState>>
The entry roll: stepping into the starting world of a fight is the same moment as arriving on a side through a flip, so it rolls the same die.
revision is None here — a fight start is not a flip and carries no
revision, and the per-flip latch it feeds exists to stop ONE flip rolling
twice, which a fight start cannot do (the fight has exactly one).
Sourcepub fn apply_pet_facets(
&mut self,
state: &mut OverlordState,
events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>,
event: &OverlordEvent,
)
pub fn apply_pet_facets( &mut self, state: &mut OverlordState, events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>, event: &OverlordEvent, )
Success hook: spends the facet state this Core event consumes.
The pet half of what [crate::logic::stones::spend_effect_state] does
for stones, kept in its own hook because a facet must work for a player
with nothing socketed — the stones hook leaves through an early return
for exactly that player.
Everything it emits is Proc. It leaves immediately while
mech::APPLYING is raised, which is the guard against a
facet-generated repeat repeating itself.
Sourcepub fn handle_set_pet_facet_law(
&self,
role: PetFacetLawRole,
law_template_id: Option<LawTemplateId>,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_set_pet_facet_law( &self, role: PetFacetLawRole, law_template_id: Option<LawTemplateId>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sets (or clears) one of the three out-of-combat Law selections.
Refuses a law the character does not own — the selection is a pointer into the player’s own collection, and a dangling one would make the fallback unreachable without ever telling anyone.
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_equip_pet( &self, slot_id: u64, pet_id: PetId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_unequip_pet( &self, slot_id: PetSlotId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_equip_pets( &self, equipped_pets: EquippedPets, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_claim_quest( &mut self, quest_id: Uuid, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_new_quests( &self, quest_ids: Vec<Uuid>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_update_active_loop_task_id( &self, quest_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_patron_quest_completed( &self, quest_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_claim_quest_progression_reward( &self, quest_group_type: QuestGroupType, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_reset_repeating_quests( &self, quest_ids: Vec<Uuid>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_set_rating_reward_availability( &self, availability: RatingRewardAvailability, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_claim_referral_lvlup_reward( &self, level: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_claim_referral_daily_reward( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_referral_daily_reward_status_update( &self, referral_daily_reward_status: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Source§impl OverlordLogic
impl OverlordLogic
pub fn handle_insert_stone( &self, template_id: StoneTemplateId, item_type: ItemType, socket: StoneSocketSlot, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_remove_stone( &self, template_id: StoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Sourcepub fn handle_upgrade_stone(
&self,
template_id: StoneTemplateId,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_upgrade_stone( &self, template_id: StoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Raises one stone by one level, paid for in raw copies.
The client names the stone only; the cost and the spend are the
server’s, so a UI cannot spend more than the rung asks. The cost comes
from the per-level ladder in stones_settings.upgrade_ladder, never a
constant. A level with no rung is refused rather than guessed —
GameConfig::validate_stones makes that unreachable in a deployed
config.
Sourcepub fn missing_milestone_stones(
game_config: &GameConfig,
chapter: i64,
stones: &StoneInventory,
) -> (Vec<StoneTemplateId>, Vec<StoneTemplateId>)
pub fn missing_milestone_stones( game_config: &GameConfig, chapter: i64, stones: &StoneInventory, ) -> (Vec<StoneTemplateId>, Vec<StoneTemplateId>)
BAL-024/BAL-025: the guaranteed milestone stones the character should own at their chapter but does not. Granting the result converges — an owned template is never listed — so the check is safe to run on every chapter advance and on connect.
Sourcepub fn handle_player_new_stones(
&self,
trigger_stones: &[StoneTemplateId],
effect_stones: &[StoneTemplateId],
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_player_new_stones( &self, trigger_stones: &[StoneTemplateId], effect_stones: &[StoneTemplateId], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Banks granted copies in their collections. Kept separate from the grant roll so the sole writer of the inventory is one function.
A copy of a template the player already owns raises that stone’s
copies count; only the first copy of a template creates an instance.
The tier comes from the catalog, so a template missing from config is
skipped and logged rather than banked with a guessed tier.
Sourcepub fn roll_stone_drop(
&self,
rng: &mut StdRng,
rolls: i64,
chance_scale: f64,
) -> Option<EventPluginized<OverlordEvent, OverlordState>>
pub fn roll_stone_drop( &self, rng: &mut StdRng, rolls: i64, chance_scale: f64, ) -> Option<EventPluginized<OverlordEvent, OverlordState>>
The stone faucet: rolls independent draws at
stones_settings.kill_drop.chance × chance_scale, split between the two
collections by kill_drop.trigger_share.
It hangs off ENEMY KILLS (Self::roll_stone_kill_drop). It used to
hang off the item-chest open, which tied the whole faucet to a purchased
channel: a whale opening ~26k chests a day drew two orders of magnitude
more stones than a player who fought for them.
A copy of a template the player already owns is banked as a copy by the handler, not as a second instance. Draws from the caller’s stream (like every other handler) rather than the global RNG, so a test can seed the drop.
Sourcepub fn roll_stone_kill_drop(
&self,
rng: &mut StdRng,
wave_share: f64,
) -> Option<EventPluginized<OverlordEvent, OverlordState>>
pub fn roll_stone_kill_drop( &self, rng: &mut StdRng, wave_share: f64, ) -> Option<EventPluginized<OverlordEvent, OverlordState>>
One stone roll for one dead enemy, scaled by that mob’s wave_share.
The wave_share scaling is the same rule the cores currency and the law
copies already follow on this path: an inflated wave is more mobs of less
weight each, and without the scaling it would inflate every per-kill
faucet with it.
Sourcepub fn handle_quick_equip_stones(
&self,
item_type: ItemType,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_quick_equip_stones( &self, item_type: ItemType, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Fills the open, empty sockets of one item with the BEST usable stones the player is not already wearing.
Modelled on FastEquipAbilities but kept pure: a stone inventory lives
in character_state, not a side table, so the whole decision is a state
transition and the same code runs in both dispatch paths.
“Best” is Stone::quality — tier first, then level — with the canonical
catalog order breaking ties. Locked sockets are skipped, occupied sockets
are left alone, stones worn on other gear are never taken, and a socket
with nothing to put in it stays empty without an error.
Sourcepub fn handle_upgrade_all_stones(
&self,
kind: StoneKind,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_upgrade_all_stones( &self, kind: StoneKind, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Raises every stone of one catalog that the player can currently afford to raise, as far as its banked copies reach (design v0.2 §9).
Modelled on UpgradeAllAbilities and named for it — the codebase says
UpgradeAll*, and §9 sanctions matching it. Like
Self::handle_upgrade_stone the cost is the server’s business: the
client asks for “everything of this kind”, the ladder decides what that
costs, and a stone that cannot pay for its next level is skipped rather
than failing the whole call.
kind comes from which of the two catalogs the caller asked for — the
screen has a Trigger tab and an Effect tab and its button raises the open
one, so the two arrive as separate events.
Sourcepub fn apply_stone_triggers(
&mut self,
state: &mut OverlordState,
events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>,
event: &OverlordEvent,
)
pub fn apply_stone_triggers( &mut self, state: &mut OverlordState, events: &mut Vec<EventPluginized<OverlordEvent, OverlordState>>, event: &OverlordEvent, )
Fire every socketed trigger whose condition event satisfies: run the
globally active side’s effect, feed the flip gauge by the trigger’s tier,
then put the whole build on one cooldown.
Runs from apply_success_hooks, after the event’s own handler has
mutated the state, so a trigger reacts to the world the hit produced.
The order inside is load-bearing:
- classify the event — anything non-Core leaves here;
- fold it into the trigger memory, whether or not anything will fire;
- spend whatever effect state this event consumes — independent of the cooldown;
- collect the triggers whose condition matched;
- if the cooldown is still running, drop them and restart the sequence counters;
- otherwise write the global cooldown, then run the effects.
Step 6’s order makes the hook re-entrancy-safe: an effect can dispatch work that comes back through here, and it finds the build already spent.
A build with nothing socketed leaves through the first early return having touched no state at all.
Source§impl OverlordLogic
impl OverlordLogic
Sourcepub fn handle_claim_talent_research(
&self,
state: OverlordState,
) -> EventHandleResult<OverlordEvent, OverlordState>
pub fn handle_claim_talent_research( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>
Apply completed talent: increment level and clear upgrade timer fields.