Skip to content

Commit

Permalink
Release 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dev7355608 committed Oct 13, 2024
1 parent 964d9dd commit 92f24df
Show file tree
Hide file tree
Showing 89 changed files with 9,347 additions and 6,321 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/.vscode
/node_modules
/_docs
/_types
/module.zip
/script.js
/script.js.map
312 changes: 2 additions & 310 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,314 +5,6 @@

# Limits (Foundry VTT Module)

This module allows you to define the maximum range of light, sight, and sound within the scene, drawings, templates, and tiles.
This module allows you to limit the range of sight, light, darkness, and sound within regions.

![config](images/config.png)

```js
object.document.setFlag("limits", {
light: {
enabled: true,
range: 0,
},
sight: {
basicSight: {
enabled: true,
range: 0,
},
seeAll: {
enabled: true,
range: 30,
},
// ...
},
sound: {
enabled: false,
range: null, // Infinity
},
});
```

## Macros

### D&D 5e

Recommended modules:

- [Vision 5e](https://foundryvtt.com/packages/vision-5e)
- [Walled Templates](https://foundryvtt.com/packages/walledtemplates)

#### Darkness spell

```js
// === Darkness spell template ===

if (!game.modules.get("limits")?.active) {
ui.notifications.warn("The Limits module is not enabled!");
}

const templateData = {
t: CONST.MEASURED_TEMPLATE_TYPES.CIRCLE,
distance: 15,
fillColor: "#000000",
flags: {
limits: {
// Block sight-based senses except for Devil's Sight and Truesight
sight: {
basicSight: { enabled: true, range: 0 }, // Darkvision
ghostlyGaze: { enabled: true, range: 0 }, // Ghostly Gaze (Vision 5e)
lightPerception: { enabled: true, range: 0 }, // Light Perception (Vision 5e)
},
// Block light
light: { enabled: true, range: 0 },
},
},
};

// Walled Templates (optional)
if (game.modules.get("walledtemplates")?.active) {
templateData.flags.walledtemplates = {
wallsBlock: "recurse", // blocked by walls and spreads around corners
wallRestriction: "move",
};
}

const template = (
await new dnd5e.canvas.AbilityTemplate(
new CONFIG.MeasuredTemplate.documentClass(templateData, {
parent: canvas.scene,
})
).drawPreview()
).at(0);

// Sequencer + JB2A Assets (optional)
if (
game.modules.get("sequencer")?.active &&
(game.modules.get("JB2A_DnD5e")?.active ||
game.modules.get("jb2a_patreon")?.active)
) {
new Sequence()
.effect()
.persist(true)
.file("jb2a.darkness.black")
.opacity(0.5)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.play();
}
```
#### Hunger of Hadar spell
```js
// === Hunger of Hadar spell template ===

if (!game.modules.get("limits")?.active) {
ui.notifications.warn("The Limits module is not enabled!");
}

const templateData = {
t: CONST.MEASURED_TEMPLATE_TYPES.CIRCLE,
distance: 20,
fillColor: "#000000",
flags: {
limits: {
// Block sight-based senses
sight: {
basicSight: { enabled: true, range: 0 }, // Darkvision
devilsSight: { enabled: true, range: 0 }, // Devil's Sight (Vision 5e)
ghostlyGaze: { enabled: true, range: 0 }, // Ghostly Gaze (Vision 5e)
lightPerception: { enabled: true, range: 0 }, // Light Perception (Vision 5e)
seeAll: { enabled: true, range: 0 }, // Truesight
},
// Block light
light: { enabled: true, range: 0 },
},
},
};

// Walled Templates (optional)
if (game.modules.get("walledtemplates")?.active) {
templateData.flags.walledtemplates = {
wallsBlock: "walled", // blocked by walls and does not spread around corners
wallRestriction: "move",
};
}

const template = (
await new dnd5e.canvas.AbilityTemplate(
new CONFIG.MeasuredTemplate.documentClass(templateData, {
parent: canvas.scene,
})
).drawPreview()
).at(0);

// Sequencer + JB2A Assets (optional)
if (
game.modules.get("sequencer")?.active &&
(game.modules.get("JB2A_DnD5e")?.active ||
game.modules.get("jb2a_patreon")?.active)
) {
new Sequence()
.effect()
.persist(true)
.file("jb2a.darkness.black")
.opacity(0.5)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.zIndex(0)
.effect()
.persist(true)
.file("jb2a.arms_of_hadar.dark_purple")
.opacity(0.5)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.zIndex(1)
.play();
}
```
#### Fog Cloud spell
```js
// === Fog Cloud Spell Template ===

if (!game.modules.get("limits")?.active) {
ui.notifications.warn("The Limits module is not enabled!");
}

const spellLevel = 1;
const templateData = {
t: CONST.MEASURED_TEMPLATE_TYPES.CIRCLE,
distance: 20 * spellLevel,
fillColor: "#ffffff",
flags: {
limits: {
// Block sight-based senses
sight: {
basicSight: { enabled: true, range: 0 }, // Darkvision
devilsSight: { enabled: true, range: 0 }, // Devil's Sight (Vision 5e)
ghostlyGaze: { enabled: true, range: 0 }, // Ghostly Gaze (Vision 5e)
lightPerception: { enabled: true, range: 0 }, // Light Perception (Vision 5e)
seeAll: { enabled: true, range: 0 }, // Truesight
},
},
},
};

// Walled Templates (optional)
if (game.modules.get("walledtemplates")?.active) {
templateData.flags.walledtemplates = {
wallsBlock: "recurse", // blocked by walls and spreads around corners
wallRestriction: "move",
};
}

const template = (
await new dnd5e.canvas.AbilityTemplate(
new CONFIG.MeasuredTemplate.documentClass(templateData, {
parent: canvas.scene,
})
).drawPreview()
).at(0);

// Sequencer + JB2A Assets (optional)
if (
game.modules.get("sequencer")?.active &&
(game.modules.get("JB2A_DnD5e")?.active ||
game.modules.get("jb2a_patreon")?.active)
) {
new Sequence()
.effect()
.persist(true)
.file("jb2a.fog_cloud.01.white")
.opacity(0.5)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.play();
}
```
#### Silence spell
```js
// === Silence spell template ===

if (!game.modules.get("limits")?.active) {
ui.notifications.warn("The Limits module is not enabled!");
}

const templateData = {
t: CONST.MEASURED_TEMPLATE_TYPES.CIRCLE,
distance: 20,
fillColor: "#7fffff",
flags: {
limits: {
// Block hearing
sight: {
hearing: { enabled: true, range: 0 }, // Hearing (Vision 5e)
},
// Block sound
sound: { enabled: true, range: 0 },
},
},
};

// Walled Templates (optional)
if (game.modules.get("walledtemplates")?.active) {
templateData.flags.walledtemplates = {
wallsBlock: "walled", // blocked by walls and does not spread around corners
wallRestriction: "move",
};
}

const template = (
await new dnd5e.canvas.AbilityTemplate(
new CONFIG.MeasuredTemplate.documentClass(templateData, {
parent: canvas.scene,
})
).drawPreview()
).at(0);

// Sequencer + JB2A Assets (optional)
if (
game.modules.get("sequencer")?.active &&
(game.modules.get("JB2A_DnD5e")?.active ||
game.modules.get("jb2a_patreon")?.active)
) {
new Sequence()
.effect()
.persist(true)
.file("jb2a.energy_field.02.below.blue")
.opacity(0.25)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.zIndex(0)
.effect()
.persist(true)
.file("jb2a.energy_field.02.above.blue")
.opacity(0.25)
.attachTo(template)
.scaleToObject((template.distance + 2.5) / template.distance)
.xray(true)
.aboveLighting()
.mask(game.modules.get("walledtemplates")?.active ? [template] : [])
.zIndex(1)
.play();
}
```
<img src="images/demo.png" style="max-height: 560px"> <img src="images/config.png" style="max-height: 560px">
61 changes: 61 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import stylistic from "@stylistic/eslint-plugin";

export default [
{
ignores: ["_docs", "_types", "script.js"],
},
pluginJs.configs.recommended,
stylistic.configs.customize({
indent: 4,
quotes: "double",
semi: true,
jsx: false,
arrowParens: "always",
braceStyle: "1tbs",
blockSpacing: true,
quoteProps: "consistent-as-needed",
commaDangle: "always-multiline",
}),
{
languageOptions: {
ecmaVersion: "latest",
globals: {
...globals.browser,
canvas: "readonly",
CONFIG: "readonly",
CONST: "readonly",
DetectionMode: "readonly",
foundry: "readonly",
game: "readonly",
Hooks: "readonly",
libWrapper: "readonly",
PIXI: "readonly",
},
},
rules: {
"no-unused-vars": ["error", {
vars: "all",
args: "none",
argsIgnorePattern: "^_",
caughtErrors: "all",
caughtErrorsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
ignoreRestSiblings: false,
reportUsedIgnorePattern: false,
}],
"@stylistic/padding-line-between-statements": [
"error",
{ blankLine: "always", prev: "*", next: ["block-like", "break", "class", "continue", "function", "return"] },
{ blankLine: "always", prev: ["block-like", "class", "function"], next: "*" },
{ blankLine: "always", prev: "expression", next: ["const", "let", "var"] },
{ blankLine: "always", prev: ["const", "let", "var"], next: "expression" },
{ blankLine: "never", prev: ["break", "continue", "return"], next: "*" },
{ blankLine: "never", prev: "*", next: "case" },
],
"@stylistic/no-mixed-operators": "off",
"@stylistic/no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
},
},
];
Binary file modified images/config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 92f24df

Please sign in to comment.