Struct OverlordLogic

Source
pub struct OverlordLogic { /* private fields */ }

Implementations§

Source§

impl OverlordLogic

Source

pub fn handle_equip_ability( &self, slot_id: u64, ability_id: AbilityId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_unequip_ability( &self, slot_id: AbilitySlotId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_equip_abilities( &self, equipped_abilities: EquippedAbilities, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn make_cast_effect_action( &self, entity_id: EntityId, effect_id: EffectId, ) -> EntityAction

Source

pub fn make_start_cast_ability_action( &self, by_entity_id: EntityId, ability_id: AbilityId, ) -> EntityAction

Source§

impl OverlordLogic

Source

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.

Source

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.

Source

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’s unslot) 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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Source§

impl OverlordLogic

Source§

impl OverlordLogic

Source

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.

Source

pub fn is_battle_active(&self, state: &OverlordState) -> bool

Source

pub fn handle_prepare_fight( &mut self, prepare_fight_type: PrepareFightType, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_start_fight( &mut self, event: OverlordEvent, fight_id: Uuid, rand_gen: StdRng, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn get_prepare_fight_delay( &self, is_win: bool, chapter: &Chapter, state: &OverlordState, ) -> u64

Source

pub fn get_end_fight_delay(&self, fight_id: FightTemplateId) -> u64

Source

pub fn handle_afk_rewards_gating_unlocked( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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

Source

pub fn handle_run_cheat( &mut self, cheat: &Cheat, current_tick: u64, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source§

impl OverlordLogic

Source

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>

Source

pub fn handle_start_move( &mut self, entity_id: Uuid, to: Coordinates, duration_ticks: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_move_progress( &self, entity_id: Uuid, to: Coordinates, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_end_move( &self, entity_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_entity_stun( &mut self, entity_id: Uuid, duration_ticks: u64, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_entity_cancel_cast_with_cooldown( &mut self, entity_id: Uuid, ability_id: Uuid, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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>

Source

pub fn handle_entity_incr_attribute( &mut self, entity_id: Uuid, attribute: &str, delta: i64, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_entity_apply_effect( &mut self, entity_id: Uuid, effect_id: Uuid, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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>

Source

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>

Source

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.

Source

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>

Source

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>

Source

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>

Source

pub fn handle_player_death( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_entity_death( &mut self, entity_id: Uuid, reward: Vec<CurrencyUnit>, rand_gen: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_heal( &mut self, by_entity_id: Option<EntityId>, entity_id: Uuid, heal: u64, source: CombatSource, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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>

Source

pub fn handle_fight_progress( &mut self, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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

Source§

impl OverlordLogic

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn handle_event( &mut self, event: &OverlordEvent, state: OverlordState, rand_gen: StdRng, current_tick: u64, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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.

Source

pub fn collect_due_scheduled(&mut self, current_tick: u64) -> Vec<OverlordEvent>

Source

pub fn compute_fields( &self, state: &mut OverlordState, prev_state: &OverlordState, ) -> Vec<OverlordEvent>

Source§

impl OverlordLogic

Source

pub fn new( game_config: SharedGameConfig, behaviors: Arc<BehaviorRegistry>, frontend: bool, ) -> Self

Source

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).

Source

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.

Source

pub fn handle_set_custom_value( &self, key: String, value: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_new_character_level( &self, level: i64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_noop( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_set_fight_content_loading( &self, fight_id: Uuid, loading: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_tutorial_step_completed( &self, step_number: i16, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source§

impl OverlordLogic

Source

pub fn compute_character_level( &self, state: &mut OverlordState, ) -> Vec<OverlordEvent>

Source

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>

Source

pub fn handle_currency_increase( &self, currencies: &[CurrencyUnit], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_currency_decrease( &self, currencies: &[CurrencyUnit], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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.

Source

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.

Source

pub fn handle_show_bird( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_bird_shown( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_rate_us_shown( &mut self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source§

impl OverlordLogic

Source

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.

Source

pub fn handle_open_item_case( &self, batch_size: i64, rng: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_auto_chest_open_item_case( &self, batch_size: i64, rng: StdRng, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_player_new_items( &self, items: &[Item], state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_player_equip_item( &self, item_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_sell_item( &self, item_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_enable_auto_sell( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_disable_auto_sell( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_set_gear_override_enabled( &self, item_type: ItemType, enabled: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_enable_case_upgrade_pop_up( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_disable_case_upgrade_pop_up( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source§

impl OverlordLogic

Source

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.

Source

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.

Source

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:

  1. the charge is delivered to the receiving law and starts amplifying it;
  2. the charge is zeroed;
  3. 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

Source§

impl OverlordLogic

Source

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.

Source

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).

Source

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.

Source

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

Source

pub fn handle_equip_pet( &self, slot_id: u64, pet_id: PetId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_unequip_pet( &self, slot_id: PetSlotId, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_equip_pets( &self, equipped_pets: EquippedPets, current_tick: u64, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source§

impl OverlordLogic

Source§

impl OverlordLogic

Source§

impl OverlordLogic

Source§

impl OverlordLogic

Source

pub fn handle_insert_stone( &self, template_id: StoneTemplateId, item_type: ItemType, socket: StoneSocketSlot, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_remove_stone( &self, template_id: StoneTemplateId, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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:

  1. classify the event — anything non-Core leaves here;
  2. fold it into the trigger memory, whether or not anything will fire;
  3. spend whatever effect state this event consumes — independent of the cooldown;
  4. collect the triggers whose condition matched;
  5. if the cooldown is still running, drop them and restart the sequence counters;
  6. 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

Source

pub fn handle_claim_talent_research( &self, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Apply completed talent: increment level and clear upgrade timer fields.

Source§

impl OverlordLogic

Source

pub fn handle_new_task( &self, new_task: VassalTask, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_give_resist_task( &self, new_task: VassalTask, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_accept_task( &self, task_id: Uuid, is_good: bool, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_task_accepted( &self, task_id: Uuid, started_good: bool, started_at: DateTime<Utc>, finish_at: DateTime<Utc>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_resist_task_accepted( &self, resist_task: VassalTask, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_hit_hands( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_catch_resist_task( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_hands_hitted( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_resist_task_catched( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_finish_task( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_resist_task_finished( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_claim_task_reward( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_claim_resist_task_reward( &self, task_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_new_suzerain( &self, new_suzerain: Option<Suzerain>, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Source

pub fn handle_remove_vassal( &self, vassal_id: Uuid, state: OverlordState, ) -> EventHandleResult<OverlordEvent, OverlordState>

Trait Implementations§

Source§

impl Debug for OverlordLogic

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more