diff options
-rw-r--r-- | data.js | 4 | ||||
-rw-r--r-- | play.js | 460 | ||||
-rw-r--r-- | rules.js | 47 |
3 files changed, 29 insertions, 482 deletions
@@ -2250,21 +2250,25 @@ const data = { { "title": "Minor Campaign", "type": "campaign", + "event": "campaign", "count": 2 }, { "title": "Minor Campaign", "type": "campaign", + "event": "campaign", "count": 2 }, { "title": "Minor Campaign", "type": "campaign", + "event": "campaign", "count": 2 }, { "title": "Major Campaign", "type": "campaign", + "event": "campaign", "count": 3 }, { @@ -776,463 +776,3 @@ function on_log(text) { p.innerHTML = text return p } - -/* OLD --- -function on_log(text) { - let p = document.createElement("div") - text = text.replace(/&/g, "&") - text = text.replace(/</g, "<") - text = text.replace(/>/g, ">") - - text = text.replace(/#(\d+)/g, - '<span class="tip" onmouseenter="on_focus_card_tip($1)" onmouseleave="on_blur_card_tip()">$&</span>') - // text = text.replace(/%(\d+)/g, sub_space_name) - - if (text.match(/^\.h1 /)) { - p.className = "h1" - text = text.substring(4) - } else if (text.match(/^\.h2.american /)) { - p.className = "h2 american" - text = text.substring(13) - } else if (text.match(/^\.h2.british /)) { - p.className = "h2 british" - text = text.substring(12) - } - - p.innerHTML = text - return p -} - - -function on_focus_card_tip(card_number) { - document.getElementById("tooltip").className = "card show card_" + card_number -} - -function on_blur_card_tip() { - document.getElementById("tooltip").classList = "card" -} - -function on_focus_last_card() { - if (typeof view.last_card === 'number') { - document.getElementById("tooltip").className = "card show card_" + view.last_card - } -} - -function on_blur_last_card() { - document.getElementById("tooltip").classList = "card" -} - -function clearList(container) { - while (container.firstChild) - container.removeChild(container.firstChild) -} - -function onHoverCard(X) { - let c = CARDS[X.id.split("+")[1]] - document.getElementById("status").textContent = JSON.stringify(c) -} - -function onFocusNode(evt) { - let space = SPACES[evt.target.my_id] - document.getElementById("status").textContent = space.name -} - -function onBlurNode(evt) { - let space = SPACES[evt.target.my_id] - document.getElementById("status").textContent = "" -} - -function clear_group(name) { - let container = document.getElementById(name) - while (container.firstChild) - container.removeChild(container.firstChild) -} - -function build_marker(container, id, x, y, w, h, classList) { - let e = document.createElement("div") - e.foo = { w: w, h: h } - e.classList.add("marker") - for (let c of classList) - e.classList.add(c) - e.my_id = id - e.style.left = ((x - w / 2) | 0) + "px" - e.style.top = ((y - h / 2) | 0) + "px" - document.getElementById(container).appendChild(e) - return e -} - -function update_marker(e, space) { - let box - if (typeof space === "number") - box = SPACES[space] - else - return - e.style.left = ((box.x - e.foo.w / 2) | 0) + "px" - e.style.top = ((box.y - e.foo.h / 2) | 0) + "px" -} - -function update_marker_xy(e, x, y) { - e.style.left = ((x - e.foo.w / 2) | 0) + "px" - e.style.top = ((y - e.foo.h / 2) | 0) + "px" -} - -function build_map() { - - ui.french_navy = build_marker( - "markers", - "FrenchNavy", - SPACES[data.space_index["French Reinforcements"]].x - 64 - 10, - SPACES[data.space_index["French Reinforcements"]].y - 32, - //64, 130, - 55, 55, - [ "french-navy" ] - ) - - ui.congress = build_marker( - "markers", - "Congress", - SPACES[data.space_index["Philadelphia"]].x, - SPACES[data.space_index["Philadelphia"]].y, - 55, - 55, - [ "congress" ] - ) - -} - -function update_units() { - const generalX = 50 - const generalY = 0 - const cuX = 20 - const cuY = 10 - - update_marker(ui.turn, "Game Turn " + view.year) - if (view.flags & F_REGULARS) - ui.turn.classList.remove("no-regulars") - else - ui.turn.classList.add("no-regulars") - - update_marker(ui.congress, view.congress) - - update_marker(ui.french_alliance, "French Alliance Track " + view.french_alliance) - if (view.flags & F_EUROPEAN_WAR) - ui.french_alliance.classList.add("european-war") - else - ui.french_alliance.classList.remove("european-war") - - if (view.french_navy < 0) { - let x = SPACES[data.space_index["French Reinforcements"]].x - 64 - 10 - let y = SPACES[data.space_index["French Reinforcements"]].y - 32 - update_marker_xy(ui.french_navy, x, y) - } else { - let s - if (view.french_navy > 1700) - s = "Game Turn "+ view.french_navy - else - s = "Sea "+ view.french_navy - update_marker(ui.french_navy, s) - } - - for (let space = 0; space < space_count; ++space) { - let space_pc = get_space_pc(space) - let e = ui.pc[space] - if (space_pc === PC_BRITISH) { - e.classList.remove("american") - e.classList.add("british") - } else if (space_pc === PC_AMERICAN) { - e.classList.add("american") - e.classList.remove("british") - } else { - e.classList.remove("american") - e.classList.remove("british") - } - } - - for (let c = 0; c <= 13; ++c) { - let control = 0 - for (let space of COLONIES[c]) { - if (get_space_pc(space) == PC_BRITISH) - --control - else if (get_space_pc(space) == PC_AMERICAN) - ++control - } - if (control < 0) - ui.control[c].className = "marker control british" - else if (control > 0) - ui.control[c].className = "marker control american" - else - ui.control[c].className = "marker control" - } - - let count = [] - for (let g in GENERALS) { - let loc = view.loca[g] - count[loc] = (count[loc] | 0) + 1 - } - - let offset = [] - for (let g in GENERALS) { - let e = ui.generals[g] - let loc = view.loca[g] - let space = SPACES[loc] || BOXES[loc] - if (space) { - let n = count[loc] - let o = offset[loc] | 0 - let oo = 0 + o // -(n-1)/2 + o - // update_marker_xy(e, space.x + oo * generalX, space.y + oo * generalY - 32) - update_marker_xy(e, space.x + oo * generalX + 20, space.y + oo * generalY - 10) - e.classList.remove("offmap") - offset[loc] = ++o - } else { - e.classList.add("offmap") - } - if (view.who == g) - e.classList.add("selected") - else - e.classList.remove("selected") - } - - // TODO: reuse CU elements - offset = [] - function add_cu_marker(s, n, cn) { - if (n > 0) { - let space = SPACES[s] - let o = offset[s] | 0 - let x = space.x + o * cuX - let y = space.y + o * cuY - let e = build_marker("cu", null, x, y, 60, 60, cn) - e.textContent = n - offset[s] = ++o - } - } - clear_group("cu") - for (let s = 0; s < view.cupc.length; ++s) { - add_cu_marker(s, count_british_cu(s), [ "cu", "british" ]) - add_cu_marker(s, count_american_cu(s), [ "cu", "american" ]) - add_cu_marker(s, count_french_cu(s), [ "cu", "french" ]) - } -} - -build_map() - -function player_info(player, nc, nq) { - let info = "" - if (player == P_AMERICA) { - if ((view.flags & F_MUTINIES) || view.congress === CONTINENTAL_CONGRESS_DISPERSED) - info += "\u{1f6ab} " - } - if (nq > 0) - info += nq + "\u{231b} " - info += nc + "\u{1f3b4}" - return info -} - -function on_update() { - let e - - roles.America.stat.textContent = player_info(P_AMERICA, view.a_cards, view.a_queue) - roles.Britain.stat.textContent = player_info(P_BRITAIN, view.b_cards, view.b_queue) - - if (!view.last_played) - document.getElementById("last_played").className = "card show card_back" - else - document.getElementById("last_played").className = "card show card_" + view.last_played - - action_button("pickup_british_cu", "Pick up British CU") - action_button("pickup_american_cu", "Pick up American CU") - action_button("pickup_french_cu", "Pick up French CU") - action_button("drop_british_cu", "Drop off British CU") - action_button("drop_american_cu", "Drop off American CU") - action_button("drop_french_cu", "Drop off French CU") - action_button("britain_first", "Britain") - action_button("america_first", "America") - action_button("surrender", "Surrender") - action_button("pass", "Next") - action_button("undo", "Undo") - - e = document.getElementById("war_ends") - e.classList.remove("year_1779") - e.classList.remove("year_1780") - e.classList.remove("year_1781") - e.classList.remove("year_1782") - e.classList.remove("year_1783") - if (view.war_ends) - e.classList.add("year_" + CARDS[view.war_ends].year) - - e = document.getElementById("played_british_reinforcements") - e.classList.remove("ops_1") - e.classList.remove("ops_2") - e.classList.remove("ops_3") - if (view.reinforcements[0] > 0) - e.classList.add("ops_" + CARDS[view.reinforcements[0]].count) - - e = document.getElementById("played_american_reinforcements_1") - e.classList.remove("ops_1") - e.classList.remove("ops_2") - e.classList.remove("ops_3") - if (view.reinforcements[1] > 0) - e.classList.add("ops_" + CARDS[view.reinforcements[1]].count) - - e = document.getElementById("played_american_reinforcements_2") - e.classList.remove("ops_1") - e.classList.remove("ops_2") - e.classList.remove("ops_3") - if (view.reinforcements[2] > 0) - e.classList.add("ops_" + CARDS[view.reinforcements[2]].count) - - let cards = view.hand - for (let c = 1; c <= 110; ++c) { - ui.cards[c].classList.toggle("selected", view.selected_card === c) - if (cards && cards.includes(c)) - ui.cards[c].classList.add("show") - else - ui.cards[c].classList.remove("show") - } - - for (let space = 0; space < space_count; ++space) - ui.spaces[space].classList.remove("enabled") - - for (let general = 0; general < general_count; ++general) - ui.generals[general].classList.remove("enabled") - - for (let zone of BLOCKADE_ZONES) - ui.blockade[zone].classList.remove("enabled") - - update_units() - - if (view.actions) - for (let action of Object.keys(view.actions)) { - let args = view.actions[action] - switch (action) { - case "card_play_event": - case "card_discard_event": - case "card_campaign": - case "card_ops_general": - case "card_ops_pc": - case "card_ops_reinforcements": - case "card_ops_queue": - case "card_battle_play": - case "card_battle_discard": - case "exchange_for_discard": - for (let card of args) - ui.cards[card].classList.add("enabled") - break - case "remove_cu": - // TODO: target CU not space? - case "move": - case "sea_move": - case "place_continental_congress": - case "place_reinforcements": - case "place_american_pc": - case "place_british_pc": - case "remove_pc": - case "flip_pc": - console.log("ACTION", args) - for (let space of args) - ui.spaces[space].classList.add("enabled") - break - case "select_general": - for (let general of args) - ui.generals[general].classList.add("enabled") - break - case "place_navy": - for (let zone of args) - ui.blockade[zone].classList.add("enabled") - } - } -} - -function is_action(action, card) { - return view.actions && view.actions[action] && view.actions[action].includes(card) -} - -function show_popup_menu(evt, menu_id, target_id, title) { - let menu = document.getElementById(menu_id) - - let show = false - for (let item of menu.querySelectorAll("li")) { - let action = item.dataset.action - if (action) { - if (is_action(action, target_id)) { - show = true - item.classList.add("action") - item.classList.remove("disabled") - item.onclick = function () { - send_action(action, target_id) - hide_popup_menu() - evt.stopPropagation() - } - } else { - item.classList.remove("action") - item.classList.add("disabled") - item.onclick = null - } - } - } - - if (show) { - menu.onmouseleave = hide_popup_menu - menu.style.display = "block" - if (title) { - let item = menu.querySelector("li.title") - if (item) { - item.onclick = hide_popup_menu - item.textContent = title - } - } - - let w = menu.clientWidth - let h = menu.clientHeight - let x = Math.max(5, Math.min(evt.clientX - w / 2, window.innerWidth - w - 5)) - let y = Math.max(5, Math.min(evt.clientY - 12, window.innerHeight - h - 40)) - menu.style.left = x + "px" - menu.style.top = y + "px" - - evt.stopPropagation() - } else { - menu.style.display = "none" - } -} - -function hide_popup_menu() { - document.getElementById("popup").style.display = "none" -} - -function on_card(evt) { - if (view.actions) { - let c = evt.target.id.split("+")[1] | 0 - show_popup_menu(evt, "popup", c, CARDS[c].title) - } -} - -function get_action_from_arg(x) { - for (let action of Object.keys(view.actions)) { - let args = view.actions[action] - if (Array.isArray(args) && args.includes(x)) - return action - } - return null -} - -function on_space(evt) { - if (view.actions) { - let space = evt.target.my_id - let action = get_action_from_arg(space) - if (action) - send_action(action, space) - } -} - -function on_general(evt) { - if (view.actions) { - let general = evt.target.my_id - let action = get_action_from_arg(general) - if (action) - send_action(action, general) - } -} - -function toggle_markers() { - document.querySelector("#map").classList.toggle("hide_markers") -} -*/ @@ -122,6 +122,10 @@ var events = {} var game var view +function card_name(c) { + return "\u201c" + CARDS[c].title + "\u201d" +} + /* SETUP */ function setup_game(seed) { @@ -1127,23 +1131,24 @@ states.british_declare_first = { view.actions.pass = 1 for (let c of CAMPAIGN_CARDS) { if (game.b_hand.includes(c)) { - gen_action_card("card_campaign", c) + gen_action_card("card", c) } } }, - card_campaign(c) { + card(c) { + push_undo() clear_flag(F_CONGRESS_WAS_DISPERSED) logp("went first by playing a campaign card") - game.active = P_BRITAIN - goto_campaign(c) + game.card = c + game.state = "strategy_phase_event" }, pass() { if (has_flag(F_CONGRESS_WAS_DISPERSED)) game.active = P_BRITAIN else game.active = P_AMERICA - game.state = "choose_first_player" clear_flag(F_CONGRESS_WAS_DISPERSED) + game.state = "choose_first_player" }, } @@ -1221,7 +1226,6 @@ states.strategy_phase_OLD = { card_campaign(c) { game.did_discard_event = 0 clear_queue() - goto_campaign(c) }, card_play_event(c) { push_undo() @@ -1307,7 +1311,7 @@ states.strategy_phase = { states.exchange = { inactive: "to play a strategy card", prompt() { - view.prompt = "Exchange an OPS card for the event card." + view.prompt = "Exchange an OPS card for " + card_name(game.did_discard_event) + "." view.selected_card = game.did_discard_event for (let c of active_hand()) if (can_exchange_for_discard(c)) @@ -1325,16 +1329,16 @@ states.strategy_phase_ops = { prompt() { let c = game.card view.selected_card = game.card - view.prompt = "Use " + CARDS[c].title + "." - if (can_exchange_for_discard(c)) - view.actions.exchange = 1 + view.prompt = "Use " + card_name(c) + "." +// if (can_exchange_for_discard(c)) +// view.actions.exchange = 1 if (can_activate_general(c)) view.actions.activate = 1 if (can_play_reinforcements()) view.actions.reinforce = 1 - if (game.active === P_AMERICA && game.a_queue < 2 && CARDS[c].count < 3) + if (game.active === P_AMERICA && game.a_queue + CARDS[c].count < 3) view.actions.queue = 1 - if (game.active === P_BRITAIN && game.b_queue < 2 && CARDS[c].count < 3) + if (game.active === P_BRITAIN && game.b_queue + CARDS[c].count < 3) view.actions.queue = 1 view.actions.pc_action = 1 }, @@ -1383,7 +1387,7 @@ states.strategy_phase_event = { prompt() { let c = game.card view.selected_card = game.card - view.prompt = "Use event card." + view.prompt = "Use " + card_name(c) + "." view.actions.event = 0 view.actions.pc_action = 0 @@ -1395,8 +1399,8 @@ states.strategy_phase_event = { view.actions.pc_action = 0 break case "campaign": - view.actions.campaign = 1 - view.actions.pc_action = 0 + view.actions.event = 1 + view.actions.pc_action = 1 break case "british-event": case "british-event-or-battle": @@ -1707,7 +1711,7 @@ states.ops_british_reinforcements_who = { no_general() { push_undo() game.state = "ops_british_reinforcements_where" - delete game.who + game.who = NOBODY }, } @@ -1750,7 +1754,7 @@ states.ops_american_reinforcements_who = { no_general() { push_undo() game.state = "ops_american_reinforcements_where" - delete game.who + game.who = NOBODY }, } @@ -2582,6 +2586,7 @@ states.play_attacker_battle_card_confirm = { view.prompt = "Attack: Played card for +2 DRM." else view.prompt = "Attack: Discarded card for +1 DRM." + view.actions.next = 1 }, next() { clear_undo() @@ -3083,12 +3088,12 @@ function end_battle() { end_move() } -/* CAMPAIGN */ +/* EVENTS */ -function goto_campaign(c) { +events.campaign = function (c, card) { play_card(c) game.state = "campaign" - game.campaign = CARDS[c].count + game.campaign = card.count if (game.active === P_BRITAIN) set_flag(F_LANDING_PARTY) else @@ -3097,8 +3102,6 @@ function goto_campaign(c) { game.state = "ops_general_who" } -/* EVENTS */ - events.the_war_ends = function (c, card) { logp("played #" + c) log("The war will end in " + card.year) |