diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 94 |
1 files changed, 60 insertions, 34 deletions
@@ -9,6 +9,7 @@ // TODO: manual "pursuit" ? // TODO: allow placing dice on full special formations? +// TODO: fizzle when action says to take cards from other dice? const data = require("./data.js") @@ -83,6 +84,10 @@ exports.view = function (state, player) { morale: game.morale, front: game.front, reserve: game.reserve, + selected: game.selected, + target: game.target, + hits: game.hits, + self: game.self, } if (game.state === "game_over") { @@ -133,8 +138,6 @@ states.game_over = { exports.setup = function (seed, scenario, options) { // TODO: "Random" - console.log("SETUP", scenario) - scenario = parseInt(scenario) scenario = data.scenarios.findIndex(s => s.number === scenario) if (scenario < 0) @@ -163,12 +166,18 @@ exports.setup = function (seed, scenario, options) { // cubes (map special formation -> count) cubes: [], - morale: [ info.players[0].morale, info.players[1].morale ], + morale: [ info.players[0].morale || -1, info.players[1].morale || -1 ], front: [ [], [], ], reserve: [ [], [] ], // dice value placed on what card placed: [], + + // current action + selected: -1, + target: -1, + hits: 0, + self: 0, } function setup_formation(front, reserve, c) { @@ -305,10 +314,10 @@ function set_dice_value(d, v) { function is_card_in_play(c) { return ( - set_has(game.players[0].front, c) || - set_has(game.players[1].front, c) || - set_has(game.players[0].reserve, c) || - set_has(game.players[1].reserve, c) + set_has(game.front[0], c) || + set_has(game.front[1], c) || + set_has(game.reserve[0], c) || + set_has(game.reserve[1], c) ) } @@ -317,24 +326,25 @@ function is_card_attack_with_target_in_play(c) { if (a.type === "Attack") { for (let t of a.target_list) if (is_card_in_play(c)) - return false + return true } } + return false } function check_impossible_to_attack_victory() { let p = player_index() - for (let c of game.players[p].front) + for (let c of game.front[p]) if (is_card_attack_with_target_in_play(c)) return false - for (let c of game.players[p].reserve) + for (let c of game.reserve[p]) if (is_card_attack_with_target_in_play(c)) return false return true } function check_morale_loss(p) { - return game.players[0].morale === 0 + return game.morale[0] === 0 } // === ROLL PHASE === @@ -790,7 +800,7 @@ states.place = { states.place_on_card = { prompt() { let card = data.cards[game.selected] - view.selected = game.selected + // XXX view.selected = game.selected view.prompt = "Place dice on " + card.name + "." gen_place_dice_select_card() @@ -811,8 +821,10 @@ states.place_on_card = { die(d) { push_undo() place_dice_take[data.cards[game.selected].dice](game.selected, d) - if (!can_place_dice(game.selected)) + if (!can_place_dice(game.selected)) { + game.selected = -1 game.state = "place" + } }, end_turn() { end_roll_phase() @@ -979,7 +991,7 @@ function can_take_any_action() { function goto_action_phase() { if (check_impossible_to_attack_victory()) { - if (player === P1) + if (player_index() === 0) goto_game_over(P2, P1 + " has no more attacks!") else goto_game_over(P1, P2 + " has no more attacks!") @@ -1076,7 +1088,7 @@ function goto_take_action(c, ix) { game.action = ix switch (a.type) { case "Attack": - game.state = "attack" + goto_attack() break case "Bombard": game.state = "bombard" @@ -1125,9 +1137,8 @@ states.bombard = { } function format_attack_result() { - let a = current_action() - let hits = get_attack_hits(game.selected, a) - let self = get_attack_self(game.selected, a) + let hits = game.hits + let self = game.self if (hits !== 1 && self > 0) return ` ${hits} hits. ${self} self.` if (hits === 1 && self > 0) @@ -1139,19 +1150,23 @@ function format_attack_result() { return "" } +function goto_attack(c) { + let a = current_action() + game.state = "attack" + game.target = find_target_of_attack(a) + game.hits = get_attack_hits(game.selected, a) + game.self = get_attack_self(game.selected, a) +} + states.attack = { prompt() { - let t = find_target_of_attack(current_action()) - view.prompt = "Attack " + card_name(t) + "." + format_attack_result() - view.selected = game.selected - gen_action_card(t) + view.prompt = "Attack " + card_name(game.target) + "." + format_attack_result() + // XXX view.selected = game.selected + gen_action_card(game.target) + view.actions.attack = 1 }, card(c) { log(card_name(game.selected) + " attacked " + card_name(c) + ".") - let a = current_action() - game.target = c - game.hits = get_attack_hits(game.selected, a) - game.self = get_attack_self(game.selected, a) if (can_opponent_react()) { clear_undo() set_opponent_active() @@ -1165,8 +1180,11 @@ states.attack = { function resume_attack() { apply_hits(game.hits) apply_self(game.self) - game.hits = game.self = 0 pay_for_action(game.selected) + + game.hits = game.self = 0 + game.selected = -1 + game.target = -1 end_action_phase() } @@ -1174,17 +1192,15 @@ states.command = { prompt() { let t = find_target_of_command(current_action()) view.prompt = "Bring " + card_name(t) + " out of reserve." - view.selected = game.selected + // XXX view.selected = game.selected gen_action_card(t) }, card(c) { log(card_name(game.selected) + " commanded " + card_name(c) + " out of reserve.") - console.log("PRE COMMAND", JSON.stringify(game)) let p = player_index() array_remove_item(game.reserve[p], c) set_add(game.front[p], c) pay_for_action(game.selected) - console.log("POST COMMAND", JSON.stringify(game)) end_action_phase() }, } @@ -1256,8 +1272,8 @@ function can_take_reaction(c, a) { states.react = { prompt() { view.prompt = card_name(game.selected) + " attacks " + card_name(game.target) + "! " + format_attack_result() - view.selected = game.selected - view.target = game.target + // XXX view.selected = game.selected + // XXX view.target = game.target let voluntary = true let p = player_index() @@ -1320,9 +1336,19 @@ function goto_screen(c, a) { log(card_name(c) + " screened.") game.reacted = 1 pay_for_action(c) + + switch (a.effect) + { + default: + throw new Error("invalid screen effect: " + a.effect) + case "": + game.hits = 0 + game.self = 0 + break + } + set_opponent_active() - pay_for_action(game.selected) - end_action_phase() + resume_attack() } function goto_absorb(c, a) { |