From c3001a522a2c7886091538a51b3adbd13d791dd8 Mon Sep 17 00:00:00 2001 From: Tristan Bernard Date: Fri, 23 Feb 2024 14:12:42 -0500 Subject: [PATCH 1/2] Add Postal III support * Adds a new check box option to tell if we want to decompile a Postal III MDL file. * Makes decompiling character models from Postal III output their modified $bodygroup and $texturegroup QC commands as well as their custom $bolton and $prefab ones. --- Crowbar/Core/- Application/AppEnums.vb | 15 + Crowbar/Core/- Application/AppSettings.vb | 11 + Crowbar/Core/GameModel/- Base/SourceQcFile.vb | 6 +- .../SourceMdlFileData/SourceMdlBolton.vb | 11 + .../SourceMdlFileData/SourceMdlPrefab.vb | 17 + .../SourceModel49/SourceMdlFile49.vb | 128 +- .../SourceMdlFileData/SourceMdlFileData49.vb | 6 + .../GameModel/SourceModel49/SourceModel49.vb | 12 + .../GameModel/SourceModel49/SourceQcFile49.vb | 273 ++- Crowbar/Crowbar.vbproj | 24 + Crowbar/My Project/AssemblyInfo.vb | 2 +- .../DecompileUserControl.Designer.vb | 1501 +++++++++-------- .../Widgets/Main Tabs/DecompileUserControl.vb | 1 + 13 files changed, 1216 insertions(+), 791 deletions(-) create mode 100644 Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlBolton.vb create mode 100644 Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlPrefab.vb diff --git a/Crowbar/Core/- Application/AppEnums.vb b/Crowbar/Core/- Application/AppEnums.vb index d64db330..699ae576 100644 --- a/Crowbar/Core/- Application/AppEnums.vb +++ b/Crowbar/Core/- Application/AppEnums.vb @@ -189,4 +189,19 @@ Public Module AppEnums [Decimal] End Enum + Public Enum BoltonType + Hair + Glasses + Masks + Bracelet1 + Bracelet2 + Earring1 + Earring2 + Hat + Ring1 + Ring2 + Pin1 + Pin2 + End Enum + End Module diff --git a/Crowbar/Core/- Application/AppSettings.vb b/Crowbar/Core/- Application/AppSettings.vb index ec872f84..12e4d15e 100644 --- a/Crowbar/Core/- Application/AppSettings.vb +++ b/Crowbar/Core/- Application/AppSettings.vb @@ -767,6 +767,16 @@ Public Class AppSettings End Set End Property + Public Property IsPostal3IsChecked() As Boolean + Get + Return Me.theIsPostal3IsChecked + End Get + Set(ByVal value As Boolean) + Me.theIsPostal3IsChecked = value + NotifyPropertyChanged("IsPostal3IsChecked") + End Set + End Property + Public Property DecompileRemovePathFromSmdMaterialFileNamesIsChecked() As Boolean Get Return Me.theDecompileRemovePathFromSmdMaterialFileNamesIsChecked @@ -1913,6 +1923,7 @@ Public Class AppSettings Private theDecompileVertexAnimationVtaFileIsChecked As Boolean Private theDecompileProceduralBonesVrdFileIsChecked As Boolean + Private theIsPostal3IsChecked As Boolean Private theDecompileDeclareSequenceQciFileIsChecked As Boolean Private theDecompileFolderForEachModelIsChecked As Boolean diff --git a/Crowbar/Core/GameModel/- Base/SourceQcFile.vb b/Crowbar/Core/GameModel/- Base/SourceQcFile.vb index bcdc563c..974daae7 100644 --- a/Crowbar/Core/GameModel/- Base/SourceQcFile.vb +++ b/Crowbar/Core/GameModel/- Base/SourceQcFile.vb @@ -260,7 +260,11 @@ Public Class SourceQcFile length = textureFileNameMaxLengths(textureFileNameIndex) 'NOTE: Need at least "+ 2" to account for the double-quotes. - line += LSet("""" + aTextureFileName + """", length + 3) + If TheApp.Settings.IsPostal3IsChecked AndAlso textureFileNameIndex = 0 Then + line += LSet("""#Skin" + skinFamilyIndex.ToString() + """ """ + aTextureFileName + """", length + 16) + Else + line += LSet("""" + aTextureFileName + """", length + 3) + End If Next 'line += " " diff --git a/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlBolton.vb b/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlBolton.vb new file mode 100644 index 00000000..bd5a901f --- /dev/null +++ b/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlBolton.vb @@ -0,0 +1,11 @@ +Public Class SourceMdlBolton + Public Sub New() + 'Nothing here + End Sub + + Public type As Integer + + Public szmodelnameindex As Integer + + Public theModelName As String +End Class diff --git a/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlPrefab.vb b/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlPrefab.vb new file mode 100644 index 00000000..d763dc6d --- /dev/null +++ b/Crowbar/Core/GameModel/SourceCommon/SourceMdlFileData/SourceMdlPrefab.vb @@ -0,0 +1,17 @@ +Public Class SourceMdlPrefab + Public Sub New() + 'Nothing here + End Sub + + Public sznameindex As Integer + + Public theName As String + + Public skin As Integer + + Public boltonsmask As Integer + + Public bodypartsindex As Integer + + Public theBodyParts As List(Of Byte) +End Class diff --git a/Crowbar/Core/GameModel/SourceModel49/SourceMdlFile49.vb b/Crowbar/Core/GameModel/SourceModel49/SourceMdlFile49.vb index 0b0b14d6..d1124b74 100644 --- a/Crowbar/Core/GameModel/SourceModel49/SourceMdlFile49.vb +++ b/Crowbar/Core/GameModel/SourceModel49/SourceMdlFile49.vb @@ -299,30 +299,48 @@ Public Class SourceMdlFile49 'TODO: According to MDL v48 source code, the following fields are not used. ' Test various MDL v48 models to see if any use these. + If TheApp.Settings.IsPostal3IsChecked Then + 'Just fillers for Crowbar + Me.theMdlFileData.theNameCopy = "" - Me.theMdlFileData.nameCopyOffset = Me.theInputFileReader.ReadInt32() - If Me.theMdlFileData.nameCopyOffset > 0 Then - inputFileStreamPosition = Me.theInputFileReader.BaseStream.Position - Me.theInputFileReader.BaseStream.Seek(fileOffsetStart + Me.theMdlFileData.nameCopyOffset, SeekOrigin.Begin) - fileOffsetStart2 = Me.theInputFileReader.BaseStream.Position + Me.theMdlFileData.boneFlexDriverCount = 0 + Me.theMdlFileData.boneFlexDriverOffset = 0 - Me.theMdlFileData.theNameCopy = FileManager.ReadNullTerminatedString(Me.theInputFileReader) - Me.theMdlFileData.theModelName = Me.theMdlFileData.theNameCopy + Me.theMdlFileData.unknownValue = 0 - fileOffsetEnd2 = Me.theInputFileReader.BaseStream.Position - 1 - Me.theMdlFileData.theFileSeekLog.Add(fileOffsetStart2, fileOffsetEnd2, "theMdlFileData.theNameCopy = " + Me.theMdlFileData.theNameCopy) - Me.theInputFileReader.BaseStream.Seek(inputFileStreamPosition, SeekOrigin.Begin) + Me.theMdlFileData.bodygroupPresetCount = 0 + Me.theMdlFileData.bodygroupPresetOffset = 0 + + 'Actual Postal III data here + Me.theMdlFileData.numBoltons = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.boltonIndex = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.numPrefabs = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.prefabIndex = Me.theInputFileReader.ReadInt32() Else - Me.theMdlFileData.theNameCopy = "" - End If + Me.theMdlFileData.nameCopyOffset = Me.theInputFileReader.ReadInt32() + If Me.theMdlFileData.nameCopyOffset > 0 Then + inputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + Me.theInputFileReader.BaseStream.Seek(fileOffsetStart + Me.theMdlFileData.nameCopyOffset, SeekOrigin.Begin) + fileOffsetStart2 = Me.theInputFileReader.BaseStream.Position + + Me.theMdlFileData.theNameCopy = FileManager.ReadNullTerminatedString(Me.theInputFileReader) + Me.theMdlFileData.theModelName = Me.theMdlFileData.theNameCopy - Me.theMdlFileData.boneFlexDriverCount = Me.theInputFileReader.ReadInt32() - Me.theMdlFileData.boneFlexDriverOffset = Me.theInputFileReader.ReadInt32() + fileOffsetEnd2 = Me.theInputFileReader.BaseStream.Position - 1 + Me.theMdlFileData.theFileSeekLog.Add(fileOffsetStart2, fileOffsetEnd2, "theMdlFileData.theNameCopy = " + Me.theMdlFileData.theNameCopy) + Me.theInputFileReader.BaseStream.Seek(inputFileStreamPosition, SeekOrigin.Begin) + Else + Me.theMdlFileData.theNameCopy = "" + End If - Me.theMdlFileData.unknownValue = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.boneFlexDriverCount = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.boneFlexDriverOffset = Me.theInputFileReader.ReadInt32() - Me.theMdlFileData.bodygroupPresetCount = Me.theInputFileReader.ReadInt32() - Me.theMdlFileData.bodygroupPresetOffset = fileOffsetStart + Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.unknownValue = Me.theInputFileReader.ReadInt32() + + Me.theMdlFileData.bodygroupPresetCount = Me.theInputFileReader.ReadInt32() + Me.theMdlFileData.bodygroupPresetOffset = fileOffsetStart + Me.theInputFileReader.ReadInt32() + End If For x As Integer = 0 To Me.theMdlFileData.reserved.Length - 1 Me.theMdlFileData.reserved(x) = Me.theInputFileReader.ReadInt32() @@ -4281,6 +4299,82 @@ Public Class SourceMdlFile49 End If End Sub + Public Sub ReadBoltons() + If Me.theMdlFileData.numBoltons > 0 Then + Dim boltonInputFileStreamPosition As Long + Dim inputFileStreamPosition As Long + + Try + Me.theInputFileReader.BaseStream.Seek(Me.theMdlFileData.boltonIndex, SeekOrigin.Begin) + + Me.theMdlFileData.theBoltons = New List(Of SourceMdlBolton)(Me.theMdlFileData.numBoltons) + For i As Integer = 0 To Me.theMdlFileData.numBoltons - 1 + boltonInputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + Dim aBolton As New SourceMdlBolton() + + aBolton.type = Me.theInputFileReader.ReadInt32() + aBolton.szmodelnameindex = Me.theInputFileReader.ReadInt32() + + Me.theMdlFileData.theBoltons.Add(aBolton) + + inputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + + Me.theInputFileReader.BaseStream.Seek(boltonInputFileStreamPosition + aBolton.szmodelnameindex, SeekOrigin.Begin) + + aBolton.theModelName = FileManager.ReadNullTerminatedString(Me.theInputFileReader) + + Me.theInputFileReader.BaseStream.Seek(inputFileStreamPosition, SeekOrigin.Begin) + Next + Catch ex As Exception + + End Try + End If + End Sub + + Public Sub ReadPrefabs() + If Me.theMdlFileData.numPrefabs > 0 Then + Dim prefabInputFileStreamPosition As Long + Dim inputFileStreamPosition As Long + + Try + Me.theInputFileReader.BaseStream.Seek(Me.theMdlFileData.prefabIndex, SeekOrigin.Begin) + + Me.theMdlFileData.thePrefabs = New List(Of SourceMdlPrefab)(Me.theMdlFileData.numPrefabs) + For i As Integer = 0 To Me.theMdlFileData.numPrefabs - 1 + prefabInputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + Dim aPrefab As New SourceMdlPrefab() + + aPrefab.sznameindex = Me.theInputFileReader.ReadInt32() + aPrefab.skin = Me.theInputFileReader.ReadInt32() + aPrefab.boltonsmask = Me.theInputFileReader.ReadInt32() + aPrefab.bodypartsindex = Me.theInputFileReader.ReadInt32() + + inputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + + Me.theInputFileReader.BaseStream.Seek(prefabInputFileStreamPosition + aPrefab.bodypartsindex, SeekOrigin.Begin) + + aPrefab.theBodyParts = New List(Of Byte)(Me.theMdlFileData.bodyPartCount) + + For j As Integer = 0 To Me.theMdlFileData.bodyPartCount - 1 + aPrefab.theBodyParts.Add(Me.theInputFileReader.ReadByte()) + Next + + Me.theMdlFileData.thePrefabs.Add(aPrefab) + + 'inputFileStreamPosition = Me.theInputFileReader.BaseStream.Position + + Me.theInputFileReader.BaseStream.Seek(prefabInputFileStreamPosition + aPrefab.sznameindex, SeekOrigin.Begin) + + aPrefab.theName = FileManager.ReadNullTerminatedString(Me.theInputFileReader) + + Me.theInputFileReader.BaseStream.Seek(inputFileStreamPosition, SeekOrigin.Begin) + Next + Catch ex As Exception + + End Try + End If + End Sub + 'Public Sub ReadFinalBytesAlignment() ' Me.theMdlFileData.theFileSeekLog.LogAndAlignFromFileSeekLogEnd(Me.theInputFileReader, 4, "Final bytes alignment") 'End Sub diff --git a/Crowbar/Core/GameModel/SourceModel49/SourceMdlFileData/SourceMdlFileData49.vb b/Crowbar/Core/GameModel/SourceModel49/SourceMdlFileData/SourceMdlFileData49.vb index 49f21989..5d34b9fa 100644 --- a/Crowbar/Core/GameModel/SourceModel49/SourceMdlFileData/SourceMdlFileData49.vb +++ b/Crowbar/Core/GameModel/SourceModel49/SourceMdlFileData/SourceMdlFileData49.vb @@ -494,6 +494,10 @@ Public illumPositionAttachmentNumber As Integer Public maxEyeDeflection As Single Public linearBoneOffset As Integer + Public numBoltons As Integer + Public boltonIndex As Integer + Public numPrefabs As Integer + Public prefabIndex As Integer Public nameCopyOffset As Integer Public boneFlexDriverCount As Integer Public boneFlexDriverOffset As Integer @@ -541,6 +545,8 @@ Public theTexturePaths As List(Of String) Public theTextures As List(Of SourceMdlTexture) Public theWeightLists As List(Of SourceMdlWeightList) + Public theBoltons As List(Of SourceMdlBolton) + Public thePrefabs As List(Of SourceMdlPrefab) Public theAnimBlockSizeNoStallOptionIsUsed As Boolean Public theBoneNameToBoneIndexMap As New SortedList(Of String, Integer)() diff --git a/Crowbar/Core/GameModel/SourceModel49/SourceModel49.vb b/Crowbar/Core/GameModel/SourceModel49/SourceModel49.vb index 437a0791..7afc3fe7 100644 --- a/Crowbar/Core/GameModel/SourceModel49/SourceModel49.vb +++ b/Crowbar/Core/GameModel/SourceModel49/SourceModel49.vb @@ -538,6 +538,12 @@ Public Class SourceModel49 mdlFile.ReadBodygroupPresets() + 'Postal III stuffs + If TheApp.Settings.IsPostal3IsChecked Then + mdlFile.ReadBoltons() + mdlFile.ReadPrefabs() + End If + 'mdlFile.ReadFinalBytesAlignment() 'mdlFile.ReadUnknownValues(Me.theMdlFileData.theFileSeekLog) mdlFile.ReadUnreadBytes() @@ -684,6 +690,12 @@ Public Class SourceModel49 command = "$keyvalues" End If qcFile.WriteKeyValues(Me.theMdlFileData.theKeyValuesText, command) + + 'Postal III stuffs + If TheApp.Settings.IsPostal3IsChecked Then + qcFile.WriteBoltons() + qcFile.WritePrefabs() + End If Catch ex As Exception Dim debug As Integer = 4242 Finally diff --git a/Crowbar/Core/GameModel/SourceModel49/SourceQcFile49.vb b/Crowbar/Core/GameModel/SourceModel49/SourceQcFile49.vb index fb03d60c..d4234925 100644 --- a/Crowbar/Core/GameModel/SourceModel49/SourceQcFile49.vb +++ b/Crowbar/Core/GameModel/SourceModel49/SourceQcFile49.vb @@ -77,6 +77,10 @@ Public Class SourceQcFile49 Try If File.Exists(qciPathFileName) Then Dim qciFileInfo As New FileInfo(qciPathFileName) + Dim bodyPartIndex As Integer + bodyPartIndex = Me.theMdlFileData.theBodyParts.IndexOf(Me.theBodyPartForFlexWriting) + Dim aBodyPart As SourceMdlBodyPart + aBodyPart = Me.theMdlFileData.theBodyParts(bodyPartIndex) If qciFileInfo.Length > 0 Then Dim line As String = "" @@ -87,6 +91,9 @@ Public Class SourceQcFile49 End If If includeLineIsIndented Then line += vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If End If If TheApp.Settings.DecompileQcUseMixedCaseForKeywordsIsChecked Then line += "$Include " @@ -230,7 +237,9 @@ Public Class SourceQcFile49 'Dim aBodyPart As SourceMdlBodyPart Dim bodyPartIndex As Integer Dim aBodyModel As SourceMdlModel + Dim aVtxBodyPart As SourceVtxBodyPart07 Dim eyeballNames As List(Of String) + Dim aVtxModel As SourceVtxModel07 '$model "producer" "producer_model_merged.dmx.smd" { '//-doesn't work eyeball righteye ValveBiped.Bip01_Head1 -1.260 -0.086 64.594 eyeball_r 1.050 3.000 producer_head 0.530 @@ -246,30 +255,95 @@ Public Class SourceQcFile49 bodyPartIndex = Me.theMdlFileData.theBodyParts.IndexOf(aBodyPart) aBodyModel.theSmdFileNames(0) = SourceFileNamesModule.CreateBodyGroupSmdFileName(aBodyModel.theSmdFileNames(0), bodyPartIndex, 0, 0, Me.theModelName, aBodyPart.theModels(0).name) - If TheApp.Settings.DecompileQcUseMixedCaseForKeywordsIsChecked Then - line = "$Model " + 'Because Postal III supports multiple bodypart meshes with $model features for each studio mesh + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + If TheApp.Settings.DecompileQcUseMixedCaseForKeywordsIsChecked Then + line = "$BodyGroup " + Else + line = "$bodygroup " + End If Else - line = "$model " + If TheApp.Settings.DecompileQcUseMixedCaseForKeywordsIsChecked Then + line = "$Model " + Else + line = "$model " + End If End If line += """" line += aBodyPart.theName - line += """ """ - line += aBodyModel.theSmdFileNames(0) - line += """" + 'line += """ """ + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += """" + Me.theOutputFileStreamWriter.WriteLine(line) + line = "{" + Else + line += """ """ + line += aBodyModel.theSmdFileNames(0) + line += """" + + line += " {" + End If - line += " {" Me.theOutputFileStreamWriter.WriteLine(line) - 'NOTE: Must call WriteEyeballLines() before WriteEyelidLines(), because eyeballNames are created in first and sent to other. - Me.WriteEyeballLines(aBodyPart, eyeballNames) - Me.WriteEyelidLines(aBodyPart, eyeballNames) + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + If Me.theVtxFileData IsNot Nothing AndAlso Me.theVtxFileData.theVtxBodyParts IsNot Nothing AndAlso Me.theVtxFileData.theVtxBodyParts.Count > 0 Then + aVtxBodyPart = Me.theVtxFileData.theVtxBodyParts(bodyPartIndex) + Else + aVtxBodyPart = Nothing + End If - If bodyPartIndex = 0 Then - Me.WriteMouthLines() - End If + If aBodyPart.theModels IsNot Nothing AndAlso aBodyPart.theModels.Count > 0 Then + For modelIndex As Integer = 0 To aBodyPart.theModels.Count - 1 + aBodyModel = aBodyPart.theModels(modelIndex) + + If aVtxBodyPart IsNot Nothing AndAlso aVtxBodyPart.theVtxModels IsNot Nothing AndAlso aVtxBodyPart.theVtxModels.Count > 0 Then + aVtxModel = aVtxBodyPart.theVtxModels(modelIndex) + Else + aVtxModel = Nothing + End If + + line = vbTab + If aBodyModel.name(0) = ChrW(0) AndAlso (aVtxModel IsNot Nothing AndAlso aVtxModel.theVtxModelLods(0).theVtxMeshes Is Nothing) Then + line += "blank" + Else + aBodyModel.theSmdFileNames(0) = SourceFileNamesModule.CreateBodyGroupSmdFileName(aBodyModel.theSmdFileNames(0), bodyPartIndex, modelIndex, 0, Me.theModelName, aBodyModel.name) + line += "studio " + line += """" + line += aBodyModel.theSmdFileNames(0) + line += """ ""#" + line += aBodyModel.theSmdFileNames(0).Substring(0, aBodyModel.theSmdFileNames(0).Length - 4) + line += """ {" + Me.theOutputFileStreamWriter.WriteLine(line) + + 'NOTE: Must call WriteEyeballLines() before WriteEyelidLines(), because eyeballNames are created in first and sent to other. + Me.WriteEyeballLines(aBodyPart, eyeballNames) + Me.WriteEyelidLines(aBodyPart, eyeballNames) - Me.theBodyPartForFlexWriting = aBodyPart - Me.WriteGroup("flex", AddressOf WriteGroupFlex, False, True) + If bodyPartIndex = 0 Then + Me.WriteMouthLines(aBodyPart) + End If + + Me.theBodyPartForFlexWriting = aBodyPart + Me.WriteGroup("flex", AddressOf WriteGroupFlex, False, True) + line = vbTab + line += "}" + End If + Me.theOutputFileStreamWriter.WriteLine(line) + Next + End If + Else + 'NOTE: Must call WriteEyeballLines() before WriteEyelidLines(), because eyeballNames are created in first and sent to other. + Me.WriteEyeballLines(aBodyPart, eyeballNames) + Me.WriteEyelidLines(aBodyPart, eyeballNames) + + If bodyPartIndex = 0 Then + Me.WriteMouthLines(aBodyPart) + End If + + Me.theBodyPartForFlexWriting = aBodyPart + Me.WriteGroup("flex", AddressOf WriteGroupFlex, False, True) + End If line = "}" Me.theOutputFileStreamWriter.WriteLine(line) @@ -304,8 +378,10 @@ Public Class SourceQcFile49 If aBodyPart.theModels IsNot Nothing AndAlso aBodyPart.theModels.Count > 0 Then aModel = aBodyPart.theModels(0) If aModel.theEyeballs IsNot Nothing AndAlso aModel.theEyeballs.Count > 0 Then - line = "" - Me.theOutputFileStreamWriter.WriteLine(line) + If Not TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line = "" + Me.theOutputFileStreamWriter.WriteLine(line) + End If For eyeballIndex As Integer = 0 To aModel.theEyeballs.Count - 1 anEyeball = aModel.theEyeballs(eyeballIndex) @@ -372,6 +448,9 @@ Public Class SourceQcFile49 End If line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "eyeball """ line += eyeballNames(eyeballIndex) line += """ """ @@ -445,8 +524,10 @@ Public Class SourceQcFile49 If aBodyPart.theModels IsNot Nothing AndAlso aBodyPart.theModels.Count > 0 Then aModel = aBodyPart.theModels(0) If aModel.theEyeballs IsNot Nothing AndAlso aModel.theEyeballs.Count > 0 Then - line = "" - Me.theOutputFileStreamWriter.WriteLine(line) + If Not TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line = "" + Me.theOutputFileStreamWriter.WriteLine(line) + End If 'frameIndex = 0 For eyeballIndex As Integer = 0 To aModel.theEyeballs.Count - 1 @@ -467,6 +548,9 @@ Public Class SourceQcFile49 eyelidName = Me.theMdlFileData.theFlexDescs(anEyeball.upperLidFlexDesc).theName line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "eyelid " line += eyelidName 'line += " """ @@ -545,6 +629,9 @@ Public Class SourceQcFile49 eyelidName = Me.theMdlFileData.theFlexDescs(anEyeball.lowerLidFlexDesc).theName line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "eyelid " line += eyelidName 'line += " """ @@ -636,7 +723,7 @@ Public Class SourceQcFile49 End If End Function - Private Sub WriteMouthLines() + Private Sub WriteMouthLines(ByVal aBodyPart As SourceMdlBodyPart) Dim line As String = "" Dim offsetX As Double Dim offsetY As Double @@ -644,8 +731,10 @@ Public Class SourceQcFile49 'NOTE: Writes out mouth line correctly for teenangst zoey. If Me.theMdlFileData.theMouths IsNot Nothing AndAlso Me.theMdlFileData.theMouths.Count > 0 Then - line = "" - Me.theOutputFileStreamWriter.WriteLine(line) + If Not TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line = "" + Me.theOutputFileStreamWriter.WriteLine(line) + End If For i As Integer = 0 To Me.theMdlFileData.theMouths.Count - 1 Dim aMouth As SourceMdlMouth @@ -655,6 +744,9 @@ Public Class SourceQcFile49 offsetZ = Math.Round(aMouth.forward.z, 3) line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "mouth " line += i.ToString(TheApp.InternalNumberFormat) line += " """ @@ -691,11 +783,16 @@ Public Class SourceQcFile49 'If Me.theBodyPartForFlexWriting.theFlexFrames IsNot Nothing AndAlso Me.theBodyPartForFlexWriting.theFlexFrames.Count > 1 Then Dim bodyPartIndex As Integer bodyPartIndex = Me.theMdlFileData.theBodyParts.IndexOf(Me.theBodyPartForFlexWriting) + Dim aBodyPart As SourceMdlBodyPart + aBodyPart = Me.theMdlFileData.theBodyParts(bodyPartIndex) line = "" Me.theOutputFileStreamWriter.WriteLine(line) line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "flexfile" 'line += Path.GetFileNameWithoutExtension(CStr(Me.theSourceEngineModel.theMdlFileHeader.theBodyParts(0).theModels(0).name).Trim(Chr(0))) 'line += ".vta""" @@ -705,12 +802,18 @@ Public Class SourceQcFile49 Me.theOutputFileStreamWriter.WriteLine(line) line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "{" Me.theOutputFileStreamWriter.WriteLine(line) '====== line = vbTab line += vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "defaultflex frame 0" Me.theOutputFileStreamWriter.WriteLine(line) @@ -722,6 +825,9 @@ Public Class SourceQcFile49 aFlexFrame = Me.theBodyPartForFlexWriting.theFlexFrames(frameIndex) line = vbTab line += vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If If Me.theMdlFileData.theFlexDescs(aFlexFrame.flexes(0).flexDescIndex).theDescIsUsedByEyelid Then line += "// Already in eyelid lines: " End If @@ -821,6 +927,9 @@ Public Class SourceQcFile49 'Next line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "}" Me.theOutputFileStreamWriter.WriteLine(line) 'End If @@ -833,6 +942,10 @@ Public Class SourceQcFile49 Dim aFlexController As SourceMdlFlexController Dim flexControllerNames As New List(Of String)() Dim commentOperatorText As String + Dim bodyPartIndex As Integer + bodyPartIndex = Me.theMdlFileData.theBodyParts.IndexOf(Me.theBodyPartForFlexWriting) + Dim aBodyPart As SourceMdlBodyPart + aBodyPart = Me.theMdlFileData.theBodyParts(bodyPartIndex) line = "" Me.theOutputFileStreamWriter.WriteLine(line) @@ -842,6 +955,9 @@ Public Class SourceQcFile49 If flexControllerNames.Contains(aFlexController.theName) Then line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "// Although in the original model, the line below is a duplicate of a line above and is commented-out to avoid problems in Source Filmmaker (and possibly other tools)." Me.theOutputFileStreamWriter.WriteLine(line) commentOperatorText = "//" @@ -857,6 +973,9 @@ Public Class SourceQcFile49 End If line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += commentOperatorText line += "flexcontroller " line += aFlexController.theType @@ -878,6 +997,10 @@ Public Class SourceQcFile49 If Me.theMdlFileData.theFlexRules IsNot Nothing AndAlso Me.theMdlFileData.theFlexRules.Count > 0 Then Dim aFlexRule As SourceMdlFlexRule + Dim bodyPartIndex As Integer + bodyPartIndex = Me.theMdlFileData.theBodyParts.IndexOf(Me.theBodyPartForFlexWriting) + Dim aBodyPart As SourceMdlBodyPart + aBodyPart = Me.theMdlFileData.theBodyParts(bodyPartIndex) line = "" Me.theOutputFileStreamWriter.WriteLine(line) @@ -888,6 +1011,9 @@ Public Class SourceQcFile49 If Not flexDesc.theDescIsUsedByFlex AndAlso flexDesc.theDescIsUsedByFlexRule Then line = vbTab + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line += vbTab + End If line += "localvar " line += flexDesc.theName Me.theOutputFileStreamWriter.WriteLine(line) @@ -897,7 +1023,13 @@ Public Class SourceQcFile49 For i As Integer = 0 To Me.theMdlFileData.theFlexRules.Count - 1 aFlexRule = Me.theMdlFileData.theFlexRules(i) 'line = Me.GetFlexRule(aFlexRule) - line = Common.GetFlexRule(Me.theMdlFileData.theFlexDescs, Me.theMdlFileData.theFlexControllers, aFlexRule) + If TheApp.Settings.IsPostal3IsChecked AndAlso aBodyPart.modelCount > 1 Then + line = vbTab + line += Common.GetFlexRule(Me.theMdlFileData.theFlexDescs, Me.theMdlFileData.theFlexControllers, aFlexRule) + Else + line = Common.GetFlexRule(Me.theMdlFileData.theFlexDescs, Me.theMdlFileData.theFlexControllers, aFlexRule) + End If + Me.theOutputFileStreamWriter.WriteLine(line) Next End If @@ -4828,11 +4960,21 @@ Public Class SourceQcFile49 If aBodyModel.name(0) = ChrW(0) AndAlso (aVtxModel IsNot Nothing AndAlso aVtxModel.theVtxModelLods(0).theVtxMeshes Is Nothing) Then line += "blank" Else - aBodyModel.theSmdFileNames(0) = SourceFileNamesModule.CreateBodyGroupSmdFileName(aBodyModel.theSmdFileNames(0), bodyPartIndex, modelIndex, 0, Me.theModelName, aBodyModel.name) - line += "studio " - line += """" - line += aBodyModel.theSmdFileNames(0) - line += """" + If TheApp.Settings.IsPostal3IsChecked Then + aBodyModel.theSmdFileNames(0) = SourceFileNamesModule.CreateBodyGroupSmdFileName(aBodyModel.theSmdFileNames(0), bodyPartIndex, modelIndex, 0, Me.theModelName, aBodyModel.name) + line += "studio " + line += """" + line += aBodyModel.theSmdFileNames(0) + line += """ ""#" + line += aBodyModel.theSmdFileNames(0).Substring(0, aBodyModel.theSmdFileNames(0).Length - 4) + line += """" + Else + aBodyModel.theSmdFileNames(0) = SourceFileNamesModule.CreateBodyGroupSmdFileName(aBodyModel.theSmdFileNames(0), bodyPartIndex, modelIndex, 0, Me.theModelName, aBodyModel.name) + line += "studio " + line += """" + line += aBodyModel.theSmdFileNames(0) + line += """" + End If End If Me.theOutputFileStreamWriter.WriteLine(line) Next @@ -5051,6 +5193,81 @@ Public Class SourceQcFile49 End Try End Sub + Public Sub WriteBoltons() + Dim line As String = "" + + Try + If Me.theMdlFileData.numBoltons > 0 Then + Dim aBolton As SourceMdlBolton + Dim m_BoltonType As BoltonType + + For i As Integer = 0 To Me.theMdlFileData.numBoltons - 1 + aBolton = Me.theMdlFileData.theBoltons(i) + + line = "$bolton ""Bolton" + i.ToString() + line += """ """ + + m_BoltonType = CType(aBolton.type, BoltonType) + line += m_BoltonType.ToString() + line += """ """ + line += aBolton.theModelName + line += """" + + Me.theOutputFileStreamWriter.WriteLine(line) + Next + End If + Catch ex As Exception + + End Try + End Sub + + Public Sub WritePrefabs() + Dim line As String = "" + + Try + If Me.theMdlFileData.numPrefabs > 0 Then + Dim aPrefab As SourceMdlPrefab + + For i As Integer = 0 To Me.theMdlFileData.numPrefabs - 1 + aPrefab = Me.theMdlFileData.thePrefabs(i) + + line = "$prefab """ + line += aPrefab.theName + line += """ """ + line += "#Skin" + aPrefab.skin.ToString() + line += """" + + For j As Integer = 0 To Me.theMdlFileData.numBoltons - 1 + Dim bits As Integer + bits = 1 << j + + If (bits And aPrefab.boltonsmask) = bits Then + line += " ""Bolton" + j.ToString() + line += """" + End If + Next + + For j As Integer = 0 To Me.theMdlFileData.bodyPartCount - 1 + Dim aBodyPart As SourceMdlBodyPart + aBodyPart = Me.theMdlFileData.theBodyParts(j) + Dim aModel As SourceMdlModel + aModel = aBodyPart.theModels(aPrefab.theBodyParts(j)) + Dim bodyPartName As String + If Not aModel.theSmdFileNames(0) = "" Then + bodyPartName = aModel.theSmdFileNames(0).Substring(0, aModel.theSmdFileNames(0).Length - 4) + line += " ""#" + bodyPartName + line += """" + End If + Next + + Me.theOutputFileStreamWriter.WriteLine(line) + Next + End If + Catch ex As Exception + + End Try + End Sub + Private Sub WriteTextLines(ByVal text As String, ByVal indentCount As Integer) Dim line As String = "" Dim textChar As Char diff --git a/Crowbar/Crowbar.vbproj b/Crowbar/Crowbar.vbproj index 49ab8387..85d73535 100644 --- a/Crowbar/Crowbar.vbproj +++ b/Crowbar/Crowbar.vbproj @@ -20,6 +20,21 @@ 2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true true @@ -127,6 +142,8 @@ + + @@ -1010,6 +1027,13 @@ + + + False + .NET Framework 3.5 SP1 + false + +