Table of Contents

Class ShieldInterceptAction

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Sweeps a shield volume for ability objects in flight and destroys what it catches — the outward-looking half of a block.

[Serializable]
public class ShieldInterceptAction : BaseAction, IAction
Inheritance
ShieldInterceptAction
Implements
Inherited Members

Remarks

Why this exists alongside the gate. DamageMitigation.TryBlockAtVolume already guarantees the OUTCOME: a projectile whose impact lands inside a raised shield is stopped and deals nothing, decided by the incoming object's own swept query, which is tunnel-proof and runs inside the caster's rewind. What it cannot do is stop something that was never going to hit you. A tower shield held out to the side should sweep an arrow out of the air whether or not that arrow was aimed at your body, and a fireball should die on the shield face rather than reaching your chest and expiring there. That is what this adds.

It cannot change whether damage lands, and that is deliberate. Both halves read the same authored ShieldVolume, so anything this catches would have been gated anyway if it had gone on to strike. Its ordering is therefore free to be imperfect — see below — because the worst it can do is stop a projectile a tick later than it might have, or stop one that was going to miss.

Tick order, stated rather than relied upon. Every AbilityObject subscribes to TimeManager.OnTick when it spawns, so an object already in flight ticks BEFORE a shield object spawned this tick — it moves and resolves its own sweep first. A fast projectile can therefore reach the body on the same tick this would have caught it. The gate is what makes that harmless; this is an accelerator, not the mechanism.

Wire it to the channel's OnTick. A channelled block re-spawns its object every tick, so an OnSpawn event fires this once per tick for the life of the channel — which is the same cadence and the simpler authoring. Put it on OnTick instead for a shield that is one long-lived object rather than a stream of short ones.

Fields

InterceptLayers

Layers the sweep looks on. Should be the layer ability objects live on.

[Tooltip("Layers to sweep for incoming ability objects.")]
public LayerMask InterceptLayers

Field Value

LayerMask

MaxIntercepts

Maximum objects to stop in one tick. Zero or less means no cap.

[Tooltip("Objects the shield may stop in one tick. 0 or less means no cap.")]
[Min(0)]
public int MaxIntercepts

Field Value

int

Remarks

Matches CappedCount(int, int) and every other capped path in the project. A cap here is a balance knob — how many arrows one shield can eat in a tick — rather than a performance one; the query is bounded by the shield's own size.

Volume

The shield's dimensions, in the blocking character's own space.

[Tooltip("Shield dimensions in the blocker's own space. Leave Shape as None to sweep whatever volumes the character's active block buffs already define.")]
public ShieldVolume Volume

Field Value

ShieldVolume

Remarks

Authored here as well as on the buff, on purpose. This action is what a designer reaches for when the shield's REACH is a property of the ability rather than of the buff it applies — a shield bash that sweeps forward, a parry that only covers the weapon arm. Leave Shape at None and this action instead sweeps every volume the character's active block buffs have raised, so the common case authors the dimensions exactly once, on the buff.

Methods

Execute(ICharacter, EventData)

Sweeps the shield and destroys the ability objects inside it.

public override void Execute(ICharacter initiator, EventData eventData)

Parameters

initiator ICharacter

The blocking character.

eventData EventData

The event the block ability dispatched this from.