mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
Merge 585f3c34b1 into f73a8906ce
This commit is contained in:
commit
1bd6685a1d
47 changed files with 5095 additions and 1837 deletions
24
index.css
24
index.css
|
|
@ -19,6 +19,11 @@ font {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
form input:invalid {
|
||||
outline: 1px solid #ed4337;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
button {
|
||||
|
|
@ -53,6 +58,7 @@ input:read-only {
|
|||
input[type="radio"] {
|
||||
vertical-align: bottom;
|
||||
cursor: pointer;
|
||||
accent-color: var(--header);
|
||||
}
|
||||
|
||||
textarea {
|
||||
|
|
@ -1506,12 +1512,6 @@ div.states > select {
|
|||
appearance: none;
|
||||
}
|
||||
|
||||
div.states > .burgName,
|
||||
div.states > .burgState,
|
||||
div.states > .burgCulture {
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
div.states span.inactive {
|
||||
color: #c6c2c2;
|
||||
}
|
||||
|
|
@ -1893,10 +1893,11 @@ div.editorLine {
|
|||
}
|
||||
|
||||
#militaryOptionsTable input[type="number"] {
|
||||
width: 4em;
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
#militaryOptionsTable button {
|
||||
#militaryOptionsTable button,
|
||||
#burgGroupsBody button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
@ -1929,7 +1930,12 @@ ul.share-buttons img {
|
|||
width: 2em;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
input[type="checkbox"].native {
|
||||
accent-color: var(--header);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:not(.native) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
408
index.html
408
index.html
|
|
@ -646,14 +646,6 @@
|
|||
>
|
||||
Emblems
|
||||
</li>
|
||||
<li
|
||||
id="toggleLabels"
|
||||
data-tip="Labels: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
||||
data-shortcut="L"
|
||||
onclick="toggleLabels(event)"
|
||||
>
|
||||
<u>L</u>abels
|
||||
</li>
|
||||
<li
|
||||
id="toggleBurgIcons"
|
||||
data-tip="Burg icons: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
||||
|
|
@ -662,6 +654,14 @@
|
|||
>
|
||||
<u>I</u>cons
|
||||
</li>
|
||||
<li
|
||||
id="toggleLabels"
|
||||
data-tip="Labels: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
||||
data-shortcut="L"
|
||||
onclick="toggleLabels(event)"
|
||||
>
|
||||
<u>L</u>abels
|
||||
</li>
|
||||
<li
|
||||
id="toggleMilitary"
|
||||
data-tip="Military forces: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
||||
|
|
@ -1057,6 +1057,61 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id="styleBurgIcons">
|
||||
<tr data-tip="Select group icon">
|
||||
<td>Icon</td>
|
||||
<td>
|
||||
<select id="styleBurgIconsIcon">
|
||||
<option value="#icon-circle">Circle</option>
|
||||
<option value="#icon-square">Square</option>
|
||||
<option value="#icon-triangle">Triangle</option>
|
||||
<option value="#icon-cross">Cross</option>
|
||||
<option value="#icon-star">Star</option>
|
||||
<option value="#icon-circled">Circled</option>
|
||||
<option value="#icon-squared">Squared</option>
|
||||
<option value="#icon-star-circled">Star circled</option>
|
||||
<option value="#icon-star-circled-empty">Star circled empty</option>
|
||||
<option value="#icon-star-squared">Star squared</option>
|
||||
<option value="#icon-watabou-capital">Watabou capital</option>
|
||||
<option value="#icon-watabou-city">Watabou city</option>
|
||||
<option value="#icon-watabou-town">Watabou town</option>
|
||||
<option value="#icon-watabou-village">Watabou village</option>
|
||||
<option value="#icon-watabou-hamlet">Watabou hamlet</option>
|
||||
<option value="#icon-watabou-fort">Watabou fort</option>
|
||||
<option value="#icon-watabou-monastery">Watabou monastery</option>
|
||||
<option value="#icon-watabou-caravanserai">Watabou caravanserai</option>
|
||||
<option value="#icon-watabou-post">Watabou trade post</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set icon size">
|
||||
<td>Icon size</td>
|
||||
<td>
|
||||
<slider-input id="styleBurgIconsIconSize" min="0.01" max="20" step=".01"></slider-input>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set icon stroke linejoin"></tr>
|
||||
<td>Stroke linejoin</td>
|
||||
<td>
|
||||
<select id="styleBurgIconsStrokeLinejoin">
|
||||
<option value="inherit" selected>Inherit</option>
|
||||
<option value="butt">Butt</option>
|
||||
<option value="round">Round</option>
|
||||
<option value="square">Square</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Define transparency of fill color">
|
||||
<td>Fill opacity</td>
|
||||
<td>
|
||||
<slider-input id="styleBurgIconsFillOpacity" min="0" max="1" step=".01"></slider-input>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id="styleGrid">
|
||||
<tr data-tip="Select grid overlay type">
|
||||
<td>Type</td>
|
||||
|
|
@ -1175,7 +1230,7 @@
|
|||
<tr data-tip="Set stroke width">
|
||||
<td>Stroke width</td>
|
||||
<td>
|
||||
<slider-input id="styleStrokeWidthInput" min="0" max="5" step=".01"></slider-input>
|
||||
<slider-input id="styleStrokeWidthInput" min="0" max="10" step=".01"></slider-input>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -1184,7 +1239,7 @@
|
|||
<tr data-tip="Set letter spacing">
|
||||
<td>Letter spacing</td>
|
||||
<td>
|
||||
<slider-input id="styleLetterSpacingInput" min="0" max="20" step=".01"></slider-input>
|
||||
<slider-input id="styleLetterSpacingInput" min="-1" max="10" step=".01"></slider-input>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -1208,7 +1263,7 @@
|
|||
<tr data-tip="Set text shadow">
|
||||
<td>Text shadow</td>
|
||||
<td>
|
||||
<input id="styleShadowInput" type="text" value="0 0 4px white" />
|
||||
<input id="styleShadowInput" type="text" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -1234,24 +1289,12 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id="styleRadius">
|
||||
<tr data-tip="Set icon size">
|
||||
<td>Radius</td>
|
||||
<tbody id="styleFontShift">
|
||||
<tr data-tip="Set label shift along X and Y axes">
|
||||
<td>Label shift</td>
|
||||
<td>
|
||||
<button id="styleRadiusPlus" data-tip="Multiply radius by 1.1" class="whiteButton">+</button>
|
||||
<button id="styleRadiusMinus" data-tip="Multiply radius by 1.1" class="whiteButton">-</button>
|
||||
<input id="styleRadiusInput" type="number" min=".2" max="10" step=".02" value="1" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id="styleIconSize">
|
||||
<tr data-tip="Set icon size">
|
||||
<td>Size</td>
|
||||
<td>
|
||||
<button id="styleIconSizePlus" data-tip="Multiply size by 1.1" class="whiteButton">+</button>
|
||||
<button id="styleIconSizeMinus" data-tip="Multiply size by 1.1" class="whiteButton">-</button>
|
||||
<input id="styleIconSizeInput" type="number" min=".2" max="10" step=".02" value="1" />
|
||||
<input id="styleFontShiftX" data-tip="Set label shift along Y axis" type="number" min="-5" max="5" step=".01" />
|
||||
<input id="styleFontShiftY" data-tip="Set label shift along Y axis" type="number" min="-5" max="5" step=".01" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -1707,11 +1750,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Define a number of towns to be placed (if enough suitable land exists)">
|
||||
<tr data-tip="Define a number of non-capital settlements to be placed (if enough suitable land exists)">
|
||||
<td>
|
||||
<i data-locked="0" id="lock_manors" class="icon-lock-open"></i>
|
||||
</td>
|
||||
<td>Towns number</td>
|
||||
<td>Burgs number</td>
|
||||
<td>
|
||||
<input id="manorsInput" data-stored="manors" type="range" min="0" max="1000" step="1" value="1000" />
|
||||
</td>
|
||||
|
|
@ -3373,6 +3416,12 @@
|
|||
></span>
|
||||
</div>
|
||||
|
||||
<div data-tip="Select burg group. Groups defines burg icon, label size and style">
|
||||
<div class="label">Group:</div>
|
||||
<select id="burgGroup" style="width: 9em"></select>
|
||||
<span id="burgGroupConfigure" data-tip="Configure burg groups" class="icon-cog pointer"></span>
|
||||
</div>
|
||||
|
||||
<div data-tip="Select burg type. Type slightly affects emblem generation">
|
||||
<div class="label">Type:</div>
|
||||
<select id="burgType" style="width: 9em">
|
||||
|
|
@ -3477,12 +3526,6 @@
|
|||
<div style="display: flex; justify-content: space-between">
|
||||
<span>Burg preview:</span>
|
||||
<div style="display: flex; gap: 0.5em">
|
||||
<i
|
||||
id="burgLinkEdit"
|
||||
data-tip="Provide custom link to the burg map"
|
||||
class="icon-pencil pointer"
|
||||
style="margin-top: -0.1em"
|
||||
></i>
|
||||
<i id="burgLinkOpen" data-tip="Open burg map in a new tab" class="icon-link-ext pointer"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3491,20 +3534,6 @@
|
|||
</div>
|
||||
|
||||
<div id="burgBottom">
|
||||
<button id="burgGroupShow" data-tip="Show group change section" class="icon-tags"></button>
|
||||
<div id="burgGroupSection" style="display: none">
|
||||
<button id="burgGroupHide" data-tip="Hide group change section" class="icon-tags"></button>
|
||||
<select id="burgSelectGroup" data-tip="Select a group for this burg" style="width: 10em"></select>
|
||||
<input
|
||||
id="burgInputGroup"
|
||||
placeholder="new group name"
|
||||
data-tip="Create a new Group for the Burg"
|
||||
style="display: none; width: 10em"
|
||||
/>
|
||||
<i id="burgAddGroup" data-tip="Create a new group for the burg" class="icon-plus pointer"></i>
|
||||
<i id="burgRemoveGroup" data-tip="Remove selected burg group" class="icon-trash pointer"></i>
|
||||
</div>
|
||||
|
||||
<button id="burgStyleShow" data-tip="Show style edit section" class="icon-brush"></button>
|
||||
<div id="burgStyleSection" style="display: none">
|
||||
<button id="burgStyleHide" data-tip="Hide style edit section" class="icon-brush"></button>
|
||||
|
|
@ -3526,7 +3555,7 @@
|
|||
</div>
|
||||
|
||||
<button id="burgEditEmblem" data-tip="Edit emblem" class="icon-shield-alt"></button>
|
||||
<button id="burgTogglePreview" data-tip="Toggle preview" class="icon-map"></button>
|
||||
<button id="burgSetPreviewLink" data-tip="Set custom burg map URL" class="icon-map-o"></button>
|
||||
<button id="burgLocate" data-tip="Zoom map and center view in the burg" class="icon-target"></button>
|
||||
<button
|
||||
id="burgRelocate"
|
||||
|
|
@ -5266,7 +5295,7 @@
|
|||
</slider-input>
|
||||
</div>
|
||||
|
||||
<div data-tip="Set urbanization rate: burgs population relative to all population">
|
||||
<div data-tip="Set urban population modifier. Change to increase or descrese burgs population">
|
||||
<slider-input id="urbanizationInput" data-stored="urbanization" min=".01" max="5" step=".01" value="1">
|
||||
<label>Urbanization rate:</label>
|
||||
</slider-input>
|
||||
|
|
@ -5309,7 +5338,7 @@
|
|||
</div>
|
||||
|
||||
<div id="burgsOverview" class="dialog stable" style="display: none">
|
||||
<div id="burgsHeader" class="header" style="grid-template-columns: 8em 6em 6em 6em 8em 6em">
|
||||
<div id="burgsHeader" class="header" style="grid-template-columns: 9em 7em 7.5em 7.2em 6.5em 7em 6em">
|
||||
<div data-tip="Click to sort by burg name" class="sortable alphabetically" data-sortby="name">Burg</div>
|
||||
<div data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="province">
|
||||
Province
|
||||
|
|
@ -5318,6 +5347,7 @@
|
|||
<div data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="culture">
|
||||
Culture
|
||||
</div>
|
||||
<div data-tip="Click to sort by culture group" class="sortable alphabetically" data-sortby="group">Group</div>
|
||||
<div
|
||||
data-tip="Click to sort by burg population"
|
||||
class="sortable icon-sort-number-down"
|
||||
|
|
@ -5352,6 +5382,7 @@
|
|||
|
||||
<div id="burgsBottom">
|
||||
<button id="burgsOverviewRefresh" data-tip="Refresh the Editor" class="icon-cw"></button>
|
||||
<button id="burgsGroupsEditorButton" data-tip="Edit burg groups" class="icon-cog"></button>
|
||||
<button id="burgsChart" data-tip="Show burgs bubble chart" class="icon-chart-area"></button>
|
||||
<button
|
||||
id="regenerateBurgNames"
|
||||
|
|
@ -5374,6 +5405,37 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="burgGroupsEditor" class="dialog stable" style="display: none">
|
||||
<form id="burgGroupsForm">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-tip="Rendering order: higher values are rendered on top">Order</th>
|
||||
<th data-tip="Type group name">Name</th>
|
||||
<th data-tip="Burg preview generator">Preview generator</th>
|
||||
<th data-tip="Set min population constraint" colspan="2">Population</th>
|
||||
<th
|
||||
data-tip="Set population percentile: 0-100, where 90 means the burg must have a population higher than 90% of all burgs"
|
||||
>
|
||||
Percentile
|
||||
</th>
|
||||
<th data-tip="Select allowed biomes">Biomes</th>
|
||||
<th data-tip="Select allowed states">States</th>
|
||||
<th data-tip="Select allowed cultures">Cultures</th>
|
||||
<th data-tip="Select allowed religions">Religions</th>
|
||||
<th data-tip="Select allowed features">Features</th>
|
||||
<th data-tip="Number of burgs in group">Count</th>
|
||||
<th data-tip="Activate/deactivate group">Active</th>
|
||||
<th data-tip="Select group to be assigned if burg doesn't pass the criteria for other groups">
|
||||
Default
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="burgGroupsBody"></tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="routesOverview" class="dialog stable" style="display: none">
|
||||
<div id="routesHeader" class="header" style="grid-template-columns: 17em 8em 8em">
|
||||
<div data-tip="Click to sort by route name" class="sortable alphabetically" data-sortby="name">
|
||||
|
|
@ -5931,6 +5993,11 @@
|
|||
>
|
||||
</div>
|
||||
|
||||
<div data-tip="Toggle wireframe mode" style="margin: 0.6em 0 0.3em -0.2em">
|
||||
<input id="options3dMeshWireframeMode" class="checkbox" type="checkbox" />
|
||||
<label for="options3dMeshWireframeMode" class="checkbox-label"><i>Show wireframe</i></label>
|
||||
</div>
|
||||
|
||||
<div data-tip="Set sky and water color" id="options3dColorSection" style="display: none">
|
||||
<span>Sky:</span
|
||||
><input
|
||||
|
|
@ -6230,7 +6297,7 @@
|
|||
<input type="file" accept=".csv" id="culturesCSVToLoad" />
|
||||
</div>
|
||||
|
||||
<!-- svg elements not required for map display -->
|
||||
<!-- reusable svg elements -->
|
||||
<svg id="defElements" width="0" height="0" style="position: absolute">
|
||||
<defs>
|
||||
<marker id="end-arrow" viewBox="0 -5 10 10" refX="6" markerWidth="7" markerHeight="7" orient="auto">
|
||||
|
|
@ -6240,25 +6307,6 @@
|
|||
<path d="M0,-5L10,0L0,5" fill="#555" />
|
||||
</marker>
|
||||
|
||||
<symbol id="icon-store" viewBox="0 0 616 512">
|
||||
<path
|
||||
d="M602 118.6L537.1 15C531.3 5.7 521 0 510 0H106C95 0 84.7 5.7 78.9 15L14 118.6c-33.5 53.5-3.8 127.9 58.8 136.4 4.5.6 9.1.9 13.7.9 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18.1 20.1 44.3 33.1 73.8 33.1 4.7 0 9.2-.3 13.7-.9 62.8-8.4 92.6-82.8 59-136.4zM529.5 288c-10 0-19.9-1.5-29.5-3.8V384H116v-99.8c-9.6 2.2-19.5 3.8-29.5 3.8-6 0-12.1-.4-18-1.2-5.6-.8-11.1-2.1-16.4-3.6V480c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32V283.2c-5.4 1.6-10.8 2.9-16.4 3.6-6.1.8-12.1 1.2-18.2 1.2z"
|
||||
/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-anchor" viewBox="0 0 30 28">
|
||||
<title>Port</title>
|
||||
<path
|
||||
d="M15 4c0-0.547-0.453-1-1-1s-1 0.453-1 1 0.453 1 1 1 1-0.453 1-1zM28 18.5v5.5c0 0.203-0.125 0.391-0.313 0.469-0.063 0.016-0.125 0.031-0.187 0.031-0.125 0-0.25-0.047-0.359-0.141l-1.453-1.453c-2.453 2.953-6.859 4.844-11.688 4.844s-9.234-1.891-11.688-4.844l-1.453 1.453c-0.094 0.094-0.234 0.141-0.359 0.141-0.063 0-0.125-0.016-0.187-0.031-0.187-0.078-0.313-0.266-0.313-0.469v-5.5c0-0.281 0.219-0.5 0.5-0.5h5.5c0.203 0 0.391 0.125 0.469 0.313s0.031 0.391-0.109 0.547l-1.563 1.563c1.406 1.891 4.109 3.266 7.203 3.687v-10.109h-3c-0.547 0-1-0.453-1-1v-2c0-0.547 0.453-1 1-1h3v-2.547c-1.188-0.688-2-1.969-2-3.453 0-2.203 1.797-4 4-4s4 1.797 4 4c0 1.484-0.812 2.766-2 3.453v2.547h3c0.547 0 1 0.453 1 1v2c0 0.547-0.453 1-1 1h-3v10.109c3.094-0.422 5.797-1.797 7.203-3.687l-1.563-1.563c-0.141-0.156-0.187-0.359-0.109-0.547s0.266-0.313 0.469-0.313h5.5c0.281 0 0.5 0.219 0.5 0.5z"
|
||||
/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-route" viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M416 320h-96c-17.6 0-32-14.4-32-32s14.4-32 32-32h96s96-107 96-160-43-96-96-96-96 43-96 96c0 25.5 22.2 63.4 45.3 96H320c-52.9 0-96 43.1-96 96s43.1 96 96 96h96c17.6 0 32 14.4 32 32s-14.4 32-32 32H185.5c-16 24.8-33.8 47.7-47.3 64H416c52.9 0 96-43.1 96-96s-43.1-96-96-96zm0-256c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zM96 256c-53 0-96 43-96 96s96 160 96 160 96-107 96-160-43-96-96-96zm0 128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"
|
||||
/>
|
||||
</symbol>
|
||||
|
||||
<g id="defs-relief">
|
||||
<symbol id="relief-mount-1" viewBox="0 0 100 100">
|
||||
<path d="m3,69 16,-12 31,-32 15,20 30,24" fill="#fff" stroke="#5c5c70" stroke-width="1" />
|
||||
|
|
@ -7800,6 +7848,214 @@
|
|||
</symbol>
|
||||
</g>
|
||||
|
||||
<g id="defs-icons">
|
||||
<symbol id="icon-circle" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<circle cx="0" cy="0" r="5" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-square" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<rect x="-5" y="-5" width="10" height="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-triangle" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<polygon points="0,-5 5,5 -5,5" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-cross" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<polygon points="-1.5,-5 1.5,-5 1.5,-1.5 5,-1.5 5,1.5 1.5,1.5 1.5,5 -1.5,5 -1.5,1.5 -5,1.5 -5,-1.5 -1.5,-1.5" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-star" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<polygon points="0,-5 1.5,-1.5 5,-1.5 2,1.5 3,5 0,3 -3,5 -2,1.5 -5,-1.5 -1.5,-1.5" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-circled" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<circle cx="0" cy="0" r="5" />
|
||||
<circle cx="0" cy="0" r="1" stroke-width="4.4"></circle>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-squared" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<rect x="-5" y="-5" width="10" height="10" />
|
||||
<rect x="-1" y="-1" width="2" height="2" stroke-width="4.5"></rect>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-star-circled" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<circle cx="0" cy="0" r="5" />
|
||||
<polygon points="0,-5 1.5,-1.5 5,-1.5 2,1.5 3,5 0,3 -3,5 -2,1.5 -5,-1.5 -1.5,-1.5" transform="scale(0.38 0.38)" stroke-width="5"></polygon>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-star-circled-empty" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<circle cx="0" cy="0" r="5" />
|
||||
<polygon points="0,-5 1.5,-1.5 5,-1.5 2,1.5 3,5 0,3 -3,5 -2,1.5 -5,-1.5 -1.5,-1.5" transform="scale(0.78 0.78)" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-star-squared" viewBox="0 0 10 10" width="1em" height="1em" overflow="visible">
|
||||
<rect x="-5" y="-5" width="10" height="10" />
|
||||
<polygon points="0,-5 1.5,-1.5 5,-1.5 2,1.5 3,5 0,3 -3,5 -2,1.5 -5,-1.5 -1.5,-1.5" transform="scale(0.78 0.78)" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-capital" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(-60 -194) scale(2 2)">
|
||||
<path fill="#EBE8DF" d="M26 90H13l1.3-37.3-1-1v-16h12.6v16l-1 1L26 90"/>
|
||||
<path d="m19.5 12 1.3 6.9 1 3.8 1 3 1.5 3.6 3.1 6.4H11.6l3.1-6.4 1.5-3.6 1-3 1-3.8 1.3-7"/>
|
||||
<path fill="#4D3F36" d="M19.5 10.4V5.6L21.3 4l1-.3 1 .5.9 1 1 1.7.9 1 .9.5.9-.3.9-.8.7-.5.8-.2.6.2.5.5.6.4.7.3 1 .1h1.8l-1.8.6-1 .1H32l-.6-.2L31 8h-.6l-.8.4-.7.7-1 1.1-.8.5-1-.1-.9-.8-1-1.4-.9-.7-.9-.2-1 .6-1.8 2.2"/>
|
||||
<path fill="#4D3F36" d="M19.5 12V5.5"/>
|
||||
<path fill="#4D3F36" d="M17.2 46h1.6V42l-.3-.6h-1l-.3.6v4"/>
|
||||
<path fill="#EBE8DF" d="M41.7 90H31.2l1-24.5-.8-.9v-16h10.1v16l-.8.9 1 24.5"/>
|
||||
<path d="m36.5 29.7 1 5.6.8 3 .8 2.4 1.2 2.9 2.5 5H30.2l2.5-5 1.2-3 .8-2.3.7-3 1-5.6"/>
|
||||
<path fill="#4D3F36" d="M36.5 28.2v-4.8l1.5-2 .9-.4.7.4.6 1 .7 1.7.7 1.1.8.5.7-.1.8-.7 1-.4h1l1 .2 1.2.5 1 .4 1 .3h2.4l-1.5.5-1 .2h-1.9l-1.2-.3-1 .1-1 .4-1 .7-.8.9-.7.3-.8-.2-.7-1-.7-1.4-.6-.8-.7-.2-.9.7-1.5 2.4"/>
|
||||
<path fill="#4D3F36" d="M36.5 29.7v-6.3"/>
|
||||
<path fill="#4D3F36" d="M34 59h1.6V55l-.3-.7h-1l-.3.7V59"/>
|
||||
<path fill="#4D3F36" d="M47.6 88.8h1.6v-4.1l-.4-.7h-1l-.2.7v4.1"/>
|
||||
<path fill="#EBE8DF" d="M14.8 94.6H1.5L2 84.4 8.3 73l6.3 11.4.2 10.2m8.3 0h-8.3l-.2-10.2L8.3 73l2 .4h4l2-.4 6.3 11.4.5 10.2"/>
|
||||
<path d="M22.6 84.4h-8L8.3 73l2 .4h4l2-.4 6.3 11.4"/>
|
||||
<path fill="#4D3F36" d="M9.5 94.6H7V89l.5-1H9l.5 1v5.5"/>
|
||||
<path fill="#EBE8DF" d="M50.4 95.3H33.1l.5-10.4L42 70l8.3 15 .2 10.3m8.3 0h-8.3l-.2-10.4L41.9 70l2 .5 2 .1 2-.1 2-.5 8.3 15 .5 10.3"/>
|
||||
<path d="M58.2 85h-8l-8.3-15 2 .5 2 .1 2-.1 2-.5 8.3 15"/>
|
||||
<path fill="#4D3F36" d="M43 95.3h-2.3v-5.5l.5-1h1.4l.5 1v5.5"/>
|
||||
<path fill="#EBE8DF" d="M27.9 97.3H13.4l1-19.8L21 65.8l6.5 11.7.5 19.8m8.5 0h-8.5l-.5-19.8-6.5-11.7 2 .4 2 .1 2-.1 2-.4 6.5 11.7 1 19.8"/>
|
||||
<path d="M35.4 77.5h-8l-6.5-11.7 2 .4 2 .1 2-.1 2-.4 6.5 11.7"/>
|
||||
<path fill="#4D3F36" d="m21.6 77.1.1.4-.1.4-.3.3-.4.1h-.4l-.3-.4v-.8l.3-.3h.8l.3.3"/>
|
||||
<path fill="#4D3F36" d="M22.1 97.3h-2.4v-5.5l.5-1h1.4l.5 1v5.5"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-city" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(-60 -150) scale(2 2)">
|
||||
<path fill="#EBE8DF" d="M29.5 70H18L19 48.7l-.9-.9v-16h11v16l-.8 1L29.5 70"/>
|
||||
<path d="m23.7 11 1.2 6.2.8 3.3 1 2.6 1.2 3.1 2.8 5.6H16.8l2.8-5.6 1.3-3.1.9-2.6.8-3.3 1.1-6.1"/>
|
||||
<path fill="#4D3F36" d="M23.7 9.6V4.8l1.4-.7h.9l.8.3 1 .7 1.1 1 1 .6.9.2.7-.4.6-.7.7-.4h.7l.7.3.8.8.8.5.9.3h1l2-.1-2 .8-1 .2h-.9l-.8-.3-.8-.5-.7-.1-.7.2-.7.6-.6 1-.7.5h-.9l-1-.2-1-.7-1-.4-1-.1-.8.3-1.4 1M23.7 11V4.9M23 42.2h1.5v-4.1l-.3-.7h-1l-.3.7v4.1"/>
|
||||
<path fill="#EBE8DF" d="M19 71.2H1.5L2 63l4-15 4.2.4 4.2.1 4.2-.1 4.1-.5-4 15 .2 8.3M2 63h16.7m8.4 8.2H19l-.2-8.2 4-15 4 15 .4 8.2"/>
|
||||
<path d="M18.7 63H2l4-15 4.2.4 4.2.1 4.2-.1 4.1-.5-4 15"/>
|
||||
<path fill="#4D3F36" d="M9.6 69.5h1.6v-4.2l-.3-.6h-1l-.3.6v4.2"/>
|
||||
<path fill="#EBE8DF" d="M49.4 71.8H32.5l.5-8.9 4-14.6 4 .5 4.1.1 4-.1 4.1-.5-4 14.6.2 8.9M33 62.9h16.2m8.5 8.9h-8.3l-.2-8.9 4-14.6 4 14.6.5 8.9"/>
|
||||
<path d="M49.2 63H33l4-14.7 4 .5 4.1.1 4-.1 4.1-.5-4 14.6"/>
|
||||
<path fill="#4D3F36" d="M40.3 69.8h1.6v-4.2l-.3-.6h-1l-.3.6v4.2"/>
|
||||
<path fill="#EBE8DF" d="M32.6 75.3H15.9l1-19 7.6-13.6 7.6 13.6.5 19m8.5 0h-8.5l-.5-19-7.6-13.6 2 .4 2 .1 2-.1 2-.5 7.6 13.8 1 19"/>
|
||||
<path d="M40.1 56.4h-8l-7.6-13.8 2 .5 2 .1 2-.1 2-.5 7.6 13.8"/>
|
||||
<path fill="#4D3F36" d="m25.2 56 .1.4-.1.4-.3.2-.4.1h-.4l-.3-.4-.1-.4.1-.3.3-.3.4-.2.4.2.3.3M25.7 75.3h-2.4V70l.5-1h1.4l.5 1v5.4"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-town" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(0 -10) scale(2 2)">
|
||||
<path fill="#EBE8DF" d="M18.9-2H2.6l.5-9 7.8-14 7.8 14 .2 9M27-2H19l-.2-9-7.8-14 2 .4 2 .1 2-.1 2-.5 7.8 14L27-2 Z"/>
|
||||
<path d="M26.7-11h-8l-7.8-14 2 .4 2 .1 2-.1 2-.5 7.8 14"/>
|
||||
<path fill="#4D3F36" stroke="none" d="M12-2H9.8v-5.4l.4-1h1.5l.5 1V-2"/>
|
||||
<path fill="#EBE8DF" d="M-10.3.4h-19.6l.4-8 4-17.2 4.8.5 4.7.2 4.8-.2 4.7-.5-4 17.1.2 8m-19.2-8h19m8.4 8h-8.2l-.2-8 4-17 4 17 .4 8Z"/>
|
||||
<path d="M-10.5-7.7h-19l4-17 4.8.4 4.7.2 4.8-.2 4.7-.5-4 17.1"/>
|
||||
<path fill="#4D3F36" stroke="none" d="M-24-1.3h1.7v-4.1l-.4-.7h-1l-.2.7v4.1"/>
|
||||
<path fill="#EBE8DF" d="M-1.4 5H-17l.8-15 7.2-13.1 7.3 13 .4 15.2M7 5h-8.4L-1.8-10-9-23.1l2 .3 2 .2 2-.2 2-.3 7.3 13L7 4 Z"/>
|
||||
<path d="M6.2-10h-8L-9-23.1l2 .3 2 .2 2-.2 2-.3 7.3 13"/>
|
||||
<path fill="#4D3F36" stroke="none" d="M-7.9 5h-2.4V-.3l.5-1h1.5l.4 1v5.5"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-village" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(0 -6) scale(2 2)">
|
||||
<path d="M 9.778,-3.849 L -3.296,-3.849 L -2.723,-15.318 L 3.384,-26.311 L 9.491,-15.318 L 9.778,-3.849 M 18.065,-3.849 L 9.778,-3.849 L 9.491,-15.318 L 3.384,-26.311 L 5.384,-25.981 L 7.384,-25.871 L 9.384,-25.981 L 11.384,-26.311 L 17.491,-15.318 L 18.065,-3.849" fill="#EBE8DF" />
|
||||
<path d="M 17.491,-15.318 L 9.491,-15.318 L 3.384,-26.311 L 5.384,-25.981 L 7.384,-25.871 L 9.384,-25.981 L 11.384,-26.311 L 17.491,-15.318"/>
|
||||
<path d="M 4.584,-3.849 L 2.184,-3.849 L 2.184,-9.289 L 2.664,-10.249 L 4.104,-10.249 L 4.584,-9.289 L 4.584,-3.849" fill="#4D3F36"/>
|
||||
<path d="M -5.555,2.988 L -20.357,2.988 L -19.872,-6.711 L -15.872,-19.379 L -12.354,-18.999 L -8.835,-18.872 L -5.316,-18.999 L -1.797,-19.379 L -5.797,-6.711 L -5.555,2.988 M -19.872,-6.711 L -5.797,-6.711 M 2.688,2.988 L -5.555,2.988 L -5.797,-6.711 L -1.797,-19.379 L 2.203,-6.711 L 2.688,2.988" fill="#EBE8DF" />
|
||||
<path d=" M -5.797,-6.711 L -19.872,-6.711 L -15.872,-19.379 L -12.354,-18.999 L -8.835,-18.872 L -5.316,-18.999 L -1.797,-19.379 L -5.797,-6.711"/>
|
||||
<path d="M -13.635,0.539 L -12.035,0.539 L -12.035,-3.621 L -12.355,-4.261 L -13.315,-4.261 L -13.635,-3.621 L -13.635,0.539" fill="#4D3F36"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-hamlet" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(-120 -95) scale(2 2)">
|
||||
<path fill="#EBE8DF" d="M63 48H48.6l.4-8.7 6.8-12.2 6.8 12.2.2 8.7m8.3 0h-8.3l-.2-8.7L56 27.1l2 .3 2 .2 2-.2 2-.3 6.8 12.2.5 8.7"/>
|
||||
<path d="M70.7 39.3h-8L56 27.1l2 .3 2 .2 2-.2 2-.3 6.8 12.2"/>
|
||||
<path fill="#4D3F36" d="M57.1 48h-2.4v-5.4l.5-1h1.4l.5 1V48"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-fort" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(0 0) scale(2 1.6)">
|
||||
<path fill="#EBE8DF" d="M 4.439,0 L -18.531,0 L -18.994,-61.849 L 4.902,-61.849 L 4.439,0 Z"/>
|
||||
<path fill="#EBE8DF" d="M 19.103,0 L 1.283,0 L 0.924,-45.875 L 19.462,-45.875 L 19.103,0 Z"/>
|
||||
<path d="M 10.193,-49.907 L 10.193,-54.973 L 11.638,-55.519 L 12.545,-55.52 L 13.396,-55.159 L 14.352,-54.496 L 15.413,-53.531 L 16.454,-52.885 L 17.476,-52.559 L 18.478,-52.553 L 19.462,-52.865 L 20.367,-53.044 L 21.194,-53.089 L 22.112,-52.943 L 23.623,-52.44 L 22.112,-52.373 L 21.194,-52.173 L 20.367,-51.816 L 19.462,-51.296 L 18.478,-50.612 L 17.476,-50.241 L 16.454,-50.181 L 15.413,-50.434 L 14.352,-50.999 L 13.396,-51.301 L 12.545,-51.342 L 11.638,-50.998 L 10.193,-49.907"/>
|
||||
<path fill="#EBE8DF" d="M 10.193,-45.875 L 10.193,-54.973"/>
|
||||
<g stroke-width="0.6" stroke-linecap="mitter" fill="#4D3F36">
|
||||
<path d="M -16.365,-58.727 L -16.365,-61.849 L -14.796,-61.849 L -14.796,-58.727 L -16.365,-58.727 Z"/>
|
||||
<path d="M -12.951,-58.727 L -12.951,-61.849 L -11.382,-61.849 L -11.382,-58.727 L -12.951,-58.727 Z"/>
|
||||
<path d="M -9.538,-58.727 L -9.538,-61.849 L -7.968,-61.849 L -7.968,-58.727 L -9.538,-58.727 Z"/>
|
||||
<path d="M -6.124,-58.727 L -6.124,-61.849 L -4.554,-61.849 L -4.554,-58.727 L -6.124,-58.727 Z"/>
|
||||
<path d="M -2.71,-58.727 L -2.71,-61.849 L -1.141,-61.849 L -1.141,-58.727 L -2.71,-58.727 Z"/>
|
||||
<path d="M 0.704,-58.727 L 0.704,-61.849 L 2.273,-61.849 L 2.273,-58.727 L 0.704,-58.727 Z"/>
|
||||
<path d="M 3.847,-42.752 L 3.847,-45.875 L 5.416,-45.875 L 5.416,-42.752 L 3.847,-42.752 Z"/>
|
||||
<path d="M 7.555,-42.752 L 7.555,-45.875 L 9.124,-45.875 L 9.124,-42.752 L 7.555,-42.752 Z"/>
|
||||
<path d="M 11.263,-42.752 L 11.263,-45.875 L 12.832,-45.875 L 12.832,-42.752 L 11.263,-42.752 Z"/>
|
||||
<path d="M 14.97,-42.752 L 14.97,-45.875 L 16.539,-45.875 L 16.539,-42.752 L 14.97,-42.752 Z"/>
|
||||
<path d="M -8.475,-52.589 L -6.906,-52.589 L -6.906,-55.16 L -7.181,-55.711 L -8.199,-55.711 L -8.475,-55.16 L -8.475,-52.589 Z"/>
|
||||
<path d="M 9.463,-36.614 L 11.032,-36.614 L 11.032,-39.185 L 10.756,-39.737 L 9.739,-39.737 L 9.463,-39.185 L 9.463,-36.614 Z"/>
|
||||
<path d="M -5,0 V -5 H -8 V 0"/>
|
||||
</g>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-caravanserai" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(21 -2) scale(2 2)">
|
||||
<path d="M -7.316,1.248 L -24.272,1.248 L -22.919,-10.943 L -15.456,-10.943 L -7.993,-10.943 L -7.316,1.248 M 3.531,1.248 L -7.316,1.248 L -7.993,-10.943 L -15.456,-10.943 L -12.913,-10.943 L -10.371,-10.943 L -7.828,-10.943 L -5.286,-10.943 L 2.177,-10.943 L 3.531,1.248 M -7.993,-10.943 L 2.177,-10.943" fill="#EBE8DF"/>
|
||||
<path d="M -14.585,1.248 L -16.326,1.248 L -16.326,-2.59 L -16.15,-2.943 L -14.761,-2.943 L -14.585,-2.59 L -14.585,1.248" fill="#4D3F36"/>
|
||||
<path d="M -10.371,-14.623 L -10.371,-14.623 L -7.542,-14.187 L -4.975,-12.922 L -2.908,-10.943 L -17.833,-10.943 L -15.766,-12.922 L -13.199,-14.187 L -10.371,-14.623"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-monastery" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(20 -10) scale(2 2)">
|
||||
<g transform="translate(0 6)">
|
||||
<path d="M -9.764,-0.93 L -29.859,-0.93 L -29.954,-10.141 L -25.873,-31.202 L -20.814,-31.292 L -15.755,-31.322 L -10.695,-31.292 L -5.636,-31.202 L -9.716,-10.141 L -9.764,-0.93 M -29.954,-10.141 L -9.716,-10.141 M -1.651,-0.93 L -9.764,-0.93 L -9.716,-10.141 L -5.636,-31.202 L -1.556,-10.141 L -1.651,-0.93" fill="#EBE8DF" stroke="#4D3F36"/>
|
||||
<path d="M -9.716,-10.141 L -29.954,-10.141 L -25.873,-31.202 L -20.814,-31.292 L -15.755,-31.322 L -10.695,-31.292 L -5.636,-31.202 L -9.716,-10.141"/>
|
||||
<path stroke="none" d="M -23.484,-0.93 L -26.304,-0.93 L -26.304,-8.18 L -26.046,-8.696 L -23.742,-8.696 L -23.484,-8.18 L -23.484,-0.93" fill="#4D3F36"/>
|
||||
<path stroke="none" d="M -18.425,-0.93 L -21.245,-0.93 L -21.245,-8.18 L -20.987,-8.696 L -18.683,-8.696 L -18.425,-8.18 L -18.425,-0.93" fill="#4D3F36"/>
|
||||
<path stroke="none" d="M -13.366,-0.93 L -16.185,-0.93 L -16.185,-8.18 L -15.928,-8.696 L -13.623,-8.696 L -13.366,-8.18 L -13.366,-0.93" fill="#4D3F36"/>
|
||||
</g>
|
||||
<path d="M 0.927,5.327 L -10.543,5.327 L -10.815,-20.976 L -4.876,-33.337 L 1.063,-20.976 L 0.927,5.327 M 8.952,5.327 L 0.927,5.327 L 1.063,-20.976 L -4.876,-33.337 L -2.836,-33.39 L -0.795,-33.408 L 1.245,-33.39 L 3.285,-33.337 L 9.224,-20.976 L 8.952,5.327" fill="#EBE8DF" stroke="#4D3F36"/>
|
||||
<path d="M 9.224,-20.976 L 1.063,-20.976 L -4.876,-33.337 L -2.836,-33.39 L -0.795,-33.408 L 1.245,-33.39 L 3.285,-33.337 L 9.224,-20.976"/>
|
||||
<path stroke="none" d="M -5.445,5.327 L -8.265,5.327 L -8.265,-1.923 L -8.007,-2.439 L -5.703,-2.439 L -5.445,-1.923 L -5.445,5.327" fill="#4D3F36"/>
|
||||
<path stroke="none" d="M -1.486,5.327 L -4.306,5.327 L -4.306,-1.923 L -4.048,-2.439 L -1.744,-2.439 L -1.486,-1.923 L -1.486,5.327" fill="#4D3F36"/>
|
||||
<circle cx="-5" cy="-20" r="1.6" fill="#4D3F36"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-watabou-post" viewBox="0 0 100 100" width="1em" height="1em" overflow="visible">
|
||||
<g transform="translate(-10 -10) scale(2 2)">
|
||||
<path d="M 12.321,4.738 L -8.119,4.738 L -8.522,-8.706 L 2,-23.172 L 12.522,-8.706 L 12.321,4.738 M 22.814,4.738 L 12.321,4.738 L 12.522,-8.706 L 2,-23.172 L 4.674,-22.56 L 7.347,-22.356 L 10.021,-22.56 L 12.695,-23.172 L 23.217,-8.706 L 22.814,4.738" fill="#EBE8DF"/>
|
||||
<path d="M 23.217,-8.706 L 12.522,-8.706 L 2,-23.172 L 4.674,-22.56 L 7.347,-22.356 L 10.021,-22.56 L 12.695,-23.172 L 23.217,-8.706" />
|
||||
<path d="M -4,-8 v12 M 9,-8 v12"/>
|
||||
<path d="M -10,-4.6 h24 l-2,-4 h-20 z"/>
|
||||
<path d="M 4.5,4.5 V -1 H 0 V 4" fill="#4D3F36"/>
|
||||
<circle cx="2.2" cy="-13" r="1" fill="#4D3F36"/>
|
||||
</g>
|
||||
<circle fill="#EBE8DF" stroke-width="3" cx="0" cy="0" r="10" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-anchor" viewBox="0 0 30 30" width="1em" height="1em" overflow="visible">
|
||||
<path d="m 1.003,-9.873 c 0,-0.547 -0.453,-1 -1,-1 -0.547,0 -1,0.453 -1,1 0,0.547 0.453,1 1,1 0.547,0 1,-0.453 1,-1 z m 13,14.5 v 5.5 c 0,0.203 -0.125,0.391 -0.313,0.469 -0.063,0.016 -0.125,0.031 -0.187,0.031 -0.125,0 -0.25,-0.047 -0.359,-0.141 L 11.691,9.033 c -2.453,2.953 -6.859,4.844 -11.688,4.844 -4.829,0 -9.234,-1.891 -11.688,-4.844 l -1.453,1.453 c -0.094,0.094 -0.234,0.141 -0.359,0.141 -0.063,0 -0.125,-0.016 -0.187,-0.031 -0.187,-0.078 -0.313,-0.266 -0.313,-0.469 v -5.5 c 0,-0.281 0.219,-0.5 0.5,-0.5 h 5.5 c 0.203,0 0.391,0.125 0.469,0.313 0.078,0.188 0.031,0.391 -0.109,0.547 L -9.2,6.55 c 1.406,1.891 4.109,3.266 7.203,3.687 V 0.128 h -3 c -0.547,0 -1,-0.453 -1,-1 v -2 c 0,-0.547 0.453,-1 1,-1 h 3 v -2.547 c -1.188,-0.688 -2,-1.969 -2,-3.453 0,-2.203 1.797,-4 4,-4 2.203,0 4,1.797 4,4 0,1.484 -0.812,2.766 -2,3.453 v 2.547 h 3 c 0.547,0 1,0.453 1,1 v 2 c 0,0.547 -0.453,1 -1,1 h -3 V 10.237 C 5.097,9.815 7.8,8.44 9.206,6.55 L 7.643,4.987 C 7.502,4.831 7.456,4.628 7.534,4.44 7.612,4.252 7.8,4.127 8.003,4.127 h 5.5 c 0.281,0 0.5,0.219 0.5,0.5 z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-store" viewBox="0 0 616 512">
|
||||
<path
|
||||
d="M602 118.6L537.1 15C531.3 5.7 521 0 510 0H106C95 0 84.7 5.7 78.9 15L14 118.6c-33.5 53.5-3.8 127.9 58.8 136.4 4.5.6 9.1.9 13.7.9 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18.1 20.1 44.3 33.1 73.8 33.1 4.7 0 9.2-.3 13.7-.9 62.8-8.4 92.6-82.8 59-136.4zM529.5 288c-10 0-19.9-1.5-29.5-3.8V384H116v-99.8c-9.6 2.2-19.5 3.8-29.5 3.8-6 0-12.1-.4-18-1.2-5.6-.8-11.1-2.1-16.4-3.6V480c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32V283.2c-5.4 1.6-10.8 2.9-16.4 3.6-6.1.8-12.1 1.2-18.2 1.2z"
|
||||
/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="icon-route" viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M416 320h-96c-17.6 0-32-14.4-32-32s14.4-32 32-32h96s96-107 96-160-43-96-96-96-96 43-96 96c0 25.5 22.2 63.4 45.3 96H320c-52.9 0-96 43.1-96 96s43.1 96 96 96h96c17.6 0 32 14.4 32 32s-14.4 32-32 32H185.5c-16 24.8-33.8 47.7-47.3 64H416c52.9 0 96-43.1 96-96s-43.1-96-96-96zm0-256c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zM96 256c-53 0-96 43-96 96s96 160 96 160 96-107 96-160-43-96-96-96zm0 128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"
|
||||
/>
|
||||
</symbol>
|
||||
</g>
|
||||
|
||||
<g id="defs-compass-rose" stroke-width="1.1">
|
||||
<g id="rose-coord-line" stroke="#3f3f3f">
|
||||
<line id="sL1" x1="0" y1="-20000" x2="0" y2="20000" />
|
||||
|
|
@ -8097,9 +8353,10 @@
|
|||
<script src="modules/river-generator.js?v=1.106.7"></script>
|
||||
<script src="modules/lakes.js?v=1.99.00"></script>
|
||||
<script src="modules/biomes.js?v=1.99.00"></script>
|
||||
<script src="modules/names-generator.js?v=1.105.11"></script>
|
||||
<script src="modules/names-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/cultures-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/burgs-and-states.js?v=1.106.0"></script>
|
||||
<script src="modules/burgs-generator.js?v=1.107.0"></script>
|
||||
<script src="modules/states-generator.js?v=1.107.0"></script>
|
||||
<script src="modules/provinces-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/routes-generator.js?v=1.106.0"></script>
|
||||
<script src="modules/religions-generator.js?v=1.106.0"></script>
|
||||
|
|
@ -8140,6 +8397,7 @@
|
|||
<script defer src="modules/ui/rivers-editor.js?v=1.106.0"></script>
|
||||
<script defer src="modules/ui/rivers-creator.js?v=1.106.0"></script>
|
||||
<script defer src="modules/ui/relief-editor.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/burg-group-editor.js?v=1.106.0"></script>
|
||||
<script defer src="modules/ui/burg-editor.js?v=1.106.6"></script>
|
||||
<script defer src="modules/ui/units-editor.js?v=1.108.12"></script>
|
||||
<script defer src="modules/ui/notes-editor.js?v=1.107.3"></script>
|
||||
|
|
|
|||
105
main.js
105
main.js
|
|
@ -77,8 +77,8 @@ let ice = viewbox.append("g").attr("id", "ice");
|
|||
let prec = viewbox.append("g").attr("id", "prec").style("display", "none");
|
||||
let population = viewbox.append("g").attr("id", "population");
|
||||
let emblems = viewbox.append("g").attr("id", "emblems").style("display", "none");
|
||||
let labels = viewbox.append("g").attr("id", "labels");
|
||||
let icons = viewbox.append("g").attr("id", "icons");
|
||||
let labels = viewbox.append("g").attr("id", "labels");
|
||||
let burgIcons = icons.append("g").attr("id", "burgIcons");
|
||||
let anchors = icons.append("g").attr("id", "anchors");
|
||||
let armies = viewbox.append("g").attr("id", "armies");
|
||||
|
|
@ -106,17 +106,9 @@ coastline.append("g").attr("id", "lake_island");
|
|||
terrs.append("g").attr("id", "oceanHeights");
|
||||
terrs.append("g").attr("id", "landHeights");
|
||||
|
||||
let burgLabels = labels.append("g").attr("id", "burgLabels");
|
||||
labels.append("g").attr("id", "states");
|
||||
labels.append("g").attr("id", "addedLabels");
|
||||
|
||||
burgIcons.append("g").attr("id", "cities");
|
||||
burgLabels.append("g").attr("id", "cities");
|
||||
anchors.append("g").attr("id", "cities");
|
||||
|
||||
burgIcons.append("g").attr("id", "towns");
|
||||
burgLabels.append("g").attr("id", "towns");
|
||||
anchors.append("g").attr("id", "towns");
|
||||
let burgLabels = labels.append("g").attr("id", "burgLabels");
|
||||
|
||||
// population groups
|
||||
population.append("g").attr("id", "rural");
|
||||
|
|
@ -159,9 +151,25 @@ let notes = [];
|
|||
let rulers = new Rulers();
|
||||
let customization = 0;
|
||||
|
||||
// global options; in v2.0 to be used for all UI settings
|
||||
let options = {
|
||||
pinNotes: false,
|
||||
winds: [225, 45, 225, 315, 135, 315],
|
||||
temperatureEquator: 27,
|
||||
temperatureNorthPole: -30,
|
||||
temperatureSouthPole: -15,
|
||||
stateLabelsMode: "auto",
|
||||
showBurgPreview: true,
|
||||
burgs: {
|
||||
groups: JSON.safeParse(localStorage.getItem("burg-groups")) || Burgs.getDefaultGroups()
|
||||
}
|
||||
};
|
||||
|
||||
// global style object; in v2.0 to be used for all map styles and render settings
|
||||
let style = {burgLabels: {}, burgIcons: {}, anchors: {}};
|
||||
|
||||
let biomesData = Biomes.getDefault();
|
||||
let nameBases = Names.getNameBases(); // cultures-related data
|
||||
|
||||
let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme
|
||||
const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation
|
||||
|
||||
|
|
@ -185,18 +193,6 @@ const onZoom = debounce(function () {
|
|||
}, 50);
|
||||
const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", onZoom);
|
||||
|
||||
// default options, based on Earth data
|
||||
let options = {
|
||||
pinNotes: false,
|
||||
winds: [225, 45, 225, 315, 135, 315],
|
||||
temperatureEquator: 27,
|
||||
temperatureNorthPole: -30,
|
||||
temperatureSouthPole: -15,
|
||||
stateLabelsMode: "auto",
|
||||
showBurgPreview: true,
|
||||
villageMaxPopulation: 2000
|
||||
};
|
||||
|
||||
let mapCoordinates = {}; // map coordinates on globe
|
||||
let populationRate = +byId("populationRateInput").value;
|
||||
let distanceScale = +byId("distanceScaleInput").value;
|
||||
|
|
@ -531,12 +527,6 @@ function invokeActiveZooming() {
|
|||
});
|
||||
}
|
||||
|
||||
// turn off ocean pattern if scale is big (improves performance)
|
||||
oceanPattern
|
||||
.select("rect")
|
||||
.attr("fill", scale > 10 ? "#fff" : "url(#oceanic)")
|
||||
.attr("opacity", scale > 10 ? 0.2 : null);
|
||||
|
||||
// change states halo width
|
||||
if (!customization && !isOptimized) {
|
||||
const desired = +statesHalo.attr("data-width");
|
||||
|
|
@ -650,13 +640,18 @@ async function generate(options) {
|
|||
rankCells();
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
BurgsAndStates.generate();
|
||||
|
||||
Burgs.generate();
|
||||
States.generate();
|
||||
Routes.generate();
|
||||
Religions.generate();
|
||||
BurgsAndStates.defineStateForms();
|
||||
|
||||
Burgs.specify();
|
||||
States.collectStatistics();
|
||||
States.defineStateForms();
|
||||
|
||||
Provinces.generate();
|
||||
Provinces.getPoles();
|
||||
BurgsAndStates.defineBurgFeatures();
|
||||
|
||||
Rivers.specify();
|
||||
Features.specify();
|
||||
|
|
@ -683,7 +678,7 @@ async function generate(options) {
|
|||
title: "Generation error",
|
||||
width: "32em",
|
||||
buttons: {
|
||||
"Clear cache": () => cleanupData(),
|
||||
"Cleanup data": () => cleanupData(),
|
||||
Regenerate: function () {
|
||||
regenerateMap("generation error");
|
||||
$(this).dialog("close");
|
||||
|
|
@ -1172,36 +1167,44 @@ function rankCells() {
|
|||
cells.s = new Int16Array(cells.i.length); // cell suitability array
|
||||
cells.pop = new Float32Array(cells.i.length); // cell population array
|
||||
|
||||
const flMean = d3.median(cells.fl.filter(f => f)) || 0;
|
||||
const flMax = d3.max(cells.fl) + d3.max(cells.conf); // to normalize flux
|
||||
const areaMean = d3.mean(cells.area); // to adjust population by cell area
|
||||
const meanFlux = d3.median(cells.fl.filter(f => f)) || 0;
|
||||
const maxFlux = d3.max(cells.fl) + d3.max(cells.conf); // to normalize flux
|
||||
const meanArea = d3.mean(cells.area); // to adjust population by cell area
|
||||
|
||||
const scoreMap = {
|
||||
estuary: 15,
|
||||
ocean_coast: 5,
|
||||
save_harbor: 20,
|
||||
freshwater: 30,
|
||||
salt: 10,
|
||||
frozen: 1,
|
||||
dry: -5,
|
||||
sinkhole: -5,
|
||||
lava: -30
|
||||
};
|
||||
|
||||
for (const i of cells.i) {
|
||||
if (cells.h[i] < 20) continue; // no population in water
|
||||
let s = +biomesData.habitability[cells.biome[i]]; // base suitability derived from biome habitability
|
||||
if (!s) continue; // uninhabitable biomes has 0 suitability
|
||||
if (flMean) s += normalize(cells.fl[i] + cells.conf[i], flMean, flMax) * 250; // big rivers and confluences are valued
|
||||
s -= (cells.h[i] - 50) / 5; // low elevation is valued, high is not;
|
||||
let score = biomesData.habitability[cells.biome[i]]; // base suitability derived from biome habitability
|
||||
if (!score) continue; // uninhabitable biomes has 0 suitability
|
||||
|
||||
if (meanFlux) score += normalize(cells.fl[i] + cells.conf[i], meanFlux, maxFlux) * 250; // big rivers and confluences are valued
|
||||
score -= (cells.h[i] - 50) / 5; // low elevation is valued, high is not;
|
||||
|
||||
if (cells.t[i] === 1) {
|
||||
if (cells.r[i]) s += 15; // estuary is valued
|
||||
if (cells.r[i]) score += scoreMap.estuary;
|
||||
const feature = features[cells.f[cells.haven[i]]];
|
||||
if (feature.type === "lake") {
|
||||
if (feature.group === "freshwater") s += 30;
|
||||
else if (feature.group == "salt") s += 10;
|
||||
else if (feature.group == "frozen") s += 1;
|
||||
else if (feature.group == "dry") s -= 5;
|
||||
else if (feature.group == "sinkhole") s -= 5;
|
||||
else if (feature.group == "lava") s -= 30;
|
||||
score += scoreMap[feature.water] || 0;
|
||||
} else {
|
||||
s += 5; // ocean coast is valued
|
||||
if (cells.harbor[i] === 1) s += 20; // safe sea harbor is valued
|
||||
score += scoreMap.ocean_coast;
|
||||
if (cells.harbor[i] === 1) score += scoreMap.save_harbor;
|
||||
}
|
||||
}
|
||||
|
||||
cells.s[i] = s / 5; // general population rate
|
||||
cells.s[i] = score / 5; // general population rate
|
||||
// cell rural population is suitability adjusted by cell area
|
||||
cells.pop[i] = cells.s[i] > 0 ? (cells.s[i] * cells.area[i]) / areaMean : 0;
|
||||
cells.pop[i] = cells.s[i] > 0 ? (cells.s[i] * cells.area[i]) / meanArea : 0;
|
||||
}
|
||||
|
||||
TIME && console.timeEnd("rankCells");
|
||||
|
|
|
|||
592
modules/burgs-generator.js
Normal file
592
modules/burgs-generator.js
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
"use strict";
|
||||
|
||||
window.Burgs = (() => {
|
||||
const generate = () => {
|
||||
TIME && console.time("generateBurgs");
|
||||
const {cells} = pack;
|
||||
|
||||
let burgs = [0]; // burgs array
|
||||
cells.burg = new Uint16Array(cells.i.length);
|
||||
|
||||
const populatedCells = cells.i.filter(i => cells.s[i] > 0 && cells.culture[i]);
|
||||
if (!populatedCells.length) {
|
||||
WARN && console.warn("There is no populated cells. Cannot generate states");
|
||||
return burgs;
|
||||
}
|
||||
|
||||
let quadtree = d3.quadtree();
|
||||
generateCapitals();
|
||||
generateTowns();
|
||||
shiftBurgs();
|
||||
|
||||
pack.burgs = burgs;
|
||||
TIME && console.timeEnd("generateBurgs");
|
||||
|
||||
function getCapitalsNumber() {
|
||||
let number = +byId("statesNumber").value;
|
||||
|
||||
if (populatedCells.length < number * 10) {
|
||||
WARN && console.warn(`Not enough populated cells. Generating only ${number} capitals/states`);
|
||||
number = Math.floor(sorted.length / 10);
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
function getTownsNumber() {
|
||||
const manorsInput = byId("manorsInput");
|
||||
const isAuto = manorsInput.value === "1000"; // '1000' is considered as auto
|
||||
if (isAuto) return rn(populatedCells.length / 5 / (grid.points.length / 10000) ** 0.8);
|
||||
|
||||
return Math.min(manorsInput.valueAsNumber, sorted.length);
|
||||
}
|
||||
|
||||
function generateCapitals() {
|
||||
const randomize = score => score * (0.5 + Math.random() * 0.5);
|
||||
const score = new Int16Array(cells.s.map(randomize));
|
||||
const sorted = populatedCells.sort((a, b) => score[b] - score[a]);
|
||||
|
||||
const capitalsNumber = getCapitalsNumber();
|
||||
let spacing = (graphWidth + graphHeight) / 2 / capitalsNumber; // min distance between capitals
|
||||
|
||||
for (let i = 0; burgs.length <= capitalsNumber; i++) {
|
||||
const cell = sorted[i];
|
||||
const [x, y] = cells.p[cell];
|
||||
|
||||
if (quadtree.find(x, y, spacing) === undefined) {
|
||||
burgs.push({cell, x, y});
|
||||
quadtree.add([x, y]);
|
||||
}
|
||||
|
||||
// reset if all cells were checked
|
||||
if (i === sorted.length - 1) {
|
||||
WARN && console.warn("Cannot place capitals with current spacing. Trying again with reduced spacing");
|
||||
quadtree = d3.quadtree();
|
||||
i = -1;
|
||||
burgs = [0];
|
||||
spacing /= 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
burgs.forEach((burg, burgId) => {
|
||||
if (!burgId) return;
|
||||
burg.i = burgId;
|
||||
burg.state = burgId;
|
||||
burg.culture = cells.culture[burg.cell];
|
||||
burg.name = Names.getCultureShort(burg.culture);
|
||||
burg.feature = cells.f[burg.cell];
|
||||
burg.capital = 1;
|
||||
cells.burg[burg.cell] = burgId;
|
||||
});
|
||||
}
|
||||
|
||||
function generateTowns() {
|
||||
const randomize = score => score * gauss(1, 3, 0, 20, 3);
|
||||
const score = new Int16Array(cells.s.map(randomize));
|
||||
const sorted = populatedCells.sort((a, b) => score[b] - score[a]);
|
||||
|
||||
const burgsNumber = getTownsNumber();
|
||||
let spacing = (graphWidth + graphHeight) / 150 / (burgsNumber ** 0.7 / 66); // min distance between town
|
||||
|
||||
for (let added = 0; added < burgsNumber && spacing > 1; ) {
|
||||
for (let i = 0; added < burgsNumber && i < sorted.length; i++) {
|
||||
if (cells.burg[sorted[i]]) continue;
|
||||
const cell = sorted[i];
|
||||
const [x, y] = cells.p[cell];
|
||||
|
||||
const minSpacing = spacing * gauss(1, 0.3, 0.2, 2, 2); // randomize to make placement not uniform
|
||||
if (quadtree.find(x, y, minSpacing) !== undefined) continue; // to close to existing burg
|
||||
|
||||
const burgId = burgs.length;
|
||||
const culture = cells.culture[cell];
|
||||
const name = Names.getCulture(culture);
|
||||
const feature = cells.f[cell];
|
||||
burgs.push({cell, x, y, i: burgId, state: 0, culture, name, feature, capital: 0});
|
||||
added++;
|
||||
cells.burg[cell] = burgId;
|
||||
}
|
||||
|
||||
spacing *= 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
// define port status and shift ports and burgs on rivers
|
||||
function shiftBurgs() {
|
||||
const {cells, features} = pack;
|
||||
const temp = grid.cells.temp;
|
||||
|
||||
// port is a capital with any harbor OR any burg with a safe harbor
|
||||
const featurePorts = {};
|
||||
for (const burg of burgs) {
|
||||
if (!burg.i || burg.lock) continue;
|
||||
const i = burg.cell;
|
||||
|
||||
const haven = cells.haven[i];
|
||||
const harbor = cells.harbor[i];
|
||||
|
||||
if (haven !== undefined && temp[cells.g[i]] > 0) {
|
||||
const featureId = cells.f[haven];
|
||||
const canBePort = features[featureId].cells > 1 && ((burg.capital && harbor) || harbor === 1);
|
||||
if (canBePort) {
|
||||
if (!featurePorts[featureId]) featurePorts[featureId] = [];
|
||||
featurePorts[featureId].push(burg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shift ports to the edge of the water body. Only bodies with 2+ ports are considered
|
||||
Object.entries(featurePorts).forEach(([featureId, burgs]) => {
|
||||
if (burgs.length < 2) return;
|
||||
burgs.forEach(burg => {
|
||||
burg.port = featureId;
|
||||
const haven = cells.haven[burg.cell];
|
||||
const [x, y] = getCloseToEdgePoint(burg.cell, haven);
|
||||
burg.x = x;
|
||||
burg.y = y;
|
||||
});
|
||||
});
|
||||
|
||||
// shift non-port river burgs a bit
|
||||
for (const burg of burgs) {
|
||||
if (!burg.i || burg.lock || burg.port || !cells.r[burg.cell]) continue;
|
||||
const cellId = burg.cell;
|
||||
const shift = Math.min(cells.fl[cellId] / 150, 1);
|
||||
burg.x = cellId % 2 ? rn(burg.x + shift, 2) : rn(burg.x - shift, 2);
|
||||
burg.y = cells.r[cellId] % 2 ? rn(burg.y + shift, 2) : rn(burg.y - shift, 2);
|
||||
}
|
||||
|
||||
function getCloseToEdgePoint(cell1, cell2) {
|
||||
const {cells, vertices} = pack;
|
||||
|
||||
const [x0, y0] = cells.p[cell1];
|
||||
const commonVertices = cells.v[cell1].filter(vertex => vertices.c[vertex].some(cell => cell === cell2));
|
||||
const [x1, y1] = vertices.p[commonVertices[0]];
|
||||
const [x2, y2] = vertices.p[commonVertices[1]];
|
||||
const xEdge = (x1 + x2) / 2;
|
||||
const yEdge = (y1 + y2) / 2;
|
||||
|
||||
const x = rn(x0 + 0.95 * (xEdge - x0), 2);
|
||||
const y = rn(y0 + 0.95 * (yEdge - y0), 2);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const specify = () => {
|
||||
TIME && console.time("specifyBurgs");
|
||||
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || burg.removed || burg.lock) return;
|
||||
definePopulation(burg);
|
||||
defineEmblem(burg);
|
||||
defineFeatures(burg);
|
||||
});
|
||||
|
||||
const populations = pack.burgs
|
||||
.filter(b => b.i && !b.removed)
|
||||
.map(b => b.population)
|
||||
.sort((a, b) => a - b); // ascending
|
||||
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || burg.removed) return;
|
||||
defineGroup(burg, populations);
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("specifyBurgs");
|
||||
};
|
||||
|
||||
const getType = (cellId, port) => {
|
||||
const {cells, features} = pack;
|
||||
|
||||
if (port) return "Naval";
|
||||
|
||||
const haven = cells.haven[cellId];
|
||||
if (haven !== undefined && features[cells.f[haven]].type === "lake") return "Lake";
|
||||
|
||||
if (cells.h[cellId] > 60) return "Highland";
|
||||
|
||||
if (cells.r[cellId] && cells.fl[cellId] >= 100) return "River";
|
||||
|
||||
const biome = cells.biome[cellId];
|
||||
const population = cells.pop[cellId];
|
||||
if (!cells.burg[cellId] || population <= 5) {
|
||||
if (population < 5 && [1, 2, 3, 4].includes(biome)) return "Nomadic";
|
||||
if (biome > 4 && biome < 10) return "Hunting";
|
||||
}
|
||||
|
||||
return "Generic";
|
||||
};
|
||||
|
||||
function definePopulation(burg) {
|
||||
const cellId = burg.cell;
|
||||
let population = pack.cells.s[cellId] / 5;
|
||||
if (burg.capital) population *= 1.5;
|
||||
const connectivityRate = Routes.getConnectivityRate(cellId);
|
||||
if (connectivityRate) population *= connectivityRate;
|
||||
population *= gauss(1, 1, 0.25, 4, 5); // randomize
|
||||
population += ((burg.i % 100) - (cellId % 100)) / 1000; // unround
|
||||
burg.population = rn(Math.max(population, 0.01), 3);
|
||||
}
|
||||
|
||||
function defineEmblem(burg) {
|
||||
burg.type = getType(burg.cell, burg.port);
|
||||
|
||||
const state = pack.states[burg.state];
|
||||
const stateCOA = state.coa;
|
||||
|
||||
let kinship = 0.25;
|
||||
if (burg.capital) kinship += 0.1;
|
||||
else if (burg.port) kinship -= 0.1;
|
||||
if (burg.culture !== state.culture) kinship -= 0.25;
|
||||
|
||||
const type = burg.capital && P(0.2) ? "Capital" : burg.type === "Generic" ? "City" : burg.type;
|
||||
burg.coa = COA.generate(stateCOA, kinship, null, type);
|
||||
burg.coa.shield = COA.getShield(burg.culture, burg.state);
|
||||
}
|
||||
|
||||
function defineFeatures(burg) {
|
||||
const pop = burg.population;
|
||||
burg.citadel = Number(burg.capital || (pop > 50 && P(0.75)) || (pop > 15 && P(0.5)) || P(0.1));
|
||||
burg.plaza = Number(
|
||||
Routes.isCrossroad(burg.cell) || (Routes.hasRoad(burg.cell) && P(0.7)) || pop > 20 || (pop > 10 && P(0.8))
|
||||
);
|
||||
burg.walls = Number(burg.capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.1));
|
||||
burg.shanty = Number(pop > 60 || (pop > 40 && P(0.75)) || (pop > 20 && burg.walls && P(0.4)));
|
||||
const religion = pack.cells.religion[burg.cell];
|
||||
const theocracy = pack.states[burg.state].form === "Theocracy";
|
||||
burg.temple = Number(
|
||||
(religion && theocracy && P(0.5)) || pop > 50 || (pop > 35 && P(0.75)) || (pop > 20 && P(0.5))
|
||||
);
|
||||
}
|
||||
|
||||
const getDefaultGroups = () => [
|
||||
{name: "capital", active: true, order: 9, features: {capital: true}, preview: "watabou-city"},
|
||||
{name: "city", active: true, order: 8, percentile: 90, min: 5, preview: "watabou-city"},
|
||||
{
|
||||
name: "fort",
|
||||
active: true,
|
||||
features: {citadel: true, walls: false, plaza: false, port: false},
|
||||
order: 6,
|
||||
max: 1
|
||||
},
|
||||
{
|
||||
name: "monastery",
|
||||
active: true,
|
||||
features: {temple: true, walls: false, plaza: false, port: false},
|
||||
order: 5,
|
||||
max: 0.8
|
||||
},
|
||||
{
|
||||
name: "caravanserai",
|
||||
active: true,
|
||||
features: {port: false, plaza: true},
|
||||
order: 4,
|
||||
max: 0.8,
|
||||
biomes: [1, 2, 3]
|
||||
},
|
||||
{
|
||||
name: "trading_post",
|
||||
active: true,
|
||||
order: 3,
|
||||
features: {plaza: true},
|
||||
max: 0.8,
|
||||
biomes: [5, 6, 7, 8, 9, 10, 11, 12]
|
||||
},
|
||||
{
|
||||
name: "village",
|
||||
active: true,
|
||||
order: 2,
|
||||
min: 0.1,
|
||||
max: 2,
|
||||
preview: "watabou-village"
|
||||
},
|
||||
{
|
||||
name: "hamlet",
|
||||
active: true,
|
||||
order: 1,
|
||||
features: {plaza: false},
|
||||
max: 0.1,
|
||||
preview: "watabou-village"
|
||||
},
|
||||
{name: "town", active: true, order: 7, isDefault: true, preview: "watabou-city"}
|
||||
];
|
||||
|
||||
function defineGroup(burg, populations) {
|
||||
if (burg.lock && burg.group) {
|
||||
// locked burgs: don't change group if it still exists
|
||||
const group = options.burgs.groups.find(g => g.name === burg.group);
|
||||
if (group) return;
|
||||
}
|
||||
|
||||
const defaultGroup = options.burgs.groups.find(g => g.isDefault);
|
||||
if (!defaultGroup) {
|
||||
ERROR & console.error("No default group defined");
|
||||
return;
|
||||
}
|
||||
burg.group = defaultGroup.name;
|
||||
|
||||
for (const group of options.burgs.groups) {
|
||||
if (!group.active) continue;
|
||||
|
||||
if (group.min) {
|
||||
const isFit = burg.population >= group.min;
|
||||
if (!isFit) continue;
|
||||
}
|
||||
|
||||
if (group.max) {
|
||||
const isFit = burg.population <= group.max;
|
||||
if (!isFit) continue;
|
||||
}
|
||||
|
||||
if (group.features) {
|
||||
const isFit = Object.entries(group.features).every(([feature, value]) => Boolean(burg[feature]) === value);
|
||||
if (!isFit) continue;
|
||||
}
|
||||
|
||||
if (group.biomes) {
|
||||
const isFit = group.biomes.includes(pack.cells.biome[burg.cell]);
|
||||
if (!isFit) continue;
|
||||
}
|
||||
|
||||
if (group.percentile) {
|
||||
const index = populations.indexOf(burg.population);
|
||||
const isFit = index >= Math.floor((populations.length * group.percentile) / 100);
|
||||
if (!isFit) continue;
|
||||
}
|
||||
|
||||
burg.group = group.name; // apply fitting group
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const previewGeneratorsMap = {
|
||||
"watabou-city": createWatabouCityLinks,
|
||||
"watabou-village": createWatabouVillageLinks,
|
||||
"watabou-dwelling": createWatabouDwellingLinks
|
||||
};
|
||||
|
||||
function getPreview(burg) {
|
||||
if (burg.link) return {link: burg.link, preview: burg.link};
|
||||
|
||||
const group = options.burgs.groups.find(g => g.name === burg.group);
|
||||
if (!group?.preview || !previewGeneratorsMap[group.preview]) return {link: null, preview: null};
|
||||
|
||||
return previewGeneratorsMap[group.preview](burg);
|
||||
}
|
||||
|
||||
function createWatabouCityLinks(burg) {
|
||||
const cells = pack.cells;
|
||||
const {i, name, population: burgPopulation, cell} = burg;
|
||||
const burgSeed = burg.MFCG || seed + String(burg.i).padStart(4, 0);
|
||||
|
||||
const sizeRaw = 2.13 * Math.pow((burgPopulation * populationRate) / urbanDensity, 0.385);
|
||||
const size = minmax(Math.ceil(sizeRaw), 6, 100);
|
||||
const population = rn(burgPopulation * populationRate * urbanization);
|
||||
|
||||
const river = cells.r[cell] ? 1 : 0;
|
||||
const coast = Number(burg.port > 0);
|
||||
const sea = (() => {
|
||||
if (!coast || !cells.haven[cell]) return null;
|
||||
|
||||
// calculate see direction: 0 = east, 0.5 = north, 1 = west, 1.5 = south
|
||||
const [x1, y1] = cells.p[cell];
|
||||
const [x2, y2] = cells.p[cells.haven[cell]];
|
||||
const deg = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI;
|
||||
|
||||
if (deg <= 0) return normalize(Math.abs(deg), 0, 180);
|
||||
return 2 - normalize(deg, 0, 180);
|
||||
})();
|
||||
|
||||
const arableBiomes = river ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||
const farms = +arableBiomes.includes(cells.biome[cell]);
|
||||
|
||||
const citadel = +burg.citadel;
|
||||
const urban_castle = +(citadel && each(2)(i));
|
||||
|
||||
const hub = Routes.isCrossroad(cell);
|
||||
const walls = +burg.walls;
|
||||
const plaza = +burg.plaza;
|
||||
const temple = +burg.temple;
|
||||
const shantytown = +burg.shanty;
|
||||
|
||||
const style = "natural";
|
||||
|
||||
const url = new URL("https://watabou.github.io/city-generator/");
|
||||
url.search = new URLSearchParams({
|
||||
name,
|
||||
population,
|
||||
size,
|
||||
seed: burgSeed,
|
||||
river,
|
||||
coast,
|
||||
farms,
|
||||
citadel,
|
||||
urban_castle,
|
||||
hub,
|
||||
plaza,
|
||||
temple,
|
||||
walls,
|
||||
shantytown,
|
||||
gates: -1,
|
||||
style
|
||||
});
|
||||
if (sea) url.searchParams.append("sea", sea);
|
||||
|
||||
const link = url.toString();
|
||||
return {link, preview: link + "&preview=1"};
|
||||
}
|
||||
|
||||
function createWatabouVillageLinks(burg) {
|
||||
const {cells, features} = pack;
|
||||
const {i, population, cell} = burg;
|
||||
|
||||
const burgSeed = seed + String(i).padStart(4, 0);
|
||||
const pop = rn(population * populationRate * urbanization);
|
||||
const tags = [];
|
||||
|
||||
if (cells.r[cell] && cells.haven[cell]) tags.push("estuary");
|
||||
else if (cells.haven[cell] && features[cells.f[cell]].cells === 1) tags.push("island,district");
|
||||
else if (burg.port) tags.push("coast");
|
||||
else if (cells.conf[cell]) tags.push("confluence");
|
||||
else if (cells.r[cell]) tags.push("river");
|
||||
else if (pop < 200 && each(4)(cell)) tags.push("pond");
|
||||
|
||||
const connectivityRate = Routes.getConnectivityRate(cell);
|
||||
tags.push(connectivityRate > 1 ? "highway" : connectivityRate === 1 ? "dead end" : "isolated");
|
||||
|
||||
const biome = cells.biome[cell];
|
||||
const arableBiomes = cells.r[cell] ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||
if (!arableBiomes.includes(biome)) tags.push("uncultivated");
|
||||
else if (each(6)(cell)) tags.push("farmland");
|
||||
|
||||
const temp = grid.cells.temp[cells.g[cell]];
|
||||
if (temp <= 0 || temp > 28 || (temp > 25 && each(3)(cell))) tags.push("no orchards");
|
||||
|
||||
if (!burg.plaza) tags.push("no square");
|
||||
if (burg.walls) tags.push("palisade");
|
||||
|
||||
if (pop < 100) tags.push("sparse");
|
||||
else if (pop > 300) tags.push("dense");
|
||||
|
||||
const width = (() => {
|
||||
if (pop > 1500) return 1600;
|
||||
if (pop > 1000) return 1400;
|
||||
if (pop > 500) return 1000;
|
||||
if (pop > 200) return 800;
|
||||
if (pop > 100) return 600;
|
||||
return 400;
|
||||
})();
|
||||
const height = rn(width / 2.05);
|
||||
|
||||
const style = (() => {
|
||||
if ([1, 2].includes(biome)) return "sand";
|
||||
if (temp <= 5 || [9, 10, 11].includes(biome)) return "snow";
|
||||
return "default";
|
||||
})();
|
||||
|
||||
const url = new URL("https://watabou.github.io/village-generator/");
|
||||
url.search = new URLSearchParams({pop, name: burg.name, seed: burgSeed, width, height, style, tags});
|
||||
|
||||
const link = url.toString();
|
||||
return {link, preview: link + "&preview=1"};
|
||||
}
|
||||
|
||||
function createWatabouDwellingLinks(burg) {
|
||||
const burgSeed = seed + String(burg.i).padStart(4, 0);
|
||||
const pop = rn(burg.population * populationRate * urbanization);
|
||||
|
||||
const tags = (() => {
|
||||
if (pop > 200) return ["large", "tall"];
|
||||
if (pop > 100) return ["large"];
|
||||
if (pop > 50) return ["tall"];
|
||||
if (pop > 20) return ["low"];
|
||||
return ["small"];
|
||||
})();
|
||||
|
||||
const url = new URL("https://watabou.github.io/dwellings/");
|
||||
url.search = new URLSearchParams({pop, name: "", seed: burgSeed, tags});
|
||||
|
||||
const link = url.toString();
|
||||
return {link, preview: link + "&preview=1"};
|
||||
}
|
||||
|
||||
function add([x, y]) {
|
||||
const {cells} = pack;
|
||||
|
||||
const burgId = pack.burgs.length;
|
||||
const cellId = findCell(x, y);
|
||||
const culture = cells.culture[cellId];
|
||||
const name = Names.getCulture(culture);
|
||||
const state = cells.state[cellId];
|
||||
const feature = cells.f[cellId];
|
||||
|
||||
const burg = {
|
||||
cell: cellId,
|
||||
x,
|
||||
y,
|
||||
i: burgId,
|
||||
state,
|
||||
culture,
|
||||
name,
|
||||
feature,
|
||||
capital: 0,
|
||||
port: 0
|
||||
};
|
||||
definePopulation(burg);
|
||||
defineEmblem(burg);
|
||||
defineFeatures(burg);
|
||||
|
||||
const populations = pack.burgs
|
||||
.filter(b => b.i && !b.removed)
|
||||
.map(b => b.population)
|
||||
.sort((a, b) => a - b); // ascending
|
||||
defineGroup(burg, populations);
|
||||
|
||||
pack.burgs.push(burg);
|
||||
cells.burg[cellId] = burgId;
|
||||
|
||||
const newRoute = Routes.connect(cellId);
|
||||
if (newRoute && layerIsOn("toggleRoutes")) drawRoute(newRoute);
|
||||
|
||||
drawBurgIcon(burg);
|
||||
drawBurgLabel(burg);
|
||||
|
||||
return burgId;
|
||||
}
|
||||
|
||||
function changeGroup(burg, group) {
|
||||
if (group) {
|
||||
burg.group = group;
|
||||
} else {
|
||||
const validBurgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const populations = validBurgs.map(b => b.population).sort((a, b) => a - b);
|
||||
defineGroup(burg, populations);
|
||||
}
|
||||
|
||||
drawBurgIcon(burg);
|
||||
drawBurgLabel(burg);
|
||||
}
|
||||
|
||||
function remove(burgId) {
|
||||
const burg = pack.burgs[burgId];
|
||||
if (!burg) return tip(`Burg ${burgId} not found`, false, "error");
|
||||
|
||||
pack.cells.burg[burg.cell] = 0;
|
||||
burg.removed = true;
|
||||
|
||||
const noteId = notes.findIndex(note => note.id === `burg${burgId}`);
|
||||
if (noteId !== -1) notes.splice(noteId, 1);
|
||||
|
||||
if (burg.coa) {
|
||||
byId("burgCOA" + burgId)?.remove();
|
||||
emblems.select(`#burgEmblems > use[data-i='${burgId}']`).remove();
|
||||
delete burg.coa;
|
||||
}
|
||||
|
||||
removeBurgIcon(burg.i);
|
||||
removeBurgLabel(burg.i);
|
||||
}
|
||||
|
||||
return {generate, getDefaultGroups, specify, defineGroup, getPreview, getType, add, changeGroup, remove};
|
||||
})();
|
||||
|
|
@ -47,10 +47,10 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
|
||||
// v1.0 added state relations, provinces, forms and full names
|
||||
provs = viewbox.insert("g", "#borders").attr("id", "provs").attr("opacity", 0.6);
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.generateCampaigns();
|
||||
BurgsAndStates.generateDiplomacy();
|
||||
BurgsAndStates.defineStateForms();
|
||||
States.collectStatistics();
|
||||
States.generateCampaigns();
|
||||
States.generateDiplomacy();
|
||||
States.defineStateForms();
|
||||
Provinces.generate();
|
||||
Provinces.getPoles();
|
||||
if (!layerIsOn("toggleBorders")) $("#borders").fadeOut();
|
||||
|
|
@ -260,7 +260,7 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
|
||||
if (isOlderThan("1.22.0")) {
|
||||
// v1.22 changed state neighbors from Set object to array
|
||||
BurgsAndStates.collectStatistics();
|
||||
States.collectStatistics();
|
||||
}
|
||||
|
||||
if (isOlderThan("1.3.0")) {
|
||||
|
|
@ -273,7 +273,7 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
options = {winds, year, era, eraShort, military};
|
||||
|
||||
// v1.3 added campaings data for all states
|
||||
BurgsAndStates.generateCampaigns();
|
||||
States.generateCampaigns();
|
||||
|
||||
// v1.3 added militry layer
|
||||
armies = viewbox.insert("g", "#icons").attr("id", "armies");
|
||||
|
|
@ -348,7 +348,7 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
// v1.5 added burg type value
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || burg.removed) return;
|
||||
burg.type = BurgsAndStates.getType(burg.cell, burg.port);
|
||||
burg.type = Burgs.getType(burg.cell, burg.port);
|
||||
});
|
||||
|
||||
// v1.5 added emblems
|
||||
|
|
@ -467,12 +467,6 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
if (oceanPattern) oceanPattern.removeAttribute("opacity");
|
||||
const oceanicPattern = document.getElementById("oceanicPattern");
|
||||
if (!oceanicPattern.getAttribute("opacity")) oceanicPattern.setAttribute("opacity", 0.2);
|
||||
|
||||
// v 1.63 moved label text-shadow from css to editable inline style
|
||||
burgLabels.select("#cities").style("text-shadow", "white 0 0 4px");
|
||||
burgLabels.select("#towns").style("text-shadow", "white 0 0 4px");
|
||||
labels.select("#states").style("text-shadow", "white 0 0 4px");
|
||||
labels.select("#addedLabels").style("text-shadow", "white 0 0 4px");
|
||||
}
|
||||
|
||||
if (isOlderThan("1.64.0")) {
|
||||
|
|
@ -836,22 +830,6 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
});
|
||||
}
|
||||
|
||||
if (isOlderThan("1.97.0")) {
|
||||
// v1.97.00 changed MFCG link to an arbitrary preview URL
|
||||
options.villageMaxPopulation = 2000;
|
||||
options.showBurgPreview = options.showMFCGMap;
|
||||
delete options.showMFCGMap;
|
||||
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || burg.removed) return;
|
||||
|
||||
if (burg.MFCG) {
|
||||
burg.link = getBurgLink(burg);
|
||||
delete burg.MFCG;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isOlderThan("1.98.0")) {
|
||||
// v1.98.00 changed compass layer and rose element id
|
||||
const rose = compass.select("use");
|
||||
|
|
@ -944,7 +922,7 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
|
||||
if (isOlderThan("1.104.0")) {
|
||||
// v1.104.00 separated pole of inaccessibility detection from layer rendering
|
||||
BurgsAndStates.getPoles();
|
||||
States.getPoles();
|
||||
Provinces.getPoles();
|
||||
}
|
||||
|
||||
|
|
@ -994,4 +972,71 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
// some old maps has incorrect "heights" groups
|
||||
viewbox.selectAll("#heights").remove();
|
||||
}
|
||||
|
||||
if (isOlderThan("1.109.0")) {
|
||||
// v1.109.0 added customizable burg groups and icons
|
||||
options.burgs = {groups: []};
|
||||
|
||||
// default groups were 'cities' and 'towns'
|
||||
const iconGroups = burgIcons.selectAll("g");
|
||||
const citiesGroup = burgIcons.select("#cities");
|
||||
const townsGroup = burgIcons.select("#towns");
|
||||
if (!iconGroups.size() || (iconGroups.size() === 2 && citiesGroup.size() && townsGroup.size())) {
|
||||
// it looks the loaded map has old default groups
|
||||
options.burgs.groups = Burgs.getDefaultGroups();
|
||||
} else {
|
||||
burgIcons.selectAll("circle, use").each(function () {
|
||||
const group = this.parentNode.id;
|
||||
const id = this.id.replace(/^burg/, "");
|
||||
const burg = pack.burgs[id];
|
||||
if (group && burg) burg.group = group;
|
||||
});
|
||||
|
||||
burgIcons.selectAll("g").each(function (_el, index) {
|
||||
const name = this.id;
|
||||
const isDefault = name === "towns";
|
||||
options.burgs.groups.push({name, active: true, order: index + 1, isDefault, preview: "watabou-city"});
|
||||
|
||||
const size = Number(this.getAttribute("size") || 2) * 2;
|
||||
this.removeAttribute("size");
|
||||
this.setAttribute("font-size", size);
|
||||
|
||||
this.setAttribute("stroke-width", 1);
|
||||
});
|
||||
|
||||
if (options.burgs.groups.filter(g => g.isDefault).length === 0) {
|
||||
options.burgs.groups[0].isDefault = true;
|
||||
}
|
||||
|
||||
anchors.selectAll("g").each(function () {
|
||||
const size = Number(this.getAttribute("size") || 1);
|
||||
this.removeAttribute("size");
|
||||
this.setAttribute("font-size", size);
|
||||
});
|
||||
}
|
||||
|
||||
const iconSymbol = byId("icon-anchor");
|
||||
if (iconSymbol) {
|
||||
iconSymbol.outerHTML = /* html */ `<symbol id="icon-anchor" viewBox="0 0 30 30" width="1em" height="1em" overflow="visible">
|
||||
<path d="m 1.003,-9.873 c 0,-0.547 -0.453,-1 -1,-1 -0.547,0 -1,0.453 -1,1 0,0.547 0.453,1 1,1 0.547,0 1,-0.453 1,-1 z m 13,14.5 v 5.5 c 0,0.203 -0.125,0.391 -0.313,0.469 -0.063,0.016 -0.125,0.031 -0.187,0.031 -0.125,0 -0.25,-0.047 -0.359,-0.141 L 11.691,9.033 c -2.453,2.953 -6.859,4.844 -11.688,4.844 -4.829,0 -9.234,-1.891 -11.688,-4.844 l -1.453,1.453 c -0.094,0.094 -0.234,0.141 -0.359,0.141 -0.063,0 -0.125,-0.016 -0.187,-0.031 -0.187,-0.078 -0.313,-0.266 -0.313,-0.469 v -5.5 c 0,-0.281 0.219,-0.5 0.5,-0.5 h 5.5 c 0.203,0 0.391,0.125 0.469,0.313 0.078,0.188 0.031,0.391 -0.109,0.547 L -9.2,6.55 c 1.406,1.891 4.109,3.266 7.203,3.687 V 0.128 h -3 c -0.547,0 -1,-0.453 -1,-1 v -2 c 0,-0.547 0.453,-1 1,-1 h 3 v -2.547 c -1.188,-0.688 -2,-1.969 -2,-3.453 0,-2.203 1.797,-4 4,-4 2.203,0 4,1.797 4,4 0,1.484 -0.812,2.766 -2,3.453 v 2.547 h 3 c 0.547,0 1,0.453 1,1 v 2 c 0,0.547 -0.453,1 -1,1 h -3 V 10.237 C 5.097,9.815 7.8,8.44 9.206,6.55 L 7.643,4.987 C 7.502,4.831 7.456,4.628 7.534,4.44 7.612,4.252 7.8,4.127 8.003,4.127 h 5.5 c 0.281,0 0.5,0.219 0.5,0.5 z"/>
|
||||
</symbol>`;
|
||||
}
|
||||
|
||||
const validBurgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const populations = validBurgs.map(b => b.population).sort((a, b) => a - b);
|
||||
validBurgs.forEach(burg => {
|
||||
if (!burg.group) Burgs.defineGroup(burg, populations);
|
||||
|
||||
if (burg.MFCG) {
|
||||
burg.link = getBurgLink(burg);
|
||||
delete burg.MFCG;
|
||||
}
|
||||
});
|
||||
|
||||
layerIsOn("toggleBurgIcons") && drawBurgIcons();
|
||||
|
||||
delete options.showBurgPreview;
|
||||
delete options.showMFCGMap;
|
||||
delete options.villageMaxPopulation;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ function addListeners() {
|
|||
}
|
||||
|
||||
function refreshStatesEditor() {
|
||||
BurgsAndStates.collectStatistics();
|
||||
States.collectStatistics();
|
||||
statesEditorAddLines();
|
||||
}
|
||||
|
||||
|
|
@ -603,7 +603,7 @@ function stateRemove(stateId) {
|
|||
burg.state = 0;
|
||||
if (burg.capital) {
|
||||
burg.capital = 0;
|
||||
moveBurgToGroup(burg.i, "towns");
|
||||
Burgs.changeGroup(burg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -840,10 +840,10 @@ function openRegenerationMenu() {
|
|||
function recalculateStates(must) {
|
||||
if (!must && !statesAutoChange.checked) return;
|
||||
|
||||
BurgsAndStates.expandStates();
|
||||
States.expandStates();
|
||||
Provinces.generate();
|
||||
Provinces.getPoles();
|
||||
BurgsAndStates.getPoles();
|
||||
States.getPoles();
|
||||
|
||||
if (layerIsOn("toggleStates")) drawStates();
|
||||
if (layerIsOn("toggleBorders")) drawBorders();
|
||||
|
|
@ -985,7 +985,7 @@ function applyStatesManualAssignent() {
|
|||
|
||||
if (affectedStates.length) {
|
||||
refreshStatesEditor();
|
||||
BurgsAndStates.getPoles();
|
||||
States.getPoles();
|
||||
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
||||
if (adjustLabels.checked) drawStateLabels([...new Set(affectedStates)]);
|
||||
adjustProvinces([...new Set(affectedProvinces)]);
|
||||
|
|
@ -1103,7 +1103,7 @@ function adjustProvinces(affectedProvinces) {
|
|||
const color = getMixedColor(states[stateId].color);
|
||||
|
||||
const kinship = nameByBurg ? 0.8 : 0.4;
|
||||
const type = BurgsAndStates.getType(center, burg?.port);
|
||||
const type = Burgs.getType(center, burg?.port);
|
||||
const coa = COA.generate(burg?.coa || states[stateId].coa, kinship, burg ? null : 0.9, type);
|
||||
coa.shield = COA.getShield(culture, stateId);
|
||||
|
||||
|
|
@ -1181,30 +1181,30 @@ function addState() {
|
|||
if (cells.h[center] < 20)
|
||||
return tip("You cannot place state into the water. Please click on a land cell", false, "error");
|
||||
|
||||
let burg = cells.burg[center];
|
||||
if (burg && burgs[burg].capital)
|
||||
let burgId = cells.burg[center];
|
||||
if (burgId && burgs[burgId].capital)
|
||||
return tip("Existing capital cannot be selected as a new state capital! Select other cell", false, "error");
|
||||
|
||||
if (!burg) burg = addBurg(point); // add new burg
|
||||
if (!burgId) burgId = Burgs.add(point);
|
||||
|
||||
const oldState = cells.state[center];
|
||||
const newState = states.length;
|
||||
|
||||
// turn burg into a capital
|
||||
burgs[burg].capital = 1;
|
||||
burgs[burg].state = newState;
|
||||
moveBurgToGroup(burg, "cities");
|
||||
burgs[burgId].capital = 1;
|
||||
burgs[burgId].state = newState;
|
||||
Burgs.changeGroup(burgs[burgId]);
|
||||
|
||||
if (d3.event.shiftKey === false) exitAddStateMode();
|
||||
|
||||
const culture = cells.culture[center];
|
||||
const basename = center % 5 === 0 ? burgs[burg].name : Names.getCulture(culture);
|
||||
const basename = center % 5 === 0 ? burgs[burgId].name : Names.getCulture(culture);
|
||||
const name = Names.getState(basename, culture);
|
||||
const color = getRandomColor();
|
||||
|
||||
// generate emblem
|
||||
const cultureType = pack.cultures[culture].type;
|
||||
const coa = COA.generate(burgs[burg].coa, 0.4, null, cultureType);
|
||||
const coa = COA.generate(burgs[burgId].coa, 0.4, null, cultureType);
|
||||
coa.shield = COA.getShield(culture, null);
|
||||
|
||||
// update diplomacy and reverse relations
|
||||
|
|
@ -1244,7 +1244,7 @@ function addState() {
|
|||
provinces: [],
|
||||
color,
|
||||
expansionism: 0.5,
|
||||
capital: burg,
|
||||
capital: burgId,
|
||||
type: "Generic",
|
||||
center,
|
||||
culture,
|
||||
|
|
@ -1253,9 +1253,10 @@ function addState() {
|
|||
coa
|
||||
});
|
||||
|
||||
BurgsAndStates.getPoles();
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.defineStateForms([newState]);
|
||||
States.getPoles();
|
||||
States.findNeighbors();
|
||||
States.collectStatistics();
|
||||
States.defineStateForms([newState]);
|
||||
adjustProvinces([cells.province[center]]);
|
||||
|
||||
drawStateLabels([newState]);
|
||||
|
|
@ -1379,19 +1380,19 @@ function openStateMergeDialog() {
|
|||
});
|
||||
|
||||
// reassing burgs
|
||||
pack.burgs.forEach(b => {
|
||||
if (statesToMerge.includes(b.state)) {
|
||||
if (b.capital) {
|
||||
moveBurgToGroup(b.i, "towns");
|
||||
b.capital = 0;
|
||||
pack.burgs.forEach(burg => {
|
||||
if (statesToMerge.includes(burg.state)) {
|
||||
if (burg.capital) {
|
||||
burg.capital = 0;
|
||||
Burgs.changeGroup(burg);
|
||||
}
|
||||
b.state = rulingStateId;
|
||||
burg.state = rulingStateId;
|
||||
}
|
||||
});
|
||||
|
||||
// reassign provinces
|
||||
pack.provinces.forEach((p, i) => {
|
||||
if (statesToMerge.includes(p.state)) p.state = rulingStateId;
|
||||
pack.provinces.forEach(province => {
|
||||
if (statesToMerge.includes(province.state)) province.state = rulingStateId;
|
||||
});
|
||||
|
||||
// reassing cells
|
||||
|
|
@ -1402,7 +1403,7 @@ function openStateMergeDialog() {
|
|||
unfog();
|
||||
debug.selectAll(".highlight").remove();
|
||||
|
||||
BurgsAndStates.getPoles();
|
||||
States.getPoles();
|
||||
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
||||
layerIsOn("toggleBorders") ? drawBorders() : toggleBorders();
|
||||
layerIsOn("toggleProvinces") && drawProvinces();
|
||||
|
|
|
|||
|
|
@ -168,8 +168,9 @@ async function exportToPngTiles() {
|
|||
}
|
||||
|
||||
// parse map svg to object url
|
||||
async function getMapURL(type, options) {
|
||||
const {
|
||||
async function getMapURL(
|
||||
type,
|
||||
{
|
||||
debug = false,
|
||||
noLabels = false,
|
||||
noWater = false,
|
||||
|
|
@ -177,8 +178,8 @@ async function getMapURL(type, options) {
|
|||
noIce = false,
|
||||
noVignette = false,
|
||||
fullMap = false
|
||||
} = options || {};
|
||||
|
||||
} = {}
|
||||
) {
|
||||
const cloneEl = byId("map").cloneNode(true); // clone svg
|
||||
cloneEl.id = "fantasyMap";
|
||||
document.body.appendChild(cloneEl);
|
||||
|
|
@ -307,6 +308,15 @@ async function getMapURL(type, options) {
|
|||
if (rose) cloneDefs.appendChild(rose.cloneNode(true));
|
||||
}
|
||||
|
||||
// add burs icons
|
||||
if (cloneEl.getElementById("burgIcons")) {
|
||||
const groups = cloneEl.getElementById("burgIcons").querySelectorAll("g");
|
||||
for (const group of Array.from(groups)) {
|
||||
const icon = svgDefs.querySelector(group.dataset.icon);
|
||||
if (icon) cloneDefs.appendChild(icon.cloneNode(true));
|
||||
}
|
||||
}
|
||||
|
||||
// add port icon
|
||||
if (cloneEl.getElementById("anchors")) {
|
||||
const anchor = svgDefs.getElementById("icon-anchor");
|
||||
|
|
|
|||
|
|
@ -618,14 +618,12 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (!state.i && capitalBurgs.length) {
|
||||
ERROR &&
|
||||
console.error(
|
||||
`[Data integrity] Neutral burgs (${capitalBurgs
|
||||
.map(b => b.i)
|
||||
.join(", ")}) marked as capitals. Moving them to towns`
|
||||
`[Data integrity] Neutral burgs (${capitalBurgs.map(b => b.i).join(", ")}) marked as capitals`
|
||||
);
|
||||
|
||||
capitalBurgs.forEach(burg => {
|
||||
burg.capital = 0;
|
||||
moveBurgToGroup(burg.i, "towns");
|
||||
Burgs.changeGroup(burg);
|
||||
});
|
||||
|
||||
return;
|
||||
|
|
@ -634,23 +632,23 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (capitalBurgs.length > 1) {
|
||||
const message = `[Data integrity] State ${state.i} has multiple capitals (${capitalBurgs
|
||||
.map(b => b.i)
|
||||
.join(", ")}) assigned. Keeping the first as capital and moving others to towns`;
|
||||
.join(", ")}) assigned. Keeping the first as capital and moving others`;
|
||||
ERROR && console.error(message);
|
||||
|
||||
capitalBurgs.forEach((burg, i) => {
|
||||
if (!i) return;
|
||||
burg.capital = 0;
|
||||
moveBurgToGroup(burg.i, "towns");
|
||||
Burgs.changeGroup(burg);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.i && stateBurgs.length && !capitalBurgs.length) {
|
||||
ERROR &&
|
||||
console.error(`[Data integrity] State ${state.i} has no capital. Assigning the first burg as capital`);
|
||||
stateBurgs[0].capital = 1;
|
||||
moveBurgToGroup(stateBurgs[0].i, "cities");
|
||||
ERROR && console.error(`[Data integrity] State ${state.i} has no capital. Making the first burg capital`);
|
||||
const capital = stateBurgs[0];
|
||||
capital.capital = 1;
|
||||
Burgs.changeGroup(capital);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ window.Markers = (function () {
|
|||
const {cells, states} = pack;
|
||||
|
||||
const state = states[cells.state[cell]];
|
||||
if (!state.campaigns) state.campaigns = BurgsAndStates.generateCampaign(state);
|
||||
if (!state.campaigns) state.campaigns = States.generateCampaign(state);
|
||||
const campaign = ra(state.campaigns);
|
||||
const date = generateDate(campaign.start, campaign.end);
|
||||
const name = Names.getCulture(cells.culture[cell]) + " Battlefield";
|
||||
|
|
@ -1203,7 +1203,7 @@ window.Markers = (function () {
|
|||
const burgName = burgs[cells.burg[cell]].name;
|
||||
|
||||
const name = `${burgName} Portal`;
|
||||
const legend = `An element of the magic portal system connecting major cities. The portals were installed centuries ago, but still work fine.`;
|
||||
const legend = `An element of the magic portal system connecting major city. The portals were installed centuries ago, but still work fine.`;
|
||||
notes.push({id, name, legend});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ window.Provinces = (function () {
|
|||
const fullName = name + " " + formName;
|
||||
const color = getMixedColor(s.color);
|
||||
const kinship = nameByBurg ? 0.8 : 0.4;
|
||||
const type = BurgsAndStates.getType(center, burg.port);
|
||||
const type = Burgs.getType(center, burg.port);
|
||||
const coa = COA.generate(stateBurgs[i].coa, kinship, null, type);
|
||||
coa.shield = COA.getShield(c, s.i);
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ window.Provinces = (function () {
|
|||
|
||||
const dominion = colony ? P(0.95) : singleIsle || isleGroup ? P(0.7) : P(0.3);
|
||||
const kinship = dominion ? 0 : 0.4;
|
||||
const type = BurgsAndStates.getType(center, burgs[burg]?.port);
|
||||
const type = Burgs.getType(center, burgs[burg]?.port);
|
||||
const coa = COA.generate(s.coa, kinship, dominion, type);
|
||||
coa.shield = COA.getShield(c, s.i);
|
||||
|
||||
|
|
|
|||
|
|
@ -851,13 +851,6 @@ window.Religions = (function () {
|
|||
cells.religion[center] = i;
|
||||
};
|
||||
|
||||
function updateCultures() {
|
||||
pack.religions = pack.religions.map((religion, index) => {
|
||||
if (index === 0) return religion;
|
||||
return {...religion, culture: pack.cells.culture[religion.center]};
|
||||
});
|
||||
}
|
||||
|
||||
// get supreme deity name
|
||||
const getDeityName = function (culture) {
|
||||
if (culture === undefined) {
|
||||
|
|
@ -924,5 +917,5 @@ window.Religions = (function () {
|
|||
return [trimVowels(random()) + "ism", "global"]; // else
|
||||
}
|
||||
|
||||
return {generate, add, getDeityName, updateCultures, recalculate};
|
||||
return {generate, add, getDeityName, recalculate};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -2,68 +2,105 @@
|
|||
|
||||
function drawBurgIcons() {
|
||||
TIME && console.time("drawBurgIcons");
|
||||
createIconGroups();
|
||||
|
||||
icons.selectAll("circle, use").remove(); // cleanup
|
||||
for (const {name} of options.burgs.groups) {
|
||||
const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed);
|
||||
if (!burgsInGroup.length) continue;
|
||||
|
||||
// capitals
|
||||
const capitals = pack.burgs.filter(b => b.capital && !b.removed);
|
||||
const capitalIcons = burgIcons.select("#cities");
|
||||
const capitalSize = capitalIcons.attr("size") || 1;
|
||||
const capitalAnchors = anchors.selectAll("#cities");
|
||||
const capitalAnchorsSize = capitalAnchors.attr("size") || 2;
|
||||
const iconsGroup = document.querySelector("#burgIcons > g#" + name);
|
||||
if (!iconsGroup) continue;
|
||||
|
||||
capitalIcons
|
||||
.selectAll("circle")
|
||||
.data(capitals)
|
||||
.enter()
|
||||
.append("circle")
|
||||
.attr("id", d => "burg" + d.i)
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("cx", d => d.x)
|
||||
.attr("cy", d => d.y)
|
||||
.attr("r", capitalSize);
|
||||
const icon = iconsGroup.dataset.icon || "#icon-circle";
|
||||
iconsGroup.innerHTML = burgsInGroup
|
||||
.map(b => `<use id="burg${b.i}" data-id="${b.i}" href="${icon}" x="${b.x}" y="${b.y}"></use>`)
|
||||
.join("");
|
||||
|
||||
capitalAnchors
|
||||
.selectAll("use")
|
||||
.data(capitals.filter(c => c.port))
|
||||
.enter()
|
||||
.append("use")
|
||||
.attr("xlink:href", "#icon-anchor")
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("x", d => rn(d.x - capitalAnchorsSize * 0.47, 2))
|
||||
.attr("y", d => rn(d.y - capitalAnchorsSize * 0.47, 2))
|
||||
.attr("width", capitalAnchorsSize)
|
||||
.attr("height", capitalAnchorsSize);
|
||||
const portsInGroup = burgsInGroup.filter(b => b.port);
|
||||
if (!portsInGroup.length) continue;
|
||||
|
||||
// towns
|
||||
const towns = pack.burgs.filter(b => b.i && !b.capital && !b.removed);
|
||||
const townIcons = burgIcons.select("#towns");
|
||||
const townSize = townIcons.attr("size") || 0.5;
|
||||
const townsAnchors = anchors.selectAll("#towns");
|
||||
const townsAnchorsSize = townsAnchors.attr("size") || 1;
|
||||
const portGroup = document.querySelector("#anchors > g#" + name);
|
||||
if (!portGroup) continue;
|
||||
|
||||
townIcons
|
||||
.selectAll("circle")
|
||||
.data(towns)
|
||||
.enter()
|
||||
.append("circle")
|
||||
.attr("id", d => "burg" + d.i)
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("cx", d => d.x)
|
||||
.attr("cy", d => d.y)
|
||||
.attr("r", townSize);
|
||||
|
||||
townsAnchors
|
||||
.selectAll("use")
|
||||
.data(towns.filter(c => c.port))
|
||||
.enter()
|
||||
.append("use")
|
||||
.attr("xlink:href", "#icon-anchor")
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("x", d => rn(d.x - townsAnchorsSize * 0.47, 2))
|
||||
.attr("y", d => rn(d.y - townsAnchorsSize * 0.47, 2))
|
||||
.attr("width", townsAnchorsSize)
|
||||
.attr("height", townsAnchorsSize);
|
||||
portGroup.innerHTML = portsInGroup
|
||||
.map(b => `<use id="anchor${b.i}" data-id="${b.i}" href="#icon-anchor" x="${b.x}" y="${b.y}"></use>`)
|
||||
.join("");
|
||||
}
|
||||
|
||||
TIME && console.timeEnd("drawBurgIcons");
|
||||
}
|
||||
|
||||
function drawBurgIcon(burg) {
|
||||
removeBurgIcon(burg.i);
|
||||
|
||||
const iconGroup = burgIcons.select("#" + burg.group);
|
||||
if (iconGroup.empty()) return;
|
||||
|
||||
const icon = iconGroup.attr("data-icon") || "#icon-circle";
|
||||
burgIcons
|
||||
.select("#" + burg.group)
|
||||
.append("use")
|
||||
.attr("href", icon)
|
||||
.attr("id", "burg" + burg.i)
|
||||
.attr("data-id", burg.i)
|
||||
.attr("x", burg.x)
|
||||
.attr("y", burg.y);
|
||||
|
||||
if (burg.port) {
|
||||
anchors
|
||||
.select("#" + burg.group)
|
||||
.append("use")
|
||||
.attr("href", "#icon-anchor")
|
||||
.attr("id", "anchor" + burg.i)
|
||||
.attr("data-id", burg.i)
|
||||
.attr("x", burg.x)
|
||||
.attr("y", burg.y);
|
||||
}
|
||||
}
|
||||
|
||||
function removeBurgIcon(burgId) {
|
||||
const existingIcon = document.getElementById("burg" + burgId);
|
||||
if (existingIcon) existingIcon.remove();
|
||||
|
||||
const existingAnchor = document.getElementById("anchor" + burgId);
|
||||
if (existingAnchor) existingAnchor.remove();
|
||||
}
|
||||
|
||||
function createIconGroups() {
|
||||
// save existing styles and remove all groups
|
||||
document.querySelectorAll("g#burgIcons > g").forEach(group => {
|
||||
style.burgIcons[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
|
||||
acc[attribute.name] = attribute.value;
|
||||
return acc;
|
||||
}, {});
|
||||
group.remove();
|
||||
});
|
||||
|
||||
document.querySelectorAll("g#anchors > g").forEach(group => {
|
||||
style.anchors[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
|
||||
acc[attribute.name] = attribute.value;
|
||||
return acc;
|
||||
}, {});
|
||||
group.remove();
|
||||
});
|
||||
|
||||
// create groups for each burg group and apply stored or default style
|
||||
const defaultIconStyle = style.burgIcons.town || Object.values(style.burgIcons)[0];
|
||||
const defaultAnchorStyle = style.anchors.town || Object.values(style.anchors)[0];
|
||||
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
|
||||
for (const {name} of sortedGroups) {
|
||||
const burgGroup = burgIcons.append("g");
|
||||
const iconStyles = style.burgIcons[name] || defaultIconStyle;
|
||||
Object.entries(iconStyles).forEach(([key, value]) => {
|
||||
burgGroup.attr(key, value);
|
||||
});
|
||||
burgGroup.attr("id", name);
|
||||
|
||||
const anchorGroup = anchors.append("g");
|
||||
const anchorStyles = style.anchors[name] || defaultAnchorStyle;
|
||||
Object.entries(anchorStyles).forEach(([key, value]) => {
|
||||
anchorGroup.attr(key, value);
|
||||
});
|
||||
anchorGroup.attr("id", name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,40 +2,80 @@
|
|||
|
||||
function drawBurgLabels() {
|
||||
TIME && console.time("drawBurgLabels");
|
||||
createLabelGroups();
|
||||
|
||||
burgLabels.selectAll("text").remove(); // cleanup
|
||||
for (const {name} of options.burgs.groups) {
|
||||
const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed);
|
||||
if (!burgsInGroup.length) continue;
|
||||
|
||||
const capitals = pack.burgs.filter(b => b.capital && !b.removed);
|
||||
const capitalSize = burgIcons.select("#cities").attr("size") || 1;
|
||||
burgLabels
|
||||
.select("#cities")
|
||||
.selectAll("text")
|
||||
.data(capitals)
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("text-rendering", "optimizeSpeed")
|
||||
.attr("id", d => "burgLabel" + d.i)
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("x", d => d.x)
|
||||
.attr("y", d => d.y)
|
||||
.attr("dy", `${capitalSize * -1.5}px`)
|
||||
.text(d => d.name);
|
||||
const labelGroup = burgLabels.select("#" + name);
|
||||
if (labelGroup.empty()) continue;
|
||||
|
||||
const towns = pack.burgs.filter(b => b.i && !b.capital && !b.removed);
|
||||
const townSize = burgIcons.select("#towns").attr("size") || 0.5;
|
||||
burgLabels
|
||||
.select("#towns")
|
||||
.selectAll("text")
|
||||
.data(towns)
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("text-rendering", "optimizeSpeed")
|
||||
.attr("id", d => "burgLabel" + d.i)
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("x", d => d.x)
|
||||
.attr("y", d => d.y)
|
||||
.attr("dy", `${townSize * -2}px`)
|
||||
.text(d => d.name);
|
||||
const dx = labelGroup.attr("data-dx") || 0;
|
||||
const dy = labelGroup.attr("data-dy") || 0;
|
||||
|
||||
labelGroup
|
||||
.selectAll("text")
|
||||
.data(burgsInGroup)
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("text-rendering", "optimizeSpeed")
|
||||
.attr("id", d => "burgLabel" + d.i)
|
||||
.attr("data-id", d => d.i)
|
||||
.attr("x", d => d.x)
|
||||
.attr("y", d => d.y)
|
||||
.attr("dx", dx + "em")
|
||||
.attr("dy", dy + "em")
|
||||
.text(d => d.name);
|
||||
}
|
||||
|
||||
TIME && console.timeEnd("drawBurgLabels");
|
||||
}
|
||||
|
||||
function drawBurgLabel(burg) {
|
||||
removeBurgLabel(burg.i);
|
||||
|
||||
const labelGroup = burgLabels.select("#" + burg.group);
|
||||
if (labelGroup.empty()) return;
|
||||
const dx = labelGroup.attr("data-dx") || 0;
|
||||
const dy = labelGroup.attr("data-dy") || 0;
|
||||
|
||||
labelGroup
|
||||
.append("text")
|
||||
.attr("text-rendering", "optimizeSpeed")
|
||||
.attr("id", "burgLabel" + burg.i)
|
||||
.attr("data-id", burg.i)
|
||||
.attr("x", burg.x)
|
||||
.attr("y", burg.y)
|
||||
.attr("dx", dx + "em")
|
||||
.attr("dy", dy + "em")
|
||||
.text(burg.name);
|
||||
}
|
||||
|
||||
function removeBurgLabel(burgId) {
|
||||
const existingLabel = document.getElementById("burgLabel" + burgId);
|
||||
if (existingLabel) existingLabel.remove();
|
||||
}
|
||||
|
||||
function createLabelGroups() {
|
||||
// save existing styles and remove all groups
|
||||
document.querySelectorAll("g#burgLabels > g").forEach(group => {
|
||||
style.burgLabels[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
|
||||
acc[attribute.name] = attribute.value;
|
||||
return acc;
|
||||
}, {});
|
||||
group.remove();
|
||||
});
|
||||
|
||||
// create groups for each burg group and apply stored or default style
|
||||
const defaultStyle = style.burgLabels.town || Object.values(style.burgLabels)[0];
|
||||
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
|
||||
for (const {name} of sortedGroups) {
|
||||
const group = burgLabels.append("g");
|
||||
const styles = style.burgLabels[name] || defaultStyle;
|
||||
Object.entries(styles).forEach(([key, value]) => {
|
||||
group.attr(key, value);
|
||||
});
|
||||
group.attr("id", name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,7 +360,8 @@ window.Routes = (function () {
|
|||
// connect cell with routes system by land
|
||||
function connect(cellId) {
|
||||
const getCost = createCostEvaluator({isWater: false, connections: new Map()});
|
||||
const pathCells = findPath(cellId, isConnected, getCost);
|
||||
const isExit = cellId => isLand(cellId) && isConnected(cellId);
|
||||
const pathCells = findPath(cellId, isExit, getCost);
|
||||
if (!pathCells) return;
|
||||
|
||||
const pointsArray = preparePointsArray();
|
||||
|
|
@ -432,6 +433,26 @@ window.Routes = (function () {
|
|||
return roadConnections.length > 2;
|
||||
}
|
||||
|
||||
const connectivityRateMap = {
|
||||
roads: 0.2,
|
||||
trails: 0.1,
|
||||
searoutes: 0.2,
|
||||
default: 0.1
|
||||
};
|
||||
|
||||
function getConnectivityRate(cellId) {
|
||||
const connections = pack.cells.routes[cellId];
|
||||
if (!connections) return 0;
|
||||
|
||||
const connectivity = Object.values(connections).reduce((acc, routeId) => {
|
||||
const route = pack.routes.find(route => route.i === routeId);
|
||||
const rate = connectivityRateMap[route.group] || connectivityRateMap.default;
|
||||
return acc + rate;
|
||||
}, 0.8);
|
||||
|
||||
return connectivity;
|
||||
}
|
||||
|
||||
// name generator data
|
||||
const models = {
|
||||
roads: {burg_suffix: 3, prefix_suffix: 6, the_descriptor_prefix_suffix: 2, the_descriptor_burg_suffix: 1},
|
||||
|
|
@ -645,6 +666,7 @@ window.Routes = (function () {
|
|||
getRoute,
|
||||
hasRoad,
|
||||
isCrossroad,
|
||||
getConnectivityRate,
|
||||
generateName,
|
||||
getPath,
|
||||
getLength,
|
||||
|
|
|
|||
|
|
@ -1,283 +1,47 @@
|
|||
"use strict";
|
||||
|
||||
window.BurgsAndStates = (() => {
|
||||
window.States = (() => {
|
||||
const generate = () => {
|
||||
const {cells, cultures} = pack;
|
||||
const n = cells.i.length;
|
||||
|
||||
cells.burg = new Uint16Array(n); // cell burg
|
||||
|
||||
const burgs = (pack.burgs = placeCapitals());
|
||||
TIME && console.time("generateStates");
|
||||
pack.states = createStates();
|
||||
|
||||
placeTowns();
|
||||
expandStates();
|
||||
normalizeStates();
|
||||
normalize();
|
||||
getPoles();
|
||||
|
||||
specifyBurgs();
|
||||
|
||||
collectStatistics();
|
||||
findNeighbors();
|
||||
assignColors();
|
||||
|
||||
generateCampaigns();
|
||||
generateDiplomacy();
|
||||
|
||||
function placeCapitals() {
|
||||
TIME && console.time("placeCapitals");
|
||||
let count = +byId("statesNumber").value;
|
||||
let burgs = [0];
|
||||
TIME && console.timeEnd("generateStates");
|
||||
|
||||
const rand = () => 0.5 + Math.random() * 0.5;
|
||||
const score = new Int16Array(cells.s.map(s => s * rand())); // cell score for capitals placement
|
||||
const sorted = cells.i.filter(i => score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
|
||||
|
||||
if (sorted.length < count * 10) {
|
||||
count = Math.floor(sorted.length / 10);
|
||||
if (!count) {
|
||||
WARN && console.warn("There is no populated cells. Cannot generate states");
|
||||
return burgs;
|
||||
} else {
|
||||
WARN && console.warn(`Not enough populated cells (${sorted.length}). Will generate only ${count} states`);
|
||||
}
|
||||
}
|
||||
|
||||
let burgsTree = d3.quadtree();
|
||||
let spacing = (graphWidth + graphHeight) / 2 / count; // min distance between capitals
|
||||
|
||||
for (let i = 0; burgs.length <= count; i++) {
|
||||
const cell = sorted[i];
|
||||
const [x, y] = cells.p[cell];
|
||||
|
||||
if (burgsTree.find(x, y, spacing) === undefined) {
|
||||
burgs.push({cell, x, y});
|
||||
burgsTree.add([x, y]);
|
||||
}
|
||||
|
||||
if (i === sorted.length - 1) {
|
||||
WARN && console.warn("Cannot place capitals with current spacing. Trying again with reduced spacing");
|
||||
burgsTree = d3.quadtree();
|
||||
i = -1;
|
||||
burgs = [0];
|
||||
spacing /= 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
burgs[0] = burgsTree;
|
||||
TIME && console.timeEnd("placeCapitals");
|
||||
return burgs;
|
||||
}
|
||||
|
||||
// For each capital create a state
|
||||
// for each capital create a state
|
||||
function createStates() {
|
||||
TIME && console.time("createStates");
|
||||
const states = [{i: 0, name: "Neutrals"}];
|
||||
const colors = getColors(burgs.length - 1);
|
||||
const each5th = each(5);
|
||||
|
||||
burgs.forEach((b, i) => {
|
||||
if (!i) return; // skip first element
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || !burg.capital) return;
|
||||
|
||||
// burgs data
|
||||
b.i = b.state = i;
|
||||
b.culture = cells.culture[b.cell];
|
||||
b.name = Names.getCultureShort(b.culture);
|
||||
b.feature = cells.f[b.cell];
|
||||
b.capital = 1;
|
||||
|
||||
// states data
|
||||
const expansionism = rn(Math.random() * byId("sizeVariety").value + 1, 1);
|
||||
const basename = b.name.length < 9 && each5th(b.cell) ? b.name : Names.getCultureShort(b.culture);
|
||||
const name = Names.getState(basename, b.culture);
|
||||
const type = cultures[b.culture].type;
|
||||
|
||||
const basename = burg.name.length < 9 && each5th(burg.cell) ? burg.name : Names.getCultureShort(burg.culture);
|
||||
const name = Names.getState(basename, burg.culture);
|
||||
const type = pack.cultures[burg.culture].type;
|
||||
const coa = COA.generate(null, null, null, type);
|
||||
coa.shield = COA.getShield(b.culture, null);
|
||||
coa.shield = COA.getShield(burg.culture, null);
|
||||
states.push({
|
||||
i,
|
||||
color: colors[i - 1],
|
||||
i: burg.i,
|
||||
name,
|
||||
expansionism,
|
||||
capital: i,
|
||||
capital: burg.i,
|
||||
type,
|
||||
center: b.cell,
|
||||
culture: b.culture,
|
||||
center: burg.cell,
|
||||
culture: burg.culture,
|
||||
coa
|
||||
});
|
||||
cells.burg[b.cell] = i;
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("createStates");
|
||||
return states;
|
||||
}
|
||||
|
||||
// place secondary settlements based on geo and economical evaluation
|
||||
function placeTowns() {
|
||||
TIME && console.time("placeTowns");
|
||||
const score = new Int16Array(cells.s.map(s => s * gauss(1, 3, 0, 20, 3))); // a bit randomized cell score for towns placement
|
||||
const sorted = cells.i
|
||||
.filter(i => !cells.burg[i] && score[i] > 0 && cells.culture[i])
|
||||
.sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
|
||||
|
||||
const desiredNumber =
|
||||
manorsInput.value == 1000
|
||||
? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8)
|
||||
: manorsInput.valueAsNumber;
|
||||
const burgsNumber = Math.min(desiredNumber, sorted.length); // towns to generate
|
||||
let burgsAdded = 0;
|
||||
|
||||
const burgsTree = burgs[0];
|
||||
let spacing = (graphWidth + graphHeight) / 150 / (burgsNumber ** 0.7 / 66); // min distance between towns
|
||||
|
||||
while (burgsAdded < burgsNumber && spacing > 1) {
|
||||
for (let i = 0; burgsAdded < burgsNumber && i < sorted.length; i++) {
|
||||
if (cells.burg[sorted[i]]) continue;
|
||||
const cell = sorted[i];
|
||||
const [x, y] = cells.p[cell];
|
||||
const s = spacing * gauss(1, 0.3, 0.2, 2, 2); // randomize to make placement not uniform
|
||||
if (burgsTree.find(x, y, s) !== undefined) continue; // to close to existing burg
|
||||
const burg = burgs.length;
|
||||
const culture = cells.culture[cell];
|
||||
const name = Names.getCulture(culture);
|
||||
burgs.push({cell, x, y, state: 0, i: burg, culture, name, capital: 0, feature: cells.f[cell]});
|
||||
burgsTree.add([x, y]);
|
||||
cells.burg[cell] = burg;
|
||||
burgsAdded++;
|
||||
}
|
||||
spacing *= 0.5;
|
||||
}
|
||||
|
||||
if (manorsInput.value != 1000 && burgsAdded < desiredNumber) {
|
||||
ERROR && console.error(`Cannot place all burgs. Requested ${desiredNumber}, placed ${burgsAdded}`);
|
||||
}
|
||||
|
||||
burgs[0] = {name: undefined}; // do not store burgsTree anymore
|
||||
TIME && console.timeEnd("placeTowns");
|
||||
}
|
||||
};
|
||||
|
||||
// define burg coordinates, coa, port status and define details
|
||||
const specifyBurgs = () => {
|
||||
TIME && console.time("specifyBurgs");
|
||||
const {cells, features} = pack;
|
||||
const temp = grid.cells.temp;
|
||||
|
||||
for (const b of pack.burgs) {
|
||||
if (!b.i || b.lock) continue;
|
||||
const i = b.cell;
|
||||
|
||||
// asign port status to some coastline burgs with temp > 0 °C
|
||||
const haven = cells.haven[i];
|
||||
if (haven && temp[cells.g[i]] > 0) {
|
||||
const f = cells.f[haven]; // water body id
|
||||
// port is a capital with any harbor OR town with good harbor
|
||||
const port = features[f].cells > 1 && ((b.capital && cells.harbor[i]) || cells.harbor[i] === 1);
|
||||
b.port = port ? f : 0; // port is defined by water body id it lays on
|
||||
} else b.port = 0;
|
||||
|
||||
// define burg population (keep urbanization at about 10% rate)
|
||||
b.population = rn(Math.max(cells.s[i] / 8 + b.i / 1000 + (i % 100) / 1000, 0.1), 3);
|
||||
if (b.capital) b.population = rn(b.population * 1.3, 3); // increase capital population
|
||||
|
||||
if (b.port) {
|
||||
b.population = b.population * 1.3; // increase port population
|
||||
const [x, y] = getCloseToEdgePoint(i, haven);
|
||||
b.x = x;
|
||||
b.y = y;
|
||||
}
|
||||
|
||||
// add random factor
|
||||
b.population = rn(b.population * gauss(2, 3, 0.6, 20, 3), 3);
|
||||
|
||||
// shift burgs on rivers semi-randomly and just a bit
|
||||
if (!b.port && cells.r[i]) {
|
||||
const shift = Math.min(cells.fl[i] / 150, 1);
|
||||
if (i % 2) b.x = rn(b.x + shift, 2);
|
||||
else b.x = rn(b.x - shift, 2);
|
||||
if (cells.r[i] % 2) b.y = rn(b.y + shift, 2);
|
||||
else b.y = rn(b.y - shift, 2);
|
||||
}
|
||||
|
||||
// define emblem
|
||||
const state = pack.states[b.state];
|
||||
const stateCOA = state.coa;
|
||||
let kinship = 0.25;
|
||||
if (b.capital) kinship += 0.1;
|
||||
else if (b.port) kinship -= 0.1;
|
||||
if (b.culture !== state.culture) kinship -= 0.25;
|
||||
b.type = getType(i, b.port);
|
||||
const type = b.capital && P(0.2) ? "Capital" : b.type === "Generic" ? "City" : b.type;
|
||||
b.coa = COA.generate(stateCOA, kinship, null, type);
|
||||
b.coa.shield = COA.getShield(b.culture, b.state);
|
||||
}
|
||||
|
||||
// de-assign port status if it's the only one on feature
|
||||
const ports = pack.burgs.filter(b => !b.removed && b.port > 0);
|
||||
for (const f of features) {
|
||||
if (!f.i || f.land || f.border) continue;
|
||||
const featurePorts = ports.filter(b => b.port === f.i);
|
||||
if (featurePorts.length === 1) featurePorts[0].port = 0;
|
||||
}
|
||||
|
||||
TIME && console.timeEnd("specifyBurgs");
|
||||
};
|
||||
|
||||
function getCloseToEdgePoint(cell1, cell2) {
|
||||
const {cells, vertices} = pack;
|
||||
|
||||
const [x0, y0] = cells.p[cell1];
|
||||
|
||||
const commonVertices = cells.v[cell1].filter(vertex => vertices.c[vertex].some(cell => cell === cell2));
|
||||
const [x1, y1] = vertices.p[commonVertices[0]];
|
||||
const [x2, y2] = vertices.p[commonVertices[1]];
|
||||
const xEdge = (x1 + x2) / 2;
|
||||
const yEdge = (y1 + y2) / 2;
|
||||
|
||||
const x = rn(x0 + 0.95 * (xEdge - x0), 2);
|
||||
const y = rn(y0 + 0.95 * (yEdge - y0), 2);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
const getType = (cellId, port) => {
|
||||
const {cells, features, burgs} = pack;
|
||||
|
||||
if (port) return "Naval";
|
||||
|
||||
const haven = cells.haven[cellId];
|
||||
if (haven !== undefined && features[cells.f[haven]].type === "lake") return "Lake";
|
||||
|
||||
if (cells.h[cellId] > 60) return "Highland";
|
||||
|
||||
if (cells.r[cellId] && cells.fl[cellId] >= 100) return "River";
|
||||
|
||||
const biome = cells.biome[cellId];
|
||||
const population = cells.pop[cellId];
|
||||
if (!cells.burg[cellId] || population <= 5) {
|
||||
if (population < 5 && [1, 2, 3, 4].includes(biome)) return "Nomadic";
|
||||
if (biome > 4 && biome < 10) return "Hunting";
|
||||
}
|
||||
|
||||
return "Generic";
|
||||
};
|
||||
|
||||
const defineBurgFeatures = burg => {
|
||||
const {cells} = pack;
|
||||
|
||||
pack.burgs
|
||||
.filter(b => (burg ? b.i == burg.i : b.i && !b.removed && !b.lock))
|
||||
.forEach(b => {
|
||||
const pop = b.population;
|
||||
b.citadel = Number(b.capital || (pop > 50 && P(0.75)) || (pop > 15 && P(0.5)) || P(0.1));
|
||||
b.plaza = Number(pop > 20 || (pop > 10 && P(0.8)) || (pop > 4 && P(0.7)) || P(0.6));
|
||||
b.walls = Number(b.capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.1));
|
||||
b.shanty = Number(pop > 60 || (pop > 40 && P(0.75)) || (pop > 20 && b.walls && P(0.4)));
|
||||
const religion = cells.religion[b.cell];
|
||||
const theocracy = pack.states[b.state].form === "Theocracy";
|
||||
b.temple = Number(
|
||||
(religion && theocracy && P(0.5)) || pop > 50 || (pop > 35 && P(0.75)) || (pop > 20 && P(0.5))
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// expand cultures across the map (Dijkstra-like algorithm)
|
||||
|
|
@ -379,7 +143,7 @@ window.BurgsAndStates = (() => {
|
|||
TIME && console.timeEnd("expandStates");
|
||||
};
|
||||
|
||||
const normalizeStates = () => {
|
||||
const normalize = () => {
|
||||
TIME && console.time("normalizeStates");
|
||||
const {cells, burgs} = pack;
|
||||
|
||||
|
|
@ -409,23 +173,53 @@ window.BurgsAndStates = (() => {
|
|||
});
|
||||
};
|
||||
|
||||
// Resets the cultures of all burgs and states to their cell or center cell's (respectively) culture
|
||||
const updateCultures = () => {
|
||||
TIME && console.time("updateCulturesForBurgsAndStates");
|
||||
const findNeighbors = () => {
|
||||
const {cells, states} = pack;
|
||||
|
||||
// Assign the culture associated with the burgs cell
|
||||
pack.burgs = pack.burgs.map((burg, index) => {
|
||||
if (index === 0) return burg;
|
||||
return {...burg, culture: pack.cells.culture[burg.cell]};
|
||||
states.forEach(s => {
|
||||
if (s.removed) return;
|
||||
s.neighbors = new Set();
|
||||
});
|
||||
|
||||
// Assign the culture associated with the states' center cell
|
||||
pack.states = pack.states.map((state, index) => {
|
||||
if (index === 0) return state;
|
||||
return {...state, culture: pack.cells.culture[state.center]};
|
||||
for (const i of cells.i) {
|
||||
if (cells.h[i] < 20) continue;
|
||||
const s = cells.state[i];
|
||||
|
||||
cells.c[i]
|
||||
.filter(c => cells.h[c] >= 20 && cells.state[c] !== s)
|
||||
.forEach(c => states[s].neighbors.add(cells.state[c]));
|
||||
}
|
||||
|
||||
// convert neighbors Set object into array
|
||||
states.forEach(s => {
|
||||
if (!s.neighbors || s.removed) return;
|
||||
s.neighbors = Array.from(s.neighbors);
|
||||
});
|
||||
};
|
||||
|
||||
const assignColors = () => {
|
||||
TIME && console.time("assignColors");
|
||||
const colors = ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f"]; // d3.schemeSet2;
|
||||
const states = pack.states;
|
||||
|
||||
// assign basic color using greedy coloring algorithm
|
||||
states.forEach(state => {
|
||||
if (!state.i || state.removed || state.lock) return;
|
||||
state.color = colors.find(color => state.neighbors.every(neibStateId => states[neibStateId].color !== color));
|
||||
if (!state.color) state.color = getRandomColor();
|
||||
colors.push(colors.shift());
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("updateCulturesForBurgsAndStates");
|
||||
// randomize each already used color a bit
|
||||
colors.forEach(c => {
|
||||
const sameColored = states.filter(state => state.color === c && state.i && !state.lock);
|
||||
sameColored.forEach((state, index) => {
|
||||
if (!index) return;
|
||||
state.color = getMixedColor(state.color);
|
||||
});
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("assignColors");
|
||||
};
|
||||
|
||||
// calculate states data like area, population etc.
|
||||
|
|
@ -436,18 +230,12 @@ window.BurgsAndStates = (() => {
|
|||
states.forEach(s => {
|
||||
if (s.removed) return;
|
||||
s.cells = s.area = s.burgs = s.rural = s.urban = 0;
|
||||
s.neighbors = new Set();
|
||||
});
|
||||
|
||||
for (const i of cells.i) {
|
||||
if (cells.h[i] < 20) continue;
|
||||
const s = cells.state[i];
|
||||
|
||||
// check for neighboring states
|
||||
cells.c[i]
|
||||
.filter(c => cells.h[c] >= 20 && cells.state[c] !== s)
|
||||
.forEach(c => states[s].neighbors.add(cells.state[c]));
|
||||
|
||||
// collect stats
|
||||
states[s].cells += 1;
|
||||
states[s].area += cells.area[i];
|
||||
|
|
@ -458,40 +246,9 @@ window.BurgsAndStates = (() => {
|
|||
}
|
||||
}
|
||||
|
||||
// convert neighbors Set object into array
|
||||
states.forEach(s => {
|
||||
if (!s.neighbors) return;
|
||||
s.neighbors = Array.from(s.neighbors);
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("collectStatistics");
|
||||
};
|
||||
|
||||
const assignColors = () => {
|
||||
TIME && console.time("assignColors");
|
||||
const colors = ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f"]; // d3.schemeSet2;
|
||||
|
||||
// assign basic color using greedy coloring algorithm
|
||||
pack.states.forEach(s => {
|
||||
if (!s.i || s.removed || s.lock) return;
|
||||
const neibs = s.neighbors;
|
||||
s.color = colors.find(c => neibs.every(n => pack.states[n].color !== c));
|
||||
if (!s.color) s.color = getRandomColor();
|
||||
colors.push(colors.shift());
|
||||
});
|
||||
|
||||
// randomize each already used color a bit
|
||||
colors.forEach(c => {
|
||||
const sameColored = pack.states.filter(s => s.color === c && !s.lock);
|
||||
sameColored.forEach((s, d) => {
|
||||
if (!d) return;
|
||||
s.color = getMixedColor(s.color);
|
||||
});
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("assignColors");
|
||||
};
|
||||
|
||||
const wars = {
|
||||
War: 6,
|
||||
Conflict: 2,
|
||||
|
|
@ -868,19 +625,15 @@ window.BurgsAndStates = (() => {
|
|||
return {
|
||||
generate,
|
||||
expandStates,
|
||||
normalizeStates,
|
||||
normalize,
|
||||
getPoles,
|
||||
findNeighbors,
|
||||
assignColors,
|
||||
specifyBurgs,
|
||||
defineBurgFeatures,
|
||||
getType,
|
||||
collectStatistics,
|
||||
generateCampaign,
|
||||
generateCampaigns,
|
||||
generateDiplomacy,
|
||||
defineStateForms,
|
||||
getFullName,
|
||||
updateCultures,
|
||||
getCloseToEdgePoint
|
||||
getFullName
|
||||
};
|
||||
})();
|
||||
|
|
@ -237,7 +237,7 @@ window.Submap = (function () {
|
|||
? pack.burgs[s.capital].cell // capital is the best bet
|
||||
: pack.cells.state.findIndex(x => x === i); // otherwise use the first valid cell
|
||||
});
|
||||
BurgsAndStates.getPoles();
|
||||
States.getPoles();
|
||||
|
||||
// transfer provinces, mark provinces without land as removed.
|
||||
stage("Porting provinces");
|
||||
|
|
|
|||
164
modules/ui/3d.js
164
modules/ui/3d.js
|
|
@ -39,6 +39,7 @@ window.ThreeD = (function () {
|
|||
let labels = [];
|
||||
let icons = [];
|
||||
let lines = [];
|
||||
let gridToPackCellMap = null; // Map from grid cell index to pack cell index
|
||||
|
||||
const context2d = document.createElement("canvas").getContext("2d");
|
||||
|
||||
|
|
@ -298,10 +299,6 @@ window.ThreeD = (function () {
|
|||
raycaster.set(new THREE.Vector3(0, 1000, 0), new THREE.Vector3(0, -1, 0));
|
||||
|
||||
const states = viewbox.select("#labels #states");
|
||||
const cities = burgLabels.select("#cities");
|
||||
const towns = burgLabels.select("#towns");
|
||||
const city_icons = burgIcons.select("#cities");
|
||||
const town_icons = burgIcons.select("#towns");
|
||||
|
||||
const stateOptions = {
|
||||
font: states.attr("font-family"),
|
||||
|
|
@ -311,62 +308,81 @@ window.ThreeD = (function () {
|
|||
quality: 20
|
||||
};
|
||||
|
||||
const cityOptions = {
|
||||
font: cities.attr("font-family"),
|
||||
size: +cities.attr("data-size"),
|
||||
color: cities.attr("fill"),
|
||||
elevation: 10,
|
||||
quality: 20,
|
||||
iconSize: 1,
|
||||
iconColor: "#666",
|
||||
line: 10 - cities.attr("data-size") / 2
|
||||
};
|
||||
// Cache icon materials and geometries by group to avoid recreating them
|
||||
const iconMaterials = {};
|
||||
const iconGeometries = {};
|
||||
const lineMaterials = {};
|
||||
|
||||
const townOptions = {
|
||||
font: towns.attr("font-family"),
|
||||
size: +towns.attr("data-size"),
|
||||
color: towns.attr("fill"),
|
||||
elevation: 5,
|
||||
quality: 30,
|
||||
iconSize: 0.5,
|
||||
iconColor: "#666",
|
||||
line: 5 - towns.attr("data-size") / 2
|
||||
};
|
||||
// Helper function to get burg label options from its group
|
||||
function getBurgLabelOptions(burg) {
|
||||
if (!burg.group) return null;
|
||||
|
||||
const city_icon_material = new THREE.MeshPhongMaterial({color: cityOptions.iconColor});
|
||||
city_icon_material.wireframe = options.wireframe;
|
||||
const town_icon_material = new THREE.MeshPhongMaterial({color: townOptions.iconColor});
|
||||
town_icon_material.wireframe = options.wireframe;
|
||||
const city_icon_geometry = new THREE.CylinderGeometry(
|
||||
cityOptions.iconSize * 2,
|
||||
cityOptions.iconSize * 2,
|
||||
cityOptions.iconSize,
|
||||
16,
|
||||
1
|
||||
);
|
||||
const town_icon_geometry = new THREE.CylinderGeometry(
|
||||
townOptions.iconSize * 2,
|
||||
townOptions.iconSize * 2,
|
||||
townOptions.iconSize,
|
||||
16,
|
||||
1
|
||||
);
|
||||
const line_material = new THREE.LineBasicMaterial({color: cityOptions.iconColor});
|
||||
const labelGroup = burgLabels.select("#" + burg.group);
|
||||
if (labelGroup.empty()) return null;
|
||||
|
||||
const font = labelGroup.attr("font-family") || "Arial";
|
||||
const size = +labelGroup.attr("data-size") || 10;
|
||||
const color = labelGroup.attr("fill") || "#000";
|
||||
|
||||
// Calculate elevation, icon size, and line height based on label size
|
||||
// Larger labels get higher elevation and larger icons
|
||||
const elevation = Math.max(5, size * 0.5);
|
||||
const iconSize = Math.max(0.3, size * 0.08);
|
||||
const iconColor = "#666";
|
||||
|
||||
return {
|
||||
font,
|
||||
size,
|
||||
color,
|
||||
elevation,
|
||||
quality: 20,
|
||||
iconSize,
|
||||
iconColor
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function to get or create icon material for a group
|
||||
function getIconMaterial(groupName, iconColor) {
|
||||
if (!iconMaterials[groupName]) {
|
||||
const material = new THREE.MeshPhongMaterial({color: iconColor});
|
||||
material.wireframe = options.wireframe;
|
||||
iconMaterials[groupName] = material;
|
||||
}
|
||||
return iconMaterials[groupName];
|
||||
}
|
||||
|
||||
// Helper function to get or create icon geometry for a group
|
||||
function getIconGeometry(groupName, iconSize) {
|
||||
const key = `${groupName}_${iconSize.toFixed(2)}`;
|
||||
if (!iconGeometries[key]) {
|
||||
iconGeometries[key] = new THREE.CylinderGeometry(iconSize * 2, iconSize * 2, iconSize, 16, 1);
|
||||
}
|
||||
return iconGeometries[key];
|
||||
}
|
||||
|
||||
// Helper function to get or create line material for a group
|
||||
function getLineMaterial(groupName, iconColor) {
|
||||
if (!lineMaterials[groupName]) {
|
||||
lineMaterials[groupName] = new THREE.LineBasicMaterial({color: iconColor});
|
||||
}
|
||||
return lineMaterials[groupName];
|
||||
}
|
||||
|
||||
// burg labels
|
||||
for (let i = 1; i < pack.burgs.length; i++) {
|
||||
const burg = pack.burgs[i];
|
||||
if (burg.removed) continue;
|
||||
|
||||
const isCity = burg.capital;
|
||||
const burgOptions = getBurgLabelOptions(burg);
|
||||
if (!burgOptions) continue;
|
||||
|
||||
const [x, y, z] = get3dCoords(burg.x, burg.y);
|
||||
const options = isCity ? cityOptions : townOptions;
|
||||
|
||||
if (layerIsOn("toggleLabels")) {
|
||||
const burgSprite = await createTextLabel({text: burg.name, ...options});
|
||||
const burgSprite = await createTextLabel({text: burg.name, ...burgOptions});
|
||||
|
||||
burgSprite.position.set(x, y + options.elevation, z);
|
||||
burgSprite.size = options.size;
|
||||
burgSprite.position.set(x, y + burgOptions.elevation, z);
|
||||
burgSprite.size = burgOptions.size;
|
||||
|
||||
labels.push(burgSprite);
|
||||
scene.add(burgSprite);
|
||||
|
|
@ -374,15 +390,19 @@ window.ThreeD = (function () {
|
|||
|
||||
// icons
|
||||
if (layerIsOn("toggleBurgIcons")) {
|
||||
const geometry = isCity ? city_icon_geometry : town_icon_geometry;
|
||||
const material = isCity ? city_icon_material : town_icon_material;
|
||||
const geometry = getIconGeometry(burg.group, burgOptions.iconSize);
|
||||
const material = getIconMaterial(burg.group, burgOptions.iconColor);
|
||||
const iconMesh = new THREE.Mesh(geometry, material);
|
||||
iconMesh.position.set(x, y, z);
|
||||
|
||||
icons.push(iconMesh);
|
||||
scene.add(iconMesh);
|
||||
|
||||
const points = [new THREE.Vector3(x, y, z), new THREE.Vector3(x, y + options.line, z)];
|
||||
const line_material = getLineMaterial(burg.group, burgOptions.iconColor);
|
||||
// Line starts from top of icon (iconSize/2 above ground) and goes to just below label
|
||||
const lineStart = y + burgOptions.iconSize / 2;
|
||||
const lineEnd = y + burgOptions.elevation - burgOptions.size * 0.5;
|
||||
const points = [new THREE.Vector3(x, lineStart, z), new THREE.Vector3(x, lineEnd, z)];
|
||||
const line_geometry = new THREE.BufferGeometry().setFromPoints(points);
|
||||
const line = new THREE.Line(line_geometry, line_material);
|
||||
|
||||
|
|
@ -467,8 +487,20 @@ window.ThreeD = (function () {
|
|||
};
|
||||
});
|
||||
}
|
||||
|
||||
// create a mesh from pixel data
|
||||
async function createMesh(width, height, segmentsX, segmentsY) {
|
||||
// Build lookup map from grid cell index to pack cell index
|
||||
gridToPackCellMap = new Map();
|
||||
if (pack.cells?.g && pack.cells?.i) {
|
||||
for (const packCellIndex of pack.cells.i) {
|
||||
const gridCellIndex = pack.cells.g[packCellIndex];
|
||||
if (!gridToPackCellMap.has(gridCellIndex)) {
|
||||
gridToPackCellMap.set(gridCellIndex, packCellIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (texture) texture.dispose();
|
||||
if (!options.wireframe) {
|
||||
texture = new THREE.TextureLoader().load(await createMeshTextureUrl(), render);
|
||||
|
|
@ -522,9 +554,32 @@ window.ThreeD = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
const LOWER_BY_WATER = 18;
|
||||
const DIVIDER = 100 - LOWER_BY_WATER;
|
||||
|
||||
function getMeshHeight(i) {
|
||||
const h = grid.cells.h[i];
|
||||
return h < 20 ? 0 : ((h - 18) / 82) * options.scale;
|
||||
const height = grid.cells.h[i];
|
||||
|
||||
let waterCellId = null;
|
||||
if (height < 20) {
|
||||
waterCellId = i;
|
||||
} else if (grid.cells.c[i]) {
|
||||
waterCellId = grid.cells.c[i].find(c => grid.cells.h[c] < 20) ?? null;
|
||||
}
|
||||
|
||||
// If water vertex, get uniform elevation
|
||||
if (waterCellId !== null) {
|
||||
const packCellIndex = gridToPackCellMap.get(waterCellId);
|
||||
const featureId = pack.cells.f[packCellIndex];
|
||||
if (featureId === undefined) return 0;
|
||||
|
||||
const feature = pack.features[featureId];
|
||||
const waterHeight = feature.type === "lake" && feature.height ? feature.height : 20;
|
||||
return ((waterHeight - LOWER_BY_WATER) / DIVIDER) * options.scale;
|
||||
}
|
||||
|
||||
// Land vertex
|
||||
return ((height - LOWER_BY_WATER) / DIVIDER) * options.scale;
|
||||
}
|
||||
|
||||
function extendWater(width, height) {
|
||||
|
|
@ -577,7 +632,7 @@ window.ThreeD = (function () {
|
|||
// controls
|
||||
controls = await OrbitControls(camera, Renderer.domElement);
|
||||
controls.zoomSpeed = 0.25;
|
||||
controls.minDistance = 1.8;
|
||||
controls.minDistance = 1.5;
|
||||
controls.maxDistance = 10;
|
||||
controls.autoRotate = Boolean(options.rotateGlobe);
|
||||
controls.autoRotateSpeed = options.rotateGlobe;
|
||||
|
|
@ -680,6 +735,7 @@ window.ThreeD = (function () {
|
|||
script.onerror = () => resolve(false);
|
||||
});
|
||||
}
|
||||
|
||||
function OrbitControls(camera, domElement) {
|
||||
if (THREE.OrbitControls) return new THREE.OrbitControls(camera, domElement);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ function editBurg(id) {
|
|||
const burg = id || d3.event.target.dataset.id;
|
||||
elSelected = burgLabels.select("[data-id='" + burg + "']");
|
||||
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true);
|
||||
updateGroupsList();
|
||||
updateBurgValues();
|
||||
|
||||
$("#burgEditor").dialog({
|
||||
|
|
@ -21,38 +22,39 @@ function editBurg(id) {
|
|||
modules.editBurg = true;
|
||||
|
||||
// add listeners
|
||||
byId("burgGroupShow").addEventListener("click", showGroupSection);
|
||||
byId("burgGroupHide").addEventListener("click", hideGroupSection);
|
||||
byId("burgSelectGroup").addEventListener("change", changeGroup);
|
||||
byId("burgInputGroup").addEventListener("change", createNewGroup);
|
||||
byId("burgAddGroup").addEventListener("click", toggleNewGroupInput);
|
||||
byId("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
|
||||
byId("burgName").on("input", changeName);
|
||||
byId("burgNameReRandom").on("click", generateNameRandom);
|
||||
byId("burgGroup").on("change", changeGroup);
|
||||
byId("burgGroupConfigure").on("click", editBurgGroups);
|
||||
byId("burgType").on("change", changeType);
|
||||
byId("burgCulture").on("change", changeCulture);
|
||||
byId("burgNameReCulture").on("click", generateNameCulture);
|
||||
byId("burgPopulation").on("change", changePopulation);
|
||||
burgBody.querySelectorAll(".burgFeature").forEach(el => el.on("click", toggleFeature));
|
||||
byId("burgLinkOpen").on("click", openBurgLink);
|
||||
|
||||
byId("burgName").addEventListener("input", changeName);
|
||||
byId("burgNameReRandom").addEventListener("click", generateNameRandom);
|
||||
byId("burgType").addEventListener("input", changeType);
|
||||
byId("burgCulture").addEventListener("input", changeCulture);
|
||||
byId("burgNameReCulture").addEventListener("click", generateNameCulture);
|
||||
byId("burgPopulation").addEventListener("change", changePopulation);
|
||||
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature));
|
||||
byId("burgLinkOpen").addEventListener("click", openBurgLink);
|
||||
byId("burgLinkEdit").addEventListener("click", changeBurgLink);
|
||||
byId("burgStyleShow").on("click", showStyleSection);
|
||||
byId("burgStyleHide").on("click", hideStyleSection);
|
||||
byId("burgEditLabelStyle").on("click", editGroupLabelStyle);
|
||||
byId("burgEditIconStyle").on("click", editGroupIconStyle);
|
||||
byId("burgEditAnchorStyle").on("click", editGroupAnchorStyle);
|
||||
|
||||
byId("burgStyleShow").addEventListener("click", showStyleSection);
|
||||
byId("burgStyleHide").addEventListener("click", hideStyleSection);
|
||||
byId("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle);
|
||||
byId("burgEditIconStyle").addEventListener("click", editGroupIconStyle);
|
||||
byId("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle);
|
||||
byId("burgEmblem").on("click", openEmblemEdit);
|
||||
byId("burgSetPreviewLink").on("click", setCustomPreview);
|
||||
byId("burgEditEmblem").on("click", openEmblemEdit);
|
||||
byId("burgLocate").on("click", zoomIntoBurg);
|
||||
byId("burgRelocate").on("click", toggleRelocateBurg);
|
||||
byId("burglLegend").on("click", editBurgLegend);
|
||||
byId("burgLock").on("click", toggleBurgLockButton);
|
||||
byId("burgRemove").on("click", removeSelectedBurg);
|
||||
byId("burgTemperatureGraph").on("click", showTemperatureGraph);
|
||||
|
||||
byId("burgEmblem").addEventListener("click", openEmblemEdit);
|
||||
byId("burgTogglePreview").addEventListener("click", toggleBurgPreview);
|
||||
byId("burgEditEmblem").addEventListener("click", openEmblemEdit);
|
||||
byId("burgLocate").addEventListener("click", zoomIntoBurg);
|
||||
byId("burgRelocate").addEventListener("click", toggleRelocateBurg);
|
||||
byId("burglLegend").addEventListener("click", editBurgLegend);
|
||||
byId("burgLock").addEventListener("click", toggleBurgLockButton);
|
||||
byId("burgRemove").addEventListener("click", removeSelectedBurg);
|
||||
byId("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
|
||||
function updateGroupsList() {
|
||||
byId("burgGroup").options.length = 0; // remove all options
|
||||
for (const {name} of options.burgs.groups) {
|
||||
byId("burgGroup").options.add(new Option(name, name));
|
||||
}
|
||||
}
|
||||
|
||||
function updateBurgValues() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
|
|
@ -63,6 +65,7 @@ function editBurg(id) {
|
|||
byId("burgProvinceAndState").innerHTML = provinceName + stateName;
|
||||
|
||||
byId("burgName").value = b.name;
|
||||
byId("burgGroup").value = b.group;
|
||||
byId("burgType").value = b.type || "Generic";
|
||||
byId("burgPopulation").value = rn(b.population * populationRate * urbanization);
|
||||
byId("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
|
||||
|
|
@ -80,44 +83,22 @@ function editBurg(id) {
|
|||
byId("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]);
|
||||
|
||||
// toggle features
|
||||
if (b.capital) byId("burgCapital").classList.remove("inactive");
|
||||
else byId("burgCapital").classList.add("inactive");
|
||||
if (b.port) byId("burgPort").classList.remove("inactive");
|
||||
else byId("burgPort").classList.add("inactive");
|
||||
if (b.citadel) byId("burgCitadel").classList.remove("inactive");
|
||||
else byId("burgCitadel").classList.add("inactive");
|
||||
if (b.walls) byId("burgWalls").classList.remove("inactive");
|
||||
else byId("burgWalls").classList.add("inactive");
|
||||
if (b.plaza) byId("burgPlaza").classList.remove("inactive");
|
||||
else byId("burgPlaza").classList.add("inactive");
|
||||
if (b.temple) byId("burgTemple").classList.remove("inactive");
|
||||
else byId("burgTemple").classList.add("inactive");
|
||||
if (b.shanty) byId("burgShanty").classList.remove("inactive");
|
||||
else byId("burgShanty").classList.add("inactive");
|
||||
byId("burgCapital").classList.toggle("inactive", !b.capital);
|
||||
byId("burgPort").classList.toggle("inactive", !b.port);
|
||||
byId("burgCitadel").classList.toggle("inactive", !b.citadel);
|
||||
byId("burgWalls").classList.toggle("inactive", !b.walls);
|
||||
byId("burgPlaza").classList.toggle("inactive", !b.plaza);
|
||||
byId("burgTemple").classList.toggle("inactive", !b.temple);
|
||||
byId("burgShanty").classList.toggle("inactive", !b.shanty);
|
||||
|
||||
//toggle lock
|
||||
updateBurgLockIcon();
|
||||
|
||||
// select group
|
||||
const group = elSelected.node().parentNode.id;
|
||||
const select = byId("burgSelectGroup");
|
||||
select.options.length = 0; // remove all options
|
||||
|
||||
burgLabels.selectAll("g").each(function () {
|
||||
select.options.add(new Option(this.id, this.id, false, this.id === group));
|
||||
});
|
||||
|
||||
// set emlem image
|
||||
const coaID = "burgCOA" + id;
|
||||
COArenderer.trigger(coaID, b.coa);
|
||||
byId("burgEmblem").setAttribute("href", "#" + coaID);
|
||||
|
||||
if (options.showBurgPreview) {
|
||||
byId("burgPreviewSection").style.display = "block";
|
||||
updateBurgPreview(b);
|
||||
} else {
|
||||
byId("burgPreviewSection").style.display = "none";
|
||||
}
|
||||
updateBurgPreview(b);
|
||||
}
|
||||
|
||||
function dragBurgLabel() {
|
||||
|
|
@ -133,128 +114,6 @@ function editBurg(id) {
|
|||
});
|
||||
}
|
||||
|
||||
function showGroupSection() {
|
||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
|
||||
byId("burgGroupSection").style.display = "inline-block";
|
||||
}
|
||||
|
||||
function hideGroupSection() {
|
||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
|
||||
byId("burgGroupSection").style.display = "none";
|
||||
byId("burgInputGroup").style.display = "none";
|
||||
byId("burgInputGroup").value = "";
|
||||
byId("burgSelectGroup").style.display = "inline-block";
|
||||
}
|
||||
|
||||
function changeGroup() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
moveBurgToGroup(id, this.value);
|
||||
}
|
||||
|
||||
function toggleNewGroupInput() {
|
||||
if (burgInputGroup.style.display === "none") {
|
||||
burgInputGroup.style.display = "inline-block";
|
||||
burgInputGroup.focus();
|
||||
burgSelectGroup.style.display = "none";
|
||||
} else {
|
||||
burgInputGroup.style.display = "none";
|
||||
burgSelectGroup.style.display = "inline-block";
|
||||
}
|
||||
}
|
||||
|
||||
function createNewGroup() {
|
||||
if (!this.value) {
|
||||
tip("Please provide a valid group name", false, "error");
|
||||
return;
|
||||
}
|
||||
const group = this.value
|
||||
.toLowerCase()
|
||||
.replace(/ /g, "_")
|
||||
.replace(/[^\w\s]/gi, "");
|
||||
|
||||
if (byId(group)) {
|
||||
tip("Element with this id already exists. Please provide a unique name", false, "error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Number.isFinite(+group.charAt(0))) {
|
||||
tip("Group name should start with a letter", false, "error");
|
||||
return;
|
||||
}
|
||||
|
||||
const id = +elSelected.attr("data-id");
|
||||
const oldGroup = elSelected.node().parentNode.id;
|
||||
|
||||
const label = document.querySelector("#burgLabels [data-id='" + id + "']");
|
||||
const icon = document.querySelector("#burgIcons [data-id='" + id + "']");
|
||||
const anchor = document.querySelector("#anchors [data-id='" + id + "']");
|
||||
if (!label || !icon) {
|
||||
ERROR && console.error("Cannot find label or icon elements");
|
||||
return;
|
||||
}
|
||||
|
||||
const labelG = document.querySelector("#burgLabels > #" + oldGroup);
|
||||
const iconG = document.querySelector("#burgIcons > #" + oldGroup);
|
||||
const anchorG = document.querySelector("#anchors > #" + oldGroup);
|
||||
|
||||
// just rename if only 1 element left
|
||||
const count = elSelected.node().parentNode.childElementCount;
|
||||
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
|
||||
byId("burgSelectGroup").selectedOptions[0].remove();
|
||||
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
|
||||
toggleNewGroupInput();
|
||||
byId("burgInputGroup").value = "";
|
||||
labelG.id = group;
|
||||
iconG.id = group;
|
||||
if (anchor) anchorG.id = group;
|
||||
return;
|
||||
}
|
||||
|
||||
// create new groups
|
||||
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
|
||||
toggleNewGroupInput();
|
||||
byId("burgInputGroup").value = "";
|
||||
|
||||
addBurgsGroup(group);
|
||||
moveBurgToGroup(id, group);
|
||||
}
|
||||
|
||||
function removeBurgsGroup() {
|
||||
const group = elSelected.node().parentNode;
|
||||
const basic = group.id === "cities" || group.id === "towns";
|
||||
|
||||
const burgsInGroup = [];
|
||||
for (let i = 0; i < group.children.length; i++) {
|
||||
burgsInGroup.push(+group.children[i].dataset.id);
|
||||
}
|
||||
const burgsToRemove = burgsInGroup.filter(b => !(pack.burgs[b].capital || pack.burgs[b].lock));
|
||||
const capital = burgsToRemove.length < burgsInGroup.length;
|
||||
|
||||
confirmationDialog({
|
||||
title: "Remove burg group",
|
||||
message: `Are you sure you want to remove ${
|
||||
basic || capital ? "all unlocked elements in the burg group" : "the entire burg group"
|
||||
}?<br />Please note that capital or locked burgs will not be deleted. <br /><br />Burgs to be removed: ${
|
||||
burgsToRemove.length
|
||||
}. This action cannot be reverted`,
|
||||
confirm: "Remove",
|
||||
onConfirm: () => {
|
||||
$("#burgEditor").dialog("close");
|
||||
hideGroupSection();
|
||||
burgsToRemove.forEach(b => removeBurg(b));
|
||||
|
||||
if (!basic && !capital) {
|
||||
const labelG = document.querySelector("#burgLabels > #" + group.id);
|
||||
const iconG = document.querySelector("#burgIcons > #" + group.id);
|
||||
const anchorG = document.querySelector("#anchors > #" + group.id);
|
||||
if (labelG) labelG.remove();
|
||||
if (iconG) iconG.remove();
|
||||
if (anchorG) anchorG.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changeName() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
pack.burgs[id].name = burgName.value;
|
||||
|
|
@ -267,6 +126,12 @@ function editBurg(id) {
|
|||
changeName();
|
||||
}
|
||||
|
||||
function changeGroup() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
Burgs.changeGroup(burg, this.value);
|
||||
}
|
||||
|
||||
function changeType() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
pack.burgs[id].type = this.value;
|
||||
|
|
@ -293,21 +158,68 @@ function editBurg(id) {
|
|||
}
|
||||
|
||||
function toggleFeature() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
const feature = this.dataset.feature;
|
||||
const turnOn = this.classList.contains("inactive");
|
||||
if (feature === "port") togglePort(id);
|
||||
else if (feature === "capital") toggleCapital(id);
|
||||
else burg[feature] = +turnOn;
|
||||
if (burg[feature]) this.classList.remove("inactive");
|
||||
else if (!burg[feature]) this.classList.add("inactive");
|
||||
const burgId = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[burgId];
|
||||
|
||||
if (burg.port) byId("burgEditAnchorStyle").style.display = "inline-block";
|
||||
else byId("burgEditAnchorStyle").style.display = "none";
|
||||
const feature = this.dataset.feature;
|
||||
const value = Number(this.classList.contains("inactive"));
|
||||
|
||||
if (feature === "port") togglePort(burgId);
|
||||
else if (feature === "capital") toggleCapital(burgId);
|
||||
else burg[feature] = value;
|
||||
|
||||
this.classList.toggle("inactive", !burg[feature]);
|
||||
|
||||
byId("burgEditAnchorStyle").style.display = burg.port ? "inline-block" : "none";
|
||||
updateBurgPreview(burg);
|
||||
}
|
||||
|
||||
function togglePort(burgId) {
|
||||
const burg = pack.burgs[burgId];
|
||||
if (burg.port) {
|
||||
burg.port = 0;
|
||||
|
||||
const anchor = document.querySelector("#anchors [data-id='" + burgId + "']");
|
||||
if (anchor) anchor.remove();
|
||||
} else {
|
||||
const haven = pack.cells.haven[burg.cell];
|
||||
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
|
||||
const portFeature = haven ? pack.cells.f[haven] : -1;
|
||||
burg.port = portFeature;
|
||||
|
||||
anchors
|
||||
.select("#" + burg.group)
|
||||
.append("use")
|
||||
.attr("href", "#icon-anchor")
|
||||
.attr("id", "anchor" + burg.i)
|
||||
.attr("data-id", burg.i)
|
||||
.attr("x", burg.x)
|
||||
.attr("y", burg.y);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleCapital(burgId) {
|
||||
const {burgs, states} = pack;
|
||||
|
||||
if (burgs[burgId].capital)
|
||||
return tip("To change capital please assign a capital status to another burg of this state", false, "error");
|
||||
|
||||
const stateId = burgs[burgId].state;
|
||||
if (!stateId) return tip("Neutral lands cannot have a capital", false, "error");
|
||||
|
||||
const oldCapitalId = states[stateId].capital;
|
||||
states[stateId].capital = burgId;
|
||||
states[stateId].center = burgs[burgId].cell;
|
||||
|
||||
const capital = burgs[burgId];
|
||||
capital.capital = 1;
|
||||
Burgs.changeGroup(capital);
|
||||
|
||||
const oldCapital = burgs[oldCapitalId];
|
||||
oldCapital.capital = 0;
|
||||
Burgs.changeGroup(oldCapital);
|
||||
}
|
||||
|
||||
function toggleBurgLockButton() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
|
|
@ -340,45 +252,54 @@ function editBurg(id) {
|
|||
|
||||
function editGroupLabelStyle() {
|
||||
const g = elSelected.node().parentNode.id;
|
||||
closeDialogs(".stable");
|
||||
editStyle("labels", g);
|
||||
}
|
||||
|
||||
function editGroupIconStyle() {
|
||||
const g = elSelected.node().parentNode.id;
|
||||
closeDialogs(".stable");
|
||||
editStyle("burgIcons", g);
|
||||
}
|
||||
|
||||
function editGroupAnchorStyle() {
|
||||
const g = elSelected.node().parentNode.id;
|
||||
closeDialogs(".stable");
|
||||
editStyle("anchors", g);
|
||||
}
|
||||
|
||||
function updateBurgPreview(burg) {
|
||||
const src = getBurgLink(burg) + "&preview=1";
|
||||
const preview = Burgs.getPreview(burg).preview;
|
||||
if (!preview) {
|
||||
byId("burgPreviewSection").style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
byId("burgPreviewSection").style.display = "block";
|
||||
|
||||
// recreate object to force reload (Chrome bug)
|
||||
const container = byId("burgPreviewObject");
|
||||
container.innerHTML = "";
|
||||
const object = document.createElement("object");
|
||||
object.style.width = "100%";
|
||||
object.data = src;
|
||||
object.data = preview;
|
||||
container.insertBefore(object, null);
|
||||
}
|
||||
|
||||
function openBurgLink() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
|
||||
openURL(getBurgLink(burg));
|
||||
const link = Burgs.getPreview(burg).link;
|
||||
if (link) openURL(link);
|
||||
}
|
||||
|
||||
function changeBurgLink() {
|
||||
function setCustomPreview() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
|
||||
prompt(
|
||||
"Provide custom link to the burg map. It can be a link to Medieval Fantasy City Generator, a different tool, or just an image. Leave empty to use the default map",
|
||||
{default: getBurgLink(burg), required: false},
|
||||
"Provide custom URL to the burg map. It can be a link to a generator or just an image. Leave empty to use the default map preview",
|
||||
{default: Burgs.getPreview(burg).link, required: false},
|
||||
link => {
|
||||
if (link) burg.link = link;
|
||||
else delete burg.link;
|
||||
|
|
@ -388,17 +309,11 @@ function editBurg(id) {
|
|||
}
|
||||
|
||||
function openEmblemEdit() {
|
||||
const id = +elSelected.attr("data-id"),
|
||||
burg = pack.burgs[id];
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
editEmblem("burg", "burgCOA" + id, burg);
|
||||
}
|
||||
|
||||
function toggleBurgPreview() {
|
||||
options.showBurgPreview = !options.showBurgPreview;
|
||||
byId("burgPreviewSection").style.display = options.showBurgPreview ? "block" : "none";
|
||||
byId("burgTogglePreview").className = options.showBurgPreview ? "icon-map" : "icon-map-o";
|
||||
}
|
||||
|
||||
function zoomIntoBurg() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
|
|
@ -430,41 +345,26 @@ function editBurg(id) {
|
|||
function relocateBurgOnClick() {
|
||||
const cells = pack.cells;
|
||||
const point = d3.mouse(this);
|
||||
const cell = findCell(point[0], point[1]);
|
||||
const cellId = findCell(...point);
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
|
||||
if (cells.h[cell] < 20) {
|
||||
tip("Cannot place burg into the water! Select a land cell", false, "error");
|
||||
return;
|
||||
}
|
||||
if (cells.h[cellId] < 20) return tip("Cannot place burg into the water! Select a land cell", false, "error");
|
||||
if (cells.burg[cellId] && cells.burg[cellId] !== id)
|
||||
return tip("There is already a burg in this cell. Please select a free cell", false, "error");
|
||||
|
||||
if (cells.burg[cell] && cells.burg[cell] !== id) {
|
||||
tip("There is already a burg in this cell. Please select a free cell", false, "error");
|
||||
return;
|
||||
}
|
||||
|
||||
const newState = cells.state[cell];
|
||||
const newState = cells.state[cellId];
|
||||
const oldState = burg.state;
|
||||
|
||||
if (newState !== oldState && burg.capital) {
|
||||
tip("Capital cannot be relocated into another state!", false, "error");
|
||||
return;
|
||||
}
|
||||
if (newState !== oldState && burg.capital)
|
||||
return tip("Capital cannot be relocated into another state!", false, "error");
|
||||
|
||||
// change UI
|
||||
const x = rn(point[0], 2),
|
||||
y = rn(point[1], 2);
|
||||
burgIcons
|
||||
.select("[data-id='" + id + "']")
|
||||
.attr("transform", null)
|
||||
.attr("cx", x)
|
||||
.attr("cy", y);
|
||||
burgLabels
|
||||
.select("text[data-id='" + id + "']")
|
||||
.attr("transform", null)
|
||||
.attr("x", x)
|
||||
.attr("y", y);
|
||||
const x = rn(point[0], 2);
|
||||
const y = rn(point[1], 2);
|
||||
|
||||
burgIcons.select(`#burg${id}`).attr("x", x).attr("y", y);
|
||||
burgLabels.select(`#burgLabel${id}`).attr("transform", null).attr("x", x).attr("y", y);
|
||||
|
||||
const anchor = anchors.select("use[data-id='" + id + "']");
|
||||
if (anchor.size()) {
|
||||
const size = anchor.attr("width");
|
||||
|
|
@ -475,8 +375,8 @@ function editBurg(id) {
|
|||
|
||||
// change data
|
||||
cells.burg[burg.cell] = 0;
|
||||
cells.burg[cell] = id;
|
||||
burg.cell = cell;
|
||||
cells.burg[cellId] = id;
|
||||
burg.cell = cellId;
|
||||
burg.state = newState;
|
||||
burg.x = x;
|
||||
burg.y = y;
|
||||
|
|
@ -497,10 +397,11 @@ function editBurg(id) {
|
|||
}
|
||||
|
||||
function removeSelectedBurg() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
if (pack.burgs[id].capital) {
|
||||
alertMessage.innerHTML = /* html */ `You cannot remove the burg as it is a state capital.<br /><br />
|
||||
You can change the capital using Burgs Editor (shift + T)`;
|
||||
const burgId = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[burgId];
|
||||
|
||||
if (burg.capital) {
|
||||
alertMessage.innerHTML = /* html */ `You cannot remove the capital. You must change the state capital first`;
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
title: "Remove burg",
|
||||
|
|
@ -516,7 +417,7 @@ function editBurg(id) {
|
|||
message: "Are you sure you want to remove the burg? <br>This action cannot be reverted",
|
||||
confirm: "Remove",
|
||||
onConfirm: () => {
|
||||
removeBurg(id); // see Editors module
|
||||
Burgs.remove(burgId);
|
||||
$("#burgEditor").dialog("close");
|
||||
}
|
||||
});
|
||||
|
|
@ -530,7 +431,7 @@ function editBurg(id) {
|
|||
}
|
||||
}
|
||||
|
||||
// in °C, array from -1 °C; source: https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
|
||||
// in °C, array from -1 °C; source: https://en.wikipedia.org/wiki/List_of_city_by_average_temperature
|
||||
const meanTempCityMap = {
|
||||
"-5": "Snag (Yukon)",
|
||||
"-4": "Yellowknife (Canada)",
|
||||
|
|
|
|||
329
modules/ui/burg-group-editor.js
Normal file
329
modules/ui/burg-group-editor.js
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
"use strict";
|
||||
|
||||
function editBurgGroups() {
|
||||
if (customization) return;
|
||||
addLines();
|
||||
|
||||
$("#burgGroupsEditor").dialog({
|
||||
title: "Configure Burg groups",
|
||||
resizable: false,
|
||||
position: {my: "center", at: "center", of: "svg"},
|
||||
buttons: {
|
||||
Apply: () => {
|
||||
byId("burgGroupsForm").requestSubmit();
|
||||
},
|
||||
Add: () => {
|
||||
byId("burgGroupsBody").innerHTML += createLine({name: "", active: true, preview: null});
|
||||
},
|
||||
Restore: () => {
|
||||
options.burgs.groups = Burgs.getDefaultGroups();
|
||||
addLines();
|
||||
},
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (modules.editBurgGroups) return;
|
||||
modules.editBurgGroups = true;
|
||||
|
||||
// add listeners
|
||||
byId("burgGroupsForm").on("change", validateForm).on("submit", submitForm);
|
||||
byId("burgGroupsBody").on("click", ev => {
|
||||
const el = ev.target;
|
||||
const line = el.closest("tr");
|
||||
if (!line) return;
|
||||
|
||||
if (el.name === "biomes") {
|
||||
const biomes = Array(biomesData.i.length)
|
||||
.fill(null)
|
||||
.map((_, i) => ({i, name: biomesData.name[i], color: biomesData.color[i]}));
|
||||
return selectLimitation(el, biomes);
|
||||
}
|
||||
if (el.name === "states") return selectLimitation(el, pack.states);
|
||||
if (el.name === "cultures") return selectLimitation(el, pack.cultures);
|
||||
if (el.name === "religions") return selectLimitation(el, pack.religions);
|
||||
if (el.name === "features") return selectFeaturesLimitation(el);
|
||||
if (el.name === "up") return line.parentNode.insertBefore(line, line.previousElementSibling);
|
||||
if (el.name === "down") return line.parentNode.insertBefore(line.nextElementSibling, line);
|
||||
if (el.name === "remove") return removeLine(line);
|
||||
});
|
||||
|
||||
function addLines() {
|
||||
const lines = options.burgs.groups.map(createLine);
|
||||
byId("burgGroupsBody").innerHTML = lines.join("");
|
||||
}
|
||||
|
||||
function createLine(group) {
|
||||
const count = pack.burgs.filter(burg => !burg.removed && burg.group === group.name).length;
|
||||
// prettier-ignore
|
||||
return /* html */ `<tr name="${group.name}">
|
||||
<td data-tip="Rendering order: higher values are rendered on top"><input type="number" name="order" min="1" max="999" step="1" required value="${group.order || ''}" /></td>
|
||||
<td data-tip="Type group name. It can contain only text, digits and underscore"><input type="text" name="name" value="${group.name}" required pattern="\\w+" /></td>
|
||||
<td data-tip="Burg preview generator">
|
||||
<select name="preview">
|
||||
<option value="" ${!group.preview ? "selected" : ""}>no</option>
|
||||
<option value="watabou-city" ${group.preview === "watabou-city" ? "selected" : ""}>Watabou City</option>
|
||||
<option value="watabou-village" ${group.preview === "watabou-village" ? "selected" : ""}>Watabou Village</option>
|
||||
<option value="watabou-dwelling" ${group.preview === "watabou-dwellings" ? "selected" : ""}>Watabou Dwelling</option>
|
||||
</select>
|
||||
</td>
|
||||
<td data-tip="Set min population constraint"><input type="number" name="min" min="0" step="any" value="${group.min || ''}" /></td>
|
||||
<td data-tip="Set max population constraint"><input type="number" name="max" min="0" step="any" value="${group.max || ''}" /></td>
|
||||
<td data-tip="Set population percentile"><input type="number" name="percentile" min="0" max="100" step="any" value="${group.percentile || ''}" /></td>
|
||||
<td data-tip="Select allowed biomes">
|
||||
<input type="hidden" name="biomes" value="${group.biomes || ""}">
|
||||
<button type="button" name="biomes">${group.biomes ? "some" : "all"}</button>
|
||||
</td>
|
||||
<td data-tip="Select allowed states">
|
||||
<input type="hidden" name="states" value="${group.states || ""}">
|
||||
<button type="button" name="states">${group.states ? "some" : "all"}</button>
|
||||
</td>
|
||||
<td data-tip="Select allowed cultures">
|
||||
<input type="hidden" name="cultures" value="${group.cultures || ""}">
|
||||
<button type="button" name="cultures">${group.cultures ? "some" : "all"}</button>
|
||||
</td>
|
||||
<td data-tip="Select allowed religions">
|
||||
<input type="hidden" name="religions" value="${group.religions || ""}">
|
||||
<button type="button" name="religions">${group.religions ? "some" : "all"}</button>
|
||||
</td>
|
||||
<td data-tip="Select allowed features" >
|
||||
<input type="hidden" name="features" value='${JSON.stringify(group.features || {})}'>
|
||||
<button type="button" name="features">${Object.keys(group.features || {}).length ? "some" : "any"}</button>
|
||||
</td>
|
||||
<td data-tip="Number of burgs in group">${count}</td>
|
||||
<td data-tip="Activate/deactivate group"><input type="checkbox" name="active" class="native" ${group.active && "checked"} /></td>
|
||||
<td data-tip="Select group to be assigned if other groups are not passed"><input type="radio" name="isDefault" ${group.isDefault && "checked"}></td>
|
||||
<td data-tip="Assignment order: move group up"><button type="button" name="up" class="icon-up-big"></button></td>
|
||||
<td data-tip="Assignment order: move group down"><button type="button" name="down" class="icon-down-big"></button></td>
|
||||
<td data-tip="Remove group"><button type="button" name="remove" class="icon-trash"></button></td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
function selectLimitation(el, data) {
|
||||
const value = el.previousElementSibling.value;
|
||||
const initial = value ? value.split(",").map(v => +v) : [];
|
||||
|
||||
const filtered = data.filter(datum => datum.i && !datum.removed);
|
||||
const lines = filtered.map(
|
||||
({i, name, fullName, color}) => /* html */ `
|
||||
<tr data-tip="${name}">
|
||||
<td>
|
||||
<span style="color:${color}">⬤</span>
|
||||
</td>
|
||||
<td>
|
||||
<input data-i="${i}" id="el${i}" type="checkbox" class="checkbox" ${
|
||||
!initial.length || initial.includes(i) ? "checked" : ""
|
||||
} >
|
||||
<label for="el${i}" class="checkbox-label">${fullName || name}</label>
|
||||
</td>
|
||||
</tr>`
|
||||
);
|
||||
|
||||
alertMessage.innerHTML = /* html */ `<b>Limit group by ${el.name}:</b>
|
||||
<table style="margin-top:.3em">
|
||||
<tbody>
|
||||
${lines.join("")}
|
||||
</tbody>
|
||||
</table>`;
|
||||
|
||||
$("#alert").dialog({
|
||||
width: fitContent(),
|
||||
title: "Limit group",
|
||||
buttons: {
|
||||
Invert: function () {
|
||||
alertMessage.querySelectorAll("input").forEach(el => (el.checked = !el.checked));
|
||||
},
|
||||
Apply: function () {
|
||||
const inputs = Array.from(alertMessage.querySelectorAll("input"));
|
||||
const selected = inputs.reduce((acc, input) => {
|
||||
if (input.checked) acc.push(input.dataset.i);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
if (!selected.length) return tip("Select at least one element", false, "error");
|
||||
|
||||
const allAreSelected = selected.length === inputs.length;
|
||||
el.previousElementSibling.value = allAreSelected ? "" : selected.join(",");
|
||||
el.innerHTML = allAreSelected ? "all" : "some";
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function selectFeaturesLimitation(el) {
|
||||
const value = el.previousElementSibling.value;
|
||||
const initial = value ? JSON.parse(value) : {};
|
||||
|
||||
const features = [
|
||||
{name: "capital", icon: "icon-star"},
|
||||
{name: "port", icon: "icon-anchor"},
|
||||
{name: "citadel", icon: "icon-chess-rook"},
|
||||
{name: "walls", icon: "icon-fort-awesome"},
|
||||
{name: "plaza", icon: "icon-store"},
|
||||
{name: "temple", icon: "icon-chess-bishop"},
|
||||
{name: "shanty", icon: "icon-campground"}
|
||||
];
|
||||
|
||||
const lines = features.map(
|
||||
// prettier-ignore
|
||||
({name, icon}) => /* html */ `
|
||||
<tr data-tip="Select limitation for burg feature: ${name}">
|
||||
<td>
|
||||
<span class="${icon}"></span>
|
||||
<span style="margin-left:.2em">${name}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="${name}" value="true" ${initial[name] === true ? "checked" : ""} style="margin:0" >
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="${name}" value="false" ${initial[name] === false ? "checked" : ""} style="margin:0">
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="${name}" value="undefined" ${initial[name] === undefined ? "checked" : ""} style="margin:0">
|
||||
</td>
|
||||
</tr>`
|
||||
);
|
||||
|
||||
alertMessage.innerHTML = /* html */ `
|
||||
<form id="featuresLimitationForm">
|
||||
<table>
|
||||
<thead style="font-weight:bold">
|
||||
<td style="width:6em">Features</td>
|
||||
<td style="width:3em">True</td>
|
||||
<td style="width:3em">False</td>
|
||||
<td style="width:3em">Any</td>
|
||||
</thead>
|
||||
<tbody>
|
||||
${lines.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>`;
|
||||
|
||||
$("#alert").dialog({
|
||||
width: fitContent(),
|
||||
title: "Limit group by features",
|
||||
buttons: {
|
||||
Apply: function () {
|
||||
const form = byId("featuresLimitationForm");
|
||||
const values = features.reduce((acc, {name}) => {
|
||||
const value = form[name].value;
|
||||
if (value !== "undefined") acc[name] = value === "true";
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
el.previousElementSibling.value = JSON.stringify(values);
|
||||
el.innerHTML = Object.keys(values).length ? "some" : "any";
|
||||
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeLine(line) {
|
||||
const lines = byId("burgGroupsBody").children;
|
||||
if (lines.length < 2) return tip("At least one group should be defined", false, "error");
|
||||
|
||||
confirmationDialog({
|
||||
title: "Remove group",
|
||||
message:
|
||||
"Are you sure you want to remove the group? <br>This WON'T change the burgs unless the changes are applied",
|
||||
confirm: "Remove",
|
||||
onConfirm: () => {
|
||||
line.remove();
|
||||
validateForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function validateForm() {
|
||||
const form = byId("burgGroupsForm");
|
||||
|
||||
if (form.name.length) {
|
||||
const names = Array.from(form.name).map(input => input.value);
|
||||
form.name.forEach(nameInput => {
|
||||
const value = nameInput.value;
|
||||
const isUnique = names.filter(n => n === value).length === 1;
|
||||
nameInput.setCustomValidity(isUnique ? "" : "Group name should be unique");
|
||||
nameInput.reportValidity();
|
||||
});
|
||||
}
|
||||
|
||||
if (form.active.length) {
|
||||
const active = Array.from(form.active).map(input => input.checked);
|
||||
form.active[0].setCustomValidity(active.includes(true) ? "" : "At least one group should be active");
|
||||
form.active[0].reportValidity();
|
||||
} else {
|
||||
const active = form.active.checked;
|
||||
form.active.setCustomValidity(active ? "" : "At least one group should be active");
|
||||
form.active.reportValidity();
|
||||
}
|
||||
|
||||
if (form.isDefault.length) {
|
||||
const checked = Array.from(form.isDefault).map(input => input.checked);
|
||||
form.isDefault[0].setCustomValidity(checked.includes(true) ? "" : "At least one group should be default");
|
||||
form.isDefault[0].reportValidity();
|
||||
} else {
|
||||
const checked = form.isDefault.checked;
|
||||
form.isDefault.setCustomValidity(checked ? "" : "At least one group should be default");
|
||||
form.isDefault.reportValidity();
|
||||
}
|
||||
}
|
||||
|
||||
function submitForm(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const lines = Array.from(byId("burgGroupsBody").children);
|
||||
if (!lines.length) return tip("At least one group should be defined", false, "error");
|
||||
|
||||
function parseInput(input) {
|
||||
if (input.name === "name") return sanitizeId(input.value);
|
||||
if (input.name === "features") {
|
||||
const isValid = JSON.isValid(input.value);
|
||||
const parsed = isValid ? JSON.parse(input.value) : {};
|
||||
if (Object.keys(parsed).length) return parsed;
|
||||
return null;
|
||||
}
|
||||
if (input.type === "hidden") return input.value || null;
|
||||
if (input.type === "radio") return input.checked;
|
||||
if (input.type === "checkbox") return input.checked;
|
||||
if (input.type === "number") {
|
||||
const value = input.valueAsNumber;
|
||||
if (value === 0 || isNaN(value)) return null;
|
||||
return value;
|
||||
}
|
||||
return input.value || null;
|
||||
}
|
||||
|
||||
options.burgs.groups = lines.map(line => {
|
||||
const inputs = line.querySelectorAll("input, select");
|
||||
const group = Array.from(inputs).reduce((obj, input) => {
|
||||
const value = parseInput(input);
|
||||
if (value !== null) obj[input.name] = value;
|
||||
return obj;
|
||||
}, {});
|
||||
return group;
|
||||
});
|
||||
localStorage.setItem("burg-groups", JSON.stringify(options.burgs.groups));
|
||||
|
||||
// put burgs to new groups
|
||||
const validBurgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const populations = validBurgs.map(b => b.population).sort((a, b) => a - b);
|
||||
validBurgs.forEach(burg => Burgs.defineGroup(burg, populations));
|
||||
|
||||
if (layerIsOn("toggleBurgIcons")) drawBurgIcons();
|
||||
if (layerIsOn("toggleLabels")) drawBurgLabels();
|
||||
if (byId("burgsOverviewRefresh")?.offsetParent) burgsOverviewRefresh.click();
|
||||
|
||||
$("#burgGroupsEditor").dialog("close");
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
|
||||
// add listeners
|
||||
byId("burgsOverviewRefresh").addEventListener("click", refreshBurgsEditor);
|
||||
byId("burgsGroupsEditorButton").addEventListener("click", editBurgGroups);
|
||||
byId("burgsChart").addEventListener("click", showBurgsChart);
|
||||
byId("burgsFilterState").addEventListener("change", burgsOverviewAddLines);
|
||||
byId("burgsFilterCulture").addEventListener("change", burgsOverviewAddLines);
|
||||
|
|
@ -88,29 +89,24 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
data-state="${state}"
|
||||
data-province="${province}"
|
||||
data-culture="${culture}"
|
||||
data-group="${b.group}"
|
||||
data-population=${population}
|
||||
data-features="${features}"
|
||||
>
|
||||
<span data-tip="Click to zoom into view" class="icon-dot-circled pointer"></span>
|
||||
<input data-tip="Burg name. Click and type to change" class="burgName" value="${
|
||||
b.name
|
||||
}" autocorrect="off" spellcheck="false" />
|
||||
<input data-tip="Burg province" class="burgState" value="${province}" disabled />
|
||||
<input data-tip="Burg state" class="burgState" value="${state}" disabled />
|
||||
<select data-tip="Dominant culture. Click to change burg culture (to change cell culture use Cultures Editor)" class="stateCulture">
|
||||
${getCultureOptions(b.culture)}
|
||||
</select>
|
||||
<input data-tip="Burg name" class="burgName" value="${b.name}" disabled />
|
||||
<input data-tip="Burg province" value="${province}" disabled />
|
||||
<input data-tip="Burg state" value="${state}" disabled />
|
||||
<input data-tip="Dominant culture" value="${culture}" disabled />
|
||||
<input data-tip="Burg group" value="${b.group}" disabled />
|
||||
<span data-tip="Burg population" class="icon-male"></span>
|
||||
<input data-tip="Burg population. Type to change" value=${si(
|
||||
population
|
||||
)} class="burgPopulation" style="width: 5em" />
|
||||
<input data-tip="Burg population" value=${si(population)} style="width: 5em" disabled />
|
||||
<div style="width: 3em">
|
||||
<span
|
||||
data-tip="${b.capital ? " This burg is a state capital" : "Click to assign a capital status"}"
|
||||
class="icon-star-empty${b.capital ? "" : " inactive pointer"}" style="padding: 0 1px;"></span>
|
||||
<span data-tip="Click to toggle port status" class="icon-anchor pointer${
|
||||
b.port ? "" : " inactive"
|
||||
}" style="font-size: .9em; padding: 0 1px;"></span>
|
||||
data-tip="${b.capital ? " This burg is a state capital" : "This burg is a NOT state capital"}"
|
||||
class="icon-star-empty${b.capital ? "" : " inactive"}" style="padding: 0 1px;"></span>
|
||||
<span data-tip="${b.port ? " This burg is a port" : "This burg is NOT a port"}"
|
||||
class="icon-anchor${b.port ? "" : " inactive"}" style="font-size: .9em; padding: 0 1px;"></span>
|
||||
</div>
|
||||
<span data-tip="Edit burg" class="icon-pencil"></span>
|
||||
<span class="locks pointer ${
|
||||
|
|
@ -129,16 +125,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
// add listeners
|
||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => burgHighlightOn(ev)));
|
||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => burgHighlightOff(ev)));
|
||||
body.querySelectorAll("div > input.burgName").forEach(el => el.addEventListener("input", changeBurgName));
|
||||
body.querySelectorAll("div > span.icon-dot-circled").forEach(el => el.addEventListener("click", zoomIntoBurg));
|
||||
body.querySelectorAll("div > select.stateCulture").forEach(el => el.addEventListener("change", changeBurgCulture));
|
||||
body
|
||||
.querySelectorAll("div > input.burgPopulation")
|
||||
.forEach(el => el.addEventListener("change", changeBurgPopulation));
|
||||
body
|
||||
.querySelectorAll("div > span.icon-star-empty")
|
||||
.forEach(el => el.addEventListener("click", toggleCapitalStatus));
|
||||
body.querySelectorAll("div > span.icon-anchor").forEach(el => el.addEventListener("click", togglePortStatus));
|
||||
body.querySelectorAll("div > span.locks").forEach(el => el.addEventListener("click", toggleBurgLockStatus));
|
||||
body.querySelectorAll("div > span.icon-pencil").forEach(el => el.addEventListener("click", openBurgEditor));
|
||||
body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", triggerBurgRemove));
|
||||
|
|
@ -164,15 +151,6 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
burgLabels.selectAll("text.drag").classed("drag", false);
|
||||
}
|
||||
|
||||
function changeBurgName() {
|
||||
if (this.value == "") tip("Please provide a name", false, "error");
|
||||
const burg = +this.parentNode.dataset.id;
|
||||
pack.burgs[burg].name = this.value;
|
||||
this.parentNode.dataset.name = this.value;
|
||||
const label = document.querySelector("#burgLabels [data-id='" + burg + "']");
|
||||
if (label) label.innerHTML = this.value;
|
||||
}
|
||||
|
||||
function zoomIntoBurg() {
|
||||
const burg = +this.parentNode.dataset.id;
|
||||
const label = document.querySelector("#burgLabels [data-id='" + burg + "']");
|
||||
|
|
@ -181,42 +159,6 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
zoomTo(x, y, 8, 2000);
|
||||
}
|
||||
|
||||
function changeBurgCulture() {
|
||||
const burg = +this.parentNode.dataset.id;
|
||||
const v = +this.value;
|
||||
pack.burgs[burg].culture = v;
|
||||
this.parentNode.dataset.culture = pack.cultures[v].name;
|
||||
}
|
||||
|
||||
function changeBurgPopulation() {
|
||||
const burg = +this.parentNode.dataset.id;
|
||||
if (this.value == "" || isNaN(+this.value)) {
|
||||
tip("Please provide an integer number (like 10000, not 10K)", false, "error");
|
||||
this.value = si(pack.burgs[burg].population * populationRate * urbanization);
|
||||
return;
|
||||
}
|
||||
pack.burgs[burg].population = this.value / populationRate / urbanization;
|
||||
this.parentNode.dataset.population = this.value;
|
||||
this.value = si(this.value);
|
||||
|
||||
const population = [];
|
||||
body.querySelectorAll(":scope > div").forEach(el => population.push(+getInteger(el.dataset.population)));
|
||||
burgsFooterPopulation.innerHTML = si(d3.mean(population));
|
||||
}
|
||||
|
||||
function toggleCapitalStatus() {
|
||||
const burg = +this.parentNode.parentNode.dataset.id;
|
||||
toggleCapital(burg);
|
||||
burgsOverviewAddLines();
|
||||
}
|
||||
|
||||
function togglePortStatus() {
|
||||
const burg = +this.parentNode.parentNode.dataset.id;
|
||||
togglePort(burg);
|
||||
if (this.classList.contains("inactive")) this.classList.remove("inactive");
|
||||
else this.classList.add("inactive");
|
||||
}
|
||||
|
||||
function toggleBurgLockStatus() {
|
||||
const burgId = +this.parentNode.dataset.id;
|
||||
|
||||
|
|
@ -240,16 +182,16 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
}
|
||||
|
||||
function triggerBurgRemove() {
|
||||
const burg = +this.parentNode.dataset.id;
|
||||
if (pack.burgs[burg].capital)
|
||||
return tip("You cannot remove the capital. Please change the capital first", false, "error");
|
||||
const burgId = +this.parentNode.dataset.id;
|
||||
if (pack.burgs[burgId].capital)
|
||||
return tip("You cannot remove the capital. Please change the state capital first", false, "error");
|
||||
|
||||
confirmationDialog({
|
||||
title: "Remove burg",
|
||||
message: "Are you sure you want to remove the burg? <br>This action cannot be reverted",
|
||||
confirm: "Remove",
|
||||
onConfirm: () => {
|
||||
removeBurg(burg);
|
||||
Burgs.remove(burgId);
|
||||
burgsOverviewAddLines();
|
||||
}
|
||||
});
|
||||
|
|
@ -286,7 +228,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
if (pack.cells.burg[cell])
|
||||
return tip("There is already a burg in this cell. Please select a free cell", false, "error");
|
||||
|
||||
addBurg(point); // add new burg
|
||||
Burgs.add(point); // add new burg
|
||||
|
||||
if (d3.event.shiftKey === false) {
|
||||
exitAddBurgMode();
|
||||
|
|
@ -481,7 +423,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
}
|
||||
|
||||
function downloadBurgsData() {
|
||||
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Temperature,Temperature likeness,Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town,Emblem,City Generator Link\n`; // headers
|
||||
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Group,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Temperature,Temperature likeness,Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town,Emblem,Preview link\n`; // headers
|
||||
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
||||
|
||||
valid.forEach(b => {
|
||||
|
|
@ -494,6 +436,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
data += pack.states[b.state].fullName + ",";
|
||||
data += pack.cultures[b.culture].name + ",";
|
||||
data += pack.religions[pack.cells.religion[b.cell]].name + ",";
|
||||
data += b.group + ",";
|
||||
data += rn(b.population * populationRate * urbanization) + ",";
|
||||
|
||||
// add geography data
|
||||
|
|
@ -515,7 +458,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
data += b.temple ? "temple," : ",";
|
||||
data += b.shanty ? "shanty town," : ",";
|
||||
data += b.coa ? JSON.stringify(b.coa).replace(/"/g, "").replace(/,/g, ";") + "," : ",";
|
||||
data += getBurgLink(b);
|
||||
data += Burgs.getPreview(b).link;
|
||||
|
||||
data += "\n";
|
||||
});
|
||||
|
|
@ -593,17 +536,15 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
|||
title: `Remove ${number} burgs`,
|
||||
message: `
|
||||
Are you sure you want to remove all <i>unlocked</i> burgs except for capitals?
|
||||
<br><i>To remove a capital you have to remove a state first</i>`,
|
||||
<br><i>To remove a capital you have to remove its state first</i>`,
|
||||
confirm: "Remove",
|
||||
onConfirm: removeAllBurgs
|
||||
onConfirm: () => {
|
||||
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => Burgs.remove(b.i));
|
||||
burgsOverviewAddLines();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeAllBurgs() {
|
||||
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => removeBurg(b.i));
|
||||
burgsOverviewAddLines();
|
||||
}
|
||||
|
||||
function toggleLockAll() {
|
||||
const activeBurgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const allLocked = activeBurgs.every(burg => burg.lock);
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ function editDiplomacy() {
|
|||
}
|
||||
|
||||
function regenerateRelations() {
|
||||
BurgsAndStates.generateDiplomacy();
|
||||
States.generateDiplomacy();
|
||||
refreshDiplomacyEditor();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -128,308 +128,6 @@ function applySorting(headers) {
|
|||
.forEach(line => list.appendChild(line));
|
||||
}
|
||||
|
||||
function addBurg(point) {
|
||||
const {cells, states} = pack;
|
||||
const x = rn(point[0], 2);
|
||||
const y = rn(point[1], 2);
|
||||
|
||||
const cellId = findCell(x, y);
|
||||
const i = pack.burgs.length;
|
||||
const culture = cells.culture[cellId];
|
||||
const name = Names.getCulture(culture);
|
||||
const state = cells.state[cellId];
|
||||
const feature = cells.f[cellId];
|
||||
|
||||
const population = Math.max(cells.s[cellId] / 3 + i / 1000 + (cellId % 100) / 1000, 0.1);
|
||||
const type = BurgsAndStates.getType(cellId, false);
|
||||
|
||||
// generate emblem
|
||||
const coa = COA.generate(states[state].coa, 0.25, null, type);
|
||||
coa.shield = COA.getShield(culture, state);
|
||||
COArenderer.add("burg", i, coa, x, y);
|
||||
|
||||
const burg = {
|
||||
name,
|
||||
cell: cellId,
|
||||
x,
|
||||
y,
|
||||
state,
|
||||
i,
|
||||
culture,
|
||||
feature,
|
||||
capital: 0,
|
||||
port: 0,
|
||||
temple: 0,
|
||||
population,
|
||||
coa,
|
||||
type
|
||||
};
|
||||
pack.burgs.push(burg);
|
||||
cells.burg[cellId] = i;
|
||||
|
||||
const townSize = burgIcons.select("#towns").attr("size") || 0.5;
|
||||
burgIcons
|
||||
.select("#towns")
|
||||
.append("circle")
|
||||
.attr("id", "burg" + i)
|
||||
.attr("data-id", i)
|
||||
.attr("cx", x)
|
||||
.attr("cy", y)
|
||||
.attr("r", townSize);
|
||||
burgLabels
|
||||
.select("#towns")
|
||||
.append("text")
|
||||
.attr("text-rendering", "optimizeSpeed")
|
||||
.attr("id", "burgLabel" + i)
|
||||
.attr("data-id", i)
|
||||
.attr("x", x)
|
||||
.attr("y", y)
|
||||
.attr("dy", `${townSize * -1.5}px`)
|
||||
.text(name);
|
||||
|
||||
BurgsAndStates.defineBurgFeatures(burg);
|
||||
|
||||
const newRoute = Routes.connect(cellId);
|
||||
if (newRoute && layerIsOn("toggleRoutes")) {
|
||||
routes
|
||||
.select("#" + newRoute.group)
|
||||
.append("path")
|
||||
.attr("d", Routes.getPath(newRoute))
|
||||
.attr("id", "route" + newRoute.i);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
function moveBurgToGroup(id, g) {
|
||||
const label = document.querySelector("#burgLabels [data-id='" + id + "']");
|
||||
const icon = document.querySelector("#burgIcons [data-id='" + id + "']");
|
||||
const anchor = document.querySelector("#anchors [data-id='" + id + "']");
|
||||
if (!label || !icon) {
|
||||
ERROR && console.error(`Cannot find label or icon elements for id ${id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector("#burgLabels > #" + g).appendChild(label);
|
||||
document.querySelector("#burgIcons > #" + g).appendChild(icon);
|
||||
|
||||
const iconSize = icon.parentNode.getAttribute("size");
|
||||
icon.setAttribute("r", iconSize);
|
||||
label.setAttribute("dy", `${iconSize * -1.5}px`);
|
||||
|
||||
if (anchor) {
|
||||
document.querySelector("#anchors > #" + g).appendChild(anchor);
|
||||
const anchorSize = +anchor.parentNode.getAttribute("size");
|
||||
anchor.setAttribute("width", anchorSize);
|
||||
anchor.setAttribute("height", anchorSize);
|
||||
anchor.setAttribute("x", rn(pack.burgs[id].x - anchorSize * 0.47, 2));
|
||||
anchor.setAttribute("y", rn(pack.burgs[id].y - anchorSize * 0.47, 2));
|
||||
}
|
||||
}
|
||||
|
||||
function moveAllBurgsToGroup(fromGroup, toGroup) {
|
||||
const groupToMove = document.querySelector(`#burgIcons #${fromGroup}`);
|
||||
const burgsToMove = Array.from(groupToMove.children).map(x => x.dataset.id);
|
||||
addBurgsGroup(toGroup);
|
||||
burgsToMove.forEach(x => moveBurgToGroup(x, toGroup));
|
||||
}
|
||||
|
||||
function addBurgsGroup(group) {
|
||||
if (document.querySelector(`#burgLabels > #${group}`)) return;
|
||||
const labelCopy = document.querySelector("#burgLabels > #towns").cloneNode(false);
|
||||
const iconCopy = document.querySelector("#burgIcons > #towns").cloneNode(false);
|
||||
const anchorCopy = document.querySelector("#anchors > #towns").cloneNode(false);
|
||||
|
||||
// FIXME: using the same id is against the spec!
|
||||
document.querySelector("#burgLabels").appendChild(labelCopy).id = group;
|
||||
document.querySelector("#burgIcons").appendChild(iconCopy).id = group;
|
||||
document.querySelector("#anchors").appendChild(anchorCopy).id = group;
|
||||
}
|
||||
|
||||
function removeBurg(id) {
|
||||
document.querySelector("#burgLabels [data-id='" + id + "']")?.remove();
|
||||
document.querySelector("#burgIcons [data-id='" + id + "']")?.remove();
|
||||
document.querySelector("#anchors [data-id='" + id + "']")?.remove();
|
||||
|
||||
const cells = pack.cells;
|
||||
const burg = pack.burgs[id];
|
||||
|
||||
burg.removed = true;
|
||||
cells.burg[burg.cell] = 0;
|
||||
|
||||
const noteId = notes.findIndex(note => note.id === `burg${id}`);
|
||||
if (noteId !== -1) notes.splice(noteId, 1);
|
||||
|
||||
if (burg.coa) {
|
||||
const coaId = "burgCOA" + id;
|
||||
if (byId(coaId)) byId(coaId).remove();
|
||||
emblems.select(`#burgEmblems > use[data-i='${id}']`).remove();
|
||||
delete burg.coa; // remove to save data
|
||||
}
|
||||
}
|
||||
|
||||
function toggleCapital(burgId) {
|
||||
const {burgs, states} = pack;
|
||||
if (burgs[burgId].capital)
|
||||
return tip("To change capital please assign a capital status to another burg of this state", false, "error");
|
||||
|
||||
const stateId = burgs[burgId].state;
|
||||
if (!stateId) return tip("Neutral lands cannot have a capital", false, "error");
|
||||
|
||||
const prevCapitalId = states[stateId].capital;
|
||||
states[stateId].capital = burgId;
|
||||
states[stateId].center = burgs[burgId].cell;
|
||||
burgs[burgId].capital = 1;
|
||||
burgs[prevCapitalId].capital = 0;
|
||||
|
||||
moveBurgToGroup(burgId, "cities");
|
||||
moveBurgToGroup(prevCapitalId, "towns");
|
||||
}
|
||||
|
||||
function togglePort(burg) {
|
||||
const anchor = document.querySelector("#anchors [data-id='" + burg + "']");
|
||||
if (anchor) anchor.remove();
|
||||
const b = pack.burgs[burg];
|
||||
if (b.port) {
|
||||
b.port = 0;
|
||||
return;
|
||||
} // not a port anymore
|
||||
|
||||
const haven = pack.cells.haven[b.cell];
|
||||
const port = haven ? pack.cells.f[haven] : -1;
|
||||
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
|
||||
b.port = port;
|
||||
|
||||
const g = b.capital ? "cities" : "towns";
|
||||
const group = anchors.select("g#" + g);
|
||||
const size = +group.attr("size");
|
||||
group
|
||||
.append("use")
|
||||
.attr("xlink:href", "#icon-anchor")
|
||||
.attr("data-id", burg)
|
||||
.attr("x", rn(b.x - size * 0.47, 2))
|
||||
.attr("y", rn(b.y - size * 0.47, 2))
|
||||
.attr("width", size)
|
||||
.attr("height", size);
|
||||
}
|
||||
|
||||
function getBurgLink(burg) {
|
||||
if (burg.link) return burg.link;
|
||||
|
||||
const population = burg.population * populationRate * urbanization;
|
||||
if (population >= options.villageMaxPopulation || burg.citadel || burg.walls || burg.temple || burg.shanty)
|
||||
return createMfcgLink(burg);
|
||||
|
||||
return createVillageGeneratorLink(burg);
|
||||
}
|
||||
|
||||
function createMfcgLink(burg) {
|
||||
const {cells} = pack;
|
||||
const {i, name, population: burgPopulation, cell} = burg;
|
||||
const burgSeed = burg.MFCG || seed + String(burg.i).padStart(4, 0);
|
||||
|
||||
const sizeRaw = 2.13 * Math.pow((burgPopulation * populationRate) / urbanDensity, 0.385);
|
||||
const size = minmax(Math.ceil(sizeRaw), 6, 100);
|
||||
const population = rn(burgPopulation * populationRate * urbanization);
|
||||
|
||||
const river = cells.r[cell] ? 1 : 0;
|
||||
const coast = Number(burg.port > 0);
|
||||
const sea = (() => {
|
||||
if (!coast || !cells.haven[cell]) return null;
|
||||
|
||||
// calculate see direction: 0 = south, 0.5 = west, 1 = north, 1.5 = east
|
||||
const p1 = cells.p[cell];
|
||||
const p2 = cells.p[cells.haven[cell]];
|
||||
let deg = (Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180) / Math.PI - 90;
|
||||
if (deg < 0) deg += 360;
|
||||
return rn(normalize(deg, 0, 360) * 2, 2);
|
||||
})();
|
||||
|
||||
const arableBiomes = river ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||
const farms = +arableBiomes.includes(cells.biome[cell]);
|
||||
|
||||
const citadel = +burg.citadel;
|
||||
const urban_castle = +(citadel && each(2)(i));
|
||||
|
||||
const hub = Routes.isCrossroad(cell);
|
||||
const walls = +burg.walls;
|
||||
const plaza = +burg.plaza;
|
||||
const temple = +burg.temple;
|
||||
const shantytown = +burg.shanty;
|
||||
|
||||
const url = new URL("https://watabou.github.io/city-generator/");
|
||||
url.search = new URLSearchParams({
|
||||
name,
|
||||
population,
|
||||
size,
|
||||
seed: burgSeed,
|
||||
river,
|
||||
coast,
|
||||
farms,
|
||||
citadel,
|
||||
urban_castle,
|
||||
hub,
|
||||
plaza,
|
||||
temple,
|
||||
walls,
|
||||
shantytown,
|
||||
gates: -1
|
||||
});
|
||||
if (sea) url.searchParams.append("sea", sea);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function createVillageGeneratorLink(burg) {
|
||||
const {cells, features} = pack;
|
||||
const {i, population, cell} = burg;
|
||||
|
||||
const pop = rn(population * populationRate * urbanization);
|
||||
const burgSeed = seed + String(i).padStart(4, 0);
|
||||
const tags = [];
|
||||
|
||||
if (cells.r[cell] && cells.haven[cell]) tags.push("estuary");
|
||||
else if (cells.haven[cell] && features[cells.f[cell]].cells === 1) tags.push("island,district");
|
||||
else if (burg.port) tags.push("coast");
|
||||
else if (cells.conf[cell]) tags.push("confluence");
|
||||
else if (cells.r[cell]) tags.push("river");
|
||||
else if (pop < 200 && each(4)(cell)) tags.push("pond");
|
||||
|
||||
const roadsNumber = Object.values(pack.cells.routes[cell] || {}).filter(routeId => {
|
||||
const route = pack.routes.find(route => route.i === routeId);
|
||||
if (!route) return false;
|
||||
return route.group === "roads" || route.group === "trails";
|
||||
}).length;
|
||||
tags.push(roadsNumber > 1 ? "highway" : roadsNumber === 1 ? "dead end" : "isolated");
|
||||
|
||||
const biome = cells.biome[cell];
|
||||
const arableBiomes = cells.r[cell] ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||
if (!arableBiomes.includes(biome)) tags.push("uncultivated");
|
||||
else if (each(6)(cell)) tags.push("farmland");
|
||||
|
||||
const temp = grid.cells.temp[cells.g[cell]];
|
||||
if (temp <= 0 || temp > 28 || (temp > 25 && each(3)(cell))) tags.push("no orchards");
|
||||
|
||||
if (!burg.plaza) tags.push("no square");
|
||||
|
||||
if (pop < 100) tags.push("sparse");
|
||||
else if (pop > 300) tags.push("dense");
|
||||
|
||||
const width = (() => {
|
||||
if (pop > 1500) return 1600;
|
||||
if (pop > 1000) return 1400;
|
||||
if (pop > 500) return 1000;
|
||||
if (pop > 200) return 800;
|
||||
if (pop > 100) return 600;
|
||||
return 400;
|
||||
})();
|
||||
const height = rn(width / 2.2);
|
||||
|
||||
const url = new URL("https://watabou.github.io/village-generator/");
|
||||
url.search = new URLSearchParams({pop, name: "", seed: burgSeed, width, height, tags});
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
// draw legend box
|
||||
function drawLegend(name, data) {
|
||||
legend.selectAll("*").remove(); // fully redraw every time
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ function showMapTooltip(point, e, i, g) {
|
|||
if (burgId) {
|
||||
const burg = pack.burgs[burgId];
|
||||
const population = si(burg.population * populationRate * urbanization);
|
||||
tip(`${burg.name}. Population: ${population}. Click to edit`);
|
||||
tip(`${burg.name} ${burg.group}. Population: ${population}. Click to edit`);
|
||||
if (burgsOverview?.offsetParent) highlightEditorLine(burgsOverview, burgId, 5000);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,18 +238,22 @@ function editHeightmap(options) {
|
|||
}
|
||||
|
||||
Biomes.define();
|
||||
rankCells();
|
||||
|
||||
rankCells();
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
|
||||
BurgsAndStates.generate();
|
||||
Burgs.generate();
|
||||
States.generate();
|
||||
Routes.generate();
|
||||
Religions.generate();
|
||||
BurgsAndStates.defineStateForms();
|
||||
|
||||
Burgs.specify();
|
||||
States.collectStatistics();
|
||||
States.defineStateForms();
|
||||
|
||||
Provinces.generate();
|
||||
Provinces.getPoles();
|
||||
BurgsAndStates.defineBurgFeatures();
|
||||
|
||||
Rivers.specify();
|
||||
Features.specify();
|
||||
|
|
@ -405,7 +409,7 @@ function editHeightmap(options) {
|
|||
b.feature = pack.cells.f[b.cell];
|
||||
|
||||
pack.cells.burg[b.cell] = b.i;
|
||||
if (!b.capital && pack.cells.h[b.cell] < 20) removeBurg(b.i);
|
||||
if (!b.capital && pack.cells.h[b.cell] < 20) Burgs.remove(b.i);
|
||||
if (b.capital) pack.states[b.state].center = b.cell;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -845,6 +845,14 @@ function drawRoutes() {
|
|||
TIME && console.timeEnd("drawRoutes");
|
||||
}
|
||||
|
||||
function drawRoute(route) {
|
||||
routes
|
||||
.select("#" + route.group)
|
||||
.append("path")
|
||||
.attr("d", Routes.getPath(route))
|
||||
.attr("id", "route" + route.i);
|
||||
}
|
||||
|
||||
function toggleMilitary(event) {
|
||||
if (!layerIsOn("toggleMilitary")) {
|
||||
turnButtonOn("toggleMilitary");
|
||||
|
|
|
|||
|
|
@ -381,14 +381,17 @@ function overviewMilitary() {
|
|||
|
||||
const filtered = data.filter(datum => datum.i && !datum.removed);
|
||||
const lines = filtered.map(
|
||||
({i, name, fullName, color}) =>
|
||||
`<tr data-tip="${name}"><td><span style="color:${color}">⬤</span></td>
|
||||
<td><input data-i="${i}" id="el${i}" type="checkbox" class="checkbox" ${
|
||||
!initial.length || initial.includes(i) ? "checked" : ""
|
||||
} >
|
||||
<label for="el${i}" class="checkbox-label">${fullName || name}</label>
|
||||
</td></tr>`
|
||||
({i, name, fullName, color}) => /* html */ `
|
||||
<tr data-tip="${name}">
|
||||
<td><span style="color:${color}">⬤</span></td>
|
||||
<td>
|
||||
<input data-i="${i}" id="el${i}" type="checkbox" class="checkbox"
|
||||
${!initial.length || initial.includes(i) ? "checked" : ""} >
|
||||
<label for="el${i}" class="checkbox-label">${fullName || name}</label>
|
||||
</td>
|
||||
</tr>`
|
||||
);
|
||||
|
||||
alertMessage.innerHTML = /* html */ `<b>Limit unit by ${type}:</b>
|
||||
<table style="margin-top:.3em">
|
||||
<tbody>
|
||||
|
|
@ -398,7 +401,7 @@ function overviewMilitary() {
|
|||
|
||||
$("#alert").dialog({
|
||||
width: fitContent(),
|
||||
title: `Limit unit`,
|
||||
title: "Limit unit",
|
||||
buttons: {
|
||||
Invert: function () {
|
||||
alertMessage.querySelectorAll("input").forEach(el => (el.checked = !el.checked));
|
||||
|
|
@ -427,7 +430,7 @@ function overviewMilitary() {
|
|||
|
||||
function applyMilitaryOptions() {
|
||||
const unitLines = Array.from(tableBody.querySelectorAll("tr"));
|
||||
const names = unitLines.map(r => r.querySelector("input").value.replace(/[&\/\\#, +()$~%.'":*?<>{}]/g, "_"));
|
||||
const names = unitLines.map(r => sanitizeId(r.querySelector("input").value));
|
||||
if (new Set(names).size !== names.length) return tip("All units should have unique names", false, "error");
|
||||
|
||||
$("#militaryOptions").dialog("close");
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ function changeEmblemShape(emblemShape) {
|
|||
|
||||
function changeStatesNumber(value) {
|
||||
byId("statesNumber").style.color = +value ? null : "#b12117";
|
||||
burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - value / 20), 3));
|
||||
burgLabels.select("#capital").attr("data-size", Math.max(rn(6 - value / 20), 3));
|
||||
labels.select("#countries").attr("data-size", Math.max(rn(18 - value / 6), 4));
|
||||
}
|
||||
|
||||
|
|
@ -1051,7 +1051,7 @@ function toggle3dOptions() {
|
|||
byId("options3dMeshSky").addEventListener("input", changeColors);
|
||||
byId("options3dMeshWater").addEventListener("input", changeColors);
|
||||
byId("options3dGlobeResolution").addEventListener("change", changeResolution);
|
||||
// byId("options3dMeshWireframeMode").addEventListener("change",toggleWireframe3d);
|
||||
byId("options3dMeshWireframeMode").addEventListener("change", toggleWireframe3d);
|
||||
byId("options3dSunColor").addEventListener("input", changeSunColor);
|
||||
byId("options3dSubdivide").addEventListener("change", toggle3dSubdivision);
|
||||
|
||||
|
|
@ -1116,9 +1116,9 @@ function toggle3dOptions() {
|
|||
ThreeD.toggle3dSubdivision();
|
||||
}
|
||||
|
||||
// function toggleWireframe3d() {
|
||||
// ThreeD.toggleWireframe();
|
||||
// }
|
||||
function toggleWireframe3d() {
|
||||
ThreeD.toggleWireframe();
|
||||
}
|
||||
|
||||
function toggleSkyMode() {
|
||||
const hide = ThreeD.options.extendedWater;
|
||||
|
|
|
|||
|
|
@ -296,8 +296,9 @@ function editProvinces() {
|
|||
const newStateId = states.length;
|
||||
|
||||
// turn province burg into a capital
|
||||
burgs[burgId].capital = 1;
|
||||
moveBurgToGroup(burgId, "cities");
|
||||
const capital = burgs[burgId];
|
||||
capital.capital = 1;
|
||||
Burgs.changeGroup(capital);
|
||||
|
||||
// move all burgs to a new state
|
||||
province.burgs.forEach(b => (burgs[b].state = newStateId));
|
||||
|
|
@ -367,9 +368,14 @@ function editProvinces() {
|
|||
function updateStatesPostRelease(oldStates, newStates) {
|
||||
const allStates = unique([...oldStates, ...newStates]);
|
||||
|
||||
BurgsAndStates.getPoles();
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.defineStateForms(newStates);
|
||||
layerIsOn("toggleProvinces") && toggleProvinces();
|
||||
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
||||
layerIsOn("toggleBorders") ? drawBorders() : toggleBorders();
|
||||
|
||||
States.getPoles();
|
||||
States.findNeighbors();
|
||||
States.collectStatistics();
|
||||
States.defineStateForms(newStates);
|
||||
drawStateLabels(allStates);
|
||||
|
||||
// redraw emblems
|
||||
|
|
@ -1032,7 +1038,7 @@ function editProvinces() {
|
|||
// generate emblem
|
||||
const kinship = burg ? 0.8 : 0.4;
|
||||
const parent = burg ? pack.burgs[burg].coa : pack.states[state].coa;
|
||||
const type = BurgsAndStates.getType(center, parent.port);
|
||||
const type = Burgs.getType(center, parent.port);
|
||||
const coa = COA.generate(parent, kinship, P(0.1), type);
|
||||
coa.shield = COA.getShield(c, state);
|
||||
COArenderer.add("province", province, coa, point[0], point[1]);
|
||||
|
|
|
|||
|
|
@ -71,24 +71,35 @@ async function fetchSystemPreset(preset) {
|
|||
}
|
||||
}
|
||||
|
||||
function applyStyle(style) {
|
||||
for (const selector in style) {
|
||||
function applyStyle(styleJSON) {
|
||||
for (const selector in styleJSON) {
|
||||
if (selector.startsWith("#burgLabels")) {
|
||||
const group = selector.split("#").pop();
|
||||
style.burgLabels[group] = styleJSON[selector];
|
||||
}
|
||||
|
||||
if (selector.startsWith("#burgIcons")) {
|
||||
const group = selector.split("#").pop();
|
||||
style.burgIcons[group] = styleJSON[selector];
|
||||
}
|
||||
|
||||
if (selector.startsWith("#anchors")) {
|
||||
const group = selector.split("#").pop();
|
||||
style.anchors[group] = styleJSON[selector];
|
||||
}
|
||||
|
||||
const el = document.querySelector(selector);
|
||||
if (!el) continue;
|
||||
|
||||
for (const attribute in style[selector]) {
|
||||
const value = style[selector][attribute];
|
||||
for (const attribute in styleJSON[selector]) {
|
||||
const value = styleJSON[selector][attribute];
|
||||
|
||||
if (value === "null" || value === null) {
|
||||
el.removeAttribute(attribute);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attribute === "text-shadow") {
|
||||
el.style[attribute] = value;
|
||||
} else {
|
||||
el.setAttribute(attribute, value);
|
||||
}
|
||||
el.setAttribute(attribute, value);
|
||||
|
||||
if (selector === "#texture") {
|
||||
const image = document.querySelector("#texture > image");
|
||||
|
|
@ -130,6 +141,11 @@ async function changeStyle(desiredPreset) {
|
|||
const [presetName, style] = styleData;
|
||||
localStorage.setItem("presetStyle", presetName);
|
||||
applyStyleWithUiRefresh(style);
|
||||
if (layerIsOn("toggleBurgIcons")) drawBurgIcons();
|
||||
if (layerIsOn("toggleLabels")) {
|
||||
drawBurgLabels();
|
||||
drawStateLabels();
|
||||
}
|
||||
}
|
||||
|
||||
function applyStyleWithUiRefresh(style) {
|
||||
|
|
@ -271,52 +287,12 @@ function addStylePreset() {
|
|||
"data-columns"
|
||||
],
|
||||
"#legendBox": ["fill", "fill-opacity"],
|
||||
"#burgLabels > #cities": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"text-shadow",
|
||||
"letter-spacing",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family"
|
||||
],
|
||||
"#burgIcons > #cities": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"size",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap"
|
||||
],
|
||||
"#anchors > #cities": ["opacity", "fill", "size", "stroke", "stroke-width"],
|
||||
"#burgLabels > #towns": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"text-shadow",
|
||||
"letter-spacing",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family"
|
||||
],
|
||||
"#burgIcons > #towns": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"size",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap"
|
||||
],
|
||||
"#anchors > #towns": ["opacity", "fill", "size", "stroke", "stroke-width"],
|
||||
"#labels > #states": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"text-shadow",
|
||||
"style",
|
||||
"letter-spacing",
|
||||
"data-size",
|
||||
"font-size",
|
||||
|
|
@ -328,7 +304,7 @@ function addStylePreset() {
|
|||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"text-shadow",
|
||||
"style",
|
||||
"letter-spacing",
|
||||
"data-size",
|
||||
"font-size",
|
||||
|
|
@ -352,6 +328,39 @@ function addStylePreset() {
|
|||
]
|
||||
};
|
||||
|
||||
const burgLabelsAttributes = [
|
||||
"opacity",
|
||||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"style",
|
||||
"letter-spacing",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family",
|
||||
"data-dx",
|
||||
"data-dy"
|
||||
];
|
||||
const burgIconsAttributes = [
|
||||
"opacity",
|
||||
"data-icon",
|
||||
"font-size",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap",
|
||||
"stroke-linejoin",
|
||||
"filter"
|
||||
];
|
||||
const anchorsAttributes = ["opacity", "fill", "font-size", "stroke", "stroke-width", "filter"];
|
||||
options.burgs.groups.forEach(({name}) => {
|
||||
attributes[`#burgLabels > g#${name}`] = burgLabelsAttributes;
|
||||
attributes[`#burgIcons > g#${name}`] = burgIconsAttributes;
|
||||
attributes[`#anchors > g#${name}`] = anchorsAttributes;
|
||||
});
|
||||
|
||||
for (const selector in attributes) {
|
||||
const el = document.querySelector(selector);
|
||||
if (!el) continue;
|
||||
|
|
|
|||
|
|
@ -248,6 +248,16 @@ function selectStyleElement() {
|
|||
styleStatesHaloBlur.value = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0;
|
||||
}
|
||||
|
||||
if (styleElement === "provs") {
|
||||
styleFill.style.display = "block";
|
||||
styleSize.style.display = "block";
|
||||
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#111111";
|
||||
|
||||
styleFont.style.display = "block";
|
||||
styleSelectFont.value = el.attr("font-family");
|
||||
styleFontSize.value = el.attr("font-size");
|
||||
}
|
||||
|
||||
if (styleElement === "labels") {
|
||||
styleFill.style.display = "block";
|
||||
styleStroke.style.display = "block";
|
||||
|
|
@ -261,46 +271,46 @@ function selectStyleElement() {
|
|||
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3a3a3a";
|
||||
styleStrokeWidthInput.value = el.attr("stroke-width") || 0;
|
||||
styleLetterSpacingInput.value = el.attr("letter-spacing") || 0;
|
||||
styleShadowInput.value = el.style("text-shadow") || "white 0 0 4px";
|
||||
styleShadowInput.value = el.style("text-shadow") || "";
|
||||
|
||||
styleFont.style.display = "block";
|
||||
styleSelectFont.value = el.attr("font-family");
|
||||
styleFontSize.value = el.attr("data-size");
|
||||
|
||||
if (el.node().parentNode.id === "burgLabels") {
|
||||
styleFontShift.style.display = "block";
|
||||
styleFontShiftX.value = el.attr("data-dx") || 0;
|
||||
styleFontShiftY.value = el.attr("data-dy") || 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (styleElement === "provs") {
|
||||
styleFill.style.display = "block";
|
||||
styleSize.style.display = "block";
|
||||
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#111111";
|
||||
if (styleElement === "burgIcons") {
|
||||
styleBurgIcons.style.display = "block";
|
||||
styleBurgIconsIcon.value = el.attr("data-icon");
|
||||
styleBurgIconsIconSize.value = el.attr("font-size");
|
||||
styleBurgIconsStrokeLinejoin.value = el.attr("stroke-linejoin");
|
||||
styleBurgIconsFillOpacity.value = el.attr("fill-opacity");
|
||||
|
||||
styleFont.style.display = "block";
|
||||
styleSelectFont.value = el.attr("font-family");
|
||||
styleFontSize.value = el.attr("font-size");
|
||||
}
|
||||
|
||||
if (styleElement == "burgIcons") {
|
||||
styleFill.style.display = "block";
|
||||
styleStroke.style.display = "block";
|
||||
styleStrokeWidth.style.display = "block";
|
||||
styleStrokeDash.style.display = "block";
|
||||
styleRadius.style.display = "block";
|
||||
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
|
||||
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
|
||||
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
|
||||
styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
|
||||
styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit";
|
||||
styleRadiusInput.value = el.attr("size") || 1;
|
||||
}
|
||||
|
||||
if (styleElement == "anchors") {
|
||||
if (styleElement === "anchors") {
|
||||
styleFill.style.display = "block";
|
||||
styleStroke.style.display = "block";
|
||||
styleStrokeWidth.style.display = "block";
|
||||
styleIconSize.style.display = "block";
|
||||
styleSize.style.display = "block";
|
||||
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
|
||||
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
|
||||
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
|
||||
styleIconSizeInput.value = el.attr("size") || 2;
|
||||
styleFontSize.value = el.attr("font-size") || 1;
|
||||
}
|
||||
|
||||
if (styleElement === "legend") {
|
||||
|
|
@ -758,6 +768,22 @@ stylePopulationUrbanStrokeInput.on("input", e => {
|
|||
stylePopulationUrbanStrokeOutput.value = e.target.value;
|
||||
});
|
||||
|
||||
styleBurgIconsIcon.on("change", e => {
|
||||
getEl().attr("data-icon", e.target.value).selectAll("use").attr("href", e.target.value);
|
||||
});
|
||||
|
||||
styleBurgIconsIconSize.on("input", e => {
|
||||
getEl().attr("font-size", e.target.value);
|
||||
});
|
||||
|
||||
styleBurgIconsStrokeLinejoin.on("change", e => {
|
||||
getEl().attr("stroke-linejoin", e.target.value);
|
||||
});
|
||||
|
||||
styleBurgIconsFillOpacity.on("input", e => {
|
||||
getEl().attr("fill-opacity", e.target.value);
|
||||
});
|
||||
|
||||
styleCompassSizeInput.on("input", shiftCompass);
|
||||
styleCompassShiftX.on("input", shiftCompass);
|
||||
styleCompassShiftY.on("input", shiftCompass);
|
||||
|
|
@ -840,12 +866,12 @@ styleFontSize.on("change", function () {
|
|||
|
||||
styleFontPlus.on("click", function () {
|
||||
const current = +styleFontSize.value || 12;
|
||||
changeFontSize(getEl(), Math.min(current + 1, 999));
|
||||
changeFontSize(getEl(), Math.min(rn(current + 0.1, 1), 999));
|
||||
});
|
||||
|
||||
styleFontMinus.on("click", function () {
|
||||
const current = +styleFontSize.value || 12;
|
||||
changeFontSize(getEl(), Math.max(current - 1, 1));
|
||||
changeFontSize(getEl(), Math.max(rn(current - 0.1, 1), 0.1));
|
||||
});
|
||||
|
||||
function changeFontSize(el, size) {
|
||||
|
|
@ -866,71 +892,20 @@ function changeFontSize(el, size) {
|
|||
if (styleElementSelect.value === "legend") redrawLegend();
|
||||
}
|
||||
|
||||
styleRadiusInput.on("change", function () {
|
||||
changeRadius(+this.value);
|
||||
});
|
||||
|
||||
styleRadiusPlus.on("click", function () {
|
||||
const size = Math.max(rn(getEl().attr("size") * 1.1, 2), 0.2);
|
||||
changeRadius(size);
|
||||
});
|
||||
|
||||
styleRadiusMinus.on("click", function () {
|
||||
const size = Math.max(rn(getEl().attr("size") * 0.9, 2), 0.2);
|
||||
changeRadius(size);
|
||||
});
|
||||
|
||||
function changeRadius(size, group) {
|
||||
const el = group ? burgIcons.select("#" + group) : getEl();
|
||||
const g = el.attr("id");
|
||||
el.attr("size", size);
|
||||
el.selectAll("circle").each(function () {
|
||||
this.setAttribute("r", size);
|
||||
});
|
||||
styleRadiusInput.value = size;
|
||||
burgLabels
|
||||
.select("g#" + g)
|
||||
styleFontShiftX.on("input", e => {
|
||||
getEl()
|
||||
.attr("data-dx", e.target.value)
|
||||
.selectAll("text")
|
||||
.each(function () {
|
||||
this.setAttribute("dy", `${size * -1.5}px`);
|
||||
});
|
||||
changeIconSize(size * 2, g); // change also anchor icons
|
||||
}
|
||||
|
||||
styleIconSizeInput.on("change", function () {
|
||||
changeIconSize(+this.value);
|
||||
.attr("dx", e.target.value + "em");
|
||||
});
|
||||
|
||||
styleIconSizePlus.on("click", function () {
|
||||
const size = Math.max(rn(getEl().attr("size") * 1.1, 2), 0.2);
|
||||
changeIconSize(size);
|
||||
styleFontShiftY.on("input", e => {
|
||||
getEl()
|
||||
.attr("data-dy", e.target.value)
|
||||
.selectAll("text")
|
||||
.attr("dy", e.target.value + "em");
|
||||
});
|
||||
|
||||
styleIconSizeMinus.on("click", function () {
|
||||
const size = Math.max(rn(getEl().attr("size") * 0.9, 2), 0.2);
|
||||
changeIconSize(size);
|
||||
});
|
||||
|
||||
function changeIconSize(size, group) {
|
||||
const el = group ? anchors.select("#" + group) : getEl();
|
||||
if (!el.size()) {
|
||||
console.warn(`Group ${group} not found. Can not set icon size!`);
|
||||
return;
|
||||
}
|
||||
const oldSize = +el.attr("size");
|
||||
const shift = (size - oldSize) / 2;
|
||||
el.attr("size", size);
|
||||
el.selectAll("use").each(function () {
|
||||
const x = +this.getAttribute("x");
|
||||
const y = +this.getAttribute("y");
|
||||
this.setAttribute("x", x - shift);
|
||||
this.setAttribute("y", y - shift);
|
||||
this.setAttribute("width", size);
|
||||
this.setAttribute("height", size);
|
||||
});
|
||||
styleIconSizeInput.value = size;
|
||||
}
|
||||
|
||||
styleStatesBodyOpacity.on("input", e => {
|
||||
statesBody.attr("opacity", e.target.value);
|
||||
});
|
||||
|
|
@ -1133,39 +1108,6 @@ styleScaleBar.on("input", function (event) {
|
|||
});
|
||||
|
||||
function updateElements() {
|
||||
// burgIcons to desired size
|
||||
burgIcons.selectAll("g").each(function () {
|
||||
const size = +this.getAttribute("size");
|
||||
d3.select(this)
|
||||
.selectAll("circle")
|
||||
.each(function () {
|
||||
this.setAttribute("r", size);
|
||||
});
|
||||
burgLabels
|
||||
.select("g#" + this.id)
|
||||
.selectAll("text")
|
||||
.each(function () {
|
||||
this.setAttribute("dy", `${size * -1.5}px`);
|
||||
});
|
||||
});
|
||||
|
||||
// anchor icons to desired size
|
||||
anchors.selectAll("g").each(function (d) {
|
||||
const size = +this.getAttribute("size");
|
||||
d3.select(this)
|
||||
.selectAll("use")
|
||||
.each(function () {
|
||||
const id = +this.dataset.id;
|
||||
const x = pack.burgs[id].x,
|
||||
y = pack.burgs[id].y;
|
||||
this.setAttribute("x", rn(x - size * 0.47, 2));
|
||||
this.setAttribute("y", rn(y - size * 0.47, 2));
|
||||
this.setAttribute("width", size);
|
||||
this.setAttribute("height", size);
|
||||
});
|
||||
});
|
||||
|
||||
// redraw elements
|
||||
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||
if (legend.selectAll("*").size() && window.redrawLegend) redrawLegend();
|
||||
oceanLayers.selectAll("path").remove();
|
||||
|
|
|
|||
|
|
@ -82,10 +82,11 @@ function openSubmapTool() {
|
|||
function rescaleBurgStyles(scale) {
|
||||
const burgIcons = [...byId("burgIcons").querySelectorAll("g")];
|
||||
for (const group of burgIcons) {
|
||||
const newRadius = rn(minmax(group.getAttribute("size") * scale, 0.2, 10), 2);
|
||||
changeRadius(newRadius, group.id);
|
||||
const strokeWidth = group.attributes["stroke-width"];
|
||||
strokeWidth.value = strokeWidth.value * scale;
|
||||
const newSize = rn(minmax(group.getAttribute("size") * scale, 0.2, 10), 2);
|
||||
group.setAttribute("font-size", newSize);
|
||||
|
||||
const newStroke = rn(group.getAttribute("stroke-width") * scale, 2);
|
||||
group.setAttribute("stroke-width", newStroke);
|
||||
}
|
||||
|
||||
const burgLabels = [...byId("burgLabels").querySelectorAll("g")];
|
||||
|
|
|
|||
|
|
@ -154,14 +154,16 @@ function regenerateStates() {
|
|||
if (!newStates) return;
|
||||
|
||||
pack.states = newStates;
|
||||
BurgsAndStates.expandStates();
|
||||
BurgsAndStates.normalizeStates();
|
||||
BurgsAndStates.getPoles();
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.assignColors();
|
||||
BurgsAndStates.generateCampaigns();
|
||||
BurgsAndStates.generateDiplomacy();
|
||||
BurgsAndStates.defineStateForms();
|
||||
States.expandStates();
|
||||
States.normalize();
|
||||
States.getPoles();
|
||||
States.findNeighbors();
|
||||
States.collectStatistics();
|
||||
States.assignColors();
|
||||
States.generateCampaigns();
|
||||
States.generateDiplomacy();
|
||||
States.defineStateForms();
|
||||
|
||||
Provinces.generate(true);
|
||||
Provinces.getPoles();
|
||||
|
||||
|
|
@ -209,13 +211,13 @@ function recreateStates() {
|
|||
return null;
|
||||
}
|
||||
|
||||
// turn all old capitals into towns, except for the capitals of locked states
|
||||
// turn all old capitals into town, except for the capitals of locked states
|
||||
for (const burg of validBurgs) {
|
||||
if (!burg.capital) continue;
|
||||
if (lockedStatesCapitals.includes(burg.i)) continue;
|
||||
|
||||
moveBurgToGroup(burg.i, "towns");
|
||||
burg.capital = 0;
|
||||
if (burg.capital) {
|
||||
if (lockedStatesCapitals.includes(burg.i)) continue;
|
||||
burg.capital = 0;
|
||||
Burgs.changeGroup(burg);
|
||||
}
|
||||
}
|
||||
|
||||
// remove labels and emblems for non-locked states
|
||||
|
|
@ -302,7 +304,7 @@ function recreateStates() {
|
|||
burg.capital = 1;
|
||||
capital = burg;
|
||||
capitalsTree.add([x, y]);
|
||||
moveBurgToGroup(burg.i, "cities");
|
||||
Burgs.changeGroup(capital);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -400,7 +402,7 @@ function regenerateBurgs() {
|
|||
const burgsCount =
|
||||
(manorsInput.value === "1000" ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) : +manorsInput.value) +
|
||||
existingStatesCount;
|
||||
const spacing = (graphWidth + graphHeight) / 150 / (burgsCount ** 0.7 / 66); // base min distance between towns
|
||||
const spacing = (graphWidth + graphHeight) / 150 / (burgsCount ** 0.7 / 66); // base min distance between town
|
||||
|
||||
for (let i = 0; i < sorted.length && newBurgs.length < burgsCount; i++) {
|
||||
const id = newBurgs.length;
|
||||
|
|
@ -431,20 +433,21 @@ function regenerateBurgs() {
|
|||
.filter(s => s.i && !s.removed && !s.capital)
|
||||
.forEach(s => {
|
||||
const [x, y] = cells.p[s.center];
|
||||
const burgId = addBurg([x, y]);
|
||||
const burgId = Burgs.add([x, y]);
|
||||
s.capital = burgId;
|
||||
s.center = pack.burgs[burgId].cell;
|
||||
pack.burgs[burgId].capital = 1;
|
||||
pack.burgs[burgId].state = s.i;
|
||||
moveBurgToGroup(burgId, "cities");
|
||||
|
||||
const burg = pack.burgs[burgId];
|
||||
burg.state = s.i;
|
||||
burg.capital = 1;
|
||||
Burgs.changeGroup(burg);
|
||||
});
|
||||
|
||||
features.forEach(f => {
|
||||
if (f.port) f.port = 0; // reset features ports counter
|
||||
});
|
||||
|
||||
BurgsAndStates.specifyBurgs();
|
||||
BurgsAndStates.defineBurgFeatures();
|
||||
Burgs.specify();
|
||||
regenerateRoutes();
|
||||
|
||||
drawBurgIcons();
|
||||
|
|
@ -503,7 +506,7 @@ function regenerateEmblems() {
|
|||
const nameByBurg = province.burg && province.name.slice(0, 3) === parent.name.slice(0, 3);
|
||||
const kinship = dominion ? 0 : nameByBurg ? 0.8 : 0.4;
|
||||
const culture = pack.cells.culture[province.center];
|
||||
const type = BurgsAndStates.getType(province.center, parent.port);
|
||||
const type = Burgs.getType(province.center, parent.port);
|
||||
province.coa = COA.generate(parent.coa, kinship, dominion, type);
|
||||
province.coa.shield = COA.getShield(culture, province.state);
|
||||
});
|
||||
|
|
@ -521,8 +524,24 @@ function regenerateReligions() {
|
|||
function regenerateCultures() {
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
BurgsAndStates.updateCultures();
|
||||
Religions.updateCultures();
|
||||
|
||||
// update culture for states
|
||||
pack.states = pack.states.map(state => {
|
||||
if (!state.i || state.removed) return state;
|
||||
return {...state, culture: pack.cells.culture[state.center]};
|
||||
});
|
||||
|
||||
// update culture for burgs
|
||||
pack.burgs = pack.burgs.map(burg => {
|
||||
if (!burg.i || burg.removed) return burg;
|
||||
return {...burg, culture: pack.cells.culture[burg.cell]};
|
||||
});
|
||||
|
||||
// update culture for religions
|
||||
pack.religions = pack.religions.map(religion => {
|
||||
if (!religion.i || religion.removed) return religion;
|
||||
return {...religion, culture: pack.cells.culture[religion.center]};
|
||||
});
|
||||
|
||||
layerIsOn("toggleCultures") ? drawCultures() : toggleCultures();
|
||||
refreshAllEditors();
|
||||
|
|
|
|||
|
|
@ -162,11 +162,11 @@
|
|||
"filter": null
|
||||
},
|
||||
"#sea_island": {
|
||||
"opacity": 0.5,
|
||||
"stroke": "#1f3846",
|
||||
"stroke-width": 0.7,
|
||||
"filter": "url(#dropShadow)",
|
||||
"auto-filter": 1
|
||||
"opacity": 1,
|
||||
"stroke": "#c1a884",
|
||||
"stroke-width": 0.3,
|
||||
"filter": "none",
|
||||
"auto-filter": 0
|
||||
},
|
||||
"#lake_island": {
|
||||
"opacity": 1,
|
||||
|
|
@ -194,7 +194,7 @@
|
|||
"#roads": {
|
||||
"opacity": 0.7,
|
||||
"stroke": "#8d502a",
|
||||
"stroke-width": 1,
|
||||
"stroke-width": 0.8,
|
||||
"stroke-dasharray": 3,
|
||||
"stroke-linecap": "inherit",
|
||||
"filter": "",
|
||||
|
|
@ -202,7 +202,7 @@
|
|||
},
|
||||
"#trails": {
|
||||
"opacity": 0.7,
|
||||
"stroke": "#924217",
|
||||
"stroke": "#8d502a",
|
||||
"stroke-width": 0.5,
|
||||
"stroke-dasharray": "1 2",
|
||||
"stroke-linecap": "butt",
|
||||
|
|
@ -211,16 +211,14 @@
|
|||
},
|
||||
"#searoutes": {
|
||||
"opacity": 0.8,
|
||||
"stroke": "#b16925",
|
||||
"stroke-width": 0.8,
|
||||
"stroke-dasharray": "1 2",
|
||||
"stroke-linecap": "round",
|
||||
"filter": null,
|
||||
"mask": null
|
||||
"stroke": "#aa7658",
|
||||
"stroke-width": 0.6,
|
||||
"stroke-dasharray": "2 2",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#statesBody": {
|
||||
"opacity": 0.2,
|
||||
"filter": "url(#filter-sepia)"
|
||||
"filter": null
|
||||
},
|
||||
"#statesHalo": {
|
||||
"opacity": 0.4,
|
||||
|
|
@ -328,64 +326,282 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"opacity": 1,
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 12,
|
||||
"font-size": 12,
|
||||
"font-family": "Great Vibes"
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-watabou-capital",
|
||||
"opacity": 1,
|
||||
"fill": "#fdfab9",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"stroke": "#6f4e1f",
|
||||
"stroke-width": 0.3,
|
||||
"stroke-dasharray": ".3 .4",
|
||||
"stroke-linecap": "butt"
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1.5,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"opacity": 1,
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 5,
|
||||
"font-size": 5,
|
||||
"font-family": "Great Vibes"
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-watabou-city",
|
||||
"opacity": 1,
|
||||
"fill": "#fef4d8",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"stroke": "#72472c",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1.5,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-watabou-fort",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.8,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-watabou-monastery",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-watabou-caravanserai",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-watabou-post",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-watabou-village",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-watabou-hamlet",
|
||||
"opacity": 0.9,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 0.9,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "UnifrakturMaguntia",
|
||||
"data-dy": 0.85
|
||||
},
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-watabou-town",
|
||||
"opacity": 1,
|
||||
"fill": "#E59189",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#EBE8DF",
|
||||
"font-size": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 22,
|
||||
"font-size": 22,
|
||||
|
|
@ -397,7 +613,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -328,55 +328,255 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 5,
|
||||
"font-size": 5,
|
||||
"font-family": "Amarante"
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.24,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Amarante"
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"font-size": 1.2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"font-size": 1.2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Amarante",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
|
|
@ -385,7 +585,7 @@
|
|||
"fill": "#000000",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 21,
|
||||
"font-size": 21,
|
||||
|
|
@ -397,7 +597,7 @@
|
|||
"fill": "#000000",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -330,64 +330,271 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#414141",
|
||||
"text-shadow": "white 0 0 4px",
|
||||
"style": "text-shadow: white 0 0 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Arial"
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.24,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#303030",
|
||||
"stroke-width": 1.7
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#414141",
|
||||
"text-shadow": "none",
|
||||
"style": "text-shadow: none",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Arial"
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.06
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arial",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#292929",
|
||||
"stroke": "#303030",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0 0 2px",
|
||||
"style": "text-shadow: white 0 0 2px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 10,
|
||||
"font-size": 10,
|
||||
|
|
@ -399,7 +606,7 @@
|
|||
"fill": "#414141",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0 0 4px",
|
||||
"style": "text-shadow: white 0 0 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -328,64 +328,271 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 8,
|
||||
"font-size": 8,
|
||||
"font-family": "Orbitron"
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 2,
|
||||
"font-size": 2,
|
||||
"stroke": "#444444",
|
||||
"stroke-width": 0.25,
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 4,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 9,
|
||||
"font-size": 9,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron"
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"opacity": 0.95,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.8,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1.6,
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Orbitron",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
@ -397,7 +604,7 @@
|
|||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@
|
|||
"#roads": {
|
||||
"opacity": 1,
|
||||
"stroke": "#ff6000",
|
||||
"stroke-width": 1.75,
|
||||
"stroke-width": 1.25,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt",
|
||||
"filter": null,
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
"#trails": {
|
||||
"opacity": 1,
|
||||
"stroke": "#ff6000",
|
||||
"stroke-width": 1,
|
||||
"stroke-width": 0.75,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt",
|
||||
"filter": null,
|
||||
|
|
@ -317,53 +317,246 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Lugrasimo"
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"size": 1.75,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 3.5,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 5,
|
||||
"font-size": 5,
|
||||
"font-family": "Lugrasimo"
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"size": 1.25,
|
||||
"font-size": 1.25,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 1.25,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Lugrasimo",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 0.7,
|
||||
"fill": "#000000",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"stroke-dasharray": 0,
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
|
|
@ -372,7 +565,7 @@
|
|||
"fill": "#000000",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 21,
|
||||
"font-size": 21,
|
||||
|
|
@ -384,7 +577,7 @@
|
|||
"fill": "#000000",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -328,55 +328,264 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Almendra SC"
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.24,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Almendra SC"
|
||||
"data-size": 5,
|
||||
"font-size": 5,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Almendra SC",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
|
|
@ -385,7 +594,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 22,
|
||||
"font-size": 22,
|
||||
|
|
@ -397,7 +606,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@
|
|||
"#statesHalo": {
|
||||
"opacity": 0.5,
|
||||
"data-width": 12,
|
||||
"stroke-width": 12,
|
||||
"stroke-width": 10,
|
||||
"filter": "blur(10px)"
|
||||
},
|
||||
"#provs": {
|
||||
|
|
@ -331,64 +331,318 @@
|
|||
"data-columns": 8
|
||||
},
|
||||
"#legendBox": {},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0 0 2px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 8,
|
||||
"font-size": 8,
|
||||
"font-family": "Underdog"
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-watabou-capital",
|
||||
"opacity": 1,
|
||||
"font-size": 2,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 2,
|
||||
"stroke": "#444444",
|
||||
"stroke-width": 0.25,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#ffffff",
|
||||
"size": 4,
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "none",
|
||||
"letter-spacing": 0,
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 2px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.7
|
||||
},
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-watabou-city",
|
||||
"opacity": 1,
|
||||
"font-size": 2,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -2
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-watabou-fort",
|
||||
"opacity": 1,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"font-size": 2,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.8,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -1.8
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-monastery",
|
||||
"font-size": 2.3,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -1
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-caravanserai",
|
||||
"font-size": 2.75,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -1.2
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-post",
|
||||
"font-size": 2,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.6
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-village",
|
||||
"font-size": 1.7,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Underdog",
|
||||
"data-dx": 0,
|
||||
"data-dy": -1
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-hamlet",
|
||||
"font-size": 1.8,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 2px",
|
||||
"letter-spacing": null,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Underdog"
|
||||
"font-family": "Underdog",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.6
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"opacity": 0.95,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.8,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
"#burgIcons > g#town": {
|
||||
"opacity": 1,
|
||||
"data-icon": "#icon-watabou-town",
|
||||
"font-size": 1.8,
|
||||
"fill": "#8c8c8c",
|
||||
"fill-opacity": 1,
|
||||
"stroke": "#4D3F36",
|
||||
"stroke-width": 1.4,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1.6,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#4e4e4e",
|
||||
"stroke": "#b5b5b5",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0 0 2px",
|
||||
"style": "text-shadow: white 0 0 2px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 20,
|
||||
"font-size": 20,
|
||||
|
|
@ -400,7 +654,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0 0 4px",
|
||||
"style": "text-shadow: white 0 0 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -328,64 +328,318 @@
|
|||
"data-y": 62.98,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"opacity": 1,
|
||||
"fill": "#3a3a3a",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 8,
|
||||
"font-size": 8,
|
||||
"font-family": "IM Fell English"
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 3,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.4,
|
||||
"stroke-dasharray": "0.5 0.25",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 5.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-star-circled",
|
||||
"opacity": 1,
|
||||
"font-size": 2,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.6,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.5,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#3a3a3a",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circled",
|
||||
"opacity": 1,
|
||||
"font-size": 1.8,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.6,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.5,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"font-size": 0.7,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"font-size": 0.8,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"font-size": 0.7,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.5
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"font-size": 0.7,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"font-size": 0.8,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.8,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"font-size": 0.5,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.4,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.6,
|
||||
"filter": null
|
||||
},
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"stroke": null,
|
||||
"stroke-width": null,
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "IM Fell English"
|
||||
"font-family": "IM Fell English",
|
||||
"data-dx": null,
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"font-size": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1.2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": null,
|
||||
"filter": null
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2.2,
|
||||
"font-size": 0.6,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
"stroke-width": 2,
|
||||
"filter": null
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e3e",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.3,
|
||||
"text-shadow": "white 0px 0px 6px",
|
||||
"style": "text-shadow: white 0px 0px 6px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 14,
|
||||
"font-size": 14,
|
||||
|
|
@ -397,7 +651,7 @@
|
|||
"fill": "#f24706",
|
||||
"stroke": "#701b05",
|
||||
"stroke-width": 0.1,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
|
|
|
|||
|
|
@ -324,55 +324,260 @@
|
|||
"data-columns": 8
|
||||
},
|
||||
"#legendBox": {},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Courier New"
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.24,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#000000",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Courier New"
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
|
|
@ -381,7 +586,7 @@
|
|||
"fill": "#000000",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
@ -393,7 +598,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
|
|
@ -328,64 +328,271 @@
|
|||
"data-y": 99.37,
|
||||
"data-columns": null
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#dbdbe1",
|
||||
"text-shadow": "black 0px 0px 4px",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 8,
|
||||
"font-size": 8,
|
||||
"font-family": "Courier New"
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 2.1,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.2,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 4.2,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1.46
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"text-shadow": "black 0px 0px 4px",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4.28,
|
||||
"font-size": 4.28,
|
||||
"font-family": "Courier New"
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.8,
|
||||
"font-size": 1,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.1,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1.6,
|
||||
"font-size": 1,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1.53
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 8,
|
||||
"font-size": 8,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Courier New",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 1,
|
||||
"fill": "#5d77a2",
|
||||
"stroke": "#7a83ae",
|
||||
"stroke-width": 0.3,
|
||||
"text-shadow": "black 0px 0px 0.1px",
|
||||
"style": "text-shadow: black 0px 0px 0.1px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 14,
|
||||
"font-size": 14,
|
||||
|
|
@ -397,7 +604,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "black 0px 0px 4px",
|
||||
"style": "text-shadow: black 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
|
|||
247
styles/pale.json
247
styles/pale.json
|
|
@ -328,64 +328,271 @@
|
|||
"data-y": 62.98,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Arima Madurai"
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1.5,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#4f4f4f",
|
||||
"stroke-width": 0.2,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 3,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 4,
|
||||
"font-size": 4,
|
||||
"font-family": "Arima Madurai"
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.6,
|
||||
"font-size": 0.6,
|
||||
"stroke": "#4f4f4f",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1.2,
|
||||
"font-size": 0.6,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3a3a3a",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Arima Madurai",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#labels > #states": {
|
||||
"opacity": 0.8,
|
||||
"fill": "#3e3e3e",
|
||||
"fill": "#3a3a3a",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 6px",
|
||||
"style": "text-shadow: white 0px 0px 6px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 14,
|
||||
"font-size": 14,
|
||||
|
|
@ -397,7 +604,7 @@
|
|||
"fill": "#f24706",
|
||||
"stroke": "#701b05",
|
||||
"stroke-width": 0.1,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 6,
|
||||
"font-size": 6,
|
||||
|
|
|
|||
|
|
@ -328,55 +328,262 @@
|
|||
"data-y": 93,
|
||||
"data-columns": 8
|
||||
},
|
||||
"#burgLabels > #cities": {
|
||||
"#burgLabels > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"text-shadow": "white 0px 0px 2px",
|
||||
"style": "text-shadow: white 0px 0px 2px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 5,
|
||||
"font-size": 5,
|
||||
"font-family": "Comfortaa"
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #cities": {
|
||||
"#burgIcons > g#city": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 1,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.24,
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #cities": {
|
||||
"#anchors > g#city": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 2,
|
||||
"font-size": 1.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > #towns": {
|
||||
"#burgLabels > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#3e3e4b",
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Comfortaa"
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > #towns": {
|
||||
"#burgIcons > g#town": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"size": 0.5,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 0.12,
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": "",
|
||||
"stroke-linecap": "butt"
|
||||
},
|
||||
"#anchors > #towns": {
|
||||
"#anchors > g#town": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"size": 1,
|
||||
"font-size": 1,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 7,
|
||||
"font-size": 7,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#capital": {
|
||||
"data-icon": "#icon-square",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 2,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#capital": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 1.9,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#fort": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#fort": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#monastery": {
|
||||
"data-icon": "#icon-cross",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#monastery": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#caravanserai": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#caravanserai": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#trading_post": {
|
||||
"data-icon": "#icon-triangle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#trading_post": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 3,
|
||||
"font-size": 3,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#village": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#village": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.7,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
"#burgLabels > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#043449",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 2,
|
||||
"font-size": 2,
|
||||
"font-family": "Comfortaa",
|
||||
"data-dy": -0.4
|
||||
},
|
||||
"#burgIcons > g#hamlet": {
|
||||
"data-icon": "#icon-circle",
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"fill-opacity": 0.7,
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2,
|
||||
"stroke-dasharray": null,
|
||||
"stroke-linecap": "butt",
|
||||
"stroke-linejoin": "round"
|
||||
},
|
||||
"#anchors > g#hamlet": {
|
||||
"opacity": 1,
|
||||
"fill": "#ffffff",
|
||||
"font-size": 0.5,
|
||||
"stroke": "#3e3e4b",
|
||||
"stroke-width": 1.2
|
||||
},
|
||||
|
|
@ -385,7 +592,7 @@
|
|||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 0.15,
|
||||
"text-shadow": "black 1px 1px 3px",
|
||||
"style": "text-shadow: black 1px 1px 3px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 18,
|
||||
"font-size": 18,
|
||||
|
|
@ -397,7 +604,7 @@
|
|||
"fill": "#3e3e4b",
|
||||
"stroke": "#3a3a3a",
|
||||
"stroke-width": 0,
|
||||
"text-shadow": "white 0px 0px 4px",
|
||||
"style": "text-shadow: white 0px 0px 4px",
|
||||
"letter-spacing": 0,
|
||||
"data-size": 16,
|
||||
"font-size": 16,
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ void (function () {
|
|||
input.required = options.required === false ? false : true;
|
||||
input.placeholder = "type a " + type;
|
||||
input.value = options.default;
|
||||
input.style.width = promptText.length > 10 ? "100%" : "auto";
|
||||
prompt.style.display = "block";
|
||||
|
||||
form.addEventListener(
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ function parseTransform(string) {
|
|||
JSON.isValid = str => {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
JSON.safeParse = str => {
|
||||
|
|
@ -64,3 +64,18 @@ JSON.safeParse = str => {
|
|||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
function sanitizeId(string) {
|
||||
if (!string) throw new Error("No string provided");
|
||||
|
||||
let sanitized = string
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9-_]/g, "") // no invalid characters
|
||||
.replace(/\s+/g, "-"); // replace spaces with hyphens
|
||||
|
||||
// remove leading numbers
|
||||
if (sanitized.match(/^\d/)) sanitized = "_" + sanitized;
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
|
||||
*/
|
||||
|
||||
const VERSION = "1.108.12";
|
||||
const VERSION = "1.109.0";
|
||||
if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function");
|
||||
|
||||
{
|
||||
|
|
@ -33,10 +33,11 @@ if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format o
|
|||
const patreon = "https://www.patreon.com/azgaar";
|
||||
|
||||
alertMessage.innerHTML = /* html */ `The Fantasy Map Generator is updated up to version <strong>${VERSION}</strong>. This version is compatible with <a href="${changelog}" target="_blank">previous versions</a>, loaded save files will be auto-updated.
|
||||
${storedVersion ? "<span>Click on OK and then reload the page to fetch fresh code.</span>" : ""}
|
||||
${storedVersion ? "<span>In case of errors reload the page to update the code.</span>" : ""}
|
||||
|
||||
<ul>
|
||||
<strong>Latest changes:</strong>
|
||||
<li>Custom burg grouping and icon selection</li>
|
||||
<li>Ability to set custom image as Marker or Regiment icon</li>
|
||||
<li>Submap and Transform tools rework</li>
|
||||
<li>Azgaar Bot to answer questions and provide help</li>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue