From a0c45f508147969b9f83070d973cf030e3af14ed Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 20 Aug 2024 14:31:48 +0200 Subject: dice images and colored rating numbers in log --- images/die_black_pips.svg | 37 ++++++++++++++++ images/die_white_pips.svg | 37 ++++++++++++++++ play.css | 47 ++++++++++++++++++-- play.js | 79 ++++++++++++++++++++++++++++++++-- rules.js | 106 ++++++++++++++++++++++------------------------ 5 files changed, 244 insertions(+), 62 deletions(-) create mode 100644 images/die_black_pips.svg create mode 100644 images/die_white_pips.svg diff --git a/images/die_black_pips.svg b/images/die_black_pips.svg new file mode 100644 index 0000000..d641f28 --- /dev/null +++ b/images/die_black_pips.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/die_white_pips.svg b/images/die_white_pips.svg new file mode 100644 index 0000000..efc864b --- /dev/null +++ b/images/die_white_pips.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play.css b/play.css index e9485b7..452afc2 100644 --- a/play.css +++ b/play.css @@ -23,6 +23,42 @@ body.America header.your_turn { background-color: hsl(211, 50%, 75%) } #log .n { margin: 6px 0; } #log .m { margin-top: 6px; } +#log .die { + display: inline-block; + vertical-align: -3px; + width: 12px; + height: 12px; + background-size: 600% 100%; + background-repeat: no-repeat; + background-image: url(images/die_black_pips.svg); + background-color: #fff; + border: 1px solid #444; +} + +#log .d0 { background-position: -100% 0 } +#log .d1 { background-position: 0% 0; } +#log .d2 { background-position: 20% 0; } +#log .d3 { background-position: 40% 0; } +#log .d4 { background-position: 60% 0; } +#log .d5 { background-position: 80% 0; } +#log .d6 { background-position: 100% 0; } + +#log .number { + display: inline-block; + margin: 0; + text-indent: 0; + text-align: center; + width: 12px; + height: 12px; + line-height: 12px; + border: 1px solid #444; +} + +#log .number.ar { background-color: gold; border-radius: 50%; } +#log .number.br_a { background-color: hsl(211, 50%, 75%); } +#log .number.br_b { background-color: hsl(15, 90%, 75%); } +#log .number.br_f { background-color: hsl(103, 30%, 75%); } + #log .tip { cursor: pointer; } #log .tip:hover { text-decoration: underline; } @@ -31,7 +67,6 @@ body.America header.your_turn { background-color: hsl(211, 50%, 75%) } #log div.ii { padding-left: 44px; text-indent: -12px; } #tooltip { - display: none; pointer-events: none; position: fixed; z-index: 600; @@ -39,8 +74,14 @@ body.America header.your_turn { background-color: hsl(211, 50%, 75%) } top: 60px; } -#tooltip.show { - display: block; +@media (max-width: 800px) { + #tooltip { + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + } } #mapwrap { diff --git a/play.js b/play.js index 3b11b69..2a792f5 100644 --- a/play.js +++ b/play.js @@ -225,6 +225,12 @@ function build_piece(cn, w, h) { } function on_init() { + document.getElementById("war_ends").addEventListener("mouseenter", on_focus_war_ends) + document.getElementById("war_ends").addEventListener("mouseleave", on_blur_war_ends) + + document.getElementById("last_played").addEventListener("mouseenter", on_focus_last_played) + document.getElementById("last_played").addEventListener("mouseleave", on_blur_last_played) + for (let c = 0; c <= 110; ++c) { let e = ui.cards[c] = document.createElement("div") e.className = "card card_" + c @@ -792,6 +798,10 @@ function sub_general(_match, p1) { return `${n}` } +function sub_minus(match, p1) { + return "\u2212" + p1 +} + function sub_card(_match, p1) { let x = p1 | 0 let n = data.cards[x].title @@ -822,12 +832,67 @@ function on_blur_general_tip(s) { ui.generals[s].classList.remove("tip") } -function on_focus_card_tip(s) { - ui.last_played.className = "card shrink card_" + s +function on_focus_card_tip(c) { + document.getElementById("tooltip").className = "card card_" + c } function on_blur_card_tip() { - ui.last_played.className = "card shrink card_" + view.last_played + document.getElementById("tooltip").classList = "hide" +} + +function on_focus_last_played() { + if (view.last_played) + document.getElementById("tooltip").className = "card card_" + view.last_played +} + +function on_blur_last_played() { + document.getElementById("tooltip").classList = "hide" +} + +function on_focus_war_ends() { + if (view.war_ends) + document.getElementById("tooltip").className = "card card_" + view.war_ends +} + +function on_blur_war_ends() { + document.getElementById("tooltip").classList = "hide" +} + +const ICONS = { + D1: '', + D2: '', + D3: '', + D4: '', + D5: '', + D6: '', + A1: '1', + A2: '2', + A3: '3', + A4: '4', + A5: '5', + A6: '6', + AB1: '1', + AB2: '2', + AB3: '3', + AB4: '4', + AB5: '5', + AB6: '6', + BB1: '1', + BB2: '2', + BB3: '3', + BB4: '4', + BB5: '5', + BB6: '6', + FB1: '1', + FB2: '2', + FB3: '3', + FB4: '4', + FB5: '5', + FB6: '6', +} + +function sub_icon(match) { + return ICONS[match] || match } function on_log(text) { @@ -870,6 +935,14 @@ function on_log(text) { text = text.replace(//g, ">") + text = text.replace(/-(\d)/g, sub_minus) + + text = text.replace(/\b[D][1-6]\b/g, sub_icon) + text = text.replace(/\b[A][1-6]\b/g, sub_icon) + text = text.replace(/\bAB[1-6]\b/g, sub_icon) + text = text.replace(/\bBB[1-6]\b/g, sub_icon) + text = text.replace(/\bFB[1-6]\b/g, sub_icon) + text = text.replace(/C(\d+)/g, sub_card) text = text.replace(/S(\d+)/g, sub_space) text = text.replace(/G(\d+)/g, sub_general) diff --git a/rules.js b/rules.js index 9446d70..fc283b9 100644 --- a/rules.js +++ b/rules.js @@ -2401,10 +2401,11 @@ states.intercept_roll = { }, roll() { clear_undo() - let g = game.intercept.who + let who = game.intercept.who let die = roll_d6() - if (die <= GENERALS[g].agility) { - log("Intercept G" + g + "\nrolled " + die + " <= " + GENERALS[g].agility + "\nfrom S" + game.intercept.from) + let agility = GENERALS[who].agility + if (die <= agility) { + log(`Intercept with G${who}\nD${die} \xd7 A${agility} from S${game.intercept.from}`) game.move.did_intercept = 1 move_army(game.intercept) @@ -2414,7 +2415,7 @@ states.intercept_roll = { else end_intercept() } else { - log("Intercept G" + g + "\nrolled " + die + " > " + GENERALS[g].agility + "\nfailure") + log(`Intercept with G${who}\nD${die} \xd7 A${agility} failed`) delete game.intercept if (can_intercept_to(game.move.to)) game.state = "intercept_who" @@ -2523,11 +2524,13 @@ states.retreat_before_battle_roll = { let who = game.retreat.who let to = game.retreat.to let agility = GENERALS[who].agility - if (GENERALS[who].bonus) - agility += 2 + let bonus = GENERALS[who].bonus ? 2 : 0 let roll = roll_d6() - if (roll <= agility) { - log("Retreat G" + who + "\nrolled " + roll + " <= " + agility + "\nto S" + to) + if (roll <= agility + bonus) { + if (bonus) + log(`Retreat with G${who}\nD${roll} \xd7 A${agility}+2R to S${to}`) + else + log(`Retreat with G${who}\nD${roll} \xd7 A${agility} to S${to}`) move_army(game.retreat) if (has_enemy_general(to)) capture_enemy_general(to) @@ -2536,7 +2539,10 @@ states.retreat_before_battle_roll = { delete game.retreat goto_remove_general_after_retreat_before_battle(to) } else { - log("Retreat G" + who + "\nrolled " + roll + " > " + agility + "\nfailure") + if (bonus) + log(`Retreat with G${who}\nD${roll} \xd7 A${agility}+2R failed`) + else + log(`Retreat with G${who}\nD${roll} \xd7 A${agility} failed`) delete game.retreat end_retreat_before_battle() } @@ -2803,10 +2809,9 @@ function gen_battle_card() { /* RESOLVE BATTLE */ -function roll_loser_combat_losses(log) { +function roll_loser_combat_losses(side) { let roll = roll_d6() let losses = 0 - log.push("Loser Combat Loss Roll: " + roll) switch (roll) { case 1: case 2: @@ -2821,14 +2826,13 @@ function roll_loser_combat_losses(log) { losses = 3 break } + log(`${side} LOSSES:\n${-losses} CU ( D${roll} )`) return losses } -function roll_winner_combat_losses(log, losing_general) { +function roll_winner_combat_losses(side, losing_general) { let agility = losing_general !== NOBODY ? GENERALS[losing_general].agility : 0 let roll = roll_d6() - log.push("Enemy Agility Rating: " + agility) - log.push("Winner Combat Loss Roll: " + roll) let losses = 0 switch (agility) { case 0: @@ -2844,6 +2848,10 @@ function roll_winner_combat_losses(log, losing_general) { losses = roll <= 4 ? 1 : 0 break } + if (losing_general === NOBODY) + log(`${side} LOSSES:\n${-losses} CU ( D${roll} \xd7 Nobody)`) + else + log(`${side} LOSSES:\n${-losses} CU ( D${roll} \xd7 A${agility} G${losing_general} )`) return losses } @@ -2883,6 +2891,7 @@ function apply_american_and_french_combat_losses(max) { function resolve_battle() { let a_log = [] let b_log = [] + let r_log = [] game.active = ENEMY[game.active] let b_g = find_british_general(game.move.to) @@ -2892,10 +2901,14 @@ function resolve_battle() { let b_br = 0 let a_br = 0 - if (b_g !== NOBODY) - b_log.push("General: G" + b_g) - if (a_g !== NOBODY) - a_log.push("General: G" + a_g) + let b_roll = roll_d6() + let a_roll = roll_d6() + + b_log.push("D" + b_roll + " Roll") + a_log.push("D" + a_roll + " Roll") + + b_log.push("+" + b_cu + " CU") + a_log.push("+" + a_cu + " CU") if (b_g !== NOBODY) { let roll = roll_d6() @@ -2903,7 +2916,7 @@ function resolve_battle() { b_br = Math.min(Math.floor(GENERALS[b_g].battle / 2), b_cu) else b_br = Math.min(GENERALS[b_g].battle, b_cu) - b_log.push("Actual Battle Rating Roll: " + roll) + b_log.push(`+${b_br} G${b_g} ( D${roll} \xd7 BB${GENERALS[b_g].battle} )`) } if (a_g !== NOBODY) { @@ -2912,14 +2925,12 @@ function resolve_battle() { a_br = Math.min(Math.floor(GENERALS[a_g].battle / 2), a_cu) else a_br = Math.min(GENERALS[a_g].battle, a_cu) - a_log.push("Actual Battle Rating Roll: " + roll) + if (a_g === ROCHAMBEAU) + a_log.push(`+${a_br} G${a_g} ( D${roll} \xd7 FB${GENERALS[a_g].battle} )`) + else + a_log.push(`+${a_br} G${a_g} ( D${roll} \xd7 AB${GENERALS[a_g].battle} )`) } - b_log.push("+" + b_cu + " CU") - a_log.push("+" + a_cu + " CU") - b_log.push("+" + b_br + " Actual Battle Rating") - a_log.push("+" + a_br + " Actual Battle Rating") - let b_drm = b_cu + b_br + game.combat.b_bonus if (has_flag(F_REGULARS)) { b_log.push("+1 British Regulars' Advantage") @@ -2958,18 +2969,14 @@ function resolve_battle() { a_log.push("+2 Battle Card") else if (game.combat.a_bonus === 1) a_log.push("+1 Discard of an Event Card") + if (game.move.did_intercept) { a_log.push("+1 Interception") a_drm += 1 } - let b_roll = roll_d6() - let a_roll = roll_d6() - - b_log.push("Battle Roll: " + b_roll) - b_log.push("Battle Total: " + (b_roll + b_drm)) - a_log.push("Battle Roll: " + a_roll) - a_log.push("Battle Total: " + (a_roll + a_drm)) + b_log.push("Total: " + (b_roll + b_drm)) + a_log.push("Total: " + (a_roll + a_drm)) if (game.combat.attacker === P_BRITAIN) { log("BRITISH ATTACK:\n" + b_log.join("\n")) @@ -2979,9 +2986,6 @@ function resolve_battle() { log("BRITISH DEFENSE:\n" + b_log.join("\n")) } - a_log = [] - b_log = [] - let victor if (game.active === P_BRITAIN) victor = b_roll + b_drm >= a_roll + a_drm ? P_BRITAIN : P_AMERICA @@ -2990,38 +2994,28 @@ function resolve_battle() { let a_lost_cu, b_lost_cu if (victor === P_BRITAIN) { - b_lost_cu = roll_winner_combat_losses(b_log, a_g) - a_lost_cu = roll_loser_combat_losses(a_log) + log("RESULT:\nBritish victory!") + b_lost_cu = roll_winner_combat_losses("BRITISH", a_g) + a_lost_cu = roll_loser_combat_losses("AMERICAN") } else { - b_lost_cu = roll_loser_combat_losses(b_log) - a_lost_cu = roll_winner_combat_losses(a_log, b_g) + log("RESULT:\nAmerican victory!") + a_lost_cu = roll_winner_combat_losses("AMERICAN", b_g) + b_lost_cu = roll_loser_combat_losses("BRITISH") } game.combat.british_losses = apply_british_combat_losses(b_lost_cu) let american_losses = apply_american_and_french_combat_losses(a_lost_cu) - b_log.push("Losses: " + game.combat.british_losses + " CU") - a_log.push("Losses: " + american_losses + " CU") - // Special case: winning general with no CU on enemy PC is captured if (victor === P_BRITAIN) { - log("RESULT:\nBritish victory!") if (b_g && count_british_cu(game.move.to) === 0 && has_american_pc(game.move.to)) capture_british_general(game.move.to) } else { - log("RESULT:\nAmerican victory!") if (a_g && count_american_and_french_cu(game.move.to) === 0 && has_british_pc(game.move.to)) capture_american_or_french_general(game.move.to) } - - if (game.combat.attacker === P_BRITAIN) { - log("BRITISH LOSSES:\n" + b_log.join("\n")) - log("AMERICAN LOSSES:\n" + a_log.join("\n")) - } else { - log("AMERICAN LOSSES:\n" + a_log.join("\n")) - log("BRITISH LOSSES:\n" + b_log.join("\n")) - } + log(r_log.join("\n")) if (victor === P_AMERICA) advance_french_alliance(1) @@ -3797,18 +3791,17 @@ states.george_washington_captured_during_move = { function apply_single_winter_attrition(remove_cu, space) { let die = roll_d6() - log("Roll " + die + " at S" + space) if (die <= 3) { - log(">Lost 1 CU") + log(`-1 CU at S${space} ( D${die} )`) remove_cu(space, 1) } else { - log(">Lost 0 CU") + log(`-0 CU at S${space} ( D${die} )`) } } function apply_winter_attrition(remove_cu, space, n) { let half = Math.floor(n / 2) - log("Lost " + half + " CU at S" + space + ".") + log(`-${half} CU at S${space}.`) remove_cu(space, half) } @@ -4187,6 +4180,7 @@ function resume_place_pc_markers_segment() { game.active = P_AMERICA game.state = "place_american_pc_markers_segment" } else if (has_british_place_pc_markers_segment()) { + log("=b Place PC Markers") game.active = P_BRITAIN game.state = "place_british_pc_markers_segment" } else { -- cgit v1.2.3