mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
v1.3.04a
This commit is contained in:
parent
c8f758ab3c
commit
d1c795494d
12 changed files with 215 additions and 117 deletions
66
index.html
66
index.html
|
|
@ -34,31 +34,17 @@
|
||||||
#loading-text span:nth-child(3) {animation-delay: 2s;}
|
#loading-text span:nth-child(3) {animation-delay: 2s;}
|
||||||
@keyframes blink {0% {opacity: 0;} 20% {opacity: 1;} 100% {opacity: .1;}}
|
@keyframes blink {0% {opacity: 0;} 20% {opacity: 1;} 100% {opacity: .1;}}
|
||||||
</style>
|
</style>
|
||||||
<link rel="preload" href="index.css?version=1.2" as="style">
|
<link rel="preload" href="index.css?version=1.3" as="style">
|
||||||
<link rel="preload" href="icons.css?version=1.2" as="style">
|
<link rel="preload" href="icons.css?version=1.3" as="style">
|
||||||
<link rel="preload" href="libs/jquery-ui.css" as="style">
|
<link rel="preload" href="libs/jquery-ui.css" as="style">
|
||||||
<link rel="stylesheet" href="index.css?version=1.2">
|
<link rel="stylesheet" href="index.css?version=1.3">
|
||||||
<link rel="stylesheet" href="icons.css?version=1.2">
|
<link rel="stylesheet" href="icons.css?version=1.3">
|
||||||
<link rel="stylesheet" href="libs/jquery-ui.css">
|
<link rel="stylesheet" href="libs/jquery-ui.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="map" width="100%" height="100%">
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="map" width="100%" height="100%">
|
||||||
<defs>
|
<defs>
|
||||||
<style type="text/css">
|
|
||||||
#armies rect {stroke-width: .3; stroke: #000;}
|
|
||||||
#armies text {
|
|
||||||
stroke: none;
|
|
||||||
fill: #fff;
|
|
||||||
text-shadow: 0 0 4px #000;
|
|
||||||
dominant-baseline: central;
|
|
||||||
text-anchor: middle;
|
|
||||||
font-family: Helvetica;
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
#armies text.regimentIcon {font-size: .8em;}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<g id="filters">
|
<g id="filters">
|
||||||
<filter id="blurFilter" x="-1" y="-1" width="100" height="100">
|
<filter id="blurFilter" x="-1" y="-1" width="100" height="100">
|
||||||
<feGaussianBlur in="SourceGraphic" stdDeviation="0.2"/>
|
<feGaussianBlur in="SourceGraphic" stdDeviation="0.2"/>
|
||||||
|
|
@ -913,7 +899,7 @@
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
<div id="titleName"><t data-t="titleName">Azgaar's</t></div>
|
<div id="titleName"><t data-t="titleName">Azgaar's</t></div>
|
||||||
<div id="title"><t data-t="title">Fantasy Map Generator</t></div>
|
<div id="title"><t data-t="title">Fantasy Map Generator</t></div>
|
||||||
<div id="version"><t data-t="version">v. </t>1.2</div>
|
<div id="version"><t data-t="version">v. </t>1.3</div>
|
||||||
<p id="loading-text"><t data-t="loading">LOADING</t><span>.</span><span>.</span><span>.</span></p>
|
<p id="loading-text"><t data-t="loading">LOADING</t><span>.</span><span>.</span><span>.</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -947,6 +933,7 @@
|
||||||
<option value="heightmap">Heightmap</option>
|
<option value="heightmap">Heightmap</option>
|
||||||
<option value="physical">Physical map</option>
|
<option value="physical">Physical map</option>
|
||||||
<option value="poi">Places of interest</option>
|
<option value="poi">Places of interest</option>
|
||||||
|
<option value="military">Military map</option>
|
||||||
<option value="landmass">Pure landmass</option>
|
<option value="landmass">Pure landmass</option>
|
||||||
<option hidden value="custom">Custom (not saved)</option>
|
<option hidden value="custom">Custom (not saved)</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -976,7 +963,8 @@
|
||||||
<li id="togglePrec" data-tip="Precipitation map: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: A" class="buttonoff" onclick="togglePrec(event)">Precipit<u>a</u>tion</li>
|
<li id="togglePrec" data-tip="Precipitation map: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: A" class="buttonoff" onclick="togglePrec(event)">Precipit<u>a</u>tion</li>
|
||||||
<li id="toggleLabels" data-tip="Labels: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: L" onclick="toggleLabels(event)"><u>L</u>abels</li>
|
<li id="toggleLabels" data-tip="Labels: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: L" onclick="toggleLabels(event)"><u>L</u>abels</li>
|
||||||
<li id="toggleIcons" data-tip="Burg icons: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: I" onclick="toggleIcons(event)"><u>I</u>cons</li>
|
<li id="toggleIcons" data-tip="Burg icons: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: I" onclick="toggleIcons(event)"><u>I</u>cons</li>
|
||||||
<li id="toggleMarkers" data-tip="Markers: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: M" class="buttonoff" onclick="toggleMarkers(event)"><u>M</u>arkers</li>
|
<li id="toggleMilitary" data-tip="Military forces: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: M" class="buttonoff" onclick="toggleMilitary(event)"><u>M</u>ilitary</li>
|
||||||
|
<li id="toggleMarkers" data-tip="Markers: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style. Shortcut: K" class="buttonoff" onclick="toggleMarkers(event)">Mar<u>k</u>ers</li>
|
||||||
<li id="toggleRulers" data-tip="Rulers: click to toggle, drag to move, click on label to delete. Ctrl + click to edit layer style. Shortcut: = (equal)" class="buttonoff" onclick="toggleRulers(event)">Rulers</li>
|
<li id="toggleRulers" data-tip="Rulers: click to toggle, drag to move, click on label to delete. Ctrl + click to edit layer style. Shortcut: = (equal)" class="buttonoff" onclick="toggleRulers(event)">Rulers</li>
|
||||||
<li id="toggleScaleBar" data-tip="Scale Bar: click to toggle. Ctrl + click to edit style. Shortcut: - (minus)" onclick="toggleScaleBar(event)" class="solid">Scale Bar</li>
|
<li id="toggleScaleBar" data-tip="Scale Bar: click to toggle. Ctrl + click to edit style. Shortcut: - (minus)" onclick="toggleScaleBar(event)" class="solid">Scale Bar</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -1019,6 +1007,7 @@
|
||||||
<option value="landmass">Landmass</option>
|
<option value="landmass">Landmass</option>
|
||||||
<option value="legend">Legend</option>
|
<option value="legend">Legend</option>
|
||||||
<option value="markers">Markers</option>
|
<option value="markers">Markers</option>
|
||||||
|
<option value="armies">Military</option>
|
||||||
<option value="ocean">Ocean</option>
|
<option value="ocean">Ocean</option>
|
||||||
<option value="population">Population</option>
|
<option value="population">Population</option>
|
||||||
<option value="prec">Precipitation</option>
|
<option value="prec">Precipitation</option>
|
||||||
|
|
@ -1459,6 +1448,23 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
<tbody id="styleArmies">
|
||||||
|
<tr data-tip="Set fill transparency. Set to 0 to make it fully transparent">
|
||||||
|
<td>Fill opacity</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleArmiesFillOpacity" type="range" min=0 max=1 step=.01 value=1>
|
||||||
|
<output id="styleArmiesFillOpacityOutput">1</output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr data-tip="Set regiment box size. All regiments will be redrawn on change (position will defaulted)">
|
||||||
|
<td>Box Size</td>
|
||||||
|
<td>
|
||||||
|
<input id="styleArmiesSize" type="range" min=1 max=10 step=.1 value=3>
|
||||||
|
<output id="styleArmiesSizeOutput">3</output>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
<tbody id="styleFilter" style="display: block">
|
<tbody id="styleFilter" style="display: block">
|
||||||
<tr data-tip="Select filter for element. Please note filters may cause performance issues!">
|
<tr data-tip="Select filter for element. Please note filters may cause performance issues!">
|
||||||
<td>Filter</td>
|
<td>Filter</td>
|
||||||
|
|
@ -1502,13 +1508,13 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
<tbody id="styleMarkers">
|
<tbody id="styleMarkers">
|
||||||
<tr data-tip="Try to keep the same size on any map scale, turn off to get size change depending on scale">
|
<tr data-tip="Try to keep the same size on any map scale, turn off to get size change depending on scale">
|
||||||
<td colspan=2>
|
<td colspan=2>
|
||||||
<input id="styleRescaleMarkers" class="checkbox" type="checkbox">
|
<input id="styleRescaleMarkers" class="checkbox" type="checkbox">
|
||||||
<label for="styleRescaleMarkers" class="checkbox-label">Keep initial size on zoom change</label>
|
<label for="styleRescaleMarkers" class="checkbox-label">Keep initial size on zoom change</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
<tbody id="styleVisibility">
|
<tbody id="styleVisibility">
|
||||||
<tr data-tip="Define displayed label groups">
|
<tr data-tip="Define displayed label groups">
|
||||||
|
|
@ -1849,6 +1855,7 @@
|
||||||
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Burgs will remain as they are">States</button>
|
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Burgs will remain as they are">States</button>
|
||||||
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
||||||
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
||||||
|
<button id="regenerateMilitary" data-tip="Click to recalculate military forces and regenerate regiments based on current military options">Military</button>
|
||||||
<button id="regenerateMarkers" data-tip="Click to regenerate markers. Hold Ctrl and click to set markers number multiplier">Markers</button>
|
<button id="regenerateMarkers" data-tip="Click to regenerate markers. Hold Ctrl and click to set markers number multiplier">Markers</button>
|
||||||
<button id="regenerateZones" data-tip="Click to regenerate zones. Hold Ctrl and click to set zones number multiplier">Zones</button>
|
<button id="regenerateZones" data-tip="Click to regenerate zones. Hold Ctrl and click to set zones number multiplier">Zones</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3289,6 +3296,7 @@
|
||||||
<div id="militaryBottom">
|
<div id="militaryBottom">
|
||||||
<button id="militaryOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button>
|
<button id="militaryOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button>
|
||||||
<button id="militaryOptionsButton" data-tip="Edit Military units" class="icon-cog"></button>
|
<button id="militaryOptionsButton" data-tip="Edit Military units" class="icon-cog"></button>
|
||||||
|
<button id="militaryRegimentsList" data-tip="Show regiments list" class="icon-list-bullet"></button>
|
||||||
<button id="militaryPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
<button id="militaryPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
||||||
<button id="militaryOverviewRecalculate" data-tip="Recalculate military forces based on current options" class="icon-retweet"></button>
|
<button id="militaryOverviewRecalculate" data-tip="Recalculate military forces based on current options" class="icon-retweet"></button>
|
||||||
<button id="militaryExport" data-tip="Save military-related data as a text file (.csv)" class="icon-download"></button>
|
<button id="militaryExport" data-tip="Save military-related data as a text file (.csv)" class="icon-download"></button>
|
||||||
|
|
@ -3308,8 +3316,8 @@
|
||||||
<button id="regimentsOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button>
|
<button id="regimentsOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button>
|
||||||
<button id="regimentsPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
<button id="regimentsPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
||||||
<button id="regimentsAddNew" data-tip="Add new Regiment" class="icon-user-plus"></button>
|
<button id="regimentsAddNew" data-tip="Add new Regiment" class="icon-user-plus"></button>
|
||||||
<button id="regimentsExport" data-tip="Save military-related data as a text file (.csv)" class="icon-download"></button>
|
|
||||||
<div data-tip="Select state" style="display:inline-block"><span>State: </span><select id="regimentsFilter"></select></div>
|
<div data-tip="Select state" style="display:inline-block"><span>State: </span><select id="regimentsFilter"></select></div>
|
||||||
|
<button id="regimentsExport" data-tip="Save military-related data as a text file (.csv)" class="icon-download"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3487,7 +3495,7 @@
|
||||||
<input type="file" accept=".json" id="styleToLoad">
|
<input type="file" accept=".json" id="styleToLoad">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="libs/translate.js"></script>
|
<!-- <script src="libs/translate.js"></script> -->
|
||||||
<script src="libs/jquery-3.1.1.min.js"></script>
|
<script src="libs/jquery-3.1.1.min.js"></script>
|
||||||
<script src="libs/d3.min.js"></script>
|
<script src="libs/d3.min.js"></script>
|
||||||
<script src="libs/priority-queue.min.js"></script>
|
<script src="libs/priority-queue.min.js"></script>
|
||||||
|
|
|
||||||
25
main.js
25
main.js
|
|
@ -7,7 +7,7 @@
|
||||||
// See also https://github.com/Azgaar/Fantasy-Map-Generator/issues/153
|
// See also https://github.com/Azgaar/Fantasy-Map-Generator/issues/153
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const version = "1.22"; // generator version
|
const version = "1.3"; // generator version
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
||||||
// if map version is not stored, clear localStorage and show a message
|
// if map version is not stored, clear localStorage and show a message
|
||||||
|
|
@ -58,7 +58,7 @@ let labels = viewbox.append("g").attr("id", "labels");
|
||||||
let icons = viewbox.append("g").attr("id", "icons");
|
let icons = viewbox.append("g").attr("id", "icons");
|
||||||
let burgIcons = icons.append("g").attr("id", "burgIcons");
|
let burgIcons = icons.append("g").attr("id", "burgIcons");
|
||||||
let anchors = icons.append("g").attr("id", "anchors");
|
let anchors = icons.append("g").attr("id", "anchors");
|
||||||
let armies = viewbox.append("g").attr("id", "armies");
|
let armies = viewbox.append("g").attr("id", "armies").style("display", "none");
|
||||||
let markers = viewbox.append("g").attr("id", "markers").style("display", "none");
|
let markers = viewbox.append("g").attr("id", "markers").style("display", "none");
|
||||||
let fogging = viewbox.append("g").attr("id", "fogging-cont").attr("mask", "url(#fog)")
|
let fogging = viewbox.append("g").attr("id", "fogging-cont").attr("mask", "url(#fog)")
|
||||||
.append("g").attr("id", "fogging").style("display", "none");
|
.append("g").attr("id", "fogging").style("display", "none");
|
||||||
|
|
@ -118,13 +118,6 @@ const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed);
|
||||||
let options = {}; // options object
|
let options = {}; // options object
|
||||||
let mapCoordinates = {}; // map coordinates on globe
|
let mapCoordinates = {}; // map coordinates on globe
|
||||||
options.winds = [225, 45, 225, 315, 135, 315]; // default wind directions
|
options.winds = [225, 45, 225, 315, 135, 315]; // default wind directions
|
||||||
options.military = [
|
|
||||||
{name:"infantry", rural:.25, urban:.2, crew:1, type:"melee", separate:0},
|
|
||||||
{name:"archers", rural:.12, urban:.2, crew:1, type:"ranged", separate:0},
|
|
||||||
{name:"cavalry", rural:.12, urban:.03, crew:3, type:"mounted", separate:0},
|
|
||||||
{name:"artillery", rural:0, urban:.03, crew:8, type:"machinery", separate:0},
|
|
||||||
{name:"fleet", rural:0, urban:.015, crew:100, type:"naval", separate:1}
|
|
||||||
];
|
|
||||||
|
|
||||||
// woldbuilding options
|
// woldbuilding options
|
||||||
options.year = rand(100, 2000); // current year
|
options.year = rand(100, 2000); // current year
|
||||||
|
|
@ -330,7 +323,7 @@ function applyDefaultBiomesSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showWelcomeMessage() {
|
function showWelcomeMessage() {
|
||||||
const post = link("https://www.reddit.com/r/FantasyMapGenerator/comments/dlow3k/update_new_version_is_published_v_12", "Main changes:"); // announcement on Reddit
|
const post = link("https://www.reddit.com/r/FantasyMapGenerator/comments/dlow3k/update_new_version_is_published_v_13", "Main changes:"); // announcement on Reddit
|
||||||
const changelog = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog", "previous version");
|
const changelog = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog", "previous version");
|
||||||
const reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit community");
|
const reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit community");
|
||||||
const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server");
|
const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server");
|
||||||
|
|
@ -340,13 +333,15 @@ function showWelcomeMessage() {
|
||||||
This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated.
|
This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated.
|
||||||
|
|
||||||
<ul>${post}
|
<ul>${post}
|
||||||
<li>3d scene and Globe view</li>
|
<li>Military Forces generation</li>
|
||||||
<li>Ability to save map as JPEG image</li>
|
<li>Military Forces overview</li>
|
||||||
<li>Diplomacy Editor enhancements</li>
|
<li>Military Units editor</li>
|
||||||
<li>Rivers Overview screen</li>
|
<li>Regiments editor</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Thanks for all supporters on ${patreon}!</i></p>`;
|
<p>Join our ${discord} and ${reddit} to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>
|
||||||
|
|
||||||
|
<span>Thanks for all supporters on ${patreon}!</i></span>`;
|
||||||
|
|
||||||
$("#alert").dialog(
|
$("#alert").dialog(
|
||||||
{resizable: false, title: "Fantasy Map Generator update", width: "28em",
|
{resizable: false, title: "Fantasy Map Generator update", width: "28em",
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,20 @@
|
||||||
console.time("generateMilitaryForces");
|
console.time("generateMilitaryForces");
|
||||||
cells = pack.cells, p = cells.p, states = pack.states;
|
cells = pack.cells, p = cells.p, states = pack.states;
|
||||||
const valid = states.filter(s => s.i && !s.removed); // valid states
|
const valid = states.filter(s => s.i && !s.removed); // valid states
|
||||||
|
if (!options.military) options.military = getDefaultOptions();
|
||||||
|
|
||||||
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:-.2, Friendly:-.1, Neutral:0, Suspicion:.1, Enemy:1, Unknown:0, Rival:.5, Vassal:.5, Suzerain:-.5};
|
const rate = {x:0, Ally:-.2, Friendly:-.1, Neutral:0, Suspicion:.1, Enemy:1, Unknown:0, Rival:.5, Vassal:.5, Suzerain:-.5};
|
||||||
|
|
||||||
|
const stateModifier = {
|
||||||
|
"melee": {"Nomadic":.5, "Highland":1.2, "Lake":1, "Naval":.7, "Hunting":1.2, "River":1.1},
|
||||||
|
"ranged": {"Nomadic":.9, "Highland":1.3, "Lake":1, "Naval":.8, "Hunting":2, "River":.8},
|
||||||
|
"mounted": {"Nomadic":2.3, "Highland":.6, "Lake":.7, "Naval":.3, "Hunting":.7, "River":.8},
|
||||||
|
"machinery":{"Nomadic":.8, "Highland":1.4, "Lake":1.1, "Naval":1.4, "Hunting":.4, "River":1.1},
|
||||||
|
"naval": {"Nomadic":.5, "Highland":.5, "Lake":1.2, "Naval":1.8, "Hunting":.7, "River":1.2}
|
||||||
|
};
|
||||||
|
|
||||||
valid.forEach(s => {
|
valid.forEach(s => {
|
||||||
const temp = s.temp = {}, d = s.diplomacy;
|
const temp = s.temp = {}, d = s.diplomacy;
|
||||||
const expansionRate = Math.min(Math.max((s.expansionism / expn) / (s.area / area), .25), 4); // how much state expansionism is realized
|
const expansionRate = Math.min(Math.max((s.expansionism / expn) / (s.area / area), .25), 4); // how much state expansionism is realized
|
||||||
|
|
@ -25,19 +34,10 @@
|
||||||
|
|
||||||
// apply overall state modifiers for unit types based on state features
|
// apply overall state modifiers for unit types based on state features
|
||||||
for (const unit of options.military) {
|
for (const unit of options.military) {
|
||||||
let modifier = 1;
|
if (!stateModifier[unit.type]) continue;
|
||||||
|
let modifier = stateModifier[unit.type][s.type] || 1;
|
||||||
if (unit.type === "mounted") {
|
if (unit.type === "mounted" && s.form === "Horde") modifier *= 2; else
|
||||||
if (s.type === "Naval") modifier /= 1.4;
|
if (unit.type === "naval" && s.form === "Republic") modifier *= 1.2;
|
||||||
if (s.form === "Horde") modifier *= 2;
|
|
||||||
} else if (unit.type === "ranged") {
|
|
||||||
if (s.type === "Hunting") modifier *= 1.4;
|
|
||||||
} else if (unit.type === "naval") {
|
|
||||||
if (s.type === "Naval") modifier *= 2; else
|
|
||||||
if (s.type === "River") modifier *= 1.2; else
|
|
||||||
if (s.type === "Nomadic") modifier /= 1.4;
|
|
||||||
if (s.form === "Republic") modifier *= 1.2;
|
|
||||||
}
|
|
||||||
temp[unit.name] = modifier * s.alert;
|
temp[unit.name] = modifier * s.alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,9 +76,10 @@
|
||||||
if (u.type === "ranged") army *= 1.4; else
|
if (u.type === "ranged") army *= 1.4; else
|
||||||
if (u.type === "mounted") army /= 3;
|
if (u.type === "mounted") army /= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highland) { // highlands special rules
|
if (highland) { // highlands special rules
|
||||||
if (u.type === "ranged") army *= 2; else
|
if (u.type === "melee") army *= 1.2; else
|
||||||
|
if (u.type === "ranged") army *= 1.6; else
|
||||||
if (u.type === "mounted") army /= 3;
|
if (u.type === "mounted") army /= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,41 +94,41 @@
|
||||||
for (const b of pack.burgs) {
|
for (const b of pack.burgs) {
|
||||||
if (!b.i || b.removed || !b.state || !b.population) continue;
|
if (!b.i || b.removed || !b.state || !b.population) continue;
|
||||||
const s = states[b.state]; // burg state
|
const s = states[b.state]; // burg state
|
||||||
|
|
||||||
let m = b.population * urbanization.value / 100; // basic urban army in percentages
|
let m = b.population * urbanization.value / 100; // basic urban army in percentages
|
||||||
if (b.capital) m *= 1.2; // capital has household troops
|
if (b.capital) m *= 1.2; // capital has household troops
|
||||||
if (b.culture !== s.culture) m = s.form === "Union" ? m / 1.2 : m / 2; // non-dominant culture
|
if (b.culture !== s.culture) m = s.form === "Union" ? m / 1.2 : m / 2; // non-dominant culture
|
||||||
if (cells.religion[b.cell] !== cells.religion[s.center]) m = s.form === "Theocracy" ? m / 2.2 : m / 1.4; // non-dominant religion
|
if (cells.religion[b.cell] !== cells.religion[s.center]) m = s.form === "Theocracy" ? m / 2.2 : m / 1.4; // non-dominant religion
|
||||||
if (cells.f[b.cell] !== cells.f[s.center]) m = s.type === "Naval" ? m / 1.2 : m / 1.8; // different landmass
|
if (cells.f[b.cell] !== cells.f[s.center]) m = s.type === "Naval" ? m / 1.2 : m / 1.8; // different landmass
|
||||||
|
|
||||||
const biome = cells.biome[b.cell]; // burg biome
|
const biome = cells.biome[b.cell]; // burg biome
|
||||||
const nomadic = [1, 2, 3, 4].includes(biome);
|
const nomadic = [1, 2, 3, 4].includes(biome);
|
||||||
const wetland = [7, 8, 9, 12].includes(biome);
|
const wetland = [7, 8, 9, 12].includes(biome);
|
||||||
const highland = cells.h[b.cell] >= 70;
|
const highland = cells.h[b.cell] >= 70;
|
||||||
|
|
||||||
for (const u of options.military) {
|
for (const u of options.military) {
|
||||||
const perc = +u.urban;
|
const perc = +u.urban;
|
||||||
if (isNaN(perc) || perc <= 0) continue;
|
if (isNaN(perc) || perc <= 0) continue;
|
||||||
let army = m * perc; // basic army for rural cell
|
let army = m * perc; // basic army for rural cell
|
||||||
|
|
||||||
if (u.type === "naval") {
|
if (u.type === "naval") {
|
||||||
if (!b.port) continue; // only ports have naval units
|
if (!b.port) continue; // only ports have naval units
|
||||||
army *= normalizeNaval(pack.features[b.port].ports);
|
army *= normalizeNaval(pack.features[b.port].ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nomadic) { // "nomadic" biomes special rules
|
if (nomadic) { // "nomadic" biomes special rules
|
||||||
if (u.type === "melee") army /= 3; else
|
if (u.type === "melee") army /= 3; else
|
||||||
if (u.type === "machinery") army /= 2; else
|
if (u.type === "machinery") army /= 2; else
|
||||||
if (u.type === "mounted") army *= 3;
|
if (u.type === "mounted") army *= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wetland) { // "wet" biomes special rules
|
if (wetland) { // "wet" biomes special rules
|
||||||
if (u.type === "melee") army *= 1.2; else
|
if (u.type === "melee") army *= 1.2; else
|
||||||
if (u.type === "ranged") army *= 1.4; else
|
if (u.type === "ranged") army *= 1.4; else
|
||||||
if (u.type === "machinery") army *= 1.2; else
|
if (u.type === "machinery") army *= 1.2; else
|
||||||
if (u.type === "mounted") army /= 4;
|
if (u.type === "mounted") army /= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highland) { // highlands special rules
|
if (highland) { // highlands special rules
|
||||||
if (u.type === "ranged") army *= 2; else
|
if (u.type === "ranged") army *= 2; else
|
||||||
if (u.type === "naval") army /= 3; else
|
if (u.type === "naval") army /= 3; else
|
||||||
|
|
@ -196,8 +197,18 @@
|
||||||
console.timeEnd("generateMilitaryForces");
|
console.timeEnd("generateMilitaryForces");
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawRegiments(regiments, s) {
|
const getDefaultOptions = function() {
|
||||||
const size = +armies.attr("data-size");
|
return [
|
||||||
|
{name:"infantry", rural:.25, urban:.2, crew:1, type:"melee", separate:0},
|
||||||
|
{name:"archers", rural:.12, urban:.2, crew:1, type:"ranged", separate:0},
|
||||||
|
{name:"cavalry", rural:.12, urban:.03, crew:3, type:"mounted", separate:0},
|
||||||
|
{name:"artillery", rural:0, urban:.03, crew:8, type:"machinery", separate:0},
|
||||||
|
{name:"fleet", rural:0, urban:.015, crew:100, type:"naval", separate:1}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawRegiments = function(regiments, s) {
|
||||||
|
const size = +armies.attr("box-size");
|
||||||
const w = d => d.n ? size * 4 : size * 6;
|
const w = d => d.n ? size * 4 : size * 6;
|
||||||
const h = size * 2;
|
const h = size * 2;
|
||||||
const x = d => rn(d.x - w(d) / 2, 2);
|
const x = d => rn(d.x - w(d) / 2, 2);
|
||||||
|
|
@ -216,7 +227,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawRegiment = function(reg, s, x = reg.x, y = reg.y) {
|
const drawRegiment = function(reg, s, x = reg.x, y = reg.y) {
|
||||||
const size = +armies.attr("data-size");
|
const size = +armies.attr("box-size");
|
||||||
const w = reg.n ? size * 4 : size * 6;
|
const w = reg.n ? size * 4 : size * 6;
|
||||||
const h = size * 2;
|
const h = size * 2;
|
||||||
const x1 = rn(x - w / 2, 2);
|
const x1 = rn(x - w / 2, 2);
|
||||||
|
|
@ -236,7 +247,7 @@
|
||||||
const getTotal = reg => reg.a > (reg.n ? 999 : 99999) ? si(reg.a) : reg.a;
|
const getTotal = reg => reg.a > (reg.n ? 999 : 99999) ? si(reg.a) : reg.a;
|
||||||
|
|
||||||
const getName = function(r, regiments) {
|
const getName = function(r, regiments) {
|
||||||
const proper = r.n ? null :
|
const proper = r.n ? null :
|
||||||
cells.province[r.cell] ? pack.provinces[cells.province[r.cell]].name :
|
cells.province[r.cell] ? pack.provinces[cells.province[r.cell]].name :
|
||||||
cells.burg[r.cell] ? pack.burgs[cells.burg[r.cell]].name : null
|
cells.burg[r.cell] ? pack.burgs[cells.burg[r.cell]].name : null
|
||||||
const number = nth(regiments.filter(reg => reg.n === r.n && reg.i < r.i).length+1);
|
const number = nth(regiments.filter(reg => reg.n === r.n && reg.i < r.i).length+1);
|
||||||
|
|
@ -271,6 +282,6 @@
|
||||||
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, getName, generateNote, drawRegiment, getTotal, getEmblem};
|
return {generate, getDefaultOptions, getName, generateNote, drawRegiments, drawRegiment, getTotal, getEmblem};
|
||||||
|
|
||||||
})));
|
})));
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
|
|
||||||
// directly connect first port with the farthest one on the same island to remove gap
|
// directly connect first port with the farthest one on the same island to remove gap
|
||||||
void function() {
|
void function() {
|
||||||
if (pack.features[f].type === "lake") return;
|
if (!pack.features[f] || pack.features[f].type === "lake") return;
|
||||||
const portsOnIsland = ports.filter(b => cells.f[b.cell] === cells.f[first]);
|
const portsOnIsland = ports.filter(b => cells.f[b.cell] === cells.f[first]);
|
||||||
if (portsOnIsland.length < 4) return;
|
if (portsOnIsland.length < 4) return;
|
||||||
const opposite = ports[d3.scan(portsOnIsland, (a, b) => ((b.y - ports[0].y) ** 2 + (b.x - ports[0].x) ** 2) - ((a.y - ports[0].y) ** 2 + (a.x - ports[0].x) ** 2))].cell;
|
const opposite = ports[d3.scan(portsOnIsland, (a, b) => ((b.y - ports[0].y) ** 2 + (b.x - ports[0].x) ** 2) - ((a.y - ports[0].y) ** 2 + (a.x - ports[0].x) ** 2))].cell;
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ function getMapData() {
|
||||||
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value,
|
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value,
|
||||||
barPosX.value, barPosY.value, populationRate.value, urbanization.value,
|
barPosX.value, barPosY.value, populationRate.value, urbanization.value,
|
||||||
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value,
|
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value,
|
||||||
temperaturePoleOutput.value, precOutput.value, JSON.stringify(options.winds),
|
temperaturePoleOutput.value, precOutput.value, JSON.stringify(options),
|
||||||
mapName.value].join("|");
|
mapName.value].join("|");
|
||||||
const coords = JSON.stringify(mapCoordinates);
|
const coords = JSON.stringify(mapCoordinates);
|
||||||
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
||||||
|
|
@ -575,7 +575,7 @@ function parseLoadedData(data) {
|
||||||
if (settings[16]) temperatureEquatorInput.value = temperatureEquatorOutput.value = settings[16];
|
if (settings[16]) temperatureEquatorInput.value = temperatureEquatorOutput.value = settings[16];
|
||||||
if (settings[17]) temperaturePoleInput.value = temperaturePoleOutput.value = settings[17];
|
if (settings[17]) temperaturePoleInput.value = temperaturePoleOutput.value = settings[17];
|
||||||
if (settings[18]) precInput.value = precOutput.value = settings[18];
|
if (settings[18]) precInput.value = precOutput.value = settings[18];
|
||||||
if (settings[19]) options.winds = JSON.parse(settings[19]);
|
if (settings[19]) options = JSON.parse(settings[19]);
|
||||||
if (settings[20]) mapName.value = settings[20];
|
if (settings[20]) mapName.value = settings[20];
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
@ -721,6 +721,7 @@ function parseLoadedData(data) {
|
||||||
if (prec.selectAll("circle").size()) turnButtonOn("togglePrec"); else turnButtonOff("togglePrec");
|
if (prec.selectAll("circle").size()) turnButtonOn("togglePrec"); else turnButtonOff("togglePrec");
|
||||||
if (labels.style("display") !== "none") turnButtonOn("toggleLabels"); else turnButtonOff("toggleLabels");
|
if (labels.style("display") !== "none") turnButtonOn("toggleLabels"); else turnButtonOff("toggleLabels");
|
||||||
if (icons.style("display") !== "none") turnButtonOn("toggleIcons"); else turnButtonOff("toggleIcons");
|
if (icons.style("display") !== "none") turnButtonOn("toggleIcons"); else turnButtonOff("toggleIcons");
|
||||||
|
if (armies.selectAll("*").size() && armies.style("display") !== "none") turnButtonOn("toggleMilitary"); else turnButtonOff("toggleMilitary");
|
||||||
if (markers.selectAll("*").size() && markers.style("display") !== "none") turnButtonOn("toggleMarkers"); else turnButtonOff("toggleMarkers");
|
if (markers.selectAll("*").size() && markers.style("display") !== "none") turnButtonOn("toggleMarkers"); else turnButtonOff("toggleMarkers");
|
||||||
if (ruler.style("display") !== "none") turnButtonOn("toggleRulers"); else turnButtonOff("toggleRulers");
|
if (ruler.style("display") !== "none") turnButtonOn("toggleRulers"); else turnButtonOff("toggleRulers");
|
||||||
if (scaleBar.style("display") !== "none") turnButtonOn("toggleScaleBar"); else turnButtonOff("toggleScaleBar");
|
if (scaleBar.style("display") !== "none") turnButtonOn("toggleScaleBar"); else turnButtonOff("toggleScaleBar");
|
||||||
|
|
@ -774,6 +775,7 @@ function parseLoadedData(data) {
|
||||||
// 1.0 adds state relations, provinces, forms and full names
|
// 1.0 adds state relations, provinces, forms and full names
|
||||||
provs = viewbox.insert("g", "#borders").attr("id", "provs").attr("opacity", .6);
|
provs = viewbox.insert("g", "#borders").attr("id", "provs").attr("opacity", .6);
|
||||||
BurgsAndStates.collectStatistics();
|
BurgsAndStates.collectStatistics();
|
||||||
|
BurgsAndStates.generateCampaigns();
|
||||||
BurgsAndStates.generateDiplomacy();
|
BurgsAndStates.generateDiplomacy();
|
||||||
BurgsAndStates.defineStateForms();
|
BurgsAndStates.defineStateForms();
|
||||||
drawStates();
|
drawStates();
|
||||||
|
|
@ -905,7 +907,6 @@ function parseLoadedData(data) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// v 1.21 added rivers data to pack
|
// v 1.21 added rivers data to pack
|
||||||
|
|
||||||
pack.rivers = []; // rivers data
|
pack.rivers = []; // rivers data
|
||||||
rivers.selectAll("path").each(function() {
|
rivers.selectAll("path").each(function() {
|
||||||
const i = +this.id.slice(5);
|
const i = +this.id.slice(5);
|
||||||
|
|
@ -937,6 +938,24 @@ function parseLoadedData(data) {
|
||||||
if (!f.i) continue;
|
if (!f.i) continue;
|
||||||
f.ports = pack.burgs.filter(b => !b.removed && b.port === f.i).length;
|
f.ports = pack.burgs.filter(b => !b.removed && b.port === f.i).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v 1.3 added global options object
|
||||||
|
const winds = options.slice(); // previostly wnd was saved in settings[19]
|
||||||
|
const year = rand(100, 2000);
|
||||||
|
const era = Names.getBaseShort(P(.7) ? 1 : rand(nameBases.length)) + " Era";
|
||||||
|
const eraShort = era[0] + "E";
|
||||||
|
const military = Military.getDefaultOptions();
|
||||||
|
options = {winds, year, era, eraShort, military};
|
||||||
|
|
||||||
|
// v 1.3 added campaings data for all states
|
||||||
|
BurgsAndStates.generateCampaigns();
|
||||||
|
|
||||||
|
// v 1.3 added militry layer
|
||||||
|
svg.select("defs").append("style").text(armiesStyle()); // add armies style
|
||||||
|
armies = viewbox.insert("g", "#icons").attr("id", "armies");
|
||||||
|
armies.attr("opacity", 1).attr("fill-opacity", 1).attr("font-size", 6).attr("box-size", 3).attr("stroke", "#000").attr("stroke-width", .3);
|
||||||
|
turnButtonOn("toggleMilitary");
|
||||||
|
Military.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ function showDataTip(e) {
|
||||||
let dataTip = e.target.dataset.tip;
|
let dataTip = e.target.dataset.tip;
|
||||||
if (!dataTip && e.target.parentNode.dataset.tip) dataTip = e.target.parentNode.dataset.tip;
|
if (!dataTip && e.target.parentNode.dataset.tip) dataTip = e.target.parentNode.dataset.tip;
|
||||||
if (!dataTip) return;
|
if (!dataTip) return;
|
||||||
const tooltip = lang === "en" ? dataTip : translate(e.target.dataset.t || e.target.parentNode.dataset.t, dataTip);
|
//const tooltip = lang === "en" ? dataTip : translate(e.target.dataset.t || e.target.parentNode.dataset.t, dataTip);
|
||||||
tip(tooltip);
|
tip(dataTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
function moved() {
|
function moved() {
|
||||||
|
|
@ -403,7 +403,8 @@ document.addEventListener("keyup", event => {
|
||||||
else if (key === 65) togglePrec(); // "A" to toggle Precipitation layer
|
else if (key === 65) togglePrec(); // "A" to toggle Precipitation layer
|
||||||
else if (key === 76) toggleLabels(); // "L" to toggle Labels layer
|
else if (key === 76) toggleLabels(); // "L" to toggle Labels layer
|
||||||
else if (key === 73) toggleIcons(); // "I" to toggle Icons layer
|
else if (key === 73) toggleIcons(); // "I" to toggle Icons layer
|
||||||
else if (key === 77) toggleMarkers(); // "M" to toggle Markers layer
|
else if (key === 77) toggleMilitary(); // "M" to toggle Military layer
|
||||||
|
else if (key === 75) toggleMarkers(); // "K" to toggle Markers layer
|
||||||
else if (key === 187) toggleRulers(); // Equal (=) to toggle Rulers
|
else if (key === 187) toggleRulers(); // Equal (=) to toggle Rulers
|
||||||
else if (key === 189) toggleScaleBar(); // Minus (-) to toggle Scale bar
|
else if (key === 189) toggleScaleBar(); // Minus (-) to toggle Scale bar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ function getDefaultPresets() {
|
||||||
"heightmap": ["toggleHeight", "toggleRivers"],
|
"heightmap": ["toggleHeight", "toggleRivers"],
|
||||||
"physical": ["toggleCoordinates", "toggleHeight", "toggleRivers", "toggleScaleBar"],
|
"physical": ["toggleCoordinates", "toggleHeight", "toggleRivers", "toggleScaleBar"],
|
||||||
"poi": ["toggleBorders", "toggleHeight", "toggleIcons", "toggleMarkers", "toggleRivers", "toggleRoutes", "toggleScaleBar"],
|
"poi": ["toggleBorders", "toggleHeight", "toggleIcons", "toggleMarkers", "toggleRivers", "toggleRoutes", "toggleScaleBar"],
|
||||||
|
"military": ["toggleBorders", "toggleIcons", "toggleLabels", "toggleMilitary", "toggleRivers", "toggleRoutes", "toggleScaleBar", "toggleStates"],
|
||||||
"landmass": ["toggleScaleBar"]
|
"landmass": ["toggleScaleBar"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1058,6 +1059,18 @@ function toggleRoutes(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleMilitary() {
|
||||||
|
if (!layerIsOn("toggleMilitary")) {
|
||||||
|
turnButtonOn("toggleMilitary");
|
||||||
|
$('#armies').fadeIn();
|
||||||
|
if (event && isCtrlClick(event)) editStyle("armies");
|
||||||
|
} else {
|
||||||
|
if (event && isCtrlClick(event)) {editStyle("armies"); return;}
|
||||||
|
$('#armies').fadeOut();
|
||||||
|
turnButtonOff("toggleMilitary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleMarkers(event) {
|
function toggleMarkers(event) {
|
||||||
if (!layerIsOn("toggleMarkers")) {
|
if (!layerIsOn("toggleMarkers")) {
|
||||||
turnButtonOn("toggleMarkers");
|
turnButtonOn("toggleMarkers");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ function overviewMilitary() {
|
||||||
closeDialogs("#militaryOverview, .stable");
|
closeDialogs("#militaryOverview, .stable");
|
||||||
if (!layerIsOn("toggleStates")) toggleStates();
|
if (!layerIsOn("toggleStates")) toggleStates();
|
||||||
if (!layerIsOn("toggleBorders")) toggleBorders();
|
if (!layerIsOn("toggleBorders")) toggleBorders();
|
||||||
|
if (!layerIsOn("toggleMilitary")) toggleMilitary();
|
||||||
|
|
||||||
const body = document.getElementById("militaryBody");
|
const body = document.getElementById("militaryBody");
|
||||||
addLines();
|
addLines();
|
||||||
|
|
@ -22,6 +23,7 @@ function overviewMilitary() {
|
||||||
document.getElementById("militaryOverviewRefresh").addEventListener("click", addLines);
|
document.getElementById("militaryOverviewRefresh").addEventListener("click", addLines);
|
||||||
document.getElementById("militaryPercentage").addEventListener("click", togglePercentageMode);
|
document.getElementById("militaryPercentage").addEventListener("click", togglePercentageMode);
|
||||||
document.getElementById("militaryOptionsButton").addEventListener("click", militaryCustomize);
|
document.getElementById("militaryOptionsButton").addEventListener("click", militaryCustomize);
|
||||||
|
document.getElementById("militaryRegimentsList").addEventListener("click", () => overviewRegiments(-1));
|
||||||
document.getElementById("militaryOverviewRecalculate").addEventListener("click", militaryRecalculate);
|
document.getElementById("militaryOverviewRecalculate").addEventListener("click", militaryRecalculate);
|
||||||
document.getElementById("militaryExport").addEventListener("click", downloadMilitaryData);
|
document.getElementById("militaryExport").addEventListener("click", downloadMilitaryData);
|
||||||
|
|
||||||
|
|
@ -120,9 +122,11 @@ function overviewMilitary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateHighlightOn(event) {
|
function stateHighlightOn(event) {
|
||||||
if (!layerIsOn("toggleStates")) return;
|
|
||||||
const state = +event.target.dataset.id;
|
const state = +event.target.dataset.id;
|
||||||
if (customization || !state) return;
|
if (customization || !state) return;
|
||||||
|
armies.select("#army"+state).transition().duration(2000).style("fill", "#ff0000");
|
||||||
|
|
||||||
|
if (!layerIsOn("toggleStates")) return;
|
||||||
const d = regions.select("#state"+state).attr("d");
|
const d = regions.select("#state"+state).attr("d");
|
||||||
|
|
||||||
const path = debug.append("path").attr("class", "highlight").attr("d", d)
|
const path = debug.append("path").attr("class", "highlight").attr("d", d)
|
||||||
|
|
@ -132,8 +136,6 @@ function overviewMilitary() {
|
||||||
const l = path.node().getTotalLength(), dur = (l + 5000) / 2;
|
const l = path.node().getTotalLength(), dur = (l + 5000) / 2;
|
||||||
const i = d3.interpolateString("0," + l, l + "," + l);
|
const i = d3.interpolateString("0," + l, l + "," + l);
|
||||||
path.transition().duration(dur).attrTween("stroke-dasharray", function() {return t => i(t)});
|
path.transition().duration(dur).attrTween("stroke-dasharray", function() {return t => i(t)});
|
||||||
|
|
||||||
armies.select("#army"+state).transition().duration(dur).style("fill", "#ff0000");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateHighlightOff(event) {
|
function stateHighlightOff(event) {
|
||||||
|
|
@ -161,7 +163,7 @@ function overviewMilitary() {
|
||||||
el.querySelectorAll("div").forEach(function(div) {
|
el.querySelectorAll("div").forEach(function(div) {
|
||||||
const type = div.dataset.type;
|
const type = div.dataset.type;
|
||||||
if (type === "rate") return;
|
if (type === "rate") return;
|
||||||
div.textContent = rn(+el.dataset[type] / total(type) * 100) + "%";
|
div.textContent = total(type) ? rn(+el.dataset[type] / total(type) * 100) + "%" : "0%";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -181,7 +183,7 @@ function overviewMilitary() {
|
||||||
position: {my: "center", at: "center", of: "svg"},
|
position: {my: "center", at: "center", of: "svg"},
|
||||||
buttons: {
|
buttons: {
|
||||||
Apply: function() {applyMilitaryOptions(); $(this).dialog("close");},
|
Apply: function() {applyMilitaryOptions(); $(this).dialog("close");},
|
||||||
Add: () => addUnitLine({name: "custom", rural: 0.2, urban: 0.5, crew: 1, type: "default"}),
|
Add: () => addUnitLine({name: "custom"+rand(1000), rural: .2, urban: .5, crew: 1, type: "default"}),
|
||||||
Restore: restoreDefaultUnits,
|
Restore: restoreDefaultUnits,
|
||||||
Cancel: function() {$(this).dialog("close");}
|
Cancel: function() {$(this).dialog("close");}
|
||||||
}, open: function() {
|
}, open: function() {
|
||||||
|
|
@ -215,11 +217,7 @@ function overviewMilitary() {
|
||||||
|
|
||||||
function restoreDefaultUnits() {
|
function restoreDefaultUnits() {
|
||||||
removeUnitLines();
|
removeUnitLines();
|
||||||
[{name:"infantry", rural:.25, urban:.2, crew:1, type:"melee", separate:0},
|
Military.getDefaultOptions().map(u => addUnitLine(u));
|
||||||
{name:"archers", rural:.12, urban:.2, crew:1, type:"ranged", separate:0},
|
|
||||||
{name:"cavalry", rural:.12, urban:.03, crew:3, type:"mounted", separate:0},
|
|
||||||
{name:"artillery", rural:0, urban:.03, crew:8, type:"machinery", separate:0},
|
|
||||||
{name:"fleet", rural:0, urban:.015, crew:100, type:"naval", separate:1}].map(u => addUnitLine(u));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyMilitaryOptions() {
|
function applyMilitaryOptions() {
|
||||||
|
|
@ -236,7 +234,7 @@ function overviewMilitary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function militaryRecalculate() {
|
function militaryRecalculate() {
|
||||||
alertMessage.innerHTML = "Are you sure you want to recalculate military forces for all states?";
|
alertMessage.innerHTML = "Are you sure you want to recalculate military forces for all states?<br>Regiments for all states will be regenerated";
|
||||||
$("#alert").dialog({resizable: false, title: "Remove regiment",
|
$("#alert").dialog({resizable: false, title: "Remove regiment",
|
||||||
buttons: {
|
buttons: {
|
||||||
Recalculate: function() {
|
Recalculate: function() {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
function editRegiment() {
|
function editRegiment(selector) {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
closeDialogs(".stable");
|
closeDialogs(".stable");
|
||||||
// if (!layerIsOn("toggleArmies")) toggleArmies();
|
if (!layerIsOn("toggleMilitary")) toggleMilitary();
|
||||||
|
|
||||||
armies.selectAll(":scope > g").classed("draggable", true);
|
armies.selectAll(":scope > g").classed("draggable", true);
|
||||||
armies.selectAll(":scope > g > g").call(d3.drag().on("drag", dragRegiment));
|
armies.selectAll(":scope > g > g").call(d3.drag().on("drag", dragRegiment));
|
||||||
elSelected = d3.event.target.parentElement; // select g element
|
elSelected = selector ? document.querySelector(selector) : d3.event.target.parentElement; // select g element
|
||||||
if (!pack.states[elSelected.dataset.state]) return;
|
if (!pack.states[elSelected.dataset.state]) return;
|
||||||
if (!regiment()) return;
|
if (!regiment()) return;
|
||||||
updateRegimentData(regiment());
|
updateRegimentData(regiment());
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@
|
||||||
function overviewRegiments(state) {
|
function overviewRegiments(state) {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
closeDialogs(".stable");
|
closeDialogs(".stable");
|
||||||
|
if (!layerIsOn("toggleMilitary")) toggleMilitary();
|
||||||
|
|
||||||
const body = document.getElementById("regimentsBody");
|
const body = document.getElementById("regimentsBody");
|
||||||
updateFilter();
|
updateFilter(state);
|
||||||
addLines();
|
addLines();
|
||||||
$("#regimentsOverview").dialog();
|
$("#regimentsOverview").dialog();
|
||||||
|
|
||||||
|
|
@ -13,21 +14,16 @@ function overviewRegiments(state) {
|
||||||
updateHeaders();
|
updateHeaders();
|
||||||
|
|
||||||
$("#regimentsOverview").dialog({
|
$("#regimentsOverview").dialog({
|
||||||
title: "Regiments Overview", resizable: false, width: fitContent(),
|
title: "Military Overview", resizable: false, width: fitContent(),
|
||||||
position: {my: "center", at: "center", of: "svg"}
|
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
|
||||||
});
|
});
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("regimentsOverviewRefresh").addEventListener("click", addLines);
|
document.getElementById("regimentsOverviewRefresh").addEventListener("click", addLines);
|
||||||
document.getElementById("regimentsPercentage").addEventListener("click", togglePercentageMode);
|
document.getElementById("regimentsPercentage").addEventListener("click", togglePercentageMode);
|
||||||
document.getElementById("regimentsAddNew").addEventListener("click", toggleAddRegiment);
|
document.getElementById("regimentsAddNew").addEventListener("click", toggleAdd);
|
||||||
document.getElementById("regimentsExport").addEventListener("click", downloadRegimentsData);
|
document.getElementById("regimentsExport").addEventListener("click", downloadRegimentsData);
|
||||||
document.getElementById("regimentsFilter").addEventListener("change", filterRegiments);
|
document.getElementById("regimentsFilter").addEventListener("change", addLines);
|
||||||
|
|
||||||
body.addEventListener("click", function(ev) {
|
|
||||||
const el = ev.target, line = el.parentNode, state = +line.dataset.id;
|
|
||||||
//if (el.tagName === "SPAN") showRegimentList(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
// update military types in header and tooltips
|
// update military types in header and tooltips
|
||||||
function updateHeaders() {
|
function updateHeaders() {
|
||||||
|
|
@ -45,6 +41,7 @@ function overviewRegiments(state) {
|
||||||
|
|
||||||
// add line for each state
|
// add line for each state
|
||||||
function addLines() {
|
function addLines() {
|
||||||
|
const state = +regimentsFilter.value;
|
||||||
body.innerHTML = "";
|
body.innerHTML = "";
|
||||||
let lines = "";
|
let lines = "";
|
||||||
const regiments = [];
|
const regiments = [];
|
||||||
|
|
@ -64,7 +61,7 @@ function overviewRegiments(state) {
|
||||||
<input data-tip="Regiment's name" style="width:13em" value="${r.name}" readonly>
|
<input data-tip="Regiment's name" style="width:13em" value="${r.name}" readonly>
|
||||||
${lineData}
|
${lineData}
|
||||||
<div data-type="total" data-tip="Total military personnel (not considering crew)" style="font-weight: bold">${r.a}</div>
|
<div data-type="total" data-tip="Total military personnel (not considering crew)" style="font-weight: bold">${r.a}</div>
|
||||||
<span data-tip="Edit regiment" class="icon-pencil pointer"></span>
|
<span data-tip="Edit regiment" onclick="editRegiment('#regiment${s.i}-${r.i}')" class="icon-pencil pointer"></span>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
regiments.push(r);
|
regiments.push(r);
|
||||||
|
|
@ -86,7 +83,7 @@ function overviewRegiments(state) {
|
||||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => regimentHighlightOff(ev)));
|
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => regimentHighlightOff(ev)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFilter() {
|
function updateFilter(state) {
|
||||||
const filter = document.getElementById("regimentsFilter");
|
const filter = document.getElementById("regimentsFilter");
|
||||||
filter.options.length = 0; // remove all options
|
filter.options.length = 0; // remove all options
|
||||||
filter.options.add(new Option(`all`, -1, false, state === -1));
|
filter.options.add(new Option(`all`, -1, false, state === -1));
|
||||||
|
|
@ -94,11 +91,6 @@ function overviewRegiments(state) {
|
||||||
statesSorted.forEach(s => filter.options.add(new Option(s.name, s.i, false, s.i == state)));
|
statesSorted.forEach(s => filter.options.add(new Option(s.name, s.i, false, s.i == state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterRegiments() {
|
|
||||||
state = +this.value;
|
|
||||||
addLines();
|
|
||||||
}
|
|
||||||
|
|
||||||
function regimentHighlightOn(event) {
|
function regimentHighlightOn(event) {
|
||||||
const state = +event.target.dataset.s;
|
const state = +event.target.dataset.s;
|
||||||
const id = +event.target.dataset.id;
|
const id = +event.target.dataset.id;
|
||||||
|
|
@ -128,7 +120,7 @@ function overviewRegiments(state) {
|
||||||
el.querySelectorAll("div").forEach(function(div) {
|
el.querySelectorAll("div").forEach(function(div) {
|
||||||
const type = div.dataset.type;
|
const type = div.dataset.type;
|
||||||
if (type === "rate") return;
|
if (type === "rate") return;
|
||||||
div.textContent = rn(+el.dataset[type] / total(type) * 100) + "%";
|
div.textContent = total(type) ? rn(+el.dataset[type] / total(type) * 100) + "%" : "0%";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -137,8 +129,35 @@ function overviewRegiments(state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAddRegiment() {
|
function toggleAdd() {
|
||||||
|
document.getElementById("regimentsAddNew").classList.toggle("pressed");
|
||||||
|
if (document.getElementById("regimentsAddNew").classList.contains("pressed")) {
|
||||||
|
viewbox.style("cursor", "crosshair").on("click", addRegimentOnClick);
|
||||||
|
tip("Click on map to create new regiment or fleet", true);
|
||||||
|
if (regimentAdd.offsetParent) regimentAdd.classList.add("pressed");
|
||||||
|
} else {
|
||||||
|
clearMainTip();
|
||||||
|
viewbox.on("click", clicked).style("cursor", "default");
|
||||||
|
addLines();
|
||||||
|
if (regimentAdd.offsetParent) regimentAdd.classList.remove("pressed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRegimentOnClick() {
|
||||||
|
const state = +regimentsFilter.value;
|
||||||
|
if (state === -1) {tip("Please select state from the list", false, "error"); return;}
|
||||||
|
|
||||||
|
const point = d3.mouse(this);
|
||||||
|
const cell = findCell(point[0], point[1]);
|
||||||
|
const x = pack.cells.p[cell][0], y = pack.cells.p[cell][1];
|
||||||
|
const military = pack.states[state].military;
|
||||||
|
const i = military.length ? last(military).i + 1 : 0;
|
||||||
|
const n = +(pack.cells.h[cell] < 20); // naval or land
|
||||||
|
const reg = {a:0, cell, i, n, u:{}, x, y, icon:"🛡️"};
|
||||||
|
reg.name = Military.getName(reg, military);
|
||||||
|
military.push(reg);
|
||||||
|
Military.drawRegiment(reg, state);
|
||||||
|
toggleAdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadRegimentsData() {
|
function downloadRegimentsData() {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -64,6 +64,7 @@ function processFeatureRegeneration(event, button) {
|
||||||
if (button === "regenerateStates") regenerateStates(); else
|
if (button === "regenerateStates") regenerateStates(); else
|
||||||
if (button === "regenerateProvinces") regenerateProvinces(); else
|
if (button === "regenerateProvinces") regenerateProvinces(); else
|
||||||
if (button === "regenerateReligions") regenerateReligions(); else
|
if (button === "regenerateReligions") regenerateReligions(); else
|
||||||
|
if (button === "regenerateMilitary") regenerateMilitary(); else
|
||||||
if (button === "regenerateMarkers") regenerateMarkers(event); else
|
if (button === "regenerateMarkers") regenerateMarkers(event); else
|
||||||
if (button === "regenerateZones") regenerateZones(event);
|
if (button === "regenerateZones") regenerateZones(event);
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +239,12 @@ function regenerateReligions() {
|
||||||
if (!layerIsOn("toggleReligions")) toggleReligions(); else drawReligions();
|
if (!layerIsOn("toggleReligions")) toggleReligions(); else drawReligions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function regenerateMilitary() {
|
||||||
|
Military.generate();
|
||||||
|
if (!layerIsOn("toggleMilitary")) toggleMilitary();
|
||||||
|
if (document.getElementById("militaryOverviewRefresh").offsetParent) militaryOverviewRefresh.click();
|
||||||
|
}
|
||||||
|
|
||||||
function regenerateMarkers(event) {
|
function regenerateMarkers(event) {
|
||||||
let number = gauss(1, .5, .3, 5, 2);
|
let number = gauss(1, .5, .3, 5, 2);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue