Skip to content

Commit

Permalink
1.0.17 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
IronMonk88 committed Mar 30, 2021
1 parent 8275db9 commit f6ee885
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 13 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ You can also set blocks of Terrain to be shown or not shown, so if the difficult
For those who are developing Rulers based on the Enhanced Terrain Layer, to get access to the difficulty cost of terrain grid you call the cost function.
`canvas.terrrain.cost(pts, options);`
pts can be a single object {x: 0, y:0}, or an array of point objects.
options {elevation: 0, ignore:[]} lets the terrain layer know certain things about what you're asking for.
Passing in 'elevation' for the tokens elevation will ignore any difficult terrain caused by other tokens if the elevation is not the same.
Passing in an array of environments to ignore will cause the Terrain Layer to ignore any difficult terrain that has that environment label.
options {elevation: 0, reduce:[], tokenId: token.id, token:token} lets the terrain layer know certain things about what you're asking for.

- elevation: adding a value for elevation will ignore all terrain that is a ground type if the elevation is greater than 0 and ignore any air terrain if the elevation is less than or equal to 0. It will also ignore any tokens that aren't at the same elevation.
- reduce: [{id:'arctic',value:1}] will result in any calculation essentially ignoring arctic terrain. [{id:'arctic',value:'-1',stop:1}] will result in any calculation reducing the difficulty by 1 and stopping at 1. You can also use '+1' to add to the difficulty. stop is an optional parameter. And you can use the id 'token' to have these settings applied when calculating cost through another token's space.
- tokenId - pass in the token id to avoid having the result use the token's own space as difficult terrain.
- token - pass in the token, will use both the id and elevation of that token. passing in elevation:false will result in the the function ignoring the token's elevation.
- calculate - this is how you'd like the cost to be calculated. default is 'maximum', which returns the highest value found while looking through all terrains. you can also passin 'additive' if you want all costs to be added together.

if you'd like all the details of how the cost was acheived, call costDetails(pts, options). It will return the cost, and an array of details that combined to make the cost.

A list of Terrain Environments can be found by calling canvas.terrain.environment(); and can be overridden if the environments in your game differ.

Expand Down
86 changes: 76 additions & 10 deletions classes/terrainlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,45 @@ export class TerrainLayer extends PlaceablesLayer {
}

cost(pts, options = {}) {
let details = this.costDetails(pts, options);
return details.cost;
}

costDetails(pts, options = {}) {
let reduceFn = function (cost, reduce) {
let value = parseFloat(reduce.value);

if (typeof reduce.value == 'string' && (reduce.value.startsWith('+') || reduce.value.startsWith('-'))) {
value = cost + value;
if (reduce.stop) {
if (reduce.value.startsWith('+'))
value = Math.min(value, reduce.stop);
else
value = Math.max(value, reduce.stop);
}
}

return Math.max(value, 0);
}

let details = [];
let total = 0;
pts = pts instanceof Array ? pts : [pts];

const hx = canvas.grid.w / 2;
const hy = canvas.grid.h / 2;

let calculate = options.calculate || 'maximum';
let calculateFn = function (cost, total) { return cost; };
switch (calculate) {
case 'maximum':
calculateFn = function (cost, total) { return Math.max(cost, total); }; break;
case 'additive':
calculateFn = function (cost, total) { return cost + total; }; break;
}

for (let pt of pts) {
let cost = 0;
let cost = null;
let [gx, gy] = canvas.grid.grid.getPixelsFromGridPosition(pt.y, pt.x);

let elevation = (options.elevation === false ? null : (options.elevation != undefined ? options.elevation : options?.token?.data?.elevation));
Expand All @@ -98,24 +129,47 @@ export class TerrainLayer extends PlaceablesLayer {
!options.ignore?.includes(terrain.environment) &&
!((terrain.data.terraintype == 'ground' && elevation > 0) || (terrain.data.terraintype == 'air' && elevation <= 0)) &&
terrain.shape.contains(testX, testY)) {
cost = Math.max(terrain.cost(options), cost);
if (cost > 1 && options.reduce?.includes(terrain.environment)) {cost -= 1};
let detail = {object:terrain};
let terraincost = terrain.cost(options);
detail.cost = terraincost;

let reduce = options.reduce?.find(e => e.id == terrain.environment);
if (reduce) {
detail.reduce = reduce;
terraincost = reduceFn(terraincost, reduce);
}
cost = calculateFn(terraincost, cost);
detail.total = cost;

details.push(detail);

}
}

//get the cost for any measured templates, ie spells
for (let measure of canvas.templates.placeables) {
const testX = (gx + hx) - measure.data.x;
const testY = (gy + hy) - measure.data.y;
let measMult = measure.getFlag('enhanced-terrain-layer', 'multiple');
let terraincost = measure.getFlag('enhanced-terrain-layer', 'multiple');
let measType = measure.getFlag('enhanced-terrain-layer', 'terraintype') || 'ground';
let measEnv = measure.getFlag('enhanced-terrain-layer', 'environment') || '';
if (measMult &&
if (terraincost &&
!options.ignore?.includes(measEnv) &&
!((measType == 'ground' && elevation > 0) || (measType == 'air' && elevation <= 0)) &&
measure.shape.contains(testX, testY)) {
cost = Math.max(measMult, cost);
if (cost > 1 && options.reduce?.includes(measEnv)) {cost -= 1};

let detail = { object: measure, cost: terraincost };
let reduce = options.reduce?.find(e => e.id == measEnv);
if (reduce) {
detail.reduce = reduce;
terraincost = reduceFn(terraincost, reduce);
}

cost = calculateFn(terraincost, cost);
detail.total = cost;

details.push(detail);

}
}

Expand All @@ -126,16 +180,28 @@ export class TerrainLayer extends PlaceablesLayer {
const testX = (gx + hx);
const testY = (gy + hy);
if (!(testX < token.data.x || testX > token.data.x + (token.data.width * canvas.grid.w) || testY < token.data.y || testY > token.data.y + (token.data.height * canvas.grid.h))) {
cost = Math.max(2, cost);
let terraincost = 2;
let detail = { object: token, cost: terraincost };

let reduce = options.reduce?.find(e => e.id == 'token');
if (reduce) {
detail.reduce = reduce;
terraincost = reduceFn(terraincost, reduce);
}

cost = calculateFn(terraincost, cost);
detail.total = cost;

details.push(detail);
}
}
}
}

total += cost || 1;
total += (cost != undefined ? cost : 1);
}

return total;
return { cost: total, details: details, calculate: calculate };
}

terrainAt(x, y) {
Expand Down

0 comments on commit f6ee885

Please sign in to comment.