import { injectConfig } from "./lib/injectConfig.js";
|
|
import { TileHandler } from "./handlers/tileHandler.js";
|
|
import { RefreshHandler } from "./handlers/refreshHandler.js";
|
|
import { DrawingHandler } from "./handlers/drawingHandler.js";
|
|
import { UIHandler } from "./handlers/uiHandler.js";
|
|
import { SightHandler } from "./handlers/sightHandler.js";
|
|
import { LightHandler } from "./handlers/lightHandler.js";
|
|
import { SoundHandler } from "./handlers/soundHandler.js";
|
|
import { NoteHandler } from "./handlers/noteHandler.js";
|
|
import { TokenHandler } from "./handlers/tokenHandler.js";
|
|
import { TemplateHandler } from "./handlers/templateHandler.js";
|
|
import { FoWHandler } from "./handlers/fowHandler.js";
|
|
import { BackgroundHandler } from "./handlers/backgroundHandler.js";
|
|
import { SettingsHandler } from "./handlers/settingsHandler.js";
|
|
import { LevelsAPI } from "./API.js";
|
|
import { registerWrappers } from "./wrappers.js";
|
|
import { inRange, getRangeForDocument, cloneTileMesh, inDistance } from "./helpers.js";
|
|
import { setupWarnings } from "./warnings.js";
|
|
|
|
//warnings
|
|
|
|
Hooks.on("ready", () => {
|
|
if (!game.user.isGM) return;
|
|
|
|
setupWarnings();
|
|
|
|
const recommendedVersion = "10.291";
|
|
|
|
if (isNewerVersion(recommendedVersion, game.version)) {
|
|
ui.notifications.error(`Levels recommends Foundry VTT version ${recommendedVersion} or newer. Levels might not work as expected in the currently installed version (${game.version}).`, { permanent: true });
|
|
return;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(globalThis, "_levels", {
|
|
get: () => {
|
|
console.warn("Levels: _levels is deprecated. Use CONFIG.Levels.API instead.");
|
|
return CONFIG.Levels.API;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(TileDocument.prototype, "elevation", {
|
|
get: function () {
|
|
if (CONFIG.Levels?.UI?.rangeEnabled && !this.id) {
|
|
return parseFloat(CONFIG.Levels.UI.range[0] || 0);
|
|
}
|
|
return this.overhead ? this.flags?.levels?.rangeBottom ?? canvas.scene.foregroundElevation : canvas.primary.background.elevation;
|
|
},
|
|
});
|
|
|
|
Tile.prototype.inTriggeringRange = function (token) {
|
|
const bottom = this.document.elevation;
|
|
let top = this.document.flags?.levels?.rangeTop ?? Infinity;
|
|
if (game.Levels3DPreview?._active) {
|
|
const depth = this.document.flags?.["levels-3d-preview"]?.depth;
|
|
if (depth) top = bottom + (depth / canvas.scene.dimensions.size) * canvas.scene.dimensions.distance;
|
|
}
|
|
if (token) {
|
|
return token.document.elevation >= bottom && token.document.elevation <= top;
|
|
} else {
|
|
return { bottom, top };
|
|
}
|
|
};
|
|
|
|
Object.defineProperty(DrawingDocument.prototype, "elevation", {
|
|
get: function () {
|
|
if (CONFIG.Levels?.UI?.rangeEnabled && !this.id) {
|
|
return parseFloat(CONFIG.Levels.UI.range[0] || 0);
|
|
}
|
|
return this.flags?.levels?.rangeBottom ?? canvas.primary.background.elevation;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(NoteDocument.prototype, "elevation", {
|
|
get: function () {
|
|
return this.flags?.levels?.rangeBottom ?? canvas.primary.background.elevation;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(AmbientLightDocument.prototype, "elevation", {
|
|
get: function () {
|
|
if (CONFIG.Levels.UI.rangeEnabled && !this.id) {
|
|
return parseFloat(CONFIG.Levels.UI.range[0] || 0);
|
|
}
|
|
return this.flags?.levels?.rangeBottom ?? canvas.primary.background.elevation;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(AmbientSoundDocument.prototype, "elevation", {
|
|
get: function () {
|
|
if (CONFIG.Levels.UI.rangeEnabled && !this.id) {
|
|
return parseFloat(CONFIG.Levels.UI.range[0] || 0);
|
|
}
|
|
if (isNaN(this.flags?.levels?.rangeBottom)) return canvas.primary.background.elevation;
|
|
return (this.flags?.levels?.rangeBottom + (this.flags?.levels?.rangeTop ?? this.flags?.levels?.rangeBottom)) / 2;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(MeasuredTemplateDocument.prototype, "elevation", {
|
|
get: function () {
|
|
return this.flags?.levels?.elevation ?? canvas.primary.background.elevation;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(WeatherEffects.prototype, "elevation", {
|
|
get: function () {
|
|
return canvas?.scene?.flags?.levels?.weatherElevation ?? Infinity;
|
|
},
|
|
set: function (value) {
|
|
console.error("Cannot set elevation on WeatherEffects. Levels overrides WeatherEffects.prototype.elevation core behaviour. If you wish to set the WeatherEffects elevation, use SceneDocument.flags.levels.weatherElevation");
|
|
},
|
|
});
|
|
|
|
Hooks.on("init", () => {
|
|
const canvas3d = game.modules.get("levels-3d-preview")?.active;
|
|
|
|
CONFIG.Levels = {
|
|
MODULE_ID: "levels",
|
|
};
|
|
|
|
Object.defineProperty(CONFIG.Levels, "useCollision3D", {
|
|
get: function () {
|
|
return canvas3d && canvas.scene.flags["levels-3d-preview"]?.object3dSight;
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(CONFIG.Levels, "currentToken", {
|
|
get: function () {
|
|
return this._currentToken;
|
|
},
|
|
set: function (value) {
|
|
this._currentToken = value;
|
|
Hooks.callAll("levelsPerspectiveChanged", this._currentToken);
|
|
},
|
|
});
|
|
|
|
CONFIG.Levels.handlers = {
|
|
TileHandler,
|
|
RefreshHandler,
|
|
DrawingHandler,
|
|
UIHandler,
|
|
SightHandler,
|
|
LightHandler,
|
|
SoundHandler,
|
|
NoteHandler,
|
|
TokenHandler,
|
|
TemplateHandler,
|
|
FoWHandler,
|
|
BackgroundHandler,
|
|
SettingsHandler,
|
|
};
|
|
|
|
CONFIG.Levels.helpers = {
|
|
inRange,
|
|
getRangeForDocument,
|
|
cloneTileMesh,
|
|
inDistance,
|
|
};
|
|
|
|
CONFIG.Levels.API = LevelsAPI;
|
|
|
|
CONFIG.Levels.UI = new LevelsUI();
|
|
|
|
CONFIG.Levels.settings = new SettingsHandler();
|
|
|
|
Hooks.callAll("levelsInit", CONFIG.Levels);
|
|
|
|
registerWrappers();
|
|
|
|
CONFIG.Levels.FoWHandler = new FoWHandler();
|
|
CONFIG.Levels.handlers.BackgroundHandler.setupElevation();
|
|
|
|
Hooks.callAll("levelsReady", CONFIG.Levels);
|
|
});
|
|
|
|
Hooks.once("ready", () => {
|
|
if (game.modules.get("levels-3d-preview")?.active) return;
|
|
// Module title
|
|
const MODULE_ID = CONFIG.Levels.MODULE_ID;
|
|
const MODULE_TITLE = game.modules.get(MODULE_ID).title;
|
|
|
|
const FALLBACK_MESSAGE_TITLE = MODULE_TITLE;
|
|
const FALLBACK_MESSAGE = `<large>
|
|
<p><strong>This module may be very complicated for a first timer, be sure to stop by my <a href="https://theripper93.com/">Discord</a> for help and support from the wonderful community as well as many resources</strong></p>
|
|
|
|
<p>Thanks to all the patreons supporting the development of this module making continued updates possible!</p>
|
|
<p>If you want to support the development of the module or get customized support in setting up your maps you can do so here : <a href="https://www.patreon.com/theripper93">Patreon</a> </p></large>
|
|
<p><strong>Patreons</strong> get also access to <strong>15+ premium modules</strong></p>
|
|
<p>Is Levels not enough? Go Full 3D</p>
|
|
<h1>3D Canvas</h1>
|
|
<iframe width="385" height="225" src="https://www.youtube.com/embed/hC1QGZFUhcU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
<p>Check 3D Canvas and all my other <strong>15+ premium modules <a href="https://theripper93.com/">Here</a></strong></p>
|
|
<p>Special thanks to Baileywiki for the support and feedback and Blair for the amazing UI elements</p>`;
|
|
|
|
// Settings key used for the "Don't remind me again" setting
|
|
const DONT_REMIND_AGAIN_KEY = "popup-dont-remind-again-2";
|
|
|
|
// Dialog code
|
|
game.settings.register(MODULE_ID, DONT_REMIND_AGAIN_KEY, {
|
|
name: "",
|
|
default: false,
|
|
type: Boolean,
|
|
scope: "world",
|
|
config: false,
|
|
});
|
|
if (game.user.isGM && !game.settings.get(MODULE_ID, DONT_REMIND_AGAIN_KEY)) {
|
|
new Dialog({
|
|
title: FALLBACK_MESSAGE_TITLE,
|
|
content: FALLBACK_MESSAGE,
|
|
buttons: {
|
|
ok: { icon: '<i class="fas fa-check"></i>', label: "Understood" },
|
|
dont_remind: {
|
|
icon: '<i class="fas fa-times"></i>',
|
|
label: "Don't remind me again",
|
|
callback: () => game.settings.set(MODULE_ID, DONT_REMIND_AGAIN_KEY, true),
|
|
},
|
|
},
|
|
}).render(true);
|
|
}
|
|
});
|
|
|
|
Hooks.on("init", () => {
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "tokenElevScale", {
|
|
name: game.i18n.localize("levels.settings.tokenElevScale.name"),
|
|
hint: game.i18n.localize("levels.settings.tokenElevScale.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: false,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "tokenElevScaleMultiSett", {
|
|
name: game.i18n.localize("levels.settings.tokenElevScaleMultiSett.name"),
|
|
hint: game.i18n.localize("levels.settings.tokenElevScaleMultiSett.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Number,
|
|
range: {
|
|
min: 0.1,
|
|
max: 2,
|
|
step: 0.1,
|
|
},
|
|
default: 1,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "fogHiding", {
|
|
name: game.i18n.localize("levels.settings.fogHiding.name"),
|
|
hint: game.i18n.localize("levels.settings.fogHiding.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: true,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "revealTokenInFog", {
|
|
name: game.i18n.localize("levels.settings.revealTokenInFog.name"),
|
|
hint: game.i18n.localize("levels.settings.revealTokenInFog.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: false,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "lockElevation", {
|
|
name: game.i18n.localize("levels.settings.lockElevation.name"),
|
|
hint: game.i18n.localize("levels.settings.lockElevation.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: false,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "hideElevation", {
|
|
name: game.i18n.localize("levels.settings.hideElevation.name"),
|
|
hint: game.i18n.localize("levels.settings.hideElevation.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Number,
|
|
choices: {
|
|
0: game.i18n.localize("levels.settings.hideElevation.opt0"),
|
|
1: game.i18n.localize("levels.settings.hideElevation.opt1"),
|
|
2: game.i18n.localize("levels.settings.hideElevation.opt2"),
|
|
},
|
|
default: 0,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "enableTooltips", {
|
|
name: game.i18n.localize("levels.settings.enableTooltips.name"),
|
|
hint: game.i18n.localize("levels.settings.enableTooltips.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: false,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "preciseTokenVisibility", {
|
|
name: game.i18n.localize("levels.settings.preciseTokenVisibility.name"),
|
|
hint: game.i18n.localize("levels.settings.preciseTokenVisibility.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: true,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
|
|
game.settings.register(CONFIG.Levels.MODULE_ID, "exactTokenVisibility", {
|
|
name: game.i18n.localize("levels.settings.exactTokenVisibility.name"),
|
|
hint: game.i18n.localize("levels.settings.exactTokenVisibility.hint"),
|
|
scope: "world",
|
|
config: true,
|
|
type: Boolean,
|
|
default: false,
|
|
onChange: () => {
|
|
CONFIG.Levels.settings.cacheSettings();
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("updateTile", (tile, updates) => {
|
|
if (updates?.flags?.levels?.allWallBlockSight !== undefined) {
|
|
canvas.walls.placeables.forEach((w) => w.identifyInteriorState());
|
|
WallHeight.schedulePerceptionUpdate();
|
|
}
|
|
});
|
|
|
|
Hooks.on("renderTileConfig", (app, html, data) => {
|
|
const isInjected = html.find(`input[name="flags.${CONFIG.Levels.MODULE_ID}.rangeTop"]`).length > 0;
|
|
if (isInjected) return;
|
|
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
tab: {
|
|
name: "levels",
|
|
label: "Levels",
|
|
icon: "fas fa-layer-group",
|
|
},
|
|
rangeTop: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeTop.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
step: "any",
|
|
},
|
|
rangeBottom: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeBottom.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "-Infinity",
|
|
step: "any",
|
|
},
|
|
showIfAbove: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.tileconfig.showIfAbove.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.showIfAbove.hint"),
|
|
},
|
|
showAboveRange: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.showAboveRange.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.showAboveRange.hint"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
},
|
|
noCollision: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.tileconfig.noCollision.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.noCollision.hint"),
|
|
},
|
|
noFogHide: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.tileconfig.noFogHide.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.noFogHide.hint"),
|
|
},
|
|
isBasement: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.tileconfig.isBasement.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.isBasement.hint"),
|
|
},
|
|
allWallBlockSight: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.tileconfig.allWallBlockSight.name"),
|
|
notes: game.i18n.localize("levels.tileconfig.allWallBlockSight.hint"),
|
|
default: true,
|
|
},
|
|
});
|
|
injHtml.find(`input[name="flags.${CONFIG.Levels.MODULE_ID}.rangeTop"]`).closest(".form-group").before(`
|
|
<p class="notes" style="color: red" id="no-overhead-warning">${game.i18n.localize("levels.tileconfig.noOverhead")}</>
|
|
<p class="notes" style="color: red" id="occlusion-none-warning">${game.i18n.localize("levels.tileconfig.occlusionNone")}</>
|
|
`);
|
|
html.on("change", "input", (e) => {
|
|
const isOverhead = html.find(`input[name="overhead"]`).is(":checked");
|
|
const occlusionMode = html.find(`select[name="occlusion.mode"]`).val();
|
|
const isShowIfAbove = injHtml.find(`input[name="flags.levels.showIfAbove"]`).is(":checked");
|
|
injHtml.find("input").prop("disabled", !isOverhead);
|
|
injHtml.find("input[name='flags.levels.showAboveRange']").closest(".form-group").toggle(isShowIfAbove);
|
|
html.find("#no-overhead-warning").toggle(!isOverhead);
|
|
html.find("#occlusion-none-warning").toggle(occlusionMode == 0);
|
|
app.setPosition({ height: "auto" });
|
|
});
|
|
html.find(`input[name="overhead"]`).trigger("change");
|
|
app.setPosition({ height: "auto" });
|
|
});
|
|
|
|
Hooks.on("renderAmbientLightConfig", (app, html, data) => {
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="config.dim"]',
|
|
rangeTop: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeTop.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
step: "any",
|
|
},
|
|
rangeBottom: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeBottom.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "-Infinity",
|
|
step: "any",
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderNoteConfig", (app, html, data) => {
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'select[name="textAnchor"]',
|
|
rangeTop: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeTop.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
step: "any",
|
|
},
|
|
rangeBottom: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeBottom.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "-Infinity",
|
|
step: "any",
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderAmbientSoundConfig", (app, html, data) => {
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="radius"]',
|
|
rangeTop: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeTop.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
step: "any",
|
|
},
|
|
rangeBottom: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeBottom.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "-Infinity",
|
|
step: "any",
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderDrawingConfig", (app, html, data) => {
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="z"]',
|
|
drawingMode: {
|
|
type: "select",
|
|
label: game.i18n.localize("levels.drawingconfig.isHole.name"),
|
|
default: 0,
|
|
dType: "Number",
|
|
options: {
|
|
0: game.i18n.localize("levels.drawingconfig.isHole.opt0"),
|
|
2: game.i18n.localize("levels.drawingconfig.isHole.opt2"),
|
|
21: game.i18n.localize("levels.drawingconfig.isHole.opt21"),
|
|
22: game.i18n.localize("levels.drawingconfig.isHole.opt22"),
|
|
3: game.i18n.localize("levels.drawingconfig.isHole.opt3"),
|
|
},
|
|
},
|
|
elevatorFloors: {
|
|
type: "text",
|
|
label: game.i18n.localize("levels.drawingconfig.elevatorFloors.name"),
|
|
notes: game.i18n.localize("levels.drawingconfig.elevatorFloors.hint"),
|
|
},
|
|
rangeTop: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeTop.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
step: "any",
|
|
},
|
|
rangeBottom: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.tileconfig.rangeBottom.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: "",
|
|
placeholder: "-Infinity",
|
|
step: "any",
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderMeasuredTemplateConfig", (app, html, data) => {
|
|
const injHtml = injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="width"]',
|
|
elevation: {
|
|
type: "text",
|
|
dType: "Number",
|
|
label: game.i18n.localize("levels.template.elevation.name"),
|
|
units: game.i18n.localize("levels.tileconfig.range.unit"),
|
|
default: Infinity,
|
|
step: "any",
|
|
},
|
|
special: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.template.depth.name"),
|
|
default: 0,
|
|
dType: "Number",
|
|
},
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderDrawingHUD", (data, hud, drawData) => {
|
|
let drawing = data.object.document;
|
|
if (drawing.getFlag(CONFIG.Levels.MODULE_ID, "drawingMode")) {
|
|
let active = drawing.getFlag(CONFIG.Levels.MODULE_ID, "stairLocked") || false;
|
|
let toggleStairbtn = `<div class="control-icon${active ? " active" : ""}" id="toggleStair">
|
|
<i class="fas fa-lock" width="36" height="36" title='${game.i18n.localize("levels.drawingHud.title")}'></i>
|
|
</div>`;
|
|
const controlIcons = hud.find("div.control-icon");
|
|
controlIcons.last().after(toggleStairbtn);
|
|
$(hud.find(`div[id="toggleStair"]`)).on("click", test);
|
|
function test() {
|
|
console.log("test");
|
|
active = !active;
|
|
drawing.setFlag(CONFIG.Levels.MODULE_ID, "stairLocked", !(drawing.getFlag(CONFIG.Levels.MODULE_ID, "stairLocked") || false));
|
|
let hudbtn = hud.find(`div[id="toggleStair"]`);
|
|
if (active) hudbtn.addClass("active");
|
|
else hudbtn.removeClass("active");
|
|
}
|
|
}
|
|
});
|
|
|
|
Hooks.on("renderTokenHUD", (data, hud, drawData) => {
|
|
if (CONFIG.Levels.settings.get("lockElevation") && !game.user.isGM) {
|
|
const controlIcons = hud.find(`div[class="attribute elevation"]`);
|
|
$(controlIcons[0]).remove();
|
|
}
|
|
});
|
|
|
|
Hooks.on("preCreateMeasuredTemplate", (template) => {
|
|
const templateData = CONFIG.Levels.handlers.TemplateHandler.getTemplateData();
|
|
if (template.flags?.levels?.elevation) return;
|
|
template.updateSource({
|
|
flags: { levels: { elevation: templateData.elevation, special: templateData.special } },
|
|
});
|
|
});
|
|
|
|
Hooks.on("renderSceneConfig", (app, html, data) => {
|
|
injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="foregroundElevation"]',
|
|
backgroundElevation: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.sceneconfig.backgroundElevation.name"),
|
|
notes: game.i18n.localize("levels.sceneconfig.backgroundElevation.notes"),
|
|
default: 0,
|
|
},
|
|
});
|
|
|
|
injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'select[name="weather"]',
|
|
weatherElevation: {
|
|
type: "number",
|
|
label: game.i18n.localize("levels.sceneconfig.weatherElevation.name"),
|
|
notes: game.i18n.localize("levels.sceneconfig.weatherElevation.notes"),
|
|
default: "",
|
|
placeholder: "Infinity",
|
|
},
|
|
});
|
|
|
|
injectConfig.inject(app, html, {
|
|
moduleId: "levels",
|
|
inject: 'input[name="fogExploration"]',
|
|
lightMasking: {
|
|
type: "checkbox",
|
|
label: game.i18n.localize("levels.sceneconfig.lightMasking.name"),
|
|
notes: game.i18n.localize("levels.sceneconfig.lightMasking.notes"),
|
|
default: true,
|
|
},
|
|
});
|
|
});
|