From 4e92007e7a7e7e2c5a432ccb38f235abe67236b5 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 29 Jul 2022 13:03:47 +0200 Subject: Data arrays. --- data.js | 14 +- info/units.html | 12 +- play.html | 4 + play.js | 102 +++++-- rules.js | 248 ++++++++-------- tools/gendata.js | 136 ++++++++- tools/genunits.js | 114 ++++--- units-simple.svg | 570 +++++++++++++++++++++++++++++++++++ units.svg | 872 +++++++++++++++++++++++++++--------------------------- 9 files changed, 1424 insertions(+), 648 deletions(-) create mode 100644 units-simple.svg diff --git a/data.js b/data.js index 87dd052..9521797 100644 --- a/data.js +++ b/data.js @@ -1,3 +1,4 @@ +// DON'T EDIT - AUTOGENERATED const all_hexes = [7,8,9,10,30,31,32,33,34,35,36,37,38,39,40,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,197,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215] const hex_exists = [0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0] const hex_road = [0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,1,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,1,1,2,2,2,4,4,2,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,2,2,2,2,2,0,1,2,2,2,2,0,1,0,2,0,0,0,2,0,0,0,0,0,4,2,0,1,1,0,1,0,0,1,2,1,1,0,2,0,0,0,2,0,0,0,0,0,0,4,1,1,0,0,1,0,0,0,1,1,1,1,2,0,0,0,0,0,0,0,0,0,4,4,1,0,0,0,1,0,0,0,0,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0] @@ -5,5 +6,14 @@ const side_road = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,0,0,4,0,4,0 const side_limit = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,1,1,0,0,0,0,0,0,0,1,2,2,2,1,1,0,1,2,2,2,2,2,2,2,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,2,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,1,2,0,0,2,0,2,2,0,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,1,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,0,1,0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] const hex_name = {"7":"El Garib","8":"Cyrene","9":"El Gubba","10":"Derna","30":"Tocra","31":"Barce","32":"Marawa","33":"Wadi Cuff","34":"Wadi Cuff E","35":"Gazala","36":"Acroma","37":"Tobruk","38":"Belhamed","39":"Gambut","40":"Bardia","48":"Alexandria Refit","49":"Alexandria Queue","54":"Benghazi","55":"Er Regima","56":"Charruba","57":"Charruba E","58":"Mechili","59":"Rotonda Segnali","60":"Sidi Mufta","61":"Bir Harmat","62":"El Adem","63":"Sidi Rezegh","64":"Ft. Capuzzo","65":"Sollum","66":"Buq Buq","67":"Sidi Barrani","68":"Sidi Barrani E","69":"Mersa Matruh","70":"Fuka","71":"El Daba","72":"El Alamein","73":"El Hamam","74":"Alexandria","78":"Ghemines","79":"Skeleidima","80":"Msus","81":"Msus E","82":"Tengeder W","83":"Tengeder","84":"Tengeder E","85":"Bir Hacheim","86":"Retma","87":"Bir Gubi","88":"Gabr Saleh","89":"Sidi Omar","90":"Bir Habata","91":"Sofafi","92":"Sofafi E","93":"Bir el Kenayis","94":"Bir Khalda","95":"Bir Khalda E","96":"Alam Halfa W","97":"Alam Halfa","98":"Alam Halfa E","99":"Map Edge","102":"El Agheila Refit","103":"Beda Fomm","104":"Antelat","105":"Antelat E","106":"Ben Gania","107":"Ben Gania E","108":"Tengeder SE","109":"Bir Hacheim SW","110":"Bir Hacheim SE","111":"Retma SE","112":"Ft. Maddalena W","113":"Ft. Maddalena","114":"Ft. Maddalena E","115":"Bir Khamsa","116":"Bir el Qatrani","117":"Bir el Qatrani E","118":"Bir el Kenayis SE","119":"Bir Khalda SE","120":"El Himeimat W","121":"El Himeimat","122":"El Himeimat E","123":"Map Edge","127":"El Agheila Queue","128":"Agedabia","129":"Jebel el Matar","130":"Haraga","131":"Haraga E","137":"Ft. Maddalena SW","138":"Ft. Maddalena SE","139":"Bir Khamsa SW","140":"Bir Fuad W","141":"Bir Fuad","142":"Bir Fuad E","147":"El Himeimat E SE","148":"Map Edge","151":"El Agheila","152":"Mersa Brega","153":"El Haseiat","154":"El Haseiat E","155":"Haraga SE","162":"Jarabub Oasis NW","163":"Jarabub Oasis NE","165":"Bir Fuad SW","166":"Bir Fuad SE","172":"Map Edge","176":"Maaten Giofer","177":"Maaten Giofer E","178":"Sahaba","179":"Sahaba E","180":"Jalo Oasis NE","186":"Jarabub Oasis W","187":"Jarabub Oasis","188":"Jarabub Oasis E","189":"Siwa Oasis NE","197":"Map Edge","200":"Maaten Giofer SW","201":"Maaten Giofer SE","202":"Sahaba SW","203":"Jalo Oasis W","204":"Jalo Oasis","205":"Jalo Oasis E","211":"Jarabub Oasis SW","212":"Siwa Oasis W","213":"Siwa Oasis","214":"Siwa Oasis E"} const regions = {"Libya":[7,8,9,10,30,31,32,33,34,35,36,37,38,39,40,54,55,56,57,58,59,60,61,62,63,64,78,79,80,81,82,83,84,85,86,87,88,103,104,105,106,107,108,109,110,111,112,113,128,129,130,131,132,133,134,135,136,137,138,151,152,153,154,155,156,157,158,159,160,161,162,176,177,178,179,180,181,182,183,184,185,186,187,200,201,202,203,204,205,206,207,208,209,210,211],"Egypt":[65,66,67,68,69,70,71,72,73,74,89,90,91,92,93,94,95,96,97,98,114,115,116,117,118,119,120,121,122,123,139,140,141,142,143,144,163,164,165,166,167,188,189,190,191,212,213,214,215],"Sidi Omar":[89],"Tobruk":[37],"Sollum":[65],"El Agheila":[151],"Mersa Brega":[152],"East Line":[36,37,38,39,40,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,85,86,87,88,89,90,91,92,93,94,95,96,97,98,112,113,114,115,116,117,118,119,120,121,122,123,137,138,139,140,141,142,143,144,162,163,164,165,166,167,187,188,189,190,191],"West Line":[7,8,9,10,30,31,32,33,34,35,54,55,56,57,58,59,78,79,80,81,82,83,103,104,105,106,107,128,129,130],"Jebel el Akhdar":[7,8,9,32,33,34,56,57],"Sebkha el Segira":[152,176],"Sebket el Jeneinen":[179,203],"Qattara Depression":[144,145,146,168,169,192,193,216,217]} -const units = [{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":12,"name":"Tre"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":13,"name":"Pav"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":14,"name":"Bre"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":3,"elite":0,"label":15,"name":"Bol"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":3,"elite":0,"label":16,"name":"Sav"},{"nationality":"italian","type":"mech. inf.","class":1,"speed":3,"appearance":7,"steps":4,"elite":0,"label":21,"name":"Tri"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":7,"steps":2,"elite":0,"label":22,"name":"Sab"},{"nationality":"italian","type":"armor","class":0,"speed":3,"appearance":11,"steps":3,"elite":0,"label":23,"name":"Lit"},{"nationality":"italian","type":"mot. inf.","class":1,"speed":2,"appearance":17,"steps":3,"elite":0,"label":24,"name":"Fas"},{"nationality":"italian","type":"mot. inf.","class":1,"speed":2,"appearance":19,"steps":3,"elite":0,"label":25,"name":"Cen"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":19,"steps":2,"elite":0,"label":26,"name":"Pis"},{"nationality":"italian","type":"para","class":1,"speed":1,"appearance":"M","steps":4,"elite":0,"label":27,"name":"Fol"},{"nationality":"italian","type":"artillery","class":3,"speed":1,"appearance":"S","steps":2,"elite":0,"label":28,"name":"Ita"},{"nationality":"italian","type":"armor","class":0,"speed":3,"appearance":"S","steps":4,"elite":0,"label":29,"name":"Ari"},{"nationality":"german","type":"armor","class":0,"speed":3,"appearance":"S","steps":3,"elite":1,"label":14,"name":"21/5"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":"S","steps":1,"elite":1,"label":15,"name":"21/3"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":3,"elite":1,"label":16,"name":"21/104"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":3,"steps":1,"elite":1,"label":17,"name":"15/33"},{"nationality":"german","type":"mob. a/t","class":2,"speed":3,"appearance":3,"steps":2,"elite":1,"label":18,"name":"88mm/A"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":3,"steps":3,"elite":1,"label":19,"name":"15/115"},{"nationality":"german","type":"armor","class":0,"speed":3,"appearance":5,"steps":3,"elite":1,"label":21,"name":"15/8"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":5,"steps":1,"elite":1,"label":22,"name":"90/580"},{"nationality":"german","type":"mot. inf.","class":1,"speed":2,"appearance":5,"steps":2,"elite":1,"label":23,"name":"90/361"},{"nationality":"german","type":"mot. a/t","class":2,"speed":2,"appearance":5,"steps":2,"elite":1,"label":24,"name":"50mm"},{"nationality":"german","type":"artillery","class":3,"speed":1,"appearance":7,"steps":2,"elite":1,"label":25,"name":"/104"},{"nationality":"german","type":"mot. inf.","class":1,"speed":2,"appearance":7,"steps":2,"elite":1,"label":26,"name":"90/200"},{"nationality":"german","type":"mob. a/t","class":2,"speed":3,"appearance":11,"steps":2,"elite":1,"label":27,"name":"88mm/B"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":11,"steps":2,"elite":1,"label":28,"name":"90/sv288"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":11,"steps":2,"elite":1,"label":29,"name":"90/346"},{"nationality":"german","type":"para","class":1,"speed":1,"appearance":"M","steps":3,"elite":1,"label":31,"name":"Ram"},{"nationality":"german","type":"infantry","class":1,"speed":1,"appearance":"M","steps":3,"elite":1,"label":32,"name":"164/382+433"},{"nationality":"german","type":"infantry","class":1,"speed":1,"appearance":"M","steps":2,"elite":1,"label":33,"name":"164/125"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":3,"steps":3,"elite":1,"label":34,"name":"90/155"},{"nationality":"german","type":"mot. a/t","class":2,"speed":2,"appearance":17,"steps":2,"elite":1,"label":35,"name":"76mm"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":"S","steps":2,"elite":0,"label":14,"name":"2/3"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":2,"elite":0,"label":15,"name":"2/SG"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":2,"elite":0,"label":16,"name":"4IN/3m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":4,"elite":0,"label":17,"name":"9AU/20"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":4,"elite":0,"label":18,"name":"70/14+16"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":3,"elite":0,"label":19,"name":"70/23"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":"T","steps":1,"elite":1,"label":21,"name":"Matilda/A"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"T","steps":3,"elite":0,"label":22,"name":"7/SG"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"T","steps":3,"elite":0,"label":23,"name":"7/22G"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"T","steps":3,"elite":0,"label":24,"name":"/Pol"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"T","steps":3,"elite":0,"label":25,"name":"7AU/18"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":"T","steps":2,"elite":0,"label":26,"name":"/Tob"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":18,"steps":4,"elite":0,"label":27,"name":"51H/152"},{"nationality":"allied","type":"self prop. arty","class":3,"speed":3,"appearance":18,"steps":2,"elite":0,"label":28,"name":"Priest"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":18,"steps":4,"elite":0,"label":29,"name":"/C"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":2,"steps":4,"elite":0,"label":31,"name":"7/7"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":2,"steps":3,"elite":0,"label":32,"name":"4IN/7m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":2,"steps":3,"elite":0,"label":33,"name":"4IN/5"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":2,"steps":3,"elite":0,"label":34,"name":"4IN/11"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":4,"steps":1,"elite":1,"label":35,"name":"Matilda/B"},{"nationality":"allied","type":"i-tank","class":0,"speed":3,"appearance":4,"steps":4,"elite":0,"label":36,"name":"/1AT"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":4,"steps":3,"elite":0,"label":37,"name":"7/4"},{"nationality":"allied","type":"recon","class":0,"speed":4,"appearance":4,"steps":2,"elite":0,"label":38,"name":"7"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":20,"steps":3,"elite":0,"label":39,"name":"/D"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":6,"steps":3,"elite":0,"label":41,"name":"2#"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":42,"name":"2NZ/4"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":43,"name":"2NZ/5"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":44,"name":"2NZ/6"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":6,"steps":4,"elite":0,"label":45,"name":"1SA/2+5"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":6,"steps":3,"elite":0,"label":46,"name":"1SA/1"},{"nationality":"allied","type":"recon","class":0,"speed":4,"appearance":8,"steps":2,"elite":0,"label":47,"name":"1SA"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":8,"steps":3,"elite":0,"label":48,"name":"1SA/3"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":8,"steps":3,"elite":0,"label":49,"name":"2SA/4+6"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":8,"steps":4,"elite":0,"label":51,"name":"1/22"},{"nationality":"allied","type":"i-tank","class":0,"speed":3,"appearance":8,"steps":3,"elite":0,"label":52,"name":"/32AT"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":8,"steps":2,"elite":0,"label":53,"name":"/A"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":10,"steps":4,"elite":0,"label":54,"name":"1/2"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":10,"steps":3,"elite":0,"label":55,"name":"1/201G"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":10,"steps":2,"elite":0,"label":56,"name":"1/SG"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":10,"steps":3,"elite":0,"label":57,"name":"5IN/29"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":12,"steps":2,"elite":1,"label":58,"name":"Grant"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":12,"steps":3,"elite":0,"label":59,"name":"6#/A"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":14,"steps":2,"elite":0,"label":61,"name":"10IN/161m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":62,"name":"5IN/9+10"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":63,"name":"10IN/21+25"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":2,"elite":0,"label":64,"name":"8IN/18"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":65,"name":"FF/2"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":14,"steps":4,"elite":0,"label":66,"name":"/B"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":1,"label":67,"name":"Sher/B"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":0,"label":68,"name":"8/9"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":0,"label":69,"name":"8/24"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":16,"steps":4,"elite":0,"label":71,"name":"10/8"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":16,"steps":3,"elite":0,"label":72,"name":"10/23"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":73,"name":"9AU/26"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":74,"name":"9AU/24"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":75,"name":"44/131+133"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":2,"elite":0,"label":76,"name":"44/132"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":18,"steps":3,"elite":1,"label":77,"name":"Sher/A"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":18,"steps":4,"elite":0,"label":78,"name":"6#/B"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":18,"steps":4,"elite":0,"label":79,"name":"51H/154"}] -if (typeof module !== 'undefined') module.exports = { all_hexes, hex_exists, hex_name, hex_road, side_road, side_limit, regions, units } +const unit_name = ["Ari","Lit","Tri","Cen","Fas","Bre","Fol","Pav","Tre","Bol","Sav","Pis","Sab","Ita","15/33","21/3","90/580","15/8","21/5","15/115","21/104","90/155","90/346","90/sv288","90/200","90/361","164/382+433","Ram","164/125","88mm/A","88mm/B","50mm","76mm","/104","7","Sher/A","Sher/B","Grant","Matilda/A","Matilda/B","/1AT","1/2","1/22","7/7","10/8","/32AT","7/4","8/24","8/9","10/23","2/3","1/201G","7/22G","7/SG","1/SG","2/SG","44/131+133","51H/152","51H/154","70/14+16","70/23","44/132","6#/B","2#","6#/A","Priest","/B","/C","/D","/A","/Tob","4IN/7m","4IN/3m","10IN/161m","5IN/9+10","10IN/21+25","4IN/11","4IN/5","5IN/29","8IN/18","1SA","1SA/2+5","1SA/1","1SA/3","2SA/4+6","9AU/20","9AU/24","9AU/26","7AU/18","2NZ/4","2NZ/5","2NZ/6","FF/2","/Pol"] +const unit_appearance = ["S",11,7,19,17,"S","M","S","S","S","S",19,7,"S",3,"S",5,5,"S",3,"S",3,11,11,7,5,"M","M","M",3,11,5,17,7,4,18,20,12,"T",4,4,10,8,2,16,8,4,20,20,16,"S",10,"T","T",10,"S",16,18,18,"S","S",16,18,6,12,18,14,18,20,8,"T",2,"S",14,14,14,2,2,10,14,8,6,6,8,8,"S",16,16,"T",6,6,6,14,"T"] +const unit_start_steps = [4,3,4,3,3,4,4,4,4,3,3,2,2,2,1,1,1,3,3,3,3,3,2,2,2,2,3,3,2,2,2,2,2,2,2,3,3,2,1,1,4,4,4,4,4,3,3,3,3,3,2,3,3,3,2,2,4,4,4,4,3,2,4,3,3,2,4,4,3,2,2,3,2,2,4,4,3,3,3,2,2,4,3,3,3,4,4,4,3,4,4,4,4,3] +const unit_elite = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +const unit_class = [0,0,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1] +const unit_speed = [3,3,3,2,2,1,1,1,1,1,1,1,1,1,4,4,4,3,3,3,3,3,3,3,2,2,1,1,1,3,3,2,2,1,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,1,1,1,1,1,3,3,3,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,3,3,3,2,2] +if (typeof module !== 'undefined') + module.exports = { + all_hexes, hex_exists, hex_name, hex_road, side_road, side_limit, regions, + unit_name, unit_appearance, unit_start_steps, unit_elite, unit_class, unit_speed, + } diff --git a/info/units.html b/info/units.html index 26ec186..168115d 100644 --- a/info/units.html +++ b/info/units.html @@ -140,7 +140,6 @@ body {
-
@@ -157,7 +156,6 @@ body {
-
@@ -174,6 +172,7 @@ body {
+
@@ -181,7 +180,6 @@ body {
-
@@ -191,7 +189,6 @@ body {
-
@@ -201,7 +198,6 @@ body {
-
@@ -211,21 +207,21 @@ body {
-
+
-
+
@@ -236,9 +232,11 @@ body {
+
+
diff --git a/play.html b/play.html index ad295c6..4ef8647 100644 --- a/play.html +++ b/play.html @@ -371,6 +371,10 @@ svg .hex.tip { transition: top 200ms, left 200ms, transform 200ms; } +#mapwrap.fit .unit { + background-image: url(units-simple.svg); +} + .unit.italian { background-color: #f9e3b3; border-color: dimgray; diff --git a/play.js b/play.js index 3faba75..1361789 100644 --- a/play.js +++ b/play.js @@ -14,11 +14,30 @@ const class_name = [ "armor", "infantry", "anti-tank", "artillery" ] const MALTA = 4 const hex_special = [ 48, 49, 102, 127, MALTA ] +const unit_count = 94 + const ARMOR = 0 const INFANTRY = 1 const ANTITANK = 2 const ARTILLERY = 3 +function is_axis_unit(u) { return (u >= 0 && u <= 33) } +function is_italian_unit(u) { return (u >= 0 && u <= 13) } +function is_german_unit(u) { return (u >= 14 && u <= 33) } +function is_allied_unit(u) { return (u >= 34 && u <= 93) } + +function is_elite_unit(u) { return unit_elite[u] } + +function is_armor_unit(u) { return unit_class[u] === ARMOR } +function is_infantry_unit(u) { unit_class[u] === INFANTRY } +function is_antitank_unit(u) { unit_class[u] === ANTITANK } +function is_artillery_unit(u) { unit_class[u] === ARTILLERY } + +function is_recon_unit(u) { return unit_speed[u] === 4 } +function is_mechanized_unit(u) { return unit_speed[u] === 3 } +function is_motorized_unit(u) { return unit_speed[u] === 2 } +function is_leg_unit(u) { return unit_speed[u] === 1 } + function set_has(set, item) { if (!set) return false @@ -126,6 +145,10 @@ function unit_supply(u) { return hex_from_supply_source[src] } +function is_unit_unsupplied(u) { + return ((view.units[u] & UNIT_SUPPLY_MASK) >> UNIT_SUPPLY_SHIFT) === 0 +} + function set_unit_supply(u, hex) { let src = supply_source_from_hex(hex) view.units[u] = (view.units[u] & ~UNIT_SUPPLY_MASK) | (src << UNIT_SUPPLY_SHIFT) @@ -140,11 +163,11 @@ function set_unit_lost_steps(u, n) { } function unit_steps(u) { - return units[u].steps - unit_lost_steps(u) + return unit_start_steps[u] - unit_lost_steps(u) } function set_unit_steps(u, n) { - set_unit_lost_steps(u, units[u].steps - n) + set_unit_lost_steps(u, unit_start_steps[u] - n) } function is_unit_moved(u) { @@ -165,18 +188,6 @@ function is_unit_selected(unit) { return view.selected === unit } -function is_artillery_unit(u) { - return units[u].class === ARTILLERY -} - -function is_allied_unit(u) { - return units[u].nationality === 'allied' -} - -function is_axis_unit(u) { - return units[u].nationality !== 'allied' -} - function is_hex_action(hex) { return !!(view.actions && view.actions.hex && view.actions.hex.includes(hex)) } @@ -288,16 +299,56 @@ function on_focus_hex(evt) { document.getElementById("status").textContent = text } +const unit_description = [] +for (let u = 0; u <= 93; ++u) { + let t = "" + if (is_italian_unit(u)) t += " Italian" + if (is_german_unit(u)) t += " German" + if (is_allied_unit(u)) t += " Allied" + if (is_elite_unit(u) && !is_german_unit(u)) t += " Elite" + if (is_armor_unit(u)) { + if (is_recon_unit(u)) t += " Recon" + t += " Armor" + } + if (is_infantry_unit(u)) { + if (is_mechanized_unit(u)) t += " Mechanized" + if (is_motorized_unit(u)) t += " Motorized" + t += " Infantry" + } + if (is_antitank_unit(u)) { + if (is_mechanized_unit(u)) t += " Mobile" + if (is_motorized_unit(u)) t += " Motorized" + t += " Anti-tank" + } + if (is_artillery_unit(u)) { + if (is_mechanized_unit(u)) t += " Self Propelled" + t += " Artillery" + } + unit_description[u] = t +} + function on_focus_unit(evt) { let u = evt.target.unit - let data = units[u] - document.getElementById("status").textContent = `(${u}) ${data.nationality} ${data.elite ? "elite " : ""}${data.type} - ${data.steps} - ${data.name}` + let t = "(" + u + ")" + t += " " + unit_description[u] + t += " \"" + unit_name[u] + "\"" + if (is_unit_disrupted(u)) + t += " - disrupted" + if (is_unit_unsupplied(u)) + t += " - unsupplied" + if (is_unit_moved(u)) + t += " - moved" + if (is_unit_fired(u)) + t += " - fired" + document.getElementById("status").textContent = t } function on_focus_battle_unit(evt) { let u = evt.target.unit - let data = units[u] - document.getElementById("status").textContent = `(${u}) ${data.nationality} ${data.elite ? "elite " : ""}${data.type} - ${data.steps} - ${data.name}` + let t = unit_description[u] + if (is_unit_fired(u)) + t += " - fired" + document.getElementById("status").textContent = t } function toggle_units() { @@ -474,23 +525,24 @@ function build_hexes() { } function build_units() { - function build_unit(u, data) { + function build_unit(u) { + let nationality = is_german_unit(u) ? "german" : is_italian_unit(u) ? "italian" : "allied" let elt = ui.units[u] = document.createElement("div") - elt.className = `unit ${data.nationality} u${u} r0 m` + elt.className = `unit ${nationality} u${u} r0 m` elt.addEventListener("mousedown", on_click_unit) elt.addEventListener("mouseenter", on_focus_unit) elt.addEventListener("mouseleave", on_blur) elt.unit = u elt = ui.battle_units[u] = document.createElement("div") - elt.className = `unit ${data.nationality} u${u} r0` + elt.className = `unit ${nationality} u${u} r0` elt.addEventListener("mousedown", on_click_battle_unit) elt.addEventListener("mouseenter", on_focus_battle_unit) elt.addEventListener("mouseleave", on_blur) elt.unit = u } - for (let u = 0; u < units.length; ++u) { - build_unit(u, units[u]) + for (let u = 0; u < unit_count; ++u) { + build_unit(u) } } @@ -528,7 +580,7 @@ function update_map() { for (let i = 0; i < stack.length; ++i) stack[i].length = 0 - for (let u = 0; u < units.length; ++u) { + for (let u = 0; u < unit_count; ++u) { let e = ui.units[u] let hex = unit_hex(u) if (view.month <= 10 && hex > hexdeploy + 10) @@ -630,7 +682,7 @@ function update_cards() { } function update_battle_line(hex, line, test) { - for (let u = 0; u < units.length; ++u) { + for (let u = 0; u < unit_count; ++u) { let e = ui.battle_units[u] if (unit_hex(u) === hex && test(u)) { if (!line.contains(e)) diff --git a/rules.js b/rules.js index 4d93492..f28a8ab 100644 --- a/rules.js +++ b/rules.js @@ -4,7 +4,6 @@ // TODO: oasis supply // TODO: raiders // TODO: minefields -// TODO: gazala scenario // TODO: legal pass withdrawal moves (reduce supply net, withdraw from fortress attack) // TOOD: reveal/hide blocks (hexes) // TODO: group move from queue holding box to base @@ -14,6 +13,8 @@ // TODO: replacements // TODO: malta units +// TODO: sort blocks by type + // TODO: black hit outline in battles ("steploss/bad" action) // RULES: may units redeploying out of battles cross enemy controlled hexsides? @@ -38,7 +39,10 @@ var view = null var after_rout_table = {} -const { all_hexes, hex_exists, hex_road, side_road, side_limit, hex_name, units, regions } = require("./data") +const { + all_hexes, hex_exists, hex_road, side_road, side_limit, hex_name, regions, + unit_name, unit_appearance, unit_class, unit_speed, unit_start_steps, +} = require("./data") function debug_hexes3(n, list) { console.log("--", n, "--") @@ -218,9 +222,10 @@ function is_hex_or_adjacent_to(x, where) { // === STATE CACHES === const first_axis_unit = 0 -const first_allied_unit = units.findIndex(item => item.nationality === 'allied') -const last_axis_unit = first_allied_unit - 1 -const last_allied_unit = units.length - 1 +const last_axis_unit = 33 +const first_allied_unit = 34 +const last_allied_unit = 93 +const unit_count = 94 var presence_invalid = true var presence_axis = new Array(hexcount).fill(0) @@ -382,11 +387,11 @@ function set_unit_lost_steps(u, n) { } function unit_steps(u) { - return units[u].steps - unit_lost_steps(u) + return unit_start_steps[u] - unit_lost_steps(u) } function set_unit_steps(u, n) { - set_unit_lost_steps(u, units[u].steps - n) + set_unit_lost_steps(u, unit_start_steps[u] - n) } function is_unit_moved(u) { @@ -423,78 +428,46 @@ function reduce_unit(u) { // === UNIT DATA === function find_unit(name) { - for (let u = 0; u < units.length; ++u) - if (units[u].name === name) + for (let u = 0; u < unit_count; ++u) + if (unit_name[u] === name) return u - throw new Error("cannot find named block: " + name) -} - -function unit_name(u) { - return units[u].name -} - -function unit_speed(u) { - return units[u].speed + throw new Error("cannot find named block: " + name + unit_name) } -function unit_class(u) { - return units[u].class -} - -function is_artillery_unit(u) { - return units[u].class === ARTILLERY +function is_allied_unit(u) { + return u >= first_allied_unit && u <= last_allied_unit } -function is_armor_unit(u) { - return units[u].class === ARMOR +function is_axis_unit(u) { + return u >= first_axis_unit && u <= last_axis_unit } -function is_infantry_unit(u) { - return units[u].class === INFANTRY +function is_german_unit(u) { + return (u >= 14 && u <= 33) } -function is_antitank_unit(u) { - return units[u].class === ANTITANK +function is_elite_unit(u) { + return unit_elite[u] } -function is_unit_elite(u) { - return units[u].elite +function is_artillery_unit(u) { + return unit_class[u] === ARTILLERY } function unit_cv(u) { - if (is_unit_elite(u)) + if (is_elite_unit(u)) return unit_steps(u) * 2 return unit_steps(u) } function unit_hp_per_step(u) { - return is_unit_elite(u) ? 2 : 1 + return is_elite_unit(u) ? 2 : 1 } function unit_hp(u) { return unit_steps(u) * unit_hp_per_step(u) } -function is_friendly_hex(x) { - if (game.active === AXIS) - return is_axis_hex(x) - return is_allied_hex(x) -} - -function is_enemy_hex(x) { - if (game.active === ALLIED) - return is_axis_hex(x) - return is_allied_hex(x) -} - -function is_allied_unit(u) { - return u >= first_allied_unit && u <= last_allied_unit -} - -function is_axis_unit(u) { - return u >= first_axis_unit && u <= last_axis_unit -} - // === MAP STATE === function friendly_base() { @@ -616,6 +589,18 @@ function is_empty_hex(x) { return (presence_axis[x] === 0) && (presence_allied[x] === 0) } +function is_friendly_hex(x) { + if (game.active === AXIS) + return is_axis_hex(x) + return is_allied_hex(x) +} + +function is_enemy_hex(x) { + if (game.active === ALLIED) + return is_axis_hex(x) + return is_allied_hex(x) +} + function has_friendly_unit(x) { if (game.active === AXIS) return has_axis_unit(x) @@ -658,10 +643,6 @@ function has_unshielded_disrupted_friendly_unit(x) { return has_unshielded_disrupted_axis_unit(x) } -function is_overrun_hex(x) { - return has_undisrupted_friendly_unit(x) && has_unshielded_disrupted_enemy_unit(x) -} - function is_enemy_rout_hex(x) { return has_undisrupted_friendly_unit(x) && has_unshielded_disrupted_enemy_unit(x) } @@ -820,6 +801,12 @@ function for_each_hex_and_adjacent_hex(here, fn) { } } +function for_each_unit_on_map(fn) { + for (let u = 0; u < unit_count; ++u) + if (is_map_hex(unit_hex(u))) + fn(u) +} + function for_each_axis_unit(fn) { for (let u = first_axis_unit; u <= last_axis_unit; ++u) fn(u) @@ -921,9 +908,9 @@ function has_friendly_units_in_battle() { function count_normal_steps_in_battle() { let steps = [ 0, 0, 0, 0 ] for_each_undisrupted_enemy_unit_in_hex(game.battle, u => { - if (!is_unit_elite(u)) + if (!is_elite_unit(u)) if (!is_unit_retreating(u)) - steps[unit_class(u)] += unit_steps(u) + steps[unit_class[u]] += unit_steps(u) }) return steps } @@ -931,9 +918,9 @@ function count_normal_steps_in_battle() { function count_elite_steps_in_battle() { let steps = [ 0, 0, 0, 0 ] for_each_undisrupted_enemy_unit_in_hex(game.battle, u => { - if (is_unit_elite(u)) + if (is_elite_unit(u)) if (!is_unit_retreating(u)) - steps[unit_class(u)] += unit_steps(u) + steps[unit_class[u]] += unit_steps(u) }) return steps } @@ -942,7 +929,7 @@ function count_hp_in_battle() { let hp = [ 0, 0, 0, 0 ] for_each_undisrupted_enemy_unit_in_hex(game.battle, u => { if (!is_unit_retreating(u)) - hp[unit_class(u)] += unit_hp(u) + hp[unit_class[u]] += unit_hp(u) }) return hp } @@ -950,7 +937,7 @@ function count_hp_in_battle() { function count_normal_steps_in_pursuit() { let steps = 0 for_each_undisrupted_enemy_unit_in_hex(game.pursuit, u => { - if (!is_unit_elite(u)) + if (!is_elite_unit(u)) steps += unit_steps(u) }) return steps @@ -959,7 +946,7 @@ function count_normal_steps_in_pursuit() { function count_elite_steps_in_pursuit() { let steps = 0 for_each_undisrupted_enemy_unit_in_hex(game.pursuit, u => { - if (is_unit_elite(u)) + if (is_elite_unit(u)) steps += unit_steps(u) }) return steps @@ -976,7 +963,7 @@ function count_hp_in_pursuit() { function count_normal_steps_in_rout() { let steps = 0 for_each_enemy_unit_in_hex(game.pursuit, u => { - if (!is_unit_elite(u)) + if (!is_elite_unit(u)) steps += unit_steps(u) }) return steps @@ -985,7 +972,7 @@ function count_normal_steps_in_rout() { function count_elite_steps_in_rout() { let steps = 0 for_each_enemy_unit_in_hex(game.pursuit, u => { - if (is_unit_elite(u)) + if (is_elite_unit(u)) steps += unit_steps(u) }) return steps @@ -1357,7 +1344,7 @@ function search_move_retreat(start, speed) { function search_withdraw(who, bonus) { let sline = unit_supply_line(who) let sdist = unit_supply_distance(who) - let speed = unit_speed(who) + bonus + let speed = unit_speed[who] + bonus let start = unit_hex(who) search_move_bfs(path_from[0], path_cost[0], start, 0, speed, false, sline, sdist) @@ -1369,7 +1356,7 @@ function search_withdraw(who, bonus) { function search_withdraw_retreat(who, bonus) { let sline = unit_supply_line(who) let sdist = unit_supply_distance(who) - let speed = unit_speed(who) + bonus + let speed = unit_speed[who] + bonus let start = unit_hex(who) search_move_bfs(path_from[0], path_cost[0], start, 0, speed, true, sline, sdist) @@ -1493,7 +1480,7 @@ function can_move_to(to, speed) { function max_speed_of_undisrupted_and_unmoved_friendly_unit_in_hex(from) { let max_speed = 0 for_each_undisrupted_and_unmoved_friendly_unit_in_hex(from, u => { - let s = unit_speed(u) + let s = unit_speed[u] if (s > max_speed) max_speed = s }) @@ -1989,7 +1976,7 @@ states.move = { // TODO: withdraw pass move search_move(from, speed + 1 + rommel1) for_each_undisrupted_and_unmoved_friendly_unit_in_hex(from, u => { - if (can_move_to(game.to1, unit_speed(u) + 1 + rommel1)) + if (can_move_to(game.to1, unit_speed[u] + 1 + rommel1)) gen_action_unit(u) }) } @@ -2004,7 +1991,7 @@ states.move = { // TODO: withdraw pass move search_move(from, speed + 1 + rommel2) for_each_undisrupted_and_unmoved_friendly_unit_in_hex(from, u => { - if (can_move_to(game.to2, unit_speed(u) + 1 + rommel2)) + if (can_move_to(game.to2, unit_speed[u] + 1 + rommel2)) gen_action_unit(u) }) } @@ -2018,7 +2005,7 @@ states.move = { // Overrun let has_overrun_hex = false for (let x of all_hexes) { - if (is_overrun_hex(x)) { + if (is_enemy_rout_hex(x)) { has_overrun_hex = true break } @@ -2038,7 +2025,7 @@ states.move = { if (game.turn_option === 'pass') search_withdraw(game.selected, 1 + (rommel1 | rommel2)) else - search_move(unit_hex(game.selected), unit_speed(game.selected) + 1 + (rommel1 | rommel2)) + search_move(unit_hex(game.selected), unit_speed[game.selected] + 1 + (rommel1 | rommel2)) gen_move() } @@ -2084,7 +2071,7 @@ states.overrun = { prompt() { view.prompt = `Overrun!` for (let x of all_hexes) - if (is_overrun_hex(x)) + if (is_enemy_rout_hex(x)) gen_action_hex(x) }, hex(where) { @@ -2102,7 +2089,7 @@ function goto_overrun(where) { function gen_move() { let rommel1 = (game.rommel === 1) ? 1 : 0 let rommel2 = (game.rommel === 2) ? 1 : 0 - let speed = unit_speed(game.selected) + let speed = unit_speed[game.selected] let from = unit_hex(game.selected) if (!game.to1 && game.from1 === from) { @@ -2148,7 +2135,7 @@ function apply_move(to) { let rommel2 = (game.rommel === 2) ? 1 : 0 let who = pop_selected() let from = unit_hex(who) - let speed = unit_speed(who) + let speed = unit_speed[who] push_undo() @@ -2543,12 +2530,12 @@ function can_unit_disengage_and_move(who) { function can_unit_disengage_and_withdraw_to(who, to, extra) { search_withdraw_retreat(who, extra) - return can_move_to(to, unit_speed(who) + extra) + return can_move_to(to, unit_speed[who] + extra) } function can_unit_disengage_and_move_to(who, to, extra) { - search_move_retreat(unit_hex(who), unit_speed(who) + extra) - return can_move_to(to, unit_speed(who) + extra) + search_move_retreat(unit_hex(who), unit_speed[who] + extra) + return can_move_to(to, unit_speed[who] + extra) } function can_select_retreat_hex() { @@ -2745,7 +2732,7 @@ states.retreat_move = { if (game.turn_option === 'pass') search_withdraw_retreat(game.selected, 1 + (rommel1 | rommel2)) else - search_move_retreat(unit_hex(game.selected), unit_speed(game.selected) + 1 + (rommel1 | rommel2)) + search_move_retreat(unit_hex(game.selected), unit_speed[game.selected] + 1 + (rommel1 | rommel2)) gen_move() } }, @@ -2783,8 +2770,10 @@ function end_retreat() { } function end_retreat_2() { - if (can_select_retreat_hex()) + if (can_select_retreat_hex()) { + console.log("can_select_retreat_hex") game.state = 'retreat_from' + } else end_movement() } @@ -2862,7 +2851,7 @@ states.refuse_battle_move = { if (done) gen_action('end_retreat') } else { - let speed = unit_speed(game.selected) + let speed = unit_speed[game.selected] gen_action_unit(game.selected) search_withdraw_retreat(game.selected, 0) for (let to of all_hexes) @@ -2970,7 +2959,7 @@ states.rout_move = { if (done) gen_action('end_rout') } else { - let speed = unit_speed(game.selected) + let speed = unit_speed[game.selected] let eliminate = true search_withdraw_retreat(game.selected, 0) for (let to of all_hexes) { @@ -3193,7 +3182,7 @@ function is_minefield_offensive_fire() { } function roll_battle_fire(who, tc) { - let fc = unit_class(who) + let fc = unit_class[who] let cv = unit_cv(who) // Double dice during assault and non-armor defenders in fortress! @@ -3216,7 +3205,7 @@ function roll_battle_fire(who, tc) { } // Double defense in minefields! - if (is_minefield_offensive_fire()) + if (fc !== ARTILLERY && is_minefield_offensive_fire()) total = total / 2 game.flash = `${class_name_cap[fc]} ${firepower_name[fp]} ${result.join("")} at ${class_name[tc]}` @@ -3325,7 +3314,7 @@ function gen_battle_target() { hp[i] -= game.hits[i] let who = game.selected - let fc = unit_class(who) + let fc = unit_class[who] gen_action_unit(who) // deselect @@ -3362,8 +3351,8 @@ function gen_battle_hits() { let done = true for_each_undisrupted_friendly_unit_in_hex(game.battle, u => { if (!is_unit_retreating(u)) { - let c = unit_class(u) - if (is_unit_elite(u)) { + let c = unit_class[u] + if (is_elite_unit(u)) { if (game.hits[c] >= 2) { gen_action_unit(u) done = false @@ -3388,7 +3377,7 @@ function gen_battle_hits() { } function apply_battle_hit(who) { - game.hits[unit_class(who)] -= reduce_unit(who) + game.hits[unit_class[who]] -= reduce_unit(who) } states.battle_fire = { @@ -3572,7 +3561,7 @@ function goto_pursuit_hits() { function slowest_enemy_unit_speed(where) { let r = 4 for_each_enemy_unit_in_hex(where, u => { - let s = unit_speed(u) + let s = unit_speed[u] if (s < r) r = s }) @@ -3582,7 +3571,7 @@ function slowest_enemy_unit_speed(where) { function slowest_undisrupted_enemy_unit_speed(where) { let r = 4 for_each_undisrupted_enemy_unit_in_hex(where, u => { - let s = unit_speed(u) + let s = unit_speed[u] if (s < r) r = s }) @@ -3595,7 +3584,7 @@ function can_rout_fire(verbose) { if (verbose) log(`Slowest was ${speed_name[slowest]} unit.`) for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => { - if (unit_speed(u) >= slowest && !is_unit_fired(u)) + if (unit_speed[u] >= slowest && !is_unit_fired(u)) result = true }) return result @@ -3607,14 +3596,14 @@ function can_pursuit_fire(verbose) { if (verbose) log(`Slowest was ${speed_name[slowest]} unit.`) for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => { - if (unit_speed(u) >= slowest && !is_unit_fired(u)) + if (unit_speed[u] >= slowest && !is_unit_fired(u)) result = true }) return result } function roll_pursuit_fire_imp(who, n, hp) { - let speed = unit_speed(who) + let speed = unit_speed[who] if (n === 2) { let a = roll_die() let b = roll_die() @@ -3662,7 +3651,7 @@ states.pursuit_fire = { view.prompt = `Pursuit Fire.` let slowest = slowest_undisrupted_enemy_unit_speed(game.pursuit) for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => { - if (unit_speed(u) >= slowest && !is_unit_fired(u)) + if (unit_speed[u] >= slowest && !is_unit_fired(u)) gen_action_unit(u) }) // allow saving fire if there are shielded enemy units @@ -3672,7 +3661,7 @@ states.pursuit_fire = { unit(who) { let slowest = slowest_undisrupted_enemy_unit_speed(game.pursuit) set_unit_fired(who) - let done = roll_pursuit_fire(who, (unit_speed(who) > slowest ? 2 : 1)) + let done = roll_pursuit_fire(who, (unit_speed[who] > slowest ? 2 : 1)) if (done || !can_pursuit_fire(false)) goto_pursuit_hits() }, @@ -3687,14 +3676,14 @@ states.rout_fire = { view.prompt = `Pursuit Fire (Rout).` let slowest = slowest_enemy_unit_speed(game.pursuit) for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => { - if (unit_speed(u) >= slowest && !is_unit_fired(u)) + if (unit_speed[u] >= slowest && !is_unit_fired(u)) gen_action_unit(u) }) }, unit(who) { let slowest = slowest_enemy_unit_speed(game.pursuit) set_unit_fired(who) - let done = roll_rout_fire(who, (unit_speed(who) > slowest ? 2 : 1)) + let done = roll_rout_fire(who, (unit_speed[who] > slowest ? 2 : 1)) if (done || !can_rout_fire(false)) goto_rout_hits() }, @@ -3703,7 +3692,7 @@ states.rout_fire = { function gen_pursuit_hits(normal_steps, elite_steps, iterate) { let done = true iterate(game.pursuit, u => { - if (is_unit_elite(u)) { + if (is_elite_unit(u)) { if (game.hits >= 2) { gen_action_unit(u) done = false @@ -3835,18 +3824,17 @@ function end_buildup_discard() { } function init_buildup() { - // TODO: fortress supply - // TODO: assign fortress supply - game.buildup = { // redeployment network axis_network: axis_supply_network().slice(), axis_line: axis_supply_line().slice(), allied_network: allied_supply_network().slice(), allied_line: allied_supply_line().slice(), + // extra cards purchased axis_cards: 0, allied_cards: 0, + // remaining port capacity for sea redeployment bardia: 2, benghazi: 2, @@ -3855,6 +3843,9 @@ function init_buildup() { } function goto_buildup_supply_check() { + // TODO: fortress supply + // TODO: assign fortress supply + init_buildup() for_each_axis_unit_on_map(u => { @@ -3873,13 +3864,20 @@ function goto_buildup_supply_check() { set_unit_supply(u, 0) }) + for_each_unit_on_map(u => { + if (is_unit_supplied(u) && is_unit_disrupted(u) && !is_battle_hex(unit_hex(u))) { + log(`Recovered at #${unit_hex(u)}.`) + clear_unit_disrupted(u) + } + }) + log_br() - resume_buildup_supply_check() + resume_buildup_eleminate_unsupplied() } -function resume_buildup_supply_check() { - game.state = 'buildup_supply_check' +function resume_buildup_eleminate_unsupplied() { + game.state = 'buildup_eleminate_unsupplied' let done = true for_each_friendly_unit_on_map(u => { if (is_unit_unsupplied(u)) @@ -3889,14 +3887,14 @@ function resume_buildup_supply_check() { if (is_axis_player()) { log_br() set_enemy_player() - resume_buildup_supply_check() + resume_buildup_eleminate_unsupplied() } else { goto_buildup_point_determination() } } } -states.buildup_supply_check = { +states.buildup_eleminate_unsupplied = { prompt() { view.prompt = `Buildup: Eliminate unsupplied units.` for_each_friendly_unit_on_map(u => { @@ -3905,9 +3903,9 @@ states.buildup_supply_check = { }) }, unit(u) { - log(`>eliminated at #${unit_hex(u)}`) + log(`Eliminated at #${unit_hex(u)}`) eliminate_unit(u) - resume_buildup_supply_check() + resume_buildup_eleminate_unsupplied() }, } @@ -3944,9 +3942,21 @@ function goto_buildup_point_determination() { goto_buildup_reinforcements() } +function have_scheduled_reinforcements() { + let refit = friendly_refit() + for (let u = first_friendly_unit; u <= last_friendly_unit; ++u) { + let x = unit_hex(u) + if (x === refit || x === game.month || x === game.month + 1) + return true + } +} + function goto_buildup_reinforcements() { log_h2(game.active + " Buildup") - game.state = 'buildup_reinforcements' + if (have_scheduled_reinforcements()) + game.state = 'buildup_reinforcements' + else + goto_buildup_spending() } states.buildup_reinforcements = { @@ -4335,7 +4345,7 @@ function begin_game() { function find_axis_units(a) { let list = [] for (let u = first_axis_unit; u <= last_axis_unit; ++u) - if (units[u].appearance === a) + if (unit_appearance[u] === a) list.push(u) return list } @@ -4343,15 +4353,15 @@ function find_axis_units(a) { function find_allied_units(a) { let list = [] for (let u = first_allied_unit; u <= last_allied_unit; ++u) - if (units[u].appearance === a) + if (unit_appearance[u] === a) list.push(u) return list } function setup_reinforcements(m) { - for (let u = 0; u < units.length; ++u) { - if (units[u].appearance === m) { - if (m === 'M') + for (let u = 0; u < unit_count; ++u) { + if (unit_appearance[u] === m) { + if (m === "M") set_unit_hex(u, MALTA) else set_unit_hex(u, hexdeploy + m) @@ -4367,7 +4377,7 @@ function setup_units(where, steps, list) { u = find_unit(u) set_unit_hex(u, where) if (steps < 0) - set_unit_steps(u, units[u].steps + steps) + set_unit_steps(u, unit_start_steps[u] + steps) else if (steps > 0) set_unit_steps(u, steps) } @@ -4799,7 +4809,7 @@ exports.setup = function (seed, scenario, options) { axis_bps: 0, allied_bps: 0, - units: new Array(units.length).fill(0), + units: new Array(unit_count).fill(0), moved: [], fired: [], recover: [], @@ -4903,7 +4913,7 @@ exports.query = function (state, current, q) { return { axis_supply: game.buildup.axis_network, axis_supply_line: game.buildup.axis_line, - allied_supply: game.buildup.allien_network, + allied_supply: game.buildup.allied_network, allied_supply_line: game.buildup.allied_line, } } else { diff --git a/tools/gendata.js b/tools/gendata.js index cf77791..93d7502 100644 --- a/tools/gendata.js +++ b/tools/gendata.js @@ -1,5 +1,7 @@ // https://www.redblobgames.com/grids/hexagons/ +const fs = require('fs') + // Clear const CLEAR = 2; @@ -466,10 +468,58 @@ function def_block(nationality, type, appearance, steps, elite, label, name) { let speed = speed_from_type[type]; if (name in unit_map) throw new Error("duplicate block name:", name); - unit_map[name] = units.length; + unit_map[name] = 1 units.push({nationality, type, class: klass, speed, appearance, steps, elite, label, name}); } +function sort_nation(u) { + if (u.nationality === 'italian') + return 0 + if (u.nationality === 'german') + return 1 + return 2 +} + +function sort_subnation(u) { + function isn(x) { + let [a, b] = u.name.split('/'); + if (b) + b = b.split('+'); + return a.endsWith(x) || (b && b[0] === x) + } + switch (true) { + case isn("IN"): return 3 + case isn("SA"): return 4 + case isn("AU"): return 5 + case isn("NZ"): return 6 + case isn("FF"): return 7 + case isn("Pol"): return 8 + } + return 2 +} + +function sort_name(u) { + if (u.nationality === 'italian') + return 0 + if (u.nationality === 'german') + return 1 + return sort_subnation(u) +} + +function cmp_block(a, b) { + let x = sort_name(a) * 10000 + a.class * 1000 + (1-a.elite) * 10 + (4-a.speed) * 100 + (4-a.steps) + let y = sort_name(b) * 10000 + b.class * 1000 + (1-b.elite) * 10 + (4-b.speed) * 100 + (4-b.steps) + // let x = sort_nation(a) * 10000 + a.class * 1000 + (1-a.elite) * 10 + (4-a.speed) * 100 + sort_subnation(a) + // let y = sort_nation(b) * 10000 + b.class * 1000 + (1-b.elite) * 10 + (4-b.speed) * 100 + sort_subnation(b) + if (x < y) return -1 + if (x > y) return 1 + if (parseInt(a.name) < parseInt(b.name)) return -1 + if (parseInt(a.name) > parseInt(b.name)) return 1 + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + return 0 +} + let S = "S"; let M = "M"; let T = "T"; @@ -587,14 +637,80 @@ def_block("allied", "armor", 18, 3, 1, 77, "Sher/A"); def_block("allied", "mot. a/t", 18, 4, 0, 78, "6#/B"); def_block("allied", "mot. inf.", 18, 4, 0, 79, "51H/154"); +units.sort(cmp_block) + let all_hexes = hex_exists.map((x,i) => x ? i : 0).filter(x => x > 0) -console.log("const all_hexes = " + JSON.stringify(all_hexes)); -console.log("const hex_exists = " + JSON.stringify(hex_exists)); -console.log("const hex_road = " + JSON.stringify(hex_road)); -console.log("const side_road = " + JSON.stringify(side_road)); -console.log("const side_limit = " + JSON.stringify(side_limit)); -console.log("const hex_name = " + JSON.stringify(hex_name)); -console.log("const regions = " + JSON.stringify(regions)); -console.log("const units = " + JSON.stringify(units)); -console.log("if (typeof module !== 'undefined') module.exports = { all_hexes, hex_exists, hex_name, hex_road, side_road, side_limit, regions, units }"); +function gen_array(name, fn) { + data += "const " + name + " = [" + units.map(fn).join(",") + "]\n" +} + +let data = "// DON'T EDIT - AUTOGENERATED\n" +data += "const all_hexes = " + JSON.stringify(all_hexes) + "\n" +data += "const hex_exists = " + JSON.stringify(hex_exists) + "\n" +data += "const hex_road = " + JSON.stringify(hex_road) + "\n" +data += "const side_road = " + JSON.stringify(side_road) + "\n" +data += "const side_limit = " + JSON.stringify(side_limit) + "\n" +data += "const hex_name = " + JSON.stringify(hex_name) + "\n" +data += "const regions = " + JSON.stringify(regions) + "\n" + +gen_array("unit_name", u => JSON.stringify(u.name)) +gen_array("unit_appearance", u => JSON.stringify(u.appearance)) +gen_array("unit_start_steps", u => u.steps) +gen_array("unit_elite", u => u.elite) +gen_array("unit_class", u => u.class) +gen_array("unit_speed", u => u.speed) + +data += "if (typeof module !== 'undefined')\n\tmodule.exports = {\n" +data += "\t\tall_hexes, hex_exists, hex_name, hex_road, side_road, side_limit, regions,\n" +data += "\t\tunit_name, unit_appearance, unit_start_steps, unit_elite, unit_class, unit_speed,\n" +data += "\t}\n" + +fs.writeFileSync("data.js", data) + +fs.writeFileSync("rawdata.js", "exports.units = " + JSON.stringify(units)) + +// Show ranges + +let test = "" +function gen_test_range(fn) { + let ranges = []; + let start = -1; + for (let p = 0; p < units.length; ++p) { + if (fn(units[p])) { + if (start < 0) + start = p; + } else { + if (start >= 0) { + ranges.push([start,p-1]) + start = -1; + } + } + } + if (start >= 0) + ranges.push([start,units.length-1]) + return ranges.map(([a,b])=>`(u >= ${a} && u <= ${b})`).join(" || ") +} + +function gen_test(name, fn) { + test += "function " + name + "(u) { return " + gen_test_range(fn) + " }\n" +} + +gen_test("is_armor_unit", u => u.class === ARMOR) +gen_test("is_artillery_unit", u => u.class === ARTILLERY) +gen_test("is_infantry_unit", u => u.class === INFANTRY) +gen_test("is_antitank_unit", u => u.class === ANTITANK) + +gen_test("is_recon_unit", u => u.speed === 4) +gen_test("is_mechanized_unit", u => u.speed === 3) +gen_test("is_motorized_unit", u => u.speed === 2) +gen_test("is_leg_unit", u => u.speed === 1) + +gen_test("is_elite_unit", u => u.elite) + +gen_test("is_italian_unit", u => u.nationality === 'italian') +gen_test("is_german_unit", u => u.nationality === 'german') +gen_test("is_axis_unit", u => u.nationality !== 'allied') +gen_test("is_allied_unit", u => u.nationality === 'allied') + +console.log(test) diff --git a/tools/genunits.js b/tools/genunits.js index 4e0f30e..820de56 100644 --- a/tools/genunits.js +++ b/tools/genunits.js @@ -1,5 +1,9 @@ -const { units } = require("../data.js"); -const print = console.log; +const fs = require('fs') +const { units } = require("../rawdata.js"); +var out = [] +function print(s) { out.push(s) } + +function print_defs() { print(` @@ -62,9 +66,10 @@ print(` -`); +`) +} -SYMBOLS = { +const SYMBOLS = { "armor": ` @@ -175,53 +180,64 @@ const BLACK = { allied: "#5c3a1e" } -let x = 0, y = 0; -for (let u of units) { - let type = TYPEMAP[u.type]; - let black = BLACK[u.nationality]; - let fill = COLORMAP[u.nationality]; - - let [a, b] = u.name.split('/'); - if (b) - b = b.split('+'); - - for (let n in COLORMAP) - if (a.endsWith(n) || (b && b[0] === n)) - fill = COLORMAP[n]; - - print(``); - - if (type === 'armor' && u.elite && u.nationality === 'allied') - type = 'armor_elite'; - - let symbol = SYMBOLS[type]; - print(symbol.replace(/#ccc/g, fill).replace(/#111/g, black).trim()); - - if (u.elite) - print(``); - else - print(``); - - print(``); - print(`${u.appearance}`); - print(`${a}`); +function print_units(show_text) { + out = [] + print_defs() + let x = 0, y = 0; + for (let u of units) { + let type = TYPEMAP[u.type]; + let black = BLACK[u.nationality]; + let fill = COLORMAP[u.nationality]; + + let [a, b] = u.name.split('/'); + if (b) + b = b.split('+'); + + for (let n in COLORMAP) + if (a.endsWith(n) || (b && b[0] === n)) + fill = COLORMAP[n]; + + print(``); + + if (type === 'armor' && u.elite && u.nationality === 'allied') + type = 'armor_elite'; + + let symbol = SYMBOLS[type]; + print(symbol.replace(/#ccc/g, fill).replace(/#111/g, black).trim()); + + if (u.elite) + print(``); + else + print(``); + + if (show_text) { + print(``); + print(`${u.appearance}`); + print(`${a}`); + + if (b) { + if (b.length > 1) { + print(`${b[0]}`); + print(`${b[1]}`); + } else { + print(`${b[0]}`); + } + } + + print(``); + } - if (b) { - if (b.length > 1) { - print(`${b[0]}`); - print(`${b[1]}`); - } else { - print(`${b[0]}`); + print(``); + x += 51; + if (x >= 510) { + y += 51; + x = 0; } } - print(``); - print(``); - x += 51; - if (x >= 510) { - y += 51; - x = 0; - } + print(``); + return out.join("\n") } -print(``); -print(``); + +fs.writeFileSync("units.svg", print_units(true)) +fs.writeFileSync("units-simple.svg", print_units(false)) diff --git a/units-simple.svg b/units-simple.svg new file mode 100644 index 0000000..f1af5ad --- /dev/null +++ b/units-simple.svg @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/units.svg b/units.svg index 7e3c7cd..226f4ad 100644 --- a/units.svg +++ b/units.svg @@ -62,140 +62,140 @@ - + S -Tre +Ari - - + + -S -Pav +11 +Lit - + -S -Bre +7 +Tri + -S -Bol +19 +Cen + -S -Sav +17 +Fas - + -7 -Tri +S +Bre - - + + -7 -Sab +M +Fol - - + + -11 -Lit +S +Pav - - + -17 -Fas +S +Tre - -19 -Cen +S +Bol - + -19 -Pis +S +Sav - - + + -M -Fol +19 +Pis - + -S -Ita +7 +Sab - - + + S -Ari +Ita - - + + -S -21 -5 +3 +15 +33 @@ -210,33 +210,32 @@ - - + + -S -21 -104 +5 +90 +580 - - + + -3 +5 15 -33 +8 - - + -3 -88mm -A +S +21 +5 @@ -251,53 +250,53 @@ - + -5 -15 -8 +S +21 +104 - - + + -5 +3 90 -580 +155 - - + -5 +11 90 -361 +346 - - + -5 -50mm +11 +90 +sv288 - + + 7 - -104 +90 +200 @@ -306,455 +305,451 @@ -7 +5 90 -200 +361 - - - + + -11 -88mm -B +M +164 +382 +433 - - + + -11 -90 -sv288 +M +Ram - + -11 -90 -346 +M +164 +125 - - + + + -M -Ram +3 +88mm +A - - + + + -M -164 -382 -433 +11 +88mm +B - + + -M -164 -125 +5 +50mm - - + + + -3 -90 -155 +17 +76mm - - + -17 -76mm +7 + +104 - + -S -2 -3 +4 +7 - - + + -S -2 -SG +18 +Sher +A - - - + + + -S -4IN -3m +20 +Sher +B - - - - + + + -S -9AU -20 +12 +Grant - - - + + -S -70 -14 -16 +T +Matilda +A - - - + + -S -70 -23 +4 +Matilda +B - - + + + -T -Matilda -A +4 + +1AT - - + + -T -7 -SG +10 +1 +2 - - + + -T -7 -22G +8 +1 +22 - - - - + + + -T - -Pol +2 +7 +7 - - - - + + + -T -7AU -18 +16 +10 +8 - - + + + -T +8 -Tob +32AT - - - + + -18 -51H -152 +4 +7 +4 - - - - + + + -18 -Priest +20 +8 +24 - - + + -18 - -C +20 +8 +9 - + -2 -7 -7 +16 +10 +23 - - - + + + -2 -4IN -7m +S +2 +3 - - - + + -2 -4IN -5 +10 +1 +201G - - - + + -2 -4IN -11 +T +7 +22G - - + + -4 -Matilda -B +T +7 +SG - - - + + -4 - -1AT +10 +1 +SG - - + + -4 -7 -4 +S +2 +SG - - + + + -4 -7 +16 +44 +131 +133 - - + + + -20 - -D +18 +51H +152 - - - + + + -6 -2# +18 +51H +154 - - + + + -6 -2NZ -4 +S +70 +14 +16 - - - + + + + -6 -2NZ -5 +S +70 +23 - - - + + + + -6 -2NZ -6 +16 +44 +132 - - - + + + -6 -1SA -2 -5 +18 +6# +B - - - + + + 6 -1SA -1 +2# - - - + + + + -8 -1SA +12 +6# +A - - - - + + + + -8 -1SA -3 +18 +Priest - - - - + + + -8 -2SA -4 -6 +14 + +B - + -8 -1 -22 +18 + +C - - + -8 +20 -32AT +D @@ -769,67 +764,36 @@ - - + + -10 -1 -2 +T + +Tob - + -10 -1 -201G +2 +4IN +7m - + -10 -1 -SG +S +4IN +3m - - - - -10 -5IN -29 - - - - - - - -12 -Grant - - - - - - - - -12 -6# -A - - - - @@ -838,7 +802,7 @@ 161m - + @@ -850,7 +814,7 @@ 10 - + @@ -862,6 +826,39 @@ 25 + + + + + + +2 +4IN +11 + + + + + + + + +2 +4IN +5 + + + + + + + + +10 +5IN +29 + + @@ -874,74 +871,80 @@ - - - - + + + -14 -FF -2 +8 +1SA - - + + + -14 - -B +6 +1SA +2 +5 - - - + + + + -20 -Sher -B +6 +1SA +1 - - + + + -20 -8 -9 +8 +1SA +3 - - + + + -20 -8 -24 +8 +2SA +4 +6 - - + + + -16 -10 -8 +S +9AU +20 - - - + + + + 16 -10 -23 +9AU +24 @@ -959,67 +962,64 @@ - + -16 -9AU -24 +T +7AU +18 - - - + + -16 -44 -131 -133 +6 +2NZ +4 - - - - + + + -16 -44 -132 +6 +2NZ +5 - - - + + + -18 -Sher -A +6 +2NZ +6 - - - + + + -18 -6# -B +14 +FF +2 - + - + -18 -51H -154 +T + +Pol - + \ No newline at end of file -- cgit v1.2.3