<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="38">
  <CheatEntries>
    <CheatEntry>
      <ID>432</ID>
      <Description>"true camera fly (WASD+Space/Ctrl, no fall damage)"</Description>
      <LastState/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : DS2.exe
  Version:
  Date   : 2026-04-23
  Author : SERGEJ + Copilot + Codex

  Combined script:
  - Camera forward vector capture
  - Direct player translation in camera space
  - Hover / ground stabilization while enabled
  - No fall damage while fly is active

  Controls:
  - W / S : forward / backward relative to camera
  - A / D : strafe relative to camera
  - SPACE : up
  - CTRL or C : down
  - SHIFT : speed boost
}

[ENABLE]

{$lua}
if syntaxcheck then return end

if comboTrueFlyTimer ~= nil then
  comboTrueFlyTimer.destroy()
  comboTrueFlyTimer = nil
end

comboTrueFlyTimer = createTimer(nil, false)
comboTrueFlyTimer.Interval = 15
comboTrueFlyTimer.OnTimer = function(t)
  local enabled = readInteger("combo_fly_hold")
  if enabled == nil or enabled == 0 then return end

  local player = readPointer("combo_player_ptr")
  if player == nil or player == 0 then return end

  -- Keep noclip active during true fly to avoid collision-triggered trips/stumbles.
  writeBytes(player + 0x50, 0x7F)

  local fx = readFloat("combo_cam_forward")
  local fy = readFloat("combo_cam_forward+4")
  local fz = readFloat("combo_cam_forward+8")
  if fx == nil or fy == nil or fz == nil then return end

  local flen = math.sqrt(fx * fx + fy * fy + fz * fz)
  if flen &lt; 0.0001 then return end

  fx = fx / flen
  fy = fy / flen
  fz = fz / flen

  local rx = -fy
  local ry = fx
  local rlen = math.sqrt(rx * rx + ry * ry)
  if rlen &lt; 0.0001 then
    rx = 1.0
    ry = 0.0
  else
    rx = rx / rlen
    ry = ry / rlen
  end

  local mx = 0.0
  local my = 0.0
  local mz = 0.0

  if isKeyPressed(0x57) then
    mx = mx + fx
    my = my + fy
    mz = mz + fz
  end

  if isKeyPressed(0x53) then
    mx = mx - fx
    my = my - fy
    mz = mz - fz
  end

  if isKeyPressed(0x41) then
    mx = mx + rx
    my = my + ry
  end

  if isKeyPressed(0x44) then
    mx = mx - rx
    my = my - ry
  end

  if isKeyPressed(0x20) then
    mz = mz + 1.0
  end

  if isKeyPressed(0x11) or isKeyPressed(0x43) then
    mz = mz - 1.0
  end

  -- Keep the physics velocity neutral while the fly is running.
  writeFloat(player + 0x170, 0.0)
  writeFloat(player + 0x174, 0.0)
  writeFloat(player + 0x178, 0.0)

  local mlen = math.sqrt(mx * mx + my * my + mz * mz)
  if mlen &lt; 0.0001 then return end

  mx = mx / mlen
  my = my / mlen
  mz = mz / mlen

  local speed = readFloat("combo_true_speed")
  if speed == nil then speed = 24.0 end

  local boost = readFloat("combo_true_boost_mult")
  if boost == nil then boost = 2.0 end

  if isKeyPressed(0x10) then
    speed = speed * boost
  end

  local step = speed * (t.Interval / 1000.0)

  local x = readDouble(player + 0x110)
  local y = readDouble(player + 0x118)
  local z = readDouble(player + 0x120)
  if x == nil or y == nil or z == nil then return end

  writeDouble(player + 0x110, x + mx * step)
  writeDouble(player + 0x118, y + my * step)
  writeDouble(player + 0x120, z + mz * step)
end
comboTrueFlyTimer.Enabled = true
{$asm}

aobscanmodule(combo_camdir,DS2.exe,04 00 00 C5 F8 10 41 50) // should be unique
aobscanmodule(combo_flying,DS2.exe,C5 F8 11 87 70 01 00 00 48 8B 8F) // should be unique
aobscanmodule(combo_ground,DS2.exe,88 83 31 01 00 00 84 C0 75) // should be unique
aobscanmodule(combo_fall_damage,DS2.exe,C5 FA 10 87 30 0E 00 00) // should be unique

alloc(newmem_camdir,$1000,combo_camdir)
alloc(newmem_flying,$1000,combo_flying)
alloc(newmem_ground,$1000,combo_ground)
alloc(newmem_fall_damage,$1000,combo_fall_damage)
alloc(combo_data,$1000,combo_ground)

label(code_camdir)
label(return_camdir)
label(code_flying)
label(return_flying)
label(code_ground)
label(return_ground)
label(code_fall_damage)
label(return_fall_damage)
label(orig_flying)
label(done_ground)
label(orig_fall_damage)

label(combo_true_speed)
label(combo_true_boost_mult)
label(combo_fly_hold)
label(combo_player_ptr)
label(combo_cam_forward)

combo_data:
combo_true_speed:
  dd (float)24
combo_true_boost_mult:
  dd (float)4
combo_fly_hold:
  dd 1
combo_player_ptr:
  dq 0
combo_cam_forward:
  dd (float)0
  dd (float)1
  dd (float)0
  dd (float)0

newmem_camdir:
code_camdir:
  vmovups xmm0,[rcx+50]
  vmovups [combo_cam_forward],xmm0
  jmp return_camdir

newmem_flying:
code_flying:
  mov qword ptr [combo_player_ptr],rdi
  cmp dword ptr [combo_fly_hold],01
  jne orig_flying

  vxorps xmm10,xmm10,xmm10
  vmovups [rdi+00000170],xmm10
  jmp return_flying

orig_flying:
  vmovups [rdi+00000170],xmm0
  jmp return_flying

newmem_ground:
code_ground:
  mov [rbx+00000131],al

  cmp dword ptr [combo_fly_hold],01
  jne done_ground

  mov byte ptr [rbx+00000131],01

done_ground:
  jmp return_ground

newmem_fall_damage:
code_fall_damage:
  cmp dword ptr [combo_fly_hold],01
  jne orig_fall_damage

  vmovss xmm0,[rdi+00000E30]
  mov [rdi+00000E30],(float)600000
  mov [rdi+00000E34],(float)800000
  mov [rdi+00000E38],(float)900000
  jmp return_fall_damage

orig_fall_damage:
  vmovss xmm0,[rdi+00000E30]
  jmp return_fall_damage

combo_camdir+03:
  jmp newmem_camdir
return_camdir:

combo_flying:
  jmp newmem_flying
  nop 3
return_flying:

combo_ground:
  jmp newmem_ground
  nop
return_ground:

combo_fall_damage:
  jmp newmem_fall_damage
  nop 3
return_fall_damage:

registersymbol(combo_camdir)
registersymbol(combo_flying)
registersymbol(combo_ground)
registersymbol(combo_fall_damage)
registersymbol(combo_fly_hold)
registersymbol(combo_player_ptr)
registersymbol(combo_cam_forward)
registersymbol(combo_true_speed)
registersymbol(combo_true_boost_mult)

[DISABLE]

{$lua}
if syntaxcheck then return end
if comboTrueFlyTimer ~= nil then
  comboTrueFlyTimer.destroy()
  comboTrueFlyTimer = nil
end
{$asm}

combo_camdir+03:
  db C5 F8 10 41 50

combo_flying:
  db C5 F8 11 87 70 01 00 00

combo_ground:
  db 88 83 31 01 00 00

combo_fall_damage:
  db C5 FA 10 87 30 0E 00 00

unregistersymbol(combo_camdir)
unregistersymbol(combo_flying)
unregistersymbol(combo_ground)
unregistersymbol(combo_fall_damage)
unregistersymbol(combo_fly_hold)
unregistersymbol(combo_player_ptr)
unregistersymbol(combo_cam_forward)
unregistersymbol(combo_true_speed)
unregistersymbol(combo_true_boost_mult)

dealloc(newmem_camdir)
dealloc(newmem_flying)
dealloc(newmem_ground)
dealloc(newmem_fall_damage)
dealloc(combo_data)

{
// ORIGINAL CODE - INJECTION POINT: DS2.exe+246BCF6 / DS2.exe+2404EF0 / DS2.exe+EC03E0

DS2.exe+246BCCF: 48 8D 99 D0 00 00 00     - lea rbx,[rcx+000000D0]
DS2.exe+246BCD6: 48 8B F9                 - mov rdi,rcx
DS2.exe+246BCD9: 48 8B CB                 - mov rcx,rbx
DS2.exe+246BCDC: 48 8B F2                 - mov rsi,rdx
DS2.exe+246BCDF: FF 15 93 86 79 00        - call qword ptr [DS2.exe+2C04378]
DS2.exe+246BCE5: 84 C0                    - test al,al
DS2.exe+246BCE7: 75 09                    - jne DS2.exe+246BCF2
DS2.exe+246BCE9: 48 8B CB                 - mov rcx,rbx
DS2.exe+246BCEC: FF 15 C6 86 79 00        - call qword ptr [DS2.exe+2C043B8]
DS2.exe+246BCF2: C5 F8 10 06              - vmovups xmm0,[rsi]
// ---------- INJECTING HERE ----------
DS2.exe+246BCF6: C5 F8 11 87 70 01 00 00  - vmovups [rdi+00000170],xmm0
// ---------- DONE INJECTING  ----------
DS2.exe+246BCFE: 48 8B 8F E8 00 00 00     - mov rcx,[rdi+000000E8]
DS2.exe+246BD05: 48 85 C9                 - test rcx,rcx
DS2.exe+246BD08: 74 18                    - je DS2.exe+246BD22
DS2.exe+246BD0A: 48 8B 01                 - mov rax,[rcx]
DS2.exe+246BD0D: 48 8D 54 24 20           - lea rdx,[rsp+20]
DS2.exe+246BD12: C5 F8 57 C0              - vxorps xmm0,xmm0,xmm0
DS2.exe+246BD16: C5 F8 11 44 24 20        - vmovups [rsp+20],xmm0
DS2.exe+246BD1C: FF 90 00 01 00 00        - call qword ptr [rax+00000100]
DS2.exe+246BD22: 48 85 DB                 - test rbx,rbx
DS2.exe+246BD25: 74 09                    - je DS2.exe+246BD30
}
</AssemblerScript>
      <Hotkeys>
        <Hotkey>
          <Action>Toggle Activation</Action>
          <Keys>
            <Key>104</Key>
          </Keys>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
    </CheatEntry>
    <CheatEntry>
      <ID>9000</ID>
      <Description>"Enable first - auto complete structure"</Description>
      <LastState/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : DS2.exe
  Version:
  Date   : 2026-04-15
  Author : Codex

  Resolves the currently opened autopaver panel safely, waits for the handle to
  stabilize, then exposes need/current/missing values for whichever autopaver is open.
}

[ENABLE]

{$lua}
if syntaxcheck then return end

function ds2AutopaverCleanup()
  if ds2AutopaverTimer ~= nil then
    ds2AutopaverTimer.destroy()
    ds2AutopaverTimer = nil
  end

  local symbols = {
    {"ds2ApUiRootMem", "ds2_ap_ui_root", 8},
    {"ds2ApUiManagerMem", "ds2_ap_ui_manager", 8},
    {"ds2ApPanelMem", "ds2_ap_panel", 8},
    {"ds2ApEntry4Mem", "ds2_ap_entry4", 8},
    {"ds2ApHandleHolderMem", "ds2_ap_handle_holder", 8},
    {"ds2ApHandleMem", "ds2_ap_handle", 8},
    {"ds2ApRoadManagerMem", "ds2_ap_road_manager", 8},
    {"ds2ApObjectMem", "ds2_ap_obj", 8},
    {"ds2ApNeedMem", "ds2_ap_need", 24},
    {"ds2ApCurMem", "ds2_ap_cur", 24},
    {"ds2ApMissingMem", "ds2_ap_missing", 24},
    {"ds2ApHandleBufferMem", "ds2_ap_handle_buffer", 8}
  }

  for _, item in ipairs(symbols) do
    local address = _G[item[1]]
    if address ~= nil then
      pcall(unregisterSymbol, item[2])
      pcall(deAlloc, address, item[3])
      _G[item[1]] = nil
    end
  end

  ds2ApLastHandle = nil
  ds2ApStableTicks = nil
end

if ds2AutopaverCleanup ~= nil then
  ds2AutopaverCleanup()
end

local function ds2AutopaverAlloc(varName, symbolName, size)
  local address = allocateMemory(size)
  _G[varName] = address
  registerSymbol(symbolName, address, true)
  return address
end

local function ds2AutopaverZeroDwords(address, byteCount)
  local offset = 0
  while offset &lt; byteCount do
    writeInteger(address + offset, 0)
    offset = offset + 4
  end
end

local function ds2AutopaverReset()
  writeQword(ds2ApUiRootMem, 0)
  writeQword(ds2ApUiManagerMem, 0)
  writeQword(ds2ApPanelMem, 0)
  writeQword(ds2ApEntry4Mem, 0)
  writeQword(ds2ApHandleHolderMem, 0)
  writeQword(ds2ApHandleMem, 0)
  writeQword(ds2ApRoadManagerMem, 0)
  writeQword(ds2ApObjectMem, 0)
  writeQword(ds2ApHandleBufferMem, 0)
  ds2AutopaverZeroDwords(ds2ApNeedMem, 24)
  ds2AutopaverZeroDwords(ds2ApCurMem, 24)
  ds2AutopaverZeroDwords(ds2ApMissingMem, 24)
end

ds2ApUiRootMem = ds2AutopaverAlloc("ds2ApUiRootMem", "ds2_ap_ui_root", 8)
ds2ApUiManagerMem = ds2AutopaverAlloc("ds2ApUiManagerMem", "ds2_ap_ui_manager", 8)
ds2ApPanelMem = ds2AutopaverAlloc("ds2ApPanelMem", "ds2_ap_panel", 8)
ds2ApEntry4Mem = ds2AutopaverAlloc("ds2ApEntry4Mem", "ds2_ap_entry4", 8)
ds2ApHandleHolderMem = ds2AutopaverAlloc("ds2ApHandleHolderMem", "ds2_ap_handle_holder", 8)
ds2ApHandleMem = ds2AutopaverAlloc("ds2ApHandleMem", "ds2_ap_handle", 8)
ds2ApRoadManagerMem = ds2AutopaverAlloc("ds2ApRoadManagerMem", "ds2_ap_road_manager", 8)
ds2ApObjectMem = ds2AutopaverAlloc("ds2ApObjectMem", "ds2_ap_obj", 8)
ds2ApNeedMem = ds2AutopaverAlloc("ds2ApNeedMem", "ds2_ap_need", 24)
ds2ApCurMem = ds2AutopaverAlloc("ds2ApCurMem", "ds2_ap_cur", 24)
ds2ApMissingMem = ds2AutopaverAlloc("ds2ApMissingMem", "ds2_ap_missing", 24)
ds2ApHandleBufferMem = ds2AutopaverAlloc("ds2ApHandleBufferMem", "ds2_ap_handle_buffer", 8)

ds2AutopaverReset()

local function ds2AutopaverResolvePointers()
  local gameBase = getAddressSafe("DS2.exe")
  if gameBase == nil then
    ds2AutopaverReset()
    return false
  end

  local uiRoot = readQword(gameBase + 0x619C878) or 0
  local uiManager = 0
  local panel = 0
  local entry4 = 0
  local handleHolder = 0
  local handle = 0
  local roadManager = readQword(gameBase + 0x619C768) or 0
  local objectAddress = 0

  if uiRoot ~= 0 then
    uiManager = readQword(uiRoot) or 0
  end

  if uiManager ~= 0 then
    local entryArray = readQword(uiManager + 0x19A0) or 0
    local entryCount = readInteger(uiManager + 0x19A8) or 0

    if entryArray ~= 0 and entryCount &gt; 0 and entryCount &lt; 0x200 then
      for index = 0, entryCount - 1 do
        local entryAddress = entryArray + index * 0x18
        local entryId = readInteger(entryAddress + 0x8) or -1
        local entryObject = readQword(entryAddress) or 0

        if entryId == 4 then
          entry4 = entryObject
        elseif entryId == 5 then
          panel = entryObject
        end
      end
    end
  end

  if entry4 ~= 0 then
    handleHolder = readQword(entry4 + 0x90) or 0
    if handleHolder ~= 0 then
      handle = readQword(handleHolder + 0x8) or 0
    end
  end

  if roadManager ~= 0 and handle ~= 0 then
    writeQword(ds2ApHandleBufferMem, handle)
    local resolved = executeCodeEx(0, 1500, gameBase + 0x125D7E0, {type=0, value=roadManager}, {type=0, value=ds2ApHandleBufferMem})
    objectAddress = tonumber(resolved) or 0
  end

  writeQword(ds2ApUiRootMem, uiRoot)
  writeQword(ds2ApUiManagerMem, uiManager)
  writeQword(ds2ApPanelMem, panel)
  writeQword(ds2ApEntry4Mem, entry4)
  writeQword(ds2ApHandleHolderMem, handleHolder)
  writeQword(ds2ApHandleMem, handle)
  writeQword(ds2ApRoadManagerMem, roadManager)
  writeQword(ds2ApObjectMem, objectAddress)
  writeQword(ds2ApHandleBufferMem, handle)

  return handle ~= 0 and panel ~= 0
end

local function ds2AutopaverRefreshArrays()
  local gameBase = getAddressSafe("DS2.exe")
  local handle = readQword(ds2ApHandleMem) or 0

  ds2AutopaverZeroDwords(ds2ApNeedMem, 24)
  ds2AutopaverZeroDwords(ds2ApCurMem, 24)
  ds2AutopaverZeroDwords(ds2ApMissingMem, 24)

  if gameBase == nil or handle == 0 then
    return false
  end

  writeQword(ds2ApHandleBufferMem, handle)
  executeCodeEx(0, 1500, gameBase + 0x12862C0, {type=0, value=ds2ApHandleBufferMem}, {type=0, value=ds2ApNeedMem})
  executeCodeEx(0, 1500, gameBase + 0x12863A0, {type=0, value=ds2ApHandleBufferMem}, {type=0, value=ds2ApCurMem})

  for index = 0, 5 do
    local need = readInteger(ds2ApNeedMem + index * 4) or 0
    local cur = readInteger(ds2ApCurMem + index * 4) or 0
    local missing = need - cur
    if missing &lt; 0 then
      missing = 0
    end
    writeInteger(ds2ApMissingMem + index * 4, missing)
  end

  return true
end

function ds2AutopaverUpdate()
  local ready = ds2AutopaverResolvePointers()
  local handle = readQword(ds2ApHandleMem) or 0
  local panel = readQword(ds2ApPanelMem) or 0

  if not ready or handle == 0 or panel == 0 then
    ds2ApLastHandle = 0
    ds2ApStableTicks = 0
    ds2AutopaverZeroDwords(ds2ApNeedMem, 24)
    ds2AutopaverZeroDwords(ds2ApCurMem, 24)
    ds2AutopaverZeroDwords(ds2ApMissingMem, 24)
    return
  end

  if ds2ApLastHandle == handle then
    ds2ApStableTicks = (ds2ApStableTicks or 0) + 1
  else
    ds2ApLastHandle = handle
    ds2ApStableTicks = 0
    ds2AutopaverZeroDwords(ds2ApNeedMem, 24)
    ds2AutopaverZeroDwords(ds2ApCurMem, 24)
    ds2AutopaverZeroDwords(ds2ApMissingMem, 24)
    return
  end

  if ds2ApStableTicks &gt;= 2 then
    ds2AutopaverRefreshArrays()
  end
end

function ds2AutopaverRefreshNow()
  ds2ApStableTicks = 2
  ds2AutopaverUpdate()
end

function ds2AutopaverCompleteCurrent()
  ds2AutopaverRefreshNow()

  local gameBase = getAddressSafe("DS2.exe")
  local panel = readQword(ds2ApPanelMem) or 0
  local objectAddress = readQword(ds2ApObjectMem) or 0

  if gameBase == nil or objectAddress == 0 then
    return
  end

  for index = 0, 5 do
    local missing = readInteger(ds2ApMissingMem + index * 4) or 0
    if missing &gt; 0 then
      local slotAddress = objectAddress + 0x280 + index * 4
      local raw = readInteger(slotAddress) or 0
      writeInteger(slotAddress, raw + missing)
    end
  end

  if panel ~= 0 then
    executeCodeEx(0, 1500, gameBase + 0x153C2C0, {type=0, value=panel})
  end

  ds2ApStableTicks = 2
  ds2AutopaverUpdate()
end

ds2ApLastHandle = 0
ds2ApStableTicks = 0

ds2AutopaverTimer = createTimer(nil, false)
ds2AutopaverTimer.Interval = 750
ds2AutopaverTimer.OnTimer = function(timer)
  ds2AutopaverUpdate()
end
ds2AutopaverUpdate()
ds2AutopaverTimer.Enabled = true
{$asm}

[DISABLE]

{$lua}
if syntaxcheck then return end

if ds2AutopaverCleanup ~= nil then
  ds2AutopaverCleanup()
end
ds2AutopaverUpdate = nil
ds2AutopaverRefreshNow = nil
ds2AutopaverCompleteCurrent = nil
{$asm}
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>9001</ID>
          <Description>"refresh current autopaver now"</Description>
          <LastState/>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if ds2AutopaverRefreshNow ~= nil then
  ds2AutopaverRefreshNow()
elseif ds2AutopaverUpdate ~= nil then
  ds2AutopaverUpdate()
end

if memrec ~= nil then
  memrec.Active = false
end
{$asm}

[DISABLE]

{$lua}
if syntaxcheck then return end
{$asm}
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>9002</ID>
          <Description>"Toggle to complete current structure"</Description>
          <LastState/>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if ds2AutopaverCompleteCurrent ~= nil then
  ds2AutopaverCompleteCurrent()
end

if memrec ~= nil then
  memrec.Active = false
end
{$asm}

[DISABLE]

{$lua}
if syntaxcheck then return end
{$asm}
</AssemblerScript>
          <Hotkeys>
            <Hotkey>
              <Action>Toggle Activation</Action>
              <Keys>
                <Key>103</Key>
              </Keys>
              <ID>0</ID>
            </Hotkey>
          </Hotkeys>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>9030</ID>
      <Description>"instant 5 stars on first delivery (household friendship max)"</Description>
      <LastState/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : DS2.exe
  Version:
  Date   : 2026-04-23
  Author : Codex

  Forces household friendship updates to jump straight to level 5.
  The raw friendship value is raised to the level-5 threshold before the game runs
  its normal level-up handler, so a single qualifying delivery can max a facility.
}

[ENABLE]

aobscanmodule(ds2_instant_5star,DS2.exe,8B 56 08 44 8B C0 48 8B CF E8 ?? ?? ?? ?? 45 33 E4 44 8B F8 44 3B F0) // should be unique
alloc(newmem,$1000,ds2_instant_5star)
alloc(ds2_5star_enable,4)

label(code)
label(original)
label(return)

ds2_5star_enable:
  dd 1

newmem:
code:
  cmp dword ptr [ds2_5star_enable],01
  jne original

  mov edx,[rdi+40]
  mov [rsi+08],edx
  mov r8d,05
  mov rcx,rdi
  call DS2.exe+B33110
  jmp return

original:
  mov edx,[rsi+08]
  mov r8d,eax
  mov rcx,rdi
  call DS2.exe+B33110
  jmp return

ds2_instant_5star:
  jmp newmem
  nop 9
return:

registersymbol(ds2_instant_5star)
registersymbol(ds2_5star_enable)

[DISABLE]

ds2_instant_5star:
  db 8B 56 08 44 8B C0 48 8B CF E8 B0 07 00 00

unregistersymbol(ds2_instant_5star)
unregistersymbol(ds2_5star_enable)
dealloc(newmem)
dealloc(ds2_5star_enable)

</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>9031</ID>
      <Description>"always day + no rain"</Description>
      <LastState/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : DS2.exe
  Version:
  Date   : 2026-04-23
  Author : Codex

  Keeps the world in daytime and suppresses rain/timefall queries.
  - Freezes time-of-day around noon
  - Disables the day/night cycle flags
  - Forces rainy condition getters to return 0
  - Clears the weather manager's active rain-related flags
}

[ENABLE]

{$lua}
if syntaxcheck then return end

if ds2ClearWeatherTimer ~= nil then
  ds2ClearWeatherTimer.destroy()
  ds2ClearWeatherTimer = nil
end

ds2ClearWeatherTimer = createTimer(nil, false)
ds2ClearWeatherTimer.Interval = 250
ds2ClearWeatherTimer.OnTimer = function(timer)
  local todRoot = readPointer("DS2.exe+619C030")
  if todRoot ~= nil and todRoot ~= 0 then
    writeFloat(todRoot + 0x23C, 0.0)

    local tod = readPointer(todRoot + 0x58)
    if tod ~= nil and tod ~= 0 then
      writeFloat(tod + 0x20, 12.0)
      writeInteger(tod + 0x3C, 0)
      writeBytes(tod + 0x38, 0)
      writeBytes(tod + 0x39, 0)
      writeBytes(tod + 0x7C, 0)
      writeBytes(tod + 0x7D, 0)
    end
  end

  local weatherMgr = readPointer("DS2.exe+619D680")
  if weatherMgr ~= nil and weatherMgr ~= 0 then
    writeBytes(weatherMgr + 0x6B52, 0)
    writeBytes(weatherMgr + 0x6B54, 0)
    writeBytes(weatherMgr + 0x6B55, 0)
    writeBytes(weatherMgr + 0x6B56, 0)
    writeBytes(weatherMgr + 0x6B57, 0)
  end
end
ds2ClearWeatherTimer.Enabled = true
{$asm}

assert(DS2.exe+1EFBA70,48 8B D1 48 8B 0D 06 1C 2A 04)
assert(DS2.exe+1EFBA90,E9 FB 82 BC FE CC CC)
assert(DS2.exe+1EFB8B0,48 8B 05 C9 1D 2A 04)

DS2.exe+1EFBA70:
  db 31 C0 C5 F8 57 C0 C3 90 90 90

DS2.exe+1EFBA90:
  db 31 C0 C5 F8 57 C0 C3

DS2.exe+1EFB8B0:
  db 31 C0 C3 90 90 90 90

[DISABLE]

{$lua}
if syntaxcheck then return end

if ds2ClearWeatherTimer ~= nil then
  ds2ClearWeatherTimer.destroy()
  ds2ClearWeatherTimer = nil
end
{$asm}

DS2.exe+1EFBA70:
  db 48 8B D1 48 8B 0D 06 1C 2A 04

DS2.exe+1EFBA90:
  db E9 FB 82 BC FE CC CC

DS2.exe+1EFB8B0:
  db 48 8B 05 C9 1D 2A 04

</AssemblerScript>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
</CheatTable>
