Skip to content

Commit

Permalink
Add Eyes of the Grave
Browse files Browse the repository at this point in the history
  • Loading branch information
dev7355608 committed Sep 7, 2024
1 parent 86bb7d5 commit 4ae6bf2
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 3 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ The automation detects relevant feats and effects that affect the creatures sens
- Cannot detect anything on its own and requires another sense to see the target without the _ethereal_ status.
- Is not restricted by walls or blocked by darkness sources.
- Configured automatically for NPC actors that have the `Ethereal Sight`[\*](#translations) feat and PC actors with the `The Third Eye: Ethereal Sight`[\*](#translations) feat.
- **Eyes of the Grave** _(Class Feature: Cleric, XGE 19)_
- Detects undead, and PC actors with the `Hollow One`[\*](#translations) _(Character Creation Option, EGW 182)_, `Supernatural Gift: Hollow One`, or `Supernatural Gifts: Hollow One` feat.
- Cannot detect actors that are _burrowing_, _ethereal_ (from the material plane unless the `Etherealness`[\*](#translations) _(Monster Feature, e.g. SRD / MM 147)_ NPC feat says otherwise), or _petrified_. Also cannot detect actors with the `Nondetection`[\*](#translations) _(Spell, SRD / PHB 263)_ effect.
- Does not reveal the identity of detected tokens.
- Disabled while _burrowing_, _defeated_ (_dead_), _petrified_, _sleeping_, or _unconscious_.
- Is restricted by sight-blocking walls and isn't blocked by darkness sources.
- Configured automatically for PC actors with the `Eyes of the Grave`[\*](#translations) effect.
- **Hearing**
- Detects PC/NPC actors that are not objects (e.g. [Item Piles](https://foundryvtt.com/packages/item-piles)).
- Cannot detect actors that are _defeated (dead)_, _ethereal_ (from the the material plane), _inaudible_, or _petrified_.
Expand Down Expand Up @@ -161,6 +168,7 @@ While a player does have any owned nonhidden tokens with vision that are _defeat
| Devil's Sight | `ATL.detectionModes.devilsSight.range` |
| Divine Sense | `ATL.detectionModes.divineSense.range` |
| Ethereal Sight | `ATL.detectionModes.etherealSight.range` |
| Eyes of the Grave | `ATL.detectionModes.eyesOfTheGrave.range` |
| Hearing | `ATL.detectionModes.hearing.range` |
| Life Sense | `ATL.detectionModes.lifeSense.range` |
| Light Perception | `ATL.detectionModes.lightPerception.range` |
Expand Down Expand Up @@ -190,6 +198,7 @@ _Note: Attribute keys starting with `ATL.` require the [Active Token Effects](ht
| `Eldritch Adept` | _Feat_ | `Schauerlicher Adept` | `Adepte occulte` | `Adepto sobrenatural` | `Adepto Místico` |
| `Eldritch Invocation` | _Warlock feat_ | `Schauerliche Anrufung` | `Invocation occulte` / `Manifestation occulte` | `Invocación sobrenatural` | `Invocação Mística` |
| `Ethereal Sight` | _Monster feat_ | `Ätherische Sicht` | `Vision éthérée` / `Vue éthérée` | `Visión etérea` | `Visão Etérea` |
| `Eyes of the Grave` | _Cleric (Grave Domain) feat_ | `Grabesblick` | `Œil de la tombe` | `Ojos de la Tumba` | `Olhos da Sepultura` |
| `Ghostly Gaze` | _Warlock invocation_ | `Geisterhafter Blick` | `Regard fantomatique` | `Mirada fantasmal` | `Olhar Fantasmagórico` |
| `Hollow One` | _Supernatural Gift_ | `Leerwandler` | `Celui-qui-est-creux` | `Aquel que está vacío` | `Oco` |
| `Life Sense` | _Monster feat_ | `Lebensgespür` | `Perception de la vie` | `Percepción de la Vida` | `Percepção da Vida` |
Expand Down
1 change: 1 addition & 0 deletions lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"VISION5E.DevilsSight": "Teufelssicht",
"VISION5E.DivineSense": "Göttliches Gespür",
"VISION5E.EtherealSight": "Ätherische Sicht",
"VISION5E.EyesOfTheGrave": "Grabesblick",
"VISION5E.Hearing": "Hören",
"VISION5E.Inaudible": "Lautlos",
"VISION5E.LifeSense": "Lebensgespür",
Expand Down
1 change: 1 addition & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"VISION5E.DevilsSight": "Devil's Sight",
"VISION5E.DivineSense": "Divine Sense",
"VISION5E.EtherealSight": "Ethereal Sight",
"VISION5E.EyesOfTheGrave": "Eyes of the Grave",
"VISION5E.Hearing": "Hearing",
"VISION5E.Inaudible": "Inaudible",
"VISION5E.LifeSense": "Life Sense",
Expand Down
1 change: 1 addition & 0 deletions lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"VISION5E.DevilsSight": "Vista del Diablo",
"VISION5E.DivineSense": "Sentidos Divinos",
"VISION5E.EtherealSight": "Visión Etérea",
"VISION5E.EyesOfTheGrave": "Ojos de la Tumba",
"VISION5E.Hearing": "Audición",
"VISION5E.Inaudible": "Inaudible",
"VISION5E.LifeSense": "Percepción de la Vida",
Expand Down
1 change: 1 addition & 0 deletions lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"VISION5E.DevilsSight": "Vision du diable",
"VISION5E.DivineSense": "Perception divine",
"VISION5E.EtherealSight": "Vision éthérée",
"VISION5E.EyesOfTheGrave": "Œil de la tombe",
"VISION5E.Hearing": "Audition",
"VISION5E.Inaudible": "Inaudible",
"VISION5E.LifeSense": "Perception de la vie",
Expand Down
1 change: 1 addition & 0 deletions lang/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"VISION5E.DevilsSight": "Visão Diabólica",
"VISION5E.DivineSense": "Sentido Divino",
"VISION5E.EtherealSight": "Visão Etérea",
"VISION5E.EyesOfTheGrave": "Olhos da Sepultura",
"VISION5E.Hearing": "Audição",
"VISION5E.Inaudible": "Inaudível",
"VISION5E.LifeSense": "Percepção da Vida",
Expand Down
6 changes: 3 additions & 3 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"email": "[email protected]"
}
],
"version": "2.3.4",
"version": "2.4.0",
"compatibility": {
"minimum": "12",
"verified": "12"
Expand Down Expand Up @@ -60,8 +60,8 @@
},
"url": "https://github.com/dev7355608/vision-5e",
"manifest": "https://github.com/dev7355608/vision-5e/releases/latest/download/module.json",
"download": "https://github.com/dev7355608/vision-5e/releases/download/v2.3.4/module.zip",
"changelog": "https://github.com/dev7355608/vision-5e/releases/tag/v2.3.4",
"download": "https://github.com/dev7355608/vision-5e/releases/download/v2.4.0/module.zip",
"changelog": "https://github.com/dev7355608/vision-5e/releases/tag/v2.4.0",
"bugs": "https://github.com/dev7355608/vision-5e/issues",
"readme": "https://raw.githubusercontent.com/dev7355608/vision-5e/main/README.md",
"license": "https://raw.githubusercontent.com/dev7355608/vision-5e/main/LICENSE"
Expand Down
18 changes: 18 additions & 0 deletions scripts/actor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ const EFFECT_REGISTRY = {
divineSense(effect) {
upgradeDetectionMode(this, "divineSense", 60, "ft");
},
eyesOfTheGrave(item) {
upgradeDetectionMode(this, "eyesOfTheGrave", 60, "ft");
},
invocationGhostlyGaze(effect) {
upgradeDetectionMode(this, "basicSight", 30, "ft");
this.statuses.add(CONFIG.specialStatusEffects.GHOSTLY_GAZE);
Expand Down Expand Up @@ -401,6 +404,9 @@ const DATABASE = Object.values({
etherealness: [
"Etherealness",
],
eyesOfTheGrave: [
"Eyes of the Grave",
],
hollowOne: [
[["Supernatural Gift"], ["s", ""], ": Hollow One"],
"Hollow One",
Expand Down Expand Up @@ -488,6 +494,9 @@ const DATABASE = Object.values({
etherealness: [
"Körperlosigkeit",
],
eyesOfTheGrave: [
"Grabesblick",
],
hollowOne: [
[["Übernatürliche Gabe"], ["n", ""], ": ", ["Leerwandler", "Hollow One"]],
"Leerwandler",
Expand Down Expand Up @@ -576,6 +585,9 @@ const DATABASE = Object.values({
etherealness: [
"Forme éthérée",
],
eyesOfTheGrave: [
"Œil de la tombe",
],
hollowOne: [
[["Don surnaturel", "Dons surnaturels"], [": ", " : "], ["Celui-qui-est-creux", "Hollow One"]],
"Celui-qui-est-creux",
Expand Down Expand Up @@ -666,6 +678,9 @@ const DATABASE = Object.values({
etherealness: [
"Excursión Etérea",
],
eyesOfTheGrave: [
"Ojos de la Tumba",
],
hollowOne: [
[["Don Supernatural", "Dones Supernaturales"], ": ", ["Aquel que está vacío", "Hollow One"]],
"Aquel que está vacío",
Expand Down Expand Up @@ -757,6 +772,9 @@ const DATABASE = Object.values({
etherealness: [
"Forma Etérea",
],
eyesOfTheGrave: [
"Olhos da Sepultura",
],
hollowOne: [
[["Dom Sobrenatural", "Dons Sobrenaturais"], ": ", ["Oco", "Hollow One"]],
"Oco",
Expand Down
70 changes: 70 additions & 0 deletions scripts/detection-modes/eyes-of-the-grave.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import DetectionMode from "./base.mjs";

/**
* The detection mode for Eyes of the Grave.
*/
export default class DetectionModeEyesOfTheGrave extends DetectionMode {
imprecise = true;
important = true;

constructor() {
super({
id: "eyesOfTheGrave",
label: "VISION5E.EyesOfTheGrave",
type: DetectionMode.DETECTION_TYPES.OTHER,
angle: false,
important: true,
imprecise: true,
});
}

/** @override */
static getDetectionFilter() {
return this._detectionFilter ??= CONFIG.Canvas.detectionModes.detectEvilAndGood.constructor.getDetectionFilter();
}

/** @override */
_canDetect(visionSource, target) {
const source = visionSource.object;

if (!(target instanceof Token)
|| !target.actor?.system.details?.type
|| target.document.hasStatusEffect(CONFIG.specialStatusEffects.BURROWING)
|| target.document.hasStatusEffect(CONFIG.specialStatusEffects.ETHEREAL)
&& !source.document.hasStatusEffect(CONFIG.specialStatusEffects.ETHEREAL)
&& !target.document.hasStatusEffect(CONFIG.specialStatusEffects.MATERIAL)
|| target.document.hasStatusEffect(CONFIG.specialStatusEffects.NONDETECTION)
|| target.document.hasStatusEffect(CONFIG.specialStatusEffects.OBJECT)
|| target.document.hasStatusEffect(CONFIG.specialStatusEffects.PETRIFIED)) {
return false;
}

if (source.document.hasStatusEffect(CONFIG.specialStatusEffects.BURROWING)
|| source.document.hasStatusEffect(CONFIG.specialStatusEffects.DEFEATED)
|| source.document.hasStatusEffect(CONFIG.specialStatusEffects.PETRIFIED)
|| source.document.hasStatusEffect(CONFIG.specialStatusEffects.SLEEPING)
|| source.document.hasStatusEffect(CONFIG.specialStatusEffects.UNCONSCIOUS)) {
return false;
}

if (target.document.hasStatusEffect(CONFIG.specialStatusEffects.REVENANCE)) {
return true;
}

return target.actor.system.details.type.value === "undead";
}

/** @override */
_testLOS(visionSource, mode, target, test) {
return !CONFIG.Canvas.polygonBackends.sight.testCollision(
{ x: visionSource.x, y: visionSource.y },
test.point,
{
type: "sight",
mode: "any",
source: visionSource,
useThreshold: true
}
);
}
}
2 changes: 2 additions & 0 deletions scripts/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import DetectionModeDetectThoughts from "./detection-modes/detect-thoughts.mjs";
import DetectionModeDevilsSight from "./detection-modes/devils-sight.mjs";
import DetectionModeDivineSense from "./detection-modes/divine-sense.mjs";
import DetectionModeEtherealSight from "./detection-modes/ethereral-sight.mjs";
import DetectionModeEyesOfTheGrave from "./detection-modes/eyes-of-the-grave.mjs";
import DetectionModeHearing from "./detection-modes/hearing.mjs";
import DetectionModeLifeSense from "./detection-modes/life-sense.mjs";
import DetectionModeLightPerception from "./detection-modes/light-perception.mjs";
Expand Down Expand Up @@ -101,6 +102,7 @@ Hooks.once("init", () => {
DetectionModeDevilsSight,
DetectionModeDivineSense,
DetectionModeEtherealSight,
DetectionModeEyesOfTheGrave,
DetectionModeHearing,
DetectionModeLifeSense,
DetectionModeLightPerception,
Expand Down

0 comments on commit 4ae6bf2

Please sign in to comment.