summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.html21
-rw-r--r--play.js43
-rw-r--r--rules.js122
-rw-r--r--tools/boxes.svg38
4 files changed, 159 insertions, 65 deletions
diff --git a/play.html b/play.html
index cf58a88..72b876e 100644
--- a/play.html
+++ b/play.html
@@ -704,6 +704,11 @@ body.shift .mustered_vassals {
border-radius: 50%;
}
+.box.calendar.action {
+ border-color: white;
+ background-color: #fff6;
+}
+
.box.way.action {
border-color: dodgerblue;
}
@@ -963,6 +968,22 @@ body.shift .mustered_vassals {
position: absolute;
}
+.service_marker.teutonic.lord.selected {
+ box-shadow: 0 0 0 1px #111, 0 0 0 3px yellow;
+}
+
+.service_marker.russian.lord.selected {
+ box-shadow: 0 0 0 1px #555, 0 0 0 3px yellow;
+}
+
+.service_marker.teutonic.vassal.selected {
+ box-shadow: 0 0 0 1px #0f0d0d, 0 0 0 3px yellow;
+}
+
+.service_marker.russian.vassal.selected {
+ box-shadow: 0 0 0 1px #736e5e, 0 0 0 3px yellow;
+}
+
.service_marker.teutonic.lord.action {
box-shadow: 0 0 0 1px #111, 0 0 0 3px red;
}
diff --git a/play.js b/play.js
index 19e7187..a981407 100644
--- a/play.js
+++ b/play.js
@@ -205,6 +205,10 @@ function is_veche_action() {
return !!(view.actions && view.actions.veche === 1)
}
+function is_calendar_action(turn) {
+ return !!(view.actions && view.actions.calendar && set_has(view.actions.calendar, turn))
+}
+
function is_lord_action(lord) {
return !!(view.actions && view.actions.lord && set_has(view.actions.lord, lord))
}
@@ -432,6 +436,8 @@ const original_boxes = {
"calendar winter box14": [3196,1120,590,916],
"calendar rasputitsa box15": [3860,1120,590,916],
"calendar rasputitsa box16": [4470,1120,590,916],
+ "calendar box0": [6,62,1265,89],
+ "calendar box17": [3827,2056,1265,86],
}
const calendar_xy = [
@@ -671,6 +677,13 @@ function on_click_lord_service_marker(evt) {
}
}
+function on_click_calendar(evt) {
+ if (evt.button === 0) {
+ let id = evt.target.my_id
+ send_action('calendar', evt.target.my_id)
+ }
+}
+
function on_focus_lord_service_marker(evt) {
let lord = evt.target.my_id
let info = data.lords[lord]
@@ -1105,6 +1118,7 @@ function update_lord(ix) {
ui.lord_cylinder[ix].classList.toggle("marshal", !is_lord_on_map(LORD_ALEKSANDR))
ui.lord_cylinder[ix].classList.toggle("selected", is_lord_selected(ix))
+ ui.lord_service[ix].classList.toggle("selected", is_lord_selected(ix))
ui.lord_mat[ix].classList.toggle("selected", is_lord_selected(ix))
ui.lord_cylinder[ix].classList.toggle("command", is_lord_command(ix))
@@ -1503,6 +1517,9 @@ function on_update() {
update_court()
+ for (let i = 0; i <= 17; ++i)
+ ui.calendar[i].classList.toggle("action", is_calendar_action(i))
+
// Misc
action_button("left", "Left")
action_button("right", "Right")
@@ -1801,6 +1818,32 @@ function build_map() {
document.getElementById("boxes").appendChild(e)
}
+ ui.calendar = [
+ document.querySelector(".calendar.box0"),
+ document.querySelector(".calendar.box1"),
+ document.querySelector(".calendar.box2"),
+ document.querySelector(".calendar.box3"),
+ document.querySelector(".calendar.box4"),
+ document.querySelector(".calendar.box5"),
+ document.querySelector(".calendar.box6"),
+ document.querySelector(".calendar.box7"),
+ document.querySelector(".calendar.box8"),
+ document.querySelector(".calendar.box9"),
+ document.querySelector(".calendar.box10"),
+ document.querySelector(".calendar.box11"),
+ document.querySelector(".calendar.box12"),
+ document.querySelector(".calendar.box13"),
+ document.querySelector(".calendar.box14"),
+ document.querySelector(".calendar.box15"),
+ document.querySelector(".calendar.box16"),
+ document.querySelector(".calendar.box17")
+ ]
+
+ for (let i = 0; i <= 17; ++i) {
+ ui.calendar[i].my_id = i
+ ui.calendar[i].addEventListener("mousedown", on_click_calendar)
+ }
+
build_way("Crossroads", ".way.crossroads")
build_way("Peipus E", ".way.peipus-east")
build_way("Peipus W", ".way.peipus-north")
diff --git a/rules.js b/rules.js
index e75073a..c6858e3 100644
--- a/rules.js
+++ b/rules.js
@@ -49,7 +49,6 @@ const DIE_MISS = "01234567"
let game = null
let view = null
let states = {}
-let immediate_events = {}
exports.roles = [ P1, P2 ]
@@ -566,6 +565,20 @@ function add_spoils(type, n) {
game.spoils[type] += n
}
+function get_lord_calendar(lord) {
+ if (is_lord_on_calendar(lord))
+ return get_lord_locale(lord) - CALENDAR
+ else
+ return get_lord_service(lord)
+}
+
+function set_lord_calendar(lord, turn) {
+ if (is_lord_on_calendar(lord))
+ set_lord_locale(lord, CALENDAR + turn)
+ else
+ set_lord_service(lord, turn)
+}
+
function get_lord_locale(lord) {
return game.pieces.locale[lord]
}
@@ -2015,21 +2028,48 @@ function no_muster_of_or_by_lord(lord) {
}
function goto_immediate_event(c) {
- let e = data.cards[c].event
- log(e)
- if (immediate_events[e]) {
- immediate_events[e]()
- } else {
+ switch (c) {
+ // This Levy / Campaign
+ case EVENT_TEUTONIC_FAMINE:
+ case EVENT_RUSSIAN_FAMINE:
+ // No immediate effects
+ return end_immediate_event()
+ case EVENT_RUSSIAN_DEATH_OF_THE_POPE:
+ return goto_event_death_of_the_pope()
+ case EVENT_RUSSIAN_VALDEMAR:
+ return goto_event_russian_valdemar()
+ case EVENT_RUSSIAN_DIETRICH_VON_GRUNINGEN:
+ return goto_event_russian_dietrich()
+
+ // Immediate
+ case EVENT_TEUTONIC_GRAND_PRINCE:
+ case EVENT_TEUTONIC_TORZHOK:
+ case EVENT_TEUTONIC_POPE_GREGORY:
+ case EVENT_TEUTONIC_KHAN_BATY:
+ case EVENT_TEUTONIC_BOUNTIFUL_HARVEST:
+ case EVENT_TEUTONIC_MINDAUGAS:
+ case EVENT_TEUTONIC_SWEDISH_CRUSADE:
+
+ // Immediate
+ case EVENT_RUSSIAN_OSILIAN_REVOLT:
+ case EVENT_RUSSIAN_BATU_KHAN:
+ case EVENT_RUSSIAN_MINDAUGAS:
+ case EVENT_RUSSIAN_PRUSSIAN_REVOLT:
+ case EVENT_RUSSIAN_TEMPEST:
+ case EVENT_RUSSIAN_BOUNTIFUL_HARVEST:
+
+ default:
log("TODO")
- end_immediate_event()
+ return end_immediate_event()
}
}
function end_immediate_event() {
+ clear_undo()
resume_levy_arts_of_war()
}
-immediate_events["Death of the Pope"] = function () {
+function goto_event_death_of_the_pope() {
if (has_global_capability(AOW_TEUTONIC_WILLIAM_OF_MODENA))
game.state = "death_of_the_pope"
else
@@ -2049,7 +2089,7 @@ states.death_of_the_pope = {
// === EVENTS: SHIFT LORD OR SERVICE ===
-immediate_events["Dietrich von GrĂ¼ningen"] = function () {
+function goto_event_russian_dietrich() {
if (is_lord_in_play(LORD_ANDREAS) || is_lord_in_play(LORD_RUDOLF)) {
game.state = "dietrich_von_gruningen"
game.count = 1
@@ -2058,7 +2098,7 @@ immediate_events["Dietrich von GrĂ¼ningen"] = function () {
}
}
-immediate_events["Valdemar"] = function () {
+function goto_event_russian_valdemar() {
if (is_lord_in_play(LORD_KNUD_ABEL)) {
game.state = "valdemar"
game.count = 1
@@ -2108,55 +2148,23 @@ function action_shift_lord(lord) {
states.shift_lord = {
prompt() {
- view.prompt = `Shift ${lord_name[game.who]} or Service up to ${game.count}.`
- // TODO: click on calendar boxes? - need off-calendar buttons?
- let here = 0
- let lord = game.who
- if (is_lord_on_calendar(lord))
- here = get_lord_locale(lord) - CALENDAR
- else
- here = get_lord_service(lord)
- if (here > 0)
- view.actions.left = 1
- else
- view.actions.left = 0
- if (here < 17)
- view.actions.right = 1
- else
- view.actions.right = 0
+ view.prompt = `Shift ${lord_name[game.who]} up to ${game.count}.`
+ let here = get_lord_calendar(game.who)
+ for (let i = here - game.count; i <= here + game.count; ++i)
+ if (i >= 0 && i <= 17 && i !== here)
+ gen_action_calendar(i)
view.actions.done = 1
},
- turn(turn) {
- let lord = game.who
- log(`Shifted L${lord} to ${turn}.`)
- if (is_lord_on_calendar(lord))
- set_lord_locale(lord, CALENDAR + turn)
- else
- set_lord_service(lord, turn)
- if (--game.count === 0)
- end_immediate_event()
- },
- left() {
- let lord = game.who
- log(`Shifted L${lord} left.`)
- if (is_lord_on_calendar(lord))
- shift_lord_cylinder(lord, -1)
- else
- add_lord_service(lord, -1)
- if (--game.count === 0)
- end_immediate_event()
- },
- right() {
- let lord = game.who
- log(`Shifted L${lord} right.`)
- if (is_lord_on_calendar(lord))
- shift_lord_cylinder(lord, 1)
- else
- add_lord_service(lord, 1)
- if (--game.count === 0)
- end_immediate_event()
+ calendar(turn) {
+ log(`Shifted L${game.who} to ${turn}.`)
+ set_lord_calendar(game.who, turn)
+ game.who = NOBODY
+ game.count = 0
+ end_immediate_event()
},
done() {
+ game.who = NOBODY
+ game.count = 0
end_immediate_event()
},
}
@@ -8557,6 +8565,10 @@ function gen_action_locale(locale) {
gen_action("locale", locale)
}
+function gen_action_calendar(calendar) {
+ gen_action("calendar", calendar)
+}
+
function gen_action_laden_march(locale) {
gen_action("laden_march", locale)
}
diff --git a/tools/boxes.svg b/tools/boxes.svg
index 16b8e71..b314f6d 100644
--- a/tools/boxes.svg
+++ b/tools/boxes.svg
@@ -28,9 +28,9 @@
inkscape:window-height="480"
id="namedview8"
showgrid="false"
- inkscape:zoom="0.4218644"
- inkscape:cx="2021.1195"
- inkscape:cy="4535.2592"
+ inkscape:zoom="8"
+ inkscape:cx="3945.1381"
+ inkscape:cy="2061.5273"
inkscape:current-layer="svg2"
inkscape:document-rotation="0" />
<metadata
@@ -50,14 +50,14 @@
<image
sodipodi:absref="/home/tor/src/rally/public/nevsky/tools/map300.png"
xlink:href="map300.png"
- id="image12"
- preserveAspectRatio="none"
- height="6600"
- width="5100"
- style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1"
- sodipodi:insensitive="true"
+ y="0"
x="0"
- y="0" />
+ sodipodi:insensitive="true"
+ style="display:inline;fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1"
+ width="5100"
+ height="6600"
+ preserveAspectRatio="none"
+ id="image12" />
<rect
style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1"
id="rect838"
@@ -685,4 +685,22 @@
x="4426.3257"
y="6428.459"
inkscape:label="veche-label-bottom" />
+ <rect
+ style="fill:#8d0000;fill-opacity:0.341463;stroke:#000000;stroke-miterlimit:10"
+ id="rect80"
+ width="1265.0032"
+ height="88.73423"
+ x="5.7071066"
+ y="61.684658"
+ ry="0.610479"
+ inkscape:label="box0" />
+ <rect
+ style="fill:#8d0000;fill-opacity:0.341463;stroke:#000000;stroke-miterlimit:10"
+ id="rect82"
+ width="1265.125"
+ height="85.625"
+ x="3827.375"
+ y="2055.875"
+ ry="0.610479"
+ inkscape:label="box17" />
</svg>