-- Model-specific includes filein "pipeline/export/ui/weapon_exporter_ui.ms" filein "pipeline/export/model.ms" filein "pipeline/util/rb_script_generator.ms" filein "pipeline/util/skinutils.ms" filein "pipeline/export/rb_image.ms" filein "pipeline/export/models/globals.ms" -- Additional includes filein "pipeline/util/ruby.ms" filein "pipeline/util/texturemetatag_utils.ms" filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms") struct SlotItemStruct ( index, paths, usage ) struct plantsMgr_Constructor ( iddArchivePath = (RsConfigGetAssetsDir()+"export/models/plantsmgr.idd.zip"), iddArchiveTempPath = (RsConfigGetAssetsDir()+"export/models/plantsmgr.idd.TEMP.zip"), iddFolderPath = (RsConfigGetAssetsDir()+"export/models/plantsmgr.idd"), itdArchivePath = (RsConfigGetAssetsDir()+"export/textures/plantsmgr.itd.zip"), zipFile, modelArc, extractPath = (sysInfo.tempdir + "PlantsMgr"), modelPath, modelName, --zipHandler = dotnetobject "Ionic.zip", modelItems = #(), slot, model, lod, usageAssigned = #(), texturePath = (RsConfigGetArtDir()+"textures/vegetation"), txIndex, txLod, baseTxName = "txgrass", itdSourceTexturePaths = #(), itdSourceTextureIndex = "PlantMgr_SrcTexture_Index.dat", extractedINI = (extractPath + "/PlantMgr_SrcTexture_Index.dat"), plantsTxdEnum = #( DataPair idx:1 name:"Country", DataPair idx:2 name:"Ocean", DataPair idx:0 name:"All" ), plantsTxdPaths = #( DataPair name:#all path:(RsConfigGetAssetsDir()+"export/textures/plantsmgr.itd.zip"), DataPair name:#country path:(RsConfigGetAssetsDir()+"export/textures/plantsmgr1.itd.zip"), DataPair name:#ocean path:(RsConfigGetAssetsDir()+"export/textures/plantsmgr2.itd.zip") ), changeListNum = undefined, --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn buildIdd = ( --check access first if (getFileAttribute iddArchivePath #readonly) then ( messagebox ("The file: "+iddArchivePath+"\nIs write protected.\nIt needs to be checked out of perforce before continuing") title:"Error" return false ) if modelPath == undefined then ( messagebox "There is no model path specified." return false ) --set base object name base = ("grass"+model) try ( --extract current zip into it deleteFile extractPath if (not (doesfileExist extractPath)) then makeDir extractPath zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read iddArchivePath zipFile.TempFileFolder = extractPath modelArc = (dotNetClass "Ionic.Zip.ZipFile").Read modelPath --build a directory name from slot and model modelName = getFilenamePath modelArc.item[0].filename local target = case lod Of ( "base":base "lod1":(base+"_lod1") "lod2":(base+"_lod2") ) --get files from the exported model --for i = 1 to modelArc.count do print zipFile.item[i].filename --for item in modelArc where item.fileName != "entity.textures" do extractAction = dotNetClass "Ionic.Zip.ExtractExistingFileAction" for i=0 to (modelArc.count - 1) where not (matchPattern modelArc.item[i].filename pattern:"*.textures") do ( append modelItems modelArc.item[i].filename modelArc.item[i].extract extractPath extractAction.OverwriteSilently ) modelArc.dispose() --remove the old entries entries = #() for i=0 to (zipFile.count - 1) where (matchPattern zipFile.item[i].filename pattern:(target+"/*")) do ( append entries zipFile.item[i].filename ) for item in entries do zipFile.RemoveEntry item --add them to the plant manager archive zipFile.UpdateDirectory (extractPath+"/"+modelName) target --save the zip try ( print "saving" zipFile.Save iddArchivePath ) catch ( --messagebox "Could not save PlantsMgr, Is it open somewhere else?" title:"Error" --clean up if modelArc != undefined then modelArc.dispose() if zipFile != undefined then zipFile.dispose() return false ) ) catch ( if modelArc != undefined then modelArc.dispose() if zipFile != undefined then zipFile.dispose() messagebox "problems" title:"Error" return false ) --clean up if modelArc != undefined then modelArc.dispose() if zipFile != undefined then zipFile.dispose() deleteFile iddArchiveTempPath return true ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn localBuild mode = ( if mode == "idd" then ( --RsRunIronRubyScript (RsConfigGetToolsDir() + "ironlib\\util\\data_convert_file.rb") args:#(iddArchivePath) AP3Invoke.convert #(iddArchivePath) debug:true ) else if mode == "itd" then ( --RsRunIronRubyScript (RsConfigGetToolsDir() + "ironlib\\util\\data_convert_file.rb") args:#(itdArchivePath) AP3Invoke.convert #(itdArchivePath) debug:true ) ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn pickTexture = ( local oldTexturePath = texturePath local newTexturePath = getOpenFileName caption:"Texture path" types:"dds(*.dds)|*.dds" if newTexturePath == undefined then return false if getFilenameType newTexturePath != ".dds" then texturePath = undefined --if texturePath == undefined then texturePath = oldTexturePath --return --print texturePath texturePath = newTexturePath texturePath ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn extractItd = ( if (getDirectories extractPath).count == 0 then makeDir extractPath zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath zipFile.TempFileFolder = extractPath zipFile.ExtractAll extractPath (dotNetClass "Ionic.Zip.ExtractExistingFileAction").OverwriteSilently --clean zipFile.dispose() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Perforce changelist handling --//////////////////////////////////////////////////////////////////////////////////////////////////// fn checkoutArchive inPath = ( if (getFileAttribute inPath #readonly) do ( if (changeListNum == undefined) do ( changeListNum = gRsPerforce.createChangeList "PlantsMgr.itd changes" ) gRsPerforce.add_or_edit inPath gRsPerforce.addToChangelist changeListNum inPath ) return ok ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Preapre the archive for building by adding or removing entries -- based on what usage type is assigned --//////////////////////////////////////////////////////////////////////////////////////////////////// fn prepareArchive type = ( --Perforce checkout checkoutArchive itdArchivePath --work through the list, if it matches the type then add the item to the archive, or remove it. local typeName = type as String local entries = for item in itdSourceTexturePaths where ((tolower item.usage) == (tolower typeName)) collect item.index --now look through the entries in the archive local archive = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath local theNames = for i=0 to (archive.count - 1) collect archive.item[i].filename --Remove an entires that are not needed for thisName in theNames do ( if ((findString thisName "txgrass") != undefined) do --just the txgrass textures ( local thisNameIndex = substituteString ((filterString (getFilenameFile thisName) "_")[1]) "txgrass" "" --local lodName = if ((findstring thisName "_lod1") == undefined) then ((getFilenameFile thisName) + "_lod1.dds") else thisName if ((findItem entries thisNameIndex) == 0) then --remove the zip entry ( archive.RemoveEntry thisName ) ) ) --Add any that are... for filePath in (getFiles (extractPath + "/*.dds")) do ( local fileName = pathConfig.stripPathToLeaf filePath if ((findString fileName "txgrass") != undefined) do --just the txgrass textures ( local thisNameIndex = substituteString ((filterString (getFilenameFile fileName) "_")[1]) "txgrass" "" if ((findItem entries thisNameIndex) != 0) then --add the zip entry ( archive.UpdateFile (extractPath + "/" + fileName ) "" ) ) ) archive.Save() archive.Dispose() return True ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn buildItd type = ( local doBuild = true --prepare the temporary dir with the content required for the itd type --build based on which itd archive is required, set the itdArchivepath accordingly case type of ( #country: ( for item in plantsTxdPaths where (item.name == #country) do itdArchivePath = item.path doBuild = prepareArchive #country ) #ocean: ( for item in plantsTxdPaths where (item.name == #ocean) do itdArchivePath = item.path doBuild = prepareArchive #ocean ) default: --building all ( for item in plantsTxdPaths where (item.name == #all) do itdArchivePath = item.path ) ) --Perforce checkout checkoutArchive itdArchivePath -- if (getFileAttribute itdArchivePath #readonly) then -- ( -- messagebox ("The file: "+itdArchivePath+"\nIs write protected.\nIt needs to be checked out of perforce before continuing") title:"Error" -- return false -- ) --proceed wih build if doBuild do ( localBuild "itd" ) ), --//////////////////////////////////////////////////////////////////////////////////////////////////// --return a list of the textures used in the slots --//////////////////////////////////////////////////////////////////////////////////////////////////// fn getItdFileList = ( local itdItems = #() zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath local zipFileSorted = zipFile.EntriesSorted for i=1 to zipFileSorted.count do ( local thisEntry = zipFileSorted.item[i-1] append itdItems thisEntry.fileName ) --clean zipFile.dispose() return itdItems ), --//////////////////////////////////////////////////////////////////////////////////////////////////// --Extract the source texture index file from the itd archive --//////////////////////////////////////////////////////////////////////////////////////////////////// fn getItdIndexList = ( zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath --extract the index list local entry = zipFile.Item "PlantMgr_SrcTexture_Index.dat" itdSourceTextureIndex = entry.Extract extractPath (dotNetClass "Ionic.Zip.ExtractExistingFileAction").OverwriteSilently if doesFileExist extractedINI then ( for slot in (getINIsetting extractedINI) do ( local base = getINIsetting extractedINI slot "base" local lod1 = getINIsetting extractedINI slot "lod1" local usage = getINISetting extractedINI slot "usage" append itdSourceTexturePaths (SlotItemStruct index:slot paths:#(base, lod1) usage:usage) ) ) else ( print "cant find extractedINI" ) --clean zipFile.dispose() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Insert an entry into the index --//////////////////////////////////////////////////////////////////////////////////////////////////// fn insertItdIndexListItem index column sourcePath = ( --Perforce Checkout checkoutArchive itdArchivePath if itdSourceTexturePaths == undefined then getItdIndexList() local formattedIndex = if index < 10 then "0" + (index as String) else index as String local columnName = if (column == 1) then "base" else "lod1" --update the index dat setINISetting extractedINI formattedIndex columnName sourcePath zipFile.UpdateFile extractedINI "" zipFile.Save() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Indsert the given source texture into the archive -- renaming it for the slot its going into --//////////////////////////////////////////////////////////////////////////////////////////////////// fn insertItdTexture index column sourcePath = ( --Perforce Checkout checkoutArchive itdArchivePath zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath local formattedIndex = if index < 10 then "0" + (index as String) else index as String lod = if (column == 2) then lod = "_lod1" else lod = "" local slotFormattedName = "txgrass" + formattedIndex + lod + ".dds" local tempSlotPath = (extractPath + "/" + slotFormattedName) local sourceFileName = pathConfig.stripPathToLeaf sourcePath --copy the new file and rename it to the slot name --first try to delete the existing one if it exists at the extractpath if doesFileExist tempSlotPath then ( if (getFileAttribute tempSlotPath #readonly) do ( setFileAttribute tempSlotPath #readonly false ) deleteFile tempSlotPath ) copyFile sourcePath tempSlotPath if doesFileExist tempSlotPath then --copied okay ( --update the file zipFile.UpdateFile tempSlotPath "" --update the index file insertItdIndexListItem index column sourcePath ) --clean up zipFile.Dispose() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Insert a usage type into the archive index dat --//////////////////////////////////////////////////////////////////////////////////////////////////// fn insertIndexUsage index usageName = ( --Perforce Checkout checkoutArchive itdArchivePath itdSourceTexturePaths[index+1].usage = usageName zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath local formattedIndex = if index < 10 then "0" + (index as String) else index as String setINISetting extractedINI formattedIndex "usage" usageName zipFile.UpdateFile extractedINI "" zipFile.Save() zipFile.Dispose() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn buildSourceTextureNameTable = ( if itdSourceTexturePaths == undefined then getItdIndexList() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// --Delete a slot entry from the archive --//////////////////////////////////////////////////////////////////////////////////////////////////// fn deleteSlot index column = ( local formattedIndex = if index < 10 then "0" + (index as String) else index as String --local success = false --if deleting the base slot then also delete the lod slot, else just get rid of the lod local base = if column == 1 then true else false local itdList = for item in getItdFileList() where matchPattern item pattern:"txgrass*" collect item --delete the slot textures zipFile = (dotNetClass "Ionic.Zip.ZipFile").Read itdArchivePath --get the archive file list local fileList = #() local entryIt = zipFile.EntryFileNames.GetEnumerator() while entryIt.MoveNext() != false do ( append fileList entryIt.current ) local basePath = ("txgrass" + formattedIndex + ".dds") local lodPath = ("txgrass" + formattedIndex + "_lod1.dds") if base then --delete base and lod ( --base --if entry exists then remove it if findItem fileList basePath != 0 then ( zipFile.RemoveEntry basePath --delete extracted deleteFile (extractPath + "/" + basePath) ) --lod if findItem fileList lodPath != 0 then ( zipFile.RemoveEntry lodPath --delete extracted deleteFile (extractPath + "/" + lodPath) ) --update the index dat setINISetting extractedINI formattedIndex "base" "unknownsource" setINISetting extractedINI formattedIndex "lod1" "unknownsource" ) else --lod ( zipFile.RemoveEntry lodPath --delete extracted deleteFile (extractPath + "/" + lodPath) --update the index dat setINISetting extractedINI formattedIndex "lod1" "unknownsource" ) zipFile.UpdateFile extractedINI "" zipFile.Save() --clean up zipFile.Dispose() ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Get a dotnet bitmap from a max bitmap --//////////////////////////////////////////////////////////////////////////////////////////////////// fn getDNBitmapFromMax imgPath = ( if imgPath == undefined then return false local bm = openbitmap imgPath setclipboardbitmap bm local clippy = dotnetclass "System.Windows.Forms.Clipboard" if clippy.containsimage() then ( free bm return clippy.GetImage() ) else ( free bm return false ) ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn getExtractedSlotPath index lod:false = ( local padding = if index < 10 then "0" else "" lodSuffix = if lod then "_lod1" else "" local slotPath = (extractPath + "/txgrass" + padding + (index as String) + lodSuffix + ".dds") if doesFileExist slotPath then ( return (extractPath + "/txgrass" + padding + (index as String) + lodSuffix + ".dds") ) return undefined ), --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn shutdown = ( modelArc = undefined zipFile = undefined ), on create do ( extractItd() ) ) ----END STRUCT --check for existing tool instance if PlantMgrUI != undefined then ( destroydialog PlantMgrUI ) --UI rollout PlantMgrUI "Plant Manager" ( dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:PlantMgrUI.width local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"PlantsManagerMaker" filename:(getThisScriptFilename()) local plantMgr = plantsMgr_Constructor() local banks = for i = 0 to 31 collect (if i<10 then ("0" + i as string) else (i as string)) local headers = #("Slot", "Texture", "LOD", "Usage") local pickedRow = 0 local pickedCell = 0 local bitmapPreviews = #() local emptyBitmapPath = (RsConfigGetWildWestDir() + "etc/config/general/collision_textures/Default.bmp") local bmpPreviewSize = 192 local blankBitmap = bitmap bmpPreviewSize bmpPreviewSize color:black local blankDNBitmap = dotNetObject "System.Drawing.Bitmap" bmpPreviewSize bmpPreviewSize local streamPath = "x:/streamGTA5/models" local usageTypes = sort(for item in plantMgr.plantsTxdEnum collect item.name) ------------------------------------------------------------------------------------ -- DotNet values: ------------------------------------------------------------------------------------ local textFont, dingFont, textFontBold local DNknownColour = dotNetClass "system.Drawing.KnownColor" local DNcolour = dotNetClass "System.Drawing.Color" local selColour = DNcolour.fromKnownColor DNknownColour.MenuHighlight local textCol = (colorMan.getColor #windowText) * 255 local windowCol = (colorMan.getColor #window) * 255 local notLoadedCol = if (windowCol[1] < 128) then (windowCol * 1.5) else (windowCol * 0.85) local textColour = DNcolour.FromArgb textCol[1] textCol[2] textCol[3] local backColour = DNcolour.FromArgb windowCol[1] windowCol[2] windowCol[3] group "Drawable (idd)" ( --label lblSlot "Slot" across:2 align:#left --dropdownlist ddlSlot "" items:#("0", "1", "2", "3") label lblModel "Model" across:2 align:#left dropdownlist ddlModel "" items:banks across:1 label lblLod "Lod" across:2 align:#left dropdownlist ddlLod "" items:#("base", "lod1", "lod2") across:1 button btnInsert "Insert" width:120 ) dotNetControl lstTextures "DataGridView" width:300 height:450 across:3 bitmap bmpPreview width:bmpPreviewSize height:bmpPreviewSize offset:[180, 0] dropdownlist ddlUsageOpts "Usage" items:usageTypes offset:[-10, 200] --group "Texture (itd)" --( --bitmap bmpPreview width:bmpPreviewSize height:bmpPreviewSize offset:[40,0] groupbox grpItdControls "ITD" width:570 height:95 offset:[0, 0] button btnReloadItd "Reload" width:550 offset:[0, -80] dropdownlist ddlArchiveBuild "Archive:" items:#("All", "Country", "Ocean") across:2 offset:[10, 0] button btnBuildItd "Build" width:230 offset:[0, 17] --edittext txtIdtTx "" text:"Press Pick!" --button btnPickTx "Pick" width:120 --label lblTxSlot "Index" across:2 align:#left --dropdownlist ddlTxSlot "" items:(for i=0 to 31 collect i as String) --label lblTxLod "Lod" across:2 align:#left --dropdownlist ddlTxLod "" items:#("base", "lod1") across:1 --button btnTxInsert "Insert" width:120 --) --#--#--#--#--#--#--#--#--#--#--#--#--#--# --Functions --#--#--#--#--#--#--#--#--#--#--#--#--#--# --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn getUsageIndex usageName = ( local index = 0 for i=1 to usageTypes.count where ((tolower usageTypes[i]) == (tolower usageName)) do index = i --retval index ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn updateList = ( --lstTextures.Rows.Clear() plantMgr.getItdIndexList() local itdRAWList = plantMgr.getItdFileList() local cleanedList = for item in itdRAWList where matchPattern item pattern:"txgrass*" collect item local filledSlots = makeUniqueArray (for item in cleanedList collect (item[8]+item[9]) as Integer) --print filledSlots local itdList = #() local j = 1 for i=0 to 31 do ( if filledSlots[j] != i then ( append itdList undefined ) else ( append itdList (i as String) j += 1 ) ) --now populate the rows accounting for gaps where itdList is empty for i=0 to 31 do ( local thisIdx = if i<10 then thisIdx = ("0"+ i as String) else i as String --local itdIndex = itdList[itdIdx][8] + itdList[itdIdx][9] local itdIndex = itdList[i+1] --format "thisIdx: % itdIndex: % \n" thisIdx itdIndex if itdList[i+1] != undefined then ( local i = thisIdx as integer --Base_Layer local previewImage = blankDNBitmap local imgPath = plantMgr.getExtractedSlotPath i if imgPath != undefined then ( previewImage = plantMgr.getDNBitmapFromMax imgPath ) --print plantMgr.itdSourceTexturePaths[i+1].paths[1] local sourceTexName = plantMgr.itdSourceTexturePaths[i+1].paths[1] lstTextures.Rows.item[i].cells.item[1].value = previewImage lstTextures.Rows.item[i].cells.item[1].tag = sourceTexName --LOD previewImage = blankDNBitmap imgPath = plantMgr.getExtractedSlotPath i lod:true if imgPath != undefined then ( previewImage = plantMgr.getDNBitmapFromMax imgPath ) sourceTexName = plantMgr.itdSourceTexturePaths[i+1].paths[2] lstTextures.Rows.item[i].cells.item[2].value = previewImage lstTextures.Rows.item[i].cells.item[2].tag = sourceTexName --Usage local usageText = plantMgr.itdSourceTexturePaths[i+1].usage plantMgr.usageAssigned[i+1] = getUsageIndex usageText lstTextures.Rows.item[i].cells.item[3].value = usageText ) else ( lstTextures.Rows.item[i].cells.item[1].value = "EMPTY" lstTextures.Rows.item[i].cells.item[2].value = "EMPTY" ) ) ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn init = ( --lstTextures.pos.x = 0 lstTextures.RowHeadersVisible = false lstTextures.AllowUserToAddRows = false lstTextures.AllowUserToDeleteRows = false lstTextures.AllowUserToOrderColumns = false lstTextures.AllowUserToResizeRows = false lstTextures.AllowUserToResizeColumns = true lstTextures.AllowDrop = false lstTextures.MultiSelect = false lstTextures.ReadOnly = true lstTextures.dock = lstTextures.dock.fill lstTextures.DefaultCellStyle.backColor = backColour lstTextures.DefaultCellStyle.foreColor = textColour textFont = lstTextures.font dingFont = dotNetObject "System.Drawing.Font" "Webdings" textFont.size textFontBold = dotnetobject "system.drawing.font" textFont (dotnetclass "system.drawing.fontstyle").bold lstTextures.EnableHeadersVisualStyles = false lstTextures.ColumnHeadersDefaultCellStyle.backColor = backColour lstTextures.ColumnHeadersDefaultCellStyle.foreColor = textColour lstTextures.ColumnHeadersDefaultCellStyle.font = textFontBold lstTextures.ColumnHeadersHeight = 30 lstTextures.Rows lstTextures.SelectionMode = (dotNetClass "DataGridViewSelectionMode").FullRowSelect lstTextures.height = 450 lstTextures.width = 350 --startSize = GetIniRolloutSize() --arrangeCtrls size:startSize local colNum for item=1 to headers.count do ( case item of ( 1: --slot index ( colNum = lstTextures.Columns.add headers[item] headers[item] ) 4: --Usage type ( colNum = lstTextures.Columns.add headers[item] headers[item] lstTextures.Columns.item[colNum].headertext = headers[item] ) default: --Images ( colNum = lstTextures.Columns.add (dotNetObject "DataGridViewImageColumn") lstTextures.Columns.item[colNum].headertext = headers[item] ) ) /* if item == 1 then ( colNum = lstTextures.Columns.add headers[item] headers[item] ) else ( colNum = lstTextures.Columns.add (dotNetObject "DataGridViewImageColumn") lstTextures.Columns.item[colNum].headertext = headers[item] ) */ lstTextures.Columns.item[colNum].sortMode = (dotnetclass "DataGridViewColumnSortMode").NotSortable ) local firstCol = lstTextures.Columns.item[0] local lastCol = lstTextures.Columns.item[colNum] firstCol.width = 40 lastCol.AutoSizeMode = lastCol.AutoSizeMode.Fill --build slot rows for i=0 to 31 do ( local idx = i as String lstTextures.Rows.add #(idx, "EMPTY", "EMPTY", "EMPTY") lstTextures.Rows.item[i].height = 40 ) ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn updateCellContents newPath = ( lstTextures.Rows.item[pickedRow].cells.item[pickedCell].value = plantMgr.getDNBitmapFromMax newPath lstTextures.Rows.item[pickedRow].cells.item[pickedCell].tag = newPath ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn createBitmapPreview bmPath = ( bmpPreview.filename = bmPath ) --//////////////////////////////////////////////////////////////////////////////////////////////////// --Events dear boy --//////////////////////////////////////////////////////////////////////////////////////////////////// --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// fn ddlUsageOptsSelected arg = ( --get the list index and set the item accordingly lstTextures.Rows.item[pickedRow].cells.item[3].value = usageTypes[arg] plantMgr.usageAssigned[pickedRow + 1] = getUsageIndex usageTypes[arg] plantMgr.insertIndexUsage pickedRow usageTypes[arg] ) on ddlUsageOpts selected arg do ddlUsageOptsSelected arg --//////////////////////////////////////////////////////////////////////////////////////////////////// -- The insert action for the Drawable idd --//////////////////////////////////////////////////////////////////////////////////////////////////// on btnInsert pressed do ( --check access first if (getFileAttribute plantMgr.iddArchivePath #readonly) then ( messagebox ("The file: " + plantMgr.iddArchivePath + "\nIs write protected.\nIt needs to be checked out of perforce before continuing") title:"Error" return false ) --get the slot and model --print ddlSlot.selected --plantMgr.slot = ddlSlot.selected plantMgr.model = ddlModel.selected plantMgr.lod = ddlLod.selected --Export selected if ( 0 == selection.count ) then ( MessageBox "No objects selected." title:"Model Export Error" return false ) --check the model has all empty texture slots local nonEmptyMaps = #() if selection[1].material == undefined then ( messagebox "This object is missing its material.\n Please correct it." title:"FATAL ERROR" return false ) else if classof selection[1].material == Multimaterial then ( matIDs = #() RsMatGetMapIdsUsedOnObject selection[1] matIDs local meshMaterial = selection[1].material.materialList[(findItem selection[1].material.materialIDList matIDs[1])] local numSubMaps = getNumSubTexmaps meshMaterial local nonEmptyMaps = for i=1 to numSubMaps where getSubTexmap meshMaterial i != undefined collect true ) else ( local meshMaterial = selection[1].material local numSubMaps = getNumSubTexmaps meshMaterial local nonEmptyMaps = for i=1 to numSubMaps where getSubTexmap meshMaterial i != undefined collect true ) if nonEmptyMaps.count == 0 then ( messagebox "This object is missing some texture assignment. Please correct it." title:"Missing textures" return false ) -- Save our output directory. --delete it if it exists to purge it --RsDeleteDirectory streamPath local dnDir = dotnetclass "System.IO.Directory" if (dnDir.Exists @"x:\streamGTA5\models\") then ( dnDir.Delete @"x:\streamGTA5\models\" True ) RsModelSetOutputDirectory (streamPath + "/") -- Export all geometry. local drawableDirs = #() RsModelExportGroup selection asciiMesh:false local drawableDirs = for dir in (getdirectories (streamPath + "/*")) collect RsMakeSafeSlashes dir --delete any textures, we want only the txd ones, no drawables textures for dir in drawableDirs do ( for f in getfiles (dir + "*.dds") do ( deleteFile f ) ) -- Constuct drawable dictionary IDD file. local script = RsModelOutputDirectory + "create_idd.rb" if ( 0 != ( RsModelScriptGenerator.BuildDrawableDictionary script plantMgr.iddArchiveTempPath drawableDirs ) ) then MessageBox "Failed to build drawable dictionary file." title:"Model Export Error" --get the exported drawable dict (idd) plantMgr.modelPath = plantMgr.iddArchiveTempPath --stuff into the appropriate place in success = plantMgr.buildIdd() --build the data if success then ( plantMgr.localBuild("idd") messagebox "PlantsMgr.idd updated!" title:"Success" ) ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- --//////////////////////////////////////////////////////////////////////////////////////////////////// on btnReloadItd pressed do ( updateList() ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- This saves the PlantsMgr.itd.zip --//////////////////////////////////////////////////////////////////////////////////////////////////// on btnBuildItd pressed do ( plantMgr.buildItd (ddlArchiveBuild.selected as Name) ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- Right click menu opts --//////////////////////////////////////////////////////////////////////////////////////////////////// on lstTextures mouseDown args do ( local clickPoint = dotNetObject "System.Drawing.Point" args.x args.y local clickedItem = lstTextures.hitTest args.x args.y if (clickedItem != undefined) do ( pickedRow = clickedItem.rowIndex pickedCell = clickedItem.columnIndex --format "rowNum: % cellNum: % \n" rowNum cellNum if (pickedRow != -1) and (lstTextures.selectedRows.count != 0) do ( local rightClick = args.button.equals args.button.right -- RIGHT CLICK if rightClick then --show the popup menu options ( -- Rightclick menu: rcmenu RSmenu_textureOps ( local selRows menuItem itmSeltexture "Choose Texture" menuItem itmPhotoshop "Open texture in Photoshop" menuItem itmDelTexture "Delete Texture" -- Select selected textures' objects: on itmSeltexture picked do ( local validPath = plantMgr.pickTexture() if validPath == false then return false if plantMgr.texturePath != undefined then ( --print plantMgr.texturePath --textureName = filenameFromPath plantMgr.texturePath --stuff the name into the slot updateCellContents plantMgr.texturePath --add a new bitmap for the preview createBitmapPreview plantMgr.texturePath --replace the name in the itd index file --plantMgr.insertItdIndexListItem pickedRow pickedCell plantMgr.texturePath --replace the bitmap in the itd archive plantMgr.insertItdTexture pickedRow pickedCell plantMgr.texturePath plantMgr.insertIndexUsage pickedRow "All" ) ) -- Open selected textures in Photoshop: on itmPhotoshop picked do ( local selTexFilename = lstTextures.Rows.item[pickedRow].cells.item[pickedCell].tag --print selTexFilename if selTexFileName == "unknownsource" then ( messagebox "Unknown source texture" title:"Unknown" ) else if (doesFileExist selTexFileName) then ( format "Opening in Photoshop: %\n" selTexFilename shelllaunch ("Photoshop.exe") selTexFilename ) else ( messagebox "Cant find that file locally" title:"Missing File" ) ) --delete the item from the dictionary on itmDelTexture picked do ( --delete base + lod if pickedCell == 1 then ( lstTextures.Rows.item[pickedRow].cells.item[pickedCell].value = undefined lstTextures.Rows.item[pickedRow].cells.item[pickedCell+1].value = undefined ) else ( lstTextures.Rows.item[pickedRow].cells.item[pickedCell].value = undefined ) plantMgr.deleteSlot pickedRow pickedCell ) on RSmenu_textureOps open do ( ) ) popUpMenu RSmenu_textureOps ) --LEFT CLICK else --left click will update the texture preview ( local cellValue = lstTextures.Rows.item[pickedRow].cells.item[pickedCell].value --print cellValue if cellValue != "EMPTY" then ( local slotTex = "/txgrass" + (if pickedRow < 10 then "0" else "") + pickedRow as String + (if pickedCell == 2 then "_lod1" else "") + ".dds" --print (plantMgr.extractPath + slotTex) if doesFileExist (plantMgr.extractPath + slotTex) then ( bmpPreview.filename = plantMgr.extractPath + slotTex ) else ( bmpPreview.bitmap = blankBitmap ) --set the usage combo value local usageColumnValue = lstTextures.Rows.item[pickedRow].cells.item[3].value ddlUsageOpts.selection = plantMgr.usageAssigned[pickedRow + 1] ) else --empty slot ( bmpPreview.bitmap = blankBitmap ) ) ) ) ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- init --//////////////////////////////////////////////////////////////////////////////////////////////////// on PlantMgrUI open do ( banner.setup() RS_CustomDataGrid forceRecompile:true init() updateList() ) --//////////////////////////////////////////////////////////////////////////////////////////////////// -- shutdown --//////////////////////////////////////////////////////////////////////////////////////////////////// on PlantMgrUI close do ( HiddenDosCommand ("rmdir " + plantMgr.extractPath) plantMgr = undefined gc light:true ) ) ------------------- --Lets go createDialog PlantMgrUI width:590 height:700 style:#(#style_titlebar, #style_resizing, #style_sysmenu, #style_minimizebox, #style_maximizebox)