123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- # Converts an Anarch map image to usable data.
- #
- # by drummyfish, edits by pixelbath
- # released under CC0 1.0.
- from PIL import Image
- import math
- class AnarchMap:
- def __init__(self, image_path):
- self.elementTypes = [
- "NONE",
- "BARREL",
- "HEALTH",
- "BULLETS",
- "ROCKETS",
- "PLASMA",
- "TREE",
- "FINISH",
- "TELEPORTER",
- "TERMINAL",
- "COLUMN",
- "RUIN",
- "LAMP",
- "CARD0",
- "CARD1",
- "CARD2",
- "LOCK0",
- "LOCK1",
- "LOCK2",
- "BLOCKER",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "MONSTER_SPIDER",
- "MONSTER_DESTROYER",
- "MONSTER_WARRIOR",
- "MONSTER_PLASMABOT",
- "MONSTER_ENDER",
- "MONSTER_TURRET",
- "MONSTER_EXPLODER"
- ]
- self.propertyTypes = [
- "ELEVATOR",
- "SQUEEZER",
- "DOOR"
- ]
- with Image.open(image_path) as image:
- self.pixel_data = image.load()
- self.palette = []
- self.paletteInverse = [0 for i in range(256)]
- x = 5
- y = 69
- i = 0
- # load the palette/sca
- for i in range(256):
- if i % 64 == 0:
- x = 5
- y += 1
- self.palette.append(self.pixel_data[(x,y)])
- self.paletteInverse[self.pixel_data[(x,y)]] = i
- x += 1
- self.floorDict = self.load_tile_dict(5,37)
- self.ceilDict = self.load_tile_dict(5,5)
- self.floorColor = self.get_pixel(41,122)
- self.ceilColor = self.get_pixel(41,118)
- self.backgroundTex = self.get_pixel(41,126)
- self.doorTex = self.get_pixel(41,130)
- self.playerStart = [0,0,0]
- self.textures = []
- self.elements = []
- self.defines = []
- self.levelMap = [[(0,False) for i in range(64)] for j in range(64)]
- # load the map
- for y in range(64):
- for x in range(64):
- n = self.get_pixel(70 + x, 5 + y)
- if n < 64:
- self.levelMap[63 - x][y] = (n,False)
- else:
- # tile with special property, create a define for it
- prop = math.floor(n / 64) - 1
- tile = n % 64
- defNum = -1
- for i in range(len(self.defines)):
- if self.defines[i] == (tile, prop):
- defNum = i
- break
-
- if defNum == -1: # not found:
- defNum = len(self.defines)
- self.defines.append((tile,prop))
- self.levelMap[63 - x][y] = (defNum,True)
- # load elements
- playerFound = False
- for y in range(64):
- for x in range(64):
- n = self.get_pixel(x + 70, y + 70)
- if n < len(self.elementTypes):
- self.elements.append((n,63 - x,y))
- elif n >= 240:
- if playerFound:
- raise(Exception("Multiple player starting positions specified."))
- playerStart = [63 - x,y,(n - 240) * 16]
- playerFound = True
- if not playerFound:
- raise(Exception("Player starting position not specified."))
- if len(self.elements) > 128:
- raise(Exception("More than 128 level elements."))
- for i in range(128 - len(self.elements)):
- self.elements.append((0,0,0))
- # load textures
- x = 41
- y = 114
- for i in range(7):
- self.textures.append(self.get_pixel(x, y))
- x += 4
- def get_pixel(self, x, y):
- return self.paletteInverse[self.pixel_data[(x, y)]]
- def load_tile_dict(self, x, y):
- result = []
- for i in range(64):
- texture = self.get_pixel(x + i, y + 31)
- if texture > 7:
- raise(Exception("Texture index can't be higher than 7."))
- height = 0
- for j in range(31):
- if self.get_pixel(x + i, y + 30 - j) == 7:
- break
- height += 1
- result.append((texture,height))
- return result
- def defineName(self, n):
- c = chr(ord("A") + n)
- return c + c
- def numAlign(self, n):
- return str(n) + "," + (" " if n < 10 else "")
- def mapXScale(self):
- r = " // "
- for i in range(64):
- r += str(i).ljust(2) + " "
- return r + "\n"
- def printC(self):
- result = ""
- result += " { // level\n"
- result += " { // mapArray\n"
- result += " #define o 0\n"
- for i in range(len(self.defines)):
- result += " #define " + self.defineName(i) + " (" + str(self.defines[i][0]) + " | SFG_TILE_PROPERTY_" + self.propertyTypes[self.defines[i][1]] + ")\n"
- result += self.mapXScale()
- for y in range(64):
- result += "/*" + str(y).ljust(2) + "*/ "
- for x in range(64):
- item = self.levelMap[x][y]
- if not item[1]:
- result += ("o " if item[0] == 0 else str(item[0]).ljust(2))
- else:
- result += self.defineName(item[0])
- result += "," if y < 63 or x < 63 else " "
- result += " /*" + str(y).ljust(2) + "*/ \n"
- result += self.mapXScale()
- for i in range(len(self.defines)):
- result += " #undef " + self.defineName(i) + "\n"
- result += " #undef o\n"
- result += " },\n"
- result += " { // tileDictionary\n "
- for i in range(64):
- result += "SFG_TD(" + str(self.floorDict[i][1]).rjust(2) + "," + str(self.ceilDict[i][1]).rjust(2) + "," + str(self.floorDict[i][0]) + "," + str(self.ceilDict[i][0]) + ")"
- result += "," if i != 63 else " "
- if (i + 1) % 4 == 0:
- result += " // " + str(i - 3) + " \n "
- result += "}, // tileDictionary\n"
- s = ""
- first = True
- for t in self.textures:
- if first:
- first = False
- else:
- s += ","
- s += str(t).ljust(2)
- result += " {" + s + "}, // textureIndices\n"
- result += " " + self.numAlign(self.doorTex) + " // doorTextureIndex\n"
- result += " " + self.numAlign(self.floorColor) + " // floorColor\n"
- result += " " + self.numAlign(self.ceilColor) + " // ceilingColor\n"
- result += " {" + str(self.playerStart[0]).ljust(2) + ", " + str(self.playerStart[1]).ljust(2) + ", " + str(self.playerStart[2]).ljust(3) + "}, // player start: x, y, direction\n"
- result += " " + self.numAlign(self.backgroundTex) + " // backgroundImage\n"
- result += " { // elements\n"
- even = True
- i = 0
- for e in self.elements:
- if even:
- result += " "
- result += "{SFG_LEVEL_ELEMENT_" + self.elementTypes[e[0]] + ", {" + str(e[1]) + "," + str(e[2]) + "}}"
- if i < 127:
- result += ","
- if not even:
- result += "\n"
- even = not even
- i += 1
- result += " }, // elements\n"
- result += " } // level\n"
- print(result)
|