Merge branch 'v6'
This commit is contained in:
commit
8f3bdd6188
@ -41,6 +41,9 @@ select, input, textarea {
|
|||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
}
|
}
|
||||||
|
input.numInput {
|
||||||
|
width: 7em;
|
||||||
|
}
|
||||||
button {
|
button {
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -75,6 +78,20 @@ button:enabled:active {
|
|||||||
border-color: #808080;
|
border-color: #808080;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
button.activeBiomeModeButton{
|
||||||
|
background-color: #8888ff;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
button.activeBiomeModeButton:enabled:hover {
|
||||||
|
background-color: #bbbbff;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
button.activeBiomeModeButton:enabled:active {
|
||||||
|
background-color: white;
|
||||||
|
border-color: #808080;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
#biomeButtonContainer {
|
#biomeButtonContainer {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
@ -161,6 +178,9 @@ h3 {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #00ff00;
|
color: #00ff00;
|
||||||
}
|
}
|
||||||
|
#modeContainer {
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
.collapser {
|
.collapser {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
71
index.html
71
index.html
@ -19,14 +19,22 @@ ERROR: This tool requires JavaScript to work, but JavaScript is disabled in your
|
|||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- The main content container starts hidden so it doesn't clutter
|
<!-- The main content container starts hidden so it doesn't clutter
|
||||||
the page in noscript mode. It will be unhidden once the JavaScript loads -->
|
the page in noscript mode. It will be unhidden once the JavaScript loads -->
|
||||||
<div id="mainContentContainer" class="contentContainer" hidden>
|
<div id="mainContentContainer" class="contentContainer" hidden>
|
||||||
|
|
||||||
|
<div id="modeContainer">
|
||||||
|
<button id="modernModeButton" type="button" class="activeBiomeModeButton">Biome points</button>
|
||||||
|
<button id="v6ModeButton" type="button">v6 biomes</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="canvasContainer">
|
<div id="canvasContainer">
|
||||||
<canvas id="voronoiCanvas" width="500" height="500">
|
<canvas id="voronoiCanvas" width="500" height="500">
|
||||||
A Voronoi diagram is supposed to be here but for some reason it cannot be displayed. This tool is useless without this functionality.
|
A Voronoi diagram is supposed to be here but for some reason it cannot be displayed. This tool is useless without this functionality.
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="diagramInfoContainer" class="borderedSection">
|
<div id="diagramInfoContainer" class="borderedSection">
|
||||||
<span id="errorMessage" hidden></span>
|
<span id="errorMessage" hidden></span>
|
||||||
<span id="altitudeDisplay"></span>
|
<span id="altitudeDisplay"></span>
|
||||||
@ -36,7 +44,8 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
|||||||
<span id="coordinateDisplay"> </span>
|
<span id="coordinateDisplay"> </span>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
|
<div id="biomeConfigContainerOuter">
|
||||||
<h2 class="configHeader"><span class="collapser" id="biomeConfigHeaderLink">▼</span> Biome configuration</h2>
|
<h2 class="configHeader"><span class="collapser" id="biomeConfigHeaderLink">▼</span> Biome configuration</h2>
|
||||||
<div id="biomeConfigContainer" class="configFrame">
|
<div id="biomeConfigContainer" class="configFrame">
|
||||||
<form id="biomeForm">
|
<form id="biomeForm">
|
||||||
@ -65,25 +74,46 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
<label for="inputHeat">Heat: </label>
|
<label for="inputHeat">Heat: </label>
|
||||||
<input id="inputHeat" type="number" value="50" step="1" size="10" min="-1e6" max="1e6">
|
<input id="inputHeat" class="numInput" type="number" value="50" step="1" min="-1e6" max="1e6">
|
||||||
<label for="inputHumidity">Humidity: </label>
|
<label for="inputHumidity">Humidity: </label>
|
||||||
<input id="inputHumidity" type="number" value="50" step="1" size="10" min="-1e6" max="1e6">
|
<input id="inputHumidity" class="numInput" type="number" value="50" step="1" min="-1e6" max="1e6">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<label for="inputMinY">Min. Y: </label>
|
<label for="inputMinY">Min. Y: </label>
|
||||||
<input id="inputMinY" type="number" value="-31000" step="1" size="10">
|
<input id="inputMinY" class="numInput" type="number" value="-31000" step="1">
|
||||||
<label for="inputMaxY">Max. Y: </label>
|
<label for="inputMaxY">Max. Y: </label>
|
||||||
<input id="inputMaxY" type="number" value="31000" step="1" size="10">
|
<input id="inputMaxY" class="numInput" type="number" value="31000" step="1">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="biomeV6ConfigContainerOuter" hidden>
|
||||||
|
<h2 class="configHeader"><span class="collapser" id="biomeV6ConfigHeaderLink">▼</span> Biome configuration</h2>
|
||||||
|
<div id="biomeV6ConfigContainer" class="configFrame">
|
||||||
|
<form id="biomeV6Form">
|
||||||
|
<div>Flags:
|
||||||
|
<input id="inputCheckboxV6Snowbiomes" type="checkbox" checked>
|
||||||
|
<label for="inputCheckboxV6Snowbiomes">snowbiomes</label>
|
||||||
|
|
||||||
|
<input id="inputCheckboxV6Jungles" type="checkbox" checked>
|
||||||
|
<label for="inputCheckboxV6Jungles">jungles</label>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<label for="inputV6FreqDesert">Desert noise threshold: </label>
|
||||||
|
<input id="inputV6FreqDesert" class="numInput" type="number" value="0.45" step="0.01" disabled>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="viewConfigContainerOuter">
|
||||||
<h2 class="configHeader"><span class="collapser" id="viewConfigHeaderLink">▼</span> Diagram view settings</h2>
|
<h2 class="configHeader"><span class="collapser" id="viewConfigHeaderLink">▼</span> Diagram view settings</h2>
|
||||||
<div id="viewConfigContainer" class="configFrame">
|
<div id="viewConfigContainer" class="configFrame">
|
||||||
<form id="viewForm">
|
<form id="viewForm">
|
||||||
<label for="inputViewY">Altitude: </label>
|
<label for="inputViewY">Altitude: </label>
|
||||||
<input id="inputViewY" type="number" value="0" step="1" size="10">
|
<input id="inputViewY" class="numInput" type="number" value="0" step="1">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@ -104,44 +134,44 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
|
<div id="noiseConfigContainerOuter">
|
||||||
<h2 class="configHeader"><span class="collapser" id="noiseConfigHeaderLink">▼</span> Noise parameters</h2>
|
<h2 class="configHeader"><span class="collapser" id="noiseConfigHeaderLink">▼</span> Noise parameters</h2>
|
||||||
<div class="configFrame" id="noiseConfigContainer">
|
<div class="configFrame" id="noiseConfigContainer">
|
||||||
<form id="noiseForm">
|
<form id="noiseForm">
|
||||||
<h3>Heat (<code>mg_biome_np_heat</code>)</h3>
|
<h3>Heat (<code id="noiseSettingNameHeat">mg_biome_np_heat</code>)</h3>
|
||||||
<label for="inputNoiseHeatOffset">Offset: </label>
|
<label for="inputNoiseHeatOffset">Offset: </label>
|
||||||
<input id="inputNoiseHeatOffset" type="number" value="50" size="10">
|
<input id="inputNoiseHeatOffset" class="numInput" type="number" value="50" step=0.01>
|
||||||
|
|
||||||
<label for="inputNoiseHeatScale">Scale: </label>
|
<label for="inputNoiseHeatScale">Scale: </label>
|
||||||
<input id="inputNoiseHeatScale" type="number" value="50" size="10">
|
<input id="inputNoiseHeatScale" class="numInput" type="number" value="50" step=0.01>
|
||||||
|
|
||||||
<label for="inputNoiseHeatOctaves">Octaves: </label>
|
<label for="inputNoiseHeatOctaves">Octaves: </label>
|
||||||
<input id="inputNoiseHeatOctaves" type="number" value="3" step="1" min="1" max="65535" size="10">
|
<input id="inputNoiseHeatOctaves" class="numInput" type="number" value="3" step="1" min="1" max="65535">
|
||||||
|
|
||||||
<label for="inputNoiseHeatPersistence">Persistence: </label>
|
<label for="inputNoiseHeatPersistence">Persistence: </label>
|
||||||
<input id="inputNoiseHeatPersistence" type="number" value="0.5" step=0.01 size="10">
|
<input id="inputNoiseHeatPersistence" class="numInput" type="number" value="0.5" step=0.01>
|
||||||
|
|
||||||
<h3>Humidity (<code>mg_biome_np_humidity</code>)</h3>
|
<h3>Humidity (<code id="noiseSettingNameHumidity">mg_biome_np_humidity</code>)</h3>
|
||||||
<label for="inputNoiseHumidityOffset">Offset: </label>
|
<label for="inputNoiseHumidityOffset">Offset: </label>
|
||||||
<input id="inputNoiseHumidityOffset" type="number" value="50" size="10">
|
<input id="inputNoiseHumidityOffset" class="numInput" type="number" value="50" step=0.01>
|
||||||
|
|
||||||
<label for="inputNoiseHumidityScale">Scale: </label>
|
<label for="inputNoiseHumidityScale">Scale: </label>
|
||||||
<input id="inputNoiseHumidityScale" type="number" value="50" size="10">
|
<input id="inputNoiseHumidityScale" class="numInput" type="number" value="50" step=0.01>
|
||||||
|
|
||||||
<label for="inputNoiseHumidityOctaves">Octaves: </label>
|
<label for="inputNoiseHumidityOctaves">Octaves: </label>
|
||||||
<input id="inputNoiseHumidityOctaves" type="number" value="3" step="1" min="1" max="65535" size="10">
|
<input id="inputNoiseHumidityOctaves" class="numInput" type="number" value="3" step="1" min="1" max="65535">
|
||||||
|
|
||||||
<label for="inputNoiseHumidityPersistence">Persistence: </label>
|
<label for="inputNoiseHumidityPersistence">Persistence: </label>
|
||||||
<input id="inputNoiseHumidityPersistence" type="number" value="0.5" step=0.01 size="10">
|
<input id="inputNoiseHumidityPersistence" class="numInput" type="number" value="0.5" step=0.01>
|
||||||
|
|
||||||
<h3>Reset</h3>
|
<h3>Reset</h3>
|
||||||
<button id="inputNoiseReset" type="button">Reset noise parameters</button>
|
<button id="inputNoiseReset" type="button">Reset noise parameters</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div id="importContainerOuter">
|
||||||
<h2 class="configHeader"><span class="collapser" id="importHeaderLink">▶</span> Import</h2>
|
<h2 class="configHeader"><span class="collapser" id="importHeaderLink">▶</span> Import</h2>
|
||||||
<div class="configFrame" id="importContainer" style="display:none">
|
<div class="configFrame" id="importContainer" style="display:none">
|
||||||
<form id="importForm">
|
<form id="importForm">
|
||||||
@ -156,7 +186,7 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div id="exportContainerOuter">
|
||||||
<h2 class="configHeader"><span class="collapser" id="exportHeaderLink">▶</span> Export</h2>
|
<h2 class="configHeader"><span class="collapser" id="exportHeaderLink">▶</span> Export</h2>
|
||||||
<div class="configFrame" id="exportContainer" style="display:none">
|
<div class="configFrame" id="exportContainer" style="display:none">
|
||||||
<form id="exportForm">
|
<form id="exportForm">
|
||||||
@ -172,6 +202,7 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
102
manual.html
102
manual.html
@ -12,93 +12,135 @@
|
|||||||
<div id="mainContentContainer" class="contentContainer">
|
<div id="mainContentContainer" class="contentContainer">
|
||||||
<p><a href="./index.html">Back to the main program</a></p>
|
<p><a href="./index.html">Back to the main program</a></p>
|
||||||
<h2>What is this?</h2>
|
<h2>What is this?</h2>
|
||||||
<p>MiBPov is the <u>Mi</u>netest <u>B</u>iome <u>Po</u>int <u>V</u>isualizer, a tool for people who develop games and mods for <a href="https://minetest.net">Minetest</a>. It allows them to visualize the heat and humidity points of biomes. It works in your web browser using JavaScript.</p>
|
<p>MiBPov is the <u>Mi</u>netest <u>B</u>iome <u>Po</u>int <u>V</u>isualizer, a tool for people who develop games and mods for <a href="https://minetest.net">Minetest</a>. It allows them to <b>visualize the heat and humidity points</b> of biomes. It runs in your <b>web browser</b> using JavaScript.</p>
|
||||||
|
|
||||||
<h2>Features</h2>
|
<h2>Features</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Add the heat and humidity points of biomes</li>
|
<li><b>Add</b> the heat and humidity points of biomes</li>
|
||||||
<li>Visualize the biomes on a Voronoi diagram</li>
|
<li><b>Visualize</b> the biomes on a <a title="Wikipedia: Voronoi diagram" href="https://en.wikipedia.org/wiki/Voronoi_diagram">Voronoi diagram</a></li>
|
||||||
<li>Show biomes for a given Y altitude only</li>
|
<li>Show biomes for a given <b>Y altitude</b> only</li>
|
||||||
<li>Modify the noise parameters of the heat and humidity Perlin noises used by the mapgen</li>
|
<li>Modify the <b>noise parameters</b> of the heat and humidity Perlin noises used by the mapgen</li>
|
||||||
|
<li>Visualize the biomes of the <b>v6 mapgen</b> in a special diagram</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Quick reminder how biomes work</h2>
|
<h2>Quick reminder how biomes work</h2>
|
||||||
<p>When Minetest generates the world, each (X, Z) coordinate is assigned a heat and humidity value (“heat” is also sometimes called “temperature”). Also, Minetest calculates the <a title="Wikipedia: Voronoi diagram" href="https://en.wikipedia.org/wiki/Voronoi_diagram">Voronoi</a> cell for each biome. If a world position’s heat and humidity fall into a given biome’s Voronoi cell, that biome will be put at that position. And this happens for every position. The problem is that as you, as the developer, don’t see these Voronoi cells, you only see the heat and humidity points. This is where this program will help you.</p>
|
<p>When Minetest generates the world, each (X, Z) coordinate is assigned a <b>heat</b> and <b>humidity</b> value (“heat” is also sometimes called “temperature”). Also, each biome is assigned a heat and humidity value as well. Heat and humidity act as coordinates on a <b>2-dimensional plane</b>. For any world position, the biome that has a heat and humidity value that are closest to the heat and humidity will be used for that position. This happens for every position.</p>
|
||||||
|
|
||||||
|
<p>Minetest also may apply “blending” at the biome borders for a smoother transition, but this is ignored in MiBPoV.</p>
|
||||||
|
|
||||||
|
<p>The challenge for the developer is to figure out good heat and humidity points of custom biomes to make sure they are well-balanced. This is where this program will help you.</p>
|
||||||
|
|
||||||
|
<p>The v6 map generator is an exception: Here, biomes don’t have heat and humidity points. Instead, Minetest instead just checks if the world position’s heat and humidity lies between some (mostly) hardcoded values and then decides which of the hardcoded biomes to use.</p>
|
||||||
|
|
||||||
<p>Please refer to the official Minetest Lua API documentation for a more in-depth explanation.</p>
|
<p>Please refer to the official Minetest Lua API documentation for a more in-depth explanation.</p>
|
||||||
|
|
||||||
<h2>Interpreting the diagram</h2>
|
<h2>Interpreting the diagram</h2>
|
||||||
<p>On top of the page, you see the Voronoi diagram. The horizontal axis represents heat and the vertical axis represents humidity. The visible diagram area represents all mathematically possible values. Note that the further you go from the center, the less likely they will become, with the area close to the border being extremely unlikely (<0.1%). By default, the value range of heat and humidity is from −37.5 to 137.5, with 50 as the midpoint. But most values will be somewhere between 0 and 100 by default.</p>
|
<p>On top of the page, you see the biome diagram. The horizontal axis represents heat and the vertical axis represents humidity. The visible diagram area represents all mathematically possible values. Note that the further you go from the center, the less likely they will become, with the area close to the border being extremely unlikely.</p>
|
||||||
|
|
||||||
<p>Red dots represent the biome points. Dark green border lines represent the boundaries of Voronoi cells and the large colored areas represent the biomes themselves.</p>
|
<p>In “<b>biome points</b>” mode, the default value range of heat and humidity is from −37.5 to 137.5, with 50 as the midpoint. As a rule of thumb, most values will be somewhere between 0 and 100 by default.</p>
|
||||||
|
|
||||||
<p>By default, a grid is displayed. A grid line is shown for every 10 units (unless the value range of heat or humidity is very large).</p>
|
<p>In “<b>v6 biomes</b>” mode, the default value range is smaller. The value range may be changed by the noise parameters (which will be explained later).</p>
|
||||||
|
|
||||||
<p>Below the diagram, a couple of status information is shown: The current altitude (Y coordinate), the heat and humidity range of the current diagram and your cursor position (if it is on the diagram).</p>
|
<p>Red dots represent the <b>biome points</b> (only in “biome points” mode), and they are labelled by their name. Dark green border lines represent the boundaries of Voronoi cells and the large colored areas represent the biomes themselves.</p>
|
||||||
|
|
||||||
|
<p>By default, a <b>grid</b> is displayed. A grid line is shown for every 10 units in “biome points” mode and 0.1 units in “v6 biomes” mode. Note: The grid lines may disappear if there would be too many of them.</p>
|
||||||
|
|
||||||
|
<p>Below the diagram, a couple of <b>status information</b> is shown: The current altitude (Y coordinate), the heat and humidity range of the current diagram and your cursor position (if it is on the diagram).</p>
|
||||||
|
|
||||||
<h3>An example</h3>
|
<h3>An example</h3>
|
||||||
<p>Let’s say there are 2 biomes at the (heat, humidity) coordinates (10, 10) and (90, 90). This will divide the diagram in 2 sections. Each of these sections is a Voronoi cell, or the set of all (heat, humidity) value pairs of that biome. Let’s look what happens at position heat=0, humidity=0. If you read the diagram, you will see it belongs to the first biome. This means that whenever a world position has a heat of 0 and humidity of 0, that biome will be used. Now at heat=70, humidity=50, we can read it belongs to the second biome. And this is how you can understand this diagram.</p>
|
<p>Let’s say in the “biome points” mode there are 2 biomes at the (heat, humidity) coordinates (10, 10) and (90, 90). This will divide the diagram in 2 sections. Each of these sections is a Voronoi cell, or the set of all (heat, humidity) value pairs of that biome.</p>
|
||||||
|
|
||||||
|
<p>Let’s look what happens at position heat=0, humidity=0. If you read the diagram, you will see it belongs to the first biome. This means that whenever a world position has a heat of 0 and humidity of 0, that biome will be used. Now at heat=70, humidity=50, we can read it belongs to the second biome. And this is how you can understand this diagram.</p>
|
||||||
|
|
||||||
<h2>Usage</h2>
|
<h2>Usage</h2>
|
||||||
<p>This section explains how you can interact with the various parts of the program.</p>
|
<p>This section explains how you can interact with the various parts of the program.</p>
|
||||||
|
|
||||||
<p>The interactive sections have a header with an arrow symbol at the beginning. Click on this arrow to collapse or extend a section.</p>
|
<p>The interactive sections have a header with an arrow symbol at the beginning. Click on this arrow to collapse or extend a section.</p>
|
||||||
|
|
||||||
|
<h3>Biome modes</h3>
|
||||||
|
<p>Above the diagram, there are two buttons: “Biome points” and “v6 biomes”. These are the <b>biome modes</b>. Click on one of these buttons to change the biome mode. This affects the entire program.</p>
|
||||||
|
|
||||||
|
<p>In “<b>biome points</b>” mode, you can add, see and visualize heat and humidity points as well as the biome area on a diagram. This is the default mode. Biome points are used in all Minetest map generators except v6.</p>
|
||||||
|
|
||||||
|
<p>The “<b>v6 biomes</b>” mode displays the biomes of the v6 mapgen. The v6 biomes work completely differently and are hardcoded because this mapgen is very old. There are no biome points and your options to configure them are limited to a few settings only. You can’t add custom biomes here.</p>
|
||||||
|
|
||||||
<h3>Diagram</h3>
|
<h3>Diagram</h3>
|
||||||
<p>Hover with the mouse cursor over the diagram to see the heat and humidity coordinates at this position.</p>
|
<p>Hover with the mouse cursor over the diagram to see the heat and humidity coordinates at this position.</p>
|
||||||
|
|
||||||
<p>You can click on a dot to select it, click on it again and hold down the mouse button to drag it. You can add a new point by double-clicking on the diagram, provided a click wouldn’t select an already selected point.</p>
|
<p>When you hover the diagram, a small <b>grabbing widget</b> will appear in the bottom right corner. You can use this to <b>resize</b> the whole diagram. Hold down Shift while resizing to preserve the aspect ratio.</p>
|
||||||
|
|
||||||
<p>When you hover the diagram, a small grabbing widget will apper in the bottom left corner. You can use this to resize the whole diagram. Hold down Shift while resizing to preserve the aspect ratio.</p>
|
<p>In “Biome points” mode, you can click on a point to <b>select</b> it, click on it again and hold down the mouse button to <b>drag</b> it. You can add a new point by <b>double-clicking</b> on the diagram, provided a click wouldn’t select an already selected point.</p>
|
||||||
|
|
||||||
<h3>Biome configuration</h3>
|
<h3>Biome configuration</h3>
|
||||||
|
<p>You can configure the biomes here. This section differs on the selected biome mode.</p>
|
||||||
|
|
||||||
|
<h4>“Biome points” mode</h4>
|
||||||
<p>Here you can see a list of all currently active biomes. Each biome has a name of your choice. The program always starts with a default biome at (50, 50). Select a biome in the list so you can edit it.</p>
|
<p>Here you can see a list of all currently active biomes. Each biome has a name of your choice. The program always starts with a default biome at (50, 50). Select a biome in the list so you can edit it.</p>
|
||||||
|
|
||||||
<p>The “Add” button adds a new biome with a random heat and humidity. “Remove” removes the currently selected biome.</p>
|
<p>The “Add” button adds a new biome with a random heat and humidity. “Remove” removes the currently selected biome.</p>
|
||||||
|
|
||||||
<p>Once you selected a biome in the list, the fields in “Selected biome” will activate. Here, you can edit the selected biome’s heat and humidity point (corresponds to <code>heat_point</code> and <code>humidity_point</code> in the Lua API). You can also edit the minimum and maximum Y level this biome will be generated in (corresponds to <code>y_min</code> and <code>y_max</code>).</p>
|
<p>Once you’ve selected a biome in the list, the fields in “Selected biome” will activate. Here, you can <b>edit</b> the selected biome’s heat and humidity point (corresponds to <code>heat_point</code> and <code>humidity_point</code> in the Lua API). You can also edit the <b>minimum and maximum Y altitude</b> this biome will be generated in (corresponds to <code>y_min</code> and <code>y_max</code>).</p>
|
||||||
|
|
||||||
<p>Each biome has a name and a color which can be changed, too. These are only used for display purposes and don’t affect the calculations.</p>
|
<p>Each biome has a <b>name</b> and a <b>color</b> which can be changed, too. These are only used for display purposes and don’t affect the calculations.</p>
|
||||||
|
|
||||||
<p>Changing a value in any of these fields will immediately take effect.</p>
|
<p>Changing a value in any of these fields will immediately take effect.</p>
|
||||||
|
|
||||||
|
<h4>“v6 biomes” mode</h4>
|
||||||
|
<p>In this mode you can configure a few settings of the v6 biomes. The “Flags” sections changes the v6-specific mapgen flags (on/off settings) and corresponds to the Minetest setting <code>mgv6_spflags</code>. The Desert noise threshold corresponds to <code>mgv6_freq_desert</code>.</p>
|
||||||
|
|
||||||
|
<p>These settings can be changed:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>snowbiomes</b>: Activates the 5-biome system which introduces tundra and taiga. This will also force-enable jungles.</li>
|
||||||
|
<li><b>jungles</b>: Activates the jungle biome. This is only available if snowbiomes are disabled. Otherwise, jungles are force-enabled.</li>
|
||||||
|
<li><b>Desert noise threshold</b> (<code>mgv6_freq_desert</code>): Deserts will generate if the heat is above this value. This is only available if snowbiomes is off. If snowbiomes is on, the desert heat is fixed.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>You can’t add any custom biomes.</p>
|
||||||
|
|
||||||
<h3>Diagram view settings</h3>
|
<h3>Diagram view settings</h3>
|
||||||
<p>These settings only affect the visual representation and not the data. The checkboxes can be used to hide several things in the diagram, like the grid. The altitude setting changes at which altitude (Y coordinate) the diagram “looks” at. The diagram will only show biomes that would generate in this altitude, applying the biome’s Min. Y and Max. Y settings.</p>
|
<p>These settings only affect the <b>visual representation</b> and not the data. The checkboxes can be used to hide several things in the diagram, like the grid. The altitude setting changes at which altitude (Y world coordinate) the diagram “looks” at. The diagram will only show biomes that would generate in this altitude, applying the biome’s Min. Y and Max. Y settings.</p>
|
||||||
|
|
||||||
|
<p>In “v6 biomes” mode, the Y altitude has no effect.</p>
|
||||||
|
|
||||||
<p>Note: If you hide the points, you can no longer select them in the diagram. You can still select them in the biome list, however.</p>
|
<p>Note: If you hide the points, you can no longer select them in the diagram. You can still select them in the biome list, however.</p>
|
||||||
|
|
||||||
<h3>Noise parameters</h3>
|
<h3>Noise parameters</h3>
|
||||||
<p>This is fairly advanced and most games don’t use this. You can use this if you want to see what happens if you use non-default heat and/or humidity Perlin noise parameters. This corresponds to the Minetest settings <code>mg_biome_np_heat</code> and <code>mg_biome_np_humidity</code>. The explanation of Perlin noises is out of scope for this document. See the Minetest Lua API documentation.</p>
|
<p>This is fairly advanced and most games don’t modify this. You can experiment with this if you want to see what happens if you use non-default heat and/or humidity Perlin noise parameters. The parenthesis if the Heat and Humidity sections show the name of the setting the noise parameters correspond to. The noise setting names depend on the current biome mode. The explanation of Perlin noises is out of scope for this document. See the Minetest Lua API documentation.</p>
|
||||||
|
|
||||||
<p>Changing the noise parameters has an effect on the possible value range for heat and humidity which is why this has been included. This also means the recommendation that you try to keep biomes between a heat/humidity roughly between 0 and 100 goes out of the window; you have to figure out a good range yourselves.</p>
|
<p>Changing the noise parameters has an <b>effect on the possible value range</b> for heat and humidity which has an effect on the probability of all biomes.</p>
|
||||||
|
|
||||||
<p>If your game or mod does not modify these noise parameters, you can ignore this section and leave it at default. Click on “Reset noise parameters” to reset them to the default if you accidentally changed them.</p>
|
<p>If your game or mod does not modify these noise parameters, you can ignore this section and leave it at default. Click on “<b>Reset noise parameters</b>” to reset them to the default if you accidentally changed them.</p>
|
||||||
|
|
||||||
|
<p>This section works mostly the same in both biome modes. But in “v6 biomes” mode, the humidity can never exceed 0.0 and 1.0. This is why you might not immediately see a change when you change the humidity noise in this mode.</p>
|
||||||
|
|
||||||
<h3>Import</h3>
|
<h3>Import</h3>
|
||||||
<p>This allows you to import biomes from JSON text that has been exported before (see below). If you have a JSON text, just paste it in the text box and press “Import”. This will replace all biomes. A message below the text box will tell you if the import has succeeded or failed. If the import has failed, nothing will happen.</p>
|
<p>This is only available in “Biome points” mode.</p>
|
||||||
|
|
||||||
|
<p>This allows you to <b>import biomes</b> from <b>JSON</b> text that has been exported before (see below). If you have a JSON text, just paste it in the text box and press “Import”. <b>This will replace all biomes.</b> A message below the text box will tell you if the import has succeeded or failed. If the import has failed, nothing will happen.</p>
|
||||||
|
|
||||||
<h3>Export</h3>
|
<h3>Export</h3>
|
||||||
<p>This allows you to export the current biomes into a text. You can choose to export them either to Lua code or JSON. The export only includes the basic biome info but not stuff like biome color (which is only relevant for MiBPoV) or noise parameters.</p>
|
<p>This is only available in “Biome points” mode.</p>
|
||||||
|
|
||||||
<p>The <i>Lua</i> export gives you a very basic Lua code that can be pasted into an actual Lua mod. The code is very basic and does not include the “landscape materials”, like what the surface is made of (dirt, stone, sand, etc.).</p>
|
<p>This allows you to export the current biomes into a text. You can choose to export them in one of various formats. Only biome information is included, not the display settings or noise parameters.</p>
|
||||||
|
|
||||||
<p>The <i>JSON</i> export is a text you can use to import later. You could save this in a text file so you can import it later.</p>
|
<p>The <b>Lua</b> export gives you a very basic Lua code that can be pasted into an actual Lua mod. The code is very basic and does not include the “landscape materials”, like what the surface is made of (dirt, stone, sand, etc.).</p>
|
||||||
|
|
||||||
<p>The <i>Amidst for Minetest</i> export gives you a biome profile you can use for <a href="https://github.com/Treer/Amidst-for-Minetest">Amidst for Minetest</a>.</p>
|
<p>The <b>JSON</b> export is a text you can use to import the biomes in MiBPoV later. You may want to copy this into a text file.</p>
|
||||||
|
|
||||||
<p>The “Clear” button clears the previous export. This is just there to reduce clutter on the webpage.</p>
|
<p>The <b>Amidst for Minetest</b> export gives you a biome profile you can use for <a href="https://github.com/Treer/Amidst-for-Minetest">Amidst for Minetest</a>.</p>
|
||||||
|
|
||||||
|
<p>The “<b>Clear</b>” button clears the previous export.</p>
|
||||||
|
|
||||||
<h2>Caveats / Limitations</h2>
|
<h2>Caveats / Limitations</h2>
|
||||||
<p>It is perfectly legal to have the biome points to be out of the bounds of the diagram. These out-of-bounds points are represented as arrows in the diagram. However, you can’t select them with your mouse on the diagram unless it’s close to the edge. Use the biome list to edit points that are out of bounds.</p>
|
<p>In “biome points” mode, it is perfectly <b>legal</b> to have the biome points to be <b>out of the bounds</b> of the diagram. These out-of-bounds points are represented as arrows in the diagram. However, you can’t select them with your mouse on the diagram unless it’s close to the edge. Use the biome list to edit points that are out of bounds.</p>
|
||||||
|
|
||||||
<p>Heat/humidity values above 1,000,000 or below −1,000,000 are not supported and will trigger an error message. This is a much smaller range than what Minetest supports. Also, no diagram can be drawn if the heat or humidity noise scale equals 0 or is very small, although this is legal in Minetest. This does not mean that your chosen settings won’t work in Minetest, just that MiBPoV can’t visualize them.</p>
|
<p>Heat/humidity <b>values above 1,000,000 or below −1,000,000</b> are <b>not supported</b> and will trigger an error message. This is a much smaller range than what Minetest supports. Also, no diagram can be drawn if the heat or humidity noise scale equals 0 or is very small, although this is legal in Minetest. This does not mean that your chosen settings won’t work in Minetest, just that MiBPoV can’t visualize them.</p>
|
||||||
|
|
||||||
<p>MiBPoV does not visualizes the biomes of the v6 mapgen. This mapgen is special because it uses a completely different biome system.</p>
|
|
||||||
|
|
||||||
<p>MiBPoV assumes that the <code>absvalue</code> flag of the heat/humidity noises is always <code>false</code>. So if your game/mod has sets it to true, the diagram may still show a value range that is actually impossible.</p>
|
<p>MiBPoV assumes that the <code>absvalue</code> flag of the heat/humidity noises is always <code>false</code>. So if your game/mod has sets it to true, the diagram may still show a value range that is actually impossible.</p>
|
||||||
|
|
||||||
<h2>Credits / License</h2>
|
<h2>Credits / License</h2>
|
||||||
<p>This tool is free software. See the <a href="./license.html">License</a> page for details.</p>
|
<p>MiBPoV is <b>free software</b>. See the <a href="./license.html">License</a> page for details.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
517
mibpov.js
517
mibpov.js
@ -6,6 +6,7 @@ const MAX_Y_DEFAULT = 31000
|
|||||||
|
|
||||||
// Draw a grid line every GRID_STEP units
|
// Draw a grid line every GRID_STEP units
|
||||||
const GRID_STEP = 10
|
const GRID_STEP = 10
|
||||||
|
const GRID_STEP_V6 = 0.1
|
||||||
|
|
||||||
// Size of the resizing corner
|
// Size of the resizing corner
|
||||||
const RESIZE_CORNER = 14;
|
const RESIZE_CORNER = 14;
|
||||||
@ -90,10 +91,28 @@ const CELL_COLORS = [
|
|||||||
"#836299",
|
"#836299",
|
||||||
];
|
];
|
||||||
const CELL_COLOR_NEUTRAL = "#888888";
|
const CELL_COLOR_NEUTRAL = "#888888";
|
||||||
const COLOR_BUTTON_BORDER_SELECTED = "#FF0000";
|
|
||||||
|
// Mapgen v6 "cell" colors
|
||||||
|
const CELL_COLOR_V6_NORMAL = "#6b7f5c";
|
||||||
|
const CELL_COLOR_V6_JUNGLE = "#345644";
|
||||||
|
const CELL_COLOR_V6_DESERT = "#a7822c";
|
||||||
|
const CELL_COLOR_V6_TAIGA = "#548583";
|
||||||
|
const CELL_COLOR_V6_TUNDRA = "#6371b4";
|
||||||
|
|
||||||
|
// Mapgen v6 biome thresholds
|
||||||
|
const MGV6_FREQ_HOT = 0.4
|
||||||
|
const MGV6_FREQ_SNOW = -0.4
|
||||||
|
const MGV6_FREQ_TAIGA = 0.5
|
||||||
|
const MGV6_FREQ_JUNGLE = 0.5
|
||||||
|
|
||||||
/* Status variables for the diagram calculations */
|
/* Status variables for the diagram calculations */
|
||||||
|
|
||||||
|
// The current biome mode; which type of biome system
|
||||||
|
// the program will use.
|
||||||
|
// * "modern": The modern biome system, as used by mapgen v7 and many more
|
||||||
|
// * "v6": The biome system of mapgen v6
|
||||||
|
let biomeMode = "modern";
|
||||||
|
|
||||||
// Min. and max. mathematically possible values for heat and humidity
|
// Min. and max. mathematically possible values for heat and humidity
|
||||||
let limit_heat_min, limit_heat_max;
|
let limit_heat_min, limit_heat_max;
|
||||||
let limit_humidity_min, limit_humidity_max;
|
let limit_humidity_min, limit_humidity_max;
|
||||||
@ -110,6 +129,10 @@ let midpoint_humidity;
|
|||||||
// Y altitude at which the diagram is currently viewed at
|
// Y altitude at which the diagram is currently viewed at
|
||||||
let viewY = 0;
|
let viewY = 0;
|
||||||
|
|
||||||
|
let v6_flag_snowbiomes = true;
|
||||||
|
let v6_flag_jungles = true;
|
||||||
|
let v6_freq_desert = 0.45;
|
||||||
|
|
||||||
// Biome noise settings
|
// Biome noise settings
|
||||||
const NOISE_OFFSET_DEFAULT = 50;
|
const NOISE_OFFSET_DEFAULT = 50;
|
||||||
const NOISE_SCALE_DEFAULT = 50;
|
const NOISE_SCALE_DEFAULT = 50;
|
||||||
@ -117,24 +140,52 @@ const NOISE_PERSISTENCE_DEFAULT = 0.5;
|
|||||||
const NOISE_OCTAVES_DEFAULT = 3;
|
const NOISE_OCTAVES_DEFAULT = 3;
|
||||||
const NOISE_ABSVALUE_DEFAULT = false;
|
const NOISE_ABSVALUE_DEFAULT = false;
|
||||||
|
|
||||||
|
const NOISE_V6_HEAT_OFFSET_DEFAULT = 0;
|
||||||
|
const NOISE_V6_HEAT_SCALE_DEFAULT = 1;
|
||||||
|
const NOISE_V6_HEAT_PERSISTENCE_DEFAULT = 0.5;
|
||||||
|
const NOISE_V6_HEAT_OCTAVES_DEFAULT = 3;
|
||||||
|
const NOISE_V6_HEAT_ABSVALUE_DEFAULT = false;
|
||||||
|
|
||||||
|
const NOISE_V6_HUMIDITY_OFFSET_DEFAULT = 0.5;
|
||||||
|
const NOISE_V6_HUMIDITY_SCALE_DEFAULT = 0.5;
|
||||||
|
const NOISE_V6_HUMIDITY_PERSISTENCE_DEFAULT = 0.5;
|
||||||
|
const NOISE_V6_HUMIDITY_OCTAVES_DEFAULT = 3;
|
||||||
|
const NOISE_V6_HUMIDITY_ABSVALUE_DEFAULT = false;
|
||||||
|
|
||||||
|
|
||||||
// Current noise values
|
// Current noise values
|
||||||
let noises = {
|
let noises = {
|
||||||
heat: {
|
heat_modern: {
|
||||||
offset: NOISE_OFFSET_DEFAULT,
|
offset: NOISE_OFFSET_DEFAULT,
|
||||||
scale: NOISE_SCALE_DEFAULT,
|
scale: NOISE_SCALE_DEFAULT,
|
||||||
octaves: NOISE_OCTAVES_DEFAULT,
|
octaves: NOISE_OCTAVES_DEFAULT,
|
||||||
persistence: NOISE_PERSISTENCE_DEFAULT,
|
persistence: NOISE_PERSISTENCE_DEFAULT,
|
||||||
absvalue: NOISE_ABSVALUE_DEFAULT,
|
absvalue: NOISE_ABSVALUE_DEFAULT,
|
||||||
},
|
},
|
||||||
humidity: {
|
humidity_modern: {
|
||||||
offset: NOISE_OFFSET_DEFAULT,
|
offset: NOISE_OFFSET_DEFAULT,
|
||||||
scale: NOISE_SCALE_DEFAULT,
|
scale: NOISE_SCALE_DEFAULT,
|
||||||
octaves: NOISE_OCTAVES_DEFAULT,
|
octaves: NOISE_OCTAVES_DEFAULT,
|
||||||
persistence: NOISE_PERSISTENCE_DEFAULT,
|
persistence: NOISE_PERSISTENCE_DEFAULT,
|
||||||
absvalue: NOISE_ABSVALUE_DEFAULT,
|
absvalue: NOISE_ABSVALUE_DEFAULT,
|
||||||
},
|
},
|
||||||
|
heat_v6: {
|
||||||
|
offset: NOISE_V6_HEAT_OFFSET_DEFAULT,
|
||||||
|
scale: NOISE_V6_HEAT_SCALE_DEFAULT,
|
||||||
|
octaves: NOISE_V6_HEAT_OCTAVES_DEFAULT,
|
||||||
|
persistence: NOISE_V6_HEAT_PERSISTENCE_DEFAULT,
|
||||||
|
absvalue: NOISE_V6_HEAT_ABSVALUE_DEFAULT,
|
||||||
|
},
|
||||||
|
humidity_v6: {
|
||||||
|
offset: NOISE_V6_HUMIDITY_OFFSET_DEFAULT,
|
||||||
|
scale: NOISE_V6_HUMIDITY_SCALE_DEFAULT,
|
||||||
|
octaves: NOISE_V6_HUMIDITY_OCTAVES_DEFAULT,
|
||||||
|
persistence: NOISE_V6_HUMIDITY_PERSISTENCE_DEFAULT,
|
||||||
|
absvalue: NOISE_V6_HUMIDITY_ABSVALUE_DEFAULT,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
noises.heat = noises.heat_modern;
|
||||||
|
noises.humidity = noises.humidity_modern;
|
||||||
|
|
||||||
function updateAreaVarsFor(noiseType) {
|
function updateAreaVarsFor(noiseType) {
|
||||||
let noise = noises[noiseType];
|
let noise = noises[noiseType];
|
||||||
@ -181,6 +232,11 @@ function updateAreaVarsFor(noiseType) {
|
|||||||
if (min_value > max_value) {
|
if (min_value > max_value) {
|
||||||
[min_value, max_value] = [max_value, min_value]
|
[min_value, max_value] = [max_value, min_value]
|
||||||
}
|
}
|
||||||
|
// v6 humidity is forcefully clamped at 0 and 1
|
||||||
|
if (biomeMode === "v6" && noiseType == "humidity") {
|
||||||
|
min_value = Math.max(0.0, min_value);
|
||||||
|
max_value = Math.min(1.0, max_value);
|
||||||
|
}
|
||||||
|
|
||||||
// Update globals
|
// Update globals
|
||||||
let limit_min = min_value;
|
let limit_min = min_value;
|
||||||
@ -442,7 +498,7 @@ function putPoint(context, point) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Put the grid on the draw context */
|
/* Put the grid on the draw context */
|
||||||
function putGrid(context) {
|
function putGrid(context, gridStep) {
|
||||||
let [limit_x_min, limit_y_min] = biomeCoordsToCanvasPixelCoords(limit_heat_min, limit_humidity_min);
|
let [limit_x_min, limit_y_min] = biomeCoordsToCanvasPixelCoords(limit_heat_min, limit_humidity_min);
|
||||||
let [limit_x_max, limit_y_max] = biomeCoordsToCanvasPixelCoords(limit_heat_max, limit_humidity_max);
|
let [limit_x_max, limit_y_max] = biomeCoordsToCanvasPixelCoords(limit_heat_max, limit_humidity_max);
|
||||||
|
|
||||||
@ -457,8 +513,8 @@ function putGrid(context) {
|
|||||||
// on the canvas.
|
// on the canvas.
|
||||||
// This code will effectively trigger if the value range
|
// This code will effectively trigger if the value range
|
||||||
// is very high.
|
// is very high.
|
||||||
let xGridLinesPerPixel = (limit_heat_max-limit_heat_min) / voronoiCanvas.width / GRID_STEP;
|
let xGridLinesPerPixel = (limit_heat_max-limit_heat_min) / voronoiCanvas.width / gridStep;
|
||||||
let yGridLinesPerPixel = (limit_humidity_max-limit_humidity_min) / voronoiCanvas.height/ GRID_STEP;
|
let yGridLinesPerPixel = (limit_humidity_max-limit_humidity_min) / voronoiCanvas.height/ gridStep;
|
||||||
let xWidth = GRID_WIDTH_LEVEL_3;
|
let xWidth = GRID_WIDTH_LEVEL_3;
|
||||||
let yWidth = GRID_WIDTH_LEVEL_3;
|
let yWidth = GRID_WIDTH_LEVEL_3;
|
||||||
if (xGridLinesPerPixel > GRID_THRESHOLD_LEVEL_0) {
|
if (xGridLinesPerPixel > GRID_THRESHOLD_LEVEL_0) {
|
||||||
@ -484,13 +540,13 @@ function putGrid(context) {
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
let x = -xWidth*2;
|
let x = -xWidth*2;
|
||||||
let [heat, _] = canvasPixelCoordsToBiomeCoords(x, 0);
|
let [heat, _] = canvasPixelCoordsToBiomeCoords(x, 0);
|
||||||
heat = heat - (heat % GRID_STEP);
|
heat = heat - (heat % gridStep);
|
||||||
steps = 0;
|
steps = 0;
|
||||||
while (x < voronoiCanvas.width + xWidth*2) {
|
while (x < voronoiCanvas.width + xWidth*2) {
|
||||||
[x, _] = biomeCoordsToCanvasPixelCoords(heat, 0);
|
[x, _] = biomeCoordsToCanvasPixelCoords(heat, 0);
|
||||||
context.moveTo(x, limit_y_min);
|
context.moveTo(x, limit_y_min);
|
||||||
context.lineTo(x, limit_y_max);
|
context.lineTo(x, limit_y_max);
|
||||||
heat += GRID_STEP;
|
heat += gridStep;
|
||||||
steps++;
|
steps++;
|
||||||
if (steps > 10000) {
|
if (steps > 10000) {
|
||||||
console.error("Over 10000 grid lines on the X axis!");
|
console.error("Over 10000 grid lines on the X axis!");
|
||||||
@ -505,13 +561,13 @@ function putGrid(context) {
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
let y = -yWidth*2;
|
let y = -yWidth*2;
|
||||||
let [_, humidity] = canvasPixelCoordsToBiomeCoords(0, y);
|
let [_, humidity] = canvasPixelCoordsToBiomeCoords(0, y);
|
||||||
humidity = humidity - (humidity % GRID_STEP);
|
humidity = humidity - (humidity % gridStep);
|
||||||
steps = 0;
|
steps = 0;
|
||||||
while (y < voronoiCanvas.height + yWidth*2) {
|
while (y < voronoiCanvas.height + yWidth*2) {
|
||||||
[_, y] = biomeCoordsToCanvasPixelCoords(0, humidity);
|
[_, y] = biomeCoordsToCanvasPixelCoords(0, humidity);
|
||||||
context.moveTo(limit_x_min, y);
|
context.moveTo(limit_x_min, y);
|
||||||
context.lineTo(limit_x_max, y);
|
context.lineTo(limit_x_max, y);
|
||||||
humidity -= GRID_STEP;
|
humidity -= gridStep;
|
||||||
steps++;
|
steps++;
|
||||||
if (steps > 10000) {
|
if (steps > 10000) {
|
||||||
console.error("Over 10000 grid lines on the Y axis!");
|
console.error("Over 10000 grid lines on the Y axis!");
|
||||||
@ -538,8 +594,14 @@ function putAxes(context) {
|
|||||||
context.lineWidth = 2;
|
context.lineWidth = 2;
|
||||||
context.strokeStyle = AXIS_COLOR;
|
context.strokeStyle = AXIS_COLOR;
|
||||||
let [x0, y0] = biomeCoordsToCanvasPixelCoords(0, 0);
|
let [x0, y0] = biomeCoordsToCanvasPixelCoords(0, 0);
|
||||||
let tick_heat = (limit_heat_max - limit_heat_min) * (100/175);
|
let tick_heat, tick_humidity;
|
||||||
let tick_humidity = (limit_humidity_max - limit_humidity_min) * (100/175);
|
if (biomeMode === "v6") {
|
||||||
|
tick_heat = 1.0;
|
||||||
|
tick_humidity = 0.5;
|
||||||
|
} else {
|
||||||
|
tick_heat = (limit_heat_max - limit_heat_min) * (100/175);
|
||||||
|
tick_humidity = (limit_humidity_max - limit_humidity_min) * (100/175);
|
||||||
|
}
|
||||||
let [tx, ty] = biomeCoordsToCanvasPixelCoords(tick_heat, tick_humidity);
|
let [tx, ty] = biomeCoordsToCanvasPixelCoords(tick_heat, tick_humidity);
|
||||||
let w = voronoiCanvas.width;
|
let w = voronoiCanvas.width;
|
||||||
let h = voronoiCanvas.height;
|
let h = voronoiCanvas.height;
|
||||||
@ -630,7 +692,13 @@ function putAxes(context) {
|
|||||||
context.fillText("heat", lx, ly);
|
context.fillText("heat", lx, ly);
|
||||||
|
|
||||||
context.textAlign = "center";
|
context.textAlign = "center";
|
||||||
context.fillText(Math.round(tick_heat), tx, tty);
|
let str_tick_heat;
|
||||||
|
if (biomeMode === "v6") {
|
||||||
|
str_tick_heat = tick_heat.toFixed(1);
|
||||||
|
} else {
|
||||||
|
str_tick_heat = tick_heat.toFixed(0);
|
||||||
|
}
|
||||||
|
context.fillText(str_tick_heat, tx, tty);
|
||||||
|
|
||||||
// humidity label
|
// humidity label
|
||||||
context.font = "100% sans-serif";
|
context.font = "100% sans-serif";
|
||||||
@ -657,7 +725,13 @@ function putAxes(context) {
|
|||||||
ttx = x0 - AXIS_ARROW_SIZE-2;
|
ttx = x0 - AXIS_ARROW_SIZE-2;
|
||||||
}
|
}
|
||||||
context.textBaseline = "middle";
|
context.textBaseline = "middle";
|
||||||
context.fillText(Math.round(tick_humidity), ttx, ty);
|
let str_tick_humidity;
|
||||||
|
if (biomeMode === "v6") {
|
||||||
|
str_tick_humidity = tick_humidity.toFixed(1);
|
||||||
|
} else {
|
||||||
|
str_tick_humidity = tick_humidity.toFixed(0);
|
||||||
|
}
|
||||||
|
context.fillText(str_tick_humidity, ttx, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache diagram object for performance boost
|
// Cache diagram object for performance boost
|
||||||
@ -799,18 +873,7 @@ function getSelectedBiomeIDAndElement() {
|
|||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draws the diagram on the voronoiCanvas.
|
function checkDrawValid(context) {
|
||||||
Will (re-)calculate the Voronoi diagram if recalculate is true;
|
|
||||||
otherwise it may re-use a previous diagram for performance reasons. */
|
|
||||||
function draw(recalculate) {
|
|
||||||
let context = getDrawContext();
|
|
||||||
let w = voronoiCanvas.width;
|
|
||||||
let h = voronoiCanvas.height;
|
|
||||||
let y = getViewY();
|
|
||||||
|
|
||||||
// shorter function name (for "convert")
|
|
||||||
let conv = biomeCoordsToCanvasPixelCoords
|
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
if (!voronoiCanvas.hidden) {
|
if (!voronoiCanvas.hidden) {
|
||||||
voronoiCanvas.hidden = true;
|
voronoiCanvas.hidden = true;
|
||||||
@ -824,7 +887,6 @@ function draw(recalculate) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
clear(context);
|
|
||||||
|
|
||||||
let showDiagramMessage = function(context, text) {
|
let showDiagramMessage = function(context, text) {
|
||||||
context.textAlign = "center";
|
context.textAlign = "center";
|
||||||
@ -846,7 +908,7 @@ function draw(recalculate) {
|
|||||||
showDiagramMessage(context, "Value range is too small.");
|
showDiagramMessage(context, "Value range is too small.");
|
||||||
drawError = true;
|
drawError = true;
|
||||||
putResizeCorner(context);
|
putResizeCorner(context);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail and render a special message if the value range is huge
|
// Fail and render a special message if the value range is huge
|
||||||
@ -854,7 +916,7 @@ function draw(recalculate) {
|
|||||||
showDiagramMessage(context, "Value range is too large.");
|
showDiagramMessage(context, "Value range is too large.");
|
||||||
drawError = true;
|
drawError = true;
|
||||||
putResizeCorner(context);
|
putResizeCorner(context);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail and render a special message if value limit is out of permissible bounds
|
// Fail and render a special message if value limit is out of permissible bounds
|
||||||
@ -862,15 +924,35 @@ function draw(recalculate) {
|
|||||||
showDiagramMessage(context, "Maximum value is too large.");
|
showDiagramMessage(context, "Maximum value is too large.");
|
||||||
drawError = true;
|
drawError = true;
|
||||||
putResizeCorner(context);
|
putResizeCorner(context);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if ((limit_heat_min < MIN_HEAT_HUMIDITY_VALUE) || (limit_humidity_min < MIN_HEAT_HUMIDITY_VALUE)) {
|
if ((limit_heat_min < MIN_HEAT_HUMIDITY_VALUE) || (limit_humidity_min < MIN_HEAT_HUMIDITY_VALUE)) {
|
||||||
showDiagramMessage(context, "Minimum value is too small.");
|
showDiagramMessage(context, "Minimum value is too small.");
|
||||||
drawError = true;
|
drawError = true;
|
||||||
putResizeCorner(context);
|
putResizeCorner(context);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
drawError = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draws the diagram on the voronoiCanvas.
|
||||||
|
Will (re-)calculate the Voronoi diagram if recalculate is true;
|
||||||
|
otherwise it may re-use a previous diagram for performance reasons. */
|
||||||
|
function drawModern(recalculate) {
|
||||||
|
let context = getDrawContext();
|
||||||
|
let w = voronoiCanvas.width;
|
||||||
|
let h = voronoiCanvas.height;
|
||||||
|
let y = getViewY();
|
||||||
|
|
||||||
|
// shorter function name (for "convert")
|
||||||
|
let conv = biomeCoordsToCanvasPixelCoords
|
||||||
|
|
||||||
|
clear(context);
|
||||||
|
if (!checkDrawValid(context)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let points = getRenderedPoints(y);
|
let points = getRenderedPoints(y);
|
||||||
// Fail and render a special message if there are no biomes
|
// Fail and render a special message if there are no biomes
|
||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
@ -881,7 +963,7 @@ function draw(recalculate) {
|
|||||||
}
|
}
|
||||||
drawError = true;
|
drawError = true;
|
||||||
putResizeCorner(context);
|
putResizeCorner(context);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAltitudeText();
|
updateAltitudeText();
|
||||||
@ -897,7 +979,7 @@ function draw(recalculate) {
|
|||||||
if (!diagram) {
|
if (!diagram) {
|
||||||
voronoiError();
|
voronoiError();
|
||||||
drawError = true;
|
drawError = true;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
drawError = false;
|
drawError = false;
|
||||||
|
|
||||||
@ -996,7 +1078,7 @@ function draw(recalculate) {
|
|||||||
|
|
||||||
if (points.length > 0) {
|
if (points.length > 0) {
|
||||||
if (showGrid) {
|
if (showGrid) {
|
||||||
putGrid(context);
|
putGrid(context, GRID_STEP);
|
||||||
}
|
}
|
||||||
if (showAxes) {
|
if (showAxes) {
|
||||||
putAxes(context);
|
putAxes(context);
|
||||||
@ -1055,6 +1137,227 @@ function draw(recalculate) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drawV6() {
|
||||||
|
let context = getDrawContext();
|
||||||
|
let w = voronoiCanvas.width;
|
||||||
|
let h = voronoiCanvas.height;
|
||||||
|
let y = getViewY();
|
||||||
|
|
||||||
|
clear(context);
|
||||||
|
if (!checkDrawValid(context)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
|
||||||
|
let cx, cy;
|
||||||
|
|
||||||
|
// Calculate biome intersection coordinates
|
||||||
|
|
||||||
|
let cx_snow, cx_hot, cx_snow2, cy_snow2, cx_hot2, cy_hot2;
|
||||||
|
let _; // unused variable
|
||||||
|
|
||||||
|
let freq_jungle, freq_hot;
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
freq_jungle = MGV6_FREQ_JUNGLE;
|
||||||
|
freq_hot = MGV6_FREQ_HOT;
|
||||||
|
// Temperate <-> Taiga/Tundra
|
||||||
|
[cx_snow, _] = biomeCoordsToCanvasPixelCoords(MGV6_FREQ_SNOW, 0);
|
||||||
|
// Temperate <-> Desert/Jungle
|
||||||
|
[cx_hot, _] = biomeCoordsToCanvasPixelCoords(freq_hot, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Temperate <-> Desert/Jungle
|
||||||
|
freq_hot = v6_freq_desert;
|
||||||
|
[cx_hot, _] = biomeCoordsToCanvasPixelCoords(freq_hot, 0);
|
||||||
|
freq_jungle = 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taiga <-> Tundra <-> Temperate
|
||||||
|
[cx_snow2, cy_snow2] = biomeCoordsToCanvasPixelCoords(MGV6_FREQ_SNOW, MGV6_FREQ_TAIGA);
|
||||||
|
// Desert <-> Jungle <-> Temperate
|
||||||
|
[cx_hot2, cy_hot2] = biomeCoordsToCanvasPixelCoords(freq_hot, freq_jungle);
|
||||||
|
|
||||||
|
if (showCellColors) {
|
||||||
|
// Render biome areas
|
||||||
|
context.fillStyle = CELL_COLOR_V6_NORMAL;
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
// Temperate
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(cx_snow, 0);
|
||||||
|
context.lineTo(cx_snow, h);
|
||||||
|
context.lineTo(cx_hot, h);
|
||||||
|
context.lineTo(cx_hot, 0);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
// Tundra
|
||||||
|
context.fillStyle = CELL_COLOR_V6_TUNDRA;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(0, 0);
|
||||||
|
context.lineTo(cx_snow2, 0);
|
||||||
|
context.lineTo(cx_snow2, cy_snow2);
|
||||||
|
context.lineTo(0, cy_snow2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
// Taiga
|
||||||
|
context.fillStyle = CELL_COLOR_V6_TAIGA;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(cx_snow2, cy_snow2);
|
||||||
|
context.lineTo(cx_snow2, h);
|
||||||
|
context.lineTo(0, h);
|
||||||
|
context.lineTo(0, cy_snow2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
// Jungle
|
||||||
|
context.fillStyle = CELL_COLOR_V6_JUNGLE;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(w, 0);
|
||||||
|
context.lineTo(cx_hot2, 0);
|
||||||
|
context.lineTo(cx_hot2, cy_hot2);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
// Desert
|
||||||
|
context.fillStyle = CELL_COLOR_V6_DESERT;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(cx_hot2, cy_hot2);
|
||||||
|
context.lineTo(cx_hot2, h);
|
||||||
|
context.lineTo(w, h);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
} else {
|
||||||
|
// Temperate
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(0, 0);
|
||||||
|
context.lineTo(0, h);
|
||||||
|
context.lineTo(cx_hot, h);
|
||||||
|
context.lineTo(cx_hot, 0);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
if (v6_flag_jungles) {
|
||||||
|
// Jungle
|
||||||
|
context.fillStyle = CELL_COLOR_V6_JUNGLE;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(0, 0);
|
||||||
|
context.lineTo(w, 0);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
context.lineTo(0, cy_hot2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
// Desert
|
||||||
|
context.fillStyle = CELL_COLOR_V6_DESERT;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(cx_hot2, cy_hot2);
|
||||||
|
context.lineTo(cx_hot2, h);
|
||||||
|
context.lineTo(w, h);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
} else {
|
||||||
|
// Desert
|
||||||
|
context.fillStyle = CELL_COLOR_V6_DESERT;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(cx_hot2, 0);
|
||||||
|
context.lineTo(cx_hot2, h);
|
||||||
|
context.lineTo(w, h);
|
||||||
|
context.lineTo(w, 0);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use a "neutral" background color for the whole area if cell colors are disabled
|
||||||
|
context.fillStyle = CELL_COLOR_NEUTRAL;
|
||||||
|
context.fillRect(-DRAW_OFFSET, -DRAW_OFFSET, w+DRAW_OFFSET, h+DRAW_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render biome borders
|
||||||
|
context.lineWidth = 2.5;
|
||||||
|
context.strokeStyle = EDGE_COLOR;
|
||||||
|
context.beginPath();
|
||||||
|
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
// Temperate <-> Taiga/Tundra
|
||||||
|
context.moveTo(cx_snow, 0);
|
||||||
|
context.lineTo(cx_snow, h);
|
||||||
|
// Taiga <-> Tundra
|
||||||
|
context.moveTo(cx_snow2, cy_snow2);
|
||||||
|
context.lineTo(0, cy_snow2);
|
||||||
|
}
|
||||||
|
// Temperate <-> Desert/Jungle
|
||||||
|
if (v6_flag_snowbiomes || (!v6_flag_jungles)) {
|
||||||
|
context.moveTo(cx_hot, 0);
|
||||||
|
context.lineTo(cx_hot, h);
|
||||||
|
} else {
|
||||||
|
context.moveTo(cx_hot, cy_hot2);
|
||||||
|
context.lineTo(cx_hot, h);
|
||||||
|
}
|
||||||
|
// Desert <-> Jungle
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
context.moveTo(cx_hot2, cy_hot2);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
} else if (v6_flag_jungles) {
|
||||||
|
context.moveTo(0, cy_hot2);
|
||||||
|
context.lineTo(w, cy_hot2);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.closePath();
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
if (showGrid) {
|
||||||
|
putGrid(context, GRID_STEP_V6);
|
||||||
|
}
|
||||||
|
if (showAxes) {
|
||||||
|
putAxes(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Biome names
|
||||||
|
if (showNames) {
|
||||||
|
context.font = "120% sans-serif";
|
||||||
|
context.fillStyle = "#FFFFFFBB";
|
||||||
|
context.textAlign = "center";
|
||||||
|
context.textBaseline = "middle";
|
||||||
|
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
context.fillText("Taiga", cx_snow/2, cy_snow2/2);
|
||||||
|
context.fillText("Tundra", cx_snow/2, cy_snow2+((h-cy_snow2)/2));
|
||||||
|
context.fillText("Jungle", cx_hot + (w-cx_hot)/2, cy_hot2/2);
|
||||||
|
} else if (v6_flag_jungles) {
|
||||||
|
context.fillText("Jungle", cx_hot + (w-cx_hot)/2, cy_hot2/2);
|
||||||
|
}
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
context.fillText("Desert", cx_hot + (w-cx_hot)/2, cy_hot2+((h-cy_hot2)/2));
|
||||||
|
} else {
|
||||||
|
if (v6_flag_jungles) {
|
||||||
|
context.fillText("Desert", cx_hot + (w-cx_hot)/2, cy_hot2+((h-cy_hot2)/2));
|
||||||
|
} else {
|
||||||
|
context.fillText("Desert", cx_hot + (w-cx_hot)/2, h/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
context.fillText("Normal", cx_snow + (cx_hot-cx_snow)/2, h-h/4);
|
||||||
|
} else {
|
||||||
|
if (v6_flag_jungles) {
|
||||||
|
context.fillText("Normal", cx_hot/2, cy_hot2 + (h-cy_hot2)/2);
|
||||||
|
} else {
|
||||||
|
context.fillText("Normal", cx_hot/2, h/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putResizeCorner(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(recalculate) {
|
||||||
|
if (biomeMode === "v6") {
|
||||||
|
drawV6(recalculate);
|
||||||
|
} else {
|
||||||
|
drawModern(recalculate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Clears the biome list widget and (re-adds) the list elements
|
/* Clears the biome list widget and (re-adds) the list elements
|
||||||
for the biomes from scratch. */
|
for the biomes from scratch. */
|
||||||
function repopulateBiomeSelector() {
|
function repopulateBiomeSelector() {
|
||||||
@ -1127,6 +1430,15 @@ function updateWidgetStates() {
|
|||||||
inputNoiseHumidityScale.value = noises.humidity.scale;
|
inputNoiseHumidityScale.value = noises.humidity.scale;
|
||||||
inputNoiseHumidityOctaves.value = noises.humidity.octaves;
|
inputNoiseHumidityOctaves.value = noises.humidity.octaves;
|
||||||
inputNoiseHumidityPersistence.value = noises.humidity.persistence;
|
inputNoiseHumidityPersistence.value = noises.humidity.persistence;
|
||||||
|
|
||||||
|
if (v6_flag_snowbiomes) {
|
||||||
|
inputV6FreqDesert.disabled = true;
|
||||||
|
inputCheckboxV6Jungles.disabled = true;
|
||||||
|
} else {
|
||||||
|
inputV6FreqDesert.disabled = false;
|
||||||
|
inputCheckboxV6Jungles.disabled = false;
|
||||||
|
}
|
||||||
|
inputV6FreqDesert.value = v6_freq_desert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To be called when a biome value like heat was changed.
|
/* To be called when a biome value like heat was changed.
|
||||||
@ -1184,9 +1496,9 @@ function getDistance(x1, y1, x2, y2) {
|
|||||||
function canvasPixelCoordsToBiomeCoords(x, y) {
|
function canvasPixelCoordsToBiomeCoords(x, y) {
|
||||||
let w = (voronoiCanvas.width/(limit_heat_max-limit_heat_min));
|
let w = (voronoiCanvas.width/(limit_heat_max-limit_heat_min));
|
||||||
let h = (voronoiCanvas.height/(limit_humidity_max-limit_humidity_min));
|
let h = (voronoiCanvas.height/(limit_humidity_max-limit_humidity_min));
|
||||||
let heat = Math.round((x + limit_heat_min * w) / w);
|
let heat = (x + limit_heat_min * w) / w;
|
||||||
// This also flips the Y axis
|
// This also flips the Y axis
|
||||||
let humidity = limit_humidity_min + (limit_humidity_max - (Math.round((y + limit_humidity_min * h) / h)));
|
let humidity = limit_humidity_min + (limit_humidity_max - ((y + limit_humidity_min * h) / h));
|
||||||
return [heat, humidity];
|
return [heat, humidity];
|
||||||
}
|
}
|
||||||
// Converts heat and humidity coordinates to canvas pixel coordinates;
|
// Converts heat and humidity coordinates to canvas pixel coordinates;
|
||||||
@ -1255,15 +1567,15 @@ let dragDropState = 0;
|
|||||||
/* Move and update the biome point while the user
|
/* Move and update the biome point while the user
|
||||||
is dragging it */
|
is dragging it */
|
||||||
function updatePointWhenDragged(pointID) {
|
function updatePointWhenDragged(pointID) {
|
||||||
if (pointID !== null && !drawError) {
|
if (pointID !== null && !drawError && biomeMode === "modern") {
|
||||||
let selectedPoint = null;
|
let selectedPoint = null;
|
||||||
let points = getRenderedPoints(getViewY());
|
let points = getRenderedPoints(getViewY());
|
||||||
for (let i=0; i<points.length; i++) {
|
for (let i=0; i<points.length; i++) {
|
||||||
if (points[i].id === dragDropPointID) {
|
if (points[i].id === dragDropPointID) {
|
||||||
selectedPoint = points[i];
|
selectedPoint = points[i];
|
||||||
let [newHeat, newHumidity] = canvasPixelCoordsToBiomeCoords(event.offsetX, event.offsetY);
|
let [newHeat, newHumidity] = canvasPixelCoordsToBiomeCoords(event.offsetX, event.offsetY);
|
||||||
selectedPoint.heat = newHeat;
|
selectedPoint.heat = Math.round(newHeat);
|
||||||
selectedPoint.humidity = newHumidity;
|
selectedPoint.humidity = Math.round(newHumidity);
|
||||||
draw(true);
|
draw(true);
|
||||||
updateWidgetStates();
|
updateWidgetStates();
|
||||||
let [elemID, elem] = getSelectedBiomeIDAndElement();
|
let [elemID, elem] = getSelectedBiomeIDAndElement();
|
||||||
@ -1297,8 +1609,42 @@ function updateCoordinateDisplay(pixelX, pixelY) {
|
|||||||
}
|
}
|
||||||
// show coordinates
|
// show coordinates
|
||||||
let [heat, humidity] = canvasPixelCoordsToBiomeCoords(pixelX, pixelY);
|
let [heat, humidity] = canvasPixelCoordsToBiomeCoords(pixelX, pixelY);
|
||||||
|
|
||||||
|
let heat_range = limit_heat_max - limit_heat_min;
|
||||||
|
let humidity_range = limit_humidity_max - limit_humidity_min;
|
||||||
|
|
||||||
|
let heat_precision = null;
|
||||||
|
if (heat_range >= 100) {
|
||||||
|
heat_precision = 0;
|
||||||
|
} else if (heat_range >= 10) {
|
||||||
|
heat_precision = 1;
|
||||||
|
} else if (heat_range >= 1) {
|
||||||
|
heat_precision = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let humidity_precision = null;
|
||||||
|
if (humidity_range >= 100) {
|
||||||
|
humidity_precision = 0;
|
||||||
|
} else if (humidity_range >= 10) {
|
||||||
|
humidity_precision = 1;
|
||||||
|
} else if (humidity_range >= 1) {
|
||||||
|
humidity_precision = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let heatStr, humidityStr;
|
||||||
|
if (heat_precision !== null) {
|
||||||
|
heatStr = heat.toFixed(heat_precision);
|
||||||
|
} else {
|
||||||
|
heatStr = +heat;
|
||||||
|
}
|
||||||
|
if (heat_precision !== null) {
|
||||||
|
humidityStr = humidity.toFixed(humidity_precision);
|
||||||
|
} else {
|
||||||
|
humidityStr = +humidity;
|
||||||
|
}
|
||||||
|
|
||||||
if (!drawError) {
|
if (!drawError) {
|
||||||
let html = "cursor coordinates: heat=<span class='statHeat'>"+heat+"</span>; humidity=<span class='statHumidity'>"+humidity+"</span>";
|
let html = "cursor coordinates: heat=<span class='statHeat'>"+heatStr+"</span>; humidity=<span class='statHumidity'>"+humidityStr+"</span>";
|
||||||
coordinateDisplay.innerHTML = html;
|
coordinateDisplay.innerHTML = html;
|
||||||
} else {
|
} else {
|
||||||
coordinateDisplay.innerHTML = " ";
|
coordinateDisplay.innerHTML = " ";
|
||||||
@ -1315,7 +1661,7 @@ function updateCanvasCursorStatus(x, y) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawError || !showPoints) {
|
if (drawError || !showPoints || biomeMode === "v6") {
|
||||||
// a special message is shown; use auto cursor
|
// a special message is shown; use auto cursor
|
||||||
voronoiCanvas.style.cursor = "auto";
|
voronoiCanvas.style.cursor = "auto";
|
||||||
return
|
return
|
||||||
@ -1344,6 +1690,8 @@ function checkboxVarsInit() {
|
|||||||
showCellColors = inputCheckboxCellColors.checked;
|
showCellColors = inputCheckboxCellColors.checked;
|
||||||
showGrid = inputCheckboxGrid.checked;
|
showGrid = inputCheckboxGrid.checked;
|
||||||
showAxes = inputCheckboxAxes.checked;
|
showAxes = inputCheckboxAxes.checked;
|
||||||
|
v6_flag_snowbiomes = inputCheckboxV6Snowbiomes.checked;
|
||||||
|
v6_flag_jungles = inputCheckboxV6Jungles.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collapses/Expands a config section */
|
/* Collapses/Expands a config section */
|
||||||
@ -1509,7 +1857,7 @@ voronoiCanvas.onmousedown = function(event) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawError || !showPoints) {
|
if (drawError || !showPoints || biomeMode === "v6") {
|
||||||
// Points need to be shown for drag-n-drop to work
|
// Points need to be shown for drag-n-drop to work
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1530,7 +1878,7 @@ voronoiCanvas.onmousedown = function(event) {
|
|||||||
}
|
}
|
||||||
voronoiCanvas.ondblclick = function(event) {
|
voronoiCanvas.ondblclick = function(event) {
|
||||||
// Add a biome at double-click position, if possible
|
// Add a biome at double-click position, if possible
|
||||||
if (drawError || dragDropState !== 0) {
|
if (drawError || dragDropState !== 0 || biomeMode === "v6") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// No-op if in selection range
|
// No-op if in selection range
|
||||||
@ -1539,6 +1887,8 @@ voronoiCanvas.ondblclick = function(event) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let [he, hu] = canvasPixelCoordsToBiomeCoords(event.offsetX, event.offsetY);
|
let [he, hu] = canvasPixelCoordsToBiomeCoords(event.offsetX, event.offsetY);
|
||||||
|
he = Math.round(he);
|
||||||
|
hu = Math.round(hu);
|
||||||
addBiome({name: generateBiomeName(lastBiomeID), heat:he, humidity: hu, min_y:MIN_Y_DEFAULT, max_y:MAX_Y_DEFAULT});
|
addBiome({name: generateBiomeName(lastBiomeID), heat:he, humidity: hu, min_y:MIN_Y_DEFAULT, max_y:MAX_Y_DEFAULT});
|
||||||
}
|
}
|
||||||
voronoiCanvas.onmouseup = function(event) {
|
voronoiCanvas.onmouseup = function(event) {
|
||||||
@ -1673,6 +2023,23 @@ inputCheckboxAxes.onchange = function() {
|
|||||||
showAxes = this.checked;
|
showAxes = this.checked;
|
||||||
draw(false);
|
draw(false);
|
||||||
}
|
}
|
||||||
|
inputCheckboxV6Snowbiomes.onchange = function() {
|
||||||
|
v6_flag_snowbiomes = this.checked;
|
||||||
|
updateWidgetStates();
|
||||||
|
draw(false);
|
||||||
|
}
|
||||||
|
inputCheckboxV6Jungles.onchange = function() {
|
||||||
|
v6_flag_jungles = this.checked;
|
||||||
|
draw(false);
|
||||||
|
}
|
||||||
|
inputV6FreqDesert.oninput = function() {
|
||||||
|
let f = +this.value;
|
||||||
|
if (f === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
v6_freq_desert = f;
|
||||||
|
draw(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Noise parameters events */
|
/* Noise parameters events */
|
||||||
|
|
||||||
@ -1711,22 +2078,39 @@ inputNoiseHumidityPersistence.oninput = function() {
|
|||||||
inputNoiseHumidityOctaves.oninput = function() {
|
inputNoiseHumidityOctaves.oninput = function() {
|
||||||
updateNoiseParam("humidity", "octaves", this);
|
updateNoiseParam("humidity", "octaves", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inputNoiseReset.onclick = function() {
|
inputNoiseReset.onclick = function() {
|
||||||
|
if (biomeMode === "v6") {
|
||||||
|
noises.heat.offset = NOISE_V6_HEAT_OFFSET_DEFAULT;
|
||||||
|
noises.heat.scale = NOISE_V6_HEAT_SCALE_DEFAULT;
|
||||||
|
noises.heat.octaves = NOISE_V6_HEAT_OCTAVES_DEFAULT;
|
||||||
|
noises.heat.persistence = NOISE_V6_HEAT_PERSISTENCE_DEFAULT;
|
||||||
|
noises.heat.absvalue = NOISE_V6_HEAT_ABSVALUE_DEFAULT;
|
||||||
|
|
||||||
|
noises.humidity.offset = NOISE_V6_HUMIDITY_OFFSET_DEFAULT;
|
||||||
|
noises.humidity.scale = NOISE_V6_HUMIDITY_SCALE_DEFAULT;
|
||||||
|
noises.humidity.octaves = NOISE_V6_HUMIDITY_OCTAVES_DEFAULT;
|
||||||
|
noises.humidity.persistence = NOISE_V6_HUMIDITY_PERSISTENCE_DEFAULT;
|
||||||
|
noises.humidity.absvalue = NOISE_V6_HUMIDITY_ABSVALUE_DEFAULT;
|
||||||
|
} else {
|
||||||
noises.heat.offset = NOISE_OFFSET_DEFAULT;
|
noises.heat.offset = NOISE_OFFSET_DEFAULT;
|
||||||
noises.heat.scale = NOISE_SCALE_DEFAULT;
|
noises.heat.scale = NOISE_SCALE_DEFAULT;
|
||||||
noises.heat.octaves = NOISE_OCTAVES_DEFAULT;
|
noises.heat.octaves = NOISE_OCTAVES_DEFAULT;
|
||||||
noises.heat.persistence = NOISE_PERSISTENCE_DEFAULT;
|
noises.heat.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||||
noises.heat.absvalue = NOISE_ABSVALUE_DEFAULT;
|
noises.heat.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||||
inputNoiseHeatOffset.value = noises.heat.offset;
|
|
||||||
inputNoiseHeatScale.value = noises.heat.scale;
|
|
||||||
inputNoiseHeatOctaves.value = noises.heat.octaves;
|
|
||||||
inputNoiseHeatPersistence.value = noises.heat.persistence;
|
|
||||||
|
|
||||||
noises.humidity.offset = NOISE_OFFSET_DEFAULT;
|
noises.humidity.offset = NOISE_OFFSET_DEFAULT;
|
||||||
noises.humidity.scale = NOISE_SCALE_DEFAULT;
|
noises.humidity.scale = NOISE_SCALE_DEFAULT;
|
||||||
noises.humidity.octaves = NOISE_OCTAVES_DEFAULT;
|
noises.humidity.octaves = NOISE_OCTAVES_DEFAULT;
|
||||||
noises.humidity.persistence = NOISE_PERSISTENCE_DEFAULT;
|
noises.humidity.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||||
noises.humidity.absvalue = NOISE_ABSVALUE_DEFAULT;
|
noises.humidity.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputNoiseHeatOffset.value = noises.heat.offset;
|
||||||
|
inputNoiseHeatScale.value = noises.heat.scale;
|
||||||
|
inputNoiseHeatOctaves.value = noises.heat.octaves;
|
||||||
|
inputNoiseHeatPersistence.value = noises.heat.persistence;
|
||||||
|
|
||||||
inputNoiseHumidityOffset.value = noises.humidity.offset;
|
inputNoiseHumidityOffset.value = noises.humidity.offset;
|
||||||
inputNoiseHumidityScale.value = noises.humidity.scale;
|
inputNoiseHumidityScale.value = noises.humidity.scale;
|
||||||
inputNoiseHumidityOctaves.value = noises.humidity.octaves;
|
inputNoiseHumidityOctaves.value = noises.humidity.octaves;
|
||||||
@ -1956,11 +2340,50 @@ inputImportSubmit.onclick = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mode events */
|
||||||
|
modernModeButton.onclick = function() {
|
||||||
|
biomeMode = "modern";
|
||||||
|
biomeConfigContainerOuter.hidden = false;
|
||||||
|
biomeV6ConfigContainerOuter.hidden = true;
|
||||||
|
importContainerOuter.hidden = false;
|
||||||
|
exportContainerOuter.hidden = false;
|
||||||
|
inputCheckboxPoints.disabled = false;
|
||||||
|
noises.heat = noises.heat_modern;
|
||||||
|
noises.humidity = noises.humidity_modern;
|
||||||
|
noiseSettingNameHeat.innerText = "mg_biome_np_heat";
|
||||||
|
noiseSettingNameHumidity.innerText = "mg_biome_np_humidity";
|
||||||
|
modernModeButton.className = "activeBiomeModeButton";
|
||||||
|
v6ModeButton.className = "";
|
||||||
|
updateAreaVars();
|
||||||
|
updateWidgetStates();
|
||||||
|
draw(true);
|
||||||
|
}
|
||||||
|
v6ModeButton.onclick = function() {
|
||||||
|
biomeMode = "v6";
|
||||||
|
biomeConfigContainerOuter.hidden = true;
|
||||||
|
biomeV6ConfigContainerOuter.hidden = false;
|
||||||
|
importContainerOuter.hidden = true;
|
||||||
|
exportContainerOuter.hidden = true;
|
||||||
|
inputCheckboxPoints.disabled = true;
|
||||||
|
noises.heat = noises.heat_v6;
|
||||||
|
noises.humidity = noises.humidity_v6;
|
||||||
|
noiseSettingNameHeat.innerText = "mgv6_np_biome";
|
||||||
|
noiseSettingNameHumidity.innerText = "mgv6_np_humidity";
|
||||||
|
modernModeButton.className = "";
|
||||||
|
v6ModeButton.className = "activeBiomeModeButton";
|
||||||
|
updateAreaVars();
|
||||||
|
updateWidgetStates();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
/* Events for collapsing/extending config section with the arrow thingie */
|
/* Events for collapsing/extending config section with the arrow thingie */
|
||||||
|
|
||||||
biomeConfigHeaderLink.onclick = function() {
|
biomeConfigHeaderLink.onclick = function() {
|
||||||
toggleConfigSectionDisplay(this, biomeConfigContainer);
|
toggleConfigSectionDisplay(this, biomeConfigContainer);
|
||||||
}
|
}
|
||||||
|
biomeV6ConfigHeaderLink.onclick = function() {
|
||||||
|
toggleConfigSectionDisplay(this, biomeV6ConfigContainer);
|
||||||
|
}
|
||||||
viewConfigHeaderLink.onclick = function() {
|
viewConfigHeaderLink.onclick = function() {
|
||||||
toggleConfigSectionDisplay(this, viewConfigContainer);
|
toggleConfigSectionDisplay(this, viewConfigContainer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user