Wearable protective equipment.

Armor Gear represents physical armor worn by a character: chainmail, leather jerkins, plate cuirasses, helmets, shields, and similar protective equipment. Each piece of armor covers specific body locations, categorized as flexible or rigid coverage.

Protection values (protectionBase) are stored directly on the armor.

Type Parameters

Hierarchy (View Summary)

Indexable

  • [key: symbol]: true

Constructors

Properties

actions: SohlMap<string, sohl.entity.action.SohlAction>

Executable actions for this document, keyed by shortcode — context-menu entries, chat-card buttons, and lifecycle hooks. A script action shadows (wholly overrides) the intrinsic action of the same shortcode (see the constructor).

containedIn?: GearLogic

The containing item's logic, resolved from GearData.containerId, or null when not in a container.

Structural integrity as a ValueModifier, seeded from GearData.durabilityBase.

Armor encumbrance penalty as a ValueModifier, seeded from ArmorGearData.encumbrance.

protection: {
    blunt: sohl.entity.modifier.ValueModifier;
    edged: sohl.entity.modifier.ValueModifier;
    fire: sohl.entity.modifier.ValueModifier;
    piercing: sohl.entity.modifier.ValueModifier;
}

Per-aspect damage reduction as ValueModifiers, seeded from ArmorGearData.protectionBase.

Type declaration

Craftsmanship quality as a ValueModifier, seeded from GearData.qualityBase.

sharedWithCohorts: SohlActor[]

The Cohort actors this gear item is shared with, resolved from GearData.sharedWithCohortIds.

Populated during initialize by resolving each entry as a cohort reference — a system.shortcode, a document id, or a UUID (see fvttActorByRef). Sharing is normally keyed by the cohort's shortcode, the stable key an author writes. References that do not resolve are dropped. This is the inverse of sohl.document.actor.logic.CohortLogic.sharedGear, which the Cohort sheet's Shared Gear tab renders (issue #76).

traits: StrictObject<string>

Active-effect-driven armor traits, keyed by trait code.

Monetary value as a ValueModifier, seeded from GearData.valueBase.

Physical weight as a ValueModifier, seeded from GearData.weightBase.

CARRIED_DISABLED_REASON: "SOHL.Gear.actionRequiresCarried"

i18n key stamped onto each carried-gated action as its sohl.entity.action.SohlAction.Data.disabledReason, so a UI offering the action can say why it is refused instead of presenting a control that silently does nothing (issue #1135).

CARRIED_GATE_EXEMPT: readonly string[] = ...

Action shortcodes exempt from the carried gate:

  • toggleCarried — the way back. Gating it would strand an item you set down, with no action left to pick it up again.
  • editDocument / deleteDocument / outputDescription — the universal document actions every item carries. They manage or describe the item rather than doing anything with the gear, and you must always be able to edit, delete, or read out an item you are not carrying.
CARRIED_TRIGGER: "defined(itemLogic) && itemLogic.isCarried"

The sohl.entity.expr.SafeExpression source that gates a gear action on the item being carried (issue #1097). Composed into each gated action's trigger by gateOnCarriedtrigger rather than visible because an uncarried item's actions must be genuinely unavailable (refused by sohl.entity.action.SohlAction.execute, however invoked), not merely hidden from the context menu. Visibility composes with the trigger, so gated actions disappear from the menu too.

Accessors

  • get actor(): null | SohlActor
  • The owning SohlActor — the document itself when it is an actor, otherwise its owning actor (for an item, combatant, or effect), or null.

    Returns null | SohlActor

  • get actorLogic(): null | SohlActorLogic<any>
  • The logic of the owning actor — the Foundry-free way to reach the actor layer from any logic. For an actor's own logic this is itself; for an item's logic it is the owning actor's logic; otherwise null.

    Returns null | SohlActorLogic<any>

    Resolved through the SohlLogicData port, so logic code can navigate to the actor (and iterate items via allLogics / logicTypes / getItemLogic) without touching the Foundry document.

  • get data(): TData
  • This logic's typed data — its *Data interface (e.g. SkillData), the same persisted object as document.system. Prefer document.logic.data when reading a document's fields from a macro, Script Action, or module: it is the typed, API-documented surface (autocomplete and reference links resolve), whereas document.system is typed as the internal DataModel.

    Returns TData

    Convenience accessor for parent.

  • get heldLimbImpairments(): BodyPartImpairment[]
  • The derived impairment of the body part(s) currently holding this item — the per-part input to a held-weapon strike mode's impairment gating (#628). A weapon strike mode names its required limbs by count (minParts), not by role, so this resolves the specific holding limbs (via heldBy) and scores each through the being's body-part impairment. When any holding limb is unusable, a strike-mode test auto-Critically-Fails; an impaired-but-usable limb penalizes the mode's attack/defense mastery level by −5/−10 (applied at sohl.entity.modifier.MasteryLevelModifier.successTest).

    Empty when nothing holds the item (an unheld or natural weapon) or the actor has no body from which to derive per-part impairment.

    Returns BodyPartImpairment[]

    The impairment of each holding part, in heldBy order.

  • get isCarried(): boolean
  • Whether this item is on the character's person.

    Gear that is not carried has been set down — left on the ground, in a cart, or wherever the character parted with it. It still appears on the sheet, but it contributes nothing (no encumbrance, no protection) and cannot be acted with: every gear action except toggleCarried is gated on this flag (see gateOnCarried).

    Returns boolean

    true when the item is carried.

  • get item(): SohlItem
  • The owning SohlItem.

    Returns SohlItem

    If this logic is not embedded in an item.

  • get kind(): string
  • The owning document's kind (its actor or item type id).

    Returns string

  • get typeLabel(): string
  • Localized type (and sub-type, when present) label for the owning document.

    Returns string

  • get uuid(): string
  • The owning document's UUID — the opaque identity token from the data port.

    Returns string

Methods

  • Build an update() payload that adds a location to flexible coverage.

    Parameters

    • location: string

      Shortcode of the body location to add.

    Returns PlainObject

    An update payload adding the location, or an empty object if already present.

  • Build an update() payload that adds a location to rigid coverage.

    Parameters

    • location: string

      Shortcode of the body location to add.

    Returns PlainObject

    An update payload adding the location, or an empty object if already present.

  • Build an update() payload that adds a cohort reference to the sharing list.

    Parameters

    • cohortId: string

      The cohort reference (shortcode, id, or UUID) to add.

    Returns PlainObject

    An update payload adding the reference, or an empty object if already present.

  • Compute derived values that depend on sibling items being initialized.

    Returns void

    Called on every item after ALL items have completed initialize.

    Safe to access: sibling items' initialized state (e.g., reading trait attribute values for a skill base formula).

    Not safe to access: sibling items' evaluated state — another item's evaluate() may not have run yet. Dependencies on evaluated state belong in finalize.

    Example: a Skill reads trait attribute values to compute its skill base; a gear item resolves its containerId to find its parent container.

  • Resolve cross-item dependencies that require all items to have been evaluated.

    Returns void

    Called on every item after ALL items have completed evaluate.

    Safe to access: all sibling items' initialized and evaluated state.

    Example: fate mastery level (which depends on an already-evaluated Aura trait); encumbrance totals summed across all evaluated gear.

  • The context-menu options — the actions currently available — for this logic's document.

    Returns ContextMenuEntry[]

    The available context-menu entries.

    One entry per action whose visible predicate currently passes (an action's trigger / domain preconditions can hide it); SCRIPT actions are additionally permission-gated when executed. Use this to discover which actions can be performed on the document.

  • Set up base state from persisted data: create ValueModifiers, set base values.

    Returns void

    Called on every item before any item's evaluate runs.

    Safe to access: own persisted data fields (this.data.*).

    Not safe to access: sibling items on the same actor — they may not have initialized yet. Cross-item reads belong in evaluate.

    Example: a Skill creates its MasteryLevelModifier from persisted fields; it does not yet read trait attribute values.

  • Build an update() payload that removes a location from flexible coverage.

    Parameters

    • location: string

      Shortcode of the body location to remove.

    Returns PlainObject

    An update payload with the location filtered out of flexible coverage.

  • Build an update() payload that removes a location from rigid coverage.

    Parameters

    • location: string

      Shortcode of the body location to remove.

    Returns PlainObject

    An update payload with the location filtered out of rigid coverage.

  • Build an update() payload that removes a cohort reference from the sharing list.

    Parameters

    • cohortId: string

      The cohort reference (shortcode, id, or UUID) to remove.

    Returns PlainObject

    An update payload with the reference filtered out of the sharing list.

  • GM result-edit for a posted test card (#856) — the higher-fidelity counterpart to Fate. Re-opens the standard test dialog pre-filled with the result's current situational and success-level modifiers; on submit it applies the new modifiers and re-evaluates on the SAME frozen roll (never a re-roll, no Fate cost), then reposts the card. The prior result rides in context.scope.priorTestResult (the reconstruction seam), so this works for any standard test card — skill, attribute, or combat strike mode.

    Changing the situational modifier changes the effective target, so the base success level re-derives from the frozen roll; the success-level modifier is a flat offset applied after. Clicking OK without a change is a no-op (nothing re-evaluated, nothing reposted).

    GM-only. The pencil is render-hidden from non-GMs (sohl.document.chat.gateEditActionPencil); this is the click-time half of that gate — a synthesized click from a non-GM is refused here.

    Parameters

    • context: sohl.entity.action.SohlActionContext<
          {
              priorTestResult?: sohl.entity.result.SuccessTestResult;
              rollMode?: string;
              situationalModifier?: number;
              successLevelMod?: number;
          },
      >

      The action context; context.scope.priorTestResult is the result being edited. When skipDialog is set, the new situationalModifier / successLevelMod / rollMode are taken from context.scope instead of the dialog.

    Returns Promise<undefined | sohl.entity.result.SuccessTestResult>

    The re-evaluated result, or undefined when refused (non-GM), cancelled (dialog dismissed), or unchanged (no-op).

  • Toggles whether this gear is carried on the character's person.

    Setting the item down also applies stowUpdates(), clearing any derived "in use" state (e.g. worn armor) in the same update — otherwise that state would be stuck, since the action that clears it is itself gated on the item being carried.

    Intrinsic-action executor for the toggleCarried action.

    Parameters

    Returns Promise<void>

    Resolves once the item update completes.

  • Serialize this logic to a plain reference.

    Returns PlainObject

    A uuid-keyed reference to this logic.

    A logic is a behavior wrapper over a live Foundry document; it is never revived from its own JSON (its constructor needs that document). Wherever a logic is persisted — a chat card, an action sohl.entity.action.SohlActionContext.scope — it is re-resolved from its uuid (e.g. via fvttLogicFromUuidSync), not rebuilt from a payload. So it serializes as a compact, resolvable reference (name/kind are carried for display and debugging); the owning document holds the actual persisted state.