diff options
-rw-r--r-- | cards.css | 18 | ||||
-rw-r--r-- | play.html | 47 | ||||
-rw-r--r-- | play.js | 31 | ||||
-rw-r--r-- | rules.js | 35 | ||||
-rw-r--r-- | tools/gendata.js | 58 |
5 files changed, 94 insertions, 95 deletions
@@ -44,9 +44,9 @@ .name.red { background-color: #e32223; color: white; } .name.pink { background-color: #f49899; color: black; } .name.blue { background-color: #2482e4; color: white; } -.name.dkblue { background-color: #04089f; color: white; } .name.dkblue { background-color: #1239c3; color: white; } .name.dkblue { background-color: #44d; color: white; } +.name.dkblue { background-color: #04089f; color: white; } .name.sym { padding-left: 30px; @@ -188,7 +188,11 @@ min-height: 18px; } -.lore_text, .rule_text, .action_rule { +.action_effect.short { + min-height: 18px; +} + +.lore_text, .rule_text { font-family: "Source Serif SmText"; margin: 6px 0; padding: 0 12px; @@ -197,10 +201,6 @@ text-indent: 12px; } -.action_rule { - margin: 4px 0 8px 0; -} - .lore_text { font-style: italic; } @@ -283,11 +283,7 @@ /* SQUEEZE CARDS WITH TOO MUCH INFO */ -.action_effect.short { min-height: 18px; } -.squeeze1 .action_effect { min-height: 18px; } -.squeeze2 .action_row + .action_row { margin-top: 0px } -.squeeze3 .action_effect { min-height: 18px; } -.squeeze3 .action_row + .action_row { margin-top: 0px } +.squeeze .action_row + .action_row { margin-top: 6px } /* PRINT STYLE */ @@ -114,12 +114,16 @@ main { display: flex; flex-direction: row; justify-content: center; - align-content: end; + align-items: end; flex-wrap: wrap; gap: 8px; margin: 12px; } +.flip .slot_cubes { + align-items: start; +} + /* S37 Inkerman - The Fog */ [data-card="225B"] .slot_sticks { display: none } @@ -130,9 +134,6 @@ main { .slot_sticks { margin: 12px; min-height: 87px; -} - -.slot_sticks { display: flex; flex-direction: column; justify-content: end; @@ -140,11 +141,9 @@ main { gap: 1px; } -GRID.slot_sticks { - display: grid; - grid-template-rows: repeat(8, 10px); - grid-auto-flow: column; - gap: 1px; +.flip .slot_sticks { + justify-content: start; + flex-direction: column-reverse; } .slot_shift { @@ -172,15 +171,6 @@ GRID.slot_sticks { margin: 12px 0; } -.flip .slot_sticks { - justify-content: start; - flex-direction: column-reverse; -} - -.flip .slot_cubes { - align-items: start; -} - .stick { width: 90%; //margin: 0 auto; @@ -189,27 +179,6 @@ GRID.slot_sticks { box-shadow: 0 0 0 1px #0008, 1px 1px 3px 1px #0004; } -/* -.slot_sticks { flex-wrap: wrap; } -.stick:first-child:nth-last-child(8) { width: 45%; } -.stick:first-child:nth-last-child(9) { width: 45%; } -.stick:first-child:nth-last-child(10) { width: 45%; } -.stick:first-child:nth-last-child(11) { width: 45%; } -.stick:first-child:nth-last-child(12) { width: 45%; } -.stick:first-child:nth-last-child(13) { width: 45%; } -.stick:first-child:nth-last-child(14) { width: 45%; } -.stick:first-child:nth-last-child(15) { width: 45%; } -.stick:first-child:nth-last-child(16) { width: 45%; } -.stick:first-child:nth-last-child(9) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(10) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(11) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(12) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(13) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(14) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(15) ~ .stick { width: 45%; } -.stick:first-child:nth-last-child(16) ~ .stick { width: 45%; } -*/ - :root { --red: hsl(360, 77%, 51%); --pink: hsl(359, 81%, 78%); @@ -153,7 +153,7 @@ function create_formation_card(id) { let e = create_div("card formation " + wing_name[card.wing]) if (card.squeeze) - e.classList.add("squeeze" + card.squeeze) + e.classList.add("squeeze") register_action(e, "card", id) @@ -206,22 +206,27 @@ function create_formation_card(id) { append_div(ee, "action_target", a.target.map(t=>data.cards[t].name).join(", ")) else append_div(ee, "action_target", a.target) - if (a.effect && a.rule_text) - append_div(ee, "action_effect short", a.effect) - else if (a.effect) - append_div(ee, "action_effect", a.effect) - if (a.rule_text) - append_div(e, "action_rule", a.rule_text) + if (a.effect) { + if (a.short) + append_div(ee, "action_effect short", a.effect) + else + append_div(ee, "action_effect", a.effect) + } return et } if (card.actions.length >= 1) create_action(card.actions[0], 1) + + if (card.rule_text_1) + append_div(e, "rule_text", card.rule_text_1) + if (card.actions.length >= 2) create_action(card.actions[1], 2) - if (card.rule_text) - append_div(e, "rule_text", card.rule_text) + if (card.rule_text_2) + append_div(e, "rule_text", card.rule_text_2) + if (card.lore_text) append_div(e, "lore_text", card.lore_text) @@ -351,13 +356,13 @@ function on_update() { ui.role_name[0].textContent = data.scenarios[view.scenario].players[0].name ui.role_name[1].textContent = data.scenarios[view.scenario].players[1].name - if (data.scenarios[view.scenario].players[1].tactical) - ui.role_stat[0].textContent = `${view.morale[0]} (-${view.lost[0]})` + if (data.scenarios[view.scenario].players[0].tactical) + ui.role_stat[0].textContent = `${view.morale[0]} (${view.tv1})` else ui.role_stat[0].textContent = view.morale[0] - if (data.scenarios[view.scenario].players[0].tactical) - ui.role_stat[1].textContent = `${view.morale[1]} (-${view.lost[1]})` + if (data.scenarios[view.scenario].players[1].tactical) + ui.role_stat[1].textContent = `${view.morale[1]} (${view.tv2})` else ui.role_stat[1].textContent = view.morale[1] @@ -124,7 +124,8 @@ exports.view = function (state, player) { sticks: game.sticks, cubes: game.cubes, morale: game.morale, - lost: game.lost, + tv1: get_tactical_victory_points(0), + tv2: get_tactical_victory_points(1), front: game.front, reserve: game.reserve, selected: game.selected, @@ -333,6 +334,10 @@ const S45_SOOR = find_scenario(45) const S45_AUSTRIAN_GUNS = find_card(45, "Austrian Guns") const S45_CUIRASSIERS = find_card(45, "Cuirassiers") +const S46_ROCOUX = find_scenario(46) +const S46_AUSTRIANS = find_card(46, "Austrians") +const S46_THE_MOUTH_OF_HELL = find_card(46, "The Mouth of Hell") + // === SETUP === exports.setup = function (seed, scenario, options) { @@ -620,6 +625,16 @@ function remove_card(c) { } function pay_for_action(c) { + if (game.scenario === S46_ROCOUX) { + if (c === S46_THE_MOUTH_OF_HELL) { + // icky test for second reaction... + if (game.state === "screen") { + remove_cubes(c, 2) + return + } + } + } + if (data.cards[c].special) remove_cubes(c, 1) else @@ -730,6 +745,17 @@ function check_impossible_to_attack_victory() { return false } +function get_tactical_victory_points(p) { + let n = game.lost[1-p] + + if (game.scenario === S46_ROCOUX) { + if (p === 0) + n += get_sticks(S46_AUSTRIANS) + } + + return n +} + function check_victory() { let info = data.scenarios[game.scenario] @@ -750,8 +776,8 @@ function check_victory() { if (game.morale[1] === 0) return goto_game_over(P1, player_name(1) + " has run out of morale!") - let tv0 = info.players[1].lost - let tv1 = info.players[0].lost + let tv0 = get_tactical_victory_points(0) + let tv1 = get_tactical_victory_points(1) if (info.players[0].tactical > 0 && tv0 >= info.players[0].tactical) return goto_game_over(P1, player_name(0) + " tactical victory!") @@ -1653,6 +1679,7 @@ function check_cube_requirement(c, req) { return get_cubes(c) >= 3 case "Two Cubes": return get_cubes(c) >= 2 + case "One Cube*": case "Voluntary": case undefined: return get_cubes(c) >= 1 @@ -2086,7 +2113,7 @@ states.shift_to = { if (game.target2 < 0) { if (is_infantry(game.selected)) for (let c of game.front[p]) - if (c !== game.selected && is_infantry(c)) + if (c !== game.selected && is_infantry(c) && c !== S46_AUSTRIANS) gen_action_card(c) if (is_cavalry(game.selected)) for (let c of game.front[p]) diff --git a/tools/gendata.js b/tools/gendata.js index 4f091b5..101a88e 100644 --- a/tools/gendata.js +++ b/tools/gendata.js @@ -29,7 +29,7 @@ const WING = { red: 0, pink: 1, blue: 2, dkblue: 3 } const WING_ICON = [ "\u2666", "\u2665", "\u2663", "\u2660" ] const SQUEEZE_BOXES = [ "82A", "128A", "136B" , "274B", "291A" ] -const SQUEEZE_MARGINS = [ "91B", "239B", "274B", "291A", "69B", "82A" ] +const SQUEEZE_MARGINS = [ "91B", "239B", "274B", "291A", "69B" ] var cards = [ ] var card_index = {} @@ -113,16 +113,14 @@ for (let c of card_records) { card.actions = [] let squeeze = 0 - if (c.action1_effect && c.action2_effect && (c.rule_text || c.lore_text)) - squeeze |= 1 + if (c.action1_effect && c.action2_effect && (c.rule_text_2 || c.lore_text)) + squeeze = 1 else if (SQUEEZE_BOXES.includes(c.number)) - squeeze |= 1 - if (SQUEEZE_MARGINS.includes(c.number)) - squeeze |= 2 + squeeze = 1 - if (squeeze) { - card.squeeze = squeeze - result.push(`<div class="formation card squeeze${squeeze}">`) + if (SQUEEZE_MARGINS.includes(c.number)) { + card.squeeze = 1 + result.push(`<div class="formation card squeeze">`) } else { result.push(`<div class="formation card">`) } @@ -164,17 +162,19 @@ for (let c of card_records) { result.push(`<div class="dice_area">${c.dice}</div>`) } - function make_action(type, requirement, target, effect, rule_text) { + function make_action(type, requirement, target, effect, rule_text, short) { let a = { type } if (requirement) a.requirement = requirement if (target) a.target = target if (effect) a.effect = effect if (rule_text) a.rule_text = rule_text + if (short) a.short = 1 return a } if (c.action1_type) { - card.actions.push(make_action(c.action1_type, c.action1_req, c.action1_target, c.action1_effect, c.action1_rule_text)) + let short = c.action1_effect && (c.rule_text_1 || squeeze) + card.actions.push(make_action(c.action1_type, c.action1_req, c.action1_target, c.action1_effect, c.action1_rule_text, short)) result.push(`<div class="action_row">`) if (/Screen|Absorb|Counterattack/.test(c.action1_type)) result.push(`<div class="action_type reaction">${c.action1_type}</div>`) @@ -183,18 +183,22 @@ for (let c of card_records) { result.push(`<div class="action_requirement">${c.action1_req}</div>`) result.push(`<div class="action_target">${c.action1_target}</div>`) if (c.action1_effect) { - if (c.action1_rule_text) + if (c.rule_text_1 || squeeze) result.push(`<div class="action_effect short">${c.action1_effect}</div>`) else result.push(`<div class="action_effect">${c.action1_effect}</div>`) } result.push(`</div>`) - if (c.action1_rule_text) - result.push(`<div class="action_rule">${c.action1_rule_text}</div>`) + } + + if (c.rule_text_1) { + card.rule_text_1 = c.rule_text_1 + result.push(`<div class="rule_text">${c.rule_text_1}</div>`) } if (c.action2_type || c.action2_effect) { - card.actions.push(make_action(c.action2_type, c.action2_req, c.action2_target, c.action2_effect, c.action2_rule_text)) + let short = c.action2_effect && (c.rule_text_2 || squeeze) + card.actions.push(make_action(c.action2_type, c.action2_req, c.action2_target, c.action2_effect, c.action2_rule_text, short)) result.push(`<div class="action_row">`) if (/Screen|Absorb|Counterattack/.test(c.action2_type)) result.push(`<div class="action_type reaction">${c.action2_type}</div>`) @@ -203,14 +207,22 @@ for (let c of card_records) { result.push(`<div class="action_requirement">${c.action2_req}</div>`) result.push(`<div class="action_target">${c.action2_target}</div>`) if (c.action2_effect) { - if (c.action2_rule_text) + if (c.rule_text_2 || squeeze) result.push(`<div class="action_effect short">${c.action2_effect}</div>`) else result.push(`<div class="action_effect">${c.action2_effect}</div>`) } result.push(`</div>`) - if (c.action2_rule_text) - result.push(`<div class="rule_text">${c.action2_rule_text}</div>`) + } + + if (c.rule_text_2) { + card.rule_text_2 = c.rule_text_2 + result.push(`<div class="rule_text">${c.rule_text_2}</div>`) + } + + if (c.lore_text) { + card.lore_text = c.lore_text + result.push(`<div class="lore_text">${c.lore_text}</div>`) } if (c.rule) { @@ -225,16 +237,6 @@ for (let c of card_records) { } } - if (c.rule_text) { - card.rule_text = c.rule_text - result.push(`<div class="rule_text">${c.rule_text}</div>`) - } - - if (c.lore_text) { - card.lore_text = c.lore_text - result.push(`<div class="lore_text">${c.lore_text}</div>`) - } - if (c.reserve) { if (c.reserve === "RETIRE, Ward") { card.retire = 1 |