struct RstExpressionFinder ( expressionToUse = undefined, fn getDlcBranch pathArg stopConcatAt:"art" = ( local branch = "" local stopConcat = false local pathPartArr = filterString pathArg "/\\" splitEmptyTokens:false for part in pathPartArr do ( if not stopConcat do ( if finditem pathPartArr part > 1 do branch += "/" if ((stricmp part stopConcatAt) == 0) then ( stopConcat = true ) else branch += part ) ) return branch ), -- Gets the ped meta and syncs it fn getPedMeta branch = ( local pedMetaPath = branch + "build/dev_ng/common/data/peds.meta" try(gRsPerforce.sync pedMetaPath callerName:"ExpressionFinder" force:true)catch("Problem syncing ped meta.") return pedMetaPath ), -- Gets the expression set from meta fn getExpressionSet metaPath currCharName = ( local doc = dotNetObject "System.Xml.XmlDocument" doc.load metaPath local root = doc.childNodes.ItemOf[1] -- 0 is the xml header node local rootChildCount = root.childNodes.count -- Get the InitDatas node, where we search for our character local initDatasNode = undefined for childNum=0 to rootChildCount-1 do ( local currNode = root.childNodes.ItemOf[childNum] if currNode.Name == "InitDatas" do initDatasNode = currNode ) if (initDatasNode != undefined) do ( local exprSetName = undefined local itemNodeCount = initDatasNode.childNodes.count for itemNodeNum=0 to itemNodeCount-1 do ( if (exprSetName == undefined) do ( local itemNode = initDatasNode.childNodes.ItemOf[itemNodeNum] for itemParamNum=0 to itemNode.childNodes.count-1 do ( local currItemParamNode = itemNode.childNodes.ItemOf[itemParamNum] if (currItemParamNode.Name == "Name") and (stricmp currItemParamNode.InnerText currCharName == 0) do ( local targetItemNode = itemNode -- Search the same itemNode for the ExpressionDictionaryName for targetItemParamNum=0 to targetItemNode.childNodes.count-1 do ( local targetParamNode = targetItemNode.childNodes.ItemOf[targetItemParamNum] if targetParamNode.Name == "ExpressionDictionaryName" do ( exprSetName = targetParamNode.InnerText return exprSetName ) ) ) ) ) ) ) ), fn getExpressionOrderDict exprFiles = ( local exprOrderDict = #() -- Get the setup xmls for exprFile in exprFiles do ( if (matchPattern exprFile pattern:"*assets_ng*") do -- Check if the found file is in the assets_ng directory ( local orderVal = 0 local exprFile_local = gRsPerforce.depot2local exprFile -- The local file path local xmlPathBase = this.getDlcBranch exprFile_local stopConcatAt:"assets_ng"-- Get the dlc branch local xmlPath = xmlPathBase + "build/dev_ng/setup2.xml" gRsPerforce.sync xmlPath force:true if doesFileExist xmlPath do ( local doc = dotNetObject "System.Xml.XmlDocument" doc.Load xmlPath local setupDataNode = doc.childNodes.ItemOf[1] -- 0 is the xml header node local setupDataChildCount = setupDataNode.childNodes.count for dataNodeNum=0 to setupDataChildCount-1 do ( local dataNode = setupDataNode.childNodes.ItemOf[dataNodeNum] if (stricmp dataNode.Name "order" == 0) do ( try(orderVal = dataNode.Attributes.ItemOf["value"].Value)catch() ) ) ) -- Add the expr file and its pack order value to a dict for comparison append exprOrderDict (dataPair expression:exprFile orderValue:(orderVal as integer)) ) ) return exprOrderDict ), fn getHighestExpr exprOrderDict = ( local exprToUse = undefined local exprVal = -1 for dp in exprOrderDict do ( if dp.orderValue > exprVal do ( exprToUse = dp.expression exprVal = dp.orderValue ) ) return exprToUse ), fn run triggeredByUser:false = ( -- Abort if a max file is not open if (maxFileName == "") do ( if triggeredByUser do ( messageBox "Please run this within the max file of the target ped." ) print "Please run this within the max file of the target ped." return false ) -- Launch a progress indicator progressStart "Finding Expression..." -- Init the expression field of the struct this.expressionToUse = undefined -- Connect to p4 gRsPerforce.Connect() progressUpdate 10 --local maxPath = RsMakeSafeSlashes (toLower (getUserProp selection[1] "UDP3DSMAX")) -- UDP usage discarded local maxPath = RsMakeSafeSlashes (toLower (maxFilePath + maxFileName)) local maxPath_parts = filterString maxPath "/" splitEmptyTokens:false local projectRoot = maxPath_parts[1] + "/" + maxPath_parts[2] -- Store character name local charName = getFileNameFile maxPath local exprSetname = undefined -- Find DLC Pack for the current file local devBranch = "assets_ng" local dlcBranch = getDlcBranch maxPath stopConcatAt:"art" progressUpdate 25 -- Get the ped meta local pedMeta = this.getPedMeta dlcBranch -- Get the expression set from the ped meta local exprSetName = this.getExpressionSet pedMeta charName progressUpdate 35 -- Search perforce for the .expr files (OLDER METHOD) /* pathBase = projectRoot + "/mpPacks" pathTrail = "anim/expressions/" + exprSetName + "/Components/Head_000_R.expr" p4SearchPath = pathBase + "..." + pathTrail local exprRecords = gRsPerforce.FILES p4SearchPath */ progressUpdate 50 -- Search perforce for the .expr files local exprRecords = #() local pathTrail = "anim/expressions/" + exprSetName + "/Components/Head_000_R.expr" local pathBases = #((projectRoot + "/mpPacks/"), "//depot/gta5/assets_ng/") for pBase in pathBases do ( local p4SearchPath = pBase + "..." + pathTrail local eRecords = gRsPerforce.FILES p4SearchPath if (eRecords.count > 0) do join exprRecords eRecords ) makeUniqueArray exprRecords progressUpdate 75 -- Get all expressions and their order value from its build xml local exprOrderDict = this.getExpressionOrderDict exprRecords -- Get the final expression to use, i.e. the one with the highest pack order local finalExpr_depot = this.getHighestExpr exprOrderDict gRsPerforce.sync finalExpr_depot this.expressionToUse = gRsPerforce.depot2local finalExpr_depot progressUpdate 85 if (this.expressionToUse != undefined) then ( print("Expression Found: " + (this.expressionToUse as string)) ) else print("Could not find expression for target ped.") progressUpdate 100 progressEnd() ) )