diff options
Diffstat (limited to '')
| -rw-r--r-- | src/exporter.py | 116 | 
1 files changed, 79 insertions, 37 deletions
| diff --git a/src/exporter.py b/src/exporter.py index f706a38..0c24d50 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -1,6 +1,7 @@  from common import *  import array  import sys +import math  from ctypes import create_string_buffer  # Useful Stuff @@ -74,8 +75,8 @@ class KPMapExporter:  			sectorLeft = layerX / 16  			sectorTop = layerY / 16 -			sectorRight = (layerX + layerWidth) / 16 -			sectorBottom = (layerY + layerHeight) / 16 +			sectorRight = (layerX + layerWidth - 1) / 16 +			sectorBottom = (layerY + layerHeight - 1) / 16  			rawSectors = []  			for i in xrange(sectorBottom - sectorTop + 1): @@ -107,7 +108,7 @@ class KPMapExporter:  			# now add the created sectors to the data  			count = reduce(lambda x,y: x+len(y), rawSectors, 0) -			sectorMap = [-1 for i in xrange(count)] +			sectorMap = [0xFFFF for i in xrange(count)]  			destIdx = 0  			for srcRow in rawSectors: @@ -126,6 +127,7 @@ class KPMapExporter:  					destIdx += 1  			self.sectorBounds = (sectorLeft, sectorTop, sectorRight, sectorBottom) +			self.realBounds = (layerX, layerY, layerX+layerWidth-1, layerY+layerHeight-1)  			self.sectorMap = sectorMap  	class DoodadLayerExporter(LayerExporter): @@ -170,6 +172,7 @@ class KPMapExporter:  		requiredFixUps = []  		stringsToAdd = set()  		textures = set() +		tilesets = set()  		offsets = {None: 0xFFFFFFFF}  		# first off, build the sectors @@ -192,6 +195,22 @@ class KPMapExporter:  			requiredFixUps.append((len(data), layer))  			data += zero32 +		# map all paths to unlock info +		unlockInfo = {} + +		for node in self.map.pathLayer.nodes: +			if not node.level: continue + +			checked = set() +			affected = [] +			self._findUnlocksForNode(node, checked, affected) + +			level1, level2 = node.level + +			for item, secret in affected: +				unlockInfo[item] = (level1, level2, secret) + +  		# now build the layers  		for eLayer in self.layers:  			layer = eLayer.layer @@ -203,12 +222,15 @@ class KPMapExporter:  				data += u32.pack(0)  				# tileset name -				stringsToAdd.add(layer.tileset) -				requiredFixUps.append((len(data), layer.tileset)) +				tileset = '/Maps/%s.bin' % layer.tileset +				tilesets.add(tileset) +				stringsToAdd.add(tileset) +				requiredFixUps.append((len(data), ('tileset', tileset)))  				data += zero32  				# sector info  				data += struct.pack('>IIII', *eLayer.sectorBounds) +				data += struct.pack('>IIII', *eLayer.realBounds)  				data += ''.join(map(u16.pack, eLayer.sectorMap))  				pad = (4 - (len(data) & 3)) % 4 @@ -246,7 +268,7 @@ class KPMapExporter:  						loopid = self.ANIM_LOOPS.index(rLoop)  						curveid = self.ANIM_CURVES.index(rCurve)  						typeid = self.ANIM_TYPES.index(rType) -						data += struct.pack('>iififf', loopid, curveid, rFrames, typeid, rStart, rEnd) +						data += struct.pack('>iiiiiiii', loopid, curveid, rFrames, typeid, rStart, rEnd, 0, 0)  			elif isinstance(eLayer, self.PathLayerExporter):  				data += u32.pack(2) @@ -271,9 +293,38 @@ class KPMapExporter:  					x, y = node.position  					current = len(data) -					data += struct.pack('>hhiiiiii', x, y, 0, 0, 0, 0, 0, 0) +					data += struct.pack('>hhiiiiii', x+12, y+12, 0, 0, 0, 0, 0, 0) + +					# this varies +					if node.isStop(): +						# figure out the exits by direction +						leftExit, rightExit, upExit, downExit = None, None, None, None + +						for exit in node.exits: +							start, end = exit._startNodeRef(), exit._endNodeRef() +							opposite = end if (start == node) else start + +							oX, oY = opposite.position +							deltaX, deltaY = oX-x, oY-y +							angle = math.degrees(math.atan2(deltaX, deltaY)) % 360 +							print "Here: %d,%d Opposite %d,%d Delta: %d,%d Angle: %d" % (x,y,oX,oY,deltaX,deltaY,angle) + +							# Left = 270, Right = 90, Up = 180, Down = 0 +							if angle >= 225 and angle <= 315: +								leftExit = exit +							elif angle >= 45 and angle <= 135: +								rightExit = exit +							elif angle > 135 and angle < 225: +								upExit = exit +							elif angle > 315 or angle < 45: +								downExit = exit + +						exits = [leftExit, rightExit, upExit, downExit] + +					else: +						# not a stop, so just dump them in +						exits = node.exits + [None,None,None,None] -					exits = node.exits + [None,None,None,None] # TODO  					requiredFixUps.append((current+4, exits[0]))  					requiredFixUps.append((current+8, exits[1]))  					requiredFixUps.append((current+12, exits[2])) @@ -320,26 +371,13 @@ class KPMapExporter:  					data += (zero32 * 4) -					data += struct.pack('>fi', path.movementSpeed, path.animation) +					try: +						unlockL1, unlockL2, isSecret = unlockInfo[path] +						unlockType = (2 if isSecret else 1) +					except KeyError: +						unlockL1, unlockL2, unlockType = 0, 0, 0 -		# unlocking paths/nodes! -		unlocks = [] -		us = struct.Struct('>bbbbi') - -		for node in self.map.pathLayer.nodes: -			if not node.level: continue - -			checked = set() -			affected = [] -			self._findUnlocksForNode(node, checked, affected, True) - -			level1, level2 = node.level - -			for item, secret in affected: -				unlocks.append(us.pack(secret, level1, level2, 0, offsets[item])) - -		struct.pack_into('>ii', data, 8, len(unlocks), len(data)) -		data += ''.join(unlocks) +					data += struct.pack('>bbbbfi', unlockType, unlockL1, unlockL2, 1, path.movementSpeed, path.animation)  		# now that we're almost done... pack the strings  		for string in stringsToAdd: @@ -348,16 +386,21 @@ class KPMapExporter:  			data += '\0'  		# textures -		texHeaderStartOffset = len(data) -		texHeaderEndOffset = texHeaderStartOffset + (len(textures) * 0x20) +		texPadding = ((len(data) + 0x1F) & ~0x1F) - len(data) +		data += ('\0' * texPadding) -		texDataStartOffset = (texHeaderEndOffset + 0x1F) & ~0x1F -		texPadding = texDataStartOffset - texHeaderEndOffset +		texHeaderStartOffset = len(data) +		texDataStartOffset = texHeaderStartOffset + ((len(textures) + len(tilesets)) * 0x20)  		currentTexOffset = texDataStartOffset  		imageData = [] +		struct.pack_into('>ii', data, 8, len(textures), len(data)) +		for setname in tilesets: +			offsets[('tileset', setname)] = len(data) +			data += self._buildGXTexObjRGB5A3(1024, 512, offsets[setname]) +  		for tex in textures:  			offsets[tex] = len(data)  			data += self._buildGXTexObjRGB5A3(tex.width(), tex.height(), currentTexOffset) @@ -366,7 +409,6 @@ class KPMapExporter:  			imageData.append(converted)  			currentTexOffset += len(converted) -		data += ('\0' * texPadding)  		for piece in imageData:  			data += piece @@ -381,7 +423,7 @@ class KPMapExporter:  	ANIM_TYPES = ['X Position', 'Y Position', 'Angle', 'X Scale', 'Y Scale', 'Opacity'] -	def _findUnlocksForNode(self, node, checked, affected, isFirstBranch=False, secret=None): +	def _findUnlocksForNode(self, node, checked, affected, isFirstBranch=True, secret=None):  		if node in checked: return  		checked.add(node) @@ -415,11 +457,11 @@ class KPMapExporter:  		# Format: RGB5A3 (5)  		# Wrap: CLAMP (0)  		return struct.pack('>IIIIIIIHH', -				0x10, 0, -				(0x20000 | ((height - 1) << 10) | (width - 1)), -				imgOffset, # (imgptr >> 5) +				0x90, 0, +				(0x500000 | ((height - 1) << 10) | (width - 1)), +				0x10000000 + imgOffset, # (imgptr >> 5)  				0, 0, 0, -				(((width + 3) / 4) * ((height + 3) / 4)) & 0x1FFFF, +				(((width + 3) / 4) * ((height + 3) / 4)) & 0x7FFF,  				0x0202  				) | 
