The ArmorGear data interface.
Binds this logic to its parent data model and builds the actions map from the parent's intrinsic and scripted action definitions, selecting a default action.
Reserved base data (unused by the base class).
Must provide options.parent, the data model this logic
is embedded in; the parent's actionDefs are used to build
actions.
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).
OptionalcontainedThe 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.
Per-aspect damage reduction as ValueModifiers, seeded from ArmorGearData.protectionBase.
Protection against blunt impact.
Protection against edged impact.
Protection against fire/heat impact.
Protection against piercing impact.
Craftsmanship quality as a ValueModifier, seeded from GearData.qualityBase.
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).
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.
Static ReadonlyCARRIED_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).
Static ReadonlyCARRIED_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.Static ReadonlyCARRIED_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 gateOnCarried — trigger 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.
The owning SohlActor — the document itself when it is an actor,
otherwise its owning actor (for an item, combatant, or effect), or null.
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.
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.
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.
Convenience accessor for parent.
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.
The impairment of each holding part, in heldBy order.
The owning document's id.
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).
true when the item is carried.
The owning SohlItem.
The owning document's kind (its actor or item type id).
Localized display label combining the typeLabel and the document's name.
The owning document's name.
A SohlSpeaker for the owning actor/item (a blank speaker if neither resolves).
Localized type (and sub-type, when present) label for the owning document.
The owning document's UUID — the opaque identity token from the data port.
Build an update() payload that adds a cohort reference to the sharing list.
The cohort reference (shortcode, id, or UUID) to add.
An update payload adding the reference, or an empty object if already present.
Delete the owning document, after confirming with the user.
The action context; unused.
Open the sheet for the owning document.
The action context; unused.
Compute derived values that depend on sibling items being initialized.
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.
Execute an action by shortcode, using the provided context or creating a new one.
The shortcode of the action to execute.
Optionalcontext: sohl.entity.action.SohlActionContextThe action context to use, if any.
The result of the action execution, or undefined if the action was not found or could not be executed.
Resolve cross-item dependencies that require all items to have been evaluated.
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.
The available context-menu entries.
Set up base state from persisted data: create ValueModifiers, set base values.
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.
Post this item's description to the chat log — a human-triggered, informational card (no follow-up buttons) built by buildItemDescCardData. Assist, never act: this only shows the item's own text; it takes no action on any character.
The action context; unused.
Intrinsic action performed after finalize lifecycle stage. This is intended for modules to hook into (or ActionItems to override) to perform additional logic after the main lifecycle stages have completed.
The action context for the post-finalize hook.
Build an update() payload that removes a cohort reference from the sharing list.
The cohort reference (shortcode, id, or UUID) to remove.
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.
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.
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.
The action context (unused).
Resolves once the item update completes.
Toggles whether this armor is currently worn.
Intrinsic-action executor for the toggleWorn action. Only worn armor
contributes to a being's armor-protection totals.
The action context (unused).
Resolves once the item update completes.
Serialize this logic to a plain reference.
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.
StaticdefineDefine and return all intrinsic actions for this logic type.
The gear intrinsic actions plus the armor worn toggle.
StaticgateGate a list of action definitions on the item being carried — the seam every gear logic runs its defineIntrinsicActions result through.
Each definition not named in CARRIED_GATE_EXEMPT has
CARRIED_TRIGGER conjoined onto its trigger, so the action is
unavailable while system.isCarried is false. An author's existing
trigger is preserved (parenthesized and &&-ed), never replaced.
Each gated definition also carries CARRIED_DISABLED_REASON as its
disabledReason (unless the author declared one), so a surface that
offers the action can explain the refusal (issue #1135).
The transform is idempotent — a subclass gates the list it already
received from its parent's defineIntrinsicActions(), so definitions pass
through it once per level of the hierarchy — and non-mutating: gated
definitions are returned as copies.
The action definitions to gate.
The definitions, with the carried gate applied to each non-exempt entry.
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.