<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="40">
  <CheatEntries>

    <!-- == tint-cheats community: free, open-source CE tables (no paywalls, no malware, no surveys) == -->
    <CheatEntry>
      <ID>900</ID>
      <Description>tint-cheats  -  free, open-source CE tables  -  no paywalls, no malware, no surveys</Description>
      <Color>1E90FF</Color>
      <GroupHeader>1</GroupHeader>
      <Options moHideChildren="0"/>
      <CheatEntries>
        <CheatEntry>
          <ID>901</ID>
          <Description>[ Open ]  Official site and free downloads  (thereisnotime.github.io/tint-cheats)</Description>
          <Color>1E90FF</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{$LUA}
if syntaxcheck then return end
[ENABLE]
shellExecute([[https://thereisnotime.github.io/tint-cheats]])
local mr = memrec
if mr then synchronize(function() mr.Active = false end) end
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>902</ID>
          <Description>[ Open ]  Join the Telegram group</Description>
          <Color>26A5E4</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{$LUA}
if syntaxcheck then return end
[ENABLE]
shellExecute([[https://t.me/+xgtzaZBrKRA2OWI8]])
local mr = memrec
if mr then synchronize(function() mr.Active = false end) end
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>903</ID>
          <Description>[ Open ]  Join the Matrix room</Description>
          <Color>00A86B</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{$LUA}
if syntaxcheck then return end
[ENABLE]
shellExecute([[https://matrix.to/#/!GkVomrhlzPROGFzueG:matrix.org?via=matrix.org]])
local mr = memrec
if mr then synchronize(function() mr.Active = false end) end
[DISABLE]
</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>

    <!-- ===================== separator: header / cheats ===================== -->
    <CheatEntry>
      <ID>904</ID>
      <Description>=========================================================================</Description>
      <Color>404040</Color>
      <GroupHeader>1</GroupHeader>
      <Options moHideChildren="0"/>
    </CheatEntry>

    <!-- ── Group header ──────────────────────────────────────────────── -->
    <CheatEntry>
      <ID>1</ID>
      <Description>Fatekeeper Trainer v1.1.1  by TINT</Description>
      <Color>808080</Color>
      <GroupHeader>1</GroupHeader>
      <Options moHideChildren="0" moDeactivateChildrenAsWell="1"/>
    </CheatEntry>

    <!--
      Shared resource hook  (God Mode + Unlimited Mana on ONE instruction)

        AOB (unique, 1 match):  F3 0F 11 76 34 E8 ?? ?? ?? ?? 48 8B F8
        Hooked instruction:     movss [rsi+34],xmm6   (generic "current value" store)
        rsi    = a resource object (shared base class, vtable SLASHER+8E4A420)
        rsi+30 = max value (float)        rsi+34 = current value (float)
        rsi+378 = health-component flag:  != 0 -> HEALTH (player/enemy),  == 0 -> non-health
                                          resource (MANA / stamina / etc.)

      The same instruction writes health on the pawn AND mana on the mana object;
      they are distinguished only by [rsi+378].  So both cheats must share one hook.

        fkFlags+0 (dword) = God Mode      : if set, force HEALTH (rsi+378!=0) to 999
        fkFlags+4 (dword) = Unlimited Mana: if set, and the object is the MANA
                                            attribute (type id @ +8 == 0x1C927),
                                            force current(rsi+34) = max(rsi+30).

      The +8 id matters: rsi+378==0 covers ~2600 non-health attributes (rates,
      resists, multipliers); maxing all of them is wrong, so we match only Mana's
      type id.  These attribute objects share vtable SLASHER+8E4A420; their type id
      sits at +8 (e.g. Mana=1C927, found by enumerating the class and comparing).

      Zero-regen note: the hook acts on the game's writes, so it can't raise mana
      from empty if nothing writes it.  F2's enable script kickstarts every Mana
      object to its max once; the hook holds it thereafter.

      F1 / F2 just flip those flag dwords; either one auto-installs the shared hook
      (the "[ Core ]" record).  Found via debugger "find what writes" on the live
      mana address -> it resolved to this exact God Mode instruction.

      Why AOB: the original qteeq offset +5E187A0 died on a patch; AOB now lands at
      +5E1A140.  aobscanmodule re-locates it every enable, self-healing across updates.
    -->
    <CheatEntry>
      <ID>3</ID>
      <Description>[ Core ]  Cheat hook  (shared)</Description>
      <Color>808080</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
aobscanmodule(fkHP,SLASHER-Win64-Shipping.exe,F3 0F 11 76 34 E8 ?? ?? ?? ?? 48 8B F8)
alloc(newmem,$1000,fkHP)
alloc(fkFlags,8,fkHP)

registersymbol(fkHP)
registersymbol(fkFlags)

label(orig)
label(return)
label(nonhealth)

newmem:
  cmp dword ptr [rsi+378],0
  je nonhealth
  // health-bearing object -> God Mode
  cmp dword ptr [fkFlags],0
  je orig
  mov dword ptr [rsi+34],(float)999.0
  jmp return
nonhealth:
  // non-health resource -> Unlimited Mana, but ONLY the Mana attribute.
  // Each attribute object carries a type id at +8; Mana == 0x1C927.
  // (Without this, EVERY non-health attribute -- ~2600 rates/resists/etc -- gets maxed.)
  cmp dword ptr [fkFlags+4],0
  je orig
  cmp dword ptr [rsi+08],1C927
  jne orig
  push rax
  mov eax,[rsi+30]
  mov [rsi+34],eax
  pop rax
  jmp return
orig:
  movss [rsi+34],xmm6
  jmp return

fkHP:
  jmp newmem
return:

[DISABLE]
fkHP:
  db F3 0F 11 76 34
  // movss [rsi+34],xmm6   (original)

unregistersymbol(fkHP)
unregistersymbol(fkFlags)
dealloc(newmem)
dealloc(fkFlags)
</AssemblerScript>
    </CheatEntry>

    <!-- ── F1: God Mode (flag bit) ──────────────────────────────────── -->
    <CheatEntry>
      <ID>2</ID>
      <Description>[ F1 ]  God Mode</Description>
      <Color>00FF80</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <Hotkeys>
        <Hotkey>
          <Action>Toggle</Action>
          <Keys>112</Keys>
          <ActivateSound>Activate</ActivateSound>
          <DeactivateSound>Deactivate</DeactivateSound>
        </Hotkey>
      </Hotkeys>
      <AssemblerScript>{$LUA}
if syntaxcheck then return end
[ENABLE]
-- make sure the shared hook is installed
local al = getAddressList()
local core = al.getMemoryRecordByDescription("[ Core ]  Cheat hook  (shared)")
if core and not core.Active then synchronize(function() core.Active = true end); checkSynchronize(1500) end
if not pcall(function() writeInteger("fkFlags", 1) end) then
  reinitializeSymbolhandler()
  pcall(function() writeInteger("fkFlags", 1) end)
end
[DISABLE]
pcall(function() writeInteger("fkFlags", 0) end)
</AssemblerScript>
    </CheatEntry>

    <!-- ── F2: Unlimited Mana (flag bit) ────────────────────────────── -->
    <CheatEntry>
      <ID>4</ID>
      <Description>[ F2 ]  Unlimited Mana  (freeze at max)</Description>
      <Color>00C0FF</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <Hotkeys>
        <Hotkey>
          <Action>Toggle</Action>
          <Keys>113</Keys>
          <ActivateSound>Activate</ActivateSound>
          <DeactivateSound>Deactivate</DeactivateSound>
        </Hotkey>
      </Hotkeys>
      <AssemblerScript>{$LUA}
if syntaxcheck then return end
[ENABLE]
-- make sure the shared hook is installed
local al = getAddressList()
local core = al.getMemoryRecordByDescription("[ Core ]  Cheat hook  (shared)")
if core and not core.Active then synchronize(function() core.Active = true end); checkSynchronize(1500) end
if not pcall(function() writeInteger("fkFlags+4", 1) end) then
  reinitializeSymbolhandler()
  pcall(function() writeInteger("fkFlags+4", 1) end)
end
-- Kickstart: with zero regen the write-hook can't lift mana from empty, so set
-- every existing Mana attribute (type id @ +8 == 0x1C927) to its max once; the
-- hook then holds it there through every cast.
pcall(function()
  local mod = getAddress("SLASHER-Win64-Shipping.exe")
  if not mod or mod == 0 then return end
  local VT = mod + 0x8E4A420                 -- shared resource-object vtable
  local ms = createMemScan()
  ms.firstScan(soExactValue, vtQword, rtRounded, string.format("%d", VT), "",
               0, 0x7fffffffffff, "+W-C", fsmAligned, "4", false, false, false, false)
  ms.waitTillDone()
  local fl = createFoundList(ms); fl.initialize()
  for i = 0, fl.Count - 1 do
    local b = tonumber(fl.getAddress(i), 16)
    if b and readInteger(b + 0x08, false) == 0x1C927 then
      writeInteger(b + 0x34, readInteger(b + 0x30, false))   -- cur = max
    end
  end
  fl.destroy(); ms.destroy()
end)
[DISABLE]
pcall(function() writeInteger("fkFlags+4", 0) end)
</AssemblerScript>
    </CheatEntry>

    <!-- ===================== separator: footer ===================== -->
    <CheatEntry>
      <ID>998</ID>
      <Description>=========================================================================</Description>
      <Color>404040</Color>
      <GroupHeader>1</GroupHeader>
      <Options moHideChildren="0"/>
    </CheatEntry>

    <!-- ── F12: Disable All (always last) ───────────────────────────── -->
    <CheatEntry>
      <ID>99</ID>
      <Description>[ F12 ]  Disable All Cheats</Description>
      <Color>808080</Color>
      <VariableType>Auto Assembler Script</VariableType>
      <Hotkeys>
        <Hotkey>
          <Action>Toggle</Action>
          <Keys>123</Keys>
          <ActivateSound>Deactivate</ActivateSound>
        </Hotkey>
      </Hotkeys>
      <AssemblerScript>{$LUA}
if syntaxcheck then return end

[ENABLE]
local al = getAddressList()
for i = 0, al.Count - 1 do
  local mr = al.getMemoryRecord(i)
  pcall(function()
    if mr and not mr.isGroupHeader then mr.Active = false end
  end)
end
MainForm.Caption = "Fatekeeper Trainer v1.1.1  [ALL CHEATS OFF]"

[DISABLE]
</AssemblerScript>
    </CheatEntry>

  </CheatEntries>

  <LuaScript>
--[[ Fatekeeper Trainer v1.1.1  by TINT
     Game version: current Steam build (AOB-based, version independent)
     Process: SLASHER-Win64-Shipping.exe

     Hotkeys:
       F1  -- God Mode            (force health to 999)
       F2  -- Unlimited Mana      (freeze mana/non-health resources at max)
       F12 -- Disable All (panic key)

     Mechanisms:
       - Auto-attaches on load; polls every 2s until game runs.
       - Disables all active cheats when game process exits.
       - Title bar shows attach status.

     Shared hook  (one instruction does health AND mana):
       aobscanmodule on  F3 0F 11 76 34 E8 ?? ?? ?? ?? 48 8B F8
       = movss [rsi+34],xmm6   (generic current-value store; rsi = resource object)
       rsi+30 = max,  rsi+34 = current,  rsi+378 = health flag (!=0 health / ==0 mana)
       God Mode  -> rsi+378!=0 : current = 999
       Unlim Mana-> rsi+378==0 : current = max   (pinned full)
       fkFlags+0 = God Mode on/off,  fkFlags+4 = Unlimited Mana on/off
       F1/F2 flip those flags and auto-install the "[ Core ]" hook on demand.
       Original qteeq offset +5E187A0 died on a patch; AOB now lands at +5E1A140.
]]

local FK_PROC = "SLASHER-Win64-Shipping.exe"
local _FK_attached = false
local _FK_pid      = 0

local function FK_disableAll()
  local al = getAddressList()
  for i = 0, al.Count - 1 do
    local mr = al.getMemoryRecord(i)
    pcall(function()
      if mr and not mr.isGroupHeader then mr.Active = false end
    end)
  end
end

local _FK_watchTimer = createTimer(nil, false)
_FK_watchTimer.Interval = 2000
_FK_watchTimer.OnTimer = function()
  local pid = getProcessIDFromProcessName(FK_PROC)
  if pid and pid ~= 0 then
    if not _FK_attached or _FK_pid ~= pid then
      if _FK_attached then FK_disableAll() end
      openProcess(pid)
      _FK_attached = true
      _FK_pid      = pid
      MainForm.Caption = "Fatekeeper Trainer v1.1.1  [ATTACHED pid=" .. pid .. "]"
    end
  else
    if _FK_attached then
      FK_disableAll()
      _FK_attached = false
      _FK_pid      = 0
      MainForm.Caption = "Fatekeeper Trainer v1.1.1  [WAITING FOR GAME...]"
    end
  end
end
_FK_watchTimer.Enabled = true

local _pid0 = getProcessIDFromProcessName(FK_PROC)
if _pid0 and _pid0 ~= 0 then
  openProcess(_pid0)
  _FK_attached = true
  _FK_pid      = _pid0
  MainForm.Caption = "Fatekeeper Trainer v1.1.1  [ATTACHED pid=" .. _pid0 .. "]"
else
  MainForm.Caption = "Fatekeeper Trainer v1.1.1  [WAITING FOR GAME...]"
end
  </LuaScript>
  <UserdefinedSymbols/>
</CheatTable>
