summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-12-18 16:37:10 +0100
committerTor Andersson <tor@ccxvii.net>2025-02-15 15:52:46 +0100
commitd628ce1a97686a77417946d86ce3346db588ea05 (patch)
treecbfebe7e8fb9edf38b72c4ef76f85734494f1dcb
parentab2604ea91bb47663199026f71a0552ccd2ad05a (diff)
downloadmaria-d628ce1a97686a77417946d86ce3346db588ea05.tar.gz
Add combat card play validation phase.
-rw-r--r--info/readme.html2
-rw-r--r--play.html6
-rw-r--r--play.js4
-rw-r--r--rules.js84
4 files changed, 87 insertions, 9 deletions
diff --git a/info/readme.html b/info/readme.html
index 903beb0..c6c42af 100644
--- a/info/readme.html
+++ b/info/readme.html
@@ -47,7 +47,7 @@ to write down the promises and duration. Deals that have been noted this way wil
on the political display.
<p>
-If you check the Politics/Movement/Retreat/Hussars checkboxes when creating a deal,
+If you check the Politics/Movement/Combat/Retreat/Hussars checkboxes when creating a deal,
the counterparty will be able to validate your actions so that you keep your promise.
If they deem that you have broken your promise, your moves will be undone and you have to
start over. This can be a helpful feature so you don't break your promises accidentally.
diff --git a/play.html b/play.html
index 277311a..654e077 100644
--- a/play.html
+++ b/play.html
@@ -184,8 +184,9 @@
<p>
<label id="a_politics_label"><input type="checkbox" name="a_phase" value="1" id="a_phase_politics">Politics</label>
<label><input type="checkbox" name="a_phase" value="4" id="a_phase_movement">Movement</label>
+ <label><input type="checkbox" name="a_phase" value="16" id="a_phase_combat">Combat</label>
<label><input type="checkbox" name="a_phase" value="8" id="a_phase_retreat">Retreat</label>
- <label id="a_hussars_label"><input type="checkbox" name="a_phase" value="2" id="a_phase_hussars">Hussars</label>
+ <label id="a_hussars_label"><br><input type="checkbox" name="a_phase" value="2" id="a_phase_hussars">Hussars</label>
<p>
<textarea name="a_promise" placeholder="Promise..." rows=3 cols=40></textarea>
@@ -218,8 +219,9 @@
<p>
<label id="b_politics_label"><input type="checkbox" name="b_phase" value="1" id="b_phase_politics">Politics</label>
<label><input type="checkbox" name="b_phase" value="4" id="b_phase_movement">Movement</label>
+ <label><input type="checkbox" name="b_phase" value="16" id="b_phase_combat">Combat</label>
<label><input type="checkbox" name="b_phase" value="8" id="b_phase_retreat">Retreat</label>
- <label id="b_hussars_label"><input type="checkbox" name="b_phase" value="2" id="b_phase_hussars">Hussars</label>
+ <label id="b_hussars_label"><br><input type="checkbox" name="b_phase" value="2" id="b_phase_hussars">Hussars</label>
<p>
<textarea name="b_promise" placeholder="Promise..." rows=3 cols=40></textarea>
diff --git a/play.js b/play.js
index a954e2d..f78c7fb 100644
--- a/play.js
+++ b/play.js
@@ -125,6 +125,7 @@ const V_POLITICS = 1
const V_HUSSARS = 2
const V_MOVEMENT = 4
const V_RETREAT = 8
+const V_COMBAT = 16
const SPADES = 0
const CLUBS = 1
@@ -1872,6 +1873,7 @@ function phase_list(phase) {
if (phase & V_POLITICS) list.push("politics")
if (phase & V_HUSSARS) list.push("hussars")
if (phase & V_MOVEMENT) list.push("movement")
+ if (phase & V_COMBAT) list.push("combat")
if (phase & V_RETREAT) list.push("retreat")
return list.join(" ")
}
@@ -1961,6 +1963,8 @@ function propose_deal() {
window.b_phase_movement.checked = false
window.a_phase_retreat.checked = false
window.b_phase_retreat.checked = false
+ window.a_phase_combat.checked = false
+ window.b_phase_combat.checked = false
form.a_power.value = view.power
switch (view.power) {
diff --git a/rules.js b/rules.js
index f035903..9e94cd2 100644
--- a/rules.js
+++ b/rules.js
@@ -116,6 +116,7 @@ const V_POLITICS = 1
const V_HUSSARS = 2
const V_MOVEMENT = 4
const V_RETREAT = 8
+const V_COMBAT = 16
const SPADES = 0
const CLUBS = 1
@@ -3903,6 +3904,8 @@ function goto_resolve_combat() {
set_active_defender()
game.state = "combat_defend"
}
+
+ save_checkpoint()
}
function end_resolve_combat() {
@@ -3982,6 +3985,18 @@ function resume_combat_defend() {
game.state = "combat_defend"
}
+function resume_combat_attack_v() {
+ set_active_attacker()
+ game.state = "combat_attack"
+ save_checkpoint()
+}
+
+function resume_combat_defend_v() {
+ set_active_defender()
+ game.state = "combat_defend"
+ save_checkpoint()
+}
+
function gen_play_card(suit) {
let score = Math.abs(game.count)
let has_suit = false
@@ -4052,7 +4067,7 @@ states.combat_attack = {
play_combat_card(c, +1, resume_combat_attack, "combat_attack_reserve")
},
pass() {
- end_resolve_combat()
+ goto_validate_combat(end_resolve_combat)
},
}
@@ -4066,7 +4081,7 @@ states.combat_defend = {
play_combat_card(c, -1, resume_combat_defend, "combat_defend_reserve")
},
pass() {
- end_resolve_combat()
+ goto_validate_combat(end_resolve_combat)
},
}
@@ -4103,8 +4118,7 @@ states.combat_attack_swap = {
view.actions.next = 1
},
next() {
- set_active_defender()
- game.state = "combat_defend"
+ goto_validate_combat(resume_combat_defend_v)
},
}
@@ -4115,8 +4129,7 @@ states.combat_defend_swap = {
view.actions.next = 1
},
next() {
- set_active_attacker()
- game.state = "combat_attack"
+ goto_validate_combat(resume_combat_attack_v)
},
}
@@ -7045,6 +7058,65 @@ states.validate_movement_fail = {
},
}
+/* VALIDATE: COMBAT */
+
+const validate_combat_next = {
+ end_resolve_combat,
+ resume_combat_defend_v,
+ resume_combat_attack_v,
+}
+
+function goto_validate_combat(next) {
+ game.validate_next = next.name
+ goto_validate_promise(V_COMBAT, resume_validate_combat)
+}
+
+function resume_validate_combat() {
+ resume_validate_promise("validate_combat", end_validate_combat)
+}
+
+function end_validate_combat() {
+ let next = validate_combat_next[game.validate_next]
+ delete game.validate_next
+ clear_checkpoint()
+ next()
+}
+
+states.validate_combat = {
+ dont_snap: true,
+ inactive: "confirm that promises were kept",
+ prompt() {
+ let other = game.restart.power
+ prompt("Did " + power_name[other] + " keep their combat promise?")
+ view.actions.keep = 1
+ view.actions.break = 1
+ view.actions.undo = 0
+ },
+ keep() {
+ resume_validate_combat()
+ },
+ break() {
+ let other = game.power
+ restore_checkpoint()
+ game.proposal = { other, state: game.state }
+ game.state = "validate_combat_fail"
+ },
+}
+
+states.validate_combat_fail = {
+ dont_snap: true,
+ inactive: "combat",
+ prompt() {
+ prompt("Combat promise to " + power_name[game.proposal.other] + " was not kept.")
+ view.actions.resume = 1
+ view.actions.undo = 0
+ },
+ resume() {
+ game.state = game.proposal.state
+ delete game.proposal
+ },
+}
+
/* VALIDATE: RETREAT */
function goto_validate_retreat() {