BTW, as long as we're on this topic and it seems to get more hits. What functions/features do people want to see from both tools? I eventually do run out of ideas of what to add to make it better, or fix issues that are present in it.
Regarding Nif Texture Stripper, I'd like an option to automatically strip the Textures\ prefix from path containing only the texture filename and no other subdirs, for instance
Textures\tx_name.dds could be simply tx_name.dds, as the Textures folder is the default one.
This way there would not be unneeded changes to nifs referencing textures in the default directory, and some bytes spared. By the way, thanks for the added option to keep original file dates
Regarding SmartMerger, as a player continuously modding/changing my playing list
, I am mainly interested about merging a few mods at a time than making a handy for playing but hard to re-mod unique 1GByte mega-mod, so I'd like a option to generate only merged objects similar to TESTools, and /or eventually merged leveled lists similar to Mash /tes3cmd.exe multipatch.
So far I have mainly tested how to interface it with Mash, to be able to select multiple files in Mash and feed them to Data Files\SmartMerger.exe, it makes things easier.
As I'm not Python savvy, I'm mainly copying and pasting, here are changes to masher.py, Python experts feel free to fix!
Code tag sorry, spoiler tag spoils indentation
#-- ... ( other Mash code here )class File_Sort(Link): """Sort the selected files.""" def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('Sort')) menu.AppendItem(menuItem) if len(data) < 2: menuItem.Enable(False) def Execute(self,event): """Handle menu selection.""" message = _("This command will sort the selected files alphabetically, assigning them dates one minute after each other. It cannot be undone.\n\nNote that some mods need to be in a specific order to work correctly, and this sort operation may break that order.") if ContinueQuery(self.window,message,'mash.sortMods.continue',_('Sort Mods')) != wx.ID_OK: return #--Scan for earliest date fileInfos = self.window.data newTime = min(fileInfos[fileName].mtime for fileName in self.data) #--Do it for fileName in sorted(self.data,key=lambda a: a[:-4].lower()): fileInfos[fileName].setMTime(newTime) newTime += 60 #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()#--begin changes by abot#------------------------------------------------------------------------------class File_UpdateTime(Link): def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('Update time from current system time')) menu.AppendItem(menuItem) if len(data) < 1: menuItem.Enable(False) def Execute(self,event): message = _("This command will update the time of selected files, starting from current system time, keeping the same plugin order. It cannot be undone (at least, not in a single step).\nIt is meant to be used with files displayed in loading order. If you know what you are doing, this function is great to sort/move entire groups of files that must be loaded last, keeping the relative loading order (just ctrl+click or shift+click the files to organize).") if ContinueQuery(self.window,message,'masher.File_UpdateTimeFromCurrentSystemTime.continue',_('Update time from current system time')) != wx.ID_OK: return #--Scan fileInfos = self.window.data newTime = time.time() #--Do it for fileName in self.data: fileInfos[fileName].setMTime(newTime) newTime += 60 #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()#------------------------------------------------------------------------------class File_UpdateTimeFromCurrentTime(Link): """Sort the selected files.""" def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('Update Time from first selected file time')) menu.AppendItem(menuItem) if len(data) < 1: menuItem.Enable(False) def Execute(self,event): message = _("This command will update the time of selected files, starting from the time of first selected file, keeping the same file order. It cannot be undone (at least, not in a single step).\nIt is meant to be used with files displayed in loading order. If you know what you are doing, this function is great to sort/move entire groups of files keeping the relative loading order (just ctrl+click or shift+click the files to organize).") if ContinueQuery(self.window,message,'masher.File_UpdateTimeFromCurrentFileTime.continue',_('Update Time from first selected file time')) != wx.ID_OK: return #--Scan for earliest date fileInfos = self.window.data newTime = fileInfos[self.data[0]].mtime for fileName in self.data: newTime = min(newTime,fileInfos[fileName].mtime) #--Do it for fileName in self.data: fileInfos[fileName].setMTime(newTime) newTime += 60 #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()# tes3cmd.exe clean --replace [selected files]#------------------------------------------------------------------------------class File_tes3cmd(Link): def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('tes3cmd.exe clean --replace [selected files] > out.txt')) menu.AppendItem(menuItem) if len(data) < 1: menuItem.Enable(False) def Execute(self,event): message = _("This command will call Data Files\\tes3cmd.exe clean --replace passing selected files.") if ContinueQuery(self.window,message,'masher.File_tes3cmd.continue',_('tes3cmd.exe clean --replace [selected files]')) != wx.ID_OK: return #--Scan fileInfos = self.window.data path = os.path.join(settings['mwDir'],'Data Files') exe = os.path.join(path,'tes3cmd.exe') args = ['tes3cmd.exe'] args.append('clean') for fileName in self.data: args.append('"' + fileName + '"') args.append('--replace') #args.append('>') #args.append('out.txt') #--debug #print exe #for x in args: #print x cwd = os.getcwd() os.chdir(path) os.spawnv(os.P_NOWAIT,exe,args) os.chdir(cwd) #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()#------------------------------------------------------------------------------class File_SmartMerge(Link): def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('SmartMerge selected files to smartmerged.esp')) menu.AppendItem(menuItem) if len(data) < 2: menuItem.Enable(False) def Execute(self,event): message = _("This command will call Data Files\\SmartMerger.exe passing selected files, creating smartmerged.esp.") if ContinueQuery(self.window,message,'masher.File_SmartMerge.continue',_('SmartMerge selected files to smartmerged.esp')) != wx.ID_OK: return #--Scan fileInfos = self.window.data path = os.path.join(settings['mwDir'],'Data Files') exe = os.path.join(path,'SmartMerger.exe') args = ['SmartMerger.exe'] for fileName in self.data: args.append('"' + fileName + '"') #args.append('--reference') args.append('smartmerged.esp') #--debug #print exe #for x in args: #print x cwd = os.getcwd() os.chdir(path) os.spawnv(os.P_NOWAIT,exe,args) os.chdir(cwd) #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()#------------------------------------------------------------------------------class File_SmartMerge2(Link): def AppendToMenu(self,menu,window,data): Link.AppendToMenu(self,menu,window,data) menuItem = wx.MenuItem(menu,self.id,_('SmartMerge selected files to smartmerged.esp with --no_disabled_fix option')) menu.AppendItem(menuItem) if len(data) < 2: menuItem.Enable(False) def Execute(self,event): message = _("This command will call Data Files\\SmartMerger.exe passing selected files with --no_disabled_fix option, creating smartmerged.esp.") if ContinueQuery(self.window,message,'masher.File_SmartMerge2.continue',_('SmartMerge selected files to smartmerged.esp with --no_disabled_fix option')) != wx.ID_OK: return #--Scan fileInfos = self.window.data path = os.path.join(settings['mwDir'],'Data Files') exe = os.path.join(path,'SmartMerger.exe') args = ['SmartMerger.exe'] for fileName in self.data: args.append('"' + fileName + '"') args.append('--no_disabled_fix') args.append('smartmerged.esp') #--debug #for x in args: #print x cwd = os.getcwd() os.chdir(path) os.spawnv(os.P_NOWAIT,exe,args) os.chdir(cwd) #--Refresh fileInfos.refreshDoubleTime() self.window.Refresh()#--end changes by abot#-- ... ( other Mash code here ) fileMenu.links.append(File_Sort()) #--begin changes by abot fileMenu.links.append(File_UpdateTime()) fileMenu.links.append(File_UpdateTimeFromCurrentTime()) fileMenu.links.append(File_tes3cmd()) fileMenu.links.append(File_SmartMerge()) fileMenu.links.append(File_SmartMerge2()) #--end changes by abot
[EDIT]fixed double quote
[EDIT2]changed from args = [exe] to args = ['SmartMerger.exe'], seems to work better with path stripped
[EDIT3]updated; options to sort files like TESTool, to call tes3cmd, to call smartmerged with or without --no_disabled_fix option