Shattered Codex

Wiki

Modules/SC - Conditional Activities

SC - Conditional Activities

Foundry v13-v14System D&D 5eFree

SC - Conditional Activities

Overview

SC - Conditional Activities adds a Condition tab to D&D 5e activity sheets in Foundry VTT.

Use it when an activity should only be available if a JavaScript condition passes. If the condition returns true, the activity works normally. If it returns false, the activity is blocked before use and can show a locked-state badge or warning.

Core behavior:

  • adds a Condition tab to supported activity sheets
  • evaluates JavaScript before activity.use()
  • shows locked-state badges and warnings for unavailable activities
  • supports native dnd5e activities and activity types added by More Activities

Typical checks:

  • actor HP, resources, attributes, or flags
  • item equipped, attuned, or identified state
  • selected targets
  • combat state
  • activity type checks
  • socket checks on items that also use SC - Simple Sockets

Installation

  1. In Foundry VTT, open Add-on Modules and install the module with this manifest:
code
https://github.com/Shattered-Codex/sc-conditional-activities/releases/latest/download/module.json
  1. Enable SC - Conditional Activities in your world.
  2. Open an item with one or more dnd5e activities.
  3. Edit an activity and open the Condition tab.
  4. Save a condition script on that activity.

Compatibility:

  • Foundry VTT v13 to v14
  • system: dnd5e
  • minimum dnd5e version: 5.0.0
  • compatible with activity types added by More Activities

Module Settings

From Configure Settings > Module Settings > SC - Conditional Activities, you can access:

  • Hide unavailable activities in the choice dialog
  • Open wiki
  • Patreon support

The availability-hiding setting is world-scoped and GM-facing. When enabled, activities that fail their condition are removed from the activity choice dialog instead of staying visible there with a locked label.

Activity Condition

Every supported activity sheet gets a dedicated Condition tab.

The Condition tab includes a JavaScript editor, custom warning and badge controls, a preview area, and a direct link back to the wiki.

The module stores its activity data on these flag paths:

code
flags.sc-conditional-activities.condition
flags.sc-conditional-activities.warningMessage
flags.sc-conditional-activities.disableWarningMessage
flags.sc-conditional-activities.badgeLabel

Condition Tab Controls

The tab does more than store a script. It also controls how the locked state is presented to users.

ControlWhat it doesNotes
Condition editorStores the JavaScript that decides whether the activity is currently available.Accepts a single expression or a full script.
Warning messageSets the warning notification shown when the condition returns false.Leave blank to use the module default.
Disable warning messageBlocks the activity without showing the normal condition-failed warning.Condition errors still warn so invalid scripts remain visible.
Locked badge labelOverrides the visible label shown on blocked activities.Single line, maximum 36 characters.
PreviewShows the current badge and warning output before saving.Useful when you customize player-facing wording.
Open wikiOpens this documentation from inside the activity sheet.Anchors directly to the Activity Condition section.

Where Locked Activities Appear

By default, blocked activities remain visible so users can understand what exists and why it is unavailable.

Activity choice
When the hide setting is off, blocked activities remain visible in the choice dialog with a locked-state label.
1 / 2

The module decorates activity state in:

  • dnd5e activity choice dialogs
  • item sheet activity lists
  • actor sheet activity lists
  • Tidy actor-sheet activity surfaces
  • chat activity controls

If Hide unavailable activities in the choice dialog is enabled, the choice dialog is the exception: blocked activities are filtered out there instead of being shown with a badge.

Writing Conditions

Conditions receive these context variables:

VariableWhat it gives you
`activity`The current activity document.
`activityType`The activity type, such as `attack` or another registered activity type.
`item`The item that owns the activity.
`actor`The actor that owns the item, when available.
`user`The current Foundry user.
`usage`Cloned usage data passed into `activity.use()`.
`dialog`Cloned dialog data passed into `activity.use()`.
`message`Cloned message data passed into `activity.use()`.
`rollData`The owning item's roll data, when available.
`source`The evaluation source, such as UI checks or activity use.
`getProperty`Foundry's property helper.
`hasProperty`Foundry's property existence helper.
`deepClone`Foundry's deep clone helper.
`game`The Foundry `game` object.
`moduleId`The module id: `sc-conditional-activities`.

There is no dedicated target variable. When you need targets, read them from user.targets.

You can write a complete script:

js
return actor?.system?.attributes?.hp?.value > 0;

You can also write a single expression:

js
actor?.system?.attributes?.hp?.value > 0

Expression shorthand only works when the whole condition is one expression. If you use statements such as const, let, if, or await, finish with return.

This works:

js
const hp = actor?.system?.attributes?.hp?.value ?? 0;
return hp > 0;

This does not work:

js
const hp = actor?.system?.attributes?.hp?.value ?? 0;
hp > 0;

Conditions can be asynchronous. The Simple Sockets examples below use await.

Searchable Condition Examples

Condition Example Finder

Search only within this example set. Use it to filter by actor, target, combat, flag, equipped, or other condition terms.

20 / 20 examples

Actor Must Be Alive

Allow the activity only while the owning actor has more than 0 HP.

Example Code
return (actor?.system?.attributes?.hp?.value ?? 0) > 0;

Only The GM Can Use This Activity

Restrict the activity to the current GM user.

Example Code
return user?.isGM === true;

Item Must Be Equipped

Only allow the activity while the owning item is equipped.

Example Code
return item?.system?.equipped === true;

Item Must Be Attuned

Gate the activity behind the item's attuned state.

Example Code
return item?.system?.attuned === true;

Item Must Be Identified

Hide the activity behind item identification rules.

Example Code
return item?.system?.identified === true;

Actor Must Have A Minimum Strength Score

Require a minimum Strength score before the activity can be used.

Example Code
return (actor?.system?.abilities?.str?.value ?? 0) >= 16;

Actor Must Have A Specific Item

Allow the activity only if the actor owns an item that matches the required name.

Example Code
const items = actor?.items?.contents ?? [];
return items.some((ownedItem) => ownedItem.name === "Essence Core");

Actor Must Have A Specific Active Effect

Require an Active Effect with a matching name to already be applied to the actor.

Example Code
const effects = actor?.effects?.contents ?? [];
return effects.some((effect) => effect.name === "Rage");

Actor Must Have A Specific Flag

Read a custom actor flag with Foundry's property helper.

Example Code
return getProperty(actor, "flags.world.canUseAncientPower") === true;

Activity Must Be An Attack Activity

Only allow the condition for one activity type.

Example Code
return activityType === "attack";

Require At Least One Target

Block the activity unless the current user has selected a target.

Example Code
return user?.targets?.size > 0;

Require Exactly One Target

Useful for effects that must resolve against one selected target only.

Example Code
return user?.targets?.size === 1;

Selected Target Must Have A Specific Effect

Check the first selected target for a named Active Effect.

Example Code
const targetActor = Array.from(user?.targets ?? [])[0]?.actor;
const effects = targetActor?.effects?.contents ?? [];
return effects.some((effect) => effect.name === "Marked");

Any Selected Target Must Have A Specific Effect

Allow the activity if any selected target matches the required effect.

Example Code
const targets = Array.from(user?.targets ?? []);
return targets.some((target) =>
  (target.actor?.effects?.contents ?? []).some(
    (effect) => effect.name === "Marked",
  ),
);

Require Combat To Be Active

Only allow the activity while combat is running.

Example Code
return Boolean(game.combat?.started);

At Least One Occupied Socket

Simple Sockets example. Require at least one occupied socket on the owning item.

Example Code
const socketsApi = game.modules.get("sc-simple-sockets")?.api?.sockets;
if (!socketsApi) return false;

const slots = await socketsApi.getItemSlots(item);
return slots.some((entry) => entry.hasGem);

First Socket Must Be Occupied

Simple Sockets example. Require the first socket slot to contain a gem.

Example Code
const socketsApi = game.modules.get("sc-simple-sockets")?.api?.sockets;
if (!socketsApi) return false;

const slots = await socketsApi.getItemSlots(item);
return slots[0]?.hasGem === true;

At Least Two Occupied Sockets

Simple Sockets example. Require two or more filled sockets on the item.

Example Code
const socketsApi = game.modules.get("sc-simple-sockets")?.api?.sockets;
if (!socketsApi) return false;

const slots = await socketsApi.getItemSlots(item);
return slots.filter((entry) => entry.hasGem).length >= 2;

Specific Gem Name Present

Simple Sockets example. Check whether any socketed gem name includes a keyword.

Example Code
const socketsApi = game.modules.get("sc-simple-sockets")?.api?.sockets;
if (!socketsApi) return false;

const gems = await socketsApi.getItemGems(item);
return gems.some((gem) => gem.name?.toLowerCase().includes("ruby"));

Direct Flag Check For Occupied Socket

Simple Sockets example. Use a direct flag read when you do not need the API helpers.

Example Code
const sockets = item?.getFlag?.("sc-simple-sockets", "sockets") ?? [];
return sockets.some((slot) => Boolean(slot?.gem));

Notes and Limits

  • conditions are JavaScript and should be treated like other trusted Foundry scripting surfaces
  • empty conditions allow the activity
  • falsy results and thrown errors block it
  • condition errors switch the UI state to Condition error
  • conditions are checked during UI rendering and again during activity use
  • async conditions are supported, but slow code can make activity surfaces feel slower because availability is checked during render
  • the documentation page is in English, but the module UI is localized for English and Brazilian Portuguese