Skip to content

Commit

Permalink
Update for V13
Browse files Browse the repository at this point in the history
  • Loading branch information
dev7355608 committed Nov 1, 2024
1 parent 60f0587 commit 637ba90
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 40 deletions.
8 changes: 4 additions & 4 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"email": "[email protected]"
}
],
"version": "2.0.1",
"version": "2.0.2",
"compatibility": {
"minimum": "12",
"verified": "12"
"verified": "13"
},
"documentTypes": {
"RegionBehavior": {
Expand Down Expand Up @@ -43,8 +43,8 @@
],
"url": "https://github.com/dev7355608/limits",
"manifest": "https://github.com/dev7355608/limits/releases/latest/download/module.json",
"download": "https://github.com/dev7355608/limits/releases/download/v2.0.1/module.zip",
"changelog": "https://github.com/dev7355608/limits/releases/tag/v2.0.1",
"download": "https://github.com/dev7355608/limits/releases/download/v2.0.2/module.zip",
"changelog": "https://github.com/dev7355608/limits/releases/tag/v2.0.2",
"bugs": "https://github.com/dev7355608/limits/issues",
"readme": "https://raw.githubusercontent.com/dev7355608/limits/main/README.md",
"license": "https://raw.githubusercontent.com/dev7355608/limits/main/LICENSE"
Expand Down
79 changes: 62 additions & 17 deletions scripts/_index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,74 @@ Hooks.once("init", () => {
CONFIG.Canvas.darknessSourceClass = PointDarknessSourceMixin(CONFIG.Canvas.darknessSourceClass);
CONFIG.Canvas.soundSourceClass = PointSoundSourceMixin(CONFIG.Canvas.soundSourceClass);

if (game.modules.get("lib-wrapper")?.active) {
libWrapper.register(
"limits",
"DetectionMode.prototype._testPoint",
function (wrapped, visionSource, mode, target, test) {
return wrapped(visionSource, mode, target, test)
&& visionSource._testLimit(mode, test.point, test.elevation);
},
libWrapper.WRAPPER,
{ perf_mode: libWrapper.PERF_FAST },
);
if (game.release.version >= 13) {
if (game.modules.get("lib-wrapper")?.active) {
libWrapper.register(
"limits",
"foundry.canvas.perception.DetectionMode.prototype._testPoint",
function (wrapped, visionSource, mode, target, test) {
return wrapped(visionSource, mode, target, test)
&& visionSource._testLimit(mode, test.point);
},
libWrapper.WRAPPER,
{ perf_mode: libWrapper.PERF_FAST },
);
} else {
const DetectionMode = foundry.canvas.perception.DetectionMode;
const testPoint = DetectionMode.prototype._testPoint;

DetectionMode.prototype._testPoint = function (visionSource, mode, target, test) {
return testPoint.call(this, visionSource, mode, target, test)
&& visionSource._testLimit(mode, test.point);
};
}
} else {
const testPoint = DetectionMode.prototype._testPoint;
const TEST_POINT = { x: 0.0, y: 0.0, elevation: 0.0 };

if (game.modules.get("lib-wrapper")?.active) {
libWrapper.register(
"limits",
"DetectionMode.prototype._testPoint",
function (wrapped, visionSource, mode, target, test) {
if (!wrapped(visionSource, mode, target, test)) {
return false;
}

const { x, y } = test.point;

TEST_POINT.x = x;
TEST_POINT.y = y;
TEST_POINT.elevation = test.elevation;

return visionSource._testLimit(mode, TEST_POINT);
},
libWrapper.WRAPPER,
{ perf_mode: libWrapper.PERF_FAST },
);
} else {
const testPoint = DetectionMode.prototype._testPoint;

DetectionMode.prototype._testPoint = function (visionSource, mode, target, test) {
if (!testPoint.call(this, visionSource, mode, target, test)) {
return false;
}

const { x, y } = test.point;

TEST_POINT.x = x;
TEST_POINT.y = y;
TEST_POINT.elevation = test.elevation;

DetectionMode.prototype._testPoint = function (visionSource, mode, target, test) {
return testPoint.call(this, visionSource, mode, target, test)
&& visionSource._testLimit(mode, test.point, test.elevation);
};
return visionSource._testLimit(mode, TEST_POINT);
};
}
}
});
});
});

Hooks.once("ready", () => {
CONFIG.RegionBehavior.sheetClasses[TYPE]["core.RegionBehaviorConfig"].cls = LimitRangeRegionBehaviorConfig;
if (game.release.version < 13) {
CONFIG.RegionBehavior.sheetClasses[TYPE]["core.RegionBehaviorConfig"].cls = LimitRangeRegionBehaviorConfig;
}
});
21 changes: 21 additions & 0 deletions scripts/canvas/sources/darkness.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import Limits from "../../limits.mjs";
import PointSourcePolygonConstraint from "../geometry/constraint.mjs";
import PointSourceRayCaster from "./caster.mjs";

/**
* @param {typeof foundry.canvas.sources.PointDarknessSource} PointDarknessSource
* @returns {typeof foundry.canvas.sources.PointDarknessSource}
*/
export const PointDarknessSourceMixin = (PointDarknessSource) => class extends PointDarknessSource {
/**
* @type {PointSourceRayCaster}
* @readonly
*/
#caster = new PointSourceRayCaster();

/** @override */
_createShapes() {
super._createShapes();
Expand All @@ -21,6 +28,20 @@ export const PointDarknessSourceMixin = (PointDarknessSource) => class extends P
} else {
PointSourcePolygonConstraint.apply(this.shape, Limits.darkness);
}

if (game.release.version >= 13) {
const { x, y, elevation, radius } = this.data;
const z = elevation * canvas.dimensions.distancePixels;
const { left: minX, right: maxX, top: minY, bottom: maxY } = this.shape.bounds;
const space = Limits.darkness.crop(minX, minY, z - radius, maxX, maxY, z + radius);

this.#caster.initialize(space, x, y, z, 0.0, Infinity);
}
}

/** @override */
testPoint(point) {
return super.testPoint(point) && this.#caster.castRay(point.x, point.y, point.elevation * canvas.dimensions.distancePixels).targetHit;
}
};

Expand Down
21 changes: 21 additions & 0 deletions scripts/canvas/sources/light.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
import Limits from "../../limits.mjs";
import PointSourcePolygonConstraint from "../geometry/constraint.mjs";
import PointSourceRayCaster from "./caster.mjs";

/**
* @param {typeof foundry.canvas.sources.PointLightSource} PointLightSource
* @returns {typeof foundry.canvas.sources.PointLightSource}
*/
export const PointLightSourceMixin = (PointLightSource) => class extends PointLightSource {
/**
* @type {PointSourceRayCaster}
* @readonly
*/
#caster = new PointSourceRayCaster();

/** @override */
_createShapes() {
super._createShapes();

PointSourcePolygonConstraint.apply(this.shape, Limits.light);

if (game.release.version >= 13) {
const { x, y, elevation, radius } = this.data;
const z = elevation * canvas.dimensions.distancePixels;
const { left: minX, right: maxX, top: minY, bottom: maxY } = this.shape.bounds;
const space = Limits.light.crop(minX, minY, z - radius, maxX, maxY, z + radius);

this.#caster.initialize(space, x, y, z, 0.0, Infinity);
}
}

/** @override */
testPoint(point) {
return super.testPoint(point) && this.#caster.castRay(point.x, point.y, point.elevation * canvas.dimensions.distancePixels).targetHit;
}
};

Expand Down
31 changes: 28 additions & 3 deletions scripts/canvas/sources/sound.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,45 @@ export const PointSoundSourceMixin = (PointSoundSource) => class extends PointSo

PointSourcePolygonConstraint.apply(this.shape, Limits.sound);

const { x, y, elevation } = this.data;
const { x, y, elevation, radius } = this.data;
const z = elevation * canvas.dimensions.distancePixels;
const { left: minX, right: maxX, top: minY, bottom: maxY } = this.shape.bounds;
const space = Limits.sound.crop(minX, minY, z, maxX, maxY, z);

let minZ;
let maxZ;

if (game.release.version >= 13) {
minZ = z - radius;
maxZ = z + radius;
} else {
minZ = z;
maxZ = z;
}

const space = Limits.sound.crop(minX, minY, minZ, maxX, maxY, maxZ);

this.#caster.initialize(space, x, y, z, 0.0, Infinity);
}

/** @override */
testPoint(point) {
return super.testPoint(point) && this.#caster.castRay(point.x, point.y, point.elevation * canvas.dimensions.distancePixels).targetHit;
}

/** @override */
getVolumeMultiplier(listener, options) {
let volume = super.getVolumeMultiplier(listener, options);

if (volume > 0.0) {
volume *= this.#caster.castRay(listener.x, listener.y, this.#caster.ray.originZ).remainingEnergy;
let z;

if (game.release.version >= 13) {
z = listener.elevation * canvas.dimensions.distancePixels;
} else {
z = this.#caster.ray.originZ;
}

volume *= this.#caster.castRay(listener.x, listener.y, z).remainingEnergy;
}

return volume;
Expand Down
63 changes: 47 additions & 16 deletions scripts/canvas/sources/vision.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,75 @@ export const PointVisionSourceMixin = (PointVisionSource) => class extends Point
}
}

/** @override */
testPoint(point) {
return super.testPoint(point) && this.#getCaster().castRay(point.x, point.y, point.elevation * canvas.dimensions.distancePixels).targetHit;
}

/**
* Test whether the ray hits the target.
* @param {foundry.types.TokenDetectionMode} - The detection mode data.
* @param {{ x: number, y: number }} point - The target point.
* @param {number} elevation - The target elevation.
* @param {foundry.types.ElevatedPoint} point - The target point.
* @returns {boolean} Does the ray hit the target?
* @internal
*/
_testLimit(mode, point, elevation) {
const caster = this.#casters[mode.id];
_testLimit(mode, point) {
return this.#getCaster(mode).castRay(point.x, point.y, point.elevation * canvas.dimensions.distancePixels).targetHit;
}

/**
* Get the ray caster for this source.
* @overload
* @returns {PointSourceRayCaster} The ray caster.
*/
/**
* Get the ray caster for the given detection mode.
* @overload
* @param {foundry.types.TokenDetectionMode} - The detection mode data.
* @returns {PointSourceRayCaster} The ray caster.
*/
#getCaster(mode) {
const id = mode ? mode.id : "";
const caster = this.#casters[id];

if (!caster.initialized) {
const { x, y, elevation, externalRadius } = this.data;
const z = elevation * canvas.dimensions.distancePixels;
const radius = this.object.getLightRadius(mode.range);
let minX = x - radius;
let minY = y - radius;
let maxX = x + radius;
let maxY = y + radius;
const radius = mode ? this.object.getLightRadius(mode.range) : this.data.radius;
let bounds;

if (mode.id === "lightPerception") {
if (!mode) {
bounds = this.shape.bounds;
} else if (id === "lightPerception") {
bounds = this.los.bounds;
} else {
bounds = this.los.config.useInnerBounds ? canvas.dimensions.sceneRect : canvas.dimensions.rect;
}

minX = Math.max(minX, bounds.left);
minY = Math.max(minY, bounds.top);
maxX = Math.min(maxX, bounds.right);
maxY = Math.min(maxY, bounds.bottom);
let { left: minX, right: maxX, top: minY, bottom: maxY } = bounds;

minX = Math.max(minX, x - radius);
minY = Math.max(minY, y - radius);
maxX = Math.min(maxX, x + radius);
maxY = Math.min(maxY, y + radius);

let minZ;
let maxZ;

if (game.release.version >= 13) {
minZ = z - radius;
maxZ = z + radius;
} else {
minZ = -Infinity;
maxZ = Infinity;
}

const space = Limits.sight[mode.id].crop(minX, minY, -Infinity, maxX, maxY, Infinity);
const space = Limits.sight[id].crop(minX, minY, minZ, maxX, maxY, maxZ);

caster.initialize(space, x, y, z, externalRadius, Infinity);
}

return caster.castRay(point.x, point.y, elevation * canvas.dimensions.distancePixels).targetHit;
return caster;
}
};

Expand Down

0 comments on commit 637ba90

Please sign in to comment.