<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="52">
  <Files>
    <File Name="launchgame.dat" Encoding="Ascii85">i*3J62,qhaOU=1l%S[KG)MzpJ/#M**arbvua8JxlEslZ6DnO)aLW*uoi%W{AfefH/42D))uC(CQ.#3F.00</File>
  </Files>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"Activate First"</Description>
      <Options moDeactivateChildrenAsWell="1"/>
      <Color>000000</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{$LUA}
if syntaxcheck then return end

[ENABLE]
if not process or not readInteger(process) then
  if getProcessIDFromProcessName('ShovelKnight.exe') then
    openProcess('ShovelKnight.exe')
  else
    showMessage('Launch ShovelKnight.exe first!')
    error('Process not found')
  end
end

hackingPoints = {}
local function updateHackingPoint(address, symbol, record)
  if address then
    registerSymbol(symbol, address)
    table.insert(hackingPoints, symbol)

    if record then
      record.Color = 0x00AA00 -- Green
    end
  elseif record then
    record.Color = 0x0000AA -- Red
  end
end

-- Infinite Health
local aobstring = 'D9 5D 0C D9 46 20 D8 65 0C D9 5D 0C D9 45 0C D9 56 20'
local lifeHack = AOBScanModuleUnique('ShovelKnight.exe', aobstring)
local record = AddressList.getMemoryRecordByDescription('Infinite Health')
updateHackingPoint(lifeHack, 'lifeHack', record)

-- Invincibility
aobstring = 'C6 86 ?? ?? ?? ?? 00 D8 96 ?? ?? 00 00 DF E0 F6 C4 05 0F 8A'
local invincibleHack = AOBScanModuleUnique('ShovelKnight.exe', aobstring)
if invincibleHack then
 invincibleHack = invincibleHack + 0x07
end
local record = AddressList.getMemoryRecordByDescription('Invincibility')
updateHackingPoint(invincibleHack, 'invincibleHack', record)

-- Infinite Jump
-- Skip
-- Edit Jump Height
aobstring = 'D9 86 ?? ?? 00 00 80 BE ?? ?? 00 00 00 D9 5D FC 76'
local jumpHack = AOBScanModuleUnique('ShovelKnight.exe', aobstring)
record = AddressList.getMemoryRecordByDescription('Edit Jump')
updateHackingPoint(jumpHack, 'jumpHack', record)

-- Infinite Magic
aobstring = '2A C1 88 86 ?? ?? 00 00 5E 5D C2'
local itemHack = AOBScanModuleUnique('ShovelKnight.exe', aobstring)
record = AddressList.getMemoryRecordByDescription('Infinite Magic')
updateHackingPoint(itemHack, 'itemHack', record)

-- Edit Money
aobstring = '8B C8 75 ?? 8B 81 ?? ?? ?? ?? C3'
local goldHack = AOBScanModuleUnique('ShovelKnight.exe', aobstring)
if goldHack then
  goldHack = goldHack + 0x04
end
record = AddressList.getMemoryRecordByDescription('Edit Money')
updateHackingPoint(goldHack, 'goldHack', record)


[DISABLE]
for index, symbol in ipairs(hackingPoints) do
    unregisterSymbol(symbol)
end

for i = 0, AddressList.Count - 1 do
  AddressList[i].Color = 'clWindowText'
end

if readInteger(process) == 0 then
  for i = 0, AddressList.Count - 1 do
      local record = AddressList.getMemoryRecord(i)
      if record.Type == vtAutoAssembler and record.Active then
          record.Active = false
      end
  end
end

</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>1</ID>
          <Description>"Infinite Health"</Description>
          <Color>000000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$LUA}
if syntaxcheck then return end
if not getAddressSafe('lifeHack') then
  showMessage('AOB Scan for Infinite Health not found!')
  error()
end
{$ASM}
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(infiniteHealth,2048)
label(returnhere)
label(exit)

infiniteHealth:
cmp ebx, 1 // Check if Player
je @f

// Original Code for the Enemy
fstp dword ptr [ebp+0C]
fld dword ptr [esi+20]
fsub dword ptr [ebp+0C]
fstp dword ptr [ebp+0C]
fld dword ptr [ebp+0C]
fst dword ptr [esi+20]

jmp exit

// Cheat
@@:
fstp st(0) // Pop the first value on the stack
fld dword ptr [esi+24] // Place Max Health on the stack
fst dword ptr [ebp+0C] // Load Max Health onto Changed Health
fst dword ptr [esi+20] // Load Max Health onto Current Health

exit:
jmp returnhere

lifeHack:
jmp infiniteHealth
nop D
returnhere:




[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(infiniteHealth)
lifeHack:
db D9 5D 0C D9 46 20 D8 65 0C D9 5D 0C D9 45 0C D9 56 20
//fstp dword ptr [ebp+0C]
//fld dword ptr [esi+20]
//fsub dword ptr [ebp+0C]
//fstp dword ptr [ebp+0C]
//fld dword ptr [ebp+0C]
//fst dword ptr [esi+20]

</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>12</ID>
          <Description>"Invincibility"</Description>
          <Color>000000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$LUA}
if syntaxcheck then return end

local address = getAddressSafe('invincibleHack')
if not address then
  showMessage('AOB Scan for Invincibility not found!')
  error()
end


-- fcom dword ptr [esi+00000D0C]
-- First 2 bytes are D8 96
-- Last 4 bytes is the offset
local aob = readBytes(address + 0x02, 4, true)

local offset = ''
for i = 4, 1, -1 do
  offset = offset .. string.format('%02X', aob[i])
end

registerSymbol('invincibleHackOffset', offset)
{$ASM}
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem:
mov dword ptr [esi+invincibleHackOffset],(float)1.0

originalcode:
fcom dword ptr [esi+invincibleHackOffset]

exit:
jmp returnhere

invincibleHack:
jmp newmem
nop
returnhere:

[DISABLE]
dealloc(newmem)
invincibleHack:
fcom dword ptr [esi+invincibleHackOffset]

unregistersymbol(invincibleHackOffset)
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>10</ID>
          <Description>"Edit Jump"</Description>
          <Options moHideChildren="1"/>
          <Color>000000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$LUA}
if syntaxcheck then return end

local address = getAddressSafe('jumpHack')
if not address then
  showMessage('AOB Scan for Edit Jump not found!')
  error()
end


-- fld dword ptr [esi+????????]
-- First 2 bytes are D9 86
-- Last 4 bytes is the offset
local aob = readBytes(address + 0x02, 4, true)

local offset = ''
for i = 4, 1, -1 do
  offset = offset .. string.format('%02X', aob[i])
end

registerSymbol('jumpHackOffset', offset)
{$ASM}
alloc(newmem,2048)
label(returnhere)
label(exit)

alloc(jumpMultiplier, 4)
registersymbol(jumpMultiplier)

jumpMultiplier:
dd (float)29.0

newmem: //this is allocated memory, you have read,write,execute access
//place your code here
fld dword ptr [jumpMultiplier]

exit:
jmp returnhere

jumpHack:
jmp newmem
nop
returnhere:


 
 
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
dealloc(jumpMultiplier)
unregistersymbol(jumpMultiplier)
jumpHack:
fld dword ptr [esi+jumpHackOffset]

unregistersymbol(jumpHackOffset)
</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>11</ID>
              <Description>"Jump Multiplier"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>000000</Color>
              <VariableType>Float</VariableType>
              <Address>jumpMultiplier</Address>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>2</ID>
          <Description>"Infinite Magic"</Description>
          <Color>000000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$LUA}
if syntaxcheck then return end

if not getAddressSafe('itemHack') then
  showMessage("AOB Scan for Infinite Magic not found!")
  error()
end
{$ASM}
itemHack:
db 90 90

[DISABLE]
itemHack:
db 2A C1
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>3</ID>
          <Description>"Edit Money"</Description>
          <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
          <Color>000000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$LUA}
if syntaxcheck then return end

local address = getAddressSafe('goldHack')
if not address then
  showMessage('AOB Scan for Edit Money not found!')
  error()
end

-- First two bytes are the instruction "mov eax, [ecx+..." last 4 bytes is the offset
local aob = readBytes(address + 0x02, 4, true)

local offset = ''
for i = 4, 1, -1 do
  offset = offset .. string.format('%02X', aob[i])
end

registerSymbol('goldHackOffset', offset)
{$ASM}

alloc(newmem,256)
label(returnhere)
label(originalcode)
label(exit)

alloc(pMoney, 8)
registersymbol(pMoney)

newmem:
mov [pMoney], ecx
add [pMoney], goldHackOffset

originalcode:
mov eax,[ecx+goldHackOffset]

exit:
jmp returnhere

goldHack:
jmp newmem
nop
returnhere:




[DISABLE]
dealloc(newmem)
dealloc(pMoney)
unregistersymbol(pMoney)
goldHack:
mov eax,[ecx+goldHackOffset]

unregistersymbol(goldHackOffset)
</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>4</ID>
              <Description>"Money"</Description>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>000000</Color>
              <VariableType>4 Bytes</VariableType>
              <Address>pMoney</Address>
              <Offsets>
                <Offset>0</Offset>
              </Offsets>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
  <DisassemblerComments>
    <DisassemblerComment>
      <Address>"ShovelKnight.exe"+23A4E</Address>
      <Comment>X Coordinate
</Comment>
    </DisassemblerComment>
  </DisassemblerComments>
</CheatTable>
