mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
v1.1.09
This commit is contained in:
parent
38abc74c11
commit
c050353d70
15 changed files with 626 additions and 282 deletions
36
index.css
36
index.css
|
|
@ -184,8 +184,7 @@ i.icon-lock {
|
||||||
#riverEditor > *,
|
#riverEditor > *,
|
||||||
#routeEditor > *,
|
#routeEditor > *,
|
||||||
#labelEditor div,
|
#labelEditor div,
|
||||||
#markerEditor div,
|
#markerEditor div {
|
||||||
#burgEditor * {
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1206,6 +1205,7 @@ div.states>.statePopulation {
|
||||||
width: 3em;
|
width: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.states .icon-pencil,
|
||||||
div.states .icon-trash-empty,
|
div.states .icon-trash-empty,
|
||||||
div.states .icon-eye,
|
div.states .icon-eye,
|
||||||
div.states .icon-pin {
|
div.states .icon-pin {
|
||||||
|
|
@ -1244,7 +1244,6 @@ div.states>.small {
|
||||||
|
|
||||||
div.states>.cultureName {
|
div.states>.cultureName {
|
||||||
width: 5em;
|
width: 5em;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.states>.culturePopulation {
|
div.states>.culturePopulation {
|
||||||
|
|
@ -1301,10 +1300,6 @@ div.states span.inactive:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.states > div.stateName {
|
|
||||||
width: 12em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#burgsFooterPopulation {
|
#burgsFooterPopulation {
|
||||||
border: 0;
|
border: 0;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
|
@ -1313,6 +1308,33 @@ div.states > div.stateName {
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#stateNameEditor input,
|
||||||
|
#provinceNameEditor input {
|
||||||
|
padding-left: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stateNameEditor div.label,
|
||||||
|
#provinceNameEditor div.label,
|
||||||
|
#burgBody div.label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 5.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.burgFeature {
|
||||||
|
font-size: 1.2em;
|
||||||
|
padding: 1px 2px;
|
||||||
|
color: #555;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.burgFeature.inactive {
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.burgFeature.inactive:hover {
|
||||||
|
color: #abaaaa;
|
||||||
|
}
|
||||||
|
|
||||||
div.states>.religionName {
|
div.states>.religionName {
|
||||||
width: 11em;
|
width: 11em;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
209
index.html
209
index.html
|
|
@ -204,6 +204,9 @@
|
||||||
<title>Port</title>
|
<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"></path>
|
<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"></path>
|
||||||
</symbol>
|
</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"></path>
|
||||||
|
</symbol>
|
||||||
</g>
|
</g>
|
||||||
<g id="defs-relief">
|
<g id="defs-relief">
|
||||||
<symbol id="relief-mount-1" viewBox="0 0 100 100">
|
<symbol id="relief-mount-1" viewBox="0 0 100 100">
|
||||||
|
|
@ -1742,7 +1745,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toolsContent" class="tabcontent">
|
<div id="toolsContent" class="tabcontent">
|
||||||
<div id="openEditor">
|
<div>
|
||||||
<p>Click to configure:</p>
|
<p>Click to configure:</p>
|
||||||
<button id="editHeightmapButton" data-tip="Click to open Heightmap customization menu. Shortcut: Shift + H">Heightmap</button>
|
<button id="editHeightmapButton" data-tip="Click to open Heightmap customization menu. Shortcut: Shift + H">Heightmap</button>
|
||||||
<button id="editBiomesButton" data-tip="Click to open Biomes Editor. Shortcut: Shift + B">Biomes</button>
|
<button id="editBiomesButton" data-tip="Click to open Biomes Editor. Shortcut: Shift + B">Biomes</button>
|
||||||
|
|
@ -1753,11 +1756,19 @@
|
||||||
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor. Shortcut: Shift + N">Namesbase</button>
|
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor. Shortcut: Shift + N">Namesbase</button>
|
||||||
<button id="editZonesButton" data-tip="Click to open Zones Editor. Shortcut: Shift + Z">Zones</button>
|
<button id="editZonesButton" data-tip="Click to open Zones Editor. Shortcut: Shift + Z">Zones</button>
|
||||||
<button id="editReligions" data-tip="Click to open Religions Editor. Shortcut: Shift + R">Religions</button>
|
<button id="editReligions" data-tip="Click to open Religions Editor. Shortcut: Shift + R">Religions</button>
|
||||||
<button id="editBurgsButton" data-tip="Click to open Burgs Editor. Shortcut: Shift + T">Burgs</button>
|
|
||||||
<button id="editUnitsButton" data-tip="Click to open Units Editor. Shortcut: Shift + U">Units</button>
|
<button id="editUnitsButton" data-tip="Click to open Units Editor. Shortcut: Shift + U">Units</button>
|
||||||
<button id="editNotesButton" data-tip="Click to open Notes Editor. Shortcut: Shift + O">Notes</button>
|
<button id="editNotesButton" data-tip="Click to open Notes Editor. Shortcut: Shift + O">Notes</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>Click to overview:</p>
|
||||||
|
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview. Shortcut: Shift + T">Burgs</button>
|
||||||
|
<!-- <button id="overviewLandmassedButton" data-tip="Click to open Landmasses Overview. Shortcut: Shift + L">Landmasses</button> -->
|
||||||
|
<!-- <button id="overviewWaterbodiesButton" data-tip="Click to open Waterbodies Overview. Shortcut: Shift + W">Waterbodies</button> -->
|
||||||
|
<!-- <button id="overviewRiversButton" data-tip="Click to open Rivers Overview. Shortcut: Shift + V">Rivers</button> -->
|
||||||
|
<!-- <button id="overviewRoutesButton" data-tip="Click to open Routes Overview. Shortcut: Shift + U">Routes</button> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="regenerateFeature">
|
<div id="regenerateFeature">
|
||||||
<p>Click to regenerate:</p>
|
<p>Click to regenerate:</p>
|
||||||
<button id="regenerateStateLabels" data-tip="Click to update state labels placement based on current borders">State labels</button>
|
<button id="regenerateStateLabels" data-tip="Click to update state labels placement based on current borders">State labels</button>
|
||||||
|
|
@ -2249,36 +2260,56 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="burgEditor" class="dialog" style="display: none">
|
<div id="burgEditor" class="dialog" style="display: none">
|
||||||
<button id="burgGroupShow" data-tip="Show group change section" class="icon-tags"></button>
|
|
||||||
<div id="burgGroupSection" style="display: none">
|
<div id="burgBody" style="padding-bottom: .3em">
|
||||||
<button id="burgGroupHide" data-tip="Hide group change section" class="icon-tags"></button>
|
<div style="padding: .1em">
|
||||||
<select id="burgSelectGroup" data-tip="Select a group for this burg" style="width: 10em;"></select>
|
<div class="label">Name:</div>
|
||||||
<input id="burgInputGroup" placeholder="new group name" data-tip="Create new Group for the Burg" style="display: none; width: 10em"/>
|
<input id="burgName" data-tip="Type to rename the burg" autocorrect="off" spellcheck="false" style="width: 7em">
|
||||||
<i id="burgAddGroup" data-tip="Create new group for the burg" class="icon-plus pointer"></i>
|
<span id="burgNameReCulture" data-tip="Generate culture-specific name for the burg" class="icon-book pointer"></span>
|
||||||
<i id="burgRemoveGroup" data-tip="Remove selected burg group" class="icon-trash pointer"></i>
|
<span id="burgNameReRandom" data-tip="Generate random name for the burg" class="icon-globe pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div class="label">Population:</div>
|
||||||
|
<input id="burgPopulation" data-tip="Set burg population" type="number" min=0 step=1 style="width: 7em">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div class="label">Features:</div>
|
||||||
|
<span id="burgCapital" data-tip="Shows whether the burg is a state capital. Click to toggle" data-feature="capital" class="burgFeature icon-star"></span>
|
||||||
|
<span id="burgPort" data-tip="Shows whether the burg is a port. Click to toggle" data-feature="port" class="burgFeature icon-anchor"></span>
|
||||||
|
<span id="burgCitadel" data-tip="Shows whether the burg has a citadel (castle). Click to toggle" data-feature="citadel" class="burgFeature icon-chess-rook" style="font-size: 1.1em"></span>
|
||||||
|
<span id="burgWalls" data-tip="Shows whether the burg has walls. Click to toggle" data-feature="walls" class="burgFeature icon-fort-awesome"></span>
|
||||||
|
<span id="burgPlaza" data-tip="Shows whether the burg has a plaza (marketplace). Click to toggle" data-feature="plaza" class="burgFeature icon-store" style="font-size: 1em"></span>
|
||||||
|
<span id="burgTemple" data-tip="Shows whether the burg has a place of worship. Click to toggle" data-feature="temple" class="burgFeature icon-bank" style="font-size: 1.1em; margin-left: 3px"></span>
|
||||||
|
<span id="burgShanty" data-tip="Shows whether the burg has a shanty town. Click to toggle" data-feature="shanty" class="burgFeature icon-campground" style="font-size: 1em"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="burgNameShow" data-tip="Show name change section" class="icon-pencil"></button>
|
<div id="burgBottom">
|
||||||
<div id="burgNameSection" style="display: none">
|
<button id="burgGroupShow" data-tip="Show group change section" class="icon-tags"></button>
|
||||||
<button id="burgNameHide" data-tip="Hide name change section" class="icon-pencil"></button>
|
<div id="burgGroupSection" style="display: none">
|
||||||
<input id="burgNameInput" data-tip="Populate to rename the burg"/>
|
<button id="burgGroupHide" data-tip="Hide group change section" class="icon-tags"></button>
|
||||||
<span id="burgNameReCulture" data-tip="Generate culture-specific name for the burg" class="icon-book pointer"></span>
|
<select id="burgSelectGroup" data-tip="Select a group for this burg" style="width: 10em;"></select>
|
||||||
<span id="burgNameReRandom" data-tip="Generate random name for the burg" class="icon-globe pointer"></span>
|
<input id="burgInputGroup" placeholder="new group name" data-tip="Create new Group for the Burg" style="display: none; width: 10em"/>
|
||||||
|
<i id="burgAddGroup" data-tip="Create 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>
|
||||||
|
<button id="burgEditLabelStyle" data-tip="Edit label style for burg group in Style Editor" class="icon-font"></button>
|
||||||
|
<button id="burgEditIconStyle" data-tip="Edit icon style for burg group in Style Editor" class="icon-dot-circled"></button>
|
||||||
|
<button id="burgEditAnchorStyle" data-tip="Edit port icon (anchor) style for burg group in Style Editor" class="icon-anchor"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="burgSeeInMFCG" data-tip="Open burg in the Medieval Fantasy City Generator by Watabou. Ctrl + click to change the seed" class="icon-map-o"></button>
|
||||||
|
<button id="burgOpenCOA" data-tip="Open burg's COA in the Iron Arachne Heraldry Generator. Ctrl + click to change the seed" class="icon-fleur"></button>
|
||||||
|
<button id="burgRelocate" data-tip="Relocate burg" class="icon-target"></button>
|
||||||
|
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
||||||
|
<button id="burgRemove" data-tip="Remove non-capital burg. Shortcut: Delete" class="icon-trash"></button>
|
||||||
</div>
|
</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>
|
|
||||||
<button id="burgEditLabelStyle" data-tip="Edit label style for burg group in Style Editor" class="icon-font"></button>
|
|
||||||
<button id="burgEditIconStyle" data-tip="Edit icon style for burg group in Style Editor" class="icon-dot-circled"></button>
|
|
||||||
<button id="burgEditAnchorStyle" data-tip="Edit port icon (anchor) style for burg group in Style Editor" class="icon-anchor"></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button id="burgSeeInMFCG" data-tip="Open the burg representation in the Medieval Fantasy City Generator by Watabou" class="icon-map-o"></button>
|
|
||||||
<button id="burgOpenCOA" data-tip="Open burg's COA in the Iron Arachne Heraldry Generator" class="icon-fleur"></button>
|
|
||||||
<button id="burgRelocate" data-tip="Relocate burg" class="icon-target"></button>
|
|
||||||
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
|
||||||
<button id="burgRemove" data-tip="Remove non-capital burg. Shortcut: Delete" class="icon-trash"></button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="markerEditor" class="dialog" style="display: none">
|
<div id="markerEditor" class="dialog" style="display: none">
|
||||||
|
|
@ -2545,7 +2576,7 @@
|
||||||
<div id="statesHeader" class="header">
|
<div id="statesHeader" class="header">
|
||||||
<div style="left:1.4em" data-tip="Click to sort by state name" class="sortable alphabetically" data-sortby="name">State </div>
|
<div style="left:1.4em" data-tip="Click to sort by state name" class="sortable alphabetically" data-sortby="name">State </div>
|
||||||
<div style="left:8.7em" data-tip="Click to sort by state form name" class="sortable alphabetically" data-sortby="form">Form </div>
|
<div style="left:8.7em" data-tip="Click to sort by state form name" class="sortable alphabetically" data-sortby="form">Form </div>
|
||||||
<div style="left:16em" data-tip="Click to sort by capital name" class="sortable alphabetically hide" data-sortby="capital">Capital </div>
|
<div style="left:15.9em" data-tip="Click to sort by capital name" class="sortable alphabetically hide" data-sortby="capital">Capital </div>
|
||||||
<div style="left:22.3em" data-tip="Click to sort by state dominant culture" class="sortable alphabetically hide" data-sortby="culture">Culture </div>
|
<div style="left:22.3em" data-tip="Click to sort by state dominant culture" class="sortable alphabetically hide" data-sortby="culture">Culture </div>
|
||||||
<div style="left:27em" data-tip="Click to sort by state burgs count" class="sortable hide" data-sortby="burgs">Burgs </div>
|
<div style="left:27em" data-tip="Click to sort by state burgs count" class="sortable hide" data-sortby="burgs">Burgs </div>
|
||||||
<div style="left:32.5em" data-tip="Click to sort by state area" class="sortable hide icon-sort-number-down" data-sortby="area">Area </div>
|
<div style="left:32.5em" data-tip="Click to sort by state area" class="sortable hide icon-sort-number-down" data-sortby="area">Area </div>
|
||||||
|
|
@ -2607,6 +2638,72 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="stateNameEditor" class="dialog" data-state="0" style="display: none">
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div data-tip="State short name" class="label">Short name:</div>
|
||||||
|
<input id="stateNameEditorShort" data-tip="Type to change the short name" autocorrect="off" spellcheck="false" style="width: 11em">
|
||||||
|
<span id="stateNameEditorShortCulture" data-tip="Generate culture-specific name" class="icon-book pointer"></span>
|
||||||
|
<span id="stateNameEditorShortRandom" data-tip="Generate random name" class="icon-globe pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em" data-tip="Select form name">
|
||||||
|
<div data-tip="State form name" class="label">Form name:</div>
|
||||||
|
<select id="stateNameEditorSelectForm" style="display: inline-block; width: 11.7em; height: 1.645em">
|
||||||
|
<option value="Beylik">Beylik</option>
|
||||||
|
<option value="Caliphate">Caliphate</option>
|
||||||
|
<option value="City-state">City-state</option>
|
||||||
|
<option value="Commonwealth">Commonwealth</option>
|
||||||
|
<option value="Confederation">Confederation</option>
|
||||||
|
<option value="Despotate">Despotate</option>
|
||||||
|
<option value="Diarchy">Diarchy</option>
|
||||||
|
<option value="Diocese">Diocese</option>
|
||||||
|
<option value="Duchy">Duchy</option>
|
||||||
|
<option value="Emirate">Emirate</option>
|
||||||
|
<option value="Empire">Empire</option>
|
||||||
|
<option value="Eparchy">Eparchy</option>
|
||||||
|
<option value="Federation">Federation</option>
|
||||||
|
<option value="Free City">Free City</option>
|
||||||
|
<option value="Grand Duchy">Grand Duchy</option>
|
||||||
|
<option value="Heptarchy">Heptarchy</option>
|
||||||
|
<option value="Horde">Horde</option>
|
||||||
|
<option value="Imamah">Imamah</option>
|
||||||
|
<option value="Khaganate">Khaganate</option>
|
||||||
|
<option value="Kingdom">Kingdom</option>
|
||||||
|
<option value="League">League</option>
|
||||||
|
<option value="Marches">Marches</option>
|
||||||
|
<option value="Oligarchy">Oligarchy</option>
|
||||||
|
<option value="Principality">Principality</option>
|
||||||
|
<option value="Protectorate">Protectorate</option>
|
||||||
|
<option value="Republic">Republic</option>
|
||||||
|
<option value="Satrapy">Satrapy</option>
|
||||||
|
<option value="Sultanate">Sultanate</option>
|
||||||
|
<option value="Tetrarchy">Tetrarchy</option>
|
||||||
|
<option value="Theocracy">Theocracy</option>
|
||||||
|
<option value="Trade Company">Trade Company</option>
|
||||||
|
<option value="Triumvirate">Triumvirate</option>
|
||||||
|
<option value="Tsardom">Tsardom</option>
|
||||||
|
<option value="Ulus">Ulus</option>
|
||||||
|
<option value="Union">Union</option>
|
||||||
|
<option value="United Kingdom">United Kingdom</option>
|
||||||
|
<option value="United Provinces">United Provinces</option>
|
||||||
|
<option value="United Republic">United Republic</option>
|
||||||
|
</select>
|
||||||
|
<input id="stateNameEditorCustomForm" placeholder="type form name" data-tip="Create custom state form name" style="display: none; width: 11em;">
|
||||||
|
<span id="stateNameEditorAddForm" data-tip="Click to add custom state form name to the list" class="icon-plus pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div data-tip="State full name" class="label">Full name:</div>
|
||||||
|
<input id="stateNameEditorFull" data-tip="Type to change the full name" autocorrect="off" spellcheck="false" style="width: 11em">
|
||||||
|
<span id="stateNameEditorFullRegenerate" data-tip="Click to re-generate full name" data-tick="0" class="icon-arrows-cw pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Uncheck to not update state label on name change" style="padding: .2em">
|
||||||
|
<input id="stateNameEditorUpdateLabel" class="checkbox" type="checkbox" checked>
|
||||||
|
<label for="stateNameEditorUpdateLabel" class="checkbox-label"><i>Update label</i></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="provincesEditor" class="dialog stable" style="display: none">
|
<div id="provincesEditor" class="dialog stable" style="display: none">
|
||||||
<div id="provincesHeader" class="header">
|
<div id="provincesHeader" class="header">
|
||||||
<div style="left:1.4em" data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="name">Province </div>
|
<div style="left:1.4em" data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="name">Province </div>
|
||||||
|
|
@ -2704,6 +2801,49 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="provinceNameEditor" class="dialog" data-province="0" style="display: none">
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div data-tip="Province short name" class="label">Short name:</div>
|
||||||
|
<input id="provinceNameEditorShort" data-tip="Type to change the short name" autocorrect="off" spellcheck="false" style="width: 11em">
|
||||||
|
<span id="provinceNameEditorShortCulture" data-tip="Generate culture-specific name" class="icon-book pointer"></span>
|
||||||
|
<span id="provinceNameEditorShortRandom" data-tip="Generate random name" class="icon-globe pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em" data-tip="Select form name">
|
||||||
|
<div data-tip="Province form name" class="label">Form name:</div>
|
||||||
|
<select id="provinceNameEditorSelectForm" style="display: inline-block; width: 11.7em; height: 1.645em">
|
||||||
|
<option value="Barony">Barony</option>
|
||||||
|
<option value="Canton">Canton</option>
|
||||||
|
<option value="Council">Council</option>
|
||||||
|
<option value="County">County</option>
|
||||||
|
<option value="Deanery">Deanery</option>
|
||||||
|
<option value="Department">Department</option>
|
||||||
|
<option value="District">District</option>
|
||||||
|
<option value="Earldom">Earldom</option>
|
||||||
|
<option value="Governorate">Governorate</option>
|
||||||
|
<option value="Land">Land</option>
|
||||||
|
<option value="Landgrave">Landgrave</option>
|
||||||
|
<option value="Margrave">Margrave</option>
|
||||||
|
<option value="Parish">Parish</option>
|
||||||
|
<option value="Prefecture">Prefecture</option>
|
||||||
|
<option value="Province">Province</option>
|
||||||
|
<option value="Region">Region</option>
|
||||||
|
<option value="Republic">Republic</option>
|
||||||
|
<option value="Shire">Shire</option>
|
||||||
|
<option value="State">State</option>
|
||||||
|
<option value="Territory">Territory</option>
|
||||||
|
</select>
|
||||||
|
<input id="provinceNameEditorCustomForm" placeholder="type form name" data-tip="Create custom province form name" style="display: none; width: 11em;">
|
||||||
|
<span id="provinceNameEditorAddForm" data-tip="Click to add custom province form name to the list" class="icon-plus pointer"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: .1em">
|
||||||
|
<div data-tip="Province full name" class="label">Full name:</div>
|
||||||
|
<input id="provinceNameEditorFull" data-tip="Type to change the full name" autocorrect="off" spellcheck="false" style="width: 11em">
|
||||||
|
<span id="provinceNameEditorFullRegenerate" data-tip="Click to re-generate full name" class="icon-arrows-cw pointer"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="culturesEditor" class="dialog stable" style="display: none">
|
<div id="culturesEditor" class="dialog stable" style="display: none">
|
||||||
<div id="culturesHeader" class="header">
|
<div id="culturesHeader" class="header">
|
||||||
<div style="left:1.4em" data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="name">Culture </div>
|
<div style="left:1.4em" data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="name">Culture </div>
|
||||||
|
|
@ -2936,7 +3076,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="unitsHeader" data-tip="Select Temperature scale">
|
<div class="unitsHeader" data-tip="Select Temperature scale">
|
||||||
<span class="icon-asterisk"></span>
|
<span class="icon-temperature-high"></span>
|
||||||
<div>Temperature:</div>
|
<div>Temperature:</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3002,8 +3142,8 @@
|
||||||
|
|
||||||
<div id="unitsBottom">
|
<div id="unitsBottom">
|
||||||
<button id="addLinearRuler" data-tip="Click to place a linear measurer (ruler)" class="icon-ruler"></button>
|
<button id="addLinearRuler" data-tip="Click to place a linear measurer (ruler)" class="icon-ruler"></button>
|
||||||
<button id="addOpisometer" data-tip="Drag to measure a curve length (opisometer)" class="icon-curve"></button>
|
<button id="addOpisometer" data-tip="Drag to measure a curve length (opisometer)" class="icon-drafting-compass"></button>
|
||||||
<button id="addPlanimeter" data-tip="Drag to measure a polygon area (planimeter)" class="icon-area"></button>
|
<button id="addPlanimeter" data-tip="Drag to measure a polygon area (planimeter)" class="icon-draw-polygon"></button>
|
||||||
<button id="removeRulers" data-tip="Remove all rulers from the map. Click on ruler label to remove a ruler separately" class="icon-trash"></button>
|
<button id="removeRulers" data-tip="Remove all rulers from the map. Click on ruler label to remove a ruler separately" class="icon-trash"></button>
|
||||||
<button id="unitsRestore" data-tip="Restore default units settings" class="icon-ccw"></button>
|
<button id="unitsRestore" data-tip="Restore default units settings" class="icon-ccw"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3013,9 +3153,6 @@
|
||||||
<p id="alertMessage">Warning!</p>
|
<p id="alertMessage">Warning!</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="alert2" style="display: none">
|
|
||||||
<p id="alertMessage2">Warning!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="map-dragged" class="shadowed" style="display: none">
|
<div id="map-dragged" class="shadowed" style="display: none">
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
b.culture = cells.culture[b.cell];
|
b.culture = cells.culture[b.cell];
|
||||||
b.name = Names.getCultureShort(b.culture);
|
b.name = Names.getCultureShort(b.culture);
|
||||||
b.feature = cells.f[b.cell];
|
b.feature = cells.f[b.cell];
|
||||||
b.capital = true;
|
b.capital = 1;
|
||||||
|
|
||||||
// states data
|
// states data
|
||||||
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
|
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
|
||||||
|
|
@ -122,7 +122,7 @@
|
||||||
const burg = burgs.length;
|
const burg = burgs.length;
|
||||||
const culture = cells.culture[cell];
|
const culture = cells.culture[cell];
|
||||||
const name = Names.getCulture(culture);
|
const name = Names.getCulture(culture);
|
||||||
burgs.push({cell, x, y, state: 0, i: burg, culture, name, capital: false, feature:cells.f[cell]});
|
burgs.push({cell, x, y, state: 0, i: burg, culture, name, capital: 0, feature:cells.f[cell]});
|
||||||
burgsTree.add([x, y]);
|
burgsTree.add([x, y]);
|
||||||
cells.burg[cell] = burg;
|
cells.burg[cell] = burg;
|
||||||
burgsAdded++;
|
burgsAdded++;
|
||||||
|
|
@ -161,19 +161,19 @@
|
||||||
const e = cells.v[i].filter(v => vertices.c[v].some(c => c === cells.haven[i])); // vertices of common edge
|
const e = cells.v[i].filter(v => vertices.c[v].some(c => c === cells.haven[i])); // vertices of common edge
|
||||||
b.x = rn((vertices.p[e[0]][0] + vertices.p[e[1]][0]) / 2, 2);
|
b.x = rn((vertices.p[e[0]][0] + vertices.p[e[1]][0]) / 2, 2);
|
||||||
b.y = rn((vertices.p[e[0]][1] + vertices.p[e[1]][1]) / 2, 2);
|
b.y = rn((vertices.p[e[0]][1] + vertices.p[e[1]][1]) / 2, 2);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add random factor
|
// add random factor
|
||||||
b.population = rn(b.population * gauss(2,3,.6,20,3), 3);
|
b.population = rn(b.population * gauss(2,3,.6,20,3), 3);
|
||||||
|
|
||||||
// shift burgs on rivers semi-randomly and just a bit
|
// shift burgs on rivers semi-randomly and just a bit
|
||||||
if (cells.r[i]) {
|
if (!port && cells.r[i]) {
|
||||||
const shift = Math.min(cells.fl[i]/150, 1);
|
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 (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);
|
if (cells.r[i]%2) b.y = rn(b.y + shift, 2); else b.y = rn(b.y - shift, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineFeatures(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// de-assign port status if it's the only one on feature
|
// de-assign port status if it's the only one on feature
|
||||||
|
|
@ -188,6 +188,15 @@
|
||||||
console.timeEnd("specifyBurgs");
|
console.timeEnd("specifyBurgs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defineFeatures = function(b) {
|
||||||
|
const pop = b.population;
|
||||||
|
b.citadel = pop > 50 && Math.random() < .75 || Math.random() < .5 ? 1 : 0;
|
||||||
|
b.plaza = pop > 50 || pop > 30 && Math.random() < .75 || pop > 10 && Math.random() < .5 || Math.random() < .25 ? 1 : 0;
|
||||||
|
b.walls = b.capital || pop > 30 || pop > 20 && Math.random() < .75 || pop > 10 && Math.random() < .5 || Math.random() < .2 ? 1 : 0;
|
||||||
|
b.shanty = pop > 30 || pop > 20 && Math.random() < .75 || b.walls && Math.random() < .75 ? 1 : 0;
|
||||||
|
b.temple = pop > 100 || pop > 80 && Math.random() < .75 || pop > 50 && Math.random() < .5 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
const drawBurgs = function() {
|
const drawBurgs = function() {
|
||||||
console.time("drawBurgs");
|
console.time("drawBurgs");
|
||||||
|
|
||||||
|
|
@ -218,7 +227,7 @@
|
||||||
.attr("width", caSize).attr("height", caSize);
|
.attr("width", caSize).attr("height", caSize);
|
||||||
|
|
||||||
// towns
|
// towns
|
||||||
const towns = pack.burgs.filter(b => b.capital === false);
|
const towns = pack.burgs.filter(b => !b.capital);
|
||||||
const townIcons = burgIcons.select("#towns");
|
const townIcons = burgIcons.select("#towns");
|
||||||
const townLabels = burgLabels.select("#towns");
|
const townLabels = burgLabels.select("#towns");
|
||||||
const townSize = townIcons.attr("size") || 0.5;
|
const townSize = townIcons.attr("size") || 0.5;
|
||||||
|
|
@ -978,18 +987,11 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//if (s.i == 1) debug.append("circle").attr("cx", cells.p[n][0]).attr("cy", cells.p[n][1]).attr("r", .5);
|
|
||||||
//debug.append("text").attr("x", cells.p[n][0]).attr("y", cells.p[n][1]).text(s.i).attr("font-size", 3);
|
|
||||||
|
|
||||||
// debug.selectAll(".text").data(cells.i).enter().append("text")
|
|
||||||
// .attr("x", d => cells.p[d][0]).attr("y", d => cells.p[d][1])
|
|
||||||
// .text(d => cells.province[d] ? cells.province[d] : null).attr("font-size", 3);
|
|
||||||
|
|
||||||
console.timeEnd("generateProvinces");
|
console.timeEnd("generateProvinces");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {generate, expandStates, normalizeStates, assignColors,
|
return {generate, expandStates, normalizeStates, assignColors,
|
||||||
drawBurgs, specifyBurgs, drawStateLabels, collectStatistics,
|
drawBurgs, specifyBurgs, defineFeatures, drawStateLabels, collectStatistics,
|
||||||
generateDiplomacy, defineStateForms, getFullName, generateProvinces};
|
generateDiplomacy, defineStateForms, getFullName, generateProvinces};
|
||||||
|
|
||||||
})));
|
})));
|
||||||
|
|
|
||||||
|
|
@ -118,10 +118,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate state name based on capital or random name and culture-specific suffix
|
// generate state name based on capital or random name and culture-specific suffix
|
||||||
const getState = function(name, culture) {
|
const getState = function(name, culture, base) {
|
||||||
if (name === undefined) {console.error("Please define a base name"); return;}
|
if (name === undefined) {console.error("Please define a base name"); return;}
|
||||||
if (culture === undefined) {console.error("Please define a culture"); return;}
|
if (culture === undefined && base === undefined) {console.error("Please define a culture"); return;}
|
||||||
const base = pack.cultures[culture].base;
|
if (base === undefined) base = pack.cultures[culture].base;
|
||||||
|
|
||||||
// exclude endings inappropriate for states name
|
// exclude endings inappropriate for states name
|
||||||
if (name.includes(" ")) name = capitalize(name.replace(/ /g, "").toLowerCase()); // don't allow multiword state names
|
if (name.includes(" ")) name = capitalize(name.replace(/ /g, "").toLowerCase()); // don't allow multiword state names
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ function editBiomes() {
|
||||||
body.addEventListener("click", function(ev) {
|
body.addEventListener("click", function(ev) {
|
||||||
const el = ev.target, cl = el.classList;
|
const el = ev.target, cl = el.classList;
|
||||||
if (cl.contains("zoneFill")) biomeChangeColor(el); else
|
if (cl.contains("zoneFill")) biomeChangeColor(el); else
|
||||||
|
if (cl.contains("icon-info-circled")) openWiki(el); else
|
||||||
if (cl.contains("icon-trash-empty")) removeCustomBiome(el);
|
if (cl.contains("icon-trash-empty")) removeCustomBiome(el);
|
||||||
if (customization === 6) selectBiomeOnLineClick(el);
|
if (customization === 6) selectBiomeOnLineClick(el);
|
||||||
});
|
});
|
||||||
|
|
@ -96,6 +97,7 @@ function editBiomes() {
|
||||||
<div data-tip="Biome area" class="biomeArea hide">${si(area) + unit}</div>
|
<div data-tip="Biome area" class="biomeArea hide">${si(area) + unit}</div>
|
||||||
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
||||||
<div data-tip="${populationTip}" class="biomePopulation hide">${si(population)}</div>
|
<div data-tip="${populationTip}" class="biomePopulation hide">${si(population)}</div>
|
||||||
|
<span data-tip="Open Wikipedia articale about the biome" class="icon-info-circled pointer hide"></span>
|
||||||
${i>12 && !b.cells[i] ? '<span data-tip="Remove the custom biome" class="icon-trash-empty hide"></span>' : ''}
|
${i>12 && !b.cells[i] ? '<span data-tip="Remove the custom biome" class="icon-trash-empty hide"></span>' : ''}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
@ -164,6 +166,28 @@ function editBiomes() {
|
||||||
refreshBiomesEditor();
|
refreshBiomesEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openWiki(el) {
|
||||||
|
const name = el.parentNode.dataset.name;
|
||||||
|
if (name === "Custom" || !name) {tip("Please provide a biome name", false, "error"); return;}
|
||||||
|
const wiki = "https://en.wikipedia.org/wiki/";
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case "Hot desert": openURL(wiki + "Desert_climate#Hot_desert_climates");
|
||||||
|
case "Cold desert": openURL(wiki + "Desert_climate#Cold_desert_climates");
|
||||||
|
case "Savanna": openURL(wiki + "Tropical_and_subtropical_grasslands,_savannas,_and_shrublands");
|
||||||
|
case "Grassland": openURL(wiki + "Temperate_grasslands,_savannas,_and_shrublands");
|
||||||
|
case "Tropical seasonal forest": openURL(wiki + "Seasonal_tropical_forest");
|
||||||
|
case "Temperate deciduous forest": openURL(wiki + "Temperate_deciduous_forest");
|
||||||
|
case "Tropical rainforest": openURL(wiki + "Tropical_rainforest");
|
||||||
|
case "Temperate rainforest": openURL(wiki + "Temperate_rainforest");
|
||||||
|
case "Taiga": openURL(wiki + "Taiga");
|
||||||
|
case "Tundra": openURL(wiki + "Tundra");
|
||||||
|
case "Glacier": openURL(wiki + "Glacier");
|
||||||
|
case "Wetland": openURL(wiki + "Wetland");
|
||||||
|
default: openURL(`https://en.wikipedia.org/w/index.php?search=${name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleLegend() {
|
function toggleLegend() {
|
||||||
if (legend.selectAll("*").size()) {clearLegend(); return;}; // hide legend
|
if (legend.selectAll("*").size()) {clearLegend(); return;}; // hide legend
|
||||||
const d = biomesData;
|
const d = biomesData;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,22 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
function editBurg() {
|
function editBurg(id) {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
closeDialogs(".stable");
|
closeDialogs(".stable");
|
||||||
if (!layerIsOn("toggleIcons")) toggleIcons();
|
if (!layerIsOn("toggleIcons")) toggleIcons();
|
||||||
if (!layerIsOn("toggleLabels")) toggleLabels();
|
if (!layerIsOn("toggleLabels")) toggleLabels();
|
||||||
|
|
||||||
const id = +d3.event.target.dataset.id;
|
const burg = id || d3.event.target.dataset.id;
|
||||||
elSelected = burgLabels.select("[data-id='" + id + "']");
|
elSelected = burgLabels.select("[data-id='" + burg + "']");
|
||||||
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true);
|
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true);
|
||||||
|
updateBurgValues();
|
||||||
|
|
||||||
selectBurgGroup(d3.event.target);
|
const my = id || d3.event.target.tagName === "text" ? "center bottom" : "center top+10";
|
||||||
document.getElementById("burgNameInput").value = elSelected.text();
|
const at = id ? "center" : d3.event.target.tagName === "text" ? "top" : "bottom";
|
||||||
const my = elSelected.attr("id") == d3.event.target.id ? "center bottom" : "center top+10";
|
const of = id ? "svg" : d3.event.target;
|
||||||
const at = elSelected.attr("id") == d3.event.target.id ? "top" : "bottom";
|
|
||||||
|
|
||||||
document.getElementById("burgEditAnchorStyle").style.display = +pack.burgs[id].port ? "inline-block" : "none";
|
|
||||||
|
|
||||||
$("#burgEditor").dialog({
|
$("#burgEditor").dialog({
|
||||||
title: "Edit Burg: " + elSelected.text(), resizable: false,
|
title: "Edit Burg", resizable: false, close: closeBurgEditor,
|
||||||
position: {my, at, of: d3.event.target, collision: "fit"},
|
position: {my, at, of, collision: "fit"}
|
||||||
close: closeBurgEditor
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (modules.editBurg) return;
|
if (modules.editBurg) return;
|
||||||
|
|
@ -33,11 +30,11 @@ function editBurg() {
|
||||||
document.getElementById("burgAddGroup").addEventListener("click", toggleNewGroupInput);
|
document.getElementById("burgAddGroup").addEventListener("click", toggleNewGroupInput);
|
||||||
document.getElementById("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
|
document.getElementById("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
|
||||||
|
|
||||||
document.getElementById("burgNameShow").addEventListener("click", showNameSection);
|
document.getElementById("burgName").addEventListener("input", changeName);
|
||||||
document.getElementById("burgNameHide").addEventListener("click", hideNameSection);
|
|
||||||
document.getElementById("burgNameInput").addEventListener("input", changeName);
|
|
||||||
document.getElementById("burgNameReCulture").addEventListener("click", generateNameCulture);
|
document.getElementById("burgNameReCulture").addEventListener("click", generateNameCulture);
|
||||||
document.getElementById("burgNameReRandom").addEventListener("click", generateNameRandom);
|
document.getElementById("burgNameReRandom").addEventListener("click", generateNameRandom);
|
||||||
|
document.getElementById("burgPopulation").addEventListener("change", changePopulation);
|
||||||
|
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature));
|
||||||
|
|
||||||
document.getElementById("burgStyleShow").addEventListener("click", showStyleSection);
|
document.getElementById("burgStyleShow").addEventListener("click", showStyleSection);
|
||||||
document.getElementById("burgStyleHide").addEventListener("click", hideStyleSection);
|
document.getElementById("burgStyleHide").addEventListener("click", hideStyleSection);
|
||||||
|
|
@ -51,6 +48,39 @@ function editBurg() {
|
||||||
document.getElementById("burglLegend").addEventListener("click", editBurgLegend);
|
document.getElementById("burglLegend").addEventListener("click", editBurgLegend);
|
||||||
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg);
|
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg);
|
||||||
|
|
||||||
|
function updateBurgValues() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const b = pack.burgs[id];
|
||||||
|
document.getElementById("burgName").value = b.name;
|
||||||
|
document.getElementById("burgPopulation").value = rn(b.population * populationRate.value * urbanization.value);
|
||||||
|
document.getElementById("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
|
||||||
|
|
||||||
|
// toggle features
|
||||||
|
if (b.capital) document.getElementById("burgCapital").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgCapital").classList.add("inactive");
|
||||||
|
if (b.port) document.getElementById("burgPort").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgPort").classList.add("inactive");
|
||||||
|
if (b.citadel) document.getElementById("burgCitadel").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgCitadel").classList.add("inactive");
|
||||||
|
if (b.walls) document.getElementById("burgWalls").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgWalls").classList.add("inactive");
|
||||||
|
if (b.plaza) document.getElementById("burgPlaza").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgPlaza").classList.add("inactive");
|
||||||
|
if (b.temple) document.getElementById("burgTemple").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgTemple").classList.add("inactive");
|
||||||
|
if (b.shanty) document.getElementById("burgShanty").classList.remove("inactive");
|
||||||
|
else document.getElementById("burgShanty").classList.add("inactive");
|
||||||
|
|
||||||
|
// select group
|
||||||
|
const group = elSelected.node().parentNode.id;
|
||||||
|
const select = document.getElementById("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));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function dragBurgLabel() {
|
function dragBurgLabel() {
|
||||||
const tr = parseTransform(this.getAttribute("transform"));
|
const tr = parseTransform(this.getAttribute("transform"));
|
||||||
const dx = +tr[0] - d3.event.x, dy = +tr[1] - d3.event.y;
|
const dx = +tr[0] - d3.event.x, dy = +tr[1] - d3.event.y;
|
||||||
|
|
@ -62,23 +92,13 @@ function editBurg() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectBurgGroup(node) {
|
|
||||||
const group = node.parentNode.id;
|
|
||||||
const select = document.getElementById("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));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function showGroupSection() {
|
function showGroupSection() {
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "none");
|
document.querySelectorAll("#burgBottom > button").forEach(el => el.style.display = "none");
|
||||||
document.getElementById("burgGroupSection").style.display = "inline-block";
|
document.getElementById("burgGroupSection").style.display = "inline-block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideGroupSection() {
|
function hideGroupSection() {
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "inline-block");
|
document.querySelectorAll("#burgBottom > button").forEach(el => el.style.display = "inline-block");
|
||||||
document.getElementById("burgGroupSection").style.display = "none";
|
document.getElementById("burgGroupSection").style.display = "none";
|
||||||
document.getElementById("burgInputGroup").style.display = "none";
|
document.getElementById("burgInputGroup").style.display = "none";
|
||||||
document.getElementById("burgInputGroup").value = "";
|
document.getElementById("burgInputGroup").value = "";
|
||||||
|
|
@ -194,42 +214,52 @@ function editBurg() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showNameSection() {
|
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "none");
|
|
||||||
document.getElementById("burgNameSection").style.display = "inline-block";
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideNameSection() {
|
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "inline-block");
|
|
||||||
document.getElementById("burgNameSection").style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeName() {
|
function changeName() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
pack.burgs[id].name = burgNameInput.value;
|
pack.burgs[id].name = burgName.value;
|
||||||
elSelected.text(burgNameInput.value);
|
elSelected.text(burgName.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateNameCulture() {
|
function generateNameCulture() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const culture = pack.burgs[id].culture;
|
const culture = pack.burgs[id].culture;
|
||||||
burgNameInput.value = Names.getCulture(culture);
|
burgName.value = Names.getCulture(culture);
|
||||||
changeName();
|
changeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateNameRandom() {
|
function generateNameRandom() {
|
||||||
const base = rand(nameBase.length-1);
|
const base = rand(nameBase.length-1);
|
||||||
burgNameInput.value = Names.getBase(base);
|
burgName.value = Names.getBase(base);
|
||||||
changeName();
|
changeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changePopulation() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
pack.burgs[id].population = burgPopulation.value / populationRate.value / urbanization.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFeature() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const b = 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 b[feature] = +turnOn;
|
||||||
|
if (b[feature]) this.classList.remove("inactive");
|
||||||
|
else if (!b[feature]) this.classList.add("inactive");
|
||||||
|
|
||||||
|
if (b.port) document.getElementById("burgEditAnchorStyle").style.display = "inline-block";
|
||||||
|
else document.getElementById("burgEditAnchorStyle").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
function showStyleSection() {
|
function showStyleSection() {
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "none");
|
document.querySelectorAll("#burgBottom > button").forEach(el => el.style.display = "none");
|
||||||
document.getElementById("burgStyleSection").style.display = "inline-block";
|
document.getElementById("burgStyleSection").style.display = "inline-block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideStyleSection() {
|
function hideStyleSection() {
|
||||||
document.querySelectorAll("#burgEditor > button").forEach(el => el.style.display = "inline-block");
|
document.querySelectorAll("#burgBottom > button").forEach(el => el.style.display = "inline-block");
|
||||||
document.getElementById("burgStyleSection").style.display = "none";
|
document.getElementById("burgStyleSection").style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,33 +278,53 @@ function editBurg() {
|
||||||
editStyle("anchors", g);
|
editStyle("anchors", g);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openInMFCG() {
|
function openInMFCG(event) {
|
||||||
const id = elSelected.attr("data-id");
|
const id = elSelected.attr("data-id");
|
||||||
const name = elSelected.text();
|
const burg = pack.burgs[id];
|
||||||
const cell = pack.burgs[id].cell;
|
const defSeed = seed + id.padStart(4, 0);
|
||||||
const pop = rn(pack.burgs[id].population);
|
|
||||||
const size = Math.max(Math.min(pop, 65), 6);
|
|
||||||
|
|
||||||
// MFCG seed is FMG map seed + burg id padded to 4 chars with zeros
|
if (event.ctrlKey) {
|
||||||
const s = seed + id.padStart(4, 0);
|
const newSeed = prompt(`Please provide a Medieval Fantasy City Generator seed. `+
|
||||||
|
`Seed should be a number. Default seed is FMG map seed + burg id padded to 4 chars with zeros (${defSeed}). `+
|
||||||
|
`Please note that if seed is custom, "Overworld" button from MFCG will open a different map`, burg.MFCG || defSeed);
|
||||||
|
if (newSeed && newSeed != defSeed) burg.MFCG = newSeed; else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = elSelected.text();
|
||||||
|
const size = Math.max(Math.min(rn(burg.population), 65), 6);
|
||||||
|
|
||||||
|
const s = burg.MFCG || defSeed;
|
||||||
|
const cell = burg.cell;
|
||||||
const hub = +pack.cells.road[cell] > 50;
|
const hub = +pack.cells.road[cell] > 50;
|
||||||
const river = pack.cells.r[cell] ? 1 : 0;
|
const river = pack.cells.r[cell] ? 1 : 0;
|
||||||
const coast = +pack.burgs[id].port;
|
|
||||||
|
|
||||||
const half = rn(pop) % 2;
|
const coast = +burg.port;
|
||||||
const most = (+id + rn(pop)) % 3 ? 1 : 0;
|
const citadel = +burg.citadel;
|
||||||
const walls = pop > 10 && half || pop > 20 && most || pop > 30 ? 1 : 0;;
|
const walls = +burg.walls;
|
||||||
const shanty = pop > 40 && half || pop > 60 && most || pop > 80 ? 1 : 0;
|
const plaza = +burg.plaza;
|
||||||
const temple = pop > 50 && half || pop > 80 && most || pop > 100 ? 1 : 0;
|
const temple = +burg.temple;
|
||||||
|
const shanty = +burg.shanty;
|
||||||
|
|
||||||
const url = `http://fantasycities.watabou.ru/?name=${name}&size=${size}&seed=${s}&hub=${hub}&random=0&continuous=0&river=${river}&coast=${coast}&citadel=${half}&plaza=${half}&temple=${temple}&walls=${walls}&shantytown=${shanty}`;
|
const url = `http://fantasycities.watabou.ru/?
|
||||||
window.open(url, '_blank');
|
name=${name}&size=${size}&seed=${s}&hub=${hub}&random=0&continuous=0
|
||||||
|
&river=${river}&coast=${coast}
|
||||||
|
&citadel=${citadel}&plaza=${plaza}&temple=${temple}&walls=${walls}&shantytown=${shanty}`;
|
||||||
|
openURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openInIAHG() {
|
function openInIAHG() {
|
||||||
const id = elSelected.attr("data-id");
|
const id = elSelected.attr("data-id");
|
||||||
const url = `https://ironarachne.com/heraldry/${seed}-b${id}`;
|
const burg = pack.burgs[id];
|
||||||
window.open(url, '_blank');
|
const defSeed = `${seed}-b${id}`;
|
||||||
|
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
const newSeed = prompt(`Please provide an Iron Arachne Heraldry Generator seed. `+
|
||||||
|
`Default seed is a combination of FMG map seed and burg id (${defSeed})`, burg.IAHG || defSeed);
|
||||||
|
if (newSeed && newSeed != defSeed) burg.IAHG = newSeed; else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s = burg.IAHG || defSeed;
|
||||||
|
openURL("https://ironarachne.com/heraldry/" + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleRelocateBurg() {
|
function toggleRelocateBurg() {
|
||||||
|
|
@ -348,11 +398,9 @@ function editBurg() {
|
||||||
|
|
||||||
function removeSelectedBurg() {
|
function removeSelectedBurg() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const capital = pack.burgs[id].capital;
|
if (pack.burgs[id].capital) {
|
||||||
|
alertMessage.innerHTML = `You cannot remove the burg as it is a state capital.<br><br>
|
||||||
if (capital) {
|
You can change the capital using Burgs Editor (shift + T)`;
|
||||||
alertMessage.innerHTML = `You cannot remove the burg as it is a capital.<br><br>
|
|
||||||
You can change the capital using the Burgs Editor`;
|
|
||||||
$("#alert").dialog({resizable: false, title: "Remove burg",
|
$("#alert").dialog({resizable: false, title: "Remove burg",
|
||||||
buttons: {Ok: function() {$(this).dialog("close");}}
|
buttons: {Ok: function() {$(this).dialog("close");}}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ function editBurgs() {
|
||||||
modules.editBurgs = true;
|
modules.editBurgs = true;
|
||||||
|
|
||||||
$("#burgsEditor").dialog({
|
$("#burgsEditor").dialog({
|
||||||
title: "Burgs Editor", resizable: false, width: fitContent(), close: exitAddBurgMode,
|
title: "Burgs Overview", resizable: false, width: fitContent(), close: exitAddBurgMode,
|
||||||
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
|
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -78,13 +78,14 @@ function editBurgs() {
|
||||||
<input data-tip="Burg name. Click and type to change" class="burgName" value="${b.name}" autocorrect="off" spellcheck="false">
|
<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 province" class="burgState" value="${province}" disabled>
|
||||||
<input data-tip="Burg state" class="burgState" value="${state}" disabled>
|
<input data-tip="Burg state" class="burgState" value="${state}" disabled>
|
||||||
<select data-tip="Dominant culture. Click to change" class="stateCulture">${getCultureOptions(b.culture)}</select>
|
<select data-tip="Dominant culture. Click to change burg culture (to change cell cultrure use Cultures Editor)" class="stateCulture">${getCultureOptions(b.culture)}</select>
|
||||||
<span data-tip="Burg population" class="icon-male"></span>
|
<span data-tip="Burg population" class="icon-male"></span>
|
||||||
<input data-tip="Burg population. Type to change" class="burgPopulation" value=${si(population)}>
|
<input data-tip="Burg population. Type to change" class="burgPopulation" value=${si(population)}>
|
||||||
<div class="burgType">
|
<div class="burgType">
|
||||||
<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'}"></span>
|
<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'}"></span>
|
||||||
<span data-tip="Click to toggle port status" class="icon-anchor pointer${b.port ? '' : ' inactive'}" style="font-size:.9em"></span>
|
<span data-tip="Click to toggle port status" class="icon-anchor pointer${b.port ? '' : ' inactive'}" style="font-size:.9em"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<span data-tip="Edit burg" class="icon-pencil"></span>
|
||||||
<span data-tip="Remove burg" class="icon-trash-empty"></span>
|
<span data-tip="Remove burg" class="icon-trash-empty"></span>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
@ -103,6 +104,7 @@ function editBurgs() {
|
||||||
body.querySelectorAll("div > input.burgPopulation").forEach(el => el.addEventListener("change", changeBurgPopulation));
|
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-star-empty").forEach(el => el.addEventListener("click", toggleCapitalStatus));
|
||||||
body.querySelectorAll("div > span.icon-anchor").forEach(el => el.addEventListener("click", togglePortStatus));
|
body.querySelectorAll("div > span.icon-anchor").forEach(el => el.addEventListener("click", togglePortStatus));
|
||||||
|
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));
|
body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", triggerBurgRemove));
|
||||||
|
|
||||||
applySorting(burgsHeader);
|
applySorting(burgsHeader);
|
||||||
|
|
@ -164,51 +166,38 @@ function editBurgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleCapitalStatus() {
|
function toggleCapitalStatus() {
|
||||||
const burg = +this.parentNode.parentNode.dataset.id, state = pack.burgs[burg].state;
|
const burg = +this.parentNode.parentNode.dataset.id;
|
||||||
if (pack.burgs[burg].capital) {tip("To change capital please assign a capital status to another burg", false, "error"); return;}
|
toggleCapital(burg);
|
||||||
if (!state) {tip("Neutral lands do not have a capital", false, "error"); return;}
|
|
||||||
const old = pack.states[state].capital;
|
|
||||||
|
|
||||||
// change statuses
|
|
||||||
pack.states[state].capital = burg;
|
|
||||||
pack.states[state].center = pack.burgs[burg].cell;
|
|
||||||
pack.burgs[burg].capital = true;
|
|
||||||
pack.burgs[old].capital = false;
|
|
||||||
moveBurgToGroup(burg, "cities");
|
|
||||||
moveBurgToGroup(old, "towns");
|
|
||||||
|
|
||||||
burgsEditorAddLines();
|
burgsEditorAddLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
function togglePortStatus() {
|
function togglePortStatus() {
|
||||||
const burg = +this.parentNode.parentNode.dataset.id;
|
const burg = +this.parentNode.parentNode.dataset.id;
|
||||||
const anchor = document.querySelector("#anchors [data-id='" + burg + "']");
|
togglePort(burg);
|
||||||
if (anchor) anchor.remove();
|
if (this.classList.contains("inactive")) this.classList.remove("inactive");
|
||||||
|
else this.classList.add("inactive");
|
||||||
|
}
|
||||||
|
|
||||||
if (!pack.burgs[burg].port) {
|
function openBurgEditor() {
|
||||||
const haven = pack.cells.haven[pack.burgs[burg].cell];
|
const burg = +this.parentNode.dataset.id;
|
||||||
const port = haven ? pack.cells.f[haven] : -1;
|
editBurg(burg);
|
||||||
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
|
|
||||||
pack.burgs[burg].port = port;
|
|
||||||
|
|
||||||
const g = pack.burgs[burg].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(pack.burgs[burg].x - size * .47, 2)).attr("y", rn(pack.burgs[burg].y - size * .47, 2))
|
|
||||||
.attr("width", size).attr("height", size);
|
|
||||||
} else {
|
|
||||||
pack.burgs[burg].port = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
burgsEditorAddLines();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerBurgRemove() {
|
function triggerBurgRemove() {
|
||||||
const burg = +this.parentNode.dataset.id;
|
const burg = +this.parentNode.dataset.id;
|
||||||
if (pack.burgs[burg].capital) {tip("You cannot remove the capital. Please change the capital first", false, "error"); return;}
|
if (pack.burgs[burg].capital) {tip("You cannot remove the capital. Please change the capital first", false, "error"); return;}
|
||||||
removeBurg(burg);
|
|
||||||
burgsEditorAddLines();
|
alertMessage.innerHTML = "Are you sure you want to remove the burg?";
|
||||||
|
$("#alert").dialog({resizable: false, title: "Remove burg",
|
||||||
|
buttons: {
|
||||||
|
Remove: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
removeBurg(burg);
|
||||||
|
burgsEditorAddLines();
|
||||||
|
},
|
||||||
|
Cancel: function() {$(this).dialog("close");}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateNames() {
|
function regenerateNames() {
|
||||||
|
|
@ -226,7 +215,7 @@ function editBurgs() {
|
||||||
if (this.classList.contains("pressed")) {exitAddBurgMode(); return;};
|
if (this.classList.contains("pressed")) {exitAddBurgMode(); return;};
|
||||||
customization = 3;
|
customization = 3;
|
||||||
this.classList.add("pressed");
|
this.classList.add("pressed");
|
||||||
tip("Click on the map to create a new burg. Hold Shift to add multiple", true);
|
tip("Click on the map to create a new burg. Hold Shift to add multiple", true, "warn");
|
||||||
viewbox.style("cursor", "crosshair").on("click", addBurgOnClick);
|
viewbox.style("cursor", "crosshair").on("click", addBurgOnClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ function editDiplomacy() {
|
||||||
const tip = s.fullName + description[index] + selName;
|
const tip = s.fullName + description[index] + selName;
|
||||||
|
|
||||||
lines += `<div class="states" data-id=${s.i} data-name="${s.fullName}" data-relations="${relation}">
|
lines += `<div class="states" data-id=${s.i} data-name="${s.fullName}" data-relations="${relation}">
|
||||||
<div data-tip="${tip}. Click to see relations to ${s.name}" class="stateName">${s.fullName}</div>
|
<div data-tip="${tip}. Click to see relations to ${s.name}" style="width:12em">${s.fullName}</div>
|
||||||
<input data-tip="${tip}. Click to see relations to ${s.name}" class="stateColor" type="color" value="${color}" disabled>
|
<input data-tip="${tip}. Click to see relations to ${s.name}" class="stateColor" type="color" value="${color}" disabled>
|
||||||
<select data-tip="Click to change ${getAdjective(s.name)} relations to ${selName}" class="diplomacyRelations">${getRelations(relation)}</select>
|
<select data-tip="Click to change ${getAdjective(s.name)} relations to ${selName}" class="diplomacyRelations">${getRelations(relation)}</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,8 @@ function addBurg(point) {
|
||||||
const feature = cells.f[cell];
|
const feature = cells.f[cell];
|
||||||
|
|
||||||
const population = Math.max((cells.s[cell] + cells.road[cell]) / 3 + i / 1000 + cell % 100 / 1000, .1);
|
const population = Math.max((cells.s[cell] + cells.road[cell]) / 3 + i / 1000 + cell % 100 / 1000, .1);
|
||||||
pack.burgs.push({name, cell, x, y, state, i, culture, feature, capital: false, port: 0, population});
|
|
||||||
|
pack.burgs.push({name, cell, x, y, state, i, culture, feature, capital: 0, port: 0, population});
|
||||||
cells.burg[cell] = i;
|
cells.burg[cell] = i;
|
||||||
|
|
||||||
const townSize = burgIcons.select("#towns").attr("size") || 0.5;
|
const townSize = burgIcons.select("#towns").attr("size") || 0.5;
|
||||||
|
|
@ -135,6 +136,7 @@ function addBurg(point) {
|
||||||
burgLabels.select("#towns").append("text").attr("id", "burgLabel"+i).attr("data-id", i)
|
burgLabels.select("#towns").append("text").attr("id", "burgLabel"+i).attr("data-id", i)
|
||||||
.attr("x", x).attr("y", y).attr("dy", `${townSize * -1.5}px`).text(name);
|
.attr("x", x).attr("y", y).attr("dy", `${townSize * -1.5}px`).text(name);
|
||||||
|
|
||||||
|
BurgsAndStates.defineFeatures(pack.burgs[i]);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,6 +175,40 @@ function removeBurg(id) {
|
||||||
pack.cells.burg[cell] = 0;
|
pack.cells.burg[cell] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleCapital(burg) {
|
||||||
|
const state = pack.burgs[burg].state;
|
||||||
|
if (!state) {tip("Neutral lands cannot have a capital", false, "error"); return;}
|
||||||
|
if (pack.burgs[burg].capital) {tip("To change capital please assign a capital status to another burg of this state", false, "error"); return;}
|
||||||
|
const old = pack.states[state].capital;
|
||||||
|
|
||||||
|
// change statuses
|
||||||
|
pack.states[state].capital = burg;
|
||||||
|
pack.states[state].center = pack.burgs[burg].cell;
|
||||||
|
pack.burgs[burg].capital = 1;
|
||||||
|
pack.burgs[old].capital = 0;
|
||||||
|
moveBurgToGroup(burg, "cities");
|
||||||
|
moveBurgToGroup(old, "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 * .47, 2)).attr("y", rn(b.y - size * .47, 2))
|
||||||
|
.attr("width", size).attr("height", size);
|
||||||
|
}
|
||||||
|
|
||||||
// draw legend box
|
// draw legend box
|
||||||
function drawLegend(name, data) {
|
function drawLegend(name, data) {
|
||||||
legend.selectAll("*").remove(); // fully redraw every time
|
legend.selectAll("*").remove(); // fully redraw every time
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ function editHeightmap() {
|
||||||
} else if (type === "risk") {
|
} else if (type === "risk") {
|
||||||
terrs.attr("mask", null);
|
terrs.attr("mask", null);
|
||||||
defs.selectAll("#land, #water").selectAll("path").remove();
|
defs.selectAll("#land, #water").selectAll("path").remove();
|
||||||
viewbox.selectAll("#coastline *, #lakes *, #oceanLayers path").remove();
|
viewbox.selectAll("#coastline path, #lakes path, #oceanLayers path").remove();
|
||||||
changeOnlyLand.checked = false;
|
changeOnlyLand.checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,6 +239,16 @@ function getHeight(h) {
|
||||||
c.y = p[1];
|
c.y = p[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// recalculate zones to grid
|
||||||
|
zones.selectAll("g").each(function() {
|
||||||
|
const zone = d3.select(this);
|
||||||
|
const dataCells = zone.attr("data-cells");
|
||||||
|
const cells = dataCells ? dataCells.split(",").map(i => +i) : [];
|
||||||
|
const g = cells.map(i => pack.cells.g[i]);
|
||||||
|
zone.attr("data-cells", g);
|
||||||
|
zone.selectAll("*").remove();
|
||||||
|
});
|
||||||
|
|
||||||
markFeatures();
|
markFeatures();
|
||||||
OceanLayers();
|
OceanLayers();
|
||||||
calculateTemperatures();
|
calculateTemperatures();
|
||||||
|
|
@ -324,6 +334,20 @@ function getHeight(h) {
|
||||||
drawStates();
|
drawStates();
|
||||||
drawBorders();
|
drawBorders();
|
||||||
|
|
||||||
|
// restore zones from grid
|
||||||
|
zones.selectAll("g").each(function() {
|
||||||
|
const zone = d3.select(this);
|
||||||
|
const g = zone.attr("data-cells");
|
||||||
|
const gCells = g ? g.split(",").map(i => +i) : [];
|
||||||
|
const cells = pack.cells.i.filter(i => gCells.includes(pack.cells.g[i]));
|
||||||
|
|
||||||
|
zone.attr("data-cells", cells);
|
||||||
|
zone.selectAll("*").remove();
|
||||||
|
const base = zone.attr("id") + "_"; // id generic part
|
||||||
|
zone.selectAll("*").data(cells).enter().append("polygon")
|
||||||
|
.attr("points", d => getPackPolygon(d)).attr("id", d => base + d);
|
||||||
|
});
|
||||||
|
|
||||||
console.timeEnd("restoreRiskedData");
|
console.timeEnd("restoreRiskedData");
|
||||||
console.groupEnd("Edit Heightmap");
|
console.groupEnd("Edit Heightmap");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,20 +36,17 @@ function editProvinces() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const el = ev.target, cl = el.classList, line = el.parentNode, p = +line.dataset.id;
|
const el = ev.target, cl = el.classList, line = el.parentNode, p = +line.dataset.id;
|
||||||
if (cl.contains("zoneFill")) changeFill(el); else
|
if (cl.contains("zoneFill")) changeFill(el); else
|
||||||
if (cl.contains("icon-fleur")) provinceOpenCOA(p); else
|
if (cl.contains("name")) editProvinceName(p); else
|
||||||
|
if (cl.contains("icon-fleur")) provinceOpenCOA(ev, p); else
|
||||||
if (cl.contains("icon-star-empty")) capitalZoomIn(p); else
|
if (cl.contains("icon-star-empty")) capitalZoomIn(p); else
|
||||||
if (cl.contains("icon-flag-empty")) declareProvinceIndependence(p); else
|
if (cl.contains("icon-flag-empty")) declareProvinceIndependence(p); else
|
||||||
if (cl.contains("culturePopulation")) changePopulation(p); else
|
if (cl.contains("culturePopulation")) changePopulation(p); else
|
||||||
if (cl.contains("icon-pin")) focusOn(p, cl); else
|
if (cl.contains("icon-pin")) focusOn(p, cl); else
|
||||||
if (cl.contains("icon-trash-empty")) removeProvince(p);
|
if (cl.contains("icon-trash-empty")) removeProvince(p);
|
||||||
if (cl.contains("hoverButton") && cl.contains("stateName")) regenerateName(p, line); else
|
|
||||||
if (cl.contains("hoverButton") && cl.contains("stateForm")) regenerateForm(p, line);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
body.addEventListener("input", function(ev) {
|
body.addEventListener("input", function(ev) {
|
||||||
const el = ev.target, cl = el.classList, line = el.parentNode, p = +line.dataset.id;
|
const el = ev.target, cl = el.classList, line = el.parentNode, p = +line.dataset.id;
|
||||||
if (cl.contains("stateName")) changeName(p, line, el.value); else
|
|
||||||
if (cl.contains("stateForm")) changeForm(p, line, el.value); else
|
|
||||||
if (cl.contains("cultureBase")) changeCapital(p, line, el.value);
|
if (cl.contains("cultureBase")) changeCapital(p, line, el.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -62,7 +59,7 @@ function editProvinces() {
|
||||||
function collectStatistics() {
|
function collectStatistics() {
|
||||||
const cells = pack.cells, provinces = pack.provinces;
|
const cells = pack.cells, provinces = pack.provinces;
|
||||||
provinces.forEach(p => {
|
provinces.forEach(p => {
|
||||||
if (!p.i) return;
|
if (!p.i || p.removed) return;
|
||||||
p.area = p.rural = p.urban = 0;
|
p.area = p.rural = p.urban = 0;
|
||||||
p.burgs = [];
|
p.burgs = [];
|
||||||
});
|
});
|
||||||
|
|
@ -77,6 +74,11 @@ function editProvinces() {
|
||||||
provinces[p].urban += pack.burgs[cells.burg[i]].population;
|
provinces[p].urban += pack.burgs[cells.burg[i]].population;
|
||||||
provinces[p].burgs.push(cells.burg[i]);
|
provinces[p].burgs.push(cells.burg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provinces.forEach(p => {
|
||||||
|
if (!p.i || p.removed) return;
|
||||||
|
if (!p.burg && p.burgs.length) p.burg = p.burgs[0];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFilter() {
|
function updateFilter() {
|
||||||
|
|
@ -112,11 +114,9 @@ function editProvinces() {
|
||||||
const focused = defs.select("#fog #focusProvince"+p.i).size();
|
const focused = defs.select("#fog #focusProvince"+p.i).size();
|
||||||
lines += `<div class="states" data-id=${p.i} data-name=${p.name} data-form=${p.formName} data-color="${p.color}" data-capital="${capital}" data-state="${stateName}" data-area=${area} data-population=${population}>
|
lines += `<div class="states" data-id=${p.i} data-name=${p.name} data-form=${p.formName} data-color="${p.color}" data-capital="${capital}" data-state="${stateName}" data-area=${area} data-population=${population}>
|
||||||
<svg data-tip="Province fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${p.color}" class="zoneFill"></svg>
|
<svg data-tip="Province fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${p.color}" class="zoneFill"></svg>
|
||||||
<input data-tip="Province name. Click and type to change" class="stateName" value="${p.name}" autocorrect="off" spellcheck="false">
|
<input data-tip="Province name. Click and type to change" class="name pointer" value="${p.name}" readonly>
|
||||||
<span data-tip="Click to re-generate province name" class="icon-arrows-cw stateName hoverButton placeholder"></span>
|
<span data-tip="Click to open province COA in the Iron Arachne Heraldry Generator. Ctrl + click to change the seed" class="icon-fleur pointer hide"></span>
|
||||||
<span data-tip="Click to open province COA in the Iron Arachne Heraldry Generator" class="icon-fleur pointer hide"></span>
|
<input data-tip="Province form name. Click and type to change" class="name pointer hide" value="${p.formName}" readonly>
|
||||||
<input data-tip="Province form name. Click and type to change" class="stateForm hide" value="${p.formName}" autocorrect="off" spellcheck="false">
|
|
||||||
<span data-tip="Click to re-generate form name" class="icon-arrows-cw stateForm hoverButton placeholder"></span>
|
|
||||||
<span data-tip="Province capital. Click to zoom into view" class="icon-star-empty pointer hide ${p.burg?'':'placeholder'}"></span>
|
<span data-tip="Province capital. Click to zoom into view" class="icon-star-empty pointer hide ${p.burg?'':'placeholder'}"></span>
|
||||||
<select data-tip="Province capital. Click to select from burgs within the state. No capital means the province is governed from the state capital" class="cultureBase hide ${p.burgs.length?'':'placeholder'}">${p.burgs.length ? getCapitalOptions(p.burgs, p.burg) : ''}</select>
|
<select data-tip="Province capital. Click to select from burgs within the state. No capital means the province is governed from the state capital" class="cultureBase hide ${p.burgs.length?'':'placeholder'}">${p.burgs.length ? getCapitalOptions(p.burgs, p.burg) : ''}</select>
|
||||||
<input data-tip="Province owner" class="provinceOwner" value="${stateName}" disabled">
|
<input data-tip="Province owner" class="provinceOwner" value="${stateName}" disabled">
|
||||||
|
|
@ -156,8 +156,6 @@ function editProvinces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function provinceHighlightOn(event) {
|
function provinceHighlightOn(event) {
|
||||||
if (!customization) event.target.querySelectorAll(".hoverButton").forEach(el => el.classList.remove("placeholder"));
|
|
||||||
|
|
||||||
const province = +event.target.dataset.id;
|
const province = +event.target.dataset.id;
|
||||||
const el = body.querySelector(`div[data-id='${province}']`);
|
const el = body.querySelector(`div[data-id='${province}']`);
|
||||||
if (el) el.classList.add("active");
|
if (el) el.classList.add("active");
|
||||||
|
|
@ -169,8 +167,6 @@ function editProvinces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function provinceHighlightOff(event) {
|
function provinceHighlightOff(event) {
|
||||||
if (!customization) event.target.querySelectorAll(".hoverButton").forEach(el => el.classList.add("placeholder"));
|
|
||||||
|
|
||||||
const province = +event.target.dataset.id;
|
const province = +event.target.dataset.id;
|
||||||
const el = body.querySelector(`div[data-id='${province}']`);
|
const el = body.querySelector(`div[data-id='${province}']`);
|
||||||
if (el) el.classList.remove("active");
|
if (el) el.classList.remove("active");
|
||||||
|
|
@ -194,9 +190,17 @@ function editProvinces() {
|
||||||
openPicker(currentFill, callback);
|
openPicker(currentFill, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function provinceOpenCOA(p) {
|
function provinceOpenCOA(event, p) {
|
||||||
const url = `https://ironarachne.com/heraldry/${seed}-p${p}`;
|
const defSeed = `${seed}-p${p}`;
|
||||||
window.open(url, '_blank');
|
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
const newSeed = prompt(`Please provide an Iron Arachne Heraldry Generator seed. `+
|
||||||
|
`Default seed is a combination of FMG map seed and province id (${defSeed})`, pack.provinces[p].IAHG || defSeed);
|
||||||
|
if (newSeed && newSeed != defSeed) pack.provinces[p].IAHG = newSeed; else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s = pack.provinces[p].IAHG || defSeed;
|
||||||
|
openURL("https://ironarachne.com/heraldry/" + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function capitalZoomIn(p) {
|
function capitalZoomIn(p) {
|
||||||
|
|
@ -211,16 +215,18 @@ function editProvinces() {
|
||||||
const oldState = pack.provinces[p].state;
|
const oldState = pack.provinces[p].state;
|
||||||
const newState = pack.states.length;
|
const newState = pack.states.length;
|
||||||
|
|
||||||
// turn burg into a capital
|
// turn province burg into a capital
|
||||||
const burg = provinces[p].burg;
|
const burg = provinces[p].burg;
|
||||||
if (!burg) return;
|
if (!burg) return;
|
||||||
pack.burgs[burg].capital = true;
|
pack.burgs[burg].capital = 1;
|
||||||
pack.burgs[burg].state = newState;
|
|
||||||
moveBurgToGroup(burg, "cities");
|
moveBurgToGroup(burg, "cities");
|
||||||
|
|
||||||
|
// move all burgs to a new state
|
||||||
|
provinces[p].burgs.forEach(b => pack.burgs[b].state = newState);
|
||||||
|
|
||||||
// difine new state attributes
|
// difine new state attributes
|
||||||
const center = provinces[p].center;
|
const center = pack.burgs[burg].cell;
|
||||||
const culture = cells.culture[center];
|
const culture = pack.burgs[burg].culture;
|
||||||
const name = provinces[p].name;
|
const name = provinces[p].name;
|
||||||
const color = getRandomColor();
|
const color = getRandomColor();
|
||||||
|
|
||||||
|
|
@ -358,28 +364,69 @@ function editProvinces() {
|
||||||
refreshProvincesEditor();
|
refreshProvincesEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeName(p, line, value) {
|
function editProvinceName(province) {
|
||||||
pack.provinces[p].name = line.querySelector(".stateName").value = line.dataset.name = value;
|
const p = pack.provinces[province];
|
||||||
pack.provinces[p].fullName = value + " " + pack.provinces[p].formName;
|
document.getElementById("provinceNameEditor").dataset.province = province;
|
||||||
provs.select("#provinceLabel"+p).text(value);
|
document.getElementById("provinceNameEditorShort").value = p.name;
|
||||||
}
|
applyOption(provinceNameEditorSelectForm, p.formName)
|
||||||
|
document.getElementById("provinceNameEditorFull").value = p.fullName;
|
||||||
|
|
||||||
function regenerateName(p, line) {
|
$("#provinceNameEditor").dialog({
|
||||||
const c = pack.cells.culture[pack.provinces[p].center];
|
resizable: false, title: "Change province name", width: "22em", buttons: {
|
||||||
const name = Names.getState(Names.getCultureShort(c), c);
|
Apply: function() {applyNameChange(p); $(this).dialog("close");},
|
||||||
changeName(p, line, name);
|
Cancel: function() {$(this).dialog("close");}
|
||||||
}
|
}, position: {my: "center", at: "center", of: "svg"}
|
||||||
|
});
|
||||||
|
|
||||||
function changeForm(p, line, value) {
|
if (modules.editProvinceName) return;
|
||||||
pack.provinces[p].formName = line.querySelector(".stateForm").value = line.dataset.form = value;
|
modules.editProvinceName = true;
|
||||||
pack.provinces[p].fullName = pack.provinces[p].name + " " + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function regenerateForm(p, line) {
|
// add listeners
|
||||||
const forms = ["County", "Earldom", "Shire", "Landgrave", 'Margrave', "Barony", "Province",
|
document.getElementById("provinceNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture);
|
||||||
"Department", "Governorate", "State", "Canton", "Prefecture", "Parish", "Deanery",
|
document.getElementById("provinceNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
|
||||||
"Council", "District", "Republic", "Territory", "Land", "Region"];
|
document.getElementById("provinceNameEditorAddForm").addEventListener("click", addCustomForm);
|
||||||
changeForm(p, line, ra(forms));
|
document.getElementById("provinceNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
|
||||||
|
|
||||||
|
function regenerateShortNameCuture() {
|
||||||
|
const province = +provinceNameEditor.dataset.province;
|
||||||
|
const culture = pack.cells.culture[pack.provinces[province].center];
|
||||||
|
const name = Names.getState(Names.getCultureShort(culture), culture);
|
||||||
|
document.getElementById("provinceNameEditorShort").value = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function regenerateShortNameRandom() {
|
||||||
|
const base = rand(nameBase.length-1);
|
||||||
|
const name = Names.getState(Names.getBase(base), undefined, base);
|
||||||
|
document.getElementById("provinceNameEditorShort").value = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCustomForm() {
|
||||||
|
const value = provinceNameEditorCustomForm.value;
|
||||||
|
const displayed = provinceNameEditorCustomForm.style.display === "inline-block";
|
||||||
|
provinceNameEditorCustomForm.style.display = displayed ? "none" : "inline-block";
|
||||||
|
provinceNameEditorSelectForm.style.display = displayed ? "inline-block" : "none";
|
||||||
|
if (displayed && value) applyOption(provinceNameEditorSelectForm, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function regenerateFullName() {
|
||||||
|
const short = document.getElementById("provinceNameEditorShort").value;
|
||||||
|
const form = document.getElementById("provinceNameEditorSelectForm").value;
|
||||||
|
document.getElementById("provinceNameEditorFull").value = getFullName();
|
||||||
|
|
||||||
|
function getFullName() {
|
||||||
|
if (!form) return short;
|
||||||
|
if (!short && form) return "The " + form;
|
||||||
|
return short + " " + form;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyNameChange(p) {
|
||||||
|
p.name = document.getElementById("provinceNameEditorShort").value;
|
||||||
|
p.formName = document.getElementById("provinceNameEditorSelectForm").value;
|
||||||
|
p.fullName = document.getElementById("provinceNameEditorFull").value;
|
||||||
|
provs.select("#provinceLabel"+p.i).text(p.name);
|
||||||
|
refreshProvincesEditor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeCapital(p, line, value) {
|
function changeCapital(p, line, value) {
|
||||||
|
|
|
||||||
|
|
@ -41,19 +41,16 @@ function editStates() {
|
||||||
body.addEventListener("click", function(ev) {
|
body.addEventListener("click", function(ev) {
|
||||||
const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
|
const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
|
||||||
if (cl.contains("zoneFill")) stateChangeFill(el); else
|
if (cl.contains("zoneFill")) stateChangeFill(el); else
|
||||||
if (cl.contains("icon-fleur")) stateOpenCOA(state); else
|
if (cl.contains("name")) editStateName(state); else
|
||||||
|
if (cl.contains("icon-fleur")) stateOpenCOA(ev, state); else
|
||||||
if (cl.contains("icon-star-empty")) stateCapitalZoomIn(state); else
|
if (cl.contains("icon-star-empty")) stateCapitalZoomIn(state); else
|
||||||
if (cl.contains("culturePopulation")) changePopulation(state); else
|
if (cl.contains("culturePopulation")) changePopulation(state); else
|
||||||
if (cl.contains("icon-pin")) focusOnState(state, cl); else
|
if (cl.contains("icon-pin")) focusOnState(state, cl); else
|
||||||
if (cl.contains("icon-trash-empty")) stateRemove(state); else
|
if (cl.contains("icon-trash-empty")) stateRemove(state);
|
||||||
if (cl.contains("hoverButton") && cl.contains("stateName")) regenerateName(state, line); else
|
|
||||||
if (cl.contains("hoverButton") && cl.contains("stateForm")) regenerateForm(state, line);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
body.addEventListener("input", function(ev) {
|
body.addEventListener("input", function(ev) {
|
||||||
const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
|
const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
|
||||||
if (cl.contains("stateName")) stateChangeName(state, line, el.value); else
|
|
||||||
if (cl.contains("stateForm")) stateChangeForm(state, line, el.value); else
|
|
||||||
if (cl.contains("stateCapital")) stateChangeCapitalName(state, line, el.value); else
|
if (cl.contains("stateCapital")) stateChangeCapitalName(state, line, el.value); else
|
||||||
if (cl.contains("cultureType")) stateChangeType(state, line, el.value); else
|
if (cl.contains("cultureType")) stateChangeType(state, line, el.value); else
|
||||||
if (cl.contains("stateCulture")) stateChangeCulture(state, line, el.value); else
|
if (cl.contains("stateCulture")) stateChangeCulture(state, line, el.value); else
|
||||||
|
|
@ -88,7 +85,7 @@ function editStates() {
|
||||||
lines += `<div class="states" data-id=${s.i} data-name="${s.name}" data-cells=${s.cells} data-area=${area}
|
lines += `<div class="states" data-id=${s.i} data-name="${s.name}" data-cells=${s.cells} data-area=${area}
|
||||||
data-population=${population} data-burgs=${s.burgs} data-color="" data-form="" data-capital="" data-culture="" data-type="" data-expansionism="">
|
data-population=${population} data-burgs=${s.burgs} data-color="" data-form="" data-capital="" data-culture="" data-type="" data-expansionism="">
|
||||||
<svg width="9" height="9" class="placeholder"></svg>
|
<svg width="9" height="9" class="placeholder"></svg>
|
||||||
<input data-tip="State name. Click and type to change" class="stateName italic" value="${s.name}" autocorrect="off" spellcheck="false">
|
<input data-tip="Neutral lands name. Click to change" class="stateName name pointer italic" value="${s.name}" readonly>
|
||||||
<span class="icon-fleur placeholder hide"></span>
|
<span class="icon-fleur placeholder hide"></span>
|
||||||
<input class="stateForm placeholder" value="none">
|
<input class="stateForm placeholder" value="none">
|
||||||
<span class="icon-star-empty placeholder hide"></span>
|
<span class="icon-star-empty placeholder hide"></span>
|
||||||
|
|
@ -96,8 +93,8 @@ function editStates() {
|
||||||
<select class="stateCulture placeholder hide">${getCultureOptions(0)}</select>
|
<select class="stateCulture placeholder hide">${getCultureOptions(0)}</select>
|
||||||
<span data-tip="Burgs count" style="padding-right: 1px" class="icon-dot-circled hide"></span>
|
<span data-tip="Burgs count" style="padding-right: 1px" class="icon-dot-circled hide"></span>
|
||||||
<div data-tip="Burgs count" class="stateBurgs hide">${s.burgs}</div>
|
<div data-tip="Burgs count" class="stateBurgs hide">${s.burgs}</div>
|
||||||
<span data-tip="State area" style="padding-right: 4px" class="icon-map-o hide"></span>
|
<span data-tip="Neutral lands area" style="padding-right: 4px" class="icon-map-o hide"></span>
|
||||||
<div data-tip="State area" class="biomeArea hide">${si(area) + unit}</div>
|
<div data-tip="Neutral lands area" class="biomeArea hide">${si(area) + unit}</div>
|
||||||
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
||||||
<div data-tip="${populationTip}" class="culturePopulation hide">${si(population)}</div>
|
<div data-tip="${populationTip}" class="culturePopulation hide">${si(population)}</div>
|
||||||
<select class="cultureType ${hidden} placeholder show hide">${getTypeOptions(0)}</select>
|
<select class="cultureType ${hidden} placeholder show hide">${getTypeOptions(0)}</select>
|
||||||
|
|
@ -111,12 +108,10 @@ function editStates() {
|
||||||
const capital = pack.burgs[s.capital].name;
|
const capital = pack.burgs[s.capital].name;
|
||||||
lines += `<div class="states" data-id=${s.i} data-name="${s.name}" data-form="${s.formName}" data-capital="${capital}" data-color="${s.color}" data-cells=${s.cells}
|
lines += `<div class="states" data-id=${s.i} data-name="${s.name}" data-form="${s.formName}" data-capital="${capital}" data-color="${s.color}" data-cells=${s.cells}
|
||||||
data-area=${area} data-population=${population} data-burgs=${s.burgs} data-culture=${pack.cultures[s.culture].name} data-type=${s.type} data-expansionism=${s.expansionism}>
|
data-area=${area} data-population=${population} data-burgs=${s.burgs} data-culture=${pack.cultures[s.culture].name} data-type=${s.type} data-expansionism=${s.expansionism}>
|
||||||
<svg data-tip="State fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${s.color}" class="zoneFill"></svg>
|
<svg data-tip="State fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${s.color}" class="zoneFill"></svg>
|
||||||
<input data-tip="State name. Click and type to change" class="stateName" value="${s.name}" autocorrect="off" spellcheck="false">
|
<input data-tip="State name. Click to change" class="stateName name pointer" value="${s.name}" readonly>
|
||||||
<span data-tip="Click to re-generate name" class="icon-arrows-cw stateName hoverButton placeholder"></span>
|
<span data-tip="Click to open state COA in the Iron Arachne Heraldry Generator. Ctrl + click to change the seed" class="icon-fleur pointer hide"></span>
|
||||||
<span data-tip="Click to open state COA in the Iron Arachne Heraldry Generator" class="icon-fleur pointer hide"></span>
|
<input data-tip="State form name. Click to change" class="stateForm name pointer" value="${s.formName}" readonly>
|
||||||
<input data-tip="State form name. Click and type to change" class="stateForm" value="${s.formName}" autocorrect="off" spellcheck="false">
|
|
||||||
<span data-tip="Click to re-generate form name" class="icon-arrows-cw stateForm hoverButton placeholder"></span>
|
|
||||||
<span data-tip="State capital. Click to zoom into view" class="icon-star-empty pointer hide"></span>
|
<span data-tip="State capital. Click to zoom into view" class="icon-star-empty pointer hide"></span>
|
||||||
<input data-tip="Capital name. Click and type to rename" class="stateCapital hide" value="${capital}" autocorrect="off" spellcheck="false"/>
|
<input data-tip="Capital name. Click and type to rename" class="stateCapital hide" value="${capital}" autocorrect="off" spellcheck="false"/>
|
||||||
<select data-tip="Dominant culture. Click to change" class="stateCulture hide">${getCultureOptions(s.culture)}</select>
|
<select data-tip="Dominant culture. Click to change" class="stateCulture hide">${getCultureOptions(s.culture)}</select>
|
||||||
|
|
@ -171,7 +166,6 @@ function editStates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateHighlightOn(event) {
|
function stateHighlightOn(event) {
|
||||||
if (!customization) event.target.querySelectorAll(".hoverButton").forEach(el => el.classList.remove("placeholder"));
|
|
||||||
if (!layerIsOn("toggleStates")) return;
|
if (!layerIsOn("toggleStates")) return;
|
||||||
const state = +event.target.dataset.id;
|
const state = +event.target.dataset.id;
|
||||||
if (customization || !state) return;
|
if (customization || !state) return;
|
||||||
|
|
@ -197,7 +191,6 @@ function editStates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateHighlightOff() {
|
function stateHighlightOff() {
|
||||||
event.target.querySelectorAll(".hoverButton").forEach(el => el.classList.add("placeholder"));
|
|
||||||
debug.selectAll(".highlight").each(function(el) {
|
debug.selectAll(".highlight").each(function(el) {
|
||||||
d3.select(this).call(removePath);
|
d3.select(this).call(removePath);
|
||||||
});
|
});
|
||||||
|
|
@ -219,63 +212,71 @@ function editStates() {
|
||||||
openPicker(currentFill, callback);
|
openPicker(currentFill, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateChangeName(state, line, value) {
|
function editStateName(state) {
|
||||||
const oldName = pack.states[state].name;
|
const s = pack.states[state];
|
||||||
pack.states[state].name = line.dataset.name = value;
|
document.getElementById("stateNameEditor").dataset.state = state;
|
||||||
pack.states[state].fullName = BurgsAndStates.getFullName(pack.states[state]);
|
document.getElementById("stateNameEditorShort").value = s.name || "";
|
||||||
changeLabel(state, oldName, value);
|
applyOption(stateNameEditorSelectForm, s.formName);
|
||||||
}
|
document.getElementById("stateNameEditorFull").value = s.fullName || "";
|
||||||
|
|
||||||
function regenerateName(state, line) {
|
$("#stateNameEditor").dialog({
|
||||||
const culture = pack.states[state].culture;
|
resizable: false, title: "Change state name", width: "22em", buttons: {
|
||||||
const oldName = pack.states[state].name;
|
Apply: function() {applyNameChange(s); $(this).dialog("close");},
|
||||||
const newName = Names.getState(Names.getCultureShort(culture), culture);
|
Cancel: function() {$(this).dialog("close");}
|
||||||
pack.states[state].name = line.dataset.name = line.querySelector(".stateName").value = newName;
|
}, position: {my: "center", at: "center", of: "svg"}
|
||||||
pack.states[state].fullName = BurgsAndStates.getFullName(pack.states[state]);
|
});
|
||||||
changeLabel(state, oldName, newName);
|
|
||||||
}
|
|
||||||
|
|
||||||
function stateChangeForm(state, line, value) {
|
if (modules.editStateName) return;
|
||||||
const oldForm = pack.states[state].formName;
|
modules.editStateName = true;
|
||||||
pack.states[state].formName = line.dataset.form = value;
|
|
||||||
pack.states[state].fullName = BurgsAndStates.getFullName(pack.states[state]);
|
|
||||||
changeLabel(state, oldForm, value, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function regenerateForm(state, line) {
|
// add listeners
|
||||||
const oldForm = pack.states[state].formName;
|
document.getElementById("stateNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture);
|
||||||
let newForm = oldForm;
|
document.getElementById("stateNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
|
||||||
|
document.getElementById("stateNameEditorAddForm").addEventListener("click", addCustomForm);
|
||||||
|
document.getElementById("stateNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
|
||||||
|
|
||||||
for (let i=0; newForm === oldForm && i < 50; i++) {
|
function regenerateShortNameCuture() {
|
||||||
BurgsAndStates.defineStateForms([state]);
|
const state = +stateNameEditor.dataset.state;
|
||||||
newForm = pack.states[state].formName;
|
const culture = pack.states[state].culture;
|
||||||
|
const name = Names.getState(Names.getCultureShort(culture), culture);
|
||||||
|
document.getElementById("stateNameEditorShort").value = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
line.dataset.form = line.querySelector(".stateForm").value = newForm;
|
function regenerateShortNameRandom() {
|
||||||
changeLabel(state, oldForm, newForm, true);
|
const base = rand(nameBase.length-1);
|
||||||
}
|
const name = Names.getState(Names.getBase(base), undefined, base);
|
||||||
|
document.getElementById("stateNameEditorShort").value = name;
|
||||||
function changeLabel(state, oldName, newName, form) {
|
|
||||||
const label = document.getElementById("stateLabel"+state);
|
|
||||||
if (!label) return;
|
|
||||||
|
|
||||||
const tspan = Array.from(label.querySelectorAll('tspan'));
|
|
||||||
const tspanAdj = !form && oldName && newName && pack.states[state].formName ? tspan.find(el => el.textContent.includes(getAdjective(oldName))) : null;
|
|
||||||
const tspanName = tspanAdj || !oldName || !newName ? null : tspan.find(el => el.textContent.includes(oldName));
|
|
||||||
|
|
||||||
if (tspanAdj) {
|
|
||||||
tspanAdj.textContent = tspanAdj.textContent.replace(getAdjective(oldName), getAdjective(newName));
|
|
||||||
const l = tspanAdj.getComputedTextLength();
|
|
||||||
tspanAdj.setAttribute("x", l / -2);
|
|
||||||
} if (tspanName) {
|
|
||||||
tspanName.textContent = tspanName.textContent.replace(oldName, newName);
|
|
||||||
const l = tspanName.getComputedTextLength();
|
|
||||||
tspanName.setAttribute("x", l / -2);
|
|
||||||
} else {
|
|
||||||
BurgsAndStates.drawStateLabels([state]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tip("State label is automatically changed. To make a custom change click on a label and edit the text there", false, "warn");
|
function addCustomForm() {
|
||||||
|
const value = stateNameEditorCustomForm.value;
|
||||||
|
const displayed = stateNameEditorCustomForm.style.display === "inline-block";
|
||||||
|
stateNameEditorCustomForm.style.display = displayed ? "none" : "inline-block";
|
||||||
|
stateNameEditorSelectForm.style.display = displayed ? "inline-block" : "none";
|
||||||
|
if (displayed && value) applyOption(stateNameEditorSelectForm, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function regenerateFullName() {
|
||||||
|
const short = document.getElementById("stateNameEditorShort").value;
|
||||||
|
const form = document.getElementById("stateNameEditorSelectForm").value;
|
||||||
|
document.getElementById("stateNameEditorFull").value = getFullName();
|
||||||
|
|
||||||
|
function getFullName() {
|
||||||
|
if (!form) return short;
|
||||||
|
if (!short && form) return "The " + form;
|
||||||
|
const tick = +stateNameEditorFullRegenerate.dataset.tick;
|
||||||
|
stateNameEditorFullRegenerate.dataset.tick = tick+1;
|
||||||
|
return tick%2 ? getAdjective(short) + " " + form : form + " of " + short;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyNameChange(s) {
|
||||||
|
s.name = document.getElementById("stateNameEditorShort").value;
|
||||||
|
s.formName = document.getElementById("stateNameEditorSelectForm").value;
|
||||||
|
s.fullName = document.getElementById("stateNameEditorFull").value;
|
||||||
|
if (stateNameEditorUpdateLabel.checked) BurgsAndStates.drawStateLabels([s.i]);
|
||||||
|
refreshStatesEditor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateChangeCapitalName(state, line, value) {
|
function stateChangeCapitalName(state, line, value) {
|
||||||
|
|
@ -286,9 +287,17 @@ function editStates() {
|
||||||
document.querySelector("#burgLabel"+capital).textContent = value;
|
document.querySelector("#burgLabel"+capital).textContent = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateOpenCOA(state) {
|
function stateOpenCOA(event, state) {
|
||||||
const url = `https://ironarachne.com/heraldry/${seed}-s${state}`;
|
const defSeed = `${seed}-s${state}`;
|
||||||
window.open(url, '_blank');
|
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
const newSeed = prompt(`Please provide an Iron Arachne Heraldry Generator seed. `+
|
||||||
|
`Default seed is a combination of FMG map seed and province id (${defSeed})`, pack.states[state].IAHG || defSeed);
|
||||||
|
if (newSeed && newSeed != defSeed) pack.states[state].IAHG = newSeed; else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s = pack.states[state].IAHG || defSeed;
|
||||||
|
openURL("https://ironarachne.com/heraldry/" + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePopulation(state) {
|
function changePopulation(state) {
|
||||||
|
|
@ -413,7 +422,7 @@ function editStates() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const capital = pack.states[state].capital;
|
const capital = pack.states[state].capital;
|
||||||
pack.burgs[capital].capital = false;
|
pack.burgs[capital].capital = 0;
|
||||||
pack.burgs[capital].state = 0;
|
pack.burgs[capital].state = 0;
|
||||||
moveBurgToGroup(capital, "towns");
|
moveBurgToGroup(capital, "towns");
|
||||||
|
|
||||||
|
|
@ -788,7 +797,7 @@ function editStates() {
|
||||||
const newState = states.length;
|
const newState = states.length;
|
||||||
|
|
||||||
// turn burg into a capital
|
// turn burg into a capital
|
||||||
burgs[burg].capital = true;
|
burgs[burg].capital = 1;
|
||||||
burgs[burg].state = newState;
|
burgs[burg].state = newState;
|
||||||
moveBurgToGroup(burg, "cities");
|
moveBurgToGroup(burg, "cities");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ toolsContent.addEventListener("click", function(event) {
|
||||||
if (button === "editCulturesButton") editCultures(); else
|
if (button === "editCulturesButton") editCultures(); else
|
||||||
if (button === "editReligions") editReligions(); else
|
if (button === "editReligions") editReligions(); else
|
||||||
if (button === "editNamesBaseButton") editNamesbase(); else
|
if (button === "editNamesBaseButton") editNamesbase(); else
|
||||||
if (button === "editBurgsButton") editBurgs(); else
|
if (button === "overviewBurgsButton") editBurgs(); else
|
||||||
if (button === "editUnitsButton") editUnits(); else
|
if (button === "editUnitsButton") editUnits(); else
|
||||||
if (button === "editNotesButton") editNotes(); else
|
if (button === "editNotesButton") editNotes(); else
|
||||||
if (button === "editZonesButton") editZones();
|
if (button === "editZonesButton") editZones();
|
||||||
|
|
@ -122,7 +122,7 @@ function regenerateBurgs() {
|
||||||
const burg = addBurg([cells.p[s.center][0], cells.p[s.center][1]]); // add new burg
|
const burg = addBurg([cells.p[s.center][0], cells.p[s.center][1]]); // add new burg
|
||||||
s.capital = burg;
|
s.capital = burg;
|
||||||
s.center = pack.burgs[burg].cell;
|
s.center = pack.burgs[burg].cell;
|
||||||
pack.burgs[burg].capital = true;
|
pack.burgs[burg].capital = 1;
|
||||||
pack.burgs[burg].state = s.i;
|
pack.burgs[burg].state = s.i;
|
||||||
moveBurgToGroup(burg, "cities");
|
moveBurgToGroup(burg, "cities");
|
||||||
});
|
});
|
||||||
|
|
@ -153,7 +153,7 @@ function regenerateStates() {
|
||||||
// turn all old capitals into towns
|
// turn all old capitals into towns
|
||||||
burgs.filter(b => b.capital).forEach(b => {
|
burgs.filter(b => b.capital).forEach(b => {
|
||||||
moveBurgToGroup(b.i, "towns");
|
moveBurgToGroup(b.i, "towns");
|
||||||
b.capital = false;
|
b.capital = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const neutral = pack.states[0].name;
|
const neutral = pack.states[0].name;
|
||||||
|
|
@ -171,7 +171,7 @@ function regenerateStates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
capitalsTree.add([x, y]);
|
capitalsTree.add([x, y]);
|
||||||
capital.capital = true;
|
capital.capital = 1;
|
||||||
moveBurgToGroup(capital.i, "cities");
|
moveBurgToGroup(capital.i, "cities");
|
||||||
|
|
||||||
const culture = capital.culture;
|
const culture = capital.culture;
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,8 @@ function editZones() {
|
||||||
zone.attr("data-cells", cells);
|
zone.attr("data-cells", cells);
|
||||||
zone.selectAll("*").remove();
|
zone.selectAll("*").remove();
|
||||||
const base = zone.attr("id") + "_"; // id generic part
|
const base = zone.attr("id") + "_"; // id generic part
|
||||||
zone.selectAll("*").data(cells).enter().append("polygon").attr("points", d => getPackPolygon(d)).attr("id", d => base + d);
|
zone.selectAll("*").data(cells).enter().append("polygon")
|
||||||
|
.attr("points", d => getPackPolygon(d)).attr("id", d => base + d);
|
||||||
});
|
});
|
||||||
|
|
||||||
exitZonesManualAssignment();
|
exitZonesManualAssignment();
|
||||||
|
|
|
||||||
|
|
@ -537,6 +537,11 @@ function parseError(error) {
|
||||||
return errorParsed;
|
return errorParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// open URL in a new tab or window
|
||||||
|
function openURL(url) {
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
// polyfills
|
// polyfills
|
||||||
if (Array.prototype.flat === undefined) {
|
if (Array.prototype.flat === undefined) {
|
||||||
Array.prototype.flat = function() {
|
Array.prototype.flat = function() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue