summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--const.js2
-rw-r--r--data.js2
-rw-r--r--play.css35
-rw-r--r--play.html4
-rw-r--r--play.js125
-rw-r--r--rules.js243
-rw-r--r--tools/gendata.js13
7 files changed, 296 insertions, 128 deletions
diff --git a/const.js b/const.js
index 90862ef..d0cebea 100644
--- a/const.js
+++ b/const.js
@@ -34,4 +34,4 @@ const SOP_LIMITED_COMMAND = 1
const SOP_COMMAND_DECREE = 2
const SOP_EVENT_OR_COMMAND = 3
const SOP_PASS = 4
-const INELIGIBLE = 5
+const INELIGIBLE = 5 \ No newline at end of file
diff --git a/data.js b/data.js
index 4cbd6a8..cf1b2c4 100644
--- a/data.js
+++ b/data.js
@@ -1,2 +1,2 @@
-const data = {"card_title":[null,"Malik Kafur","Mongol Army Repelled","Diamond Mines of Golconda","Ears of the Sultan","Siege of Chittor","Siege of Warangal","The Conquest of Madurai","Yadava Kingdom Annexed","Kakatiya Empire Extinguished","Capital Relocated","Hindu Kush Mountains","Musunuri Nayakas","Sage of Vidyaranya","Last Great King of the Hoysalas","Uprising in Daulatabad","Gulbarga Fort","Sufi Shaikh Relocates","Center of High Culture","Bengali Resistance","Eastern Ganga Dynasty","Vindhya Range","A New Calculus","Virupaksha Temple","Stone Temple Chariots","Empire Building","Of Gods and Kings","Taghi the Elusive","The Turquoise Throne","Ashvapati, Lord of Horses","Bara Gazi Toph","The Raichur Doab","The Hare and the Hounds","Commercial Port of Goa","Bahmani Sultan Assassinated","Hindu-Muslim Marriages","Northern Alliances"],"card_order":[null,[0,1,2],[0,1,2],[1,0,2],[0,2,1],[2,0,1],[0,2,1],[0,2,1],[0,1,2],[0,2,1],[1,0,2],[0,1,2],[2,0,1],[2,1,0],[2,1,0],[1,0,2],[1,2,0],[1,2,0],[1,2,0],[1,0,2],[0,1,2],[0,1,2],[0,2,1],[2,0,1],[2,0,1],[2,1,0],[2,1,0],[0,2,1],[1,2,0],[1,0,2],[1,0,2],[1,2,0],[2,1,0],[2,1,0],[2,0,1],[1,2,0],[2,0,1]],"card_flavor":[null,"General assassinated, power struggle ensues","Pyrrhic victory","Untold riches lie just beneath the surface","Sultan’s plans intercepted","Hammir Singh reclaims a Rajput Kingdom","Continual looting encourages resistance","Tale of Madurai Sultan’s defeat chronicled in epic Sanskrit poem","Multi-ethnic polity seeds development","Telugu kingdom leaves a mythic legacy","Political damage and chaos ensues as the Delhi elite is forced to migrate","Sultanate army perishes in the snow on a scheme of foreign conquest","“Warrior kings” rise in the shadow of the Kakatiya Empire","Meeting with revered jagadguru in Sringeri sparks a foundational myth","Vijayanagara emerges from the crumbling kingdom of Veera Ballala III","Delhi resentment reaches breaking point","Defenses expanded in the first Bahmani capital","Siraj-al-Din Junaidi takes up residence","Bahmani Kingdom attracts great minds from afar; culture flourishes in the Deccan","Governors repeatedly assert independence","Prosperous kingdom falls into decline","Mountainous region provides a natural buffer from Delhi","Madhava of Sangamagrama founds the Kerala School of Astronomy and Mathematics","Temple to Shiva merges regional goddess cults","Chariots carry representations of Puranic Hindu gods","Lords of the Eastern and Western Oceans","Telugu poet Srinatha revolutionizes the craft and weaves the tapestry of an Empire, while Sufi devotional songs of Amir Khusrau praise the Sultans in Delhi","Fugitive rebel an expensive distraction","Bahmanis cross the Krishna river into Telangana","Bahmani rulers likened to Hindu god","Gigantic cannons defend Bahmani forts","Repeated raids over fertile lands","Identical empire origin stories lean on regional cult mythologies","Struggle for critical maritime routes","Vijayanagara captures Goa while the Bahmanis are destabilized","Bahmani Sultan weds a Hindu bride","Vijayanagara probes an alliance with Delhi"],"card_flavor_shaded":[null,"Favored slave-general brilliant in battle","Sultan’s mercenary army victorious","Sultan’s oppressive taxation","Network of spies covers the Deccan","Massacre at Chittor","Koh-i-Noor diamond among war spoils","Sultan’s generals plunder Pandyan kingdom","Sultanate reclaims natural stronghold","Sultanate tires of awaiting tribute","Sultan shortens his reach into the Deccan","Grandiose schemes pay dividends","Telugu warriors no match for siege technology from Central Asia","Inferior military suffers early defeats","Delhi’s armies plunder the Hoysala Capital","Commanders sentenced to death","Bahmani Kingdom threatens control","Relationships sour between Bahmani rulers and Sufi shaikhs","Divisions among Deccanis and newcomers","Criminals conscripted to reclaim Bengal","Sultanate invades Orissa","Long campaigns go unchallenged","Narayana Pandita’s mathematical treatises offer new insights of immediate use","Symbols of sovereignty destroyed","Cultural development draws interest","Sultan’s new roads thrust into the Deccan",null,"The Sultan marches west in pursuit","Telangana Nayakas implore allies to attack","War horses and siege technology imported from overseas","Gunpowder and cannons appear suddenly in the subcontinent","Massive casualties in both kingdoms","Persian values inherited from Delhi","Competition over ports boils over","Bahmani successor ushers in a period of social reform and cultural revival","Diffusion and dilution of culture","Alliance rejected"],"spaces":[{"type":"province","id":"Andhra","pop":1,"adjacent":[2,5,6,7,9,12]},{"type":"province","id":"Bengal","pop":2,"adjacent":[2,4,9]},{"type":"province","id":"Gondwana","pop":1,"adjacent":[0,1,4,6,9]},{"type":"province","id":"Gujarat","pop":2,"adjacent":[6,7,8,10,11]},{"type":"province","id":"Jaunpur","pop":1,"adjacent":[1,2,13,8]},{"type":"province","id":"Karnataka","pop":2,"adjacent":[0,7,12]},{"type":"province","id":"Madhyadesh","pop":1,"adjacent":[0,2,3,8,7,9]},{"type":"province","id":"Maharashtra","pop":2,"adjacent":[0,3,5,6,8]},{"type":"province","id":"Malwa","pop":2,"adjacent":[3,4,6,7,13,10]},{"type":"province","id":"Orissa","pop":1,"adjacent":[0,1,2,6]},{"type":"province","id":"Rajput Kingdoms","pop":1,"adjacent":[3,8,13,15,11]},{"type":"province","id":"Sindh","pop":1,"adjacent":[3,10,14,15]},{"type":"province","id":"Tamilakam","pop":1,"adjacent":[0,5]},{"type":"capital","id":"Delhi","pop":0,"adjacent":[4,8,10,15]},{"type":"mongol","id":"Mountain Passes","pop":0,"adjacent":[11,15]},{"type":"mongol","id":"Punjab","pop":0,"adjacent":[10,11,13,14]},{"type":"holdbox","id":"MI_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"DS_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_DI_2","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_DI_4","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_1","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_2","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_3","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_4","pop":null,"adjacent":[]}],"space_name":["Andhra","Bengal","Gondwana","Gujarat","Jaunpur","Karnataka","Madhyadesh","Maharashtra","Malwa","Orissa","Rajput Kingdoms","Sindh","Tamilakam","Delhi","Mountain Passes","Punjab","MI_available","DS_available","BK_available","VE_available","BK_DI_2","BK_DI_4","VE_DI_1","VE_DI_2","VE_DI_3","VE_DI_4"],"first_piece":[[0,5,10],[42,47,null],[65,70,null],[null,null,92]],"last_piece":[[4,9,41],[46,64,null],[69,91,null],[null,null,103]]}
+const data = {"card_title":[null,"Malik Kafur","Mongol Army Repelled","Diamond Mines of Golconda","Ears of the Sultan","Siege of Chittor","Siege of Warangal","The Conquest of Madurai","Yadava Kingdom Annexed","Kakatiya Empire Extinguished","Capital Relocated","Hindu Kush Mountains","Musunuri Nayakas","Sage of Vidyaranya","Last Great King of the Hoysalas","Uprising in Daulatabad","Gulbarga Fort","Sufi Shaikh Relocates","Center of High Culture","Bengali Resistance","Eastern Ganga Dynasty","Vindhya Range","A New Calculus","Virupaksha Temple","Stone Temple Chariots","Empire Building","Of Gods and Kings","Taghi the Elusive","The Turquoise Throne","Ashvapati, Lord of Horses","Bara Gazi Toph","The Raichur Doab","The Hare and the Hounds","Commercial Port of Goa","Bahmani Sultan Assassinated","Hindu-Muslim Marriages","Northern Alliances","Mongol Invasion","Mongol Invasion","Mongol Invasion","Mongol Invasion","Mongol Invasion","Mongol Invasion","Timurid Empire","Timurid Empire","Zenith of the Delhi Sultanate","Rise of the Rebel Sultans","Lords of the Deccan"],"card_order":[null,[0,1,2],[0,1,2],[1,0,2],[0,2,1],[2,0,1],[0,2,1],[0,2,1],[0,1,2],[0,2,1],[1,0,2],[0,1,2],[2,0,1],[2,1,0],[2,1,0],[1,0,2],[1,2,0],[1,2,0],[1,2,0],[1,0,2],[0,1,2],[0,1,2],[0,2,1],[2,0,1],[2,0,1],[2,1,0],[2,1,0],[0,2,1],[1,2,0],[1,0,2],[1,0,2],[1,2,0],[2,1,0],[2,1,0],[2,0,1],[1,2,0],[2,0,1],null,null,null,null,null,null,null,null,null,null,null],"card_flavor":[null,"General assassinated, power struggle ensues","Pyrrhic victory","Untold riches lie just beneath the surface","Sultan’s plans intercepted","Hammir Singh reclaims a Rajput Kingdom","Continual looting encourages resistance","Tale of Madurai Sultan’s defeat chronicled in epic Sanskrit poem","Multi-ethnic polity seeds development","Telugu kingdom leaves a mythic legacy","Political damage and chaos ensues as the Delhi elite is forced to migrate","Sultanate army perishes in the snow on a scheme of foreign conquest","“Warrior kings” rise in the shadow of the Kakatiya Empire","Meeting with revered jagadguru in Sringeri sparks a foundational myth","Vijayanagara emerges from the crumbling kingdom of Veera Ballala III","Delhi resentment reaches breaking point","Defenses expanded in the first Bahmani capital","Siraj-al-Din Junaidi takes up residence","Bahmani Kingdom attracts great minds from afar; culture flourishes in the Deccan","Governors repeatedly assert independence","Prosperous kingdom falls into decline","Mountainous region provides a natural buffer from Delhi","Madhava of Sangamagrama founds the Kerala School of Astronomy and Mathematics","Temple to Shiva merges regional goddess cults","Chariots carry representations of Puranic Hindu gods","Lords of the Eastern and Western Oceans","Telugu poet Srinatha revolutionizes the craft and weaves the tapestry of an Empire, while Sufi devotional songs of Amir Khusrau praise the Sultans in Delhi","Fugitive rebel an expensive distraction","Bahmanis cross the Krishna river into Telangana","Bahmani rulers likened to Hindu god","Gigantic cannons defend Bahmani forts","Repeated raids over fertile lands","Identical empire origin stories lean on regional cult mythologies","Struggle for critical maritime routes","Vijayanagara captures Goa while the Bahmanis are destabilized","Bahmani Sultan weds a Hindu bride","Vijayanagara probes an alliance with Delhi"],"card_flavor_shaded":[null,"Favored slave-general brilliant in battle","Sultan’s mercenary army victorious","Sultan’s oppressive taxation","Network of spies covers the Deccan","Massacre at Chittor","Koh-i-Noor diamond among war spoils","Sultan’s generals plunder Pandyan kingdom","Sultanate reclaims natural stronghold","Sultanate tires of awaiting tribute","Sultan shortens his reach into the Deccan","Grandiose schemes pay dividends","Telugu warriors no match for siege technology from Central Asia","Inferior military suffers early defeats","Delhi’s armies plunder the Hoysala Capital","Commanders sentenced to death","Bahmani Kingdom threatens control","Relationships sour between Bahmani rulers and Sufi shaikhs","Divisions among Deccanis and newcomers","Criminals conscripted to reclaim Bengal","Sultanate invades Orissa","Long campaigns go unchallenged","Narayana Pandita’s mathematical treatises offer new insights of immediate use","Symbols of sovereignty destroyed","Cultural development draws interest","Sultan’s new roads thrust into the Deccan",null,"The Sultan marches west in pursuit","Telangana Nayakas implore allies to attack","War horses and siege technology imported from overseas","Gunpowder and cannons appear suddenly in the subcontinent","Massive casualties in both kingdoms","Persian values inherited from Delhi","Competition over ports boils over","Bahmani successor ushers in a period of social reform and cultural revival","Diffusion and dilution of culture","Alliance rejected"],"spaces":[{"type":"province","id":"Andhra","pop":1,"adjacent":[2,5,6,7,9,12]},{"type":"province","id":"Bengal","pop":2,"adjacent":[2,4,9]},{"type":"province","id":"Gondwana","pop":1,"adjacent":[0,1,4,6,9]},{"type":"province","id":"Gujarat","pop":2,"adjacent":[6,7,8,10,11]},{"type":"province","id":"Jaunpur","pop":1,"adjacent":[1,2,13,8]},{"type":"province","id":"Karnataka","pop":2,"adjacent":[0,7,12]},{"type":"province","id":"Madhyadesh","pop":1,"adjacent":[0,2,3,8,7,9]},{"type":"province","id":"Maharashtra","pop":2,"adjacent":[0,3,5,6,8]},{"type":"province","id":"Malwa","pop":2,"adjacent":[3,4,6,7,13,10]},{"type":"province","id":"Orissa","pop":1,"adjacent":[0,1,2,6]},{"type":"province","id":"Rajput Kingdoms","pop":1,"adjacent":[3,8,13,15,11]},{"type":"province","id":"Sindh","pop":1,"adjacent":[3,10,14,15]},{"type":"province","id":"Tamilakam","pop":1,"adjacent":[0,5]},{"type":"capital","id":"Delhi","pop":0,"adjacent":[4,8,10,15]},{"type":"mongol","id":"Mountain Passes","pop":0,"adjacent":[11,15]},{"type":"mongol","id":"Punjab","pop":0,"adjacent":[10,11,13,14]},{"type":"holdbox","id":"MI_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"DS_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_available","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_DI_2","pop":null,"adjacent":[]},{"type":"holdbox","id":"BK_DI_4","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_1","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_2","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_3","pop":null,"adjacent":[]},{"type":"holdbox","id":"VE_DI_4","pop":null,"adjacent":[]}],"space_name":["Andhra","Bengal","Gondwana","Gujarat","Jaunpur","Karnataka","Madhyadesh","Maharashtra","Malwa","Orissa","Rajput Kingdoms","Sindh","Tamilakam","Delhi","Mountain Passes","Punjab","MI_available","DS_available","BK_available","VE_available","BK_DI_2","BK_DI_4","VE_DI_1","VE_DI_2","VE_DI_3","VE_DI_4"],"first_piece":[[0,5,10],[42,47,null],[65,70,null],[null,null,92]],"last_piece":[[4,9,41],[46,64,null],[69,91,null],[null,null,103]]}
if (typeof module !== 'undefined') module.exports = data
diff --git a/play.css b/play.css
index 069a4a2..7924533 100644
--- a/play.css
+++ b/play.css
@@ -67,6 +67,7 @@ main { background-color: #777; }
#log .h1 { background-image: linear-gradient(60deg, gray, turquoise, gold); text-shadow: 0 0 4px white; }
#log .h2 { background-color: gainsboro; padding-top:2px; padding-bottom:2px; text-align: center; }
+#log .h1.mi { background-image: linear-gradient(60deg, rgb(83, 8, 8), rgb(255, 0, 0), rgb(44, 44, 40)); text-shadow: 0 0 4px rgb(0, 0, 0); color: white}
#log .h2.ds { background-color: silver }
#log .h2.bk { background-color: #85dbd2 }
#log .h2.ve { background-color: #e4ba6e }
@@ -374,17 +375,14 @@ path.tip { stroke: white; stroke-dasharray: 4 4; }
.card.card_37{background-image:url(cards100/Mongol_Invasion_BK_front.jpg)}
.card.card_38{background-image:url(cards100/Mongol_Invasion_BK_front.jpg)}
.card.card_39{background-image:url(cards100/Mongol_Invasion_BK_front.jpg)}
-.card.card_40{background-image:url(cards100/Mongol_Invasion_BK_front.jpg)}
-.card.card_41{background-image:url(cards100/Mongol_Invasion_BK_front.jpg)}
+.card.card_40{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
+.card.card_41{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
.card.card_42{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
-.card.card_43{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
-.card.card_44{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
-.card.card_45{background-image:url(cards100/Mongol_Invasion_VE_front.jpg)}
-.card.card_46{background-image:url(cards100/Timurid_Empire_front.jpg)}
-.card.card_47{background-image:url(cards100/Timurid_Empire_front.jpg)}
-.card.card_48{background-image:url(cards100/Succession1_front.jpg)}
-.card.card_49{background-image:url(cards100/Succession2_front.jpg)}
-.card.card_50{background-image:url(cards100/Succession3_front.jpg)}
+.card.card_43{background-image:url(cards100/Timurid_Empire_front.jpg)}
+.card.card_44{background-image:url(cards100/Timurid_Empire_front.jpg)}
+.card.card_45{background-image:url(cards100/Succession1_front.jpg)}
+.card.card_46{background-image:url(cards100/Succession2_front.jpg)}
+.card.card_47{background-image:url(cards100/Succession3_front.jpg)}
.card.card_dynasty_khalji{background-image:url(cards100/Dynasty_front.jpg)}
.card.card_dynasty_khalji{background-image:url(cards100/Dynasty_back.jpg)}
@@ -429,17 +427,14 @@ path.tip { stroke: white; stroke-dasharray: 4 4; }
.card.card_37{background-image:url(cards200/Mongol_Invasion_BK_front.jpg)}
.card.card_38{background-image:url(cards200/Mongol_Invasion_BK_front.jpg)}
.card.card_39{background-image:url(cards200/Mongol_Invasion_BK_front.jpg)}
-.card.card_40{background-image:url(cards200/Mongol_Invasion_BK_front.jpg)}
-.card.card_41{background-image:url(cards200/Mongol_Invasion_BK_front.jpg)}
+.card.card_40{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
+.card.card_41{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
.card.card_42{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
-.card.card_43{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
-.card.card_44{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
-.card.card_45{background-image:url(cards200/Mongol_Invasion_VE_front.jpg)}
-.card.card_46{background-image:url(cards200/Timurid_Empire_front.jpg)}
-.card.card_47{background-image:url(cards200/Timurid_Empire_front.jpg)}
-.card.card_48{background-image:url(cards200/Succession1_front.jpg)}
-.card.card_49{background-image:url(cards200/Succession2_front.jpg)}
-.card.card_50{background-image:url(cards200/Succession3_front.jpg)}
+.card.card_43{background-image:url(cards200/Timurid_Empire_front.jpg)}
+.card.card_44{background-image:url(cards200/Timurid_Empire_front.jpg)}
+.card.card_45{background-image:url(cards200/Succession1_front.jpg)}
+.card.card_46{background-image:url(cards200/Succession2_front.jpg)}
+.card.card_47{background-image:url(cards200/Succession3_front.jpg)}
.card.card_dynasty_khalji{background-image:url(cards200/Dynasty_front.jpg)}
.card.card_dynasty_khalji{background-image:url(cards200/Dynasty_back.jpg)}
}
diff --git a/play.html b/play.html
index 5f0d504..79cc6fb 100644
--- a/play.html
+++ b/play.html
@@ -318,8 +318,8 @@ c-32 0 -38 0 -46 2 -11 2 -20 5 -23 6 -2 0 -5 2 -8 3 -4 1 -10 4 -14 6 -6 4
<div class="token" id="token_bk_vp" style="left:23px;top:8px"></div>
<div class="token" id="token_ve_vp" style="left:23px;top:36px"></div>
- <div class="token" id="token_bk_influence" style="left:25px;top:1195px"></div>
- <div class="token" id="token_ve_influence" style="left:25px;top:1300px"></div>
+ <div class="token" id="token_bk_influence" style="left:25px;top:1193px"></div>
+ <div class="token" id="token_ve_influence" style="left:95px;top:1299px"></div>
<div class="token" id="token_mongol_cavalry" style="left:89px;top:220px"></div>
</div>
diff --git a/play.js b/play.js
index 1187b79..02d85d7 100644
--- a/play.js
+++ b/play.js
@@ -509,6 +509,9 @@ function init_ui() {
register_action(ui.resources[DS], "resources", DS)
register_action(ui.resources[BK], "resources", BK)
register_action(ui.resources[VE], "resources", VE)
+ register_action(ui.tokens.token_bk_influence, "inf", BK)
+ register_action(ui.tokens.token_ve_influence, "inf", VE)
+ register_action(ui.tokens.token_mongol_cavalry, "token", 10)
ui.this_card.onmouseenter = on_focus_this_event
ui.this_card.onmouseleave = on_blur_event
@@ -657,6 +660,13 @@ function layout_available(faction, type, xorig, yorig) {
layout_pieces(list, xorig, yorig + 35, null, AVAILABLE)
}
+function layout_influence() {
+ let e = ui.tokens.token_bk_influence
+ e.style.left = 25 + 71 * view.inf[BK] + "px"
+ e = ui.tokens.token_ve_influence
+ e.style.left = 25 + 71 * view.inf[VE] + "px"
+}
+
function layout_pieces(list, xorig, yorig, discs, s) {
const dx = 17
const dy = 11
@@ -756,13 +766,12 @@ let sop_xy = [
function layout_sop() {
let i, z
let n_sop, offset
- let order = data.card_order[view.deck[0]]
for (let [sop, [x, y, dx, dy]] of sop_xy.entries()) {
n_sop = view.cylinder.filter(v => v === sop).length
i = 0
z = 1
- for (let faction of order) {
+ for (let faction of view.order) {
if (view.cylinder[faction] === sop) {
offset = n_sop === 1 ? 0 : (-1 + i * (2/(n_sop - 1))) * n_sop
place_piece(ui.cylinder[faction], x + dx * offset, y + dy * offset, z)
@@ -866,8 +875,8 @@ function on_update() {
ui.header.classList.toggle("bk", view.current === BK)
ui.header.classList.toggle("ve", view.current === VE)
- ui.tokens.token_bk_influence.classList.toggle("action", is_action("bk_inf"))
- ui.tokens.token_ve_influence.classList.toggle("action", is_action("ve_inf"))
+ ui.tokens.token_bk_influence.classList.toggle("action", is_action("inf", BK))
+ ui.tokens.token_ve_influence.classList.toggle("action", is_action("inf", VE))
ui.resources[DS].classList.toggle("action", is_action("resources", DS))
ui.resources[BK].classList.toggle("action", is_action("resources", BK))
@@ -939,7 +948,7 @@ function on_update() {
}
// Action highlighting
- if (s <= S_PUNJAB) {
+ if (s <= S_MONGOL_INVADERS) {
ui.spaces[s].classList.toggle("action", is_action("space", s))
ui.spaces[s].classList.toggle("selected", view.where === s)
}
@@ -1011,6 +1020,9 @@ function on_update() {
for (let i = 0; i < ui.pieces.length; ++i)
ui.pieces[i].classList.toggle("selected", view.who === i)
+ // Influence
+ layout_influence()
+
// SOP buttons
action_button("command_decree", "Command & Decree")
action_button("event_command", "Event or Command")
@@ -1039,6 +1051,13 @@ function on_update() {
action_button("tax", "Tax")
action_button("trade", "Trade")
+ // MI buttons
+ action_button("advance", "Advance")
+ action_button("end_advance", "End Advance")
+ action_button("amass", "Amass")
+ action_button("mi_attack", "Attack & Plunder")
+ action_button("end_gifts", "End Compromising Gifts")
+
action_button("next", "Next")
action_button("undo", "Undo")
@@ -1228,76 +1247,6 @@ return
"ask_resources",
"ask_shipment",
])
-
- // Select Faction
- action_button("govt", "Government")
- action_button("farc", "FARC")
- action_button("auc", "AUC")
- action_button("cartels", "Cartels")
-
- confirm_action_button("choose_govt", "Government", "Choose GOVERNMENT to execute this event?")
- confirm_action_button("choose_farc", "FARC", "Choose FARC to execute this event?")
- confirm_action_button("choose_auc", "AUC", "Choose AUC to execute this event?")
- confirm_action_button("choose_cartels", "Cartels", "Choose CARTELS to execute this event?")
-
- // Select Operation
- action_button("train", "Train")
- action_button("patrol", "Patrol")
- action_button("sweep", "Sweep")
- action_button("assault", "Assault")
- action_button("rally", "Rally")
- action_button("march", "March")
- action_button("attack", "Attack")
- action_button("terror", "Terror")
-
- // Select Special Activity
- action_button("air_lift", "Air Lift")
- action_button("air_strike", "Air Strike")
- action_button("eradicate", "Eradicate")
- action_button("extort", "Extort")
- action_button("ambush", "Ambush")
- action_button("assassinate", "Assassinate")
- action_button("kidnap", "Kidnap")
- action_button("cultivate", "Cultivate")
- action_button("process", "Process")
- action_button("bribe", "Bribe")
-
- // Train/Rally sub-actions
- action_button("move", "Move")
- action_button("flip", "Flip")
- action_button("base", "Base")
- action_button("civic", "Civic Action")
-
- action_button("support", "Support")
- action_button("opposition", "Opposition")
-
- action_button("remove", "Remove")
- action_button("roll", "Roll")
- action_button("skip", "Skip")
- action_button("next", "Next")
- action_button("pass", "Pass")
-
- action_button("end_train", "End Train")
- action_button("end_patrol", "End Patrol")
- action_button("end_sweep", "End Sweep")
- action_button("end_assault", "End Assault")
- action_button("end_rally", "End Rally")
- action_button("end_march", "End March")
- action_button("end_attack", "End Attack")
- action_button("end_terror", "End Terror")
-
- action_button("end_air_lift", "End Air Lift")
- action_button("end_extort", "End Extort")
- action_button("end_assassinate", "End Assassinate")
- action_button("end_kidnap", "End Kidnap")
- action_button("end_process", "End Process")
- action_button("end_bribe", "End Bribe")
-
- action_button("end_event", "End Event")
-
- action_button("deny", "Deny")
- action_button("done", "Done")
- action_button("undo", "Undo")
}
/* TOOLTIPS */
@@ -1381,24 +1330,40 @@ function on_log(text) {
text = text.replace(/</g, "&lt;")
text = text.replace(/>/g, "&gt;")
- if (text.match(/^\.h1/)) {
+ if (text.match(/^\.h1 Mongol Invaders/)) {
+ text = text.substring(19)
+ p.className = "h1 mi"
+ }
+ else if (text.match(/^\.h1/)) {
text = text.substring(4)
p.className = "h1"
}
else if (text.match(/^\.h2 Delhi Sultanate/)) {
- text = text.substring(3)
+ text = text.substring(4)
+ p.className = "h2 ds"
+ }
+ else if (text.match(/^\.h2 ds/)) {
+ text = text.substring(6)
p.className = "h2 ds"
}
else if (text.match(/^\.h2 Bahmani Kingdom/)) {
- text = text.substring(3)
+ text = text.substring(4)
+ p.className = "h2 bk"
+ }
+ else if (text.match(/^\.h2 bk/)) {
+ text = text.substring(6)
p.className = "h2 bk"
}
else if (text.match(/^\.h2 Vijayanagara Empire/)) {
- text = text.substring(3)
+ text = text.substring(4)
+ p.className = "h2 ve"
+ }
+ else if (text.match(/^\.h2 ve/)) {
+ text = text.substring(6)
p.className = "h2 ve"
}
else if (text.match(/^\.h2 Mongol Invaders/)) {
- text = text.substring(3)
+ text = text.substring(4)
p.className = "h2 mi"
}
else if (text.match(/^\.h2 /)) {
diff --git a/rules.js b/rules.js
index ba0a1d8..d3a6a3b 100644
--- a/rules.js
+++ b/rules.js
@@ -47,6 +47,7 @@ const last_space = S_PUNJAB
const last_province = S_TAMILAKAM
const faction_name = [ "Delhi Sultanate", "Bahmani Kingdom", "Vijayanagara Empire", "Mongol Invaders" ]
+const faction_acronyms = [ "ds", "bk", "ve", "mi" ]
exports.scenarios = [ "Standard", "Solo" ]
@@ -89,14 +90,14 @@ exports.view = function (state, role) {
let deck_size = Math.max(0, game.deck.length - 1)
view = {
+ state: game.state,
prompt: null,
actions: null,
log: game.log,
current: game.current,
vp: game.vp,
resources: game.resources,
- bk_inf: 0,
- ve_inf: 0,
+ inf: game.inf,
deck: [ this_card, deck_size, game.of_gods_and_kings ],
cavalry: game.cavalry,
cylinder: game.cylinder,
@@ -104,6 +105,7 @@ exports.view = function (state, role) {
tributary: game.tributary,
control: game.control,
rebel: game.rebel,
+ order: game.order,
}
if (game.result) {
@@ -189,14 +191,14 @@ exports.setup = function (seed, scenario, _options) {
resources: [ 12, 6, 7 ],
vp: [ 18, 0, 0 ],
prosperity: [ 0, 0, 0 ],
- bk_inf: 0,
- ve_inf: 0,
+ inf: [null, 1, 2],
tributary: 8191, // all 13 provinces
control: [0, 0, 0],
rebel: [null, 0, 0], // amir/raja rebel status
pieces: Array(104).fill(AVAILABLE), // piece locations
cavalry: Array(10).fill(AVAILABLE),
deck: [],
+ order: [],
cmd: {
type: null,
limited: null,
@@ -204,6 +206,7 @@ exports.setup = function (seed, scenario, _options) {
spaces: [],
pieces: [],
where: null,
+ who: null,
},
decree: 0
}
@@ -230,7 +233,7 @@ exports.setup = function (seed, scenario, _options) {
}
function setup_deck() {
- game.deck = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
+ game.deck = [ 1, 37, 2, 41, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
}
function setup_standard() {
@@ -285,11 +288,19 @@ function this_card() {
}
function goto_card() {
- log_h1("C" + this_card())
- if (this_card() === "todo")
- console.log("todo")
- else
+ if (this_card() >= 37 && this_card() <= 39) {
+ log_h1("Mongol Invaders C" + this_card())
+ goto_mongol_invaders(BK)
+ } else if (this_card() >= 40 && this_card() <= 42) {
+ log_h1("Mongol Invaders C" + this_card())
+ goto_mongol_invaders(VE)
+ } else {
+ log_h1("C" + this_card())
+ adjust_eligibility(DS)
+ adjust_eligibility(BK)
+ adjust_eligibility(VE)
resume_event_card()
+ }
}
function resume_event_card() {
@@ -304,10 +315,6 @@ function resume_event_card() {
function end_card() {
clear_undo()
- adjust_eligibility(DS)
- adjust_eligibility(BK)
- adjust_eligibility(VE)
-
array_remove(game.deck, 0)
goto_card()
}
@@ -341,8 +348,8 @@ function did_option(e) {
}
function next_eligible_faction() {
- let order = data.card_order[this_card()]
- for (let faction of order)
+ game.order = data.card_order[this_card()]
+ for (let faction of game.order)
if (is_eligible(faction))
return faction
return -1
@@ -373,6 +380,16 @@ function goto_pass() {
resume_event_card()
}
+function goto_advance() {
+ init_command("Advance")
+ game.state = "advance"
+}
+
+function goto_amass() {
+ init_command("Amass")
+ game.state = "amass"
+}
+
function goto_build() {
init_command("Build")
game.state = "build"
@@ -388,6 +405,13 @@ function goto_collect() {
game.state = "collect"
}
+function goto_compromising_gifts() {
+ if (game.inf[game.cmd.who] === 0)
+ end_card()
+ else
+ game.state = "compromising_gifts"
+}
+
function goto_conscript() {
init_command("Conscript")
game.state = "conscript"
@@ -462,6 +486,29 @@ function end_march_space() {
game.state = "march"
}
+function goto_mi_attack() {
+ init_command("Attack & Plunder")
+ game.state = "mi_attack"
+}
+
+function goto_mongol_invaders(faction) {
+ game.cmd = {}
+ game.current = faction
+ game.cmd.free = 2
+ goto_strategic_assistance()
+}
+
+function goto_strategic_assistance() {
+ if (game.cmd.free > 0) {
+ game.state = "strategic_assistance"
+ }
+ else {
+ game.cmd.free = 1
+ goto_compromising_gifts()
+ }
+
+}
+
function goto_rally() {
init_command("Rally")
game.state = "rally"
@@ -589,6 +636,55 @@ states.lim_command = {
rebel: goto_rebel,
}
+states.advance = {
+ prompt() {
+ view.prompt = "Advance: Select the Advance destination"
+
+ if (has_piece(S_MOUNTAIN_PASSES, MI, TROOPS))
+ gen_action_space(S_PUNJAB)
+
+ if (has_piece(S_PUNJAB, MI, TROOPS))
+ gen_action_space(S_DELHI)
+ },
+ space(s) {
+ game.cmd.where = s
+ game.state = "advance_space"
+ }
+}
+
+states.advance_space = {
+ prompt() {
+ view.prompt = "Advance: Move any number of Mongol Invaders into destination"
+
+ let origin = game.cmd.where === S_DELHI ? S_PUNJAB : S_MOUNTAIN_PASSES
+ for (let p = first_piece[MI][TROOPS]; p <= last_piece[MI][TROOPS]; ++p)
+ if (piece_space(p) === origin)
+ gen_action_piece(p)
+
+ view.actions.end_advance = true
+ },
+ piece(p) {
+ place_piece(p, game.cmd.where)
+ },
+ end_advance() {
+ game.cmd.free -= 1
+ goto_strategic_assistance()
+ }
+}
+
+states.amass = {
+ prompt() {
+ view.prompt = "Amass: Place three invaders into the Mountain Passes"
+
+ gen_action_space(S_MONGOL_INVADERS)
+ },
+ space(s) {
+ amass()
+ game.cmd.free -= 1
+ goto_strategic_assistance()
+ }
+}
+
states.build = {
prompt() {
if (game.current === BK)
@@ -619,15 +715,15 @@ states.build = {
states.cavalry = {
prompt() {
view.prompt = `Gain Cavalry: Take ${game.cmd.n_count} calvary tokens`
-
gen_take_cavalry(game.current)
+
},
token(c) {
game.cmd.n_count -= 1
set_cavalry_faction(c, game.current)
- if (!game.cmd.n_count)
- game.state = "command_decree"
-
+ if (!game.cmd.n_count) {
+ game.state = game.cmd.save
+ }
}
}
@@ -646,6 +742,32 @@ states.collect = {
}
}
+states.compromising_gifts = {
+ prompt() {
+
+ if (game.cmd.free === 1) {
+ view.prompt = "Compromising gifts: Reduce your influence by one to gain two Resources and two Cavalry tokens"
+ gen_action_influence(game.current)
+ } else {
+ view.prompt = "Compromising gifts: End gift exchange"
+ }
+
+ view.actions.end_gifts = true
+ },
+ inf() {
+ game.cmd.free = 0
+ game.inf[game.current] -= 1
+ log_h2(faction_acronyms[game.current] + "Compromising Gifts")
+ logi_resources(game.current, 2)
+ add_resources(game.current, 2)
+ game.cmd.save = "compromising_gifts"
+ goto_cavalry(2)
+ },
+ end_gifts() {
+ end_card()
+ }
+}
+
states.conscript = {
prompt() {
@@ -894,6 +1016,18 @@ states.rebel = {
end_rebel: end_command,
}
+states.strategic_assistance = {
+ prompt() {
+ let n_command = (game.cmd.free === 2) ? "two" : "one"
+ view.prompt = `Strategic Assistance: ${faction_name[game.cmd.who]} must execute ${n_command} Mongol Invaders Commands`
+
+ gen_mi_command()
+ },
+ amass: goto_amass,
+ advance: goto_advance,
+ mi_attack: goto_mi_attack,
+}
+
states.tax = {
prompt() {
view.prompt = `Tax: Collect ${tax_count()} from Controlled Prosperity and Temples`
@@ -910,7 +1044,6 @@ states.tax = {
}
states.trade = {
- // TODO : Add horses logic to trade
prompt() {
view.prompt = `Trade: Collect ${trade_count()} from Provinces with your presence`
@@ -1141,6 +1274,64 @@ function trade_count() {
return count
}
+/* MONGOL INVADERS COMMANDS */
+
+function gen_mi_command() {
+ view.actions.amass = can_amass() ? 1 : 0
+ view.actions.advance = can_advance() ? 1 : 0
+ view.actions.mi_attack = can_mi_attack() ? 1 : 0
+}
+
+function can_advance() {
+ return (has_piece(S_MOUNTAIN_PASSES, MI, TROOPS) || has_piece(S_PUNJAB, MI, TROOPS))
+}
+
+function can_amass() {
+ return has_piece(AVAILABLE, MI, TROOPS)
+}
+
+function can_mi_attack() {
+ let first = first_piece[MI][TROOPS]
+ let last = last_piece[MI][TROOPS]
+ for (let p = first; p <= last; ++p)
+ if (piece_space(p) >= 0)
+ return true
+ return false
+}
+
+function amass() {
+ let n_available = Math.min(count_faction_pieces(AVAILABLE, MI), 3)
+
+ // Add three to mountain pass
+ log_space(S_MOUNTAIN_PASSES, "Amass")
+ push_summary()
+ for (let i = 0; i < n_available; ++i) {
+ let p = find_piece(AVAILABLE, MI, TROOPS)
+ log_summary_place(p)
+ place_piece(p, S_MOUNTAIN_PASSES)
+ }
+ pop_summary()
+
+ amass_trinkle_down(S_MOUNTAIN_PASSES, S_PUNJAB)
+ amass_trinkle_down(S_PUNJAB, S_DELHI)
+
+}
+
+function amass_trinkle_down(s_source, s_dest) {
+ let n = count_faction_pieces(s_source, MI) - 4
+ if (n > 0) {
+ log_space(s_dest, "Amass")
+ push_summary()
+ for (let i = n; i > 0; --i) {
+ let p = find_piece(s_source, MI, TROOPS)
+ log_summary_place(p)
+ place_piece(p, s_dest)
+ }
+ pop_summary()
+ }
+}
+
+
/* TRIBUTARY AND REBELS */
function add_tributary(s) {
@@ -1376,8 +1567,8 @@ function set_cavalry_faction(c, f) {
}
function trade_cavalry_count() {
- if (game.bk_inf === 0) return 1;
- if (game.bk_inf <= 2) return 2;
+ if (game.inf[BK] === 0) return 1;
+ if (game.inf[BK] <= 2) return 2;
return 3;
}
@@ -1407,8 +1598,8 @@ function update_control() {
function update_vp() {
game.vp[DS] = game.prosperity[DS]
- game.vp[BK] = game.prosperity[BK] + count_pieces_on_map(BK, DISC) + game.bk_inf
- game.vp[VE] = game.prosperity[VE] + count_pieces_on_map(VE, DISC) + game.ve_inf
+ game.vp[BK] = game.prosperity[BK] + count_pieces_on_map(BK, DISC) + game.inf[BK]
+ game.vp[VE] = game.prosperity[VE] + count_pieces_on_map(VE, DISC) + game.inf[VE]
}
/* ACTIONS */
@@ -1419,6 +1610,10 @@ function gen_action(action, argument) {
set_add(view.actions[action], argument)
}
+function gen_action_influence(faction) {
+ gen_action("inf", faction)
+}
+
function gen_action_piece(p) {
gen_action("piece", p)
}
diff --git a/tools/gendata.js b/tools/gendata.js
index 6b93daf..0828f7e 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -80,6 +80,19 @@ def_card(23, "Virupaksha Temple")
def_card(24, "Stone Temple Chariots")
def_card(34, "Bahmani Sultan Assassinated")
def_card(36, "Northern Alliances")
+order = null
+def_card(37, "Mongol Invasion")
+def_card(38, "Mongol Invasion")
+def_card(39, "Mongol Invasion")
+def_card(40, "Mongol Invasion")
+def_card(41, "Mongol Invasion")
+def_card(42, "Mongol Invasion")
+def_card(43, "Timurid Empire")
+def_card(44, "Timurid Empire")
+def_card(45, "Zenith of the Delhi Sultanate")
+def_card(46, "Rise of the Rebel Sultans")
+def_card(47, "Lords of the Deccan")
+
flavor("1. Malik Kafur", "General assassinated, power struggle ensues", "Favored slave-general brilliant in battle")