mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-21 19:41:23 +01:00
making sure no log errors but there is a problem with the menu
This commit is contained in:
parent
d4a979a67f
commit
c82e0a69f7
4 changed files with 622 additions and 1039 deletions
|
|
@ -1,3 +1,29 @@
|
||||||
|
function restoreDefaultOptions() {
|
||||||
|
// remove ALL saved data from LocalStorage
|
||||||
|
localStorage.clear();
|
||||||
|
// set defaut values
|
||||||
|
mapWidthInput.value = window.innerWidth;
|
||||||
|
mapHeightInput.value = window.innerHeight;
|
||||||
|
changeMapSize();
|
||||||
|
graphSize = sizeInput.value = sizeOutput.value = 1;
|
||||||
|
$("#options i[class^='icon-lock']").each(function() {
|
||||||
|
this.setAttribute("data-locked", 0);
|
||||||
|
this.className = "icon-lock-open";
|
||||||
|
if (this.id === "lockNeutralInput" || this.id === "lockSwampinessInput") {
|
||||||
|
this.setAttribute("data-locked", 1);
|
||||||
|
this.className = "icon-lock";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
neutralInput.value = neutralOutput.value = 200;
|
||||||
|
swampinessInput.value = swampinessOutput.value = 10;
|
||||||
|
outlineLayersInput.value = "-6,-3,-1";
|
||||||
|
transparencyInput.value = transparencyOutput.value = 0;
|
||||||
|
changeDialogsTransparency(0);
|
||||||
|
pngResolutionInput.value = 5;
|
||||||
|
pngResolutionOutput.value = "5x";
|
||||||
|
randomizeOptions();
|
||||||
|
}
|
||||||
|
|
||||||
// Heighmap Template: Volcano
|
// Heighmap Template: Volcano
|
||||||
function templateVolcano(mod) {
|
function templateVolcano(mod) {
|
||||||
addMountain();
|
addMountain();
|
||||||
|
|
|
||||||
|
|
@ -2089,3 +2089,155 @@ function templateVolcano(mod) {
|
||||||
// convert length to distance
|
// convert length to distance
|
||||||
routeLength.innerHTML = rn(l * distanceScale.value) + " " + distanceUnit.value;
|
routeLength.innerHTML = rn(l * distanceScale.value) + " " + distanceUnit.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addRoutePoint(point) {
|
||||||
|
const controlPoints = debug.select(".controlPoints").size()
|
||||||
|
? debug.select(".controlPoints")
|
||||||
|
: debug.append("g").attr("class", "controlPoints");
|
||||||
|
controlPoints.append("circle")
|
||||||
|
.attr("cx", point.x).attr("cy", point.y).attr("r", 0.35)
|
||||||
|
.call(d3.drag().on("drag", routePointDrag))
|
||||||
|
.on("click", function(d) {
|
||||||
|
if ($("#routeSplit").hasClass('pressed')) {
|
||||||
|
routeSplitInPoint(this);
|
||||||
|
} else {
|
||||||
|
$(this).remove();
|
||||||
|
routeRedraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function routePointDrag() {
|
||||||
|
d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
|
||||||
|
routeRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeRedraw() {
|
||||||
|
let points = [];
|
||||||
|
debug.select(".controlPoints").selectAll("circle").each(function() {
|
||||||
|
const el = d3.select(this);
|
||||||
|
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
||||||
|
});
|
||||||
|
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
||||||
|
elSelected.attr("d", lineGen(points));
|
||||||
|
// get route distance
|
||||||
|
const l = elSelected.node().getTotalLength();
|
||||||
|
routeLength.innerHTML = rn(l * distanceScale.value) + " " + distanceUnit.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNewRoute() {
|
||||||
|
let routeType = elSelected && elSelected.node() ? elSelected.node().parentNode.id : "searoutes";
|
||||||
|
const group = routes.select("#"+routeType);
|
||||||
|
const id = routeType + "" + group.selectAll("*").size();
|
||||||
|
elSelected = group.append("path").attr("data-route", "new").attr("id", id).on("click", editRoute);
|
||||||
|
routeUpdateGroups();
|
||||||
|
$("#routeEditor").dialog({
|
||||||
|
title: "Edit Route", minHeight: 30, width: "auto", resizable: false,
|
||||||
|
close: function() {
|
||||||
|
if ($("#addRoute").hasClass('pressed')) completeNewRoute();
|
||||||
|
if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed');
|
||||||
|
unselect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function newRouteAddPoint() {
|
||||||
|
const point = d3.mouse(this);
|
||||||
|
const x = rn(point[0],2), y = rn(point[1],2);
|
||||||
|
addRoutePoint({x, y});
|
||||||
|
routeRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function completeNewRoute() {
|
||||||
|
$("#routeNew, #addRoute").removeClass('pressed');
|
||||||
|
restoreDefaultEvents();
|
||||||
|
if (!elSelected.size()) return;
|
||||||
|
if (elSelected.attr("data-route") === "new") {
|
||||||
|
routeRedraw();
|
||||||
|
elSelected.attr("data-route", "");
|
||||||
|
const node = elSelected.node();
|
||||||
|
const l = node.getTotalLength();
|
||||||
|
let pathCells = [];
|
||||||
|
for (let i = 0; i <= l; i ++) {
|
||||||
|
const p = node.getPointAtLength(i);
|
||||||
|
const cell = diagram.find(p.x, p.y);
|
||||||
|
if (!cell) {return;}
|
||||||
|
pathCells.push(cell.index);
|
||||||
|
}
|
||||||
|
const uniqueCells = [...new Set(pathCells)];
|
||||||
|
uniqueCells.map(function(c) {
|
||||||
|
if (cells[c].path !== undefined) {cells[c].path += 1;}
|
||||||
|
else {cells[c].path = 1;}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tip("", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeUpdateGroups() {
|
||||||
|
routeGroup.innerHTML = "";
|
||||||
|
routes.selectAll("g").each(function() {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = opt.innerHTML = this.id;
|
||||||
|
routeGroup.add(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeSplitInPoint(clicked) {
|
||||||
|
const group = d3.select(elSelected.node().parentNode);
|
||||||
|
$("#routeSplit").removeClass('pressed');
|
||||||
|
const points1 = [],points2 = [];
|
||||||
|
let points = points1;
|
||||||
|
debug.select(".controlPoints").selectAll("circle").each(function() {
|
||||||
|
const el = d3.select(this);
|
||||||
|
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
||||||
|
if (this === clicked) {
|
||||||
|
points = points2;
|
||||||
|
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
||||||
|
}
|
||||||
|
el.remove();
|
||||||
|
});
|
||||||
|
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
||||||
|
elSelected.attr("d", lineGen(points1));
|
||||||
|
const id = routeGroup.value + "" + group.selectAll("*").size();
|
||||||
|
group.append("path").attr("id", id).attr("d", lineGen(points2)).on("click", editRoute);
|
||||||
|
routeDrawPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#routeGroup").change(function() {
|
||||||
|
$(elSelected.node()).detach().appendTo($("#"+this.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
// open legendsEditor
|
||||||
|
document.getElementById("routeLegend").addEventListener("click", function() {
|
||||||
|
let id = elSelected.attr("id");
|
||||||
|
editLegends(id, id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#routeNew").click(function() {
|
||||||
|
if ($(this).hasClass('pressed')) {
|
||||||
|
completeNewRoute();
|
||||||
|
} else {
|
||||||
|
// enter creation mode
|
||||||
|
$(".pressed").removeClass('pressed');
|
||||||
|
$("#routeNew, #addRoute").addClass('pressed');
|
||||||
|
debug.select(".controlPoints").selectAll("*").remove();
|
||||||
|
addNewRoute();
|
||||||
|
viewbox.style("cursor", "crosshair").on("click", newRouteAddPoint);
|
||||||
|
tip("Click on map to add route point", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#routeRemove").click(function() {
|
||||||
|
alertMessage.innerHTML = `Are you sure you want to remove the route?`;
|
||||||
|
$("#alert").dialog({resizable: false, title: "Remove route",
|
||||||
|
buttons: {
|
||||||
|
Remove: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
elSelected.remove();
|
||||||
|
$("#routeEditor").dialog("close");
|
||||||
|
},
|
||||||
|
Cancel: function() {$(this).dialog("close");}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,316 +1,453 @@
|
||||||
|
function editBurg() {
|
||||||
|
if (customization) return;
|
||||||
|
unselect();
|
||||||
|
closeDialogs("#burgEditor, .stable");
|
||||||
|
elSelected = d3.select(this);
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
if (id === undefined) return;
|
||||||
|
d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("start", elementDrag)).classed("draggable", true);
|
||||||
|
|
||||||
function drawIconsList() {
|
// update Burg details
|
||||||
let icons = [
|
const type = elSelected.node().parentNode.id;
|
||||||
// emoticons in FF:
|
const labelGroup = burgLabels.select("#"+type);
|
||||||
["2693", "⚓", "Anchor"],
|
const iconGroup = burgIcons.select("#"+type);
|
||||||
["26EA", "⛪", "Church"],
|
burgNameInput.value = manors[id].name;
|
||||||
["1F3EF", "🏯", "Japanese Castle"],
|
updateBurgsGroupOptions();
|
||||||
["1F3F0", "🏰", "Castle"],
|
burgSelectGroup.value = labelGroup.attr("id");
|
||||||
["1F5FC", "🗼", "Tower"],
|
burgSelectDefaultFont.value = fonts.indexOf(labelGroup.attr("data-font"));
|
||||||
["1F3E0", "🏠", "House"],
|
burgSetLabelSize.value = labelGroup.attr("data-size");
|
||||||
["1F3AA", "🎪", "Tent"],
|
burgLabelColorInput.value = toHEX(labelGroup.attr("fill"));
|
||||||
["1F3E8", "🏨", "Hotel"],
|
burgLabelOpacity.value = labelGroup.attr("opacity") === undefined ? 1 : +labelGroup.attr("opacity");
|
||||||
["1F4B0", "💰", "Money bag"],
|
const tr = parseTransform(elSelected.attr("transform"));
|
||||||
["1F4A8", "💨", "Dashing away"],
|
burgLabelAngle.value = tr[2];
|
||||||
["1F334", "🌴", "Palm"],
|
burgLabelAngleOutput.innerHTML = Math.abs(+tr[2]) + "°";
|
||||||
["1F335", "🌵", "Cactus"],
|
burgIconSize.value = iconGroup.attr("size");
|
||||||
["1F33E", "🌾", "Sheaf"],
|
burgIconFillOpacity.value = iconGroup.attr("fill-opacity") === undefined ? 1 : +iconGroup.attr("fill-opacity");
|
||||||
["1F5FB", "🗻", "Mountain"],
|
burgIconFillColor.value = iconGroup.attr("fill");
|
||||||
["1F30B", "🌋", "Volcano"],
|
burgIconStrokeWidth.value = iconGroup.attr("stroke-width");
|
||||||
["1F40E", "🐎", "Horse"],
|
burgIconStrokeOpacity.value = iconGroup.attr("stroke-opacity") === undefined ? 1 : +iconGroup.attr("stroke-opacity");
|
||||||
["1F434", "🐴", "Horse Face"],
|
burgIconStrokeColor.value = iconGroup.attr("stroke");
|
||||||
["1F42E", "🐮", "Cow"],
|
const cell = cells[manors[id].cell];
|
||||||
["1F43A", "🐺", "Wolf Face"],
|
if (cell.region !== "neutral" && cell.region !== undefined) {
|
||||||
["1F435", "🐵", "Monkey face"],
|
burgToggleCapital.disabled = false;
|
||||||
["1F437", "🐷", "Pig face"],
|
const capital = states[manors[id].region] ? id === states[manors[id].region].capital ? 1 : 0 : 0;
|
||||||
["1F414", "🐔", "Chiken"],
|
d3.select("#burgToggleCapital").classed("pressed", capital);
|
||||||
["1F411", "🐑", "Eve"],
|
|
||||||
["1F42B", "🐫", "Camel"],
|
|
||||||
["1F418", "🐘", "Elephant"],
|
|
||||||
["1F422", "🐢", "Turtle"],
|
|
||||||
["1F40C", "🐌", "Snail"],
|
|
||||||
["1F40D", "🐍", "Snake"],
|
|
||||||
["1F433", "🐳", "Whale"],
|
|
||||||
["1F42C", "🐬", "Dolphin"],
|
|
||||||
["1F420", "🐟", "Fish"],
|
|
||||||
["1F432", "🐲", "Dragon Head"],
|
|
||||||
["1F479", "👹", "Ogre"],
|
|
||||||
["1F47B", "👻", "Ghost"],
|
|
||||||
["1F47E", "👾", "Alien"],
|
|
||||||
["1F480", "💀", "Skull"],
|
|
||||||
["1F374", "🍴", "Fork and knife"],
|
|
||||||
["1F372", "🍲", "Food"],
|
|
||||||
["1F35E", "🍞", "Bread"],
|
|
||||||
["1F357", "🍗", "Poultry leg"],
|
|
||||||
["1F347", "🍇", "Grapes"],
|
|
||||||
["1F34F", "🍏", "Apple"],
|
|
||||||
["1F352", "🍒", "Cherries"],
|
|
||||||
["1F36F", "🍯", "Honey pot"],
|
|
||||||
["1F37A", "🍺", "Beer"],
|
|
||||||
["1F377", "🍷", "Wine glass"],
|
|
||||||
["1F3BB", "🎻", "Violin"],
|
|
||||||
["1F3B8", "🎸", "Guitar"],
|
|
||||||
["26A1", "⚡", "Electricity"],
|
|
||||||
["1F320", "🌠", "Shooting star"],
|
|
||||||
["1F319", "🌙", "Crescent moon"],
|
|
||||||
["1F525", "🔥", "Fire"],
|
|
||||||
["1F4A7", "💧", "Droplet"],
|
|
||||||
["1F30A", "🌊", "Wave"],
|
|
||||||
["231B", "⌛", "Hourglass"],
|
|
||||||
["1F3C6", "🏆", "Goblet"],
|
|
||||||
["26F2", "⛲", "Fountain"],
|
|
||||||
["26F5", "⛵", "Sailboat"],
|
|
||||||
["26FA", "⛺", "Tend"],
|
|
||||||
["1F489", "💉", "Syringe"],
|
|
||||||
["1F4D6", "📚", "Books"],
|
|
||||||
["1F3AF", "🎯", "Archery"],
|
|
||||||
["1F52E", "🔮", "Magic ball"],
|
|
||||||
["1F3AD", "🎭", "Performing arts"],
|
|
||||||
["1F3A8", "🎨", "Artist palette"],
|
|
||||||
["1F457", "👗", "Dress"],
|
|
||||||
["1F451", "👑", "Crown"],
|
|
||||||
["1F48D", "💍", "Ring"],
|
|
||||||
["1F48E", "💎", "Gem"],
|
|
||||||
["1F514", "🔔", "Bell"],
|
|
||||||
["1F3B2", "🎲", "Die"],
|
|
||||||
// black and white icons in FF:
|
|
||||||
["26A0", "⚠", "Alert"],
|
|
||||||
["2317", "⌗", "Hash"],
|
|
||||||
["2318", "⌘", "POI"],
|
|
||||||
["2307", "⌇", "Wavy"],
|
|
||||||
["21E6", "⇦", "Left arrow"],
|
|
||||||
["21E7", "⇧", "Top arrow"],
|
|
||||||
["21E8", "⇨", "Right arrow"],
|
|
||||||
["21E9", "⇩", "Left arrow"],
|
|
||||||
["21F6", "⇶", "Three arrows"],
|
|
||||||
["2699", "⚙", "Gear"],
|
|
||||||
["269B", "⚛", "Atom"],
|
|
||||||
["0024", "$", "Dollar"],
|
|
||||||
["2680", "⚀", "Die1"],
|
|
||||||
["2681", "⚁", "Die2"],
|
|
||||||
["2682", "⚂", "Die3"],
|
|
||||||
["2683", "⚃", "Die4"],
|
|
||||||
["2684", "⚄", "Die5"],
|
|
||||||
["2685", "⚅", "Die6"],
|
|
||||||
["26B4", "⚴", "Pallas"],
|
|
||||||
["26B5", "⚵", "Juno"],
|
|
||||||
["26B6", "⚶", "Vesta"],
|
|
||||||
["26B7", "⚷", "Chiron"],
|
|
||||||
["26B8", "⚸", "Lilith"],
|
|
||||||
["263F", "☿", "Mercury"],
|
|
||||||
["2640", "♀", "Venus"],
|
|
||||||
["2641", "♁", "Earth"],
|
|
||||||
["2642", "♂", "Mars"],
|
|
||||||
["2643", "♃", "Jupiter"],
|
|
||||||
["2644", "♄", "Saturn"],
|
|
||||||
["2645", "♅", "Uranus"],
|
|
||||||
["2646", "♆", "Neptune"],
|
|
||||||
["2647", "♇", "Pluto"],
|
|
||||||
["26B3", "⚳", "Ceres"],
|
|
||||||
["2654", "♔", "Chess king"],
|
|
||||||
["2655", "♕", "Chess queen"],
|
|
||||||
["2656", "♖", "Chess rook"],
|
|
||||||
["2657", "♗", "Chess bishop"],
|
|
||||||
["2658", "♘", "Chess knight"],
|
|
||||||
["2659", "♙", "Chess pawn"],
|
|
||||||
["2660", "♠", "Spade"],
|
|
||||||
["2663", "♣", "Club"],
|
|
||||||
["2665", "♥", "Heart"],
|
|
||||||
["2666", "♦", "Diamond"],
|
|
||||||
["2698", "⚘", "Flower"],
|
|
||||||
["2625", "☥", "Ankh"],
|
|
||||||
["2626", "☦", "Orthodox"],
|
|
||||||
["2627", "☧", "Chi Rho"],
|
|
||||||
["2628", "☨", "Lorraine"],
|
|
||||||
["2629", "☩", "Jerusalem"],
|
|
||||||
["2670", "♰", "Syriac cross"],
|
|
||||||
["2020", "†", "Dagger"],
|
|
||||||
["262A", "☪", "Muslim"],
|
|
||||||
["262D", "☭", "Soviet"],
|
|
||||||
["262E", "☮", "Peace"],
|
|
||||||
["262F", "☯", "Yin yang"],
|
|
||||||
["26A4", "⚤", "Heterosexuality"],
|
|
||||||
["26A2", "⚢", "Female homosexuality"],
|
|
||||||
["26A3", "⚣", "Male homosexuality"],
|
|
||||||
["26A5", "⚥", "Male and female"],
|
|
||||||
["26AD", "⚭", "Rings"],
|
|
||||||
["2690", "⚐", "White flag"],
|
|
||||||
["2691", "⚑", "Black flag"],
|
|
||||||
["263C", "☼", "Sun"],
|
|
||||||
["263E", "☾", "Moon"],
|
|
||||||
["2668", "♨", "Hot springs"],
|
|
||||||
["2600", "☀", "Black sun"],
|
|
||||||
["2601", "☁", "Cloud"],
|
|
||||||
["2602", "☂", "Umbrella"],
|
|
||||||
["2603", "☃", "Snowman"],
|
|
||||||
["2604", "☄", "Comet"],
|
|
||||||
["2605", "★", "Black star"],
|
|
||||||
["2606", "☆", "White star"],
|
|
||||||
["269D", "⚝", "Outlined star"],
|
|
||||||
["2618", "☘", "Shamrock"],
|
|
||||||
["21AF", "↯", "Lightning"],
|
|
||||||
["269C", "⚜", "FleurDeLis"],
|
|
||||||
["2622", "☢", "Radiation"],
|
|
||||||
["2623", "☣", "Biohazard"],
|
|
||||||
["2620", "☠", "Skull"],
|
|
||||||
["2638", "☸", "Dharma"],
|
|
||||||
["2624", "☤", "Caduceus"],
|
|
||||||
["2695", "⚕", "Aeculapius staff"],
|
|
||||||
["269A", "⚚", "Hermes staff"],
|
|
||||||
["2697", "⚗", "Alembic"],
|
|
||||||
["266B", "♫", "Music"],
|
|
||||||
["2702", "✂", "Scissors"],
|
|
||||||
["2696", "⚖", "Scales"],
|
|
||||||
["2692", "⚒", "Hammer and pick"],
|
|
||||||
["2694", "⚔", "Swords"]
|
|
||||||
];
|
|
||||||
|
|
||||||
let table = document.getElementById("markerIconTable"), row = "";
|
|
||||||
table.addEventListener("click", clickMarkerIconTable, false);
|
|
||||||
table.addEventListener("mouseover", hoverMarkerIconTable, false);
|
|
||||||
|
|
||||||
for (let i=0; i < icons.length; i++) {
|
|
||||||
if (i%20 === 0) row = table.insertRow(0);
|
|
||||||
let cell = row.insertCell(0);
|
|
||||||
let icon = String.fromCodePoint(parseInt(icons[i][0],16));
|
|
||||||
cell.innerHTML = icon;
|
|
||||||
cell.id = "markerIcon" + icon.codePointAt();
|
|
||||||
cell.setAttribute("data-desc", icons[i][2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickMarkerIconTable(e) {
|
|
||||||
if (e.target !== e.currentTarget) {
|
|
||||||
let table = document.getElementById("markerIconTable");
|
|
||||||
let selected = table.getElementsByClassName("selected");
|
|
||||||
if (selected.length) selected[0].removeAttribute("class");
|
|
||||||
e.target.className = "selected";
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
let icon = e.target.innerHTML;
|
|
||||||
d3.select("#defs-markers").select(id).select("text").text(icon);
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hoverMarkerIconTable(e) {
|
|
||||||
if (e.target !== e.currentTarget) {
|
|
||||||
let desc = e.target.getAttribute("data-desc");
|
|
||||||
tip(e.target.innerHTML + " " + desc);
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// change marker icon size
|
|
||||||
document.getElementById("markerIconSize").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("font-size", this.value + "px");
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker icon x shift
|
|
||||||
document.getElementById("markerIconShiftX").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("x", this.value + "%");
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker icon y shift
|
|
||||||
document.getElementById("markerIconShiftY").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("y", this.value + "%");
|
|
||||||
});
|
|
||||||
|
|
||||||
// apply custom unicode icon on input
|
|
||||||
document.getElementById("markerIconCustom").addEventListener("input", function() {
|
|
||||||
if (!this.value) return;
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").text(this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#markerStyleButton").click(function() {
|
|
||||||
$("#markerEditor > button").not(this).toggle();
|
|
||||||
$("#markerStyleButtons").toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker size
|
|
||||||
document.getElementById("markerSize").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("data-id");
|
|
||||||
let used = document.querySelectorAll("use[data-id='"+id+"']");
|
|
||||||
let size = this.value;
|
|
||||||
used.forEach(function(e) {e.setAttribute("data-size", size);});
|
|
||||||
invokeActiveZooming();
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker base color
|
|
||||||
document.getElementById("markerBase").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select(id).select("path").attr("fill", this.value);
|
|
||||||
d3.select(id).select("circle").attr("stroke", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker fill color
|
|
||||||
document.getElementById("markerFill").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select(id).select("circle").attr("fill", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker icon y shift
|
|
||||||
document.getElementById("markerIconFill").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("fill", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker icon y shift
|
|
||||||
document.getElementById("markerIconStrokeWidth").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("stroke-width", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// change marker icon y shift
|
|
||||||
document.getElementById("markerIconStroke").addEventListener("input", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("stroke", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// toggle marker bubble display
|
|
||||||
document.getElementById("markerToggleBubble").addEventListener("click", function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
let show = 1;
|
|
||||||
if (this.className === "icon-info-circled") {
|
|
||||||
this.className = "icon-info";
|
|
||||||
show = 0;
|
|
||||||
} else {
|
} else {
|
||||||
this.className = "icon-info-circled";;
|
burgToggleCapital.disabled = true;
|
||||||
|
d3.select("#burgToggleCapital").classed("pressed", false);
|
||||||
|
}
|
||||||
|
d3.select("#burgTogglePort").classed("pressed", cell.port !== undefined);
|
||||||
|
burgPopulation.value = manors[id].population;
|
||||||
|
burgPopulationFriendly.value = rn(manors[id].population * urbanization.value * populationRate.value * 1000);
|
||||||
|
|
||||||
|
$("#burgEditor").dialog({
|
||||||
|
title: "Edit Burg: " + manors[id].name,
|
||||||
|
minHeight: 30, width: "auto", resizable: false,
|
||||||
|
position: {my: "center top+40", at: "top", of: d3.event},
|
||||||
|
close: function() {
|
||||||
|
d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("drag", null)).classed("draggable", false);
|
||||||
|
elSelected = null;
|
||||||
}
|
}
|
||||||
d3.select(id).select("circle").attr("opacity", show);
|
|
||||||
d3.select(id).select("path").attr("opacity", show);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// open legendsEditor
|
if (modules.editBurg) return;
|
||||||
document.getElementById("markerLegendButton").addEventListener("click", function() {
|
modules.editBurg = true;
|
||||||
let id = elSelected.attr("id");
|
|
||||||
let symbol = elSelected.attr("href");
|
loadDefaultFonts();
|
||||||
let icon = d3.select("#defs-markers").select(symbol).select("text").text();
|
|
||||||
let name = "Marker " + icon;
|
function updateBurgsGroupOptions() {
|
||||||
editLegends(id, name);
|
burgSelectGroup.innerHTML = "";
|
||||||
|
burgIcons.selectAll("g").each(function(d) {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = opt.innerHTML = d3.select(this).attr("id");
|
||||||
|
burgSelectGroup.add(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#burgEditor > button").not("#burgAddfromEditor").not("#burgRelocate").not("#burgRemove").click(function() {
|
||||||
|
if ($(this).next().is(":visible")) {
|
||||||
|
$("#burgEditor > button").show();
|
||||||
|
$(this).next("div").hide();
|
||||||
|
} else {
|
||||||
|
$("#burgEditor > *").not(this).hide();
|
||||||
|
$(this).next("div").show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// click on master button to add new markers on click
|
$("#burgEditor > div > button").click(function() {
|
||||||
document.getElementById("markerAdd").addEventListener("click", function() {
|
if ($(this).next().is(":visible")) {
|
||||||
document.getElementById("addMarker").click();
|
$("#burgEditor > div > button").show();
|
||||||
|
$(this).parent().prev().show();
|
||||||
|
$(this).next("div").hide();
|
||||||
|
} else {
|
||||||
|
$("#burgEditor > div > button").not(this).hide();
|
||||||
|
$(this).parent().prev().hide();
|
||||||
|
$(this).next("div").show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove marker on click
|
$("#burgSelectGroup").change(function() {
|
||||||
document.getElementById("markerRemove").addEventListener("click", function() {
|
const id = +elSelected.attr("data-id");
|
||||||
alertMessage.innerHTML = "Are you sure you want to remove the marker?";
|
const g = this.value;
|
||||||
$("#alert").dialog({resizable: false, title: "Remove marker",
|
moveBurgToGroup(id, g);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgInputGroup").change(function() {
|
||||||
|
let newGroup = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, "");
|
||||||
|
if (Number.isFinite(+newGroup.charAt(0))) newGroup = "g" + newGroup;
|
||||||
|
if (burgLabels.select("#"+newGroup).size()) {
|
||||||
|
tip('The group "'+ newGroup + '" is already exists');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
burgInputGroup.value = "";
|
||||||
|
// clone old group assigning new id
|
||||||
|
const id = elSelected.node().parentNode.id;
|
||||||
|
const l = burgLabels.select("#"+id).node().cloneNode(false);
|
||||||
|
l.id = newGroup;
|
||||||
|
const i = burgIcons.select("#"+id).node().cloneNode(false);
|
||||||
|
i.id = newGroup;
|
||||||
|
burgLabels.node().insertBefore(l, null);
|
||||||
|
burgIcons.node().insertBefore(i, null);
|
||||||
|
// select new group
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = opt.innerHTML = newGroup;
|
||||||
|
burgSelectGroup.add(opt);
|
||||||
|
$("#burgSelectGroup").val(newGroup).change();
|
||||||
|
$("#burgSelectGroup, #burgInputGroup").toggle();
|
||||||
|
updateLabelGroups();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgAddGroup").click(function() {
|
||||||
|
if ($("#burgInputGroup").css("display") === "none") {
|
||||||
|
$("#burgInputGroup").css("display", "inline-block");
|
||||||
|
$("#burgSelectGroup").css("display", "none");
|
||||||
|
burgInputGroup.focus();
|
||||||
|
} else {
|
||||||
|
$("#burgSelectGroup").css("display", "inline-block");
|
||||||
|
$("#burgInputGroup").css("display", "none");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgRemoveGroup").click(function() {
|
||||||
|
const group = d3.select(elSelected.node().parentNode);
|
||||||
|
const type = group.attr("id");
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const count = group.selectAll("*").size();
|
||||||
|
const message = "Are you sure you want to remove all Burgs (" + count + ") of that group?";
|
||||||
|
alertMessage.innerHTML = message;
|
||||||
|
$("#alert").dialog({resizable: false, title: "Remove Burgs",
|
||||||
buttons: {
|
buttons: {
|
||||||
Remove: function() {
|
Remove: function() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
elSelected.remove();
|
group.selectAll("*").each(function(d) {
|
||||||
$("#markerEditor").dialog("close");
|
const id = +d3.select(this).attr("data-id");
|
||||||
|
if (id === undefined) return;
|
||||||
|
const cell = manors[id].cell;
|
||||||
|
const state = manors[id].region;
|
||||||
|
if (states[state]) {
|
||||||
|
if (states[state].capital === id) states[state].capital = "select";
|
||||||
|
states[state].burgs --;
|
||||||
|
}
|
||||||
|
manors[id].region = "removed";
|
||||||
|
cells[cell].manor = undefined;
|
||||||
|
});
|
||||||
|
burgLabels.select("#"+type).selectAll("*").remove();
|
||||||
|
burgIcons.select("#"+type).selectAll("*").remove();
|
||||||
|
$("#icons g[id*='anchors'] [data-id=" + id + "]").parent().children().remove();
|
||||||
|
closeDialogs(".stable");
|
||||||
|
updateCountryEditors();
|
||||||
|
$("#burgEditor").dialog("close");
|
||||||
},
|
},
|
||||||
Cancel: function() {$(this).dialog("close");}
|
Cancel: function() {$(this).dialog("close");}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgNameInput").on("input", function() {
|
||||||
|
if (this.value === "") {
|
||||||
|
tip("Name should not be blank, set opacity to 0 to hide label or remove button to delete");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
burgLabels.selectAll("[data-id='" + id + "']").text(this.value);
|
||||||
|
manors[id].name = this.value;
|
||||||
|
$("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgNameReCulture, #burgNameReRandom").click(function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const culture = this.id === "burgNameReCulture" ? manors[id].culture : Math.floor(Math.random() * cultures.length);
|
||||||
|
const name = generateName(culture);
|
||||||
|
burgLabels.selectAll("[data-id='" + id + "']").text(name);
|
||||||
|
manors[id].name = name;
|
||||||
|
burgNameInput.value = name;
|
||||||
|
$("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + name);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgToggleExternalFont").click(function() {
|
||||||
|
if ($("#burgInputExternalFont").css("display") === "none") {
|
||||||
|
$("#burgInputExternalFont").css("display", "inline-block");
|
||||||
|
$("#burgSelectDefaultFont").css("display", "none");
|
||||||
|
burgInputExternalFont.focus();
|
||||||
|
} else {
|
||||||
|
$("#burgSelectDefaultFont").css("display", "inline-block");
|
||||||
|
$("#burgInputExternalFont").css("display", "none");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgSelectDefaultFont").change(function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgLabels.select("#"+type);
|
||||||
|
if (burgSelectDefaultFont.value === "") return;
|
||||||
|
const font = fonts[burgSelectDefaultFont.value].split(':')[0].replace(/\+/g, " ");
|
||||||
|
group.attr("font-family", font).attr("data-font", fonts[burgSelectDefaultFont.value]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgInputExternalFont").change(function() {
|
||||||
|
fetchFonts(this.value).then(fetched => {
|
||||||
|
if (!fetched) return;
|
||||||
|
burgToggleExternalFont.click();
|
||||||
|
burgInputExternalFont.value = "";
|
||||||
|
if (fetched === 1) $("#burgSelectDefaultFont").val(fonts.length - 1).change();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgSetLabelSize").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgLabels.select("#"+type);
|
||||||
|
group.attr("data-size", +this.value);
|
||||||
|
invokeActiveZooming();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgLabelColorInput").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgLabels.select("#"+type);
|
||||||
|
group.attr("fill", this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgLabelOpacity").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgLabels.select("#"+type);
|
||||||
|
group.attr("opacity", +this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgLabelAngle").on("input", function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const el = burgLabels.select("[data-id='"+ id +"']");
|
||||||
|
const tr = parseTransform(el.attr("transform"));
|
||||||
|
const c = el.node().getBBox();
|
||||||
|
burgLabelAngleOutput.innerHTML = Math.abs(+this.value) + "°";
|
||||||
|
const angle = +this.value;
|
||||||
|
const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`;
|
||||||
|
el.attr("transform", transform);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconSize").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
const size = +this.value;
|
||||||
|
group.attr("size", size);
|
||||||
|
group.selectAll("*").each(function() {d3.select(this).attr("r", size)});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconFillOpacity").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
group.attr("fill-opacity", +this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconFillColor").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
group.attr("fill", this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconStrokeWidth").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
group.attr("stroke-width", +this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconStrokeOpacity").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
group.attr("stroke-opacity", +this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgIconStrokeColor").on("input", function() {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const group = burgIcons.select("#"+type);
|
||||||
|
group.attr("stroke", this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgToggleCapital").click(function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const state = manors[id].region;
|
||||||
|
if (states[state] === undefined) return;
|
||||||
|
const capital = states[manors[id].region] ? id === states[manors[id].region].capital ? 0 : 1 : 1;
|
||||||
|
if (capital && states[state].capital !== "select") {
|
||||||
|
// move oldCapital to a town group
|
||||||
|
const oldCapital = states[state].capital;
|
||||||
|
moveBurgToGroup(oldCapital, "towns");
|
||||||
|
}
|
||||||
|
states[state].capital = capital ? id : "select";
|
||||||
|
d3.select("#burgToggleCapital").classed("pressed", capital);
|
||||||
|
const g = capital ? "capitals" : "towns";
|
||||||
|
moveBurgToGroup(id, g);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgTogglePort").click(function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const cell = cells[manors[id].cell];
|
||||||
|
const markAsPort = cell.port === undefined ? true : undefined;
|
||||||
|
cell.port = markAsPort;
|
||||||
|
d3.select("#burgTogglePort").classed("pressed", markAsPort);
|
||||||
|
if (markAsPort) {
|
||||||
|
const type = elSelected.node().parentNode.id;
|
||||||
|
const ag = type === "capitals" ? "#capital-anchors" : "#town-anchors";
|
||||||
|
const group = icons.select(ag);
|
||||||
|
const size = +group.attr("size");
|
||||||
|
const x = rn(manors[id].x - size * 0.47, 2);
|
||||||
|
const y = rn(manors[id].y - size * 0.47, 2);
|
||||||
|
group.append("use").attr("xlink:href", "#icon-anchor").attr("data-id", id)
|
||||||
|
.attr("x", x).attr("y", y).attr("width", size).attr("height", size)
|
||||||
|
.on("click", editIcon);
|
||||||
|
} else {
|
||||||
|
$("#icons g[id*='anchors'] [data-id=" + id + "]").remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgPopulation").on("input", function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
burgPopulationFriendly.value = rn(this.value * urbanization.value * populationRate.value * 1000);
|
||||||
|
manors[id].population = +this.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgRelocate").click(function() {
|
||||||
|
if ($(this).hasClass('pressed')) {
|
||||||
|
$(".pressed").removeClass('pressed');
|
||||||
|
restoreDefaultEvents();
|
||||||
|
tip("", true);
|
||||||
|
} else {
|
||||||
|
$(".pressed").removeClass('pressed');
|
||||||
|
const id = elSelected.attr("data-id");
|
||||||
|
$(this).addClass('pressed').attr("data-id", id);
|
||||||
|
viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick);
|
||||||
|
tip("Click on map to relocate burg. Hold Shift for continuous move", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// open legendsEditor
|
||||||
|
document.getElementById("burglLegend").addEventListener("click", function() {
|
||||||
|
let burg = +elSelected.attr("data-id");
|
||||||
|
let id = "burg" + burg;
|
||||||
|
let name = manors[burg].name;
|
||||||
|
editLegends(id, name);
|
||||||
|
});
|
||||||
|
|
||||||
|
// move burg to a different cell
|
||||||
|
function relocateBurgOnClick() {
|
||||||
|
const point = d3.mouse(this);
|
||||||
|
const index = getIndex(point);
|
||||||
|
const i = +$("#burgRelocate").attr("data-id");
|
||||||
|
if (isNaN(i) || !manors[i]) return;
|
||||||
|
|
||||||
|
if (cells[index].height < 20) {
|
||||||
|
tip("Cannot place burg in the water! Select a land cell", null, "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cells[index].manor !== undefined && cells[index].manor !== i) {
|
||||||
|
tip("There is already a burg in this cell. Please select a free cell", null, "error");
|
||||||
|
$('#grid').fadeIn();
|
||||||
|
d3.select("#toggleGrid").classed("buttonoff", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let region = cells[index].region;
|
||||||
|
const oldRegion = manors[i].region;
|
||||||
|
// relocating capital to other country you "conquer" target cell
|
||||||
|
if (states[oldRegion] && states[oldRegion].capital === i) {
|
||||||
|
if (region !== oldRegion) {
|
||||||
|
tip("Capital cannot be moved to another country!", null, "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d3.event.shiftKey === false) {
|
||||||
|
$("#burgRelocate").removeClass("pressed");
|
||||||
|
restoreDefaultEvents();
|
||||||
|
tip("", true);
|
||||||
|
if (region !== oldRegion) {
|
||||||
|
recalculateStateData(oldRegion);
|
||||||
|
recalculateStateData(region);
|
||||||
|
updateCountryEditors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = rn(point[0],2), y = rn(point[1],2);
|
||||||
|
burgIcons.select("circle[data-id='"+i+"']").attr("transform", null).attr("cx", x).attr("cy", y);
|
||||||
|
burgLabels.select("text[data-id='"+i+"']").attr("transform", null).attr("x", x).attr("y", y);
|
||||||
|
const anchor = icons.select("use[data-id='"+i+"']");
|
||||||
|
if (anchor.size()) {
|
||||||
|
const size = anchor.attr("width");
|
||||||
|
const xa = rn(x - size * 0.47, 2);
|
||||||
|
const ya = rn(y - size * 0.47, 2);
|
||||||
|
anchor.attr("transform", null).attr("x", xa).attr("y", ya);
|
||||||
|
}
|
||||||
|
cells[index].manor = i;
|
||||||
|
cells[manors[i].cell].manor = undefined;
|
||||||
|
manors[i].x = x, manors[i].y = y, manors[i].region = region, manors[i].cell = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open in MFCG
|
||||||
|
$("#burgSeeInMFCG").click(function() {
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
const name = manors[id].name;
|
||||||
|
const cell = manors[id].cell;
|
||||||
|
const pop = rn(manors[id].population);
|
||||||
|
const size = pop > 65 ? 65 : pop < 6 ? 6 : pop;
|
||||||
|
const s = seed + "" + id;
|
||||||
|
const hub = cells[cell].crossroad > 2 ? 1 : 0;
|
||||||
|
const river = cells[cell].river ? 1 : 0;
|
||||||
|
const coast = cells[cell].port !== undefined ? 1 : 0;
|
||||||
|
const sec = pop > 40 ? 1 : Math.random() < pop / 100 ? 1 : 0;
|
||||||
|
const thr = sec && Math.random() < 0.8 ? 1 : 0;
|
||||||
|
const url = "http://fantasycities.watabou.ru/";
|
||||||
|
let params = `?name=${name}&size=${size}&seed=${s}&hub=${hub}&random=0&continuous=0`;
|
||||||
|
params += `&river=${river}&coast=${coast}&citadel=${id&1}&plaza=${sec}&temple=${thr}&walls=${sec}&shantytown=${sec}`;
|
||||||
|
const win = window.open(url+params, '_blank');
|
||||||
|
win.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgAddfromEditor").click(function() {
|
||||||
|
clickToAdd(); // to load on click event function
|
||||||
|
$("#addBurg").click();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#burgRemove").click(function() {
|
||||||
|
alertMessage.innerHTML = `Are you sure you want to remove the Burg?`;
|
||||||
|
$("#alert").dialog({resizable: false, title: "Remove Burg",
|
||||||
|
buttons: {
|
||||||
|
Remove: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
const id = +elSelected.attr("data-id");
|
||||||
|
d3.selectAll("[data-id='" + id + "']").remove();
|
||||||
|
const cell = manors[id].cell;
|
||||||
|
const state = manors[id].region;
|
||||||
|
if (states[state]) {
|
||||||
|
if (states[state].capital === id) states[state].capital = "select";
|
||||||
|
states[state].burgs --;
|
||||||
|
}
|
||||||
|
manors[id].region = "removed";
|
||||||
|
cells[cell].manor = undefined;
|
||||||
|
closeDialogs(".stable");
|
||||||
|
updateCountryEditors();
|
||||||
|
},
|
||||||
|
Cancel: function() {$(this).dialog("close");}
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,154 +1,3 @@
|
||||||
function addRoutePoint(point) {
|
|
||||||
const controlPoints = debug.select(".controlPoints").size()
|
|
||||||
? debug.select(".controlPoints")
|
|
||||||
: debug.append("g").attr("class", "controlPoints");
|
|
||||||
controlPoints.append("circle")
|
|
||||||
.attr("cx", point.x).attr("cy", point.y).attr("r", 0.35)
|
|
||||||
.call(d3.drag().on("drag", routePointDrag))
|
|
||||||
.on("click", function(d) {
|
|
||||||
if ($("#routeSplit").hasClass('pressed')) {
|
|
||||||
routeSplitInPoint(this);
|
|
||||||
} else {
|
|
||||||
$(this).remove();
|
|
||||||
routeRedraw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function routePointDrag() {
|
|
||||||
d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
|
|
||||||
routeRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
function routeRedraw() {
|
|
||||||
let points = [];
|
|
||||||
debug.select(".controlPoints").selectAll("circle").each(function() {
|
|
||||||
const el = d3.select(this);
|
|
||||||
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
|
||||||
});
|
|
||||||
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
|
||||||
elSelected.attr("d", lineGen(points));
|
|
||||||
// get route distance
|
|
||||||
const l = elSelected.node().getTotalLength();
|
|
||||||
routeLength.innerHTML = rn(l * distanceScale.value) + " " + distanceUnit.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addNewRoute() {
|
|
||||||
let routeType = elSelected && elSelected.node() ? elSelected.node().parentNode.id : "searoutes";
|
|
||||||
const group = routes.select("#"+routeType);
|
|
||||||
const id = routeType + "" + group.selectAll("*").size();
|
|
||||||
elSelected = group.append("path").attr("data-route", "new").attr("id", id).on("click", editRoute);
|
|
||||||
routeUpdateGroups();
|
|
||||||
$("#routeEditor").dialog({
|
|
||||||
title: "Edit Route", minHeight: 30, width: "auto", resizable: false,
|
|
||||||
close: function() {
|
|
||||||
if ($("#addRoute").hasClass('pressed')) completeNewRoute();
|
|
||||||
if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed');
|
|
||||||
unselect();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function newRouteAddPoint() {
|
|
||||||
const point = d3.mouse(this);
|
|
||||||
const x = rn(point[0],2), y = rn(point[1],2);
|
|
||||||
addRoutePoint({x, y});
|
|
||||||
routeRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
function completeNewRoute() {
|
|
||||||
$("#routeNew, #addRoute").removeClass('pressed');
|
|
||||||
restoreDefaultEvents();
|
|
||||||
if (!elSelected.size()) return;
|
|
||||||
if (elSelected.attr("data-route") === "new") {
|
|
||||||
routeRedraw();
|
|
||||||
elSelected.attr("data-route", "");
|
|
||||||
const node = elSelected.node();
|
|
||||||
const l = node.getTotalLength();
|
|
||||||
let pathCells = [];
|
|
||||||
for (let i = 0; i <= l; i ++) {
|
|
||||||
const p = node.getPointAtLength(i);
|
|
||||||
const cell = diagram.find(p.x, p.y);
|
|
||||||
if (!cell) {return;}
|
|
||||||
pathCells.push(cell.index);
|
|
||||||
}
|
|
||||||
const uniqueCells = [...new Set(pathCells)];
|
|
||||||
uniqueCells.map(function(c) {
|
|
||||||
if (cells[c].path !== undefined) {cells[c].path += 1;}
|
|
||||||
else {cells[c].path = 1;}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tip("", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function routeUpdateGroups() {
|
|
||||||
routeGroup.innerHTML = "";
|
|
||||||
routes.selectAll("g").each(function() {
|
|
||||||
const opt = document.createElement("option");
|
|
||||||
opt.value = opt.innerHTML = this.id;
|
|
||||||
routeGroup.add(opt);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function routeSplitInPoint(clicked) {
|
|
||||||
const group = d3.select(elSelected.node().parentNode);
|
|
||||||
$("#routeSplit").removeClass('pressed');
|
|
||||||
const points1 = [],points2 = [];
|
|
||||||
let points = points1;
|
|
||||||
debug.select(".controlPoints").selectAll("circle").each(function() {
|
|
||||||
const el = d3.select(this);
|
|
||||||
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
|
||||||
if (this === clicked) {
|
|
||||||
points = points2;
|
|
||||||
points.push({scX: +el.attr("cx"), scY: +el.attr("cy")});
|
|
||||||
}
|
|
||||||
el.remove();
|
|
||||||
});
|
|
||||||
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
|
||||||
elSelected.attr("d", lineGen(points1));
|
|
||||||
const id = routeGroup.value + "" + group.selectAll("*").size();
|
|
||||||
group.append("path").attr("id", id).attr("d", lineGen(points2)).on("click", editRoute);
|
|
||||||
routeDrawPoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#routeGroup").change(function() {
|
|
||||||
$(elSelected.node()).detach().appendTo($("#"+this.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
// open legendsEditor
|
|
||||||
document.getElementById("routeLegend").addEventListener("click", function() {
|
|
||||||
let id = elSelected.attr("id");
|
|
||||||
editLegends(id, id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#routeNew").click(function() {
|
|
||||||
if ($(this).hasClass('pressed')) {
|
|
||||||
completeNewRoute();
|
|
||||||
} else {
|
|
||||||
// enter creation mode
|
|
||||||
$(".pressed").removeClass('pressed');
|
|
||||||
$("#routeNew, #addRoute").addClass('pressed');
|
|
||||||
debug.select(".controlPoints").selectAll("*").remove();
|
|
||||||
addNewRoute();
|
|
||||||
viewbox.style("cursor", "crosshair").on("click", newRouteAddPoint);
|
|
||||||
tip("Click on map to add route point", true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#routeRemove").click(function() {
|
|
||||||
alertMessage.innerHTML = `Are you sure you want to remove the route?`;
|
|
||||||
$("#alert").dialog({resizable: false, title: "Remove route",
|
|
||||||
buttons: {
|
|
||||||
Remove: function() {
|
|
||||||
$(this).dialog("close");
|
|
||||||
elSelected.remove();
|
|
||||||
$("#routeEditor").dialog("close");
|
|
||||||
},
|
|
||||||
Cancel: function() {$(this).dialog("close");}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function editIcon() {
|
function editIcon() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
|
|
@ -414,584 +263,3 @@
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function editBurg() {
|
|
||||||
if (customization) return;
|
|
||||||
unselect();
|
|
||||||
closeDialogs("#burgEditor, .stable");
|
|
||||||
elSelected = d3.select(this);
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
if (id === undefined) return;
|
|
||||||
d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("start", elementDrag)).classed("draggable", true);
|
|
||||||
|
|
||||||
// update Burg details
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const labelGroup = burgLabels.select("#"+type);
|
|
||||||
const iconGroup = burgIcons.select("#"+type);
|
|
||||||
burgNameInput.value = manors[id].name;
|
|
||||||
updateBurgsGroupOptions();
|
|
||||||
burgSelectGroup.value = labelGroup.attr("id");
|
|
||||||
burgSelectDefaultFont.value = fonts.indexOf(labelGroup.attr("data-font"));
|
|
||||||
burgSetLabelSize.value = labelGroup.attr("data-size");
|
|
||||||
burgLabelColorInput.value = toHEX(labelGroup.attr("fill"));
|
|
||||||
burgLabelOpacity.value = labelGroup.attr("opacity") === undefined ? 1 : +labelGroup.attr("opacity");
|
|
||||||
const tr = parseTransform(elSelected.attr("transform"));
|
|
||||||
burgLabelAngle.value = tr[2];
|
|
||||||
burgLabelAngleOutput.innerHTML = Math.abs(+tr[2]) + "°";
|
|
||||||
burgIconSize.value = iconGroup.attr("size");
|
|
||||||
burgIconFillOpacity.value = iconGroup.attr("fill-opacity") === undefined ? 1 : +iconGroup.attr("fill-opacity");
|
|
||||||
burgIconFillColor.value = iconGroup.attr("fill");
|
|
||||||
burgIconStrokeWidth.value = iconGroup.attr("stroke-width");
|
|
||||||
burgIconStrokeOpacity.value = iconGroup.attr("stroke-opacity") === undefined ? 1 : +iconGroup.attr("stroke-opacity");
|
|
||||||
burgIconStrokeColor.value = iconGroup.attr("stroke");
|
|
||||||
const cell = cells[manors[id].cell];
|
|
||||||
if (cell.region !== "neutral" && cell.region !== undefined) {
|
|
||||||
burgToggleCapital.disabled = false;
|
|
||||||
const capital = states[manors[id].region] ? id === states[manors[id].region].capital ? 1 : 0 : 0;
|
|
||||||
d3.select("#burgToggleCapital").classed("pressed", capital);
|
|
||||||
} else {
|
|
||||||
burgToggleCapital.disabled = true;
|
|
||||||
d3.select("#burgToggleCapital").classed("pressed", false);
|
|
||||||
}
|
|
||||||
d3.select("#burgTogglePort").classed("pressed", cell.port !== undefined);
|
|
||||||
burgPopulation.value = manors[id].population;
|
|
||||||
burgPopulationFriendly.value = rn(manors[id].population * urbanization.value * populationRate.value * 1000);
|
|
||||||
|
|
||||||
$("#burgEditor").dialog({
|
|
||||||
title: "Edit Burg: " + manors[id].name,
|
|
||||||
minHeight: 30, width: "auto", resizable: false,
|
|
||||||
position: {my: "center top+40", at: "top", of: d3.event},
|
|
||||||
close: function() {
|
|
||||||
d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("drag", null)).classed("draggable", false);
|
|
||||||
elSelected = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (modules.editBurg) return;
|
|
||||||
modules.editBurg = true;
|
|
||||||
|
|
||||||
loadDefaultFonts();
|
|
||||||
|
|
||||||
function updateBurgsGroupOptions() {
|
|
||||||
burgSelectGroup.innerHTML = "";
|
|
||||||
burgIcons.selectAll("g").each(function(d) {
|
|
||||||
const opt = document.createElement("option");
|
|
||||||
opt.value = opt.innerHTML = d3.select(this).attr("id");
|
|
||||||
burgSelectGroup.add(opt);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#burgEditor > button").not("#burgAddfromEditor").not("#burgRelocate").not("#burgRemove").click(function() {
|
|
||||||
if ($(this).next().is(":visible")) {
|
|
||||||
$("#burgEditor > button").show();
|
|
||||||
$(this).next("div").hide();
|
|
||||||
} else {
|
|
||||||
$("#burgEditor > *").not(this).hide();
|
|
||||||
$(this).next("div").show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgEditor > div > button").click(function() {
|
|
||||||
if ($(this).next().is(":visible")) {
|
|
||||||
$("#burgEditor > div > button").show();
|
|
||||||
$(this).parent().prev().show();
|
|
||||||
$(this).next("div").hide();
|
|
||||||
} else {
|
|
||||||
$("#burgEditor > div > button").not(this).hide();
|
|
||||||
$(this).parent().prev().hide();
|
|
||||||
$(this).next("div").show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgSelectGroup").change(function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const g = this.value;
|
|
||||||
moveBurgToGroup(id, g);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgInputGroup").change(function() {
|
|
||||||
let newGroup = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, "");
|
|
||||||
if (Number.isFinite(+newGroup.charAt(0))) newGroup = "g" + newGroup;
|
|
||||||
if (burgLabels.select("#"+newGroup).size()) {
|
|
||||||
tip('The group "'+ newGroup + '" is already exists');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
burgInputGroup.value = "";
|
|
||||||
// clone old group assigning new id
|
|
||||||
const id = elSelected.node().parentNode.id;
|
|
||||||
const l = burgLabels.select("#"+id).node().cloneNode(false);
|
|
||||||
l.id = newGroup;
|
|
||||||
const i = burgIcons.select("#"+id).node().cloneNode(false);
|
|
||||||
i.id = newGroup;
|
|
||||||
burgLabels.node().insertBefore(l, null);
|
|
||||||
burgIcons.node().insertBefore(i, null);
|
|
||||||
// select new group
|
|
||||||
const opt = document.createElement("option");
|
|
||||||
opt.value = opt.innerHTML = newGroup;
|
|
||||||
burgSelectGroup.add(opt);
|
|
||||||
$("#burgSelectGroup").val(newGroup).change();
|
|
||||||
$("#burgSelectGroup, #burgInputGroup").toggle();
|
|
||||||
updateLabelGroups();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgAddGroup").click(function() {
|
|
||||||
if ($("#burgInputGroup").css("display") === "none") {
|
|
||||||
$("#burgInputGroup").css("display", "inline-block");
|
|
||||||
$("#burgSelectGroup").css("display", "none");
|
|
||||||
burgInputGroup.focus();
|
|
||||||
} else {
|
|
||||||
$("#burgSelectGroup").css("display", "inline-block");
|
|
||||||
$("#burgInputGroup").css("display", "none");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgRemoveGroup").click(function() {
|
|
||||||
const group = d3.select(elSelected.node().parentNode);
|
|
||||||
const type = group.attr("id");
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const count = group.selectAll("*").size();
|
|
||||||
const message = "Are you sure you want to remove all Burgs (" + count + ") of that group?";
|
|
||||||
alertMessage.innerHTML = message;
|
|
||||||
$("#alert").dialog({resizable: false, title: "Remove Burgs",
|
|
||||||
buttons: {
|
|
||||||
Remove: function() {
|
|
||||||
$(this).dialog("close");
|
|
||||||
group.selectAll("*").each(function(d) {
|
|
||||||
const id = +d3.select(this).attr("data-id");
|
|
||||||
if (id === undefined) return;
|
|
||||||
const cell = manors[id].cell;
|
|
||||||
const state = manors[id].region;
|
|
||||||
if (states[state]) {
|
|
||||||
if (states[state].capital === id) states[state].capital = "select";
|
|
||||||
states[state].burgs --;
|
|
||||||
}
|
|
||||||
manors[id].region = "removed";
|
|
||||||
cells[cell].manor = undefined;
|
|
||||||
});
|
|
||||||
burgLabels.select("#"+type).selectAll("*").remove();
|
|
||||||
burgIcons.select("#"+type).selectAll("*").remove();
|
|
||||||
$("#icons g[id*='anchors'] [data-id=" + id + "]").parent().children().remove();
|
|
||||||
closeDialogs(".stable");
|
|
||||||
updateCountryEditors();
|
|
||||||
$("#burgEditor").dialog("close");
|
|
||||||
},
|
|
||||||
Cancel: function() {$(this).dialog("close");}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgNameInput").on("input", function() {
|
|
||||||
if (this.value === "") {
|
|
||||||
tip("Name should not be blank, set opacity to 0 to hide label or remove button to delete");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
burgLabels.selectAll("[data-id='" + id + "']").text(this.value);
|
|
||||||
manors[id].name = this.value;
|
|
||||||
$("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgNameReCulture, #burgNameReRandom").click(function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const culture = this.id === "burgNameReCulture" ? manors[id].culture : Math.floor(Math.random() * cultures.length);
|
|
||||||
const name = generateName(culture);
|
|
||||||
burgLabels.selectAll("[data-id='" + id + "']").text(name);
|
|
||||||
manors[id].name = name;
|
|
||||||
burgNameInput.value = name;
|
|
||||||
$("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + name);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgToggleExternalFont").click(function() {
|
|
||||||
if ($("#burgInputExternalFont").css("display") === "none") {
|
|
||||||
$("#burgInputExternalFont").css("display", "inline-block");
|
|
||||||
$("#burgSelectDefaultFont").css("display", "none");
|
|
||||||
burgInputExternalFont.focus();
|
|
||||||
} else {
|
|
||||||
$("#burgSelectDefaultFont").css("display", "inline-block");
|
|
||||||
$("#burgInputExternalFont").css("display", "none");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgSelectDefaultFont").change(function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgLabels.select("#"+type);
|
|
||||||
if (burgSelectDefaultFont.value === "") return;
|
|
||||||
const font = fonts[burgSelectDefaultFont.value].split(':')[0].replace(/\+/g, " ");
|
|
||||||
group.attr("font-family", font).attr("data-font", fonts[burgSelectDefaultFont.value]);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgInputExternalFont").change(function() {
|
|
||||||
fetchFonts(this.value).then(fetched => {
|
|
||||||
if (!fetched) return;
|
|
||||||
burgToggleExternalFont.click();
|
|
||||||
burgInputExternalFont.value = "";
|
|
||||||
if (fetched === 1) $("#burgSelectDefaultFont").val(fonts.length - 1).change();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgSetLabelSize").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgLabels.select("#"+type);
|
|
||||||
group.attr("data-size", +this.value);
|
|
||||||
invokeActiveZooming();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgLabelColorInput").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgLabels.select("#"+type);
|
|
||||||
group.attr("fill", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgLabelOpacity").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgLabels.select("#"+type);
|
|
||||||
group.attr("opacity", +this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgLabelAngle").on("input", function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const el = burgLabels.select("[data-id='"+ id +"']");
|
|
||||||
const tr = parseTransform(el.attr("transform"));
|
|
||||||
const c = el.node().getBBox();
|
|
||||||
burgLabelAngleOutput.innerHTML = Math.abs(+this.value) + "°";
|
|
||||||
const angle = +this.value;
|
|
||||||
const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`;
|
|
||||||
el.attr("transform", transform);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconSize").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
const size = +this.value;
|
|
||||||
group.attr("size", size);
|
|
||||||
group.selectAll("*").each(function() {d3.select(this).attr("r", size)});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconFillOpacity").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
group.attr("fill-opacity", +this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconFillColor").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
group.attr("fill", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconStrokeWidth").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
group.attr("stroke-width", +this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconStrokeOpacity").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
group.attr("stroke-opacity", +this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgIconStrokeColor").on("input", function() {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const group = burgIcons.select("#"+type);
|
|
||||||
group.attr("stroke", this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgToggleCapital").click(function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const state = manors[id].region;
|
|
||||||
if (states[state] === undefined) return;
|
|
||||||
const capital = states[manors[id].region] ? id === states[manors[id].region].capital ? 0 : 1 : 1;
|
|
||||||
if (capital && states[state].capital !== "select") {
|
|
||||||
// move oldCapital to a town group
|
|
||||||
const oldCapital = states[state].capital;
|
|
||||||
moveBurgToGroup(oldCapital, "towns");
|
|
||||||
}
|
|
||||||
states[state].capital = capital ? id : "select";
|
|
||||||
d3.select("#burgToggleCapital").classed("pressed", capital);
|
|
||||||
const g = capital ? "capitals" : "towns";
|
|
||||||
moveBurgToGroup(id, g);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgTogglePort").click(function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const cell = cells[manors[id].cell];
|
|
||||||
const markAsPort = cell.port === undefined ? true : undefined;
|
|
||||||
cell.port = markAsPort;
|
|
||||||
d3.select("#burgTogglePort").classed("pressed", markAsPort);
|
|
||||||
if (markAsPort) {
|
|
||||||
const type = elSelected.node().parentNode.id;
|
|
||||||
const ag = type === "capitals" ? "#capital-anchors" : "#town-anchors";
|
|
||||||
const group = icons.select(ag);
|
|
||||||
const size = +group.attr("size");
|
|
||||||
const x = rn(manors[id].x - size * 0.47, 2);
|
|
||||||
const y = rn(manors[id].y - size * 0.47, 2);
|
|
||||||
group.append("use").attr("xlink:href", "#icon-anchor").attr("data-id", id)
|
|
||||||
.attr("x", x).attr("y", y).attr("width", size).attr("height", size)
|
|
||||||
.on("click", editIcon);
|
|
||||||
} else {
|
|
||||||
$("#icons g[id*='anchors'] [data-id=" + id + "]").remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgPopulation").on("input", function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
burgPopulationFriendly.value = rn(this.value * urbanization.value * populationRate.value * 1000);
|
|
||||||
manors[id].population = +this.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgRelocate").click(function() {
|
|
||||||
if ($(this).hasClass('pressed')) {
|
|
||||||
$(".pressed").removeClass('pressed');
|
|
||||||
restoreDefaultEvents();
|
|
||||||
tip("", true);
|
|
||||||
} else {
|
|
||||||
$(".pressed").removeClass('pressed');
|
|
||||||
const id = elSelected.attr("data-id");
|
|
||||||
$(this).addClass('pressed').attr("data-id", id);
|
|
||||||
viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick);
|
|
||||||
tip("Click on map to relocate burg. Hold Shift for continuous move", true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// open legendsEditor
|
|
||||||
document.getElementById("burglLegend").addEventListener("click", function() {
|
|
||||||
let burg = +elSelected.attr("data-id");
|
|
||||||
let id = "burg" + burg;
|
|
||||||
let name = manors[burg].name;
|
|
||||||
editLegends(id, name);
|
|
||||||
});
|
|
||||||
|
|
||||||
// move burg to a different cell
|
|
||||||
function relocateBurgOnClick() {
|
|
||||||
const point = d3.mouse(this);
|
|
||||||
const index = getIndex(point);
|
|
||||||
const i = +$("#burgRelocate").attr("data-id");
|
|
||||||
if (isNaN(i) || !manors[i]) return;
|
|
||||||
|
|
||||||
if (cells[index].height < 20) {
|
|
||||||
tip("Cannot place burg in the water! Select a land cell", null, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cells[index].manor !== undefined && cells[index].manor !== i) {
|
|
||||||
tip("There is already a burg in this cell. Please select a free cell", null, "error");
|
|
||||||
$('#grid').fadeIn();
|
|
||||||
d3.select("#toggleGrid").classed("buttonoff", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let region = cells[index].region;
|
|
||||||
const oldRegion = manors[i].region;
|
|
||||||
// relocating capital to other country you "conquer" target cell
|
|
||||||
if (states[oldRegion] && states[oldRegion].capital === i) {
|
|
||||||
if (region !== oldRegion) {
|
|
||||||
tip("Capital cannot be moved to another country!", null, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d3.event.shiftKey === false) {
|
|
||||||
$("#burgRelocate").removeClass("pressed");
|
|
||||||
restoreDefaultEvents();
|
|
||||||
tip("", true);
|
|
||||||
if (region !== oldRegion) {
|
|
||||||
recalculateStateData(oldRegion);
|
|
||||||
recalculateStateData(region);
|
|
||||||
updateCountryEditors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const x = rn(point[0],2), y = rn(point[1],2);
|
|
||||||
burgIcons.select("circle[data-id='"+i+"']").attr("transform", null).attr("cx", x).attr("cy", y);
|
|
||||||
burgLabels.select("text[data-id='"+i+"']").attr("transform", null).attr("x", x).attr("y", y);
|
|
||||||
const anchor = icons.select("use[data-id='"+i+"']");
|
|
||||||
if (anchor.size()) {
|
|
||||||
const size = anchor.attr("width");
|
|
||||||
const xa = rn(x - size * 0.47, 2);
|
|
||||||
const ya = rn(y - size * 0.47, 2);
|
|
||||||
anchor.attr("transform", null).attr("x", xa).attr("y", ya);
|
|
||||||
}
|
|
||||||
cells[index].manor = i;
|
|
||||||
cells[manors[i].cell].manor = undefined;
|
|
||||||
manors[i].x = x, manors[i].y = y, manors[i].region = region, manors[i].cell = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open in MFCG
|
|
||||||
$("#burgSeeInMFCG").click(function() {
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
const name = manors[id].name;
|
|
||||||
const cell = manors[id].cell;
|
|
||||||
const pop = rn(manors[id].population);
|
|
||||||
const size = pop > 65 ? 65 : pop < 6 ? 6 : pop;
|
|
||||||
const s = seed + "" + id;
|
|
||||||
const hub = cells[cell].crossroad > 2 ? 1 : 0;
|
|
||||||
const river = cells[cell].river ? 1 : 0;
|
|
||||||
const coast = cells[cell].port !== undefined ? 1 : 0;
|
|
||||||
const sec = pop > 40 ? 1 : Math.random() < pop / 100 ? 1 : 0;
|
|
||||||
const thr = sec && Math.random() < 0.8 ? 1 : 0;
|
|
||||||
const url = "http://fantasycities.watabou.ru/";
|
|
||||||
let params = `?name=${name}&size=${size}&seed=${s}&hub=${hub}&random=0&continuous=0`;
|
|
||||||
params += `&river=${river}&coast=${coast}&citadel=${id&1}&plaza=${sec}&temple=${thr}&walls=${sec}&shantytown=${sec}`;
|
|
||||||
const win = window.open(url+params, '_blank');
|
|
||||||
win.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgAddfromEditor").click(function() {
|
|
||||||
clickToAdd(); // to load on click event function
|
|
||||||
$("#addBurg").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#burgRemove").click(function() {
|
|
||||||
alertMessage.innerHTML = `Are you sure you want to remove the Burg?`;
|
|
||||||
$("#alert").dialog({resizable: false, title: "Remove Burg",
|
|
||||||
buttons: {
|
|
||||||
Remove: function() {
|
|
||||||
$(this).dialog("close");
|
|
||||||
const id = +elSelected.attr("data-id");
|
|
||||||
d3.selectAll("[data-id='" + id + "']").remove();
|
|
||||||
const cell = manors[id].cell;
|
|
||||||
const state = manors[id].region;
|
|
||||||
if (states[state]) {
|
|
||||||
if (states[state].capital === id) states[state].capital = "select";
|
|
||||||
states[state].burgs --;
|
|
||||||
}
|
|
||||||
manors[id].region = "removed";
|
|
||||||
cells[cell].manor = undefined;
|
|
||||||
closeDialogs(".stable");
|
|
||||||
updateCountryEditors();
|
|
||||||
},
|
|
||||||
Cancel: function() {$(this).dialog("close");}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function editMarker() {
|
|
||||||
if (customization) return;
|
|
||||||
|
|
||||||
unselect();
|
|
||||||
closeDialogs("#markerEditor, .stable");
|
|
||||||
elSelected = d3.select(this).call(d3.drag().on("start", elementDrag)).classed("draggable", true);
|
|
||||||
|
|
||||||
$("#markerEditor").dialog({
|
|
||||||
title: "Edit Marker",
|
|
||||||
minHeight: 30, width: "auto", maxWidth: 275, resizable: false,
|
|
||||||
position: {my: "center top+30", at: "bottom", of: d3.event},
|
|
||||||
close: unselect
|
|
||||||
});
|
|
||||||
|
|
||||||
// update inputs
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
let symbol = d3.select("#defs-markers").select(id);
|
|
||||||
let icon = symbol.select("text");
|
|
||||||
markerSelectGroup.value = id.slice(1);
|
|
||||||
markerIconSize.value = parseFloat(icon.attr("font-size"));
|
|
||||||
markerIconShiftX.value = parseFloat(icon.attr("x"));
|
|
||||||
markerIconShiftY.value = parseFloat(icon.attr("y"));
|
|
||||||
markerIconFill.value = icon.attr("fill");
|
|
||||||
markerIconStrokeWidth.value = icon.attr("stroke-width");
|
|
||||||
markerIconStroke.value = icon.attr("stroke");
|
|
||||||
markerSize.value = elSelected.attr("data-size");
|
|
||||||
markerBase.value = symbol.select("path").attr("fill");
|
|
||||||
markerFill.value = symbol.select("circle").attr("fill");
|
|
||||||
let opacity = symbol.select("circle").attr("opacity");
|
|
||||||
markerToggleBubble.className = opacity === "0" ? "icon-info" : "icon-info-circled";
|
|
||||||
|
|
||||||
let table = document.getElementById("markerIconTable");
|
|
||||||
let selected = table.getElementsByClassName("selected");
|
|
||||||
if (selected.length) selected[0].removeAttribute("class");
|
|
||||||
selected = document.querySelectorAll("#markerIcon" + icon.text().codePointAt());
|
|
||||||
if (selected.length) selected[0].className = "selected";
|
|
||||||
markerIconCustom.value = selected.length ? "" : icon.text();
|
|
||||||
|
|
||||||
if (modules.editMarker) return;
|
|
||||||
modules.editMarker = true;
|
|
||||||
|
|
||||||
$("#markerGroup").click(function() {
|
|
||||||
$("#markerEditor > button").not(this).toggle();
|
|
||||||
$("#markerGroupSection").toggle();
|
|
||||||
updateMarkerGroupOptions();
|
|
||||||
});
|
|
||||||
|
|
||||||
function updateMarkerGroupOptions() {
|
|
||||||
markerSelectGroup.innerHTML = "";
|
|
||||||
d3.select("#defs-markers").selectAll("symbol").each(function() {
|
|
||||||
let opt = document.createElement("option");
|
|
||||||
opt.value = opt.innerHTML = this.id;
|
|
||||||
markerSelectGroup.add(opt);
|
|
||||||
});
|
|
||||||
let id = elSelected.attr("href").slice(1);
|
|
||||||
markerSelectGroup.value = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// on add marker type click
|
|
||||||
document.getElementById("markerAddGroup").addEventListener("click", function() {
|
|
||||||
if ($("#markerInputGroup").css("display") === "none") {
|
|
||||||
$("#markerInputGroup").css("display", "inline-block");
|
|
||||||
$("#markerSelectGroup").css("display", "none");
|
|
||||||
markerInputGroup.focus();
|
|
||||||
} else {
|
|
||||||
$("#markerSelectGroup").css("display", "inline-block");
|
|
||||||
$("#markerInputGroup").css("display", "none");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// on marker type change
|
|
||||||
document.getElementById("markerSelectGroup").addEventListener("change", function() {
|
|
||||||
elSelected.attr("href", "#"+this.value);
|
|
||||||
elSelected.attr("data-id", "#"+this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// on new type input
|
|
||||||
document.getElementById("markerInputGroup").addEventListener("change", function() {
|
|
||||||
let newGroup = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, "");
|
|
||||||
if (Number.isFinite(+newGroup.charAt(0))) newGroup = "m" + newGroup;
|
|
||||||
if (d3.select("#defs-markers").select("#"+newGroup).size()) {
|
|
||||||
tip('The type "'+ newGroup + '" is already exists');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
markerInputGroup.value = "";
|
|
||||||
// clone old group assigning new id
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
let l = d3.select("#defs-markers").select(id).node().cloneNode(true);
|
|
||||||
l.id = newGroup;
|
|
||||||
elSelected.attr("href", "#"+newGroup);
|
|
||||||
elSelected.attr("data-id", "#"+newGroup);
|
|
||||||
document.getElementById("defs-markers").insertBefore(l, null);
|
|
||||||
|
|
||||||
// select new group
|
|
||||||
let opt = document.createElement("option");
|
|
||||||
opt.value = opt.innerHTML = newGroup;
|
|
||||||
markerSelectGroup.add(opt);
|
|
||||||
$("#markerSelectGroup").val(newGroup).change();
|
|
||||||
$("#markerSelectGroup, #markerInputGroup").toggle();
|
|
||||||
updateMarkerGroupOptions();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#markerIconButton").click(function() {
|
|
||||||
$("#markerEditor > button").not(this).toggle();
|
|
||||||
$("#markerIconButtons").toggle();
|
|
||||||
if (!$("#markerIconTable").text()) drawIconsList(icons);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#markerRemoveGroup").click(function() {
|
|
||||||
let id = elSelected.attr("href");
|
|
||||||
let used = document.querySelectorAll("use[data-id='"+id+"']");
|
|
||||||
let count = used.length === 1 ? "1 element" : used.length + " elements";
|
|
||||||
const message = "Are you sure you want to remove the marker (" + count + ")?";
|
|
||||||
alertMessage.innerHTML = message;
|
|
||||||
$("#alert").dialog({resizable: false, title: "Remove marker",
|
|
||||||
buttons: {
|
|
||||||
Remove: function() {
|
|
||||||
$(this).dialog("close");
|
|
||||||
if (id !== "#marker0") d3.select("#defs-markers").select(id).remove();
|
|
||||||
used.forEach(function(e) {e.remove();});
|
|
||||||
updateMarkerGroupOptions();
|
|
||||||
$("#markerEditor").dialog("close");
|
|
||||||
},
|
|
||||||
Cancel: function() {$(this).dialog("close");}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue