Skip to content

Commit

Permalink
Make RegionBehavior system data resolvable by type (foundryvtt#14886)
Browse files Browse the repository at this point in the history
  • Loading branch information
In3luki authored and CarlosFdez committed May 29, 2024
1 parent 17b70cc commit dbe3f9f
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 14 deletions.
8 changes: 8 additions & 0 deletions src/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
TileDocumentPF2e,
TokenDocumentPF2e,
} from "@scene";
import type { RegionBehaviorInstance } from "@scene/region-behaviors/types.ts";
import type { ActorDeltaPF2e } from "@scene/token-document/actor-delta.ts";
import type { PF2ECONFIG, StatusEffectIconTheme } from "@scripts/config/index.ts";
import type { DicePF2e } from "@scripts/dice.ts";
Expand Down Expand Up @@ -69,6 +70,7 @@ import type {
import type { TextEditorPF2e } from "@system/text-editor.ts";
import type { sluggify } from "@util";
import type EnJSON from "static/lang/en.json";
import type { CanvasBaseRegion } from "types/foundry/client/data/documents/client-base-mixes.d.ts";

interface GamePF2e
extends Game<
Expand Down Expand Up @@ -343,6 +345,12 @@ declare global {
ternary: (condition: boolean | number, ifTrue: number, ifFalse: number) => number;
}

interface RegionDocument<TParent extends Scene | null = Scene | null> extends CanvasBaseRegion<TParent> {
tokens: Set<TokenDocumentPF2e>;

readonly behaviors: foundry.abstract.EmbeddedCollection<RegionBehaviorInstance<this>>;
}

const BUILD_MODE: "development" | "production";
const CONDITION_SOURCES: ConditionSource[];
const EN_JSON: typeof EnJSON;
Expand Down
9 changes: 5 additions & 4 deletions src/module/actor/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
extractRollSubstitutions,
extractRollTwice,
} from "@module/rules/helpers.ts";
import { EnvironmentTypeData } from "@scene/region-behaviors/terrain.ts";
import { EnviornmentPF2eRegionBehavior } from "@scene/region-behaviors/types.ts";
import { eventToRollParams } from "@scripts/sheet-util.ts";
import { CheckCheckContext, CheckPF2e, CheckRoll } from "@system/check/index.ts";
import { DamageDamageContext, DamagePF2e } from "@system/damage/index.ts";
Expand Down Expand Up @@ -271,9 +271,10 @@ function createEnvironmentRollOptions(actor: ActorPF2e): Record<string, boolean>
const top = region.elevation.top ?? Infinity;
if (token.elevation < bottom || token.elevation > top) continue;

for (const behavior of region.behaviors.filter((b) => b.type === "pf2eEnvironment")) {
// todo: remove once type resolution is possible
const system = behavior.system as EnvironmentTypeData;
for (const behavior of region.behaviors.filter(
(b): b is EnviornmentPF2eRegionBehavior => b.type === "pf2eEnvironment",
)) {
const system = behavior.system;
switch (system.mode) {
case "add": {
for (const terrain of system.environmentTypes) {
Expand Down
4 changes: 2 additions & 2 deletions src/module/scene/region-behaviors/terrain.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { resetActors } from "@actor/helpers.ts";
import type { TokenDocumentPF2e } from "@scene";
import type { RegionEventType } from "types/foundry/client-esm/data/region-behaviors/base.d.ts";
import type { SetField, StringField } from "types/foundry/common/data/fields.d.ts";
import type { RegionEventPF2e } from "./types.ts";

class EnvironmentBehaviorTypePF2e extends foundry.data.regionBehaviors.RegionBehaviorType<EnvironmentTypeSchema> {
override events = new Set<RegionEventType>(["tokenEnter", "tokenExit"]);
Expand Down Expand Up @@ -30,7 +30,7 @@ class EnvironmentBehaviorTypePF2e extends foundry.data.regionBehaviors.RegionBeh
};
}

protected override async _handleRegionEvent(event: RegionEvent<TokenDocumentPF2e>): Promise<void> {
protected override async _handleRegionEvent(event: RegionEventPF2e): Promise<void> {
if (event.name === "tokenEnter" || event.name === "tokenExit") {
if (event.data.token.actor) resetActors([event.data.token.actor], { tokens: true });
}
Expand Down
86 changes: 86 additions & 0 deletions src/module/scene/region-behaviors/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { CombatantPF2e } from "@module/encounter/combatant.ts";
import type { UserPF2e } from "@module/user/document.ts";
import type { ScenePF2e, TokenDocumentPF2e } from "@scene";
import type { AdjustDarknessLevelRegionBehaviorSchema } from "types/foundry/client-esm/data/region-behaviors/adjust-darkness-level.d.ts";
import type { ExecuteMacroRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/execute-macro.d.ts";
import type { ExecuteScriptRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/execute-script.d.ts";
import type { PauseGameRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/pause-game.d.ts";
import type { SuppressWeatherRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/suppress-weather.d.ts";
import type { TeleportTokenRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/teleport-token.d.ts";
import type { ToggleBehaviorRegionBehaviorTypeSchema } from "types/foundry/client-esm/data/region-behaviors/toggle-behavior.d.ts";
import type { EnvironmentTypeData } from "./terrain.ts";

type RegionEventPF2e = RegionEvent<TokenDocumentPF2e, UserPF2e, CombatantPF2e, RegionDocument<ScenePF2e | null>>;

interface BaseRegionBehavior<TParent extends RegionDocument = RegionDocument> extends RegionBehavior<TParent> {
get scene(): ScenePF2e | null;

_handleRegionEvent(event: RegionEventPF2e): Promise<void>;
}

interface AdjustDarknessLevelRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "adjustDarknessLevel";

system: ModelPropsFromSchema<AdjustDarknessLevelRegionBehaviorSchema>;
}

interface ExecuteMacroRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "executeMacro";

system: ModelPropsFromSchema<ExecuteMacroRegionBehaviorTypeSchema>;
}

interface ExecuteScriptRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "executeScript";

system: ModelPropsFromSchema<ExecuteScriptRegionBehaviorTypeSchema>;
}

interface PauseGameRegionBehavior<TParent extends RegionDocument = RegionDocument> extends BaseRegionBehavior<TParent> {
type: "pauseGame";

system: ModelPropsFromSchema<PauseGameRegionBehaviorTypeSchema>;
}

interface SuppressWeatherRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "suppressWeather";

system: ModelPropsFromSchema<SuppressWeatherRegionBehaviorTypeSchema>;
}

interface TeleportTokenRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "teleportToken";

system: ModelPropsFromSchema<TeleportTokenRegionBehaviorTypeSchema>;
}

interface ToggleBehaviorRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "toggleBehavior";

system: ModelPropsFromSchema<ToggleBehaviorRegionBehaviorTypeSchema>;
}

interface EnviornmentPF2eRegionBehavior<TParent extends RegionDocument = RegionDocument>
extends BaseRegionBehavior<TParent> {
type: "pf2eEnvironment";

system: EnvironmentTypeData;
}

type RegionBehaviorInstance<TParent extends RegionDocument = RegionDocument> =
| AdjustDarknessLevelRegionBehavior<TParent>
| ExecuteMacroRegionBehavior<TParent>
| ExecuteScriptRegionBehavior<TParent>
| PauseGameRegionBehavior<TParent>
| SuppressWeatherRegionBehavior<TParent>
| TeleportTokenRegionBehavior<TParent>
| ToggleBehaviorRegionBehavior<TParent>
| EnviornmentPF2eRegionBehavior<TParent>;

export type { EnviornmentPF2eRegionBehavior, RegionBehaviorInstance, RegionEventPF2e };
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface ExecuteMacroRegionBehaviorType
extends RegionBehaviorType<ExecuteMacroRegionBehaviorTypeSchema>,
ModelPropsFromSchema<ExecuteMacroRegionBehaviorTypeSchema> {}

type ExecuteMacroRegionBehaviorTypeSchema = {
export type ExecuteMacroRegionBehaviorTypeSchema = {
/** The events that are handled by the behavior. */
events: EventsField;
/** The Macro UUID. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ExecuteScriptRegionBehaviorType
extends RegionBehaviorType<ExecuteScriptRegionBehaviorTypeSchema>,
ModelPropsFromSchema<ExecuteScriptRegionBehaviorTypeSchema> {}

type ExecuteScriptRegionBehaviorTypeSchema = {
export type ExecuteScriptRegionBehaviorTypeSchema = {
/** The events that are handled by the behavior. */
events: EventsField;
/** The source code of the script. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface PauseGameRegionBehaviorType
extends RegionBehaviorType<PauseGameRegionBehaviorTypeSchema>,
ModelPropsFromSchema<PauseGameRegionBehaviorTypeSchema> {}

type PauseGameRegionBehaviorTypeSchema = {
export type PauseGameRegionBehaviorTypeSchema = {
/** Disable the behavior once a player-controlled Token enters the region? */
once: fields.BooleanField;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ export interface SuppressWeatherRegionBehaviorType
extends RegionBehaviorType<SuppressWeatherRegionBehaviorTypeSchema>,
ModelPropsFromSchema<SuppressWeatherRegionBehaviorTypeSchema> {}

type SuppressWeatherRegionBehaviorTypeSchema = {};
export type SuppressWeatherRegionBehaviorTypeSchema = {};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface TeleportTokenRegionBehaviorType
extends RegionBehaviorType<TeleportTokenRegionBehaviorTypeSchema>,
ModelPropsFromSchema<TeleportTokenRegionBehaviorTypeSchema> {}

type TeleportTokenRegionBehaviorTypeSchema = {
export type TeleportTokenRegionBehaviorTypeSchema = {
/** The destination Region the Token is teleported to. */
destination: fields.DocumentUUIDField;
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface ToggleBehaviorRegionBehaviorType
extends RegionBehaviorType<ToggleBehaviorRegionBehaviorTypeSchema>,
ModelPropsFromSchema<ToggleBehaviorRegionBehaviorTypeSchema> {}

type ToggleBehaviorRegionBehaviorTypeSchema = {
export type ToggleBehaviorRegionBehaviorTypeSchema = {
/** The events that are handled by the behavior. */
events: EventsField;
/** The Region Behavior UUIDs that are enabled. */
Expand Down
10 changes: 8 additions & 2 deletions types/foundry/client/data/documents/region-document.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ declare global {
TDocument extends RegionDocument = RegionDocument,
TUser extends User = User,
TTokenDocument extends TokenDocument = TokenDocument,
TCombatant extends Combatant<Combat, TTokenDocument> = Combatant<Combat, TTokenDocument>,
TCombatant extends Combatant<Combat | null, TTokenDocument | null> = Combatant<
Combat | null,
TTokenDocument | null
>,
> extends BaseRegionEvent<TDocument, TUser> {
name: "tokenRoundStart" | "tokenRoundEnd" | "tokenTurnStart" | "tokenTurnEnd";
data: {
Expand Down Expand Up @@ -121,7 +124,10 @@ declare global {
type RegionEvent<
TTokenDocument extends TokenDocument = TokenDocument,
TUser extends User = User,
TCombatant extends Combatant<Combat, TTokenDocument> = Combatant<Combat, TTokenDocument>,
TCombatant extends Combatant<Combat | null, TTokenDocument | null> = Combatant<
Combat | null,
TTokenDocument | null
>,
TDocument extends RegionDocument = RegionDocument,
> =
| BehaviorStatusRegionEvent<TDocument, TUser>
Expand Down

0 comments on commit dbe3f9f

Please sign in to comment.