From e8a5f5410a0e876d889a2a8137c34bb925f65408 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 8 Apr 2022 01:29:54 +0200 Subject: Assets. --- tools/gencss.js | 7 + tools/gendata.js | 576 +++++++++++++++++++++++++++++++++++++++++++++ tools/gentextures.sh | 36 +++ tools/genunits.js | 227 ++++++++++++++++++ tools/rock_overlay.png | Bin 0 -> 44367 bytes tools/rock_overlay@2x.png | Bin 0 -> 160515 bytes tools/scree_overlay.png | Bin 0 -> 21813 bytes tools/scree_overlay@2x.png | Bin 0 -> 72197 bytes tools/wetland.pbm | Bin 0 -> 8203 bytes 9 files changed, 846 insertions(+) create mode 100644 tools/gencss.js create mode 100644 tools/gendata.js create mode 100644 tools/gentextures.sh create mode 100644 tools/genunits.js create mode 100644 tools/rock_overlay.png create mode 100644 tools/rock_overlay@2x.png create mode 100644 tools/scree_overlay.png create mode 100644 tools/scree_overlay@2x.png create mode 100644 tools/wetland.pbm (limited to 'tools') diff --git a/tools/gencss.js b/tools/gencss.js new file mode 100644 index 0000000..4981d7c --- /dev/null +++ b/tools/gencss.js @@ -0,0 +1,7 @@ +// let n = 51, u = 'px'; +let n = 100 / 9, u = '%'; +for (let i = 0; i < 94; ++i) { + let x = (i % 10) | 0; + let y = (i / 10) | 0; + console.log(`.unit.u${i}{background-position:${x*n}${u} ${y*n}${u}}`); +} diff --git a/tools/gendata.js b/tools/gendata.js new file mode 100644 index 0000000..fb0348c --- /dev/null +++ b/tools/gendata.js @@ -0,0 +1,576 @@ +// https://www.redblobgames.com/grids/hexagons/ + +// Clear +const CLEAR = 2; + +// Constricted +const GAP = 1; + +// Rough (impassable) +const OFFMAP = 0; +const RIDGE = 0; +const MARSH = 0; +const MOUNTAIN = 0; + +// Road +const TRAIL = 1; +const TRACK = 2; +const HIGHWAY = 4; + +const map_w = 25; +const map_h = 9; + +let next = [ 1, map_w, map_w-1, -1, -map_w, -(map_w-1) ]; + +let nextdir = [ -1, 1, map_w, map_w-1, -map_w, -(map_w-1) ] +let nextname = [ "E", "W", "NW", "NE", "SE", "SW" ]; + +let hex_exists = new Array(map_w*map_h).fill(1); +let side_limit = new Array(map_w*map_h*3).fill(CLEAR); +let side_road = new Array(map_w*map_h*3).fill(0); +let hex_road = new Array(map_w*map_h).fill(0); + +function add_side(s, t) { + if (side_limit[s]) + side_limit[s] += "/" + t; + else + side_limit[s] = t; +} + +function to_side_id(a, b) { + if (a > b) { + let c = b; b = a; a = c; + } + if (a + next[0] === b) + return a * 3 + 0; + else if (a + next[1] === b) + return a * 3 + 1; + else if (a + next[2] === b) + return a * 3 + 2; + throw new Error("not a hexside " + a + " to " + b); +} + +function def_side(t,a,b) { + side_limit[to_side_id(a,b)] = t; +} + +function def_road(t, list) { + for (let i = 0; i < list.length; ++i) + hex_road[list[i]] = t; + for (let i = 1; i < list.length; ++i) { + let s = to_side_id(list[i-1], list[i]); + side_road[s] = t; + if (side_limit[s] === MOUNTAIN) + side_limit[s] = GAP; + } +} + +def_side(MARSH, 176, 152); +def_side(MARSH, 179, 203); + +def_side(RIDGE, 144, 145); +def_side(RIDGE, 120, 145); +def_side(RIDGE, 121, 145); +def_side(RIDGE, 121, 146); +def_side(RIDGE, 122, 146); +def_side(RIDGE, 144, 169); +def_side(RIDGE, 144, 168); +def_side(RIDGE, 143, 168); +def_side(RIDGE, 167, 168); +def_side(RIDGE, 167, 192); +def_side(RIDGE, 191, 192); +def_side(RIDGE, 191, 216); +def_side(RIDGE, 215, 216); +def_side(RIDGE, 217, 218); +def_side(RIDGE, 217, 193); +def_side(RIDGE, 192, 193); +def_side(RIDGE, 168, 193); +def_side(RIDGE, 168, 169); +def_side(RIDGE, 69, 94); +def_side(RIDGE, 67, 92); +def_side(RIDGE, 68, 92); +def_side(RIDGE, 68, 93); +def_side(RIDGE, 65, 40); +def_side(RIDGE, 65, 64); +def_side(RIDGE, 65, 89); +def_side(RIDGE, 65, 90); +def_side(RIDGE, 66, 90); +def_side(RIDGE, 66, 91); +def_side(RIDGE, 39, 63); +def_side(RIDGE, 37, 38); +def_side(RIDGE, 36, 37); +def_side(RIDGE, 36, 61); +def_side(RIDGE, 36, 60); +def_side(RIDGE, 109, 133); +def_side(RIDGE, 108, 133); +def_side(RIDGE, 204, 179); +def_side(RIDGE, 204, 180); +def_side(RIDGE, 205, 180); +def_side(RIDGE, 31, 30); +def_side(RIDGE, 31, 55); +def_side(RIDGE, 55, 54); +def_side(RIDGE, 78, 79); +def_side(RIDGE, 30, 55); +def_side(RIDGE, 54, 79); +def_side(RIDGE, 103, 79); +def_side(RIDGE, 176, 200); +def_side(RIDGE, 176, 201); +def_side(RIDGE, 177, 152); +def_side(RIDGE, 177, 153); +def_side(RIDGE, 178, 153); +def_side(RIDGE, 153, 154); +def_side(RIDGE, 129, 154); + +def_side(MOUNTAIN, 7, 8); +def_side(MOUNTAIN, 7, 31); +def_side(MOUNTAIN, 7, 32); +def_side(MOUNTAIN, 8, 9); +def_side(MOUNTAIN, 8, 32); +def_side(MOUNTAIN, 8, 33); +def_side(MOUNTAIN, 9, 33); +def_side(MOUNTAIN, 9, 34); +def_side(MOUNTAIN, 9, 10); +def_side(MOUNTAIN, 32, 31); +def_side(MOUNTAIN, 32, 33); +def_side(MOUNTAIN, 32, 56); +def_side(MOUNTAIN, 32, 57); +def_side(MOUNTAIN, 33, 34); +def_side(MOUNTAIN, 33, 57); +def_side(MOUNTAIN, 33, 58); +def_side(MOUNTAIN, 34, 10); +def_side(MOUNTAIN, 34, 35); +def_side(MOUNTAIN, 34, 58); +def_side(MOUNTAIN, 34, 59); +def_side(MOUNTAIN, 55, 80); +def_side(MOUNTAIN, 56, 80); +def_side(MOUNTAIN, 56, 55); +def_side(MOUNTAIN, 56, 31); +def_side(MOUNTAIN, 56, 81); +def_side(MOUNTAIN, 56, 57); +def_side(MOUNTAIN, 57, 58); + +def_side(GAP, 176, 152); +def_side(GAP, 65, 40); +def_side(GAP, 65, 64); +def_side(GAP, 65, 89); +def_side(GAP, 37, 38); +def_side(GAP, 36, 37); +def_side(GAP, 36, 61); +def_side(GAP, 109, 133); +def_side(GAP, 31, 30); +def_side(GAP, 31, 55); +def_side(GAP, 55, 54); +def_side(GAP, 78, 79); +def_side(GAP, 177, 153); +def_side(GAP, 178, 153); +def_side(GAP, 129, 154); + +def_road(HIGHWAY, [151,152,128,103,78,54,30,31,7,8,9,10,35,36,37,38,39,40,64,65,66,67,68,69,70,71,72,73,74]); +def_road(HIGHWAY, [54,55,31]); +def_road(HIGHWAY, [31,32,33,9]); +def_road(HIGHWAY, [36,61,62,38]); + +def_road(TRACK, [78,79,80,81,82,58,59,35]); +def_road(TRACK, [128,104,80]); +def_road(TRACK, [83,59,60,61,86,87,88,89]); +def_road(TRACK, [37,62,87]); +def_road(TRACK, [64,89,113]); +def_road(TRACK, [62,63,64]); +def_road(TRACK, [213,189,165,141,117,93,69]); +def_road(TRACK, [72,97,121]); + +def_road(TRAIL, [152,153,178,203,204,205,181,182,183,184,185,186,187]); +def_road(TRAIL, [153,128,129,104,103]); +def_road(TRAIL, [79,55]); +def_road(TRAIL, [55,56,57,58,34,10]); +def_road(TRAIL, [58,83,107,106,130,129]); +def_road(TRAIL, [35,60,85,61]); +def_road(TRAIL, [85,86]); +def_road(TRAIL, [85,109,133,157,181]); +def_road(TRAIL, [64,88]); +def_road(TRAIL, [88,113,138,162,187]); +def_road(TRAIL, [87,112,137,162]); +def_road(TRAIL, [65,89,114,139,163,188,213]); +def_road(TRAIL, [67,91,115,140,164,189]); + +function def_offmap(a, b) { + for (let hex_id = 0; hex_id < map_w * map_h; ++hex_id) { + if (hex_id >= a && hex_id <= b) { + hex_exists[hex_id] = 0; + side_limit[hex_id * 3 + 0] = OFFMAP; + side_limit[hex_id * 3 + 1] = OFFMAP; + side_limit[hex_id * 3 + 2] = OFFMAP; + } + for (let s = 0; s < 3; ++s) { + let next_id = hex_id + next[s]; + if (next_id >= a && next_id <= b) + side_limit[hex_id * 3 + s] = OFFMAP; + } + } +} + +def_offmap(0,6); +def_offmap(11,29); +def_offmap(41,53); +def_offmap(75,77); +def_offmap(99,102); +def_offmap(124,127); +def_offmap(148,150); +def_offmap(173,175); +def_offmap(197,199); +def_offmap(222,224); + +// show spines +def_offmap(175,175, 1); +def_offmap(99,99, 1); +def_offmap(148,148, 1); +def_offmap(197,197, 1); + +// depression +def_offmap(168,168); +def_offmap(168,168); +def_offmap(192,192); +def_offmap(193,193); +def_offmap(216,217); + +// Hexes not in 2004 edition: +// def_offmap(200,202); +// def_offmap(206,212); +// def_offmap(214,221); + +// Terrain chart hexes +// def_offmap(145,146); +// def_offmap(168,172); +// def_offmap(192,196); +// def_offmap(216,221); + +// Qattara Depression and east of it +def_offmap(145,148); +def_offmap(168,172); +def_offmap(192,196); +def_offmap(216,221); + +let regions = {}; +function def_region(name, a, b) { + if (!(name in regions)) + regions[name] = []; + for (let i = a; i <= b; ++i) + regions[name].push(i); +} + +def_region("Libya", 7, 10); +def_region("Libya", 30, 40); +def_region("Libya", 54, 64); +def_region("Libya", 78, 88); +def_region("Libya", 103, 113); +def_region("Libya", 128, 138); +def_region("Libya", 151, 162); +def_region("Libya", 176, 187); +def_region("Libya", 200, 211); + +def_region("Egypt", 65, 74); +def_region("Egypt", 89, 98); +def_region("Egypt", 114, 123); +def_region("Egypt", 139, 144); +def_region("Egypt", 163, 167); +def_region("Egypt", 188, 191); +def_region("Egypt", 212, 215); + +def_region("Sidi Omar", 89, 89); +def_region("Tobruk", 37, 37); +def_region("Sollum", 65, 65); +def_region("El Agheila", 151, 151); +def_region("Mersa Brega", 152, 152); + +def_region("East Line", 36, 40); +def_region("East Line", 60, 74); +def_region("East Line", 85, 98); +def_region("East Line", 112, 123); +def_region("East Line", 137, 144); +def_region("East Line", 162, 167); +def_region("East Line", 187, 191); + +def_region("West Line", 7, 10); +def_region("West Line", 30, 35); +def_region("West Line", 54, 59); +def_region("West Line", 78, 83); +def_region("West Line", 103, 107); +def_region("West Line", 128, 130); + +def_region("Jebel el Akhdar", 7, 9); +def_region("Jebel el Akhdar", 32, 34); +def_region("Jebel el Akhdar", 56, 57); + +def_region("Sebkha el Segira", 152, 152); +def_region("Sebkha el Segira", 176, 176); +def_region("Sebket el Jeneinen", 179, 179); +def_region("Sebket el Jeneinen", 203, 203); + +def_region("Qattara Depression", 144, 146); +def_region("Qattara Depression", 168, 169); +def_region("Qattara Depression", 192, 193); +def_region("Qattara Depression", 216, 217); + +hex_name = { + 7: "El Garib", + 8: "Cyrene", + 9: "El Gubba", + 10: "Derna", + + 30: "Tocra", + 31: "Barce", + 32: "Marawa", + 33: "Wadi Cuff", + 35: "Gazala", + 36: "Acroma", + 37: "Tobruk", + 38: "Belhamed", + 39: "Gambut", + 40: "Bardia", + + 54: "Benghazi", + 55: "Er Regima", + 56: "Charruba", + 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", + 69: "Mersa Matruh", + 70: "Fuka", + 71: "El Daba", + 72: "El Alamein", + 73: "El Hamam", + 74: "Alexandria", + + 78: "Ghemines", + 79: "Skeleidima", + 80: "Msus", + 83: "Tengeder", + 85: "Bir Hacheim", + 86: "Retma", + 87: "Bir Gubi", + 88: "Gabr Saleh", + 89: "Sidi Omar", + 90: "Bir Habata", + 91: "Sofafi", + 93: "Bir el Kenayis", + 94: "Bir Khalda", + 97: "Alam Halfa", + + 103: "Beda Fomm", + 104: "Antelat", + 106: "Ben Gania", + 113: "Ft. Maddalena", + 115: "Bir Khamsa", + 116: "Bir el Qatrani", + 121: "El Himeimat", + + 128: "Agedabia", + 129: "Jebel el Matar", + 130: "Haraga", + 141: "Bir Fuad", + + 151: "El Agheila", + 152: "Mersa Brega", + 153: "El Haseiat", + + 176: "Maaten Giofer", + 178: "Sahaba", + 187: "Jarabub Oasis", + + 204: "Jalo Oasis", + 213: "Siwa Oasis", +} + + +function expand_names() { + let hex_name2 = { } + for (let hex_id = 0; hex_id < map_w * map_h; ++hex_id) { + if (hex_exists[hex_id] && !hex_name[hex_id]) { + for (let s = 0; s < 6; ++s) { + let next_id = hex_id + nextdir[s]; + if (hex_name[next_id]) { + hex_name2[hex_id] = hex_name[next_id] + " " + nextname[s]; + break; + } + } + } + } + for (let hex_id in hex_name2) + hex_name[hex_id] = hex_name2[hex_id]; +} + +expand_names(); + +let units = []; + +const class_from_type = { + "recon": "armor", + "armor": "armor", + "i-tank": "armor", + "infantry": "infantry", + "mech. inf.": "infantry", + "mot. inf.": "infantry", + "para": "infantry", + "mob. a/t": "antitank", + "mot. a/t": "antitank", + "self prop. arty": "artillery", + "artillery": "artillery", +} + +const speed_from_type = { + "recon": 4, + "armor": 3, + "i-tank": 3, // optional rule: allied i-tanks set this to 2 + "mech. inf.": 3, + "mob. a/t": 3, + "self prop. arty": 3, + "mot. inf.": 2, + "mot. a/t": 2, + "infantry": 1, + "para": 1, + "artillery": 1, +} + +let unit_map = {}; + +function def_block(nationality, type, appearance, steps, elite, label, name) { + let type_class = class_from_type[type]; + let speed = speed_from_type[type]; + if (name in unit_map) + throw new Error("duplicate block name:", name); + unit_map[name] = units.length; + units.push({nationality, type, class: type_class, speed, appearance, steps, elite, label, name}); +} + +let S = "S"; +let M = "M"; +let T = "T"; + +//def_block("italian", battle block 1); +def_block("italian", "infantry", S, 4, 0, 12, "Tre"); +def_block("italian", "infantry", S, 4, 0, 13, "Pav"); +def_block("italian", "infantry", S, 4, 0, 14, "Bre"); +def_block("italian", "infantry", S, 3, 0, 15, "Bol"); +def_block("italian", "infantry", S, 3, 0, 16, "Sav"); + +def_block("italian", "mech. inf.", 7, 4, 0, 21, "Tri"); +def_block("italian", "infantry", 7, 2, 0, 22, "Sab"); +def_block("italian", "armor", 11, 3, 0, 23, "Lit"); +def_block("italian", "mot. inf.", 17, 3, 0, 24, "Fas"); +def_block("italian", "mot. inf.", 19, 3, 0, 25, "Cen"); +def_block("italian", "infantry", 19, 2, 0, 26, "Pis"); +def_block("italian", "para", M, 4, 0, 27, "Fol"); +def_block("italian", "artillery", S, 2, 0, 28, "Ita"); +def_block("italian", "armor", S, 4, 0, 29, "Ari"); + +//def_block("german", battle block 1); +//def_block("german", battle block 2); +//def_block("german", battle block 3); +def_block("german", "armor", S, 3, 1, 14, "21/5"); +def_block("german", "recon", S, 1, 1, 15, "21/3"); +def_block("german", "mech. inf.", S, 3, 1, 16, "21/104"); +def_block("german", "recon", 3, 1, 1, 17, "15/33"); +def_block("german", "mob. a/t", 3, 2, 1, 18, "88mm/A"); +def_block("german", "mech. inf.", 3, 3, 1, 19, "15/115"); + +def_block("german", "armor", 5, 3, 1, 21, "15/8"); +def_block("german", "recon", 5, 1, 1, 22, "90/580"); +def_block("german", "mot. inf.", 5, 2, 1, 23, "90/361"); +def_block("german", "mot. a/t", 5, 2, 1, 24, "50mm"); +def_block("german", "artillery", 7, 2, 1, 25, "/104"); +def_block("german", "mot. inf.", 7, 2, 1, 26, "90/200"); +def_block("german", "mob. a/t", 11, 2, 1, 27, "88mm/B"); +def_block("german", "mech. inf.", 11, 2, 1, 28, "90/sv288"); +def_block("german", "mech. inf.", 11, 2, 1, 29, "90/346"); + +def_block("german", "para", M, 3, 1, 31, "Ram"); +def_block("german", "infantry", M, 3, 1, 32, "164/382+433"); +def_block("german", "infantry", M, 2, 1, 33, "164/125"); +def_block("german", "mech. inf.", 3, 3, 1, 34, "90/155"); +def_block("german", "mot. a/t", 17, 2, 1, 35, "76mm"); + +// def_block("allied", bb 1 +// def_block("allied", bb 2 +// def_block("allied", bb 3 +def_block("allied", "armor", S, 2, 0, 14, "2/3"); +def_block("allied", "mech. inf.", S, 2, 0, 15, "2/SG"); +def_block("allied", "mech. inf.", S, 2, 0, 16, "4IN/3m"); +def_block("allied", "mot. inf.", S, 4, 0, 17, "9AU/20"); +def_block("allied", "mot. inf.", S, 4, 0, 18, "70/14+16"); +def_block("allied", "mot. inf.", S, 3, 0, 19, "70/23"); + +def_block("allied", "armor", T, 1, 1, 21, "Matilda/A"); +def_block("allied", "mech. inf.", T, 3, 0, 22, "7/SG"); +def_block("allied", "mech. inf.", T, 3, 0, 23, "7/22G"); +def_block("allied", "mot. inf.", T, 3, 0, 24, "/Pol"); +def_block("allied", "mot. inf.", T, 3, 0, 25, "7AU/18"); +def_block("allied", "artillery", T, 2, 0, 26, "/Tob"); +def_block("allied", "mot. inf.", 18, 4, 0, 27, "51H/152"); +def_block("allied", "self prop. arty", 18, 2, 0, 28, "Priest"); +def_block("allied", "artillery", 18, 4, 0, 29, "/C"); + +def_block("allied", "armor", 2, 4, 0, 31, "7/7"); +def_block("allied", "mech. inf.", 2, 3, 0, 32, "4IN/7m"); +def_block("allied", "mot. inf.", 2, 3, 0, 33, "4IN/5"); +def_block("allied", "mot. inf.", 2, 3, 0, 34, "4IN/11"); +def_block("allied", "armor", 4, 1, 1, 35, "Matilda/B"); +def_block("allied", "i-tank", 4, 4, 0, 36, "/1AT"); +def_block("allied", "armor", 4, 3, 0, 37, "7/4"); +def_block("allied", "recon", 4, 2, 0, 38, "7"); +def_block("allied", "artillery", 20, 3, 0, 39, "/D"); + +def_block("allied", "mot. a/t", 6, 3, 0, 41, "2#"); +def_block("allied", "mech. inf.", 6, 4, 0, 42, "2NZ/4"); +def_block("allied", "mech. inf.", 6, 4, 0, 43, "2NZ/5"); +def_block("allied", "mech. inf.", 6, 4, 0, 44, "2NZ/6"); +def_block("allied", "mot. inf.", 6, 4, 0, 45, "1SA/2+5"); +def_block("allied", "mot. inf.", 6, 3, 0, 46, "1SA/1"); +def_block("allied", "recon", 8, 2, 0, 47, "1SA"); +def_block("allied", "mot. inf.", 8, 3, 0, 48, "1SA/3"); +def_block("allied", "mot. inf.", 8, 3, 0, 49, "2SA/4+6"); + +def_block("allied", "armor", 8, 4, 0, 51, "1/22"); +def_block("allied", "i-tank", 8, 3, 0, 52, "/32AT"); +def_block("allied", "artillery", 8, 2, 0, 53, "/A"); +def_block("allied", "armor", 10, 4, 0, 54, "1/2"); +def_block("allied", "mech. inf.", 10, 3, 0, 55, "1/201G"); +def_block("allied", "mech. inf.", 10, 2, 0, 56, "1/SG"); +def_block("allied", "mot. inf.", 10, 3, 0, 57, "5IN/29"); +def_block("allied", "armor", 12, 2, 1, 58, "Grant"); +def_block("allied", "mot. a/t", 12, 3, 0, 59, "6#/A"); + +def_block("allied", "mech. inf.", 14, 2, 0, 61, "10IN/161m"); +def_block("allied", "mot. inf.", 14, 4, 0, 62, "5IN/9+10"); +def_block("allied", "mot. inf.", 14, 4, 0, 63, "10IN/21+25"); +def_block("allied", "mot. inf.", 14, 2, 0, 64, "8IN/18"); +def_block("allied", "mot. inf.", 14, 4, 0, 65, "FF/2"); +def_block("allied", "artillery", 14, 4, 0, 66, "/B"); +def_block("allied", "armor", 20, 3, 1, 67, "Sher/B"); +def_block("allied", "armor", 20, 3, 0, 68, "8/9"); +def_block("allied", "armor", 20, 3, 0, 69, "8/24"); + +def_block("allied", "armor", 16, 4, 0, 71, "10/8"); +def_block("allied", "armor", 16, 3, 0, 72, "10/23"); +def_block("allied", "mot. inf.", 16, 4, 0, 73, "9AU/26"); +def_block("allied", "mot. inf.", 16, 4, 0, 74, "9AU/24"); +def_block("allied", "mot. inf.", 16, 4, 0, 75, "44/131+133"); +def_block("allied", "mot. inf.", 16, 2, 0, 76, "44/132"); +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"); + +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 = { hex_name, hex_road, side_road, side_limit, regions, units }"); diff --git a/tools/gentextures.sh b/tools/gentextures.sh new file mode 100644 index 0000000..cacd968 --- /dev/null +++ b/tools/gentextures.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# 2022 +# depression: c4ab8b b39e83 +# depression (old): c4bd9c +# marsh: 939874 747e5c +# mountain: b3b37d 9a9a6e +# desert: ccbda4 d6c5aa + +cat tools/wetland.pbm | pgmtoppm "#747e5c-#939874" | ppmquant 2 | pnmtopng > texture_marsh.png +#pngtopnm tools/scree_overlay@2x.png | pgmtoppm "black-#c4ab8b" | ppmquant 2 | pnmtopng > texture_scree.png +pngtopnm tools/scree_overlay@2x.png | pgmtoppm "black-#c4bd9c" | ppmquant 2 | pnmtopng > texture_scree.png +#pngtopnm tools/rock_overlay@2x.png | pnmnorm | pgmtoppm "#aaa26f-#bab079" | ppmquant 2 | pnmtopng > texture_mountain.png +pngtopnm tools/rock_overlay@2x.png | pnmnorm | pgmtoppm "#9d9d6a-#aaaa77" | ppmquant 2 | pnmtopng > texture_mountain.png +pngtopnm tools/rock_overlay@2x.png | pnmnorm | pgmtoppm "#ccbda4-#d6c5aa" | ppmquant 2 | pnmtopng > texture_clear.png +pngtopnm tools/rock_overlay@2x.png | pnmnorm | pgmtoppm "#bba487-#c4ab8b" | ppmquant 2 | pnmtopng > texture_depression.png + +for PNG in texture_*.png +do + zopflipng -y $PNG $PNG +done + +exit 0 + +OUT=textures.svg +rm -f $OUT +for PNG in texture_*.png +do +SIZE=$(file $PNG | sed 's/[^0-9]*//;s/ .*//') +echo '' >> $OUT +echo '' >> $OUT +echo '"' >> $OUT +echo >> $OUT +done diff --git a/tools/genunits.js b/tools/genunits.js new file mode 100644 index 0000000..4e0f30e --- /dev/null +++ b/tools/genunits.js @@ -0,0 +1,227 @@ +const { units } = require("../data.js"); +const print = console.log; + +print(` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); + +SYMBOLS = { + +"armor": ` + + +`, + +"armor_elite": ` + + +`, + +"armor_itank": ` + + + +`, + +"artillery": ` + + +`, + +"infantry": ` + + +`, + +"mechanized_infantry": ` + + +`, + +"mobile_antitank": ` + + + +`, + +"motorized_antitank_new": ` + + + +`, + +"motorized_antitank_old": ` + + +`, + +"motorized_infantry": ` + + + +`, + +"paratroopers": ` + + +`, + +"recon": ` + + +`, + +"self_propelled_artillery": ` + + + +`, + +} + +const TYPEMAP = { + "armor": "armor", + "artillery": "artillery", + "i-tank": "armor_itank", + "infantry": "infantry", + "mech. inf.": "mechanized_infantry", + "mob. a/t": "mobile_antitank", + "mot. a/t": "motorized_antitank_new", + "mot. inf.": "motorized_infantry", + "para": "paratroopers", + "recon": "recon", + "self prop. arty": "self_propelled_artillery", +}; + +// 94 units + +let smcp = /(IN|AU|NZ|SA|AT|H|G)$/; +smcp = /NEVER/; + +const COLORMAP = { + "italian": "#b0c5d4", + "german": "#f9e3b3", + "allied": "#cead78", + "Pol": "#ffffff", + "FF": "#8197cd", + "NZ": "#95c3d6", + "AU": "#f48480", + "SA": "#f9a64a", + "IN": "#84c88b", +} + +const BLACK = { + italian: "#221f1f", + german: "#004e2f", + 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}`); + + if (b) { + if (b.length > 1) { + print(`${b[0]}`); + print(`${b[1]}`); + } else { + print(`${b[0]}`); + } + } + + print(``); + print(``); + x += 51; + if (x >= 510) { + y += 51; + x = 0; + } +} +print(``); +print(``); diff --git a/tools/rock_overlay.png b/tools/rock_overlay.png new file mode 100644 index 0000000..d2c6976 Binary files /dev/null and b/tools/rock_overlay.png differ diff --git a/tools/rock_overlay@2x.png b/tools/rock_overlay@2x.png new file mode 100644 index 0000000..8710ab6 Binary files /dev/null and b/tools/rock_overlay@2x.png differ diff --git a/tools/scree_overlay.png b/tools/scree_overlay.png new file mode 100644 index 0000000..cab6b5c Binary files /dev/null and b/tools/scree_overlay.png differ diff --git a/tools/scree_overlay@2x.png b/tools/scree_overlay@2x.png new file mode 100644 index 0000000..5680582 Binary files /dev/null and b/tools/scree_overlay@2x.png differ diff --git a/tools/wetland.pbm b/tools/wetland.pbm new file mode 100644 index 0000000..aa9151c Binary files /dev/null and b/tools/wetland.pbm differ -- cgit v1.2.3