From e1a636df18394d60f808f210235045fbf2533291 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 16 Dec 2022 16:07:39 +0100 Subject: Add adjacent_by_waterway. --- data.js | 106 +++++++-------- rules.js | 391 +++++++++++++++++++++++++++++++++++++------------------ tools/gendata.js | 5 + 3 files changed, 322 insertions(+), 180 deletions(-) diff --git a/data.js b/data.js index 4d8cc22..c1a60fc 100644 --- a/data.js +++ b/data.js @@ -3,59 +3,59 @@ seaports:[0,2,8,9,15,29,30,34], conquerable:[0,1,7,8,9,10,11,12,13,24,25,26,27,28,29,30,31,32,33,34,35,36], strongholds:[0,1,7,8,9,10,11,12,13,24,25,26,27,32,33,34,35,36], locales:[ -{"name":"Reval","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Danish Estonia","ways":[[5,25],[3,32]],"box":{"x":601,"y":3564,"w":206,"h":91},"adjacent":[3,5],"adjacent_by_trackway":[3,5]}, -{"name":"Wesenberg","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Danish Estonia","ways":[[5,26],[17,30],[6,31]],"box":{"x":1448,"y":3625,"w":304,"h":60},"adjacent":[5,6,17],"adjacent_by_trackway":[5,6,17]}, -{"name":"Narwia","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[7,2],[38,2],[49,2],[46,17],[6,27],[33,28]],"box":{"x":2371,"y":3549,"w":123,"h":31},"adjacent":[6,7,33,38,46,49],"adjacent_by_trackway":[6,33]}, -{"name":"Warbola","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[0,32],[4,33],[8,35]],"box":{"x":292,"y":3797,"w":142,"h":31},"adjacent":[0,4,8],"adjacent_by_trackway":[0,4,8]}, -{"name":"Harrien","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[3,33],[17,34]],"box":{"x":567,"y":3983,"w":200,"h":100},"adjacent":[3,17],"adjacent_by_trackway":[3,17]}, -{"name":"Revala","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[0,25],[1,26]],"box":{"x":1030,"y":3410,"w":200,"h":100},"adjacent":[0,1],"adjacent_by_trackway":[0,1]}, -{"name":"Wierland","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[2,27],[23,29],[1,31]],"box":{"x":1999,"y":3680,"w":200,"h":100},"adjacent":[1,2,23],"adjacent_by_trackway":[1,2,23]}, -{"name":"Dorpat","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[12,0,3],[22,0],[2,2],[38,2],[49,2],[11,3],[23,36]],"box":{"x":1625,"y":4589,"w":253,"h":91},"adjacent":[2,11,12,22,23,38,49],"adjacent_by_trackway":[12,22,23]}, -{"name":"Leal","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[3,35],[15,37]],"box":{"x":108,"y":4266,"w":205,"h":91},"adjacent":[3,15],"adjacent_by_trackway":[3,15]}, -{"name":"Riga","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[13,8]],"box":{"x":273,"y":6231,"w":205,"h":91},"adjacent":[13],"adjacent_by_trackway":[]}, -{"name":"Adsel","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[13,9],[18,44],[21,44],[14,45]],"box":{"x":1504,"y":5612,"w":185,"h":60},"adjacent":[13,14,18,21],"adjacent_by_trackway":[14,18,21]}, -{"name":"Fellin","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[7,3],[12,3],[15,7],[17,7],[20,38]],"box":{"x":1013,"y":4583,"w":184,"h":61},"adjacent":[7,12,15,17,20],"adjacent_by_trackway":[20]}, -{"name":"Odenpäh","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[7,0,3],[22,0],[11,3],[14,46]],"box":{"x":1378,"y":5103,"w":250,"h":61},"adjacent":[7,11,14,22],"adjacent_by_trackway":[7,14,22]}, -{"name":"Wenden","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[9,8],[10,9],[19,40],[21,41]],"box":{"x":909,"y":5759,"w":232,"h":60},"adjacent":[9,10,19,21],"adjacent_by_trackway":[19,21]}, -{"name":"Kirrumpäh","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[10,45],[12,46],[32,47]],"box":{"x":1877,"y":5389,"w":175,"h":30},"adjacent":[10,12,32],"adjacent_by_trackway":[10,12,32]}, -{"name":"Pernau","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,7],[17,7],[8,37]],"box":{"x":517,"y":4580,"w":118,"h":30},"adjacent":[8,11,17],"adjacent_by_trackway":[8]}, -{"name":"Rositten","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[21,42],[18,43]],"box":{"x":2046,"y":6307,"w":146,"h":30},"adjacent":[18,21],"adjacent_by_trackway":[18,21]}, -{"name":"Jerwen","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,7],[15,7],[1,30],[4,34]],"box":{"x":1064,"y":3946,"w":200,"h":100},"adjacent":[1,4,11,15],"adjacent_by_trackway":[1,4]}, -{"name":"Lettgallia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[16,43],[10,44],[21,44],[39,50],[32,51]],"box":{"x":2048,"y":5777,"w":200,"h":100},"adjacent":[10,16,21,32,39],"adjacent_by_trackway":[10,16,21,32,39]}, -{"name":"Metsepole","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[20,39],[13,40]],"box":{"x":509,"y":5226,"w":200,"h":100},"adjacent":[13,20],"adjacent_by_trackway":[13,20]}, -{"name":"Sackala","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,38],[19,39]],"box":{"x":617,"y":4769,"w":200,"h":100},"adjacent":[11,19],"adjacent_by_trackway":[11,19]}, -{"name":"Tolowa","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[13,41],[16,42],[10,44],[18,44]],"box":{"x":1541,"y":5933,"w":200,"h":100},"adjacent":[10,13,16,18],"adjacent_by_trackway":[10,13,16,18]}, -{"name":"Ugaunia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[7,0],[12,0],[49,48],[32,49]],"box":{"x":1957,"y":4940,"w":200,"h":100},"adjacent":[7,12,32,49],"adjacent_by_trackway":[7,12,32,49]}, -{"name":"Waiga","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[6,29],[7,36]],"box":{"x":1535,"y":4113,"w":200,"h":100},"adjacent":[6,7],"adjacent_by_trackway":[6,7]}, -{"name":"Novgorod","type":"novgorod","stronghold":3,"walls":3,"vp":3,"region":"Novgorodan Rus","ways":[[27,6],[47,6],[31,23],[41,62],[40,63]],"box":{"x":4318,"y":4315,"w":333,"h":112},"adjacent":[27,31,40,41,47],"adjacent_by_trackway":[40,41]}, -{"name":"Ladoga","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[31,22],[30,24],[44,59]],"box":{"x":4619,"y":2817,"w":238,"h":90},"adjacent":[30,31,44],"adjacent_by_trackway":[44]}, -{"name":"Pskov","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[49,4],[39,10],[32,52],[52,68],[37,69]],"box":{"x":2680,"y":5263,"w":205,"h":91},"adjacent":[32,37,39,49,52],"adjacent_by_trackway":[32,37,52]}, -{"name":"Rusa","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[24,6],[47,6],[28,13]],"box":{"x":4329,"y":5166,"w":205,"h":92},"adjacent":[24,28,47],"adjacent_by_trackway":[]}, -{"name":"Lovat","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[27,13],[36,14]],"box":{"x":4243,"y":5581,"w":187,"h":63},"adjacent":[27,36],"adjacent_by_trackway":[]}, -{"name":"Luga","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[33,18]],"box":{"x":2667,"y":3295,"w":148,"h":62},"adjacent":[33],"adjacent_by_trackway":[]}, -{"name":"Neva","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[25,24],[51,55],[45,57],[44,58]],"box":{"x":3924,"y":2934,"w":148,"h":62},"adjacent":[25,44,45,51],"adjacent_by_trackway":[44,45,51]}, -{"name":"Volkhov","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[25,22],[24,23]],"box":{"x":4591,"y":3783,"w":231,"h":63},"adjacent":[24,25],"adjacent_by_trackway":[]}, -{"name":"Izborsk","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[14,47],[22,49],[18,51],[26,52]],"box":{"x":2240,"y":5431,"w":241,"h":62},"adjacent":[14,18,22,26],"adjacent_by_trackway":[14,18,22,26]}, -{"name":"Kaibolovo","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[29,18],[42,19],[2,28],[34,53]],"box":{"x":2904,"y":3522,"w":285,"h":62},"adjacent":[2,29,34,42],"adjacent_by_trackway":[2,34]}, -{"name":"Koporye","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[33,53],[51,54]],"box":{"x":3133,"y":3160,"w":241,"h":62},"adjacent":[33,51],"adjacent_by_trackway":[33,51]}, -{"name":"Porkhov","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[47,16],[37,70],[48,71]],"box":{"x":3515,"y":5467,"w":241,"h":63},"adjacent":[37,47,48],"adjacent_by_trackway":[37,48]}, -{"name":"Velikiye Luki","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[28,14],[50,72]],"box":{"x":3706,"y":6347,"w":351,"h":61},"adjacent":[28,50],"adjacent_by_trackway":[50]}, -{"name":"Dubrovno","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[47,15],[26,69],[35,70]],"box":{"x":3153,"y":5214,"w":161,"h":31},"adjacent":[26,35,47],"adjacent_by_trackway":[26,35]}, -{"name":"Gdov","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[49,1,2],[2,2],[7,2],[46,65]],"box":{"x":2427,"y":4149,"w":88,"h":30},"adjacent":[2,7,46,49],"adjacent_by_trackway":[46]}, -{"name":"Ostrov","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[26,10],[50,11],[18,50]],"box":{"x":2746,"y":5717,"w":115,"h":30},"adjacent":[18,26,50],"adjacent_by_trackway":[18]}, -{"name":"Sablia","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[42,20],[24,63],[47,64]],"box":{"x":3788,"y":4541,"w":104,"h":31},"adjacent":[24,42,47],"adjacent_by_trackway":[24,47]}, -{"name":"Tesovo","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[42,21],[43,61],[24,62]],"box":{"x":3936,"y":4102,"w":121,"h":32},"adjacent":[24,42,43],"adjacent_by_trackway":[24,43]}, -{"name":"Zheltsy","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[33,19],[40,20],[41,21],[46,66]],"box":{"x":3501,"y":4176,"w":128,"h":30},"adjacent":[33,40,41,46],"adjacent_by_trackway":[46]}, -{"name":"Ingria","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[51,56],[44,60],[41,61]],"box":{"x":3820,"y":3639,"w":200,"h":100},"adjacent":[41,44,51],"adjacent_by_trackway":[41,44,51]}, -{"name":"Izhora","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[30,58],[25,59],[43,60]],"box":{"x":4074,"y":3323,"w":200,"h":100},"adjacent":[25,30,43],"adjacent_by_trackway":[25,30,43]}, -{"name":"Karelia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[30,57]],"box":{"x":3833,"y":2408,"w":200,"h":100},"adjacent":[30],"adjacent_by_trackway":[30]}, -{"name":"Plyussa River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[2,17],[38,65],[42,66],[52,67]],"box":{"x":2829,"y":4234,"w":200,"h":100},"adjacent":[2,38,42,52],"adjacent_by_trackway":[38,42,52]}, -{"name":"Shelon River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[24,6],[27,6],[37,15],[35,16],[40,64]],"box":{"x":3654,"y":4864,"w":200,"h":100},"adjacent":[24,27,35,37,40],"adjacent_by_trackway":[40]}, -{"name":"Sorot River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[50,12],[35,71]],"box":{"x":3299,"y":5781,"w":200,"h":100},"adjacent":[35,50],"adjacent_by_trackway":[35]}, -{"name":"Uzmen","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[38,1,2],[2,2],[7,2],[26,4],[52,5],[22,48]],"box":{"x":2112,"y":4692,"w":200,"h":100},"adjacent":[2,7,22,26,38,52],"adjacent_by_trackway":[22]}, -{"name":"Velikaya River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[39,11],[48,12],[36,72]],"box":{"x":3029,"y":6090,"w":200,"h":100},"adjacent":[36,39,48],"adjacent_by_trackway":[36]}, -{"name":"Vod","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[34,54],[30,55],[43,56]],"box":{"x":3488,"y":3345,"w":200,"h":100},"adjacent":[30,34,43],"adjacent_by_trackway":[30,34,43]}, -{"name":"Zhelcha River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[49,5],[46,67],[26,68]],"box":{"x":2782,"y":4586,"w":200,"h":100},"adjacent":[26,46,49],"adjacent_by_trackway":[26,46]}, +{"name":"Reval","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Danish Estonia","ways":[[5,25],[3,32]],"box":{"x":601,"y":3564,"w":206,"h":91},"adjacent":[3,5],"adjacent_by_trackway":[3,5],"adjacent_by_waterway":[]}, +{"name":"Wesenberg","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Danish Estonia","ways":[[5,26],[17,30],[6,31]],"box":{"x":1448,"y":3625,"w":304,"h":60},"adjacent":[5,6,17],"adjacent_by_trackway":[5,6,17],"adjacent_by_waterway":[]}, +{"name":"Narwia","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[7,2],[38,2],[49,2],[46,17],[6,27],[33,28]],"box":{"x":2371,"y":3549,"w":123,"h":31},"adjacent":[6,7,33,38,46,49],"adjacent_by_trackway":[6,33],"adjacent_by_waterway":[7,38,46,49]}, +{"name":"Warbola","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[0,32],[4,33],[8,35]],"box":{"x":292,"y":3797,"w":142,"h":31},"adjacent":[0,4,8],"adjacent_by_trackway":[0,4,8],"adjacent_by_waterway":[]}, +{"name":"Harrien","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[3,33],[17,34]],"box":{"x":567,"y":3983,"w":200,"h":100},"adjacent":[3,17],"adjacent_by_trackway":[3,17],"adjacent_by_waterway":[]}, +{"name":"Revala","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[0,25],[1,26]],"box":{"x":1030,"y":3410,"w":200,"h":100},"adjacent":[0,1],"adjacent_by_trackway":[0,1],"adjacent_by_waterway":[]}, +{"name":"Wierland","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Danish Estonia","ways":[[2,27],[23,29],[1,31]],"box":{"x":1999,"y":3680,"w":200,"h":100},"adjacent":[1,2,23],"adjacent_by_trackway":[1,2,23],"adjacent_by_waterway":[]}, +{"name":"Dorpat","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[12,0,3],[22,0],[2,2],[38,2],[49,2],[11,3],[23,36]],"box":{"x":1625,"y":4589,"w":253,"h":91},"adjacent":[2,11,12,22,23,38,49],"adjacent_by_trackway":[12,22,23],"adjacent_by_waterway":[2,11,38,49]}, +{"name":"Leal","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[3,35],[15,37]],"box":{"x":108,"y":4266,"w":205,"h":91},"adjacent":[3,15],"adjacent_by_trackway":[3,15],"adjacent_by_waterway":[]}, +{"name":"Riga","type":"bishopric","stronghold":3,"walls":4,"vp":2,"region":"Crusader Livonia","ways":[[13,8]],"box":{"x":273,"y":6231,"w":205,"h":91},"adjacent":[13],"adjacent_by_trackway":[],"adjacent_by_waterway":[13]}, +{"name":"Adsel","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[13,9],[18,44],[21,44],[14,45]],"box":{"x":1504,"y":5612,"w":185,"h":60},"adjacent":[13,14,18,21],"adjacent_by_trackway":[14,18,21],"adjacent_by_waterway":[13]}, +{"name":"Fellin","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[7,3],[12,3],[15,7],[17,7],[20,38]],"box":{"x":1013,"y":4583,"w":184,"h":61},"adjacent":[7,12,15,17,20],"adjacent_by_trackway":[20],"adjacent_by_waterway":[7,12,15,17]}, +{"name":"Odenpäh","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[7,0,3],[22,0],[11,3],[14,46]],"box":{"x":1378,"y":5103,"w":250,"h":61},"adjacent":[7,11,14,22],"adjacent_by_trackway":[7,14,22],"adjacent_by_waterway":[11]}, +{"name":"Wenden","type":"castle","stronghold":2,"walls":4,"vp":1,"region":"Crusader Livonia","ways":[[9,8],[10,9],[19,40],[21,41]],"box":{"x":909,"y":5759,"w":232,"h":60},"adjacent":[9,10,19,21],"adjacent_by_trackway":[19,21],"adjacent_by_waterway":[9,10]}, +{"name":"Kirrumpäh","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[10,45],[12,46],[32,47]],"box":{"x":1877,"y":5389,"w":175,"h":30},"adjacent":[10,12,32],"adjacent_by_trackway":[10,12,32],"adjacent_by_waterway":[]}, +{"name":"Pernau","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,7],[17,7],[8,37]],"box":{"x":517,"y":4580,"w":118,"h":30},"adjacent":[8,11,17],"adjacent_by_trackway":[8],"adjacent_by_waterway":[11,17]}, +{"name":"Rositten","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[21,42],[18,43]],"box":{"x":2046,"y":6307,"w":146,"h":30},"adjacent":[18,21],"adjacent_by_trackway":[18,21],"adjacent_by_waterway":[]}, +{"name":"Jerwen","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,7],[15,7],[1,30],[4,34]],"box":{"x":1064,"y":3946,"w":200,"h":100},"adjacent":[1,4,11,15],"adjacent_by_trackway":[1,4],"adjacent_by_waterway":[11,15]}, +{"name":"Lettgallia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[16,43],[10,44],[21,44],[39,50],[32,51]],"box":{"x":2048,"y":5777,"w":200,"h":100},"adjacent":[10,16,21,32,39],"adjacent_by_trackway":[10,16,21,32,39],"adjacent_by_waterway":[]}, +{"name":"Metsepole","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[20,39],[13,40]],"box":{"x":509,"y":5226,"w":200,"h":100},"adjacent":[13,20],"adjacent_by_trackway":[13,20],"adjacent_by_waterway":[]}, +{"name":"Sackala","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[11,38],[19,39]],"box":{"x":617,"y":4769,"w":200,"h":100},"adjacent":[11,19],"adjacent_by_trackway":[11,19],"adjacent_by_waterway":[]}, +{"name":"Tolowa","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[13,41],[16,42],[10,44],[18,44]],"box":{"x":1541,"y":5933,"w":200,"h":100},"adjacent":[10,13,16,18],"adjacent_by_trackway":[10,13,16,18],"adjacent_by_waterway":[]}, +{"name":"Ugaunia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[7,0],[12,0],[49,48],[32,49]],"box":{"x":1957,"y":4940,"w":200,"h":100},"adjacent":[7,12,32,49],"adjacent_by_trackway":[7,12,32,49],"adjacent_by_waterway":[]}, +{"name":"Waiga","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Crusader Livonia","ways":[[6,29],[7,36]],"box":{"x":1535,"y":4113,"w":200,"h":100},"adjacent":[6,7],"adjacent_by_trackway":[6,7],"adjacent_by_waterway":[]}, +{"name":"Novgorod","type":"novgorod","stronghold":3,"walls":3,"vp":3,"region":"Novgorodan Rus","ways":[[27,6],[47,6],[31,23],[41,62],[40,63]],"box":{"x":4318,"y":4315,"w":333,"h":112},"adjacent":[27,31,40,41,47],"adjacent_by_trackway":[40,41],"adjacent_by_waterway":[27,31,47]}, +{"name":"Ladoga","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[31,22],[30,24],[44,59]],"box":{"x":4619,"y":2817,"w":238,"h":90},"adjacent":[30,31,44],"adjacent_by_trackway":[44],"adjacent_by_waterway":[30,31]}, +{"name":"Pskov","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[49,4],[39,10],[32,52],[52,68],[37,69]],"box":{"x":2680,"y":5263,"w":205,"h":91},"adjacent":[32,37,39,49,52],"adjacent_by_trackway":[32,37,52],"adjacent_by_waterway":[39,49]}, +{"name":"Rusa","type":"city","stronghold":3,"walls":3,"vp":2,"region":"Novgorodan Rus","ways":[[24,6],[47,6],[28,13]],"box":{"x":4329,"y":5166,"w":205,"h":92},"adjacent":[24,28,47],"adjacent_by_trackway":[],"adjacent_by_waterway":[24,28,47]}, +{"name":"Lovat","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[27,13],[36,14]],"box":{"x":4243,"y":5581,"w":187,"h":63},"adjacent":[27,36],"adjacent_by_trackway":[],"adjacent_by_waterway":[27,36]}, +{"name":"Luga","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[33,18]],"box":{"x":2667,"y":3295,"w":148,"h":62},"adjacent":[33],"adjacent_by_trackway":[],"adjacent_by_waterway":[33]}, +{"name":"Neva","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[25,24],[51,55],[45,57],[44,58]],"box":{"x":3924,"y":2934,"w":148,"h":62},"adjacent":[25,44,45,51],"adjacent_by_trackway":[44,45,51],"adjacent_by_waterway":[25]}, +{"name":"Volkhov","type":"traderoute","stronghold":0,"walls":0,"vp":1,"region":"Novgorodan Rus","ways":[[25,22],[24,23]],"box":{"x":4591,"y":3783,"w":231,"h":63},"adjacent":[24,25],"adjacent_by_trackway":[],"adjacent_by_waterway":[24,25]}, +{"name":"Izborsk","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[14,47],[22,49],[18,51],[26,52]],"box":{"x":2240,"y":5431,"w":241,"h":62},"adjacent":[14,18,22,26],"adjacent_by_trackway":[14,18,22,26],"adjacent_by_waterway":[]}, +{"name":"Kaibolovo","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[29,18],[42,19],[2,28],[34,53]],"box":{"x":2904,"y":3522,"w":285,"h":62},"adjacent":[2,29,34,42],"adjacent_by_trackway":[2,34],"adjacent_by_waterway":[29,42]}, +{"name":"Koporye","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[33,53],[51,54]],"box":{"x":3133,"y":3160,"w":241,"h":62},"adjacent":[33,51],"adjacent_by_trackway":[33,51],"adjacent_by_waterway":[]}, +{"name":"Porkhov","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[47,16],[37,70],[48,71]],"box":{"x":3515,"y":5467,"w":241,"h":63},"adjacent":[37,47,48],"adjacent_by_trackway":[37,48],"adjacent_by_waterway":[47]}, +{"name":"Velikiye Luki","type":"fort","stronghold":1,"walls":3,"vp":1,"region":"Novgorodan Rus","ways":[[28,14],[50,72]],"box":{"x":3706,"y":6347,"w":351,"h":61},"adjacent":[28,50],"adjacent_by_trackway":[50],"adjacent_by_waterway":[28]}, +{"name":"Dubrovno","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[47,15],[26,69],[35,70]],"box":{"x":3153,"y":5214,"w":161,"h":31},"adjacent":[26,35,47],"adjacent_by_trackway":[26,35],"adjacent_by_waterway":[47]}, +{"name":"Gdov","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[49,1,2],[2,2],[7,2],[46,65]],"box":{"x":2427,"y":4149,"w":88,"h":30},"adjacent":[2,7,46,49],"adjacent_by_trackway":[46],"adjacent_by_waterway":[2,7,49]}, +{"name":"Ostrov","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[26,10],[50,11],[18,50]],"box":{"x":2746,"y":5717,"w":115,"h":30},"adjacent":[18,26,50],"adjacent_by_trackway":[18],"adjacent_by_waterway":[26,50]}, +{"name":"Sablia","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[42,20],[24,63],[47,64]],"box":{"x":3788,"y":4541,"w":104,"h":31},"adjacent":[24,42,47],"adjacent_by_trackway":[24,47],"adjacent_by_waterway":[42]}, +{"name":"Tesovo","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[42,21],[43,61],[24,62]],"box":{"x":3936,"y":4102,"w":121,"h":32},"adjacent":[24,42,43],"adjacent_by_trackway":[24,43],"adjacent_by_waterway":[42]}, +{"name":"Zheltsy","type":"town","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[33,19],[40,20],[41,21],[46,66]],"box":{"x":3501,"y":4176,"w":128,"h":30},"adjacent":[33,40,41,46],"adjacent_by_trackway":[46],"adjacent_by_waterway":[33,40,41]}, +{"name":"Ingria","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[51,56],[44,60],[41,61]],"box":{"x":3820,"y":3639,"w":200,"h":100},"adjacent":[41,44,51],"adjacent_by_trackway":[41,44,51],"adjacent_by_waterway":[]}, +{"name":"Izhora","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[30,58],[25,59],[43,60]],"box":{"x":4074,"y":3323,"w":200,"h":100},"adjacent":[25,30,43],"adjacent_by_trackway":[25,30,43],"adjacent_by_waterway":[]}, +{"name":"Karelia","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[30,57]],"box":{"x":3833,"y":2408,"w":200,"h":100},"adjacent":[30],"adjacent_by_trackway":[30],"adjacent_by_waterway":[]}, +{"name":"Plyussa River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[2,17],[38,65],[42,66],[52,67]],"box":{"x":2829,"y":4234,"w":200,"h":100},"adjacent":[2,38,42,52],"adjacent_by_trackway":[38,42,52],"adjacent_by_waterway":[2]}, +{"name":"Shelon River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[24,6],[27,6],[37,15],[35,16],[40,64]],"box":{"x":3654,"y":4864,"w":200,"h":100},"adjacent":[24,27,35,37,40],"adjacent_by_trackway":[40],"adjacent_by_waterway":[24,27,35,37]}, +{"name":"Sorot River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[50,12],[35,71]],"box":{"x":3299,"y":5781,"w":200,"h":100},"adjacent":[35,50],"adjacent_by_trackway":[35],"adjacent_by_waterway":[50]}, +{"name":"Uzmen","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[38,1,2],[2,2],[7,2],[26,4],[52,5],[22,48]],"box":{"x":2112,"y":4692,"w":200,"h":100},"adjacent":[2,7,22,26,38,52],"adjacent_by_trackway":[22],"adjacent_by_waterway":[2,7,26,38,52]}, +{"name":"Velikaya River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[39,11],[48,12],[36,72]],"box":{"x":3029,"y":6090,"w":200,"h":100},"adjacent":[36,39,48],"adjacent_by_trackway":[36],"adjacent_by_waterway":[39,48]}, +{"name":"Vod","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[34,54],[30,55],[43,56]],"box":{"x":3488,"y":3345,"w":200,"h":100},"adjacent":[30,34,43],"adjacent_by_trackway":[30,34,43],"adjacent_by_waterway":[]}, +{"name":"Zhelcha River","type":"region","stronghold":0,"walls":0,"vp":0,"region":"Novgorodan Rus","ways":[[49,5],[46,67],[26,68]],"box":{"x":2782,"y":4586,"w":200,"h":100},"adjacent":[26,46,49],"adjacent_by_trackway":[26,46],"adjacent_by_waterway":[49]}, ], ways:[ {"type":"trackway","locales":[7,12,22],"name":"Crossroads"}, diff --git a/rules.js b/rules.js index e283e94..85f4745 100644 --- a/rules.js +++ b/rules.js @@ -1,7 +1,8 @@ "use strict" // TODO: delay pay step if there is no feed or disband to be done -// TODO: supply (+ lodya) + +// TODO: Supply (+ lodya) // CAPABILITIES // TODO: Ransom (T) @@ -403,6 +404,18 @@ function enemy_player() { return null } +function get_global_assets(type) { + return pack4_get(game.assets, type) +} + +function set_global_assets(type, n) { + game.assets = pack4_set(game.assets, type, n) +} + +function add_global_assets(type, n) { + game.assets = pack4_set(game.assets, type, pack4_get(game.assets) + n) +} + function get_lord_locale(lord) { return game.lords.locale[lord] } @@ -552,6 +565,116 @@ function count_lord_horses(lord) { ) } +function count_lord_boats(lord) { + let boats = get_lord_assets(lord, BOAT) + + if (lord_has_capability(lord, AOW_RUSSIAN_LODYA)) { + // TODO: one option or the other (only matters for supply) + let ships = get_lord_assets(lord, SHIP) + if (ships > 2) + ships = 2 + if (boats * 2 > boats + ships) + boats = boats * 2 + else + boats = boats + ships + } + + return boats +} + +function count_shared_boats() { + let here = get_lord_locale(game.command) + let n = 0 + for (let lord = first_friendly_lord; lord <= last_friendly_lord; ++lord) + if (get_lord_locale(lord) === here) + n += count_lord_boats(lord) + return n +} + +function count_lord_ships(lord) { + let ships = get_lord_assets(lord, SHIP) + + if (lord_has_capability(lord, AOW_TEUTONIC_COGS)) { + ships *= 2 + } + + if (lord_has_capability(lord, AOW_RUSSIAN_LODYA)) { + // TODO: one option or the other (only matters for supply) + let boats = get_lord_assets(lord, BOAT) + if (boats > 2) + boats = 2 + ships += boats + } + + return ships +} + +function count_shared_ships() { + let here = get_lord_locale(game.command) + let n = 0 + for (let lord = first_friendly_lord; lord <= last_friendly_lord; ++lord) + if (get_lord_locale(lord) === here) + n += count_lord_ships(lord) + return n +} + +function count_shared_cogs_not_in_group() { + let n = 0 + if (game.active === TEUTONS) { + for (let lord = first_friendly_lord; lord <= last_friendly_lord; ++lord) + if (lord_has_capability(lord, AOW_TEUTONIC_COGS)) + if (!set_has(game.group, lord)) // not already counted for + n += get_lord_assets(lord, SHIP) * 2 + } + return n +} + +function count_shared_cogs_not_in_locale(here) { + let n = 0 + if (game.active === TEUTONS) { + for (let lord = first_friendly_lord; lord <= last_friendly_lord; ++lord) + if (lord_has_capability(lord, AOW_TEUTONIC_COGS)) + if (get_lord_locale(lord) !== here) + n += get_lord_assets(lord, SHIP) * 2 + } + return n +} + +function count_group_ships() { + let n = 0 + for (let lord of game.group) + n += count_lord_ships(lord) + return n +} + +function count_group_assets(asset) { + let n = 0 + for (let lord of game.group) + n += get_lord_assets(lord, asset) + return n +} + +function count_group_forces(type) { + let n = 0 + for (let lord of game.group) + n += count_lord_forces(lord, type) + return n +} + +function count_group_horses() { + let n = 0 + for (let lord of game.group) + n += count_lord_horses(lord) + return n +} + +function count_group_transport(type) { + let n = 0 + for (let lord of game.group) + n += count_lord_transport(lord, type) + return n +} + function max_plan_length() { switch (current_season()) { case SUMMER: @@ -946,8 +1069,8 @@ function can_add_transport(who, what) { return get_lord_assets(who, what) < 8 } -function count_lord_transport(lord, way) { - let type = data.ways[way].type + +function count_lord_transport(lord, type) { let season = current_season() let n = 0 switch (type) { @@ -1036,11 +1159,6 @@ function is_located_with_legate(lord) { return get_lord_locale(lord) === game.call_to_arms.legate } -function for_each_group_lord(fn) { - for (let lord of game.group) - fn(lord) -} - function group_has_capability(c) { for (let lord of game.group) if (lord_has_capability(lord, c)) @@ -1048,41 +1166,6 @@ function group_has_capability(c) { return false } -function count_group_ships() { - let n = 0 - for (let lord of game.group) - n += count_lord_ships(lord) - return n -} - -function count_group_assets(asset) { - let n = 0 - for (let lord of game.group) - n += get_lord_assets(lord, asset) - return n -} - -function count_group_forces(type) { - let n = 0 - for (let lord of game.group) - n += count_lord_forces(lord, type) - return n -} - -function count_group_horses() { - let n = 0 - for (let lord of game.group) - n += count_lord_horses(lord) - return n -} - -function count_group_transport(way) { - let n = 0 - for (let lord of game.group) - n += count_lord_transport(lord, way) - return n -} - // === SETUP === function setup_lord_on_calendar(lord, turn) { @@ -1090,6 +1173,7 @@ function setup_lord_on_calendar(lord, turn) { } function muster_lord_forces(lord) { + let info = data.lords[lord] set_lord_forces(lord, KNIGHTS, info.forces.knights | 0) set_lord_forces(lord, SERGEANTS, info.forces.sergeants | 0) set_lord_forces(lord, LIGHT_HORSE, info.forces.light_horse | 0) @@ -1100,6 +1184,7 @@ function muster_lord_forces(lord) { } function muster_vassal_forces(lord, vassal) { + let info = data.vassals[vassal] add_lord_forces(lord, KNIGHTS, info.forces.knights | 0) add_lord_forces(lord, SERGEANTS, info.forces.sergeants | 0) add_lord_forces(lord, LIGHT_HORSE, info.forces.light_horse | 0) @@ -1138,7 +1223,6 @@ function muster_lord(lord, locale, service) { } function muster_vassal(lord, vassal) { - let info = data.vassals[vassal] game.lords.vassals[vassal] = VASSAL_MUSTERED muster_vassal_forces(lord, vassal) } @@ -1206,7 +1290,7 @@ exports.setup = function (seed, scenario, options) { approach: 0, avoid: 0, - spoils: 0, + assets: 0, } update_aliases() @@ -2341,11 +2425,13 @@ states.actions = { game.call_to_arms.legate_selected = 0 ++game.extra }, + pass() { push_undo() log("Passed.") spend_all_actions() // TODO: maybe only one action? }, + end_actions() { clear_undo() end_actions() @@ -2353,25 +2439,24 @@ states.actions = { forage: goto_forage, ravage: goto_ravage, - sail: goto_sail, + supply: goto_supply, tax: goto_tax, - siege: goto_siege, storm: goto_storm, sally: goto_sally, + sail: goto_sail, - lord(lord) { - set_toggle(game.group, lord) - if (is_upper_lord(lord)) - set_toggle(game.group, get_lower_lord(lord)) - }, + locale: goto_march, legate() { toggle_legate_selected() }, - // March! - locale: goto_march, + lord(lord) { + set_toggle(game.group, lord) + if (is_upper_lord(lord)) + set_toggle(game.group, get_lower_lord(lord)) + }, } // === ACTION: MARCH === @@ -2443,7 +2528,7 @@ states.march_way = { function march_with_group_1() { let way = game.approach - let transport = count_group_transport(way) + let transport = count_group_transport(data.ways[way].type) let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) @@ -2460,7 +2545,7 @@ states.march_laden = { prompt() { let to = game.where let way = game.approach - let transport = count_group_transport(way) + let transport = count_group_transport(data.ways[way].type) let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) @@ -2486,7 +2571,7 @@ states.march_laden = { } if (loot > 0 || prov > transport) { - for_each_group_lord(lord => { + for (let lord of game.group) { if (loot > 0) { if (get_lord_assets(lord, LOOT) > 0) gen_action_loot(lord) @@ -2498,7 +2583,7 @@ states.march_laden = { if (get_lord_assets(lord, PROV) > 0) gen_action_prov(lord) } - }) + } } }, prov: drop_prov, @@ -2512,7 +2597,7 @@ function march_with_group_2() { let from = get_lord_locale(game.command) let way = game.approach let to = game.where - let transport = count_group_transport(way) + let transport = count_group_transport(data.ways[way].type) let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) let laden = loot > 0 || prov > transport @@ -2529,10 +2614,10 @@ function march_with_group_2() { else log(`Marched to %${to}.`) - for_each_group_lord(lord => { + for (let lord of game.group) { set_lord_locale(lord, to) set_lord_moved(lord, 1) - }) + } if (game.call_to_arms.legate_selected) game.call_to_arms.legate = to @@ -2602,13 +2687,13 @@ function stronghold_capacity(loc) { function spoil_prov(lord) { log("Discarded Provender.") add_lord_assets(lord, PROV, -1) - game.spoils = pack4_set(game.spoils, PROV, pack4_get(game.spoils) + 1) + add_global_assets(PROV, 1) } function spoil_loot(lord) { log("Discarded Loot.") add_lord_assets(lord, LOOT, -1) - game.spoils = pack4_set(game.spoils, LOOT, pack4_get(game.spoils) + 1) + add_global_assets(LOOT, 1) } function can_avoid_battle(to, way) { @@ -2634,7 +2719,7 @@ function goto_avoid_battle() { game.stack = game.group game.who = NOBODY game.state = "avoid_battle" - game.spoils = 0 + game.assets = 0 resume_avoid_battle() } @@ -2711,7 +2796,7 @@ states.avoid_battle_way = { function avoid_battle_1() { let way = game.avoid - let transport = count_group_transport(way) + let transport = count_group_transport(data.ways[way].type) let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) if (prov > transport || loot > 0) @@ -2724,7 +2809,7 @@ states.avoid_battle_laden = { prompt() { let to = game.where let way = game.avoid - let transport = count_group_transport(way) + let transport = count_group_transport(data.ways[way].type) let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) @@ -2733,16 +2818,16 @@ states.avoid_battle_laden = { if (loot > 0) { view.prompt += " Discard Loot." - for_each_group_lord(lord => { + for (let lord of game.group) { if (get_lord_assets(lord, LOOT) > 0) gen_action_loot(lord) - }) + } } else if (prov > transport) { view.prompt += " Discard Provender." - for_each_group_lord(lord => { + for (let lord of game.group) { if (get_lord_assets(lord, PROV) > 0) gen_action_prov(lord) - }) + } } else { gen_action_locale(to) } @@ -2768,10 +2853,10 @@ function avoid_battle_2() { else log(`Avoided Battle to %${to}.`) - for_each_group_lord(lord => { + for (let lord of game.group) { set_lord_locale(lord, to) set_lord_moved(lord, 1) - }) + } game.where = get_lord_locale(game.command) game.avoid = 0 @@ -2862,7 +2947,7 @@ function end_withdraw() { // === ACTION: MARCH - DIVIDE SPOILS AFTER AVOID BATTLE === function goto_divide_spoils_after_avoid_battle() { - if (game.spoils > 0) + if (game.assets > 0) game.state = "divide_spoils_after_avoid_battle" else march_with_group_3() @@ -2873,7 +2958,7 @@ states.divide_spoils_after_avoid_battle = { view.actions.end_spoils = 1 }, end_spoils() { - game.spoils = 0 + game.assets = 0 march_with_group_3() }, } @@ -3008,11 +3093,109 @@ function goto_sally() { // === ACTION: SUPPLY === +function can_supply_from_sea() { + let season = current_season() + if (season === SUMMER || season === RASPUTITSA) { + let here = get_lord_locale(game.command) + let ships = count_shared_ships() + count_shared_cogs_not_in_locale(here) + return ships > 0 + } +} + +function list_supply_sources() { + let sources = [] + + for_each_seat(game.command, seat => { + set_add(sources, seat) + }) + + if (can_supply_from_sea()) { + if (game.active === TEUTONS) + for (let port of data.seaports) + set_add(sources, port) + if (game.active === RUSSIANS) + set_add(sources, LOC_NOVGOROD) + } + + return sources +} + +function search_supply_rec(result, seen, sources, here, boats, carts, sleds) { + console.log("search", "".padStart(16-(boats+carts+sleds), "-"), here) + + set_add(seen, here) + + if (set_has(sources, here)) + set_add(result, here) + + if (boats > 0) + for (let next of data.locales[here].adjacent_by_waterway) + search_supply_rec(result, seen, sources, next, boats - 1, carts, sleds) + if (carts > 0) + for (let next of data.locales[here].adjacent_by_trackway) + search_supply_rec(result, seen, sources, next, boats, carts - 1, sleds) + if (sleds > 0) + for (let next of data.locales[here].adjacent) + search_supply_rec(result, seen, sources, next, boats, carts, sleds - 1) + + set_delete(seen, here) +} + +function search_supply() { + let sources = list_supply_sources() + let start = get_lord_locale(game.command) + + let result = [] + + let boats = get_global_assets(BOAT) + let carts = get_global_assets(CART) + let sleds = get_global_assets(SLED) + + console.log("SUPPLY", sources, boats, carts, sleds) + + search_supply_rec(result, [], sources, start, boats, carts, sleds) + + console.log(" => ", result) +} + function can_action_supply(avail) { if (avail < 1) return false + return true +} - return false +function goto_supply() { + push_undo() + game.state = "supply" + + // TODO: Lodya - select boat OR ship (we count both here...) + + let season = current_season() + let here = get_lord_locale(game.command) + let boats = 0, carts = 0, sleds = 0, ships = 0 + if (season === SUMMER) { + carts = get_shared_assets(here, CART) + } + if (season === SUMMER || season === RASPUTITSA) { + boats = count_shared_boats() + ships = count_shared_ships() + count_shared_cogs_not_in_locale(here) + } + if (season === EARLY_WINTER || season === LATE_WINTER) { + sleds = get_shared_assets(here, SLED) + } + + set_global_assets(BOAT, boats) + set_global_assets(CART, carts) + set_global_assets(SLED, sleds) + set_global_assets(SHIP, ships) +} + +states.supply = { + prompt() { + view.prompt = "Supply: Select supply sources." + + search_supply() + }, } // === ACTION: FORAGE === @@ -3205,54 +3388,8 @@ function drop_loot(lord) { add_lord_assets(lord, LOOT, -1) } -function count_lord_ships(lord) { - let ships = get_lord_assets(lord, SHIP) - - if (lord_has_capability(lord, AOW_TEUTONIC_COGS)) { - ships *= 2 - } - - if (lord_has_capability(lord, AOW_RUSSIAN_LODYA)) { - // TODO: one option or the other (only matters for supply) - let boats = get_lord_assets(lord, BOAT) - if (boats > 2) - boats = 2 - ships += boats - } - - return ships -} - -function count_shared_cogs() { - let n = 0 - if (game.active === TEUTONS) { - for (let lord = first_friendly_lord; lord <= last_friendly_lord; ++lord) - if (lord_has_capability(lord, AOW_TEUTONIC_COGS)) - if (!set_has(game.group, lord)) // not already counted for - n += get_lord_assets(lord, SHIP) * 2 - } - return n -} - -function count_lord_boats(lord) { - let boats = get_lord_assets(lord, BOAT) - - if (lord_has_capability(lord, AOW_RUSSIAN_LODYA)) { - // TODO: one option or the other (only matters for supply) - let ships = get_lord_assets(lord, SHIP) - if (ships > 2) - ships = 2 - if (boats * 2 > boats + ships) - boats = boats * 2 - else - boats = boats + ships - } - - return boats -} - function has_enough_available_ships_for_horses() { - let ships = count_group_ships() + count_shared_cogs() + let ships = count_group_ships() + count_shared_cogs_not_in_group() let horses = count_group_horses() let needed_ships = horses @@ -3295,7 +3432,7 @@ states.sail = { view.group = game.group let here = get_lord_locale(game.command) - let ships = count_group_ships() + count_shared_cogs() + let ships = count_group_ships() + count_shared_cogs_not_in_group() let horses = count_group_horses() let prov = count_group_assets(PROV) let loot = count_group_assets(LOOT) @@ -3310,14 +3447,14 @@ states.sail = { view.prompt = `Sailing with ${ships} ships and ${horses} horses. Discard loot or provender.` // TODO: how strict is greed? if (loot > 0 || prov > 0) { - for_each_group_lord(lord => { + for (let lord of game.group) { if (loot > 0) if (get_lord_assets(lord, LOOT) > 0) gen_action_loot(lord) if (prov > 0) if (get_lord_assets(lord, PROV) > 0) gen_action_prov(lord) - }) + } } } else { view.prompt = `Sail: Choose a destination Seaport.` @@ -3337,10 +3474,10 @@ states.sail = { let from = get_lord_locale(game.command) - for_each_group_lord(lord => { + for (let lord of game.group) { set_lord_locale(lord, to) set_lord_moved(lord, 1) - }) + } if (game.call_to_arms.legate_selected) game.call_to_arms.legate = to diff --git a/tools/gendata.js b/tools/gendata.js index ba32d49..e922246 100644 --- a/tools/gendata.js +++ b/tools/gendata.js @@ -306,15 +306,20 @@ function dumplist(name, list) { locales.forEach(loc => { loc.adjacent = [] loc.adjacent_by_trackway = [] + loc.adjacent_by_waterway = [] for (let [to, way] of loc.ways) { if (!loc.adjacent.includes(to)) loc.adjacent.push(to) if (ways[way].type === "trackway") if (!loc.adjacent_by_trackway.includes(to)) loc.adjacent_by_trackway.push(to) + if (ways[way].type === "waterway") + if (!loc.adjacent_by_waterway.includes(to)) + loc.adjacent_by_waterway.push(to) } loc.adjacent.sort(cmpnum) loc.adjacent_by_trackway.sort(cmpnum) + loc.adjacent_by_waterway.sort(cmpnum) }) function seats(list) { -- cgit v1.2.3