z Baldur's Gate 3

Upload your cheat tables here (No requests)
bluehinter
What is cheating?
What is cheating?
Posts: 1
Joined: Sat Jul 04, 2020 5:19 am
Reputation: 0

Re: z Baldur's Gate 3

Post by bluehinter »

just a warning that the "add 1000 gold" cheat occasionally crashes the game.
So far, it's only done it for me when I've hit it twice or more in a row.

How to use this cheat table?
  1. Install Cheat Engine
  2. Double-click the .CT file in order to open it.
  3. Click the PC icon in Cheat Engine in order to select the game process.
  4. Keep the list.
  5. Activate the trainer options by checking boxes or setting values from 0 to 1

Hexagroudon
What is cheating?
What is cheating?
Posts: 3
Joined: Sun Aug 06, 2023 8:11 am
Reputation: 0

Re: z Baldur's Gate 3

Post by Hexagroudon »

EvenLess wrote:
Fri Aug 04, 2023 11:42 pm
I have added a LOT of items to the Item Spawner. Primarily Legendary and Very Rare, and some Rare and Uncommon. I have sorted and color-coded them.

I have found 4 paths with UUIDs.
  • Gustav\Public\Gustav\Stats\Generated\Data
  • Gustav\Public\GustavDev\Stats\Generated\Data
  • Shared\Public\Shared\Stats\Generated\Data
  • Shared\Public\SharedDev\Stats\Generated\Data
It looks to be the RootTemplate UUID that is used (not the ValueUUID).

As CKeylos already pointed out, there's a guide on how to extract the .PAK-files to read the item tables, which was essentially what I used.
<edit count=2>
Just to be easier to find, here is my summary:
  1. Download and extract the latest version of Norbyte's ExportTool [Link].
  2. Download and extract the latest version of ShinyHobo's BG3-Modders-Multitool [Link].
I extracted the BG3-Modders-Multitool to the base directory of Norbyte's ExportTool, as the Multitool requires a file from there (which is added by clicking the asterisk in the lower right hand corner after opening the Multitool).
</edit>

Fixed issue. Split items into 3 files.
Added an update version of the old one. It is based on Zanzer's "bg3.CT v4.1.1.3624901 (2)" with dilde's spells added as well.


Disclaimer!
Zanzer deserves all the credit here. I only used his work. And I honestly do not really understand what is happening in the LUA/assembler code.

<edit count=1>
BG3 did crash several times when I tested the various UUIDs. However, that did not always mean the UUID did not work, as when I tried again (sometimes after several crashes) they did work. Just something to keep in mind.
</edit>

<edit count=2>
It seems I forgot to enable the "hide children" again, after moving my additions to Zanzers. However, I dropped this approach for a method that would be easier to maintain. I have removed the previous cheat table and added the one that contains ALL 2711 items. The items where a rarity was found, also have that added. I have also added a CSV file containing all the same items that you can use as you wish.

YOU MUST FIRST LOAD Zanzer's Cheat Table and Activate Console Commands, then Register Commands, before being able to use the Item Spawner.
Then from the already opened Cheat Engine, with Zanzer's bg3.CT loaded, open my bg3_items.CT and merge.
Image


First I wrote a PowerShell script to extract all the items in an easily manageable format.
bg3_items.ps1

Code: Select all

# Get the path for the My Documents folder.
$DocumentsFolder = [System.Environment]::GetFolderPath('MyDocuments')

# The default location where Cheat Engine saves cheat tables.
$CheatTablesFolder = Join-Path -Path $DocumentsFolder -ChildPath 'My Cheat Tables'

$ItemsCsvFile = 'bg3_items.csv'
$ItemsCsvPath = Join-Path -Path $CheatTablesFolder -ChildPath $ItemsCsvFile
$ItemsCtFile = 'bg3_armor.CT'
$ItemsCtPath = Join-Path -Path $CheatTablesFolder -ChildPath $ItemsCtFile

# Base-path of the unpacked data/.pak-files.
$BasePath = 'C:\Games\BG3-Tools\UnpackedData'
# Get tools to extract with here:
# https://github.com/Norbyte/lslib/releases/latest
# https://github.com/ShinyHobo/BG3-Modders-Multitool/releases/latest

# Sub-paths to the armor, object, and weapon .txt-files.
$ArmorFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Armor.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Armor.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Armor.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Armor.txt'
)
$WeaponFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Weapon.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Weapon.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Weapon.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Weapon.txt'
)
$ObjectFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Object.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Object.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Object.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Object.txt'
)

# Combine to one.
#$Files = $ArmorFiles + $WeaponFiles + $ObjectFiles
$Files = $ArmorFiles + $WeaponFiles + $ObjectFiles

$RarityColor = @{
    'RARITY_UNKNOWN' = 'C0C0C0'
    'Uncommon'       = '00FF00'
    'Rare'           = 'FFFF00'
    'VeryRare'       = 'FF00FF'
    'Legendary'      = '4080FF'
}

$CheatTableHead = @"
<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="45">
    <CheatEntries>
        <CheatEntry>
            <ID>@@CE_ID@@</ID>
            <Description>"Item Spawner"</Description>
            <Options moHideChildren="1"/>
            <GroupHeader>1</GroupHeader>
            <CheatEntries>
"@
$CheatTableFoot = @"
            </CheatEntries>
        </CheatEntry>
    </CheatEntries>
    <UserdefinedSymbols>
        <SymbolEntry>
            <Name>playerCharactersPtr</Name>
            <Address>1D4526F0000</Address>
        </SymbolEntry>
    </UserdefinedSymbols>
    <DisassemblerComments>
        <DisassemblerComment>
            <Address>"bg3.exe"+25C0F20</Address>
            <Comment>Zanzer</Comment>
        </DisassemblerComment>
    </DisassemblerComments>
</CheatTable>
"@
$CheatEntryTemplate = @"
                <CheatEntry>
                    <ID>@@CE_ID@@</ID>
                    <Description>"@@ITEM_NAME@@"</Description>
                    <Color>@@RARITY_COLOR@@</Color>
                    <VariableType>Auto Assembler Script</VariableType>
                    <AssemblerScript Async="1">[ENABLE]
{`$lua}
if syntaxcheck then return end

local uuid = "@@ITEM_UUID@@"

local cmdCall = getAddress("cmdCall")
local cmdAddr = getAddress("cmdAddr")
local cmdArgs = getAddress("cmdArgs")
local cmdStr1 = getAddress("cmdStr1")
PrepareCall("GetHostCharacter")
executeCodeEx(0, nil, cmdCall)

writePointer(cmdArgs + 0x18, readPointer(cmdArgs + 0x08))
PrepareCall("CreateAtObject")
writePointer(cmdArgs + 0x08, cmdStr1)
writeString(cmdStr1, uuid)
writeBytes(cmdStr1 + #uuid, 0)
writeQword(cmdArgs + 0x28, 0)
writeQword(cmdArgs + 0x38, 0)
writeQword(cmdArgs + 0x48, 0)
writeQword(cmdArgs + 0x58, 0)
executeCodeEx(0, nil, cmdCall)

{`$asm}
assert(true)
[DISABLE]
                    </AssemblerScript>
                </CheatEntry>
"@

# Regular Expression to check if the UUID looks right.
$RegexUUID = [regex]'^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$'

# Create an empty array to store all the items.
$Items = ''

# Create an empty string variable to store the content of the files.
$Content = ''
# Loop through the files and read their contents into one big string.
foreach ($File in $Files) {
    # Combine base-path and sub-path to the full path.
    $FullPath = Join-Path -Path $BasePath -ChildPath $File
    $Content += Get-Content -Raw -Path $FullPath
}
# Split the content string into an array of lines.
$Line = $Content -split '\n'

# Create an empty array to store the item objects in.
$Items = @()
# Ensure the Item variable is empty for the first iteration.
Clear-Variable -Name Item -ErrorAction SilentlyContinue
# Loop through all the lines.
for ($l = 0; $l -lt $Line.Count; $l++) {
    # Check if the current line is the start of a new item entry.
    if ($Line[$l] -match '^new entry "(?<Name>\w+)"') {
        # Store the items "name" in a new variable, so it does not get overwritten by following mathes.
        $ItemName = $Matches.Name
        # Check if we already have an item object, and if that item object contains a valid UUID.
        if ($Item -and $Item.UUID -match $RegexUUID) {
            # Store the previous item object in the array.
            $Items += New-Object -TypeName psobject -Property $Item
        }
        # Create a fresh hashtable and populate it with the default values.
        $Item = [ordered]@{
            Name   = $ItemName
            UUID   = $null
            Type   = 'TYPE_UNKNOWN'
            Rarity = 'RARITY_UNKNOWN'
        }
    }
    else {
        # Not a new item entry, so look for the current item entrys data.
        # Check if the current line is the item type.
        if ($Line[$l] -match 'type "(?<Type>\w+)"') {
            # Update the hashtable with the found value.
            $Item.Type = $Matches.Type
        }
        # Check if the current line is the item rarity.
        if ($Line[$l] -match '^data "Rarity" "(?<Rarity>\w+)"') {
            # Update the hashtable with the found value.
            $Item.Rarity = $Matches.Rarity
        }
        # Check if the current line is the item UUID.
        if ($Line[$l] -match '^data "RootTemplate" "(?<UUID>[a-f0-9-]+)"') {
            # Update the hashtable with the found value.
            $Item.UUID = $Matches.UUID
        }
    }
}

# Export the items to a the items CSV-file. Using semi-colon (;) as delimiter, simply because the CSV file will automatically be shown in colums, in spreadsheet programs.
$Items | Sort-Object -Property Name | Export-Csv -Force -NoTypeInformation -Encoding Default -Delimiter ';' -Path $ItemsCsvPath

# Build the Cheat Table.
foreach ($t in ($Items | Select-Object -ExpandProperty Type -Unique)) {
    $CtFile = "bg3_$($t.ToLower()).CT"
    $CtPath = Join-Path -Path $CheatTablesFolder -ChildPath $CtFile
    $CheatID = 1
    $CheatTableHead.Replace('@@CE_ID@@', $CheatID) | Out-File -Force -Encoding default -FilePath $CtPath
    foreach ($i in ($Items | Where-Object { $_.Type -eq $t} | Sort-Object -Property Name)) {
        $CheatID++
        $CheatEntryTemplate.Replace('@@CE_ID@@', $CheatID).Replace('@@ITEM_NAME@@', $i.Name).Replace('@@RARITY_COLOR@@', $RarityColor."$($i.Rarity)").Replace('@@ITEM_UUID@@', $i.UUID) | Out-File -Append -Encoding default -FilePath $CtPath
    }
    $CheatTableFoot | Out-File -Append -Encoding default -FilePath $CtPath
}
</edit>
<edit>
Issue with the bg_items.CT was a mixture of me forgetting to escape $lua and $asm in the table, which caused PowerShell to interpret them as variables rather than literal tekst. Apparently the CharacterPtr in the original, needs to be added at the bottom of mine as well, for it to work I would have thought it just was inherited from the first loaded. I don't know LUA or Assembler, so I'm just trying my way :oops:
</edit>
Is it just me or this table crashes the game 8/10 times when I used the item spawner. The game also crashes if I use it to spawn items more than 2/3 times. I am also using your advice of starting the main cheat table first and then loading yours, but it still results in frequent crashes. Then I tried adding UUIDs manually, that's also a partial success.

Could it be that the game is allergic to mods/cheats? Or is there anything wrong in my process.

Hexagroudon
What is cheating?
What is cheating?
Posts: 3
Joined: Sun Aug 06, 2023 8:11 am
Reputation: 0

Re: z Baldur's Gate 3

Post by Hexagroudon »

bluehinter wrote:
Sun Aug 06, 2023 8:13 am
just a warning that the "add 1000 gold" cheat occasionally crashes the game.
So far, it's only done it for me when I've hit it twice or more in a row.
I second this. I also tried manually editing gold values, but it was not completely a success as there are piles of gold and multiple characters with gold.

marcelmc
What is cheating?
What is cheating?
Posts: 2
Joined: Sun Oct 11, 2020 3:28 am
Reputation: 0

Re: z Baldur's Gate 3

Post by marcelmc »

does anyone have the current spell list?

i cant unse Target_ArcaneGate

shuiko
Expert Cheater
Expert Cheater
Posts: 77
Joined: Tue Feb 13, 2018 8:21 am
Reputation: 0

Re: z Baldur's Gate 3

Post by shuiko »

Using scripts to "spawn" stuff in the game will cause crashes if you do to them very fast. If you do it slowly give it 6-8 secs between each use it won't crash. This applies to all items. For gold just change the amount and it won't crash.

Hexagroudon
What is cheating?
What is cheating?
Posts: 3
Joined: Sun Aug 06, 2023 8:11 am
Reputation: 0

Re: z Baldur's Gate 3

Post by Hexagroudon »

shuiko wrote:
Sun Aug 06, 2023 8:31 am
Using scripts to "spawn" stuff in the game will cause crashes if you do to them very fast. If you do it slowly give it 6-8 secs between each use it won't crash. This applies to all items. For gold just change the amount and it won't crash.
Thank you for the advice, let me try that.

Tiffany
Expert Cheater
Expert Cheater
Posts: 101
Joined: Fri Mar 24, 2017 9:38 am
Reputation: 33

Re: z Baldur's Gate 3

Post by Tiffany »

Hexagroudon wrote:
Sun Aug 06, 2023 8:14 am
Is it just me or this table crashes the game 8/10 times when I used the item spawner. The game also crashes if I use it to spawn items more than 2/3 times. I am also using your advice of starting the main cheat table first and then loading yours, but it still results in frequent crashes. Then I tried adding UUIDs manually, that's also a partial success.

Could it be that the game is allergic to mods/cheats? Or is there anything wrong in my process.
EvenLess doesn't really know anything about the lua/assembly coding stuff going on, so probably a better question for Zanzer.

That said, maybe it doesn't like items being placed in the same exact location - that's my working theory anyways. I don't have many issues if I just pick up an item right after spawning it. Occasionally spawning items can still crash the game but 2-3 crashes with 3-4 dozens of items spawned isn't all that bad all things considered. Just make sure to quicksave regularly and it's hardly an inconvenience.

That also happens just with the example code supplied by Zanzer by the way so it's definitely not something stemming from EvenLess.

arkayus
What is cheating?
What is cheating?
Posts: 2
Joined: Tue Aug 01, 2023 5:33 am
Reputation: 0

Re: z Baldur's Gate 3

Post by arkayus »

How do I go about changing the amount of gold I have/adding it? I don't see any option specifically for gold.

hackbeater
Novice Cheater
Novice Cheater
Posts: 24
Joined: Sat Sep 19, 2020 9:40 pm
Reputation: 0

Re: z Baldur's Gate 3

Post by hackbeater »

What am i doing wrong?
I want to increase the spell slots of my character permanently but spell slots changes back after i load a save.please help.

Code: Select all

[ENABLE]
{$lua}
if syntaxcheck then return end

local uuid = "ActionResource(WarlockSpellSlot,2,2)"

local cmdCall = getAddress("cmdCall")
local cmdArgs = getAddress("cmdArgs")
local cmdStr1 = getAddress("cmdStr1")
PrepareCall("GetHostCharacter")
executeCodeEx(0, nil, cmdCall)
PrepareCall("AddBoosts")
writePointer(cmdArgs + 0x18, cmdStr1)
writeString(cmdStr1, uuid)
writeBytes(cmdStr1 + #uuid, 0)
writeQword(cmdArgs + 0x28, 0)
writeQword(cmdArgs + 0x38, 0)
executeCodeEx(0, nil, cmdCall)
{$asm}
assert(true)
[DISABLE]

Sticktothebrick
Noobzor
Noobzor
Posts: 8
Joined: Thu Sep 02, 2021 10:51 am
Reputation: 1

Re: z Baldur's Gate 3

Post by Sticktothebrick »

arkayus wrote:
Sun Aug 06, 2023 8:44 am
How do I go about changing the amount of gold I have/adding it? I don't see any option specifically for gold.
You can use the "last item moved" option. Move or split your coin stack and then edit the value. Seems to work for me.

Tiffany
Expert Cheater
Expert Cheater
Posts: 101
Joined: Fri Mar 24, 2017 9:38 am
Reputation: 33

Re: z Baldur's Gate 3

Post by Tiffany »

arkayus wrote:
Sun Aug 06, 2023 8:44 am
How do I go about changing the amount of gold I have/adding it? I don't see any option specifically for gold.
Right click on the gold command and edit script.

You'll then see this:

Code: Select all

[ENABLE]
{$lua}
if syntaxcheck then return end
local cmdCall = getAddress("cmdCall")
local cmdArgs = getAddress("cmdArgs")
PrepareCall("GetHostCharacter")
executeCodeEx(0, nil, cmdCall)
PrepareCall("AddGold")
writeInteger(cmdArgs + 0x18, 1000)
executeCodeEx(0, nil, cmdCall)
{$asm}

[DISABLE]
The line you want to change is

Code: Select all

writeInteger(cmdArgs + 0x18, 1000)
So for instance...

Code: Select all

[ENABLE]
{$lua}
if syntaxcheck then return end
local cmdCall = getAddress("cmdCall")
local cmdArgs = getAddress("cmdArgs")
PrepareCall("GetHostCharacter")
executeCodeEx(0, nil, cmdCall)
PrepareCall("AddGold")
writeInteger(cmdArgs + 0x18, 99000)
executeCodeEx(0, nil, cmdCall)
{$asm}

[DISABLE]
Though I personally just use items don't decrease in a different trainer we can't mention here and split stacks... which is definitely not exactly efficient or fast.

When you're done with the table make sure you uncheck everything again and save the table so you don't have to do the edit again.

User avatar
Csimbi
RCE Fanatics
RCE Fanatics
Posts: 892
Joined: Sat Apr 29, 2017 9:04 pm
Reputation: 1227

Re: z Baldur's Gate 3

Post by Csimbi »

Babbymode wrote:
Sun Aug 06, 2023 2:02 am

MVP stuff right there: you're missing a few things, like MaximizeHealing(Incoming) or MaximizeHealing(Outgoing) and I've discovered that you can apply conditionals to your UUID scripts here is an example I discovered after noticing that my damage script was also applying damage to effects hurting yourself:

Code: Select all

local uuid = "IF(IsAttack() or IsSpell()):DamageBonus(2d6+8)"

This would apply 2d6+8 damage of the same type as your spells and attacks you make on top of their normal amount.
I did say it is incomplete - I did it manually, so I am sure a lot are missing.
The quest-related ones, I left out on purpose.

Your formula looks good, one can do more complex ones, too.
You can chain things with comma.
Babbymode wrote:
Sun Aug 06, 2023 2:52 am
If any of you psychopaths want an all in one script, this works perfectly and you can edit it to your heart's content
Well done, this is what I had in mind, except I want to break it down by classes.
You know, to boost a fighter, a monk, a mage, etc.
I have not actually played the game yet, if you can evolve your character in any way, this generic script will do, of course ;-)
Tiffany wrote:
Sun Aug 06, 2023 4:34 am
Question... in your powershell code you have
PowerShell?
There is no PowerShell here.
You need to run this in CE. Copy-paste into an AA script and enable it.
{$asm} tells CE that the following code is Assembly (not LUA, C, etc.)
bluehinter wrote:
Sun Aug 06, 2023 8:13 am
just a warning that the "add 1000 gold" cheat occasionally crashes the game.
So far, it's only done it for me when I've hit it twice or more in a row.
You should save before each attempt.
I wonder if it'd make sense to spawn gold like items - at your feet.

Saiaxs
What is cheating?
What is cheating?
Posts: 2
Joined: Sun Jul 31, 2022 1:58 am
Reputation: 0

Re: z Baldur's Gate 3

Post by Saiaxs »

So is the Max All Stats in the Permanent Codes section actually supposed to be permanent? Because they revert to normal when I load a save or close the game. They don’t even revert to the “max” natural scores, they go back to my original ones pre-code.

Tiffany
Expert Cheater
Expert Cheater
Posts: 101
Joined: Fri Mar 24, 2017 9:38 am
Reputation: 33

Re: z Baldur's Gate 3

Post by Tiffany »

Csimbi wrote:
Sun Aug 06, 2023 9:17 am
PowerShell?
There is no PowerShell here.
You need to run this in CE. Copy-paste into an AA script and enable it.
{$asm} tells CE that the following code is Assembly (not LUA, C, etc.)
You seem to have made the mistake of assuming I was asking about Zanzer's table. I'm not sure how since I actually quoted EvenLess talking about the PowerShell script. But if you see my post I was asking about a PowerShell script EvenLess made for generating the item spawner codes. Which is why I'm making comparisons between what it generated and Zanzer's code.

Extricated
Novice Cheater
Novice Cheater
Posts: 21
Joined: Thu Sep 26, 2019 12:56 pm
Reputation: 1

Re: z Baldur's Gate 3

Post by Extricated »

EvenLess wrote:
Fri Aug 04, 2023 11:42 pm
I have added a LOT of items to the Item Spawner. Primarily Legendary and Very Rare, and some Rare and Uncommon. I have sorted and color-coded them.

I have found 4 paths with UUIDs.
  • Gustav\Public\Gustav\Stats\Generated\Data
  • Gustav\Public\GustavDev\Stats\Generated\Data
  • Shared\Public\Shared\Stats\Generated\Data
  • Shared\Public\SharedDev\Stats\Generated\Data
It looks to be the RootTemplate UUID that is used (not the ValueUUID).

As CKeylos already pointed out, there's a guide on how to extract the .PAK-files to read the item tables, which was essentially what I used.
<edit count=2>
Just to be easier to find, here is my summary:
  1. Download and extract the latest version of Norbyte's ExportTool [Link].
  2. Download and extract the latest version of ShinyHobo's BG3-Modders-Multitool [Link].
I extracted the BG3-Modders-Multitool to the base directory of Norbyte's ExportTool, as the Multitool requires a file from there (which is added by clicking the asterisk in the lower right hand corner after opening the Multitool).
</edit>

Fixed issue. Split items into 3 files.
Added an update version of the old one. It is based on Zanzer's "bg3.CT v4.1.1.3624901 (2)" with dilde's spells added as well.


Disclaimer!
Zanzer deserves all the credit here. I only used his work. And I honestly do not really understand what is happening in the LUA/assembler code.

<edit count=1>
BG3 did crash several times when I tested the various UUIDs. However, that did not always mean the UUID did not work, as when I tried again (sometimes after several crashes) they did work. Just something to keep in mind.
</edit>

<edit count=2>
It seems I forgot to enable the "hide children" again, after moving my additions to Zanzers. However, I dropped this approach for a method that would be easier to maintain. I have removed the previous cheat table and added the one that contains ALL 2711 items. The items where a rarity was found, also have that added. I have also added a CSV file containing all the same items that you can use as you wish.

YOU MUST FIRST LOAD Zanzer's Cheat Table and Activate Console Commands, then Register Commands, before being able to use the Item Spawner.
Then from the already opened Cheat Engine, with Zanzer's bg3.CT loaded, open my bg3_items.CT and merge.
Image


First I wrote a PowerShell script to extract all the items in an easily manageable format.
bg3_items.ps1

Code: Select all

# Get the path for the My Documents folder.
$DocumentsFolder = [System.Environment]::GetFolderPath('MyDocuments')

# The default location where Cheat Engine saves cheat tables.
$CheatTablesFolder = Join-Path -Path $DocumentsFolder -ChildPath 'My Cheat Tables'

$ItemsCsvFile = 'bg3_items.csv'
$ItemsCsvPath = Join-Path -Path $CheatTablesFolder -ChildPath $ItemsCsvFile
$ItemsCtFile = 'bg3_armor.CT'
$ItemsCtPath = Join-Path -Path $CheatTablesFolder -ChildPath $ItemsCtFile

# Base-path of the unpacked data/.pak-files.
$BasePath = 'C:\Games\BG3-Tools\UnpackedData'
# Get tools to extract with here:
# https://github.com/Norbyte/lslib/releases/latest
# https://github.com/ShinyHobo/BG3-Modders-Multitool/releases/latest

# Sub-paths to the armor, object, and weapon .txt-files.
$ArmorFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Armor.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Armor.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Armor.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Armor.txt'
)
$WeaponFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Weapon.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Weapon.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Weapon.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Weapon.txt'
)
$ObjectFiles = @(
     'Shared\Public\Shared\Stats\Generated\Data\Object.txt'
    ,'Shared\Public\SharedDev\Stats\Generated\Data\Object.txt'
    ,'Gustav\Public\Gustav\Stats\Generated\Data\Object.txt'
    ,'Gustav\Public\GustavDev\Stats\Generated\Data\Object.txt'
)

# Combine to one.
#$Files = $ArmorFiles + $WeaponFiles + $ObjectFiles
$Files = $ArmorFiles + $WeaponFiles + $ObjectFiles

$RarityColor = @{
    'RARITY_UNKNOWN' = 'C0C0C0'
    'Uncommon'       = '00FF00'
    'Rare'           = 'FFFF00'
    'VeryRare'       = 'FF00FF'
    'Legendary'      = '4080FF'
}

$CheatTableHead = @"
<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="45">
    <CheatEntries>
        <CheatEntry>
            <ID>@@CE_ID@@</ID>
            <Description>"Item Spawner"</Description>
            <Options moHideChildren="1"/>
            <GroupHeader>1</GroupHeader>
            <CheatEntries>
"@
$CheatTableFoot = @"
            </CheatEntries>
        </CheatEntry>
    </CheatEntries>
    <UserdefinedSymbols>
        <SymbolEntry>
            <Name>playerCharactersPtr</Name>
            <Address>1D4526F0000</Address>
        </SymbolEntry>
    </UserdefinedSymbols>
    <DisassemblerComments>
        <DisassemblerComment>
            <Address>"bg3.exe"+25C0F20</Address>
            <Comment>Zanzer</Comment>
        </DisassemblerComment>
    </DisassemblerComments>
</CheatTable>
"@
$CheatEntryTemplate = @"
                <CheatEntry>
                    <ID>@@CE_ID@@</ID>
                    <Description>"@@ITEM_NAME@@"</Description>
                    <Color>@@RARITY_COLOR@@</Color>
                    <VariableType>Auto Assembler Script</VariableType>
                    <AssemblerScript Async="1">[ENABLE]
{`$lua}
if syntaxcheck then return end

local uuid = "@@ITEM_UUID@@"

local cmdCall = getAddress("cmdCall")
local cmdAddr = getAddress("cmdAddr")
local cmdArgs = getAddress("cmdArgs")
local cmdStr1 = getAddress("cmdStr1")
PrepareCall("GetHostCharacter")
executeCodeEx(0, nil, cmdCall)

writePointer(cmdArgs + 0x18, readPointer(cmdArgs + 0x08))
PrepareCall("CreateAtObject")
writePointer(cmdArgs + 0x08, cmdStr1)
writeString(cmdStr1, uuid)
writeBytes(cmdStr1 + #uuid, 0)
writeQword(cmdArgs + 0x28, 0)
writeQword(cmdArgs + 0x38, 0)
writeQword(cmdArgs + 0x48, 0)
writeQword(cmdArgs + 0x58, 0)
executeCodeEx(0, nil, cmdCall)

{`$asm}
assert(true)
[DISABLE]
                    </AssemblerScript>
                </CheatEntry>
"@

# Regular Expression to check if the UUID looks right.
$RegexUUID = [regex]'^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$'

# Create an empty array to store all the items.
$Items = ''

# Create an empty string variable to store the content of the files.
$Content = ''
# Loop through the files and read their contents into one big string.
foreach ($File in $Files) {
    # Combine base-path and sub-path to the full path.
    $FullPath = Join-Path -Path $BasePath -ChildPath $File
    $Content += Get-Content -Raw -Path $FullPath
}
# Split the content string into an array of lines.
$Line = $Content -split '\n'

# Create an empty array to store the item objects in.
$Items = @()
# Ensure the Item variable is empty for the first iteration.
Clear-Variable -Name Item -ErrorAction SilentlyContinue
# Loop through all the lines.
for ($l = 0; $l -lt $Line.Count; $l++) {
    # Check if the current line is the start of a new item entry.
    if ($Line[$l] -match '^new entry "(?<Name>\w+)"') {
        # Store the items "name" in a new variable, so it does not get overwritten by following mathes.
        $ItemName = $Matches.Name
        # Check if we already have an item object, and if that item object contains a valid UUID.
        if ($Item -and $Item.UUID -match $RegexUUID) {
            # Store the previous item object in the array.
            $Items += New-Object -TypeName psobject -Property $Item
        }
        # Create a fresh hashtable and populate it with the default values.
        $Item = [ordered]@{
            Name   = $ItemName
            UUID   = $null
            Type   = 'TYPE_UNKNOWN'
            Rarity = 'RARITY_UNKNOWN'
        }
    }
    else {
        # Not a new item entry, so look for the current item entrys data.
        # Check if the current line is the item type.
        if ($Line[$l] -match 'type "(?<Type>\w+)"') {
            # Update the hashtable with the found value.
            $Item.Type = $Matches.Type
        }
        # Check if the current line is the item rarity.
        if ($Line[$l] -match '^data "Rarity" "(?<Rarity>\w+)"') {
            # Update the hashtable with the found value.
            $Item.Rarity = $Matches.Rarity
        }
        # Check if the current line is the item UUID.
        if ($Line[$l] -match '^data "RootTemplate" "(?<UUID>[a-f0-9-]+)"') {
            # Update the hashtable with the found value.
            $Item.UUID = $Matches.UUID
        }
    }
}

# Export the items to a the items CSV-file. Using semi-colon (;) as delimiter, simply because the CSV file will automatically be shown in colums, in spreadsheet programs.
$Items | Sort-Object -Property Name | Export-Csv -Force -NoTypeInformation -Encoding Default -Delimiter ';' -Path $ItemsCsvPath

# Build the Cheat Table.
foreach ($t in ($Items | Select-Object -ExpandProperty Type -Unique)) {
    $CtFile = "bg3_$($t.ToLower()).CT"
    $CtPath = Join-Path -Path $CheatTablesFolder -ChildPath $CtFile
    $CheatID = 1
    $CheatTableHead.Replace('@@CE_ID@@', $CheatID) | Out-File -Force -Encoding default -FilePath $CtPath
    foreach ($i in ($Items | Where-Object { $_.Type -eq $t} | Sort-Object -Property Name)) {
        $CheatID++
        $CheatEntryTemplate.Replace('@@CE_ID@@', $CheatID).Replace('@@ITEM_NAME@@', $i.Name).Replace('@@RARITY_COLOR@@', $RarityColor."$($i.Rarity)").Replace('@@ITEM_UUID@@', $i.UUID) | Out-File -Append -Encoding default -FilePath $CtPath
    }
    $CheatTableFoot | Out-File -Append -Encoding default -FilePath $CtPath
}
</edit>
<edit>
Issue with the bg_items.CT was a mixture of me forgetting to escape $lua and $asm in the table, which caused PowerShell to interpret them as variables rather than literal tekst. Apparently the CharacterPtr in the original, needs to be added at the bottom of mine as well, for it to work I would have thought it just was inherited from the first loaded. I don't know LUA or Assembler, so I'm just trying my way :oops:
</edit>
This is very, very incomplete. It's without a doubt missing the UUIDs for the Twitch items.

Post Reply

Who is online

Users browsing this forum: atamax, Baidu [Spider], didin, Ginger256, Google Adsense [Bot], guytonetter, Jetadawoot, ParadoxChris, Ricksanchez, sonycman, The Mogician, torinator, turophilia