summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.css37
-rw-r--r--play.html7
-rw-r--r--play.js75
-rw-r--r--rules.js39
4 files changed, 138 insertions, 20 deletions
diff --git a/play.css b/play.css
index f5a4a4a..00d50ce 100644
--- a/play.css
+++ b/play.css
@@ -72,7 +72,7 @@ header.your_turn.ve { background-color: #ffbf32 }
/* COMBAT TABLE */
.player_pool {
- width: 500px;
+ width: 375px;
background-color: #0003;
padding: 8px;
border-radius: 24px;
@@ -80,11 +80,9 @@ header.your_turn.ve { background-color: #ffbf32 }
}
.player_name {
- color: antiquewhite;
- text-shadow: 0 0 3px goldenrod;
+ color: rgb(31, 27, 23);
font-size: 20px;
text-align: center;
- font-style: italic;
font-family: "Source Serif";
padding: 4px;
}
@@ -190,6 +188,37 @@ header.your_turn.ve { background-color: #ffbf32 }
#map.hide_pieces #pieces { display: none; }
#map.hide_tokens #tokens { display: none; }
+/* BATTLE */
+
+#attack_table {
+ position: absolute;
+ scroll-margin: 20px;
+ z-index: 200;
+ box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.5);
+ border: 1px solid black;
+ min-width: 425px;
+ background-color: #d6c4a9;
+}
+
+@media (max-width: 400px) {
+ #attack_table {
+ min-width: 90vw;
+ min-width: 90dvw;
+ }
+}
+
+#attack_header { background-color: brown; color: gold }
+#attack_header {
+ list-style: none;
+ cursor: move;
+ padding: 2px 8px;
+ line-height: 24px;
+ min-height: 24px;
+ text-align: center;
+ font-weight: bold;
+ font-size: 18px;
+}
+
/* SPACES */
path { fill: none; stroke-width: 4; }
diff --git a/play.html b/play.html
index 9dbd7b4..b8399e7 100644
--- a/play.html
+++ b/play.html
@@ -57,10 +57,11 @@
<div id="table">
-<details id="combat_table" class="hide">
+<div id="attack_table" class="hide">
+ <summary id="attack_header">Attack in $NAME</summary>
<div id="attacker" class="player_pool">
- <div id="name_attack" class="player_name">Attacker</div>
+ <div id="name_attacker" class="player_name">Attacker</div>
<div id="pool_a" class="table_pool attacker"></div>
</div>
<div id="defender" class="player_pool defender">
@@ -68,7 +69,7 @@
<div id="name_defender" class="player_name">Defender</div>
</div>
-</details>
+</div>
<div id="mapwrap">
<div id="map">
diff --git a/play.js b/play.js
index 9872564..7ac3dcc 100644
--- a/play.js
+++ b/play.js
@@ -8,6 +8,8 @@ const first_piece = data.first_piece
const last_piece = data.last_piece
const last_cavalry = 9
+const faction_name = [ "Delhi Sultanate", "Bahmani Kingdom", "Vijayanagara Empire", "Mongol Invaders" ]
+
// :r !python3 tools/genlayout.py
const LAYOUT = {
"Andhra DS": [785, 1014],
@@ -469,7 +471,11 @@ let ui = {
document.getElementById("pool_a"),
document.getElementById("pool_d"),
],
- dice: []
+ dice: [],
+ attack_table: document.getElementById("attack_table"),
+ attack_header: document.getElementById("attack_header"),
+ attack_attacker: document.getElementById("name_attacker"),
+ attack_defender: document.getElementById("name_defender"),
}
function create(t, p, ...c) {
@@ -525,6 +531,9 @@ function init_ui() {
ui.unshaded_event.onmouseenter = on_focus_unshaded_event
ui.unshaded_event.onmouseleave = on_focus_this_event
+ // Make combat table draggable
+ dragElement(ui.attack_table)
+
// player cavalry tokens
for (let i = 0; i <= LAST_CAVALRY; ++i) {
let e = null
@@ -866,12 +875,68 @@ function make_card_class_name(c) {
else
return "card card_" + c + " u" + data.card_unshaded_lines[c] + " s" + data.card_shaded_lines[c]
}
-S_VE_AVAILABLE
+
function update_player_active(name, x) {
if (roles[name])
roles[name].element.classList.toggle("active", x)
}
+function update_dice_box() {
+ ui.attack_header.textContent = "Attack in " + data.space_name[view.attack.where]
+ ui.attack_attacker.textContent = "Attacker - " + faction_name[view.attack.attacker]
+ ui.attack_defender.textContent = "Defender - " + faction_name[view.attack.target]
+
+ if (ui.attack_table.classList.contains("hide"))
+ show_dice_box(ui.attack_table)
+}
+
+function show_dice_box(box) {
+ box.classList.remove("hide")
+ box.classList.add("show")
+ box.style.top = null
+ box.style.left = null
+ // box.setAttribute("open", true)
+
+ // calculate size
+ let w = box.clientWidth
+ let h = box.clientHeight
+
+ // center where possible
+ let x = 500
+ let y = 500
+
+ box.style.top = y + "px"
+ box.style.left = x + "px"
+}
+
+function dragElement(elmnt) {
+ var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
+ ui.attack_header.onmousedown = dragMouseDown;
+
+ function dragMouseDown(e) {
+ e.preventDefault();
+ pos3 = e.clientX;
+ pos4 = e.clientY;
+ document.onmouseup = closeDragElement;
+ document.onmousemove = elementDrag;
+ }
+
+ function elementDrag(e) {
+ e.preventDefault();
+ pos1 = pos3 - e.clientX;
+ pos2 = pos4 - e.clientY;
+ pos3 = e.clientX;
+ pos4 = e.clientY;
+ elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
+ elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
+ }
+
+ function closeDragElement() {
+ document.onmouseup = null;
+ document.onmousemove = null;
+ }
+}
+
let once = true
function on_update() {
if (once) {
@@ -885,6 +950,12 @@ function on_update() {
case "VE": ui.favicon.href = "images/Flags_VE.png"; break
}
+ // Dice rolling
+ if (view.dice.reduce((sum, num) => sum + num, 0) > 0)
+ update_dice_box()
+ else
+ ui.attack_table.classList.add("hide")
+
ui.header.classList.toggle("ds", view.current === DS)
ui.header.classList.toggle("bk", view.current === BK)
ui.header.classList.toggle("ve", view.current === VE)
diff --git a/rules.js b/rules.js
index ce16773..1905b3d 100644
--- a/rules.js
+++ b/rules.js
@@ -127,6 +127,14 @@ exports.view = function (state, role) {
dice: game.dice,
}
+ if (game.cmd && game.cmd.attacker) {
+ view.attack = {
+ where: game.cmd.where,
+ attacker: game.cmd.attacker,
+ target: game.cmd.target
+ }
+ }
+
if (game.result) {
view.prompt = game.victory
} else if (!is_current_role(role)) {
@@ -1036,7 +1044,7 @@ function attack_use_cavalry(d) {
} else if (is_a_die && !is_attacker) {
screen_die(d)
} else if (!is_a_die && !is_attacker) {
- charge_die[d]
+ charge_die(d)
}
}
@@ -1214,7 +1222,7 @@ function goto_attack_cavalry() {
states.attack_cavalry = {
prompt() {
- view.prompt = "Attack: Use cavalry to..."
+ view.prompt = "Attack: Use cavalry to Charge your dice or Screen your opponent's dice."
view.who = game.cmd.selected
let curr_die = [0, 1, 2, 3, 4, 5]
@@ -1232,7 +1240,6 @@ states.attack_cavalry = {
log(`${faction_acronyms[game.current]} is using Cavalry.`)
game.cmd.cavalry = true
}
-
attack_use_cavalry(d)
},
next() {
@@ -1251,25 +1258,30 @@ function get_attack_victor() {
}
function goto_attack_casualties(step) {
+ let next_state
if (step === "target") {
game.current = game.cmd.target
game.cmd.count = game.cmd.a_hit
- game.state = "attack_casualties"
+ next_state = "attack_casualties"
} else if (step === "attacker") {
game.current = game.cmd.attacker
game.cmd.count = game.cmd.d_hit
- game.state = "attack_casualties"
+ next_state = "attack_casualties"
}
+
+ if (game.cmd.count > 0)
+ game.state = next_state
+ else
+ end_attack_casualties()
}
states.attack_casualties = {
prompt() {
-
if (
game.cmd.count > 0 &&
game.cmd.selected.filter(p => piece_faction(p) === game.current).length > 0
) {
- view.prompt = `Attack: ${faction_acronyms[game.current]} must remove ${game.cmd.count} pieces as casualties.`
+ view.prompt = `Attack: Must remove ${game.cmd.count} pieces as casualties.`
for (let p of game.cmd.selected)
if (piece_faction(p) === game.current)
@@ -1286,16 +1298,21 @@ states.attack_casualties = {
game.cmd.count -= 1
},
next() {
- if (game.current === game.cmd.target)
- goto_attack_casualties("attacker")
- else
- goto_attack_resolution()
+ end_attack_casualties()
}
}
+function end_attack_casualties() {
+ if (game.current === game.cmd.target)
+ goto_attack_casualties("attacker")
+ else
+ goto_attack_resolution()
+}
+
function goto_attack_resolution() {
if (is_rebel_faction(game.cmd.target) && is_rebel_faction(game.cmd.attacker))
console.log("Implement shift")
+ game.dice = [0, 0, 0, 0, 0, 0]
game.state = "attack"
}