mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-19 18:41:23 +01:00
Merge branch 'Azgaar:master' into grid-overlay-layer
This commit is contained in:
commit
d21697f12c
38 changed files with 1304 additions and 608 deletions
18
index.css
18
index.css
|
|
@ -1876,12 +1876,6 @@ div.editorLine {
|
||||||
margin: 0.4em 0 0 -0.9em;
|
margin: 0.4em 0 0 -0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#barBackColor {
|
|
||||||
width: 3.5em;
|
|
||||||
padding: 0px;
|
|
||||||
height: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ruler {
|
#ruler {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
fill: none;
|
fill: none;
|
||||||
|
|
@ -1921,18 +1915,6 @@ div.editorLine {
|
||||||
stroke: #737373;
|
stroke: #737373;
|
||||||
}
|
}
|
||||||
|
|
||||||
#scaleBar {
|
|
||||||
stroke: none;
|
|
||||||
fill: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#scaleBar text {
|
|
||||||
fill: #353540;
|
|
||||||
text-anchor: middle;
|
|
||||||
font-family: var(--serif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#militaryOptionsTable select {
|
#militaryOptionsTable select {
|
||||||
border: 1px solid #d4d4d4;
|
border: 1px solid #d4d4d4;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
299
index.html
299
index.html
|
|
@ -138,7 +138,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link rel="preload" href="index.css?v=1.95.00" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
<link rel="preload" href="index.css?v=1.96.00" 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="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'" />
|
<link rel="preload" href="libs/jquery-ui.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -366,7 +366,9 @@
|
||||||
</mask>
|
</mask>
|
||||||
</defs>
|
</defs>
|
||||||
<g id="viewbox"></g>
|
<g id="viewbox"></g>
|
||||||
<g id="scaleBar"></g>
|
<g id="scaleBar">
|
||||||
|
<rect id="scaleBarBack"></rect>
|
||||||
|
</g>
|
||||||
<g id="vignette" mask="url(#vignette-mask)">
|
<g id="vignette" mask="url(#vignette-mask)">
|
||||||
<rect x="0" y="0" width="100%" height="100%" />
|
<rect x="0" y="0" width="100%" height="100%" />
|
||||||
</g>
|
</g>
|
||||||
|
|
@ -799,6 +801,7 @@
|
||||||
<option value="rivers">Rivers</option>
|
<option value="rivers">Rivers</option>
|
||||||
<option value="routes">Routes</option>
|
<option value="routes">Routes</option>
|
||||||
<option value="ruler">Rulers</option>
|
<option value="ruler">Rulers</option>
|
||||||
|
<option value="scaleBar">Scale Bar</option>
|
||||||
<option value="regions" selected>States</option>
|
<option value="regions" selected>States</option>
|
||||||
<option value="temperature">Temperature</option>
|
<option value="temperature">Temperature</option>
|
||||||
<option value="texture">Texture</option>
|
<option value="texture">Texture</option>
|
||||||
|
|
@ -824,6 +827,63 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
<tbody id="styleHeightmap">
|
||||||
|
<tr id="styleHeightmapRenderOceanOption" data-tip="Check to render ocean heights">
|
||||||
|
<td colspan="2">
|
||||||
|
<input id="styleHeightmapRenderOcean" class="checkbox" type="checkbox" />
|
||||||
|
<label for="styleHeightmapRenderOcean" class="checkbox-label">Render ocean heights</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Terracing rate. Set to 0 (toggle off) to improve performance">
|
||||||
|
<td>Terracing</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleHeightmapTerracingInput" type="range" min="0" max="20" step="1" />
|
||||||
|
<output id="styleHeightmapTerracingOutput">0</output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Layers reduction rate. Increase to improve performance">
|
||||||
|
<td>Reduce layers</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleHeightmapSkipInput" type="range" min="0" max="10" step="1" value="5" />
|
||||||
|
<output id="styleHeightmapSkipOutput">5</output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Line simplification rate. Increase to slightly improve performance">
|
||||||
|
<td>Simplify line</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleHeightmapSimplificationInput" type="range" min="0" max="10" step="1" value="0" />
|
||||||
|
<output id="styleHeightmapSimplificationOutput">0</output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Select line interpolation type">
|
||||||
|
<td>Line style</td>
|
||||||
|
<td>
|
||||||
|
<select id="styleHeightmapCurve">
|
||||||
|
<option value="curveBasisClosed" selected>Curved</option>
|
||||||
|
<option value="curveLinear">Linear</option>
|
||||||
|
<option value="curveStep">Rectangular</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Select color scheme for the element">
|
||||||
|
<td>Color scheme</td>
|
||||||
|
<td>
|
||||||
|
<select id="styleHeightmapScheme"></select>
|
||||||
|
<button
|
||||||
|
id="openCreateHeightmapSchemeButton"
|
||||||
|
data-tip="Click to add a custom heightmap color scheme"
|
||||||
|
data-stops="#ffffff,#EEEECC,#D2B48C,#008000,#008080"
|
||||||
|
class="icon-plus sideButton"
|
||||||
|
></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
<tbody id="styleOpacity" style="display: none">
|
<tbody id="styleOpacity" style="display: none">
|
||||||
<tr data-tip="Set opacity. 0: transparent, 1: solid">
|
<tr data-tip="Set opacity. 0: transparent, 1: solid">
|
||||||
<td>Opacity</td>
|
<td>Opacity</td>
|
||||||
|
|
@ -1287,56 +1347,6 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
<tbody id="styleHeightmap">
|
|
||||||
<tr data-tip="Terracing rate. Set to 0 (toggle off) to improve performance">
|
|
||||||
<td>Terracing</td>
|
|
||||||
<td>
|
|
||||||
<input id="styleHeightmapTerracingInput" type="range" min="0" max="20" step="1" />
|
|
||||||
<output id="styleHeightmapTerracingOutput">0</output>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr data-tip="Layers reduction rate. Increase to improve performance">
|
|
||||||
<td>Reduce layers</td>
|
|
||||||
<td>
|
|
||||||
<input id="styleHeightmapSkipInput" type="range" min="0" max="10" step="1" value="5" />
|
|
||||||
<output id="styleHeightmapSkipOutput">5</output>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr data-tip="Line simplification rate. Increase to slightly improve performance">
|
|
||||||
<td>Simplify line</td>
|
|
||||||
<td>
|
|
||||||
<input id="styleHeightmapSimplificationInput" type="range" min="0" max="10" step="1" value="0" />
|
|
||||||
<output id="styleHeightmapSimplificationOutput">0</output>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr data-tip="Select line interpolation type">
|
|
||||||
<td>Line style</td>
|
|
||||||
<td>
|
|
||||||
<select id="styleHeightmapCurve">
|
|
||||||
<option value="0" selected>Curved</option>
|
|
||||||
<option value="1">Linear</option>
|
|
||||||
<option value="2">Rectangular</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr data-tip="Select color scheme for the element">
|
|
||||||
<td>Color scheme</td>
|
|
||||||
<td>
|
|
||||||
<select id="styleHeightmapScheme"></select>
|
|
||||||
<button
|
|
||||||
id="openCreateHeightmapSchemeButton"
|
|
||||||
data-tip="Click to add a custom heightmap color scheme"
|
|
||||||
data-stops="#ffffff,#EEEECC,#D2B48C,#008000,#008080"
|
|
||||||
class="icon-plus sideButton"
|
|
||||||
></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
<tbody id="styleArmies">
|
<tbody id="styleArmies">
|
||||||
<tr data-tip="Set fill transparency. Set to 0 to make it fully transparent">
|
<tr data-tip="Set fill transparency. Set to 0 to make it fully transparent">
|
||||||
<td>Fill opacity</td>
|
<td>Fill opacity</td>
|
||||||
|
|
@ -1452,6 +1462,84 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
<tbody id="styleScaleBar">
|
||||||
|
<tr data-tip="Set bar and font size">
|
||||||
|
<td>Size</td>
|
||||||
|
<td>
|
||||||
|
<span>Bar </span>
|
||||||
|
<input id="styleScaleBarSize" type="number" min=".5" max="5" step=".1" />
|
||||||
|
<span>Font </span>
|
||||||
|
<input id="styleScaleBarFontSize" type="number" min="1" max="100" step=".1" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Set position of the Scale bar bottom right corner (in percents)">
|
||||||
|
<td>Position</td>
|
||||||
|
<td>
|
||||||
|
<span>x </span>
|
||||||
|
<input id="styleScaleBarPositionX" type="number" min="0" max="100" step="0.1" style="width: 5em" />
|
||||||
|
<span>y </span>
|
||||||
|
<input id="styleScaleBarPositionY" type="number" min="0" max="100" step="0.1" style="width: 5em" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Type scale bar label, leave blank to hide label">
|
||||||
|
<td>Label</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleScaleBarLabel" type="text" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Set background opacity. 0: transparent, 1: solid">
|
||||||
|
<td>Back opacity</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleScaleBarBackgroundOpacityInput" type="range" min="0" max="1" step="0.01" />
|
||||||
|
<output id="styleScaleBarBackgroundOpacityOutput"></output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Set background fill color">
|
||||||
|
<td>Back fill</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleScaleBarBackgroundFillInput" type="color" />
|
||||||
|
<output id="styleScaleBarBackgroundFillOutput"></output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Set background stroke color and width">
|
||||||
|
<td>Back stroke</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleScaleBarBackgroundStrokeInput" type="color" />
|
||||||
|
<output id="styleScaleBarBackgroundStrokeOutput"></output>
|
||||||
|
|
||||||
|
<span>Width </span>
|
||||||
|
<input
|
||||||
|
id="styleScaleBarBackgroundStrokeWidth"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="10"
|
||||||
|
step="0.1"
|
||||||
|
style="width: 5em"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Set background element padding: top, right, bottom, left (in pixels)">
|
||||||
|
<td>Back padding</td>
|
||||||
|
<td style="display: flex; gap: 4px">
|
||||||
|
<input id="styleScaleBarBackgroundPaddingTop" type="number" min="0" max="100" style="width: 5em" />
|
||||||
|
<input id="styleScaleBarBackgroundPaddingRight" type="number" min="0" max="100" style="width: 5em" />
|
||||||
|
<input id="styleScaleBarBackgroundPaddingBottom" type="number" min="0" max="100" style="width: 5em" />
|
||||||
|
<input id="styleScaleBarBackgroundPaddingLeft" type="number" min="0" max="100" style="width: 5em" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Select background filter">
|
||||||
|
<td>Back filter</td>
|
||||||
|
<td><select id="styleScaleBarBackgroundFilter" /></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div id="mapFilters" data-tip="Set a filter to be applied to the map in general">
|
<div id="mapFilters" data-tip="Set a filter to be applied to the map in general">
|
||||||
|
|
@ -4456,7 +4544,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="provincesEditor" class="dialog stable" style="display: none">
|
<div id="provincesEditor" class="dialog stable" style="display: none">
|
||||||
<div id="provincesHeader" class="header" style="grid-template-columns: 11em 8em 8em 8em 5em 8em">
|
<div id="provincesHeader" class="header" style="grid-template-columns: 11em 8em 8em 6em 6em 6em 8em">
|
||||||
<div data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="name">
|
<div data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="name">
|
||||||
Province
|
Province
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -4469,6 +4557,9 @@
|
||||||
<div data-tip="Click to sort by province owner" class="sortable alphabetically" data-sortby="state">
|
<div data-tip="Click to sort by province owner" class="sortable alphabetically" data-sortby="state">
|
||||||
State
|
State
|
||||||
</div>
|
</div>
|
||||||
|
<div data-tip="Click to sort by province burgs count" class="sortable hide" data-sortby="burgs">
|
||||||
|
Burgs
|
||||||
|
</div>
|
||||||
<div data-tip="Click to sort by province area" class="sortable hide" data-sortby="area">Area </div>
|
<div data-tip="Click to sort by province area" class="sortable hide" data-sortby="area">Area </div>
|
||||||
<div data-tip="Click to sort by province population" class="sortable hide" data-sortby="population">
|
<div data-tip="Click to sort by province population" class="sortable hide" data-sortby="population">
|
||||||
Population
|
Population
|
||||||
|
|
@ -4481,6 +4572,9 @@
|
||||||
<div data-tip="Provinces displayed" style="margin-left: 4px">
|
<div data-tip="Provinces displayed" style="margin-left: 4px">
|
||||||
Provinces: <span id="provincesFooterNumber">0</span>
|
Provinces: <span id="provincesFooterNumber">0</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div data-tip="Total burgs number" style="margin-left: 12px">
|
||||||
|
Burgs: <span id="provincesFooterBurgs">0</span>
|
||||||
|
</div>
|
||||||
<div data-tip="Average area" style="margin-left: 14px">
|
<div data-tip="Average area" style="margin-left: 14px">
|
||||||
Mean area: <span id="provincesFooterArea">0</span>
|
Mean area: <span id="provincesFooterArea">0</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -4618,7 +4712,7 @@
|
||||||
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
||||||
<span
|
<span
|
||||||
id="provinceNameEditorShortCulture"
|
id="provinceNameEditorShortCulture"
|
||||||
data-tip="Generate culture-specific name"
|
data-tip="Generate culture-specific name for the province"
|
||||||
class="icon-book pointer"
|
class="icon-book pointer"
|
||||||
></span>
|
></span>
|
||||||
<span id="provinceNameEditorShortRandom" data-tip="Generate random name" class="icon-globe pointer"></span>
|
<span id="provinceNameEditorShortRandom" data-tip="Generate random name" class="icon-globe pointer"></span>
|
||||||
|
|
@ -4694,6 +4788,14 @@
|
||||||
class="icon-arrows-cw pointer"
|
class="icon-arrows-cw pointer"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="provinceCultureName"
|
||||||
|
data-tip="Dominant culture in the province. This defines culture-based naming. Can be changed via the Cultures Editor"
|
||||||
|
style="margin-top: 0.2em"
|
||||||
|
>
|
||||||
|
Dominant culture: <span id="provinceCultureDisplay"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="namesbaseEditor" class="dialog stable textual" style="display: none">
|
<div id="namesbaseEditor" class="dialog stable textual" style="display: none">
|
||||||
|
|
@ -5138,49 +5240,6 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="unitsHeader">
|
|
||||||
<span class="icon-minus"></span>
|
|
||||||
<div>Scale bar:</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Set scale bar size">
|
|
||||||
<div>Bar size:</div>
|
|
||||||
<input id="barSizeOutput" data-stored="barSize" type="range" min=".5" max="5" value="2" step=".1" />
|
|
||||||
<input id="barSizeInput" data-stored="barSize" type="number" min=".5" max="5" value="2" step=".1" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Type scale bar label, leave blank to hide label">
|
|
||||||
<div>Bar label:</div>
|
|
||||||
<input id="barLabel" data-stored="barLabel" type="text" placeholder="hidden" value="" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Set background for Scale bar">
|
|
||||||
<div>Bar background:</div>
|
|
||||||
<input
|
|
||||||
id="barBackOpacity"
|
|
||||||
data-stored="barBackOpacity"
|
|
||||||
type="range"
|
|
||||||
min="0"
|
|
||||||
max="1"
|
|
||||||
value=".2"
|
|
||||||
step=".01"
|
|
||||||
/>
|
|
||||||
<input id="barBackColor" data-stored="barBackColor" type="color" value="#ffffff" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Set position of the Scale bar bottom right corner in percents">
|
|
||||||
<div>Bar position:</div>
|
|
||||||
x:<input id="barPosX" data-stored="barPosX" type="number" min="0" max="100" step=".1" value="99" /> y:<input
|
|
||||||
id="barPosY"
|
|
||||||
data-stored="barPosY"
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="100"
|
|
||||||
step=".1"
|
|
||||||
value="99"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="unitsHeader">
|
<div class="unitsHeader">
|
||||||
<span class="icon-male"></span>
|
<span class="icon-male"></span>
|
||||||
<div>Population:</div>
|
<div>Population:</div>
|
||||||
|
|
@ -7987,7 +8046,7 @@
|
||||||
<script src="utils/commonUtils.js?v=1.89.29"></script>
|
<script src="utils/commonUtils.js?v=1.89.29"></script>
|
||||||
<script src="utils/arrayUtils.js"></script>
|
<script src="utils/arrayUtils.js"></script>
|
||||||
<script src="utils/colorUtils.js"></script>
|
<script src="utils/colorUtils.js"></script>
|
||||||
<script src="utils/graphUtils.js?v=1.93.12"></script>
|
<script src="utils/graphUtils.js?v=1.96.00"></script>
|
||||||
<script src="utils/nodeUtils.js"></script>
|
<script src="utils/nodeUtils.js"></script>
|
||||||
<script src="utils/numberUtils.js?v=1.89.08"></script>
|
<script src="utils/numberUtils.js?v=1.89.08"></script>
|
||||||
<script src="utils/polyfills.js?v=1.95.03"></script>
|
<script src="utils/polyfills.js?v=1.95.03"></script>
|
||||||
|
|
@ -8000,39 +8059,39 @@
|
||||||
<script src="config/heightmap-templates.js"></script>
|
<script src="config/heightmap-templates.js"></script>
|
||||||
<script src="config/precreated-heightmaps.js"></script>
|
<script src="config/precreated-heightmaps.js"></script>
|
||||||
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
|
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
|
||||||
<script src="modules/ocean-layers.js?v=1.95.00"></script>
|
<script src="modules/ocean-layers.js?v=1.96.00"></script>
|
||||||
<script src="modules/river-generator.js?v=1.89.13"></script>
|
<script src="modules/river-generator.js?v=1.89.13"></script>
|
||||||
<script src="modules/lakes.js"></script>
|
<script src="modules/lakes.js"></script>
|
||||||
<script src="modules/biomes.js"></script>
|
<script src="modules/biomes.js"></script>
|
||||||
<script src="modules/names-generator.js?v=1.87.14"></script>
|
<script src="modules/names-generator.js?v=1.87.14"></script>
|
||||||
<script src="modules/cultures-generator.js?v=1.89.10"></script>
|
<script src="modules/cultures-generator.js?v=1.96.00"></script>
|
||||||
<script src="modules/renderers/state-labels.js"></script>
|
<script src="modules/renderers/state-labels.js"></script>
|
||||||
<script src="modules/burgs-and-states.js?v=1.92.00"></script>
|
<script src="modules/burgs-and-states.js?v=1.92.00"></script>
|
||||||
<script src="modules/routes-generator.js"></script>
|
<script src="modules/routes-generator.js"></script>
|
||||||
<script src="modules/religions-generator.js?v=1.93.08"></script>
|
<script src="modules/religions-generator.js?v=1.93.08"></script>
|
||||||
<script src="modules/military-generator.js"></script>
|
<script src="modules/military-generator.js?v=1.96.00"></script>
|
||||||
<script src="modules/markers-generator.js?v=1.93.04"></script>
|
<script src="modules/markers-generator.js?v=1.93.04"></script>
|
||||||
<script src="modules/coa-generator.js?v=1.91.05"></script>
|
<script src="modules/coa-generator.js?v=1.91.05"></script>
|
||||||
<script src="modules/submap.js?v=1.94.01"></script>
|
<script src="modules/submap.js?v=1.96.00"></script>
|
||||||
<script src="libs/polylabel.min.js"></script>
|
<script src="libs/polylabel.min.js"></script>
|
||||||
<script src="libs/lineclip.min.js"></script>
|
<script src="libs/lineclip.min.js"></script>
|
||||||
<script src="libs/alea.min.js"></script>
|
<script src="libs/alea.min.js"></script>
|
||||||
<script src="modules/fonts.js?v=1.89.18"></script>
|
<script src="modules/fonts.js?v=1.89.18"></script>
|
||||||
<script src="modules/ui/layers.js?v=1.94.00"></script>
|
<script src="modules/ui/layers.js?v=1.96.00"></script>
|
||||||
<script src="modules/ui/measurers.js?v=1.94.03"></script>
|
<script src="modules/ui/measurers.js?v=1.96.00"></script>
|
||||||
<script src="modules/ui/stylePresets.js?v=1.95.00"></script>
|
<script src="modules/ui/stylePresets.js?v=1.96.00"></script>
|
||||||
|
|
||||||
<script src="modules/ui/general.js?v=1.94.01"></script>
|
<script src="modules/ui/general.js?v=1.96.00"></script>
|
||||||
<script src="modules/ui/options.js?v=1.94.06"></script>
|
<script src="modules/ui/options.js?v=1.96.00"></script>
|
||||||
<script src="main.js?v=1.94.05"></script>
|
<script src="main.js?v=1.96.00"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
<script defer src="modules/ui/style.js?v=1.95.00"></script>
|
<script defer src="modules/ui/style.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/editors.js?v=1.95.04"></script>
|
<script defer src="modules/ui/editors.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/tools.js?v=1.95.01"></script>
|
<script defer src="modules/ui/tools.js?v=1.95.01"></script>
|
||||||
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
||||||
<script defer src="modules/ui/heightmap-editor.js?v=1.93.00"></script>
|
<script defer src="modules/ui/heightmap-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/provinces-editor.js?v=1.92.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>
|
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
||||||
<script defer src="modules/ui/namesbase-editor.js?v=1.95.02"></script>
|
<script defer src="modules/ui/namesbase-editor.js?v=1.95.02"></script>
|
||||||
<script defer src="modules/ui/elevation-profile.js"></script>
|
<script defer src="modules/ui/elevation-profile.js"></script>
|
||||||
|
|
@ -8045,12 +8104,12 @@
|
||||||
<script defer src="modules/ui/rivers-editor.js"></script>
|
<script defer src="modules/ui/rivers-editor.js"></script>
|
||||||
<script defer src="modules/ui/rivers-creator.js?v=1.89.13"></script>
|
<script defer src="modules/ui/rivers-creator.js?v=1.89.13"></script>
|
||||||
<script defer src="modules/ui/relief-editor.js"></script>
|
<script defer src="modules/ui/relief-editor.js"></script>
|
||||||
<script defer src="modules/ui/burg-editor.js"></script>
|
<script defer src="modules/ui/burg-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/units-editor.js?v=1.94.02"></script>
|
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/notes-editor.js?v=1.93.09"></script>
|
<script defer src="modules/ui/notes-editor.js?v=1.93.09"></script>
|
||||||
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
||||||
<script defer src="modules/ui/zones-editor.js"></script>
|
<script defer src="modules/ui/zones-editor.js"></script>
|
||||||
<script defer src="modules/ui/burgs-overview.js?v=1.93.10"></script>
|
<script defer src="modules/ui/burgs-overview.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/rivers-overview.js"></script>
|
<script defer src="modules/ui/rivers-overview.js"></script>
|
||||||
<script defer src="modules/ui/military-overview.js"></script>
|
<script defer src="modules/ui/military-overview.js"></script>
|
||||||
<script defer src="modules/ui/regiments-overview.js?v=1.89.20"></script>
|
<script defer src="modules/ui/regiments-overview.js?v=1.89.20"></script>
|
||||||
|
|
@ -8060,15 +8119,15 @@
|
||||||
<script defer src="modules/ui/emblems-editor.js?v=1.91.00"></script>
|
<script defer src="modules/ui/emblems-editor.js?v=1.91.00"></script>
|
||||||
<script defer src="modules/ui/markers-editor.js"></script>
|
<script defer src="modules/ui/markers-editor.js"></script>
|
||||||
<script defer src="modules/ui/3d.js?v=1.94.03"></script>
|
<script defer src="modules/ui/3d.js?v=1.94.03"></script>
|
||||||
<script defer src="modules/ui/submap.js?v=1.94.03"></script>
|
<script defer src="modules/ui/submap.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/hotkeys.js?v=1.95.00"></script>
|
<script defer src="modules/ui/hotkeys.js?v=1.95.00"></script>
|
||||||
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
<script defer src="modules/io/save.js?v=1.93.02"></script>
|
<script defer src="modules/io/save.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/load.js?v=1.95.00"></script>
|
<script defer src="modules/io/load.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/cloud.js?v=1.94.04"></script>
|
<script defer src="modules/io/cloud.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/export.js?v=1.95.05"></script>
|
<script defer src="modules/io/export.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/formats.js"></script>
|
<script defer src="modules/io/formats.js"></script>
|
||||||
|
|
||||||
<!-- Web Components -->
|
<!-- Web Components -->
|
||||||
|
|
|
||||||
2
libs/polylabel.min.js
vendored
2
libs/polylabel.min.js
vendored
|
|
@ -1 +1 @@
|
||||||
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).polylabel=t()}}(function(){return function t(n,e,r){function o(a,u){if(!e[a]){if(!n[a]){var f="function"==typeof require&&require;if(!u&&f)return f(a,!0);if(i)return i(a,!0);var h=new Error("Cannot find module '"+a+"'");throw h.code="MODULE_NOT_FOUND",h}var s=e[a]={exports:{}};n[a][0].call(s.exports,function(t){var e=n[a][1][t];return o(e||t)},s,s.exports,t,n,e,r)}return e[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(t,n,e){"use strict";var r=t("tinyqueue");function o(t,n){return n.max-t.max}function i(t,n,e,r){this.x=t,this.y=n,this.h=e,this.d=function(t,n,e){for(var r=!1,o=1/0,i=0;i<e.length;i++)for(var u=e[i],f=0,h=u.length,s=h-1;f<h;s=f++){var d=u[f],l=u[s];d[1]>n!=l[1]>n&&t<(l[0]-d[0])*(n-d[1])/(l[1]-d[1])+d[0]&&(r=!r),o=Math.min(o,a(t,n,d,l))}return(r?1:-1)*Math.sqrt(o)}(t,n,r),this.max=this.d+this.h*Math.SQRT2}function a(t,n,e,r){var o=e[0],i=e[1],a=r[0]-o,u=r[1]-i;if(0!==a||0!==u){var f=((t-o)*a+(n-i)*u)/(a*a+u*u);f>1?(o=r[0],i=r[1]):f>0&&(o+=a*f,i+=u*f)}return(a=t-o)*a+(u=n-i)*u}n.exports=function(t,n,e){var a,u,f,h;n=n||1;for(var s=0;s<t[0].length;s++){var d=t[0][s];(!s||d[0]<a)&&(a=d[0]),(!s||d[1]<u)&&(u=d[1]),(!s||d[0]>f)&&(f=d[0]),(!s||d[1]>h)&&(h=d[1])}for(var l=f-a,p=h-u,c=Math.min(l,p),v=c/2,g=new r(null,o),x=a;x<f;x+=c)for(var y=u;y<h;y+=c)g.push(new i(x+v,y+v,v,t));var w=function(t){for(var n=0,e=0,r=0,o=t[0],a=0,u=o.length,f=u-1;a<u;f=a++){var h=o[a],s=o[f],d=h[0]*s[1]-s[0]*h[1];e+=(h[0]+s[0])*d,r+=(h[1]+s[1])*d,n+=3*d}return new i(e/n,r/n,0,t)}(t),m=g.length;for(;g.length;){var b=g.pop();b.d>w.d&&(w=b,e&&console.log("found best %d after %d probes",Math.round(1e4*b.d)/1e4,m)),b.max-w.d<=n||(v=b.h/2,g.push(new i(b.x-v,b.y-v,v,t)),g.push(new i(b.x+v,b.y-v,v,t)),g.push(new i(b.x-v,b.y+v,v,t)),g.push(new i(b.x+v,b.y+v,v,t)),m+=4)}e&&(console.log("num probes: "+m),console.log("best distance: "+w.d));return[w.x,w.y]}},{tinyqueue:2}],2:[function(t,n,e){"use strict";function r(t,n){if(!(this instanceof r))return new r(t,n);if(this.data=t||[],this.length=this.data.length,this.compare=n||o,t)for(var e=Math.floor(this.length/2);e>=0;e--)this._down(e)}function o(t,n){return t<n?-1:t>n?1:0}function i(t,n,e){var r=t[n];t[n]=t[e],t[e]=r}n.exports=r,r.prototype={push:function(t){this.data.push(t),this.length++,this._up(this.length-1)},pop:function(){var t=this.data[0];return this.data[0]=this.data[this.length-1],this.length--,this.data.pop(),this._down(0),t},peek:function(){return this.data[0]},_up:function(t){for(var n=this.data,e=this.compare;t>0;){var r=Math.floor((t-1)/2);if(!(e(n[t],n[r])<0))break;i(n,r,t),t=r}},_down:function(t){for(var n=this.data,e=this.compare,r=this.length;;){var o=2*t+1,a=o+1,u=t;if(o<r&&e(n[o],n[u])<0&&(u=o),a<r&&e(n[a],n[u])<0&&(u=a),u===t)return;i(n,u,t),t=u}}}},{}]},{},[1])(1)});
|
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).polylabel=t()}}(function(){return function t(n,e,r){function o(a,u){if(!e[a]){if(!n[a]){var f="function"==typeof require&&require;if(!u&&f)return f(a,!0);if(i)return i(a,!0);var h=new Error("Cannot find module '"+a+"'");throw h.code="MODULE_NOT_FOUND",h}var s=e[a]={exports:{}};n[a][0].call(s.exports,function(t){var e=n[a][1][t];return o(e||t)},s,s.exports,t,n,e,r)}return e[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(t,n,e){"use strict";var r=t("tinyqueue");function o(t,n){return n.max-t.max}function i(t,n,e,r){this.x=t,this.y=n,this.h=e,this.d=function(t,n,e){for(var r=!1,o=1/0,i=0;i<e.length;i++)for(var u=e[i],f=0,h=u.length,s=h-1;f<h;s=f++){var d=u[f],l=u[s];d[1]>n!=l[1]>n&&t<(l[0]-d[0])*(n-d[1])/(l[1]-d[1])+d[0]&&(r=!r),o=Math.min(o,a(t,n,d,l))}return(r?1:-1)*Math.sqrt(o)}(t,n,r),this.max=this.d+this.h*Math.SQRT2}function a(t,n,e,r){var o=e[0],i=e[1],a=r[0]-o,u=r[1]-i;if(0!==a||0!==u){var f=((t-o)*a+(n-i)*u)/(a*a+u*u);f>1?(o=r[0],i=r[1]):f>0&&(o+=a*f,i+=u*f)}return(a=t-o)*a+(u=n-i)*u}n.exports=function(t,n,e){var a,u,f,h;n=n||1;for(var s=0;s<t[0].length;s++){var d=t[0][s];(!s||d[0]<a)&&(a=d[0]),(!s||d[1]<u)&&(u=d[1]),(!s||d[0]>f)&&(f=d[0]),(!s||d[1]>h)&&(h=d[1])}for(var l=f-a,p=h-u,c=Math.min(l,p),v=c/2,g=new r(null,o),x=a;x<f;x+=c)for(var y=u;y<h;y+=c)g.push(new i(x+v,y+v,v,t));var w=function(t){for(var n=0,e=0,r=0,o=t[0],a=0,u=o.length,f=u-1;a<u;f=a++){var h=o[a],s=o[f],d=h[0]*s[1]-s[0]*h[1];e+=(h[0]+s[0])*d,r+=(h[1]+s[1])*d,n+=3*d}return new i(e/n,r/n,0,t)}(t),m=g.length;for(;g.length;){var b=g.pop();b.d>w.d&&(w=b,e&&console.info("found best %d after %d probes",Math.round(1e4*b.d)/1e4,m)),b.max-w.d<=n||(v=b.h/2,g.push(new i(b.x-v,b.y-v,v,t)),g.push(new i(b.x+v,b.y-v,v,t)),g.push(new i(b.x-v,b.y+v,v,t)),g.push(new i(b.x+v,b.y+v,v,t)),m+=4)}e&&(console.info("num probes: "+m),console.info("best distance: "+w.d));return[w.x,w.y]}},{tinyqueue:2}],2:[function(t,n,e){"use strict";function r(t,n){if(!(this instanceof r))return new r(t,n);if(this.data=t||[],this.length=this.data.length,this.compare=n||o,t)for(var e=Math.floor(this.length/2);e>=0;e--)this._down(e)}function o(t,n){return t<n?-1:t>n?1:0}function i(t,n,e){var r=t[n];t[n]=t[e],t[e]=r}n.exports=r,r.prototype={push:function(t){this.data.push(t),this.length++,this._up(this.length-1)},pop:function(){var t=this.data[0];return this.data[0]=this.data[this.length-1],this.length--,this.data.pop(),this._down(0),t},peek:function(){return this.data[0]},_up:function(t){for(var n=this.data,e=this.compare;t>0;){var r=Math.floor((t-1)/2);if(!(e(n[t],n[r])<0))break;i(n,r,t),t=r}},_down:function(t){for(var n=this.data,e=this.compare,r=this.length;;){var o=2*t+1,a=o+1,u=t;if(o<r&&e(n[o],n[u])<0&&(u=o),a<r&&e(n[a],n[u])<0&&(u=a),u===t)return;i(n,u,t),t=u}}}},{}]},{},[1])(1)});
|
||||||
2
libs/three.min.js
vendored
2
libs/three.min.js
vendored
File diff suppressed because one or more lines are too long
53
main.js
53
main.js
|
|
@ -92,16 +92,19 @@ let fogging = viewbox
|
||||||
let ruler = viewbox.append("g").attr("id", "ruler").style("display", "none");
|
let ruler = viewbox.append("g").attr("id", "ruler").style("display", "none");
|
||||||
let debug = viewbox.append("g").attr("id", "debug");
|
let debug = viewbox.append("g").attr("id", "debug");
|
||||||
|
|
||||||
// lake and coast groups
|
|
||||||
lakes.append("g").attr("id", "freshwater");
|
lakes.append("g").attr("id", "freshwater");
|
||||||
lakes.append("g").attr("id", "salt");
|
lakes.append("g").attr("id", "salt");
|
||||||
lakes.append("g").attr("id", "sinkhole");
|
lakes.append("g").attr("id", "sinkhole");
|
||||||
lakes.append("g").attr("id", "frozen");
|
lakes.append("g").attr("id", "frozen");
|
||||||
lakes.append("g").attr("id", "lava");
|
lakes.append("g").attr("id", "lava");
|
||||||
lakes.append("g").attr("id", "dry");
|
lakes.append("g").attr("id", "dry");
|
||||||
|
|
||||||
coastline.append("g").attr("id", "sea_island");
|
coastline.append("g").attr("id", "sea_island");
|
||||||
coastline.append("g").attr("id", "lake_island");
|
coastline.append("g").attr("id", "lake_island");
|
||||||
|
|
||||||
|
terrs.append("g").attr("id", "oceanHeights");
|
||||||
|
terrs.append("g").attr("id", "landHeights");
|
||||||
|
|
||||||
labels.append("g").attr("id", "states");
|
labels.append("g").attr("id", "states");
|
||||||
labels.append("g").attr("id", "addedLabels");
|
labels.append("g").attr("id", "addedLabels");
|
||||||
|
|
||||||
|
|
@ -841,8 +844,8 @@ function openNearSeaLakes() {
|
||||||
const LIMIT = 22; // max height that can be breached by water
|
const LIMIT = 22; // max height that can be breached by water
|
||||||
|
|
||||||
for (const i of cells.i) {
|
for (const i of cells.i) {
|
||||||
const lake = cells.f[i];
|
const lakeFeatureId = cells.f[i];
|
||||||
if (features[lake].type !== "lake") continue; // not a lake cell
|
if (features[lakeFeatureId].type !== "lake") continue; // not a lake
|
||||||
|
|
||||||
check_neighbours: for (const c of cells.c[i]) {
|
check_neighbours: for (const c of cells.c[i]) {
|
||||||
if (cells.t[c] !== 1 || cells.h[c] > LIMIT) continue; // water cannot break this
|
if (cells.t[c] !== 1 || cells.h[c] > LIMIT) continue; // water cannot break this
|
||||||
|
|
@ -850,20 +853,24 @@ function openNearSeaLakes() {
|
||||||
for (const n of cells.c[c]) {
|
for (const n of cells.c[c]) {
|
||||||
const ocean = cells.f[n];
|
const ocean = cells.f[n];
|
||||||
if (features[ocean].type !== "ocean") continue; // not an ocean
|
if (features[ocean].type !== "ocean") continue; // not an ocean
|
||||||
removeLake(c, lake, ocean);
|
removeLake(c, lakeFeatureId, ocean);
|
||||||
break check_neighbours;
|
break check_neighbours;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeLake(threshold, lake, ocean) {
|
function removeLake(thresholdCellId, lakeFeatureId, oceanFeatureId) {
|
||||||
cells.h[threshold] = 19;
|
cells.h[thresholdCellId] = 19;
|
||||||
cells.t[threshold] = -1;
|
cells.t[thresholdCellId] = -1;
|
||||||
cells.f[threshold] = ocean;
|
cells.f[thresholdCellId] = oceanFeatureId;
|
||||||
cells.c[threshold].forEach(function (c) {
|
cells.c[thresholdCellId].forEach(function (c) {
|
||||||
if (cells.h[c] >= 20) cells.t[c] = 1; // mark as coastline
|
if (cells.h[c] >= 20) cells.t[c] = 1; // mark as coastline
|
||||||
});
|
});
|
||||||
features[lake].type = "ocean"; // mark former lake as ocean
|
|
||||||
|
cells.i.forEach(i => {
|
||||||
|
if (cells.f[i] === lakeFeatureId) cells.f[i] = oceanFeatureId;
|
||||||
|
});
|
||||||
|
features[lakeFeatureId].type = "ocean"; // mark former lake as ocean
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME && console.timeEnd("openLakes");
|
TIME && console.timeEnd("openLakes");
|
||||||
|
|
@ -1250,6 +1257,7 @@ function drawCoastline() {
|
||||||
features[f].vertices = vchain;
|
features[f].vertices = vchain;
|
||||||
|
|
||||||
const path = round(lineGen(points));
|
const path = round(lineGen(points));
|
||||||
|
|
||||||
if (features[f].type === "lake") {
|
if (features[f].type === "lake") {
|
||||||
landMask
|
landMask
|
||||||
.append("path")
|
.append("path")
|
||||||
|
|
@ -1347,22 +1355,14 @@ function drawCoastline() {
|
||||||
// Re-mark features (ocean, lakes, islands)
|
// Re-mark features (ocean, lakes, islands)
|
||||||
function reMarkFeatures() {
|
function reMarkFeatures() {
|
||||||
TIME && console.time("reMarkFeatures");
|
TIME && console.time("reMarkFeatures");
|
||||||
const cells = pack.cells,
|
const cells = pack.cells;
|
||||||
features = (pack.features = [0]);
|
const features = (pack.features = [0]);
|
||||||
|
|
||||||
cells.f = new Uint16Array(cells.i.length); // cell feature number
|
cells.f = new Uint16Array(cells.i.length); // cell feature number
|
||||||
cells.t = new Int8Array(cells.i.length); // cell type: 1 = land along coast; -1 = water along coast;
|
cells.t = new Int8Array(cells.i.length); // cell type: 1 = land along coast; -1 = water along coast;
|
||||||
cells.haven = cells.i.length < 65535 ? new Uint16Array(cells.i.length) : new Uint32Array(cells.i.length); // cell haven (opposite water cell);
|
cells.haven = cells.i.length < 65535 ? new Uint16Array(cells.i.length) : new Uint32Array(cells.i.length); // cell haven (opposite water cell);
|
||||||
cells.harbor = new Uint8Array(cells.i.length); // cell harbor (number of adjacent water cells);
|
cells.harbor = new Uint8Array(cells.i.length); // cell harbor (number of adjacent water cells);
|
||||||
|
|
||||||
const defineHaven = i => {
|
|
||||||
const water = cells.c[i].filter(c => cells.h[c] < 20);
|
|
||||||
const dist2 = water.map(c => (cells.p[i][0] - cells.p[c][0]) ** 2 + (cells.p[i][1] - cells.p[c][1]) ** 2);
|
|
||||||
const closest = water[dist2.indexOf(Math.min.apply(Math, dist2))];
|
|
||||||
|
|
||||||
cells.haven[i] = closest;
|
|
||||||
cells.harbor[i] = water.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!cells.i.length) return; // no cells -> there is nothing to do
|
if (!cells.i.length) return; // no cells -> there is nothing to do
|
||||||
for (let i = 1, queue = [0]; queue[0] !== -1; i++) {
|
for (let i = 1, queue = [0]; queue[0] !== -1; i++) {
|
||||||
const start = queue[0]; // first cell
|
const start = queue[0]; // first cell
|
||||||
|
|
@ -1403,6 +1403,15 @@ function reMarkFeatures() {
|
||||||
// markupPackLand
|
// markupPackLand
|
||||||
markup(pack.cells, 3, 1, 0);
|
markup(pack.cells, 3, 1, 0);
|
||||||
|
|
||||||
|
function defineHaven(i) {
|
||||||
|
const water = cells.c[i].filter(c => cells.h[c] < 20);
|
||||||
|
const dist2 = water.map(c => (cells.p[i][0] - cells.p[c][0]) ** 2 + (cells.p[i][1] - cells.p[c][1]) ** 2);
|
||||||
|
const closest = water[dist2.indexOf(Math.min.apply(Math, dist2))];
|
||||||
|
|
||||||
|
cells.haven[i] = closest;
|
||||||
|
cells.harbor[i] = water.length;
|
||||||
|
}
|
||||||
|
|
||||||
function defineOceanGroup(number) {
|
function defineOceanGroup(number) {
|
||||||
if (number > grid.cells.i.length / 25) return "ocean";
|
if (number > grid.cells.i.length / 25) return "ocean";
|
||||||
if (number > grid.cells.i.length / 100) return "sea";
|
if (number > grid.cells.i.length / 100) return "sea";
|
||||||
|
|
@ -1925,7 +1934,7 @@ function showStatistics() {
|
||||||
|
|
||||||
mapId = Date.now(); // unique map id is it's creation date number
|
mapId = Date.now(); // unique map id is it's creation date number
|
||||||
mapHistory.push({seed, width: graphWidth, height: graphHeight, template: heightmap, created: mapId});
|
mapHistory.push({seed, width: graphWidth, height: graphHeight, template: heightmap, created: mapId});
|
||||||
INFO && console.log(stats);
|
INFO && console.info(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
const regenerateMap = debounce(async function (options) {
|
const regenerateMap = debounce(async function (options) {
|
||||||
|
|
|
||||||
|
|
@ -71,28 +71,31 @@ window.Cultures = (function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cell = (c.center = placeCenter(c.sort ? c.sort : i => cells.s[i]));
|
const sortingFn = c.sort ? c.sort : i => cells.s[i];
|
||||||
centers.add(cells.p[cell]);
|
const center = placeCenter(sortingFn);
|
||||||
|
|
||||||
|
centers.add(cells.p[center]);
|
||||||
|
c.center = center;
|
||||||
c.i = newId;
|
c.i = newId;
|
||||||
delete c.odd;
|
delete c.odd;
|
||||||
delete c.sort;
|
delete c.sort;
|
||||||
c.color = colors[i];
|
c.color = colors[i];
|
||||||
c.type = defineCultureType(cell);
|
c.type = defineCultureType(center);
|
||||||
c.expansionism = defineCultureExpansionism(c.type);
|
c.expansionism = defineCultureExpansionism(c.type);
|
||||||
c.origins = [0];
|
c.origins = [0];
|
||||||
c.code = abbreviate(c.name, codes);
|
c.code = abbreviate(c.name, codes);
|
||||||
codes.push(c.code);
|
codes.push(c.code);
|
||||||
cultureIds[cell] = newId;
|
cultureIds[center] = newId;
|
||||||
if (emblemShape === "random") c.shield = getRandomShield();
|
if (emblemShape === "random") c.shield = getRandomShield();
|
||||||
});
|
});
|
||||||
|
|
||||||
cells.culture = cultureIds;
|
cells.culture = cultureIds;
|
||||||
|
|
||||||
function placeCenter(v) {
|
function placeCenter(sortingFn) {
|
||||||
let spacing = (graphWidth + graphHeight) / 2 / count;
|
let spacing = (graphWidth + graphHeight) / 2 / count;
|
||||||
const MAX_ATTEMPTS = 100;
|
const MAX_ATTEMPTS = 100;
|
||||||
|
|
||||||
const sorted = [...populated].sort((a, b) => v(b) - v(a));
|
const sorted = [...populated].sort((a, b) => sortingFn(b) - sortingFn(a));
|
||||||
const max = Math.floor(sorted.length / 2);
|
const max = Math.floor(sorted.length / 2);
|
||||||
|
|
||||||
let cellId = 0;
|
let cellId = 0;
|
||||||
|
|
|
||||||
|
|
@ -736,4 +736,95 @@ export function resolveVersionConflicts(version) {
|
||||||
.style("display", "none");
|
.style("display", "none");
|
||||||
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version < 1.96) {
|
||||||
|
// v1.96 added ocean rendering for heightmap
|
||||||
|
terrs.selectAll("*").remove();
|
||||||
|
|
||||||
|
const opacity = terrs.attr("opacity");
|
||||||
|
const filter = terrs.attr("filter");
|
||||||
|
const scheme = terrs.attr("scheme");
|
||||||
|
const terracing = terrs.attr("terracing");
|
||||||
|
const skip = terrs.attr("skip");
|
||||||
|
const relax = terrs.attr("relax");
|
||||||
|
|
||||||
|
const curveTypes = {0: "curveBasisClosed", 1: "curveLinear", 2: "curveStep"};
|
||||||
|
const curve = curveTypes[terrs.attr("curve")] || "curveBasisClosed";
|
||||||
|
|
||||||
|
terrs
|
||||||
|
.attr("mask", null)
|
||||||
|
.attr("scheme", null)
|
||||||
|
.attr("terracing", null)
|
||||||
|
.attr("skip", null)
|
||||||
|
.attr("relax", null)
|
||||||
|
.attr("curve", null);
|
||||||
|
|
||||||
|
terrs
|
||||||
|
.append("g")
|
||||||
|
.attr("id", "oceanHeights")
|
||||||
|
.attr("data-render", 0)
|
||||||
|
.attr("opacity", opacity)
|
||||||
|
.attr("filter", filter)
|
||||||
|
.attr("scheme", scheme)
|
||||||
|
.attr("terracing", 0)
|
||||||
|
.attr("skip", 0)
|
||||||
|
.attr("relax", 1)
|
||||||
|
.attr("curve", curve);
|
||||||
|
terrs
|
||||||
|
.append("g")
|
||||||
|
.attr("id", "landHeights")
|
||||||
|
.attr("opacity", opacity)
|
||||||
|
.attr("scheme", scheme)
|
||||||
|
.attr("filter", filter)
|
||||||
|
.attr("terracing", terracing)
|
||||||
|
.attr("skip", skip)
|
||||||
|
.attr("relax", relax)
|
||||||
|
.attr("curve", curve)
|
||||||
|
.attr("mask", "url(#land)");
|
||||||
|
|
||||||
|
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||||
|
|
||||||
|
// v1.96.00 moved scaleBar options from units editor to style
|
||||||
|
d3.select("#scaleBar").remove();
|
||||||
|
|
||||||
|
scaleBar = svg
|
||||||
|
.insert("g", "#viewbox + *")
|
||||||
|
.attr("id", "scaleBar")
|
||||||
|
.attr("opacity", 1)
|
||||||
|
.attr("fill", "#353540")
|
||||||
|
.attr("data-bar-size", 2)
|
||||||
|
.attr("font-size", 10)
|
||||||
|
.attr("data-x", 99)
|
||||||
|
.attr("data-y", 99)
|
||||||
|
.attr("data-label", "");
|
||||||
|
|
||||||
|
scaleBar
|
||||||
|
.append("rect")
|
||||||
|
.attr("id", "scaleBarBack")
|
||||||
|
.attr("opacity", 0.2)
|
||||||
|
.attr("fill", "#ffffff")
|
||||||
|
.attr("stroke", "#000000")
|
||||||
|
.attr("stroke-width", 1)
|
||||||
|
.attr("filter", "url(#blur5)")
|
||||||
|
.attr("data-top", 20)
|
||||||
|
.attr("data-right", 15)
|
||||||
|
.attr("data-bottom", 15)
|
||||||
|
.attr("data-left", 10);
|
||||||
|
|
||||||
|
drawScaleBar(scaleBar, scale);
|
||||||
|
fitScaleBar(scaleBar, svgWidth, svgHeight);
|
||||||
|
|
||||||
|
if (!layerIsOn("toggleScaleBar")) scaleBar.style("display", "none");
|
||||||
|
|
||||||
|
// v1.96.00 changed coloring approach for regiments
|
||||||
|
armies.selectAll(":scope > g").each(function () {
|
||||||
|
const fill = this.getAttribute("fill");
|
||||||
|
if (!fill) return;
|
||||||
|
const darkerColor = d3.color(fill).darker().hex();
|
||||||
|
this.setAttribute("color", darkerColor);
|
||||||
|
this.querySelectorAll("g > rect:nth-child(2)").forEach(rect => {
|
||||||
|
rect.setAttribute("fill", "currentColor");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -434,13 +434,13 @@ function editStateName(state) {
|
||||||
modules.editStateName = true;
|
modules.editStateName = true;
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
byId("stateNameEditorShortCulture").on("click", regenerateShortNameCuture);
|
byId("stateNameEditorShortCulture").on("click", regenerateShortNameCulture);
|
||||||
byId("stateNameEditorShortRandom").on("click", regenerateShortNameRandom);
|
byId("stateNameEditorShortRandom").on("click", regenerateShortNameRandom);
|
||||||
byId("stateNameEditorAddForm").on("click", addCustomForm);
|
byId("stateNameEditorAddForm").on("click", addCustomForm);
|
||||||
byId("stateNameEditorCustomForm").on("change", addCustomForm);
|
byId("stateNameEditorCustomForm").on("change", addCustomForm);
|
||||||
byId("stateNameEditorFullRegenerate").on("click", regenerateFullName);
|
byId("stateNameEditorFullRegenerate").on("click", regenerateFullName);
|
||||||
|
|
||||||
function regenerateShortNameCuture() {
|
function regenerateShortNameCulture() {
|
||||||
const state = +stateNameEditor.dataset.state;
|
const state = +stateNameEditor.dataset.state;
|
||||||
const culture = pack.states[state].culture;
|
const culture = pack.states[state].culture;
|
||||||
const name = Names.getState(Names.getCultureShort(culture), culture);
|
const name = Names.getState(Names.getCultureShort(culture), culture);
|
||||||
|
|
@ -1394,6 +1394,7 @@ function openStateMergeDialog() {
|
||||||
|
|
||||||
function mergeStates(statesToMerge, rulingStateId) {
|
function mergeStates(statesToMerge, rulingStateId) {
|
||||||
const rulingState = pack.states[rulingStateId];
|
const rulingState = pack.states[rulingStateId];
|
||||||
|
const rulingStateArmy = byId("army" + rulingStateId);
|
||||||
|
|
||||||
// remove states to be merged
|
// remove states to be merged
|
||||||
statesToMerge.forEach(stateId => {
|
statesToMerge.forEach(stateId => {
|
||||||
|
|
@ -1410,27 +1411,25 @@ function openStateMergeDialog() {
|
||||||
emblems.select(`#stateEmblems > use[data-i='${stateId}']`).remove();
|
emblems.select(`#stateEmblems > use[data-i='${stateId}']`).remove();
|
||||||
|
|
||||||
// add merged state regiments to the ruling state
|
// add merged state regiments to the ruling state
|
||||||
state.military.forEach(m => {
|
state.military.forEach(regiment => {
|
||||||
const oldId = `regiment${stateId}-${m.i}`;
|
const oldId = `regiment${stateId}-${regiment.i}`;
|
||||||
|
const newIndex = rulingState.military.length;
|
||||||
const newRegiment = {...m, i: rulingState.military.length};
|
rulingState.military.push({...regiment, i: newIndex});
|
||||||
rulingState.military.push(newRegiment);
|
const newId = `regiment${rulingStateId}-${newIndex}`;
|
||||||
|
|
||||||
const newId = `regiment${rulingStateId}-${newRegiment.i}`;
|
|
||||||
|
|
||||||
const note = notes.find(n => n.id === oldId);
|
const note = notes.find(n => n.id === oldId);
|
||||||
if (note) note.id = newId;
|
if (note) note.id = newId;
|
||||||
|
|
||||||
const rulingStateArmy = armies.select("g#army" + rulingStateId);
|
const element = byId(oldId);
|
||||||
armies
|
if (element) {
|
||||||
.select("g#army" + stateId)
|
element.id = newId;
|
||||||
.selectAll("g")
|
element.dataset.state = rulingStateId;
|
||||||
.each(function () {
|
element.dataset.i = newIndex;
|
||||||
this.setAttribute("id", newId);
|
rulingStateArmy.appendChild(element);
|
||||||
rulingStateArmy.node().appendChild(this);
|
}
|
||||||
});
|
|
||||||
armies.select("g#army" + stateId).remove();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
armies.select("g#army" + stateId).remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
// reassing burgs
|
// reassing burgs
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,6 @@ function getSettings() {
|
||||||
heightUnit: heightUnit.value,
|
heightUnit: heightUnit.value,
|
||||||
heightExponent: heightExponentInput.value,
|
heightExponent: heightExponentInput.value,
|
||||||
temperatureScale: temperatureScale.value,
|
temperatureScale: temperatureScale.value,
|
||||||
barSize: barSizeInput.value,
|
|
||||||
barLabel: barLabel.value,
|
|
||||||
barBackOpacity: barBackOpacity.value,
|
|
||||||
barBackColor: barBackColor.value,
|
|
||||||
barPosX: barPosX.value,
|
|
||||||
barPosY: barPosY.value,
|
|
||||||
populationRate: populationRate,
|
populationRate: populationRate,
|
||||||
urbanization: urbanization,
|
urbanization: urbanization,
|
||||||
mapSize: mapSizeOutput.value,
|
mapSize: mapSizeOutput.value,
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,6 @@ function confirmHeightmapEdit() {
|
||||||
function getHeightmapPreview(heights) {
|
function getHeightmapPreview(heights) {
|
||||||
const scheme = getColorScheme(byId("heightmapSelectionColorScheme").value);
|
const scheme = getColorScheme(byId("heightmapSelectionColorScheme").value);
|
||||||
const renderOcean = byId("heightmapSelectionRenderOcean").checked;
|
const renderOcean = byId("heightmapSelectionRenderOcean").checked;
|
||||||
const dataUrl = drawHeights({heights, width: grid.cellsX, height: grid.cellsY, scheme, renderOcean});
|
const dataUrl = drawHeights({heights, width: graph.cellsX, height: graph.cellsY, scheme, renderOcean});
|
||||||
return dataUrl;
|
return dataUrl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ window.Cloud = (function () {
|
||||||
|
|
||||||
async save(fileName, contents) {
|
async save(fileName, contents) {
|
||||||
const resp = await this.call("filesUpload", {path: "/" + fileName, contents});
|
const resp = await this.call("filesUpload", {path: "/" + fileName, contents});
|
||||||
DEBUG && console.log("Dropbox response:", resp);
|
DEBUG && console.info("Dropbox response:", resp);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ window.Cloud = (function () {
|
||||||
|
|
||||||
// Callback function for auth window
|
// Callback function for auth window
|
||||||
async setDropBoxToken(token) {
|
async setDropBoxToken(token) {
|
||||||
DEBUG && console.log("Access token:", token);
|
DEBUG && console.info("Access token:", token);
|
||||||
setToken(this.name, token);
|
setToken(this.name, token);
|
||||||
await this.connect(token);
|
await this.connect(token);
|
||||||
this.authWindow.close();
|
this.authWindow.close();
|
||||||
|
|
@ -131,7 +131,7 @@ window.Cloud = (function () {
|
||||||
allow_download: true
|
allow_download: true
|
||||||
};
|
};
|
||||||
const resp = await this.call("sharingCreateSharedLinkWithSettings", {path, settings});
|
const resp = await this.call("sharingCreateSharedLinkWithSettings", {path, settings});
|
||||||
DEBUG && console.log("Dropbox link object:", resp.result);
|
DEBUG && console.info("Dropbox link object:", resp.result);
|
||||||
return resp.result.url;
|
return resp.result.url;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ async function quickLoad() {
|
||||||
async function loadFromDropbox() {
|
async function loadFromDropbox() {
|
||||||
const mapPath = byId("loadFromDropboxSelect")?.value;
|
const mapPath = byId("loadFromDropboxSelect")?.value;
|
||||||
|
|
||||||
DEBUG && console.log("Loading map from Dropbox:", mapPath);
|
DEBUG && console.info("Loading map from Dropbox:", mapPath);
|
||||||
const blob = await Cloud.providers.dropbox.load(mapPath);
|
const blob = await Cloud.providers.dropbox.load(mapPath);
|
||||||
uploadMap(blob);
|
uploadMap(blob);
|
||||||
}
|
}
|
||||||
|
|
@ -183,22 +183,22 @@ function showUploadMessage(type, mapData, mapVersion) {
|
||||||
title = "Newer file";
|
title = "Newer file";
|
||||||
canBeLoaded = false;
|
canBeLoaded = false;
|
||||||
} else if (type === "outdated") {
|
} else if (type === "outdated") {
|
||||||
message = `The map version (${mapVersion}) does not match the Generator version (${version}).<br>That is fine, click OK to the get map <b style="color: #005000">auto-updated</b>.<br>In case of issues please keep using an ${archive} of the Generator`;
|
INFO && console.info(`Loading map. Auto-update from ${mapVersion} to ${version}`);
|
||||||
title = "Outdated file";
|
parseLoadedData(mapData, mapVersion);
|
||||||
canBeLoaded = true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
alertMessage.innerHTML = message;
|
alertMessage.innerHTML = message;
|
||||||
const buttons = {
|
const buttons = {
|
||||||
OK: function () {
|
OK: function () {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
if (canBeLoaded) parseLoadedData(mapData);
|
if (canBeLoaded) parseLoadedData(mapData, mapVersion);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$("#alert").dialog({title, buttons});
|
$("#alert").dialog({title, buttons});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function parseLoadedData(data) {
|
async function parseLoadedData(data, mapVersion) {
|
||||||
try {
|
try {
|
||||||
// exit customization
|
// exit customization
|
||||||
if (window.closeDialogs) closeDialogs();
|
if (window.closeDialogs) closeDialogs();
|
||||||
|
|
@ -218,6 +218,7 @@ async function parseLoadedData(data) {
|
||||||
|
|
||||||
INFO && console.group("Loaded Map " + seed);
|
INFO && console.group("Loaded Map " + seed);
|
||||||
|
|
||||||
|
// TODO: move all to options object
|
||||||
void (function parseSettings() {
|
void (function parseSettings() {
|
||||||
const settings = data[1].split("|");
|
const settings = data[1].split("|");
|
||||||
if (settings[0]) applyOption(distanceUnitInput, settings[0]);
|
if (settings[0]) applyOption(distanceUnitInput, settings[0]);
|
||||||
|
|
@ -226,23 +227,16 @@ async function parseLoadedData(data) {
|
||||||
if (settings[3]) applyOption(heightUnit, settings[3]);
|
if (settings[3]) applyOption(heightUnit, settings[3]);
|
||||||
if (settings[4]) heightExponentInput.value = heightExponentOutput.value = settings[4];
|
if (settings[4]) heightExponentInput.value = heightExponentOutput.value = settings[4];
|
||||||
if (settings[5]) temperatureScale.value = settings[5];
|
if (settings[5]) temperatureScale.value = settings[5];
|
||||||
if (settings[6]) barSizeInput.value = barSizeOutput.value = settings[6];
|
// setting 6-11 (scaleBar) are part of style now, kept as "" in newer versions for compatibility
|
||||||
if (settings[7] !== undefined) barLabel.value = settings[7];
|
|
||||||
if (settings[8] !== undefined) barBackOpacity.value = settings[8];
|
|
||||||
if (settings[9]) barBackColor.value = settings[9];
|
|
||||||
if (settings[10]) barPosX.value = settings[10];
|
|
||||||
if (settings[11]) barPosY.value = settings[11];
|
|
||||||
if (settings[12]) populationRate = populationRateInput.value = populationRateOutput.value = settings[12];
|
if (settings[12]) populationRate = populationRateInput.value = populationRateOutput.value = settings[12];
|
||||||
if (settings[13]) urbanization = urbanizationInput.value = urbanizationOutput.value = settings[13];
|
if (settings[13]) urbanization = urbanizationInput.value = urbanizationOutput.value = settings[13];
|
||||||
if (settings[14]) mapSizeInput.value = mapSizeOutput.value = minmax(settings[14], 1, 100);
|
if (settings[14]) mapSizeInput.value = mapSizeOutput.value = minmax(settings[14], 1, 100);
|
||||||
if (settings[15]) latitudeInput.value = latitudeOutput.value = minmax(settings[15], 0, 100);
|
if (settings[15]) latitudeInput.value = latitudeOutput.value = minmax(settings[15], 0, 100);
|
||||||
if (settings[18]) precInput.value = precOutput.value = settings[18];
|
if (settings[18]) precInput.value = precOutput.value = settings[18];
|
||||||
|
|
||||||
if (settings[19]) options = JSON.parse(settings[19]);
|
if (settings[19]) options = JSON.parse(settings[19]);
|
||||||
// setting 16 and 17 (temperature) are part of options now, kept as "" in newer versions for compatibility
|
// setting 16 and 17 (temperature) are part of options now, kept as "" in newer versions for compatibility
|
||||||
if (settings[16]) options.temperatureEquator = +settings[16];
|
if (settings[16]) options.temperatureEquator = +settings[16];
|
||||||
if (settings[17]) options.temperatureNorthPole = options.temperatureSouthPole = +settings[17];
|
if (settings[17]) options.temperatureNorthPole = options.temperatureSouthPole = +settings[17];
|
||||||
|
|
||||||
if (settings[20]) mapName.value = settings[20];
|
if (settings[20]) mapName.value = settings[20];
|
||||||
if (settings[21]) hideLabels.checked = +settings[21];
|
if (settings[21]) hideLabels.checked = +settings[21];
|
||||||
if (settings[22]) stylePreset.value = settings[22];
|
if (settings[22]) stylePreset.value = settings[22];
|
||||||
|
|
@ -462,16 +456,16 @@ async function parseLoadedData(data) {
|
||||||
{
|
{
|
||||||
// dynamically import and run auto-update script
|
// dynamically import and run auto-update script
|
||||||
const versionNumber = parseFloat(params[0]);
|
const versionNumber = parseFloat(params[0]);
|
||||||
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.95.00");
|
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.96.00");
|
||||||
resolveVersionConflicts(versionNumber);
|
resolveVersionConflicts(versionNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// add custom heightmap color scheme if any
|
// add custom heightmap color scheme if any
|
||||||
const scheme = terrs.attr("scheme");
|
const oceanScheme = terrs.select("#oceanHeights").attr("scheme");
|
||||||
if (!(scheme in heightmapColorSchemes)) {
|
const landScheme = terrs.select("#landHeights").attr("scheme");
|
||||||
addCustomColorScheme(scheme);
|
if (!(oceanScheme in heightmapColorSchemes)) addCustomColorScheme(oceanScheme);
|
||||||
}
|
if (!(landScheme in heightmapColorSchemes)) addCustomColorScheme(landScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -645,7 +639,7 @@ async function parseLoadedData(data) {
|
||||||
ERROR && console.error(error);
|
ERROR && console.error(error);
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
|
|
||||||
alertMessage.innerHTML = /* html */ `An error is occured on map loading. Select a different file to load, <br />generate a new random map or cancel the loading
|
alertMessage.innerHTML = /* html */ `An error is occured on map loading. Select a different file to load, <br>generate a new random map or cancel the loading.<br>Map version: ${mapVersion}. Generator version: ${version}.
|
||||||
<p id="errorBox">${parseError(error)}</p>`;
|
<p id="errorBox">${parseError(error)}</p>`;
|
||||||
|
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,12 @@ function prepareMapData() {
|
||||||
heightUnit.value,
|
heightUnit.value,
|
||||||
heightExponentInput.value,
|
heightExponentInput.value,
|
||||||
temperatureScale.value,
|
temperatureScale.value,
|
||||||
barSizeInput.value,
|
"", // previously used for barSize.value
|
||||||
barLabel.value,
|
"", // previously used for barLabel.value
|
||||||
barBackOpacity.value,
|
"", // previously used for barBackColor.value
|
||||||
barBackColor.value,
|
"", // previously used for barBackColor.value
|
||||||
barPosX.value,
|
"", // previously used for barPosX.value
|
||||||
barPosY.value,
|
"", // previously used for barPosY.value
|
||||||
populationRate,
|
populationRate,
|
||||||
urbanization,
|
urbanization,
|
||||||
mapSizeOutput.value,
|
mapSizeOutput.value,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,18 @@ window.Military = (function () {
|
||||||
|
|
||||||
const expn = d3.sum(valid.map(s => s.expansionism)); // total expansion
|
const expn = d3.sum(valid.map(s => s.expansionism)); // total expansion
|
||||||
const area = d3.sum(valid.map(s => s.area)); // total area
|
const area = d3.sum(valid.map(s => s.area)); // total area
|
||||||
const rate = {x: 0, Ally: -0.2, Friendly: -0.1, Neutral: 0, Suspicion: 0.1, Enemy: 1, Unknown: 0, Rival: 0.5, Vassal: 0.5, Suzerain: -0.5};
|
const rate = {
|
||||||
|
x: 0,
|
||||||
|
Ally: -0.2,
|
||||||
|
Friendly: -0.1,
|
||||||
|
Neutral: 0,
|
||||||
|
Suspicion: 0.1,
|
||||||
|
Enemy: 1,
|
||||||
|
Unknown: 0,
|
||||||
|
Rival: 0.5,
|
||||||
|
Vassal: 0.5,
|
||||||
|
Suzerain: -0.5
|
||||||
|
};
|
||||||
|
|
||||||
const stateModifier = {
|
const stateModifier = {
|
||||||
melee: {Nomadic: 0.5, Highland: 1.2, Lake: 1, Naval: 0.7, Hunting: 1.2, River: 1.1},
|
melee: {Nomadic: 0.5, Highland: 1.2, Lake: 1, Naval: 0.7, Hunting: 1.2, River: 1.1},
|
||||||
|
|
@ -24,14 +35,59 @@ window.Military = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
const cellTypeModifier = {
|
const cellTypeModifier = {
|
||||||
nomadic: {melee: 0.2, ranged: 0.5, mounted: 3, machinery: 0.4, naval: 0.3, armored: 1.6, aviation: 1, magical: 0.5},
|
nomadic: {
|
||||||
wetland: {melee: 0.8, ranged: 2, mounted: 0.3, machinery: 1.2, naval: 1.0, armored: 0.2, aviation: 0.5, magical: 0.5},
|
melee: 0.2,
|
||||||
highland: {melee: 1.2, ranged: 1.6, mounted: 0.3, machinery: 3, naval: 1.0, armored: 0.8, aviation: 0.3, magical: 2}
|
ranged: 0.5,
|
||||||
|
mounted: 3,
|
||||||
|
machinery: 0.4,
|
||||||
|
naval: 0.3,
|
||||||
|
armored: 1.6,
|
||||||
|
aviation: 1,
|
||||||
|
magical: 0.5
|
||||||
|
},
|
||||||
|
wetland: {
|
||||||
|
melee: 0.8,
|
||||||
|
ranged: 2,
|
||||||
|
mounted: 0.3,
|
||||||
|
machinery: 1.2,
|
||||||
|
naval: 1.0,
|
||||||
|
armored: 0.2,
|
||||||
|
aviation: 0.5,
|
||||||
|
magical: 0.5
|
||||||
|
},
|
||||||
|
highland: {
|
||||||
|
melee: 1.2,
|
||||||
|
ranged: 1.6,
|
||||||
|
mounted: 0.3,
|
||||||
|
machinery: 3,
|
||||||
|
naval: 1.0,
|
||||||
|
armored: 0.8,
|
||||||
|
aviation: 0.3,
|
||||||
|
magical: 2
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const burgTypeModifier = {
|
const burgTypeModifier = {
|
||||||
nomadic: {melee: 0.3, ranged: 0.8, mounted: 3, machinery: 0.4, naval: 1.0, armored: 1.6, aviation: 1, magical: 0.5},
|
nomadic: {
|
||||||
wetland: {melee: 1, ranged: 1.6, mounted: 0.2, machinery: 1.2, naval: 1.0, armored: 0.2, aviation: 0.5, magical: 0.5},
|
melee: 0.3,
|
||||||
|
ranged: 0.8,
|
||||||
|
mounted: 3,
|
||||||
|
machinery: 0.4,
|
||||||
|
naval: 1.0,
|
||||||
|
armored: 1.6,
|
||||||
|
aviation: 1,
|
||||||
|
magical: 0.5
|
||||||
|
},
|
||||||
|
wetland: {
|
||||||
|
melee: 1,
|
||||||
|
ranged: 1.6,
|
||||||
|
mounted: 0.2,
|
||||||
|
machinery: 1.2,
|
||||||
|
naval: 1.0,
|
||||||
|
armored: 0.2,
|
||||||
|
aviation: 0.5,
|
||||||
|
magical: 0.5
|
||||||
|
},
|
||||||
highland: {melee: 1.2, ranged: 2, mounted: 0.3, machinery: 3, naval: 1.0, armored: 0.8, aviation: 0.3, magical: 2}
|
highland: {melee: 1.2, ranged: 2, mounted: 0.3, machinery: 3, naval: 1.0, armored: 0.8, aviation: 0.3, magical: 2}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -40,8 +96,16 @@ window.Military = (function () {
|
||||||
const d = s.diplomacy;
|
const d = s.diplomacy;
|
||||||
|
|
||||||
const expansionRate = minmax(s.expansionism / expn / (s.area / area), 0.25, 4); // how much state expansionism is realized
|
const expansionRate = minmax(s.expansionism / expn / (s.area / area), 0.25, 4); // how much state expansionism is realized
|
||||||
const diplomacyRate = d.some(d => d === "Enemy") ? 1 : d.some(d => d === "Rival") ? 0.8 : d.some(d => d === "Suspicion") ? 0.5 : 0.1; // peacefulness
|
const diplomacyRate = d.some(d => d === "Enemy")
|
||||||
const neighborsRateRaw = s.neighbors.map(n => (n ? pack.states[n].diplomacy[s.i] : "Suspicion")).reduce((s, r) => (s += rate[r]), 0.5);
|
? 1
|
||||||
|
: d.some(d => d === "Rival")
|
||||||
|
? 0.8
|
||||||
|
: d.some(d => d === "Suspicion")
|
||||||
|
? 0.5
|
||||||
|
: 0.1; // peacefulness
|
||||||
|
const neighborsRateRaw = s.neighbors
|
||||||
|
.map(n => (n ? pack.states[n].diplomacy[s.i] : "Suspicion"))
|
||||||
|
.reduce((s, r) => (s += rate[r]), 0.5);
|
||||||
const neighborsRate = minmax(neighborsRateRaw, 0.3, 3); // neighbors rate
|
const neighborsRate = minmax(neighborsRateRaw, 0.3, 3); // neighbors rate
|
||||||
s.alert = minmax(rn(expansionRate * diplomacyRate * neighborsRate, 2), 0.1, 5); // alert rate (area modifier)
|
s.alert = minmax(rn(expansionRate * diplomacyRate * neighborsRate, 2), 0.1, 5); // alert rate (area modifier)
|
||||||
s.temp.platoons = [];
|
s.temp.platoons = [];
|
||||||
|
|
@ -86,8 +150,10 @@ window.Military = (function () {
|
||||||
|
|
||||||
let modifier = cells.pop[i] / 100; // basic rural army in percentages
|
let modifier = cells.pop[i] / 100; // basic rural army in percentages
|
||||||
if (culture !== stateObj.culture) modifier = stateObj.form === "Union" ? modifier / 1.2 : modifier / 2; // non-dominant culture
|
if (culture !== stateObj.culture) modifier = stateObj.form === "Union" ? modifier / 1.2 : modifier / 2; // non-dominant culture
|
||||||
if (religion !== cells.religion[stateObj.center]) modifier = stateObj.form === "Theocracy" ? modifier / 2.2 : modifier / 1.4; // non-dominant religion
|
if (religion !== cells.religion[stateObj.center])
|
||||||
if (cells.f[i] !== cells.f[stateObj.center]) modifier = stateObj.type === "Naval" ? modifier / 1.2 : modifier / 1.8; // different landmass
|
modifier = stateObj.form === "Theocracy" ? modifier / 2.2 : modifier / 1.4; // non-dominant religion
|
||||||
|
if (cells.f[i] !== cells.f[stateObj.center])
|
||||||
|
modifier = stateObj.type === "Naval" ? modifier / 1.2 : modifier / 1.8; // different landmass
|
||||||
const type = getType(i);
|
const type = getType(i);
|
||||||
|
|
||||||
for (const unit of options.military) {
|
for (const unit of options.military) {
|
||||||
|
|
@ -111,7 +177,17 @@ window.Military = (function () {
|
||||||
n = 1;
|
n = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stateObj.temp.platoons.push({cell: i, a: total, t: total, x, y, u: unit.name, n, s: unit.separate, type: unit.type});
|
stateObj.temp.platoons.push({
|
||||||
|
cell: i,
|
||||||
|
a: total,
|
||||||
|
t: total,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
u: unit.name,
|
||||||
|
n,
|
||||||
|
s: unit.separate,
|
||||||
|
type: unit.type
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,7 +229,17 @@ window.Military = (function () {
|
||||||
n = 1;
|
n = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stateObj.temp.platoons.push({cell: b.cell, a: total, t: total, x, y, u: unit.name, n, s: unit.separate, type: unit.type});
|
stateObj.temp.platoons.push({
|
||||||
|
cell: b.cell,
|
||||||
|
a: total,
|
||||||
|
t: total,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
u: unit.name,
|
||||||
|
n,
|
||||||
|
s: unit.separate,
|
||||||
|
type: unit.type
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,7 +347,8 @@ window.Military = (function () {
|
||||||
const army = armies
|
const army = armies
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("id", "army" + s)
|
.attr("id", "army" + s)
|
||||||
.attr("fill", baseColor);
|
.attr("fill", baseColor)
|
||||||
|
.attr("color", darkerColor);
|
||||||
|
|
||||||
const g = army
|
const g = army
|
||||||
.selectAll("g")
|
.selectAll("g")
|
||||||
|
|
@ -282,7 +369,7 @@ window.Military = (function () {
|
||||||
.attr("y", d => d.y)
|
.attr("y", d => d.y)
|
||||||
.text(d => getTotal(d));
|
.text(d => getTotal(d));
|
||||||
g.append("rect")
|
g.append("rect")
|
||||||
.attr("fill", darkerColor)
|
.attr("fill", "currentColor")
|
||||||
.attr("x", d => x(d) - h)
|
.attr("x", d => x(d) - h)
|
||||||
.attr("y", d => y(d))
|
.attr("y", d => y(d))
|
||||||
.attr("width", h)
|
.attr("width", h)
|
||||||
|
|
@ -304,12 +391,13 @@ window.Military = (function () {
|
||||||
let army = armies.select("g#army" + s);
|
let army = armies.select("g#army" + s);
|
||||||
if (!army.size()) {
|
if (!army.size()) {
|
||||||
const baseColor = pack.states[s].color[0] === "#" ? pack.states[s].color : "#999";
|
const baseColor = pack.states[s].color[0] === "#" ? pack.states[s].color : "#999";
|
||||||
|
const darkerColor = d3.color(army.attr("fill")).darker().hex();
|
||||||
army = armies
|
army = armies
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("id", "army" + s)
|
.attr("id", "army" + s)
|
||||||
.attr("fill", baseColor);
|
.attr("fill", baseColor)
|
||||||
|
.attr("color", darkerColor);
|
||||||
}
|
}
|
||||||
const darkerColor = d3.color(army.attr("fill")).darker().hex();
|
|
||||||
|
|
||||||
const g = army
|
const g = army
|
||||||
.append("g")
|
.append("g")
|
||||||
|
|
@ -320,7 +408,7 @@ window.Military = (function () {
|
||||||
g.append("rect").attr("x", x1).attr("y", y1).attr("width", w).attr("height", h);
|
g.append("rect").attr("x", x1).attr("y", y1).attr("width", w).attr("height", h);
|
||||||
g.append("text").attr("x", reg.x).attr("y", reg.y).text(getTotal(reg));
|
g.append("text").attr("x", reg.x).attr("y", reg.y).text(getTotal(reg));
|
||||||
g.append("rect")
|
g.append("rect")
|
||||||
.attr("fill", darkerColor)
|
.attr("fill", "currentColor")
|
||||||
.attr("x", x1 - h)
|
.attr("x", x1 - h)
|
||||||
.attr("y", y1)
|
.attr("y", y1)
|
||||||
.attr("width", h)
|
.attr("width", h)
|
||||||
|
|
@ -379,7 +467,13 @@ window.Military = (function () {
|
||||||
// get default regiment emblem
|
// get default regiment emblem
|
||||||
const getEmblem = function (r) {
|
const getEmblem = function (r) {
|
||||||
if (!r.n && !Object.values(r.u).length) return "🔰"; // "Newbie" regiment without troops
|
if (!r.n && !Object.values(r.u).length) return "🔰"; // "Newbie" regiment without troops
|
||||||
if (!r.n && pack.states[r.state].form === "Monarchy" && pack.cells.burg[r.cell] && pack.burgs[pack.cells.burg[r.cell]].capital) return "👑"; // "Royal" regiment based in capital
|
if (
|
||||||
|
!r.n &&
|
||||||
|
pack.states[r.state].form === "Monarchy" &&
|
||||||
|
pack.cells.burg[r.cell] &&
|
||||||
|
pack.burgs[pack.cells.burg[r.cell]].capital
|
||||||
|
)
|
||||||
|
return "👑"; // "Royal" regiment based in capital
|
||||||
const mainUnit = Object.entries(r.u).sort((a, b) => b[1] - a[1])[0][0]; // unit with more troops in regiment
|
const mainUnit = Object.entries(r.u).sort((a, b) => b[1] - a[1])[0][0]; // unit with more troops in regiment
|
||||||
const unit = options.military.find(u => u.name === mainUnit);
|
const unit = options.military.find(u => u.name === mainUnit);
|
||||||
return unit.icon;
|
return unit.icon;
|
||||||
|
|
@ -400,7 +494,9 @@ window.Military = (function () {
|
||||||
.map(t => `— ${t}: ${r.u[t]}`)
|
.map(t => `— ${t}: ${r.u[t]}`)
|
||||||
.join("\r\n")
|
.join("\r\n")
|
||||||
: null;
|
: null;
|
||||||
const troops = composition ? `\r\n\r\nRegiment composition in ${options.year} ${options.eraShort}:\r\n${composition}.` : "";
|
const troops = composition
|
||||||
|
? `\r\n\r\nRegiment composition in ${options.year} ${options.eraShort}:\r\n${composition}.`
|
||||||
|
: "";
|
||||||
|
|
||||||
const campaign = s.campaigns ? ra(s.campaigns) : null;
|
const campaign = s.campaigns ? ra(s.campaigns) : null;
|
||||||
const year = campaign ? rand(campaign.start, campaign.end) : gauss(options.year - 100, 150, 1, options.year - 6);
|
const year = campaign ? rand(campaign.start, campaign.end) : gauss(options.year - 100, 150, 1, options.year - 6);
|
||||||
|
|
@ -409,5 +505,16 @@ window.Military = (function () {
|
||||||
notes.push({id: `regiment${s.i}-${r.i}`, name: `${r.icon} ${r.name}`, legend});
|
notes.push({id: `regiment${s.i}-${r.i}`, name: `${r.icon} ${r.name}`, legend});
|
||||||
};
|
};
|
||||||
|
|
||||||
return {generate, redraw, getDefaultOptions, getName, generateNote, drawRegiments, drawRegiment, moveRegiment, getTotal, getEmblem};
|
return {
|
||||||
|
generate,
|
||||||
|
redraw,
|
||||||
|
getDefaultOptions,
|
||||||
|
getName,
|
||||||
|
generateNote,
|
||||||
|
drawRegiments,
|
||||||
|
drawRegiment,
|
||||||
|
moveRegiment,
|
||||||
|
getTotal,
|
||||||
|
getEmblem
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ window.Submap = (function () {
|
||||||
|
|
||||||
const projection = options.projection;
|
const projection = options.projection;
|
||||||
const inverse = options.inverse;
|
const inverse = options.inverse;
|
||||||
const stage = s => INFO && console.log("SUBMAP:", s);
|
const stage = s => INFO && console.info("SUBMAP:", s);
|
||||||
const timeStart = performance.now();
|
const timeStart = performance.now();
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ window.Submap = (function () {
|
||||||
seed = parentMap.seed;
|
seed = parentMap.seed;
|
||||||
Math.random = aleaPRNG(seed);
|
Math.random = aleaPRNG(seed);
|
||||||
INFO && console.group("SubMap with seed: " + seed);
|
INFO && console.group("SubMap with seed: " + seed);
|
||||||
DEBUG && console.log("Using Options:", options);
|
DEBUG && console.info("Using Options:", options);
|
||||||
|
|
||||||
// create new grid
|
// create new grid
|
||||||
applyGraphSize();
|
applyGraphSize();
|
||||||
|
|
@ -396,7 +396,7 @@ window.Submap = (function () {
|
||||||
b.removed = true;
|
b.removed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DEBUG && console.log(`Moving ${b.name} from ${cityCell} to ${newCell} near ${neighbor}.`);
|
DEBUG && console.info(`Moving ${b.name} from ${cityCell} to ${newCell} near ${neighbor}.`);
|
||||||
[b.x, b.y] = b.port ? getMiddlePoint(newCell, neighbor) : cells.p[newCell];
|
[b.x, b.y] = b.port ? getMiddlePoint(newCell, neighbor) : cells.p[newCell];
|
||||||
if (b.port) b.port = cells.f[neighbor]; // copy feature number
|
if (b.port) b.port = cells.f[neighbor]; // copy feature number
|
||||||
b.cell = newCell;
|
b.cell = newCell;
|
||||||
|
|
|
||||||
|
|
@ -126,51 +126,6 @@ function editBurg(id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// in °C, array from -1 °C; source: https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
|
|
||||||
function getTemperatureLikeness(temperature) {
|
|
||||||
if (temperature < -5) return "Yakutsk";
|
|
||||||
const cities = [
|
|
||||||
"Snag (Yukon)",
|
|
||||||
"Yellowknife (Canada)",
|
|
||||||
"Okhotsk (Russia)",
|
|
||||||
"Fairbanks (Alaska)",
|
|
||||||
"Nuuk (Greenland)",
|
|
||||||
"Murmansk", // -5 - 0
|
|
||||||
"Arkhangelsk",
|
|
||||||
"Anchorage",
|
|
||||||
"Tromsø",
|
|
||||||
"Reykjavik",
|
|
||||||
"Riga",
|
|
||||||
"Stockholm",
|
|
||||||
"Halifax",
|
|
||||||
"Prague",
|
|
||||||
"Copenhagen",
|
|
||||||
"London", // 1 - 10
|
|
||||||
"Antwerp",
|
|
||||||
"Paris",
|
|
||||||
"Milan",
|
|
||||||
"Batumi",
|
|
||||||
"Rome",
|
|
||||||
"Dubrovnik",
|
|
||||||
"Lisbon",
|
|
||||||
"Barcelona",
|
|
||||||
"Marrakesh",
|
|
||||||
"Alexandria", // 11 - 20
|
|
||||||
"Tegucigalpa",
|
|
||||||
"Guangzhou",
|
|
||||||
"Rio de Janeiro",
|
|
||||||
"Dakar",
|
|
||||||
"Miami",
|
|
||||||
"Jakarta",
|
|
||||||
"Mogadishu",
|
|
||||||
"Bangkok",
|
|
||||||
"Aden",
|
|
||||||
"Khartoum"
|
|
||||||
]; // 21 - 30
|
|
||||||
if (temperature > 30) return "Mecca";
|
|
||||||
return cities[temperature + 5] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragBurgLabel() {
|
function dragBurgLabel() {
|
||||||
const tr = parseTransform(this.getAttribute("transform"));
|
const tr = parseTransform(this.getAttribute("transform"));
|
||||||
const dx = +tr[0] - d3.event.x,
|
const dx = +tr[0] - d3.event.x,
|
||||||
|
|
@ -284,7 +239,9 @@ function editBurg(id) {
|
||||||
alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${
|
alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${
|
||||||
basic || capital ? "all unlocked elements in the burg group" : "the entire burg group"
|
basic || capital ? "all unlocked elements in the burg group" : "the entire burg group"
|
||||||
}?
|
}?
|
||||||
<br />Please note that capital or locked burgs will not be deleted. <br /><br />Burgs to be removed: ${burgsToRemove.length}`;
|
<br />Please note that capital or locked burgs will not be deleted. <br /><br />Burgs to be removed: ${
|
||||||
|
burgsToRemove.length
|
||||||
|
}`;
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
resizable: false,
|
resizable: false,
|
||||||
title: "Remove burg group",
|
title: "Remove burg group",
|
||||||
|
|
@ -433,7 +390,8 @@ function editBurg(id) {
|
||||||
function addCustomMfcgLink() {
|
function addCustomMfcgLink() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const burg = pack.burgs[id];
|
const burg = pack.burgs[id];
|
||||||
const message = "Enter custom link to the burg map. It can be a link to Medieval Fantasy City Generator or other tool. Keep empty to use MFCG seed";
|
const message =
|
||||||
|
"Enter custom link to the burg map. It can be a link to Medieval Fantasy City Generator or other tool. Keep empty to use MFCG seed";
|
||||||
prompt(message, {default: burg.link || "", required: false}, link => {
|
prompt(message, {default: burg.link || "", required: false}, link => {
|
||||||
if (link) burg.link = link;
|
if (link) burg.link = link;
|
||||||
else delete burg.link;
|
else delete burg.link;
|
||||||
|
|
@ -581,3 +539,48 @@ function editBurg(id) {
|
||||||
unselect();
|
unselect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in °C, array from -1 °C; source: https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
|
||||||
|
function getTemperatureLikeness(temperature) {
|
||||||
|
if (temperature < -5) return "Yakutsk";
|
||||||
|
const cities = [
|
||||||
|
"Snag (Yukon)",
|
||||||
|
"Yellowknife (Canada)",
|
||||||
|
"Okhotsk (Russia)",
|
||||||
|
"Fairbanks (Alaska)",
|
||||||
|
"Nuuk (Greenland)",
|
||||||
|
"Murmansk", // -5 - 0
|
||||||
|
"Arkhangelsk",
|
||||||
|
"Anchorage",
|
||||||
|
"Tromsø",
|
||||||
|
"Reykjavik",
|
||||||
|
"Riga",
|
||||||
|
"Stockholm",
|
||||||
|
"Halifax",
|
||||||
|
"Prague",
|
||||||
|
"Copenhagen",
|
||||||
|
"London", // 1 - 10
|
||||||
|
"Antwerp",
|
||||||
|
"Paris",
|
||||||
|
"Milan",
|
||||||
|
"Batumi",
|
||||||
|
"Rome",
|
||||||
|
"Dubrovnik",
|
||||||
|
"Lisbon",
|
||||||
|
"Barcelona",
|
||||||
|
"Marrakesh",
|
||||||
|
"Alexandria", // 11 - 20
|
||||||
|
"Tegucigalpa",
|
||||||
|
"Guangzhou",
|
||||||
|
"Rio de Janeiro",
|
||||||
|
"Dakar",
|
||||||
|
"Miami",
|
||||||
|
"Jakarta",
|
||||||
|
"Mogadishu",
|
||||||
|
"Bangkok",
|
||||||
|
"Aden",
|
||||||
|
"Khartoum"
|
||||||
|
]; // 21 - 30
|
||||||
|
if (temperature > 30) return "Mecca";
|
||||||
|
return cities[temperature + 5] || null;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
closeDialogs("#burgsOverview, .stable");
|
closeDialogs("#burgsOverview, .stable");
|
||||||
if (!layerIsOn("toggleIcons")) toggleIcons();
|
if (!layerIsOn("toggleIcons")) toggleIcons();
|
||||||
|
|
@ -45,7 +45,7 @@ function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
||||||
|
|
||||||
function updateFilter() {
|
function updateFilter() {
|
||||||
const stateFilter = byId("burgsFilterState");
|
const stateFilter = byId("burgsFilterState");
|
||||||
const selectedState = options.stateId !== null ? options.stateId : stateFilter.value || -1;
|
const selectedState = settings.stateId !== null ? settings.stateId : stateFilter.value || -1;
|
||||||
stateFilter.options.length = 0; // remove all options
|
stateFilter.options.length = 0; // remove all options
|
||||||
stateFilter.options.add(new Option("all", -1, false, selectedState === -1));
|
stateFilter.options.add(new Option("all", -1, false, selectedState === -1));
|
||||||
stateFilter.options.add(new Option(pack.states[0].name, 0, false, selectedState === 0));
|
stateFilter.options.add(new Option(pack.states[0].name, 0, false, selectedState === 0));
|
||||||
|
|
@ -53,7 +53,7 @@ function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
||||||
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
|
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
|
||||||
|
|
||||||
const cultureFilter = byId("burgsFilterCulture");
|
const cultureFilter = byId("burgsFilterCulture");
|
||||||
const selectedCulture = options.cultureId !== null ? options.cultureId : cultureFilter.value || -1;
|
const selectedCulture = settings.cultureId !== null ? settings.cultureId : cultureFilter.value || -1;
|
||||||
cultureFilter.options.length = 0; // remove all options
|
cultureFilter.options.length = 0; // remove all options
|
||||||
cultureFilter.options.add(new Option(`all`, -1, false, selectedCulture === -1));
|
cultureFilter.options.add(new Option(`all`, -1, false, selectedCulture === -1));
|
||||||
cultureFilter.options.add(new Option(pack.cultures[0].name, 0, false, selectedCulture === 0));
|
cultureFilter.options.add(new Option(pack.cultures[0].name, 0, false, selectedCulture === 0));
|
||||||
|
|
@ -480,10 +480,7 @@ function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadBurgsData() {
|
function downloadBurgsData() {
|
||||||
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town`; // headers
|
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Temperature,Temperature likeness,Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town,Emblem,City Generator Link\n`; // headers
|
||||||
if (options.showMFCGMap) data += `,City Generator Link`;
|
|
||||||
data += "\n";
|
|
||||||
|
|
||||||
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
||||||
|
|
||||||
valid.forEach(b => {
|
valid.forEach(b => {
|
||||||
|
|
@ -504,6 +501,9 @@ function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
||||||
data += getLatitude(b.y, 2) + ",";
|
data += getLatitude(b.y, 2) + ",";
|
||||||
data += getLongitude(b.x, 2) + ",";
|
data += getLongitude(b.x, 2) + ",";
|
||||||
data += parseInt(getHeight(pack.cells.h[b.cell])) + ",";
|
data += parseInt(getHeight(pack.cells.h[b.cell])) + ",";
|
||||||
|
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
|
||||||
|
data += convertTemperature(temperature) + ",";
|
||||||
|
data += getTemperatureLikeness(temperature) + ",";
|
||||||
|
|
||||||
// add status data
|
// add status data
|
||||||
data += b.capital ? "capital," : ",";
|
data += b.capital ? "capital," : ",";
|
||||||
|
|
@ -513,7 +513,9 @@ function overviewBurgs(options = {stateId: null, cultureId: null}) {
|
||||||
data += b.plaza ? "plaza," : ",";
|
data += b.plaza ? "plaza," : ",";
|
||||||
data += b.temple ? "temple," : ",";
|
data += b.temple ? "temple," : ",";
|
||||||
data += b.shanty ? "shanty town," : ",";
|
data += b.shanty ? "shanty town," : ",";
|
||||||
if (options.showMFCGMap) data += getMFCGlink(b);
|
data += b.coa ? JSON.stringify(b.coa).replace(/"/g, "").replace(/,/g, ";") + "," : ",";
|
||||||
|
data += getMFCGlink(b);
|
||||||
|
|
||||||
data += "\n";
|
data += "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1176,18 +1176,18 @@ function refreshAllEditors() {
|
||||||
// dynamically loaded editors
|
// dynamically loaded editors
|
||||||
async function editStates() {
|
async function editStates() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const Editor = await import("../dynamic/editors/states-editor.js?v=1.93.10");
|
const Editor = await import("../dynamic/editors/states-editor.js?v=1.96.00");
|
||||||
Editor.open();
|
Editor.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editCultures() {
|
async function editCultures() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.95.04");
|
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.96.00");
|
||||||
Editor.open();
|
Editor.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editReligions() {
|
async function editReligions() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.89.10");
|
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.96.00");
|
||||||
Editor.open();
|
Editor.open();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,92 +188,135 @@ function restoreLayers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleHeight(event) {
|
function toggleHeight(event) {
|
||||||
if (customization === 1) {
|
if (customization === 1) return tip("You cannot turn off the layer when heightmap is in edit mode", false, "error");
|
||||||
tip("You cannot turn off the layer when heightmap is in edit mode", false, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!terrs.selectAll("*").size()) {
|
const children = terrs.selectAll("#oceanHeights > *, #landHeights > *");
|
||||||
|
if (!children.size()) {
|
||||||
turnButtonOn("toggleHeight");
|
turnButtonOn("toggleHeight");
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
if (event && isCtrlClick(event)) editStyle("terrs");
|
if (event && isCtrlClick(event)) editStyle("terrs");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("terrs");
|
||||||
editStyle("terrs");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
turnButtonOff("toggleHeight");
|
turnButtonOff("toggleHeight");
|
||||||
terrs.selectAll("*").remove();
|
children.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawHeightmap() {
|
function drawHeightmap() {
|
||||||
TIME && console.time("drawHeightmap");
|
TIME && console.time("drawHeightmap");
|
||||||
terrs.selectAll("*").remove();
|
|
||||||
|
|
||||||
const {cells, vertices} = pack;
|
const ocean = terrs.select("#oceanHeights");
|
||||||
const n = cells.i.length;
|
const land = terrs.select("#landHeights");
|
||||||
const used = new Uint8Array(cells.i.length);
|
|
||||||
const paths = new Array(101).fill("");
|
|
||||||
|
|
||||||
const scheme = getColorScheme(terrs.attr("scheme"));
|
ocean.selectAll("*").remove();
|
||||||
const terracing = terrs.attr("terracing") / 10; // add additional shifted darker layer for pseudo-3d effect
|
land.selectAll("*").remove();
|
||||||
const skip = +terrs.attr("skip") + 1;
|
|
||||||
const simplification = +terrs.attr("relax");
|
|
||||||
|
|
||||||
switch (+terrs.attr("curve")) {
|
const paths = new Array(101);
|
||||||
case 0:
|
|
||||||
lineGen.curve(d3.curveBasisClosed);
|
// ocean cells
|
||||||
break;
|
const renderOceanCells = Boolean(+ocean.attr("data-render"));
|
||||||
case 1:
|
if (renderOceanCells) {
|
||||||
lineGen.curve(d3.curveLinear);
|
const {cells, vertices} = grid;
|
||||||
break;
|
const used = new Uint8Array(cells.i.length);
|
||||||
case 2:
|
|
||||||
lineGen.curve(d3.curveStep);
|
const skip = +ocean.attr("skip") + 1 || 1;
|
||||||
break;
|
const relax = +ocean.attr("relax") || 0;
|
||||||
default:
|
lineGen.curve(d3[ocean.attr("curve") || "curveBasisClosed"]);
|
||||||
lineGen.curve(d3.curveBasisClosed);
|
|
||||||
|
let currentLayer = 0;
|
||||||
|
const heights = Array.from(cells.i).sort((a, b) => cells.h[a] - cells.h[b]);
|
||||||
|
|
||||||
|
for (const i of heights) {
|
||||||
|
const h = cells.h[i];
|
||||||
|
if (h > currentLayer) currentLayer += skip;
|
||||||
|
if (h < currentLayer) continue;
|
||||||
|
if (currentLayer >= 20) break;
|
||||||
|
if (used[i]) continue; // already marked
|
||||||
|
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
||||||
|
if (!onborder) continue;
|
||||||
|
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
||||||
|
const chain = connectVertices(cells, vertices, vertex, h, used);
|
||||||
|
if (chain.length < 3) continue;
|
||||||
|
const points = simplifyLine(chain, relax).map(v => vertices.p[v]);
|
||||||
|
if (!paths[h]) paths[h] = "";
|
||||||
|
paths[h] += round(lineGen(points));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentLayer = 20;
|
// land cells
|
||||||
const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]);
|
{
|
||||||
for (const i of heights) {
|
const {cells, vertices} = pack;
|
||||||
const h = cells.h[i];
|
const used = new Uint8Array(cells.i.length);
|
||||||
if (h > currentLayer) currentLayer += skip;
|
|
||||||
if (currentLayer > 100) break; // no layers possible with height > 100
|
const skip = +land.attr("skip") + 1 || 1;
|
||||||
if (h < currentLayer) continue;
|
const relax = +land.attr("relax") || 0;
|
||||||
if (used[i]) continue; // already marked
|
lineGen.curve(d3[land.attr("curve") || "curveBasisClosed"]);
|
||||||
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
|
||||||
if (!onborder) continue;
|
let currentLayer = 20;
|
||||||
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
const heights = Array.from(cells.i).sort((a, b) => cells.h[a] - cells.h[b]);
|
||||||
const chain = connectVertices(vertex, h);
|
for (const i of heights) {
|
||||||
if (chain.length < 3) continue;
|
const h = cells.h[i];
|
||||||
const points = simplifyLine(chain).map(v => vertices.p[v]);
|
if (h > currentLayer) currentLayer += skip;
|
||||||
paths[h] += round(lineGen(points));
|
if (h < currentLayer) continue;
|
||||||
|
if (currentLayer > 100) break; // no layers possible with height > 100
|
||||||
|
if (used[i]) continue; // already marked
|
||||||
|
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
||||||
|
if (!onborder) continue;
|
||||||
|
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
||||||
|
const chain = connectVertices(cells, vertices, vertex, h, used);
|
||||||
|
if (chain.length < 3) continue;
|
||||||
|
const points = simplifyLine(chain, relax).map(v => vertices.p[v]);
|
||||||
|
if (!paths[h]) paths[h] = "";
|
||||||
|
paths[h] += round(lineGen(points));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
terrs
|
// render paths
|
||||||
.append("rect")
|
for (const height of d3.range(0, 101)) {
|
||||||
.attr("x", 0)
|
const group = height < 20 ? ocean : land;
|
||||||
.attr("y", 0)
|
const scheme = getColorScheme(group.attr("scheme"));
|
||||||
.attr("width", graphWidth)
|
|
||||||
.attr("height", graphHeight)
|
if (height === 0 && renderOceanCells) {
|
||||||
.attr("fill", scheme(0.8)); // draw base layer
|
// draw base ocean layer
|
||||||
for (const i of d3.range(20, 101)) {
|
group
|
||||||
if (paths[i].length < 10) continue;
|
.append("rect")
|
||||||
const color = getColor(i, scheme);
|
.attr("x", 0)
|
||||||
if (terracing)
|
.attr("y", 0)
|
||||||
terrs
|
.attr("width", graphWidth)
|
||||||
.append("path")
|
.attr("height", graphHeight)
|
||||||
.attr("d", paths[i])
|
.attr("fill", scheme(1));
|
||||||
.attr("transform", "translate(.7,1.4)")
|
}
|
||||||
.attr("fill", d3.color(color).darker(terracing))
|
|
||||||
.attr("data-height", i);
|
if (height === 20) {
|
||||||
terrs.append("path").attr("d", paths[i]).attr("fill", color).attr("data-height", i);
|
// draw base land layer
|
||||||
|
group
|
||||||
|
.append("rect")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("width", graphWidth)
|
||||||
|
.attr("height", graphHeight)
|
||||||
|
.attr("fill", scheme(0.8));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paths[height] && paths[height].length >= 10) {
|
||||||
|
const terracing = group.attr("terracing") / 10 || 0;
|
||||||
|
const color = getColor(height, scheme);
|
||||||
|
|
||||||
|
if (terracing) {
|
||||||
|
group
|
||||||
|
.append("path")
|
||||||
|
.attr("d", paths[height])
|
||||||
|
.attr("transform", "translate(.7,1.4)")
|
||||||
|
.attr("fill", d3.color(color).darker(terracing))
|
||||||
|
.attr("data-height", height);
|
||||||
|
}
|
||||||
|
group.append("path").attr("d", paths[height]).attr("fill", color).attr("data-height", height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect vertices to chain
|
// connect vertices to chain
|
||||||
function connectVertices(start, h) {
|
function connectVertices(cells, vertices, start, h, used) {
|
||||||
|
const n = cells.i.length;
|
||||||
const chain = []; // vertices chain to form a path
|
const chain = []; // vertices chain to form a path
|
||||||
for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
|
for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
|
||||||
const prev = chain[chain.length - 1]; // previous vertex in chain
|
const prev = chain[chain.length - 1]; // previous vertex in chain
|
||||||
|
|
@ -295,7 +338,7 @@ function drawHeightmap() {
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function simplifyLine(chain) {
|
function simplifyLine(chain, simplification) {
|
||||||
if (!simplification) return chain;
|
if (!simplification) return chain;
|
||||||
const n = simplification + 1; // filter each nth element
|
const n = simplification + 1; // filter each nth element
|
||||||
return chain.filter((d, i) => i % n === 0);
|
return chain.filter((d, i) => i % n === 0);
|
||||||
|
|
@ -1670,10 +1713,7 @@ function toggleLabels(event) {
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
if (event && isCtrlClick(event)) editStyle("labels");
|
if (event && isCtrlClick(event)) editStyle("labels");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("labels");
|
||||||
editStyle("labels");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
turnButtonOff("toggleLabels");
|
turnButtonOff("toggleLabels");
|
||||||
labels.style("display", "none");
|
labels.style("display", "none");
|
||||||
}
|
}
|
||||||
|
|
@ -1685,10 +1725,7 @@ function toggleIcons(event) {
|
||||||
$("#icons").fadeIn();
|
$("#icons").fadeIn();
|
||||||
if (event && isCtrlClick(event)) editStyle("burgIcons");
|
if (event && isCtrlClick(event)) editStyle("burgIcons");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("burgIcons");
|
||||||
editStyle("burgIcons");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
turnButtonOff("toggleIcons");
|
turnButtonOff("toggleIcons");
|
||||||
$("#icons").fadeOut();
|
$("#icons").fadeOut();
|
||||||
}
|
}
|
||||||
|
|
@ -1701,10 +1738,7 @@ function toggleRulers(event) {
|
||||||
rulers.draw();
|
rulers.draw();
|
||||||
ruler.style("display", null);
|
ruler.style("display", null);
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("ruler");
|
||||||
editStyle("ruler");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
turnButtonOff("toggleRulers");
|
turnButtonOff("toggleRulers");
|
||||||
ruler.selectAll("*").remove();
|
ruler.selectAll("*").remove();
|
||||||
ruler.style("display", "none");
|
ruler.style("display", "none");
|
||||||
|
|
@ -1715,17 +1749,113 @@ function toggleScaleBar(event) {
|
||||||
if (!layerIsOn("toggleScaleBar")) {
|
if (!layerIsOn("toggleScaleBar")) {
|
||||||
turnButtonOn("toggleScaleBar");
|
turnButtonOn("toggleScaleBar");
|
||||||
$("#scaleBar").fadeIn();
|
$("#scaleBar").fadeIn();
|
||||||
if (event && isCtrlClick(event)) editUnits();
|
if (event && isCtrlClick(event)) editStyle("scaleBar");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("scaleBar");
|
||||||
editUnits();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$("#scaleBar").fadeOut();
|
$("#scaleBar").fadeOut();
|
||||||
turnButtonOff("toggleScaleBar");
|
turnButtonOff("toggleScaleBar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drawScaleBar(scaleBar, scaleLevel) {
|
||||||
|
if (!scaleBar.size() || scaleBar.style("display") === "none") return;
|
||||||
|
|
||||||
|
const distanceScale = +distanceScaleInput.value;
|
||||||
|
const unit = distanceUnitInput.value;
|
||||||
|
const size = +scaleBar.attr("data-bar-size");
|
||||||
|
|
||||||
|
const length = (function () {
|
||||||
|
const init = 100;
|
||||||
|
let val = (init * size * distanceScale) / scaleLevel; // bar length in distance unit
|
||||||
|
if (val > 900) val = rn(val, -3); // round to 1000
|
||||||
|
else if (val > 90) val = rn(val, -2); // round to 100
|
||||||
|
else if (val > 9) val = rn(val, -1); // round to 10
|
||||||
|
else val = rn(val); // round to 1
|
||||||
|
const length = (val * scaleLevel) / distanceScale; // actual length in pixels on this scale
|
||||||
|
return length;
|
||||||
|
})();
|
||||||
|
|
||||||
|
scaleBar.select("#scaleBarContent").remove(); // redraw content every time
|
||||||
|
const content = scaleBar.append("g").attr("id", "scaleBarContent");
|
||||||
|
|
||||||
|
const lines = content.append("g");
|
||||||
|
lines
|
||||||
|
.append("line")
|
||||||
|
.attr("x1", 0.5)
|
||||||
|
.attr("y1", 0)
|
||||||
|
.attr("x2", length + size - 0.5)
|
||||||
|
.attr("y2", 0)
|
||||||
|
.attr("stroke-width", size)
|
||||||
|
.attr("stroke", "white");
|
||||||
|
lines
|
||||||
|
.append("line")
|
||||||
|
.attr("x1", 0)
|
||||||
|
.attr("y1", size)
|
||||||
|
.attr("x2", length + size)
|
||||||
|
.attr("y2", size)
|
||||||
|
.attr("stroke-width", size)
|
||||||
|
.attr("stroke", "#3d3d3d");
|
||||||
|
lines
|
||||||
|
.append("line")
|
||||||
|
.attr("x1", 0)
|
||||||
|
.attr("y1", 0)
|
||||||
|
.attr("x2", length + size)
|
||||||
|
.attr("y2", 0)
|
||||||
|
.attr("stroke-width", rn(size * 3, 2))
|
||||||
|
.attr("stroke-dasharray", size + " " + rn(length / 5 - size, 2))
|
||||||
|
.attr("stroke", "#3d3d3d");
|
||||||
|
|
||||||
|
const texts = content.append("g").attr("text-anchor", "middle").attr("font-family", "var(--serif)");
|
||||||
|
texts
|
||||||
|
.selectAll("text")
|
||||||
|
.data(d3.range(0, 6))
|
||||||
|
.enter()
|
||||||
|
.append("text")
|
||||||
|
.attr("x", d => rn((d * length) / 5, 2))
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("dy", "-.6em")
|
||||||
|
.text(d => rn((((d * length) / 5) * distanceScale) / scaleLevel) + (d < 5 ? "" : " " + unit));
|
||||||
|
|
||||||
|
const label = scaleBar.attr("data-label");
|
||||||
|
if (label) {
|
||||||
|
texts
|
||||||
|
.append("text")
|
||||||
|
.attr("x", (length + 1) / 2)
|
||||||
|
.attr("dy", ".6em")
|
||||||
|
.attr("dominant-baseline", "text-before-edge")
|
||||||
|
.text(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scaleBarBack = scaleBar.select("#scaleBarBack");
|
||||||
|
if (scaleBarBack.size()) {
|
||||||
|
const bbox = content.node().getBBox();
|
||||||
|
const paddingTop = +scaleBarBack.attr("data-top") || 0;
|
||||||
|
const paddingLeft = +scaleBarBack.attr("data-left") || 0;
|
||||||
|
const paddingRight = +scaleBarBack.attr("data-right") || 0;
|
||||||
|
const paddingBottom = +scaleBarBack.attr("data-bottom") || 0;
|
||||||
|
|
||||||
|
scaleBar
|
||||||
|
.select("#scaleBarBack")
|
||||||
|
.attr("x", -paddingLeft)
|
||||||
|
.attr("y", -paddingTop)
|
||||||
|
.attr("width", bbox.width + paddingRight)
|
||||||
|
.attr("height", bbox.height + paddingBottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fit ScaleBar to screen size
|
||||||
|
function fitScaleBar(scaleBar, fullWidth, fullHeight) {
|
||||||
|
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
|
||||||
|
|
||||||
|
const posX = +scaleBar.attr("data-x") || 99;
|
||||||
|
const posY = +scaleBar.attr("data-y") || 99;
|
||||||
|
const bbox = scaleBar.select("rect").node().getBBox();
|
||||||
|
|
||||||
|
const x = rn((fullWidth * posX) / 100 - bbox.width + 10);
|
||||||
|
const y = rn((fullHeight * posY) / 100 - bbox.height + 20);
|
||||||
|
scaleBar.attr("transform", `translate(${x},${y})`);
|
||||||
|
}
|
||||||
|
|
||||||
function toggleZones(event) {
|
function toggleZones(event) {
|
||||||
if (!layerIsOn("toggleZones")) {
|
if (!layerIsOn("toggleZones")) {
|
||||||
turnButtonOn("toggleZones");
|
turnButtonOn("toggleZones");
|
||||||
|
|
@ -1748,10 +1878,7 @@ function toggleEmblems(event) {
|
||||||
$("#emblems").fadeIn();
|
$("#emblems").fadeIn();
|
||||||
if (event && isCtrlClick(event)) editStyle("emblems");
|
if (event && isCtrlClick(event)) editStyle("emblems");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("emblems");
|
||||||
editStyle("emblems");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$("#emblems").fadeOut();
|
$("#emblems").fadeOut();
|
||||||
turnButtonOff("toggleEmblems");
|
turnButtonOff("toggleEmblems");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -532,101 +532,3 @@ class Planimeter extends Measurer {
|
||||||
this.el.select("text").attr("x", c[0]).attr("y", c[1]).text(area);
|
this.el.select("text").attr("x", c[0]).attr("y", c[1]).text(area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale bar
|
|
||||||
function drawScaleBar(scaleBar, scaleLevel) {
|
|
||||||
if (!scaleBar.size() || scaleBar.style("display") === "none") return;
|
|
||||||
scaleBar.selectAll("*").remove(); // fully redraw every time
|
|
||||||
|
|
||||||
const distanceScale = +distanceScaleInput.value;
|
|
||||||
const unit = distanceUnitInput.value;
|
|
||||||
const size = +barSizeInput.value;
|
|
||||||
|
|
||||||
// calculate size
|
|
||||||
const init = 100;
|
|
||||||
let val = (init * size * distanceScale) / scaleLevel; // bar length in distance unit
|
|
||||||
if (val > 900) val = rn(val, -3);
|
|
||||||
// round to 1000
|
|
||||||
else if (val > 90) val = rn(val, -2);
|
|
||||||
// round to 100
|
|
||||||
else if (val > 9) val = rn(val, -1);
|
|
||||||
// round to 10
|
|
||||||
else val = rn(val); // round to 1
|
|
||||||
const length = (val * scaleLevel) / distanceScale; // actual length in pixels on this scale
|
|
||||||
|
|
||||||
scaleBar
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", 0.5)
|
|
||||||
.attr("y1", 0)
|
|
||||||
.attr("x2", length + size - 0.5)
|
|
||||||
.attr("y2", 0)
|
|
||||||
.attr("stroke-width", size)
|
|
||||||
.attr("stroke", "white");
|
|
||||||
scaleBar
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", 0)
|
|
||||||
.attr("y1", size)
|
|
||||||
.attr("x2", length + size)
|
|
||||||
.attr("y2", size)
|
|
||||||
.attr("stroke-width", size)
|
|
||||||
.attr("stroke", "#3d3d3d");
|
|
||||||
const dash = size + " " + rn(length / 5 - size, 2);
|
|
||||||
scaleBar
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", 0)
|
|
||||||
.attr("y1", 0)
|
|
||||||
.attr("x2", length + size)
|
|
||||||
.attr("y2", 0)
|
|
||||||
.attr("stroke-width", rn(size * 3, 2))
|
|
||||||
.attr("stroke-dasharray", dash)
|
|
||||||
.attr("stroke", "#3d3d3d");
|
|
||||||
|
|
||||||
const fontSize = rn(5 * size, 1);
|
|
||||||
scaleBar
|
|
||||||
.selectAll("text")
|
|
||||||
.data(d3.range(0, 6))
|
|
||||||
.enter()
|
|
||||||
.append("text")
|
|
||||||
.attr("x", d => rn((d * length) / 5, 2))
|
|
||||||
.attr("y", 0)
|
|
||||||
.attr("dy", "-.6em")
|
|
||||||
.attr("font-size", fontSize)
|
|
||||||
.text(d => rn((((d * length) / 5) * distanceScale) / scaleLevel) + (d < 5 ? "" : " " + unit));
|
|
||||||
|
|
||||||
if (barLabel.value !== "") {
|
|
||||||
scaleBar
|
|
||||||
.append("text")
|
|
||||||
.attr("x", (length + 1) / 2)
|
|
||||||
.attr("y", 2 * size)
|
|
||||||
.attr("dominant-baseline", "text-before-edge")
|
|
||||||
.attr("font-size", fontSize)
|
|
||||||
.text(barLabel.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bbox = scaleBar.node().getBBox();
|
|
||||||
// append backbround rectangle
|
|
||||||
scaleBar
|
|
||||||
.insert("rect", ":first-child")
|
|
||||||
.attr("x", -10)
|
|
||||||
.attr("y", -20)
|
|
||||||
.attr("width", bbox.width + 10)
|
|
||||||
.attr("height", bbox.height + 15)
|
|
||||||
.attr("stroke-width", size)
|
|
||||||
.attr("stroke", "none")
|
|
||||||
.attr("filter", "url(#blur5)")
|
|
||||||
.attr("fill", barBackColor.value)
|
|
||||||
.attr("opacity", +barBackOpacity.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fit ScaleBar to screen size
|
|
||||||
function fitScaleBar(scaleBar, fullWidth, fullHeight) {
|
|
||||||
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
|
|
||||||
|
|
||||||
const px = isNaN(+barPosX.value) ? 0.99 : barPosX.value / 100;
|
|
||||||
const py = isNaN(+barPosY.value) ? 0.99 : barPosY.value / 100;
|
|
||||||
const bbox = scaleBar.select("rect").node().getBBox();
|
|
||||||
|
|
||||||
const x = rn(fullWidth * px - bbox.width + 10);
|
|
||||||
const y = rn(fullHeight * py - bbox.height + 20);
|
|
||||||
scaleBar.attr("transform", `translate(${x},${y})`);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,7 @@ function changeEra() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openTemplateSelectionDialog() {
|
async function openTemplateSelectionDialog() {
|
||||||
const HeightmapSelectionDialog = await import("../dynamic/heightmap-selection.js?v=1.93.12");
|
const HeightmapSelectionDialog = await import("../dynamic/heightmap-selection.js?v=1.96.00");
|
||||||
HeightmapSelectionDialog.open();
|
HeightmapSelectionDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -774,7 +774,7 @@ function showExportPane() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exportToJson(type) {
|
async function exportToJson(type) {
|
||||||
const {exportToJson} = await import("../dynamic/export-json.js?v=1.93.03");
|
const {exportToJson} = await import("../dynamic/export-json.js?v=1.96.00");
|
||||||
exportToJson(type);
|
exportToJson(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,14 @@ function editProvinces() {
|
||||||
cl = el.classList,
|
cl = el.classList,
|
||||||
line = el.parentNode,
|
line = el.parentNode,
|
||||||
p = +line.dataset.id;
|
p = +line.dataset.id;
|
||||||
|
const stateId = pack.provinces[p].state;
|
||||||
|
|
||||||
if (el.tagName === "FILL-BOX") changeFill(el);
|
if (el.tagName === "FILL-BOX") changeFill(el);
|
||||||
else if (cl.contains("name")) editProvinceName(p);
|
else if (cl.contains("name")) editProvinceName(p);
|
||||||
else if (cl.contains("coaIcon")) editEmblem("province", "provinceCOA" + p, pack.provinces[p]);
|
else if (cl.contains("coaIcon")) editEmblem("province", "provinceCOA" + p, pack.provinces[p]);
|
||||||
else if (cl.contains("icon-star-empty")) capitalZoomIn(p);
|
else if (cl.contains("icon-star-empty")) capitalZoomIn(p);
|
||||||
else if (cl.contains("icon-flag-empty")) triggerIndependencePromps(p);
|
else if (cl.contains("icon-flag-empty")) triggerIndependencePromps(p);
|
||||||
|
else if (cl.contains("icon-dot-circled")) overviewBurgs({stateId});
|
||||||
else if (cl.contains("culturePopulation")) changePopulation(p);
|
else if (cl.contains("culturePopulation")) changePopulation(p);
|
||||||
else if (cl.contains("icon-pin")) toggleFog(p, cl);
|
else if (cl.contains("icon-pin")) toggleFog(p, cl);
|
||||||
else if (cl.contains("icon-trash-empty")) removeProvince(p);
|
else if (cl.contains("icon-trash-empty")) removeProvince(p);
|
||||||
|
|
@ -71,9 +73,8 @@ function editProvinces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectStatistics() {
|
function collectStatistics() {
|
||||||
const cells = pack.cells,
|
const {cells, provinces, burgs} = pack;
|
||||||
provinces = pack.provinces,
|
|
||||||
burgs = pack.burgs;
|
|
||||||
provinces.forEach(p => {
|
provinces.forEach(p => {
|
||||||
if (!p.i || p.removed) return;
|
if (!p.i || p.removed) return;
|
||||||
p.area = p.rural = p.urban = 0;
|
p.area = p.rural = p.urban = 0;
|
||||||
|
|
@ -107,16 +108,18 @@ function editProvinces() {
|
||||||
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
|
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add line for each state
|
// add line for each province
|
||||||
function provincesEditorAddLines() {
|
function provincesEditorAddLines() {
|
||||||
const unit = " " + getAreaUnit();
|
const unit = " " + getAreaUnit();
|
||||||
const selectedState = +document.getElementById("provincesFilterState").value;
|
const selectedState = +document.getElementById("provincesFilterState").value;
|
||||||
let filtered = pack.provinces.filter(p => p.i && !p.removed); // all valid burgs
|
let filtered = pack.provinces.filter(p => p.i && !p.removed); // all valid burgs
|
||||||
if (selectedState != -1) filtered = filtered.filter(p => p.state === selectedState); // filtered by state
|
if (selectedState != -1) filtered = filtered.filter(p => p.state === selectedState); // filtered by state
|
||||||
body.innerHTML = "";
|
body.innerHTML = "";
|
||||||
let lines = "",
|
|
||||||
totalArea = 0,
|
let lines = "";
|
||||||
totalPopulation = 0;
|
let totalArea = 0;
|
||||||
|
let totalPopulation = 0;
|
||||||
|
let totalBurgs = 0;
|
||||||
|
|
||||||
for (const p of filtered) {
|
for (const p of filtered) {
|
||||||
const area = getArea(p.area);
|
const area = getArea(p.area);
|
||||||
|
|
@ -128,6 +131,7 @@ function editProvinces() {
|
||||||
rural
|
rural
|
||||||
)}; Urban population: ${si(urban)}`;
|
)}; Urban population: ${si(urban)}`;
|
||||||
totalPopulation += population;
|
totalPopulation += population;
|
||||||
|
totalBurgs += p.burgs.length;
|
||||||
|
|
||||||
const stateName = pack.states[p.state].name;
|
const stateName = pack.states[p.state].name;
|
||||||
const capital = p.burg ? pack.burgs[p.burg].name : "";
|
const capital = p.burg ? pack.burgs[p.burg].name : "";
|
||||||
|
|
@ -144,6 +148,7 @@ function editProvinces() {
|
||||||
data-state="${stateName}"
|
data-state="${stateName}"
|
||||||
data-area=${area}
|
data-area=${area}
|
||||||
data-population=${population}
|
data-population=${population}
|
||||||
|
data-burgs=${p.burgs.length}
|
||||||
>
|
>
|
||||||
<fill-box fill="${p.color}"></fill-box>
|
<fill-box fill="${p.color}"></fill-box>
|
||||||
<input data-tip="Province name. Click to change" class="name pointer" value="${p.name}" readonly />
|
<input data-tip="Province name. Click to change" class="name pointer" value="${p.name}" readonly />
|
||||||
|
|
@ -163,6 +168,8 @@ function editProvinces() {
|
||||||
${p.burgs.length ? getCapitalOptions(p.burgs, p.burg) : ""}
|
${p.burgs.length ? getCapitalOptions(p.burgs, p.burg) : ""}
|
||||||
</select>
|
</select>
|
||||||
<input data-tip="Province owner" class="provinceOwner" value="${stateName}" disabled">
|
<input data-tip="Province owner" class="provinceOwner" value="${stateName}" disabled">
|
||||||
|
<span data-tip="Click to overview province burgs" style="padding-right: 1px" class="icon-dot-circled pointer hide"></span>
|
||||||
|
<div data-tip="Burgs count" class="provinceBurgs hide">${p.burgs.length}</div>
|
||||||
<span data-tip="Province area" style="padding-right: 4px" class="icon-map-o hide"></span>
|
<span data-tip="Province area" style="padding-right: 4px" class="icon-map-o hide"></span>
|
||||||
<div data-tip="Province area" class="biomeArea hide">${si(area) + unit}</div>
|
<div data-tip="Province area" class="biomeArea hide">${si(area) + unit}</div>
|
||||||
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
||||||
|
|
@ -179,11 +186,12 @@ function editProvinces() {
|
||||||
body.innerHTML = lines;
|
body.innerHTML = lines;
|
||||||
|
|
||||||
// update footer
|
// update footer
|
||||||
provincesFooterNumber.innerHTML = filtered.length;
|
byId("provincesFooterNumber").innerHTML = filtered.length;
|
||||||
provincesFooterArea.innerHTML = filtered.length ? si(totalArea / filtered.length) + unit : 0 + unit;
|
byId("provincesFooterBurgs").innerHTML = totalBurgs;
|
||||||
provincesFooterPopulation.innerHTML = filtered.length ? si(totalPopulation / filtered.length) : 0;
|
byId("provincesFooterArea").innerHTML = filtered.length ? si(totalArea / filtered.length) + unit : 0 + unit;
|
||||||
provincesFooterArea.dataset.area = totalArea;
|
byId("provincesFooterPopulation").innerHTML = filtered.length ? si(totalPopulation / filtered.length) : 0;
|
||||||
provincesFooterPopulation.dataset.population = totalPopulation;
|
byId("provincesFooterArea").dataset.area = totalArea;
|
||||||
|
byId("provincesFooterPopulation").dataset.population = totalPopulation;
|
||||||
|
|
||||||
body.querySelectorAll("div.states").forEach(el => {
|
body.querySelectorAll("div.states").forEach(el => {
|
||||||
el.addEventListener("click", selectProvinceOnLineClick);
|
el.addEventListener("click", selectProvinceOnLineClick);
|
||||||
|
|
@ -294,7 +302,7 @@ function editProvinces() {
|
||||||
// move all burgs to a new state
|
// move all burgs to a new state
|
||||||
province.burgs.forEach(b => (burgs[b].state = newStateId));
|
province.burgs.forEach(b => (burgs[b].state = newStateId));
|
||||||
|
|
||||||
// difine new state attributes
|
// define new state attributes
|
||||||
const {cell: center, culture} = burgs[burgId];
|
const {cell: center, culture} = burgs[burgId];
|
||||||
const color = getRandomColor();
|
const color = getRandomColor();
|
||||||
const coa = province.coa;
|
const coa = province.coa;
|
||||||
|
|
@ -501,6 +509,9 @@ function editProvinces() {
|
||||||
applyOption(provinceNameEditorSelectForm, p.formName);
|
applyOption(provinceNameEditorSelectForm, p.formName);
|
||||||
document.getElementById("provinceNameEditorFull").value = p.fullName;
|
document.getElementById("provinceNameEditorFull").value = p.fullName;
|
||||||
|
|
||||||
|
const cultureId = pack.cells.culture[p.center];
|
||||||
|
document.getElementById("provinceCultureDisplay").innerText = pack.cultures[cultureId].name;
|
||||||
|
|
||||||
$("#provinceNameEditor").dialog({
|
$("#provinceNameEditor").dialog({
|
||||||
resizable: false,
|
resizable: false,
|
||||||
title: "Change province name",
|
title: "Change province name",
|
||||||
|
|
@ -520,12 +531,12 @@ function editProvinces() {
|
||||||
modules.editProvinceName = true;
|
modules.editProvinceName = true;
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("provinceNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture);
|
document.getElementById("provinceNameEditorShortCulture").addEventListener("click", regenerateShortNameCulture);
|
||||||
document.getElementById("provinceNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
|
document.getElementById("provinceNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
|
||||||
document.getElementById("provinceNameEditorAddForm").addEventListener("click", addCustomForm);
|
document.getElementById("provinceNameEditorAddForm").addEventListener("click", addCustomForm);
|
||||||
document.getElementById("provinceNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
|
document.getElementById("provinceNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
|
||||||
|
|
||||||
function regenerateShortNameCuture() {
|
function regenerateShortNameCulture() {
|
||||||
const province = +provinceNameEditor.dataset.province;
|
const province = +provinceNameEditor.dataset.province;
|
||||||
const culture = pack.cells.culture[pack.provinces[province].center];
|
const culture = pack.cells.culture[pack.provinces[province].center];
|
||||||
const name = Names.getState(Names.getCultureShort(culture), culture);
|
const name = Names.getState(Names.getCultureShort(culture), culture);
|
||||||
|
|
@ -576,12 +587,15 @@ function editProvinces() {
|
||||||
function togglePercentageMode() {
|
function togglePercentageMode() {
|
||||||
if (body.dataset.type === "absolute") {
|
if (body.dataset.type === "absolute") {
|
||||||
body.dataset.type = "percentage";
|
body.dataset.type = "percentage";
|
||||||
|
const totalBurgs = +byId("provincesFooterBurgs").innerText;
|
||||||
const totalArea = +provincesFooterArea.dataset.area;
|
const totalArea = +provincesFooterArea.dataset.area;
|
||||||
const totalPopulation = +provincesFooterPopulation.dataset.population;
|
const totalPopulation = +provincesFooterPopulation.dataset.population;
|
||||||
|
|
||||||
body.querySelectorAll(":scope > div").forEach(function (el) {
|
body.querySelectorAll(":scope > div").forEach(function (el) {
|
||||||
el.querySelector(".biomeArea").innerHTML = rn((+el.dataset.area / totalArea) * 100) + "%";
|
const {cells, burgs, area, population} = el.dataset;
|
||||||
el.querySelector(".culturePopulation").innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + "%";
|
el.querySelector(".provinceBurgs").innerText = rn((+burgs / totalBurgs) * 100) + "%";
|
||||||
|
el.querySelector(".biomeArea").innerHTML = rn((+area / totalArea) * 100) + "%";
|
||||||
|
el.querySelector(".culturePopulation").innerHTML = rn((+population / totalPopulation) * 100) + "%";
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
body.dataset.type = "absolute";
|
body.dataset.type = "absolute";
|
||||||
|
|
@ -1064,10 +1078,7 @@ function editProvinces() {
|
||||||
|
|
||||||
function downloadProvincesData() {
|
function downloadProvincesData() {
|
||||||
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
|
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
|
||||||
let data =
|
let data = `Id,Province,Full Name,Form,State,Color,Capital,Area ${unit},Total Population,Rural Population,Urban Population,Burgs\n`; // headers
|
||||||
"Id,Province,Full Name,Form,State,Color,Capital,Area " +
|
|
||||||
unit +
|
|
||||||
",Total Population,Rural Population,Urban Population\n"; // headers
|
|
||||||
|
|
||||||
body.querySelectorAll(":scope > div").forEach(function (el) {
|
body.querySelectorAll(":scope > div").forEach(function (el) {
|
||||||
const key = parseInt(el.dataset.id);
|
const key = parseInt(el.dataset.id);
|
||||||
|
|
@ -1081,8 +1092,9 @@ function editProvinces() {
|
||||||
data += el.dataset.capital + ",";
|
data += el.dataset.capital + ",";
|
||||||
data += el.dataset.area + ",";
|
data += el.dataset.area + ",";
|
||||||
data += el.dataset.population + ",";
|
data += el.dataset.population + ",";
|
||||||
data += `${Math.round(provincePack.rural * populationRate)},`;
|
data += Math.round(provincePack.rural * populationRate) + ",";
|
||||||
data += `${Math.round(provincePack.urban * populationRate * urbanization)}\n`;
|
data += Math.round(provincePack.urban * populationRate * urbanization) + ",";
|
||||||
|
data += el.dataset.burgs + "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
const name = getFileName("Provinces") + ".csv";
|
const name = getFileName("Provinces") + ".csv";
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
byId("styleFilterInput").innerHTML = allOptions;
|
byId("styleFilterInput").innerHTML = allOptions;
|
||||||
byId("styleStatesBodyFilter").innerHTML = allOptions;
|
byId("styleStatesBodyFilter").innerHTML = allOptions;
|
||||||
|
byId("styleScaleBarBackgroundFilter").innerHTML = allOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store some style inputs as options
|
// store some style inputs as options
|
||||||
|
|
@ -31,6 +32,7 @@ function editStyle(element, group) {
|
||||||
|
|
||||||
styleElementSelect.classList.add("glow");
|
styleElementSelect.classList.add("glow");
|
||||||
if (group) styleGroupSelect.classList.add("glow");
|
if (group) styleGroupSelect.classList.add("glow");
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
styleElementSelect.classList.remove("glow");
|
styleElementSelect.classList.remove("glow");
|
||||||
if (group) styleGroupSelect.classList.remove("glow");
|
if (group) styleGroupSelect.classList.remove("glow");
|
||||||
|
|
@ -81,10 +83,10 @@ function selectStyleElement() {
|
||||||
styleIsOff.style.display = isLayerOff ? "block" : "none";
|
styleIsOff.style.display = isLayerOff ? "block" : "none";
|
||||||
|
|
||||||
// active group element
|
// active group element
|
||||||
const group = styleGroupSelect.value;
|
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders", "terrs"].includes(styleElement)) {
|
||||||
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(styleElement)) {
|
const group = styleGroupSelect.value;
|
||||||
const gEl = group && el.select("#" + group);
|
const defaultGroupSelector = styleElement === "terrs" ? "#landHeights" : "g";
|
||||||
el = group && gEl.size() ? gEl : el.select("g");
|
el = group && el.select("#" + group).size() ? el.select("#" + group) : el.select(defaultGroupSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// opacity
|
// opacity
|
||||||
|
|
@ -94,13 +96,13 @@ function selectStyleElement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter
|
// filter
|
||||||
if (!["landmass", "legend", "regions"].includes(styleElement)) {
|
if (!["landmass", "legend", "regions", "scaleBar"].includes(styleElement)) {
|
||||||
styleFilter.style.display = "block";
|
styleFilter.style.display = "block";
|
||||||
styleFilterInput.value = el.attr("filter") || "";
|
styleFilterInput.value = el.attr("filter") || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill
|
// fill
|
||||||
if (["rivers", "lakes", "landmass", "prec", "ice", "fogging", "vignette"].includes(styleElement)) {
|
if (["rivers", "lakes", "landmass", "prec", "ice", "fogging", "scaleBar", "vignette"].includes(styleElement)) {
|
||||||
styleFill.style.display = "block";
|
styleFill.style.display = "block";
|
||||||
styleFillInput.value = styleFillOutput.value = el.attr("fill");
|
styleFillInput.value = styleFillOutput.value = el.attr("fill");
|
||||||
}
|
}
|
||||||
|
|
@ -170,11 +172,14 @@ function selectStyleElement() {
|
||||||
|
|
||||||
if (styleElement === "terrs") {
|
if (styleElement === "terrs") {
|
||||||
styleHeightmap.style.display = "block";
|
styleHeightmap.style.display = "block";
|
||||||
styleHeightmapScheme.value = terrs.attr("scheme");
|
styleHeightmapRenderOceanOption.style.display = el.attr("id") === "oceanHeights" ? "block" : "none";
|
||||||
styleHeightmapTerracingInput.value = styleHeightmapTerracingOutput.value = terrs.attr("terracing");
|
styleHeightmapRenderOcean.checked = +el.attr("data-render");
|
||||||
styleHeightmapSkipInput.value = styleHeightmapSkipOutput.value = terrs.attr("skip");
|
|
||||||
styleHeightmapSimplificationInput.value = styleHeightmapSimplificationOutput.value = terrs.attr("relax");
|
styleHeightmapScheme.value = el.attr("scheme");
|
||||||
styleHeightmapCurve.value = terrs.attr("curve");
|
styleHeightmapTerracingInput.value = styleHeightmapTerracingOutput.value = el.attr("terracing");
|
||||||
|
styleHeightmapSkipInput.value = styleHeightmapSkipOutput.value = el.attr("skip");
|
||||||
|
styleHeightmapSimplificationInput.value = styleHeightmapSimplificationOutput.value = el.attr("relax");
|
||||||
|
styleHeightmapCurve.value = el.attr("curve");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styleElement === "markers") {
|
if (styleElement === "markers") {
|
||||||
|
|
@ -336,7 +341,7 @@ function selectStyleElement() {
|
||||||
|
|
||||||
// update group options
|
// update group options
|
||||||
styleGroupSelect.options.length = 0; // remove all options
|
styleGroupSelect.options.length = 0; // remove all options
|
||||||
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(styleElement)) {
|
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders", "terrs"].includes(styleElement)) {
|
||||||
const groups = byId(styleElement).querySelectorAll("g");
|
const groups = byId(styleElement).querySelectorAll("g");
|
||||||
groups.forEach(el => {
|
groups.forEach(el => {
|
||||||
if (el.id === "burgLabels") return;
|
if (el.id === "burgLabels") return;
|
||||||
|
|
@ -356,6 +361,31 @@ function selectStyleElement() {
|
||||||
if (auto) styleFilter.style.display = "none";
|
if (auto) styleFilter.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (styleElement === "scaleBar") {
|
||||||
|
styleScaleBar.style.display = "block";
|
||||||
|
|
||||||
|
styleScaleBarSize.value = el.attr("data-bar-size");
|
||||||
|
styleScaleBarFontSize.value = el.attr("font-size");
|
||||||
|
styleScaleBarPositionX.value = el.attr("data-x") || "99";
|
||||||
|
styleScaleBarPositionY.value = el.attr("data-y") || "99";
|
||||||
|
styleScaleBarLabel.value = el.attr("data-label") || "";
|
||||||
|
|
||||||
|
const scaleBarBack = el.select("#scaleBarBack");
|
||||||
|
if (scaleBarBack.size()) {
|
||||||
|
styleScaleBarBackgroundOpacityInput.value = styleScaleBarBackgroundOpacityOutput.value =
|
||||||
|
scaleBarBack.attr("opacity");
|
||||||
|
styleScaleBarBackgroundFillInput.value = styleScaleBarBackgroundFillOutput.value = scaleBarBack.attr("fill");
|
||||||
|
styleScaleBarBackgroundStrokeInput.value = styleScaleBarBackgroundStrokeOutput.value =
|
||||||
|
scaleBarBack.attr("stroke");
|
||||||
|
styleScaleBarBackgroundStrokeWidth.value = scaleBarBack.attr("stroke-width");
|
||||||
|
styleScaleBarBackgroundFilter.value = scaleBarBack.attr("filter");
|
||||||
|
styleScaleBarBackgroundPaddingTop.value = scaleBarBack.attr("data-top");
|
||||||
|
styleScaleBarBackgroundPaddingRight.value = scaleBarBack.attr("data-right");
|
||||||
|
styleScaleBarBackgroundPaddingBottom.value = scaleBarBack.attr("data-bottom");
|
||||||
|
styleScaleBarBackgroundPaddingLeft.value = scaleBarBack.attr("data-left");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (styleElement === "vignette") {
|
if (styleElement === "vignette") {
|
||||||
styleVignette.style.display = "block";
|
styleVignette.style.display = "block";
|
||||||
|
|
||||||
|
|
@ -519,18 +549,16 @@ outlineLayers.addEventListener("change", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
styleHeightmapScheme.addEventListener("change", function () {
|
styleHeightmapScheme.addEventListener("change", function () {
|
||||||
terrs.attr("scheme", this.value);
|
getEl().attr("scheme", this.value);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
});
|
});
|
||||||
|
|
||||||
openCreateHeightmapSchemeButton.addEventListener("click", function () {
|
openCreateHeightmapSchemeButton.addEventListener("click", function () {
|
||||||
// start with current scheme
|
// start with current scheme
|
||||||
this.dataset.stops = terrs.attr("scheme").startsWith("#")
|
const scheme = getEl().attr("scheme");
|
||||||
? terrs.attr("scheme")
|
this.dataset.stops = scheme.startsWith("#")
|
||||||
: (function () {
|
? scheme
|
||||||
const scheme = heightmapColorSchemes[terrs.attr("scheme")];
|
: (() => [0, 0.25, 0.5, 0.75, 1].map(heightmapColorSchemes[scheme]).map(toHEX).join(","))();
|
||||||
return [0, 0.25, 0.5, 0.75, 1].map(scheme).map(toHEX).join(",");
|
|
||||||
})();
|
|
||||||
|
|
||||||
// render dialog base structure
|
// render dialog base structure
|
||||||
alertMessage.innerHTML = /* html */ `<div>
|
alertMessage.innerHTML = /* html */ `<div>
|
||||||
|
|
@ -622,7 +650,7 @@ openCreateHeightmapSchemeButton.addEventListener("click", function () {
|
||||||
if (stops in heightmapColorSchemes) return tip("This scheme already exists", false, "error");
|
if (stops in heightmapColorSchemes) return tip("This scheme already exists", false, "error");
|
||||||
|
|
||||||
addCustomColorScheme(stops);
|
addCustomColorScheme(stops);
|
||||||
terrs.attr("scheme", stops);
|
getEl().attr("scheme", stops);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
|
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
@ -644,23 +672,28 @@ openCreateHeightmapSchemeButton.addEventListener("click", function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
styleHeightmapRenderOcean.addEventListener("change", function () {
|
||||||
|
getEl().attr("data-render", +this.checked);
|
||||||
|
drawHeightmap();
|
||||||
|
});
|
||||||
|
|
||||||
styleHeightmapTerracingInput.addEventListener("input", function () {
|
styleHeightmapTerracingInput.addEventListener("input", function () {
|
||||||
terrs.attr("terracing", this.value);
|
getEl().attr("terracing", this.value);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
});
|
});
|
||||||
|
|
||||||
styleHeightmapSkipInput.addEventListener("input", function () {
|
styleHeightmapSkipInput.addEventListener("input", function () {
|
||||||
terrs.attr("skip", this.value);
|
getEl().attr("skip", this.value);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
});
|
});
|
||||||
|
|
||||||
styleHeightmapSimplificationInput.addEventListener("input", function () {
|
styleHeightmapSimplificationInput.addEventListener("input", function () {
|
||||||
terrs.attr("relax", this.value);
|
getEl().attr("relax", this.value);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
});
|
});
|
||||||
|
|
||||||
styleHeightmapCurve.addEventListener("change", function () {
|
styleHeightmapCurve.addEventListener("change", function () {
|
||||||
terrs.attr("curve", this.value);
|
getEl().attr("curve", this.value);
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -957,7 +990,7 @@ function textureProvideURL() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchTextureURL(url) {
|
function fetchTextureURL(url) {
|
||||||
INFO && console.log("Provided URL is", url);
|
INFO && console.info("Provided URL is", url);
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
const canvas = byId("texturePreview");
|
const canvas = byId("texturePreview");
|
||||||
|
|
@ -1043,6 +1076,44 @@ styleVignetteBlur.addEventListener("input", function () {
|
||||||
byId("vignette-rect")?.setAttribute("filter", `blur(${this.value}px)`);
|
byId("vignette-rect")?.setAttribute("filter", `blur(${this.value}px)`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
styleScaleBar.addEventListener("input", function (event) {
|
||||||
|
const scaleBarBack = scaleBar.select("#scaleBarBack");
|
||||||
|
if (!scaleBarBack.size()) return;
|
||||||
|
|
||||||
|
const {id, value} = event.target;
|
||||||
|
|
||||||
|
if (id === "styleScaleBarSize") scaleBar.attr("data-bar-size", value);
|
||||||
|
else if (id === "styleScaleBarFontSize") scaleBar.attr("font-size", value);
|
||||||
|
else if (id === "styleScaleBarPositionX") scaleBar.attr("data-x", value);
|
||||||
|
else if (id === "styleScaleBarPositionY") scaleBar.attr("data-y", value);
|
||||||
|
else if (id === "styleScaleBarLabel") scaleBar.attr("data-label", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundOpacityInput") scaleBarBack.attr("opacity", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundFillInput") scaleBarBack.attr("fill", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundStrokeInput") scaleBarBack.attr("stroke", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundStrokeWidth") scaleBarBack.attr("stroke-width", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundFilter") scaleBarBack.attr("filter", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundPaddingTop") scaleBarBack.attr("data-top", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundPaddingRight") scaleBarBack.attr("data-right", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundPaddingBottom") scaleBarBack.attr("data-bottom", value);
|
||||||
|
else if (id === "styleScaleBarBackgroundPaddingLeft") scaleBarBack.attr("data-left", value);
|
||||||
|
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"styleScaleBarSize",
|
||||||
|
"styleScaleBarPositionX",
|
||||||
|
"styleScaleBarPositionY",
|
||||||
|
"styleScaleBarLabel",
|
||||||
|
"styleScaleBarBackgroundPaddingLeft",
|
||||||
|
"styleScaleBarBackgroundPaddingTop",
|
||||||
|
"styleScaleBarBackgroundPaddingRight",
|
||||||
|
"styleScaleBarBackgroundPaddingBottom"
|
||||||
|
].includes(id)
|
||||||
|
) {
|
||||||
|
drawScaleBar(scaleBar, scale);
|
||||||
|
fitScaleBar(scaleBar, svgWidth, svgHeight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function updateElements() {
|
function updateElements() {
|
||||||
// burgIcons to desired size
|
// burgIcons to desired size
|
||||||
burgIcons.selectAll("g").each(function () {
|
burgIcons.selectAll("g").each(function () {
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,9 @@ function applyStyleWithUiRefresh(style) {
|
||||||
|
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
setPresetRemoveButtonVisibiliy();
|
setPresetRemoveButtonVisibiliy();
|
||||||
|
|
||||||
|
drawScaleBar(scaleBar, scale);
|
||||||
|
fitScaleBar(scaleBar, svgWidth, svgHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStylePreset() {
|
function addStylePreset() {
|
||||||
|
|
@ -239,7 +242,18 @@ function addStylePreset() {
|
||||||
"#oceanLayers": ["filter", "layers"],
|
"#oceanLayers": ["filter", "layers"],
|
||||||
"#oceanBase": ["fill"],
|
"#oceanBase": ["fill"],
|
||||||
"#oceanicPattern": ["href", "opacity"],
|
"#oceanicPattern": ["href", "opacity"],
|
||||||
"#terrs": ["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"],
|
"#terrs #oceanHeights": [
|
||||||
|
"data-render",
|
||||||
|
"opacity",
|
||||||
|
"scheme",
|
||||||
|
"terracing",
|
||||||
|
"skip",
|
||||||
|
"relax",
|
||||||
|
"curve",
|
||||||
|
"filter",
|
||||||
|
"mask"
|
||||||
|
],
|
||||||
|
"#terrs #landHeights": ["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"],
|
||||||
"#legend": [
|
"#legend": [
|
||||||
"data-size",
|
"data-size",
|
||||||
"font-size",
|
"font-size",
|
||||||
|
|
@ -301,7 +315,19 @@ function addStylePreset() {
|
||||||
],
|
],
|
||||||
"#fogging": ["opacity", "fill", "filter"],
|
"#fogging": ["opacity", "fill", "filter"],
|
||||||
"#vignette": ["opacity", "fill", "filter"],
|
"#vignette": ["opacity", "fill", "filter"],
|
||||||
"#vignette-rect": ["x", "y", "width", "height", "rx", "ry", "filter"]
|
"#vignette-rect": ["x", "y", "width", "height", "rx", "ry", "filter"],
|
||||||
|
"#scaleBar": ["opacity", "fill", "font-size", "data-bar-size", "data-x", "data-y", "data-label"],
|
||||||
|
"#scaleBarBack": [
|
||||||
|
"opacity",
|
||||||
|
"fill",
|
||||||
|
"stroke",
|
||||||
|
"stroke-width",
|
||||||
|
"filter",
|
||||||
|
"data-top",
|
||||||
|
"data-right",
|
||||||
|
"data-bottom",
|
||||||
|
"data-left"
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const selector in attributes) {
|
for (const selector in attributes) {
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,6 @@ function editUnits() {
|
||||||
byId("heightExponentInput").addEventListener("input", changeHeightExponent);
|
byId("heightExponentInput").addEventListener("input", changeHeightExponent);
|
||||||
byId("heightExponentOutput").addEventListener("input", changeHeightExponent);
|
byId("heightExponentOutput").addEventListener("input", changeHeightExponent);
|
||||||
byId("temperatureScale").addEventListener("change", changeTemperatureScale);
|
byId("temperatureScale").addEventListener("change", changeTemperatureScale);
|
||||||
byId("barSizeOutput").addEventListener("input", renderScaleBar);
|
|
||||||
byId("barSizeInput").addEventListener("input", renderScaleBar);
|
|
||||||
byId("barLabel").addEventListener("input", renderScaleBar);
|
|
||||||
byId("barPosX").addEventListener("input", fitScaleBar);
|
|
||||||
byId("barPosY").addEventListener("input", fitScaleBar);
|
|
||||||
byId("barBackOpacity").addEventListener("input", changeScaleBarOpacity);
|
|
||||||
byId("barBackColor").addEventListener("input", changeScaleBarColor);
|
|
||||||
|
|
||||||
byId("populationRateOutput").addEventListener("input", changePopulationRate);
|
byId("populationRateOutput").addEventListener("input", changePopulationRate);
|
||||||
byId("populationRateInput").addEventListener("change", changePopulationRate);
|
byId("populationRateInput").addEventListener("change", changePopulationRate);
|
||||||
|
|
@ -84,14 +77,6 @@ function editUnits() {
|
||||||
if (layerIsOn("toggleTemp")) drawTemp();
|
if (layerIsOn("toggleTemp")) drawTemp();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeScaleBarOpacity() {
|
|
||||||
scaleBar.select("rect").attr("opacity", this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeScaleBarColor() {
|
|
||||||
scaleBar.select("rect").attr("fill", this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function changePopulationRate() {
|
function changePopulationRate() {
|
||||||
populationRate = +this.value;
|
populationRate = +this.value;
|
||||||
}
|
}
|
||||||
|
|
@ -129,19 +114,6 @@ function editUnits() {
|
||||||
localStorage.removeItem("heightExponent");
|
localStorage.removeItem("heightExponent");
|
||||||
calculateTemperatures();
|
calculateTemperatures();
|
||||||
|
|
||||||
// scale bar
|
|
||||||
barSizeOutput.value = barSizeInput.value = 2;
|
|
||||||
barLabel.value = "";
|
|
||||||
barBackOpacity.value = 0.2;
|
|
||||||
barBackColor.value = "#ffffff";
|
|
||||||
barPosX.value = barPosY.value = 99;
|
|
||||||
|
|
||||||
localStorage.removeItem("barSize");
|
|
||||||
localStorage.removeItem("barLabel");
|
|
||||||
localStorage.removeItem("barBackOpacity");
|
|
||||||
localStorage.removeItem("barBackColor");
|
|
||||||
localStorage.removeItem("barPosX");
|
|
||||||
localStorage.removeItem("barPosY");
|
|
||||||
renderScaleBar();
|
renderScaleBar();
|
||||||
|
|
||||||
// population
|
// population
|
||||||
|
|
|
||||||
|
|
@ -286,14 +286,25 @@
|
||||||
"href": "./images/kiwiroo.png",
|
"href": "./images/kiwiroo.png",
|
||||||
"opacity": 0.4
|
"opacity": 0.4
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
"opacity": null,
|
"data-render": 0,
|
||||||
"scheme": "bright",
|
"opacity": 1,
|
||||||
|
"scheme": "light",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": "url(#filter-sepia)",
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 1,
|
||||||
|
"scheme": "light",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 2,
|
"skip": 2,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "url(#blur3)",
|
"filter": "url(#filter-sepia)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "0%",
|
"rx": "0%",
|
||||||
"ry": "0%",
|
"ry": "0%",
|
||||||
"filter": "blur(50px)"
|
"filter": "blur(50px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,24 @@
|
||||||
"href": "",
|
"href": "",
|
||||||
"opacity": 1
|
"opacity": 1
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
"opacity": null,
|
"data-render": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 1,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 0,
|
"skip": 0,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(30px)"
|
"filter": "blur(30px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 9,
|
||||||
|
"data-bar-size": 1.5,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": null,
|
||||||
|
"data-top": 18,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,13 +288,24 @@
|
||||||
"href": "",
|
"href": "",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
|
"opacity": 0.5,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
"opacity": 0.5,
|
"opacity": 0.5,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
@ -400,5 +411,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 8,
|
||||||
|
"data-bar-size": 1.5,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "",
|
||||||
|
"data-top": 17,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,14 +286,25 @@
|
||||||
"href": "",
|
"href": "",
|
||||||
"opacity": 0.15
|
"opacity": 0.15
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"scheme": "monochrome",
|
"scheme": "olive",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 0.8,
|
||||||
|
"scheme": "livid",
|
||||||
"terracing": 6,
|
"terracing": 6,
|
||||||
"skip": 0,
|
"skip": 0,
|
||||||
"relax": 2,
|
"relax": 2,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "",
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#d0d0dc",
|
||||||
|
"font-size": 11,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.3,
|
||||||
|
"fill": "#05001f",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "",
|
||||||
|
"data-top": 23,
|
||||||
|
"data-right": 18,
|
||||||
|
"data-bottom": 18,
|
||||||
|
"data-left": 12
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,24 @@
|
||||||
"href": "./images/pattern1.png",
|
"href": "./images/pattern1.png",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
"opacity": null,
|
"data-render": 0,
|
||||||
|
"opacity": 1,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 1,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,14 +288,25 @@
|
||||||
"href": "./images/pattern3.png",
|
"href": "./images/pattern3.png",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
"opacity": 1,
|
"data-render": 1,
|
||||||
|
"opacity": 0.8,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 0.8,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 2,
|
"terracing": 2,
|
||||||
"skip": 1,
|
"skip": 1,
|
||||||
"relax": 2,
|
"relax": 2,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "url(#filter-grayscale)",
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -400,5 +411,25 @@
|
||||||
"rx": "10%",
|
"rx": "10%",
|
||||||
"ry": "10%",
|
"ry": "10%",
|
||||||
"filter": "blur(30px)"
|
"filter": "blur(30px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#121212",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#607671",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,24 @@
|
||||||
"href": "./images/pattern1.png",
|
"href": "./images/pattern1.png",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
"opacity": 0.4,
|
"opacity": 0.4,
|
||||||
"scheme": "light",
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": "url(#turbulence)",
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 0.4,
|
||||||
|
"scheme": "bright",
|
||||||
"terracing": 10,
|
"terracing": 10,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "url(#turbulence)",
|
"filter": "url(#turbulence)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -281,14 +281,25 @@
|
||||||
"href": "",
|
"href": "",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"scheme": "monochrome",
|
"scheme": "monochrome",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 0,
|
||||||
"relax": 0,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "url(#blur3)",
|
"filter": "url(#turbulence)",
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs #landHeights": {
|
||||||
|
"opacity": 1,
|
||||||
|
"scheme": "monochrome",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": "url(#turbulence)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -394,5 +405,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"font-size": 8,
|
||||||
|
"data-bar-size": 1.5,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "",
|
||||||
|
"data-top": 18,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,14 +286,25 @@
|
||||||
"href": "",
|
"href": "",
|
||||||
"opacity": 0.3
|
"opacity": 0.3
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
|
"opacity": 0.5,
|
||||||
|
"scheme": "livid",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"scheme": "livid",
|
"scheme": "livid",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 10,
|
"skip": 10,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "url(#blurFilter)",
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#b5c1d4",
|
||||||
|
"font-size": 11,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.5,
|
||||||
|
"fill": "#0a1e24",
|
||||||
|
"stroke": "#40547a",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "",
|
||||||
|
"data-top": 22,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 16,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,14 +286,25 @@
|
||||||
"href": "./images/kiwiroo.png",
|
"href": "./images/kiwiroo.png",
|
||||||
"opacity": 0.3
|
"opacity": 0.3
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 0,
|
||||||
|
"opacity": 0.7,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 2,
|
"skip": 2,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": "",
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
"#legend": {
|
"#legend": {
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(30px)"
|
"filter": "blur(30px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,24 @@
|
||||||
"href": "./images/kiwiroo.png",
|
"href": "./images/kiwiroo.png",
|
||||||
"opacity": 0.5
|
"opacity": 0.5
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
|
"data-render": 1,
|
||||||
|
"opacity": 0.5,
|
||||||
|
"scheme": "light",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
"opacity": 0.5,
|
"opacity": 0.5,
|
||||||
"scheme": "light",
|
"scheme": "light",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
@ -398,5 +409,25 @@
|
||||||
"rx": "5%",
|
"rx": "5%",
|
||||||
"ry": "5%",
|
"ry": "5%",
|
||||||
"filter": "blur(20px)"
|
"filter": "blur(20px)"
|
||||||
|
},
|
||||||
|
"#scaleBar": {
|
||||||
|
"opacity": 1,
|
||||||
|
"fill": "#353540",
|
||||||
|
"font-size": 10,
|
||||||
|
"data-bar-size": 2,
|
||||||
|
"data-x": 99,
|
||||||
|
"data-y": 99,
|
||||||
|
"data-label": ""
|
||||||
|
},
|
||||||
|
"#scaleBarBack": {
|
||||||
|
"opacity": 0.2,
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"stroke": "#000000",
|
||||||
|
"stroke-width": 1,
|
||||||
|
"filter": "url(#blur5)",
|
||||||
|
"data-top": 20,
|
||||||
|
"data-right": 15,
|
||||||
|
"data-bottom": 15,
|
||||||
|
"data-left": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ function drawCellsValue(data) {
|
||||||
function drawPolygons(data) {
|
function drawPolygons(data) {
|
||||||
const max = d3.max(data),
|
const max = d3.max(data),
|
||||||
min = d3.min(data),
|
min = d3.min(data),
|
||||||
scheme = getColorScheme(terrs.attr("scheme"));
|
scheme = getColorScheme(terrs.select("#landHeights").attr("scheme"));
|
||||||
data = data.map(d => 1 - normalize(d, min, max));
|
data = data.map(d => 1 - normalize(d, min, max));
|
||||||
|
|
||||||
debug.selectAll("polygon").remove();
|
debug.selectAll("polygon").remove();
|
||||||
|
|
@ -338,7 +338,7 @@ function drawPolygons(data) {
|
||||||
.data(data)
|
.data(data)
|
||||||
.enter()
|
.enter()
|
||||||
.append("polygon")
|
.append("polygon")
|
||||||
.attr("points", (d, i) => getPackPolygon(i))
|
.attr("points", (d, i) => getGridPolygon(i))
|
||||||
.attr("fill", d => scheme(d))
|
.attr("fill", d => scheme(d))
|
||||||
.attr("stroke", d => scheme(d));
|
.attr("stroke", d => scheme(d));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.95.05"; // generator version, update each time
|
const version = "1.96.00"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
@ -28,6 +28,8 @@ const version = "1.95.05"; // generator version, update each time
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<strong>Latest changes:</strong>
|
<strong>Latest changes:</strong>
|
||||||
|
<li>Ability to render ocean heightmap</li>
|
||||||
|
<li>Scale bar styling features</li>
|
||||||
<li>Vignette visual layer and vignette styling options</li>
|
<li>Vignette visual layer and vignette styling options</li>
|
||||||
<li>Ability to define custom heightmap color scheme</li>
|
<li>Ability to define custom heightmap color scheme</li>
|
||||||
<li>New style preset Night and new heightmap color schemes</li>
|
<li>New style preset Night and new heightmap color schemes</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue