mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
* Scale bar styling (#1025) * feat: style scale bar * feat: style scale bar - style presets --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com> * Ocean heightmap to v1.96 (#1044) * feat: allow to render ocean heightmap * feat: allow to render ocean heightmap - test * feat: allow to render ocean heightmap - fix issue * feat: allow to render ocean heightmap - cleanup --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com> * fix: scale bar size * fix: remove mask on terrs lavel * fix: regenerate heigtmap preview to use current graph size * Add the name of culture and namesbase in the name editor dialog (#1033) * Add the name of culture and namesbase in the name editor dialog Added the name of the culture and namesbase in the dialog "name editor". This tells information on the "click to generate a culture-specific name" It tells you the culture before changing name. * cultureName into cultureId + cultureName And deleted the incomplete code of showing culture name on datatip * refactor: leave culture name only --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com> * Added Burgs column to province editor (#1031) * Added Burgs column to province editor Added to province editor: + Burgs column + the number of Burgs, p.burgs.length + "icon-dot-circled" to go to overviewBurgs. + overviewBurgs Filtered by state id. + Fixed some typos. * fixed code as Azgaar suggested + Corrected provincesHeader distance in em. + const stateId = pack.provinces[p].state; - Deleted cell count. * deleted HTML code for provincesFooter cells - Deleted Total land cells number HTML from provincesFooter. * deleting totalCells in the code, maybe i will add provinceCells in the future. Deleted lines for const totalCells and for (+cells / totalCells) * 100 + "%"; * refactor: cleanup * refactor: cleanup --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com> * fix: burgs overview - add MFCG link back * feat: add more details to burgs export * feat: don't show auto-update dialog * feat: pump version * fix: #1041 * feat: update style presets --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com> Co-authored-by: Ángel Montero Lamas <angel.montero1@gmail.com>
319 lines
9.6 KiB
JavaScript
319 lines
9.6 KiB
JavaScript
const initialSeed = generateSeed();
|
||
let graph = getGraph(grid);
|
||
|
||
appendStyleSheet();
|
||
insertHtml();
|
||
addListeners();
|
||
|
||
export function open() {
|
||
closeDialogs(".stable");
|
||
|
||
const $templateInput = byId("templateInput");
|
||
setSelected($templateInput.value);
|
||
graph = getGraph(graph);
|
||
|
||
$("#heightmapSelection").dialog({
|
||
title: "Select Heightmap",
|
||
resizable: false,
|
||
position: {my: "center", at: "center", of: "svg"},
|
||
buttons: {
|
||
Cancel: function () {
|
||
$(this).dialog("close");
|
||
},
|
||
Select: function () {
|
||
const id = getSelected();
|
||
applyOption($templateInput, id, getName(id));
|
||
lock("template");
|
||
|
||
$(this).dialog("close");
|
||
},
|
||
"New Map": function () {
|
||
const id = getSelected();
|
||
applyOption($templateInput, id, getName(id));
|
||
lock("template");
|
||
|
||
const seed = getSeed();
|
||
regeneratePrompt({seed, graph});
|
||
|
||
$(this).dialog("close");
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function appendStyleSheet() {
|
||
const style = document.createElement("style");
|
||
style.textContent = /* css */ `
|
||
div.dialog > div.heightmap-selection {
|
||
width: 70vw;
|
||
height: 70vh;
|
||
}
|
||
|
||
.heightmap-selection_container {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||
grid-gap: 6px;
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.heightmap-selection_container {
|
||
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
||
grid-gap: 4px;
|
||
}
|
||
}
|
||
|
||
@media (min-width: 2000px) {
|
||
.heightmap-selection_container {
|
||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||
grid-gap: 8px;
|
||
}
|
||
}
|
||
|
||
.heightmap-selection_options {
|
||
display: grid;
|
||
grid-template-columns: 2fr 1fr;
|
||
}
|
||
|
||
.heightmap-selection_options > div:first-child {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
align-items: center;
|
||
justify-self: start;
|
||
justify-items: start;
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.heightmap-selection_options {
|
||
grid-template-columns: 3fr 1fr;
|
||
}
|
||
|
||
.heightmap-selection_options > div:first-child {
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
.heightmap-selection_options > div:last-child {
|
||
justify-self: end;
|
||
}
|
||
|
||
.heightmap-selection article {
|
||
padding: 4px;
|
||
border-radius: 8px;
|
||
transition: all 0.1s ease-in-out;
|
||
filter: drop-shadow(1px 1px 4px #999);
|
||
}
|
||
|
||
.heightmap-selection article:hover {
|
||
background-color: #ddd;
|
||
filter: drop-shadow(1px 1px 8px #999);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.heightmap-selection article.selected {
|
||
background-color: #ccc;
|
||
outline: 1px solid var(--dark-solid);
|
||
filter: drop-shadow(1px 1px 8px #999);
|
||
}
|
||
|
||
.heightmap-selection article > div {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 2px 1px;
|
||
}
|
||
|
||
.heightmap-selection article > img {
|
||
width: 100%;
|
||
aspect-ratio: ${graphWidth}/${graphHeight};
|
||
border-radius: 8px;
|
||
object-fit: fill;
|
||
}
|
||
|
||
.heightmap-selection article .regeneratePreview {
|
||
outline: 1px solid #bbb;
|
||
padding: 1px 3px;
|
||
border-radius: 4px;
|
||
transition: all 0.1s ease-in-out;
|
||
}
|
||
|
||
.heightmap-selection article .regeneratePreview:hover {
|
||
outline: 1px solid #666;
|
||
}
|
||
|
||
.heightmap-selection article .regeneratePreview:active {
|
||
outline: 1px solid #333;
|
||
color: #000;
|
||
transform: rotate(45deg);
|
||
}
|
||
`;
|
||
|
||
document.head.appendChild(style);
|
||
}
|
||
|
||
function insertHtml() {
|
||
const heightmapColorSchemeOptions = Object.keys(heightmapColorSchemes)
|
||
.map(scheme => `<option value="${scheme}">${scheme}</option>`)
|
||
.join("");
|
||
|
||
const heightmapSelectionHtml = /* html */ `<div id="heightmapSelection" class="dialog stable">
|
||
<div class="heightmap-selection">
|
||
<section data-tip="Select heightmap template – template provides unique, but similar-looking maps on generation">
|
||
<header><h1>Heightmap templates</h1></header>
|
||
<div class="heightmap-selection_container"></div>
|
||
</section>
|
||
<section data-tip="Select precreated heightmap – it will be the same for each map">
|
||
<header><h1>Precreated heightmaps</h1></header>
|
||
<div class="heightmap-selection_container"></div>
|
||
</section>
|
||
<section>
|
||
<header><h1>Options</h1></header>
|
||
<div class="heightmap-selection_options">
|
||
<div>
|
||
<label data-tip="Rerender all preview images" class="checkbox-label" id="heightmapSelectionRedrawPreview">
|
||
<i class="icon-cw"></i>
|
||
Redraw preview
|
||
</label>
|
||
<div>
|
||
<input id="heightmapSelectionRenderOcean" class="checkbox" type="checkbox" />
|
||
<label data-tip="Draw heights of water cells" for="heightmapSelectionRenderOcean" class="checkbox-label">Render ocean heights</label>
|
||
</div>
|
||
<div data-tip="Color scheme used for heightmap preview">
|
||
Color scheme
|
||
<select id="heightmapSelectionColorScheme">${heightmapColorSchemeOptions}</select>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<button data-tip="Open Template Editor" data-tool="templateEditor" id="heightmapSelectionEditTemplates">Edit Templates</button>
|
||
<button data-tip="Open Image Converter" data-tool="imageConverter" id="heightmapSelectionImportHeightmap">Import Heightmap</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>`;
|
||
|
||
byId("dialogs").insertAdjacentHTML("beforeend", heightmapSelectionHtml);
|
||
|
||
const sections = document.getElementsByClassName("heightmap-selection_container");
|
||
|
||
sections[0].innerHTML = Object.keys(heightmapTemplates)
|
||
.map(key => {
|
||
const name = heightmapTemplates[key].name;
|
||
Math.random = aleaPRNG(initialSeed);
|
||
const heights = HeightmapGenerator.fromTemplate(graph, key);
|
||
|
||
return /* html */ `<article data-id="${key}" data-seed="${initialSeed}">
|
||
<img src="${getHeightmapPreview(heights)}" alt="${name}" />
|
||
<div>
|
||
${name}
|
||
<span data-tip="Regenerate preview" class="icon-cw regeneratePreview"></span>
|
||
</div>
|
||
</article>`;
|
||
})
|
||
.join("");
|
||
|
||
sections[1].innerHTML = Object.keys(precreatedHeightmaps)
|
||
.map(key => {
|
||
const name = precreatedHeightmaps[key].name;
|
||
drawPrecreatedHeightmap(key);
|
||
|
||
return /* html */ `<article data-id="${key}" data-seed="${initialSeed}">
|
||
<img alt="${name}" />
|
||
<div>${name}</div>
|
||
</article>`;
|
||
})
|
||
.join("");
|
||
}
|
||
|
||
function addListeners() {
|
||
byId("heightmapSelection").on("click", event => {
|
||
const article = event.target.closest("#heightmapSelection article");
|
||
if (!article) return;
|
||
|
||
const id = article.dataset.id;
|
||
if (event.target.matches("span.icon-cw")) regeneratePreview(article, id);
|
||
setSelected(id);
|
||
});
|
||
|
||
byId("heightmapSelectionRenderOcean").on("change", redrawAll);
|
||
byId("heightmapSelectionColorScheme").on("change", redrawAll);
|
||
byId("heightmapSelectionRedrawPreview").on("click", redrawAll);
|
||
byId("heightmapSelectionEditTemplates").on("click", confirmHeightmapEdit);
|
||
byId("heightmapSelectionImportHeightmap").on("click", confirmHeightmapEdit);
|
||
}
|
||
|
||
function getSelected() {
|
||
return byId("heightmapSelection").querySelector(".selected")?.dataset?.id;
|
||
}
|
||
|
||
function setSelected(id) {
|
||
const $heightmapSelection = byId("heightmapSelection");
|
||
$heightmapSelection.querySelector(".selected")?.classList?.remove("selected");
|
||
$heightmapSelection.querySelector(`[data-id="${id}"]`)?.classList?.add("selected");
|
||
}
|
||
|
||
function getSeed() {
|
||
return byId("heightmapSelection").querySelector(".selected")?.dataset?.seed;
|
||
}
|
||
|
||
function getName(id) {
|
||
const isTemplate = id in heightmapTemplates;
|
||
return isTemplate ? heightmapTemplates[id].name : precreatedHeightmaps[id].name;
|
||
}
|
||
|
||
function getGraph(currentGraph) {
|
||
const newGraph = shouldRegenerateGrid(currentGraph, seed) ? generateGrid() : deepCopy(currentGraph);
|
||
delete newGraph.cells.h;
|
||
return newGraph;
|
||
}
|
||
|
||
function drawTemplatePreview(id) {
|
||
const heights = HeightmapGenerator.fromTemplate(graph, id);
|
||
const dataUrl = getHeightmapPreview(heights);
|
||
const article = byId("heightmapSelection").querySelector(`[data-id="${id}"]`);
|
||
article.querySelector("img").src = dataUrl;
|
||
}
|
||
|
||
async function drawPrecreatedHeightmap(id) {
|
||
const heights = await HeightmapGenerator.fromPrecreated(graph, id);
|
||
const dataUrl = getHeightmapPreview(heights);
|
||
const article = byId("heightmapSelection").querySelector(`[data-id="${id}"]`);
|
||
article.querySelector("img").src = dataUrl;
|
||
}
|
||
|
||
function regeneratePreview(article, id) {
|
||
graph = getGraph(graph);
|
||
const seed = generateSeed();
|
||
article.dataset.seed = seed;
|
||
Math.random = aleaPRNG(seed);
|
||
drawTemplatePreview(id);
|
||
}
|
||
|
||
function redrawAll() {
|
||
graph = getGraph(graph);
|
||
const articles = byId("heightmapSelection").querySelectorAll(`article`);
|
||
for (const article of articles) {
|
||
const {id, seed} = article.dataset;
|
||
Math.random = aleaPRNG(seed);
|
||
|
||
const isTemplate = id in heightmapTemplates;
|
||
if (isTemplate) drawTemplatePreview(id);
|
||
else drawPrecreatedHeightmap(id);
|
||
}
|
||
}
|
||
|
||
function confirmHeightmapEdit() {
|
||
const tool = this.dataset.tool;
|
||
|
||
confirmationDialog({
|
||
title: this.dataset.tip,
|
||
message: "Opening the tool will erase the current map. Are you sure you want to proceed?",
|
||
confirm: "Continue",
|
||
onConfirm: () => editHeightmap({mode: "erase", tool})
|
||
});
|
||
}
|
||
|
||
function getHeightmapPreview(heights) {
|
||
const scheme = getColorScheme(byId("heightmapSelectionColorScheme").value);
|
||
const renderOcean = byId("heightmapSelectionRenderOcean").checked;
|
||
const dataUrl = drawHeights({heights, width: graph.cellsX, height: graph.cellsY, scheme, renderOcean});
|
||
return dataUrl;
|
||
}
|