mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
v1.4.14
This commit is contained in:
parent
6dd1e22e93
commit
2a67ee5d9f
14 changed files with 1010 additions and 267 deletions
|
|
@ -271,10 +271,14 @@
|
|||
|
||||
// remove river and all its tributaries
|
||||
const remove = function(id) {
|
||||
const cells = pack.cells;
|
||||
const riversToRemove = pack.rivers.filter(r => r.i === id || getBasin(r.i, r.parent, id) === id).map(r => r.i);
|
||||
riversToRemove.forEach(r => rivers.select("#river"+r).remove());
|
||||
pack.cells.r.forEach((r, i) => {
|
||||
if (r && riversToRemove.includes(r)) pack.cells.r[i] = 0;
|
||||
cells.r.forEach((r, i) => {
|
||||
if (!r || !riversToRemove.includes(r)) return;
|
||||
cells.r[i] = 0;
|
||||
cells.fl[i] = grid.cells.prec[cells.g[i]];
|
||||
cells.conf[i] = 0;
|
||||
});
|
||||
pack.rivers = pack.rivers.filter(r => !riversToRemove.includes(r.i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,14 +294,6 @@ async function saveMap() {
|
|||
link.click();
|
||||
tip(`${link.download} is saved. Open "Downloads" screen (CTRL + J) to check`, true, "success", 7000);
|
||||
window.URL.revokeObjectURL(URL);
|
||||
|
||||
// send saved files count and size to server for usage analysis (for the future Cloud storage)
|
||||
publicstorage.get("fmg").then(fmg => {
|
||||
if (!fmg) return;
|
||||
fmg.size = (fmg.size * fmg.maps + blob.size) / (fmg.maps + 1);
|
||||
fmg.maps += 1;
|
||||
publicstorage.set("fmg", fmg).then(fmg => console.log(fmg));
|
||||
});
|
||||
}
|
||||
|
||||
// Send .map file to server [test function]
|
||||
|
|
|
|||
|
|
@ -111,12 +111,6 @@ function applySorting(headers) {
|
|||
}).forEach(line => list.appendChild(line));
|
||||
}
|
||||
|
||||
// trigger trash button click on "Delete" keypress
|
||||
function removeElementOnKey() {
|
||||
$(".dialog:visible .icon-trash").click();
|
||||
$("button:visible:contains('Remove')").click();
|
||||
}
|
||||
|
||||
function addBurg(point) {
|
||||
const cells = pack.cells;
|
||||
const x = rn(point[0], 2), y = rn(point[1], 2);
|
||||
|
|
|
|||
|
|
@ -462,4 +462,10 @@ function pressControl() {
|
|||
if (zonesRemove.offsetParent) {
|
||||
zonesRemove.classList.contains("pressed") ? zonesRemove.classList.remove("pressed") : zonesRemove.classList.add("pressed");
|
||||
}
|
||||
}
|
||||
|
||||
// trigger trash button click on "Delete" keypress
|
||||
function removeElementOnKey() {
|
||||
$(".dialog:visible .fastDelete").click();
|
||||
$("button:visible:contains('Remove')").click();
|
||||
}
|
||||
|
|
@ -21,7 +21,6 @@ function editHeightmap() {
|
|||
});
|
||||
}()
|
||||
|
||||
let edits = [];
|
||||
restartHistory();
|
||||
viewbox.insert("g", "#terrs").attr("id", "heights");
|
||||
|
||||
|
|
@ -131,6 +130,10 @@ function editHeightmap() {
|
|||
return;
|
||||
}
|
||||
|
||||
delete window.edits; // remove global variable
|
||||
redo.disabled = templateRedo.disabled = true;
|
||||
undo.disabled = templateUndo.disabled = true;
|
||||
|
||||
customization = 0;
|
||||
customizationMenu.style.display = "none";
|
||||
if (document.getElementById("options").querySelector(".tab > button.active").id === "toolsTab") toolsContent.style.display = "block";
|
||||
|
|
@ -141,7 +144,6 @@ function editHeightmap() {
|
|||
closeDialogs();
|
||||
resetZoom();
|
||||
|
||||
restartHistory();
|
||||
if (document.getElementById("preview")) document.getElementById("preview").remove();
|
||||
if (document.getElementById("canvas3d")) enterStandardView();
|
||||
|
||||
|
|
@ -316,9 +318,7 @@ function editHeightmap() {
|
|||
const land = pack.cells.h[i] >= 20;
|
||||
|
||||
// check biome
|
||||
if (!biome[g]) pack.cells.biome[i] = getBiomeId(grid.cells.prec[g], grid.cells.temp[g]);
|
||||
else if (!land && biome[g]) pack.cells.biome[i] = 0;
|
||||
else pack.cells.biome[i] = biome[g];
|
||||
pack.cells.biome[i] = land && biome[g] ? biome[g] : getBiomeId(grid.cells.prec[g], pack.cells.h[i]);
|
||||
|
||||
// rivers data
|
||||
if (!changeHeights.checked) {
|
||||
|
|
@ -482,8 +482,8 @@ function editHeightmap() {
|
|||
|
||||
// restart edits from 1st step
|
||||
function restartHistory() {
|
||||
edits = [];
|
||||
edits.n = 0;
|
||||
window.edits = []; // declare temp global variable
|
||||
window.edits.n = 0;
|
||||
redo.disabled = templateRedo.disabled = true;
|
||||
undo.disabled = templateUndo.disabled = true;
|
||||
updateHistory();
|
||||
|
|
@ -503,7 +503,7 @@ function editHeightmap() {
|
|||
document.getElementById("brushesButtons").addEventListener("click", e => toggleBrushMode(e));
|
||||
document.getElementById("changeOnlyLand").addEventListener("click", e => changeOnlyLandClick(e));
|
||||
document.getElementById("undo").addEventListener("click", () => restoreHistory(edits.n-1));
|
||||
document.getElementById("redo").addEventListener("click", () => restoreHistory(edits.n+1));
|
||||
document.getElementById("redo").addEventListener("click", () => restoreHistory(edits.n+1));
|
||||
document.getElementById("rescaleShow").addEventListener("click", () => {
|
||||
document.getElementById("modifyButtons").style.display = "none";
|
||||
document.getElementById("rescaleSection").style.display = "block";
|
||||
|
|
@ -986,7 +986,7 @@ function editHeightmap() {
|
|||
setOverlayOpacity(0);
|
||||
|
||||
document.getElementById("convertImageLoad").classList.add("glow"); // add glow effect
|
||||
tip('Image Converter is opened. Upload the image and assign the height for each of the colors', true, "warn"); // main tip
|
||||
tip('Image Converter is opened. Upload the image and assign height value for each of the colors', true, "warn"); // main tip
|
||||
|
||||
// remove all heights
|
||||
grid.cells.h = new Uint8Array(grid.cells.i.length);
|
||||
|
|
@ -998,8 +998,8 @@ function editHeightmap() {
|
|||
|
||||
// add color pallete
|
||||
void function createColorPallete() {
|
||||
const container = d3.select("#colorScheme");
|
||||
container.selectAll("div").data(d3.range(101)).enter().append("div").attr("data-color", i => i)
|
||||
d3.select("#imageConverterPalette").selectAll("div").data(d3.range(101))
|
||||
.enter().append("div").attr("data-color", i => i)
|
||||
.style("background-color", i => color(1-(i < 20 ? i-5 : i) / 100))
|
||||
.style("width", i => i < 20 || i > 70 ? ".2em" : ".1em")
|
||||
.on("touchmove mousemove", showPalleteHeight).on("click", assignHeight);
|
||||
|
|
@ -1020,7 +1020,7 @@ function editHeightmap() {
|
|||
const height = +this.getAttribute("data-color");
|
||||
colorsSelectValue.innerHTML = height;
|
||||
colorsSelectFriendly.innerHTML = getHeight(height);
|
||||
const former = colorScheme.querySelector(".hoveredColor")
|
||||
const former = imageConverterPalette.querySelector(".hoveredColor")
|
||||
if (former) former.className = "";
|
||||
this.className = "hoveredColor";
|
||||
}
|
||||
|
|
@ -1038,14 +1038,15 @@ function editHeightmap() {
|
|||
convertImageLoad.classList.remove("glow");
|
||||
};
|
||||
|
||||
reader.onloadend = function() {img.src = reader.result;};
|
||||
reader.onloadend = () => img.src = reader.result;
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
function heightsFromImage(count) {
|
||||
const ctx = document.getElementById("canvas").getContext("2d");
|
||||
const imageData = ctx.getImageData(0, 0, graphWidth, graphHeight);
|
||||
const data = imageData.data;
|
||||
const q = new RgbQuant({colors:count});
|
||||
q.sample(ctx);
|
||||
const data = q.reduce(ctx);
|
||||
|
||||
viewbox.select("#heights").selectAll("*").remove();
|
||||
d3.select("#imageConverter").selectAll("div.color-div").remove();
|
||||
|
|
@ -1053,27 +1054,22 @@ function editHeightmap() {
|
|||
colorsUnassigned.style.display = "block";
|
||||
colorsAssigned.style.display = "none";
|
||||
|
||||
const gridColors = grid.points.map(p => {
|
||||
let usedColors = new Set();
|
||||
let gridColors = grid.points.map(p => {
|
||||
const x = Math.floor(p[0]-.01), y = Math.floor(p[1]-.01);
|
||||
const i = (x + y * graphWidth) * 4;
|
||||
const r = data[i], g = data[i+1], b = data[i+2];
|
||||
usedColors.add(`rgb(${r},${g},${b})`);
|
||||
return [r, g, b];
|
||||
});
|
||||
|
||||
const cmap = MMCQ.quantize(gridColors, count);
|
||||
const usedColors = new Set();
|
||||
|
||||
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])})`;
|
||||
usedColors.add(clr);
|
||||
return clr;
|
||||
}).on("click", mapClicked);
|
||||
.attr("id", d => "cell"+d).attr("fill", d => `rgb(${gridColors[d].join(",")})`)
|
||||
.on("click", mapClicked);
|
||||
|
||||
const unassigned = [...usedColors].sort((a, b) => d3.lab(a).l - d3.lab(b).l);
|
||||
const unassignedContainer = d3.select("#colorsUnassigned");
|
||||
unassignedContainer.selectAll("div").data(unassigned).enter().append("div")
|
||||
d3.select("#colorsUnassigned").selectAll("div").data(unassigned).enter().append("div")
|
||||
.attr("data-color", i => i).style("background-color", i => i)
|
||||
.attr("class", "color-div").on("click", colorClicked);
|
||||
|
||||
|
|
@ -1092,7 +1088,7 @@ function editHeightmap() {
|
|||
|
||||
const selectedColor = imageConverter.querySelector("div.selectedColor");
|
||||
if (selectedColor) selectedColor.classList.remove("selectedColor");
|
||||
const hoveredColor = colorScheme.querySelector("div.hoveredColor");
|
||||
const hoveredColor = imageConverterPalette.querySelector("div.hoveredColor");
|
||||
if (hoveredColor) hoveredColor.classList.remove("hoveredColor");
|
||||
colorsSelectValue.innerHTML = colorsSelectFriendly.innerHTML = 0;
|
||||
|
||||
|
|
@ -1101,7 +1097,7 @@ function editHeightmap() {
|
|||
|
||||
if (this.dataset.height) {
|
||||
const height = +this.dataset.height;
|
||||
colorScheme.querySelector(`div[data-color="${height}"]`).classList.add("hoveredColor");
|
||||
imageConverterPalette.querySelector(`div[data-color="${height}"]`).classList.add("hoveredColor");
|
||||
colorsSelectValue.innerHTML = height;
|
||||
colorsSelectFriendly.innerHTML = getHeight(height);
|
||||
}
|
||||
|
|
@ -1142,8 +1138,8 @@ function editHeightmap() {
|
|||
const lab = d3.lab(colorFrom);
|
||||
const normalized = type === "hue" ? rn(normalize(lab.b + lab.a / 2, -50, 200), 2) : rn(normalize(lab.l, -15, 100), 2);
|
||||
let heightTo = rn(normalized * 100);
|
||||
if (assinged[heightTo] && heightTo < 100) heightTo += 1; // if height is already added, try increated one
|
||||
if (assinged[heightTo] && heightTo < 100) heightTo += 1; // if height is already added, try increated one
|
||||
if (assinged[heightTo] && heightTo < 100) heightTo += 1; // if height is already added, try increased one
|
||||
if (assinged[heightTo] && heightTo < 100) heightTo += 1; // if height is already added, try increased one
|
||||
if (assinged[heightTo] && heightTo > 3) heightTo -= 3; // if increased one is also added, try decreased one
|
||||
if (assinged[heightTo] && heightTo > 1) heightTo -= 1; // if increased one is also added, try decreased one
|
||||
|
||||
|
|
@ -1158,16 +1154,16 @@ function editHeightmap() {
|
|||
});
|
||||
|
||||
// sort assigned colors by height
|
||||
Array.from(colorsAssigned.children).sort((a, b) => {
|
||||
return +a.dataset.height - +b.dataset.height;
|
||||
}).forEach(line => colorsAssigned.appendChild(line));
|
||||
Array.from(colorsAssigned.children)
|
||||
.sort((a, b) => +a.dataset.height - +b.dataset.height)
|
||||
.forEach(line => colorsAssigned.appendChild(line));
|
||||
|
||||
colorsAssigned.style.display = "block";
|
||||
colorsUnassigned.style.display = "none";
|
||||
}
|
||||
|
||||
function setConvertColorsNumber() {
|
||||
prompt(`Please provide a desired number of colors. <br>An actual number depends on color scheme and may vary from desired`,
|
||||
prompt(`Please set maximum number of colors. <br>An actual number is lower and depends on color scheme`,
|
||||
{default:+convertColors.value, step:1, min:3, max:255}, number => {
|
||||
convertColors.value = number;
|
||||
heightsFromImage(number);
|
||||
|
|
|
|||
|
|
@ -135,14 +135,18 @@ function editMarker() {
|
|||
const id = elSelected.attr("data-id");
|
||||
const used = document.querySelectorAll("use[data-id='"+id+"']");
|
||||
const count = used.length === 1 ? "1 element" : used.length + " elements";
|
||||
alertMessage.innerHTML = "Are you sure you want to remove the marker (" + count + ")?";
|
||||
alertMessage.innerHTML = "Are you sure you want to remove all markers of that type (" + count + ")?";
|
||||
|
||||
$("#alert").dialog({resizable: false, title: "Remove marker",
|
||||
$("#alert").dialog({resizable: false, title: "Remove marker type",
|
||||
buttons: {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
if (id !== "#marker0") d3.select("#defs-markers").select(id).remove();
|
||||
used.forEach(e => e.remove());
|
||||
used.forEach(e => {
|
||||
const index = notes.findIndex(n => n.id === e.id);
|
||||
if (index != -1) notes.splice(index, 1);
|
||||
e.remove();
|
||||
});
|
||||
updateGroupOptions();
|
||||
updateGroupOptions();
|
||||
$("#markerEditor").dialog("close");
|
||||
|
|
@ -187,12 +191,6 @@ function editMarker() {
|
|||
d3.select("#defs-markers").select(id).select("text").attr("y", this.value + "%");
|
||||
}
|
||||
|
||||
function applyCustomUnicodeIcon() {
|
||||
if (!this.value) return;
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers").select(id).select("text").text(this.value);
|
||||
}
|
||||
|
||||
function toggleStyleSection() {
|
||||
if (markerStyleSection.style.display === "inline-block") {
|
||||
markerEditor.querySelectorAll("button:not(#markerStyle)").forEach(b => b.style.display = "inline-block");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function editNotes(id, name) {
|
|||
document.getElementById("notesDownload").addEventListener("click", downloadLegends);
|
||||
document.getElementById("notesUpload").addEventListener("click", () => legendsToLoad.click());
|
||||
document.getElementById("legendsToLoad").addEventListener("change", function() {uploadFile(this, uploadLegends)});
|
||||
document.getElementById("notesRemove").addEventListener("click", triggernotesRemove);
|
||||
document.getElementById("notesRemove").addEventListener("click", triggerNotesRemove);
|
||||
|
||||
function changeObject() {
|
||||
const note = notes.find(note => note.id === this.value);
|
||||
|
|
@ -96,7 +96,7 @@ function editNotes(id, name) {
|
|||
editNotes(notes[0].id, notes[0].name);
|
||||
}
|
||||
|
||||
function triggernotesRemove() {
|
||||
function triggerNotesRemove() {
|
||||
alertMessage.innerHTML = "Are you sure you want to remove the selected note?";
|
||||
$("#alert").dialog({resizable: false, title: "Remove note",
|
||||
buttons: {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ function editProvinces() {
|
|||
const capital = p.burg ? pack.burgs[p.burg].name : '';
|
||||
const separable = p.burg && p.burg !== pack.states[p.state].capital;
|
||||
const focused = defs.select("#fog #focusProvince"+p.i).size();
|
||||
lines += `<div class="states" data-id=${p.i} data-name=${p.name} data-form=${p.formName} data-color="${p.color}" data-capital="${capital}" data-state="${stateName}" data-area=${area} data-population=${population}>
|
||||
lines += `<div class="states" data-id=${p.i} data-name="${p.name}" data-form="${p.formName}" data-color="${p.color}" data-capital="${capital}" data-state="${stateName}" data-area=${area} data-population=${population}>
|
||||
<svg data-tip="Province fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${p.color}" class="fillRect pointer"></svg>
|
||||
<input data-tip="Province name. Click to change" class="name pointer" value="${p.name}" readonly>
|
||||
<span data-tip="Click to open province COA in the Iron Arachne Heraldry Generator. Ctrl + click to change the seed" class="icon-coa pointer hide"></span>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue