summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js309
1 files changed, 220 insertions, 89 deletions
diff --git a/rules.js b/rules.js
index d3a6a3b..31ac8fd 100644
--- a/rules.js
+++ b/rules.js
@@ -191,7 +191,7 @@ exports.setup = function (seed, scenario, _options) {
resources: [ 12, 6, 7 ],
vp: [ 18, 0, 0 ],
prosperity: [ 0, 0, 0 ],
- inf: [null, 1, 2],
+ inf: [null, 0, 0],
tributary: 8191, // all 13 provinces
control: [0, 0, 0],
rebel: [null, 0, 0], // amir/raja rebel status
@@ -207,8 +207,12 @@ exports.setup = function (seed, scenario, _options) {
pieces: [],
where: null,
who: null,
+ event: 0
},
- decree: 0
+ cav: null,
+ inf_shift: null,
+ decree: null,
+ vm: null,
}
if (scenario === "Solo")
@@ -391,17 +395,20 @@ function goto_amass() {
}
function goto_build() {
- init_command("Build")
+ init_decree("Build")
game.state = "build"
}
-function goto_cavalry(n_cavalry) {
- game.cmd.n_count = n_cavalry
+function goto_cavalry(n, next) {
+ game.cav = {
+ "n": n,
+ "next": next
+ }
game.state = "cavalry"
}
function goto_collect() {
- init_command("Collect")
+ init_decree("Collect")
game.state = "collect"
}
@@ -438,7 +445,7 @@ function end_conscript_space() {
}
function goto_demand() {
- init_command("Demand Obedience")
+ init_decree("Demand Obedience")
game.state = "demand"
}
@@ -540,12 +547,12 @@ function goto_rebel() {
}
function goto_tax() {
- init_command("Tax")
+ init_decree("Tax")
game.state = "tax"
}
function goto_trade() {
- init_command("Trade")
+ init_decree("Trade")
game.state = "trade"
}
@@ -575,28 +582,48 @@ states.eligible = {
push_undo()
game.cylinder[game.current] = SOP_COMMAND_DECREE
game.decree = 1
- game.state = "command_decree"
+ game.state = "main_phase"
},
event_command() {
push_undo()
game.cylinder[game.current] = SOP_EVENT_OR_COMMAND
- game.state = "event_command"
+ game.cmd.event = 1
+ game.state = "main_phase"
},
lim_command() {
push_undo()
game.cylinder[game.current] = SOP_LIMITED_COMMAND
game.cmd.limited = 1
- game.state = "lim_command"
+ game.state = "main_phase"
},
}
-states.command_decree = {
- inactive: "Command & Decree",
+states.main_phase = {
+ inactive: "Eligible Faction",
prompt() {
- view.prompt = "Select a Command and a Decree!"
- gen_any_command()
- if (game.decree === 1)
+
+ if (game.cmd && game.cmd.limited === 1) {
+ view.prompt = "Select a limited Command."
+ gen_any_command()
+ } else if (game.cmd && game.decree === 1) {
+ view.prompt = "Select a Command and a Decree."
+ gen_any_command()
+ gen_any_decree()
+ } else if (game.cmd && game.cmd.event === 1) {
+ view.prompt = "Select a Command or the Event."
+ gen_any_command()
+ // gen_event()
+ } else if (game.cmd) {
+ view.prompt = "Select a Command."
+ gen_any_command()
+ } else if (game.decree === 1) {
+ view.prompt = "Select a Decree."
gen_any_decree()
+ } else {
+ view.prompt = "End of turn."
+ view.actions.end_of_turn = 1
+ }
+
},
build: goto_build,
collect: goto_collect,
@@ -608,32 +635,7 @@ states.command_decree = {
rebel: goto_rebel,
tax: goto_tax,
trade: goto_trade,
-}
-
-states.event_command = {
- inactive: "Event or Command",
- prompt() {
- view.prompt = "Select the card Event or a Command!"
- gen_any_command()
- },
- conscript: goto_conscript,
- govern: goto_govern,
- march: goto_march,
- rally: goto_rally,
- rebel: goto_rebel,
-}
-
-states.lim_command = {
- inactive: "Limited command",
- prompt() {
- view.prompt = "Select a limited Command!"
- gen_any_command()
- },
- conscript: goto_conscript,
- govern: goto_govern,
- march: goto_march,
- rally: goto_rally,
- rebel: goto_rebel,
+ end_of_turn: resume_event_card,
}
states.advance = {
@@ -647,6 +649,7 @@ states.advance = {
gen_action_space(S_DELHI)
},
space(s) {
+ push_summary()
game.cmd.where = s
game.state = "advance_space"
}
@@ -661,20 +664,23 @@ states.advance_space = {
if (piece_space(p) === origin)
gen_action_piece(p)
- view.actions.end_advance = true
+ view.actions.end_advance = 1
},
piece(p) {
+ log_summary_move_from(p)
place_piece(p, game.cmd.where)
},
end_advance() {
game.cmd.free -= 1
+ log_space(game.cmd.where, "Advance")
+ pop_summary()
goto_strategic_assistance()
}
}
states.amass = {
prompt() {
- view.prompt = "Amass: Place three invaders into the Mountain Passes"
+ view.prompt = "Amass: Place up to three invaders into the Mountain Passes"
gen_action_space(S_MONGOL_INVADERS)
},
@@ -688,15 +694,18 @@ states.amass = {
states.build = {
prompt() {
if (game.current === BK)
- view.prompt = "Build: Select a Province with an Amir"
+ view.prompt = "Build: Select a Province with an Amir."
else if (game.current === VE)
- view.prompt = "Build: Select a Province with a Raja"
+ view.prompt = "Build: Select a Province with a Raja."
- if (can_build()) {
+ if (game.decree === 1) {
for (let s = first_space; s <= last_space; ++s) {
if (can_build_in_space(s))
gen_action_space(s)
}
+ } else {
+ view.prompt = "Build: Done."
+ view.actions.end_build = 1
}
},
space(s) {
@@ -708,60 +717,72 @@ states.build = {
log_space(s, "Build")
pop_summary()
game.decree = 0
- game.state = "command_decree"
- }
+ },
+ end_build: end_decree,
}
states.cavalry = {
prompt() {
- view.prompt = `Gain Cavalry: Take ${game.cmd.n_count} calvary tokens`
- gen_take_cavalry(game.current)
-
+ if (game.cav.n > 0) {
+ view.prompt = `Gain Cavalry: Take ${game.cav.n} calvary tokens.`
+ gen_take_cavalry(game.current)
+ } else {
+ view.prompt = "Gain Cavalry: Done."
+ view.actions.end_cavalry = 1
+ }
},
token(c) {
- game.cmd.n_count -= 1
+ game.cav.n -= 1
set_cavalry_faction(c, game.current)
- if (!game.cmd.n_count) {
- game.state = game.cmd.save
- }
+ // TODO: cavalry log
+ },
+ end_cavalry() {
+ if (game.cav.next)
+ game.state = game.cav.next
+ else
+ end_card()
}
}
states.collect = {
prompt() {
- view.prompt = `Collect Tribute: Collect ${collect_count()} from half the Tributaries prosperity`
-
- gen_action_resources(DS)
+ if (game.decree > 0) {
+ view.prompt = `Collect Tribute: Collect ${collect_count()} from half the Tributaries prosperity`
+ gen_action_resources(DS)
+ } else {
+ view.prompt = "Collect Tribute: Done."
+ view.actions.end_collect = 1
+ }
},
resources(f) {
let c = collect_count()
add_resources(DS, c)
logi_resources(DS, c)
game.decree = 0
- goto_cavalry(2)
- }
+ goto_cavalry(2, "collect")
+ },
+ end_collect: end_decree,
}
states.compromising_gifts = {
prompt() {
+ view.prompt = "Compromising gifts: Reduce your influence by one to gain two Resources and two Cavalry tokens"
+ gen_action_influence(game.current)
- if (game.cmd.free === 1) {
- view.prompt = "Compromising gifts: Reduce your influence by one to gain two Resources and two Cavalry tokens"
- gen_action_influence(game.current)
- } else {
- view.prompt = "Compromising gifts: End gift exchange"
- }
-
- view.actions.end_gifts = true
+ view.actions.end_gifts = 1
},
inf() {
- game.cmd.free = 0
- game.inf[game.current] -= 1
log_h2(faction_acronyms[game.current] + "Compromising Gifts")
logi_resources(game.current, 2)
add_resources(game.current, 2)
- game.cmd.save = "compromising_gifts"
- goto_cavalry(2)
+ game.inf_shift = {
+ "next": "cavalry",
+ }
+ game.cav = {
+ "n": 2,
+ "next": null
+ }
+ remove_influence(game.current)
},
end_gifts() {
end_card()
@@ -828,10 +849,7 @@ states.demand = {
to_obedient_space(s)
log_space(s, "Demand Obedience")
},
- end_demand() {
- game.decree = 0
- game.state = "command_decree"
- }
+ end_demand: end_decree,
}
states.govern = {
@@ -1019,7 +1037,7 @@ states.rebel = {
states.strategic_assistance = {
prompt() {
let n_command = (game.cmd.free === 2) ? "two" : "one"
- view.prompt = `Strategic Assistance: ${faction_name[game.cmd.who]} must execute ${n_command} Mongol Invaders Commands`
+ view.prompt = `Strategic Assistance: ${faction_name[game.current]} must execute ${n_command} Mongol Invaders Commands`
gen_mi_command()
},
@@ -1030,32 +1048,42 @@ states.strategic_assistance = {
states.tax = {
prompt() {
- view.prompt = `Tax: Collect ${tax_count()} from Controlled Prosperity and Temples`
+ if (game.decree === 1) {
+ view.prompt = `Tax: Collect ${tax_count()} from Controlled Prosperity and Temples.`
+ gen_action_resources(VE)
+ } else {
+ view.prompt = "Tax: Done."
+ view.actions.end_tax = 1
+ }
- gen_action_resources(VE)
},
resources(f) {
let t = tax_count()
add_resources(game.current, t)
logi_resources(VE, t)
game.decree = 0
- game.state = "command_decree"
- }
+ },
+ end_tax: end_decree
}
states.trade = {
prompt() {
- view.prompt = `Trade: Collect ${trade_count()} from Provinces with your presence`
-
- gen_action_resources(BK)
+ if (game.decree === 1) {
+ view.prompt = `Trade: Collect ${trade_count()} from Provinces with your presence.`
+ gen_action_resources(BK)
+ } else {
+ view.prompt = "Trade: Done."
+ view.actions.end_trade = 1
+ }
},
resources(f) {
let t = trade_count()
add_resources(game.current, t)
logi_resources(BK, t)
game.decree = 0
- goto_cavalry(trade_cavalry_count())
- }
+ goto_cavalry(trade_cavalry_count(), "trade")
+ },
+ end_trade: end_decree,
}
@@ -1215,11 +1243,22 @@ function prompt_end_cmd(cost) {
function end_command() {
log_br()
game.cmd = null
- resume_event_card()
+ game.state = "main_phase"
+}
+
+function end_decree() {
+ log_br()
+ game.decree = 0
+ game.state = "main_phase"
}
/* DECREES */
+function init_decree(type) {
+ push_undo()
+ log_h2(faction_name[game.current] + " - " + type)
+}
+
function gen_any_decree() {
if (game.current === DS) {
view.actions.collect = can_collect() ? 1 : 0
@@ -1473,6 +1512,14 @@ function gen_place_piece(faction, type) {
return can_place
}
+function move_all_faction_piece_from(faction, type, from, to) {
+ let first = first_piece[faction][type]
+ let last = last_piece[faction][type]
+ for (let p = first; p <= last; ++p)
+ if (piece_space(p) === from)
+ set_piece_space(p, to)
+}
+
function is_selected_cmd_space(s) {
return game.cmd.spaces && set_has(game.cmd.spaces, s)
}
@@ -1572,6 +1619,90 @@ function trade_cavalry_count() {
return 3;
}
+/* INFLUENCE */
+
+function add_influence(faction) {
+ if (game.inf[faction] === 4)
+ return
+
+ game.inf[faction]++
+
+ if (faction === BK && game.inf[faction] === 2)
+ move_all_faction_piece_from(BK, ELITE, S_BK_INF_2, AVAILABLE)
+ else if (faction === BK && game.inf[faction] === 4)
+ move_all_faction_piece_from(BK, ELITE, S_BK_INF_4, AVAILABLE)
+ else if (faction === VE)
+ move_all_faction_piece_from(VE, ELITE, S_VE_INF_1 + game.inf[faction] - 1, AVAILABLE)
+}
+
+function remove_influence(faction) {
+ if (game.inf[faction] === 0)
+ return
+
+ game.inf[faction]--
+
+ if (faction === BK && game.inf[faction] === 3)
+ troops_to_inf_track(BK, S_BK_INF_4)
+ else if (faction === BK && game.inf[faction] === 1)
+ troops_to_inf_track(BK, S_BK_INF_2)
+ else if (faction === VE)
+ troops_to_inf_track(VE, S_VE_INF_1 + game.inf[faction])
+}
+
+function troops_to_inf_track(faction, s) {
+ let n_available = Math.min(count_pieces(AVAILABLE, faction, ELITE), 2)
+ let moved = 0
+
+ let p = null
+ while (n_available > moved) {
+ p = find_piece(AVAILABLE, faction, ELITE)
+ place_piece(p, s)
+ moved++
+ }
+
+ if (moved < 2) {
+ goto_return_troops(faction, 2-moved, s)
+ } else {
+ game.state = game.inf_shift.next
+ }
+}
+
+function goto_return_troops(faction, n_troops, s) {
+ push_summary()
+ game.inf_shift.n = n_troops
+ game.inf_shift.s = s
+ game.inf_shift.save_current = game.current
+ game.current = faction
+ game.state = "return_troops"
+}
+
+states.return_troops = {
+ prompt() {
+
+ if (game.inf_shift.n > 0) {
+ view.prompt = "Deccan Influence dwindles: Return troops to the influence track."
+ for (let p of iter_faction_pieces(game.current, ELITE))
+ if (piece_space(p) >= 0 && piece_space(p) <= S_PUNJAB)
+ gen_action_piece(p)
+ }
+ else {
+ view.prompt = "Deccan Influence dwindles: Done."
+ view.actions.end_return = 1
+ }
+
+ },
+ piece(p) {
+ log_summary_move_from(p)
+ place_piece(p, game.inf_shift.s)
+ game.inf_shift.n -= 1
+ },
+ end_return() {
+ pop_summary()
+ game.current = game.inf_shift.save_current
+ game.state = game.inf_shift.next
+ }
+}
+
/* UTILS */
function add_resources(faction, n) {