Advertisement
GeoffreyYeung

messy hoi3 map

Mar 27th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.29 KB | None | 0 0
  1. save_file = "C:/Users/Geoffrey/Documents/Paradox Interactive/Hearts of Iron III/WW1Modv1.0/save games/German_Empire1914_12_28_02.hoi3"
  2. common = "D:/Games/SteamLibrary/steamapps/common/Hearts of Iron 3/tfh/mod/WW1Mod_v1.0/common/"
  3. map_path = "D:/Games/SteamLibrary/steamapps/common/Hearts of Iron 3/tfh/mod/WW1Mod_v1.0/map/"
  4.  
  5. bmp_path = map_path + "provinces.bmp"
  6. map_def_path = map_path + "definition.csv"
  7.  
  8.  
  9. #remove quotation marks, and try to convert to int or float
  10. def tidy(s):
  11.     if len(s) >= 2:
  12.         if s[0] == '"' and s[-1] == '"':
  13.             s = s[1:-1]
  14.     if '.' in s:
  15.         try:
  16.             float(s)
  17.         except ValueError:
  18.             return s
  19.         return float(s)
  20.     else:
  21.         try:
  22.             int(s)
  23.         except ValueError:
  24.             return s
  25.         return int(s)
  26.  
  27. delim = [' ', '\n', '\t']
  28.  
  29. def parse(f, d):
  30.     #print "parse"
  31.     "read first non-space char"
  32.     b = f.read(1)
  33.     while b in delim:
  34.         b = f.read(1)
  35.     "exit if close bracket"
  36.     if b == '}':
  37.         #print 1
  38.         return 1
  39.     "exit if end of file"
  40.     if b == '':
  41.         #print 2
  42.         return 2
  43.     if b == '{':
  44.         sub_d = []
  45.         while not parse(f, sub_d):
  46.             pass
  47.         d.append(sub_d)
  48.         #print 0
  49.         return 0
  50.     if b == '#':
  51.         while not b == '\n':
  52.             b = f.read(1)
  53.         parse(f, d)
  54.         #print 4
  55.         return 0
  56.  
  57.     "read first item (string)"
  58.     name = b
  59.     #print "name:",b
  60.     b = f.read(1)
  61.     while not (b == '=' or b in delim):
  62.         name += b
  63.         #print "n:",b
  64.         b = f.read(1)
  65.  
  66.     if b in delim:
  67.         while b in delim:
  68.             b = f.read(1)
  69.         if b == '=':
  70.             pass
  71.             "no '=' means this is a space-seperated list"
  72.         else:
  73.             name = tidy(name)
  74.             d.append(name)
  75.             name = ""
  76.             while not b == '}':
  77.                 if b in delim:
  78.                     if len(name) > 0:
  79.                         name = tidy(name)
  80.                         d.append(name)
  81.                     name = ""
  82.                 else:
  83.                     name += b
  84.                 b = f.read(1)
  85.             #print "l:", d, type(d)
  86.             #print 3
  87.             return 3
  88.  
  89.     "read content"
  90.     b = f.read(1)
  91.     while b in delim:
  92.         b = f.read(1)
  93.     if b == '{':
  94.         sub_d = []
  95.         while not parse(f, sub_d):
  96.             pass
  97.         name = tidy(name)
  98.         d.append((name,sub_d))
  99.         #print 5
  100.         return 0
  101.     else:
  102.         content = b
  103.         #print "content:",b
  104.         if b == '"':
  105.             b = f.read(1)
  106.             content += b
  107.             while not b == '"':
  108.                 b = f.read(1)
  109.                 content += b
  110.         else:
  111.             b = f.read(1)
  112.             while not b in delim:
  113.                 content += b
  114.                 #print "c:",b
  115.                 b = f.read(1)
  116.         name = tidy(name)
  117.         content = tidy(content)
  118.         d.append((name,content))
  119.         #print 6
  120.         return 0
  121.  
  122. def show_data(d, depth = 0):
  123.     if type(d) == tuple:
  124.         print "  " * depth, d[0], ":"
  125.         show_data(d[1], depth+1)
  126.     elif type(d) == int or type(d) == float or type(d) == str:
  127.         print "  " * depth, d
  128.     elif len(d) == 0:
  129.         print "  " * depth, d
  130.     elif type(d[0]) == tuple:
  131.         for t in d:
  132.             show_data(t, depth + 1)
  133.     else:
  134.         print "  " * depth, d
  135.  
  136. def file_data(d, f_out, depth = 0):
  137.     indent = "  " * depth
  138.     if type(d) == tuple:
  139.         f_out.write(indent+str(d[0])+":\n")
  140.         file_data(d[1], f_out, depth + 1)
  141.     elif type(d) == int or type(d) == float or type(d) == str:
  142.         f_out.write(indent+str(d)+"\n")
  143.     elif len(d) == 0:
  144.         f_out.write(indent+str(d)+"\n")
  145.     elif type(d[0]) == tuple:
  146.         for t in d:
  147.             file_data(t, f_out, depth + 1)
  148.     else:
  149.         f_out.write(indent+str(d)+"\n")
  150.  
  151. def get_country_data(data, country_name):
  152.     country = [x for x in data if x[0] == country_name]
  153.     return country[0]
  154.  
  155. army_ranks = ["theatre", "army", "corps", "division", "regiment"]
  156. army_filter = ["name", "id", "leader", "type", "location",
  157.                "strength", "organisation", "experience"]
  158. def filter_army(army_data):
  159.     info = [x for x in army_data[1] if x[0] in army_filter]
  160.     info = [(x[0], x[1][0][1]) if x[0] == "id" or x[0] == "leader"
  161.             else x for x in info]
  162.     subordinate = [filter_army(x) for x in army_data[1]
  163.                    if x[0] in army_ranks]
  164.     return (army_data[0], info + subordinate)
  165.  
  166. def get_army(country_data):
  167.     country_data = country_data[1]
  168.     army = [x for x in country_data if x[0] in army_ranks]
  169.     return [filter_army(x) for x in army]
  170.  
  171.  
  172.  
  173. save = []
  174. with open(save_file) as f:
  175.     while not parse(f, save):
  176.         pass
  177.  
  178. #print data
  179. #show_data(data, -1)
  180.  
  181. #g = [x for x in data if x[0] == "GER"]
  182. #with open("dump.txt", 'w') as write_file:
  183. #    file_data(g, write_file)
  184.  
  185. ger = get_country_data(save, "GER")
  186. print len(ger)
  187.  
  188. file_data(get_army(ger), open("army.txt", 'w'))
  189.  
  190. from PIL import Image
  191.  
  192. def get_pixels(bmp):
  193.     pixels = list(bmp.getdata())
  194.     width, height = bmp.size
  195.     pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)]
  196.     return pixels
  197.  
  198. def read_map_def(file_name):
  199.     num_to_rgb, rgb_to_num = {}, {}
  200.     with open(file_name, 'r') as f:
  201.         for line in f.readlines()[1:]:
  202.             l = line.strip().split(";")
  203.             if len(l[0]) > 0:
  204.                 [num, r, g, b] = [int(x) for x in l[:4]]
  205.                 num_to_rgb[num] = (r,g,b)
  206.                 rgb_to_num[(r,g,b)] = num
  207.     return num_to_rgb, rgb_to_num
  208.  
  209. map_bmp = Image.open(bmp_path)
  210. pixels = [map_bmp.getpixel((i,0)) for i in xrange(map_bmp.size[0])]
  211. print map_bmp.format, map_bmp.size, map_bmp.mode
  212. pixels = get_pixels(map_bmp)
  213. print len(pixels[0]), len(pixels), pixels[0][0], pixels[0][1]
  214.  
  215. num_to_rgb, rgb_to_num  = read_map_def(map_def_path)
  216. print len(num_to_rgb)
  217.  
  218. print pixels[0].count(num_to_rgb[13442])
  219.  
  220. def get_controllers(save):
  221.     num = [x for x in save if type(x[0]) == int]
  222.     land = [(x[0], x[1][2][1]) for x in num if x[1][2][0] == "controller"]
  223.     d = {}
  224.     for province in land:
  225.         d[province[0]] = province[1]
  226.     return d
  227.  
  228. controller_dict = get_controllers(save)
  229.  
  230. countries_def = common + "countries.txt"
  231. countries_files = []
  232. with open(countries_def, 'r') as f:
  233.     while not parse(f, countries_files):
  234.         pass
  235. file_data(countries_files, open("colours.txt", 'w'))
  236.  
  237. countries_paths = {}
  238. for country in countries_files:
  239.     countries_paths[country[0]] = common + country[1]
  240.  
  241. countries_colours = {}
  242. for k, v in countries_paths.iteritems():
  243.     with open(v, 'r') as f:
  244.         c = [("no",0)]
  245.         while not c[0][0] == "color":
  246.             c = []
  247.             parse(f, c)
  248.         countries_colours[k] = tuple(c[0][1])
  249. print countries_colours["GER"]
  250.  
  251. old_pixels = [[x for x in row] for row in pixels]
  252. """
  253. test_colour = [(84, 71, 85)]
  254. for x in xrange(map_bmp.size[0]):
  255.    for y in xrange(map_bmp.size[1]):
  256.        if old_pixels[y][x] in test_colour:
  257.            map_bmp.putpixel((x,y),(0,0,0))
  258.            print (x,y)
  259.  
  260. for x in xrange(398):
  261.    for y in xrange(267):
  262.        map_bmp.putpixel((x,y), (0,0,0))
  263.  
  264. """
  265. ignore_colour = [(255,255,255)] #lakes
  266.                  #(10,8,245), #at (398, 267)
  267.                  #(156, 62, 74), #at (1782, 423)
  268.                  #(84, 71, 85)] #at (1574, 474)
  269. for y in xrange(map_bmp.size[1]):
  270.     if y % 100 == 0:
  271.         print "y:",y
  272.     for x in xrange(map_bmp.size[0]):
  273.         try:
  274.             old_colour = old_pixels[y][x]
  275.             if not old_colour in ignore_colour:
  276.                 province = rgb_to_num[old_colour]
  277.                 try:
  278.                     country = controller_dict[province]
  279.                     new_colour = countries_colours[country]
  280.                     map_bmp.putpixel((x, y), new_colour)
  281.                 except KeyError as e:
  282.                     #print e
  283.                     map_bmp.putpixel((x, y), (255,255,255))
  284.                 except TypeError as e:
  285.                     print country, new_colour, province
  286.                     print e
  287.         except KeyError as e:
  288.             print e, "at", (x, y)
  289.  
  290. map_bmp = map_bmp.transpose(Image.FLIP_TOP_BOTTOM)
  291. map_bmp.save("test.bmp")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement