From 5e09139c86adb5389d8146d7b3e8bf6d588ea24a Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 6 Jun 2020 16:10:46 +0300 Subject: [PATCH 1/4] v1.4.22 --- icons.css | 4 +++ index.html | 15 +++++---- modules/ui/battle-screen.js | 66 ++++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/icons.css b/icons.css index 4a350cc89..2ccbb190d 100644 --- a/icons.css +++ b/icons.css @@ -288,6 +288,10 @@ .icon-button-surprise:before {content:'⚡'; padding-right: .4em;} .icon-button-shock:before {content:'💫'; padding-right: .4em;} + +.icon-button-flee:before {content:'⛵'; padding-right: .4em;} +.icon-button-waiting:before {content:'⌛'; padding-right: .4em;} + .icon-button-maneuvering:before {content:'💢'; padding-right: .4em;} .icon-button-dogfight:before {content:'🐕'; padding-right: .4em;} diff --git a/index.html b/index.html index 824e00af9..d8a46d184 100644 --- a/index.html +++ b/index.html @@ -2481,7 +2481,7 @@ @@ -2512,17 +2512,18 @@ diff --git a/modules/ui/battle-screen.js b/modules/ui/battle-screen.js index b53789efd..e2ad006f2 100644 --- a/modules/ui/battle-screen.js +++ b/modules/ui/battle-screen.js @@ -37,11 +37,11 @@ class Battle { // add listeners document.getElementById("battleType").addEventListener("click", ev => this.toggleChange(ev)); document.getElementById("battleType").nextElementSibling.addEventListener("click", ev => Battle.prototype.context.changeType(ev)); - document.getElementById("battleNameShow").addEventListener("click", () => this.showNameSection()); - document.getElementById("battleNamePlace").addEventListener("change", ev => this.place = ev.target.value); - document.getElementById("battleNameFull").addEventListener("change", ev => this.changeName(ev)); - document.getElementById("battleNameCulture").addEventListener("click", () => this.generateName(Names.getCulture(pack.cells.culture[this.cell], null, null, ""))); - document.getElementById("battleNameRandom").addEventListener("click", () => this.generateName(Names.getBase(rand(nameBases.length-1)))); + document.getElementById("battleNameShow").addEventListener("click", () => Battle.prototype.context.showNameSection()); + document.getElementById("battleNamePlace").addEventListener("change", ev => Battle.prototype.context.place = ev.target.value); + document.getElementById("battleNameFull").addEventListener("change", ev => Battle.prototype.context.changeName(ev)); + document.getElementById("battleNameCulture").addEventListener("click", () => Battle.prototype.context.generateName("culture")); + document.getElementById("battleNameRandom").addEventListener("click", () => Battle.prototype.context.generateName("random")); document.getElementById("battleNameHide").addEventListener("click", this.hideNameSection); document.getElementById("battleAddRegiment").addEventListener("click", this.addSide); document.getElementById("battleRoll").addEventListener("click", () => Battle.prototype.context.randomize()); @@ -136,8 +136,8 @@ class Battle { ${regiment.icon}`; const body = ``; - let initial = `${icon}${regiment.name.slice(0, 24)}`; - let casualties = `${state.fullName.slice(0, 26)}`; + let initial = `${icon}${regiment.name.slice(0, 24)}`; + let casualties = `${state.fullName.slice(0, 26)}`; let survivors = `Distance to base: ${distance} ${distanceUnitInput.value}`; for (const u of options.military) { @@ -239,7 +239,10 @@ class Battle { $("#battleScreen").dialog({"title":this.name}); } - generateName(place) { + generateName(type) { + const place = type === "culture" + ? Names.getCulture(pack.cells.culture[this.cell], null, null, "") + : Names.getBase(rand(nameBases.length-1)); document.getElementById("battleNamePlace").value = this.place = place; document.getElementById("battleNameFull").value = this.name = this.defineName(); $("#battleScreen").dialog({"title":this.name}); @@ -280,8 +283,13 @@ class Battle { "surrendering": {"melee":.1, "ranged":.1, "mounted":.05, "machinery":.01, "naval":.01, "armored":.02, "aviation":.01, "magical":.03}, // reduced // ambush phases - "surprise": {"melee":2.2, "ranged":3, "mounted":1.5, "machinery":1.3, "naval":1, "armored":1.3, "aviation":1, "magical":2}, // increased - "shock": {"melee":.8, "ranged":.8, "mounted":.6, "machinery":.5, "naval":.5, "armored":.1, "aviation":.5, "magical":.7} // reduced + "surprise": {"melee":2, "ranged":2.4, "mounted":1, "machinery":1, "naval":1, "armored":1, "aviation":.8, "magical":1.2}, // increased + "shock": {"melee":.5, "ranged":.5, "mounted":.5, "machinery":.4, "naval":.3, "armored":.1, "aviation":.4, "magical":.5}, // reduced + + // langing phases + "landing": {"melee":.8, "ranged":.6, "mounted":.6, "machinery":.5, "naval":.5, "armored":.5, "aviation":.5, "magical":.6}, // reduced + "flee": {"melee":.1, "ranged":.01, "mounted":.5, "machinery":.01, "naval":.5, "armored":.1, "aviation":.2, "magical":.05}, // reduced + "waiting": {"melee":.05, "ranged":.5, "mounted":.05, "machinery":.5, "naval":2, "armored":.05, "aviation":.5, "magical":.5} // reduced }; const forces = this.getJoinedForces(this[side].regiments); @@ -406,12 +414,27 @@ class Battle { } const getLandingPhase = () => { - // ⚓ landing / 💫 shock OR 🛡️ defense, ⚔️ melee, 🏳️ retreat / 🐎 pursue + const prev = [this.attackers.phase || "landing", this.defenders.phase || "defense"]; // previous phase + + if (prev[1] === "waiting") return ["flee", "waiting"]; + if (prev[1] === "pursue") return ["flee", P(.3) ? "pursue" : "waiting"]; + if (prev[1] === "retreat") return ["pursue", "retreat"]; + + if (prev[0] === "landing") { + const attackers = P(i/2) ? "melee" : "landing"; + const defenders = i ? prev[1] : P(.5) ? "defense" : "shock"; + return [attackers, defenders]; + } + if (P(1 - morale[0] / 40)) return ["flee", "pursue"]; // chance if moral < 40 + if (P(1 - morale[1] / 25)) return ["pursue", "retreat"]; // chance if moral < 25 + + return ["melee", "melee"]; // default option } const getAirBattlePhase = () => { // 🎯 maneuvering, 🐕 dogfight, 🏳️ retreat / 🐎 pursue + } @@ -429,10 +452,14 @@ class Battle { this.attackers.phase = phase[0]; this.defenders.phase = phase[1]; - document.getElementById("battlePhase_attackers").className = "icon-button-" + this.attackers.phase; - document.getElementById("battlePhase_defenders").className = "icon-button-" + this.defenders.phase; - document.getElementById("battlePhase_attackers").dataset.tip = battleBody.querySelector(".battlePhases > [data-phase='"+phase[0]+"']").dataset.tip; - document.getElementById("battlePhase_defenders").dataset.tip = battleBody.querySelector(".battlePhases > [data-phase='"+phase[1]+"']").dataset.tip; + + const buttonA = document.getElementById("battlePhase_attackers"); + buttonA.className = "icon-button-" + this.attackers.phase; + buttonA.dataset.tip = buttonA.nextElementSibling.querySelector("[data-phase='"+phase[0]+"']").dataset.tip; + + const buttonD = document.getElementById("battlePhase_defenders"); + buttonD.className = "icon-button-" + this.defenders.phase; + buttonD.dataset.tip = buttonD.nextElementSibling.querySelector("[data-phase='"+phase[1]+"']").dataset.tip; } run() { @@ -442,19 +469,20 @@ class Battle { // calculate casualties const attack = this.attackers.power * (this.attackers.die / 10 + .4); - const defence = this.defenders.power * (this.defenders.die / 10 + .4); + const defense = this.defenders.power * (this.defenders.die / 10 + .4); // casualties modifier for phase const phase = { "skirmish":.1, "melee":.2, "pursue":.3, "retreat":.3, "boarding":.2, "shelling":.1, "chase":.03, "withdrawal": .03, "blockade":0, "sheltering":0, "sortie":.1, "bombardment":.05, "storming":.2, "defense":.2, "looting":.5, "surrendering":.5, - "surprise":.3, "shock":.3 + "surprise":.3, "shock":.3, + "landing":.3, "flee":0, "waiting":0 }; const casualties = Math.random() * (Math.max(phase[this.attackers.phase], phase[this.defenders.phase])); // total casualties, ~10% per iteration - const casualtiesA = casualties * defence / (attack + defence); // attackers casualties, ~5% per iteration - const casualtiesD = casualties * attack / (attack + defence); // defenders casualties, ~5% per iteration + const casualtiesA = casualties * defense / (attack + defense); // attackers casualties, ~5% per iteration + const casualtiesD = casualties * attack / (attack + defense); // defenders casualties, ~5% per iteration this.calculateCasualties("attackers", casualtiesA); this.calculateCasualties("defenders", casualtiesD); From 7e25012e0f71cecb057e6219d3c5607059ae5813 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 6 Jun 2020 17:13:13 +0300 Subject: [PATCH 2/4] v1.4.23 --- icons.css | 5 ----- modules/ui/battle-screen.js | 38 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/icons.css b/icons.css index 2ccbb190d..eab23067c 100644 --- a/icons.css +++ b/icons.css @@ -271,12 +271,10 @@ .icon-button-skirmish:before {content:'🎯'; padding-right: .4em;} .icon-button-pursue:before {content:'🐎'; padding-right: .4em;} .icon-button-retreat:before {content:'🏳️'; padding-right: .4em;} - .icon-button-shelling:before {content:'💣'; padding-right: .4em;} .icon-button-boarding:before {content:'⚔️'; padding-right: .4em;} .icon-button-chase:before {content:'⛵'; padding-right: .4em;} .icon-button-withdrawal:before {content:'🏳️'; padding-right: .4em;} - .icon-button-bombardment:before {content:'💣'; padding-right: .4em;} .icon-button-blockade:before {content:'⏳'; padding-right: .4em;} .icon-button-sheltering:before {content:'🔒'; padding-right: .4em;} @@ -285,13 +283,10 @@ .icon-button-storming:before {content:'⚔️'; padding-right: .4em;} .icon-button-looting:before {content:'☠️'; padding-right: .4em;} .icon-button-surrendering:before {content:'🏳️'; padding-right: .4em;} - .icon-button-surprise:before {content:'⚡'; padding-right: .4em;} .icon-button-shock:before {content:'💫'; padding-right: .4em;} - .icon-button-flee:before {content:'⛵'; padding-right: .4em;} .icon-button-waiting:before {content:'⌛'; padding-right: .4em;} - .icon-button-maneuvering:before {content:'💢'; padding-right: .4em;} .icon-button-dogfight:before {content:'🐕'; padding-right: .4em;} diff --git a/modules/ui/battle-screen.js b/modules/ui/battle-screen.js index e2ad006f2..6bf2e0c7a 100644 --- a/modules/ui/battle-screen.js +++ b/modules/ui/battle-screen.js @@ -61,19 +61,14 @@ class Battle { const attacker = this.attackers.regiments[0]; const defender = this.defenders.regiments[0]; const getType = () => { - if (attacker.n && defender.n) return "naval"; // attacker and defender are navals - if (!defender.n && pack.burgs[pack.cells.burg[this.cell]].walls) return "siege"; // defender is in walled town - if (P(.1) && [5,6,7,8,9,12].includes(pack.cells.biome[this.cell])) return "ambush"; // 20% if defenders are in forest or marshes - const typesA = Object.keys(attacker.u).map(name => options.military.find(u => u.name === name).type); const typesD = Object.keys(defender.u).map(name => options.military.find(u => u.name === name).type); - // if attacked is naval with non-naval units and defender is not naval - if (attacker.n && !defender.n && typesA.some(t => t !== "naval")) return "landing"; - - // if attacked and defender have only aviation units - if (typesA.every(t => t === "aviation") && typesD.every(t => t === "aviation")) return "air"; - + if (attacker.n && defender.n) return "naval"; // attacker and defender are navals + if (typesA.every(t => t === "aviation") && typesD.every(t => t === "aviation")) return "air"; // if attacked and defender have only aviation units + if (attacker.n && !defender.n && typesA.some(t => t !== "naval")) return "landing"; // if attacked is naval with non-naval units and defender is not naval + if (!defender.n && pack.burgs[pack.cells.burg[this.cell]].walls) return "siege"; // defender is in walled town + if (P(.1) && [5,6,7,8,9,12].includes(pack.cells.biome[this.cell])) return "ambush"; // 20% if defenders are in forest or marshes return "field"; } @@ -289,7 +284,11 @@ class Battle { // langing phases "landing": {"melee":.8, "ranged":.6, "mounted":.6, "machinery":.5, "naval":.5, "armored":.5, "aviation":.5, "magical":.6}, // reduced "flee": {"melee":.1, "ranged":.01, "mounted":.5, "machinery":.01, "naval":.5, "armored":.1, "aviation":.2, "magical":.05}, // reduced - "waiting": {"melee":.05, "ranged":.5, "mounted":.05, "machinery":.5, "naval":2, "armored":.05, "aviation":.5, "magical":.5} // reduced + "waiting": {"melee":.05, "ranged":.5, "mounted":.05, "machinery":.5, "naval":2, "armored":.05, "aviation":.5, "magical":.5}, // reduced + + // air battle phases + "maneuvering": {"melee":0, "ranged":.1, "mounted":0, "machinery":.2, "naval":0, "armored":0, "aviation":1, "magical":.2}, // aviation + "dogfight": {"melee":0, "ranged":.1, "mounted":0, "machinery":.1, "naval":0, "armored":0, "aviation":2, "magical":.1} // aviation }; const forces = this.getJoinedForces(this[side].regiments); @@ -433,9 +432,15 @@ class Battle { } const getAirBattlePhase = () => { - // 🎯 maneuvering, 🐕 dogfight, 🏳️ retreat / 🐎 pursue - + const prev = [this.attackers.phase || "maneuvering", this.defenders.phase || "maneuvering"]; // previous phase + + // chance if moral < 25 + if (P(1 - morale[0] / 25)) return ["retreat", "pursue"]; + if (P(1 - morale[1] / 25)) return ["pursue", "retreat"]; + if (prev[0] === "maneuvering" && P(1-i/10)) return ["maneuvering", "maneuvering"]; + + return ["dogfight", "dogfight"]; // default option } const phase = function(type) { @@ -473,12 +478,9 @@ class Battle { // casualties modifier for phase const phase = { - "skirmish":.1, "melee":.2, "pursue":.3, "retreat":.3, - "boarding":.2, "shelling":.1, "chase":.03, "withdrawal": .03, + "skirmish":.1, "melee":.2, "pursue":.3, "retreat":.3, "boarding":.2, "shelling":.1, "chase":.03, "withdrawal": .03, "blockade":0, "sheltering":0, "sortie":.1, "bombardment":.05, "storming":.2, "defense":.2, "looting":.5, "surrendering":.5, - "surprise":.3, "shock":.3, - "landing":.3, "flee":0, "waiting":0 - }; + "surprise":.3, "shock":.3, "landing":.3, "flee":0, "waiting":0, "maneuvering":.1, "dogfight":.2}; const casualties = Math.random() * (Math.max(phase[this.attackers.phase], phase[this.defenders.phase])); // total casualties, ~10% per iteration const casualtiesA = casualties * defense / (attack + defense); // attackers casualties, ~5% per iteration From 164f593b754889ecb5c8fcb91d9d505472928a4e Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 6 Jun 2020 17:39:33 +0300 Subject: [PATCH 3/4] v1.4.24 --- modules/ui/battle-screen.js | 8 ++++---- modules/utils.js | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/ui/battle-screen.js b/modules/ui/battle-screen.js index 6bf2e0c7a..53b1e7391 100644 --- a/modules/ui/battle-screen.js +++ b/modules/ui/battle-screen.js @@ -608,8 +608,8 @@ class Battle { losses > .05 ? "suffered significant losses" : losses > 0 ? "suffered unsignificant losses" : "left the battle without loss"; - const casualties = Object.keys(r.casualties).map(t => r.casualties[t] ? `${Math.abs(r.casualties[t])} ${t}` : null).filter(c => c).join(", "); - const casualtiesText = casualties ? " Casualties: " + casualties : ""; + const casualties = Object.keys(r.casualties).map(t => r.casualties[t] ? `${Math.abs(r.casualties[t])} ${t}` : null).filter(c => c); + const casualtiesText = casualties.length ? " Casualties: " + list(casualties) + "." : ""; const legend = `\r\n\r\n${battleName} (${options.year} ${options.eraShort}): ${status}. The regiment ${regStatus}.${casualtiesText}`; note.legend += legend; } @@ -631,11 +631,11 @@ class Battle { }() const getSide = (regs, n) => regs.length > 1 ? - `${n ? "regiments" : "forces"} of ${[... new Set(regs.map(r => pack.states[r.state].name))].join(", ")}` : + `${n ? "regiments" : "forces"} of ${list([... new Set(regs.map(r => pack.states[r.state].name))])}` : getAdjective(pack.states[regs[0].state].name) + " " + regs[0].name; const getLosses = casualties => Math.min(rn(casualties * 100), 100); - const legend = `${this.name} took place in ${options.year} ${options.eraShort}. It was fought between ${getSide(this.attackers.regiments, 1)} and ${getSide(this.defenders.regiments, 0)}. The battle ended in ${battleStatus[+P(.7)]}. + const legend = `${this.name} took place in ${options.year} ${options.eraShort}. It was fought between ${getSide(this.attackers.regiments, 1)} and ${getSide(this.defenders.regiments, 0)}. The ${this.type} ended in ${battleStatus[+P(.7)]}. \r\nAttackers losses: ${getLosses(this.attackers.casualties)}%, defenders losses: ${getLosses(this.defenders.casualties)}%`; const id = getNextId("markerElement"); notes.push({id, name:this.name, legend}); diff --git a/modules/utils.js b/modules/utils.js index a7c0328e1..7882f37a7 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -416,6 +416,12 @@ function getAdjective(string) { // get ordinal out of integer: 1 => 1st const nth = n => n+(["st","nd","rd"][((n+90)%100-10)%10-1]||"th"); +// conjunct array: [A,B,C] => "A, B and C" +function list(array) { + const conjunction = new Intl.ListFormat(window.lang || "en", {style:"long", type:"conjunction"}); + return conjunction.format(array); +} + // split string into 2 almost equal parts not breaking words function splitInTwo(str) { const half = str.length / 2; From 9c8594e085a70e64dfbafa7045d8f95a8c1a9aef Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 8 Jun 2020 01:11:51 +0300 Subject: [PATCH 4/4] v1.4.25 --- modules/military-generator.js | 95 +++++++++++------------------------ modules/ui/layers.js | 1 + 2 files changed, 29 insertions(+), 67 deletions(-) diff --git a/modules/military-generator.js b/modules/military-generator.js index f0821400a..a4b578e63 100644 --- a/modules/military-generator.js +++ b/modules/military-generator.js @@ -28,6 +28,18 @@ "magical": {"Nomadic":1, "Highland":2, "Lake":1, "Naval":1, "Hunting":1, "River":1} }; + const cellTypeModifier = { + "nomadic": {"melee":.2, "ranged":.5, "mounted":3, "machinery":.4, "naval":.3, "armored":1.6, "aviation":1, "magical":.5}, + "wetland": {"melee":.8, "ranged":2, "mounted":0.3, "machinery":1.2, "naval":1.0, "armored":0.2, "aviation":.5, "magical":0.5}, + "highland": {"melee":1.2, "ranged":1.6, "mounted":0.3, "machinery":3, "naval":1.0, "armored":0.8, "aviation":.3, "magical":2} + } + + const burgTypeModifier = { + "nomadic": {"melee":.3, "ranged":.8, "mounted":3, "machinery":.4, "naval":1.0, "armored":1.6, "aviation":1, "magical":0.5}, + "wetland": {"melee":1, "ranged":1.6, "mounted":.2, "machinery":1.2, "naval":1.0, "armored":0.2, "aviation":0.5, "magical":0.5}, + "highland": {"melee":1.2, "ranged":2, "mounted":.3, "machinery":3, "naval":1.0, "armored":0.8, "aviation":0.3, "magical":2} + } + valid.forEach(s => { const temp = s.temp = {}, d = s.diplomacy; const expansionRate = Math.min(Math.max((s.expansionism / expn) / (s.area / area), .25), 4); // how much state expansionism is realized @@ -47,6 +59,13 @@ }); + const getType = cell => { + if ([1, 2, 3, 4].includes(cells.biome[cell])) return "nomadic"; + if ([7, 8, 9, 12].includes(cells.biome[cell])) return "wetland"; + if (cells.h[cell] >= 70) return "highland"; + return "generic"; + } + for (const i of cells.i) { if (!cells.pop[i]) continue; const s = states[cells.state[i]]; // cell state @@ -56,35 +75,15 @@ if (cells.culture[i] !== s.culture) m = s.form === "Union" ? m / 1.2 : m / 2; // non-dominant culture if (cells.religion[i] !== cells.religion[s.center]) m = s.form === "Theocracy" ? m / 2.2 : m / 1.4; // non-dominant religion if (cells.f[i] !== cells.f[s.center]) m = s.type === "Naval" ? m / 1.2 : m / 1.8; // different landmass - - const nomadic = [1, 2, 3, 4].includes(cells.biome[i]); - const wetland = [7, 8, 9, 12].includes(cells.biome[i]); - const highland = cells.h[i] >= 70; + const type = getType(i); for (const u of options.military) { const perc = +u.rural; if (isNaN(perc) || perc <= 0 || !s.temp[u.name]) continue; - let army = m * perc; // basic army for rural cell - if (nomadic) { // "nomadic" biomes special rules - if (u.type === "melee") army /= 5; else - if (u.type === "ranged") army /= 2; else - if (u.type === "mounted") army *= 3; - } - - if (wetland) { // "wet" biomes special rules - if (u.type === "melee") army *= 1.2; else - if (u.type === "ranged") army *= 1.4; else - if (u.type === "mounted") army /= 3; - } - - if (highland) { // highlands special rules - if (u.type === "melee") army *= 1.2; else - if (u.type === "ranged") army *= 1.6; else - if (u.type === "mounted") army /= 3; - } - - const t = rn(army * s.temp[u.name] * populationRate.value); + const mod = type === "generic" ? 1 : cellTypeModifier[type][u.type] // cell specific modifier + const army = m * perc * mod; // rural cell army + const t = rn(army * s.temp[u.name] * populationRate.value); // total troops if (!t) continue; let x = p[i][0], y = p[i][1], n = 0; if (u.type === "naval") {let haven = cells.haven[i]; x = p[haven][0], y = p[haven][1]; n = 1}; // place naval to sea @@ -101,43 +100,16 @@ if (b.culture !== s.culture) m = s.form === "Union" ? m / 1.2 : m / 2; // non-dominant culture if (cells.religion[b.cell] !== cells.religion[s.center]) m = s.form === "Theocracy" ? m / 2.2 : m / 1.4; // non-dominant religion if (cells.f[b.cell] !== cells.f[s.center]) m = s.type === "Naval" ? m / 1.2 : m / 1.8; // different landmass - - const biome = cells.biome[b.cell]; // burg biome - const nomadic = [1, 2, 3, 4].includes(biome); - const wetland = [7, 8, 9, 12].includes(biome); - const highland = cells.h[b.cell] >= 70; + const type = getType(b.cell); for (const u of options.military) { + if (u.type === "naval" && !b.port) continue; // only ports produce naval units const perc = +u.urban; if (isNaN(perc) || perc <= 0 || !s.temp[u.name]) continue; - let army = m * perc; // basic army for rural cell - - if (u.type === "naval" && !b.port) continue; // only ports produce naval units - - if (nomadic) { // "nomadic" biomes special rules - if (u.type === "melee") army /= 3; else - if (u.type === "machinery") army /= 2; else - if (u.type === "mounted") army *= 3; else - if (u.type === "armored") army *= 2; - } - if (wetland) { // "wet" biomes special rules - if (u.type === "melee") army *= 1.2; else - if (u.type === "ranged") army *= 1.4; else - if (u.type === "machinery") army *= 1.2; else - if (u.type === "mounted") army /= 4; else - if (u.type === "armored") army /= 3; - } - - if (highland) { // highlands special rules - if (u.type === "ranged") army *= 2; else - if (u.type === "naval") army /= 3; else - if (u.type === "mounted") army /= 3; else - if (u.type === "armored") army /= 2; else - if (u.type === "magical") army *= 2; - } - - const t = rn(army * s.temp[u.name] * populationRate.value); + const mod = type === "generic" ? 1 : burgTypeModifier[type][u.type] // cell specific modifier + const army = m * perc * mod; // urban cell army + const t = rn(army * s.temp[u.name] * populationRate.value); // total troops if (!t) continue; let x = p[b.cell][0], y = p[b.cell][1], n = 0; if (u.type === "naval") {let haven = cells.haven[b.cell]; x = p[haven][0], y = p[haven][1]; n = 1}; // place naval in sea cell @@ -313,17 +285,6 @@ notes.push({id:`regiment${s.i}-${r.i}`, name:`${r.icon} ${r.name}`, legend}); } - // const updateNote = function(r, s) { - // const id = `regiment${s}-${r.i}`; - // const note = notes.find(n => n.id === id); - // if (!note) return; - - // const oldComposition = note.legend.split("composition:\r\n")[1]||"".split(".")[0]; - // if (!oldComposition) return; - // const newComposition = Object.keys(r.u).map(t => `— ${t}: ${r.u[t]}`).join("\r\n") + "."; - // note.legend = note.legend.replace(oldComposition, newComposition); - // } - return {generate, getDefaultOptions, getName, generateNote, drawRegiments, drawRegiment, moveRegiment, getTotal, getEmblem}; }))); \ No newline at end of file diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 4298ec177..b834c9d2a 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1263,6 +1263,7 @@ function getLayer(id) { if (id === "toggleTemp") return $("#temperature"); if (id === "togglePrec") return $("#prec"); if (id === "togglePopulation") return $("#population"); + if (id === "toggleIce") return $("#ice"); if (id === "toggleTexture") return $("#texture"); if (id === "toggleLabels") return $("#labels"); if (id === "toggleIcons") return $("#icons");