Skip to content

Commit

Permalink
10.4 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ironmonk88 committed Oct 9, 2022
1 parent c885d0f commit 6028658
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 58 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Version 10.4

Fixed issue when restoring a Terrain after it's been deleted when using Ctrl-Z.

Fixed issue finding data when the Measured Template has no flags set.

Addeed the option to set if you only want hostile creatures to cause difficult terrain.

Updated the API for calculating terrain cost.

Fixed issue with drawing shapes towards the upper left.

Fixed issue getting the correct shape data.

# Version 10.3

Fixed a spelling mistake in one of my fixes.
Expand Down
2 changes: 2 additions & 0 deletions classes/terraindocument.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ export class TerrainDocument extends CanvasDocumentMixin(BaseTerrain) {
let originals = [];
let created = [];
for (let terrain of data) {
if (terrain instanceof TerrainDocument)
terrain = terrain.toObject();
//update this object
// mergeObject(terrainDoc.data, data);
terrain._id = terrain._id || makeid();
Expand Down
91 changes: 47 additions & 44 deletions classes/terrainlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { PolygonTerrainInfo, TemplateTerrainInfo, TokenTerrainInfo } from './ter
import { makeid, log, debug, warn, error, i18n, setting, getflag } from '../terrain-main.js';
import EmbeddedCollection from "../../../common/abstract/embedded-collection.mjs";

export let environments = key => {
export let environments = (key) => {
return canvas.terrain.getEnvironments();
};

Expand Down Expand Up @@ -174,7 +174,7 @@ export class TerrainLayer extends PlaceablesLayer {
continue;
if (options.ignore?.includes(terrain.document.environment))
continue;
let reducers = options.reduce?.filter(e => e.id == terrain.document.environment || (useObstacles && e.id == terrain.document.obstacle));
let reducers = options.reduce?.filter((e) => e.id == terrain.document.environment || (useObstacles && e.id == terrain.document.obstacle));
terrainInfos.push(new PolygonTerrainInfo(terrain, reducers));
}
return terrainInfos;
Expand All @@ -186,7 +186,7 @@ export class TerrainLayer extends PlaceablesLayer {

const terrainInfos = options.list || [];
for (const template of canvas.templates.placeables) {
const terrainFlag = template.flags['enhanced-terrain-layer'];
const terrainFlag = getProperty(template, "flags.enhanced-terrain-layer");
if (!terrainFlag)
continue;
const terraincost = terrainFlag.multiple ?? 1;
Expand All @@ -200,7 +200,7 @@ export class TerrainLayer extends PlaceablesLayer {
continue;
if (options.ignore?.includes(environment))
continue;
let reducers = options.reduce?.filter(e => e.id == environment || (useObstacles && e.id == obstacle));
let reducers = options.reduce?.filter((e) => e.id == environment || (useObstacles && e.id == obstacle));
terrainInfos.push(new TemplateTerrainInfo(template, reducers));
}
return terrainInfos;
Expand All @@ -212,22 +212,28 @@ export class TerrainLayer extends PlaceablesLayer {
let isDead = options.isDead || function (token) {
return !!token.actor?.effects?.find(e => {
const core = e.flags["core"];
return core && core["statusId"] === CONFIG.specialStatusEffects.DEFEATED;
return (core && core["statusId"] === CONFIG.specialStatusEffects.DEFEATED);
});
}

if ((setting("tokens-cause-difficult") || setting("dead-cause-difficult")) && canvas.grid.type != CONST.GRID_TYPES.GRIDLESS && !options.ignore?.includes("tokens")) {
let tokenDifficult = setting("tokens-cause-difficult");
let tokenDead = setting("dead-cause-difficult");

if ((tokenDifficult != "false" || tokenDead != "false") && canvas.grid.type != CONST.GRID_TYPES.GRIDLESS && !options.ignore?.includes("tokens")) {
const elevation = this.calcElevationFromOptions(options);
const tokenId = options.tokenId || options?.token?.id;
for (const token of canvas.tokens.placeables) {
if (token.id == tokenId)
continue;
if (token.hidden)
continue;
if (elevation != undefined && token.elevation != elevation)
if (elevation != undefined && token.elevation != undefined && token.elevation != elevation)
continue;
let dead = isDead(token);
if ((setting("dead-cause-difficult") && dead) || (setting("tokens-cause-difficult") && !dead)) {
let checkValue = dead ? tokenDead : tokenDifficult;
if (checkValue == 'true' ||
(token.document.disposition == CONST.TOKEN_DISPOSITIONS.FRIENDLY && checkValue == "friendly") ||
(token.document.disposition != CONST.TOKEN_DISPOSITIONS.FRIENDLY && checkValue == "hostile")) {
let reducers = options.reduce?.filter(e => e.id == 'token')
terrainInfos.push(new TokenTerrainInfo(token, reducers));
}
Expand All @@ -241,12 +247,7 @@ export class TerrainLayer extends PlaceablesLayer {
return this.listTokenTerrain({ list: this.listMeasuredTerrain({ list: this.listTerrain(options), ...options }), ...options })
}

costWithTerrain(pts, terrain, options = {}) {
pts = pts instanceof Array ? pts : [pts];

const hx = (canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? 0 : canvas.dimensions.size / 2);
const hy = (canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? 0 : canvas.dimensions.size / 2);

calculateCombinedCost(terrain, options = {}) {
let calculate = options.calculate || 'maximum';
let calculateFn;
if (typeof calculate == 'function')
Expand All @@ -262,42 +263,37 @@ export class TerrainLayer extends PlaceablesLayer {
}
}

const details = [];
let total = 0;
for (const pt of pts) {
let cost = null;
const [gx, gy] = (canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? [pt.x, pt.y] : canvas.grid.grid.getPixelsFromGridPosition(pt.y, pt.x));
let total = null;
for (const terrainInfo of terrain) {
if (typeof calculateFn == 'function')
total = calculateFn(terrainInfo.cost, total, terrainInfo.object);
}
return total ?? 1;
}

const tx = (gx + hx);
const ty = (gy + hy);
costWithTerrain(pts, terrain, options = {}) {
const multipleResults = pts instanceof Array;
pts = multipleResults ? pts : [pts];

for (const terrainInfo of terrain) {
const testX = tx - terrainInfo.object.document.x;
const testY = ty - terrainInfo.object.document.y;
const hx = (canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? 0 : canvas.dimensions.size / 2);
const hy = (canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? 0 : canvas.dimensions.size / 2);

if (!terrainInfo.shape.contains(testX, testY))
continue;
const costs = [];
for (const pt of pts) {
const [gx, gy] = canvas.grid.type == CONST.GRID_TYPES.GRIDLESS || options.ignoreGrid === true ? [pt.x, pt.y] : canvas.grid.grid.getPixelsFromGridPosition(pt.y, pt.x);

const terraincost = terrainInfo.cost;
if (typeof calculateFn == 'function')
cost = calculateFn(terraincost, cost, terrainInfo.object);

const detail = {
cost: terrainInfo.rawCost,
object: terrainInfo.object,
reduce: terrainInfo.reducers,
total: cost,
};
details.push(detail);
}
const tx = gx + hx;
const ty = gy + hy;

total += (cost != undefined ? cost : 1);
terrain = terrain.filter((t) =>
t.shape.contains(tx - t.object.x, ty - t.object.y)
);
const cost = this.calculateCombinedCost(terrain, options);
costs.push(cost);
}

if (options.verbose === true)
return { cost: total, details: details, calculate: calculate };
else
return total;
if (multipleResults) return costs;
else return costs[0];
}

cost(pts, options = {}) {
Expand All @@ -320,6 +316,13 @@ export class TerrainLayer extends PlaceablesLayer {
return t.shape.contains(testX, testY);
});

const elevation = this.calcElevationFromOptions(options);
if (elevation !== null) {
terrains = terrains.filter(
(t) => (elevation) => t.bottom && elevation <= t.top
);
}

return terrains;
}

Expand Down Expand Up @@ -571,7 +574,7 @@ export class TerrainLayer extends PlaceablesLayer {

// Successful drawing completion
if (createState === 2) {
const distance = Math.hypot(destination.x - preview.x, destination.y - preview.y);
const distance = Math.hypot(preview.shape.width, preview.shape.height);
const minDistance = distance >= (canvas.dimensions.size / this.gridPrecision);
const completePolygon = preview.isPolygon && (preview.document.shape.points.length > 4);

Expand Down
13 changes: 7 additions & 6 deletions classes/terrainshape.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,20 @@ export class TerrainShape extends DrawingShape {
}

get _pixishape() {
let shape;
switch (this.document.shape.type) {
let { x, y, width, height, shape } = this.document;
let result;
switch (shape.type) {
case Drawing.SHAPE_TYPES.RECTANGLE:
shape = new PIXI.Rectangle(this.x, this.y, this.width, this.height);
result = new PIXI.Rectangle(0, 0, width, height);
break;
case Drawing.SHAPE_TYPES.ELLIPSE:
shape = new PIXI.Ellipse(this.x, this.y, this.width / 2, this.height / 2);
result = new PIXI.Ellipse(width / 2, height / 2, Math.max(Math.abs(width / 2), 0), Math.max(Math.abs(height / 2), 0));
break;
case Drawing.SHAPE_TYPES.POLYGON:
shape = new PIXI.Polygon(this.document.shape.points);
result = new PIXI.Polygon(shape.points);
break;
}
return shape;
return result;
}

contains(x, y) {
Expand Down
4 changes: 2 additions & 2 deletions js/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ Hooks.on('getSceneControlButtons', (controls) => {
{
name: "rect",
title: "CONTROLS.DrawingRect",
icon: "fa-solid fa-square"
icon: "fa-regular fa-square"
},
{
name: "ellipse",
title: "CONTROLS.DrawingEllipse",
icon: "fa-solid fa-circle"
icon: "fa-regular fa-circle"
},
{
name: "polygon",
Expand Down
17 changes: 13 additions & 4 deletions js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export const registerSettings = function () {
'clear': 'Clear'
};

let tokenoptions = {
'false': 'None',
'friendly': 'Friendly',
'hostile': 'Hostile',
'true': 'Any'
};

game.settings.registerMenu(modulename, 'edit-colors', {
name: 'Edit Colors',
label: 'Edit Colors',
Expand Down Expand Up @@ -100,16 +107,18 @@ export const registerSettings = function () {
hint: "EnhancedTerrainLayer.tokens-cause-difficult.hint",
scope: "world",
config: true,
default: false,
type: Boolean
choices: tokenoptions,
default: "false",
type: String
});
game.settings.register(modulename, 'dead-cause-difficult', {
name: "EnhancedTerrainLayer.dead-cause-difficult.name",
hint: "EnhancedTerrainLayer.dead-cause-difficult.hint",
scope: "world",
config: true,
default: false,
type: Boolean
choices: tokenoptions,
default: "false",
type: String
});
game.settings.register(modulename, 'use-obstacles', {
name: "EnhancedTerrainLayer.use-obstacles.name",
Expand Down
4 changes: 2 additions & 2 deletions module.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"title": "Enhanced Terrain Layer",
"description": "A base module that adds a Terrain Layer to Foundry. Used as a library for Rulers and other modules",
"version": "10.3",
"version": "10.4",
"authors": [
{
"name": "IronMonk",
Expand Down Expand Up @@ -47,7 +47,7 @@
"css/terrainlayer.css"
],
"url": "https://github.com/ironmonk88/enhanced-terrain-layer",
"download": "https://github.com/ironmonk88/enhanced-terrain-layer/archive/10.3.zip",
"download": "https://github.com/ironmonk88/enhanced-terrain-layer/archive/10.4.zip",
"manifest": "https://github.com/ironmonk88/enhanced-terrain-layer/releases/latest/download/module.json",
"bugs": "https://github.com/ironmonk88/enhanced-terrain-layer/issues",
"allowBugReporter": true,
Expand Down

0 comments on commit 6028658

Please sign in to comment.