mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-02-04 17:41:23 +01:00
prototype for ice seperation
This commit is contained in:
parent
f30ffd812e
commit
7f99323d22
9 changed files with 322 additions and 106 deletions
|
|
@ -632,6 +632,9 @@ async function generate(options) {
|
|||
Biomes.define();
|
||||
Features.defineGroups();
|
||||
|
||||
Ice.initialize();
|
||||
Ice.generate();
|
||||
|
||||
rankCells();
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
|
|
|
|||
170
public/modules/ice.js
Normal file
170
public/modules/ice.js
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
"use strict";
|
||||
|
||||
// Ice layer data model - separates ice data from SVG rendering
|
||||
const Ice = (() => {
|
||||
// Initialize ice data structure
|
||||
function initialize() {
|
||||
pack.ice = {
|
||||
glaciers: [], // auto-generated glaciers on cold land
|
||||
icebergs: [] // manually edited and auto-generated icebergs on cold water
|
||||
};
|
||||
}
|
||||
|
||||
// Generate glaciers and icebergs based on temperature and height
|
||||
function generate() {
|
||||
const {cells, features} = grid;
|
||||
const {temp, h} = cells;
|
||||
Math.random = aleaPRNG(seed);
|
||||
|
||||
const ICEBERG_MAX_TEMP = 0;
|
||||
const GLACIER_MAX_TEMP = -8;
|
||||
const minMaxTemp = d3.min(temp);
|
||||
|
||||
// Generate glaciers on cold land
|
||||
{
|
||||
const type = "iceShield";
|
||||
const getType = cellId =>
|
||||
h[cellId] >= 20 && temp[cellId] <= GLACIER_MAX_TEMP ? type : null;
|
||||
const isolines = getIsolines(grid, getType, {polygons: true});
|
||||
|
||||
if (isolines[type]?.polygons) {
|
||||
isolines[type].polygons.forEach(points => {
|
||||
const clipped = clipPoly(points);
|
||||
pack.ice.glaciers.push({
|
||||
points: clipped,
|
||||
offset: null
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Generate icebergs on cold water
|
||||
for (const cellId of grid.cells.i) {
|
||||
const t = temp[cellId];
|
||||
if (h[cellId] >= 20) continue; // no icebergs on land
|
||||
if (t > ICEBERG_MAX_TEMP) continue; // too warm: no icebergs
|
||||
if (features[cells.f[cellId]].type === "lake") continue; // no icebergs on lakes
|
||||
if (P(0.8)) continue; // skip most of eligible cells
|
||||
|
||||
const randomFactor = 0.8 + rand() * 0.4; // random size factor
|
||||
let baseSize = (1 - normalize(t, minMaxTemp, 1)) * 0.8; // size: 0 = zero, 1 = full
|
||||
if (cells.t[cellId] === -1) baseSize /= 1.3; // coastline: smaller icebergs
|
||||
const size = minmax(rn(baseSize * randomFactor, 2), 0.1, 1);
|
||||
|
||||
const [cx, cy] = grid.points[cellId];
|
||||
const points = getGridPolygon(cellId).map(([x, y]) => [
|
||||
rn(lerp(cx, x, size), 2),
|
||||
rn(lerp(cy, y, size), 2)
|
||||
]);
|
||||
|
||||
pack.ice.icebergs.push({
|
||||
cellId,
|
||||
size,
|
||||
points,
|
||||
offset: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new iceberg (manual editing)
|
||||
function addIceberg(cellId, size) {
|
||||
const [cx, cy] = grid.points[cellId];
|
||||
const points = getGridPolygon(cellId).map(([x, y]) => [
|
||||
rn(lerp(cx, x, size), 2),
|
||||
rn(lerp(cy, y, size), 2)
|
||||
]);
|
||||
|
||||
pack.ice.icebergs.push({
|
||||
cellId,
|
||||
size,
|
||||
points,
|
||||
offset: null
|
||||
});
|
||||
|
||||
return pack.ice.icebergs.length - 1; // return index
|
||||
}
|
||||
|
||||
// Remove ice element by index
|
||||
function removeIce(type, index) {
|
||||
if (type === "glacier" && pack.ice.glaciers[index]) {
|
||||
pack.ice.glaciers.splice(index, 1);
|
||||
} else if (type === "iceberg" && pack.ice.icebergs[index]) {
|
||||
pack.ice.icebergs.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Update iceberg points and size
|
||||
function updateIceberg(index, points, size) {
|
||||
if (pack.ice.icebergs[index]) {
|
||||
pack.ice.icebergs[index].points = points;
|
||||
pack.ice.icebergs[index].size = size;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomize iceberg shape
|
||||
function randomizeIcebergShape(index) {
|
||||
const iceberg = pack.ice.icebergs[index];
|
||||
if (!iceberg) return;
|
||||
|
||||
const cellId = iceberg.cellId;
|
||||
const size = iceberg.size;
|
||||
const [cx, cy] = grid.points[cellId];
|
||||
|
||||
// Get a different random cell for the polygon template
|
||||
const i = ra(grid.cells.i);
|
||||
const cn = grid.points[i];
|
||||
const poly = getGridPolygon(i).map(p => [p[0] - cn[0], p[1] - cn[1]]);
|
||||
const points = poly.map(p => [
|
||||
rn(cx + p[0] * size, 2),
|
||||
rn(cy + p[1] * size, 2)
|
||||
]);
|
||||
|
||||
iceberg.points = points;
|
||||
}
|
||||
|
||||
// Change iceberg size and recalculate points
|
||||
function changeIcebergSize(index, newSize) {
|
||||
const iceberg = pack.ice.icebergs[index];
|
||||
if (!iceberg) return;
|
||||
|
||||
const cellId = iceberg.cellId;
|
||||
const [cx, cy] = grid.points[cellId];
|
||||
const oldSize = iceberg.size;
|
||||
|
||||
// Recalculate points based on new size
|
||||
const flat = iceberg.points.flat();
|
||||
const pairs = [];
|
||||
while (flat.length) pairs.push(flat.splice(0, 2));
|
||||
const poly = pairs.map(p => [(p[0] - cx) / oldSize, (p[1] - cy) / oldSize]);
|
||||
const points = poly.map(p => [
|
||||
rn(cx + p[0] * newSize, 2),
|
||||
rn(cy + p[1] * newSize, 2)
|
||||
]);
|
||||
|
||||
iceberg.points = points;
|
||||
iceberg.size = newSize;
|
||||
}
|
||||
|
||||
// Get all ice data
|
||||
function getData() {
|
||||
return pack.ice;
|
||||
}
|
||||
|
||||
// Clear all ice
|
||||
function clear() {
|
||||
pack.ice.glaciers = [];
|
||||
pack.ice.icebergs = [];
|
||||
}
|
||||
|
||||
return {
|
||||
initialize,
|
||||
generate,
|
||||
addIceberg,
|
||||
removeIce,
|
||||
updateIceberg,
|
||||
randomizeIcebergShape,
|
||||
changeIcebergSize,
|
||||
getData,
|
||||
clear
|
||||
};
|
||||
})();
|
||||
|
|
@ -406,6 +406,7 @@ async function parseLoadedData(data, mapVersion) {
|
|||
pack.cells.province = data[27] ? Uint16Array.from(data[27].split(",")) : new Uint16Array(pack.cells.i.length);
|
||||
// data[28] had deprecated cells.crossroad
|
||||
pack.cells.routes = data[36] ? JSON.parse(data[36]) : {};
|
||||
pack.ice = data[39] ? JSON.parse(data[39]) : {glaciers: [], icebergs: []};
|
||||
|
||||
if (data[31]) {
|
||||
const namesDL = data[31].split("/");
|
||||
|
|
@ -449,7 +450,11 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (isVisible(routes) && hasChild(routes, "path")) turnOn("toggleRoutes");
|
||||
if (hasChildren(temperature)) turnOn("toggleTemperature");
|
||||
if (hasChild(population, "line")) turnOn("togglePopulation");
|
||||
if (hasChildren(ice)) turnOn("toggleIce");
|
||||
if (pack.ice?.glaciers?.length || pack.ice?.icebergs?.length) {
|
||||
ice.selectAll("*").remove(); // clear old SVG
|
||||
drawIce(); // re-render ice from data
|
||||
turnOn("toggleIce");
|
||||
}
|
||||
if (hasChild(prec, "circle")) turnOn("togglePrecipitation");
|
||||
if (isVisible(emblems) && hasChild(emblems, "use")) turnOn("toggleEmblems");
|
||||
if (isVisible(labels)) turnOn("toggleLabels");
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ function prepareMapData() {
|
|||
const cellRoutes = JSON.stringify(pack.cells.routes);
|
||||
const routes = JSON.stringify(pack.routes);
|
||||
const zones = JSON.stringify(pack.zones);
|
||||
const ice = JSON.stringify(pack.ice);
|
||||
|
||||
// store name array only if not the same as default
|
||||
const defaultNB = Names.getNameBases();
|
||||
|
|
@ -155,7 +156,8 @@ function prepareMapData() {
|
|||
markers,
|
||||
cellRoutes,
|
||||
routes,
|
||||
zones
|
||||
zones,
|
||||
ice
|
||||
].join("\r\n");
|
||||
return mapData;
|
||||
}
|
||||
|
|
|
|||
37
public/modules/renderers/draw-ice.js
Normal file
37
public/modules/renderers/draw-ice.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
"use strict";
|
||||
|
||||
// Ice layer renderer - renders ice from data model to SVG
|
||||
function drawIce() {
|
||||
TIME && console.time("drawIce");
|
||||
|
||||
// Clear existing ice SVG
|
||||
ice.selectAll("*").remove();
|
||||
|
||||
// Draw glaciers
|
||||
pack.ice.glaciers.forEach((glacier, index) => {
|
||||
ice
|
||||
.append("polygon")
|
||||
.attr("points", glacier.points)
|
||||
.attr("type", "iceShield")
|
||||
.attr("data-index", index)
|
||||
.attr("class", "glacier");
|
||||
});
|
||||
|
||||
// Draw icebergs
|
||||
pack.ice.icebergs.forEach((iceberg, index) => {
|
||||
ice
|
||||
.append("polygon")
|
||||
.attr("points", iceberg.points)
|
||||
.attr("cell", iceberg.cellId)
|
||||
.attr("size", iceberg.size)
|
||||
.attr("data-index", index)
|
||||
.attr("class", "iceberg");
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("drawIce");
|
||||
}
|
||||
|
||||
// Re-render ice layer from data model
|
||||
function redrawIce() {
|
||||
drawIce();
|
||||
}
|
||||
|
|
@ -5,10 +5,14 @@ function editIce() {
|
|||
if (!layerIsOn("toggleIce")) toggleIce();
|
||||
|
||||
elSelected = d3.select(d3.event.target);
|
||||
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
|
||||
document.getElementById("iceRandomize").style.display = type === "Glacier" ? "none" : "inline-block";
|
||||
document.getElementById("iceSize").style.display = type === "Glacier" ? "none" : "inline-block";
|
||||
if (type === "Iceberg") document.getElementById("iceSize").value = +elSelected.attr("size");
|
||||
const index = +elSelected.attr("data-index");
|
||||
const isGlacier = elSelected.attr("type") === "iceShield";
|
||||
const type = isGlacier ? "Glacier" : "Iceberg";
|
||||
|
||||
document.getElementById("iceRandomize").style.display = isGlacier ? "none" : "inline-block";
|
||||
document.getElementById("iceSize").style.display = isGlacier ? "none" : "inline-block";
|
||||
if (!isGlacier) document.getElementById("iceSize").value = +elSelected.attr("size");
|
||||
|
||||
ice.selectAll("*").classed("draggable", true).call(d3.drag().on("drag", dragElement));
|
||||
|
||||
$("#iceEditor").dialog({
|
||||
|
|
@ -29,28 +33,18 @@ function editIce() {
|
|||
document.getElementById("iceRemove").addEventListener("click", removeIce);
|
||||
|
||||
function randomizeShape() {
|
||||
const c = grid.points[+elSelected.attr("cell")];
|
||||
const s = +elSelected.attr("size");
|
||||
const i = ra(grid.cells.i),
|
||||
cn = grid.points[i];
|
||||
const poly = getGridPolygon(i).map(p => [p[0] - cn[0], p[1] - cn[1]]);
|
||||
const points = poly.map(p => [rn(c[0] + p[0] * s, 2), rn(c[1] + p[1] * s, 2)]);
|
||||
elSelected.attr("points", points);
|
||||
Ice.randomizeIcebergShape(index);
|
||||
redrawIce();
|
||||
elSelected = ice.selectAll(`[data-index="${index}"]`).node();
|
||||
elSelected = d3.select(elSelected);
|
||||
}
|
||||
|
||||
function changeSize() {
|
||||
const c = grid.points[+elSelected.attr("cell")];
|
||||
const s = +elSelected.attr("size");
|
||||
const flat = elSelected
|
||||
.attr("points")
|
||||
.split(",")
|
||||
.map(el => +el);
|
||||
const pairs = [];
|
||||
while (flat.length) pairs.push(flat.splice(0, 2));
|
||||
const poly = pairs.map(p => [(p[0] - c[0]) / s, (p[1] - c[1]) / s]);
|
||||
const size = +this.value;
|
||||
const points = poly.map(p => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]);
|
||||
elSelected.attr("points", points).attr("size", size);
|
||||
const newSize = +this.value;
|
||||
Ice.changeIcebergSize(index, newSize);
|
||||
redrawIce();
|
||||
elSelected = ice.selectAll(`[data-index="${index}"]`).node();
|
||||
elSelected = d3.select(elSelected);
|
||||
}
|
||||
|
||||
function toggleAdd() {
|
||||
|
|
@ -67,17 +61,16 @@ function editIce() {
|
|||
function addIcebergOnClick() {
|
||||
const [x, y] = d3.mouse(this);
|
||||
const i = findGridCell(x, y, grid);
|
||||
const [cx, cy] = grid.points[i];
|
||||
const size = +document.getElementById("iceSize")?.value || 1;
|
||||
|
||||
const points = getGridPolygon(i).map(([x, y]) => [rn(lerp(cx, x, size), 2), rn(lerp(cy, y, size), 2)]);
|
||||
const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", size);
|
||||
iceberg.call(d3.drag().on("drag", dragElement));
|
||||
Ice.addIceberg(i, size);
|
||||
redrawIce();
|
||||
|
||||
if (d3.event.shiftKey === false) toggleAdd();
|
||||
}
|
||||
|
||||
function removeIce() {
|
||||
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
|
||||
const type = isGlacier ? "Glacier" : "Iceberg";
|
||||
alertMessage.innerHTML = /* html */ `Are you sure you want to remove the ${type}?`;
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
|
|
@ -85,7 +78,8 @@ function editIce() {
|
|||
buttons: {
|
||||
Remove: function () {
|
||||
$(this).dialog("close");
|
||||
elSelected.remove();
|
||||
Ice.removeIce(isGlacier ? "glacier" : "iceberg", index);
|
||||
redrawIce();
|
||||
$("#iceEditor").dialog("close");
|
||||
},
|
||||
Cancel: function () {
|
||||
|
|
@ -96,14 +90,25 @@ function editIce() {
|
|||
}
|
||||
|
||||
function dragElement() {
|
||||
const tr = parseTransform(this.getAttribute("transform"));
|
||||
const dx = +tr[0] - d3.event.x,
|
||||
dy = +tr[1] - d3.event.y;
|
||||
const isGlacier = elSelected.attr("type") === "iceShield";
|
||||
const idx = +elSelected.attr("data-index");
|
||||
const initialTransform = parseTransform(this.getAttribute("transform"));
|
||||
const dx = initialTransform[0] - d3.event.x;
|
||||
const dy = initialTransform[1] - d3.event.y;
|
||||
|
||||
d3.event.on("drag", function () {
|
||||
const x = d3.event.x,
|
||||
y = d3.event.y;
|
||||
this.setAttribute("transform", `translate(${dx + x},${dy + y})`);
|
||||
const x = d3.event.x;
|
||||
const y = d3.event.y;
|
||||
const transform = `translate(${dx + x},${dy + y})`;
|
||||
this.setAttribute("transform", transform);
|
||||
|
||||
// Update data model with new position
|
||||
const offset = [dx + x, dy + y];
|
||||
const iceData = isGlacier ? pack.ice.glaciers[idx] : pack.ice.icebergs[idx];
|
||||
if (iceData) {
|
||||
// Store offset for visual positioning, actual geometry stays in points
|
||||
iceData.offset = offset;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -114,3 +119,4 @@ function editIce() {
|
|||
unselect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -420,42 +420,31 @@ function toggleIce(event) {
|
|||
function drawIce() {
|
||||
TIME && console.time("drawIce");
|
||||
|
||||
const {cells, features} = grid;
|
||||
const {temp, h} = cells;
|
||||
Math.random = aleaPRNG(seed);
|
||||
// Clear existing ice SVG
|
||||
ice.selectAll("*").remove();
|
||||
|
||||
const ICEBERG_MAX_TEMP = 0;
|
||||
const GLACIER_MAX_TEMP = -8;
|
||||
const minMaxTemp = d3.min(temp);
|
||||
// Draw glaciers
|
||||
pack.ice.glaciers.forEach((glacier, index) => {
|
||||
ice
|
||||
.append("polygon")
|
||||
.attr("points", glacier.points)
|
||||
.attr("type", "iceShield")
|
||||
.attr("data-index", index)
|
||||
.attr("class", "glacier")
|
||||
.attr("transform", glacier.offset ? `translate(${glacier.offset[0]},${glacier.offset[1]})` : null);
|
||||
});
|
||||
|
||||
// cold land: draw glaciers
|
||||
{
|
||||
const type = "iceShield";
|
||||
const getType = cellId => (h[cellId] >= 20 && temp[cellId] <= GLACIER_MAX_TEMP ? type : null);
|
||||
const isolines = getIsolines(grid, getType, {polygons: true});
|
||||
isolines[type]?.polygons?.forEach(points => {
|
||||
const clipped = clipPoly(points);
|
||||
ice.append("polygon").attr("points", clipped).attr("type", type);
|
||||
});
|
||||
}
|
||||
|
||||
// cold water: draw icebergs
|
||||
for (const cellId of grid.cells.i) {
|
||||
const t = temp[cellId];
|
||||
if (h[cellId] >= 20) continue; // no icebergs on land
|
||||
if (t > ICEBERG_MAX_TEMP) continue; // too warm: no icebergs
|
||||
if (features[cells.f[cellId]].type === "lake") continue; // no icebers on lakes
|
||||
if (P(0.8)) continue; // skip most of eligible cells
|
||||
|
||||
const randomFactor = 0.8 + rand() * 0.4; // random size factor
|
||||
let baseSize = (1 - normalize(t, minMaxTemp, 1)) * 0.8; // size: 0 = zero size, 1 = full size
|
||||
if (cells.t[cellId] === -1) baseSize /= 1.3; // coasline: smaller icebergs
|
||||
const size = minmax(rn(baseSize * randomFactor, 2), 0.1, 1);
|
||||
|
||||
const [cx, cy] = grid.points[cellId];
|
||||
const points = getGridPolygon(cellId).map(([x, y]) => [rn(lerp(cx, x, size), 2), rn(lerp(cy, y, size), 2)]);
|
||||
ice.append("polygon").attr("points", points).attr("cell", cellId).attr("size", size);
|
||||
}
|
||||
// Draw icebergs
|
||||
pack.ice.icebergs.forEach((iceberg, index) => {
|
||||
ice
|
||||
.append("polygon")
|
||||
.attr("points", iceberg.points)
|
||||
.attr("cell", iceberg.cellId)
|
||||
.attr("size", iceberg.size)
|
||||
.attr("data-index", index)
|
||||
.attr("class", "iceberg")
|
||||
.attr("transform", iceberg.offset ? `translate(${iceberg.offset[0]},${iceberg.offset[1]})` : null);
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("drawIce");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ function regenerateMilitary() {
|
|||
|
||||
function regenerateIce() {
|
||||
if (!layerIsOn("toggleIce")) toggleIce();
|
||||
ice.selectAll("*").remove();
|
||||
Ice.generate();
|
||||
drawIce();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8491,40 +8491,43 @@
|
|||
<script type="module" src="utils/index.ts"></script>
|
||||
<script type="module" src="modules/index.ts"></script>
|
||||
|
||||
<script defer src="config/heightmap-templates.js"></script>
|
||||
<script defer src="config/precreated-heightmaps.js"></script>
|
||||
<script defer src="modules/features.js?v=1.104.0"></script>
|
||||
<script defer src="modules/ocean-layers.js?v=1.108.4"></script>
|
||||
<script defer src="modules/river-generator.js?v=1.106.7"></script>
|
||||
<script defer src="modules/lakes.js?v=1.99.00"></script>
|
||||
<script defer src="modules/biomes.js?v=1.99.00"></script>
|
||||
<script defer src="modules/names-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/cultures-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/burgs-generator.js?v=1.109.5"></script>
|
||||
<script defer src="modules/states-generator.js?v=1.107.0"></script>
|
||||
<script defer src="modules/provinces-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/routes-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/religions-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/military-generator.js?v=1.107.0"></script>
|
||||
<script defer src="modules/markers-generator.js?v=1.107.0"></script>
|
||||
<script defer src="modules/zones-generator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/coa-generator.js?v=1.99.00"></script>
|
||||
<script defer src="modules/resample.js?v=1.106.4"></script>
|
||||
<script defer src="libs/alea.min.js?v1.105.0"></script>
|
||||
<script defer src="libs/polylabel.min.js?v1.105.0"></script>
|
||||
<script defer src="libs/lineclip.min.js?v1.105.0"></script>
|
||||
<script defer src="libs/simplify.js?v1.105.6"></script>
|
||||
<script defer src="modules/fonts.js?v=1.99.03"></script>
|
||||
<script defer src="modules/ui/layers.js?v=1.108.4"></script>
|
||||
<script defer src="modules/ui/measurers.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/style-presets.js?v=1.100.00"></script>
|
||||
<script defer src="modules/ui/general.js?v=1.100.00"></script>
|
||||
<script defer src="modules/ui/options.js?v=1.106.2"></script>
|
||||
<script defer src="main.js?v=1.108.1"></script>
|
||||
<script src="modules/voronoi.js"></script>
|
||||
<script src="config/heightmap-templates.js"></script>
|
||||
<script src="config/precreated-heightmaps.js"></script>
|
||||
<script src="modules/heightmap-generator.js?v=1.99.00"></script>
|
||||
<script src="modules/features.js?v=1.104.0"></script>
|
||||
<script src="modules/ocean-layers.js?v=1.108.4"></script>
|
||||
<script src="modules/river-generator.js?v=1.106.7"></script>
|
||||
<script src="modules/lakes.js?v=1.99.00"></script>
|
||||
<script src="modules/biomes.js?v=1.99.00"></script>
|
||||
<script src="modules/ice.js?v=1.109.6"></script>
|
||||
<script src="modules/names-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/cultures-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/burgs-generator.js?v=1.109.5"></script>
|
||||
<script src="modules/states-generator.js?v=1.107.0"></script>
|
||||
<script src="modules/provinces-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/routes-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/religions-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/military-generator.js?v=1.107.0"></script>
|
||||
<script src="modules/markers-generator.js?v=1.107.0"></script>
|
||||
<script src="modules/zones-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/coa-generator.js?v=1.99.00"></script>
|
||||
<script src="modules/resample.js?v=1.106.4"></script>
|
||||
<script src="libs/alea.min.js?v1.105.0"></script>
|
||||
<script src="libs/polylabel.min.js?v1.105.0"></script>
|
||||
<script src="libs/lineclip.min.js?v1.105.0"></script>
|
||||
<script src="libs/simplify.js?v1.105.6"></script>
|
||||
<script src="modules/fonts.js?v=1.99.03"></script>
|
||||
<script src="modules/ui/layers.js?v=1.109.6"></script>
|
||||
<script src="modules/ui/measurers.js?v=1.99.00"></script>
|
||||
<script src="modules/ui/style-presets.js?v=1.100.00"></script>
|
||||
<script src="modules/ui/general.js?v=1.100.00"></script>
|
||||
<script src="modules/ui/options.js?v=1.106.2"></script>
|
||||
<script src="main.js?v=1.109.6"></script>
|
||||
|
||||
<script defer src="modules/ui/style.js?v=1.108.4"></script>
|
||||
<script defer src="modules/ui/editors.js?v=1.108.5"></script>
|
||||
<script defer src="modules/ui/tools.js?v=1.108.5"></script>
|
||||
<script defer src="modules/ui/tools.js?v=1.109.6"></script>
|
||||
<script defer src="modules/ui/world-configurator.js?v=1.105.4"></script>
|
||||
<script defer src="modules/ui/heightmap-editor.js?v=1.105.2"></script>
|
||||
<script defer src="modules/ui/provinces-editor.js?v=1.108.1"></script>
|
||||
|
|
@ -8535,7 +8538,7 @@
|
|||
<script defer src="modules/ui/routes-editor.js?v=1.104.3"></script>
|
||||
<script defer src="modules/ui/routes-creator.js?v=1.104.3"></script>
|
||||
<script defer src="modules/ui/route-group-editor.js?v=1.103.8"></script>
|
||||
<script defer src="modules/ui/ice-editor.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/ice-editor.js?v=1.109.6"></script>
|
||||
<script defer src="modules/ui/lakes-editor.js?v=1.106.0"></script>
|
||||
<script defer src="modules/ui/coastline-editor.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/labels-editor.js?v=1.106.0"></script>
|
||||
|
|
@ -8566,8 +8569,8 @@
|
|||
<script defer src="modules/coa-renderer.js?v=1.99.00"></script>
|
||||
<script defer src="libs/rgbquant.min.js"></script>
|
||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||
<script defer src="modules/io/save.js?v=1.107.4"></script>
|
||||
<script defer src="modules/io/load.js?v=1.109.4"></script>
|
||||
<script defer src="modules/io/save.js?v=1.109.6"></script>
|
||||
<script defer src="modules/io/load.js?v=1.109.6"></script>
|
||||
<script defer src="modules/io/cloud.js?v=1.106.0"></script>
|
||||
<script defer src="modules/io/export.js?v=1.108.13"></script>
|
||||
|
||||
|
|
@ -8583,5 +8586,6 @@
|
|||
<script defer src="modules/renderers/draw-burg-labels.js?v=1.109.4"></script>
|
||||
<script defer src="modules/renderers/draw-burg-icons.js?v=1.109.4"></script>
|
||||
<script defer src="modules/renderers/draw-relief-icons.js?v=1.108.4"></script>
|
||||
<script defer src="modules/renderers/draw-ice.js?v=1.109.6"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue