summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-12-18 16:08:33 +0100
committerTor Andersson <tor@ccxvii.net>2023-02-18 13:02:38 +0100
commit38831a6bc8ba83bd09fa09ba3a16da5cdfcac5c0 (patch)
tree1e537fffd27cc9daef20e2f68008dccf831d8c56
parent58a20120dc72fe7a4ad35d0322664ff0ad3c9ab2 (diff)
downloadnevsky-38831a6bc8ba83bd09fa09ba3a16da5cdfcac5c0.tar.gz
Summer Crusaders (WIP).
-rw-r--r--data.js2
-rw-r--r--rules.js78
-rw-r--r--tools/gendata.js12
3 files changed, 79 insertions, 13 deletions
diff --git a/data.js b/data.js
index d29d3ae..fb39f05 100644
--- a/data.js
+++ b/data.js
@@ -4,7 +4,7 @@ bishoprics:[0,7,8,9],
conquerable:[0,1,7,8,9,10,11,12,13,24,25,26,27,28,29,30,31,32,33,34,35,36],
strongholds:[0,1,7,8,9,10,11,12,13,24,25,26,27,32,33,34,35,36],
steppe_warriors:[18,19,22,23],
-crusaders:[2,13],
+summer_crusaders:[2,13],
locales:[
{"name":"Reval","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Danish Estonia","ways":[[5,25],[3,32]],"box":{"x":601,"y":3564,"w":206,"h":91},"adjacent":[3,5],"adjacent_by_trackway":[3,5],"adjacent_by_waterway":[]},
{"name":"Wesenberg","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Danish Estonia","ways":[[5,26],[17,30],[6,31]],"box":{"x":1448,"y":3625,"w":304,"h":60},"adjacent":[5,6,17],"adjacent_by_trackway":[5,6,17],"adjacent_by_waterway":[]},
diff --git a/rules.js b/rules.js
index bc89759..d6693c4 100644
--- a/rules.js
+++ b/rules.js
@@ -7,16 +7,21 @@
// TODO: 2nd edition ravage cost
// TODO: 2nd edition disband during campaign
+// TODO: click on summer crusaders to muster them
+// TODO: click on summer crusaders to restore them
+
// CAPABILITIES
// TODO: Ransom (T)
// TODO: Ransom (R)
-// TODO: Crusade - free summer muster, discard late winter
+// TODO: Crusade - free summer muster
// TODO: Black Sea Trade
// TODO: Baltic Sea Trade
// TODO: Hillforts
// TODO: BATTLE + STORM + SALLY
+// TODO: remove push_state/pop_state stuff - use explicit substates with common functions instead
+
const data = require("./data.js")
const TODO = false
@@ -234,7 +239,6 @@ const AOW_RUSSIAN_LODYA = R16
const AOW_RUSSIAN_VELIKY_KNYAZ = R17
const AOW_RUSSIAN_STONE_KREMLIN = R18
-// TODO: advanced service
const VASSAL_UNAVAILABLE = 0
const VASSAL_READY = 1
const VASSAL_MUSTERED = 2
@@ -769,7 +773,7 @@ function is_lord_ready(lord) {
return loc >= CALENDAR && loc <= CALENDAR + (game.turn >> 1)
}
-function is_vassal_available(vassal) {
+function is_special_vassal_available(vassal) {
let cap = data.vassals[vassal].capability
if (cap === "Crusade")
return has_global_capability(AOW_TEUTONIC_CRUSADE)
@@ -1223,6 +1227,27 @@ function muster_vassal_forces(lord, vassal) {
add_lord_forces(lord, SERFS, info.forces.serfs | 0)
}
+function restore_lord_forces(lord, type, count) {
+ if (get_lord_forces(lord, type) < count) {
+ set_lord_forces(lord, type, count)
+ return 1
+ }
+ return 0
+}
+
+function restore_vassal_forces(lord, vassal) {
+ let info = data.vassals[vassal]
+ let restored = 0
+ restored |= restore_lord_forces(lord, KNIGHTS, info.forces.knights | 0)
+ restored |= restore_lord_forces(lord, SERGEANTS, info.forces.sergeants | 0)
+ restored |= restore_lord_forces(lord, LIGHT_HORSE, info.forces.light_horse | 0)
+ restored |= restore_lord_forces(lord, ASIATIC_HORSE, info.forces.asiatic_horse | 0)
+ restored |= restore_lord_forces(lord, MEN_AT_ARMS, info.forces.men_at_arms | 0)
+ restored |= restore_lord_forces(lord, MILITIA, info.forces.militia | 0)
+ restored |= restore_lord_forces(lord, SERFS, info.forces.serfs | 0)
+ return restored > 0
+}
+
function muster_lord(lord, locale, service) {
let info = data.lords[lord]
@@ -1244,7 +1269,7 @@ function muster_lord(lord, locale, service) {
muster_lord_forces(lord)
for (let v of info.vassals) {
- if (is_vassal_available(v))
+ if (is_special_vassal_available(v))
game.lords.vassals[v] = VASSAL_READY
else
game.lords.vassals[v] = VASSAL_UNAVAILABLE
@@ -1643,8 +1668,9 @@ function deploy_global_capability(c) {
}
if (c === AOW_TEUTONIC_CRUSADE) {
- for (let v of data.crusaders)
+ for (let v of data.summer_crusaders)
game.lords.vassals[v] = VASSAL_READY
+ muster_summer_crusaders()
}
if (c === AOW_RUSSIAN_SMERDI) {
@@ -1665,7 +1691,7 @@ function discard_global_capability(c) {
}
if (c === AOW_TEUTONIC_CRUSADE) {
- for (let v of data.crusaders) {
+ for (let v of data.summer_crusaders) {
if (is_vassal_mustered(v))
disband_vassal(v)
game.lords.vassals[v] = VASSAL_UNAVAILABLE
@@ -1861,6 +1887,9 @@ function end_levy_arts_of_war() {
function goto_levy_muster() {
log_h2(game.active + " Muster")
game.state = "levy_muster"
+
+ restore_summer_crusaders()
+ muster_summer_crusaders()
}
function end_levy_muster() {
@@ -1913,6 +1942,7 @@ states.levy_muster_lord = {
view.prompt = `Levy: Muster ${lord_name[game.who]}.`
if (game.count > 0) {
+ let season = current_season()
view.prompt += ` ${game.count} lordship left.`
// Roll to muster Ready Lord at Seat
@@ -1927,9 +1957,8 @@ states.levy_muster_lord = {
// Muster Ready Vassal Forces
for (let vassal of data.lords[game.who].vassals) {
- // Crusaders can ONLY muster via special free muster in summer
- // with AOW_TEUTONIC_CRUSADE capability that is handled elsewhere.
- if (set_has(data.crusaders, vassal))
+ // NOTE: Summer Crusaders muster specially
+ if (game.active === TEUTONS && set_has(data.summer_crusaders, vassal))
continue
if (is_vassal_ready(vassal))
gen_action_vassal(vassal)
@@ -2029,6 +2058,7 @@ states.muster_lord_at_seat = {
// TODO: clean up these transitions
set_lord_moved(game.who, 1)
muster_lord(game.who, loc)
+ muster_summer_crusaders()
game.state = "muster_lord_transport"
game.count = data.lords[game.who].assets.transport | 0
resume_muster_lord_transport()
@@ -2298,6 +2328,7 @@ states.papal_legate_active = {
// TODO: clean up these transitions
muster_lord(lord, here)
+ muster_summer_crusaders()
push_state("muster_lord_transport")
game.who = lord
game.count = data.lords[lord].assets.transport | 0
@@ -4324,6 +4355,35 @@ function end_feed() {
}
}
+// === LEVY: SUMMER CRUSADERS ===
+
+function muster_summer_crusaders() {
+ // TODO: muster as separate state
+ if (game.active === TEUTONS && current_season() === SUMMER && has_global_capability(AOW_TEUTONIC_CRUSADE)) {
+ for (let v of data.summer_crusaders) {
+ let lord = data.vassals[v].lord
+ if (is_lord_on_map(lord) && is_lord_unbesieged(lord) && is_vassal_ready(v)) {
+ log(`Mustered L${lord}'s Summer Crusaders.`)
+ muster_vassal(lord, v)
+ }
+ }
+ }
+}
+
+function restore_summer_crusaders() {
+ // TODO: restore as separate state
+ if (game.active === TEUTONS && current_season() === SUMMER && has_global_capability(AOW_TEUTONIC_CRUSADE)) {
+ for (let v of data.summer_crusaders) {
+ let lord = data.vassals[v].lord
+ if (is_lord_on_map(lord) && is_lord_unbesieged(lord) && is_vassal_ready(v)) {
+ if (restore_vassal_forces(lord, v)) {
+ log(`Restored L${lord}'s Summer Crusaders.`)
+ }
+ }
+ }
+ }
+}
+
// === LEVY & CAMPAIGN: PAY ===
function can_pay_lord(lord) {
diff --git a/tools/gendata.js b/tools/gendata.js
index 8da9e17..15b8780 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -827,15 +827,20 @@ vassals.forEach((vassal,id) => {
})
let steppe_warriors = []
-let crusaders = []
+let summer_crusaders = []
for (let i = 0; i < vassals.length; ++i) {
if (vassals[i].capability === "Steppe Warriors")
steppe_warriors.push(i)
if (vassals[i].capability === "Crusade")
- crusaders.push(i)
+ summer_crusaders.push(i)
}
+let bishoprics = []
+for (let loc = 0; loc < locales.length; ++loc)
+ if (locales[loc].type === "bishopric")
+ bishoprics.push(loc)
+
let script = []
script.push("mkdir -p service300")
script.push("montage -mode concatenate -tile 1x " + lord_service.Teutonic.join(" ") + " service300/service_lords_teutonic.png")
@@ -845,10 +850,11 @@ script.push("montage -mode concatenate -tile 3x " + vassal_service.Russian.join(
print("const data = {")
print("seaports:" + JSON.stringify(seaports) + ",")
+print("bishoprics:" + JSON.stringify(bishoprics) + ",")
print("conquerable:" + JSON.stringify(conquerable) + ",")
print("strongholds:" + JSON.stringify(strongholds) + ",")
print("steppe_warriors:" + JSON.stringify(steppe_warriors) + ",")
-print("crusaders:" + JSON.stringify(crusaders) + ",")
+print("summer_crusaders:" + JSON.stringify(summer_crusaders) + ",")
dumplist("locales", locales)
dumplist("ways", ways)
dumplist("lords", lords)