diff options
-rw-r--r-- | events.txt | 26 | ||||
-rw-r--r-- | rules.js | 147 | ||||
-rw-r--r-- | tools/gencode.js | 4 |
3 files changed, 137 insertions, 40 deletions
@@ -85,10 +85,26 @@ SHADED 8 log "NOT IMPLEMENTED" EVENT 9 - log "NOT IMPLEMENTED" + current VE + prompt "Compel in a Province adjacent to Warangal that you do not control and then Build there." + add_influence VE + space 1 (is_adjacent_to_city(C_WARANGAL, s) && !is_faction_control(s, game.current)) + free_compel + mark_space + endspace + prompt `Build in the same Province.` + space_opt 1 (s === game.vm.m[0] && can_place_piece(s, game.current, DISC)) + free_build + endspace SHADED 9 - log "NOT IMPLEMENTED" + current DS + resources (game.current) 3 + prompt "Add up to 4 Troops and 1 Governor in one Province adjacent to Warangal." + space 1 is_adjacent_to_city(C_WARANGAL, s) + place_opt 4 DS TROOPS + place_opt 1 DS ELITE + endspace EVENT 10 prompt "Move up to 4 Delhi Sultanate Units into adjacent Provinces." @@ -110,15 +126,13 @@ SHADED 10 endpiece prompt "Add up to 2 Troops in each Space with a Qasbah." space_opt all has_qasbah(s) - place_opt DS TROOPS - place_opt DS TROOPS + place_opt 2 DS TROOPS endspace EVENT 11 prompt "Place up to two Mongol Invaders in each of Mtn Passes and Punjab." space_opt 2 (s === S_PUNJAB || s === S_MOUNTAIN_PASSES) - place MI TROOPS - place_opt MI TROOPS + place_opt 2 MI TROOPS endspace SHADED 11 @@ -258,7 +258,7 @@ exports.setup = function (seed, scenario, _options) { } function setup_deck() { - game.deck = [ 5, 3, 36, 10, 37, 11, 2, 41, 4, 6, 7, 8, 9, 10, 1, 12, 13, 14 ] + game.deck = [ 9, 8, 7, 6, 5, 3, 36, 10, 37, 11, 2, 10, 1, 12, 13, 14 ] } function setup_standard() { @@ -863,7 +863,10 @@ function end_decree() { } log_br() game.decree = null - game.state = "main_phase" + if (game.vm) + vm_next() + else + game.state = "main_phase" } function prompt_end_cmd(cost) { @@ -1683,6 +1686,18 @@ function init_decree(type) { game.decree.type = type } +function init_free_decree(type, s) { + game.decree = { + type: type, + limited: s >= 0 ? 1 : 0, + free: 1, + spaces: [], + where: s, + } + if (s >= 0) + set_add(game.decree.spaces, s) +} + function gen_any_decree() { if (game.current === DS) { view.actions.collect = can_collect() ? 1 : 0 @@ -1888,17 +1903,21 @@ states.build = { }, space(s) { push_undo() - push_summary() - let p = find_piece(AVAILABLE, game.current, DISC) - log_summary_place(p) - place_piece(p, s) - log_space(s, "Build") - pop_summary() + build_in_space(s) game.decree.count = 0 }, end_build: end_decree, } +function build_in_space(s) { + push_summary() + let p = find_piece(AVAILABLE, game.current, DISC) + log_summary_place(p) + place_piece(p, s) + log_space(s, "Build") + pop_summary() +} + function can_compel() { for (let s = first_space; s <= last_province; ++s) if (can_compel_in_space(s)) @@ -1917,7 +1936,6 @@ function can_compel_in_space(s) { function goto_compel() { init_decree("Compel") - game.decree.count = 2 game.state = "compel" } @@ -1930,13 +1948,18 @@ states.compel = { gen_action_space(s) }, space(s) { - log_space(s, "Compel") - push_summary() game.decree.where = s - game.state = "compel_space" + goto_compel_space() } } +function goto_compel_space() { + log_space(game.decree.where, "Compel") + push_summary() + game.decree.count = 2 + game.state = "compel_space" +} + states.compel_space = { prompt() { if (game.decree.count > 0) { @@ -2422,6 +2445,7 @@ function place_piece(p, s) { set_piece_space(p, s) update_control() update_rebel(p, s) + return p } function remove_piece(p) { @@ -2579,6 +2603,7 @@ function add_influence(faction) { return game.inf[faction]++ + log(faction_name[faction] + " gains influence.") if (faction === BK && game.inf[faction] === 2) move_all_faction_piece_from(BK, ELITE, S_BK_INF_2, AVAILABLE) @@ -2823,6 +2848,17 @@ function pop_summary() { game.summary = null } +function placed_summary(type="") { + if (game.summary.length > 0) { + for (let [n, msg] of game.summary) { + log("Placed " + msg.replace("%", String(n)) + " in S" + game.vm.s + ".") + } + } else { + log("Declined placing " + type + " in S" + game.vm.s + ".") + } + game.summary = null +} + function log_summary_place(p) { let from = piece_space(p) if (from !== AVAILABLE) @@ -3633,6 +3669,9 @@ states.vm_piece = { }, } +function is_piece_in_event_space(p) { + return piece_space(p) === game.vm.s +} // VM: PLACE PIECE @@ -3649,10 +3688,13 @@ function vm_auto_place() { } function vm_place() { - if (can_vm_place()) + if (can_vm_place()) { + push_summary() + game.vm.pp = [] game.state = "vm_place" - else + } else { vm_next() + } } function vm_place_space() { @@ -3668,8 +3710,8 @@ function can_vm_place_imp(s, faction, type) { } function can_vm_place() { - let faction = vm_operand(3) - let type = vm_operand(4) + let faction = vm_operand(4) + let type = vm_operand(5) if (typeof faction === "object" && typeof type === "object") { for (let f of faction) for (let t of type) @@ -3693,13 +3735,14 @@ function can_vm_place() { states.vm_place = { prompt() { let skip = vm_inst(2) - let faction = vm_operand(3) - let type = vm_operand(4) + let n = vm_inst(3) - game.vm.pp.length + let faction = vm_operand(4) + let type = vm_operand(5) let where = SPACE_NAME[game.vm.s] let possible = false view.where = game.vm.s - event_prompt(`Place ${PIECE_FACTION_TYPE_NAME[faction][type]} in ${where}.`) + event_prompt(`Place up to ${n} ${PIECE_FACTION_TYPE_NAME[faction][type]} in ${where}.`) if (gen_place_piece(faction, type)) possible = true if (skip || !possible) @@ -3708,22 +3751,33 @@ states.vm_place = { piece(p) { if (vm_inst(1)) push_undo() - log("Placed " + piece_name(p) + " in S" + game.vm.s + ".") - place_piece(p, game.vm.s) - vm_next() + log_summary_place(p) + let pp = place_piece(p, game.vm.s) + set_add(game.vm.pp, pp) + + if (vm_inst(3) - game.vm.pp.length === 0) { + placed_summary() + vm_next() + } }, skip() { if (vm_inst(1)) push_undo() if (vm_inst(2)) // only flag as optional if opcode is opt game.vm.opt = 1 - else - log("Did not place piece in S" + game.vm.s + ".") + placed_summary(PIECE_FACTION_TYPE_NAME[vm_operand(4)][vm_operand(5)]) vm_next() }, } -// VM : RESOURCES +// VM: INFLUENCE + +function vm_add_influence() { + add_influence(vm_operand(1)) + vm_next() +} + +// VM: RESOURCES function vm_resources() { game.state = "vm_resources" @@ -3783,7 +3837,22 @@ states.vm_steal = { } } -// VM : RALLY + +// VM: BUILD + +function vm_free_build() { + build_in_space(game.vm.s) + vm_next() +} + +// VM: COMPEL + +function vm_free_compel() { + init_free_decree("Compel", game.vm.s) + goto_compel_space() +} + +// VM: RALLY function vm_free_rally() { init_free_command("Rally", game.vm.s) @@ -3968,13 +4037,29 @@ CODE[8 * 2 + 1] = [ // EVENT 9 CODE[9 * 2 + 0] = [ - [ vm_log, "NOT IMPLEMENTED" ], + [ vm_current, VE ], + [ vm_prompt, "Compel in a Province adjacent to Warangal that you do not control and then Build there." ], + [ vm_add_influence, VE ], + [ vm_space, true, 1, 1, (s)=>(is_adjacent_to_city(C_WARANGAL, s) && !is_faction_control(s, game.current)) ], + [ vm_free_compel ], + [ vm_mark_space ], + [ vm_endspace ], + [ vm_prompt, ()=>`Build in the same Province.` ], + [ vm_space, true, 0, 1, (s)=>(s === game.vm.m[0] && can_place_piece(s, game.current, DISC)) ], + [ vm_free_build ], + [ vm_endspace ], [ vm_return ], ] // SHADED 9 CODE[9 * 2 + 1] = [ - [ vm_log, "NOT IMPLEMENTED" ], + [ vm_current, DS ], + [ vm_resources, false, ()=>(game.current), 3 ], + [ vm_prompt, "Add up to 4 Troops and 1 Governor in one Province adjacent to Warangal." ], + [ vm_space, true, 1, 1, (s)=>is_adjacent_to_city(C_WARANGAL, s) ], + [ vm_place, false, 1, 4, DS, TROOPS ], + [ vm_place, false, 1, 1, DS, ELITE ], + [ vm_endspace ], [ vm_return ], ] @@ -4002,8 +4087,7 @@ CODE[10 * 2 + 1] = [ [ vm_endpiece ], [ vm_prompt, "Add up to 2 Troops in each Space with a Qasbah." ], [ vm_space, true, 0, 999, (s)=>has_qasbah(s) ], - [ vm_place, false, 1, DS, TROOPS ], - [ vm_place, false, 1, DS, TROOPS ], + [ vm_place, false, 1, 2, DS, TROOPS ], [ vm_endspace ], [ vm_return ], ] @@ -4012,8 +4096,7 @@ CODE[10 * 2 + 1] = [ CODE[11 * 2 + 0] = [ [ vm_prompt, "Place up to two Mongol Invaders in each of Mtn Passes and Punjab." ], [ vm_space, true, 0, 2, (s)=>(s === S_PUNJAB || s === S_MOUNTAIN_PASSES) ], - [ vm_place, false, 0, MI, TROOPS ], - [ vm_place, false, 1, MI, TROOPS ], + [ vm_place, false, 1, 2, MI, TROOPS ], [ vm_endspace ], [ vm_return ], ] diff --git a/tools/gencode.js b/tools/gencode.js index 946464f..e70794e 100644 --- a/tools/gencode.js +++ b/tools/gencode.js @@ -106,10 +106,10 @@ for (let line of fs.readFileSync("events.txt", "utf-8").split("\n")) { break case "place": - emit([ "place", false, 0, line[1], line[2] ]) + emit([ "place", false, 0, line[1], line[2], line[3] ]) break case "place_opt": - emit([ "place", false, 1, line[1], line[2] ]) + emit([ "place", false, 1, line[1], line[2], line[3] ]) break case "auto_place": emit([ "auto_place", false, 0, false, line[1], line[2] ]) |