-- -- File:: rockstar/helpers/pedvarcutmgr.ms -- Description:: Rockstar Ped Variation Manager for .cut files: -- Allows artists to visualise ped variations and ped props and write out a result to a cut file -- for c class cutscene characters -- -- Author:: Luke Openshaw -- Date:: 18/06/2007 -- ----------------------------------------------------------------------------- -- Uses ----------------------------------------------------------------------------- filein "pipeline/util/string.ms" filein "rockstar/util/material.ms" filein "pipeline/util/file.ms" filein "rockstar/export/settings.ms" filein "rockstar/helpers/ShowMapsinViewport.ms" RsPedName = "" RsDefaultTextureLocation = maxfilepath + "Textures\\TGA\\*" RsVarTexLst = #() RsVarMeshLst = #() ----------------------------------------------------------------------------- -- Rollout ----------------------------------------------------------------------------- rollout RsTexVarRoll "Texture Swap Util" width:720 height:250 ( ) rollout RsCsPedVarMgrRoll "CS Ped Variation Manager" width:720 height:250 ( struct modelEntry (modelName, animName, facialAnimName) struct variationEntry (modelIdx, componentIdx, drawableIdx, textureIdx, swapTime=0) struct propEntry (modelIdx, propIdx, anchorIdx) local modelLst = #() local variationLst = #() local propLst = #() local varTexLst = #() local varTexPathLst = #() local HEAD_IDX = 0 local UPPR_IDX = 1 local LOWR_IDX = 2 local SUSE_IDX = 3 local FEET_IDX = 5 local HAIR_IDX = 7 local TEEF_IDX = 9 local HAND_IDX = 4 --//////////////////////////////////////////////////////////// -- interface --//////////////////////////////////////////////////////////// hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Ped_Var_Manager" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255) dropdownlist lstHeads "Heads" pos:[10,100] width:135 height:94 dropdownlist lstUppers "Upper" pos:[150,100] width:135 height:94 dropdownlist lstLowers "Lower" pos:[290,100] width:135 height:94 dropdownlist lstFeet "Feet" pos:[430,100] width:135 height:94 dropdownlist lstSuses "Special Use" pos:[570,100] width:135 height:94 dropdownlist lstHair "Hair" pos:[710,100] width:135 height:94 dropdownlist lstTeef "Teeth" pos:[850,100] width:135 height:94 dropdownlist lstHands "Hands" pos:[990,100] width:135 height:94 dropdownlist lstTexHeads pos:[10,150] width:135 height:94 dropdownlist lstTexUppers pos:[150,150] width:135 height:94 dropdownlist lstTexLowers pos:[290,150] width:135 height:94 dropdownlist lstTexFeet pos:[430,150] width:135 height:94 dropdownlist lstTexSuses pos:[570,150] width:135 height:94 dropdownlist lstTexHair pos:[710,150] width:135 height:94 dropdownlist lstTexTeef pos:[850,150] width:135 height:94 dropdownlist lstTexHands pos:[990,150] width:135 height:94 dropdownlist lstPHeads "Heads" pos:[10,205] width:95 height:94 dropdownlist lstPEyes "Eyes" pos:[110,205] width:95 height:94 dropdownlist lstPEars "Ears" pos:[210,205] width:95 height:94 dropdownlist lstPLWrist "Left Wrist" pos:[310,205] width:95 height:94 dropdownlist lstPRWrist "Right Wrist" pos:[410,205] width:95 height:94 dropdownlist lstPLHand "Left Hand" pos:[510,205] width:95 height:94 dropdownlist lstPRhand "Right Hand" pos:[610,205] width:95 height:94 dropdownlist lstCutfiles "Cut files" pos:[210,20] width:135 height:94 dropdownlist lstModels "Characters" pos:[355,20] width:135 height:94 groupbox grpCutFileInfo "Cut File Info" pos:[200,1] width:320 height:70 groupbox grpVariations "Variations" pos:[5,80] width:1125 height:100 groupbox grpProps "Props" pos:[5,185] width:1125 height:70 button btnSaveToCut "Save To Cut" pos:[267,260] width:168 height:48 button btnCreateTexSwap "Create Texture Swap" pos:[450,260] width:168 height:48 -------------------------------------------------------------- -- Return the ped name. This centralises the base_ hack that -- I put in so whenever the ped name is required, this should -- be called -------------------------------------------------------------- fn GetPedName = ( return RsPedName ) -------------------------------------------------------------- -- Load textures from pedtex files -------------------------------------------------------------- fn LoadTextureList = ( if maxfilename == undefined then return 0 if maxfilename == "" then return 0 varTexLst = #() varTexPathLst = #() textureLocation = "" headMesh = getnodebyname "head_000_r" exact:true if headMesh != undefined then ( headMaps = #() RsGetMainTexMapsFromMaterial headMesh headMesh.material headMaps if headMaps.count > 0 then ( if headMaps[1] != undefined then ( primaryTexture = headMaps[1].filename textureLocation = (RsRemoveFile primaryTexture) + "*" ) else textureLocation = RsDefaultTextureLocation ) else textureLocation = RsDefaultTextureLocation ) else textureLocation = RsDefaultTextureLocation tempTexList = getfiles textureLocation for tex in tempTexList do ( append varTexPathLst tex append varTexLst (RsRemovePathAndExtension tex) ) RsVarTexLst = varTexLst ) -------------------------------------------------------------- -- Store the models and variations in relevant arrays -------------------------------------------------------------- fn ParseCutFileRead cutPath = ( modelLst = #() variationLst = #() propLst = #() cutFile = openFile cutPath cutFileArray = #() if cutFile != undefined then ( while eof cutFile == false do ( buffer = readLine cutFile if buffer != "" and buffer != undefined then (--buffer = "\n" append cutFileArray buffer ) ) charFound = false sectionIdx = 0 for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[MODELS]" and sectionIdx == 0 then ( while cutFileArray[i] != "[/MODELS]" do ( modelTokens = filterstring cutFileArray[i] " " if modelTokens.count > 1 then append modelLst (modelEntry modelName:modelTokens[1] animName:modelTokens[2]) i = i + 1 ) sectionIdx = sectionIdx + 1 ) else if cutFileArray[i] == "[VARIATION]" then ( while cutFileArray[i] != "[/VARIATION]" do ( variationTokens = filterstring cutFileArray[i] " " if variationTokens.count == 4 then append variationLst (variationEntry modelIdx:(variationTokens[1] as integer) componentIdx:(variationTokens[2] as integer) drawableIdx:(variationTokens[3] as integer) textureIdx:(variationTokens[4] as integer)) if variationTokens.count == 5 then append variationLst (variationEntry modelIdx:(variationTokens[1] as integer) componentIdx:(variationTokens[2] as integer) drawableIdx:(variationTokens[3] as integer) textureIdx:(variationTokens[4] as integer) swapTime:(variationTokens[4] as integer)) i = i + 1 ) variationSectionFound = true ) else if cutFileArray[i] == "[PROPS]" then ( while cutFileArray[i] != "[/PROPS]" do ( propTokens = filterstring cutFileArray[i] " " if propTokens.count == 3 then append propLst (propEntry modelIdx:(propTokens [1] as integer) propIdx:(propTokens [2] as integer) anchorIdx:(propTokens [3] as integer)) i = i + 1 ) propsSectionFound = true ) ) close cutFile ) ) -------------------------------------------------------------- -- Change the texure id from letter to a number -------------------------------------------------------------- fn ResolveTextureId texLetter = ( if texLetter == "a" then return "0" if texLetter == "b" then return "1" if texLetter == "c" then return "2" if texLetter == "d" then return "3" if texLetter == "e" then return "4" if texLetter == "f" then return "5" if texLetter == "g" then return "6" if texLetter == "h" then return "7" if texLetter == "i" then return "8" if texLetter == "j" then return "9" if texLetter == "k" then return "10" if texLetter == "l" then return "11" if texLetter == "m" then return "12" if texLetter == "n" then return "13" if texLetter == "o" then return "14" if texLetter == "p" then return "15" ) -------------------------------------------------------------- -- Write to the cut file. Nasty function -------------------------------------------------------------- fn ParseCutFileWrite cutPath = ( -- First pass reads from variation and props section cutFile = openFile cutPath cutFileArray = #() tempVarList = #() tempPropList = #() if cutFile != undefined then ( while eof cutFile == false do ( buffer = readLine cutFile if buffer != "" and buffer != undefined then (--buffer = "\n" append cutFileArray buffer ) ) sectionVarIdx = 0 sectionPropIdx = 0 for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[VARIATION]" then ( while cutFileArray[i] != "[/VARIATION]" and sectionVarIdx == 0 do ( variationTokens = filterstring cutFileArray[i] " " if variationTokens.count == 4 then ( if (variationTokens[1] as integer) != lstModels.selection - 2 then ( append tempVarList (variationEntry modelIdx:(variationTokens[1] as integer) componentIdx:(variationTokens[2] as integer) drawableIdx:(variationTokens[3] as integer) textureIdx:(variationTokens[4] as integer)) ) ) else if variationTokens.count == 5 then ( append tempVarList (variationEntry modelIdx:(variationTokens[1] as integer) componentIdx:(variationTokens[2] as integer) drawableIdx:(variationTokens[3] as integer) textureIdx:(variationTokens[4] as integer) swapTime:(variationTokens[5] as integer)) ) i = i + 1 ) sectionVarIdx = sectionVarIdx + 1 ) if cutFileArray[i] == "[PROPS]" then ( while cutFileArray[i] != "[/PROPS]" and sectionPropIdx == 0 do ( propTokens = filterstring cutFileArray[i] " " if propTokens.count == 3 then ( if (propTokens[1] as integer) != lstModels.selection - 2 then ( append tempPropList (propEntry modelIdx:(propTokens[1] as integer) propIdx:(propTokens[2] as integer) anchorIdx:(propTokens[3] as integer)) ) ) i = i + 1 ) sectionPropIdx = sectionPropIdx + 1 ) ) close cutFile ) else ( messagebox "Could not open cut file " + cutPath + " for writing" return false ) -- Second pass writes to variation section cutFile = openFile cutPath mode:"w" if cutfile != undefined then ( readingSection = false propsSectionFound = false variationSectionFound = false for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[/VARIATION]" or cutFileArray[i] == "[/PROPS]" then readingSection = false if cutFileArray[i] == "[VARIATION]" and variationSectionFound == false then ( readingSection = true format (cutFileArray[i] + "\n") to:cutFile for var in tempVarList do ( format ((var.modelIdx as string) + " " + (var.componentIdx as string) + " " + (var.drawableIdx as string) + " " + (var.textureIdx as string) + " " + (var.swapTime as string) + "\n") to:cutFile ) -- Minus 1 for the offset for maxscript 1 based arrays and another -- minus 1 for the "None" at the start of the list modelIdx = lstModels.selection - 2 if lstHeads.selection != 1 then ( meshNameTokens = filterstring lstHeads.selected "_" texNameTokens = filterstring lstTexHeads.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (HEAD_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstUppers.selection != 1 then ( meshNameTokens = filterstring lstUppers.selected "_" texNameTokens = filterstring lstTexUppers.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (UPPR_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstLowers.selection != 1 then ( meshNameTokens = filterstring lstLowers.selected "_" texNameTokens = filterstring lstTexLowers.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (LOWR_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstFeet.selection != 1 then ( meshNameTokens = filterstring lstFeet.selected "_" texNameTokens = filterstring lstTexFeet.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (FEET_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstSuses.selection != 1 then ( meshNameTokens = filterstring lstSuses.selected "_" texNameTokens = filterstring lstTexSuses.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (SUSE_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstHair.selection != 1 then ( meshNameTokens = filterstring lstHair.selected "_" texNameTokens = filterstring lstTexHair.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (HAIR_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstTeef.selection != 1 then ( meshNameTokens = filterstring lstTeef.selected "_" texNameTokens = filterstring lstTexTeef.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (TEEF_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) if lstHands.selection != 1 then ( meshNameTokens = filterstring lstHands.selected "_" texNameTokens = filterstring lstTexHands.selected "_" if meshNameTokens.count == 3 and texNameTokens.count == 5 then ( texIdx = ResolveTextureId texNameTokens[4] meshIdx = meshNameTokens[2] as integer format ((modelIdx as string) + " " + (HAND_IDX as string) + " " + (meshIdx as string) + " " + texIdx + " 0" + "\n") to:cutFile ) ) variationSectionFound = true ) else if cutFileArray[i] == "[PROPS]" and propsSectionFound == false then ( readingSection = true format (cutFileArray[i] + "\n") to:cutFile for prop in tempPropList do ( format ((prop.modelIdx as string) + " " + (prop.propIdx as string) + " " + (prop.anchorIdx as string) + "\n") to:cutFile ) modelIdx = lstModels.selection - 2 if lstPHeads.selection != 1 then ( meshNameTokens = filterstring lstPHeads.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "0" + "\n") to:cutFile ) ) if lstPEyes.selection != 1 then ( meshNameTokens = filterstring lstPEyes.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "1" + "\n") to:cutFile ) ) if lstPEars.selection != 1 then ( meshNameTokens = filterstring lstPEars.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "2" + "\n") to:cutFile ) ) if lstPLWrist.selection != 1 then ( meshNameTokens = filterstring lstPLWrist.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "6" + "\n") to:cutFile ) ) if lstPRWrist.selection != 1 then ( meshNameTokens = filterstring lstPRWrist.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "7" + "\n") to:cutFile ) ) if lstPLHand.selection != 1 then ( meshNameTokens = filterstring lstPLHand.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "4" + "\n") to:cutFile ) ) if lstPRhand.selection != 1 then ( meshNameTokens = filterstring lstPRhand.selected "_" if meshNameTokens.count == 3 then ( meshIdx = meshNameTokens[3] as integer format ((modelIdx as string) + " " + (meshIdx as string) + " " + "5" + "\n") to:cutFile ) ) propsSectionFound = true ) else if cutFileArray[i] == "[SECTION_END]" then ( if propsSectionFound == false then ( format ("[PROPS]\n") to:cutFile format ("[/PROPS]\n") to:cutFile ) if variationSectionFound == false then ( format ("[VARIATION]\n") to:cutFile format ("[/VARIATION]\n") to:cutFile ) format (cutFileArray[i] + "\n") to:cutFile ) else ( if readingSection == false then ( format (cutFileArray[i] + "\n") to:cutFile ) ) ) ) else ( messagebox "Could not open cut file " + cutPath + " for writing" return false ) if propsSectionFound == false or variationSectionFound == false then messagebox "This cut file did not have a props or a variation section. It has been added but you'll need to save to the cut file again." else messagebox "Success." close cutFile ) -------------------------------------------------------------- -- Initialise variation and prop list boxes -------------------------------------------------------------- fn InitialiseListBoxes = ( modelName = substring maxfilename 1 (maxfilename.count - 4) --execute ("select $" + modelName) --sceneObj = selection[1] sceneObj = getNodeByName modelName exact:true rootSearchStr = (substring modelName 6 (modelName.count-5)) if sceneObj == undefined then ( sceneObj = getNodeByName rootSearchStr exact:true RsPedName = substring modelName 6 (modelName.count-5) ) else RsPedName = modelName if sceneObj == undefined then ( messagebox ("Root node " + rootSearchStr + " not found. List boxes cannot be populated") return false ) headsArr = #(undefined) uppersArr = #(undefined) lowersArr = #(undefined) feetArr = #(undefined) susesArr = #(undefined) hairArr = #(undefined) teefArr = #(undefined) handsArr = #(undefined) pHeadsArr = #(undefined) pEyesArr = #(undefined) pEarsArr = #(undefined) pRWristArr = #(undefined) pLWristArr = #(undefined) pRHandArr = #(undefined) pLhandArr = #(undefined) headsNameArr = #("None") uppersNameArr = #("None") lowersNameArr = #("None") feetNameArr = #("None") susesNameArr = #("None") hairNameArr = #("None") teefNameArr = #("None") handsNameArr = #("None") pHeadsNameArr = #("None") pEyesNameArr = #("None") pEarsNameArr = #("None") pRWristNameArr = #("None") pLWristNameArr = #("None") pRHandNameArr = #("None") pLhandNameArr = #("None") for sceneObjChild in sceneObj.children do ( sceneObjChildName = RsLowercase sceneObjChild.name if (substring sceneObjChildName 1 4) == "head" then ( append headsArr sceneObjChild append headsNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "lowr" then ( append lowersArr sceneObjChild append lowersNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "uppr" then ( append uppersArr sceneObjChild append uppersNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "feet" then ( append feetArr sceneObjChild append feetNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "suse" then ( append susesArr sceneObjChild append susesNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "hair" then ( append hairArr sceneObjChild append hairNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "teef" then ( append teefArr sceneObjChild append teefNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 4) == "hand" then ( append handsArr sceneObjChild append handsNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 6) == "p_head" then ( append pHeadsArr sceneObjChild append pHeadsNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 6) == "p_eyes" then ( append pEyesArr sceneObjChild append pEyesNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 6) == "p_ears" then ( append pEarsArr sceneObjChild append pEarsNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 8) == "p_rwrist" then ( append pRWristArr sceneObjChild append pRWristNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 8) == "p_lwrist" then ( append pLWristArr sceneObjChild append pLWristNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 7) == "p_rhand" then ( append pRHandArr sceneObjChild append pRhandNameArr sceneObjChild.name ) else if (substring sceneObjChildName 1 7) == "p_lhand" then ( append pLHandArr sceneObjChild append pLhandNameArr sceneObjChild.name ) ) RsVarMeshLst = headsNameArr + lowersNameArr + uppersNameArr + feetNameArr + susesNameArr + hairNameArr + handsNameArr lstHeads.items = headsNameArr lstLowers.items = lowersNameArr lstUppers.items = uppersNameArr lstFeet.items = feetNameArr lstSuses.items = susesNameArr lstHair.items = hairNameArr lstTeef.items = teefNameArr lstHands.items = handsNameArr lstPHeads.items = pHeadsNameArr lstPEyes.items = pEyesNameArr lstPEars.items = pEarsNameArr lstPLWrist.items = pLWristNameArr lstPRWrist.items = pRWristNameArr lstPLHand.items = pLhandNameArr lstPRhand.items = pRhandNameArr lstHeads.selection = 1 lstLowers.selection = 1 lstUppers.selection = 1 lstFeet.selection = 1 lstSuses.selection = 1 lstHair.selection = 1 lstTeef.selection = 1 lstHands.selection = 1 lstPHeads.selection = 1 lstPEyes.selection = 1 lstPEars.selection = 1 lstPLWrist.selection = 1 lstPRWrist.selection = 1 lstPLHand.selection = 1 lstPRhand.selection = 1 ) -------------------------------------------------------------- -- Load the cutfile data (models and variations) -------------------------------------------------------------- fn LoadCutFileList = ( cutSceneDir = RsConfigGetCutsceneDir() filePaths = getFiles (cutSceneDir + "*.cut") files = #() for fullPath in filePaths do ( fullPathTokens = filterstring fullPath "\\" print fullPathTokens[fullPathTokens.count] append files fullPathTokens[fullPathTokens.count] ) lstCutfiles.items = files ) -------------------------------------------------------------- -- Update texture list boxes according to what' selected in the -- variation list boxes -------------------------------------------------------------- fn UpdateTexList = ( headsTexArr = #("None") uppersTexArr = #("None") lowersTexArr = #("None") feetTexArr = #("None") susesTexArr = #("None") hairTexArr = #("None") teefTexArr = #("None") handsTexArr = #("None") for texName in varTexLst do ( textureNameTokens = filterstring texName "_" if textureNameTokens.count > 2 then ( textureId = textureNameTokens[3] as integer textureName = textureNameTokens[1] + "_" + textureNameTokens[2] if RsLowercase textureName == RsLowercase "head_diff" then ( meshNameTokens = filterstring lstHeads.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append headsTexArr texName ) ) else if RsLowercase textureName == RsLowercase "lowr_diff" then ( meshNameTokens = filterstring lstLowers.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append lowersTexArr texName ) ) else if RsLowercase textureName == RsLowercase "uppr_diff" then ( meshNameTokens = filterstring lstUppers.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append uppersTexArr texName ) ) else if RsLowercase textureName == RsLowercase "feet_diff" then ( meshNameTokens = filterstring lstFeet.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append feetTexArr texName ) ) else if RsLowercase textureName == RsLowercase "suse_diff" then ( meshNameTokens = filterstring lstSuses.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append susesTexArr texName ) ) else if RsLowercase textureName == RsLowercase "hair_diff" then ( meshNameTokens = filterstring lstHair.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append hairTexArr texName ) ) else if RsLowercase textureName == RsLowercase "teef_diff" then ( meshNameTokens = filterstring lstTeef.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append teefTexArr texName ) ) else if RsLowercase textureName == RsLowercase "hand_diff" then ( meshNameTokens = filterstring lstHands.selected "_" if meshNameTokens.count == 3 then ( meshId = meshNameTokens[2] as integer if textureId == meshId then append handsTexArr texName ) ) ) ) lstTexHeads.items = headsTexArr lstTexUppers.items = uppersTexArr lstTexLowers.items = lowersTexArr lstTexFeet.items = feetTexArr lstTexSuses.items = susesTexArr lstTexHair.items = hairTexArr lstTexTeef.items = teefTexArr lstTexHands.items = handsTexArr ) fn UpdateVisibleSelection = ( select $* hide selection objs = #() --modelName = substring maxfilename 1 (maxfilename.count - 4) modelName = GetPedName() objname = lstHeads.selected if objname != undefined then objs = getnodebyname lstHeads.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstUppers.selected if objname != undefined then objs = getnodebyname lstUppers.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstLowers.selected if objname != undefined then objs = getnodebyname lstLowers.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstFeet.selected if objname != undefined then objs = getnodebyname lstFeet.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstSuses.selected if objname != undefined then objs = getnodebyname lstSuses.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstHair.selected if objname != undefined then objs = getnodebyname lstHair.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstTeef.selected if objname != undefined then objs = getnodebyname lstTeef.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstTeef.selected if objname != undefined then objs = getnodebyname lstHands.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPHeads.selected if objname != undefined then objs = getnodebyname lstPHeads.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPEyes.selected if objname != undefined then objs = getnodebyname lstPEyes.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPEars.selected if objname != undefined then objs = getnodebyname lstPEars.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPLWrist.selected if objname != undefined then objs = getnodebyname lstPLWrist.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPRWrist.selected if objname != undefined then objs = getnodebyname lstPRWrist.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPLHand.selected if objname != undefined then objs = getnodebyname lstPLHand.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) objname = lstPRhand.selected if objname != undefined then objs = getnodebyname lstPRhand.selected all:true for obj in objs do ( if RsLowercase obj.parent.name == RsLowercase modelName then unhide obj ) ) fn ResolveTexPathId texName = ( i = 1 for tex in varTexLst do ( if texName == tex then return i i = i + 1 ) return -1 ) -------------------------------------------------------------- -- Map the selected texture on the relevant component and draw -------------------------------------------------------------- fn UpdateVisibleTexSelection lstObj lstObjTex = ( texList = #() objname = lstObj.selected if objname != undefined then obj = getnodebyname lstObj.selected if obj != undefined then ( texPathId = ResolveTexPathId lstObjTex.selected RsGetMainTexMapsFromMaterial obj obj.material texList if texList[1] != undefined then ( if texPathId != -1 then texList[1].filename = varTexPathLst[texPathId] texList[1].reload() ) else messagebox ("There is something wrong with material applied to " + objname + ". Slap the character artist who owns this model") ) ) fn ResolveCutVariationEntry variation lstObject = ( drawableIdx = variation.drawableIdx found = false i = 1 for meshName in lstObject.items do ( meshToken = filterstring meshName "_" if meshToken.count > 1 then ( meshIdx = meshToken[2] as integer if drawableIdx == meshIdx then lstObject.selection = i found = true ) i = i + 1 ) if found == false then messagebox "Bogus mesh index. Are you sure you have the correct model loaded?" ) fn ResolveCutTexVariationEntry variation lstObject = ( textureIdx = variation.textureIdx found = false i = 1 for meshName in lstObject.items do ( meshToken = filterstring meshName "_" if meshToken.count > 1 then ( meshIdxStr = (ResolveTextureID meshToken[4]) if meshIdxStr != undefined then ( meshIdx = meshIdxStr as integer ) if textureIdx == meshIdx then lstObject.selection = i found = true ) i = i + 1 ) --if found == false then messagebox "Bogus texture index. Are you sure you have the correct model loaded?" ) fn ResolveCutPropEntry prop lstObject = ( propIdx = prop.propIdx found = false i = 1 for meshName in lstObject.items do ( meshToken = filterstring meshName "_" if meshToken.count > 2 then ( meshIdx = meshToken[3] as integer if propIdx == meshIdx then lstObject.selection = i found = true ) i = i + 1 ) if found == false then messagebox "Bogus mesh index. Are you sure you have the correct model loaded?" ) fn RefreshVariations = ( lstModels.visible = true lstHeads.visible = true lstUppers.visible = true lstLowers.visible = true lstFeet.visible = true lstSuses.visible = true lstHair.visible = true lstTeef.visible = true lstHands.visible = true lstPHeads.visible = true lstPEyes.visible = true lstPEars.visible = true lstPLWrist.visible = true lstPRWrist.visible = true lstPLHand.visible = true lstPRhand.visible = true lstTexHeads.visible = true lstTexUppers.visible = true lstTexLowers.visible = true lstTexFeet.visible = true lstTexSuses.visible = true lstTexHair.visible = true lstTexTeef.visible = true lstTexHands.visible = true modelIdx = lstModels.selection - 2 varListForChar = #() propListForChar = #() for var in variationLst do ( if (var.modelIdx as integer) == modelidx then append varListForChar var ) for variation in varListForChar do ( if variation.componentIdx == HEAD_IDX then ( --head ResolveCutVariationEntry variation lstHeads --ResolveCutTexVariationEntry variation lstTexHeads ) else if variation.componentIdx == UPPR_IDX then ( --uppr ResolveCutVariationEntry variation lstUppers --ResolveCutTexVariationEntry variation lstTexUppers ) else if variation.componentIdx == LOWR_IDX then ( --lowr ResolveCutVariationEntry variation lstLowers --ResolveCutTexVariationEntry variation lstTexLowers ) else if variation.componentIdx == SUSE_IDX then ( --suse ResolveCutVariationEntry variation lstSuses --ResolveCutTexVariationEntry variation lstTexSuse ) else if variation.componentIdx == FEET_IDX then ( --feet ResolveCutVariationEntry variation lstFeet --ResolveCutTexVariationEntry variation lstTexFeet ) else if variation.componentIdx == HAIR_IDX then ( --hair ResolveCutVariationEntry variation lstHair --ResolveCutTexVariationEntry variation lstTexFeet ) else if variation.componentIdx == TEEF_IDX then ( --teef ResolveCutVariationEntry variation lstTeef --ResolveCutTexVariationEntry variation lstTexFeet ) else if variation.componentIdx == HAND_IDX then ( --teef ResolveCutVariationEntry variation lstHands --ResolveCutTexVariationEntry variation lstTexFeet ) ) for prop in propLst do ( if (prop.modelIdx as integer) == modelidx then append propListForChar prop ) for prop in propListForChar do ( if prop.anchorIdx == 0 then ( --head ResolveCutPropEntry prop lstPHeads ) else if prop.anchorIdx == 1 then ( --eyes ResolveCutPropEntry prop lstPEyes ) else if prop.anchorIdx == 2 then ( --ears ResolveCutPropEntry prop lstPEars ) else if prop.anchorIdx == 4 then ( --lhand ResolveCutPropEntry prop lstPLHand ) else if prop.anchorIdx == 5 then ( --rhand ResolveCutPropEntry prop lstPRhand ) else if prop.anchorIdx == 6 then ( --lwrist ResolveCutPropEntry prop lstPLWrist ) else if prop.anchorIdx == 7 then ( --rwrist ResolveCutPropEntry prop lstPRWrist ) ) UpdateVisibleSelection() ) fn RefreshTextureVariations = ( lstTexHeads.visible = true lstTexUppers.visible = true lstTexLowers.visible = true lstTexFeet.visible = true lstTexSuses.visible = true lstTexHair.visible = true lstTexHands.visible = true modelIdx = lstModels.selection - 2 varListForChar = #() for var in variationLst do ( if (var.modelIdx as integer) == modelidx then append varListForChar var ) for variation in varListForChar do ( if variation.componentIdx == HEAD_IDX then ( --head ResolveCutTexVariationEntry variation lstTexHeads ) else if variation.componentIdx == UPPR_IDX then ( --uppr ResolveCutTexVariationEntry variation lstTexUppers ) else if variation.componentIdx == LOWR_IDX then ( --lowr ResolveCutTexVariationEntry variation lstTexLowers ) else if variation.componentIdx == SUSE_IDX then ( --suse ResolveCutTexVariationEntry variation lstTexSuses ) else if variation.componentIdx == FEET_IDX then ( --feet ResolveCutTexVariationEntry variation lstTexFeet ) else if variation.componentIdx == HAIR_IDX then ( --hair ResolveCutTexVariationEntry variation lstTexHair ) else if variation.componentIdx == TEEF_IDX then ( ResolveCutTexVariationEntry variation lstTexTeef ) else if variation.componentIdx == HAND_IDX then ( ResolveCutTexVariationEntry variation lstTexHands ) ) ) fn DefaultTexListBoxes = ( lstTexLowers.visible = true lstTexFeet.visible = true lstTexSuses.visible = true ) --//////////////////////////////////////////////////////////// -- events --//////////////////////////////////////////////////////////// -------------------------------------------------------------- -- -------------------------------------------------------------- on lstCutfiles selected newsel do ( ParseCutFileRead (RsConfigGetCutsceneDir() + lstCutfiles.selected) tempLst = #() append tempLst "None" for mdl in modelLst do ( append tempLst mdl.animName ) lstModels.items = tempLst --maxFileNameTokens = filterstring maxfilename "." filenameLwr = RsLowercase(GetPedName()) i = 1 found = false for mdl in lstModels.items do ( mdlNameLwr = RsLowerCase(mdl) if findstring mdlNameLwr filenameLwr != undefined then ( lstModels.selection = i found = true ) ) --if found == false then messagebox "The model open in max has not been found in the cut file you have selected." lstModels.visible = true /* LoadTextureList() InitialiseListBoxes() RefreshVariations() UpdateTexList() RefreshTextureVariations() UpdateVisibleTexSelection lstHeads lstTexHeads UpdateVisibleTexSelection lstUppers lstTexUppers UpdateVisibleTexSelection lstLowers lstTexLowers UpdateVisibleTexSelection lstFeet lstTexFeet UpdateVisibleTexSelection lstSuses lstTexSuses UpdateVisibleTexSelection lstHair lstTexHair */ ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstModels selected newsel do ( LoadTextureList() InitialiseListBoxes() RefreshVariations() UpdateTexList() RefreshTextureVariations() if lstModels.selected != "None" then btnCreateTexSwap.enabled = true else btnCreateTexSwap.enabled = fallse UpdateVisibleTexSelection lstHeads lstTexHeads UpdateVisibleTexSelection lstUppers lstTexUppers UpdateVisibleTexSelection lstLowers lstTexLowers UpdateVisibleTexSelection lstFeet lstTexFeet UpdateVisibleTexSelection lstSuses lstTexSuses UpdateVisibleTexSelection lstHair lstTexHair UpdateVisibleTexSelection lstTeef lstTexTeef UpdateVisibleTexSelection lstHands lstTexHands ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstHeads selected newsel do ( UpdateVisibleSelection() lstTexHeads.selection = 1 UpdateVisibleTexSelection lstHeads lstTexHeads UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstUppers selected newsel do ( UpdateVisibleSelection() lstTexUppers.selection = 1 UpdateVisibleTexSelection lstUppers lstTexUppers UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstLowers selected newsel do ( UpdateVisibleSelection() lstTexLowers.selection = 1 UpdateVisibleTexSelection lstLowers lstTexLowers UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstFeet selected newsel do ( UpdateVisibleSelection() lstTexFeet.selection = 1 UpdateVisibleTexSelection lstFeet lstTexFeet UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstSuses selected newsel do ( UpdateVisibleSelection() lstTexSuses.selection = 1 UpdateVisibleTexSelection lstSuses lstTexSuses UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstHair selected newsel do ( UpdateVisibleSelection() lstTexHair.selection = 1 UpdateVisibleTexSelection lstHair lstTexHair UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTeef selected newsel do ( UpdateVisibleSelection() lstTexTeef.selection = 1 UpdateVisibleTexSelection lstTeef lstTexTeef UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstHands selected newsel do ( UpdateVisibleSelection() lstTexHands.selection = 1 UpdateVisibleTexSelection lstHands lstTexHands UpdateTexList() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPHeads selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPEyes selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPEars selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPLWrist selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPRWrist selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPLHand selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstPRhand selected newsel do ( UpdateVisibleSelection() ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexHeads selected newsel do ( UpdateVisibleTexSelection lstHeads lstTexHeads ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexUppers selected newsel do ( UpdateVisibleTexSelection lstUppers lstTexUppers ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexLowers selected newsel do ( UpdateVisibleTexSelection lstLowers lstTexLowers ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexFeet selected newsel do ( UpdateVisibleTexSelection lstFeet lstTexFeet ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexSuses selected newsel do ( UpdateVisibleTexSelection lstSuses lstTexSuses ) -------------------------------------------------------------- -- -------------------------------------------------------------- on lstTexHair selected newsel do ( UpdateVisibleTexSelection lstHair lstTexHair ) on lstTexTeef selected newsel do ( UpdateVisibleTexSelection lstTeef lstTexTeef ) on lstTexHands selected newsel do ( UpdateVisibleTexSelection lstHands lstTexHands ) -------------------------------------------------------------- -- -------------------------------------------------------------- on RsCsPedVarMgrRoll open do ( RsShowMapsInViewportRoll.setVisibility sceneMaterials on lstModels.visible = false lstHeads.visible = false lstUppers.visible = false lstLowers.visible = false lstFeet.visible = false lstSuses.visible = false lstHair.visible = false lstTeef.visible = false lstHands.visible = false lstPHeads.visible = false lstPEyes.visible = false lstPEars.visible = false lstPLWrist.visible = false lstPRWrist.visible = false lstPLHand.visible = false lstPRhand.visible = false lstTexHeads.visible = false lstTexUppers.visible = false lstTexLowers.visible = false lstTexFeet.visible = false lstTexSuses.visible = false lstTexHair.visible = false lstTexTeef.visible = false lstTexHands.visible = false btnCreateTexSwap.enabled = false LoadCutFileList() --InitialiseListBoxes() --UpdateVisibleSelection() ) on btnSaveToCut pressed do ( cutSceneDir = RsConfigGetCutsceneDir() ParseCutFileWrite (cutSceneDir + lstCutfiles.selected) ) on btnCreateTexSwap pressed do ( try CloseRolloutFloater RsTexVar catch() CreateDialog RsTexVarRoll width:180 height:350 addRollout RsTexVarRoll RsTexVar ) ) rollout RsTexVarRoll "Texture Swap Util" width:720 height:250 ( dropdownlist lstMesh "Mesh" width:135 dropdownlist lstTexture "Texture" width:135 listbox lboExistingVars "Existing Variations" button btnRemoveSelected "Remove Selected" spinner spnFrameSwap "Frame Swap" range:[0,10000,1] button btnSave "Save" width:100 local SwapTexList = #() local SwapMeshList = #() local CsModelList = #() local ExistingSwaps = #() local HEAD_IDX = 0 local UPPR_IDX = 1 local LOWR_IDX = 2 local SUSE_IDX = 3 local FEET_IDX = 5 local HAIR_IDX = 7 local TEEF_IDX = 9 local HANDS_IDX = 4 local MESH_TOKEN_COUNT = 3 local TEX_TOKEN_COUNT = 5 local FPS = 30 struct CsModel (idx, mdlName) fn ResolveModelIdxFromName mdlName = ( for mdl in CsModelList do ( print "mdlName" if RsLowercase mdlName == mdl.mdlName then return (mdl.idx as integer) ) return -1 ) fn ResolveComponentIdx cmpntName = ( tokens = filterstring cmpntName "_" if tokens.count == MESH_TOKEN_COUNT then ( if RsLowercase tokens[1] == "head" then return HEAD_IDX else if RsLowercase tokens[1] == "uppr" then return UPPR_IDX else if RsLowercase tokens[1] == "lowr" then return LOWR_IDX else if RsLowercase tokens[1] == "suse" then return SUSE_IDX else if RsLowercase tokens[1] == "feet" then return FEET_IDX else if RsLowercase tokens[1] == "hair" then return HAIR_IDX else if RsLowercase tokens[1] == "teef" then return TEEF_IDX else if RsLowercase tokens[1] == "hand" then return HANDS_IDX else return -1 ) else messagebox "Ped component name in incorrect format" ) fn ResolveTexIdx texturename = ( tokens = filterstring texturename "_" if tokens.count == TEX_TOKEN_COUNT then ( if RsLowercase tokens[4] == "a" then return 0 else if RsLowercase tokens[4] == "b" then return 1 else if RsLowercase tokens[4] == "c" then return 2 else if RsLowercase tokens[4] == "d" then return 3 else if RsLowercase tokens[4] == "e" then return 4 else if RsLowercase tokens[4] == "f" then return 5 else if RsLowercase tokens[4] == "g" then return 6 else if RsLowercase tokens[4] == "h" then return 7 else if RsLowercase tokens[4] == "i" then return 8 else if RsLowercase tokens[4] == "j" then return 9 else return -1 ) else messagebox ("Texture " + texturename + " in incorrect format.") ) fn ResolveMeshIdx meshName = ( tokens = filterstring meshName "_" if tokens.count == MESH_TOKEN_COUNT then ( return (tokens[2] as integer) ) ) fn LoadCutFileIntoArray cutFileBuffer cutpath = ( cutFileIn = openFile cutPath cutFileArray = #() -- Load the cutfile into an array of strings if cutFileIn != undefined then ( while eof cutFileIn == false do ( cutFileBuffer = readLine cutFileIn if buffer != "" and cutFileBuffer != undefined then (--buffer = "\n" append cutFileArray cutFileBuffer ) ) ) close cutFileIn return cutFileArray ) fn ExistsInModelList idx = ( for mdl in CsModelList do if mdl.idx == idx then return true return false ) fn BuildModelList = ( cutPath = RsConfigGetCutsceneDir() + RsCsPedVarMgrRoll.lstCutfiles.selected buffer = #() cutFileArray = #() cutFileArray = LoadCutFileIntoArray buffer cutPath -- Prespass the cutfile to store all characters amd their index -- Must be done since characters may not exist in every section i = 1 while i <= cutFileArray.count do ( if cutFileArray[i] == "[MODELS]" then ( i = i + 1 while cutFileArray[i] != "[/MODELS]" do ( tokens = filterstring cutFileArray[i] " " if tokens.count > 2 then ( mdlIdx = tokens[1] mdlName = RsLowercase tokens[2] if ExistsInModelList mdlIdx == false then ( newMdlEntry = CsModel idx:mdlIdx mdlName:mdlName append CsModelList newMdlEntry ) ) i = i + 1 ) ) i = i + 1 ) ) fn BuildExistingSwapList = ( ExistingSwaps = #() cutPath = RsConfigGetCutsceneDir() + RsCsPedVarMgrRoll.lstCutfiles.selected buffer = #() cutFileArray = #() cutFileArray = LoadCutFileIntoArray buffer cutPath modelidx = ResolveModelIdxFromName RsCsPedVarMgrRoll.lstModels.selected for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[VARIATION]" then ( i = i + 1 while cutFileArray[i] != "[/VARIATION]" do ( tokens = filterstring cutFileArray[i] " " if tokens.count == 5 then ( --if (tokens[5] as integer) > 0 and (tokens[1] as integer) == modelidx then append ExistingSwaps cutFileArray[i] if (tokens[5] as integer) > 0 then append ExistingSwaps cutFileArray[i] ) i = i + 1 ) ) ) ) fn SaveSwapVariation = ( cutPath = RsConfigGetCutsceneDir() + RsCsPedVarMgrRoll.lstCutfiles.selected buffer = #() cutFileArray = #() cutFileArray = LoadCutFileIntoArray buffer cutPath tempFilename = (RsConfigGetCutsceneDir() + "temp.cut") cutFileOut = createFile tempFilename firstpass = true varSection = false startFrame = 0 for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[CUTSCENE_HEADER]" then ( j = 1 while cutFileArray[i] != "[/CUTSCENE_HEADER]" do ( tokens = filterstring cutFileArray[i] "\t" if tokens.count > 0 then ( startFrame = tokens[1] as integer ) i = i + 1 ) ) ) for i = 1 to cutFileArray.count do ( if cutFileArray[i] == "[VARIATION]" and firstpass == true then ( varSection = true format (cutFileArray[i] + "\n") to:cutFileOut for existingVar in lboExistingVars.items do format (existingVar + "\n") to:cutFileOut compIdx = ResolveComponentIdx lstMesh.selected meshIdx = ResolveMeshIdx lstMesh.selected swapTime = ((((spnFrameSwap.value - startFrame) / FPS) * 1000) as integer) if swapTime > 0 then ( if compIdx != -1 then ( mdlIdx = -1 for csMdl in CsModelList do ( if RsLowercase RsCsPedVarMgrRoll.lstModels.selected == csMdl.mdlname then mdlIdx = csMdl.idx ) if mdlIdx != -1 then ( texIdx = ResolveTexIdx lstTexture.selected if texIdx != -1 then ( varStringOut = (mdlIdx as string) + " " + (compIdx as string) + " " + (meshIdx as string) + " " + (texIdx as string) + " " + (swapTime as string) alreadyExists = false for existingVar in lboExistingVars.items while alreadyExists == false do ( if varStringOut == existingVar then ( alreadyExists = true messagebox "This variation already exists in the cut file" ) ) if alreadyExists == false then ( format (varStringOut + "\n") to:cutFileOut ) ) else messagebox ("Invalid texture name " + lstTexture.selected + ".") ) else messagebox "Model selection cannot be found in cut file. Try closing the texture variation window and reopening" -- Write out entry here ) else messagebox ("Failed to resolve component index for " + lstMesh.selection + ". Check the mesh name is in the correct format") ) else messagebox "Swap time needs to be greater than zero" firstpass = false ) else if cutFileArray[i] == "[/VARIATION]" then ( varSection = false format (cutFileArray[i] + "\n") to:cutFileOut ) else if varSection == true then ( tokens = filterString cutFileArray[i] " " if tokens.count == 5 then ( print tokens if (tokens[5] as integer) == 0 then ( format (cutFileArray[i] + "\n") to:cutFileOut ) ) else format (cutFileArray[i] + "\n") to:cutFileOut ) else ( format (cutFileArray[i] + "\n") to:cutFileOut ) i = i + 1 ) close cutFileOut deletefile cutPath if renameFile tempFilename cutPath == false then messagebox "Failed to write to cut file. Check it is not read-only." ) fn PopulateAvailableTextures component variation = ( SwapTexList = #() for tex in RsVarTexLst do ( tokens = filterstring tex "_" if tokens.count > 2 then ( if RsLowercase tokens[2] == "diff" and RsLowercase tokens[1] == component and (tokens[3] as integer) == variation then ( append SwapTexList tex ) ) ) lstTexture.items = SwapTexList ) on lstMesh selected newsel do ( tokens = filterstring lstMesh.selected "_" if tokens.count == 3 then ( PopulateAvailableTextures (RsLowercase tokens[1]) (tokens[2] as integer) ) ) on lstTexture selected newsel do ( RsCsPedVarMgrRoll.UpdateVisibleTexSelection lstMesh lstTexture ) on btnRemoveSelected pressed do ( delIdx = finditem ExistingSwaps lboExistingVars.selected if delIdx > 0 then ( deleteItem ExistingSwaps delIdx lboExistingVars.items = ExistingSwaps ) ) on btnSave pressed do ( SaveSwapVariation() BuildExistingSwapList() lboExistingVars.items = ExistingSwaps ) on RsTexVarRoll open do ( SwapMeshList = #() append SwapMeshList "None" for meshvar in RsVarMeshLst do (if meshvar != "None" then append SwapMeshList meshvar) lstMesh.items = SwapMeshList BuildModelList() BuildExistingSwapList() lboExistingVars.items = ExistingSwaps ) ) try CloseRolloutFloater RsCsPedVarMgr catch() RsCsPedVarMgr = newRollOutFloater "The Ped Fiddler" 1150 350 addRollout RsCsPedVarMgrRoll RsCsPedVarMgr