1772 lines
57 KiB
Plaintext
Executable File
1772 lines
57 KiB
Plaintext
Executable File
--
|
|
-- 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 <luke.openshaw@rockstarnorth.com>
|
|
-- 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
|
|
|
|
|