diff options
-rw-r--r-- | play.html | 21 | ||||
-rw-r--r-- | play.js | 43 | ||||
-rw-r--r-- | rules.js | 122 | ||||
-rw-r--r-- | tools/boxes.svg | 38 |
4 files changed, 159 insertions, 65 deletions
@@ -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; } @@ -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") @@ -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> |