def saveNewArea(self, innerfilename, course_new, L0_new, L1_new, L2_new): """ Save the level back to a file (when adding a new or deleting an existing Area) """ # Make a new archive newArchive = SarcLib.SARC_Archive() # Create a folder within the archive courseFolder = SarcLib.Folder('course') newArchive.addFolder(courseFolder) # Go through the areas, save them and add them back to the archive for areanum, area in enumerate(self.areas): course, L0, L1, L2 = area.save(True) if course is not None: courseFolder.addFile(SarcLib.File('course%d.bin' % (areanum + 1), course)) if L0 is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1), L0)) if L1 is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1), L1)) if L2 is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1), L2)) if course_new is not None: courseFolder.addFile(SarcLib.File('course%d.bin' % (len(self.areas) + 1), course_new)) if L0_new is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL0.bin' % (len(self.areas) + 1), L0_new)) if L1_new is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL1.bin' % (len(self.areas) + 1), L1_new)) if L2_new is not None: courseFolder.addFile(SarcLib.File('course%d_bgdatL2.bin' % (len(self.areas) + 1), L2_new)) # Here we have the new inner-SARC savedata innersarc = newArchive.save()[0] # Now make an outer SARC outerArchive = SarcLib.SARC_Archive() # Add the innersarc to it outerArchive.addFile(SarcLib.File(innerfilename, innersarc)) # Make it easy for future Miyamotos to pick out the innersarc level name outerArchive.addFile(SarcLib.File('levelname', innerfilename.encode('utf-8'))) # Add all the other stuff, too for szsThingName in globals.szsData: if szsThingName in [globals.levelNameCache, 'levelname']: continue outerArchive.addFile(SarcLib.File(szsThingName, globals.szsData[szsThingName])) # Save the outer sarc and return it return outerArchive.save()[0]
def save(self, innerfilename): """ Save the level back to a file """ print("") print("Saving level...") # Make a new archive newArchive = SarcLib.SARC_Archive() # Create a folder within the archive courseFolder = SarcLib.Folder('course') newArchive.addFolder(courseFolder) # Go through the areas, save them and add them back to the archive for areanum, area in enumerate(self.areas): course, L0, L1, L2 = area.save(innerfilename) if course is not None: courseFolder.addFile( SarcLib.File('course%d.bin' % (areanum + 1), course)) if L0 is not None: courseFolder.addFile( SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1), L0)) if L1 is not None: courseFolder.addFile( SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1), L1)) if L2 is not None: courseFolder.addFile( SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1), L2)) # Here we have the new inner-SARC savedata innersarc = newArchive.save(0x04, 0x170) globals.szsData[innerfilename] = innersarc # Now make an outer SARC outerArchive = SarcLib.SARC_Archive() # Add the innersarc to it outerArchive.addFile(SarcLib.File(innerfilename, innersarc)) # Make it easy for future Miyamotos to pick out the innersarc level name outerArchive.addFile( SarcLib.File('levelname', innerfilename.encode('utf-8'))) globals.szsData['levelname'] = innerfilename.encode('utf-8') # Save all the tilesets if globals.Area.tileset1: tilesetData = SaveTileset(1) if tilesetData: globals.szsData[globals.Area.tileset1] = tilesetData if globals.Area.tileset2: tilesetData = SaveTileset(2) if tilesetData: globals.szsData[globals.Area.tileset2] = tilesetData if globals.Area.tileset3: tilesetData = SaveTileset(3) if tilesetData: globals.szsData[globals.Area.tileset3] = tilesetData # Add all the other stuff, too if os.path.isdir(globals.miyamoto_path + '/data'): szsNewData = {} szsNewData[innerfilename] = innersarc szsNewData['levelname'] = innerfilename.encode('utf-8') # Read the sprites resources xml tree = etree.parse(globals.miyamoto_path + '/miyamotodata/spriteresources.xml') root = tree.getroot() # Get all sprites' filenames and add them to a tuple sprites_xml = {} for sprite in root.iter('sprite'): id = int(sprite.get('id')) name = [] for id2 in sprite: name.append(id2.get('name')) sprites_xml[id] = tuple(name) # Look up every sprite and tileset used in each area sprites_SARC = [] tilesets_names = [] for area_SARC in globals.Level.areas: for sprite in area_SARC.sprites: sprites_SARC.append(sprite.type) if area_SARC.tileset0 not in ('', None): tilesets_names.append(area_SARC.tileset0) if area_SARC.tileset1 not in ('', None): tilesets_names.append(area_SARC.tileset1) if area_SARC.tileset2 not in ('', None): tilesets_names.append(area_SARC.tileset2) if area_SARC.tileset3 not in ('', None): tilesets_names.append(area_SARC.tileset3) sprites_SARC = tuple(set(sprites_SARC)) tilesets_names = tuple(set(tilesets_names)) # Sort the filenames for each "used" sprite sprites_names = [] for sprite in sprites_SARC: for sprite_name in sprites_xml[sprite]: sprites_names.append(sprite_name) sprites_names = tuple(set(sprites_names)) # Look up each needed file and add it to our archive for sprite_name in sprites_names: # Get it from inside the original archive if not globals.OverwriteSprite and sprite_name in globals.szsData: outerArchive.addFile( SarcLib.File(sprite_name, globals.szsData[sprite_name])) szsNewData[sprite_name] = globals.szsData[sprite_name] # Get it from the "custom" data folder elif os.path.isfile(globals.miyamoto_path + '/data/custom/' + sprite_name): with open( globals.miyamoto_path + '/data/custom/' + sprite_name, 'rb') as f: f1 = f.read() outerArchive.addFile(SarcLib.File(sprite_name, f1)) szsNewData[sprite_name] = f1 # Get it from the data folder elif os.path.isfile(globals.miyamoto_path + '/data/' + sprite_name): with open(globals.miyamoto_path + '/data/' + sprite_name, 'rb') as f: f1 = f.read() outerArchive.addFile(SarcLib.File(sprite_name, f1)) szsNewData[sprite_name] = f1 # Throw a warning because the file was not found... else: print("WARNING: Could not find the file: %s" % sprite_name) print("Expect the level to crash ingame...") # Add each tileset to our archive for tileset_name in tilesets_names: if tileset_name in globals.szsData: outerArchive.addFile( SarcLib.File(tileset_name, globals.szsData[tileset_name])) szsNewData[tileset_name] = globals.szsData[tileset_name] globals.szsData = szsNewData else: # data folder not found, copy the files for szsThingName in globals.szsData: if szsThingName in [ globals.levelNameCache, innerfilename, 'levelname' ]: continue outerArchive.addFile( SarcLib.File(szsThingName, globals.szsData[szsThingName])) # Save the outer sarc and return it print("") print('\n'.join( sorted([x.name for x in outerArchive.contents], key=str.lower))) print("") print("Saved!") print("") return outerArchive.save(0x2000)