From 2d5f74c94b1ac69598c0b00a2bfb3601a5703c61 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 21 Jun 2023 01:13:46 +0200 Subject: Streamline UI action flow. --- play.css | 78 +++++++++++++------ play.js | 31 ++++---- rules.js | 259 ++++++++++++++++++++++++++++++++------------------------------- 3 files changed, 203 insertions(+), 165 deletions(-) diff --git a/play.css b/play.css index bfa1577..65a5d64 100644 --- a/play.css +++ b/play.css @@ -62,29 +62,33 @@ svg { svg .region, svg .sea { fill: transparent; stroke: transparent; - stroke-width: 3px; + stroke-width: 4px; } -svg .region.action { - fill: gold; - fill-opacity: 0.1; - stroke: yellow; - stroke-opacity: 0.5; - stroke-width: 3px; +svg .region.action, svg .sea.action { + fill: white; + fill-opacity: 0.3; } -svg .region.selected { - stroke: gold; - stroke-opacity: 0.8; - stroke-width: 3px; +body.sel_general svg .region.action { + fill: hsl(358, 78%, 51%); } -svg .sea.action { - fill: dodgerblue; - fill-opacity: 0.1; - stroke: dodgerblue; - stroke-opacity: 0.5; - stroke-width: 3px; +body.sel_governor svg .region.action { + fill: hsl(206, 100%, 35%); +} + +body.sel_governor svg .region.selected { + fill: hsl(206, 100%, 35%); + fill-opacity: 0.3; + stroke: hsl(206, 100%, 35%); + stroke-width: 4px; + stroke-dasharray: 8 4; +} + +body.sel_general svg .sea.action { + fill: hsl(206, 100%, 35%); + fill-opacity: 0.25; } #pieces div { @@ -98,12 +102,20 @@ svg .sea.action { box-sizing: border-box; width: 54px; height: 54px; - border: 3px solid transparent; + border: 4px solid transparent; border-radius: 8px; + z-index: 0; + display: none; } .support.action { - border-color: yellow; + background-color: hsla(44, 80%, 52%, 0.4); + border-color: white; + display: block; +} + +.support.s0.action { + background-color: hsla(206, 100%, 35%, 0.4); } .dice { @@ -149,13 +161,27 @@ svg .sea.action { .governor.s8 { transform: translate(181px, 52px) } .capital { - width: 60px; - height: 60px; + display: none; + box-sizing: border-box; + width: 72px; + height: 72px; } .capital.action { - border: 6px solid white; - box-shadow: 0px 0px 8px white; + display: block; + border: 5px solid white; + //box-shadow: 0px 0px 8px white; + z-index: 2; +} + +body.sel_general .capital.action { + border-color: hsl(358, 78%, 51%); + background-color: hsla(358, 75%, 51%, 0.2); +} + +body.sel_governor .capital.action { + border-color: hsl(44, 80%, 52%); + background-color: hsla(44, 80%, 52%, 0.2); } body.p3 #Hispania_NPG { display: block } @@ -295,6 +321,8 @@ body.p2 #Galatia_NPG { display: block } border-style: solid; } +.governor { z-index: 1 } + .governor.unavailable { background-size: 300px 50px } .governor.unavailable.n1 { background-position: -50px 0 } .governor.unavailable.n2 { background-position: -100px 0 } @@ -396,6 +424,10 @@ body.p2 #Galatia_NPG { display: block } transform: translate(0px, 0px); } +#discard .card.action { + box-shadow: 0 0 0px 3px #a00; +} + .card.action:hover { transform: translate(0px, -12px); } diff --git a/play.js b/play.js index 33917d9..64d9aef 100644 --- a/play.js +++ b/play.js @@ -276,16 +276,16 @@ const LAYOUT_NOMADS = [ ] const LAYOUT_ITALIA = [ - [ -3, -2 ], - [ -2, -2 ], + //[ 0, -2 ], [ -1, -2 ], - [ 0, -2 ], + [ -2, -2 ], + [ -3, -2 ], [ -2, -1 ], [ -1, -1 ], [ 0, -1 ], - [ -1, 0 ], [ 1, 0 ], [ 2, 0 ], + [ -1, 0 ], [ 0, 3 ], ] @@ -627,7 +627,7 @@ function create_support_buttons(region) { for (let i = 0; i <= 4; ++i) { let x = Math.floor(-1 + x0 + i * 51.6666) let y = (-1 + y0) - let e = create_thing({ className: "support", my_action: "support", my_id: (region << 3) + i }) + let e = create_thing({ className: "support s" + i, my_action: "support", my_id: (region << 3) + i }) e.style.top = y + "px" e.style.left = x + "px" } @@ -1043,7 +1043,7 @@ function on_update() { e.classList.toggle("unavailable", region === UNAVAILABLE) e.classList.toggle("selected", view.selected_general === pi * 6 + ai) } - layout_available(avail_stack, 63, pi * 625 + 0, 30) + layout_available(avail_stack, avail_stack.length > 5 ? 48 : 63, pi * 625 + 0, 30) } for (let pi = 0; pi < player_count; ++pi) { @@ -1063,9 +1063,12 @@ function on_update() { e.classList.toggle("unavailable", region === UNAVAILABLE) e.classList.toggle("selected", view.selected_governor === pi * 6 + ai) } - layout_available(avail_stack, 58, pi * 625 + 325, 27) + layout_available(avail_stack, avail_stack.length > 5 ? 43 : 58, pi * 625 + 325, 27) } + ui.body.classList.toggle("sel_governor", typeof view.selected_governor === "number") + ui.body.classList.toggle("sel_general", typeof view.selected_general === "number") + ui.dice[0].className = "dice black d" + view.dice[0] ui.dice[1].className = "dice white d" + view.dice[1] ui.dice[2].className = "dice black d" + view.dice[2] @@ -1112,27 +1115,23 @@ function on_update() { action_button("enter", "Enter Capital") action_button("leave", "Leave Capital") - action_button("spend", "Spend") + action_button("spend_military", "Spend Military") + action_button("spend_senate", "Spend Senate") action_button("roll", "Roll") - action_button("place_militia", "Place Militia") action_button("hold_games", "Hold Games") - action_button("build_improvement", "Build an Improvement") + action_button("place_militia", "Place Militia") action_button("disperse_mob", "Disperse Mob") action_button("train_legions", "Train Legions") action_button("add_legion_to_army", "Add Legion to Army") - action_button("move_army", "Move Army") - action_button("initiate_battle", "Initiate Battle") action_button("amphitheater", "Amphitheater") action_button("basilica", "Basilica") action_button("limes", "Limes") - action_button("recall", "Recall") - action_button("recruit", "Recruit") - action_button("place_governor", "Place Governor") - action_button("create_army", "Create Army") + action_button("recruit_general", "Recruit General") + action_button("recruit_governor", "Recruit Governor") action_button("end_actions", "End Actions") diff --git a/rules.js b/rules.js index 7b7cc40..86550dc 100644 --- a/rules.js +++ b/rules.js @@ -352,8 +352,8 @@ function get_barbarian_tribe(id) { // === BOARD STATE === -function is_no_place_governor(province) { - return province >= game.support.length +function is_no_place_governor(where) { + return where >= game.support.length } function get_support(province) { return game.support[province] } @@ -652,6 +652,8 @@ function spend_ip(type, n) { } function can_place_governor(where) { + if (is_no_place_governor(where)) + return false if (is_own_province(where)) return false // Recalled or already attempted to place. @@ -783,7 +785,7 @@ states.setup_province = { prompt() { view.prompt = "Select a starting Province." for (let where = 2; where <= 12; ++where) - if (is_neutral_province(where)) + if (is_neutral_province(where) && !is_no_place_governor(where)) gen_action("capital", where) }, capital(where) { @@ -1039,8 +1041,15 @@ function action_take_actions_governor(id) { } function action_take_actions_general(id) { - game.who = id - game.state = "take_actions_general" + if (is_own_general(id)) { + game.who = id + game.state = "take_actions_general" + } else { + if (game.state === "take_actions_general") + goto_battle_vs_general(get_general_location(game.who), game.who, id) + else + goto_battle_vs_general(get_general_location(game.who), -1, id) + } } function action_take_actions_end_actions() { @@ -1066,12 +1075,13 @@ states.take_actions_governor = { let where = get_governor_location(game.who) - prompt_take_actions("Take Governor Actions", game.who, -1) + prompt_take_actions("Take Actions", game.who, -1) // Recruit Governor if (where === UNAVAILABLE) { + view.actions.recruit_governor = 0 if (sip >= game.who % 6) - view.actions.recruit = 1 + view.actions.recruit_governor = 1 } // Place Governor @@ -1080,9 +1090,15 @@ states.take_actions_governor = { } if (is_province(where)) { + view.actions.hold_games = 0 + view.actions.place_militia = 0 + view.actions.amphitheater = 0 + view.actions.basilica = 0 + view.actions.limes = 0 + // Recall Governor if (sip >= 2) - view.actions.recall = 1 + gen_action_support(where, 0) // Increase Support Level let support = game.support[where] @@ -1104,10 +1120,15 @@ states.take_actions_governor = { } // Build an Improvement - if (!has_amphitheater(where) || !has_basilica(where) || !has_limes(where)) { - if (can_build_improvement(where)) - if (pip >= 3) - view.actions.build_improvement = 1 + if (can_build_improvement(where)) { + if (pip >= 3) { + if (!has_amphitheater(where)) + view.actions.amphitheater = 1 + if (!has_basilica(where)) + view.actions.basilica = 1 + if (!has_limes(where)) + view.actions.limes = 1 + } } // Initiate Battle with Militia not stacked with General @@ -1121,41 +1142,34 @@ states.take_actions_governor = { end_actions: action_take_actions_end_actions, card: action_take_actions_card, governor: action_take_actions_governor, - general(id) { - if (is_own_general(id)) - action_take_actions_general(id) - else - goto_battle_vs_general(get_governor_location(game.who), -1, id) - }, - recruit() { + general: action_take_actions_general, + + recruit_governor() { push_undo() log("Recruited Governor " + (game.who % 6) + ".") spend_ip(SENATE, game.who % 6) set_governor_location(game.who, AVAILABLE) }, - recall() { - push_undo() - let where = get_governor_location(game.who) - log("Recalled Governor from S" + where + ".") - spend_ip(SENATE, 2) - set_placed_governor(where) - remove_governor(where) - update_neutral_italia() - }, - support() { + + support(arg) { push_undo() - let where = get_governor_location(game.who) - let support = game.support[where] - log("Built Support in S" + where + ".") - spend_ip(POPULACE, support + 1) - game.support[where] = support + 1 + let level = arg & 7 + if (level > 0) + improve_support() + else + recall_governor() }, + place_militia() { push_undo() let where = get_governor_location(game.who) spend_ip(POPULACE, 2) add_militia(where) }, + capital() { + this.place_militia() + }, + hold_games() { push_undo() let where = get_governor_location(game.who) @@ -1163,29 +1177,42 @@ states.take_actions_governor = { spend_ip(POPULACE, 3) remove_one_mob(where) }, - build_improvement() { + + region(where) { + push_undo() + spend_ip(SENATE, 1) + game.misc = { spend: 1, where: where } + game.state = "place_governor" + }, + + amphitheater() { push_undo() - game.state = "build_improvement" spend_ip(POPULACE, 3) + let where = get_governor_location(game.who) + add_amphitheater(where) + log("Built Amphitheater in S" + where + ".") }, - initiate_battle() { + basilica() { push_undo() - spend_ip(MILITARY, 1) - game.state = "initiate_battle" - game.misc = { attacker: -1, where: get_governor_location(game.who) } - set_militia_battled(get_governor_location(game.who)) + spend_ip(POPULACE, 3) + let where = get_governor_location(game.who) + add_basilica(where) + log("Built Basilica in S" + where + ".") }, - region(where) { + limes() { push_undo() - spend_ip(SENATE, 1) - game.misc = { spend: 1, where: where } - game.state = "place_governor" + spend_ip(POPULACE, 3) + let where = get_governor_location(game.who) + add_limes(where) + log("Built Limes in S" + where + ".") }, barbarian(id) { + push_undo() goto_battle_vs_barbarian(get_governor_location(game.who), -1, id) }, rival_emperor(id) { + push_undo() goto_battle_vs_rival_emperor(get_governor_location(game.who), -1, id) }, } @@ -1195,12 +1222,13 @@ states.take_actions_general = { let [ mip, sip, pip ] = game.ip let where = get_general_location(game.who) - prompt_take_actions("Take General Actions", -1, game.who) + prompt_take_actions("Take Actions", -1, game.who) // Recruit General if (where === UNAVAILABLE) { + view.actions.recruit_general = 0 if (mip >= game.who % 6) - view.actions.recruit = 1 + view.actions.recruit_general = 1 } // Create Army @@ -1210,11 +1238,14 @@ states.take_actions_general = { } if (is_region(where)) { - // Add Legion to Army - if (is_own_province(where)) { - let cost = count_legions_in_army(game.who) + 1 - if (mip >= cost) - view.actions.add_legion_to_army = 1 + view.actions.disperse_mob = 0 + view.actions.train_legions = 0 + view.actions.add_legion_to_army = 0 + + // Disperse Mob + if (has_mob(where)) { + if (mip >= 1) + view.actions.disperse_mob = 1 } // Train Legions @@ -1223,10 +1254,11 @@ states.take_actions_general = { view.actions.train_legions = 1 } - // Disperse Mob - if (has_mob(where)) { - if (mip >= 1) - view.actions.disperse_mob = 1 + // Add Legion to Army + if (is_own_province(where)) { + let cost = count_legions_in_army(game.who) + 1 + if (mip >= cost) + view.actions.add_legion_to_army = 1 } if (!has_general_battled(game.who)) { @@ -1247,29 +1279,20 @@ states.take_actions_general = { } } } - }, end_actions: action_take_actions_end_actions, card: action_take_actions_card, governor: action_take_actions_governor, - general(id) { - if (is_own_general(id)) - action_take_actions_general(id) - else - goto_battle_vs_general(get_general_location(game.who), game.who, id) - }, - recruit() { + general: action_take_actions_general, + + recruit_general() { push_undo() log("Recruited General " + (game.who % 6) + ".") spend_ip(MILITARY, game.who % 6) set_general_location(game.who, AVAILABLE) }, - create_army() { - push_undo() - spend_ip(MILITARY, 1) - game.state = "create_army" - }, + add_legion_to_army() { push_undo() log("Added Legion to Army.") @@ -1288,7 +1311,8 @@ states.take_actions_general = { if (get_general_location(game.who) === AVAILABLE) create_army(to) else - move_army_to(game.who, to, false) + // XXX move_army_to(game.who, to, false) + move_army_to(game.who, to, true) }, capital(to) { push_undo() @@ -1299,6 +1323,7 @@ states.take_actions_general = { else move_army_to(game.who, to, true) }, + enter() { push_undo() set_general_inside_capital(game.who) @@ -1308,16 +1333,39 @@ states.take_actions_general = { set_general_outside_capital(game.who) }, - initiate_battle() { + barbarian(id) { push_undo() - spend_ip(MILITARY, 1) - game.state = "initiate_battle" - game.misc = { attacker: game.who, where: get_general_location(game.who) } + goto_battle_vs_barbarian(get_general_location(game.who), game.who, id) + }, + rival_emperor(id) { + push_undo() + goto_battle_vs_rival_emperor(get_general_location(game.who), game.who, id) + }, + militia(where) { + push_undo() + goto_battle_vs_militia(get_general_location(game.who), game.who) }, +} + +// ACTION: IMPROVE SUPPORT - barbarian(id) { goto_battle_vs_barbarian(get_general_location(game.who), game.who, id) }, - rival_emperor(id) { goto_battle_vs_rival_emperor(get_general_location(game.who), game.who, id) }, - militia(where) { goto_battle_vs_militia(get_general_location(game.who), game.who) }, +function improve_support() { + let where = get_governor_location(game.who) + let support = game.support[where] + log("Built Support in S" + where + ".") + spend_ip(POPULACE, support + 1) + game.support[where] = support + 1 +} + +// ACTION: RECALL GOVERNOR + +function recall_governor() { + let where = get_governor_location(game.who) + log("Recalled Governor from S" + where + ".") + spend_ip(SENATE, 2) + set_placed_governor(where) + remove_governor(where) + update_neutral_italia() } // ACTION: PLACE GOVERNOR @@ -1416,14 +1464,11 @@ states.place_governor = { prompt(`Place Governor: ${sip} Senate. Rolling ${votes} dice. ${need} votes needed.`) - if (sip >= 1) - view.actions.spend = 1 - else - view.actions.spend = 0 + view.actions.spend_senate = (sip >= 1) view.actions.roll = 1 }, - spend() { + spend_senate() { push_undo() spend_ip(SENATE, 1) game.misc.spend += 1 @@ -1457,40 +1502,6 @@ states.place_governor = { }, } -// ACTION: BUILD IMPROVEMENT - -states.build_improvement = { - prompt() { - let where = get_governor_location(game.who) - view.selected_governor = game.who - prompt("Build Improvement.") - if (!has_amphitheater(where)) - view.actions.amphitheater = 1 - if (!has_basilica(where)) - view.actions.basilica = 1 - if (!has_limes(where)) - view.actions.limes = 1 - }, - amphitheater() { - let where = get_governor_location(game.who) - add_amphitheater(where) - log("Built Amphitheater in S" + where + ".") - game.state = "take_actions_governor" - }, - basilica() { - let where = get_governor_location(game.who) - add_basilica(where) - log("Built Basilica in S" + where + ".") - game.state = "take_actions_governor" - }, - limes() { - let where = get_governor_location(game.who) - add_limes(where) - log("Built Limes in S" + where + ".") - game.state = "take_actions_governor" - }, -} - // ACTION: CREATE ARMY function gen_create_army() { @@ -1502,7 +1513,6 @@ function gen_create_army() { } function create_army(where) { - push_undo() spend_ip(MILITARY, 1) log("Created Army in S" + where + ".") set_general_location(game.who, where) @@ -1528,8 +1538,8 @@ function gen_move_army() { } function gen_move_to_region(to) { - if (is_province(to) && can_enter_capital(to)) - gen_action_capital(to) +// if (is_province(to) && can_enter_capital(to)) +// gen_action_capital(to) gen_action_region(to) } @@ -1542,7 +1552,8 @@ states.move_army_at_sea = { }, region(to) { push_undo() - move_army_to(game.who, to, false) + // XXX move_army_to(game.who, to, false) + move_army_to(game.who, to, true) }, capital(to) { push_undo() @@ -1567,25 +1578,21 @@ function move_army_to(who, to, go_inside) { // === ACTION: INITIATE BATTLE === function goto_battle_vs_general(where, attacker, target) { - push_undo() log("Initiate Battle vs " + GENERAL_NAME[target] + " in S" + where) goto_battle("general", where, attacker, target) } function goto_battle_vs_barbarian(where, attacker, target) { - push_undo() log("Initiate Battle vs " + BARBARIAN_NAME[target] + " in S" + where) goto_battle("barbarians", where, attacker, get_barbarian_tribe(target)) } function goto_battle_vs_rival_emperor(where, attacker, target) { - push_undo() log("Initiate Battle vs Rival Emperor in S" + where) goto_battle("rival_emperor", where, attacker, target) } function goto_battle_vs_militia(where, attacker) { - push_undo() log("Initiate Battle vs Militia in S" + where) goto_battle("militia", where, attacker, -1) } @@ -2093,8 +2100,8 @@ exports.setup = function (seed, scenario, options) { // grab bag of temporary data for the current procedure misc: null, - support: new Array(12).fill(1), - mobs: new Array(12).fill(0), + support: new Array(player_count * 3).fill(1), + mobs: new Array(player_count * 3).fill(0), militia: 0, quaestor: 0, castra: 0, -- cgit v1.2.3