diff options
-rw-r--r-- | tools/boxes.svg | 688 | ||||
-rw-r--r-- | tools/build_cards1.sh | 86 | ||||
-rw-r--r-- | tools/build_cards2.sh | 10 | ||||
-rw-r--r-- | tools/build_counters1.sh | 117 | ||||
-rw-r--r-- | tools/build_counters2.sh | 119 | ||||
-rw-r--r-- | tools/build_counters3.sh | 5 | ||||
-rw-r--r-- | tools/build_map.sh | 16 | ||||
-rw-r--r-- | tools/build_mats.sh | 35 | ||||
-rw-r--r-- | tools/build_screen.sh | 10 | ||||
-rw-r--r-- | tools/build_stickers.sh | 37 | ||||
-rw-r--r-- | tools/colors.mjs | 108 | ||||
-rw-r--r-- | tools/genboxes.py | 65 | ||||
-rw-r--r-- | tools/gencss.js | 5 | ||||
-rw-r--r-- | tools/gencyl.js | 51 | ||||
-rw-r--r-- | tools/gendata.js | 705 | ||||
-rw-r--r-- | tools/scale.sh | 18 | ||||
-rw-r--r-- | tools/svgo.config.js | 10 |
17 files changed, 2085 insertions, 0 deletions
diff --git a/tools/boxes.svg b/tools/boxes.svg new file mode 100644 index 0000000..16b8e71 --- /dev/null +++ b/tools/boxes.svg @@ -0,0 +1,688 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg2" + width="5100" + height="6600" + viewBox="0 0 5100 6600" + sodipodi:docname="boxes.svg" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="640" + inkscape:window-height="480" + id="namedview8" + showgrid="false" + inkscape:zoom="0.4218644" + inkscape:cx="2021.1195" + inkscape:cy="4535.2592" + inkscape:current-layer="svg2" + inkscape:document-rotation="0" /> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <image + sodipodi:absref="/home/tor/src/rally/public/nevsky/tools/map300.png" + xlink:href="map300.png" + id="image12" + preserveAspectRatio="none" + height="6600" + width="5100" + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + sodipodi:insensitive="true" + x="0" + y="0" /> + <rect + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + id="rect838" + width="303.94965" + height="60.271549" + x="1448.1355" + y="3624.7134" + ry="0.381295" + inkscape:label="Wesenberg" /> + <rect + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + id="rect840" + width="184.05482" + height="60.919552" + x="1012.6255" + y="4583.2241" + ry="0.381295" + inkscape:label="Fellin" /> + <rect + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + id="rect844" + width="250.44016" + height="60.948803" + x="1377.8793" + y="5103.0913" + ry="0.61047864" + inkscape:label="Odenpäh" /> + <rect + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + id="rect848" + width="184.90872" + height="60.490585" + x="1503.5576" + y="5612.335" + ry="0.610479" + inkscape:label="Adsel" /> + <rect + style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-opacity:1" + id="rect850" + width="231.68872" + height="60.27153" + x="909.25671" + y="5759.166" + ry="0.610479" + inkscape:label="Wenden" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect854" + width="147.6003" + height="62.215714" + x="2666.8506" + y="3294.6785" + ry="0.610479" + inkscape:label="Luga" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect856" + width="284.58069" + height="62.094578" + x="2904.4648" + y="3521.9727" + ry="0.610479" + inkscape:label="Kaibolovo" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect858" + width="240.76186" + height="61.891674" + x="3132.8203" + y="3159.7158" + ry="0.610479" + inkscape:label="Koporye" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect860" + width="147.92438" + height="61.891689" + x="3924.1265" + y="2933.6978" + ry="0.610479" + inkscape:label="Neva" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect864" + width="230.96405" + height="63.011024" + x="4591.4414" + y="3783.0674" + ry="0.610479" + inkscape:label="Volkhov" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect870" + width="186.64714" + height="62.539753" + x="4242.9819" + y="5580.9438" + ry="0.610479" + inkscape:label="Lovat" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect872" + width="240.92387" + height="62.539753" + x="3514.5398" + y="5466.5576" + ry="0.610479" + inkscape:label="Porkhov" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00dfff;stroke-opacity:1" + id="rect876" + width="240.81668" + height="62.323635" + x="2239.7556" + y="5430.8633" + ry="0.610479" + inkscape:label="Izborsk" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect878" + width="351.25955" + height="60.595512" + x="3706.0474" + y="6347.2988" + ry="0.610479" + inkscape:label="Velikiye Luki" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect880" + width="121.21022" + height="32.307468" + x="3936.2415" + y="4101.6738" + ry="0.610479" + inkscape:label="Tesovo" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect886" + width="127.99587" + height="30.459776" + x="3500.9299" + y="4176.23" + ry="0.610479" + inkscape:label="Zheltsy" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect888" + width="104.25461" + height="31.390947" + x="3787.9937" + y="4540.689" + ry="0.610479" + inkscape:label="Sablia" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect890" + width="88.138931" + height="30.135736" + x="2427.0608" + y="4148.6865" + ry="0.610479" + inkscape:label="Gdov" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect892" + width="161.37201" + height="31.107857" + x="3152.9109" + y="5214.4546" + ry="0.610479" + inkscape:label="Dubrovno" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect894" + width="115.3583" + height="30.459776" + x="2745.9165" + y="5716.7168" + ry="0.610479" + inkscape:label="Ostrov" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect896" + width="145.81808" + height="30.459776" + x="2045.9896" + y="6307.4419" + ry="0.610479" + inkscape:label="Rositten" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect898" + width="174.98169" + height="30.135736" + x="1876.8407" + y="5389.436" + ry="0.610479" + inkscape:label="Kirrumpäh" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-opacity:1" + id="rect900" + width="118.43668" + height="29.811697" + x="516.68207" + y="4580.3081" + ry="0.610479" + inkscape:label="Pernau" /> + <rect + style="fill:none;fill-opacity:1;stroke:#efc300;stroke-opacity:1" + id="rect902" + width="123.13527" + height="30.783817" + x="2371.002" + y="3548.8879" + ry="0.610479" + inkscape:label="Narwia" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904" + cx="2099.4792" + cy="3729.7024" + rx="100.02692" + ry="50.425739" + inkscape:label="Wierland" /> + <rect + style="fill:none;fill-opacity:1;stroke:#00ff34;stroke-width:0.938948;stroke-opacity:1" + id="rect892-8" + width="141.99065" + height="31.168909" + x="292.25372" + y="3796.748" + ry="0.61167711" + inkscape:label="Warbola" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-3" + cx="1635.0789" + cy="4162.5376" + rx="100.02692" + ry="50.425739" + inkscape:label="Waiga" + sodipodi:insensitive="true" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-6" + cx="1163.9856" + cy="3996.0444" + rx="100.02692" + ry="50.425739" + inkscape:label="Jerwen" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7" + cx="667.22955" + cy="4033.4651" + rx="100.02692" + ry="50.425739" + inkscape:label="Harrien" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-5" + cx="716.7218" + cy="4819.083" + rx="100.02692" + ry="50.425739" + inkscape:label="Sackala" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-35" + cx="608.5719" + cy="5275.5122" + rx="100.02692" + ry="50.425739" + inkscape:label="Metsepole" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-62" + cx="2148.3323" + cy="5827.2598" + rx="100.02692" + ry="50.425739" + inkscape:label="Lettgallia" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-9" + cx="1640.578" + cy="5983.0688" + rx="100.02692" + ry="50.425739" + inkscape:label="Tolowa" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-1" + cx="2056.6799" + cy="4989.5566" + rx="100.02692" + ry="50.425739" + inkscape:label="Ugaunia" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-4" + cx="1130.2521" + cy="3460.1011" + rx="100.02692" + ry="50.425739" + inkscape:label="Revala" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-3" + cx="3129.4712" + cy="6140.2524" + rx="100.02692" + ry="50.425739" + inkscape:label="Velikaya River" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-1" + cx="3399.3877" + cy="5830.9258" + rx="100.02692" + ry="50.425739" + inkscape:label="Sorot River" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-49" + cx="3754.0825" + cy="4914.4019" + rx="100.02692" + ry="50.425739" + inkscape:label="Shelon River" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-2" + cx="2881.5515" + cy="4635.7783" + rx="100.02692" + ry="50.425739" + inkscape:label="Zhelcha River" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-0" + cx="2928.7524" + cy="4283.8335" + rx="100.02692" + ry="50.425739" + inkscape:label="Plyussa River" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-6" + cx="3919.5151" + cy="3689.009" + rx="100.02692" + ry="50.425739" + inkscape:label="Ingria" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-8" + cx="3587.7727" + cy="3394.645" + rx="100.02692" + ry="50.425739" + inkscape:label="Vod" + sodipodi:insensitive="true" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-9" + cx="4173.6377" + cy="3372.6101" + rx="100.02692" + ry="50.425739" + inkscape:label="Izhora" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-26" + cx="3932.5515" + cy="2457.5205" + rx="100.02692" + ry="50.425739" + inkscape:label="Karelia" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1468" + width="237.84526" + height="89.759171" + x="4618.8687" + y="2816.719" + ry="0.610479" + inkscape:label="Ladoga" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1470" + width="333.15622" + height="112.27441" + x="4318.2031" + y="4315.4531" + ry="0.610479" + inkscape:label="Novgorod" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1472" + width="205.44145" + height="91.54155" + x="4328.8525" + y="5165.6865" + ry="0.610479" + inkscape:label="Rusa" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1474" + width="205.44148" + height="91.217155" + x="272.84183" + y="6230.9683" + ry="0.610479" + inkscape:label="Riga" + sodipodi:insensitive="true" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1476" + width="205.07263" + height="90.965332" + x="2679.9163" + y="5263.1392" + ry="0.610479" + inkscape:label="Pskov" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1478" + width="252.50232" + height="90.965202" + x="1625.2262" + y="4588.5771" + ry="0.610479" + inkscape:label="Dorpat" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1480" + width="205.2198" + height="90.645508" + x="107.90538" + y="4265.9893" + ry="0.610479" + inkscape:label="Leal" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1482" + width="205.75963" + height="90.735939" + x="601.01062" + y="3563.9038" + ry="0.610479" + inkscape:label="Reval" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1506" + width="591.99841" + height="916.72931" + x="39.683407" + y="168.04262" + ry="0.610479" + inkscape:label="box1" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1508" + width="590.72522" + height="913.46924" + x="649.70056" + y="168.17685" + ry="0.610479" + inkscape:label="box2" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1510" + width="591.04926" + height="916.38562" + x="1313.0107" + y="167.20473" + ry="0.610479" + inkscape:label="box3" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1512" + width="589.75311" + height="916.38562" + x="1922.2063" + y="167.20473" + ry="0.610479" + inkscape:label="box4" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1514" + width="592.34546" + height="917.68176" + x="2587.1367" + y="167.20473" + ry="0.610479" + inkscape:label="box5" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1516" + width="588.45697" + height="916.38562" + x="3196.3323" + y="167.20473" + ry="0.610479" + inkscape:label="box6" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1518" + width="593.6416" + height="916.38562" + x="3858.6704" + y="167.20473" + ry="0.610479" + inkscape:label="box7" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1520" + width="591.04926" + height="917.68176" + x="4469.1621" + y="165.90857" + ry="0.610479" + inkscape:label="box8" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1522" + width="593.6416" + height="915.08942" + x="38.884819" + y="1118.5867" + ry="0.610479" + inkscape:label="box9" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1524" + width="217.2162" + height="215.38313" + x="172.3065" + y="183.30479" + ry="0.610479" + inkscape:label="Victory" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1526" + width="216.29967" + height="213.55009" + x="398.68796" + y="184.22133" + ry="0.610479" + inkscape:label="Turn" /> + <rect + style="fill:none;stroke:#000000" + id="rect74" + width="843.68152" + height="627.99255" + x="4192.9326" + y="5846.7227" + ry="0.610479" + inkscape:label="Novgorod Veche" /> + <ellipse + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.52793;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path904-7-36" + cx="2212.0798" + cy="4741.5249" + rx="100.02692" + ry="50.425739" + inkscape:label="Uzmen" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect895" + width="461.87738" + height="148.64993" + x="1499.7745" + y="4716.9902" + ry="0" + inkscape:label="way-crossroads" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect897" + width="175.19495" + height="350.38925" + x="1295.3806" + y="4525.8687" + inkscape:label="way-wirz" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect899" + width="220.32043" + height="464.53174" + x="2232.4082" + y="4196.7144" + inkscape:label="way-peipus-east" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect901" + width="361.00775" + height="228.28438" + x="2065.1765" + y="3835.7068" + ry="2.6544683" + inkscape:label="way-peipus-north" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect903" + width="217.66652" + height="520.27612" + x="1988.1968" + y="4140.9712" + ry="0" + inkscape:label="way-peipus-west" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect77" + width="431.35098" + height="84.279167" + x="4397.7905" + y="5836.5122" + inkscape:label="veche-label-top" /> + <rect + style="fill:#008900;fill-opacity:0.288618;stroke:#000000" + id="rect79" + width="362.33572" + height="60.389202" + x="4426.3257" + y="6428.459" + inkscape:label="veche-label-bottom" /> +</svg> diff --git a/tools/build_cards1.sh b/tools/build_cards1.sh new file mode 100644 index 0000000..3459345 --- /dev/null +++ b/tools/build_cards1.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Extract, crop, and rename card images to create 300 dpi PNG versions. + +function extract_images { + echo "$1" + mutool extract -r "$1" + mkdir -p $2 + mv image* $2 + rm -f font* +} + +extract_images "../HIRES/Nevsky_Arts of War Cards_42 Anverses.pdf" tmp/aow_front +extract_images "../HIRES/Nevsky_Arts of War Cards_42 Backs.pdf" tmp/aow_back +extract_images "../HIRES/Nevsky_Arts of War Cards_R1 and R2 Anverses_Corrected.pdf" tmp/aow_corr +extract_images "../HIRES/Nevsky_Command Cards_42 Anverses.pdf" tmp/cc_front +extract_images "../HIRES/Nevsky_Command Cards_42 Backs.pdf" tmp/cc_back + +# cards are 63.5 x 89.0 mm - 2.5 x 3.5 inches - 750 x 1050 pixels +# rounded to multiple of 12 = 744 x 1044 +for IM in tmp/aow_*/*.png tmp/cc_*/*.png +do + echo $IM + convert $IM -gravity Center -crop 744x1040+0+0 +repage ${IM/png/ppm} +done + +mkdir -p cards300 +pnmtopng tmp/aow_back/image-0083.ppm >cards300/aow_russian_back.png +pnmtopng tmp/aow_back/image-0102.ppm >cards300/aow_teutonic_back.png +pnmtopng tmp/aow_corr/image-0004.ppm >cards300/aow_russian_02.png +pnmtopng tmp/aow_corr/image-0015.ppm >cards300/aow_russian_01.png +pnmtopng tmp/aow_front/image-0004.ppm >cards300/aow_teutonic_02.png +pnmtopng tmp/aow_front/image-0008.ppm >cards300/aow_teutonic_03.png +pnmtopng tmp/aow_front/image-0012.ppm >cards300/aow_teutonic_04.png +pnmtopng tmp/aow_front/image-0016.ppm >cards300/aow_teutonic_05.png +pnmtopng tmp/aow_front/image-0020.ppm >cards300/aow_teutonic_06.png +pnmtopng tmp/aow_front/image-0024.ppm >cards300/aow_teutonic_07.png +pnmtopng tmp/aow_front/image-0028.ppm >cards300/aow_teutonic_08.png +pnmtopng tmp/aow_front/image-0032.ppm >cards300/aow_teutonic_09.png +pnmtopng tmp/aow_front/image-0036.ppm >cards300/aow_teutonic_10.png +pnmtopng tmp/aow_front/image-0040.ppm >cards300/aow_teutonic_11.png +pnmtopng tmp/aow_front/image-0044.ppm >cards300/aow_teutonic_12.png +pnmtopng tmp/aow_front/image-0048.ppm >cards300/aow_teutonic_13.png +pnmtopng tmp/aow_front/image-0052.ppm >cards300/aow_teutonic_14.png +pnmtopng tmp/aow_front/image-0056.ppm >cards300/aow_teutonic_15.png +pnmtopng tmp/aow_front/image-0060.ppm >cards300/aow_teutonic_16.png +pnmtopng tmp/aow_front/image-0064.ppm >cards300/aow_teutonic_17.png +pnmtopng tmp/aow_front/image-0068.ppm >cards300/aow_teutonic_18.png +# pnmtopng tmp/aow_front/image-0078.ppm >cards300/aow_russian_01.ppm # corrected +# pnmtopng tmp/aow_front/image-0082.ppm >cards300/aow_russian_02.ppm # corrected +pnmtopng tmp/aow_front/image-0086.ppm >cards300/aow_russian_03.png +pnmtopng tmp/aow_front/image-0090.ppm >cards300/aow_russian_04.png +pnmtopng tmp/aow_front/image-0094.ppm >cards300/aow_russian_05.png +pnmtopng tmp/aow_front/image-0098.ppm >cards300/aow_russian_06.png +pnmtopng tmp/aow_front/image-0102.ppm >cards300/aow_russian_07.png +pnmtopng tmp/aow_front/image-0106.ppm >cards300/aow_russian_08.png +pnmtopng tmp/aow_front/image-0110.ppm >cards300/aow_russian_09.png +pnmtopng tmp/aow_front/image-0114.ppm >cards300/aow_russian_10.png +pnmtopng tmp/aow_front/image-0118.ppm >cards300/aow_russian_11.png +pnmtopng tmp/aow_front/image-0122.ppm >cards300/aow_russian_12.png +pnmtopng tmp/aow_front/image-0126.ppm >cards300/aow_russian_13.png +pnmtopng tmp/aow_front/image-0130.ppm >cards300/aow_russian_14.png +pnmtopng tmp/aow_front/image-0134.ppm >cards300/aow_russian_15.png +pnmtopng tmp/aow_front/image-0138.ppm >cards300/aow_russian_16.png +pnmtopng tmp/aow_front/image-0142.ppm >cards300/aow_russian_17.png +pnmtopng tmp/aow_front/image-0146.ppm >cards300/aow_russian_18.png +pnmtopng tmp/aow_front/image-0153.ppm >cards300/aow_teutonic_none.png +pnmtopng tmp/aow_front/image-0155.ppm >cards300/aow_russian_none.png +pnmtopng tmp/aow_front/image-0175.ppm >cards300/aow_teutonic_01.png +pnmtopng tmp/cc_back/image-0083.ppm >cards300/cc_russian_back.png +pnmtopng tmp/cc_back/image-0102.ppm >cards300/cc_teutonic_back.png +pnmtopng tmp/cc_front/image-0083.ppm >cards300/cc_teutonic_andreas.png +pnmtopng tmp/cc_front/image-0085.ppm >cards300/cc_teutonic_pass.png +pnmtopng tmp/cc_front/image-0087.ppm >cards300/cc_teutonic_heinrich.png +pnmtopng tmp/cc_front/image-0089.ppm >cards300/cc_teutonic_rudolf.png +pnmtopng tmp/cc_front/image-0091.ppm >cards300/cc_teutonic_knud_and_abel.png +pnmtopng tmp/cc_front/image-0093.ppm >cards300/cc_teutonic_yaroslav.png +pnmtopng tmp/cc_front/image-0095.ppm >cards300/cc_russian_aleksandr.png +pnmtopng tmp/cc_front/image-0097.ppm >cards300/cc_russian_domash.png +pnmtopng tmp/cc_front/image-0099.ppm >cards300/cc_russian_vladislav.png +pnmtopng tmp/cc_front/image-0101.ppm >cards300/cc_russian_pass.png +pnmtopng tmp/cc_front/image-0103.ppm >cards300/cc_russian_karelians.png +pnmtopng tmp/cc_front/image-0105.ppm >cards300/cc_russian_andrey.png +pnmtopng tmp/cc_front/image-0107.ppm >cards300/cc_russian_gavrilo.png +pnmtopng tmp/cc_front/image-0126.ppm >cards300/cc_teutonic_hermann.png + +rm -rf tmp diff --git a/tools/build_cards2.sh b/tools/build_cards2.sh new file mode 100644 index 0000000..bcf4062 --- /dev/null +++ b/tools/build_cards2.sh @@ -0,0 +1,10 @@ +# 300dpi @ 744 x 1044 + +mkdir -p cards75 cards150 + +for IM in cards300/*.png +do + echo $IM + convert $IM -colorspace RGB -resize 25% -colorspace sRGB ${IM/cards300/cards75} + convert $IM -colorspace RGB -resize 50% -colorspace sRGB ${IM/cards300/cards150} +done diff --git a/tools/build_counters1.sh b/tools/build_counters1.sh new file mode 100644 index 0000000..a8573e2 --- /dev/null +++ b/tools/build_counters1.sh @@ -0,0 +1,117 @@ +# 3 counter sheet dies +# 1 and 3 has square counters, only bottom row differs +# 2 has rectangular tiles + +# circular (sheet 1 bottom) 210x210 +# large square 190x190 (188-190-ish) +# rectangle 380x190 (188-190-ish) +# small square 150x150 + +mkdir -p tmp + +# large squares (top sheet 1 and 3) +ROW=1 +for TOP in 340 586 833 1080 1326 +do + COL=1 + RCOL=12 + for LEFT in 304 551 797 1043 1290 1536 1874 2121 2367 2613 2860 3106 + do + echo large square $ROW $COL + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-1F-nf.ppm > tmp/cs_sq_large_1_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-1B-nf.ppm > tmp/cs_sq_large_1_${ROW}_${RCOL}_b.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-3F-nf.ppm > tmp/cs_sq_large_3_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-3B-nf.ppm > tmp/cs_sq_large_3_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done + +# large squares (bottom sheet 2) +ROW=1 +for TOP in 2075 2322 +do + COL=1 + RCOL=12 + for LEFT in 304 551 797 1043 1290 1536 1874 2121 2367 2613 2860 3106 + do + echo large square $ROW $COL + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-2F-nf.ppm > tmp/cs_sq_large_2_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 168 -height 168 ../HIRES/nocut/NEVSKY-2B-nf.ppm > tmp/cs_sq_large_2_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done + +# small squares (bottom sheet 1 and 3) +ROW=1 +for TOP in 1595 1745 1970 2120 2345 +do + COL=1 + RCOL=4 + for LEFT in 305 1275 2175 2695 + do + echo small square $ROW $COL + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 144 -height 144 ../HIRES/nocut/NEVSKY-1F-nf.ppm > tmp/cs_sq_small_1_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 144 -height 144 ../HIRES/nocut/NEVSKY-1B-nf.ppm > tmp/cs_sq_small_1_${ROW}_${RCOL}_b.ppm + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 144 -height 144 ../HIRES/nocut/NEVSKY-3F-nf.ppm > tmp/cs_sq_small_3_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 144 -height 144 ../HIRES/nocut/NEVSKY-3B-nf.ppm > tmp/cs_sq_small_3_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done + +# large rects (top sheet 2) +ROW=1 +for TOP in 340 586 833 1080 1326 1572 1818 +do + COL=1 + RCOL=7 + TOP=$(expr $TOP + 1) + for LEFT in 304 739 1175 1611 2047 2483 2919 + do + echo rectangle $ROW $COL + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 360 -height 168 ../HIRES/nocut/NEVSKY-2F-nf.ppm > tmp/cs_rect_2_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 360 -height 168 ../HIRES/nocut/NEVSKY-2B-nf.ppm > tmp/cs_rect_2_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done + +# circles (sheet 1) +ROW=1 +for TOP in 2332 +do + COL=1 + RCOL=6 + for LEFT in 987 1253 1518 1874 2139 2404 + do + echo circle $ROW $COL + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 204 -height 204 ../HIRES/nocut/NEVSKY-1F-nf.ppm > tmp/cs_circle_1_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 3 + $TOP) -left $(expr 3 + $LEFT) -width 204 -height 204 ../HIRES/nocut/NEVSKY-1B-nf.ppm > tmp/cs_circle_1_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done + +# rectangles (sheet 1) +ROW=1 +for TOP in 2342 +do + COL=1 + RCOL=2 + for LEFT in 416 2806 + do + echo rectangle $ROW $COL + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 360 -height 168 ../HIRES/nocut/NEVSKY-1F-nf.ppm > tmp/cs_rect_1_${ROW}_${COL}_a.ppm + pnmcut -top $(expr 10 + $TOP) -left $(expr 10 + $LEFT) -width 360 -height 168 ../HIRES/nocut/NEVSKY-1B-nf.ppm > tmp/cs_rect_1_${ROW}_${RCOL}_b.ppm + COL=$(expr $COL + 1) + RCOL=$(expr $RCOL - 1) + done + ROW=$(expr $ROW + 1) +done diff --git a/tools/build_counters2.sh b/tools/build_counters2.sh new file mode 100644 index 0000000..ad7bc5d --- /dev/null +++ b/tools/build_counters2.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +# set -x + +mkdir -p counters300 + +function marker { + pnmtopng tmp/${1}_a.ppm > counters300/$2.a.png + pnmtopng tmp/${1}_b.ppm > counters300/$2.b.png +} + +function marker2 { + pnmtopng tmp/${1}_a.ppm > counters300/$2.png + pnmtopng tmp/${1}_b.ppm > counters300/$3.png +} + +marker2 cs_circle_1_1_1 marker_battle marker_storm +marker2 cs_circle_1_1_2 marker_levy marker_campaign +marker2 cs_circle_1_1_3 marker_victory_teutonic marker_victory_half_teutonic +marker2 cs_circle_1_1_4 marker_victory_russian marker_victory_half_russian +marker2 cs_circle_1_1_5 marker_enemy_lords_removed_teutonic marker_pleskau_blue +marker2 cs_circle_1_1_6 marker_enemy_lords_removed_russian makrer_pleskau_gray + +marker2 cs_sq_small_1_1_2 marker_ravaged_teutonic marker_ravaged_russian + +marker cs_sq_small_1_1_1 unit_men_at_arms +marker cs_sq_small_3_1_1 unit_knights +marker cs_sq_small_3_1_3 unit_asiatic_horse +marker cs_sq_small_3_1_4 unit_militia +marker cs_sq_small_3_3_1 unit_light_horse +marker cs_sq_small_3_3_3 unit_serfs +marker cs_sq_small_3_5_1 unit_sergeants + +marker2 cs_sq_large_1_1_7 marker_conquered_teutonic marker_conquered_russian +marker2 cs_sq_large_1_4_11 marker_moved_fought marker_supply_source +marker2 cs_sq_large_2_1_1 marker_siege_teutonic marker_siege_russian +marker cs_sq_large_2_1_8 marker_walls + +marker2 cs_sq_large_2_1_10 marker_1_teutonic marker_1_russian +marker2 cs_sq_large_2_1_11 marker_2_teutonic marker_2_russian +marker2 cs_sq_large_2_1_12 marker_3_teutonic marker_3_russian +marker2 cs_sq_large_2_2_10 marker_4_teutonic marker_4_russian +marker2 cs_sq_large_2_2_11 marker_5_teutonic marker_5_russian +marker2 cs_sq_large_2_2_12 marker_6_teutonic marker_6_russian + +marker2 cs_sq_large_1_1_2 asset_coin_x1 asset_coin_x2 +marker2 cs_sq_large_1_3_1 asset_coin_x3 asset_coin_x4 + +marker2 cs_sq_large_1_3_3 asset_loot_x1 asset_loot_x2 +marker2 cs_sq_large_1_4_6 asset_loot_x3 asset_loot_x4 + +marker2 cs_sq_large_1_5_1 asset_prov_x1 asset_prov_x2 +marker2 cs_sq_large_3_4_10 asset_prov_x3 asset_prov_x4 + +marker2 cs_sq_large_3_1_1 asset_boat_x1 asset_ship_x1 +marker2 cs_sq_large_3_4_1 asset_boat_x2 asset_ship_x2 +marker2 cs_sq_large_3_4_2 asset_boat_x4 asset_ship_x4 + +marker2 cs_sq_large_3_1_7 asset_sled_x1 asset_cart_x1 +marker2 cs_sq_large_3_4_4 asset_sled_x2 asset_cart_x2 +marker2 cs_sq_large_3_5_6 asset_sled_x4 asset_cart_x4 + +marker cs_rect_1_1_1 marker_sea_trade_blocked + +marker cs_rect_2_1_1 lord_russian_aleksandr +marker cs_rect_2_1_2 lord_russian_andrey +marker cs_rect_2_1_3 vassal_russian_gavrilo_pskov +marker cs_rect_2_1_4 vassal_russian_andrey_vladimir +marker cs_rect_2_1_5 vassal_russian_domash_novgorod +marker cs_rect_2_1_6 vassal_russian_andrey_kipchaqs +marker cs_rect_2_1_7 vassal_teutonic_knud_and_abel_dietrich_von_kivel + +marker cs_rect_2_2_1 lord_russian_vladislav +marker cs_rect_2_2_2 lord_russian_karelians +marker cs_rect_2_2_3 vassal_russian_aleksandr_pereyaslavl +marker cs_rect_2_2_4 vassal_russian_andrey_suzdal +marker cs_rect_2_2_5 lord_teutonic_andreas +marker cs_rect_2_2_6 vassal_teutonic_andreas_summer_crusaders +marker cs_rect_2_2_7 vassal_teutonic_knud_and_abel_otto_von_luneburg + +marker cs_rect_2_3_1 lord_russian_domash +marker cs_rect_2_3_2 vassal_russian_vladislav_vepsian_auxiliaries +marker cs_rect_2_3_3 vassal_russian_aleksandr_rostov +marker cs_rect_2_3_4 vassal_teutonic_hermann_ugaunian_auxiliaries +marker cs_rect_2_3_5 lord_teutonic_hermann +marker cs_rect_2_3_6 lord_teutonic_knud_and_abel +marker cs_rect_2_3_7 vassal_teutonic_knud_and_abel_estonian_auxiliaries + +marker cs_rect_2_4_1 lord_russian_gavrilo +marker cs_rect_2_4_2 vassal_russian_vladislav_ingrian_auxiliaries +marker cs_rect_2_4_3 vassal_russian_aleksandr_yaroslavl +marker cs_rect_2_4_4 vassal_teutonic_hermann_helmond_von_luneburg +marker cs_rect_2_4_5 lord_teutonic_heinrich +marker cs_rect_2_4_6 lord_teutonic_yaroslav +marker2 cs_rect_2_4_7 marker_castle_teutonic marker_castle_russian + +marker cs_rect_2_5_1 vassal_russian_vladislav_vodian_auxiliaries +marker cs_rect_2_5_2 vassal_russian_vladislav_izhoran_auxiliaries +marker cs_rect_2_5_3 vassal_russian_aleksandr_mongols +marker cs_rect_2_5_4 vassal_teutonic_hermann_johannes_von_dolen +marker cs_rect_2_5_5 lord_teutonic_rudolf +marker cs_rect_2_5_6 vassal_teutonic_rudolf_summer_crusaders +#marker2 cs_rect_2_5_7 marker_castle_teutonic marker_castle_russian + +marker cs_rect_2_6_1 vassal_russian_gavrilo_borderland_russians +marker cs_rect_2_6_2 vassal_russian_domash_novgorod +#marker cs_rect_2_6_3 vassal_russian_aleksandr_mongols +marker cs_rect_2_6_4 vassal_teutonic_heinrich_odward_von_lode +marker cs_rect_2_6_5 vassal_teutonic_andreas_teutonic_vassals +marker cs_rect_2_6_6 vassal_teutonic_rudolf_ex_sword_brethren +marker cs_rect_2_6_7 vassal_teutonic_yaroslav_mstislavich_partisans + +marker cs_rect_2_7_1 vassal_russian_gavrilo_pskov_militia +marker cs_rect_2_7_2 vassal_russian_domash_novgorod +#marker cs_rect_2_7_3 vassal_russian_andrey_kipchaqs +marker cs_rect_2_7_4 vassal_teutonic_heinrich_heinrich_von_lode +marker cs_rect_2_7_5 vassal_teutonic_andreas_lettgallian_auxiliaries +marker cs_rect_2_7_6 vassal_teutonic_rudolf_jerwen_teutonic_vassals +marker2 cs_rect_2_7_7 marker_pursuit_teutonic marker_pursuit_russian diff --git a/tools/build_counters3.sh b/tools/build_counters3.sh new file mode 100644 index 0000000..142d802 --- /dev/null +++ b/tools/build_counters3.sh @@ -0,0 +1,5 @@ +mkdir -p service300 +montage -mode concatenate -tile 2x counters300/lord_teutonic_andreas.a.png counters300/lord_teutonic_andreas.b.png counters300/lord_teutonic_heinrich.a.png counters300/lord_teutonic_heinrich.b.png counters300/lord_teutonic_hermann.a.png counters300/lord_teutonic_hermann.b.png counters300/lord_teutonic_knud_and_abel.a.png counters300/lord_teutonic_knud_and_abel.b.png counters300/lord_teutonic_rudolf.a.png counters300/lord_teutonic_rudolf.b.png counters300/lord_teutonic_yaroslav.a.png counters300/lord_teutonic_yaroslav.b.png service300/service_lords_teutonic.png +montage -mode concatenate -tile 2x counters300/vassal_teutonic_andreas_lettgallian_auxiliaries.a.png counters300/vassal_teutonic_andreas_lettgallian_auxiliaries.b.png counters300/vassal_teutonic_andreas_summer_crusaders.a.png counters300/vassal_teutonic_andreas_summer_crusaders.b.png counters300/vassal_teutonic_andreas_teutonic_vassals.a.png counters300/vassal_teutonic_andreas_teutonic_vassals.b.png counters300/vassal_teutonic_heinrich_heinrich_von_lode.a.png counters300/vassal_teutonic_heinrich_heinrich_von_lode.b.png counters300/vassal_teutonic_heinrich_odward_von_lode.a.png counters300/vassal_teutonic_heinrich_odward_von_lode.b.png counters300/vassal_teutonic_hermann_helmond_von_luneburg.a.png counters300/vassal_teutonic_hermann_helmond_von_luneburg.b.png counters300/vassal_teutonic_hermann_johannes_von_dolen.a.png counters300/vassal_teutonic_hermann_johannes_von_dolen.b.png counters300/vassal_teutonic_hermann_ugaunian_auxiliaries.a.png counters300/vassal_teutonic_hermann_ugaunian_auxiliaries.b.png counters300/vassal_teutonic_knud_and_abel_dietrich_von_kivel.a.png counters300/vassal_teutonic_knud_and_abel_dietrich_von_kivel.b.png counters300/vassal_teutonic_knud_and_abel_estonian_auxiliaries.a.png counters300/vassal_teutonic_knud_and_abel_estonian_auxiliaries.b.png counters300/vassal_teutonic_knud_and_abel_otto_von_luneburg.a.png counters300/vassal_teutonic_knud_and_abel_otto_von_luneburg.b.png counters300/vassal_teutonic_rudolf_ex_sword_brethren.a.png counters300/vassal_teutonic_rudolf_ex_sword_brethren.b.png counters300/vassal_teutonic_rudolf_jerwen_teutonic_vassals.a.png counters300/vassal_teutonic_rudolf_jerwen_teutonic_vassals.b.png counters300/vassal_teutonic_rudolf_summer_crusaders.a.png counters300/vassal_teutonic_rudolf_summer_crusaders.b.png counters300/vassal_teutonic_yaroslav_mstislavich_partisans.a.png counters300/vassal_teutonic_yaroslav_mstislavich_partisans.b.png service300/service_vassals_teutonic.png +montage -mode concatenate -tile 2x counters300/lord_russian_aleksandr.a.png counters300/lord_russian_aleksandr.b.png counters300/lord_russian_andrey.a.png counters300/lord_russian_andrey.b.png counters300/lord_russian_domash.a.png counters300/lord_russian_domash.b.png counters300/lord_russian_gavrilo.a.png counters300/lord_russian_gavrilo.b.png counters300/lord_russian_karelians.a.png counters300/lord_russian_karelians.b.png counters300/lord_russian_vladislav.a.png counters300/lord_russian_vladislav.b.png service300/service_lords_russian.png +montage -mode concatenate -tile 2x counters300/vassal_russian_aleksandr_mongols.a.png counters300/vassal_russian_aleksandr_mongols.b.png counters300/vassal_russian_aleksandr_pereyaslavl.a.png counters300/vassal_russian_aleksandr_pereyaslavl.b.png counters300/vassal_russian_aleksandr_rostov.a.png counters300/vassal_russian_aleksandr_rostov.b.png counters300/vassal_russian_aleksandr_yaroslavl.a.png counters300/vassal_russian_aleksandr_yaroslavl.b.png counters300/vassal_russian_andrey_kipchaqs.a.png counters300/vassal_russian_andrey_kipchaqs.b.png counters300/vassal_russian_andrey_suzdal.a.png counters300/vassal_russian_andrey_suzdal.b.png counters300/vassal_russian_andrey_vladimir.a.png counters300/vassal_russian_andrey_vladimir.b.png counters300/vassal_russian_domash_novgorod.a.png counters300/vassal_russian_domash_novgorod.b.png counters300/vassal_russian_gavrilo_borderland_russians.a.png counters300/vassal_russian_gavrilo_borderland_russians.b.png counters300/vassal_russian_gavrilo_pskov_militia.a.png counters300/vassal_russian_gavrilo_pskov_militia.b.png counters300/vassal_russian_gavrilo_pskov.a.png counters300/vassal_russian_gavrilo_pskov.b.png counters300/vassal_russian_vladislav_izhoran_auxiliaries.a.png counters300/vassal_russian_vladislav_izhoran_auxiliaries.b.png counters300/vassal_russian_vladislav_ingrian_auxiliaries.a.png counters300/vassal_russian_vladislav_ingrian_auxiliaries.b.png counters300/vassal_russian_vladislav_vepsian_auxiliaries.a.png counters300/vassal_russian_vladislav_vepsian_auxiliaries.b.png counters300/vassal_russian_vladislav_vodian_auxiliaries.a.png counters300/vassal_russian_vladislav_vodian_auxiliaries.b.png service300/service_vassals_russian.png diff --git a/tools/build_map.sh b/tools/build_map.sh new file mode 100644 index 0000000..1af18c4 --- /dev/null +++ b/tools/build_map.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -x + +mutool extract -r "../HIRES/Nevsky - Game Board_CORRECTED 080919.pdf" +mv image-0017.png map300_uncropped.png + +# ArtBox 63.5197 63.5197 1287.52 1647.52 +# 5100x6600 +convert map300_uncropped.png -gravity Center -crop 5100x6600+0+0 +repage map300.png +rm map300_uncropped.png + +# convert map300.png -colorspace RGB -resize 33.3333333% -colorspace sRGB map100.png +# convert map300.png -colorspace RGB -resize 66.6666667% -colorspace sRGB map200.png +convert map300.png -colorspace RGB -resize 25% -colorspace sRGB map75.png +convert map300.png -colorspace RGB -resize 50% -colorspace sRGB map150.png diff --git a/tools/build_mats.sh b/tools/build_mats.sh new file mode 100644 index 0000000..a9e348b --- /dev/null +++ b/tools/build_mats.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -x + +mkdir -p tmp/mat +mkdir -p output300 + +if [ ! -f ../HIRES/raw_mat_01.1200.png ] +then + gs -sDEVICE=png16m -r1200 -o ../HIRES/raw_mat_%02d.1200.png "../HIRES/Lord Mats-FINAL-nf.pdf" +fi + +for F in ../HIRES/raw_mat_*.1200.png +do + convert -colorspace RGB -scale 25% -colorspace sRGB $F ${F/.1200.png/.png} +done + +# crop: 150,150 to 1650,1650 = 1500x1500 + +# ARGS="-gravity Center -crop 1500x1500+0+0 +repage -background #d0bf7d -flatten" +ARGS="-gravity Center -crop 1440x1440+0+0 +repage -background #d0bf7d -flatten" + +convert ../HIRES/raw_mat_01.png $ARGS output300/mat_russian_aleksandr.png +convert ../HIRES/raw_mat_02.png $ARGS output300/mat_russian_andrey.png +convert ../HIRES/raw_mat_03.png $ARGS output300/mat_russian_domash.png +convert ../HIRES/raw_mat_04.png $ARGS output300/mat_russian_gavrilo.png +convert ../HIRES/raw_mat_05.png $ARGS output300/mat_russian_vladislav.png +convert ../HIRES/raw_mat_06.png $ARGS output300/mat_russian_karelians.png +convert ../HIRES/raw_mat_07.png $ARGS output300/mat_teutonic_yaroslav.png +convert ../HIRES/raw_mat_08.png $ARGS output300/mat_teutonic_knud_and_abel.png +convert ../HIRES/raw_mat_09.png $ARGS output300/mat_teutonic_rudolf.png +convert ../HIRES/raw_mat_10.png $ARGS output300/mat_teutonic_heinrich.png +convert ../HIRES/raw_mat_11.png $ARGS output300/mat_teutonic_hermann.png +convert ../HIRES/raw_mat_12.png $ARGS output300/mat_teutonic_andreas.png +convert ../HIRES/raw_mat_13.png $ARGS output300/mat_battle.png diff --git a/tools/build_screen.sh b/tools/build_screen.sh new file mode 100644 index 0000000..607ca7b --- /dev/null +++ b/tools/build_screen.sh @@ -0,0 +1,10 @@ +mkdir -p tmp +convert -size 2160x750 gradient:white-none tmp/gradient.png +convert -resize 2250x750 -gravity Center -crop 2160x750+0+0 +repage ../HIRES/screen1.png tmp/screen1.png +convert -resize 2250x750 -gravity Center -crop 2160x750+0+0 +repage ../HIRES/screen2.png tmp/screen2.png +convert -resize 2250x750 -gravity Center -crop 2160x750+0+0 +repage ../HIRES/screen3.png tmp/screen3.png +convert -resize 2250x750 -gravity Center -crop 2160x750+0+0 +repage ../HIRES/screen4.png tmp/screen4.png +convert tmp/screen1.png gradient.png -compose Over -flatten screen1.png +convert tmp/screen2.png gradient.png -compose Over -flatten screen2.png +convert tmp/screen3.png gradient.png -compose Over -flatten screen3.png +convert tmp/screen4.png gradient.png -compose Over -flatten screen4.png diff --git a/tools/build_stickers.sh b/tools/build_stickers.sh new file mode 100644 index 0000000..3e49e69 --- /dev/null +++ b/tools/build_stickers.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +set -x + +#gs -sDEVICE=png16m -r1200 -o tmp/stickers1200.png ../HIRES/stickers3.pdf + +mkdir -p tmp + +# 672x672 stickers @1200 +#pngtopnm tmp/stickers1200.png > tmp/stickers1200.ppm +pnmcut -top 1912 -height 672 tmp/stickers1200.ppm > tmp/row1x.ppm +pnmcut -top 2856 -height 672 tmp/stickers1200.ppm > tmp/row2x.ppm + +I=1 +for LEFT in 405 641 877 1113 1349 1586 1822 +do + pnmcut -left $(expr 4 '*' $LEFT) -width 672 tmp/row1x.ppm | pnmtopng > tmp/lord_teutonic_$I.png + pnmcut -left $(expr 4 '*' $LEFT) -width 672 tmp/row2x.ppm | pnmtopng > tmp/lord_russian_$I.png + I=$(expr $I + 1) +done + +# 150dpi -> 84x84 +# 75dpi -> 42x42 +# 3d -> 42x28 +for I in 1 2 3 4 5 6 7 +do + convert tmp/lord_teutonic_$I.png -colorspace RGB -geometry 84x56! -colorspace sRGB output150/lord_teutonic_${I}_3d.png + convert tmp/lord_russian_$I.png -colorspace RGB -geometry 84x56! -colorspace sRGB output150/lord_russian_${I}_3d.png + convert tmp/lord_teutonic_$I.png -colorspace RGB -geometry 84x84! -colorspace sRGB output150/lord_teutonic_${I}.png + convert tmp/lord_russian_$I.png -colorspace RGB -geometry 84x84! -colorspace sRGB output150/lord_russian_${I}.png + + convert tmp/lord_teutonic_$I.png -colorspace RGB -geometry 42x28! -colorspace sRGB output75/lord_teutonic_${I}_3d.png + convert tmp/lord_russian_$I.png -colorspace RGB -geometry 42x28! -colorspace sRGB output75/lord_russian_${I}_3d.png + convert tmp/lord_teutonic_$I.png -colorspace RGB -geometry 42x42! -colorspace sRGB output75/lord_teutonic_${I}.png + convert tmp/lord_russian_$I.png -colorspace RGB -geometry 42x42! -colorspace sRGB output75/lord_russian_${I}.png +done + diff --git a/tools/colors.mjs b/tools/colors.mjs new file mode 100644 index 0000000..4af8545 --- /dev/null +++ b/tools/colors.mjs @@ -0,0 +1,108 @@ +import { formatHex, filterBrightness, parseHex, convertRgbToOklab, convertRgbToLrgb, interpolate } from 'culori' + +const yuv = true; +const gamma = 2.2; + +const data = [ +[".mat .background", "d1c07e"], +[".card.teutonic", "e1e6e8"], +[".card.russian", "e1d6c1"], +[".service_marker.teutonic.vassal", "777474"], +[".service_marker.russian.vassal", "f0ead8"], +[".asset.sled", "e5dcc1"], +[".asset.boat", "adceed"], +[".asset.cart.x1", "daba8b"], +[".asset.cart.x2", "d1a973"], +[".asset.cart.x4", "c4975b"], +[".asset.coin.x1", "d2d5d4"], +[".asset.coin.x2", "d2d5d4"], +[".asset.coin.x3", "b3b5b4"], +[".asset.coin.x4", "b3b5b4"], +[".asset.prov.x1", "ffe293"], +[".asset.prov.x2", "ffe293"], +[".asset.prov.x3", "ffcd66"], +[".asset.prov.x4", "ffcd66"], +[".asset.ship.x1", "79b7e4"], +[".asset.ship.x2", "79b7e4"], +[".asset.ship.x4", "5da9dd"], +[".asset.loot.x1", "f0b64f"], +[".asset.loot.x2", "eda44c"], +[".asset.loot.x3", "eb924a"], +[".asset.loot.x4", "e1884a"], +[".marker.battle", "d0bf7d"], +[".marker.storm", "d0bf7d"], +[".marker.pursuit", "c6ab7f"], +[".marker.turn.campaign", "6a8aa8"], +[".marker.turn.levy", "967348"], +[".marker.teutonic.victory", "ffd400"], +[".marker.teutonic.siege", "a39382"], +[".marker.russian.conquered", "649655"], +[".marker.russian.enemy_lords_removed", "ffd400"], +[".marker.russian.victory", "2d8b47"], +[".marker.walls", "e3dedc"], +[".marker.russian.number", "c6992f"], +[".marker.teutonic.number", "a02532"], + +/* +[".unit", "ffd768"], +[".marker.supply_source", "e6dcb9"], +[".marker.moved_fought", "0072bc"], +[".marker.pleskau_black", "324b5b"], +[".marker.pleskau_white", "e3dedc"], +*/ +].map(([sel,color])=>[ sel, parseHex(color) ]) + +const colors = `knights_fill ffffff +knights_stroke d1d3d4 +asiatic_horse_fill f7df93 +asiatic_horse_stroke 908357 +serfs_fill e39c43 +serfs_stroke b17b33 +militia_fill cc6a2c +militia_stroke 773b0c +men_at_arms_fill c0b6b3 +men_at_arms_stroke 716c6b +die_1 662c91 +die_2 ee161c +die_3 f7941d +die_4 ffd400 +die_5 26903a` + +let css = [] + +function brighten(color, n) { + return { mode: 'lrgb', + r: 1 - (1-color.r) * n, + g: 1 - (1-color.g) * n, + b: 1 - (1-color.b) * n, + } +} + +function darken(color, n) { + return { mode: 'lrgb', + r: (color.r) * n, + g: (color.g) * n, + b: (color.b) * n, + } +} + +let white = parseHex('#fff') +let black = parseHex('#000') + +for (let [ sel, rgb ] of data) { + let base = formatHex(rgb) + //let hi = formatHex(brighten(convertRgbToLrgb(rgb), 0.8)) + //let lo = formatHex(darken(convertRgbToLrgb(rgb), 0.8)) + //let sh = formatHex(darken(convertRgbToLrgb(rgb), 0.125)) + //let hi = formatHex(interpolate([rgb,white],'lrgb')(0.2)) + //let lo = formatHex(interpolate([rgb,black],'lrgb')(0.2)) + //let sh = formatHex(interpolate([rgb,black],'lrgb')(0.6)) + let hic = convertRgbToOklab(rgb); hic.l = Math.min(1,hic.l+0.1) + let loc = convertRgbToOklab(rgb); loc.l = Math.max(0,loc.l-0.1) + let shc = convertRgbToOklab(rgb); shc.l = Math.max(0,shc.l-0.4) + let sh = formatHex(shc) + let hi = formatHex(hic) + let lo = formatHex(loc) + css.push(`${sel} { background-color: ${base}; border-color: ${hi} ${lo} ${lo} ${hi}; box-shadow: 0 0 0 1px ${sh}, 1px 2px 4px #0008; }`) +} +console.log(css.join("\n")) diff --git a/tools/genboxes.py b/tools/genboxes.py new file mode 100644 index 0000000..92488ed --- /dev/null +++ b/tools/genboxes.py @@ -0,0 +1,65 @@ +mode = None + +list = [] + +x = y = w = h = 0 +name = None + +def flush(): + global x, y, w, h, name + if mode == 'rect': + list.append((x,y,w,h,'box',name)) + if mode == 'circle': + x = cx - rx + y = cy - ry + w = rx * 2 + h = ry * 2 + list.append((x,y,w,h,'circle',name)) + x = y = w = h = 0 + name = None + +for line in open("boxes.svg").readlines(): + line = line.strip() + if line == "<rect": + flush() + mode = 'rect' + x = y = w = h = 0 + elif line == "<ellipse": + flush() + mode = 'circle' + cx = cy = rx = ry = 0 + if line.startswith('x="'): x = round(float(line.split('"')[1])) + if line.startswith('y="'): y = round(float(line.split('"')[1])) + if line.startswith('width="'): w = round(float(line.split('"')[1])) + if line.startswith('height="'): h = round(float(line.split('"')[1])) + if line.startswith('cx="'): cx = round(float(line.split('"')[1])) + if line.startswith('cy="'): cy = round(float(line.split('"')[1])) + if line.startswith('rx="'): rx = round(float(line.split('"')[1])) + if line.startswith('ry="'): ry = round(float(line.split('"')[1])) + if line.startswith('inkscape:label="'): name = line.split('"')[1] +flush() + +def print_list(): + print("const boxes = {") + for (x,y,w,h,c,name) in list: + print(f'"{name}": [{x},{y},{w},{h}],') + print("}") + +def print_html(): + print('<html><style>') + print('.box{position:absolute;background-color:#f008;border:2px solid blue;}') + print('.circle{position:absolute;background-color:#0f08;border-radius:50%;border:2px solid blue;}') + print('img{position:absolute;display:block}') + print('</style>') + print('<div style="position:relative;width:1275px;heigth:1650px;">') + print('<img src="map75.png">') + for (x,y,w,h,c,name) in list: + x = round(x/4) - 1 + y = round(y/4) - 1 + w = round(w/4) + 2 + h = round(h/4) + 2 + print(f'<div class="{c}" style="top:{y}px;left:{x}px;width:{w-4}px;height:{h-4}px">{name}</div>') + print('</div>') + +#print_html() +print_list() diff --git a/tools/gencss.js b/tools/gencss.js new file mode 100644 index 0000000..4edc4be --- /dev/null +++ b/tools/gencss.js @@ -0,0 +1,5 @@ +const h = 42 +for (let i = 0; i < 15; ++i) + console.log(`.service_marker.image${i}{background-position:0 -${i*h}px}`) +for (let i = 0; i < 15; ++i) + console.log(`.service_marker.image${i}:hover{background-position:100% -${i*h}px}`) diff --git a/tools/gencyl.js b/tools/gencyl.js new file mode 100644 index 0000000..bae34b9 --- /dev/null +++ b/tools/gencyl.js @@ -0,0 +1,51 @@ +// physical cylinders are diameter 15mm x 10mm +// at 75dpi => 44px x 29px +// stickers: 42x28 +// image: 44x? - outline at 1 to 2 - start at 1.5 + +const fs = require('fs') + +function print_lord(output, side, label) { + let image = fs.readFileSync(label).toString('base64') + let svg = [] + let bd = '#222' + let f = 'url(#g)' + svg.push('<svg xmlns="http://www.w3.org/2000/svg" width="44" height="48">') + svg.push('<clipPath id="c"><ellipse cx="22" cy="15" rx="20.5" ry="13.5"/></clipPath>') + + if (1) { + svg.push('<linearGradient id="g">') + if (side === 'russian') { + svg.push('<stop offset="0%" stop-color="#ddd"/>') + svg.push('<stop offset="40%" stop-color="#fff"/>') + svg.push('<stop offset="100%" stop-color="#ccc"/>') + bd = '#555' + } else { + svg.push('<stop offset="0%" stop-color="#444"/>') + svg.push('<stop offset="40%" stop-color="#666"/>') + svg.push('<stop offset="100%" stop-color="#333"/>') + bd = '#111' + } + svg.push('</linearGradient>') + } else { + if (side === 'russian') { + f = '#ddd' + bd = '#222' + } else { + f = '#555' + bd = '#222' + } + } + + svg.push(`<path fill="${f}" stroke="${bd}" d="M1.5 15v18A20.5 13.5 0 0 0 22 46.5 20.5 13.5 0 0 0 42.5 33V15h-41z"/>`) + svg.push(`<image href="data:image/png;base64,${image}" clip-path="url(#c)" x="1" y="1" width="42" height="28"/>`) + svg.push(`<ellipse fill="none" stroke="${bd}" cx="22" cy="15" rx="20.5" ry="13.5"/>`) + + svg.push('</svg>') + fs.writeFileSync(output, svg.join("\n") + "\n") +} + +for (let i = 1; i <= 7; ++i) { + print_lord(`images/lord_teutonic_${i}.svg`, "teutonic", `tools/output150/lord_teutonic_${i}_3d.png`) + print_lord(`images/lord_russian_${i}.svg`, "russian", `tools/output150/lord_russian_${i}_3d.png`) +} diff --git a/tools/gendata.js b/tools/gendata.js new file mode 100644 index 0000000..2968023 --- /dev/null +++ b/tools/gendata.js @@ -0,0 +1,705 @@ +// Run this script inside the "tools" directory to generate data.js and build_counters3.sh + +"use strict" + +const fs = require('fs') + +// :r !python3 genboxes.py +const boxes = { +"Wesenberg": [1448,3625,304,60], +"Fellin": [1013,4583,184,61], +"Odenpäh": [1378,5103,250,61], +"Adsel": [1504,5612,185,60], +"Wenden": [909,5759,232,60], +"Luga": [2667,3295,148,62], +"Kaibolovo": [2904,3522,285,62], +"Koporye": [3133,3160,241,62], +"Neva": [3924,2934,148,62], +"Volkhov": [4591,3783,231,63], +"Lovat": [4243,5581,187,63], +"Porkhov": [3515,5467,241,63], +"Izborsk": [2240,5431,241,62], +"Velikiye Luki": [3706,6347,351,61], +"Tesovo": [3936,4102,121,32], +"Zheltsy": [3501,4176,128,30], +"Sablia": [3788,4541,104,31], +"Gdov": [2427,4149,88,30], +"Dubrovno": [3153,5214,161,31], +"Ostrov": [2746,5717,115,30], +"Rositten": [2046,6307,146,30], +"Kirrumpäh": [1877,5389,175,30], +"Pernau": [517,4580,118,30], +"Narwia": [2371,3549,123,31], +"Wierland": [1999,3680,200,100], +"Warbola": [292,3797,142,31], +"Waiga": [1535,4113,200,100], +"Jerwen": [1064,3946,200,100], +"Harrien": [567,3983,200,100], +"Sackala": [617,4769,200,100], +"Metsepole": [509,5226,200,100], +"Lettgallia": [2048,5777,200,100], +"Tolowa": [1541,5933,200,100], +"Ugaunia": [1957,4940,200,100], +"Revala": [1030,3410,200,100], +"Velikaya River": [3029,6090,200,100], +"Sorot River": [3299,5781,200,100], +"Shelon River": [3654,4864,200,100], +"Zhelcha River": [2782,4586,200,100], +"Plyussa River": [2829,4234,200,100], +"Ingria": [3820,3639,200,100], +"Vod": [3488,3345,200,100], +"Izhora": [4074,3323,200,100], +"Karelia": [3833,2408,200,100], +"Ladoga": [4619,2817,238,90], +"Novgorod": [4318,4315,333,112], +"Rusa": [4329,5166,205,92], +"Riga": [273,6231,205,91], +"Pskov": [2680,5263,205,91], +"Dorpat": [1625,4589,253,91], +"Leal": [108,4266,205,91], +"Reval": [601,3564,206,91], +"box1": [40,168,592,917], +"box2": [650,168,591,913], +"box3": [1313,167,591,916], +"box4": [1922,167,590,916], +"box5": [2587,167,592,918], +"box6": [3196,167,588,916], +"box7": [3859,167,594,916], +"box8": [4469,166,591,918], +"box9": [39,1119,594,915], +"Victory": [172,183,217,215], +"Turn": [399,184,216,214], +"Novgorod Veche": [4193,5847,844,628], +"Uzmen": [2112,4692,200,100], +"way-crossroads": [1500,4717,462,149], +"way-wirz": [1295,4526,175,350], +"way-peipus-east": [2232,4197,220,465], +"way-peipus-north": [2065,3836,361,228], +"way-peipus-west": [1988,4141,218,520], +} + +let data = [] +function print(str) { + data.push(str) +} + +var locmap = {} + +// 0=offmap, 1-N=map locales, 100-M=calendar boxes +var locales = [null] +var ways = [] +var waterways = [] +var trackways = [] + +const scale = 1 + +function defloc(region, stronghold, type, name) { + let [x, y, w, h] = boxes[name] + x = Math.round(x * scale) + y = Math.round(y * scale) + w = Math.round(w * scale) + h = Math.round(h * scale) + locmap[name] = locales.length + locales.push({ name, type, stronghold, region, ways: [], box: { x, y, w, h } }) +} + +function defway(type, list) { + let ix = ways.length + list = list.map(name=>locmap[name]).sort((a,b)=>a-b) + ways.push({type, locales: list}) + for (let from of list) { + for (let to of list) { + if (from !== to) { + let old = locales[from].ways.find(w => w[0] === to) + if (old) + old.push(ix) + else + locales[from].ways.push([to, ix]) + } + } + } + return ways[ix] +} + +function waterway(locs) { return defway('waterway', locs.split(", ")) } +function trackway(locs) { return defway('trackway', locs.split(", ")) } + +defloc("Danish Estonia", 3, "bishopric", "Reval") +defloc("Danish Estonia", 2, "castle", "Wesenberg") +defloc("Danish Estonia", 0, "town", "Narwia") +defloc("Danish Estonia", 0, "town", "Warbola") +defloc("Danish Estonia", 0, "region", "Harrien") +defloc("Danish Estonia", 0, "region", "Revala") +defloc("Danish Estonia", 0, "region", "Wierland") + +defloc("Crusader Livonia", 3, "bishopric", "Dorpat") +defloc("Crusader Livonia", 3, "bishopric", "Leal") +defloc("Crusader Livonia", 3, "bishopric", "Riga") +defloc("Crusader Livonia", 2, "castle", "Adsel") +defloc("Crusader Livonia", 2, "castle", "Fellin") +defloc("Crusader Livonia", 2, "castle", "Odenpäh") +defloc("Crusader Livonia", 2, "castle", "Wenden") +defloc("Crusader Livonia", 0, "town", "Kirrumpäh") +defloc("Crusader Livonia", 0, "town", "Pernau") +defloc("Crusader Livonia", 0, "town", "Rositten") +defloc("Crusader Livonia", 0, "region", "Jerwen") +defloc("Crusader Livonia", 0, "region", "Lettgallia") +defloc("Crusader Livonia", 0, "region", "Metsepole") +defloc("Crusader Livonia", 0, "region", "Sackala") +defloc("Crusader Livonia", 0, "region", "Tolowa") +defloc("Crusader Livonia", 0, "region", "Ugaunia") +defloc("Crusader Livonia", 0, "region", "Waiga") + +defloc("Novgorodan Rus", 3, "archbishopric", "Novgorod") +defloc("Novgorodan Rus", 3, "city", "Ladoga") +defloc("Novgorodan Rus", 3, "city", "Pskov") +defloc("Novgorodan Rus", 3, "city", "Rusa") +defloc("Novgorodan Rus", 0, "traderoute", "Lovat") +defloc("Novgorodan Rus", 0, "traderoute", "Luga") +defloc("Novgorodan Rus", 0, "traderoute", "Neva") +defloc("Novgorodan Rus", 0, "traderoute", "Volkhov") +defloc("Novgorodan Rus", 1, "fort", "Izborsk") +defloc("Novgorodan Rus", 1, "fort", "Kaibolovo") +defloc("Novgorodan Rus", 1, "fort", "Koporye") +defloc("Novgorodan Rus", 1, "fort", "Porkhov") +defloc("Novgorodan Rus", 1, "fort", "Velikiye Luki") +defloc("Novgorodan Rus", 0, "town", "Dubrovno") +defloc("Novgorodan Rus", 0, "town", "Gdov") +defloc("Novgorodan Rus", 0, "town", "Ostrov") +defloc("Novgorodan Rus", 0, "town", "Sablia") +defloc("Novgorodan Rus", 0, "town", "Tesovo") +defloc("Novgorodan Rus", 0, "town", "Zheltsy") +defloc("Novgorodan Rus", 0, "region", "Ingria") +defloc("Novgorodan Rus", 0, "region", "Izhora") +defloc("Novgorodan Rus", 0, "region", "Karelia") +defloc("Novgorodan Rus", 0, "region", "Plyussa River") +defloc("Novgorodan Rus", 0, "region", "Shelon River") +defloc("Novgorodan Rus", 0, "region", "Sorot River") +defloc("Novgorodan Rus", 0, "region", "Uzmen") +defloc("Novgorodan Rus", 0, "region", "Velikaya River") +defloc("Novgorodan Rus", 0, "region", "Vod") +defloc("Novgorodan Rus", 0, "region", "Zhelcha River") + +waterway("Dorpat, Narwia, Gdov, Uzmen").name = "Pleipat W" +waterway("Gdov, Uzmen").name = "Pleipat E" +waterway("Fellin, Dorpat, Odenpäh").name = "Wirz" +trackway("Dorpat, Odenpäh, Ugaunia").name = "Crossroads" + +waterway("Uzmen, Pskov") +waterway("Uzmen, Zhelcha River") +waterway("Novgorod, Shelon River, Rusa") +waterway("Pernau, Fellin, Jerwen") +waterway("Riga, Wenden") +waterway("Wenden, Adsel") +waterway("Pskov, Ostrov") +waterway("Ostrov, Velikaya River") +waterway("Sorot River, Velikaya River") +waterway("Rusa, Lovat") +waterway("Lovat, Velikiye Luki") +waterway("Shelon River, Dubrovno") +waterway("Shelon River, Porkhov") +waterway("Narwia, Plyussa River") +waterway("Luga, Kaibolovo") +waterway("Kaibolovo, Zheltsy") +waterway("Zheltsy, Sablia") +waterway("Zheltsy, Tesovo") +waterway("Ladoga, Volkhov") +waterway("Volkhov, Novgorod") +waterway("Neva, Ladoga") + +trackway("Reval, Revala") +trackway("Revala, Wesenberg") +trackway("Wierland, Narwia") +trackway("Narwia, Kaibolovo") +trackway("Wierland, Waiga") +trackway("Wesenberg, Jerwen") +trackway("Reval, Warbola") +trackway("Warbola, Harrien") +trackway("Harrien, Jerwen") +trackway("Warbola, Leal") + +trackway("Waiga, Dorpat") +trackway("Leal, Pernau") +trackway("Fellin, Sackala") +trackway("Sackala, Metsepole") +trackway("Metsepole, Wenden") +trackway("Wenden, Tolowa") +trackway("Tolowa, Rositten") +trackway("Lettgallia, Rositten") +trackway("Adsel, Tolowa, Lettgallia") +trackway("Adsel, Kirrumpäh") +trackway("Odenpäh, Kirrumpäh") +trackway("Kirrumpäh, Izborsk") +trackway("Ugaunia, Uzmen") +trackway("Ugaunia, Izborsk") +trackway("Lettgallia, Ostrov") +trackway("Lettgallia, Izborsk") + +trackway("Izborsk, Pskov") +trackway("Kaibolovo, Koporye") +trackway("Koporye, Vod") +trackway("Vod, Neva") +trackway("Vod, Ingria") +trackway("Karelia, Neva") +trackway("Neva, Izhora") +trackway("Izhora, Ladoga") +trackway("Izhora, Ingria") +trackway("Ingria, Tesovo") +trackway("Tesovo, Novgorod") +trackway("Novgorod, Sablia") +trackway("Sablia, Shelon River") + +trackway("Gdov, Plyussa River") +trackway("Plyussa River, Zheltsy") +trackway("Plyussa River, Zhelcha River") +trackway("Zhelcha River, Pskov") +trackway("Pskov, Dubrovno") +trackway("Dubrovno, Porkhov") +trackway("Porkhov, Sorot River") +trackway("Velikaya River, Velikiye Luki") + +let seaports = [ + "Riga", "Pernau", "Leal", "Reval", "Narwia", "Luga", "Koporye", "Neva" +].map(name => locmap[name]).sort((a,b)=>a-b) + +function dumplist(name, list) { + print(name + ":[") + for (let item of list) + print(JSON.stringify(item) + ",") + print("],") +} + +function seats(list) { + return list.split(", ").map(name => locmap[name]).sort((a,b)=>a-b) +} + +let lords = [ + + { + side: "Teutonic", + name: "Andreas", + full_name: "Andreas von Felben", + title: "Landmeister in Livonia", + seats: seats("Riga, Wenden"), + marshal: 2, + fealty: 2, + service: 4, + lordship: 3, + command: 3, + forces: { + knights: 1, + sergeants: 2, + light_horse: 0, + men_at_arms: 1, + militia: 0, + }, + assets: { + transport: 2, + prov: 2, + }, + ships: 1, + }, + + { + side: "Teutonic", + name: "Heinrich", + full_name: "Heinrich", + title: "Bishop of Ösel-Wiek", + seats: seats("Leal"), + marshal: 0, + fealty: 3, + service: 4, + lordship: 2, + command: 1, + forces: { + knights: 1, + sergeants: 1, + light_horse: 0, + men_at_arms: 1, + militia: 0, + }, + assets: { + ship: 1, + coin: 2, + prov: 1, + }, + ships: 1, + }, + + { + side: "Teutonic", + name: "Hermann", + full_name: "Hermann", + title: "Bishop of Dorpat", + seats: seats("Dorpat, Odenpäh"), + marshal: 1, + fealty: 4, + service: 4, + lordship: 3, + command: 3, + forces: { + knights: 1, + sergeants: 1, + light_horse: 0, + men_at_arms: 2, + militia: 0, + }, + assets: { + transport: 1, + coin: 1, + prov: 1, + }, + ships: 0, + }, + + { + side: "Teutonic", + name: "Knud & Abel", + full_name: "Knud & Abel", + title: "Princes of Denmark", + seats: seats("Reval, Wesenburg"), + marshal: 0, + fealty: 2, + service: 3, + lordship: 3, + command: 2, + forces: { + knights: 1, + sergeants: 1, + light_horse: 3, + men_at_arms: 0, + militia: 0, + }, + assets: { + ship: 2, + prov: 2, + }, + ships: 1, + }, + + { + side: "Teutonic", + name: "Rudolf", + full_name: "Rudolf von Kassel", + title: "Castellan of Wenden", + seats: seats("Wenden"), + marshal: 0, + fealty: 5, + service: 2, + lordship: 1, + command: 3, + forces: { + knights: 1, + sergeants: 1, + light_horse: 0, + men_at_arms: 1, + militia: 0, + }, + assets: { + transport: 1, + prov: 1, + }, + ships: 0, + }, + + { + side: "Teutonic", + name: "Yaroslav", + full_name: "Yaroslav", + title: "Exile of Pskov", + seats: seats("Odenpäh, Pskov"), + marshal: 0, + fealty: 4, + service: 2, + lordship: 1, + command: 2, + forces: { + knights: 1, + sergeants: 0, + light_horse: 1, + men_at_arms: 1, + militia: 0, + }, + assets: { + transport: 1, + prov: 1, + }, + ships: 0, + }, + + { + side: "Russian", + name: "Aleksandr", + full_name: "Aleksandr", + title: "Prince of Novgorod", + seats: seats("Novgorod, Rusa"), + marshal: 2, + fealty: 0, + service: 6, + lordship: 4, + command: 3, + forces: { + knights: 3, + sergeants: 0, + light_horse: 0, + men_at_arms: 2, + militia: 0, + }, + assets: { + transport: 2, + }, + ships: 1, + }, + + { + side: "Russian", + name: "Andrey", + full_name: "Andrey", + title: "Prince of Suzdal", + seats: seats("Novgorod, Rusa"), + marshal: 1, + fealty: 4, + service: 5, + lordship: 3, + command: 2, + forces: { + knights: 3, + sergeants: 0, + light_horse: 0, + men_at_arms: 2, + militia: 0, + }, + assets: { + transport: 2, + }, + ships: 1, + }, + + { + side: "Russian", + name: "Domash", + full_name: "Domash", + title: "Tysyatskiy of Novgorod", + seats: seats("Novgorod"), + marshal: 0, + fealty: 4, + service: 4, + lordship: 2, + command: 2, + forces: { + knights: 0, + sergeants: 1, + light_horse: 1, + men_at_arms: 2, + militia: 1, + }, + assets: { + transport: 4, + prov: 4, + }, + ships: 1, + }, + + { + side: "Russian", + name: "Gavrilo", + full_name: "Gavrilo", + title: "Voyevoda of Pskov", + seats: seats("Pskov"), + marshal: 0, + fealty: 3, + service: 4, + lordship: 3, + command: 2, + forces: { + knights: 1, + sergeants: 0, + light_horse: 1, + men_at_arms: 1, + militia: 1, + }, + assets: { + transport: 2, + coin: 1, + prov: 2, + }, + ships: 1, + }, + + { + side: "Russian", + name: "Karelians", + full_name: "Karelians", + title: "Tributaries of Novgorod", + seats: seats("Ladoga"), + marshal: 0, + fealty: 4, + service: 2, + lordship: 1, + command: 2, + forces: { + knights: 0, + sergeants: 0, + light_horse: 1, + men_at_arms: 0, + militia: 4, + }, + assets: { + transport: 1, + }, + ships: 1, + }, + + { + side: "Russian", + name: "Vladislav", + full_name: "Vladislav", + title: "Bailiff of Ladoga", + seats: seats("Ladoga"), + marshal: 0, + fealty: 5, + service: 3, + lordship: 2, + command: 3, + forces: { + knights: 0, + sergeants: 1, + light_horse: 1, + men_at_arms: 2, + militia: 0, + }, + assets: { + transport: 1, + prov: 1, + }, + ships: 1, + }, + +] + +let vassals = [] +for (let lord of lords) + lord.vassals = [] + +function vassal(lord, service, name, forces, capability) { + let lord_id = lords.findIndex(x => x.name === lord) + if (lord_id < 0) throw Error("no such lord", lord) + lords[lord_id].vassals.push(vassals.length) + vassals.push({ lord: lord_id, name, service, forces, capability }) +} + +vassal("Andreas", 1, "Lettgallian Auxiliaries", { light_horse: 1, militia: 1 }) +vassal("Andreas", 2, "Summer Crusaders", { knights: 3 }, "Crusade") +vassal("Andreas", 3, "Teutonic Vassals", { knights: 1, men_at_arms: 2 }) + +vassal("Heinrich", 2, "Heinrich von Lode", { knights: 1, men_at_arms: 1 }) +vassal("Heinrich", 2, "Odward von Lode", { knights: 1, men_at_arms: 1 }) + +vassal("Hermann", 2, "Helmond von Lüneburg", { knights: 1, men_at_arms: 1 }) +vassal("Hermann", 2, "Johannes von Dolen", { knights: 1, men_at_arms: 1 }) +vassal("Hermann", 1, "Ugaunian Auxiliaries", { light_horse: 1, militia: 1 }) + +vassal("Knud & Abel", 2, "Dietrich von Kivel", { knights: 1, men_at_arms: 1 }) +vassal("Knud & Abel", 1, "Estonian Auxiliaries", { light_horse: 1, militia: 1 }) +vassal("Knud & Abel", 2, "Otto von Lüneburg", { knights: 1, men_at_arms: 1 }) + +vassal("Rudolf", 2, "Ex-Sword Brethren", { knights: 1, sergeants: 1 }) +vassal("Rudolf", 2, "Jerwen Teutonic Vassals", { knights: 1, men_at_arms: 1 }) +vassal("Rudolf", 2, "Summer Crusaders", { knights: 2 }, "Crusade") + +vassal("Yaroslav", 1, "Mstislavich Partisans", { militia: 2 }) + +vassal("Aleksandr", 3, "Mongols", { asiatic_horse: 2 }, "Steppe Warriors") +vassal("Aleksandr", 3, "Mongols", { asiatic_horse: 2 }, "Steppe Warriors") +vassal("Aleksandr", 4, "Pereyaslavl", { men_at_arms: 1 }) +vassal("Aleksandr", 3, "Rostov", { men_at_arms: 1 }) +vassal("Aleksandr", 3, "Yaroslavl", { men_at_arms: 1 }) + +vassal("Andrey", 3, "Kipchaqs", { asiatic_horse: 3 }, "Steppe Warriors") +vassal("Andrey", 3, "Kipchaqs", { asiatic_horse: 3 }, "Steppe Warriors") +vassal("Andrey", 4, "Suzdal", { men_at_arms: 1 }) +vassal("Andrey", 4, "Vladimir", { men_at_arms: 1 }) + +vassal("Domash", 2, "Novgorod", { militia: 2 }) +vassal("Domash", 2, "Novgorod", { militia: 2 }) +vassal("Domash", 2, "Novgorod", { militia: 2 }) + +vassal("Gavrilo", 1, "Borderland Russians", { light_horse: 1, militia: 1 }) +vassal("Gavrilo", 2, "Pskov Militia", { militia: 2 }) +vassal("Gavrilo", 4, "Pskov", { men_at_arms: 1 }) + +vassal("Vladislav", 1, "Izhoran Auxiliaries", { militia: 1 }) +vassal("Vladislav", 1, "Ingrian Auxiliaries", { militia: 1 }) +vassal("Vladislav", 1, "Vepsian Auxiliaries", { militia: 1 }) +vassal("Vladislav", 1, "Vodian Auxiliaries", { militia: 1 }) + +function to_path(name) { + return name + .toLowerCase() + .replace(/&/g, 'and') + .replace(/[ -]/g, '_') + .replace(/ü/g, 'u') + .replace(/ö/g, 'o') + .replace(/ä/g, 'a') +} + +let lord_service = {Russian:[],Teutonic:[]} +let vassal_service = {Russian:[],Teutonic:[]} + +let last_path, last_side, last_ix + +last_path = null +last_side = null +lords.forEach((lord,id) => { + let side = lord.side + let path = "counters300/lord_" + side.toLowerCase() + "_" + to_path(lord.name) + if (side !== last_side) { + last_ix = 0 + last_side = side + } + lord.image = last_ix + if (path !== last_path) { + last_ix++ + last_path = path + lord_service[side].push(path + ".a.png") + lord_service[side].push(path + ".b.png") + } +}) + +last_path = null +last_side = null +vassals.forEach((vassal,id) => { + let lord = lords[vassal.lord] + let side = lord.side + let path = "counters300/vassal_" + side.toLowerCase() + "_" + to_path(lord.name) + "_" + to_path(vassal.name) + if (side !== last_side) { + last_ix = 0 + last_side = side + } + vassal.image = last_ix + if (path !== last_path) { + last_ix++ + last_path = path + vassal_service[side].push(path + ".a.png") + vassal_service[side].push(path + ".b.png") + } +}) + +let script = [] +script.push("mkdir -p service300") +script.push("montage -mode concatenate -tile 2x " + lord_service.Teutonic.join(" ") + " service300/service_lords_teutonic.png") +script.push("montage -mode concatenate -tile 2x " + vassal_service.Teutonic.join(" ") + " service300/service_vassals_teutonic.png") +script.push("montage -mode concatenate -tile 2x " + lord_service.Russian.join(" ") + " service300/service_lords_russian.png") +script.push("montage -mode concatenate -tile 2x " + vassal_service.Russian.join(" ") + " service300/service_vassals_russian.png") + +print("const data = {") +print("seaports:" + JSON.stringify(seaports) + ",") +dumplist("locales", locales) +dumplist("ways", ways) +dumplist("lords", lords) +dumplist("vassals", vassals) +print("}") +print("if (typeof module !== 'undefined') module.exports = data") + +fs.writeFileSync("build_counters3.sh", script.join("\n") + "\n") +fs.writeFileSync("../data.js", data.join("\n") + "\n") diff --git a/tools/scale.sh b/tools/scale.sh new file mode 100644 index 0000000..a54d41e --- /dev/null +++ b/tools/scale.sh @@ -0,0 +1,18 @@ +mkdir -p output75 +mkdir -p output150 +for F in output300/*.png +do + echo $F + + O=${F/300/75} + gm convert $F -colorspace RGB -resize 25% -colorspace sRGB $O.tmp + rm -f $O + zopflipng -m $O.tmp $O + rm -f $O.tmp + + O=${F/300/150} + gm convert $F -colorspace RGB -resize 50% -colorspace sRGB $O.tmp + rm -f $O + zopflipng -m $O.tmp $O + rm -f $O.tmp +done diff --git a/tools/svgo.config.js b/tools/svgo.config.js new file mode 100644 index 0000000..ef3339c --- /dev/null +++ b/tools/svgo.config.js @@ -0,0 +1,10 @@ +module.exports = { + js2svg: { + 'finalNewline': true, + }, + plugins: [ + 'preset-default', + 'convertStyleToAttrs', + 'sortAttrs', + ], +} |