mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
v1.2.02
This commit is contained in:
parent
2ba1332eec
commit
a3fa5443d6
16 changed files with 137 additions and 113 deletions
|
|
@ -190,7 +190,7 @@ async function startGlobe(canvas) {
|
|||
// create globe mesh just from svg
|
||||
async function addGlobe3dMesh() {
|
||||
threeD.material = new THREE.MeshLambertMaterial();
|
||||
const url = await getMapURL("mesh");
|
||||
const url = await getMapURL("mesh", "globe");
|
||||
threeD.material.map = new THREE.TextureLoader().load(url, render);
|
||||
threeD.mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(1, 64, 64), threeD.material);
|
||||
threeD.scene.add(threeD.mesh);
|
||||
|
|
|
|||
|
|
@ -304,6 +304,9 @@ function editCultures() {
|
|||
pack.cells.culture.forEach((c, i) => {if(c === culture) pack.cells.culture[i] = 0;});
|
||||
pack.cultures[culture].removed = true;
|
||||
|
||||
const origin = pack.cultures[culture].origin;
|
||||
pack.cultures.forEach(c => {if(c.origin === culture) c.origin = origin;});
|
||||
|
||||
refreshCulturesEditor();
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +366,7 @@ function editCultures() {
|
|||
// build hierarchy tree
|
||||
pack.cultures[0].origin = null;
|
||||
const cultures = pack.cultures.filter(c => !c.removed);
|
||||
if (cultures.length < 3) {tip("Not enough cultures to show hierarchy", false, "error"); return;}
|
||||
const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(cultures);
|
||||
const treeWidth = root.leaves().length;
|
||||
const treeHeight = root.height;
|
||||
|
|
@ -452,7 +456,6 @@ function editCultures() {
|
|||
}
|
||||
}
|
||||
|
||||
// re-calculate cultures
|
||||
function recalculateCultures(must) {
|
||||
if (!must && !culturesAutoChange.checked) return;
|
||||
|
||||
|
|
@ -508,7 +511,7 @@ function editCultures() {
|
|||
body.querySelector("div.selected").classList.remove("selected");
|
||||
body.querySelector("div[data-id='"+culture+"']").classList.add("selected");
|
||||
}
|
||||
|
||||
|
||||
function dragCultureBrush() {
|
||||
const r = +culturesManuallyBrush.value;
|
||||
|
||||
|
|
@ -523,7 +526,6 @@ function editCultures() {
|
|||
});
|
||||
}
|
||||
|
||||
// change culture within selection
|
||||
function changeCultureForSelection(selection) {
|
||||
const temp = cults.select("#temp");
|
||||
const selected = body.querySelector("div.selected");
|
||||
|
|
@ -564,7 +566,7 @@ function editCultures() {
|
|||
}
|
||||
exitCulturesManualAssignment();
|
||||
}
|
||||
|
||||
|
||||
function exitCulturesManualAssignment(close) {
|
||||
customization = 0;
|
||||
cults.select("#temp").remove();
|
||||
|
|
@ -637,7 +639,7 @@ function editCultures() {
|
|||
const name = getFileName("Cultures") + ".csv";
|
||||
downloadFile(data, name);
|
||||
}
|
||||
|
||||
|
||||
function closeCulturesEditor() {
|
||||
debug.select("#cultureCenters").remove();
|
||||
exitCulturesManualAssignment("close");
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ function drawLegend(name, data) {
|
|||
fitLegendBox();
|
||||
}
|
||||
|
||||
// fit Legend box to map size
|
||||
// fit Legend box to canvas size
|
||||
function fitLegendBox() {
|
||||
if (!legend.selectAll("*").size()) return;
|
||||
const px = isNaN(+legend.attr("data-x")) ? 99 : legend.attr("data-x") / 100;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ function moved() {
|
|||
showNotes(d3.event, i);
|
||||
const g = findGridCell(point[0], point[1]); // grid cell id
|
||||
if (tooltip.dataset.main) showMainTip(); else showMapTooltip(point, d3.event, i, g);
|
||||
if (toolsContent.style.display === "block" && cellInfo.style.display === "block") updateCellInfo(point, i, g);
|
||||
if (cellInfo.offsetParent) updateCellInfo(point, i, g);
|
||||
}
|
||||
|
||||
// show note box on hover (if any)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
"use strict";
|
||||
|
||||
function editHeightmap() {
|
||||
const heights = viewbox.select("#heights").size()
|
||||
? viewbox.select("#heights")
|
||||
: viewbox.insert("g", "#terrs").attr("id", "heights");
|
||||
|
||||
void function selectEditMode() {
|
||||
alertMessage.innerHTML = `<p>Heightmap is a core element on which all other data (rivers, burgs, states etc) is based.
|
||||
So the best edit approach is to <i>erase</i> the secondary data and let the system automatically regenerate it on edit completion.</p>
|
||||
|
|
@ -31,6 +27,7 @@ function editHeightmap() {
|
|||
|
||||
let edits = [];
|
||||
restartHistory();
|
||||
viewbox.insert("g", "#terrs").attr("id", "heights");
|
||||
|
||||
if (modules.editHeightmap) return;
|
||||
modules.editHeightmap = true;
|
||||
|
|
@ -111,7 +108,7 @@ function editHeightmap() {
|
|||
|
||||
// Exit customization mode
|
||||
function finalizeHeightmap() {
|
||||
if (heights.selectAll("*").size() < 200) {
|
||||
if (viewbox.select("#heights").selectAll("*").size() < 200) {
|
||||
tip("Insufficient land area! There should be at least 200 land cells to finalize the heightmap", null, "error");
|
||||
return;
|
||||
}
|
||||
|
|
@ -136,7 +133,7 @@ function editHeightmap() {
|
|||
else if (mode === "risk") restoreRiskedData();
|
||||
|
||||
// restore initial layers
|
||||
heights.selectAll("*").remove();
|
||||
viewbox.select("#heights").remove();
|
||||
turnButtonOff("toggleHeight");
|
||||
document.getElementById("mapLayers").querySelectorAll("li").forEach(function(e) {
|
||||
if (editHeightmap.layers.includes(e.id) && !layerIsOn(e.id)) e.click(); // turn on
|
||||
|
|
@ -381,7 +378,7 @@ function editHeightmap() {
|
|||
function mockHeightmap() {
|
||||
const data = renderOcean.checked ? grid.cells.i : grid.cells.i.filter(i => grid.cells.h[i] >= 20);
|
||||
const scheme = getColorScheme();
|
||||
heights.selectAll("polygon").data(data).join("polygon").attr("points", d => getGridPolygon(d))
|
||||
viewbox.select("#heights").selectAll("polygon").data(data).join("polygon").attr("points", d => getGridPolygon(d))
|
||||
.attr("id", d => "cell"+d).attr("fill", d => getColor(grid.cells.h[d], scheme));
|
||||
}
|
||||
|
||||
|
|
@ -391,9 +388,9 @@ function editHeightmap() {
|
|||
const scheme = getColorScheme();
|
||||
|
||||
selection.forEach(function(i) {
|
||||
let cell = heights.select("#cell"+i);
|
||||
let cell = viewbox.select("#heights").select("#cell"+i);
|
||||
if (!ocean && grid.cells.h[i] < 20) {cell.remove(); return;}
|
||||
if (!cell.size()) cell = heights.append("polygon").attr("points", getGridPolygon(i)).attr("id", "cell"+i);
|
||||
if (!cell.size()) cell = viewbox.select("#heights").append("polygon").attr("points", getGridPolygon(i)).attr("id", "cell"+i);
|
||||
cell.attr("fill", getColor(grid.cells.h[i], scheme));
|
||||
});
|
||||
}
|
||||
|
|
@ -579,7 +576,7 @@ function editHeightmap() {
|
|||
const someHeights = grid.cells.h.some(h => h);
|
||||
if (!someHeights) {tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); return;}
|
||||
grid.cells.h = new Uint8Array(grid.cells.i.length);
|
||||
heights.selectAll("*").remove();
|
||||
viewbox.select("#heights").selectAll("*").remove();
|
||||
updateHistory();
|
||||
}
|
||||
|
||||
|
|
@ -941,7 +938,7 @@ function editHeightmap() {
|
|||
|
||||
// remove all heights
|
||||
grid.cells.h = new Uint8Array(grid.cells.i.length);
|
||||
heights.selectAll("*").remove();
|
||||
viewbox.select("#heights").selectAll("*").remove();
|
||||
updateHistory();
|
||||
|
||||
if (modules.openImageConverter) return;
|
||||
|
|
@ -995,7 +992,7 @@ function editHeightmap() {
|
|||
const imageData = ctx.getImageData(0, 0, graphWidth, graphHeight);
|
||||
const data = imageData.data;
|
||||
|
||||
heights.selectAll("*").remove();
|
||||
viewbox.select("#heights").selectAll("*").remove();
|
||||
d3.select("#imageConverter").selectAll("div.color-div").remove();
|
||||
colorsSelect.style.display = "block";
|
||||
colorsUnassigned.style.display = "block";
|
||||
|
|
@ -1011,7 +1008,7 @@ function editHeightmap() {
|
|||
const cmap = MMCQ.quantize(gridColors, count);
|
||||
const usedColors = new Set();
|
||||
|
||||
heights.selectAll("polygon").data(grid.cells.i).join("polygon")
|
||||
viewbox.select("#heights").selectAll("polygon").data(grid.cells.i).join("polygon")
|
||||
.attr("points", d => getGridPolygon(d))
|
||||
.attr("id", d => "cell"+d).attr("fill", d => {
|
||||
const clr = `rgb(${cmap.nearest(gridColors[d])})`;
|
||||
|
|
@ -1035,7 +1032,7 @@ function editHeightmap() {
|
|||
}
|
||||
|
||||
function colorClicked() {
|
||||
heights.selectAll(".selectedCell").attr("class", null);
|
||||
viewbox.select("#heights").selectAll(".selectedCell").attr("class", null);
|
||||
const unselect = this.classList.contains("selectedColor");
|
||||
|
||||
const selectedColor = imageConverter.querySelector("div.selectedColor");
|
||||
|
|
@ -1054,8 +1051,8 @@ function editHeightmap() {
|
|||
}
|
||||
|
||||
const color = this.getAttribute("data-color");
|
||||
heights.selectAll("polygon.selectedCell").classed("selectedCell", 0);
|
||||
heights.selectAll("polygon[fill='" + color + "']").classed("selectedCell", 1);
|
||||
viewbox.select("#heights").selectAll("polygon.selectedCell").classed("selectedCell", 0);
|
||||
viewbox.select("#heights").selectAll("polygon[fill='" + color + "']").classed("selectedCell", 1);
|
||||
}
|
||||
|
||||
function assignHeight() {
|
||||
|
|
@ -1066,7 +1063,7 @@ function editHeightmap() {
|
|||
selectedColor.setAttribute("data-color", rgb);
|
||||
selectedColor.setAttribute("data-height", height);
|
||||
|
||||
heights.selectAll(".selectedCell").each(function() {
|
||||
viewbox.select("#heights").selectAll(".selectedCell").each(function() {
|
||||
this.setAttribute("fill", rgb);
|
||||
this.setAttribute("data-height", height);
|
||||
});
|
||||
|
|
@ -1090,7 +1087,7 @@ function editHeightmap() {
|
|||
const colorTo = color(1 - (normalized < .2 ? normalized-.05 : normalized));
|
||||
const heightTo = normalized * 100;
|
||||
|
||||
heights.selectAll("polygon[fill='" + colorFrom + "']").attr("fill", colorTo).attr("data-height", heightTo);
|
||||
viewbox.select("#heights").selectAll("polygon[fill='" + colorFrom + "']").attr("fill", colorTo).attr("data-height", heightTo);
|
||||
el.style.backgroundColor = colorTo;
|
||||
el.setAttribute("data-color", colorTo);
|
||||
el.setAttribute("data-height", heightTo);
|
||||
|
|
@ -1127,13 +1124,13 @@ function editHeightmap() {
|
|||
viewbox.style("cursor", "default").on(".drag", null);
|
||||
tip('Heightmap edit mode is active. Click on "Exit Customization" to finalize the heightmap', true);
|
||||
|
||||
heights.selectAll("polygon").each(function() {
|
||||
viewbox.select("#heights").selectAll("polygon").each(function() {
|
||||
const height = +this.getAttribute("data-height") || 0;
|
||||
const i = +this.id.slice(4);
|
||||
grid.cells.h[i] = height;
|
||||
});
|
||||
|
||||
heights.selectAll("polygon").remove();
|
||||
viewbox.select("#heights").selectAll("polygon").remove();
|
||||
updateHeightmap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,7 +461,9 @@ function drawCells() {
|
|||
}
|
||||
|
||||
function toggleCultures(event) {
|
||||
if (!cults.selectAll("path").size()) {
|
||||
const cultures = pack.cultures.filter(c => c.i && !c.removed);
|
||||
const empty = !cults.selectAll("path").size();
|
||||
if (empty && cultures.length) {
|
||||
turnButtonOn("toggleCultures");
|
||||
drawCultures();
|
||||
if (event && event.ctrlKey) editStyle("cults");
|
||||
|
|
@ -472,7 +474,7 @@ function toggleCultures(event) {
|
|||
}
|
||||
}
|
||||
|
||||
function drawCultures(event) {
|
||||
function drawCultures() {
|
||||
console.time("drawCultures");
|
||||
|
||||
cults.selectAll("path").remove();
|
||||
|
|
@ -520,7 +522,8 @@ function drawCultures(event) {
|
|||
}
|
||||
|
||||
function toggleReligions(event) {
|
||||
if (!relig.selectAll("path").size()) {
|
||||
const religions = pack.religions.filter(r => r.i && !r.removed);
|
||||
if (!relig.selectAll("path").size() && religions.length) {
|
||||
turnButtonOn("toggleReligions");
|
||||
drawReligions();
|
||||
if (event && event.ctrlKey) editStyle("relig");
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ function drawScaleBar() {
|
|||
fitScaleBar();
|
||||
}
|
||||
|
||||
// fit ScaleBar to map size
|
||||
// fit ScaleBar to canvas size
|
||||
function fitScaleBar() {
|
||||
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
|
||||
const px = isNaN(+barPosX.value) ? .99 : barPosX.value / 100;
|
||||
|
|
|
|||
|
|
@ -133,26 +133,33 @@ function mapSizeInputChange() {
|
|||
|
||||
// change svg size on manual size change or window resize, do not change graph size
|
||||
function changeMapSize() {
|
||||
svgWidth = +mapWidthInput.value;
|
||||
svgHeight = +mapHeightInput.value;
|
||||
const svgWidth = Math.min(+mapWidthInput.value, window.innerWidth);
|
||||
const svgHeight = Math.min(+mapHeightInput.value, window.innerHeight);
|
||||
svg.attr("width", svgWidth).attr("height", svgHeight);
|
||||
const width = Math.max(svgWidth, graphWidth);
|
||||
const height = Math.max(svgHeight, graphHeight);
|
||||
zoom.translateExtent([[0, 0], [width, height]]);
|
||||
landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
|
||||
oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
|
||||
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
|
||||
|
||||
const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
|
||||
const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
|
||||
zoom.translateExtent([[0, 0], [maxWidth, maxHeight]]);
|
||||
landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
defs.select("#mapClip > rect").attr("width", maxWidth).attr("height", maxHeight);
|
||||
|
||||
fitScaleBar();
|
||||
if (window.fitLegendBox) fitLegendBox();
|
||||
}
|
||||
|
||||
// just apply map size that was already set, apply graph size!
|
||||
// just apply canvas size that was already set
|
||||
function applyMapSize() {
|
||||
svgWidth = graphWidth = +mapWidthInput.value;
|
||||
svgHeight = graphHeight = +mapHeightInput.value;
|
||||
graphWidth = +mapWidthInput.value;
|
||||
graphHeight = +mapHeightInput.value;
|
||||
svgWidth = Math.min(graphWidth, window.innerWidth)
|
||||
svgHeight = Math.min(graphHeight, window.innerHeight)
|
||||
svg.attr("width", svgWidth).attr("height", svgHeight);
|
||||
zoom.translateExtent([[0, 0],[graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1);
|
||||
viewbox.attr("transform", null);
|
||||
viewbox.attr("transform", null).attr("clip-path", "url(#mapClip)");
|
||||
defs.append("clipPath").attr("id", "mapClip").append("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
//zoom.translateExtent([[-svgWidth*.2, -graphHeight*.2], [svgWidth*1.2, graphHeight*1.2]]);
|
||||
}
|
||||
|
||||
function toggleFullscreen() {
|
||||
|
|
|
|||
|
|
@ -57,11 +57,12 @@ function editProvinces() {
|
|||
}
|
||||
|
||||
function collectStatistics() {
|
||||
const cells = pack.cells, provinces = pack.provinces;
|
||||
const cells = pack.cells, provinces = pack.provinces, burgs = pack.burgs;
|
||||
provinces.forEach(p => {
|
||||
if (!p.i || p.removed) return;
|
||||
p.area = p.rural = p.urban = 0;
|
||||
p.burgs = [];
|
||||
if (p.burg && !burgs[p.burg] || burgs[p.burg].removed) p.burg = 0;
|
||||
});
|
||||
|
||||
for (const i of cells.i) {
|
||||
|
|
@ -71,7 +72,7 @@ function editProvinces() {
|
|||
provinces[p].area += cells.area[i];
|
||||
provinces[p].rural += cells.pop[i];
|
||||
if (!cells.burg[i]) continue;
|
||||
provinces[p].urban += pack.burgs[cells.burg[i]].population;
|
||||
provinces[p].urban += burgs[cells.burg[i]].population;
|
||||
provinces[p].burgs.push(cells.burg[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,6 +360,7 @@ function editReligions() {
|
|||
// build hierarchy tree
|
||||
pack.religions[0].origin = null;
|
||||
const religions = pack.religions.filter(r => !r.removed);
|
||||
if (religions.length < 3) {tip("Not enough religions to show hierarchy", false, "error"); return;}
|
||||
const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(religions);
|
||||
const treeWidth = root.leaves().length;
|
||||
const treeHeight = root.height;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -15,10 +15,11 @@ toolsContent.addEventListener("click", function(event) {
|
|||
if (button === "editCulturesButton") editCultures(); else
|
||||
if (button === "editReligions") editReligions(); else
|
||||
if (button === "editNamesBaseButton") editNamesbase(); else
|
||||
if (button === "overviewBurgsButton") editBurgs(); else
|
||||
if (button === "editUnitsButton") editUnits(); else
|
||||
if (button === "editNotesButton") editNotes(); else
|
||||
if (button === "editZonesButton") editZones();
|
||||
if (button === "editZonesButton") editZones(); else
|
||||
if (button === "overviewBurgsButton") editBurgs(); else
|
||||
if (button === "overviewCellsButton") viewCellDetails();
|
||||
|
||||
// Click to Regenerate buttons
|
||||
if (event.target.parentNode.id === "regenerateFeature") {
|
||||
|
|
@ -90,7 +91,8 @@ function regenerateBurgs() {
|
|||
rankCells();
|
||||
cells.burg = new Uint16Array(cells.i.length);
|
||||
const burgs = pack.burgs = [0]; // clear burgs array
|
||||
states.filter(s => s.i).forEach(s => s.capital = 0); // clear capitals
|
||||
states.filter(s => s.i).forEach(s => s.capital = 0); // clear state capitals
|
||||
pack.provinces.filter(p => p.i).forEach(p => p.burg = 0); // clear province capitals
|
||||
const burgsTree = d3.quadtree();
|
||||
|
||||
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement
|
||||
|
|
@ -477,4 +479,8 @@ function addMarkerOnClick() {
|
|||
.attr("data-size", desired).attr("width", size).attr("height", size);
|
||||
|
||||
if (d3.event.shiftKey === false) unpressClickToAddButton();
|
||||
}
|
||||
|
||||
function viewCellDetails() {
|
||||
$("#cellInfo").dialog({resizable: false, width: "22em", title: "Cell Details"});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue