The Long Dark (Steam/JLee3D)

Upload your cheat tables here (No requests)
L4Z3R37H
Noobzor
Noobzor
Posts: 8
Joined: Mon May 08, 2023 8:46 pm
Reputation: 6

Re: The Long Dark (Steam/JLee3D)

Post by L4Z3R37H »

Fixed infinite ammo script. If you fired a weapon indoors map wouldn't load properly when exiting a a building.

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
Attachments
tld.CT
(332.42 KiB) Downloaded 1479 times

Raven_Crossfade
What is cheating?
What is cheating?
Posts: 3
Joined: Fri Dec 23, 2022 10:54 pm
Reputation: 0

Re: The Long Dark (Steam/JLee3D)

Post by Raven_Crossfade »

Hey would it be possible to add disable ai scan. I've seen it in the table posted by beta99th. Not sure where it originally came from. But for version 2.06 was the last time it worked. Below is the script for it. I've tried to learn what I can to make it work but my skills are quite lacking, lol.

Code: Select all

[ENABLE]

aobscanmodule(DisableAIScan,GameAssembly.dll,80 BE 6C 05 00 00 00) // should be unique
alloc(newmem,$1000,DisableAIScan)

label(code)
label(return)

newmem:
  cmp byte ptr [rdi+0000056C],01
code:
  jmp return

DisableAIScan:
  jmp newmem
  nop 2
return:
registersymbol(DisableAIScan)

[DISABLE]

DisableAIScan:
  db 80 BE 6C 05 00 00 00

unregistersymbol(DisableAIScan)
dealloc(newmem)

rudeboyjohn
Cheater
Cheater
Posts: 49
Joined: Mon Sep 28, 2020 3:20 am
Reputation: 5

Re: The Long Dark (Steam/JLee3D)

Post by rudeboyjohn »

What are the chances for an update?

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

This was an ordeal to wade through all the old tables and try to build something useful. I hope this helps
Most scripts were broken but thanks to having so many samples of what worked in the past, I at least knew what to look for and what was possible.

All cheats were tested and fully working without crashing the game.
There were a couple that worked with no issues or with just some minor adjustments
There were probably 12 different tables referenced so I could identify the patterns for those that were broken.
I just did the legwork to get it to work with the current game (more of a novel puzzle for me... <shrug>)
JLee3D had a lot of detailed stuff in his table for this game (most broken right now but was good reference)

Hope you all enjoy it. Way too much work to go through all the others :P Even took ideas from other consoles since the logic is pretty close

Working cheats as of April 7, 2025:
no temp reduction
no fatigue/sleep
no hunger
no thirst
unlimited stamina
no item weight (thanks to AlexS post)
no fall damage
AI Ignore Player (Silent and Invisible) per latest request. Old code helped a lot in knowing where to look
No interaction time for containers
no breakdown time (Did not expand this yet for all the other timer tasks. Later perhaps)
No item degrade, max status and repair broken items
pickup range
Map (worked as-is, thanks to sub1to)
Inf Items (thanks to justi)
Unlock containers and crack safes
Skills (thanks to sub1to)
Remove Frostbite (Using this as template to go through all the other status effects later)
I also added a detailed inventory list including object type tags (I have only expanded clothing and Evolve types. There are ~70+ types but got too tedious so just stopped here
> I did have it highlight objects you already "touched", flag items that are locked/hidden and yellow text for collectible/training/knowledge items
> generates it on request for both player and current zone you are in (Grouped so you dont have to wade through area inventory)

Apparently too large to paste at one time. I will put in groups then.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>117487</ID>
      <Description>"Gameplay"</Description>
      <Options moDeactivateChildrenAsWell="1"/>
      <Color>FFFF00</Color>
      <GroupHeader>1</GroupHeader>
      <CheatEntries>
        <CheatEntry>
          <ID>117986</ID>
          <Description>"No sprains"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>// learned that 68 : m_SecondsSprainRisk under Sprains class if set to 0 should avoid risk of sprains
// I just skipped the process altogether by just returning to caller in Sprains.Update
// seems to work so far
[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(noSprains,Sprains.Update)
define(noSprains_Match,40 53 48 83 EC 40)

assert(noSprains,noSprains_Match)
alloc(newmem,$100,noSprains)
label(code return)

newmem:
  // 68 : m_SecondsSprainRisk
  mov [rbx+68],(float)0 // setting m_SecondsSprainRisk in case used elsewhere
  ret // skipping rest of Sprains.Update

code:
// never used but left for reference
db 40 53 48 83 EC 40
  jmp return

noSprains:
  jmp newmem
  nop
return:
registersymbol(noSprains)

[DISABLE]
noSprains:
db 40 53 48 83 EC 40

unregistersymbol(*)
dealloc(*)
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>9105</ID>
          <Description>"No Temp Reduction"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// There are other processes that will affect your temperature
// However, this will reset them all back to 0

aobscanmodule(noTempChange,GameAssembly.dll,F3 41 0F 11 74 24 20)
alloc(newmem,$100,noTempChange)
label(code return)

newmem:
  movss xmm6,xmm0
  //xmm0 will be 0, transfer to xmm6 then continue with normal code

code:
  // [r12+20] is the amount to reduce your normal body temp
  movss [r12+20],xmm6
  jmp return

noTempChange:
  jmp newmem
  nop 2
return:
registersymbol(noTempChange)

[DISABLE]
noTempChange:
  db F3 41 0F 11 74 24 20

unregistersymbol(*)
dealloc(*)

{ // Under Freezing.UpdateFreezingStatus
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+5DB2EA

GameAssembly.dll+5DB2BA - 74 0E                 - je GameAssembly.dll+5DB2CA
GameAssembly.dll+5DB2BC - 48 85 DB              - test rbx,rbx
GameAssembly.dll+5DB2BF - 0F84 27010000         - je GameAssembly.dll+5DB3EC
GameAssembly.dll+5DB2C5 - F3 0F10 73 60         - movss xmm6,[rbx+60]
GameAssembly.dll+5DB2CA - 48 8B 0D 2742C403     - mov rcx,[GameAssembly.dll+421F4F8]
GameAssembly.dll+5DB2D1 - F3 0F59 F7            - mulss xmm6,xmm7
GameAssembly.dll+5DB2D5 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+5DB2DC - 75 05                 - jne GameAssembly.dll+5DB2E3
GameAssembly.dll+5DB2DE - E8 5DABCEFF           - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+5DB2E3 - F3 41 0F58 74 24 20   - addss xmm6,[r12+20]
// ---------- INJECTING HERE ----------
GameAssembly.dll+5DB2EA - F3 41 0F11 74 24 20   - movss [r12+20],xmm6
// ---------- DONE INJECTING  ----------
GameAssembly.dll+5DB2F1 - 48 8B 0D 80CFC303     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5DB2F8 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+5DB2FF - 75 05                 - jne GameAssembly.dll+5DB306
GameAssembly.dll+5DB301 - E8 3AABCEFF           - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+5DB306 - E8 2565FFFF           - call GameAssembly.dll+5D1830
GameAssembly.dll+5DB30B - 48 85 C0              - test rax,rax
GameAssembly.dll+5DB30E - 0F84 D8000000         - je GameAssembly.dll+5DB3EC
GameAssembly.dll+5DB314 - EB 39                 - jmp GameAssembly.dll+5DB34F
GameAssembly.dll+5DB316 - F3 41 0F10 44 24 20   - movss xmm0,[r12+20]
GameAssembly.dll+5DB31D - F3 0F59 F7            - mulss xmm6,xmm7
GameAssembly.dll+5DB321 - F3 0F5C C6            - subss xmm0,xmm6
GameAssembly.dll+5DB325 - F3 41 0F11 44 24 20   - movss [r12+20],xmm0
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>117984</ID>
          <Description>"Player movement multiplier (hold shift key to slow speed to 1)"</Description>
          <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>// Based on original code from JLee3D (Glad he explained what process it was from)
// Noticed that xmm15 (not xmm13) appears to be calculated speed multiplier
// Instead of doing AOB later in this process, I opted to just set these 2 xmm and return instead of running rest of the class
// so far, it appears to work with no issues

[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(SnowMoveMultiplier,PlayerMovement.GetSnowDepthMovementMultiplier)
define(SnowMoveMultiplier_Match,40 53 48 83 EC 40)

assert(SnowMoveMultiplier,SnowMoveMultiplier_Match)
alloc(newmem,$100,SnowMoveMultiplier)
label(code SnowDepthMul return)
registersymbol(SnowDepthMul)

newmem:
  movss xmm0,[SnowDepthMul]
  movaps xmm15,xmm0
  ret // skipping rest of GetSnowDepthMovementMultiplier

code:
// never used but left for reference
db 40 53 48 83 EC 40
  jmp return

SnowDepthMul:
  dq (float)2.0

SnowMoveMultiplier:
  jmp newmem
  nop
return:
registersymbol(SnowMoveMultiplier)

[DISABLE]
SnowMoveMultiplier:
db 40 53 48 83 EC 40

unregistersymbol(*)
dealloc(*)

</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>117985</ID>
              <Description>"Speed Multiplier (Normal: 1)"</Description>
              <VariableType>Float</VariableType>
              <Address>SnowDepthMul</Address>
              <Hotkeys>
                <Hotkey OnlyWhileDown="1">
                  <Action>Set Value</Action>
                  <Keys>
                    <Key>16</Key>
                  </Keys>
                  <Value>1</Value>
                  <ID>0</ID>
                </Hotkey>
              </Hotkeys>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>9111</ID>
          <Description>"No Fatigue (no sleep needed)"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// There are other processes that will affect your fatigue
// However, this will reset them all back to 0

aobscanmodule(noFatigue,GameAssembly.dll,F3 0F 11 77 1C)
alloc(newmem,$100,noFatigue)

label(code return)

newmem:
  mov [rdi+1C], (float)0

code:
//  movss [rdi+1C],xmm6
  movss xmm6,[rdi+1C]
  jmp return

noFatigue:
  jmp newmem
return:
registersymbol(noFatigue)

[DISABLE]
noFatigue:
  db F3 0F 11 77 1C

unregistersymbol(*)
dealloc(*)

{ // under Fatigue.AddFatigue
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+5D7AC8

GameAssembly.dll+5D7AA0 - 48 8B CB              - mov rcx,rbx
GameAssembly.dll+5D7AA3 - E8 285AD402           - call UnityEngine.Object.op_Implicit
GameAssembly.dll+5D7AA8 - 84 C0                 - test al,al
GameAssembly.dll+5D7AAA - 74 17                 - je GameAssembly.dll+5D7AC3
GameAssembly.dll+5D7AAC - 48 85 DB              - test rbx,rbx
GameAssembly.dll+5D7AAF - 0F84 6E010000         - je GameAssembly.dll+5D7C23
GameAssembly.dll+5D7AB5 - 83 BB A0000000 02     - cmp dword ptr [rbx+000000A0],02
GameAssembly.dll+5D7ABC - 75 05                 - jne GameAssembly.dll+5D7AC3
GameAssembly.dll+5D7ABE - F3 0F59 73 44         - mulss xmm6,[rbx+44]
GameAssembly.dll+5D7AC3 - F3 0F58 77 1C         - addss xmm6,[rdi+1C]
// ---------- INJECTING HERE ----------
GameAssembly.dll+5D7AC8 - F3 0F11 77 1C         - movss [rdi+1C],xmm6
// ---------- DONE INJECTING  ----------
GameAssembly.dll+5D7ACD - 48 8B 0D A407C403     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5D7AD4 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+5D7ADB - 75 0C                 - jne GameAssembly.dll+5D7AE9
GameAssembly.dll+5D7ADD - E8 5EE3CEFF           - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+5D7AE2 - 48 8B 0D 8F07C403     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5D7AE9 - 80 3D A059E003 00     - cmp byte ptr [GameAssembly.dll+43DD490],00
GameAssembly.dll+5D7AF0 - 75 1A                 - jne GameAssembly.dll+5D7B0C
GameAssembly.dll+5D7AF2 - 48 8D 0D 7F07C403     - lea rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5D7AF9 - E8 12E7D7FF           - call GameAssembly.dll+356210
GameAssembly.dll+5D7AFE - 48 8B 0D 7307C403     - mov rcx,[GameAssembly.dll+4218278]
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>116498</ID>
          <Description>"No Hunger (Calorie Store at max)"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// There are other processes that will affect your calorie usage
// However, this will just bring it back to max

// This code requires mono
// I incorporated the mono init code within scripts that depend on it so that others could copy the individual cheats for their use.
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

aobscanregion(noHunger,Hunger.UpdateCalorieReserves,Hunger.UpdateCalorieReserves+1000,F3 0F 11 43 18 F3 0F 5C F0) // would be 2 matches but only 1 after Hunger.UpdateCalorieReserves
alloc(newmem,$100,noHunger)
label(code return)

newmem:
// [rbx+70] = Max Calorie Store (Read only)
// [rbx+18] = Current Calorie Store
  movss xmm0, [rbx+70]
code:
  movss [rbx+18], xmm0
  jmp return

noHunger:
  jmp newmem
return:
registersymbol(noHunger)

[DISABLE]

noHunger:
  db F3 0F 11 43 18

unregistersymbol(*)
dealloc(*)

{ // under Hunger.UpdateCalorieReserves
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+5E0921

GameAssembly.dll+5E08FE - F3 0F10 73 18         - movss xmm6,[rbx+18]
GameAssembly.dll+5E0903 - F3 0F10 4B 74         - movss xmm1,[rbx+74]
GameAssembly.dll+5E0908 - 0F28 C6               - movaps xmm0,xmm6
GameAssembly.dll+5E090B - F3 0F5C C7            - subss xmm0,xmm7
GameAssembly.dll+5E090F - 0F2F C8               - comiss xmm1,xmm0
GameAssembly.dll+5E0912 - 77 0A                 - ja GameAssembly.dll+5E091E
GameAssembly.dll+5E0914 - F3 0F10 4B 70         - movss xmm1,[rbx+70]
GameAssembly.dll+5E0919 - 0F2F C1               - comiss xmm0,xmm1
GameAssembly.dll+5E091C - 76 03                 - jna GameAssembly.dll+5E0921
GameAssembly.dll+5E091E - 0F28 C1               - movaps xmm0,xmm1
// ---------- INJECTING HERE ----------
GameAssembly.dll+5E0921 - F3 0F11 43 18         - movss [rbx+18],xmm0
// ---------- DONE INJECTING  ----------
GameAssembly.dll+5E0926 - F3 0F5C F0            - subss xmm6,xmm0
GameAssembly.dll+5E092A - 48 8B 0D 4779C303     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5E0931 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+5E0938 - 75 05                 - jne GameAssembly.dll+5E093F
GameAssembly.dll+5E093A - E8 0155CEFF           - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+5E093F - E8 8C16FFFF           - call GameAssembly.dll+5D1FD0
GameAssembly.dll+5E0944 - 48 85 C0              - test rax,rax
GameAssembly.dll+5E0947 - 0F84 E7000000         - je GameAssembly.dll+5E0A34
GameAssembly.dll+5E094D - 0F28 C6               - movaps xmm0,xmm6
GameAssembly.dll+5E0950 - F3 0F58 40 18         - addss xmm0,[rax+18]
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>24</ID>
          <Description>"No Thirst"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// There are other processes that will affect your thirst
// However, this will reset them all back to 0

aobscanmodule(noThirst,GameAssembly.dll,F3 0F 11 73 1C 48 8B CB E8)

alloc(newmem,$100,noThirst)
label(code return)

newmem:
  mov [rbx+1C], (float)0
  movss xmm6, [rbx+1C]
code:
  //movss [rbx+1C],xmm6
  jmp return

noThirst:
  jmp newmem
return:
registersymbol(noThirst)

[DISABLE]
noThirst:
  db F3 0F 11 73 1C

unregistersymbol(*)
dealloc(*)

{ // under Thirst.Update
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+5E3940

GameAssembly.dll+5E3922 - F3 0F58 73 1C         - addss xmm6,[rbx+1C]
GameAssembly.dll+5E3927 - 0F2F C6               - comiss xmm0,xmm6
GameAssembly.dll+5E392A - 77 0F                 - ja GameAssembly.dll+5E393B
GameAssembly.dll+5E392C - F3 0F10 4B 20         - movss xmm1,[rbx+20]
GameAssembly.dll+5E3931 - 0F2F F1               - comiss xmm6,xmm1
GameAssembly.dll+5E3934 - 76 08                 - jna GameAssembly.dll+5E393E
GameAssembly.dll+5E3936 - 0F28 F1               - movaps xmm6,xmm1
GameAssembly.dll+5E3939 - EB 03                 - jmp GameAssembly.dll+5E393E
GameAssembly.dll+5E393B - 0F57 F6               - xorps xmm6,xmm6
GameAssembly.dll+5E393E - 33 D2                 - xor edx,edx
// ---------- INJECTING HERE ----------
GameAssembly.dll+5E3940 - F3 0F11 73 1C         - movss [rbx+1C],xmm6
// ---------- DONE INJECTING  ----------
GameAssembly.dll+5E3945 - 48 8B CB              - mov rcx,rbx
GameAssembly.dll+5E3948 - E8 330E0000           - call Thirst.UpdateAddThirstOverTime
GameAssembly.dll+5E394D - 33 D2                 - xor edx,edx
GameAssembly.dll+5E394F - 48 8B CB              - mov rcx,rbx
GameAssembly.dll+5E3952 - E8 A9070000           - call Thirst.MaybePlayPlayerThirstVoiceOver
GameAssembly.dll+5E3957 - 80 3D C5E6DF03 00     - cmp byte ptr [GameAssembly.dll+43E2023],00
GameAssembly.dll+5E395E - 75 37                 - jne GameAssembly.dll+5E3997
GameAssembly.dll+5E3960 - 48 8D 0D 1149C303     - lea rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+5E3967 - E8 A428D7FF           - call GameAssembly.dll+356210
GameAssembly.dll+5E396C - 48 8D 0D CD76C303     - lea rcx,[GameAssembly.dll+421B040]
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>28</ID>
          <Description>"Unlimited Stamina"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// There are other processes that will affect your stamina
// However, this will reset your stamina back to 100

aobscanmodule(maxStamina,GameAssembly.dll,F3 0F 11 7B 78 0F)
alloc(newmem,$100,maxStamina)

label(code return)

newmem:
  mov [rbx+78],(float)100
  movss xmm7,[rbx+78]

code:
  // movss [rbx+78],xmm7
  jmp return

maxStamina:
  jmp newmem
return:
registersymbol(maxStamina)

[DISABLE]
maxStamina:
  db F3 0F 11 7B 78

unregistersymbol(*)
dealloc(*)

{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+D79DBE
// Also writes to stamina at GameAssembly.dll+D79D9D but chose last entry

GameAssembly.dll+D79D9D - F3 0F11 7B 78         - movss [rbx+78],xmm7
GameAssembly.dll+D79DA2 - E8 99DFFFFF           - call PlayerMovement.GetMaxSprintStaminaModifier
GameAssembly.dll+D79DA7 - 44 0F2F C7            - comiss xmm8,xmm7
GameAssembly.dll+D79DAB - F3 0F58 C6            - addss xmm0,xmm6
GameAssembly.dll+D79DAF - 77 0A                 - ja GameAssembly.dll+D79DBB
GameAssembly.dll+D79DB1 - 0F2F F8               - comiss xmm7,xmm0
GameAssembly.dll+D79DB4 - 76 08                 - jna GameAssembly.dll+D79DBE
GameAssembly.dll+D79DB6 - 0F28 F8               - movaps xmm7,xmm0
GameAssembly.dll+D79DB9 - EB 03                 - jmp GameAssembly.dll+D79DBE
GameAssembly.dll+D79DBB - 0F57 FF               - xorps xmm7,xmm7
// ---------- INJECTING HERE ----------
GameAssembly.dll+D79DBE - F3 0F11 7B 78         - movss [rbx+78],xmm7
// ---------- DONE INJECTING  ----------
GameAssembly.dll+D79DC3 - 0F28 74 24 40         - movaps xmm6,[rsp+40]
GameAssembly.dll+D79DC8 - 0F28 7C 24 30         - movaps xmm7,[rsp+30]
GameAssembly.dll+D79DCD - 44 0F28 44 24 20      - movaps xmm8,[rsp+20]
GameAssembly.dll+D79DD3 - 48 83 C4 50           - add rsp,50
GameAssembly.dll+D79DD7 - 5B                    - pop rbx
GameAssembly.dll+D79DD8 - C3                    - ret
GameAssembly.dll+D79DD9 - CC                    - int 3
GameAssembly.dll+D79DDA - CC                    - int 3
GameAssembly.dll+D79DDB - CC                    - int 3
GameAssembly.dll+D79DDC - CC                    - int 3
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>10087</ID>
          <Description>"No Item weight"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// direct injection
aobscanmodule(noItemWeight,GameAssembly.dll,4C 2B C2 49 8B C0)

noItemWeight:
  xor r8,r8 // essentially sets the value to 0
registersymbol(noItemWeight)

[DISABLE]
noItemWeight:
  db 4C 2B C2
unregistersymbol(*)

{ // Under GearItem.GetItemWeightKG
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+7DE1A2

GameAssembly.dll+7DE177 - 48 B8 BD427AE5D594BFD6 - mov rax,D6BF94D5E57A42BD
GameAssembly.dll+7DE181 - 49 F7 E8              - imul r8
GameAssembly.dll+7DE184 - 49 03 D0              - add rdx,r8
GameAssembly.dll+7DE187 - 48 C1 FA 17           - sar rdx,17
GameAssembly.dll+7DE18B - 48 8B CA              - mov rcx,rdx
GameAssembly.dll+7DE18E - 48 C1 E9 3F           - shr rcx,3F
GameAssembly.dll+7DE192 - 48 03 D1              - add rdx,rcx
GameAssembly.dll+7DE195 - 48 69 CA 80969800     - imul rcx,rdx,00989680
GameAssembly.dll+7DE19C - 49 8B D0              - mov rdx,r8
GameAssembly.dll+7DE19F - 48 2B D1              - sub rdx,rcx
// ---------- INJECTING HERE ----------
GameAssembly.dll+7DE1A2 - 4C 2B C2              - sub r8,rdx
// ---------- DONE INJECTING  ----------
GameAssembly.dll+7DE1A5 - 49 8B C0              - mov rax,r8
GameAssembly.dll+7DE1A8 - E9 3AF9FFFF           - jmp GameAssembly.dll+7DDAE7
GameAssembly.dll+7DE1AD - 49 8B 5E 70           - mov rbx,[r14+70]
GameAssembly.dll+7DE1B1 - 48 85 DB              - test rbx,rbx
GameAssembly.dll+7DE1B4 - 0F84 E7000000         - je GameAssembly.dll+7DE2A1
GameAssembly.dll+7DE1BA - 80 3D 5C4CC003 00     - cmp byte ptr [GameAssembly.dll+43E2E1D],00
GameAssembly.dll+7DE1C1 - 48 8B B3 20010000     - mov rsi,[rbx+00000120]
GameAssembly.dll+7DE1C8 - 75 13                 - jne GameAssembly.dll+7DE1DD
GameAssembly.dll+7DE1CA - 48 8D 0D 270CA403     - lea rcx,[GameAssembly.dll+421EDF8]
GameAssembly.dll+7DE1D1 - E8 3A80B7FF           - call GameAssembly.dll+356210
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>9109</ID>
          <Description>"No Fall Damage"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// This will skip the entire fall damage process and return back to the calling process
// I did see one example where xor rax, rax was used but did not see the reason so skipped it for now (from old broken code so may have made sense then)

// This code requires mono
// I incorporated the mono init code within scripts that depend on it so that others could copy the individual cheats for their use.
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

// check if the memory at a given address matches the expected byte sequence
// assert does the check and stops script if the bytes don't match
define(noFallDamage,FallDamage.ApplyFallDamage)
define(noFallDamage_Match,40 53 48 81 EC)

assert(noFallDamage,noFallDamage_Match)
alloc(newmem,$100,noFallDamage)
label(code ApplyFallDamage_Origbytes return)
registersymbol(ApplyFallDamage_Origbytes)

newmem:
  ret

code:
// This is not executed. However left it here for reference and needed when restoring original code on disable
ApplyFallDamage_Origbytes:
  readMem(noFallDamage, 9)
  jmp return

noFallDamage:
  jmp newmem
  nop 4
return:
registersymbol(noFallDamage)

[DISABLE]
noFallDamage:
  readMem(ApplyFallDamage_Origbytes, 9)

unregistersymbol(*)
dealloc(*)


{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+822F20 (FallDamage.ApplyFallDamage)

GameAssembly.dll+822F1F - CC                    - int 3
// ---------- INJECTING HERE ----------
FallDamage.ApplyFallDamage- 40 53                 - push rbx
GameAssembly.dll+822F22 - 48 81 EC C0000000     - sub rsp,000000C0
// ---------- DONE INJECTING  ----------
GameAssembly.dll+822F29 - 80 3D 7FFDBB03 00     - cmp byte ptr [GameAssembly.dll+43E2CAF],00
GameAssembly.dll+822F30 - 48 8B D9              - mov rbx,rcx
GameAssembly.dll+822F33 - 44 0F29 84 24 80000000  - movaps [rsp+00000080],xmm8
GameAssembly.dll+822F3C - 44 0F28 C2            - movaps xmm8,xmm2
GameAssembly.dll+822F40 - 44 0F29 4C 24 70      - movaps [rsp+70],xmm9
GameAssembly.dll+822F46 - 44 0F28 C9            - movaps xmm9,xmm1
GameAssembly.dll+822F4A - 75 67                 - jne GameAssembly.dll+822FB3
GameAssembly.dll+822F4C - 48 8D 0D 25539F03     - lea rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+822F53 - E8 B832B3FF           - call GameAssembly.dll+356210
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>9108</ID>
          <Description>"AI Ignore Player"</Description>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
// This code requires mono
// I incorporated the mono init code within scripts that depend on it so that others could copy the code for their use.
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

alloc(newmem,$100,GameAssembly.dll)
label(code1 code2 return1 return2)

label(aiIgnoreMe_Origbytes aiIgnoreMySounds_Origbytes)
registersymbol(aiIgnoreMe_Origbytes aiIgnoreMySounds_Origbytes)

//BaseAI.ScanForNewTarget
aobscanregion(aiIgnoreMe,BaseAi.ScanForNewTarget,BaseAi.ScanForNewTarget+100,80 be ? ? ? ? 00 0f 85)
//BaseAI.IgnoreAudioEvent
aobscanregion(aiIgnoreMySounds,BaseAi.IgnoreAudioEvent,BaseAi.IgnoreAudioEvent+400,80 bb ? ? ? ? 00 0f 85)

newmem:
aiIgnoreMe_Origbytes:
  readMem(aiIgnoreMe, 7)

aiIgnoreMySounds_Origbytes:
  readMem(aiIgnoreMySounds, 7)

code1:
  test rsi, rsi
  jmp return1

code2:
  test rsi, rsi
  jmp return2

aiIgnoreMe:
  jmp code1
  nop 2
return1:
registersymbol(aiIgnoreMe)

aiIgnoreMySounds:
  jmp code2
  nop 2
return2:
registersymbol(aiIgnoreMySounds)

[DISABLE]
aiIgnoreMe:
  readMem(aiIgnoreMe_Origbytes, 7)

aiIgnoreMySounds:
  readMem(aiIgnoreMySounds_Origbytes, 7)

unregistersymbol(*)
dealloc(*)

{ // Under BaseAI.ScanForNewTarget
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+53C1DA

GameAssembly.dll+53C19E - E8 6DA0E1FF           - call GameAssembly.dll+356210
GameAssembly.dll+53C1A3 - 48 8D 0D E62ECE03     - lea rcx,[GameAssembly.dll+421F090]
GameAssembly.dll+53C1AA - E8 61A0E1FF           - call GameAssembly.dll+356210
GameAssembly.dll+53C1AF - 48 8D 0D D22ECE03     - lea rcx,[GameAssembly.dll+421F088]
GameAssembly.dll+53C1B6 - E8 55A0E1FF           - call GameAssembly.dll+356210
GameAssembly.dll+53C1BB - 48 8D 0D 5ED8CA03     - lea rcx,[GameAssembly.dll+41E9A20]
GameAssembly.dll+53C1C2 - E8 49A0E1FF           - call GameAssembly.dll+356210
GameAssembly.dll+53C1C7 - 48 8D 0D 92C0CD03     - lea rcx,[GameAssembly.dll+4218260]
GameAssembly.dll+53C1CE - E8 3DA0E1FF           - call GameAssembly.dll+356210
GameAssembly.dll+53C1D3 - C6 05 395AEA03 01     - mov byte ptr [GameAssembly.dll+43E1C13],01
// ---------- INJECTING HERE ----------
GameAssembly.dll+53C1DA - 80 BE 64050000 00     - cmp byte ptr [rsi+00000564],00
// ---------- DONE INJECTING  ----------
GameAssembly.dll+53C1E1 - 0F85 45070000         - jne GameAssembly.dll+53C92C
GameAssembly.dll+53C1E7 - 48 8B 05 62CAEB03     - mov rax,[GameAssembly.dll+43F8C50]
GameAssembly.dll+53C1EE - 48 85 C0              - test rax,rax
GameAssembly.dll+53C1F1 - 75 1C                 - jne GameAssembly.dll+53C20F
GameAssembly.dll+53C1F3 - 48 8D 0D CE572C03     - lea rcx,[GameAssembly.dll+38019C8]
GameAssembly.dll+53C1FA - E8 415DDBFF           - call GameAssembly.DllCanUnloadNow+2A40
GameAssembly.dll+53C1FF - 48 85 C0              - test rax,rax
GameAssembly.dll+53C202 - 0F84 2D0E0000         - je GameAssembly.dll+53D035
GameAssembly.dll+53C208 - 48 89 05 41CAEB03     - mov [GameAssembly.dll+43F8C50],rax
GameAssembly.dll+53C20F - FF D0                 - call rax
}

{ // Under BaseAI.IgnoreAudioEvent
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+53E627

GameAssembly.dll+53E5F7 - C6 05 AFA2EB03 01     - mov byte ptr [GameAssembly.dll+43F88AD],01
GameAssembly.dll+53E5FE - 48 85 FF              - test rdi,rdi
GameAssembly.dll+53E601 - 0F84 23010000         - je GameAssembly.dll+53E72A
GameAssembly.dll+53E607 - 48 8B 05 52B3CA03     - mov rax,[GameAssembly.dll+41E9960]
GameAssembly.dll+53E60E - 48 8B 88 B8000000     - mov rcx,[rax+000000B8]
GameAssembly.dll+53E615 - 48 8B 01              - mov rax,[rcx]
GameAssembly.dll+53E618 - 48 39 47 10           - cmp [rdi+10],rax
GameAssembly.dll+53E61C - 0F94 C0               - sete al
GameAssembly.dll+53E61F - 84 C0                 - test al,al
GameAssembly.dll+53E621 - 0F84 D6000000         - je GameAssembly.dll+53E6FD
// ---------- INJECTING HERE ----------
GameAssembly.dll+53E627 - 80 BB 64050000 00     - cmp byte ptr [rbx+00000564],00
// ---------- DONE INJECTING  ----------
GameAssembly.dll+53E62E - 0F85 C9000000         - jne GameAssembly.dll+53E6FD
GameAssembly.dll+53E634 - 8B 83 68040000        - mov eax,[rbx+00000468]
GameAssembly.dll+53E63A - 83 F8 04              - cmp eax,04
GameAssembly.dll+53E63D - 0F8E D1000000         - jng GameAssembly.dll+53E714
GameAssembly.dll+53E643 - 83 F8 08              - cmp eax,08
GameAssembly.dll+53E646 - 0F85 A7000000         - jne GameAssembly.dll+53E6F3
GameAssembly.dll+53E64C - 0F29 74 24 40         - movaps [rsp+40],xmm6
GameAssembly.dll+53E651 - F2 0F10 83 48080000   - movsd xmm0,[rbx+00000848]
GameAssembly.dll+53E659 - F2 0F10 4D 00         - movsd xmm1,[rbp+00]
GameAssembly.dll+53E65E - 0F28 D8               - movaps xmm3,xmm0
}
</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>
Last edited by ParadoxDad on Fri Apr 11, 2025 7:24 pm, edited 2 times in total.

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

First one was gameplay
below is for interaction/skills/status effects (I will post an updated one to cover all the others)

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>117488</ID>
      <Description>"Interaction"</Description>
      <LastState Value="" RealAddress="00000000"/>
      <Color>FFFF00</Color>
      <GroupHeader>1</GroupHeader>
      <CheatEntries>
        <CheatEntry>
          <ID>8954</ID>
          <Description>"No interaction time for containers"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(noCITime,ContainerInteraction.UpdateInteraction)
define(noCI_Match,40 53 48 83 EC 30)

assert(noCITime,noCI_Match)
alloc(newmem,$100,noCITime)
label(code return)

newmem:
  mov eax, [rcx+58]
  mov [rcx+54], eax

code:
db 40 53 48 83 EC 30
  jmp return

noCITime:
  jmp newmem
  nop
return:
registersymbol(noCITime)

[DISABLE]
db 40 53 48 83 EC 30

unregistersymbol(*)
dealloc(*)

{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+88B340 (ContainerInteraction.UpdateInteraction)

GameAssembly.dll+88B33F - CC                    - int 3
// ---------- INJECTING HERE ----------
ContainerInteraction.UpdateInteraction- 40 53   - push rbx
GameAssembly.dll+88B342 - 48 83 EC 30           - sub rsp,30
// ---------- DONE INJECTING  ----------
GameAssembly.dll+88B346 - 45 33 C0              - xor r8d,r8d
GameAssembly.dll+88B349 - 0F29 74 24 20         - movaps [rsp+20],xmm6
GameAssembly.dll+88B34E - 0F28 F1               - movaps xmm6,xmm1
GameAssembly.dll+88B351 - 48 8B D9              - mov rbx,rcx
GameAssembly.dll+88B354 - 41 8D 50 01           - lea edx,[r8+01]
GameAssembly.dll+88B358 - E8 03578900           - call TLD.Interactions.BaseInteraction.TriggerEvent
GameAssembly.dll+88B35D - 80 7B 48 00           - cmp byte ptr [rbx+48],00
GameAssembly.dll+88B361 - 74 16                 - je GameAssembly.dll+88B379
GameAssembly.dll+88B363 - 48 8B 03              - mov rax,[rbx]
GameAssembly.dll+88B366 - 0F28 CE               - movaps xmm1,xmm6
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>116525</ID>
          <Description>"No breakdown time"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

aobscanregion(noBDTime,Panel_BreakDown.Update,Panel_BreakDown.Update+100,48 8B 13 33 F6)
alloc(newmem,$100,noBDTime)

label(code return)

newmem:
  // 164:m_TimeSpendBreakingDown (lookup of fields for Panel_BreakDown.Update via Mono dissector)
  mov [rbx+164], (float)99999 // Just use this as it should exceed all duration expectations

code:
db 48 8B 13 33 F6
  jmp return

noBDTime:
  jmp newmem
return:
registersymbol(noBDTime)

[DISABLE]
noBDTime:
db 48 8B 13 33 F6

unregistersymbol(*)
dealloc(*)

{ // under Panel_BreakDown.Update
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+93343D

GameAssembly.dll+933401 - E8 0A2EA2FF           - call GameAssembly.dll+356210
GameAssembly.dll+933406 - 48 8D 0D 13668B03     - lea rcx,[GameAssembly.dll+41E9A20]
GameAssembly.dll+93340D - E8 FE2DA2FF           - call GameAssembly.dll+356210
GameAssembly.dll+933412 - 48 8D 0D BF3B8F03     - lea rcx,[GameAssembly.dll+4226FD8]
GameAssembly.dll+933419 - E8 F22DA2FF           - call GameAssembly.dll+356210
GameAssembly.dll+93341E - 48 8D 0D 2B4E8E03     - lea rcx,[GameAssembly.dll+4218250]
GameAssembly.dll+933425 - E8 E62DA2FF           - call GameAssembly.dll+356210
GameAssembly.dll+93342A - 48 8D 0D 1F8C8A03     - lea rcx,[GameAssembly.dll+41DC050]
GameAssembly.dll+933431 - E8 DA2DA2FF           - call GameAssembly.dll+356210
GameAssembly.dll+933436 - C6 05 BBFEAA03 01     - mov byte ptr [GameAssembly.dll+43E32F8],01
// ---------- INJECTING HERE ----------
GameAssembly.dll+93343D - 48 8B 13              - mov rdx,[rbx]
GameAssembly.dll+933440 - 33 F6                 - xor esi,esi
// ---------- DONE INJECTING  ----------
GameAssembly.dll+933442 - 48 89 74 24 60        - mov [rsp+60],rsi
GameAssembly.dll+933447 - 48 8B CB              - mov rcx,rbx
GameAssembly.dll+93344A - 48 8B 82 98010000     - mov rax,[rdx+00000198]
GameAssembly.dll+933451 - 48 8B 92 A0010000     - mov rdx,[rdx+000001A0]
GameAssembly.dll+933458 - FF D0                 - call rax
GameAssembly.dll+93345A - 84 C0                 - test al,al
GameAssembly.dll+93345C - 0F84 89080000         - je GameAssembly.dll+933CEB
GameAssembly.dll+933462 - 48 8B 0D DF438E03     - mov rcx,[GameAssembly.dll+4217848]
GameAssembly.dll+933469 - 39 B1 E0000000        - cmp [rcx+000000E0],esi
GameAssembly.dll+93346F - 75 05                 - jne GameAssembly.dll+933476
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>8555</ID>
          <Description>"No Item Degrade / Max gear HP"</Description>
          <Options moDeactivateChildrenAsWell="1"/>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

aobscanregion(noItemDegradeMaxed,GearItem.Degrade,GearItem.Degrade+100,F3 0F 5C DE 0F 2E D3)
alloc(newmem,$100,noItemDegradeMaxed)

label(code return)

newmem:
  push rax
  // 340:m_GearItemData (TLD.Gear.GearItemData)(lookup of fields for GearItem via Mono dissector)
  // 50:m_MaxHP (lookup of fields for GearItemData via Mono dissector)
  mov rax,[rbx+340]
  movss xmm3,[rax+50]
  pop rax
  // 371:m_WornOut (bool)(lookup of fields for GearItem via Mono dissector)
  mov byte ptr [rbx+371],0

code:
  // subss xmm3,xmm6 // remarked out to skip degrade process
  ucomiss xmm2,xmm3
  jmp return

noItemDegradeMaxed:
  jmp newmem
  nop 2
return:
registersymbol(noItemDegradeMaxed)

[DISABLE]
noItemDegradeMaxed:
db F3 0F 5C DE 0F 2E D3

unregistersymbol(*)
dealloc(*)

{ // under GearItem.Degrade
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+7DBDCD

GameAssembly.dll+7DBD96 - 80 3D D16CC003 00     - cmp byte ptr [GameAssembly.dll+43E2A6E],00
GameAssembly.dll+7DBD9D - 48 8B D9              - mov rbx,rcx
GameAssembly.dll+7DBDA0 - 0F29 74 24 40         - movaps [rsp+40],xmm6
GameAssembly.dll+7DBDA5 - 0F28 F1               - movaps xmm6,xmm1
GameAssembly.dll+7DBDA8 - 75 13                 - jne GameAssembly.dll+7DBDBD
GameAssembly.dll+7DBDAA - 48 8D 0D 9FC4A303     - lea rcx,[GameAssembly.dll+4218250]
GameAssembly.dll+7DBDB1 - E8 5AA4B7FF           - call GameAssembly.dll+356210
GameAssembly.dll+7DBDB6 - C6 05 B16CC003 01     - mov byte ptr [GameAssembly.dll+43E2A6E],01
GameAssembly.dll+7DBDBD - F3 0F10 9B 38030000   - movss xmm3,[rbx+00000338]
GameAssembly.dll+7DBDC5 - F3 0F10 93 38030000   - movss xmm2,[rbx+00000338]
// ---------- INJECTING HERE ----------
GameAssembly.dll+7DBDCD - F3 0F5C DE            - subss xmm3,xmm6
GameAssembly.dll+7DBDD1 - 0F2E D3               - ucomiss xmm2,xmm3
// ---------- DONE INJECTING  ----------
GameAssembly.dll+7DBDD4 - 7A 02                 - jp GameAssembly.dll+7DBDD8
GameAssembly.dll+7DBDD6 - 74 28                 - je GameAssembly.dll+7DBE00
GameAssembly.dll+7DBDD8 - 4C 8B 83 30030000     - mov r8,[rbx+00000330]
GameAssembly.dll+7DBDDF - F3 0F11 9B 38030000   - movss [rbx+00000338],xmm3
GameAssembly.dll+7DBDE7 - 4D 85 C0              - test r8,r8
GameAssembly.dll+7DBDEA - 74 14                 - je GameAssembly.dll+7DBE00
GameAssembly.dll+7DBDEC - 49 8B 40 28           - mov rax,[r8+28]
GameAssembly.dll+7DBDF0 - 48 8B D3              - mov rdx,rbx
GameAssembly.dll+7DBDF3 - 49 8B 48 40           - mov rcx,[r8+40]
GameAssembly.dll+7DBDF7 - 48 89 44 24 20        - mov [rsp+20],rax
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>116517</ID>
          <Description>"Pickup Range"</Description>
          <Options moHideChildren="1"/>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>// This was found somewhere else. I just don't recall where and only cleaned up code
[ENABLE]
aobscanmodule(pickuprange,GameAssembly.dll,F3 0F 10 48 20 45 33 C0 48)
alloc(newmem,$100,pickuprange)

label(code return maxpickuprange)
registersymbol(maxpickuprange)

newmem:
  movss xmm1,[maxpickuprange] //movss xmm1,[rax+20]

code:
  jmp return

maxpickuprange:
  dq (float)20

pickuprange:
  jmp newmem
return:
registersymbol(pickuprange)

[DISABLE]
pickuprange:
  db F3 0F 10 48 20

unregistersymbol(*)
dealloc(*)

{ // under PlayerManager.InteractiveObjectsProcess
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+C5BE96

GameAssembly.dll+C5BE61 - 80 BB 10040000 00     - cmp byte ptr [rbx+00000410],00
GameAssembly.dll+C5BE68 - 0F85 65010000         - jne GameAssembly.dll+C5BFD3
GameAssembly.dll+C5BE6E - 48 8B 0D 03C45B03     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+C5BE75 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+C5BE7C - 75 05                 - jne GameAssembly.dll+C5BE83
GameAssembly.dll+C5BE7E - E8 BD9F66FF           - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+C5BE83 - 0F29 74 24 20         - movaps [rsp+20],xmm6
GameAssembly.dll+C5BE88 - E8 83228AFF           - call GameAssembly.dll+4FE110
GameAssembly.dll+C5BE8D - 48 85 C0              - test rax,rax
GameAssembly.dll+C5BE90 - 0F84 43010000         - je GameAssembly.dll+C5BFD9
// ---------- INJECTING HERE ----------
GameAssembly.dll+C5BE96 - F3 0F10 48 20         - movss xmm1,[rax+20]
// ---------- DONE INJECTING  ----------
GameAssembly.dll+C5BE9B - 45 33 C0              - xor r8d,r8d
GameAssembly.dll+C5BE9E - 48 8B CB              - mov rcx,rbx
GameAssembly.dll+C5BEA1 - E8 DA110000           - call PlayerManager.ComputeModifiedPickupRange
GameAssembly.dll+C5BEA6 - 0F28 F0               - movaps xmm6,xmm0
GameAssembly.dll+C5BEA9 - E8 521C8AFF           - call GameAssembly.dll+4FDB00
GameAssembly.dll+C5BEAE - 48 85 C0              - test rax,rax
GameAssembly.dll+C5BEB1 - 0F84 22010000         - je GameAssembly.dll+C5BFD9
GameAssembly.dll+C5BEB7 - 33 D2                 - xor edx,edx
GameAssembly.dll+C5BEB9 - 48 8B C8              - mov rcx,rax
GameAssembly.dll+C5BEBC - E8 2F61FEFF           - call PlayerManager.GetControlMode
}
</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>116518</ID>
              <Description>"Max Pickup Range (Normally: 2)"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <VariableType>Float</VariableType>
              <Address>maxpickuprange</Address>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>8850</ID>
          <Description>"Map"</Description>
          <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : tld.exe
  Version: 1.97 85101 S
  Date   : 2021-10-30
  Author : sub1to

  https://github.com/Perfare/Il2CppDumper

  // Namespace:
  [FlagsAttribute] // RVA: 0x12A50 Offset: 0x11E50 VA: 0x7FFB0B9E2A50
  private enum Panel_Map.ResetOpts // TypeDefIndex: 8834
  {
	  // Fields
	  public int value__; // 0x0
	  public const Panel_Map.ResetOpts None = 0;
	  public const Panel_Map.ResetOpts Zoomed = 1;
	  public const Panel_Map.ResetOpts CenterOnPlayer = 2;
	  public const Panel_Map.ResetOpts ShowPlayer = 4;

  public enum SurveyType // TypeDefIndex: 8825
  {
	  // Fields
	  public int value__; // 0x0
	  public const SurveyType Charcoal = 0;
	  public const SurveyType RockCache = 1;
	  public const SurveyType SprayPaint = 2;


  survey range per SurveyType:
  0:     rcx+F0
  1:     rcx+F4
  2:     rcx+F8
}

[ENABLE]
alloc(newmem,$400,GameAssembly.dll)
label(returnhere)
label(code)
label(code_survey)
label(code_resetopt)
label(rlock)
label(panel_map_reset_to_normal_hook)
label(panel_map_reset_to_normal_bytes)
label(panel_map_base_ptr)
label(panel_map_auto_survey_toggle)
label(panel_map_auto_survey_range)
label(panel_map_show_player_toggle)
registersymbol(panel_map_reset_to_normal_hook)
registersymbol(panel_map_reset_to_normal_bytes)
registersymbol(panel_map_base_ptr)
registersymbol(panel_map_auto_survey_toggle)
registersymbol(panel_map_auto_survey_range)
registersymbol(panel_map_show_player_toggle)

//  RVA: 0x109E300 Offset: 0x109D300 VA: 0x7FFB0CA6E300
//	private void ResetToNormal(Panel_Map.ResetOpts opts) { }
aobScanModule(hook,GameAssembly.dll,40 55 53 41 57 48 8b ec 48 81 ec ? ? ? ? 80 3d ? ? ? ? ? 44 8b fa)

//	RVA: 0x108D420 Offset: 0x108C420 VA: 0x7FFB0CA5D420
//	public void DoDetailSurvey(SurveyType surveyType = 0) { }
aobScanModule(panel_map_do_detail_survey,GameAssembly.dll,48 89 5c 24 ? 57 48 83 ec ? 0f 29 74 24 ? 48 8b d9 f3 0f 10 b1)

newmem:
panel_map_reset_to_normal_bytes:
  //mov rax,rsp
  //push rbp
  //push rdi
  readMem(hook, 5)
  jmp returnhere

panel_map_base_ptr:
  dq 0

panel_map_auto_survey_toggle:
  db 0

panel_map_auto_survey_range:
  dd (float)9999

panel_map_show_player_toggle:
  db 0

rlock:
  db 0

code:
  mov [panel_map_base_ptr], rcx

code_survey:
  cmp byte ptr [panel_map_auto_survey_toggle], 0
  jz code_resetopt

  //recursion lock
  cmp byte ptr [rlock], 0
  jnz code_resetopt
  mov byte ptr [rlock], 1

  //save rcx, rdx and [rcx+F0]
  lea rsp, [rsp-48]
  mov [rsp+30], rcx
  mov [rsp+28], rdx
  mov edx, [rcx+F0]
  mov [rsp+38], edx

  //survey the map
  mov edx, [panel_map_auto_survey_range]
  mov dword ptr [rcx+F0], edx
  xor rdx, rdx
  xor r8, r8
  call panel_map_do_detail_survey

  //restore rcx, rdx and [rcx+F0]
  mov rcx, [rsp+30]
  mov edx, [rsp+38]
  mov [rcx+F0], edx
  mov rdx, [rsp+28]
  lea rsp, [rsp+48]

  //unlock
  mov byte ptr [rlock], 0

code_resetopt:
  cmp byte ptr [panel_map_show_player_toggle], 0
  jz panel_map_reset_to_normal_bytes
  or edx, 6

  jmp panel_map_reset_to_normal_bytes

hook:
panel_map_reset_to_normal_hook:
  jmp code
  returnhere:



[DISABLE]
panel_map_reset_to_normal_hook:
  //db 48 8B C4 55 57
  readMem(panel_map_reset_to_normal_bytes, 5)

unregistersymbol(panel_map_reset_to_normal_hook)
unregistersymbol(panel_map_reset_to_normal_bytes)
unregistersymbol(panel_map_base_ptr)
unregistersymbol(panel_map_auto_survey_toggle)
unregistersymbol(panel_map_auto_survey_range)
unregistersymbol(panel_map_show_player_toggle)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "GameAssembly.dll"+109E300

"GameAssembly.dll"+109E2EE: CC                       -  int 3
"GameAssembly.dll"+109E2EF: E8 0C C1 02 FF           -  call GameAssembly.dll+CA400
"GameAssembly.dll"+109E2F4: CC                       -  int 3
"GameAssembly.dll"+109E2F5: E8 06 C1 02 FF           -  call GameAssembly.dll+CA400
"GameAssembly.dll"+109E2FA: CC                       -  int 3
"GameAssembly.dll"+109E2FB: CC                       -  int 3
"GameAssembly.dll"+109E2FC: CC                       -  int 3
"GameAssembly.dll"+109E2FD: CC                       -  int 3
"GameAssembly.dll"+109E2FE: CC                       -  int 3
"GameAssembly.dll"+109E2FF: CC                       -  int 3
// ---------- INJECTING HERE ----------
"GameAssembly.dll"+109E300: 48 8B C4                 -  mov rax,rsp
"GameAssembly.dll"+109E303: 55                       -  push rbp
"GameAssembly.dll"+109E304: 57                       -  push rdi
// ---------- DONE INJECTING  ----------
"GameAssembly.dll"+109E305: 41 54                    -  push r12
"GameAssembly.dll"+109E307: 41 56                    -  push r14
"GameAssembly.dll"+109E309: 41 57                    -  push r15
"GameAssembly.dll"+109E30B: 48 8D 68 A1              -  lea rbp,[rax-5F]
"GameAssembly.dll"+109E30F: 48 81 EC A0 00 00 00     -  sub rsp,000000A0
"GameAssembly.dll"+109E316: 48 C7 45 C7 FE FF FF FF  -  mov qword ptr [rbp-39],FFFFFFFE
"GameAssembly.dll"+109E31E: 48 89 58 10              -  mov [rax+10],rbx
"GameAssembly.dll"+109E322: 48 89 70 18              -  mov [rax+18],rsi
"GameAssembly.dll"+109E326: 0F 29 70 C8              -  movaps [rax-38],xmm6
"GameAssembly.dll"+109E32A: 0F 29 78 B8              -  movaps [rax-48],xmm7
}
</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>8854</ID>
              <Description>"Base"</Description>
              <ShowAsHex>1</ShowAsHex>
              <Color>C0C0C0</Color>
              <VariableType>8 Bytes</VariableType>
              <Address>panel_map_base_ptr</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>8852</ID>
              <Description>"Auto Survey (when map is opened)"</Description>
              <LastState/>
              <Color>00FF00</Color>
              <VariableType>Auto Assembler Script</VariableType>
              <AssemblerScript>[ENABLE]
panel_map_auto_survey_toggle:
  db 01

[DISABLE]
panel_map_auto_survey_toggle:
  db 00
</AssemblerScript>
              <CheatEntries>
                <CheatEntry>
                  <ID>8859</ID>
                  <Description>"Range"</Description>
                  <VariableType>Float</VariableType>
                  <Address>panel_map_auto_survey_range</Address>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
            <CheatEntry>
              <ID>8853</ID>
              <Description>"Show Player Arrow"</Description>
              <LastState/>
              <Color>00FF00</Color>
              <VariableType>Auto Assembler Script</VariableType>
              <AssemblerScript>[ENABLE]
panel_map_show_player_toggle:
  db 01

[DISABLE]
panel_map_show_player_toggle:
  db 00
</AssemblerScript>
            </CheatEntry>
            <CheatEntry>
              <ID>8857</ID>
              <Description>"Charcoal Survey Range"</Description>
              <VariableType>Float</VariableType>
              <Address>panel_map_base_ptr</Address>
              <Offsets>
                <Offset>F0</Offset>
              </Offsets>
            </CheatEntry>
            <CheatEntry>
              <ID>8855</ID>
              <Description>"Rock Cache Survey Range"</Description>
              <VariableType>Float</VariableType>
              <Address>panel_map_base_ptr</Address>
              <Offsets>
                <Offset>F4</Offset>
              </Offsets>
            </CheatEntry>
            <CheatEntry>
              <ID>8856</ID>
              <Description>"Spray Paint Survey Range"</Description>
              <VariableType>Float</VariableType>
              <Address>panel_map_base_ptr</Address>
              <Offsets>
                <Offset>F8</Offset>
              </Offsets>
            </CheatEntry>
            <CheatEntry>
              <ID>9081</ID>
              <Description>"Polaroid Survey Range"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <VariableType>Float</VariableType>
              <Address>panel_map_base_ptr</Address>
              <Offsets>
                <Offset>FC</Offset>
              </Offsets>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>14</ID>
          <Description>"Inf Items (Only on stackable items. Must have at least 2)"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : tld.exe
  Version: 
  Date   : 2024-03-04
  Author : justi

  This script does blah blah blah
}

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

 
 
aobscanmodule(MATCHES,GameAssembly.dll,44 29 78 18 48 8B 83 28 02 00 00) // should be unique
alloc(newmem,$100,MATCHES)

label(code return)

newmem:
  add [rax+18],r15d
  add [rax+18],r15d

code:
  sub [rax+18],r15d
  mov rax,[rbx+00000228]
  jmp return

MATCHES:
  jmp newmem
  nop 6
return:
registersymbol(MATCHES)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
MATCHES:
  db 44 29 78 18 48 8B 83 28 02 00 00

unregistersymbol(MATCHES)
dealloc(newmem)


{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+7B3548

GameAssembly.dll+7B3519: 48 8B 0D 80 6D 9E 03  - mov rcx,[GameAssembly.dll+419A2A0]
GameAssembly.dll+7B3520: 83 B9 E0 00 00 00 00  - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+7B3527: 75 05                 - jne GameAssembly.dll+7B352E
GameAssembly.dll+7B3529: E8 62 30 B1 FF        - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+7B352E: 33 D2                 - xor edx,edx
GameAssembly.dll+7B3530: 48 8B CF              - mov rcx,rdi
GameAssembly.dll+7B3533: E8 C8 61 3B 00        - call GameAssembly.dll+B69700
GameAssembly.dll+7B3538: 48 8B 83 28 02 00 00  - mov rax,[rbx+00000228]
GameAssembly.dll+7B353F: 48 85 C0              - test rax,rax
GameAssembly.dll+7B3542: 0F 84 66 06 00 00     - je GameAssembly.dll+7B3BAE
// ---------- INJECTING HERE ----------
GameAssembly.dll+7B3548: 44 29 78 18           - sub [rax+18],r15d
// ---------- DONE INJECTING  ----------
GameAssembly.dll+7B354C: 48 8B 83 28 02 00 00  - mov rax,[rbx+00000228]
GameAssembly.dll+7B3553: 48 85 C0              - test rax,rax
GameAssembly.dll+7B3556: 0F 84 52 06 00 00     - je GameAssembly.dll+7B3BAE
GameAssembly.dll+7B355C: 83 78 18 00           - cmp dword ptr [rax+18],00
GameAssembly.dll+7B3560: 0F 8F 11 03 00 00     - jg GameAssembly.dll+7B3877
GameAssembly.dll+7B3566: 48 8B 0D 43 23 9E 03  - mov rcx,[GameAssembly.dll+41958B0]
GameAssembly.dll+7B356D: 83 B9 E0 00 00 00 00  - cmp dword ptr [rcx+000000E0],00
GameAssembly.dll+7B3574: 75 05                 - jne GameAssembly.dll+7B357B
GameAssembly.dll+7B3576: E8 15 30 B1 FF        - call GameAssembly.il2cpp_field_static_set_value+42E0
GameAssembly.dll+7B357B: E8 E0 9B D6 FF        - call GameAssembly.dll+51D160
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>8956</ID>
          <Description>"Unlock containers"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript Async="1">[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

aobscanregion(unlockContainer,LockedInteraction.IsLocked, LockedInteraction.IsLocked+200,83 B8 80 00 00 00 00)
alloc(newmem,$100,unlockContainer)

label(code return)

newmem:
  // 80:m_LockState (lookup of fields for LockedInteraction.IsLocked, then under Lock\LockState (bvia Mono dissector)
  mov dword ptr [rax+0x80],1

code:
db 83 B8 80 00 00 00 00
  jmp return

unlockContainer:
  jmp newmem
  nop 2
return:
registersymbol(unlockContainer)

[DISABLE]
unlockContainer:
db 83 B8 80 00 00 00 00

unregistersymbol(*)
dealloc(*)

{ // under LockedInteraction.IsLocked
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+88C985

GameAssembly.dll+88C959 - E8 B298ACFF           - call GameAssembly.dll+356210
GameAssembly.dll+88C95E - C6 05 48BFB603 01     - mov byte ptr [GameAssembly.dll+43F88AD],01
GameAssembly.dll+88C965 - 48 8B 05 F4CF9503     - mov rax,[GameAssembly.dll+41E9960]
GameAssembly.dll+88C96C - 48 8B 88 B8000000     - mov rcx,[rax+000000B8]
GameAssembly.dll+88C973 - 48 8B 01              - mov rax,[rcx]
GameAssembly.dll+88C976 - 48 39 47 10           - cmp [rdi+10],rax
GameAssembly.dll+88C97A - 74 1E                 - je GameAssembly.dll+88C99A
GameAssembly.dll+88C97C - 48 8B 43 68           - mov rax,[rbx+68]
GameAssembly.dll+88C980 - 48 85 C0              - test rax,rax
GameAssembly.dll+88C983 - 74 22                 - je GameAssembly.dll+88C9A7
// ---------- INJECTING HERE ----------
GameAssembly.dll+88C985 - 83 B8 80000000 00     - cmp dword ptr [rax+00000080],00
// ---------- DONE INJECTING  ----------
GameAssembly.dll+88C98C - 0F94 C0               - sete al
GameAssembly.dll+88C98F - 48 8B 5C 24 30        - mov rbx,[rsp+30]
GameAssembly.dll+88C994 - 48 83 C4 20           - add rsp,20
GameAssembly.dll+88C998 - 5F                    - pop rdi
GameAssembly.dll+88C999 - C3                    - ret
GameAssembly.dll+88C99A - 48 8B 5C 24 30        - mov rbx,[rsp+30]
GameAssembly.dll+88C99F - 32 C0                 - xor al,al
GameAssembly.dll+88C9A1 - 48 83 C4 20           - add rsp,20
GameAssembly.dll+88C9A5 - 5F                    - pop rdi
GameAssembly.dll+88C9A6 - C3                    - ret
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>8845</ID>
          <Description>"Crack Safe"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(safeCracked,SafeCracking.Update)
define(scUpdate_Match,40 53 41 57 48 83)

assert(safeCracked,scUpdate_Match)
alloc(newmem,$100,safeCracked)
label(code scUpdate_Origbytes return)
registersymbol(scUpdate_Origbytes)

newmem:
  // 1C:m_Cracked (lookup of fields for SafeCracking.Update via Mono dissector)
  mov byte ptr [rcx+1C],1

code:
scUpdate_Origbytes:
  readMem(safeCracked, 8)
  jmp return

safeCracked:
  jmp newmem
  nop 3
return:
registersymbol(safeCracked)

[DISABLE]
safeCracked:
  readMem(scUpdate_Origbytes, 8)

unregistersymbol(*)
dealloc(*)


{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+77E980 (SafeCracking.Update)

GameAssembly.dll+77E97F - CC                    - int 3
// ---------- INJECTING HERE ----------
SafeCracking.Update     - 40 53                 - push rbx
GameAssembly.dll+77E982 - 41 57                 - push r15
GameAssembly.dll+77E984 - 48 83 EC 68           - sub rsp,68
// ---------- DONE INJECTING  ----------
GameAssembly.dll+77E988 - 80 3D 0D3FC603 00     - cmp byte ptr [GameAssembly.dll+43E289C],00
GameAssembly.dll+77E98F - 4C 8B F9              - mov r15,rcx
GameAssembly.dll+77E992 - 75 37                 - jne GameAssembly.dll+77E9CB
GameAssembly.dll+77E994 - 48 8D 0D 95D7A303     - lea rcx,[GameAssembly.dll+41BC130]
GameAssembly.dll+77E99B - E8 7078BDFF           - call GameAssembly.dll+356210
GameAssembly.dll+77E9A0 - 48 8D 0D D198A903     - lea rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+77E9A7 - E8 6478BDFF           - call GameAssembly.dll+356210
GameAssembly.dll+77E9AC - 48 8D 0D 6DB0A603     - lea rcx,[GameAssembly.dll+41E9A20]
GameAssembly.dll+77E9B3 - E8 5878BDFF           - call GameAssembly.dll+356210
GameAssembly.dll+77E9B8 - 48 8D 0D B1D7A303     - lea rcx,[GameAssembly.dll+41BC170]
}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>8787</ID>
          <Description>"Skills"</Description>
          <LastState Value="" RealAddress="00000000"/>
          <Color>FFFF00</Color>
          <GroupHeader>1</GroupHeader>
          <CheatEntries>
            <CheatEntry>
              <ID>8654</ID>
              <Description>"Skill (Open journal skill tab to activate)"</Description>
              <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
              <LastState/>
              <Color>00FF00</Color>
              <VariableType>Auto Assembler Script</VariableType>
              <AssemblerScript>{ Game   : tld.exe
  Version: 1.95 83861 S
  Date   : 2021-10-18
  Author : sub1to

  This script does blah blah blah


  Thanks to JLee:
    // enum SkillType
	public const SkillType None = -1; // 0x0
	public const SkillType Firestarting = 0; // 0x0
	public const SkillType CarcassHarvesting = 1; // 0x0
	public const SkillType IceFishing = 2; // 0x0
	public const SkillType Cooking = 3; // 0x0
	public const SkillType Rifle = 4; // 0x0
	public const SkillType Archery = 5; // 0x0
	public const SkillType ClothingRepair = 6; // 0x0
	public const SkillType ToolRepair = 7; // 0x0
	public const SkillType Revolver = 8; // 0x0
	public const SkillType Gunsmithing = 9; // 0x0
}

[ENABLE]
alloc(newmem,$200,GameAssembly.dll)
label(returnhere)
label(code)
label(code_fire)
label(code_carcass)
label(code_fish)
label(code_cook)
label(code_rifle)
label(code_archery)
label(code_mending)
label(code_tool_repair)
label(code_revolver)
label(code_gunsmith)
label(read_journal_skill_level_hook)
label(read_journal_skill_level_bytes)
label(fire_skill_base_ptr)
label(carcass_skill_base_ptr)
label(fish_skill_base_ptr)
label(cook_skill_base_ptr)
label(rifle_skill_base_ptr)
label(archery_skill_base_ptr)
label(mending_skill_base_ptr)
label(tool_repair_skill_base_ptr)
label(revolver_skill_base_ptr)
label(gunsmith_skill_base_ptr)
registersymbol(read_journal_skill_level_hook)
registersymbol(read_journal_skill_level_bytes)
registersymbol(fire_skill_base_ptr)
registersymbol(carcass_skill_base_ptr)
registersymbol(fish_skill_base_ptr)
registersymbol(cook_skill_base_ptr)
registersymbol(rifle_skill_base_ptr)
registersymbol(archery_skill_base_ptr)
registersymbol(mending_skill_base_ptr)
registersymbol(tool_repair_skill_base_ptr)
registersymbol(revolver_skill_base_ptr)
registersymbol(gunsmith_skill_base_ptr)
aobScanModule(hook,GameAssembly.dll,44 8B 41 58 45 85 C0)

newmem:
read_journal_skill_level_bytes:
  //mov r8d,[rcx+58]
  //test r8d,r8d
  readMem(hook, 7)
  jmp returnhere

fire_skill_base_ptr:
  dq 0

carcass_skill_base_ptr:
  dq 0

fish_skill_base_ptr:
  dq 0

cook_skill_base_ptr:
  dq 0

rifle_skill_base_ptr:
  dq 0

archery_skill_base_ptr:
  dq 0

mending_skill_base_ptr:
  dq 0

tool_repair_skill_base_ptr:
  dq 0

revolver_skill_base_ptr:
  dq 0

gunsmith_skill_base_ptr:
  dq 0

code:
code_fire:
  cmp dword ptr [rcx+20], 0
  jnz code_carcass
  mov [fire_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_carcass:
  cmp dword ptr [rcx+20], 1
  jnz code_fish
  mov [carcass_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_fish:
  cmp dword ptr [rcx+20], 2
  jnz code_cook
  mov [fish_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_cook:
  cmp dword ptr [rcx+20], 3
  jnz code_rifle
  mov [cook_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_rifle:
  cmp dword ptr [rcx+20], 4
  jnz code_archery
  mov [rifle_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_archery:
  cmp dword ptr [rcx+20], 5
  jnz code_mending
  mov [archery_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_mending:
  cmp dword ptr [rcx+20], 6
  jnz code_tool_repair
  mov [mending_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_tool_repair:
  cmp dword ptr [rcx+20], 7
  jnz code_revolver
  mov [tool_repair_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_revolver:
  cmp dword ptr [rcx+20], 8
  jnz code_gunsmith
  mov [revolver_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

code_gunsmith:
  cmp dword ptr [rcx+20], 9
  jnz read_journal_skill_level_bytes
  mov [gunsmith_skill_base_ptr], rcx
  jmp read_journal_skill_level_bytes

hook:
read_journal_skill_level_hook:
  jmp code
  nop
  nop
  returnhere:



[DISABLE]
read_journal_skill_level_hook:
  //db 44 8B 41 58 45 85 C0
  readMem(read_journal_skill_level_bytes, 7)

unregistersymbol(read_journal_skill_level_hook)
unregistersymbol(read_journal_skill_level_bytes)
unregistersymbol(fire_skill_base_ptr)
unregistersymbol(carcass_skill_base_ptr)
unregistersymbol(fish_skill_base_ptr)
unregistersymbol(cook_skill_base_ptr)
unregistersymbol(rifle_skill_base_ptr)
unregistersymbol(archery_skill_base_ptr)
unregistersymbol(mending_skill_base_ptr)
unregistersymbol(tool_repair_skill_base_ptr)
unregistersymbol(revolver_skill_base_ptr)
unregistersymbol(gunsmith_skill_base_ptr)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "GameAssembly.dll"+16E7854

"GameAssembly.dll"+16E7843: CC                    -  int 3
"GameAssembly.dll"+16E7844: E8 B7 2B 9E FE        -  call GameAssembly.dll+CA400
"GameAssembly.dll"+16E7849: CC                    -  int 3
"GameAssembly.dll"+16E784A: CC                    -  int 3
"GameAssembly.dll"+16E784B: CC                    -  int 3
"GameAssembly.dll"+16E784C: CC                    -  int 3
"GameAssembly.dll"+16E784D: CC                    -  int 3
"GameAssembly.dll"+16E784E: CC                    -  int 3
"GameAssembly.dll"+16E784F: CC                    -  int 3
"GameAssembly.dll"+16E7850: 48 83 EC 28           -  sub rsp,28
// ---------- INJECTING HERE ----------
"GameAssembly.dll"+16E7854: 44 8B 41 58           -  mov r8d,[rcx+58]
"GameAssembly.dll"+16E7858: 45 85 C0              -  test r8d,r8d
// ---------- DONE INJECTING  ----------
"GameAssembly.dll"+16E785B: 74 36                 -  je GameAssembly.dll+16E7893
"GameAssembly.dll"+16E785D: 48 8B 51 28           -  mov rdx,[rcx+28]
"GameAssembly.dll"+16E7861: 48 85 D2              -  test rdx,rdx
"GameAssembly.dll"+16E7864: 74 46                 -  je GameAssembly.dll+16E78AC
"GameAssembly.dll"+16E7866: 44 8B 4A 18           -  mov r9d,[rdx+18]
"GameAssembly.dll"+16E786A: 41 83 F9 04           -  cmp r9d,04
"GameAssembly.dll"+16E786E: 76 42                 -  jna GameAssembly.dll+16E78B2
"GameAssembly.dll"+16E7870: 44 3B 42 30           -  cmp r8d,[rdx+30]
"GameAssembly.dll"+16E7874: 74 2C                 -  je GameAssembly.dll+16E78A2
"GameAssembly.dll"+16E7876: 33 C9                 -  xor ecx,ecx
}
</AssemblerScript>
              <CheatEntries>
                <CheatEntry>
                  <ID>8878</ID>
                  <Description>"Fire Starting"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>fire_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8657</ID>
                  <Description>"Carcass Harvesting"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>carcass_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8658</ID>
                  <Description>"Fishing"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>fish_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8659</ID>
                  <Description>"Cooking"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>cook_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8660</ID>
                  <Description>"Rifle"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>rifle_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8656</ID>
                  <Description>"Archery"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>archery_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8661</ID>
                  <Description>"Mending"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>mending_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8663</ID>
                  <Description>"Revolver"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>revolver_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8664</ID>
                  <Description>"Gunsmithing"</Description>
                  <VariableType>4 Bytes</VariableType>
                  <Address>gunsmith_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>58</Offset>
                  </Offsets>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
            <CheatEntry>
              <ID>8786</ID>
              <Description>"Secondary Skills (Open tool repair/gun cleaning/sharpening screen to activate)"</Description>
              <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
              <LastState/>
              <Color>00FF00</Color>
              <VariableType>Auto Assembler Script</VariableType>
              <AssemblerScript>{ Game   : tld.exe
  Version: 2.22
  Date   : 2023-08-23
  Author : sub1to

  This script does blah blah blah

  +14  tool repair skill
  +18  gun cleaning skill
  +1C  sharpening skill
}

[ENABLE]
alloc(newmem,$ff,GameAssembly.dll)
label(code)
label(returnhere)
label(secondary_skill_hook)
label(secondary_skill_bytes)
label(secondary_skill_base_ptr)
registersymbol(secondary_skill_hook)
registersymbol(secondary_skill_bytes)
registersymbol(secondary_skill_base_ptr)
aobScanModule(hook,GameAssembly.dll,f3 0f 10 71 ? 48 8b 9d ? ? ? ? f3 0f 59 35 ? ? ? ? 48 85 db 0f 84 ? ? ? ? 48 8b 9b)

newmem:
secondary_skill_bytes:
  readMem(hook, 5)
  jmp returnhere

secondary_skill_base_ptr:
  dq 0

code:
  mov [secondary_skill_base_ptr], rcx
  jmp secondary_skill_bytes

hook:
secondary_skill_hook:
  jmp code
  returnhere:


[DISABLE]
secondary_skill_hook:
  readMem(secondary_skill_bytes, 5)

unregistersymbol(secondary_skill_hook)
unregistersymbol(secondary_skill_bytes)
unregistersymbol(secondary_skill_base_ptr)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+9EBBE5

GameAssembly.dll+9EBBB2: 48 89 5C 24 70           - mov [rsp+70],rbx
GameAssembly.dll+9EBBB7: 0F 29 74 24 50           - movaps [rsp+50],xmm6
GameAssembly.dll+9EBBBC: 0F 29 7C 24 40           - movaps [rsp+40],xmm7
GameAssembly.dll+9EBBC1: 48 8B 88 B8 00 00 00     - mov rcx,[rax+000000B8]
GameAssembly.dll+9EBBC8: 48 8B 81 50 03 00 00     - mov rax,[rcx+00000350]
GameAssembly.dll+9EBBCF: 48 85 C0                 - test rax,rax
GameAssembly.dll+9EBBD2: 0F 84 90 01 00 00        - je GameAssembly.dll+9EBD68
GameAssembly.dll+9EBBD8: 48 8B 48 18              - mov rcx,[rax+18]
GameAssembly.dll+9EBBDC: 48 85 C9                 - test rcx,rcx
GameAssembly.dll+9EBBDF: 0F 84 83 01 00 00        - je GameAssembly.dll+9EBD68
// ---------- INJECTING HERE ----------
GameAssembly.dll+9EBBE5: F3 0F 10 71 18           - movss xmm6,[rcx+18]
// ---------- DONE INJECTING  ----------
GameAssembly.dll+9EBBEA: 48 8B 9D C8 04 00 00     - mov rbx,[rbp+000004C8]
GameAssembly.dll+9EBBF1: F3 0F 59 35 63 F4 88 03  - mulss xmm6,[GameAssembly.dll+427B05C]
GameAssembly.dll+9EBBF9: 48 85 DB                 - test rbx,rbx
GameAssembly.dll+9EBBFC: 0F 84 66 01 00 00        - je GameAssembly.dll+9EBD68
GameAssembly.dll+9EBC02: 48 8B 9B F8 01 00 00     - mov rbx,[rbx+000001F8]
GameAssembly.dll+9EBC09: 48 85 DB                 - test rbx,rbx
GameAssembly.dll+9EBC0C: 0F 84 56 01 00 00        - je GameAssembly.dll+9EBD68
GameAssembly.dll+9EBC12: F3 0F 10 53 28           - movss xmm2,[rbx+28]
GameAssembly.dll+9EBC17: F3 0F 10 4B 2C           - movss xmm1,[rbx+2C]
GameAssembly.dll+9EBC1C: F3 0F 10 3D 44 F8 88 03  - movss xmm7,[GameAssembly.dll+427B468]
}
</AssemblerScript>
              <CheatEntries>
                <CheatEntry>
                  <ID>8711</ID>
                  <Description>"Tool Repair"</Description>
                  <ShowAsSigned>0</ShowAsSigned>
                  <VariableType>Float</VariableType>
                  <Address>secondary_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>10</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8789</ID>
                  <Description>"Gun Cleaning"</Description>
                  <ShowAsSigned>0</ShowAsSigned>
                  <VariableType>Float</VariableType>
                  <Address>secondary_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>14</Offset>
                  </Offsets>
                </CheatEntry>
                <CheatEntry>
                  <ID>8790</ID>
                  <Description>"Sharpening"</Description>
                  <ShowAsSigned>0</ShowAsSigned>
                  <VariableType>Float</VariableType>
                  <Address>secondary_skill_base_ptr</Address>
                  <Offsets>
                    <Offset>18</Offset>
                  </Offsets>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>12398</ID>
      <Description>"Remove_StatusEffects"</Description>
      <LastState Value="" RealAddress="00000000"/>
      <Color>FFFF00</Color>
      <GroupHeader>1</GroupHeader>
      <CheatEntries>
        <CheatEntry>
          <ID>52</ID>
          <Description>"Remove Frostbite"</Description>
          <LastState/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(cureFrostbite,Frostbite.Update)
define(FBUpdate_Match,40 53 48 83 EC 20)

assert(cureFrostbite,FBUpdate_Match)

alloc(newmem,$100,cureFrostbite)
label(code return)

newmem:
  lea rsp, [rsp-38]
  mov [rsp+30], rcx
  xor rdx, rdx
  call Frostbite.FrostbiteEnd
  mov rcx, [rsp+30]
  lea rsp, [rsp+38]

code:
db 40 53 48 83 EC 20
  jmp return

cureFrostbite:
  jmp newmem
  nop
return:
registersymbol(cureFrostbite)

[DISABLE]
cureFrostbite:
db 40 53 48 83 EC 20

unregistersymbol(*)
dealloc(*)

{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+825DB0 (Frostbite.Update)

GameAssembly.dll+825DAF - CC                    - int 3
// ---------- INJECTING HERE ----------
Frostbite.Update        - 40 53                 - push rbx
GameAssembly.dll+825DB2 - 48 83 EC 20           - sub rsp,20
// ---------- DONE INJECTING  ----------
GameAssembly.dll+825DB6 - 80 3D 0ACFBB03 00     - cmp byte ptr [GameAssembly.dll+43E2CC7],00
GameAssembly.dll+825DBD - 48 8B D9              - mov rbx,rcx
GameAssembly.dll+825DC0 - 75 1F                 - jne GameAssembly.dll+825DE1
GameAssembly.dll+825DC2 - 48 8D 0D AF249F03     - lea rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+825DC9 - E8 4204B3FF           - call GameAssembly.dll+356210
GameAssembly.dll+825DCE - 48 8D 0D 731A9F03     - lea rcx,[GameAssembly.dll+4217848]
GameAssembly.dll+825DD5 - E8 3604B3FF           - call GameAssembly.dll+356210
GameAssembly.dll+825DDA - C6 05 E6CEBB03 01     - mov byte ptr [GameAssembly.dll+43E2CC7],01
GameAssembly.dll+825DE1 - 48 8B 0D 90249F03     - mov rcx,[GameAssembly.dll+4218278]
GameAssembly.dll+825DE8 - 83 B9 E0000000 00     - cmp dword ptr [rcx+000000E0],00
}
</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>
Last edited by ParadoxDad on Tue Apr 08, 2025 5:55 pm, edited 1 time in total.

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

Last one is the detailed player and area inventory listings
Updated with these optional settings:
  • Filter: Show area inventory items
    Filter: By item groups (I created the groups. You can modify code to your liking as I included a list of all item properties)
    Filter: Exclude player touched items from area inventory list
    Update: Repair, max item health & set frozen/wet to 0 for clothing
    Update: Set minimum item count for stackable items

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>116563</ID>
      <Description>"Inventory"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

-- key/values in iFields are just ones I thought to bring in that were object types. Did not dig in to find out more about each &lt;shrug&gt;
-- I will leave it to others if you want to expand this more. I just did this for my own amusement.
-- Added sublayer to keep order intact since first match is generally the main object type
-- Note: The order is not the Field ID but weight I put on the object type

InvGV_iFields = {
  {0x60, 'BlueprintItemUnlock'},
  {0x1B0, 'NarrativeCollectibleItem'},
  {0x298, 'RecipeItem'},
  {0x1E0, 'ResearchItem'},
  {0x190, 'Knowledge'},
  {0x160, 'GunItem'},
  {0x38, 'AmmoItem'},
  {0x40, 'AmmoCasingItem'},
  {0x50, 'BearSpearItem'},
  {0x58, 'Bed'},
  {0x78, 'BowItem'},
  {0x48, 'ArrowItem'},
  {0x98, 'CharcoalItem'},
  {0xA8, 'ClothingItem'},
  {0x100, 'FirstAidItem'},
  {0xD8, 'EmergencyStim'},
  {0xF8, 'FireStarterItem'},
  {0x118, 'FlareItem'},
  {0x110, 'FlareGunRoundItem'},
  {0x120, 'FlashLightItem'},
  {0x188, 'KeroseneLampItem'},
  {0x248, 'TorchItem'},
  {0x1A0, 'MatchesItem'},
  {0x150, 'FuelSourceItem'},
  {0x128, 'FoodItem'},
  {0x140, 'ForceLockItem'},
  {0x158, 'HandheldShortwaveItem'},
  {0x1E8, 'Respirator'},
  {0x1F0, 'RespiratorCanister'},
  {0x1F8, 'RopeItem'},
  {0x240, 'ToolsItem'},
  {0x218, 'SnareItem'},
  {0x88, 'CanOpeningItem'},
  {0x250, 'Travois'},
  {0x260, 'WildlifeItem'},
  {0x2A0, 'InsulatedFlask'},
  {0x2A8, 'HeatPadItem'},
  {0x1D0, 'PurifyWater'},
  {0x258, 'WaterSupply'},
  {0x198, 'LiquidItem'},
  {0x1B8, 'NoiseMakerItem'},
  {0x1C0, 'ShowOnMapItem'},
  {0x90, 'CarryCapacityBuff'},
  {0xB0, 'ConditionOverTimeBuff'},
  {0xB8, 'ConditionRestBuff'},
  {0xF0, 'FatigueBuff'},
  {0x148, 'FreezingBuff'},
  {0x268, 'WolfIntimidationBuff'},
  {0x270, 'ClimbingBuff'},
  {0x278, 'ProtectionBuff'},
  {0x280, 'WeightReductionBuff'},
  {0x238, 'StruggleBonus'},
  {0xE0, 'EnergyBoost'},
  {0xD0, 'DegradeOnUse'},
  {0x1C8, 'PowderItem'},
  {0x170, 'IceFishingHoleClearItem'},
  {0x178, 'InProgressCraftItem'},
  {0x288, 'LureItem'},
  {0x290, 'BaitItem'},
  {0x230, 'StoneItem'},
  {0xC8, 'CookingPotItem'},
  {0x220, 'SprayPaintCan'},
  {0x168, 'Harvest'},
  {0x138, 'ForageItem'},
  {0x80, 'BreakDownItem'},
  {0x68, 'BodyHarvestItem'},
  {0x70, 'BodyHarvest'},
  {0x200, 'Scent'},
  {0x1D8, 'Repairable'},
  {0x208, 'Sharpenable'},
  {0x210, 'SmashableItem'},
  {0x228, 'StackableItem'},
  {0xA0, 'Cleanable'},
  {0xC0, 'Cookable'},
  {0x1A8, 'Millable'},
  {0x108, 'FirstPersonItem'},
  {0x180, 'Inspect'},
}

InvGV_iGroups = {
  [0] = {['Unlock / Knowledge / Collectible'] = {0x60, 0x190, 0x1B0, 0x1E0, 0x298}},
  [1] = {['Buffs'] = {0x90, 0xB0, 0xB8, 0xF0, 0x148, 0x268, 0x270, 0x278, 0x280}},
  [2] = {['Clothing &amp; Equippable gear'] = {0xA8, 0x1E8, 0x1F0}},
  [3] = {['Weapon / Ammo (excluding rocks)'] = {0x50, 0x78, 0x160, 0x38, 0x40, 0x48}},
  [4] = {['Tools / Utility / Hunting / Fishing'] = {0x1F8, 0x218, 0x240, 0x288, 0x290}},
  [5] = {['Fire / Light related'] = {0xF8, 0x110, 0x118, 0x120, 0x150, 0x188, 0x1A0, 0x248}},
  [6] = {['Food, Cooking and Recovery/Health related items'] = {0xC0, 0xC8, 0x128, 0x198, 0xD8, 0xE0, 0x100}},
  [7] = {['Other (catch-all)'] = {}}
}

local fgHeader = 'Filter: Apply Item group filter (Area only)'
invGV_fGroups = {}
-- Populate IGroups entries under InvGV_GHeader
local tmrGHeader = AddressList.getMemoryRecordByDescription(fgHeader)
if tmrGHeader == nil then
  error(' Unable to find record with description "'..fgHeader..'"')
end
for i=tmrGHeader.Count-1,0,-1 do
  tmrGHeader.Child[i].delete()
end
local k1,v1,k2,v2
for k1,v1 in pairs(InvGV_iGroups) do
  for k2,v2 in pairs(v1) do
    local GrItem = AddressList.createMemoryRecord()
    GrItem.description = k2
    GrItem.IsGroupHeader = true
    GrItem.Color = 0x00A400
    GrItem.Active = k1 &lt; 5 -- my defaults, ignoring fire/food/other if filtered (normally not)
    GrItem.appendToEntry(tmrGHeader)
    invGV_fGroups[k1] = GrItem.ID
  end
end

-- when you disable this, The collapsable folder with parameters is collapsed by default. Open it back up
AddressList.getMemoryRecordByID(memrec.Id)[0].Collapsed = false
{$asm}

alloc(newmem,$100)
label(inv_IncludeArea inv_MaxLimit inv_Repairitems inv_SetMinCnt inv_MinStackableCnt inv_IgnoreTouched inv_ApplyGroupFilter)
registersymbol(inv_IncludeArea inv_MaxLimit inv_Repairitems inv_SetMinCnt inv_MinStackableCnt inv_IgnoreTouched inv_ApplyGroupFilter)

newmem:
inv_IncludeArea:      // 1 byte - 0/1
db 1

inv_MaxLimit:         // 4 byte - integer
dd #200

inv_Repairitems:      // 1 byte - 0/1
db 0

inv_SetMinCnt:        // 1 byte - 0/1
db 0

inv_MinStackableCnt:  // 4 byte - integer
dd 4

inv_IgnoreTouched:    // 1 byte - 0/1
db 1

inv_ApplyGroupFilter: // 1 byte - 0/1
db 0

[DISABLE]
{$lua}
-- clear global variables set here
InvGV_iFields = nil
InvGV_iGroups = nil
invGV_fGroups = nil
{$asm}

unregistersymbol(*)
dealloc(*)

</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>117987</ID>
          <Description>"Get/Update Inventory List based on Parameters set below"</Description>
          <Options moManualExpandCollapse="1" moDeactivateChildrenAsWell="1"/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

local mr_inv = AddressList.getMemoryRecordByDescription('InventoryBasePtr')
for i=mr_inv.Count-1,0,-1 do
  mr_inv.Child[i].delete()
end

local function SetFlagStrings(ObjectAddr)
  local ItemFlags = {
    {0xd0, 'Degrade on use'},
    {0x31, 'Hidden'},
    {0x30, 'Locked'},
    {0x23, 'In Satchel/Container'},
    {0x28, 'In Satchel/Container'},
    {0x1c, 'Touched by player'},
    {0x1d, 'Touched by player'},
    {0x1f, 'Touched by player'},
    {0x21, 'Touched by player'}
  }
  local flagValues = {}
  local k,v
  for k,v in pairs(ItemFlags) do
    if readBytes(ObjectAddr+v[1], 1, false) == 1 then
      flagValues[v[2]] = v[2]
    end
  end
  --return table.concat(flagValues, ', ')
  -- I tried other ways but seems table.concat is not working here so built string this way
  local Result = ''
  for k,v in pairs(flagValues) do
    Result = Result..v..', '
  end
  return string.sub(Result,1,-3)
end

local function TrimFirstUnderScore(tStrVal)
  local Result = 'No name found' -- in case tStrVal is nil
  if tStrVal ~= nil then
    -- used or to replace nil value with 0. This way if no match, will show entire string instead of error
    Result = string.sub(tStrVal, (string.find(tStrVal,'_') or 0)+1)
  end
  return Result
end

--table.sort not working as intended so using old fashioned quicksort
local function qsTopMemoryRecords(mrGroup, istart, iend)
  local Result, ipivot
  istart = istart or 1
  iend = iend or #mrGroup
  if iend - istart &lt; 1 then
    Result = mrGroup
  else
    ipivot = istart
    for i = istart + 1, iend do
      if mrGroup[i].description &lt;= mrGroup[ipivot].description then
        if i == ipivot + 1 then
          mrGroup[ipivot],mrGroup[ipivot+1] = mrGroup[ipivot+1],mrGroup[ipivot]
        else
          mrGroup[ipivot],mrGroup[ipivot+1],mrGroup[i] = mrGroup[i],mrGroup[ipivot],mrGroup[ipivot+1]
        end
        ipivot = ipivot + 1
      end
    end
    mrGroup = qsTopMemoryRecords(mrGroup, istart, ipivot - 1)
    Result = qsTopMemoryRecords(mrGroup, ipivot + 1, iend)
  end
  return Result
end

local function ParseTableChildrenToMR(mrParent, srcTable)
  local tmr,k,v
  if srcTable.Children ~= nil then
    for _,tmr in pairs(srcTable.Children) do
      -- check if description matches evolve

      local mr = AddressList.createMemoryRecord()
      for k,v in pairs(tmr) do
        if string.sub(k,1,1) ~= '_' and k ~= 'Children' and k ~= 'Offset' then
          -- _*, Children &amp; Offset are handled separately. Could not just do type in this case
          mr[k] = v
        end
      end
      mr.appendToEntry(mrParent)
      -- now add offset if it exists
      if tmr.OffsetCount ~= nil then
        mr.OffsetCount = tmr.OffsetCount
        for k,v in pairs(tmr.Offset) do
          mr.Offset[k] = v
        end
      end
      -- add children
      ParseTableChildrenToMR(mr, tmr)
      -- try to close if have children
      if mr.count &gt; 0 then
        mr.Collapsed = true
      end
    end
  end
end

local function RepairTgtItem(iBaseAStr)
  local iMaxHP = readFloat('[['..iBaseAStr..']+340]+50')
  local iCurHPPtr = '['..iBaseAStr..']+338'
  local ClothingWetPtr = '[['..iBaseAStr..']+A8]+98'
  local ClothingFrozenPtr = '[['..iBaseAStr..']+A8]+9C'
  if iMaxHP ~= nil and iMaxHP ~= 0 and readFloat(iCurHPPtr) &gt; 0 then
    writeFloat(iCurHPPtr, iMaxHP)
  end
  if readFloat(ClothingWetPtr) ~= nil and readFloat(ClothingFrozenPtr) ~= nil then
    writeFloat(ClothingWetPtr, 0)
    writeFloat(ClothingFrozenPtr, 0)
  end
end

local function SetMinStackCnt(iBaseAStr, MinStackCnt)
  local StackCntPtr = '[['..iBaseAStr..']+228]+18'
  local StackCnt = readInteger(StackCntPtr)
  if StackCnt ~= nil and StackCnt &gt; 0 and StackCnt &lt; MinStackCnt then
    writeInteger(StackCntPtr, MinStackCnt)
  end
end

local function GetMainGrpId(iBaseAStr)
  local Result = nil

  local k1,v1,k2,v2,k3,v3
  for k1,v1 in pairs(InvGV_iGroups) do
    for k2,v2 in pairs(v1) do
      for k3,v3 in pairs(v2) do
        if readQword('['..iBaseAStr..']+'..string.format('%x',v3)) ~= 0 then
          Result = k1
          break
        end
      end
      if Result ~= nil then
        break
      end
    end
    if Result ~= nil then
      break
    end
  end
  if Result == nil then
    Result = #InvGV_iGroups -- the last row in #InvGV_iGroups shoule have empty table (catch-all)
  end

  return Result
end

local function IsSkipItem(iBaseAStr)
  local iPlayerTouched = {0x1c,0x1d,0x1f,0x21}
  local Result = false
  local k,v
  for k,v in pairs(iPlayerTouched) do
    if readBytes('['..iBaseAStr..']+'..string.format('%x',v),1,false) == 1 then
      Result = true
      break
    end
  end

  return Result
end

-- The work items below will be done later
-- create child group headers for each group type
-- Iterate through xx items and add them to appropriate groups
-- when done, remove groups that have no children to clean view up

-- will have these be values in CE table later
local clrBaseItem = 0xFFFF00
local clrSubPropGrp = 0x808000
local clrItemTypes = 0x008000
local clrROField = 0xC0C0C0
local clrTouched = 0x008080
local clrLockedHidden = 0x4080FF
local clrCollKnowGrp = 0x00FFFF

local maxItemsList = readInteger("inv_MaxLimit") or 100
local ShowAreaItems = readBytes("inv_IncludeArea",1,false) &gt; 0
local RepairItems = readBytes("inv_Repairitems",1,false) &gt; 0
local SetMinCnt = readBytes("inv_SetMinCnt",1,false) &gt; 0
local MinStackCnt = readInteger("inv_MinStackableCnt") or 4
local SkipPlayerTouched = readBytes("inv_IgnoreTouched",1,false) &gt; 0
local ApplyGFilter = readBytes("inv_ApplyGroupFilter",1,false) &gt; 0
local IsPlayerItem = false
local iMainGrpId

local iSeq = 0
local continueLoop = true
local showItemID = false
local ceTable = {}
local EvolveDesc = 'Evolve Stats'
local iCntPlayer = 0
local iCntArea = 0
local iCntAreaNF = 0
local SkipItem = false

while continueLoop == true do
  local iBaseAStr = '[[[[GameAssembly.dll+421E880]+b8]]+10]+20+8*'..string.format('%x',iSeq)
  local iBaseAddr = readQword(iBaseAStr)

  if iBaseAddr ~= 0 then
    -- identify if player or area item (0x20 = m_InPlayerInventory)
    IsPlayerItem = readBytes(iBaseAddr+0x20, 1, false) == 1
    -- set iMainGrpId (used for filtering)
    iMainGrpId = GetMainGrpId(iBaseAStr)
    if IsPlayerItem == true then
      iCntPlayer = iCntPlayer + 1
      SkipItem = iCntPlayer &gt; maxItemsList
    else
      iCntAreaNF = iCntAreaNF + 1
      SkipItem = iCntArea &gt;= maxItemsList or not ShowAreaItems
      SkipItem = SkipItem or SkipPlayerTouched and IsSkipItem(iBaseAStr)
      SkipItem = SkipItem or ApplyGFilter and AddressList.getMemoryRecordByID(invGV_fGroups[iMainGrpId]).active ~= true
      -- only update iCntArea if not filtered out
      if SkipItem == false then
        iCntArea = iCntArea + 1
      end
    end
    -- skip this item if exceeds max (still add to count but not list items)
    if not SkipItem then
      tmr = {}
      local iName = TrimFirstUnderScore(readString('[[[['..iBaseAStr..']+340]+68]+10]+14', 128, true))

      if showItemID then
        tmr.description = iSeq..': '..iName
      else
        tmr.description = iName
      end
      tmr.Type = vtQword
      tmr.Address = iBaseAStr
      tmr.Color = clrBaseItem
      tmr.IsAddressGroupHeader = true
      tmr.options = 'moManualExpandCollapse'
      tmr._IsPlayerItem = IsPlayerItem
      tmr._IsStackable = readQword('['..iBaseAStr..']+228') ~= 0
      tmr._IsClothing = readQword('['..iBaseAStr..']+A8') ~= 0
      tmr.Children = {}

      -- now identify flags and append to description (Only if not in player inventory)
      if not IsPlayerItem then
        local FlagStr = SetFlagStrings(iBaseAddr)
        if string.len(FlagStr) &gt; 0 then
          tmr.description = tmr.description..' ('..FlagStr..')'
          -- change color if touched by player (means you probably dropped it for a reason, its not a new item)
          if string.find(string.lower(FlagStr),'player') ~= nil then
            tmr.Color = clrTouched
          elseif string.find(string.lower(FlagStr),'hidden') ~= nil or string.find(string.lower(FlagStr),'locked') ~= nil then
            tmr.Color = clrLockedHidden
          end
        end
      end

      if tmr._IsStackable == true then
        local tmrL1 = {}
        tmrL1.description = 'Stack Count'
        tmrL1.Type = vtDword
        tmrL1.Address = '+0'
        tmrL1.OffsetCount = 2
        tmrL1.Offset = {}
        tmrL1.Offset[1] = 0x228
        tmrL1.Offset[0] = 0x18
        table.insert(tmr.Children, tmrL1)
      end

      local tmrL1 = {}
      tmrL1.description = 'Quality (HP)'
      tmrL1.Type = vtSingle
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 1
      tmrL1.Offset = {}
      tmrL1.Offset[0] = 0x338
      table.insert(tmr.Children, tmrL1)

      local tmrL1 = {}
      tmrL1.description = 'Max Quality (HP)'
      tmrL1.Type = vtSingle
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 2
      tmrL1.Offset = {}
      tmrL1.Offset[1] = 0x340
      tmrL1.Offset[0] = 0x50
      tmrL1.Color = clrROField
      table.insert(tmr.Children, tmrL1)

      local tmrL1 = {}
      tmrL1.description = 'Is Broken'
      tmrL1.Type = vtByte
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 1
      tmrL1.Offset = {}
      tmrL1.Offset[0] = 0x228
      table.insert(tmr.Children, tmrL1)

      if tmr._IsClothing == true then
        local tmrL1 = {}
        tmrL1.description = 'Clothing Stats'
        tmrL1.IsAddressGroupHeader = true
        tmrL1.Address = '+0'
        tmrL1.OffsetCount = 1
        tmrL1.Offset = {}
        tmrL1.Offset[0] = 0xA8
        tmrL1.options = 'moManualExpandCollapse'
        tmrL1.Color = clrSubPropGrp
        tmrL1.Children = {}

        local tmrL2 = {}
        tmrL2.description = 'Warmth %'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x30
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Windproof %'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x38
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Toughness'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x3C
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Waterproofness %'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x44
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Wet %'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x98
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Frozen %'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x9C
        table.insert(tmrL1.Children, tmrL2)

        table.insert(tmr.Children, tmrL1)
      end

      local tmrL1 = {}
      if readQword('['..iBaseAStr..']+E8') ~= 0 then
        tmrL1.description = EvolveDesc
        tmrL1.IsAddressGroupHeader = true
        tmrL1.Type = vtQword
        tmrL1.Address = '+0'
        tmrL1.OffsetCount = 1
        tmrL1.Offset = {}
        tmrL1.Offset[0] = 0xE8
        tmrL1.Color = clrSubPropGrp
        tmrL1.Children = {}

        local tmrL2 = {}
        tmrL2.description = 'Gear Item to become'
        tmrL2.Type = vtString
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 5
        tmrL2.Offset = {}
        tmrL2.Offset[4] = 0x20
        tmrL2.Offset[3] = 0x340
        tmrL2.Offset[2] = 0x68
        tmrL2.Offset[1] = 0x10
        tmrL2.Offset[0] = 0x26
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Start Evolve %'
        tmrL2.Type = vtDword
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x28
        table.insert(tmrL1.Children, tmrL2)

        local tmrL2 = {}
        tmrL2.description = 'Time To Evolve Game Days'
        tmrL2.Type = vtSingle
        tmrL2.Address = '+0'
        tmrL2.OffsetCount = 1
        tmrL2.Offset = {}
        tmrL2.Offset[0] = 0x2C
        table.insert(tmrL1.Children, tmrL2)

        table.insert(tmr.Children, tmrL1)
      end

      -- create header containing all objectFields that contain a pointer to use for filtering and expanding content in Inventory if you choose to do so
      local iObjList = {}
      local k,v
      for k,v in pairs(InvGV_iFields) do
        if readQword(iBaseAddr+v[1]) ~= 0 then
          table.insert(iObjList, v) --v[2] for specifics but going to use this for cross reference on iGroups table
        end
      end
      if #iObjList &gt; 0 then
        tmr.description = tmr.description..' ['..iObjList[1][2]..']'
        local tmrL1 = {}
        tmrL1.description = 'Valid Object Fields (Object count: '..#iObjList..')'
        tmrL1.Color = clrSubPropGrp
        tmrL1.IsGroupHeader = true
        tmrL1.options = 'moManualExpandCollapse'
        tmrL1.Children = {}

        for _,v in pairs(iObjList) do
          local tmrL2 = {}
          tmrL2.description = v[2]
          tmrL2.Color = clrItemTypes
          tmrL2.IsGroupHeader = true
          table.insert(tmrL1.Children, tmrL2)
        end
        table.insert(tmr.Children, tmrL1)
      end
      -- Although I did do the work to someday expand this to filter / group items based on identified categories, I am just going to highlight the Collectible/Research/Unlock one for now with identified color instead
      if iMainGrpId == 0 then -- 0 = 'Unlock / Knowledge / Collectible'
        tmr.Color = clrCollKnowGrp
      end

      table.insert(ceTable, tmr)
    end
    iSeq = iSeq + 1
    continueLoop = iCntPlayer &lt; maxItemsList or iCntArea &lt; maxItemsList
  else
    continueLoop = false
  end
end
-- if is collectible, research or ... then color is 00C4C4 (gold) or perhaps yellow
-- first group. Maybe add option to set flags or color based on user preference

-- now sort tables before adding as memory records
ceTable = qsTopMemoryRecords(ceTable)

-- create main headers (Player, Area)
local mrPlayerInv = AddressList.createMemoryRecord()
mrPlayerInv.description = 'Player Inventory'
mrPlayerInv.IsGroupHeader = true
mrPlayerInv.options = 'moManualExpandCollapse'
mrPlayerInv.appendToEntry(mr_inv)

local mrAreaInv = AddressList.createMemoryRecord()
mrAreaInv.description = 'Area Inventory'
mrAreaInv.IsGroupHeader = true
mrAreaInv.options = 'moManualExpandCollapse'
mrAreaInv.appendToEntry(mr_inv)

local mrTarget
local k,v
-- Now that the content has been sorted, I can start adding the memoryrecords
for _,tmr in pairs(ceTable) do
  if tmr._IsPlayerItem then
    mrTarget = mrPlayerInv
  else
    mrTarget = mrAreaInv
  end

  local mr = AddressList.createMemoryRecord()
  for k,v in pairs(tmr) do
    if string.sub(k,1,1) ~= '_' and k ~= 'Children' and k ~= 'Offset' then
      -- _*, Children &amp; Offset are handled separately. Could not just do type in this case
      mr[k] = v
    end
  end
  mr.appendToEntry(mrTarget)
  local mrCollapse = true
  -- Perhaps add logic later where if criteria met, will expand section you are looking for

  ParseTableChildrenToMR(mr, tmr)
  mr.Collapsed = mrCollapse
  -- now check if minstack &amp; repairs need to be done (only on player items)
  if tmr._IsPlayerItem == true and tmr._IsStackable and SetMinCnt == true then
    SetMinStackCnt(tmr.Address,MinStackCnt)
  end
  if tmr._IsPlayerItem == true and RepairItems == true then
    RepairTgtItem(tmr.Address)
  end
end

-- Update each inv with count &amp; collapse
mrPlayerInv.description = mrPlayerInv.description..' (Item count: '..mrPlayerInv.count..')'
mrPlayerInv.Collapsed = true
mrAreaInv.description = mrAreaInv.description..' (Item count: '..mrAreaInv.count..'; Unfiltered count: '..iCntAreaNF..')'
mrAreaInv.Collapsed = true

-- Collapse the parameter filter when this is active. Open again when disabled (Collapse seems not to work when this is the active one...)
AddressList.getMemoryRecordByID(memrec.Id).Collapsed = true


{$asm}

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

local mr_inv = AddressList.getMemoryRecordByDescription('InventoryBasePtr')
for i=mr_inv.Count-1,0,-1 do
  mr_inv.Child[i].delete()
end

-- Collapse the parameter filter when this is active. Open again when disabled
AddressList.getMemoryRecordByID(memrec.Id).Collapsed = false
{$asm}

</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>117989</ID>
              <Description>"Filter: Show area items?"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_IncludeArea</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117988</ID>
              <Description>"Filter: Max Inventory Count (Player / Area)"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>4 Bytes</VariableType>
              <Address>inv_MaxLimit</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>118815</ID>
              <Description>"Filter: Exclude items already inspected/viewed by player (Area only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_IgnoreTouched</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>118817</ID>
              <Description>"Filter: Apply Item group filter (Area only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_ApplyGroupFilter</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117990</ID>
              <Description>"Update: Repair/max health items &amp; clear wet/frozen status for clothing? (Player only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>FF8080</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_Repairitems</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117991</ID>
              <Description>"Update: Set minimum count (Stackable only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>FF8080</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_SetMinCnt</Address>
              <CheatEntries>
                <CheatEntry>
                  <ID>117992</ID>
                  <Description>"Minimum Stackable Count - don't get greedy :P (Only if "Update: Set minimum count" is TRUE)"</Description>
                  <ShowAsSigned>0</ShowAsSigned>
                  <VariableType>4 Bytes</VariableType>
                  <Address>inv_MinStackableCnt</Address>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>116561</ID>
          <Description>"InventoryBasePtr"</Description>
          <ShowAsHex>1</ShowAsHex>
          <ShowAsSigned>0</ShowAsSigned>
          <GroupHeader>1</GroupHeader>
          <Address>[[[GameAssembly.dll+421E880]+b8]]+10</Address>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>
Last edited by ParadoxDad on Fri Apr 11, 2025 7:22 pm, edited 1 time in total.

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

Wow.. Sorry for the long post. I had insomnia working on a work related project so was awake for ~36 hours then my son asked me about this game so I started on this after I completed the work as a distraction. ~ 6 hours later I popped this on the site.

After some sleep I reviewed this again. I definitely should not do this when I am so buggy...
Context: I am 62 years old so not some big time dev like many here :)

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

Extra settings added:
* KeroseneLampItem - Always full
* Expanded feature for No Item Degrade to also remove wet/frozen status from clothing
* Movement speed multiplier
* Removed random sprains

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>117986</ID>
      <Description>"No sprains"</Description>
      <LastState Activated="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>// learned that 68 : m_SecondsSprainRisk under Sprains class if set to 0 should avoid risk of sprains
// I just skipped the process altogether by just returning to caller in Sprains.Update
// seems to work so far
[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(noSprains,Sprains.Update)
define(noSprains_Match,40 53 48 83 EC 40)

assert(noSprains,noSprains_Match)
alloc(newmem,$100,noSprains)
label(code return)

newmem:
  // 68 : m_SecondsSprainRisk
  mov [rbx+68],(float)0 // setting m_SecondsSprainRisk in case used elsewhere
  ret // skipping rest of Sprains.Update

code:
// never used but left for reference
db 40 53 48 83 EC 40
  jmp return

noSprains:
  jmp newmem
  nop
return:
registersymbol(noSprains)

[DISABLE]
noSprains:
db 40 53 48 83 EC 40

unregistersymbol(*)
dealloc(*)
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>117984</ID>
      <Description>"Player movement multiplier (hold shift key to slow speed to 1)"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <LastState Activated="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>// Based on original code from JLee3D (Glad he explained what process it was from)
// Noticed that xmm15 (not xmm13) appears to be calculated speed multiplier
// Instead of doing AOB later in this process, I opted to just set these 2 xmm and return instead of running rest of the class
// so far, it appears to work with no issues

[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(SnowMoveMultiplier,PlayerMovement.GetSnowDepthMovementMultiplier)
define(SnowMoveMultiplier_Match,40 53 48 83 EC 40)

assert(SnowMoveMultiplier,SnowMoveMultiplier_Match)
alloc(newmem,$100,SnowMoveMultiplier)
label(code SnowDepthMul return)
registersymbol(SnowDepthMul)

newmem:
  movss xmm0,[SnowDepthMul]
  movaps xmm15,xmm0
  ret // skipping rest of GetSnowDepthMovementMultiplier

code:
// never used but left for reference
db 40 53 48 83 EC 40
  jmp return

SnowDepthMul:
  dq (float)2.0

SnowMoveMultiplier:
  jmp newmem
  nop
return:
registersymbol(SnowMoveMultiplier)

[DISABLE]
SnowMoveMultiplier:
db 40 53 48 83 EC 40

unregistersymbol(*)
dealloc(*)

</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>117985</ID>
          <Description>"Speed Multiplier (Normal: 1)"</Description>
          <LastState Value="3" RealAddress="7FFBB6630018"/>
          <VariableType>Float</VariableType>
          <Address>SnowDepthMul</Address>
          <Hotkeys>
            <Hotkey OnlyWhileDown="1">
              <Action>Set Value</Action>
              <Keys>
                <Key>16</Key>
              </Keys>
              <Value>1</Value>
              <ID>0</ID>
            </Hotkey>
          </Hotkeys>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>118812</ID>
      <Description>"KeroseneLampItem - Always full"</Description>
      <LastState Activated="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>// 18:m_MaxFuel (int64)
// d0:m_TimeToBreak (type: System.Single)
// 68:m_CurrentFuelLiters (int64)
// 70:m_IntensityComponent (type: KeroseneLampIntensity)
  // 38:m_IndoorIntensity (float)
  // 3c:m_OutdoorInensity (float)

[ENABLE]
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

define(maxLanternFuel,TLD.Gear.KeroseneLampItem.Update)
define(maxLanternFuel_Match,40 57 48 83 EC)

assert(maxLanternFuel,maxLanternFuel_Match)
alloc(newmem,$100,maxLanternFuel)
label(code maxLanternFuel_Origbytes return)
registersymbol(maxLanternFuel_Origbytes)

newmem:
  push rbx
  mov rbx,[rcx+18]
  mov [rcx+68],rbx
  pop rbx

code:
maxLanternFuel_Origbytes:
  readMem(maxLanternFuel, 6)
  jmp return

maxLanternFuel:
  jmp newmem
  nop
return:
registersymbol(maxLanternFuel)

[DISABLE]
maxLanternFuel:
  readMem(maxLanternFuel_Origbytes, 6)

unregistersymbol(*)
dealloc(*)

</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>8555</ID>
      <Description>"No Item Degrade / Max gear HP / No wet/frozen"</Description>
      <Options moDeactivateChildrenAsWell="1"/>
      <LastState Activated="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
// This code requires mono
// I incorporated the mono init code within scripts that depend on it so that others could copy the individual cheats for their use.
{$lua}
if monopipe == nil then
  mono_initialize();
  LaunchMonoDataCollector();
end
{$asm}

aobscanregion(noItemDegradeMaxed,GearItem.Degrade,GearItem.Degrade+100,F3 0F 5C DE 0F 2E D3)
alloc(newmem,$100,noItemDegradeMaxed)

label(code noDegrade return)

newmem:
  push rax
  // Added no frozen/wet for clothing as well
  // A8 for clothing (98 for pctWet, 9C for pctFrozen) both are float
  mov rax,[rbx+A8]
  cmp rax,0
  jz noDegrade // means not clothing
  mov [rax+98],(float)0
  mov [rax+9C],(float)0
  // 340:m_GearItemData (TLD.Gear.GearItemData)(lookup of fields for GearItem via Mono dissector)
  // 50:m_MaxHP (lookup of fields for GearItemData via Mono dissector)
noDegrade:
  mov rax,[rbx+340]
  movss xmm3,[rax+50]
  pop rax
  // 371:m_WornOut (bool)(lookup of fields for GearItem via Mono dissector)
  mov byte ptr [rbx+371],0

code:
  // subss xmm3,xmm6 // remarked out to skip degrade process
  ucomiss xmm2,xmm3
  jmp return

noItemDegradeMaxed:
  jmp newmem
  nop 2
return:
registersymbol(noItemDegradeMaxed)

[DISABLE]
noItemDegradeMaxed:
db F3 0F 5C DE 0F 2E D3

unregistersymbol(*)
dealloc(*)

{ // under GearItem.Degrade
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+7DBDCD

GameAssembly.dll+7DBD96 - 80 3D D16CC003 00     - cmp byte ptr [GameAssembly.dll+43E2A6E],00
GameAssembly.dll+7DBD9D - 48 8B D9              - mov rbx,rcx
GameAssembly.dll+7DBDA0 - 0F29 74 24 40         - movaps [rsp+40],xmm6
GameAssembly.dll+7DBDA5 - 0F28 F1               - movaps xmm6,xmm1
GameAssembly.dll+7DBDA8 - 75 13                 - jne GameAssembly.dll+7DBDBD
GameAssembly.dll+7DBDAA - 48 8D 0D 9FC4A303     - lea rcx,[GameAssembly.dll+4218250]
GameAssembly.dll+7DBDB1 - E8 5AA4B7FF           - call GameAssembly.dll+356210
GameAssembly.dll+7DBDB6 - C6 05 B16CC003 01     - mov byte ptr [GameAssembly.dll+43E2A6E],01
GameAssembly.dll+7DBDBD - F3 0F10 9B 38030000   - movss xmm3,[rbx+00000338]
GameAssembly.dll+7DBDC5 - F3 0F10 93 38030000   - movss xmm2,[rbx+00000338]
// ---------- INJECTING HERE ----------
GameAssembly.dll+7DBDCD - F3 0F5C DE            - subss xmm3,xmm6
GameAssembly.dll+7DBDD1 - 0F2E D3               - ucomiss xmm2,xmm3
// ---------- DONE INJECTING  ----------
GameAssembly.dll+7DBDD4 - 7A 02                 - jp GameAssembly.dll+7DBDD8
GameAssembly.dll+7DBDD6 - 74 28                 - je GameAssembly.dll+7DBE00
GameAssembly.dll+7DBDD8 - 4C 8B 83 30030000     - mov r8,[rbx+00000330]
GameAssembly.dll+7DBDDF - F3 0F11 9B 38030000   - movss [rbx+00000338],xmm3
GameAssembly.dll+7DBDE7 - 4D 85 C0              - test r8,r8
GameAssembly.dll+7DBDEA - 74 14                 - je GameAssembly.dll+7DBE00
GameAssembly.dll+7DBDEC - 49 8B 40 28           - mov rax,[r8+28]
GameAssembly.dll+7DBDF0 - 48 8B D3              - mov rdx,rbx
GameAssembly.dll+7DBDF3 - 49 8B 48 40           - mov rcx,[r8+40]
GameAssembly.dll+7DBDF7 - 48 89 44 24 20        - mov [rsp+20],rax
}
</AssemblerScript>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

Added Gun details to inventory listing and additional filtering rules. It may not interest you but added it here just in case.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>116563</ID>
      <Description>"Inventory"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <Color>00FF00</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

-- key/values in iFields are just ones I thought to bring in that were object types. Did not dig in to find out more about each &lt;shrug&gt;
-- I will leave it to others if you want to expand this more. I just did this for my own amusement.
-- Added sublayer to keep order intact since first match is generally the main object type
-- Note: The order is not the Field ID but weight I put on the object type

InvGV_iFields = {
  {0x60, 'BlueprintItemUnlock'},
  {0x1B0, 'NarrativeCollectibleItem'},
  {0x298, 'RecipeItem'},
  {0x1E0, 'ResearchItem'},
  {0x190, 'Knowledge'},
  {0x160, 'GunItem'},
  {0x38, 'AmmoItem'},
  {0x40, 'AmmoCasingItem'},
  {0x50, 'BearSpearItem'},
  {0x58, 'Bed'},
  {0x78, 'BowItem'},
  {0x48, 'ArrowItem'},
  {0x98, 'CharcoalItem'},
  {0xA8, 'ClothingItem'},
  {0x100, 'FirstAidItem'},
  {0xD8, 'EmergencyStim'},
  {0xF8, 'FireStarterItem'},
  {0x118, 'FlareItem'},
  {0x110, 'FlareGunRoundItem'},
  {0x120, 'FlashLightItem'},
  {0x188, 'KeroseneLampItem'},
  {0x248, 'TorchItem'},
  {0x1A0, 'MatchesItem'},
  {0x150, 'FuelSourceItem'},
  {0x128, 'FoodItem'},
  {0x140, 'ForceLockItem'},
  {0x158, 'HandheldShortwaveItem'},
  {0x1E8, 'Respirator'},
  {0x1F0, 'RespiratorCanister'},
  {0x1F8, 'RopeItem'},
  {0x240, 'ToolsItem'},
  {0x218, 'SnareItem'},
  {0x88, 'CanOpeningItem'},
  {0x250, 'Travois'},
  {0x260, 'WildlifeItem'},
  {0x2A0, 'InsulatedFlask'},
  {0x2A8, 'HeatPadItem'},
  {0x1D0, 'PurifyWater'},
  {0x258, 'WaterSupply'},
  {0x198, 'LiquidItem'},
  {0x1B8, 'NoiseMakerItem'},
  {0x1C0, 'ShowOnMapItem'},
  {0x90, 'CarryCapacityBuff'},
  {0xB0, 'ConditionOverTimeBuff'},
  {0xB8, 'ConditionRestBuff'},
  {0xF0, 'FatigueBuff'},
  {0x148, 'FreezingBuff'},
  {0x268, 'WolfIntimidationBuff'},
  {0x270, 'ClimbingBuff'},
  {0x278, 'ProtectionBuff'},
  {0x280, 'WeightReductionBuff'},
  {0x238, 'StruggleBonus'},
  {0xE0, 'EnergyBoost'},
  {0xD0, 'DegradeOnUse'},
  {0x1C8, 'PowderItem'},
  {0x170, 'IceFishingHoleClearItem'},
  {0x178, 'InProgressCraftItem'},
  {0x288, 'LureItem'},
  {0x290, 'BaitItem'},
  {0x230, 'StoneItem'},
  {0xC8, 'CookingPotItem'},
  {0x220, 'SprayPaintCan'},
  {0x168, 'Harvest'},
  {0x138, 'ForageItem'},
  {0x80, 'BreakDownItem'},
  {0x68, 'BodyHarvestItem'},
  {0x70, 'BodyHarvest'},
  {0x200, 'Scent'},
  {0x1D8, 'Repairable'},
  {0x208, 'Sharpenable'},
  {0x210, 'SmashableItem'},
  {0x228, 'StackableItem'},
  {0xA0, 'Cleanable'},
  {0xC0, 'Cookable'},
  {0x1A8, 'Millable'},
  {0x108, 'FirstPersonItem'},
  {0x180, 'Inspect'},
}

InvGV_iGroups = {
  [0] = {['Unlock / Knowledge / Collectible'] = {0x60, 0x190, 0x1B0, 0x1E0, 0x298}},
  [1] = {['Buffs'] = {0x90, 0xB0, 0xB8, 0xF0, 0x148, 0x268, 0x270, 0x278, 0x280}},
  [2] = {['Clothing &amp; Equippable gear'] = {0xA8, 0x1E8, 0x1F0}},
  [3] = {['Weapon / Ammo (excluding rocks)'] = {0x50, 0x78, 0x160, 0x38, 0x40, 0x48}},
  [4] = {['Tools / Utility / Hunting / Fishing'] = {0x1F8, 0x218, 0x240, 0x288, 0x290}},
  [5] = {['Fire / Light related'] = {0xF8, 0x110, 0x118, 0x120, 0x150, 0x188, 0x1A0, 0x248}},
  [6] = {['Food, Cooking and Recovery/Health related items'] = {0xC0, 0xC8, 0x128, 0x198, 0xD8, 0xE0, 0x100}},
  [7] = {['Other (catch-all)'] = {}}
}

local fgHeader = 'Filter: Apply Item group filter (Area only)'
invGV_fGroups = {}
-- Populate IGroups entries under InvGV_GHeader
local tmrGHeader = AddressList.getMemoryRecordByDescription(fgHeader)
if tmrGHeader == nil then
  error(' Unable to find record with description "'..fgHeader..'"')
end
for i=tmrGHeader.Count-1,0,-1 do
  tmrGHeader.Child[i].delete()
end
local k1,v1,k2,v2
for k1,v1 in pairs(InvGV_iGroups) do
  for k2,v2 in pairs(v1) do
    local GrItem = AddressList.createMemoryRecord()
    GrItem.description = k2
    GrItem.IsGroupHeader = true
    GrItem.Color = 0x00A400
    GrItem.Active = k1 &lt; 5 -- my defaults, ignoring fire/food/other if filtered (normally not)
    GrItem.appendToEntry(tmrGHeader)
    invGV_fGroups[k1] = GrItem.ID
  end
end

-- when you disable this, The collapsable folder with parameters is collapsed by default. Open it back up
AddressList.getMemoryRecordByID(memrec.Id)[0].Collapsed = false
{$asm}

alloc(newmem,$100)
label(inv_IncludeArea inv_MaxLimit inv_Repairitems inv_SetMinCnt inv_MinStackableCnt inv_IgnoreTouched inv_ApplyGroupFilter inv_ApplyGFilter_Player)
registersymbol(inv_IncludeArea inv_MaxLimit inv_Repairitems inv_SetMinCnt inv_MinStackableCnt inv_IgnoreTouched inv_ApplyGroupFilter inv_ApplyGFilter_Player)

newmem:
inv_IncludeArea:      // 1 byte - 0/1
db 1

inv_MaxLimit:         // 4 byte - integer
dd #200

inv_Repairitems:      // 1 byte - 0/1
db 0

inv_SetMinCnt:        // 1 byte - 0/1
db 0

inv_MinStackableCnt:  // 4 byte - integer
dd 4

inv_IgnoreTouched:    // 1 byte - 0/1
db 1

inv_ApplyGroupFilter: // 1 byte - 0/1
db 0

inv_ApplyGFilter_Player: // 1 byte - 0/1
db 0

[DISABLE]
{$lua}
-- clear global variables set here
InvGV_iFields = nil
InvGV_iGroups = nil
invGV_fGroups = nil
{$asm}

unregistersymbol(*)
dealloc(*)

</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>117987</ID>
          <Description>"Get/Update Inventory List based on Parameters set below"</Description>
          <Options moManualExpandCollapse="1" moDeactivateChildrenAsWell="1"/>
          <Color>00FF00</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

local mr_inv = AddressList.getMemoryRecordByDescription('InventoryBasePtr')
for i=mr_inv.Count-1,0,-1 do
  mr_inv.Child[i].delete()
end

local function SetFlagStrings(ObjectAddr)
  local ItemFlags = {
    {0xd0, 'Degrade on use'},
    {0x31, 'Hidden'},
    {0x30, 'Locked'},
    {0x23, 'In Satchel/Container'},
    {0x28, 'In Satchel/Container'},
    {0x1c, 'Touched by player'},
    {0x1d, 'Touched by player'},
    {0x1f, 'Touched by player'},
    {0x21, 'Touched by player'}
  }
  local flagValues = {}
  local k,v
  for k,v in pairs(ItemFlags) do
    if readBytes(ObjectAddr+v[1], 1, false) == 1 then
      flagValues[v[2]] = v[2]
    end
  end
  --return table.concat(flagValues, ', ')
  -- I tried other ways but seems table.concat is not working here so built string this way
  local Result = ''
  for k,v in pairs(flagValues) do
    Result = Result..v..', '
  end
  return string.sub(Result,1,-3)
end

local function TrimFirstUnderScore(tStrVal)
  local Result = 'No name found' -- in case tStrVal is nil
  if tStrVal ~= nil then
    -- used or to replace nil value with 0. This way if no match, will show entire string instead of error
    Result = string.sub(tStrVal, (string.find(tStrVal,'_') or 0)+1)
  end
  return Result
end

--table.sort not working as intended so using old fashioned quicksort
local function qsTopMemoryRecords(mrGroup, istart, iend)
  local Result, ipivot
  istart = istart or 1
  iend = iend or #mrGroup
  if iend - istart &lt; 1 then
    Result = mrGroup
  else
    ipivot = istart
    for i = istart + 1, iend do
      if mrGroup[i].description &lt;= mrGroup[ipivot].description then
        if i == ipivot + 1 then
          mrGroup[ipivot],mrGroup[ipivot+1] = mrGroup[ipivot+1],mrGroup[ipivot]
        else
          mrGroup[ipivot],mrGroup[ipivot+1],mrGroup[i] = mrGroup[i],mrGroup[ipivot],mrGroup[ipivot+1]
        end
        ipivot = ipivot + 1
      end
    end
    mrGroup = qsTopMemoryRecords(mrGroup, istart, ipivot - 1)
    Result = qsTopMemoryRecords(mrGroup, ipivot + 1, iend)
  end
  return Result
end

local function ParseTableChildrenToMR(mrParent, srcTable)
  local tmr,k,v
  if srcTable.Children ~= nil then
    for _,tmr in pairs(srcTable.Children) do
      -- check if description matches evolve

      local mr = AddressList.createMemoryRecord()
      for k,v in pairs(tmr) do
        if string.sub(k,1,1) ~= '_' and k ~= 'Children' and k ~= 'Offset' then
          -- _*, Children &amp; Offset are handled separately. Could not just do type in this case
          mr[k] = v
        end
      end
      mr.appendToEntry(mrParent)
      -- now add offset if it exists
      if tmr.OffsetCount ~= nil then
        mr.OffsetCount = tmr.OffsetCount
        for k,v in pairs(tmr.Offset) do
          mr.Offset[k] = v
        end
      end
      -- add children
      ParseTableChildrenToMR(mr, tmr)
      -- try to close if have children
      if mr.count &gt; 0 then
        mr.Collapsed = true
      end
    end
  end
end

local function RepairTgtItem(iBaseAStr)
  local iMaxHP = readFloat('[['..iBaseAStr..']+340]+50')
  local iCurHPPtr = '['..iBaseAStr..']+338'
  local ClothingWetPtr = '[['..iBaseAStr..']+A8]+98'
  local ClothingFrozenPtr = '[['..iBaseAStr..']+A8]+9C'
  if iMaxHP ~= nil and iMaxHP ~= 0 and readFloat(iCurHPPtr) &gt; 0 then
    writeFloat(iCurHPPtr, iMaxHP)
  end
  if readFloat(ClothingWetPtr) ~= nil and readFloat(ClothingFrozenPtr) ~= nil then
    writeFloat(ClothingWetPtr, 0)
    writeFloat(ClothingFrozenPtr, 0)
  end
end

local function SetMinStackCnt(iBaseAStr, MinStackCnt)
  local StackCntPtr = '[['..iBaseAStr..']+228]+18'
  local StackCnt = readInteger(StackCntPtr)
  if StackCnt ~= nil and StackCnt &gt; 0 and StackCnt &lt; MinStackCnt then
    writeInteger(StackCntPtr, MinStackCnt)
  end
end

local function GetMainGrpId(iBaseAStr)
  local Result = nil

  local k1,v1,k2,v2,k3,v3
  for k1,v1 in pairs(InvGV_iGroups) do
    for k2,v2 in pairs(v1) do
      for k3,v3 in pairs(v2) do
        if readQword('['..iBaseAStr..']+'..string.format('%x',v3)) ~= 0 then
          Result = k1
          break
        end
      end
      if Result ~= nil then
        break
      end
    end
    if Result ~= nil then
      break
    end
  end
  if Result == nil then
    Result = #InvGV_iGroups -- the last row in #InvGV_iGroups shoule have empty table (catch-all)
  end

  return Result
end

local function IsSkipItem(iBaseAStr)
  local iPlayerTouched = {0x1c,0x1d,0x1f,0x21}
  local Result = false
  local k,v
  for k,v in pairs(iPlayerTouched) do
    if readBytes('['..iBaseAStr..']+'..string.format('%x',v),1,false) == 1 then
      Result = true
      break
    end
  end

  return Result
end

local function GetSubItemInfo(mrTemplate, grpColor)
  local Result = {}
  local k,v

  if mrTemplate.description ~= nil then
    Result.description = mrTemplate.description
    if mrTemplate.IsAddressGroupHeader ~= nil then
      Result.IsAddressGroupHeader = mrTemplate.IsAddressGroupHeader == true
    end
    if mrTemplate.address ~= nil then
      Result.Address = mrTemplate.address
    end
    if mrTemplate.valueType ~= nil then
      Result.Type = mrTemplate.valueType
    end
    if mrTemplate.offsetTable ~= nil and #mrTemplate.offsetTable &gt; 0 then
      Result.OffsetCount = #mrTemplate.offsetTable
      Result.Offset = {}
      for k,v in pairs(mrTemplate.offsetTable) do
        Result.Offset[k - 1] = v
      end
    end
    if mrTemplate.Children ~= nil and type(mrTemplate.Children) == 'table' then
      Result.Children = {}
      for k,v in pairs(mrTemplate.Children) do
        local tmrL1 = GetSubItemInfo(v, grpColor)
        if tmrL1.description ~= nil and string.len(tmrL1.description) &gt; 0 then
          table.insert(Result.Children, tmrL1)
        end
      end
      if #Result.Children &gt; 0 then
        Result.Color = grpColor
        Result.options = 'moManualExpandCollapse'
      end
    end
  end

  return Result
end

--[[
mrTableFormat: description, IsAddressGroupHeader, address, valueType, offsetTable,children
  description is text
  IsAddressGroupHeader is bool. If false, then isGroupHeader. If missing, then not set
  address if empty or missing, then not set
  valueType if empty or missing, then not set
  offsetTable is table of offsets in reverse order of entry (offsetcount will be calculated from this). if empty or missing, not set
  children is array of mrTableFormat. If none, then value (key is unused here) should be {}

Note:
* color and options are based on Top level design in code
* Any item entry with children will have moManualExpandCollapse option set and set to collapse initially in code, not in template below

table iSubInfo should be in format of [addr offsetcheck] = {mrTableFormat}
]]
local iSubInfo = {
  [0xA8] = {
    ['description'] = 'Clothing Stats',
    ['IsAddressGroupHeader'] = true,
    ['address'] = '+0',
    ['valueType'] = vtQword,
    ['offsetTable'] = {0xA8},
    ['Children'] = {
      {
        ['description'] = 'Warmth %',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x30}
      },
      {
        ['description'] = 'Windproof %',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x38}
      },
      {
        ['description'] = 'Toughness',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x3C}
      },
      {
        ['description'] = 'Waterproofness %',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x44}
      },
      {
        ['description'] = 'Wet %',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x98}
      },
      {
        ['description'] = 'Frozen %',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x9C}
      }
    }
  },
  [0xE8] = {
    ['description'] = 'Evolve Stats',
    ['IsAddressGroupHeader'] = true,
    ['address'] = '+0',
    ['valueType'] = vtQword,
    ['offsetTable'] = {0xE8},
    ['Children'] = {
      {
        ['description'] = 'Gear Item to become',
        ['IsAddressGroupHeader'] = true,
        ['address'] = '+0',
        ['valueType'] = vtString,
        ['offsetTable'] = {0x26,0x10,0x68,0x340,0x20}
      },
      {
        ['description'] = 'Start Evolve %',
        ['address'] = '+0',
        ['valueType'] = vtDword,
        ['offsetTable'] = {0x28}
      },
      {
        ['description'] = 'Time To Evolve Game Days',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x2C}
      },
      {
        ['description'] = 'Time spent evolving (Game Hours)',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x34}
      }
    }
  },
  [0x160] = {
    ['description'] = 'Gun/Rifle Stats',
    ['IsAddressGroupHeader'] = true,
    ['address'] = '+0',
    ['valueType'] = vtQword,
    ['offsetTable'] = {0x160},
    ['Children'] = {
      {
        ['description'] = 'Is Jammed',
        ['address'] = '+0',
        ['valueType'] = vtByte,
        ['offsetTable'] = {0xE8}
      },
      {
        ['description'] = 'Rounds in clip',
        ['address'] = '+0',
        ['valueType'] = vtDword,
        ['offsetTable'] = {0x34}
      },
      {
        ['description'] = 'Clip size',
        ['address'] = '+0',
        ['valueType'] = vtDword,
        ['offsetTable'] = {0x38}
      },
      {
        ['description'] = 'Rounds to reload/clip',
        ['address'] = '+0',
        ['valueType'] = vtDword,
        ['offsetTable'] = {0x3C}
      },
      {
        ['description'] = 'Damage HP',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x40}
      },
      {
        ['description'] = 'Firing rate/sec',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x44}
      },
      {
        ['description'] = 'Reload cooldown (sec)',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x48}
      },
      {
        ['description'] = 'Accuracy Range',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x54}
      },
      {
        ['description'] = 'Detailed Aim/fire Info',
        ['IsAddressGroupHeader'] = false,
        ['Children'] = {
          {
            ['description'] = 'Aim assist min distance',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x58}
          },
          {
            ['description'] = 'Aiming Multiplier',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0xEC}
          },
          {
            ['description'] = 'Fire Multiplier',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0xF0}
          },
          {
            ['description'] = 'Reload Multiplier',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0xF4}
          },
          {
            ['description'] = 'Sway (no fatigue)',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0xF8}
          },
          {
            ['description'] = 'Sway (max fatigue)',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0xFC}
          },
          {
            ['description'] = 'Sway increase/sec',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x100}
          },
          {
            ['description'] = 'Sway decrease/sec',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x104}
          },
          {
            ['description'] = 'Sway enerby boost bonus',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x108}
          },
          {
            ['description'] = 'Sway enerby stim bonus',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x10C}
          },
          {
            ['description'] = 'Aiming Sway drop threshold %',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x114}
          },
          {
            ['description'] = 'Recoil - Pitch Min',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x118}
          },
          {
            ['description'] = 'Recoil - Pitch Max',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x11C}
          },
          {
            ['description'] = 'Recoil - Yaw Min',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x120}
          },
          {
            ['description'] = 'Recoil - Yaw Max',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x124}
          },
          {
            ['description'] = 'Sway',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x128}
          },
          {
            ['description'] = 'Sway Recovery Timer',
            ['address'] = '+0',
            ['valueType'] = vtSingle,
            ['offsetTable'] = {0x12C}
          }
        }
      }
    }
  },
  [0x188] = {
    ['description'] = 'Kerosene Lamp Stats',
    ['IsAddressGroupHeader'] = true,
    ['address'] = '+0',
    ['valueType'] = vtQword,
    ['offsetTable'] = {0x188},
    ['Children'] = {
      {
        ['description'] = 'Max Fuel',
        ['address'] = '+0',
        ['valueType'] = vtQword,
        ['offsetTable'] = {0x18}
      },
      {
        ['description'] = 'Current Fuel',
        ['address'] = '+0',
        ['valueType'] = vtQword,
        ['offsetTable'] = {0x68}
      },
      {
        ['description'] = 'Current Light Intensity',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x44}
      },
      {
        ['description'] = 'Dynamic Intensity (0/1)',
        ['address'] = '+0',
        ['valueType'] = vtByte,
        ['offsetTable'] = {0x1C}
      },
      {
        ['description'] = 'Indoor Intensity',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x38}
      },
      {
        ['description'] = 'Outdoor Intensity',
        ['address'] = '+0',
        ['valueType'] = vtSingle,
        ['offsetTable'] = {0x3C}
      }
    }
  }
}


-- will have these be values in CE table later
local clrBaseItem = 0xFFFF00
local clrSubPropGrp = 0x808000
local clrItemTypes = 0x008000
local clrROField = 0xC0C0C0
local clrTouched = 0x008080
local clrLockedHidden = 0x4080FF
local clrCollKnowGrp = 0x00FFFF

local maxItemsList = readInteger("inv_MaxLimit") or 100
local ShowAreaItems = readBytes("inv_IncludeArea",1,false) &gt; 0
local RepairItems = readBytes("inv_Repairitems",1,false) &gt; 0
local SetMinCnt = readBytes("inv_SetMinCnt",1,false) &gt; 0
local MinStackCnt = readInteger("inv_MinStackableCnt") or 4
local SkipPlayerTouched = readBytes("inv_IgnoreTouched",1,false) &gt; 0
local ApplyGFilter = readBytes("inv_ApplyGroupFilter",1,false) &gt; 0
local ApplyGFilter_Player = readBytes("inv_ApplyGFilter_Player",1,false) &gt; 0
local IsPlayerItem = false
local iMainGrpId

local iSeq = 0
local continueLoop = true
local showItemID = false
local ceTable = {}
local iCntPlayer = 0
local iCntPlayerNF = 0
local iCntArea = 0
local iCntAreaNF = 0
local SkipItem = false

while continueLoop == true do
  local iBaseAStr = '[[[[GameAssembly.dll+421E880]+b8]]+10]+20+8*'..string.format('%x',iSeq)
  local iBaseAddr = readQword(iBaseAStr)

  if iBaseAddr ~= 0 then
    -- identify if player or area item (0x20 = m_InPlayerInventory)
    IsPlayerItem = readBytes(iBaseAddr+0x20, 1, false) == 1
    -- set iMainGrpId (used for filtering)
    iMainGrpId = GetMainGrpId(iBaseAStr)
    if IsPlayerItem == true then
      iCntPlayerNF = iCntPlayerNF + 1
      SkipItem = iCntPlayer &gt;= maxItemsList
      SkipItem = SkipItem or ApplyGFilter_Player and AddressList.getMemoryRecordByID(invGV_fGroups[iMainGrpId]).active ~= true
      if SkipItem == false then
        iCntPlayer = iCntPlayer + 1
      end
    else
      iCntAreaNF = iCntAreaNF + 1
      SkipItem = iCntArea &gt;= maxItemsList or not ShowAreaItems
      SkipItem = SkipItem or SkipPlayerTouched and IsSkipItem(iBaseAStr)
      SkipItem = SkipItem or ApplyGFilter and AddressList.getMemoryRecordByID(invGV_fGroups[iMainGrpId]).active ~= true
      -- only update iCntArea if not filtered out
      if SkipItem == false then
        iCntArea = iCntArea + 1
      end
    end
    -- skip this item if exceeds max (still add to count but not list items)
    if not SkipItem then
      tmr = {}
      local iName = TrimFirstUnderScore(readString('[[[['..iBaseAStr..']+340]+68]+10]+14', 128, true))

      if showItemID then
        tmr.description = iSeq..': '..iName
      else
        tmr.description = iName
      end
      tmr.Type = vtQword
      tmr.Address = iBaseAStr
      tmr.Color = clrBaseItem
      tmr.IsAddressGroupHeader = true
      tmr.options = 'moManualExpandCollapse'
      tmr._IsPlayerItem = IsPlayerItem
      tmr._IsStackable = readQword('['..iBaseAStr..']+228') ~= 0
      tmr._IsClothing = readQword('['..iBaseAStr..']+A8') ~= 0
      tmr.Children = {}

      -- now identify flags and append to description (Only if not in player inventory)
      if not IsPlayerItem then
        local FlagStr = SetFlagStrings(iBaseAddr)
        if string.len(FlagStr) &gt; 0 then
          tmr.description = tmr.description..' ('..FlagStr..')'
          -- change color if touched by player (means you probably dropped it for a reason, its not a new item)
          if string.find(string.lower(FlagStr),'player') ~= nil then
            tmr.Color = clrTouched
          elseif string.find(string.lower(FlagStr),'hidden') ~= nil or string.find(string.lower(FlagStr),'locked') ~= nil then
            tmr.Color = clrLockedHidden
          end
        end
      end

      if tmr._IsStackable == true then
        local tmrL1 = {}
        tmrL1.description = 'Stack Count'
        tmrL1.Type = vtDword
        tmrL1.Address = '+0'
        tmrL1.OffsetCount = 2
        tmrL1.Offset = {}
        tmrL1.Offset[1] = 0x228
        tmrL1.Offset[0] = 0x18
        table.insert(tmr.Children, tmrL1)
      end

      local tmrL1 = {}
      tmrL1.description = 'Quality (HP)'
      tmrL1.Type = vtSingle
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 1
      tmrL1.Offset = {}
      tmrL1.Offset[0] = 0x338
      table.insert(tmr.Children, tmrL1)

      local tmrL1 = {}
      tmrL1.description = 'Max Quality (HP)'
      tmrL1.Type = vtSingle
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 2
      tmrL1.Offset = {}
      tmrL1.Offset[1] = 0x340
      tmrL1.Offset[0] = 0x50
      tmrL1.Color = clrROField
      table.insert(tmr.Children, tmrL1)

      local tmrL1 = {}
      tmrL1.description = 'Is Worn out'
      tmrL1.Type = vtByte
      tmrL1.Address = '+0'
      tmrL1.OffsetCount = 1
      tmrL1.Offset = {}
      tmrL1.Offset[0] = 0x371
      table.insert(tmr.Children, tmrL1)

      -- Now add subItemDetails that were defined in iSubInfo
      local k,v
      for k,v in pairs(iSubInfo) do
        if readQword('['..iBaseAStr..']+'..string.format('%x',k)) ~= 0 then
          local tmrL1 = GetSubItemInfo(v, clrSubPropGrp)
          if tmrL1.description ~= nil and string.len(tmrL1.description) &gt; 0 then
            table.insert(tmr.Children, tmrL1)
          end
        end
      end

      -- create header containing all objectFields that contain a pointer to use for filtering and expanding content in Inventory if you choose to do so
      local iObjList = {}
      local k,v
      for k,v in pairs(InvGV_iFields) do
        if readQword(iBaseAddr+v[1]) ~= 0 then
          table.insert(iObjList, v) --v[2] for specifics but going to use this for cross reference on iGroups table
        end
      end
      if #iObjList &gt; 0 then
        tmr.description = tmr.description..' ['..iObjList[1][2]..']'
        local tmrL1 = {}
        tmrL1.description = 'Valid Object Fields (Object count: '..#iObjList..')'
        tmrL1.Color = clrSubPropGrp
        tmrL1.IsGroupHeader = true
        tmrL1.options = 'moManualExpandCollapse'
        tmrL1.Children = {}

        for _,v in pairs(iObjList) do
          local tmrL2 = {}
          tmrL2.description = v[2]
          tmrL2.Color = clrItemTypes
          tmrL2.IsGroupHeader = true
          table.insert(tmrL1.Children, tmrL2)
        end
        table.insert(tmr.Children, tmrL1)
      end
      -- Although I did do the work to someday expand this to filter / group items based on identified categories, I am just going to highlight the Collectible/Research/Unlock one for now with identified color instead
      if iMainGrpId == 0 then -- 0 = 'Unlock / Knowledge / Collectible'
        tmr.Color = clrCollKnowGrp
      end

      table.insert(ceTable, tmr)
    end
    iSeq = iSeq + 1
    continueLoop = iCntPlayer &lt; maxItemsList or iCntArea &lt; maxItemsList
  else
    continueLoop = false
  end
end
-- if is collectible, research or ... then color is 00C4C4 (gold) or perhaps yellow
-- first group. Maybe add option to set flags or color based on user preference

-- now sort tables before adding as memory records
ceTable = qsTopMemoryRecords(ceTable)

-- create main headers (Player, Area)
local mrPlayerInv = AddressList.createMemoryRecord()
mrPlayerInv.description = 'Player Inventory'
mrPlayerInv.IsGroupHeader = true
mrPlayerInv.options = 'moManualExpandCollapse'
mrPlayerInv.appendToEntry(mr_inv)

local mrAreaInv = AddressList.createMemoryRecord()
mrAreaInv.description = 'Area Inventory'
mrAreaInv.IsGroupHeader = true
mrAreaInv.options = 'moManualExpandCollapse'
mrAreaInv.appendToEntry(mr_inv)

local mrTarget
local k,v
-- Now that the content has been sorted, I can start adding the memoryrecords
for _,tmr in pairs(ceTable) do
  if tmr._IsPlayerItem then
    mrTarget = mrPlayerInv
  else
    mrTarget = mrAreaInv
  end

  local mr = AddressList.createMemoryRecord()
  for k,v in pairs(tmr) do
    if string.sub(k,1,1) ~= '_' and k ~= 'Children' and k ~= 'Offset' then
      -- _*, Children &amp; Offset are handled separately. Could not just do type in this case
      mr[k] = v
    end
  end
  mr.appendToEntry(mrTarget)
  local mrCollapse = true
  -- Perhaps add logic later where if criteria met, will expand section you are looking for

  ParseTableChildrenToMR(mr, tmr)
  mr.Collapsed = mrCollapse
  -- now check if minstack &amp; repairs need to be done (only on player items)
  if tmr._IsPlayerItem == true and tmr._IsStackable and SetMinCnt == true then
    SetMinStackCnt(tmr.Address,MinStackCnt)
  end
  if tmr._IsPlayerItem == true and RepairItems == true then
    RepairTgtItem(tmr.Address)
  end
end

-- Update each inv with count &amp; collapse
mrPlayerInv.description = mrPlayerInv.description..' (Item count: '..mrPlayerInv.count..'; Unfiltered count: '..iCntPlayerNF..')'
mrPlayerInv.Collapsed = true
mrAreaInv.description = mrAreaInv.description..' (Item count: '..mrAreaInv.count..'; Unfiltered count: '..iCntAreaNF..')'
mrAreaInv.Collapsed = true

-- Collapse the parameter filter when this is active. Open again when disabled (Collapse seems not to work when this is the active one...)
AddressList.getMemoryRecordByID(memrec.Id).Collapsed = true


{$asm}

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

local mr_inv = AddressList.getMemoryRecordByDescription('InventoryBasePtr')
for i=mr_inv.Count-1,0,-1 do
  mr_inv.Child[i].delete()
end

-- Collapse the parameter filter when this is active. Open again when disabled
AddressList.getMemoryRecordByID(memrec.Id).Collapsed = false
{$asm}

</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>117989</ID>
              <Description>"Filter: Show area items?"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_IncludeArea</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117988</ID>
              <Description>"Filter: Max Inventory Count (Player / Area)"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>4 Bytes</VariableType>
              <Address>inv_MaxLimit</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>118815</ID>
              <Description>"Filter: Exclude items already inspected/viewed by player (Area only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_IgnoreTouched</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>118817</ID>
              <Description>"Filter: Apply Item group filter (Area only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_ApplyGroupFilter</Address>
              <CheatEntries>
                <CheatEntry>
                  <ID>120260</ID>
                  <Description>"Unlock / Knowledge / Collectible"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120261</ID>
                  <Description>"Buffs"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120262</ID>
                  <Description>"Clothing &amp; Equippable gear"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120263</ID>
                  <Description>"Weapon / Ammo (excluding rocks)"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120264</ID>
                  <Description>"Tools / Utility / Hunting / Fishing"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120265</ID>
                  <Description>"Fire / Light related"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120266</ID>
                  <Description>"Food, Cooking and Recovery/Health related items"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
                <CheatEntry>
                  <ID>120267</ID>
                  <Description>"Other (catch-all)"</Description>
                  <Color>00A400</Color>
                  <GroupHeader>1</GroupHeader>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
            <CheatEntry>
              <ID>120259</ID>
              <Description>"Filter: Apply item group filter to Player Inventory"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>008000</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_ApplyGFilter_Player</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117990</ID>
              <Description>"Update: Repair/max health items &amp; clear wet/frozen status for clothing? (Player only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>FF8080</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_Repairitems</Address>
            </CheatEntry>
            <CheatEntry>
              <ID>117991</ID>
              <Description>"Update: Set minimum count (Stackable only)"</Description>
              <DropDownList ReadOnly="1" DescriptionOnly="1" DisplayValueAsItem="1">0:False
1:True
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>FF8080</Color>
              <VariableType>Byte</VariableType>
              <Address>inv_SetMinCnt</Address>
              <CheatEntries>
                <CheatEntry>
                  <ID>117992</ID>
                  <Description>"Minimum Stackable Count - don't get greedy :P (Only if "Update: Set minimum count" is TRUE)"</Description>
                  <ShowAsSigned>0</ShowAsSigned>
                  <VariableType>4 Bytes</VariableType>
                  <Address>inv_MinStackableCnt</Address>
                </CheatEntry>
              </CheatEntries>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>116561</ID>
          <Description>"InventoryBasePtr"</Description>
          <ShowAsHex>1</ShowAsHex>
          <ShowAsSigned>0</ShowAsSigned>
          <GroupHeader>1</GroupHeader>
          <Address>[[[GameAssembly.dll+421E880]+b8]]+10</Address>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

Decided to bypass the inventory tinkering and just created script that would manage minimum count, repairs, autoevolve, etc
Was done playing game thus all the poking around :P

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>136549</ID>
      <Description>"Inventory Items Update (on timer) (max health, no wet/frozen status, auto evolve anywhere, min count 4)"</Description>
      <Color>FF80FF</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
alloc(MinStackableCnt,4)
registersymbol(MinStackableCnt)

MinStackableCnt:
db 4

{$lua}
if syntaxcheck then return end

local function RepairTgtItem(iBaseAStr)
  local iMaxHP = readFloat('[['..iBaseAStr..']+340]+50')
  local iCurHPPtr = '['..iBaseAStr..']+338'
  local iIsWornPtr = '['..iBaseAStr..']+371'
  local ClothingWetPtr = '[['..iBaseAStr..']+A8]+98'
  local ClothingFrozenPtr = '[['..iBaseAStr..']+A8]+9C'
  if iMaxHP ~= nil and iMaxHP ~= 0 and readFloat(iCurHPPtr) &gt; 0 then
    writeBytes(iIsWornPtr, 0)
    writeFloat(iCurHPPtr, iMaxHP)
  end
  if readFloat(ClothingWetPtr) ~= nil and readFloat(ClothingFrozenPtr) ~= nil then
    writeFloat(ClothingWetPtr, 0)
    writeFloat(ClothingFrozenPtr, 0)
  end
end

local function EvolveTgtItem(iBaseAStr)
  local iTTEPtr = '[['..iBaseAStr..']+E8]+2C'
  local iEvolveReqIndoorsPtr = '[['..iBaseAStr..']+E8]+30'
  writeBytes(iEvolveReqIndoorsPtr, 0) -- set so can occur anywhere
  writeFloat(iTTEPtr, 0.0000578703703703704) -- 5 seconds to evolve
end

local function SetMinStackCnt(iBaseAStr, MinStackCnt)
  local StackCntPtr = '[['..iBaseAStr..']+228]+18'
  local StackCnt = readInteger(StackCntPtr)
  if StackCnt ~= nil and StackCnt &gt; 0 and StackCnt &lt; MinStackCnt then
    writeInteger(StackCntPtr, MinStackCnt)
  end
end

local function getTimer()
  if memrec ~= nil then
    local id = memrec.id
    if timers[id] == nil then
      timers[id] = createTimer()
      timers[id].Enabled = false
      timers[id].Interval = getFreezeTimer().Interval
    end
    return timers[id]
  end
  return nil
end

-- setting timers as global array so that I dont somehow have overlapping timers if it did not close properly
if timers == nil then
  timers = {}
end

local invTmr = getTimer()
if invTmr ~= nil then
  invTmr.OnTimer = function(UpdatePInv)
    local MinStackCnt = readInteger("MinStackableCnt") or 4
    local iSeq = 0
    local continueLoop = true

    while continueLoop == true do
      local iBaseAStr = '[[[[GameAssembly.dll+421E880]+b8]]+10]+20+8*'..string.format('%x',iSeq)
      local iBaseAddr = readQword(iBaseAStr)

      if iBaseAddr ~= 0 then
        -- identify if player or area item (0x20 = m_InPlayerInventory)
        -- Only process if it is a player item
        if readBytes(iBaseAddr+0x20, 1, false) == 1 then
          -- apply minstack if stackable
          if readQword('['..iBaseAStr..']+228') ~= 0 then
            SetMinStackCnt(iBaseAStr,MinStackCnt)
          end
          -- repair items and set wet/frozen to 0 if clothing
          RepairTgtItem(iBaseAStr)
          -- update evolve items for any item with evolve entry (sets it to be anywhere and sets time to evolve to 5 seconds)
          if readQword('['..iBaseAStr..']+E8') ~= 0 then
            EvolveTgtItem(iBaseAStr)
          end
        end
        iSeq = iSeq + 1
      else
        continueLoop = false
      end
    end
  end
  invTmr.setInterval(10000) -- every 10 seconds (takes &lt; 1 second)
  invTmr.Enabled = true
end

{$asm}

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

if memrec ~= nil then
  local id = memrec.id
  if timers[id] ~= nil then
    timers[id].Enabled = false
    timers[id]:Destroy()
    timers[id] = nil
  end
end
{$asm}
unregistersymbol(*)
dealloc(*)
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>136550</ID>
          <Description>"Minimum Stackable Count - don't get greedy :P"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <VariableType>4 Bytes</VariableType>
          <Address>MinStackableCnt</Address>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

abbo1993
Novice Cheater
Novice Cheater
Posts: 22
Joined: Fri Jul 13, 2018 9:34 am
Reputation: 1

Re: The Long Dark (Steam/JLee3D)

Post by abbo1993 »

ParadoxDad wrote:
Tue Apr 22, 2025 10:15 pm
Decided to bypass the inventory tinkering and just created script that would manage minimum count, repairs, autoevolve, etc
Was done playing game thus all the poking around :P

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>136549</ID>
      <Description>"Inventory Items Update (on timer) (max health, no wet/frozen status, auto evolve anywhere, min count 4)"</Description>
      <Color>FF80FF</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
alloc(MinStackableCnt,4)
registersymbol(MinStackableCnt)

MinStackableCnt:
db 4

{$lua}
if syntaxcheck then return end

local function RepairTgtItem(iBaseAStr)
  local iMaxHP = readFloat('[['..iBaseAStr..']+340]+50')
  local iCurHPPtr = '['..iBaseAStr..']+338'
  local iIsWornPtr = '['..iBaseAStr..']+371'
  local ClothingWetPtr = '[['..iBaseAStr..']+A8]+98'
  local ClothingFrozenPtr = '[['..iBaseAStr..']+A8]+9C'
  if iMaxHP ~= nil and iMaxHP ~= 0 and readFloat(iCurHPPtr) &gt; 0 then
    writeBytes(iIsWornPtr, 0)
    writeFloat(iCurHPPtr, iMaxHP)
  end
  if readFloat(ClothingWetPtr) ~= nil and readFloat(ClothingFrozenPtr) ~= nil then
    writeFloat(ClothingWetPtr, 0)
    writeFloat(ClothingFrozenPtr, 0)
  end
end

local function EvolveTgtItem(iBaseAStr)
  local iTTEPtr = '[['..iBaseAStr..']+E8]+2C'
  local iEvolveReqIndoorsPtr = '[['..iBaseAStr..']+E8]+30'
  writeBytes(iEvolveReqIndoorsPtr, 0) -- set so can occur anywhere
  writeFloat(iTTEPtr, 0.0000578703703703704) -- 5 seconds to evolve
end

local function SetMinStackCnt(iBaseAStr, MinStackCnt)
  local StackCntPtr = '[['..iBaseAStr..']+228]+18'
  local StackCnt = readInteger(StackCntPtr)
  if StackCnt ~= nil and StackCnt &gt; 0 and StackCnt &lt; MinStackCnt then
    writeInteger(StackCntPtr, MinStackCnt)
  end
end

local function getTimer()
  if memrec ~= nil then
    local id = memrec.id
    if timers[id] == nil then
      timers[id] = createTimer()
      timers[id].Enabled = false
      timers[id].Interval = getFreezeTimer().Interval
    end
    return timers[id]
  end
  return nil
end

-- setting timers as global array so that I dont somehow have overlapping timers if it did not close properly
if timers == nil then
  timers = {}
end

local invTmr = getTimer()
if invTmr ~= nil then
  invTmr.OnTimer = function(UpdatePInv)
    local MinStackCnt = readInteger("MinStackableCnt") or 4
    local iSeq = 0
    local continueLoop = true

    while continueLoop == true do
      local iBaseAStr = '[[[[GameAssembly.dll+421E880]+b8]]+10]+20+8*'..string.format('%x',iSeq)
      local iBaseAddr = readQword(iBaseAStr)

      if iBaseAddr ~= 0 then
        -- identify if player or area item (0x20 = m_InPlayerInventory)
        -- Only process if it is a player item
        if readBytes(iBaseAddr+0x20, 1, false) == 1 then
          -- apply minstack if stackable
          if readQword('['..iBaseAStr..']+228') ~= 0 then
            SetMinStackCnt(iBaseAStr,MinStackCnt)
          end
          -- repair items and set wet/frozen to 0 if clothing
          RepairTgtItem(iBaseAStr)
          -- update evolve items for any item with evolve entry (sets it to be anywhere and sets time to evolve to 5 seconds)
          if readQword('['..iBaseAStr..']+E8') ~= 0 then
            EvolveTgtItem(iBaseAStr)
          end
        end
        iSeq = iSeq + 1
      else
        continueLoop = false
      end
    end
  end
  invTmr.setInterval(10000) -- every 10 seconds (takes &lt; 1 second)
  invTmr.Enabled = true
end

{$asm}

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

if memrec ~= nil then
  local id = memrec.id
  if timers[id] ~= nil then
    timers[id].Enabled = false
    timers[id]:Destroy()
    timers[id] = nil
  end
end
{$asm}
unregistersymbol(*)
dealloc(*)
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>136550</ID>
          <Description>"Minimum Stackable Count - don't get greedy :P"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <VariableType>4 Bytes</VariableType>
          <Address>MinStackableCnt</Address>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>
Please excuse the noob question but how do you use the code you posted?

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

  1. Run Cheat engine
  2. Select process tld.exe
  3. Copy the entry I posted and paste it into cheat engine to create the entry
  4. click it to activate

User avatar
ParadoxDad
Cheater
Cheater
Posts: 47
Joined: Tue Nov 12, 2024 12:09 am
Reputation: 33

Re: The Long Dark (Steam/JLee3D)

Post by ParadoxDad »

I went ahead and uploaded the tld.ct file in its entirety for those who want it.
  • no sprains
  • no temp reduction
  • Player movement multiplier (no slowdown in snow)
  • No fatigue
  • No hunger
  • No thirst
  • Unlimited stamina
  • no item weight
  • no fall damage
  • ai ignore player (invisible to all)
  • etc...
Attachments
tld.CT
(119.22 KiB) Downloaded 277 times

Azbats
What is cheating?
What is cheating?
Posts: 1
Joined: Sun Jun 01, 2025 6:16 pm
Reputation: 0

Re: The Long Dark (Steam/JLee3D)

Post by Azbats »

The vast majority of this table does not seem to work or at least have an X on it when using with the Wintermute mode.

Is this a me problem or does the Wintermute mode for TLD just have completely different addresses for things?

Post Reply

Who is online

Users browsing this forum: AhrefsBot, Google [Bot], heftycool98, kvenom, loci22, Orfina, sinner2469, yamisakura