diff options
author | Joël Simoneau <simoneaujoel@gmail.com> | 2024-11-14 21:24:22 -0500 |
---|---|---|
committer | Joël Simoneau <simoneaujoel@gmail.com> | 2024-11-14 21:24:22 -0500 |
commit | d93969036927527b30cc58cf2a9744e076552efa (patch) | |
tree | 00d7a63a95e320df3cd0b5e6ed0cbc00e1a4248c | |
parent | 64d00d039aa3bf0aec0e6d453de34cd94ec5a51d (diff) | |
download | vijayanagara-d93969036927527b30cc58cf2a9744e076552efa.tar.gz |
wip; mongol invaders cards
-rw-r--r-- | const.js | 2 | ||||
-rw-r--r-- | data.js | 2 | ||||
-rw-r--r-- | play.css | 35 | ||||
-rw-r--r-- | play.html | 4 | ||||
-rw-r--r-- | play.js | 125 | ||||
-rw-r--r-- | rules.js | 243 | ||||
-rw-r--r-- | tools/gendata.js | 13 |
7 files changed, 296 insertions, 128 deletions
@@ -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 @@ -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 @@ -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)} } @@ -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> @@ -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, "<") text = text.replace(/>/g, ">") - 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 /)) { @@ -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") |