summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-11-20 14:40:58 +0100
committerTor Andersson <tor@ccxvii.net>2023-02-18 13:02:37 +0100
commit24eaf8561801306327b0e92570e95a2aea67f0c6 (patch)
treef13928f38402f9d7490042874a6633460e2cdf0b
parentdbde089d9b07e7f3cb74f70a0d92004ad8602092 (diff)
downloadnevsky-24eaf8561801306327b0e92570e95a2aea67f0c6.tar.gz
Designate lieutenants.
-rw-r--r--data.js2
-rw-r--r--rules.js176
-rw-r--r--tools/gendata.js4
3 files changed, 151 insertions, 31 deletions
diff --git a/data.js b/data.js
index 52eef6f..cb441ee 100644
--- a/data.js
+++ b/data.js
@@ -133,7 +133,7 @@ ways:[
],
lords:[
{"side":"Teutonic","name":"Andreas","full_name":"Andreas von Felben","title":"Landmeister in Livonia","seats":[9,13],"marshal":2,"fealty":2,"service":4,"lordship":3,"command":3,"forces":{"knights":1,"sergeants":2,"men_at_arms":1},"assets":{"transport":2,"prov":2},"ships":1,"vassals":[0,1,2],"image":0},
-{"side":"Teutonic","name":"Heinrich","full_name":"Heinrich","title":"Bishop of Ösel-Wiek","seats":[8],"marshal":0,"fealty":3,"service":4,"lordship":2,"command":1,"forces":{"knights":1,"sergeants":1,"men_at_arms":1},"assets":{"ship":1,"coin":2,"prov":1},"ships":1,"vassals":[3,4],"image":1},
+{"side":"Teutonic","name":"Heinrich","full_name":"Heinrich","title":"Bishop of Ösel-Wiek","seats":[8],"marshal":0,"fealty":3,"service":4,"lordship":2,"command":1,"forces":{"knights":1,"sergeants":1,"men_at_arms":1},"assets":{"coin":1,"ship":2,"prov":1},"ships":1,"vassals":[3,4],"image":1},
{"side":"Teutonic","name":"Hermann","full_name":"Hermann","title":"Bishop of Dorpat","seats":[7,12],"marshal":1,"fealty":4,"service":4,"lordship":3,"command":3,"forces":{"knights":1,"sergeants":1,"men_at_arms":1,"militia":1},"assets":{"transport":1,"coin":1,"prov":1},"ships":0,"vassals":[5,6,7],"image":2},
{"side":"Teutonic","name":"Knud & Abel","full_name":"Knud & Abel","title":"Princes of Denmark","seats":[0,null],"marshal":0,"fealty":2,"service":3,"lordship":3,"command":2,"forces":{"knights":1,"sergeants":1,"men_at_arms":2,"militia":1},"assets":{"ship":2,"prov":2},"ships":1,"vassals":[8,9,10],"image":3},
{"side":"Teutonic","name":"Rudolf","full_name":"Rudolf von Kassel","title":"Castellan of Wenden","seats":[13],"marshal":0,"fealty":5,"service":2,"lordship":1,"command":3,"forces":{"knights":1,"sergeants":1,"men_at_arms":1},"assets":{"transport":1,"prov":1},"ships":0,"vassals":[11,12,13],"image":4},
diff --git a/rules.js b/rules.js
index 51b7367..71b81a7 100644
--- a/rules.js
+++ b/rules.js
@@ -340,6 +340,10 @@ function set_lord_vassal_service(lord, n, x) {
// === GAME STATE HELPERS ===
+function roll_die() {
+ return random(6) + 1
+}
+
function count_lord_forces(lord) {
return get_lord_forces(lord, KNIGHTS)
+ get_lord_forces(lord, SERGEANTS)
@@ -358,6 +362,38 @@ function is_levy_phase() {
return (game.turn & 1) === 0
}
+function max_plan_length() {
+ switch (current_season()) {
+ case SUMMER: return 6
+ case EARLY_WINTER: return 4
+ case LATE_WINTER: return 4
+ case RASPUTITSA: return 5
+ }
+}
+
+function count_cards_in_plan(plan, lord) {
+ let n = 0
+ for (let c of plan)
+ if (c === lord)
+ ++n
+ return n
+}
+
+function is_marshal(lord) {
+ switch (lord) {
+ case LORD_ANDREAS: return true
+ case LORD_HERMANN: return is_lord_on_map(LORD_ANDREAS)
+ case LORD_ALEKSANDR: return true
+ case LORD_ANDREY: return is_lord_on_map(LORD_ALEKSANDR)
+ default: return false
+ }
+}
+
+function is_lord_besieged(lord) {
+ // TODO
+ return false
+}
+
function is_card_in_use(c) {
if (set_has(game.events, c))
return true
@@ -423,8 +459,46 @@ function can_add_transport(who, what) {
return get_lord_assets(who, what) < 8
}
-function roll_die() {
- return random(6) + 1
+function is_upper_lord(lord) {
+ for (let i = 0; i < game.lords.lieutenants.length; i += 2)
+ if (game.lords.lieutenants[i] === lord)
+ return true
+ return false
+}
+
+function is_lower_lord(lord) {
+ for (let i = 1; i < game.lords.lieutenants.length; i += 2)
+ if (game.lords.lieutenants[i] === lord)
+ return true
+ return false
+}
+
+function get_lower_lord(upper) {
+ for (let i = 0; i < game.lords.lieutenants.length; i += 2)
+ if (game.lords.lieutenants[i] === upper)
+ return game.lords.lieutenants[i+1]
+ return NOBODY
+}
+
+function set_lower_lord(upper, lower) {
+ for (let i = 0; i < game.lords.lieutenants.length; i += 2)
+ if (game.lords.lieutenants[i] === upper)
+ return game.lords.lieutenants[i+1] = lower
+}
+
+function add_lieutenant(upper) {
+ game.lords.lieutenants.push(upper)
+ game.lords.lieutenants.push(NOBODY)
+}
+
+function remove_lieutenant(upper) {
+ for (let i = 0; i < game.lords.lieutenants.length; i += 2) {
+ if (game.lords.lieutenants[i] === upper) {
+ array_remove(game.lords.lieutenants, i)
+ array_remove(game.lords.lieutenants, i)
+ return
+ }
+ }
}
// === SETUP ===
@@ -1144,12 +1218,13 @@ states.muster_lord_at_seat = {
set_lord_moved(game.who, 1)
muster_lord(game.who, loc)
game.state = 'muster_lord_transport'
- game.count = data.lords[game.who].assets.transport
+ game.count = data.lords[game.who].assets.transport | 0
+ resume_muster_lord_transport()
},
}
function resume_muster_lord_transport() {
- if (--game.count === 0)
+ if (game.count === 0)
pop_state()
if (game.state === 'levy_muster_lord')
resume_levy_muster_lord()
@@ -1175,24 +1250,28 @@ states.muster_lord_transport = {
push_undo()
logii("Ship")
add_lord_assets(game.who, SHIP, 1)
+ --game.count
resume_muster_lord_transport()
},
boat() {
push_undo()
logii("Boat")
add_lord_assets(game.who, BOAT, 1)
+ --game.count
resume_muster_lord_transport()
},
cart() {
push_undo()
logii("Cart")
add_lord_assets(game.who, CART, 1)
+ --game.count
resume_muster_lord_transport()
},
sled() {
push_undo()
logii("Sled")
add_lord_assets(game.who, SLED, 1)
+ --game.count
resume_muster_lord_transport()
},
}
@@ -1315,59 +1394,91 @@ function goto_campaign_plan() {
game.state = 'campaign_plan'
game.p1_plan = []
game.p2_plan = []
-
- // TODO: define lieutenants
}
-function max_plan_length() {
- switch (current_season()) {
- case SUMMER: return 6
- case EARLY_WINTER: return 4
- case LATE_WINTER: return 4
- case RASPUTITSA: return 5
- }
+function plan_get_upper_lord(first, last) {
+ for (let lord = first; lord <= last; ++lord)
+ if (is_upper_lord(lord) && get_lower_lord(lord) === NOBODY)
+ return lord
+ return NOBODY
}
-function count_cards_in_plan(plan, lord) {
- let n = 0
- for (let c of plan)
- if (c === lord)
- ++n
- return n
+function plan_has_upper_lord(first, last) {
+ for (let lord = first; lord <= last; ++lord)
+ if (is_upper_lord(lord))
+ return true
+ return false
}
states.campaign_plan = {
prompt(current) {
- view.prompt = "Create your plan."
+ view.prompt = "Build a Plan and designate Lieutenants."
let plan = (current === P1) ? game.p1_plan : game.p2_plan
+ let first = (current === P1) ? first_p1_lord : first_p2_lord
+ let last = (current === P1) ? last_p1_lord : last_p2_lord
+ let upper = plan_get_upper_lord(first, last)
+
view.plan = plan
+ view.who = upper
+
if (plan.length < max_plan_length()) {
view.actions.end_plan = 0
if (count_cards_in_plan(plan, -1) < 3)
gen_action_plan(-1)
- for (let lord = 0; lord <= last_lord; ++lord) {
- if (lord >= first_p1_lord && lord <= last_p1_lord && current !== P1)
- continue
- if (lord >= first_p2_lord && lord <= last_p2_lord && current !== P2)
- continue
+ for (let lord = first; lord <= last; ++lord) {
if (is_lord_on_map(lord) && count_cards_in_plan(plan, lord) < 3)
gen_action_plan(lord)
}
} else {
- view.actions.end_plan = 1
+ if (upper === NOBODY)
+ view.actions.end_plan = 1
+ }
+
+ if (upper !== NOBODY)
+ gen_action_lord(upper)
+
+ for (let lord = first; lord <= last; ++lord) {
+ if (is_marshal(lord) || is_lord_besieged(lord))
+ continue
+ if (is_upper_lord(lord) || is_lower_lord(lord))
+ continue
+ if (upper === NOBODY) {
+ gen_action_lord(lord)
+ } else {
+ if (get_lord_locale(upper) === get_lord_locale(lord))
+ gen_action_lord(lord)
+ }
}
- if (plan.length > 0)
+
+ if (plan.length > 0 || plan_has_upper_lord(first, last))
view.actions.undo = 1
else
view.actions.undo = 0
},
+ lord(lord, current) {
+ let first = (current === P1) ? first_p1_lord : first_p2_lord
+ let last = (current === P1) ? last_p1_lord : last_p2_lord
+ let upper = plan_get_upper_lord(first, last)
+ if (lord === upper)
+ remove_lieutenant(upper)
+ else if (upper === NOBODY)
+ add_lieutenant(lord)
+ else
+ set_lower_lord(upper, lord)
+ },
plan(lord, current) {
let plan = (current === P1) ? game.p1_plan : game.p2_plan
plan.push(lord)
},
undo(_, current) {
let plan = (current === P1) ? game.p1_plan : game.p2_plan
- plan.length--
+ let first = (current === P1) ? first_p1_lord : first_p2_lord
+ let last = (current === P1) ? last_p1_lord : last_p2_lord
+ game.lords.lieutenants = []
+ for (let lord = first; lord <= last; ++lord)
+ if (is_upper_lord(lord))
+ remove_lieutenant(lord)
+ plan.length = 0
},
end_plan(_, current) {
console.log("active", game.active)
@@ -1383,6 +1494,15 @@ states.campaign_plan = {
}
function end_campaign_plan() {
+ if (game.lords.lieutenants.length > 0) {
+ log(`Lieutenants`)
+ for (let i = 0; i < game.lords.lieutenants.length; i += 2) {
+ let upper = game.lords.lieutenants[i]
+ let lower = game.lords.lieutenants[i+1]
+ log(`>${lord_name[upper]} over ${lord_name[lower]}`)
+ }
+ }
+
set_active(P1)
goto_command_activation()
}
diff --git a/tools/gendata.js b/tools/gendata.js
index 53e65a7..43ee50d 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -346,8 +346,8 @@ let lords = [
men_at_arms: 1,
},
assets: {
- ship: 1,
- coin: 2,
+ coin: 1,
+ ship: 2,
prov: 1,
},
ships: 1,