Noway3 wrote: ↑Sat Sep 16, 2023 4:40 pm
Another small update to
viewtopic.php?p=311868#p311868
- Update: 2023-09-16:
- Added logic to better completely eliminate duplicates (from game patch updates).
- Added logic to put "most useful" columns in front (excel and json files).
- Added back the "All_Stats.xlsx" worksheet that was reported missing.
Unfortunately not all GameObjects (Items, Characters etc.) are stored in the RootTemplates or TimelineTemplates. I found that several items are only stored in
_merged.lsx
files.
I updated my PowerShell script to get ALL
*.lsx
files and then go through every
GameObjects
entry in each of those files (of which there are over 100k).
The script is currently running on my machine right now.
EDIT: 12+ hours later and it's still running
EDIT: 22+ hours later I stopped the script. Definitely either something wrong in my script, or simply way too much data to dig through quickly.
Also, one of the annoyances with the Templates, is that they don't always include the
DisplayName
, as this is inherited from the
ParentTemplate
. In one of my first/previous scripts I tried to resolve this writing a function that I could call recursively to get the "missing" information. However, this approach is extremely slow. I'm considering taking a look at it again, or perhaps instead just use joins/subselects in the SQL (perhaps create a view using this), so it's possible to search all the entries.
Anyway, here's my changed PowerShell script that you can use as reference, if you want. As I mentioned, it's currently running, and it's the first run, so hopefully it actually works as intended
Code: Select all
$Stopwatch = New-Object -TypeName System.Diagnostics.Stopwatch
$Stopwatch.Start()
$MyDocuments = [System.IO.FileInfo][System.Environment]::GetFolderPath('MyDocuments')
$CheatTableFolder = [System.IO.FileInfo]"$($MyDocuments.FullName)\My Cheat Tables\bg3"
$UnpackedDataFolder = [System.IO.FileInfo]'D:\BG3-Tools\BG3-Modders-Multitool\UnpackedData'
$LocalizationPath = [System.IO.FileInfo]"$($UnpackedDataFolder.FullName)\English\Localization\English\english.loca.xml"
$LocalizationData = New-Object -TypeName System.Xml.XmlDocument
$LocalizationData.PreserveWhitespace = $true
$LocalizationData.Load($LocalizationPath.FullName)
$RootFolders = @(
[System.IO.FileInfo]"$($UnpackedDataFolder)\Shared",
[System.IO.FileInfo]"$($UnpackedDataFolder)\Gustav"
)
Get-ChildItem -Directory -Filter 'Patch*' -Path $UnpackedDataFolder | ForEach-Object {
$RootFolders += [System.IO.FileInfo]$_.FullName
}
#$Files = Get-ChildItem -Recurse -File -Filter *.lsx -Path $RootFolders
$Objects = @()
foreach ($f in $Files) {
$XmlDocument = New-Object -TypeName System.Xml.XmlDocument
$XmlDocument.PreserveWhitespace = $true
$XmlDocument.Load($f.FullName)
$GameObjects = $XmlDocument.SelectNodes("//node[@id='GameObjects']")
if ($GameObjects.Count -eq 0) { continue }
foreach ($g in $GameObjects) {
$Object = [ordered]@{}
$Attributes = $GameObjects.SelectNodes("./attribute")
if ($Attributes.Count -eq 0) { continue }
foreach ($a in $Attributes) {
$Key = $a.id
$Value = $a.value
$Type = $a.type
if ($Type -eq 'TranslatedString') {
$Value = $a.handle
$Object."$($Key)English" = $LocalizationData.SelectSingleNode("//content[@contentuid='$($Value)']").'#text'
}
$Object."$($Key)" = $Value
}
$Equipment = $GameObjects.SelectNodes(".//node[@id='Equipment']")
if ($Equipment.Count -gt 0) {
$Attributes = $Equipment.SelectNodes("./attribute")
$EquipmentObject = [ordered]@{}
foreach ($a in $Attributes) {
$Key = $a.id
$Value = $a.value
$Type = $a.type
if ($Type -eq 'TranslatedString') {
$Value = $a.handle
$EquipmentObject."$($Key)English" = $LocalizationData.SelectSingleNode("//content[@contentuid='$($Value)']").'#text'
}
$Object."Equipment_$($Key)" = $Value
}
$Attributes = $Equipment.SelectNodes(".//node[@id='Slot']//attribute[@id='Object']")
if ($Attributes.Count -gt 0) {
$Object.Equipment_Slot = $Attributes.value
}
}
$Attributes = $GameObjects.SelectNodes(".//node[@id='Tags']//node[@id='Tag']/attribute[@id='Object']")
if ($Attributes.Count -gt 0) {
$Object.Tags = $Attributes.value
}
$Attributes = $GameObjects.SelectNodes(".//node[@id='PrefabChildren']/attribute[@id='Object']")
if ($Attributes.Count -gt 0) {
$Object.PrefabChildren = $Attributes.value
}
$Object.UnpackedPath = $f.FullName.Replace($UnpackedDataFolder.FullName, '')
$Objects += New-Object -TypeName PSCustomObject -Property $Object
}
}
$Timestamp = Get-Date -Format FileDateTime
$Objects | ConvertTo-Json -Depth 5 | Out-File -Force -Encoding utf8 -FilePath "$($CheatTableFolder.FullName)\Templates_$($Timestamp).json"
$Stopwatch.Stop()
$Stopwatch.Elapsed