diff --git a/index.html b/index.html
index 7475ee752..72eedf3de 100644
--- a/index.html
+++ b/index.html
@@ -365,7 +365,6 @@
data-tip="Click to show the Menu"
data-shortcut="Tab"
class="options glow"
- onclick="showOptions(event)"
>
►
@@ -391,7 +390,6 @@
data-tip="Click to hide the Menu"
data-shortcut="Tab or Esc"
class="options"
- onclick="hideOptions(event)"
>
◄
@@ -7657,8 +7655,8 @@
-
+
diff --git a/src/dialogs/dialogs/ice-editor.ts b/src/dialogs/dialogs/ice-editor.ts
index f944560f7..210a188f7 100644
--- a/src/dialogs/dialogs/ice-editor.ts
+++ b/src/dialogs/dialogs/ice-editor.ts
@@ -21,7 +21,7 @@ export function open() {
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
if (byId("iceRandomize")) byId("iceRandomize")!.style.display = type === "Glacier" ? "none" : "inline-block";
- const $iceSize = byId("iceSize") as HTMLInputElement;
+ const $iceSize = byId<'input'>("iceSize");
if ($iceSize) {
$iceSize.style.display = type === "Glacier" ? "none" : "inline-block";
if (type === "Iceberg") $iceSize.value = elSelected.attr("size");
@@ -39,11 +39,11 @@ export function open() {
isLoaded = true;
// add listeners
- byId("iceEditStyle")?.on("click", () => editStyle("ice"));
- byId("iceRandomize")?.on("click", randomizeShape);
- byId("iceSize")?.on("input", changeSize);
- byId("iceNew")?.on("click", toggleAdd);
- byId("iceRemove")?.on("click", removeIce);
+ byId("iceEditStyle").on("click", () => editStyle("ice"));
+ byId("iceRandomize").on("click", randomizeShape);
+ byId("iceSize").on("input", changeSize);
+ byId("iceNew").on("click", toggleAdd);
+ byId("iceRemove").on("click", removeIce);
function randomizeShape() {
const c = grid.points[+elSelected.attr("cell")];
diff --git a/src/layers/renderers/drawIce.js b/src/layers/renderers/drawIce.js
deleted file mode 100644
index 3755b8cf1..000000000
--- a/src/layers/renderers/drawIce.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import {getGridPolygon} from "utils/graphUtils";
-import {aleaPRNG} from "scripts/aleaPRNG";
-import {clipPoly} from "utils/lineUtils";
-
-export function drawIce() {
- const {cells, vertices} = grid;
- const {temp, h} = cells;
- const n = cells.i.length;
-
- const used = new Uint8Array(cells.i.length);
- Math.random = aleaPRNG(seed);
-
- const shieldMin = -8; // max temp to form ice shield (glacier)
- const icebergMax = 1; // max temp to form an iceberg
-
- for (const i of grid.cells.i) {
- const t = temp[i];
- if (t > icebergMax) continue; // too warm: no ice
- if (t > shieldMin && h[i] >= 20) continue; // non-glacier land: no ice
-
- if (t <= shieldMin) {
- // very cold: ice shield
- if (used[i]) continue; // already rendered
- const onborder = cells.c[i].some(n => temp[n] > shieldMin);
- if (!onborder) continue; // need to start from onborder cell
- const vertex = cells.v[i].find(v => vertices.c[v].some(i => temp[i] > shieldMin));
- const chain = connectVertices(vertex);
- if (chain.length < 3) continue;
- const points = clipPoly(chain.map(v => vertices.p[v]));
- ice.append("polygon").attr("points", points).attr("type", "iceShield");
- continue;
- }
-
- // mildly cold: iceberd
- if (P(normalize(t, -7, 2.5))) continue; // t[-5; 2] cold: skip some cells
- if (grid.features[cells.f[i]].type === "lake") continue; // lake: no icebers
- let size = (6.5 + t) / 10; // iceberg size: 0 = full size, 1 = zero size
- if (cells.t[i] === -1) size *= 1.3; // coasline: smaller icebers
- size = Math.min(size * (0.4 + Math.random() * 1.2), 0.95); // randomize iceberg size
- resizePolygon(i, size);
- }
-
- function resizePolygon(i, s) {
- const c = grid.points[i];
- const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) * s) | 0, (p[1] + (c[1] - p[1]) * s) | 0]);
- ice
- .append("polygon")
- .attr("points", points)
- .attr("cell", i)
- .attr("size", rn(1 - s, 2));
- }
-
- // connect vertices to chain
- function connectVertices(start) {
- const chain = []; // vertices chain to form a path
- for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
- const prev = last(chain); // previous vertex in chain
- chain.push(current); // add current vertex to sequence
- const c = vertices.c[current]; // cells adjacent to vertex
- c.filter(c => temp[c] <= shieldMin).forEach(c => (used[c] = 1));
- const c0 = c[0] >= n || temp[c[0]] > shieldMin;
- const c1 = c[1] >= n || temp[c[1]] > shieldMin;
- const c2 = c[2] >= n || temp[c[2]] > shieldMin;
- const v = vertices.v[current]; // neighboring vertices
- if (v[0] !== prev && c0 !== c1) current = v[0];
- else if (v[1] !== prev && c1 !== c2) current = v[1];
- else if (v[2] !== prev && c0 !== c2) current = v[2];
- if (current === chain[chain.length - 1]) {
- ERROR && console.error("Next vertex is not found");
- break;
- }
- }
- return chain;
- }
-}
diff --git a/src/layers/renderers/drawIce.ts b/src/layers/renderers/drawIce.ts
new file mode 100644
index 000000000..c1251b7db
--- /dev/null
+++ b/src/layers/renderers/drawIce.ts
@@ -0,0 +1,16 @@
+import { byId } from "utils/nodeUtils";
+
+export function drawIce() {
+ const ice = byId("ice");
+ const { ice: icePack } = pack;
+
+ let innerHTML = "";
+ for (const shield of icePack.iceShields) {
+ innerHTML += ``;
+ }
+
+ for (const iceberg of icePack.icebergs) {
+ innerHTML += ``;
+ }
+ ice.innerHTML = innerHTML;
+}
diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts
index 5bd21b92b..21b915c3d 100644
--- a/src/modules/ui/options.ts
+++ b/src/modules/ui/options.ts
@@ -32,7 +32,8 @@ byId<'button'>("optionsTrigger").on("click", showOptions);
byId<'button'>("optionsHide").on("click", hideOptions);
// Window Objects
-const {Zoom, COA, Cloud, ThreeD, Names} = window;
+const {COA, Cloud, ThreeD, Names, Zoom} = window;
+
// DIV elements
const tooltip = byId<'div'>("tooltip");
@@ -40,7 +41,8 @@ const tooltip = byId<'div'>("tooltip");
// Options pane elements
const optionsTrigger = byId<'button'>("optionsTrigger");
const regenerate = byId<'button'>("regenerate");
-const optionsDiv = byId<'div'>("optionsContainer");
+const optionsContainer = byId<'div'>("optionsContainer");
+const optionsDisplay = byId<'div'>("options");
const collapsible = byId<'div'>("collapsible");
const layersContent = byId<'div'>("layersContent");
const styleContent = byId<'div'>("styleContent");
@@ -140,7 +142,7 @@ export function showOptions(event: Event) {
}
regenerate.style.display = "none";
- optionsDiv.style.display = "block";
+ optionsDisplay.style.display = "block";
optionsTrigger.style.display = "none";
if (event) event.stopPropagation();
@@ -148,21 +150,21 @@ export function showOptions(event: Event) {
// Hide options pane on trigger click
export function hideOptions(event: Event) {
- optionsDiv.style.display = "none";
+ optionsDisplay.style.display = "none";
optionsTrigger.style.display = "block";
if (event) event.stopPropagation();
}
// To toggle options on hotkey press
export function toggleOptions(event: MouseEvent) {
- if (optionsDiv.style.display === "none") showOptions(event);
+ if (optionsContainer.style.display === "none") showOptions(event);
else hideOptions(event);
}
// Toggle "New Map!" pane on hover
optionsTrigger.on("mouseenter", function () {
if (optionsTrigger.classList.contains("glow")) return;
- if (optionsDiv.style.display === "none") regenerate.style.display = "block";
+ if (optionsContainer.style.display === "none") regenerate.style.display = "block";
});
collapsible.on("mouseleave", function () {
@@ -170,17 +172,17 @@ collapsible.on("mouseleave", function () {
});
// Activate options tab on click
-optionsDiv
+optionsContainer
.querySelector("div.tab")!
.on("click", function (event: any ) { // MARKER: any
if (event.target.tagName !== "BUTTON") return;
const id = event.target.id;
- const active = optionsDiv.querySelector(".tab > button.active");
+ const active = optionsContainer.querySelector(".tab > button.active");
if (active && id === active.id) return; // already active tab is clicked
if (active) active.classList.remove("active");
- byId(id)!.classList.add("active");
- optionsDiv
+ byId(id).classList.add("active");
+ optionsContainer
.querySelectorAll(".tabcontent")
.forEach((e: HTMLElement) => {e.style.display = "none"});
@@ -207,9 +209,9 @@ async function showSupporters() {
}
// on any option or dialog change
-optionsDiv.on("change", storeValueIfRequired);
+optionsContainer.on("change", storeValueIfRequired);
dialogDiv.on("change", storeValueIfRequired);
-optionsDiv.on("input", updateOutputToFollowInput);
+optionsContainer.on("input", updateOutputToFollowInput);
dialogDiv.on("input", updateOutputToFollowInput);
function storeValueIfRequired(ev: any) { // MARKER: any
@@ -320,10 +322,10 @@ function changeMapSize() {
// just apply canvas size that was already set
export function applyMapSize() {
- const zoomMin = Number(zoomExtentMin.value);
- const zoomMax = Number(zoomExtentMax.value);
- graphWidth = Number(mapWidthInput.value);
- graphHeight = Number(mapHeightInput.value);
+ const zoomMin = zoomExtentMin.valueAsNumber;
+ const zoomMax = zoomExtentMax.valueAsNumber;
+ graphWidth = mapWidthInput.valueAsNumber;
+ graphHeight = mapHeightInput.valueAsNumber;
svgWidth = Math.min(graphWidth, window.innerWidth);
svgHeight = Math.min(graphHeight, window.innerHeight);
svg.attr("width", svgWidth).attr("height", svgHeight);
@@ -537,7 +539,7 @@ function changeUIsize(value: number) {
uiSizeInput.valueAsNumber = uiSizeOutput.valueAsNumber = value;
document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px";
- optionsDiv.style.width = value * 300 + "px";
+ optionsContainer.style.width = value * 300 + "px";
}
function getUImaxSize() {
@@ -1126,7 +1128,7 @@ async function enter3dView(type) {
resizeStop: resize3d,
close: enterStandardView
});
- } else document.body.insertBefore(canvas, optionsDiv);
+ } else document.body.insertBefore(canvas, optionsContainer);
toggle3dOptions();
}
diff --git a/src/scripts/generation/pack/generateIce.ts b/src/scripts/generation/pack/generateIce.ts
new file mode 100644
index 000000000..5947c16f8
--- /dev/null
+++ b/src/scripts/generation/pack/generateIce.ts
@@ -0,0 +1,101 @@
+import { ERROR } from "config/logging";
+import { aleaPRNG } from "scripts/aleaPRNG";
+import { clipPoly, getGridPolygonLocal, last, normalize, P, rn } from "utils";
+
+export function generateIce(
+ grid: IGrid,
+ features: TGridFeatures,
+): IIce {
+ const shieldMin = -8; // max temp to form ice shield (glacier)
+ const icebergMax = 1; // max temp to form an iceberg
+ const { cells: gridCells, points: gridPoints, vertices } = grid;
+ const nOfCells = gridCells.i.length;
+ const used = new Uint8Array(gridCells.i.length);
+
+ Math.random = aleaPRNG(seed);
+ const icePack: IIce = { icebergs: [], iceShields: [] };
+ for (const i of gridCells.i) {
+ const temperature = gridCells.temp[i];
+ if (temperature > icebergMax) continue; // too warm: no ice
+ if (temperature > shieldMin && gridCells.h[i] >= 20) continue; // non-glacier land: no ice
+
+ if (temperature <= shieldMin) {
+ // very cold: ice shield
+ if (used[i]) continue; // already rendered
+ const onborder = gridCells.c[i].some((n) => gridCells.temp[n] > shieldMin);
+ if (!onborder) continue; // need to start from onborder cell
+ const vertex = gridCells.v[i].find((v) =>
+ vertices.c[v]?.some((i) => gridCells.temp[i] > shieldMin)
+ );
+ if (vertex === undefined) continue; // no suitable vertex found
+ const chain = connectVertices(vertex);
+ if (chain.length < 3) continue;
+ const points = clipPoly(chain.map((v) => vertices.p[v]));
+ icePack.iceShields.push({ points, transform: { x: 0, y: 0 } });
+ continue;
+ }
+ // mildly cold: iceberd
+ if (P(normalize(temperature, -7, 2.5))) continue; // t[-5; 2] cold: skip some cells
+ if (
+ gridCells.f[i] !== 0 &&
+ (features[gridCells.f[i]] as IGridFeature).type === "lake"
+ )
+ continue; // lake: no icebers // MARKER as IGridFeature
+ let size = (6.5 + temperature) / 10; // iceberg size: 0 = full size, 1 = zero size
+ if (gridCells.t[i] === -1) size *= 1.3; // coasline: smaller icebers
+ size = Math.min(size * (0.4 + Math.random() * 1.2), 0.95); // randomize iceberg size
+ icePack.icebergs.push(generateIceberg(i, size));
+ }
+ return icePack;
+
+ // Helper functions
+ function generateIceberg(i: number, size: number): IiceBerg {
+ const cellMidPoint = gridPoints[i];
+ const points: TPoints = getGridPolygonLocal(i, grid)
+ .map((point) => [
+ (point[0] + (cellMidPoint[0] - point[0]) * size) | 0,
+ (point[1] + (cellMidPoint[1] - point[1]) * size) | 0,
+ ]);
+ return {
+ points,
+ transform: { x: 0, y: 0 },
+ cell: i,
+ size: rn(1 - size, 2),
+ };
+ }
+
+ // connect vertices to chain
+ function connectVertices(start: number) {
+ const chain = []; // vertices chain to form a path
+ for (
+ let i = 0, current = start;
+ i === 0 || (current !== start && i < 20000);
+ i++
+ ) {
+ const prev = last(chain); // previous vertex in chain
+ chain.push(current); // add current vertex to sequence
+ const currentVertex = vertices.c[current]; // cells adjacent to vertex
+ currentVertex
+ .filter((cellIndicie) => gridCells.temp[cellIndicie] <= shieldMin)
+ .forEach((cellIndice) => (used[cellIndice] = 1));
+ const c0 =
+ currentVertex[0] >= nOfCells || gridCells.temp[currentVertex[0]] > shieldMin;
+ const c1 =
+ currentVertex[1] >= nOfCells || gridCells.temp[currentVertex[1]] > shieldMin;
+ const c2 =
+ currentVertex[2] >= nOfCells || gridCells.temp[currentVertex[2]] > shieldMin;
+ const vertexNeighbors = vertices.v[current]; // neighboring vertices
+ if (vertexNeighbors[0] !== prev && c0 !== c1)
+ current = vertexNeighbors[0];
+ else if (vertexNeighbors[1] !== prev && c1 !== c2)
+ current = vertexNeighbors[1];
+ else if (vertexNeighbors[2] !== prev && c0 !== c2)
+ current = vertexNeighbors[2];
+ if (current === chain[chain.length - 1]) {
+ ERROR && console.error("Next vertex is not found");
+ break;
+ }
+ }
+ return chain;
+ }
+}
diff --git a/src/scripts/generation/pack/pack.ts b/src/scripts/generation/pack/pack.ts
index 34a11b23b..89bc6634f 100644
--- a/src/scripts/generation/pack/pack.ts
+++ b/src/scripts/generation/pack/pack.ts
@@ -1,29 +1,30 @@
-import {markupPackFeatures} from "scripts/generation/markup";
-import {rankCells} from "scripts/generation/pack/rankCells";
-import {pick} from "utils/functionUtils";
-import {generateBurgsAndStates} from "./burgsAndStates/generateBurgsAndStates";
-import {expandCultures} from "./cultures/expandCultures";
-import {generateCultures} from "./cultures/generateCultures";
-import {generateLakeNames} from "./lakes/generateLakeNames";
-import {generateProvinces} from "./provinces/generateProvinces";
-import {generateReligions} from "./religions/generateReligions";
-import {repackGrid} from "./repackGrid";
-import {generateRivers} from "./rivers/generateRivers";
-import {specifyRivers} from "./rivers/specifyRivers";
-import {generateRoutes} from "./routes/generateRoutes";
-
-const {Biomes} = window;
+import { markupPackFeatures } from "scripts/generation/markup";
+import { rankCells } from "scripts/generation/pack/rankCells";
+import { pick } from "utils/functionUtils";
+import { generateBurgsAndStates } from "./burgsAndStates/generateBurgsAndStates";
+import { expandCultures } from "./cultures/expandCultures";
+import { generateCultures } from "./cultures/generateCultures";
+import { generateLakeNames } from "./lakes/generateLakeNames";
+import { generateProvinces } from "./provinces/generateProvinces";
+import { generateReligions } from "./religions/generateReligions";
+import { repackGrid } from "./repackGrid";
+import { generateRivers } from "./rivers/generateRivers";
+import { specifyRivers } from "./rivers/specifyRivers";
+import { generateRoutes } from "./routes/generateRoutes";
+import { generateIce } from "./generateIce";
+
+const { Biomes } = window;
export function createPack(grid: IGrid): IPack {
- const {temp, prec} = grid.cells;
- const {vertices, cells} = repackGrid(grid);
+ const { temp, prec } = grid.cells;
+ const { vertices, cells } = repackGrid(grid);
const {
features: rawFeatures,
featureIds,
distanceField,
haven,
- harbor
+ harbor,
} = markupPackFeatures(grid, vertices, pick(cells, "v", "c", "b", "p", "h"));
const {
@@ -32,9 +33,14 @@ export function createPack(grid: IGrid): IPack {
riverIds,
conf,
rivers: rawRivers,
- mergedFeatures
+ mergedFeatures,
} = generateRivers(
- {...pick(cells, "i", "c", "b", "g", "h", "p"), f: featureIds, t: distanceField, haven},
+ {
+ ...pick(cells, "i", "c", "b", "g", "h", "p"),
+ f: featureIds,
+ t: distanceField,
+ haven,
+ },
rawFeatures,
prec,
temp
@@ -47,10 +53,10 @@ export function createPack(grid: IGrid): IPack {
riverIds,
heights,
neighbors: cells.c,
- gridReference: cells.g
+ gridReference: cells.g,
});
- const {suitability, population} = rankCells(mergedFeatures, {
+ const { suitability, population } = rankCells(mergedFeatures, {
t: distanceField,
f: featureIds,
fl: flux,
@@ -60,7 +66,7 @@ export function createPack(grid: IGrid): IPack {
area: cells.area,
biome,
haven,
- harbor
+ harbor,
});
const cultures = generateCultures(
@@ -78,7 +84,7 @@ export function createPack(grid: IGrid): IPack {
fl: flux,
s: suitability,
pop: population,
- biome
+ biome,
},
temp
);
@@ -92,42 +98,43 @@ export function createPack(grid: IGrid): IPack {
r: riverIds,
fl: flux,
biome,
- pop: population
+ pop: population,
});
- const {burgIds, stateIds, burgs, states, conflicts} = generateBurgsAndStates(
- cultures,
- mergedFeatures,
- temp,
- rawRivers,
- vertices,
- {
- ...pick(cells, "v", "c", "p", "b", "i", "g", "area"),
- h: heights,
- f: featureIds,
- t: distanceField,
- haven,
- harbor,
- r: riverIds,
- fl: flux,
- biome,
- s: suitability,
- pop: population,
- culture: cultureIds
- }
- );
-
- const {cellRoutes, routes} = generateRoutes(burgs, temp, {
+ const { burgIds, stateIds, burgs, states, conflicts } =
+ generateBurgsAndStates(
+ cultures,
+ mergedFeatures,
+ temp,
+ rawRivers,
+ vertices,
+ {
+ ...pick(cells, "v", "c", "p", "b", "i", "g", "area"),
+ h: heights,
+ f: featureIds,
+ t: distanceField,
+ haven,
+ harbor,
+ r: riverIds,
+ fl: flux,
+ biome,
+ s: suitability,
+ pop: population,
+ culture: cultureIds,
+ }
+ );
+
+ const { cellRoutes, routes } = generateRoutes(burgs, temp, {
c: cells.c,
p: cells.p,
g: cells.g,
h: heights,
t: distanceField,
biome,
- burg: burgIds
+ burg: burgIds,
});
- const {religionIds, religions} = generateReligions({
+ const { religionIds, religions } = generateReligions({
states,
cultures,
burgs,
@@ -143,30 +150,38 @@ export function createPack(grid: IGrid): IPack {
culture: cultureIds,
burg: burgIds,
state: stateIds,
- route: cellRoutes
- }
+ route: cellRoutes,
+ },
});
- const {provinceIds, provinces} = generateProvinces(states, burgs, cultures, mergedFeatures, vertices, {
- i: cells.i,
- c: cells.c,
- v: cells.v,
- h: heights,
- t: distanceField,
- f: featureIds,
- culture: cultureIds,
- state: stateIds,
- burg: burgIds
- });
+ const { provinceIds, provinces } = generateProvinces(
+ states,
+ burgs,
+ cultures,
+ mergedFeatures,
+ vertices,
+ {
+ i: cells.i,
+ c: cells.c,
+ v: cells.v,
+ h: heights,
+ t: distanceField,
+ f: featureIds,
+ culture: cultureIds,
+ state: stateIds,
+ burg: burgIds,
+ }
+ );
const rivers = specifyRivers(rawRivers, cultureIds, cultures);
const features = generateLakeNames(mergedFeatures, cultureIds, cultures);
+ const ice = generateIce(grid, features);
// Military.generate();
// Markers.generate();
// addZones(); // add to pack data
- const events: IEvents = {conflicts};
+ const events: IEvents = { conflicts };
const pack: IPack = {
vertices,
@@ -188,7 +203,7 @@ export function createPack(grid: IGrid): IPack {
state: stateIds,
route: cellRoutes,
religion: religionIds,
- province: provinceIds
+ province: provinceIds,
},
features,
rivers,
@@ -198,7 +213,8 @@ export function createPack(grid: IGrid): IPack {
routes,
religions,
provinces,
- events
+ events,
+ ice,
};
return pack;
diff --git a/src/scripts/generation/pack/repackGrid.ts b/src/scripts/generation/pack/repackGrid.ts
index 48a32b1e1..a4c3bae96 100644
--- a/src/scripts/generation/pack/repackGrid.ts
+++ b/src/scripts/generation/pack/repackGrid.ts
@@ -9,6 +9,7 @@ import {calculateVoronoi} from "../graph";
const {LAND_COAST, WATER_COAST, DEEPER_WATER} = DISTANCE_FIELD;
+
// repack grid cells: discart deep water cells, add land cells along the coast
export function repackGrid(grid: IGrid) {
TIME && console.time("repackGrid");
diff --git a/src/types/pack/ice.d.ts b/src/types/pack/ice.d.ts
new file mode 100644
index 000000000..d16e09a6b
--- /dev/null
+++ b/src/types/pack/ice.d.ts
@@ -0,0 +1,18 @@
+
+interface IIceBase {
+ points: TPoints;
+ transform: {x: number, y: number};
+}
+
+interface IiceBerg extends IIceBase {
+ cell: number;
+ size: number;
+}
+
+interface IiceShield extends IIceBase {
+}
+
+interface IIce{
+ icebergs: IiceBerg[];
+ iceShields: IiceShield[];
+}
\ No newline at end of file
diff --git a/src/types/pack/pack.d.ts b/src/types/pack/pack.d.ts
index 824431c18..275cbb14c 100644
--- a/src/types/pack/pack.d.ts
+++ b/src/types/pack/pack.d.ts
@@ -9,6 +9,7 @@ interface IPack extends IGraph {
religions: TReligions;
routes: TRoutes;
events: IEvents;
+ ice: IIce;
}
interface IPackCells {
diff --git a/src/utils/graphUtils.ts b/src/utils/graphUtils.ts
index 963fcb1bf..cc60921a1 100644
--- a/src/utils/graphUtils.ts
+++ b/src/utils/graphUtils.ts
@@ -56,6 +56,10 @@ export function getGridPolygon(i: number): TPoints {
return grid.cells.v[i].map(v => grid.vertices.p[v]);
}
+export function getGridPolygonLocal(i: number, grid: IGrid): TPoints { // TODO: find a better name
+ return grid.cells.v[i].map(v => grid.vertices.p[v]);
+}
+
export function isLand(cellId: number) {
return pack.cells.h[cellId] >= MIN_LAND_HEIGHT;
}