summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-12-15 15:52:21 +0100
committerTor Andersson <tor@ccxvii.net>2024-01-08 16:36:48 +0100
commit096d811c5835c0d97dd687a68465e6d68adac675 (patch)
tree6a62bba001d0fb7d8ded650b20c9971ac5932d8d
parent0659b78aa31e23c8feb6d4ff57a1cd349021b28f (diff)
downloadtable-battles-096d811c5835c0d97dd687a68465e6d68adac675.tar.gz
Rocoux. Improved layout.
-rw-r--r--cards.css18
-rw-r--r--play.html47
-rw-r--r--play.js31
-rw-r--r--rules.js35
-rw-r--r--tools/gendata.js58
5 files changed, 94 insertions, 95 deletions
diff --git a/cards.css b/cards.css
index bf1cd56..b0b9221 100644
--- a/cards.css
+++ b/cards.css
@@ -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 */
diff --git a/play.html b/play.html
index b8de55f..d95925e 100644
--- a/play.html
+++ b/play.html
@@ -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%);
diff --git a/play.js b/play.js
index 3a5f87b..a35ec2e 100644
--- a/play.js
+++ b/play.js
@@ -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]
diff --git a/rules.js b/rules.js
index f9b6c74..9455fc0 100644
--- a/rules.js
+++ b/rules.js
@@ -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