From 1a7f17d93189ae9981ff286d67c9b0406e99ce96 Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 24 Jul 2012 15:55:58 +0200 Subject: preparing for exporting --- src/exporter.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/exporter.py') diff --git a/src/exporter.py b/src/exporter.py index 2396633..f39497f 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -191,7 +191,8 @@ class KPMapExporter: sectorData = self._packSectorData(sectors) # now that we've got that, we can pack the first part of the file - data = bytearray(struct.pack('>IIII', len(self.layers), 16 + len(sectorData), 0, 0)) + data = bytearray(struct.pack('>IIIII', len(self.layers), 20 + len(sectorData), 0, 0, 0)) + requiredFixUps.append((16, 'UnlockBytecode')) # list of layer pointers goes here.. or will, later data += sectorData @@ -420,6 +421,14 @@ class KPMapExporter: for piece in imageData: data += piece + # at the end comes the unlock bytecode + offsets['UnlockBytecode'] = len(data) + unlockBytecode = '' + # note: subtract 1 from the world and level number when saving + # note: also limit world to 1-10 in the parser + # note: enforce maximum term limit (64) + # note: block recursion too much + # to finish up, correct every offset for offset, target in requiredFixUps: u32.pack_into(data, offset, offsets[target]) -- cgit v1.2.3 From faaa82bd81f24fc897a5d0ae912381413625ddeb Mon Sep 17 00:00:00 2001 From: Treeki Date: Wed, 25 Jul 2012 00:36:42 +0200 Subject: moving to desktop --- src/exporter.py | 111 ++++++++++++++++++++++++++------------------------------ 1 file changed, 51 insertions(+), 60 deletions(-) (limited to 'src/exporter.py') diff --git a/src/exporter.py b/src/exporter.py index f39497f..c4bb410 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -201,22 +201,6 @@ 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 @@ -279,6 +263,14 @@ class KPMapExporter: elif isinstance(eLayer, self.PathLayerExporter): data += u32.pack(2) + # before we do anything, build the list of secret levels + # we'll need that + levelsWithSecrets = set() + + for path in layer.paths: + if hasattr(path, 'unlockSpec'): + self._checkSpecForSecrets(path.unlockSpec, levelsWithSecrets) + # lists current = len(data) nodeArray = current + 16 @@ -344,8 +336,9 @@ class KPMapExporter: if node.isStop(): if node.level: level1, level2 = node.level - # i i b b b b: node type, Extra pointer, world, level, padding (hasSecret?), padding - data += struct.pack('>iibbbb', 2, 0, level1, level2, 0, 0) + hasSecret = (1 if ((level1,level2) in levelsWithSecrets) else 0) + # i i b b b b: node type, Extra pointer, world, level, hasSecret, padding + data += struct.pack('>iibbbb', 2, 0, level1, level2, hasSecret, 0) elif node.mapChange: data += u32.pack(3) # node type @@ -364,7 +357,10 @@ class KPMapExporter: data += u32.pack(0) # node type data += u32.pack(0) # Extra pointer - for path in layer.paths: + pathIndices = {} + + for i, path in enumerate(layer.paths): + pathIndices[path] = i offsets[path] = len(data) start = path._startNodeRef() @@ -380,13 +376,7 @@ class KPMapExporter: data += (zero32 * 4) - try: - unlockL1, unlockL2, isSecret = unlockInfo[path] - unlockType = (2 if isSecret else 1) - except KeyError: - unlockL1, unlockL2, unlockType = 0, 0, 0 - - data += struct.pack('>bbbbfi', unlockType, unlockL1, unlockL2, 1, path.movementSpeed, path.animation) + data += struct.pack('>bbbbfi', 1, 0, 0, 0, path.movementSpeed, path.animation) # now that we're almost done... pack the strings for string in stringsToAdd: @@ -423,11 +413,32 @@ class KPMapExporter: # at the end comes the unlock bytecode offsets['UnlockBytecode'] = len(data) - unlockBytecode = '' - # note: subtract 1 from the world and level number when saving - # note: also limit world to 1-10 in the parser - # note: enforce maximum term limit (64) - # note: block recursion too much + + # first off, build a map of unlocks + unlockLists = {} + + for path in self.map.pathLayer.paths: + if not hasattr(path, 'unlockSpec'): + continue + spec = path.unlockSpec + if spec is None: + continue + + try: + lst = unlockLists[spec] + except KeyError: + lst = [] + unlockLists[spec] = lst + lst.append(path) + + # now produce the thing + from unlock import packUnlockSpec + + for spec, lst in unlockLists.iteritems(): + data += packUnlockSpec(spec) + data += chr(len(lst)) + for p in lst: + data += u16.pack(pathIndices[p]) # to finish up, correct every offset for offset, target in requiredFixUps: @@ -439,36 +450,16 @@ class KPMapExporter: ANIM_CURVES = ['Linear', 'Sinusoidial', 'Cosinoidial'] ANIM_TYPES = ['X Position', 'Y Position', 'Angle', 'X Scale', 'Y Scale', 'Opacity'] + def _checkSpecForSecrets(self, spec, levelSet): + kind = spec[0] - def _findUnlocksForNode(self, node, checked, affected, isFirstBranch=True, secret=None): - if node in checked: return - - checked.add(node) - - for path in node.exits: - if path not in checked: - checked.add(path) - self._findUnlocksForPath(path, node, checked, affected, isFirstBranch, secret) - - - def _findUnlocksForPath(self, path, sourceNode, checked, affected, isFirstBranch, secret=None): - start, end = path._startNodeRef(), path._endNodeRef() - if start == sourceNode: - destNode = end - if isFirstBranch and path.unlocks != 1: - return - else: - destNode = start - if isFirstBranch and path.unlocks != 2: - return - - if secret is None: - secret = path.secret - affected.append((path, secret)) - - if not destNode.isStop(): - self._findUnlocksForNode(destNode, checked, affected, False, secret) - + if kind == 'level': + k, one, two, secret = spec + if secret: + levelSet.add((one, two)) + elif kind == 'and' or kind == 'or': + for term in spec[1]: + self._checkSpecForSecrets(term, levelSet) def _buildGXTexObjRGB5A3(self, width, height, imgOffset): # Format: RGB5A3 (5) -- cgit v1.2.3 From e0aebec63011cbcb676caa92948e25c62fd6c17b Mon Sep 17 00:00:00 2001 From: Treeki Date: Wed, 25 Jul 2012 14:11:19 +0200 Subject: exporting of unlockable paths done --- src/exporter.py | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'src/exporter.py') diff --git a/src/exporter.py b/src/exporter.py index c4bb410..2f99a56 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -210,6 +210,7 @@ class KPMapExporter: if isinstance(eLayer, self.TileLayerExporter): data += u32.pack(0) + data += u32.pack(0xFF000000) # tileset name tileset = '/Maps/Texture/%s.bin' % layer.tileset @@ -228,6 +229,7 @@ class KPMapExporter: elif isinstance(eLayer, self.DoodadLayerExporter): data += u32.pack(1) + data += u32.pack(0xFF000000) # doodad list try: @@ -262,13 +264,14 @@ class KPMapExporter: elif isinstance(eLayer, self.PathLayerExporter): data += u32.pack(2) + data += zero32 # before we do anything, build the list of secret levels # we'll need that levelsWithSecrets = set() for path in layer.paths: - if hasattr(path, 'unlockSpec'): + if hasattr(path, 'unlockSpec') and path.unlockSpec is not None: self._checkSpecForSecrets(path.unlockSpec, levelsWithSecrets) # lists @@ -337,8 +340,8 @@ class KPMapExporter: if node.level: level1, level2 = node.level hasSecret = (1 if ((level1,level2) in levelsWithSecrets) else 0) - # i i b b b b: node type, Extra pointer, world, level, hasSecret, padding - data += struct.pack('>iibbbb', 2, 0, level1, level2, hasSecret, 0) + # i i i b b b b: node type, isNew, Extra pointer, world, level, hasSecret, padding + data += struct.pack('>iiibbbb', 2, 0, 0, level1, level2, hasSecret, 0) elif node.mapChange: data += u32.pack(3) # node type @@ -347,15 +350,17 @@ class KPMapExporter: requiredFixUps.append((len(data)+4, destMap)) stringsToAdd.add(destMap) - # i i b b b b: Extra pointer, dest map, map ID, foreign ID, transition, padding - data += struct.pack('>iibbbb', 0, 0, node.mapID, node.foreignID, node.transition, 0) + # i i i b b b b: isNew, Extra pointer, dest map, map ID, foreign ID, transition, padding + data += struct.pack('>iiibbbb', 0, 0, 0, node.mapID, node.foreignID, node.transition, 0) else: data += u32.pack(1) # node type - data += u32.pack(0) # Extra pointer + data += zero32 # isNew + data += zero32 # Extra pointer else: - data += u32.pack(0) # node type - data += u32.pack(0) # Extra pointer + data += zero32 # node type + data += zero32 # isNew + data += zero32 # Extra pointer pathIndices = {} @@ -376,7 +381,11 @@ class KPMapExporter: data += (zero32 * 4) - data += struct.pack('>bbbbfi', 1, 0, 0, 0, path.movementSpeed, path.animation) + available = 0 + if (not hasattr(path, 'unlockSpec')) or path.unlockSpec is None: + available = 3 + + data += struct.pack('>bbbbfi', available, 0, 0, 0, path.movementSpeed, path.animation) # now that we're almost done... pack the strings for string in stringsToAdd: @@ -416,6 +425,8 @@ class KPMapExporter: # first off, build a map of unlocks unlockLists = {} + + from unlock import stringifyUnlockData for path in self.map.pathLayer.paths: if not hasattr(path, 'unlockSpec'): @@ -424,6 +435,10 @@ class KPMapExporter: if spec is None: continue + # we stringify it first because the specs become lists when + # imported from the kpmap (not tuples) and those can't be + # used as dict keys + spec = stringifyUnlockData(spec) try: lst = unlockLists[spec] except KeyError: @@ -432,10 +447,10 @@ class KPMapExporter: lst.append(path) # now produce the thing - from unlock import packUnlockSpec + from unlock import parseUnlockText, packUnlockSpec for spec, lst in unlockLists.iteritems(): - data += packUnlockSpec(spec) + data += packUnlockSpec(parseUnlockText(spec)) data += chr(len(lst)) for p in lst: data += u16.pack(pathIndices[p]) -- cgit v1.2.3