Merge branch 'master' of https://github.com/Azgaar/Fantasy-Map-Generator into urquhart-routes

This commit is contained in:
Azgaar 2024-07-29 15:40:28 +02:00
commit c4370774e4
27 changed files with 423 additions and 294 deletions

View file

@ -1,6 +1,6 @@
MIT License
Copyright 2017-2021 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com
Copyright 2017-2024 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -14,6 +14,7 @@ copies or substantial portions of the Software.
You can produce, without restrictions, any derivative works from the original
software and even reap commercial benefits from the sale of the secondary product.
The derivates include created maps, map images, screenshots, videos, and other materials.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

View file

@ -436,6 +436,14 @@ button.options:hover {
margin: 0.8em 0 0 0;
}
#options .tip {
color: #444;
font-size: 0.9em;
font-family: sans-serif;
font-style: italic;
margin-left: 0.5em;
}
#aboutContent {
text-align: justify;
}
@ -733,7 +741,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
background-color: var(--header-active);
}
#toolsContent div {
#toolsContent > .grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
margin: 0.2em 0;
@ -757,7 +765,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
#viewMode > button {
padding: 0.35em;
margin: 0.2em 0.3em 0.6em 0.3em;
margin: 0.3em 0.3em 0.6em 0.3em;
float: left;
width: 30.7%;
}
@ -2188,7 +2196,7 @@ svg.button {
#worldControls input[type="number"] {
border: 1px solid #e5e5e5;
padding: 0px;
width: 3.2em;
width: 4em;
}
#worldControls i.icon-lock-open,
@ -2247,10 +2255,6 @@ svg.button {
fill: blue;
}
#globeOutline {
fill: url(#temperatureGradient);
}
#globeArea {
fill: white;
fill-opacity: 0.3;
@ -2261,6 +2265,11 @@ svg.button {
stroke-width: 0.2;
}
#globePrimeMeridian {
stroke: blue;
stroke-width: 1.4;
}
#globeEquator {
stroke: red;
stroke-width: 1.4;
@ -2382,6 +2391,29 @@ svg.button {
background: #ccc;
}
.separator {
display: flex;
align-items: center;
text-align: center;
font-style: italic;
font-weight: bold;
color: #222;
margin: 0.8em 0 0 0;
}
.separator::before,
.separator::after {
content: "";
flex: 1;
border-bottom: 1px solid #333;
}
.separator:not(:empty)::before {
margin-right: 0.25em;
}
.separator:not(:empty)::after {
margin-left: 0.25em;
}
@media print {
div,
canvas {

View file

@ -138,7 +138,7 @@
}
</style>
<link rel="preload" href="index.css?v=1.96.00" as="style" onload="this.onload=null; this.rel='stylesheet'" />
<link rel="preload" href="index.css?v=1.98.01" as="style" onload="this.onload=null; this.rel='stylesheet'" />
<link rel="preload" href="icons.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
<link rel="preload" href="libs/jquery-ui.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
</head>
@ -380,7 +380,7 @@
<rect x="-1%" y="-1%" width="102%" height="102%" fill="url(#oceanic)" />
</svg>
<svg id="loading-rose" width="100%" height="100%" viewBox="0 0 700 700">
<use href="#rose" x="50%" y="50%" />
<use href="#defs-compass-rose" x="50%" y="50%" />
</svg>
<div id="loading-typography">
<div id="titleName">Azgaar's</div>
@ -469,9 +469,7 @@
onclick="removePreset()"
></button>
<p data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style">
Displayed layers and layers order:
</p>
<p>Displayed layers and layers order:</p>
<ul
data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style"
id="mapLayers"
@ -717,13 +715,15 @@
<li
id="toggleVignette"
data-tip="Vignette (border fading): click to toggle. Ctrl + click to edit style"
data-shortcut="[ (left bracket)"
data-shortcut="[ (left square bracket)"
onclick="toggleVignette(event)"
class="solid"
>
Vignette
</li>
</ul>
<div class="tip">Click to toggle, drag to raise or lower the layer</div>
<div class="tip">Ctrl + click to edit layer style</div>
<div id="viewMode" data-tip="Set view node">
<p>View mode:</p>
@ -1317,6 +1317,12 @@
<td><select id="styleStatesBodyFilter" /></td>
</tr>
<tr style="margin-top: 0.8em">
<td style="font-style: italic">
Halo is only rendered if "Rendering" option is set to "Best quality"!
</td>
</tr>
<tr data-tip="Set states halo effect width">
<td>Halo width</td>
<td>
@ -2063,23 +2069,16 @@
</div>
<div id="toolsContent" class="tabcontent">
<p>Click to configure:</p>
<div>
<button
id="editHeightmapButton"
data-tip="Click to open Heightmap customization menu"
data-shortcut="Shift + H"
>
Heightmap
</button>
<div class="separator">Edit</div>
<div class="grid">
<button id="editBiomesButton" data-tip="Click to open Biomes Editor" data-shortcut="Shift + B">
Biomes
</button>
<button id="editStatesButton" data-tip="Click to open States Editor" data-shortcut="Shift + S">
States
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview" data-shortcut="Shift + T">
Burgs
</button>
<button id="editProvincesButton" data-tip="Click to open Provinces Editor" data-shortcut="Shift + P">
Provinces
<button id="editCulturesButton" data-tip="Click to open Cultures Editor" data-shortcut="Shift + C">
Cultures
</button>
<button
id="editDiplomacyButton"
@ -2088,40 +2087,18 @@
>
Diplomacy
</button>
<button id="editCulturesButton" data-tip="Click to open Cultures Editor" data-shortcut="Shift + C">
Cultures
</button>
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor" data-shortcut="Shift + N">
Namesbase
</button>
<button id="editZonesButton" data-tip="Click to open Zones Editor" data-shortcut="Shift + Z">Zones</button>
<button id="editReligions" data-tip="Click to open Religions Editor" data-shortcut="Shift + R">
Religions
</button>
<button id="editEmblemButton" data-tip="Click to open Emblem Editor" data-shortcut="Shift + Y">
Emblems
</button>
<button id="editUnitsButton" data-tip="Click to open Units Editor" data-shortcut="Shift + Q">Units</button>
<button id="editNotesButton" data-tip="Click to open Notes Editor" data-shortcut="Shift + O">Notes</button>
</div>
<p>Click to overview:</p>
<div>
<button
id="overviewChartsButton"
data-tip="Click to open Charts to overview cells data"
data-shortcut="Shift + A"
id="editHeightmapButton"
data-tip="Click to open Heightmap customization menu"
data-shortcut="Shift + H"
>
Charts
Heightmap
</button>
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview" data-shortcut="Shift + T">
Burgs
</button>
<button id="overviewRoutesButton" data-tip="Click to open Routes Overview" data-shortcut="Shift + U">
Routes
</button>
<button id="overviewRiversButton" data-tip="Click to open Rivers Overview" data-shortcut="Shift + V">
Rivers
<button id="overviewMarkersButton" data-tip="Click to open Markers Overview" data-shortcut="Shift + K">
Markers
</button>
<button
id="overviewMilitaryButton"
@ -2130,41 +2107,58 @@
>
Military
</button>
<button id="overviewMarkersButton" data-tip="Click to open Markers Overview" data-shortcut="Shift + K">
Markers
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor" data-shortcut="Shift + N">
Namesbase
</button>
<button id="overviewCellsButton" data-tip="Click to open Cell details view" data-shortcut="Shift + E">
Cells
<button id="editNotesButton" data-tip="Click to open Notes Editor" data-shortcut="Shift + O">Notes</button>
<button id="editProvincesButton" data-tip="Click to open Provinces Editor" data-shortcut="Shift + P">
Provinces
</button>
<button id="editReligions" data-tip="Click to open Religions Editor" data-shortcut="Shift + R">
Religions
</button>
<button id="overviewRiversButton" data-tip="Click to open Rivers Overview" data-shortcut="Shift + V">
Rivers
</button>
<button id="overviewRoutesButton" data-tip="Click to open Routes Overview" data-shortcut="Shift + U">
Routes
</button>
<button id="editStatesButton" data-tip="Click to open States Editor" data-shortcut="Shift + S">
States
</button>
<button id="editUnitsButton" data-tip="Click to open Units Editor" data-shortcut="Shift + Q">Units</button>
<button id="editZonesButton" data-tip="Click to open Zones Editor" data-shortcut="Shift + Z">Zones</button>
</div>
<p>Click to regenerate:</p>
<div id="regenerateFeature">
<div class="separator">Regenerate</div>
<div id="regenerateFeature" class="grid">
<button
id="regenerateBurgs"
data-tip="Click to regenerate all unlocked burgs and routes. States will remain as they are. Note: burgs are only generated in populated areas with culture assigned"
>
Burgs
</button>
<button id="regenerateCultures" data-tip="Click to regenerate non-locked cultures">Cultures</button>
<button id="regenerateEmblems" data-tip="Click to regenerate all emblems">Emblems</button>
<button id="regenerateIce" data-tip="Click to regenerate icebergs and glaciers">Ice</button>
<button
id="regenerateStateLabels"
data-tip="Click to update state labels placement based on current borders"
>
Labels
</button>
<button
id="regenerateReliefIcons"
data-tip="Click to regenerate all relief icons based on current cell biome and elevation"
>
Relief
<button id="regenerateMarkers" data-tip="Click to regenerate unlocked markers">
Markers <i id="configRegenerateMarkers" class="icon-cog" data-tip="Click to set number multiplier"></i>
</button>
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
<button id="regenerateRivers" data-tip="Click to regenerate all rivers (restore default state)">
Rivers
<button
id="regenerateMilitary"
data-tip="Click to recalculate military forces based on current military options"
>
Military
</button>
<button id="regeneratePopulation" data-tip="Click to recalculate rural and urban population">
Population
</button>
<button
id="regenerateStates"
data-tip="Click to select new capitals and regenerate non-locked states. Emblems and military forces will be regenerated as well, burgs will remain as they are"
>
States
</button>
<button
id="regenerateProvinces"
data-tip="Click to regenerate non-locked provinces. States will remain as they are"
@ -2172,23 +2166,21 @@
Provinces
</button>
<button
id="regenerateBurgs"
data-tip="Click to regenerate all unlocked burgs and routes. States will remain as they are. Note: burgs are only generated in populated areas with culture assigned"
id="regenerateReliefIcons"
data-tip="Click to regenerate all relief icons based on current cell biome and elevation"
>
Burgs
Relief
</button>
<button id="regenerateEmblems" data-tip="Click to regenerate all emblems">Emblems</button>
<button id="regenerateReligions" data-tip="Click to regenerate non-locked religions">Religions</button>
<button id="regenerateCultures" data-tip="Click to regenerate non-locked cultures">Cultures</button>
<button
id="regenerateMilitary"
data-tip="Click to recalculate military forces based on current military options"
>
Military
<button id="regenerateRivers" data-tip="Click to regenerate all rivers (restore default state)">
Rivers
</button>
<button id="regenerateIce" data-tip="Click to regenerate icebergs and glaciers">Ice</button>
<button id="regenerateMarkers" data-tip="Click to regenerate unlocked markers">
Markers <i id="configRegenerateMarkers" class="icon-cog" data-tip="Click to set number multiplier"></i>
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
<button
id="regenerateStates"
data-tip="Click to select new capitals and regenerate non-locked states. Emblems and military forces will be regenerated as well, burgs will remain as they are"
>
States
</button>
<button
id="regenerateZones"
@ -2198,8 +2190,8 @@
</button>
</div>
<p>Click to add:</p>
<div id="addFeature">
<div class="separator">Add</div>
<div id="addFeature" class="grid">
<button
id="addBurgTool"
data-tip="Click on map to place a burg. Hold Shift to add multiple"
@ -2214,14 +2206,6 @@
>
Label
</button>
<button
id="addRiver"
data-tip="Click on map to place a river. Hold Shift to add multiple"
data-shortcut="Shift + 3"
>
River
</button>
<button id="addRoute" data-tip="Open route creation dialog" data-shortcut="Shift + 4">Route</button>
<button
id="addMarker"
data-tip="Click on map to place a marker. Hold Shift to add multiple"
@ -2229,10 +2213,36 @@
>
Marker
</button>
<button
id="addRiver"
data-tip="Click on map to place a river. Hold Shift to add multiple"
data-shortcut="Shift + 3"
>
River
</button>
<<<<<<< HEAD
<button id="addRoute" data-tip="Open route creation dialog" data-shortcut="Shift + 4">Route</button>
=======
<button id="addRoute" data-tip="Click on map to place a route" data-shortcut="Shift + 4">Route</button>
</div>
<p>Click to create a new map:</p>
<div>
<div class="separator">Show</div>
<div class="grid">
<button id="overviewCellsButton" data-tip="Click to open Cell details view" data-shortcut="Shift + E">
Cells
</button>
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
<button
id="overviewChartsButton"
data-tip="Click to open Charts to overview cells data"
data-shortcut="Shift + A"
>
Charts
</button>
</div>
<div class="separator">Create</div>
<div class="grid">
<button id="openSubmapMenu" data-tip="Click to generate a submap from the current viewport">Submap</button>
<button id="openResampleMenu" data-tip="Click to transform the map">Transform</button>
</div>
@ -2321,8 +2331,7 @@
<div id="aboutContent" class="tabcontent">
<p>
<a href="https://github.com/Azgaar/Fantasy-Map-Generator" target="_blank">Fantasy Map Generator</a> is a
free
<a href="https://github.com/Azgaar/Fantasy-Map-Generator" target="_blank">Fantasy Map Generator</a> is an
<a href="https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE" target="_blank"
>open source</a
>
@ -2341,7 +2350,7 @@
<p>
Join our <a href="https://discordapp.com/invite/X7E84HU" target="_blank">Discord server</a> and
<a href="https://www.reddit.com/r/FantasyMapGenerator/" target="_blank">Reddit community</a> to ask
questions, get help and share maps.
questions, get help and share maps. The created maps can be used for free, even for commercial purposes.
</p>
<p>
@ -2539,15 +2548,15 @@
<i data-locked="0" id="lock_mapSize" class="icon-lock-open"></i>
<label data-tip="Set map size relative to the world size">
<i>Map size:</i>
<input id="mapSizeInput" data-stored="mapSize" type="number" min="1" max="100" />%
<input id="mapSizeOutput" data-stored="mapSize" type="range" min="1" max="100" />
<input id="mapSizeInput" data-stored="mapSize" type="number" min="1" max="100" step="0.1" />%
<input id="mapSizeOutput" data-stored="mapSize" type="range" min="1" max="100" step="0.1" />
</label>
</div>
<div>
<i data-locked="0" id="lock_latitude" class="icon-lock-open"></i>
<label data-tip="Set a North-South map shift">
<label data-tip="Set a North-South map shift, set to 50 to make map center lie on Equator">
<i>Latitudes:</i>
<input id="latitudeInput" data-stored="latitude" type="number" min="0" max="100" step="1" />
<input id="latitudeInput" data-stored="latitude" type="number" min="0" max="100" step="0.1" />
<br /><i>N</i
><input
id="latitudeOutput"
@ -2555,14 +2564,42 @@
type="range"
min="0"
max="100"
step="1"
step="0.1"
style="width: 10.3em"
/><i>S</i>
</label>
</div>
<div>
<label data-tip="Set precipitation - water amount clouds can bring. Defines rivers and biomes generation">
<i data-locked="0" id="lock_longitude" class="icon-lock-open"></i>
<label data-tip="Set a West-East map shift, set to 50 to make map center lie on Prime meridian">
<i>Longitudes:</i>
<input
id="longitudeInput"
data-stored="longitude"
type="number"
min="0"
max="100"
value="50"
step="0.1"
/>
<br /><i>W</i
><input
id="longitudeOutput"
data-stored="longitude"
type="range"
min="0"
max="100"
step="0.1"
style="width: 10.3em"
/><i>E</i>
</label>
</div>
<div>
<label
data-tip="Set precipitation - water amount clouds can bring. Defines rivers and biomes generation. Keep around 100% for default generation"
>
<i data-locked="0" id="lock_prec" class="icon-lock-open"></i>
<i>Precipitation:</i>
<input id="precInput" data-stored="prec" type="number" />%
@ -2637,8 +2674,10 @@
<text x="-15" y="190">60°</text>
<text x="-15" y="204">90°</text>
</g>
<circle id="globeOutline" cx="100" cy="100" r="100" />
<line id="globeEquator" x1="1" x2="199" y1="100" y2="100" />
<circle id="globeGradient" cx="100" cy="100" r="100" fill="url(#temperatureGradient)" stroke="none" />
<line id="globePrimeMeridian" x1="100" x2="100" y1="0" y2="200" />
<line id="globeEquator" x1="1" x2="200" y1="100" y2="100" />
<circle id="globeOutline" cx="100" cy="100" r="100" fill="none" />
<path id="globeGraticule" />
<path id="globeArea" />
</svg>
@ -2648,6 +2687,14 @@
</button>
</div>
</div>
<div style="margin-top: 0.3em">
<i>Presets:</i>
<button id="wcWholeWorld" data-tip="Click to set map size to cover the whole world">Whole world</button>
<button id="wcNorthern" data-tip="Click to set map size to cover the Northern latitudes">Northern</button>
<button id="wcTropical" data-tip="Click to set map size to cover the Tropical latitudes">Tropical</button>
<button id="wcSouthern" data-tip="Click to set map size to cover the Southern latitudes">Southern</button>
</div>
</div>
<div id="labelEditor" class="dialog" style="display: none">
@ -7894,18 +7941,19 @@
</symbol>
</g>
<g id="rose" stroke-width="1">
<g id="sL" stroke="#3f3f3f">
<g id="defs-compass-rose" stroke-width="1.1">
<g id="rose-coord-line" stroke="#3f3f3f">
<line id="sL1" x1="0" y1="-20000" x2="0" y2="20000" />
<line id="sL2" x1="-20000" y1="0" x2="20000" y2="0" />
</g>
<use href="#sL" transform="rotate(45)" />
<use href="#sL" transform="rotate(22.5)" />
<use href="#sL" transform="rotate(-22.5)" />
<use href="#sL" transform="rotate(11.25)" />
<use href="#sL" transform="rotate(-11.25)" />
<use href="#sL" transform="rotate(56.25)" />
<use href="#sL" transform="rotate(-56.25)" />
<use href="#rose-coord-line" transform="rotate(45)" />
<use href="#rose-coord-line" transform="rotate(22.5)" />
<use href="#rose-coord-line" transform="rotate(-22.5)" />
<use href="#rose-coord-line" transform="rotate(11.25)" />
<use href="#rose-coord-line" transform="rotate(-11.25)" />
<use href="#rose-coord-line" transform="rotate(56.25)" />
<use href="#rose-coord-line" transform="rotate(-56.25)" />
<g stroke-width="8" stroke-opacity="1" shape-rendering="geometricprecision">
<circle r="9" stroke="#000000" fill="#1b1b1b" />
<circle r="75" stroke="#008000" fill="#ffffff" fill-opacity=".1" />
@ -8136,7 +8184,7 @@
<script src="config/heightmap-templates.js"></script>
<script src="config/precreated-heightmaps.js"></script>
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
<script src="modules/ocean-layers.js?v=1.96.00"></script>
<script src="modules/ocean-layers.js?v=1.98.04"></script>
<script src="modules/river-generator.js?v=1.89.13"></script>
<script src="modules/lakes.js"></script>
<script src="modules/biomes.js"></script>
@ -8158,15 +8206,15 @@
<script src="modules/ui/measurers.js?v=1.96.00"></script>
<script src="modules/ui/stylePresets.js?v=1.96.00"></script>
<script src="modules/ui/general.js?v=1.96.00"></script>
<script src="modules/ui/options.js?v=1.97.14"></script>
<script src="main.js?v=1.97.11"></script>
<script src="modules/ui/general.js?v=1.98.01"></script>
<script src="modules/ui/options.js?v=1.98.04"></script>
<script src="main.js?v=1.98.01"></script>
<script defer src="modules/relief-icons.js"></script>
<script defer src="modules/ui/style.js?v=1.96.00"></script>
<script defer src="modules/ui/editors.js?v=1.97.12"></script>
<script defer src="modules/ui/tools.js?v=1.97.12"></script>
<script defer src="modules/ui/world-configurator.js?v=1.98.00"></script>
<script defer src="modules/ui/world-configurator.js?v=1.98.01"></script>
<script defer src="modules/ui/heightmap-editor.js?v=1.96.00"></script>
<script defer src="modules/ui/provinces-editor.js?v=1.96.00"></script>
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
@ -8204,10 +8252,10 @@
<script defer src="modules/coa-renderer.js?v=1.94.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.96.00"></script>
<script defer src="modules/io/load.js?v=1.97.04"></script>
<script defer src="modules/io/save.js?v=1.98.01"></script>
<script defer src="modules/io/load.js?v=1.98.01"></script>
<script defer src="modules/io/cloud.js?v=1.96.00"></script>
<script defer src="modules/io/export.js?v=1.97.03"></script>
<script defer src="modules/io/export.js?v=1.98.05"></script>
<!-- Web Components -->
<script defer src="components/fill-box.js"></script>

125
main.js
View file

@ -53,7 +53,7 @@ let biomes = viewbox.append("g").attr("id", "biomes");
let cells = viewbox.append("g").attr("id", "cells");
let gridOverlay = viewbox.append("g").attr("id", "gridOverlay");
let coordinates = viewbox.append("g").attr("id", "coordinates");
let compass = viewbox.append("g").attr("id", "compass");
let compass = viewbox.append("g").attr("id", "compass").style("display", "none");
let rivers = viewbox.append("g").attr("id", "rivers");
let terrain = viewbox.append("g").attr("id", "terrain");
let relig = viewbox.append("g").attr("id", "relig");
@ -126,6 +126,9 @@ emblems.append("g").attr("id", "burgEmblems");
emblems.append("g").attr("id", "provinceEmblems");
emblems.append("g").attr("id", "stateEmblems");
// compass
compass.append("use").attr("xlink:href", "#defs-compass-rose");
// fogging
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
fogging
@ -195,10 +198,10 @@ let options = {
};
let mapCoordinates = {}; // map coordinates on globe
let populationRate = +document.getElementById("populationRateInput").value;
let distanceScale = +document.getElementById("distanceScaleInput").value;
let urbanization = +document.getElementById("urbanizationInput").value;
let urbanDensity = +document.getElementById("urbanDensityInput").value;
let populationRate = +byId("populationRateInput").value;
let distanceScale = +byId("distanceScaleInput").value;
let urbanization = +byId("urbanizationInput").value;
let urbanDensity = +byId("urbanDensityInput").value;
applyStoredOptions();
@ -439,10 +442,10 @@ function handleZoom(isScaleChanged, isPositionChanged) {
// zoom image converter overlay
if (customization === 1) {
const canvas = document.getElementById("canvas");
const canvas = byId("canvas");
if (!canvas || canvas.style.opacity === "0") return;
const img = document.getElementById("imageToConvert");
const img = byId("imageToConvert");
if (!img) return;
const ctx = canvas.getContext("2d");
@ -524,7 +527,7 @@ function invokeActiveZooming() {
+markers.attr("rescale") &&
pack.markers?.forEach(marker => {
const {i, x, y, size = 30, hidden} = marker;
const el = !hidden && document.getElementById(`marker${i}`);
const el = !hidden && byId(`marker${i}`);
if (!el) return;
const zoomedSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
@ -561,18 +564,18 @@ void (function addDragToUpload() {
document.addEventListener("dragover", function (e) {
e.stopPropagation();
e.preventDefault();
document.getElementById("mapOverlay").style.display = null;
byId("mapOverlay").style.display = null;
});
document.addEventListener("dragleave", function (e) {
document.getElementById("mapOverlay").style.display = "none";
byId("mapOverlay").style.display = "none";
});
document.addEventListener("drop", function (e) {
e.stopPropagation();
e.preventDefault();
const overlay = document.getElementById("mapOverlay");
const overlay = byId("mapOverlay");
overlay.style.display = "none";
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
const file = e.dataTransfer.items[0].getAsFile();
@ -780,7 +783,7 @@ function addLakesInDeepDepressions() {
TIME && console.time("addLakesInDeepDepressions");
const {cells, features} = grid;
const {c, h, b} = cells;
const ELEVATION_LIMIT = +document.getElementById("lakeElevationLimitOutput").value;
const ELEVATION_LIMIT = +byId("lakeElevationLimitOutput").value;
if (ELEVATION_LIMIT === 80) return;
for (const i of cells.i) {
@ -880,73 +883,77 @@ function openNearSeaLakes() {
// define map size and position based on template and random factor
function defineMapSize() {
const [size, latitude] = getSizeAndLatitude();
const [size, latitude, longitude] = getSizeAndLatitude();
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
if (randomize || !locked("mapSize")) mapSizeOutput.value = mapSizeInput.value = rn(size);
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = rn(latitude);
if (randomize || !locked("mapSize")) mapSizeOutput.value = mapSizeInput.value = size;
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = latitude;
if (randomize || !locked("longitude")) longitudeOutput.value = longitudeInput.value = longitude;
function getSizeAndLatitude() {
const template = byId("templateInput").value; // heightmap template
if (template === "africa-centric") return [45, 53];
if (template === "arabia") return [20, 35];
if (template === "atlantics") return [42, 23];
if (template === "britain") return [7, 20];
if (template === "caribbean") return [15, 40];
if (template === "east-asia") return [11, 28];
if (template === "eurasia") return [38, 19];
if (template === "europe") return [20, 16];
if (template === "europe-accented") return [14, 22];
if (template === "europe-and-central-asia") return [25, 10];
if (template === "europe-central") return [11, 22];
if (template === "europe-north") return [7, 18];
if (template === "greenland") return [22, 7];
if (template === "hellenica") return [8, 27];
if (template === "iceland") return [2, 15];
if (template === "indian-ocean") return [45, 55];
if (template === "mediterranean-sea") return [10, 29];
if (template === "middle-east") return [8, 31];
if (template === "north-america") return [37, 17];
if (template === "us-centric") return [66, 27];
if (template === "us-mainland") return [16, 30];
if (template === "world") return [78, 27];
if (template === "world-from-pacific") return [75, 32];
if (template === "africa-centric") return [45, 53, 38];
if (template === "arabia") return [20, 35, 35];
if (template === "atlantics") return [42, 23, 65];
if (template === "britain") return [7, 20, 51.3];
if (template === "caribbean") return [15, 40, 74.8];
if (template === "east-asia") return [11, 28, 9.4];
if (template === "eurasia") return [38, 19, 27];
if (template === "europe") return [20, 16, 44.8];
if (template === "europe-accented") return [14, 22, 44.8];
if (template === "europe-and-central-asia") return [25, 10, 39.5];
if (template === "europe-central") return [11, 22, 46.4];
if (template === "europe-north") return [7, 18, 48.9];
if (template === "greenland") return [22, 7, 55.8];
if (template === "hellenica") return [8, 27, 43.5];
if (template === "iceland") return [2, 15, 55.3];
if (template === "indian-ocean") return [45, 55, 14];
if (template === "mediterranean-sea") return [10, 29, 45.8];
if (template === "middle-east") return [8, 31, 34.4];
if (template === "north-america") return [37, 17, 87];
if (template === "us-centric") return [66, 27, 100];
if (template === "us-mainland") return [16, 30, 77.5];
if (template === "world") return [78, 27, 40];
if (template === "world-from-pacific") return [75, 32, 30]; // longitude doesn't fit
const part = grid.features.some(f => f.land && f.border); // if land goes over map borders
const max = part ? 80 : 100; // max size
const lat = () => gauss(P(0.5) ? 40 : 60, 20, 25, 75); // latitude shift
if (!part) {
if (template === "Pangea") return [100, 50];
if (template === "Shattered" && P(0.7)) return [100, 50];
if (template === "Continents" && P(0.5)) return [100, 50];
if (template === "Archipelago" && P(0.35)) return [100, 50];
if (template === "High Island" && P(0.25)) return [100, 50];
if (template === "Low Island" && P(0.1)) return [100, 50];
if (template === "pangea") return [100, 50, 50];
if (template === "shattered" && P(0.7)) return [100, 50, 50];
if (template === "continents" && P(0.5)) return [100, 50, 50];
if (template === "archipelago" && P(0.35)) return [100, 50, 50];
if (template === "highIsland" && P(0.25)) return [100, 50, 50];
if (template === "lowIsland" && P(0.1)) return [100, 50, 50];
}
if (template === "Pangea") return [gauss(70, 20, 30, max), lat()];
if (template === "Volcano") return [gauss(20, 20, 10, max), lat()];
if (template === "Mediterranean") return [gauss(25, 30, 15, 80), lat()];
if (template === "Peninsula") return [gauss(15, 15, 5, 80), lat()];
if (template === "Isthmus") return [gauss(15, 20, 3, 80), lat()];
if (template === "Atoll") return [gauss(5, 10, 2, max), lat()];
if (template === "pangea") return [gauss(70, 20, 30, max), lat(), 50];
if (template === "volcano") return [gauss(20, 20, 10, max), lat(), 50];
if (template === "mediterranean") return [gauss(25, 30, 15, 80), lat(), 50];
if (template === "peninsula") return [gauss(15, 15, 5, 80), lat(), 50];
if (template === "isthmus") return [gauss(15, 20, 3, 80), lat(), 50];
if (template === "atoll") return [gauss(3, 2, 1, 5, 1), lat(), 50];
return [gauss(30, 20, 15, max), lat()]; // Continents, Archipelago, High Island, Low Island
return [gauss(30, 20, 15, max), lat(), 50]; // Continents, Archipelago, High Island, Low Island
}
}
// calculate map position on globe
function calculateMapCoordinates() {
const size = +document.getElementById("mapSizeOutput").value;
const latShift = +document.getElementById("latitudeOutput").value;
const sizeFraction = +byId("mapSizeOutput").value / 100;
const latShift = +byId("latitudeOutput").value / 100;
const lonShift = +byId("longitudeOutput").value / 100;
const latT = rn((size / 100) * 180, 1);
const latN = rn(90 - ((180 - latT) * latShift) / 100, 1);
const latT = rn(sizeFraction * 180, 1);
const latN = rn(90 - (180 - latT) * latShift, 1);
const latS = rn(latN - latT, 1);
const lon = rn(Math.min(((graphWidth / graphHeight) * latT) / 2, 180));
mapCoordinates = {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
const lonT = rn(Math.min((graphWidth / graphHeight) * latT, 360), 1);
const lonE = rn(180 - (360 - lonT) * lonShift, 1);
const lonW = rn(lonE - lonT, 1);
mapCoordinates = {latT, latN, latS, lonT, lonW, lonE};
}
// temperature model, trying to follow real-world data
@ -1759,7 +1766,7 @@ function addZones(number = 1) {
}
function addEruption() {
const volcano = document.getElementById("markers").querySelector("use[data-id='#marker_volcano']");
const volcano = byId("markers").querySelector("use[data-id='#marker_volcano']");
if (!volcano) return;
const x = +volcano.dataset.x,
@ -1978,7 +1985,7 @@ function undraw() {
.getElementById("deftemp")
.querySelectorAll("path, clipPath, svg")
.forEach(el => el.remove());
document.getElementById("coas").innerHTML = ""; // remove auto-generated emblems
byId("coas").innerHTML = ""; // remove auto-generated emblems
notes = [];
rulers = new Rulers();
unfog();

View file

@ -848,10 +848,23 @@ export function resolveVersionConflicts(version) {
}
if (version < 1.98) {
// v1.98.00 changed routes generation algorithm and data format
// v1.98.00 changed compass layer and rose element id
const rose = compass.select("use");
rose.attr("xlink:href", "#defs-compass-rose");
if (!compass.selectAll("*").size()) {
compass.style("display", "none");
compass.append("use").attr("xlink:href", "#defs-compass-rose");
shiftCompass();
}
}
if (version < 1.99) {
// v1.99.00 changed routes generation algorithm and data format
// 1. cells.road => cells.routes and now it an object of objects {i1: {i2: routeId, i3: routeId}}
// 2. cells.crossroad is removed
// 3. pack.routes is added as an array of objects
// 4. rendering is changed
// v1.98.00 changed compass layer and rose element id
}
}

View file

@ -94,7 +94,8 @@ function getSettings() {
populationRate: populationRate,
urbanization: urbanization,
mapSize: mapSizeOutput.value,
latitudeO: latitudeOutput.value,
latitude: latitudeOutput.value,
longitude: longitudeOutput.value,
prec: precOutput.value,
options: options,
mapName: mapName.value,

View file

@ -87,7 +87,7 @@ async function exportToPngTiles() {
imgSchema.src = urlSchema;
await loadImage(imgSchema);
status.innerHTML = "Drawing schema...";
status.innerHTML = "Rendering schema...";
ctx.drawImage(imgSchema, 0, 0, canvas.width, canvas.height);
const blob = await canvasToBlob(canvas, "image/png");
ctx.clearRect(0, 0, canvas.width, canvas.height);
@ -95,9 +95,9 @@ async function exportToPngTiles() {
// download tiles
const url = await getMapURL("tiles", {fullMap: true});
const tilesX = +byId("tileColsInput").value;
const tilesY = +byId("tileRowsInput").value;
const scale = +byId("tileScaleInput").value;
const tilesX = +byId("tileColsOutput").value || 2;
const tilesY = +byId("tileRowsOutput").value || 2;
const scale = +byId("tileScaleOutput").value || 1;
const tolesTotal = tilesX * tilesY;
const tileW = (graphWidth / tilesX) | 0;
@ -113,11 +113,17 @@ async function exportToPngTiles() {
await loadImage(img);
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
function getRowLabel(row) {
const first = row >= alphabet.length ? alphabet[Math.floor(row / alphabet.length) - 1] : "";
const last = alphabet[row % alphabet.length];
return first + last;
}
for (let y = 0, row = 0, id = 1; y + tileH <= graphHeight; y += tileH, row++) {
const rowName = alphabet[row % alphabet.length];
const rowName = getRowLabel(row);
for (let x = 0, cell = 1; x + tileW <= graphWidth; x += tileW, cell++, id++) {
status.innerHTML = `Drawing tile ${rowName}${cell} (${id} of ${tolesTotal})...`;
status.innerHTML = `Rendering tile ${rowName}${cell} (${id} of ${tolesTotal})...`;
ctx.drawImage(img, x, y, tileW, tileH, 0, 0, width, height);
const blob = await canvasToBlob(canvas, "image/png");
ctx.clearRect(0, 0, canvas.width, canvas.height);
@ -295,7 +301,7 @@ async function getMapURL(type, options) {
// add wind rose
if (cloneEl.getElementById("compass")) {
const rose = svgDefs.getElementById("rose");
const rose = svgDefs.getElementById("defs-compass-rose");
if (rose) cloneDefs.appendChild(rose.cloneNode(true));
}

View file

@ -242,6 +242,7 @@ async function parseLoadedData(data, mapVersion) {
if (settings[22]) stylePreset.value = settings[22];
if (settings[23]) rescaleLabels.checked = +settings[23];
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
if (settings[25]) longitudeInput.value = longitudeOutput.value = minmax(settings[25] || 50, 0, 100);
})();
void (function applyOptionsToUI() {
@ -458,7 +459,7 @@ async function parseLoadedData(data, mapVersion) {
{
// dynamically import and run auto-update script
const versionNumber = parseFloat(params[0]);
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.97.04");
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.98.00");
resolveVersionConflicts(versionNumber);
}

View file

@ -67,7 +67,8 @@ function prepareMapData() {
+hideLabels.checked,
stylePreset.value,
+rescaleLabels.checked,
urbanDensity
urbanDensity,
longitudeOutput.value
].join("|");
const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");

View file

@ -1070,27 +1070,29 @@ function drawStates() {
const bodyData = body.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
const gapData = gap.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
const bodyString = bodyData.map(d => `<path id="state${d[1]}" d="${d[0]}" fill="${d[2]}" stroke="none"/>`).join("");
const gapString = gapData.map(d => `<path id="state-gap${d[1]}" d="${d[0]}" fill="none" stroke="${d[2]}"/>`).join("");
statesBody.html(bodyString + gapString);
const isOptimized = shapeRendering.value === "optimizeSpeed";
if (!isOptimized) {
const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
const haloString = haloData
.map(d => {
const stroke = d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666";
return `<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${stroke}"/>`;
})
.join("");
statesHalo.html(haloString);
const clipString = bodyData
.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`)
.join("");
const haloString = haloData
.map(
d =>
`<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${
d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666"
}"/>`
)
.join("");
statesBody.html(bodyString + gapString);
defs.select("#statePaths").html(clipString);
statesHalo.html(haloString);
}
// connect vertices to chain
function connectVertices(start, state) {
const chain = []; // vertices chain to form a path
const getType = c => {
@ -1525,10 +1527,6 @@ function toggleCompass(event) {
if (!layerIsOn("toggleCompass")) {
turnButtonOn("toggleCompass");
$("#compass").fadeIn();
if (!compass.selectAll("*").size()) {
compass.append("use").attr("xlink:href", "#rose");
shiftCompass();
}
if (event && isCtrlClick(event)) editStyle("compass");
} else {
if (event && isCtrlClick(event)) {

View file

@ -644,17 +644,16 @@ function randomizeCultureSet() {
function setRendering(value) {
viewbox.attr("shape-rendering", value);
// if (value === "optimizeSpeed") {
// // block some styles
// coastline.select("#sea_island").style("filter", "none");
// statesHalo.style("display", "none");
// emblems.style("opacity", 1);
// } else {
// // remove style block
// coastline.select("#sea_island").style("filter", null);
// statesHalo.style("display", null);
// emblems.style("opacity", null);
// }
if (value === "optimizeSpeed") {
// block some styles
coastline.select("#sea_island").style("filter", "none");
statesHalo.style("display", "none");
} else {
// remove style block
coastline.select("#sea_island").style("filter", null);
statesHalo.style("display", null);
if (pack.cells && statesHalo.selectAll("*").size() === 0) drawStates();
}
}
// generate current year and era name
@ -902,9 +901,9 @@ function updateTilesOptions() {
}
const tileSize = byId("tileSize");
const tilesX = +byId("tileColsOutput").value;
const tilesY = +byId("tileRowsOutput").value;
const scale = +byId("tileScaleOutput").value;
const tilesX = +byId("tileColsOutput").value || 2;
const tilesY = +byId("tileRowsOutput").value || 2;
const scale = +byId("tileScaleOutput").value || 1;
// calculate size
const sizeX = graphWidth * scale * tilesX;
@ -921,11 +920,16 @@ function updateTilesOptions() {
const tileH = (graphHeight / tilesY) | 0;
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
function getRowLabel(row) {
const first = row >= alphabet.length ? alphabet[Math.floor(row / alphabet.length) - 1] : "";
const last = alphabet[row % alphabet.length];
return first + last;
}
for (let y = 0, row = 0; y + tileH <= graphHeight; y += tileH, row++) {
for (let x = 0, column = 1; x + tileW <= graphWidth; x += tileW, column++) {
rects.push(`<rect x=${x} y=${y} width=${tileW} height=${tileH} />`);
const label = alphabet[row % alphabet.length] + column;
labels.push(`<text x=${x + tileW / 2} y=${y + tileH / 2}>${label}</text>`);
labels.push(`<text x=${x + tileW / 2} y=${y + tileH / 2}>${getRowLabel(row)}${column}</text>`);
}
}

View file

@ -63,7 +63,7 @@ async function getStylePreset(desiredPreset) {
async function fetchSystemPreset(preset) {
try {
const res = await fetch(`./styles/${preset}.json`);
const res = await fetch(`./styles/${preset}.json?v=${version}`);
return await res.json();
} catch (err) {
throw new Error("Cannot fetch style preset", preset);
@ -198,7 +198,7 @@ function addStylePreset() {
"mask"
],
"#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"],
"#rose": ["transform"],
"#compass > use": ["transform"],
"#relig": ["opacity", "stroke", "stroke-width", "filter"],
"#cults": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
"#landmass": ["opacity", "fill", "filter"],

View file

@ -5,18 +5,17 @@ function editWorld() {
title: "Configure World",
resizable: false,
width: "minmax(40em, 85vw)",
buttons: {
"Whole World": () => applyWorldPreset(100, 50),
Northern: () => applyWorldPreset(33, 25),
Tropical: () => applyWorldPreset(33, 50),
Southern: () => applyWorldPreset(33, 75)
},
buttons: {"Update world": updateWorld},
open: function () {
const buttons = $(this).dialog("widget").find(".ui-dialog-buttonset > button");
buttons[0].addEventListener("mousemove", () => tip("Click to set map size to cover the whole World"));
buttons[1].addEventListener("mousemove", () => tip("Click to set map size to cover the Northern latitudes"));
buttons[2].addEventListener("mousemove", () => tip("Click to set map size to cover the Tropical latitudes"));
buttons[3].addEventListener("mousemove", () => tip("Click to set map size to cover the Southern latitudes"));
const checkbox = /* html */ `<div class="dontAsk" data-tip="Automatically update world on input changes and button clicks">
<input id="wcAutoChange" class="checkbox" type="checkbox" checked />
<label for="wcAutoChange" class="checkbox-label"><i>auto-apply changes</i></label>
</div>`;
const pane = this.parentElement.querySelector(".ui-dialog-buttonpane");
pane.insertAdjacentHTML("afterbegin", checkbox);
const button = this.parentElement.querySelector(".ui-dialog-buttonset > button");
button.on("mousemove", () => tip("Apply curreny settings to the map"));
},
close: function () {
$(this).dialog("destroy");
@ -34,12 +33,17 @@ function editWorld() {
if (modules.editWorld) return;
modules.editWorld = true;
byId("worldControls").addEventListener("input", e => updateWorld(e.target));
globe.select("#globeWindArrows").on("click", changeWind);
globe.select("#globeGraticule").attr("d", round(path(d3.geoGraticule()()))); // globe graticule
const graticule = d3.geoGraticule();
globe.select("#globeWindArrows").on("click", handleWindChange);
globe.select("#globeGraticule").attr("d", round(path(graticule()))); // globe graticule
updateWindDirections();
byId("restoreWinds").addEventListener("click", restoreDefaultWinds);
byId("worldControls").on("input", handleControlsChange);
byId("restoreWinds").on("click", restoreDefaultWinds);
byId("wcWholeWorld").on("click", () => applyWorldPreset(100, 50));
byId("wcNorthern").on("click", () => applyWorldPreset(33, 25));
byId("wcTropical").on("click", () => applyWorldPreset(33, 50));
byId("wcSouthern").on("click", () => applyWorldPreset(33, 75));
function updateInputValues() {
byId("temperatureEquatorInput").value = options.temperatureEquator;
@ -55,27 +59,27 @@ function editWorld() {
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
}
function updateWorld(el) {
if (el?.dataset.stored) {
const stored = el.dataset.stored;
byId(stored + "Input").value = el.value;
byId(stored + "Output").value = el.value;
lock(el.dataset.stored);
function handleControlsChange({target}) {
const stored = target.dataset.stored;
byId(stored + "Input").value = target.value;
byId(stored + "Output").value = target.value;
lock(stored);
if (stored === "temperatureEquator") {
options.temperatureEquator = Number(el.value);
options.temperatureEquator = Number(target.value);
byId("temperatureEquatorF").innerText = convertTemperature(options.temperatureEquator, "°F");
}
if (stored === "temperatureNorthPole") {
options.temperatureNorthPole = Number(el.value);
} else if (stored === "temperatureNorthPole") {
options.temperatureNorthPole = Number(target.value);
byId("temperatureNorthPoleF").innerText = convertTemperature(options.temperatureNorthPole, "°F");
}
if (stored === "temperatureSouthPole") {
options.temperatureSouthPole = Number(el.value);
} else if (stored === "temperatureSouthPole") {
options.temperatureSouthPole = Number(target.value);
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
}
if (byId("wcAutoChange").checked) updateWorld();
}
function updateWorld() {
updateGlobeTemperature();
updateGlobePosition();
calculateTemperatures();
@ -130,6 +134,7 @@ function editWorld() {
[mc.lonW, mc.latN],
[mc.lonE, mc.latS]
]);
globe.select("#globeArea").attr("d", round(path(area.outline()))); // map area
}
@ -163,21 +168,22 @@ function editWorld() {
});
}
function changeWind() {
function handleWindChange() {
const arrow = d3.event.target.nextElementSibling;
const tier = +arrow.dataset.tier;
options.winds[tier] = (options.winds[tier] + 45) % 360;
const tr = parseTransform(arrow.getAttribute("transform"));
arrow.setAttribute("transform", `rotate(${options.winds[tier]} ${tr[1]} ${tr[2]})`);
localStorage.setItem("winds", options.winds);
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
if (mapTiers.includes(tier)) updateWorld();
if (byId("wcAutoChange").checked && mapTiers.includes(tier)) updateWorld();
}
function restoreDefaultWinds() {
const defaultWinds = [225, 45, 225, 315, 135, 315];
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
const update = mapTiers.some(t => options.winds[t] != defaultWinds[t]);
const update = byId("wcAutoChange").checked && mapTiers.some(t => options.winds[t] != defaultWinds[t]);
options.winds = defaultWinds;
updateWindDirections();
if (update) updateWorld();
@ -188,6 +194,6 @@ function editWorld() {
byId("latitudeInput").value = byId("latitudeOutput").value = lat;
lock("mapSize");
lock("latitude");
updateWorld();
if (byId("wcAutoChange").checked) updateWorld();
}
}

3
run_php_server.bat Normal file
View file

@ -0,0 +1,3 @@
start chrome.exe http://localhost:3000/
@echo off
php -S localhost:3000

View file

@ -72,8 +72,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": "translate(80 80) scale(.25)"
"#compass > use": {
"transform": "translate(80 80) scale(0.25)"
},
"#relig": {
"opacity": 0.7,

View file

@ -72,7 +72,7 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {

View file

@ -73,8 +73,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {
"opacity": 0.7,

View file

@ -72,8 +72,8 @@
"mask": "",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {
"opacity": 0.5,

View file

@ -72,8 +72,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(0.25)"
},
"#relig": {
"opacity": 0.7,

View file

@ -73,7 +73,7 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"#compass > use": {
"transform": "translate(100 100) scale(0.3)"
},
"#relig": {

View file

@ -72,8 +72,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {
"opacity": 0.5,

View file

@ -73,8 +73,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {
"opacity": 0.7,

View file

@ -72,7 +72,7 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"#compass > use": {
"transform": "translate(80 80) scale(0.25)"
},
"#relig": {

View file

@ -72,8 +72,8 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"transform": null
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {
"opacity": 0.5,

View file

@ -72,7 +72,7 @@
"mask": "url(#water)",
"shape-rendering": "optimizespeed"
},
"#rose": {
"#compass > use": {
"transform": "translate(80 80) scale(.25)"
},
"#relig": {

View file

@ -1,7 +1,7 @@
"use strict";
// version and caching control
const version = "1.98.00"; // generator version, update each time
const version = "1.99.00"; // generator version, update each time
{
document.title += " v" + version;
@ -28,7 +28,11 @@ const version = "1.98.00"; // generator version, update each time
<ul>
<strong>Latest changes:</strong>
<<<<<<< HEAD
<li>New routes generatation algorithm</li>
=======
<li>Configurable longitude</li>
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
<li>Preview villages map</li>
<li>Ability to render ocean heightmap</li>
<li>Scale bar styling features</li>
@ -41,6 +45,10 @@ const version = "1.98.00"; // generator version, update each time
<li>North and South Poles temperature can be set independently</li>
<li>More than 70 new heraldic charges</li>
<li>Multi-color heraldic charges support</li>
<<<<<<< HEAD
=======
<li>New 3D scene options and improvements</li>
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
</ul>
<p>Join our <a href="${discord}" target="_blank">Discord server</a> and <a href="${reddit}" target="_blank">Reddit community</a> to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>