summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--card_real.svg6
-rw-r--r--play.html52
-rw-r--r--play.js55
-rw-r--r--rules.js87
4 files changed, 179 insertions, 21 deletions
diff --git a/card_real.svg b/card_real.svg
index 8b7d787..d5e6377 100644
--- a/card_real.svg
+++ b/card_real.svg
@@ -1,5 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="124" height="170" version="1.2" viewBox="0 0 44 60">
-<circle cx="22" cy="30" r="15" fill="black" />
-<rect x="0" y="0" width="22" height="60" fill="white" />
+<clipPath id="half">
+<rect x="22" y="0" width="22" height="60" />
+</clipPath>
+<circle cx="22" cy="30" r="15" fill="black" clip-path="url(#half)" />
<circle cx="22" cy="30" r="15" stroke-width=".5" fill="none" stroke="black"/>
</svg>
diff --git a/play.html b/play.html
index b63f76c..b496f89 100644
--- a/play.html
+++ b/play.html
@@ -20,8 +20,7 @@ header.your_turn { background-color: orange; }
#role_Axis .role_name { background-color: darkseagreen; }
#role_Allied .role_name { background-color: tan; }
#turn_info { background-color: gainsboro; }
-.role_vp { float: right; }
-.role_info { border-bottom: 1px solid black; }
+.role_supply { float: right; }
#log { background-color: ghostwhite; }
#log .h1 { background-color: silver; font-weight: bold; padding-top:2px; padding-bottom:2px; text-align: center; }
@@ -30,12 +29,47 @@ header.your_turn { background-color: orange; }
#log > .i { padding-left: 20px; }
#log > div > .i { padding-left: 12px; }
-.role_info { padding: 15px; }
-
.action {
cursor: pointer;
}
+/* CARDS */
+
+.hand {
+ margin: 0 auto;
+ display: flex;
+ flex-wrap: wrap;
+ //justify-content: center;
+ min-height: 350px;
+ max-width: 2672px;
+ gap: 20px;
+ padding: 24px;
+}
+
+.card {
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-color: ivory;
+ width: 124px;
+ height: 170px;
+ border-radius: 8px;
+ box-shadow: 1px 1px 5px rgba(0,0,0,0.5);
+ transition: 100ms;
+}
+
+.card.real {
+ background-image: url(card_real.svg);
+}
+
+.card.dummy {
+ background-image: url(card_dummy.svg);
+}
+
+.card.action:hover {
+ transform: scale(1.1);
+}
+
+
/* BATTLE DIALOG */
#battle { background-color: #d6c4a9; background: url(texture_clear.png); }
@@ -566,18 +600,16 @@ svg .hex.tip {
<div class="role" id="role_Axis">
<div class="role_name">
Axis
- <div class="role_vp" id="axis_vp"></div>
+ <div class="role_supply" id="axis_supply">0</div>
<div class="role_user">-</div>
</div>
- <div id="info_Axis" class="role_info"></div>
</div>
<div class="role" id="role_Allied">
<div class="role_name">
Allied
- <div class="role_vp" id="allied_vp"></div>
+ <div class="role_supply" id="allied_supply">0</div>
<div class="role_user">-</div>
</div>
- <div id="info_Allied" class="role_info"></div>
</div>
<div id="turn_info">1940</div>
</div>
@@ -1074,8 +1106,8 @@ svg .hex.tip {
</div>
</div>
-
-</body>
+<div id="hand" class="hand">
+</div>
</main>
diff --git a/play.js b/play.js
index e5b8e02..fbfcbf3 100644
--- a/play.js
+++ b/play.js
@@ -40,6 +40,11 @@ let ui = {
hex_y: [],
units: [],
battle_units: [],
+ cards: [],
+ axis_supply: document.getElementById("axis_supply"),
+ allied_supply: document.getElementById("allied_supply"),
+ turn_info: document.getElementById("turn_info"),
+ hand: document.getElementById("hand"),
battle: document.getElementById("battle"),
battle_hits: [
@@ -231,6 +236,14 @@ function on_blur(evt) {
document.getElementById("status").textContent = ""
}
+function on_click_real_card(evt) {
+ send_action("real_card")
+}
+
+function on_click_dummy_card(evt) {
+ send_action("dummy_card")
+}
+
function on_click_hex(evt) {
if (evt.button === 0) {
hide_supply()
@@ -462,8 +475,28 @@ function build_units() {
}
}
+function build_cards() {
+ function build_card(i, real) {
+ let elt = ui.cards[i] = document.createElement("div")
+ if (real) {
+ elt.className = "card real hide"
+ elt.addEventListener("mousedown", on_click_real_card)
+ ui.hand.appendChild(elt)
+ } else {
+ elt.className = "card dummy hide"
+ elt.addEventListener("mousedown", on_click_dummy_card)
+ ui.hand.appendChild(elt)
+ }
+ }
+ for (let i = 0; i < 28; ++i)
+ build_card(i, true)
+ for (let i = 28; i < 42; ++i)
+ build_card(i, false)
+}
+
build_hexes()
build_units()
+build_cards()
let stack = new Array(map_w * map_h + 21)
for (let i = 0; i < stack.length; ++i)
@@ -554,6 +587,18 @@ function update_map() {
}
}
+function update_cards() {
+ if (view.cards) {
+ for (let i = 0; i < 28; ++i)
+ ui.cards[i].classList.toggle("hide", i >= view.cards[0])
+ for (let i = 0; i < 14; ++i)
+ ui.cards[i+28].classList.toggle("hide", i >= view.cards[1])
+ } else {
+ for (let i = 0; i < 42; ++i)
+ ui.cards[i+28].classList.add("hide")
+ }
+}
+
function update_battle_line(hex, line, test) {
for (let u = 0; u < units.length; ++u) {
let e = ui.battle_units[u]
@@ -635,6 +680,7 @@ function target_button(action) {
function on_update() {
update_map()
+ update_cards()
if (view.battle)
update_battle()
@@ -646,6 +692,15 @@ function on_update() {
else
ui.pursuit.classList.add("hide")
+ ui.axis_supply.textContent = view.axis_hand
+ ui.allied_supply.textContent = view.allied_hand
+ ui.turn_info.textContent = `Month: ${view.month}\nSupply Commitment: ${view.commit}`
+
+ if (view.actions && (view.actions.real_card || view.actions.dummy_card))
+ ui.cards.forEach(elt => elt.classList.add("action"))
+ else
+ ui.cards.forEach(elt => elt.classList.remove("action"))
+
action_button("select_all", "Select all")
action_button("overrun", "Overrun")
diff --git a/rules.js b/rules.js
index 3ba015c..c65c84e 100644
--- a/rules.js
+++ b/rules.js
@@ -5,9 +5,8 @@
// TODO: raiders
// TODO: legal pass withdrawal moves (reduce supply net, withdraw from fortress attack)
-// TODO: MINEFIELDS
-// TODO: SUPPLY COMMITMENT
// TODO: BUILDUP
+// TODO: MINEFIELDS
// TODO: setup scenario specials
@@ -1358,9 +1357,17 @@ function is_allied_player() {
}
function end_player_turn() {
+ // Forget partial retreats
set_clear(game.partial_retreats)
- // TODO: end when both pass
+ // Reveal supply cards
+ log_br()
+ log(`Supply Cards Played:\n${game.commit[0]} real and ${game.commit[1]} dummy.`)
+ game.commit = [ 0, 0 ]
+
+ if (game.passed === 2)
+ return end_month()
+
if (game.phasing === AXIS)
game.phasing = ALLIED
else
@@ -1383,9 +1390,45 @@ function goto_player_turn() {
set_clear(game.fired)
set_clear(game.moved)
+ game.commit = [ 0, 0 ]
+
goto_initial_supply_check()
}
+function goto_supply_commitment() {
+ game.state = 'supply_commitment'
+}
+
+states.supply_commitment = {
+ prompt() {
+ view.prompt = `Supply Commitment: ${game.commit[0]} real and ${game.commit[1]} dummy.`
+ let hand = is_axis_player() ? game.axis_hand : game.allied_hand
+ if (game.commit[0] + game.commit[1] < 3) {
+ if (hand[0] > 0)
+ gen_action('real_card')
+ if (hand[1] > 0)
+ gen_action('dummy_card')
+ }
+ gen_action_next()
+ },
+ real_card() {
+ push_undo()
+ let hand = is_axis_player() ? game.axis_hand : game.allied_hand
+ hand[0]--
+ game.commit[0]++
+ },
+ dummy_card() {
+ push_undo()
+ let hand = is_axis_player() ? game.axis_hand : game.allied_hand
+ hand[1]--
+ game.commit[1]++
+ },
+ next() {
+ push_undo()
+ goto_turn_option()
+ },
+}
+
function goto_turn_option() {
set_active_player()
game.state = 'turn_option'
@@ -1395,35 +1438,51 @@ states.turn_option = {
inactive: "turn option",
prompt() {
view.prompt = "Select Turn Option"
- gen_action('basic')
- gen_action('offensive')
- gen_action('assault')
- gen_action('blitz')
- gen_action('pass')
+ if (game.commit[0] >= 1)
+ view.actions.basic = 1
+ else
+ view.actions.basic = 0
+ if (game.commit[0] >= 2)
+ view.actions.offensive = view.actions.assault = 1
+ else
+ view.actions.offensive = view.actions.assault = 0
+ if (game.commit[0] >= 3)
+ view.actions.blitz = 1
+ else
+ view.actions.blitz = 0
+ if (game.commit[0] === 0)
+ view.actions.pass = 1
+ else
+ view.actions.pass = 0
},
basic() {
push_undo()
game.turn_option = 'basic'
+ game.passed = 0
goto_move_phase()
},
offensive() {
push_undo()
game.turn_option = 'offensive'
+ game.passed = 0
goto_move_phase()
},
assault() {
push_undo()
game.turn_option = 'assault'
+ game.passed = 0
goto_move_phase()
},
blitz() {
push_undo()
game.turn_option = 'blitz'
+ game.passed = 0
goto_move_phase()
},
pass() {
push_undo()
game.turn_option = 'pass'
+ game.passed ++
goto_move_phase()
},
}
@@ -1467,7 +1526,7 @@ function goto_initial_supply_check_rout() {
}
}
if (n === 0)
- goto_turn_option()
+ goto_supply_commitment()
else if (n === 1)
goto_rout(where, false, goto_initial_supply_check_rout)
else
@@ -4091,7 +4150,9 @@ exports.setup = function (seed, scenario, options) {
allied_sides: [],
// current turn option and selected moves
+ commit: [0, 0],
turn_option: null,
+ passed: 0,
side_limit: {},
forced: null,
rommel: 0,
@@ -4132,6 +4193,9 @@ exports.view = function(state, current) {
month: game.month,
units: game.units,
moved: game.moved,
+ axis_hand: game.axis_hand[0] + game.axis_hand[1],
+ allied_hand: game.allied_hand[0] + game.allied_hand[1],
+ commit: game.commit[0] + game.commit[1],
axis_hexes: game.axis_hexes,
allied_hexes: game.allied_hexes,
axis_sides: game.axis_sides,
@@ -4139,6 +4203,11 @@ exports.view = function(state, current) {
selected: game.selected,
}
+ if (current === AXIS)
+ view.cards = game.axis_hand
+ if (current === ALLIED)
+ view.cards = game.allied_hand
+
if (game.from1) view.from1 = game.from1
if (game.from2) view.from2 = game.from2
if (game.to1) view.to1 = game.to1