mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
1.1.20
This commit is contained in:
parent
9dab5f2a9d
commit
c27d3e1689
10 changed files with 214 additions and 49 deletions
|
|
@ -195,13 +195,13 @@ i.icon-lock {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#religionHierarchy .selected {
|
#hierarchy .selected {
|
||||||
stroke: #c13119;
|
stroke: #c13119;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
#religionHierarchy text,
|
#hierarchy text,
|
||||||
#statesTree text,
|
#statesTree text,
|
||||||
#provincesTree text {
|
#provincesTree text {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
|
||||||
10
index.html
10
index.html
|
|
@ -952,7 +952,7 @@
|
||||||
<option value="styleDefault" data-system=1 selected>Default</option>
|
<option value="styleDefault" data-system=1 selected>Default</option>
|
||||||
<option value="styleGloom" data-system=1>Gloom</option>
|
<option value="styleGloom" data-system=1>Gloom</option>
|
||||||
<option value="styleAncient" data-system=1>Ancient</option>
|
<option value="styleAncient" data-system=1>Ancient</option>
|
||||||
<option value="styleMonochrome" data-system=1>Monochrome</option>
|
<option value="styleMonochrome" data-system=1>Monochrome (for heightmap)</option>
|
||||||
<option value="styleClean" data-system=1>Clean</option>
|
<option value="styleClean" data-system=1>Clean</option>
|
||||||
</select>
|
</select>
|
||||||
<button id="addStyleButton" data-tip="Click to save current style as a new preset" class="icon-plus styleButton" style="display: inline-block" onclick="addStylePreset()"></button>
|
<button id="addStyleButton" data-tip="Click to save current style as a new preset" class="icon-plus styleButton" style="display: inline-block" onclick="addStylePreset()"></button>
|
||||||
|
|
@ -1793,8 +1793,8 @@
|
||||||
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Burgs will remain as they are">States</button>
|
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Burgs will remain as they are">States</button>
|
||||||
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
||||||
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
||||||
<button id="regenerateMarkers" data-tip="Click to regenerate markers">Markers</button>
|
<button id="regenerateMarkers" data-tip="Click to regenerate markers. Hold Ctrl and click to set markers number multiplier">Markers</button>
|
||||||
<button id="regenerateZones" data-tip="Click to regenerate zones">Zones</button>
|
<button id="regenerateZones" data-tip="Click to regenerate zones. Hold Ctrl and click to set zones number multiplier">Zones</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="addFeature">
|
<div id="addFeature">
|
||||||
|
|
@ -1880,7 +1880,8 @@
|
||||||
Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun,
|
Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun,
|
||||||
Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan),
|
Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan),
|
||||||
Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI,
|
Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI,
|
||||||
Hilton Williams, Katharina Haase, Hisham Bedri, Ian arless, Karnat, Bird, Kevin and many others!</p>
|
Hilton Williams, Katharina Haase, Hisham Bedri, Ian arless, Karnat, Bird, Kevin, Jessica Thomas, Steve Hyatt, Logicspren,
|
||||||
|
Alfred García, Jonathan Killstring, John Ackley, Invad3r233, Norbert Žigmund, Jennifer, PoliticsBuff and many others!</p>
|
||||||
|
|
||||||
<ul class="share-buttons">
|
<ul class="share-buttons">
|
||||||
<li><a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fazgaar.github.io%2FFantasy-Map-Generator%2F"e=" data-tip="Share on Facebook" target="_blank"><img alt="Share on Facebook" src="images/Facebook.png" /></a></li>
|
<li><a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fazgaar.github.io%2FFantasy-Map-Generator%2F"e=" data-tip="Share on Facebook" target="_blank"><img alt="Share on Facebook" src="images/Facebook.png" /></a></li>
|
||||||
|
|
@ -2891,6 +2892,7 @@
|
||||||
<button id="culturesEditStyle" data-tip="Edit cultures style in Style Editor" class="icon-adjust"></button>
|
<button id="culturesEditStyle" data-tip="Edit cultures style in Style Editor" class="icon-adjust"></button>
|
||||||
<button id="culturesLegend" data-tip="Toggle Legend box" class="icon-list-bullet"></button>
|
<button id="culturesLegend" data-tip="Toggle Legend box" class="icon-list-bullet"></button>
|
||||||
<button id="culturesPercentage" data-tip="Toggle percentage / absolute values display mode" class="icon-percent"></button>
|
<button id="culturesPercentage" data-tip="Toggle percentage / absolute values display mode" class="icon-percent"></button>
|
||||||
|
<button id="culturesHeirarchy" data-tip="Show cultures hierarchy tree" class="icon-sitemap"></button>
|
||||||
<button id="culturesManually" data-tip="Manually re-assign cultures" class="icon-brush"></button>
|
<button id="culturesManually" data-tip="Manually re-assign cultures" class="icon-brush"></button>
|
||||||
<div id="culturesManuallyButtons" style="display: none">
|
<div id="culturesManuallyButtons" style="display: none">
|
||||||
<label data-tip="Change brush size. Shortcut: + (increase), – (decrease)" class="italic">Brush size:
|
<label data-tip="Change brush size. Shortcut: + (increase), – (decrease)" class="italic">Brush size:
|
||||||
|
|
|
||||||
1
main.js
1
main.js
|
|
@ -1136,6 +1136,7 @@ function rankCells() {
|
||||||
|
|
||||||
// generate some markers
|
// generate some markers
|
||||||
function addMarkers(number = 1) {
|
function addMarkers(number = 1) {
|
||||||
|
if (!number) return;
|
||||||
console.time("addMarkers");
|
console.time("addMarkers");
|
||||||
const cells = pack.cells;
|
const cells = pack.cells;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,25 +38,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pack.cultures = getRandomCultures(count);
|
const cultures = pack.cultures = getRandomCultures(count);
|
||||||
const centers = d3.quadtree();
|
const centers = d3.quadtree();
|
||||||
const colors = getColors(count);
|
const colors = getColors(count);
|
||||||
|
|
||||||
pack.cultures.forEach(function(culture, i) {
|
cultures.forEach(function(culture, i) {
|
||||||
const c = culture.center = placeCultureCenter();
|
const c = culture.center = placeCultureCenter();
|
||||||
centers.add(cells.p[c]);
|
centers.add(cells.p[c]);
|
||||||
culture.i = i+1;
|
culture.i = i+1;
|
||||||
|
delete culture.odd;
|
||||||
culture.color = colors[i];
|
culture.color = colors[i];
|
||||||
culture.type = defineCultureType(c);
|
culture.type = defineCultureType(c);
|
||||||
culture.expansionism = defineCultureExpansionism(culture.type);
|
culture.expansionism = defineCultureExpansionism(culture.type);
|
||||||
|
culture.origin = 0;
|
||||||
|
culture.code = getCode(culture.name);
|
||||||
cells.culture[c] = i+1;
|
cells.culture[c] = i+1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// the first culture with id 0 is for wildlands
|
// the first culture with id 0 is for wildlands
|
||||||
pack.cultures.unshift({name:"Wildlands", i:0, base:1});
|
cultures.unshift({name:"Wildlands", i:0, base:1, origin:null});
|
||||||
|
|
||||||
// check whether all bases are valid. If not, load default namesbase
|
// check whether all bases are valid. If not, load default namesbase
|
||||||
const invalidBase = pack.cultures.some(c => !nameBases[c.base]);
|
const invalidBase = cultures.some(c => !nameBases[c.base]);
|
||||||
if (invalidBase) nameBases = Names.getNameBases();
|
if (invalidBase) nameBases = Names.getNameBases();
|
||||||
|
|
||||||
function getRandomCultures(c) {
|
function getRandomCultures(c) {
|
||||||
|
|
@ -111,6 +114,36 @@
|
||||||
console.timeEnd('generateCultures');
|
console.timeEnd('generateCultures');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assign a unique two-letters code (abbreviation)
|
||||||
|
function getCode(name) {
|
||||||
|
const words = name.split(" "), letters = words.join("");
|
||||||
|
let code = words.length === 2 ? words[0][0]+words[1][0] : letters.slice(0,2);
|
||||||
|
for (let i=1; i < letters.length-1 && pack.cultures.some(c => c.code === code); i++) {
|
||||||
|
code = letters[0] + letters[i].toUpperCase();
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
const add = function(center) {
|
||||||
|
const defaultCultures = getDefault();
|
||||||
|
let culture, base, name;
|
||||||
|
if (pack.cultures.length < defaultCultures.length) {
|
||||||
|
// add one of the default cultures
|
||||||
|
culture = pack.cultures.length;
|
||||||
|
base = defaultCultures[culture].base;
|
||||||
|
name = defaultCultures[culture].name;
|
||||||
|
} else {
|
||||||
|
// add random culture besed on one of the current ones
|
||||||
|
culture = rand(pack.cultures.length - 1);
|
||||||
|
name = Names.getCulture(culture, 5, 8, "");
|
||||||
|
base = pack.cultures[culture].base;
|
||||||
|
}
|
||||||
|
const code = getCode(name);
|
||||||
|
const i = pack.cultures.length;
|
||||||
|
const color = d3.color(d3.scaleSequential(d3.interpolateRainbow)(Math.random())).hex();
|
||||||
|
pack.cultures.push({name, color, base, center, i, expansionism:1, type:"Generic", cells:0, area:0, rural:0, urban:0, origin:0, code});
|
||||||
|
}
|
||||||
|
|
||||||
const getDefault = function(count) {
|
const getDefault = function(count) {
|
||||||
if (culturesSet.value === "european") {
|
if (culturesSet.value === "european") {
|
||||||
return [
|
return [
|
||||||
|
|
@ -391,6 +424,6 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {generate, expand, getDefault};
|
return {generate, add, expand, getDefault};
|
||||||
|
|
||||||
})));
|
})));
|
||||||
|
|
|
||||||
|
|
@ -830,6 +830,14 @@ function parseLoadedData(data) {
|
||||||
terrs.attr("scheme", "bright").attr("terracing", 0).attr("skip", 5).attr("relax", 0).attr("curve", 0);
|
terrs.attr("scheme", "bright").attr("terracing", 0).attr("skip", 5).attr("relax", 0).attr("curve", 0);
|
||||||
svg.select("#oceanic > rect").attr("id", "oceanicPattern");
|
svg.select("#oceanic > rect").attr("id", "oceanicPattern");
|
||||||
oceanLayers.attr("layers", "-6,-3,-1");
|
oceanLayers.attr("layers", "-6,-3,-1");
|
||||||
|
|
||||||
|
// v 1.1 added cultures heirarchy tree
|
||||||
|
if (pack.cultures[1] && !pack.cultures[1].code) {
|
||||||
|
pack.cultures.filter(c => c.i).forEach(c => {
|
||||||
|
c.origin = 0;
|
||||||
|
c.code = c.name.slice(0, 2);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ function editBurg(id) {
|
||||||
const newSeed = prompt(`Please provide a Medieval Fantasy City Generator seed. `+
|
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}). `+
|
`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);
|
`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;
|
if (newSeed) burg.MFCG = newSeed; else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = elSelected.text();
|
const name = elSelected.text();
|
||||||
|
|
@ -309,7 +309,7 @@ function editBurg(id) {
|
||||||
openURL(url);
|
openURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openInIAHG() {
|
function openInIAHG(event) {
|
||||||
const id = elSelected.attr("data-id");
|
const id = elSelected.attr("data-id");
|
||||||
const burg = pack.burgs[id];
|
const burg = pack.burgs[id];
|
||||||
const defSeed = `${seed}-b${id}`;
|
const defSeed = `${seed}-b${id}`;
|
||||||
|
|
@ -317,7 +317,7 @@ function editBurg(id) {
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const newSeed = prompt(`Please provide an Iron Arachne Heraldry Generator seed. `+
|
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);
|
`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;
|
if (newSeed) burg.IAHG = newSeed; else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const s = burg.IAHG || defSeed;
|
const s = burg.IAHG || defSeed;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ function editCultures() {
|
||||||
document.getElementById("culturesEditStyle").addEventListener("click", () => editStyle("cults"));
|
document.getElementById("culturesEditStyle").addEventListener("click", () => editStyle("cults"));
|
||||||
document.getElementById("culturesLegend").addEventListener("click", toggleLegend);
|
document.getElementById("culturesLegend").addEventListener("click", toggleLegend);
|
||||||
document.getElementById("culturesPercentage").addEventListener("click", togglePercentageMode);
|
document.getElementById("culturesPercentage").addEventListener("click", togglePercentageMode);
|
||||||
|
document.getElementById("culturesHeirarchy").addEventListener("click", showHierarchy);
|
||||||
document.getElementById("culturesRecalculate").addEventListener("click", () => recalculateCultures(true));
|
document.getElementById("culturesRecalculate").addEventListener("click", () => recalculateCultures(true));
|
||||||
document.getElementById("culturesManually").addEventListener("click", enterCultureManualAssignent);
|
document.getElementById("culturesManually").addEventListener("click", enterCultureManualAssignent);
|
||||||
document.getElementById("culturesManuallyApply").addEventListener("click", applyCultureManualAssignent);
|
document.getElementById("culturesManuallyApply").addEventListener("click", applyCultureManualAssignent);
|
||||||
|
|
@ -148,17 +149,35 @@ function editCultures() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function cultureHighlightOn(event) {
|
function cultureHighlightOn(event) {
|
||||||
|
const culture = +event.target.dataset.id;
|
||||||
|
const info = document.getElementById("cultureInfo");
|
||||||
|
if (info) {
|
||||||
|
d3.select("#hierarchy").select("g[data-id='"+culture+"'] > path").classed("selected", 1);
|
||||||
|
const c = pack.cultures[culture];
|
||||||
|
const rural = c.rural * populationRate.value;
|
||||||
|
const urban = c.urban * populationRate.value * urbanization.value;
|
||||||
|
const population = rural + urban > 0 ? si(rn(rural + urban)) + " people" : "Extinct";
|
||||||
|
info.innerHTML = `${c.name} culture. ${c.type}. ${population}`;
|
||||||
|
tip("Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation");
|
||||||
|
}
|
||||||
|
|
||||||
if (!layerIsOn("toggleCultures")) return;
|
if (!layerIsOn("toggleCultures")) return;
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const culture = +event.target.dataset.id;
|
|
||||||
const animate = d3.transition().duration(2000).ease(d3.easeSinIn);
|
const animate = d3.transition().duration(2000).ease(d3.easeSinIn);
|
||||||
cults.select("#culture"+culture).raise().transition(animate).attr("stroke-width", 2.5).attr("stroke", "#d0240f");
|
cults.select("#culture"+culture).raise().transition(animate).attr("stroke-width", 2.5).attr("stroke", "#d0240f");
|
||||||
debug.select("#cultureCenter"+culture).raise().transition(animate).attr("r", 8).attr("stroke", "#d0240f");
|
debug.select("#cultureCenter"+culture).raise().transition(animate).attr("r", 8).attr("stroke", "#d0240f");
|
||||||
}
|
}
|
||||||
|
|
||||||
function cultureHighlightOff(event) {
|
function cultureHighlightOff(event) {
|
||||||
if (!layerIsOn("toggleCultures")) return;
|
|
||||||
const culture = +event.target.dataset.id;
|
const culture = +event.target.dataset.id;
|
||||||
|
const info = document.getElementById("cultureInfo");
|
||||||
|
if (info) {
|
||||||
|
d3.select("#hierarchy").select("g[data-id='"+culture+"'] > path").classed("selected", 0);
|
||||||
|
info.innerHTML = "‍";
|
||||||
|
tip("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layerIsOn("toggleCultures")) return;
|
||||||
cults.select("#culture"+culture).transition().attr("stroke-width", null).attr("stroke", null);
|
cults.select("#culture"+culture).transition().attr("stroke-width", null).attr("stroke", null);
|
||||||
debug.select("#cultureCenter"+culture).transition().attr("r", 6).attr("stroke", null);
|
debug.select("#cultureCenter"+culture).transition().attr("r", 6).attr("stroke", null);
|
||||||
}
|
}
|
||||||
|
|
@ -340,6 +359,99 @@ function editCultures() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showHierarchy() {
|
||||||
|
// build hierarchy tree
|
||||||
|
pack.cultures[0].origin = null;
|
||||||
|
const cultures = pack.cultures.filter(c => !c.removed);
|
||||||
|
const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(cultures);
|
||||||
|
const treeWidth = root.leaves().length;
|
||||||
|
const treeHeight = root.height;
|
||||||
|
const width = treeWidth * 40, height = treeHeight * 60;
|
||||||
|
|
||||||
|
const margin = {top: 10, right: 10, bottom: -5, left: 10};
|
||||||
|
const w = width - margin.left - margin.right;
|
||||||
|
const h = height + 30 - margin.top - margin.bottom;
|
||||||
|
const treeLayout = d3.tree().size([w, h]);
|
||||||
|
|
||||||
|
// prepare svg
|
||||||
|
alertMessage.innerHTML = "<div id='cultureInfo' class='chartInfo'>‍</div>";
|
||||||
|
const svg = d3.select("#alertMessage").insert("svg", "#cultureInfo").attr("id", "hierarchy")
|
||||||
|
.attr("width", width).attr("height", height).style("text-anchor", "middle");
|
||||||
|
const graph = svg.append("g").attr("transform", `translate(10, -45)`);
|
||||||
|
const links = graph.append("g").attr("fill", "none").attr("stroke", "#aaaaaa");
|
||||||
|
const nodes = graph.append("g");
|
||||||
|
|
||||||
|
renderTree();
|
||||||
|
function renderTree() {
|
||||||
|
treeLayout(root);
|
||||||
|
links.selectAll('path').data(root.links()).enter()
|
||||||
|
.append('path').attr("d", d => {return "M" + d.source.x + "," + d.source.y
|
||||||
|
+ "C" + d.source.x + "," + (d.source.y * 3 + d.target.y) / 4
|
||||||
|
+ " " + d.target.x + "," + (d.source.y * 2 + d.target.y) / 3
|
||||||
|
+ " " + d.target.x + "," + d.target.y;});
|
||||||
|
|
||||||
|
const node = nodes.selectAll('g').data(root.descendants()).enter()
|
||||||
|
.append('g').attr("data-id", d => d.data.i).attr("stroke", "#333333")
|
||||||
|
.attr("transform", d => `translate(${d.x}, ${d.y})`)
|
||||||
|
.on("mouseenter", () => cultureHighlightOn(event))
|
||||||
|
.on("mouseleave", () => cultureHighlightOff(event))
|
||||||
|
.call(d3.drag().on("start", d => dragToReorigin(d)));
|
||||||
|
|
||||||
|
node.append("path").attr("d", d => {
|
||||||
|
if (!d.data.i) return "M5,0A5,5,0,1,1,-5,0A5,5,0,1,1,5,0"; else // small circle
|
||||||
|
if (d.data.type === "Generic") return "M11.3,0A11.3,11.3,0,1,1,-11.3,0A11.3,11.3,0,1,1,11.3,0"; else // circle
|
||||||
|
if (d.data.type === "River") return "M0,-14L14,0L0,14L-14,0Z"; else // diamond
|
||||||
|
if (d.data.type === "Lake") return "M-6.5,-11.26l13,0l6.5,11.26l-6.5,11.26l-13,0l-6.5,-11.26Z"; else // hexagon
|
||||||
|
if (d.data.type === "Naval") return "M-11,-11h22v22h-22Z"; // square
|
||||||
|
if (d.data.type === "Highland") return "M-11,-11l11,2l11,-2l-2,11l2,11l-11,-2l-11,2l2,-11Z"; // concave square
|
||||||
|
if (d.data.type === "Nomadic") return "M-4.97,-12.01 l9.95,0 l7.04,7.04 l0,9.95 l-7.04,7.04 l-9.95,0 l-7.04,-7.04 l0,-9.95Z"; // octagon
|
||||||
|
if (d.data.type === "Hunting") return "M0,-14l14,11l-6,14h-16l-6,-14Z"; // pentagon
|
||||||
|
return "M-11,-11h22v22h-22Z"; // square
|
||||||
|
}).attr("fill", d => d.data.i ? d.data.color : "#ffffff")
|
||||||
|
.attr("stroke-dasharray", d => d.data.cells ? "null" : "1");
|
||||||
|
|
||||||
|
node.append("text").attr("dy", ".35em").text(d => d.data.i ? d.data.code : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#alert").dialog({
|
||||||
|
title: "Cultures tree", width: fitContent(), resizable: false,
|
||||||
|
position: {my: "left center", at: "left+10 center", of: "svg"}, buttons: {},
|
||||||
|
close: () => {alertMessage.innerHTML = "";}
|
||||||
|
});
|
||||||
|
|
||||||
|
function dragToReorigin(d) {
|
||||||
|
if (d3.event.sourceEvent.ctrlKey) {changeCode(d); return;}
|
||||||
|
|
||||||
|
const originLine = graph.append("path")
|
||||||
|
.attr("class", "dragLine").attr("d", `M${d.x},${d.y}L${d.x},${d.y}`);
|
||||||
|
|
||||||
|
d3.event.on("drag", () => {
|
||||||
|
originLine.attr("d", `M${d.x},${d.y}L${d3.event.x},${d3.event.y}`)
|
||||||
|
});
|
||||||
|
|
||||||
|
d3.event.on("end", () => {
|
||||||
|
originLine.remove();
|
||||||
|
const selected = graph.select("path.selected");
|
||||||
|
if (!selected.size()) return;
|
||||||
|
const culture = d.data.i;
|
||||||
|
const oldOrigin = d.data.origin;
|
||||||
|
let newOrigin = selected.datum().data.i;
|
||||||
|
if (newOrigin == oldOrigin) return; // already a child of the selected node
|
||||||
|
if (newOrigin == culture) newOrigin = 0; // move to top
|
||||||
|
if (newOrigin && d.descendants().some(node => node.id == newOrigin)) return; // cannot be a child of its own child
|
||||||
|
pack.cultures[culture].origin = d.data.origin = newOrigin; // change data
|
||||||
|
showHierarchy() // update hierarchy
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeCode(d) {
|
||||||
|
const code = prompt(`Please provide an abbreviation for culture: ${d.data.name}`, d.data.code);
|
||||||
|
if (!code) return;
|
||||||
|
pack.cultures[d.data.i].code = code;
|
||||||
|
nodes.select("g[data-id='"+d.data.i+"']").select("text").text(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// re-calculate cultures
|
// re-calculate cultures
|
||||||
function recalculateCultures(must) {
|
function recalculateCultures(must) {
|
||||||
if (!must && !culturesAutoChange.checked) return;
|
if (!must && !culturesAutoChange.checked) return;
|
||||||
|
|
@ -499,23 +611,8 @@ function editCultures() {
|
||||||
if (occupied) {tip("This cell is already a culture center. Please select a different cell", false, "error"); return;}
|
if (occupied) {tip("This cell is already a culture center. Please select a different cell", false, "error"); return;}
|
||||||
|
|
||||||
if (d3.event.shiftKey === false) exitAddCultureMode();
|
if (d3.event.shiftKey === false) exitAddCultureMode();
|
||||||
|
Cultures.add(center);
|
||||||
|
|
||||||
const defaultCultures = Cultures.getDefault();
|
|
||||||
let culture, base, name;
|
|
||||||
if (pack.cultures.length < defaultCultures.length) {
|
|
||||||
// add one of the default cultures
|
|
||||||
culture = pack.cultures.length;
|
|
||||||
base = defaultCultures[culture].base;
|
|
||||||
name = defaultCultures[culture].name;
|
|
||||||
} else {
|
|
||||||
// add random culture besed on one of the current ones
|
|
||||||
culture = rand(pack.cultures.length - 1);
|
|
||||||
name = Names.getCulture(culture, 5, 8, "");
|
|
||||||
base = pack.cultures[culture].base;
|
|
||||||
}
|
|
||||||
const i = pack.cultures.length;
|
|
||||||
const color = d3.color(d3.scaleSequential(d3.interpolateRainbow)(Math.random())).hex();
|
|
||||||
pack.cultures.push({name, color, base, center, i, expansionism:1, type:"Generic", cells:0, area:0, rural:0, urban:0});
|
|
||||||
drawCultureCenters();
|
drawCultureCenters();
|
||||||
culturesEditorAddLines();
|
culturesEditorAddLines();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ function editReligions() {
|
||||||
const religion = +event.target.dataset.id;
|
const religion = +event.target.dataset.id;
|
||||||
const info = document.getElementById("religionInfo");
|
const info = document.getElementById("religionInfo");
|
||||||
if (info) {
|
if (info) {
|
||||||
d3.select("#religionHierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 1);
|
d3.select("#hierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 1);
|
||||||
const r = pack.religions[religion];
|
const r = pack.religions[religion];
|
||||||
const type = r.name.includes(r.type) ? ""
|
const type = r.name.includes(r.type) ? ""
|
||||||
: r.type === "Folk" || r.type === "Organized"
|
: r.type === "Folk" || r.type === "Organized"
|
||||||
|
|
@ -153,7 +153,7 @@ function editReligions() {
|
||||||
const urban = r.urban * populationRate.value * urbanization.value;
|
const urban = r.urban * populationRate.value * urbanization.value;
|
||||||
const population = rural + urban > 0 ? ". " + si(rn(rural + urban)) + " believers" : ". Extinct";
|
const population = rural + urban > 0 ? ". " + si(rn(rural + urban)) + " believers" : ". Extinct";
|
||||||
info.innerHTML = `${r.name}${type}${form}${population}`;
|
info.innerHTML = `${r.name}${type}${form}${population}`;
|
||||||
tip("Drag to change parent. Hold CTRL and click to change abbreviation");
|
tip("Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = body.querySelector(`div[data-id='${religion}']`);
|
const el = body.querySelector(`div[data-id='${religion}']`);
|
||||||
|
|
@ -169,7 +169,7 @@ function editReligions() {
|
||||||
const religion = +event.target.dataset.id;
|
const religion = +event.target.dataset.id;
|
||||||
const info = document.getElementById("religionInfo");
|
const info = document.getElementById("religionInfo");
|
||||||
if (info) {
|
if (info) {
|
||||||
d3.select("#religionHierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 0);
|
d3.select("#hierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 0);
|
||||||
info.innerHTML = "‍";
|
info.innerHTML = "‍";
|
||||||
tip("");
|
tip("");
|
||||||
}
|
}
|
||||||
|
|
@ -372,7 +372,7 @@ function editReligions() {
|
||||||
|
|
||||||
// prepare svg
|
// prepare svg
|
||||||
alertMessage.innerHTML = "<div id='religionInfo' class='chartInfo'>‍</div>";
|
alertMessage.innerHTML = "<div id='religionInfo' class='chartInfo'>‍</div>";
|
||||||
const svg = d3.select("#alertMessage").insert("svg", "#religionInfo").attr("id", "religionHierarchy")
|
const svg = d3.select("#alertMessage").insert("svg", "#religionInfo").attr("id", "hierarchy")
|
||||||
.attr("width", width).attr("height", height).style("text-anchor", "middle");
|
.attr("width", width).attr("height", height).style("text-anchor", "middle");
|
||||||
const graph = svg.append("g").attr("transform", `translate(10, -45)`);
|
const graph = svg.append("g").attr("transform", `translate(10, -45)`);
|
||||||
const links = graph.append("g").attr("fill", "none").attr("stroke", "#aaaaaa");
|
const links = graph.append("g").attr("fill", "none").attr("stroke", "#aaaaaa");
|
||||||
|
|
@ -413,7 +413,7 @@ function editReligions() {
|
||||||
});
|
});
|
||||||
|
|
||||||
function dragToReorigin(d) {
|
function dragToReorigin(d) {
|
||||||
if (d3.event.sourceEvent.ctrlKey) {changeReligionCode(d); return;}
|
if (d3.event.sourceEvent.ctrlKey) {changeCode(d); return;}
|
||||||
|
|
||||||
const originLine = graph.append("path")
|
const originLine = graph.append("path")
|
||||||
.attr("class", "dragLine").attr("d", `M${d.x},${d.y}L${d.x},${d.y}`);
|
.attr("class", "dragLine").attr("d", `M${d.x},${d.y}L${d.x},${d.y}`);
|
||||||
|
|
@ -437,7 +437,7 @@ function editReligions() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeReligionCode(d) {
|
function changeCode(d) {
|
||||||
const code = prompt(`Please provide an abbreviation for ${d.data.name}`, d.data.code);
|
const code = prompt(`Please provide an abbreviation for ${d.data.name}`, d.data.code);
|
||||||
if (!code) return;
|
if (!code) return;
|
||||||
pack.religions[d.data.i].code = code;
|
pack.religions[d.data.i].code = code;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -22,12 +22,12 @@ toolsContent.addEventListener("click", function(event) {
|
||||||
|
|
||||||
// Click to Regenerate buttons
|
// Click to Regenerate buttons
|
||||||
if (event.target.parentNode.id === "regenerateFeature") {
|
if (event.target.parentNode.id === "regenerateFeature") {
|
||||||
if (sessionStorage.getItem("regenerateFeatureDontAsk")) {processFeatureRegeneration(button); return;}
|
if (sessionStorage.getItem("regenerateFeatureDontAsk")) {processFeatureRegeneration(event, button); return;}
|
||||||
|
|
||||||
alertMessage.innerHTML = `Regeneration will remove all the custom changes for the element.<br><br>Are you sure you want to proceed?`
|
alertMessage.innerHTML = `Regeneration will remove all the custom changes for the element.<br><br>Are you sure you want to proceed?`
|
||||||
$("#alert").dialog({resizable: false, title: "Regenerate element",
|
$("#alert").dialog({resizable: false, title: "Regenerate element",
|
||||||
buttons: {
|
buttons: {
|
||||||
Proceed: function() {processFeatureRegeneration(button); $(this).dialog("close");},
|
Proceed: function() {processFeatureRegeneration(event, button); $(this).dialog("close");},
|
||||||
Cancel: function() {$(this).dialog("close");}
|
Cancel: function() {$(this).dialog("close");}
|
||||||
},
|
},
|
||||||
open: function() {
|
open: function() {
|
||||||
|
|
@ -51,7 +51,7 @@ toolsContent.addEventListener("click", function(event) {
|
||||||
if (button === "addMarker") toggleAddMarker();
|
if (button === "addMarker") toggleAddMarker();
|
||||||
});
|
});
|
||||||
|
|
||||||
function processFeatureRegeneration(button) {
|
function processFeatureRegeneration(event, button) {
|
||||||
if (button === "regenerateStateLabels") {BurgsAndStates.drawStateLabels(); if (!layerIsOn("toggleLabels")) toggleLabels();} else
|
if (button === "regenerateStateLabels") {BurgsAndStates.drawStateLabels(); if (!layerIsOn("toggleLabels")) toggleLabels();} else
|
||||||
if (button === "regenerateReliefIcons") {ReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief();} else
|
if (button === "regenerateReliefIcons") {ReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief();} else
|
||||||
if (button === "regenerateRoutes") {Routes.regenerate(); if (!layerIsOn("toggleRoutes")) toggleRoutes();} else
|
if (button === "regenerateRoutes") {Routes.regenerate(); if (!layerIsOn("toggleRoutes")) toggleRoutes();} else
|
||||||
|
|
@ -61,8 +61,8 @@ function processFeatureRegeneration(button) {
|
||||||
if (button === "regenerateStates") regenerateStates(); else
|
if (button === "regenerateStates") regenerateStates(); else
|
||||||
if (button === "regenerateProvinces") regenerateProvinces(); else
|
if (button === "regenerateProvinces") regenerateProvinces(); else
|
||||||
if (button === "regenerateReligions") regenerateReligions(); else
|
if (button === "regenerateReligions") regenerateReligions(); else
|
||||||
if (button === "regenerateMarkers") regenerateMarkers(); else
|
if (button === "regenerateMarkers") regenerateMarkers(event); else
|
||||||
if (button === "regenerateZones") regenerateZones();
|
if (button === "regenerateZones") regenerateZones(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateRivers() {
|
function regenerateRivers() {
|
||||||
|
|
@ -230,19 +230,43 @@ function regenerateReligions() {
|
||||||
if (!layerIsOn("toggleReligions")) toggleReligions(); else drawReligions();
|
if (!layerIsOn("toggleReligions")) toggleReligions(); else drawReligions();
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateMarkers() {
|
function regenerateMarkers(event) {
|
||||||
|
let number = gauss(1, .5, .3, 5, 2);
|
||||||
|
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
const numberManual = prompt("Please provide markers number multiplier", 1);
|
||||||
|
if (numberManual === null || numberManual === "" || isNaN(+numberManual)) {
|
||||||
|
tip("The number provided is invalid, please try again and provide a valid number", false, "error", 4000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
number = Math.min(+numberManual, 100);
|
||||||
|
}
|
||||||
|
|
||||||
// remove existing markers and assigned notes
|
// remove existing markers and assigned notes
|
||||||
markers.selectAll("use").each(function() {
|
markers.selectAll("use").each(function() {
|
||||||
const index = notes.findIndex(n => n.id === this.id);
|
const index = notes.findIndex(n => n.id === this.id);
|
||||||
if (index != -1) notes.splice(index, 1);
|
if (index != -1) notes.splice(index, 1);
|
||||||
}).remove();
|
}).remove();
|
||||||
|
|
||||||
addMarkers(gauss(1, .5, .3, 5, 2));
|
addMarkers(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateZones() {
|
function regenerateZones(event) {
|
||||||
|
let number = gauss(1, .5, .6, 5, 2);
|
||||||
|
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
const numberManual = prompt("Please provide zones number multiplier", 1);
|
||||||
|
if (numberManual === null || numberManual === "" || isNaN(+numberManual)) {
|
||||||
|
tip("The number provided is invalid, please try again and provide a valid number", false, "error", 4000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
number = Math.min(+numberManual, 100);
|
||||||
|
}
|
||||||
|
|
||||||
zones.selectAll("g").remove(); // remove existing zones
|
zones.selectAll("g").remove(); // remove existing zones
|
||||||
addZones(gauss(1, .5, .6, 5, 2));
|
addZones(number);
|
||||||
if (document.getElementById("zonesEditorRefresh").offsetParent) zonesEditorRefresh.click();
|
if (document.getElementById("zonesEditorRefresh").offsetParent) zonesEditorRefresh.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue