<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="46">
  <CheatEntries>
    <CheatEntry>
      <ID>13</ID>
      <Description>"God Mode"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(ISPLAYER,Player:IsPlayer)
define(SETHEALTH,Character:SetHealth)

assert(ISPLAYER,48 83 EC 08 B8 01 00 00 00 48 83 C4 08 C3)
assert(SETHEALTH,55 48 8B EC 48 83 EC 40 48 89 75 F0 48 89 7D F8)

alloc(godmem,$1000)

label(playerHook)
label(healthHook)
label(normalHealth)
label(blockDamage)
label(playerPtr)

godmem:

playerPtr:
  dq 0

// Capture the Player object whenever Player:IsPlayer runs.
// Then reproduce the original function exactly.
playerHook:
  mov [playerPtr],rcx
  sub rsp,08
  mov eax,00000001
  add rsp,08
  ret

// Character:SetHealth entry:
// RCX  = Character object
// XMM1 = requested new health
healthHook:
  cmp rcx,[playerPtr]
  jne normalHealth

  // Current health is Character+524
  comiss xmm1,[rcx+524]

  // Proposed health is lower - block damage
  jb blockDamage

normalHealth:
  // Replay the 16 bytes replaced at Character:SetHealth
  push rbp
  mov rbp,rsp
  sub rsp,40
  mov [rbp-10],rsi
  mov [rbp-08],rdi

  jmp far SETHEALTH+10

blockDamage:
  ret

// Player:IsPlayer is exactly 14 bytes long
ISPLAYER:
  jmp far playerHook

// We overwrite the first 16 bytes of SetHealth
SETHEALTH:
  jmp far healthHook
  nop 2

registersymbol(playerPtr)

[DISABLE]

ISPLAYER:
  db 48 83 EC 08 B8 01 00 00 00 48 83 C4 08 C3

SETHEALTH:
  db 55 48 8B EC 48 83 EC 40 48 89 75 F0 48 89 7D F8

unregistersymbol(playerPtr)
dealloc(godmem)
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>27</ID>
      <Description>"Max Health (125)"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(MAXHEALTH,Player:SetMaxHealth)

assert(MAXHEALTH+F,F3 0F 11 4D F0)

alloc(maxhealthmem,$1000,MAXHEALTH+F)

label(return)
label(original)
label(minHealth)

maxhealthmem:

  // XMM1 = requested new max health
  // If Valheim wants less than 125, replace it with 125
  comiss xmm1,[minHealth]
  jae original

  movss xmm1,[minHealth]

original:
  // Original instruction
  movss [rbp-10],xmm1
  jmp return

minHealth:
  dd (float)125

MAXHEALTH+F:
  jmp maxhealthmem

return:


[DISABLE]

define(MAXHEALTH,Player:SetMaxHealth)

MAXHEALTH+F:
  db F3 0F 11 4D F0

dealloc(maxhealthmem)
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>14</ID>
      <Description>"Infinite Stamina"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(USESTAMINA,Player:RPC_UseStamina)

assert(USESTAMINA+4C,F3 0F 11 AE 88 09 00 00)

// Original:
// movss [rsi+00000988],xmm5
//
// Prevent reduced stamina from being stored.
USESTAMINA+4C:
  db 90 90 90 90 90 90 90 90

[DISABLE]

define(USESTAMINA,Player:RPC_UseStamina)

USESTAMINA+4C:
  db F3 0F 11 AE 88 09 00 00
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>17</ID>
      <Description>"Melee Durability"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(MELEEDURABILITY,Attack:DoMeleeAttack)

assert(MELEEDURABILITY+5B32,F3 0F 11 68 3C)

// Original:
// movss [rax+3C],xmm5
//
// Prevent melee weapon/tool durability loss
MELEEDURABILITY+5B32:
  db 90 90 90 90 90


[DISABLE]

define(MELEEDURABILITY,Attack:DoMeleeAttack)

MELEEDURABILITY+5B32:
  db F3 0F 11 68 3C

</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>20</ID>
      <Description>"Ranged Durability"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(PROJECTILEDURABILITY,Attack:ProjectileAttackTriggered)

assert(PROJECTILEDURABILITY+418,F3 0F 11 68 3C)

// Original:
// movss [rax+3C],xmm5
//
// Prevent bow / projectile weapon durability loss
PROJECTILEDURABILITY+418:
  db 90 90 90 90 90


[DISABLE]

define(PROJECTILEDURABILITY,Attack:ProjectileAttackTriggered)

PROJECTILEDURABILITY+418:
  db F3 0F 11 68 3C
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>23</ID>
      <Description>"Infinite Ammo"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(USEAMMO,Attack:UseAmmo)

// Original:
// call r11
//
// r11 = Inventory:RemoveItem
assert(USEAMMO+298,41 FF D3)

// Prevent the ammo-removal call
USEAMMO+298:
  db 90 90 90


[DISABLE]

define(USEAMMO,Attack:UseAmmo)

USEAMMO+298:
  db 41 FF D3

</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>29</ID>
      <Description>"Armour Durability"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]

{$lua}
if syntaxcheck then return end

if LaunchMonoDataCollector() == 0 then
  error("Could not activate Mono. Make sure Valheim is fully loaded.")
end

{$asm}

define(ARMORDURABILITY,Player:DamageArmorDurability)

assert(ARMORDURABILITY+3B4,F3 41 0F 11 6F 3C)

// Original:
// movss [r15+3C],xmm5
//
// Prevent armour durability loss
ARMORDURABILITY+3B4:
  db 90 90 90 90 90 90


[DISABLE]

define(ARMORDURABILITY,Player:DamageArmorDurability)

ARMORDURABILITY+3B4:
  db F3 41 0F 11 6F 3C

</AssemblerScript>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
</CheatTable>
