<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="46">
  <CheatEntries>
    <CheatEntry>
      <ID>34</ID>
      <Description>"Toggle Compact View"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

if not toggleCompactView then
    function toggleCompactView(sender, forceEnable)
        local isCompactMode = not (compactViewMenuItem.Caption == 'Compact View Mode')
        if forceEnable ~= nil then
            isCompactMode = not forceEnable
        end

        synchronize(function()
            compactViewMenuItem.Caption = isCompactMode and 'Compact View Mode' or 'Full View Mode'
            getMainForm().Splitter1.Visible = isCompactMode
            getMainForm().Panel4.Visible    = isCompactMode
            getMainForm().Panel5.Visible    = isCompactMode
        end)
    end
end

if not createCompactViewMenu then
    function createCompactViewMenu()
        if isCompactMenuCreated then return end

        synchronize(function()
            local mainMenu = getMainForm().Menu.Items
            compactViewMenuItem = createMenuItem(mainMenu)
            compactViewMenuItem.Caption = 'Compact View Mode'
            compactViewMenuItem.OnClick = toggleCompactView
            mainMenu.add(compactViewMenuItem)
        end)

        isCompactMenuCreated = true
    end
end

createCompactViewMenu()
toggleCompactView(nil, true)

[DISABLE]
{$lua}
if toggleCompactView then
    toggleCompactView(nil, false)
end
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>1</ID>
      <Description>"Get incoming (transport) resources"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-22
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_GET_RESOURCES,CrusaderDE.dll,8B 84 29 ?? ?? ?? 00 89 43 08 48 63 05 ?? ?? ?? ?? 48 69 C8 3C 58 00 00) // should be unique
alloc(newmem,$1000,INJECT_GET_RESOURCES)

alloc(INJECT_GET_RESOURCESo, 7)

label(code)
label(return)
label(i_res_offset i_res_addr)

INJECT_GET_RESOURCESo:
  readmem(INJECT_GET_RESOURCES, 7)

newmem:

code:
  //mov eax,[rcx+rbp+0012F098]
  db 8B 84 29
  readmem(INJECT_GET_RESOURCES+3, 4)

  push r15
  push r14
  xor r14, r14

  //mov r14d, ??????
  db 41 be
  readmem(INJECT_GET_RESOURCES+3, 4)

  mov [i_res_offset], r14

  lea r15, [rcx+rbp]
  lea r15, [r15+r14]
  mov [i_res_addr], r15

  pop r14
  pop r15


  jmp return
align 10 cc
  i_res_offset:
  dd 0
  dd 0
  i_res_addr:
  dq 0


INJECT_GET_RESOURCES:
  jmp newmem
  nop 2
return:
registersymbol(i_res_offset i_res_addr)
registersymbol(INJECT_GET_RESOURCES)
registersymbol(INJECT_GET_RESOURCESo)

[DISABLE]

INJECT_GET_RESOURCES:
  //db 8B 84 29 98 F0 12 00
  readmem(INJECT_GET_RESOURCESo, 7)

unregistersymbol(i_res_offset i_res_addr)
unregistersymbol(INJECT_GET_RESOURCES)
dealloc(newmem)
unregistersymbol(INJECT_GET_RESOURCESo)
dealloc(INJECT_GET_RESOURCESo)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+18D75B

CrusaderDE.dll+18D71A: 48 63 05 17 A1 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
CrusaderDE.dll+18D721: 48 69 C8 3C 58 00 00  - imul rcx,rax,0000583C
CrusaderDE.dll+18D728: 8B 84 29 94 F0 12 00  - mov eax,[rcx+rbp+0012F094]
CrusaderDE.dll+18D72F: 89 43 04              - mov [rbx+04],eax
CrusaderDE.dll+18D732: 48 63 05 FF A0 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
CrusaderDE.dll+18D739: 48 69 C8 3C 58 00 00  - imul rcx,rax,0000583C
CrusaderDE.dll+18D740: 8B 84 29 30 F0 12 00  - mov eax,[rcx+rbp+0012F030]
CrusaderDE.dll+18D747: 89 83 A0 05 00 00     - mov [rbx+000005A0],eax
CrusaderDE.dll+18D74D: 48 63 05 E4 A0 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
CrusaderDE.dll+18D754: 48 69 C8 3C 58 00 00  - imul rcx,rax,0000583C
// ---------- INJECTING HERE ----------
CrusaderDE.dll+18D75B: 8B 84 29 98 F0 12 00  - mov eax,[rcx+rbp+0012F098]
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+18D762: 89 43 08              - mov [rbx+08],eax
CrusaderDE.dll+18D765: 48 63 05 CC A0 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
CrusaderDE.dll+18D76C: 48 69 C8 3C 58 00 00  - imul rcx,rax,0000583C
CrusaderDE.dll+18D773: 8B 84 29 34 F0 12 00  - mov eax,[rcx+rbp+0012F034]
CrusaderDE.dll+18D77A: 89 83 A4 05 00 00     - mov [rbx+000005A4],eax
CrusaderDE.dll+18D780: 48 63 05 B1 A0 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
CrusaderDE.dll+18D787: 48 69 C8 3C 58 00 00  - imul rcx,rax,0000583C
CrusaderDE.dll+18D78E: 8B 84 29 9C F0 12 00  - mov eax,[rcx+rbp+0012F09C]
CrusaderDE.dll+18D795: 89 43 0C              - mov [rbx+0C],eax
CrusaderDE.dll+18D798: 48 63 05 99 A0 B7 07  - movsxd  rax,dword ptr [CrusaderDE.dll+7D07838]
}
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>14</ID>
          <Description>"Notice: incoming resources are on-the-fly."</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
        <CheatEntry>
          <ID>30</ID>
          <Description>"    Don't set to too high value when game started"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
        <CheatEntry>
          <ID>31</ID>
          <Description>"i.e. if you set wood to a high value, you will never get stone and iron"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
        <CheatEntry>
          <ID>17</ID>
          <Description>"incoming coins"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-30</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>2</ID>
          <Description>"incoming wood"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-64</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>4</ID>
          <Description>"incoming stone"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-5C</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>5</ID>
          <Description>"incoming iron"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-54</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>3</ID>
          <Description>"incoming Hops / 啤酒花"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-60</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>6</ID>
          <Description>"incoming asphalt / 瀝青"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-50</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>7</ID>
          <Description>"incoming wheat"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-48</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>8</ID>
          <Description>"incoming bread"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-44</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>29</ID>
          <Description>"incoming cheese"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-40</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>9</ID>
          <Description>"incoming meat"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-3C</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>10</ID>
          <Description>"incoming apple"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-38</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>11</ID>
          <Description>"incoming beer"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-34</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>12</ID>
          <Description>"incoming flour"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-2C</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>44</ID>
          <Description>"incoming bow"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-28</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>45</ID>
          <Description>"incoming crossbow"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-24</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>46</ID>
          <Description>"incoming spear"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-20</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>47</ID>
          <Description>"incoming halberd"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-1C</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>48</ID>
          <Description>"incoming hammer"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-18</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>49</ID>
          <Description>"incoming sword"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-14</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>50</ID>
          <Description>"incoming leather armor"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-10</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>51</ID>
          <Description>"incoming armor"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>-C</Offset>
          </Offsets>
        </CheatEntry>
        <CheatEntry>
          <ID>28</ID>
          <Description>"Coins"</Description>
          <ShowAsSigned>0</ShowAsSigned>
          <Color>FF8080</Color>
          <VariableType>4 Bytes</VariableType>
          <Address>i_res_addr</Address>
          <Offsets>
            <Offset>34</Offset>
          </Offsets>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>19</ID>
      <Description>"Set min granary resources amount"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-22
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_SET_GRANARY_RES,CrusaderDE.dll,42 8B 94 0F ?? ?? ?? 00 85 D2 0F 45 EA EB ??) // should be unique
alloc(newmem,$1000,INJECT_SET_GRANARY_RES)

alloc(INJECT_SET_GRANARY_RESo, 8)

label(code)
label(return)
label(i_base_gra_res_addr is_lock_gra_res)

INJECT_SET_GRANARY_RESo:
  readmem(INJECT_SET_GRANARY_RES, 8)

newmem:

code:
  //mov edx,[rdi+r9+0000015C]
  readmem(INJECT_SET_GRANARY_RES, 8)
  cmp dword ptr [rdi+r9+0000001C], 1
  jne code_end

  push r15
  push r14
  xor r14, r14
  db 41 be
  readmem(INJECT_SET_GRANARY_RES+4, 4)

  lea r15, [rdi+r9]
  lea r15, [r15+r14]
  mov [i_base_gra_res_addr], r15
  cmp dword ptr [is_lock_gra_res], 1
  jne endp
  cmp dword ptr [r15], 20
  jae @F
  mov dword ptr [r15], 20
@@:
  cmp dword ptr [r15+4], 20
  jae @F
  mov dword ptr [r15+4], 20
@@:
  cmp dword ptr [r15+8], 20
  jae @F
  mov dword ptr [r15+8], 20
@@:
  cmp dword ptr [r15+C], 20
  jae @F
  mov dword ptr [r15+C], 20
@@:

endp:
  pop r14
  pop r15

code_end:

  jmp return
align 10 cc
  i_base_gra_res_addr:
  dq 0
  is_lock_gra_res:
  dd 1

INJECT_SET_GRANARY_RES:
  jmp newmem
  nop 3
return:

registersymbol(i_base_gra_res_addr is_lock_gra_res)
registersymbol(INJECT_SET_GRANARY_RES)
registersymbol(INJECT_SET_GRANARY_RESo)

[DISABLE]

INJECT_SET_GRANARY_RES:
  //db 42 8B 94 0F 5C 01 00 00
  readmem(INJECT_SET_GRANARY_RESo, 8)

unregistersymbol(i_base_gra_res_addr is_lock_gra_res)
unregistersymbol(INJECT_SET_GRANARY_RES)
dealloc(newmem)
unregistersymbol(INJECT_SET_GRANARY_RESo)
dealloc(INJECT_SET_GRANARY_RESo)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+9DAAE

CrusaderDE.dll+9DA6D: 46 89 44 0F 58              - mov [rdi+r9+58],r8d
CrusaderDE.dll+9DA72: 4E 89 44 0F 70              - mov [rdi+r9+70],r8
CrusaderDE.dll+9DA77: 4E 89 44 0F 78              - mov [rdi+r9+78],r8
CrusaderDE.dll+9DA7C: 4E 89 84 0F 80 00 00 00     - mov [rdi+r9+00000080],r8
CrusaderDE.dll+9DA84: 4E 89 84 0F 88 00 00 00     - mov [rdi+r9+00000088],r8
CrusaderDE.dll+9DA8C: 49 69 C6 3C 58 00 00        - imul rax,r14,0000583C
CrusaderDE.dll+9DA93: 4E 89 84 0F 90 00 00 00     - mov [rdi+r9+00000090],r8
CrusaderDE.dll+9DA9B: 4E 89 84 0F 98 00 00 00     - mov [rdi+r9+00000098],r8
CrusaderDE.dll+9DAA3: 66 42 39 AC 38 40 0E 13 00  - cmp [rax+r15+00130E40],bp
CrusaderDE.dll+9DAAC: 75 0F                       - jne CrusaderDE.dll+9DABD
// ---------- INJECTING HERE ----------
CrusaderDE.dll+9DAAE: 42 8B 94 0F 5C 01 00 00     - mov edx,[rdi+r9+0000015C]
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+9DAB6: 85 D2                       - test edx,edx
CrusaderDE.dll+9DAB8: 0F 45 EA                    - cmovne ebp,edx
CrusaderDE.dll+9DABB: EB 02                       - jmp CrusaderDE.dll+9DABF
CrusaderDE.dll+9DABD: 8B D5                       - mov edx,ebp
CrusaderDE.dll+9DABF: 66 46 39 84 38 42 0E 13 00  - cmp [rax+r15+00130E42],r8w
CrusaderDE.dll+9DAC8: 75 10                       - jne CrusaderDE.dll+9DADA
CrusaderDE.dll+9DACA: 46 8B A4 0F 60 01 00 00     - mov r12d,[rdi+r9+00000160]
CrusaderDE.dll+9DAD2: 45 85 E4                    - test r12d,r12d
CrusaderDE.dll+9DAD5: 74 03                       - je CrusaderDE.dll+9DADA
CrusaderDE.dll+9DAD7: 41 03 EC                    - add ebp,r12d
}
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>25</ID>
      <Description>"When add res. to storage area: set min amount"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-22
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_ADD_RES_2_STORAGE_AREA,CrusaderDE.dll,8B 9C 81 34 01 00 00) // should be unique
alloc(newmem,$1000,INJECT_ADD_RES_2_STORAGE_AREA)

label(code)
label(return)

newmem:
  cmp dword ptr [rcx+rax*4+00000134], 40
  jae code
  mov dword ptr [rcx+rax*4+00000134], 40
  xor rdx, rdx

code:
  mov ebx,[rcx+rax*4+00000134]
  jmp return

INJECT_ADD_RES_2_STORAGE_AREA:
  jmp newmem
  nop 2
return:
registersymbol(INJECT_ADD_RES_2_STORAGE_AREA)

[DISABLE]

INJECT_ADD_RES_2_STORAGE_AREA:
  db 8B 9C 81 34 01 00 00

unregistersymbol(INJECT_ADD_RES_2_STORAGE_AREA)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+B1CB3

CrusaderDE.dll+B1C89: 44 2B C8              - sub r9d,eax
CrusaderDE.dll+B1C8C: 41 8B C1              - mov eax,r9d
CrusaderDE.dll+B1C8F: C3                    - ret
CrusaderDE.dll+B1C90: 48 89 5C 24 08        - mov [rsp+08],rbx
CrusaderDE.dll+B1C95: 4D 63 D8              - movsxd  r11,r8d
CrusaderDE.dll+B1C98: 4C 8D 81 38 01 00 00  - lea r8,[rcx+00000138]
CrusaderDE.dll+B1C9F: 4C 63 D2              - movsxd  r10,edx
CrusaderDE.dll+B1CA2: 49 69 C2 CB 00 00 00  - imul rax,r10,000000CB
CrusaderDE.dll+B1CA9: 49 69 D2 2C 03 00 00  - imul rdx,r10,0000032C
CrusaderDE.dll+B1CB0: 49 03 C3              - add rax,r11
// ---------- INJECTING HERE ----------
CrusaderDE.dll+B1CB3: 8B 9C 81 34 01 00 00  - mov ebx,[rcx+rax*4+00000134]
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+B1CBA: B8 01 00 00 00        - mov eax,00000001
CrusaderDE.dll+B1CBF: 4C 03 C2              - add r8,rdx
CrusaderDE.dll+B1CC2: 41 83 38 00           - cmp dword ptr [r8],00
CrusaderDE.dll+B1CC6: 74 05                 - je CrusaderDE.dll+B1CCD
CrusaderDE.dll+B1CC8: 49 3B C3              - cmp rax,r11
CrusaderDE.dll+B1CCB: 75 12                 - jne CrusaderDE.dll+B1CDF
CrusaderDE.dll+B1CCD: 48 FF C0              - inc rax
CrusaderDE.dll+B1CD0: 49 83 C0 04           - add r8,04
CrusaderDE.dll+B1CD4: 48 83 F8 19           - cmp rax,19
CrusaderDE.dll+B1CD8: 7C E8                 - jl CrusaderDE.dll+B1CC2
}
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>32</ID>
          <Description>"Not fully tested; may applied to enemy"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>26</ID>
      <Description>"Build: material no decrease (applied to enemy)"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-22
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_BUILD_MAT_NO_DEC,CrusaderDE.dll,2B D7 89 91 34 01 00 00) // should be unique
alloc(newmem,$1000,INJECT_BUILD_MAT_NO_DEC)

label(code)
label(return)

newmem:
  //cmp dword ptr [rcx+00000014], 1
  //jne code
  cmp edi, 0
  jl code
  jmp code1

code:
  sub edx,edi
code1:
  mov [rcx+00000134],edx
  jmp return

INJECT_BUILD_MAT_NO_DEC:
  jmp newmem
  nop 3
return:
registersymbol(INJECT_BUILD_MAT_NO_DEC)

[DISABLE]

INJECT_BUILD_MAT_NO_DEC:
  db 2B D7 89 91 34 01 00 00

unregistersymbol(INJECT_BUILD_MAT_NO_DEC)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+ACAB2

CrusaderDE.dll+ACA8F: 66 44 89 0B              - mov [rbx],r9w
CrusaderDE.dll+ACA93: 8B 91 34 01 00 00        - mov edx,[rcx+00000134]
CrusaderDE.dll+ACA99: C7 44 24 24 01 00 00 00  - mov [rsp+24],00000001
CrusaderDE.dll+ACAA1: 3B D7                    - cmp edx,edi
CrusaderDE.dll+ACAA3: 7C 2C                    - jl CrusaderDE.dll+ACAD1
CrusaderDE.dll+ACAA5: 45 85 ED                 - test r13d,r13d
CrusaderDE.dll+ACAA8: 74 08                    - je CrusaderDE.dll+ACAB2
CrusaderDE.dll+ACAAA: 66 89 3B                 - mov [rbx],di
CrusaderDE.dll+ACAAD: 41 8B F9                 - mov edi,r9d
CrusaderDE.dll+ACAB0: EB 59                    - jmp CrusaderDE.dll+ACB0B
// ---------- INJECTING HERE ----------
CrusaderDE.dll+ACAB2: 2B D7                    - sub edx,edi
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+ACAB4: 89 91 34 01 00 00        - mov [rcx+00000134],edx
CrusaderDE.dll+ACABA: 49 69 CE 0F 16 00 00     - imul rcx,r14,0000160F
CrusaderDE.dll+ACAC1: 49 03 C8                 - add rcx,r8
CrusaderDE.dll+ACAC4: 41 29 BC 8F 90 F0 12 00  - sub [r15+rcx*4+0012F090],edi
CrusaderDE.dll+ACACC: 41 8B F9                 - mov edi,r9d
CrusaderDE.dll+ACACF: EB 25                    - jmp CrusaderDE.dll+ACAF6
CrusaderDE.dll+ACAD1: 2B FA                    - sub edi,edx
CrusaderDE.dll+ACAD3: 45 85 ED                 - test r13d,r13d
CrusaderDE.dll+ACAD6: 74 05                    - je CrusaderDE.dll+ACADD
CrusaderDE.dll+ACAD8: 66 89 13                 - mov [rbx],dx
}
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>40</ID>
      <Description>"inf. catapult stone (engineer built)"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-24
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_INF_CATA_STONE2,CrusaderDE.dll,66 42 89 84 32 BA 09 00 00) // should be unique
alloc(newmem,$1000,INJECT_INF_CATA_STONE2)

label(code)
label(return)

newmem:
  cmp ax, #39
  jbe code
  mov ax, 64

code:
  mov [rdx+r14+000009BA],ax
  jmp return

INJECT_INF_CATA_STONE2:
  jmp newmem
  nop 4
return:
registersymbol(INJECT_INF_CATA_STONE2)

[DISABLE]

INJECT_INF_CATA_STONE2:
  db 66 42 89 84 32 BA 09 00 00

unregistersymbol(INJECT_INF_CATA_STONE2)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+14502E

CrusaderDE.dll+144FF0: 48 69 D0 90 04 00 00           - imul rdx,rax,00000490
CrusaderDE.dll+144FF7: 66 42 83 BC 32 F4 09 00 00 16  - cmp word ptr [rdx+r14+000009F4],16
CrusaderDE.dll+145001: 0F 84 01 01 00 00              - je CrusaderDE.dll+145108
CrusaderDE.dll+145007: 66 42 39 BC 32 08 0A 00 00     - cmp [rdx+r14+00000A08],di
CrusaderDE.dll+145010: 0F 85 F2 00 00 00              - jne CrusaderDE.dll+145108
CrusaderDE.dll+145016: 42 0F B7 84 32 BA 09 00 00     - movzx eax,word ptr [rdx+r14+000009BA]
CrusaderDE.dll+14501F: 66 85 C0                       - test ax,ax
CrusaderDE.dll+145022: 0F 8E A2 00 00 00              - jng CrusaderDE.dll+1450CA
CrusaderDE.dll+145028: 66 FF C8                       - dec ax
CrusaderDE.dll+14502B: 45 8B C4                       - mov r8d,r12d
// ---------- INJECTING HERE ----------
CrusaderDE.dll+14502E: 66 42 89 84 32 BA 09 00 00     - mov [rdx+r14+000009BA],ax
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+145037: 42 0F BF 8C 32 1A 07 00 00     - movsx ecx,word ptr [rdx+r14+0000071A]
CrusaderDE.dll+145040: 42 0F BF 84 32 18 07 00 00     - movsx eax,word ptr [rdx+r14+00000718]
CrusaderDE.dll+145049: 46 0F BF 8C 32 16 07 00 00     - movsx r9d,word ptr [rdx+r14+00000716]
CrusaderDE.dll+145052: 8B D6                          - mov edx,esi
CrusaderDE.dll+145054: 89 4C 24 28                    - mov [rsp+28],ecx
CrusaderDE.dll+145058: 49 8B CE                       - mov rcx,r14
CrusaderDE.dll+14505B: 89 44 24 20                    - mov [rsp+20],eax
CrusaderDE.dll+14505F: E8 9C 43 03 00                 - call CrusaderDE.dll+179400
CrusaderDE.dll+145064: 8B 35 FA 15 7C 00              - mov esi,[CrusaderDE.dll+906664]
CrusaderDE.dll+14506A: E9 F5 01 00 00                 - jmp CrusaderDE.dll+145264
}
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>41</ID>
          <Description>"# of stock must &gt; 40"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
        <CheatEntry>
          <ID>42</ID>
          <Description>"Apply to enemy if his stock &gt; 40"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>37</ID>
      <Description>"inf. trebuchet stone (engineer built)"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-24
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

aobscanmodule(INJECT_INF_CATA_STONE,CrusaderDE.dll,00 66 42 89 84 32 BA 09 00 00) // should be unique
alloc(newmem,$1000,INJECT_INF_CATA_STONE)

label(code)
label(return)

newmem:
  cmp ax, #39
  jbe code
  mov ax, 64

code:
  mov [rdx+r14+000009BA],ax
  jmp return

INJECT_INF_CATA_STONE+01:
  jmp newmem
  nop 4
return:
registersymbol(INJECT_INF_CATA_STONE)

[DISABLE]

INJECT_INF_CATA_STONE+01:
  db 66 42 89 84 32 BA 09 00 00

unregistersymbol(INJECT_INF_CATA_STONE)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+1461B1

CrusaderDE.dll+146170: 48 69 D0 90 04 00 00           - imul rdx,rax,00000490
CrusaderDE.dll+146177: 66 42 83 BC 32 F4 09 00 00 16  - cmp word ptr [rdx+r14+000009F4],16
CrusaderDE.dll+146181: 0F 84 0B 01 00 00              - je CrusaderDE.dll+146292
CrusaderDE.dll+146187: 66 42 39 B4 32 08 0A 00 00     - cmp [rdx+r14+00000A08],si
CrusaderDE.dll+146190: 0F 85 FC 00 00 00              - jne CrusaderDE.dll+146292
CrusaderDE.dll+146196: 42 0F B7 84 32 BA 09 00 00     - movzx eax,word ptr [rdx+r14+000009BA]
CrusaderDE.dll+14619F: 66 85 C0                       - test ax,ax
CrusaderDE.dll+1461A2: 0F 8E AC 00 00 00              - jng CrusaderDE.dll+146254
CrusaderDE.dll+1461A8: 66 FF C8                       - dec ax
CrusaderDE.dll+1461AB: 41 B8 03 00 00 00              - mov r8d,00000003
// ---------- INJECTING HERE ----------
CrusaderDE.dll+1461B1: 66 42 89 84 32 BA 09 00 00     - mov [rdx+r14+000009BA],ax
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+1461BA: 42 0F BF 8C 32 1A 07 00 00     - movsx ecx,word ptr [rdx+r14+0000071A]
CrusaderDE.dll+1461C3: 42 0F BF 84 32 18 07 00 00     - movsx eax,word ptr [rdx+r14+00000718]
CrusaderDE.dll+1461CC: 46 0F BF 8C 32 16 07 00 00     - movsx r9d,word ptr [rdx+r14+00000716]
CrusaderDE.dll+1461D5: 8B D5                          - mov edx,ebp
CrusaderDE.dll+1461D7: 89 4C 24 28                    - mov [rsp+28],ecx
CrusaderDE.dll+1461DB: 4C 8D 35 2E 6E B1 05           - lea r14,[CrusaderDE.dll+5C5D010]
CrusaderDE.dll+1461E2: 49 8B CE                       - mov rcx,r14
CrusaderDE.dll+1461E5: 89 44 24 20                    - mov [rsp+20],eax
CrusaderDE.dll+1461E9: E8 12 32 03 00                 - call CrusaderDE.dll+179400
CrusaderDE.dll+1461EE: 8B 2D 70 04 7C 00              - mov ebp,[CrusaderDE.dll+906664]
}
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>38</ID>
          <Description>"# of stock must &gt; 40"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
        <CheatEntry>
          <ID>43</ID>
          <Description>"Apply to enemy if his stock &gt; 40"</Description>
          <Color>8000FF</Color>
          <GroupHeader>1</GroupHeader>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>56</ID>
      <Description>"Lookout tower HP"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
{$asm}
// asm code here
{$lua}
if syntaxcheck then return end
clearLuaLog()
local list = AOBScanModuleN("CrusaderDE.dll", "41 0F BF 84 2A 20 01 00 00", 2)

if list and list[1] then
    unregisterSymbol("INJECT_WATCH_TOWER")
    registerSymbol("INJECT_WATCH_TOWER", list[1])
end


closeLuaEngine()
[DISABLE]
{$asm}
// asm code here
{$lua}
if syntaxcheck then return end
unregisterSymbol("INJECT_WATCH_TOWER")


closeLuaEngine()
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>57</ID>
          <Description>"Set lookout tower HP"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version:
  Date   : 2025-07-27
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

alloc(newmem,$1000,INJECT_WATCH_TOWER)

label(code)
label(return)

newmem:
  cmp dword ptr [r10+rbp+0000001C], 1
  jne to_enemy
  mov ax, [r10+rbp+00000122]
  mov [r10+rbp+00000120], ax
  jmp code

to_enemy:
  cmp word ptr [r10+rbp+00000120], 1
  jbe code
  mov word ptr [r10+rbp+00000120], 1


code:
  movsx eax,word ptr [r10+rbp+00000120]
  jmp return

INJECT_WATCH_TOWER:
  jmp newmem
  nop 4
return:


[DISABLE]

INJECT_WATCH_TOWER:
  db 41 0F BF 84 2A 20 01 00 00


dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+A43F6

CrusaderDE.dll+A43C2: 48 63 C7                    - movsxd  rax,edi
CrusaderDE.dll+A43C5: 48 69 C8 2C 03 00 00        - imul rcx,rax,0000032C
CrusaderDE.dll+A43CC: C7 44 29 58 89 00 00 00     - mov [rcx+rbp+58],00000089
CrusaderDE.dll+A43D4: 44 89 6C 29 30              - mov [rcx+rbp+30],r13d
CrusaderDE.dll+A43D9: 48 63 C7                    - movsxd  rax,edi
CrusaderDE.dll+A43DC: 0F 57 C0                    - xorps xmm0,xmm0
CrusaderDE.dll+A43DF: 4C 69 D0 2C 03 00 00        - imul r10,rax,0000032C
CrusaderDE.dll+A43E6: 0F 11 44 24 20              - movups [rsp+20],xmm0
CrusaderDE.dll+A43EB: 0F 11 44 24 30              - movups [rsp+30],xmm0
CrusaderDE.dll+A43F0: 41 B9 09 00 00 00           - mov r9d,00000009
// ---------- INJECTING HERE ----------
CrusaderDE.dll+A43F6: 41 0F BF 84 2A 20 01 00 00  - movsx eax,word ptr [r10+rbp+00000120]
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+A43FF: 41 0F BF 8C 2A 22 01 00 00  - movsx ecx,word ptr [r10+rbp+00000122]
CrusaderDE.dll+A4408: 8D 04 C0                    - lea eax,[rax+rax*8]
CrusaderDE.dll+A440B: 99                          - cdq
CrusaderDE.dll+A440C: F7 F9                       - idiv ecx
CrusaderDE.dll+A440E: 44 2B C8                    - sub r9d,eax
CrusaderDE.dll+A4411: 41 83 F9 08                 - cmp r9d,08
CrusaderDE.dll+A4415: 7E 08                       - jle CrusaderDE.dll+A441F
CrusaderDE.dll+A4417: 41 B9 08 00 00 00           - mov r9d,00000008
CrusaderDE.dll+A441D: EB 0B                       - jmp CrusaderDE.dll+A442A
CrusaderDE.dll+A441F: 45 85 C9                    - test r9d,r9d
}

</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>53</ID>
      <Description>"Towers HP"</Description>
      <Options moHideChildren="1" moDeactivateChildrenAsWell="1"/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
{$asm}
// asm code here
{$lua}
if syntaxcheck then return end
clearLuaLog()
local list = AOBScanModuleN("CrusaderDE.dll", "41 0F BF 84 32 20 01 00 00", 3)

if list and list[3] then
    unregisterSymbol("INJECT_ROUND_TOWER")
    registerSymbol("INJECT_ROUND_TOWER", list[3])
end

if list and list[2] then
    unregisterSymbol("INJECT_DEFENSE_TOWER")
    registerSymbol("INJECT_DEFENSE_TOWER", list[2])
end

if list and list[1] then
    unregisterSymbol("INJECT_PERIMETER_TOWER")
    registerSymbol("INJECT_PERIMETER_TOWER", list[1])
end


closeLuaEngine()
[DISABLE]
{$asm}
// asm code here
{$lua}
if syntaxcheck then return end
unregisterSymbol("INJECT_ROUND_TOWER")
unregisterSymbol("INJECT_PERIMETER_TOWER")
unregisterSymbol("INJECT_DEFENSE_TOWER")
closeLuaEngine()
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>54</ID>
          <Description>"Set round tower HP"</Description>
          <Options moHideChildren="1"/>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-27
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

alloc(newmem,$1000,INJECT_ROUND_TOWER)

label(code)
label(return is_set_enemy_rtower_hp)

newmem:
  cmp dword ptr [r10+rsi+0000001C], 1
  jne to_enemy
  mov ax, [r10+rsi+00000122]
  mov [r10+rsi+00000120], ax
  jmp code

to_enemy:
  cmp dword ptr [is_set_enemy_rtower_hp], 1
  jne code
  cmp word ptr [r10+rsi+00000120], 2
  jbe code
  mov word ptr [r10+rsi+00000120], 2

code:
  movsx eax,word ptr [r10+rsi+00000120]
  jmp return
align 10 cc
  is_set_enemy_rtower_hp:
  dd 1

registersymbol(is_set_enemy_rtower_hp)

INJECT_ROUND_TOWER:
  jmp newmem
  nop 4
return:

[DISABLE]

INJECT_ROUND_TOWER:
  db 41 0F BF 84 32 20 01 00 00

unregistersymbol(is_set_enemy_rtower_hp)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: CrusaderDE.dll+A51D1

CrusaderDE.dll+A519E: 48 63 C3                    - movsxd  rax,ebx
CrusaderDE.dll+A51A1: 48 69 C8 2C 03 00 00        - imul rcx,rax,0000032C
CrusaderDE.dll+A51A8: C7 44 31 58 5A 00 00 00     - mov [rcx+rsi+58],0000005A
CrusaderDE.dll+A51B0: 89 7C 31 30                 - mov [rcx+rsi+30],edi
CrusaderDE.dll+A51B4: 48 63 C3                    - movsxd  rax,ebx
CrusaderDE.dll+A51B7: 0F 57 C0                    - xorps xmm0,xmm0
CrusaderDE.dll+A51BA: 4C 69 D0 2C 03 00 00        - imul r10,rax,0000032C
CrusaderDE.dll+A51C1: 0F 11 44 24 20              - movups [rsp+20],xmm0
CrusaderDE.dll+A51C6: 0F 11 44 24 30              - movups [rsp+30],xmm0
CrusaderDE.dll+A51CB: 41 B9 09 00 00 00           - mov r9d,00000009
// ---------- INJECTING HERE ----------
CrusaderDE.dll+A51D1: 41 0F BF 84 32 20 01 00 00  - movsx eax,word ptr [r10+rsi+00000120]
// ---------- DONE INJECTING  ----------
CrusaderDE.dll+A51DA: 41 0F BF 8C 32 22 01 00 00  - movsx ecx,word ptr [r10+rsi+00000122]
CrusaderDE.dll+A51E3: 8D 04 C0                    - lea eax,[rax+rax*8]
CrusaderDE.dll+A51E6: 99                          - cdq 
CrusaderDE.dll+A51E7: F7 F9                       - idiv ecx
CrusaderDE.dll+A51E9: 44 2B C8                    - sub r9d,eax
CrusaderDE.dll+A51EC: 41 83 F9 08                 - cmp r9d,08
CrusaderDE.dll+A51F0: 7E 08                       - jle CrusaderDE.dll+A51FA
CrusaderDE.dll+A51F2: 41 B9 08 00 00 00           - mov r9d,00000008
CrusaderDE.dll+A51F8: EB 0B                       - jmp CrusaderDE.dll+A5205
CrusaderDE.dll+A51FA: 45 85 C9                    - test r9d,r9d
}
</AssemblerScript>
          <CheatEntries>
            <CheatEntry>
              <ID>55</ID>
              <Description>"Also set enemy's"</Description>
              <DropDownList DisplayValueAsItem="1">0:No
1:Yes
</DropDownList>
              <ShowAsSigned>0</ShowAsSigned>
              <Color>C08000</Color>
              <VariableType>4 Bytes</VariableType>
              <Address>is_set_enemy_rtower_hp</Address>
            </CheatEntry>
          </CheatEntries>
        </CheatEntry>
        <CheatEntry>
          <ID>58</ID>
          <Description>"Set perimeter tower HP"</Description>
          <Options moHideChildren="1"/>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-27
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

alloc(newmem,$1000,INJECT_PERIMETER_TOWER)

label(code)
label(return)

newmem:
  cmp dword ptr [r10+rsi+0000001C], 1
  jne to_enemy
  mov ax, [r10+rsi+00000122]
  mov [r10+rsi+00000120], ax
  jmp code

to_enemy:
  cmp word ptr [r10+rsi+00000120], 1
  jbe code
  mov word ptr [r10+rsi+00000120], 1

code:
  movsx eax,word ptr [r10+rsi+00000120]
  jmp return
align 10 cc

INJECT_PERIMETER_TOWER:
  jmp newmem
  nop 4
return:

[DISABLE]

INJECT_PERIMETER_TOWER:
  db 41 0F BF 84 32 20 01 00 00

dealloc(newmem)

</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>60</ID>
          <Description>"Set defense tower HP"</Description>
          <Options moHideChildren="1"/>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>{ Game   : Stronghold Crusader Definitive Edition.exe
  Version: 
  Date   : 2025-07-27
  Author : bbfox@https://opencheattables.com
}

[ENABLE]

alloc(newmem,$1000,INJECT_DEFENSE_TOWER)

label(code)
label(return)

newmem:
  cmp dword ptr [r10+rsi+0000001C], 1
  jne to_enemy
  mov ax, [r10+rsi+00000122]
  mov [r10+rsi+00000120], ax
  jmp code

to_enemy:
  cmp word ptr [r10+rsi+00000120], 1
  jbe code
  mov word ptr [r10+rsi+00000120], 1

code:
  movsx eax,word ptr [r10+rsi+00000120]
  jmp return
align 10 cc

INJECT_DEFENSE_TOWER:
  jmp newmem
  nop 4
return:

[DISABLE]

INJECT_DEFENSE_TOWER:
  db 41 0F BF 84 32 20 01 00 00

dealloc(newmem)
</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>33</ID>
      <Description>"Stronghold Crusader: Definitive Edition  /  https://opencheattables.com"</Description>
      <Color>009700</Color>
      <GroupHeader>1</GroupHeader>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
  <LuaScript>

--[[
[ENABLE]
{$lua}
if syntaxcheck then return end
]]--
-- **デバッグモードの設定 (デフォルト: 無効)**
local debugMode = false

-- AOBScanModule関数
if not AOBScanModule then
    function AOBScanModule(moduleName, signature, scanOptions)
        local baseAddr = nil
        local maxAddr = 0
        local modList

        synchronize(function()
            modList = enumModules()
        end)

        for _, mod in ipairs(modList) do
            if string.lower(mod.Name) == string.lower(moduleName) then
                baseAddr = mod.Address
                maxAddr = baseAddr + mod.Size
                break
            end
        end

        if not baseAddr then
            if debugMode then print("❗ Error: Module " .. moduleName .. " not found!") end
            return nil
        end

        if debugMode then
            print(string.format("✔️ %s Base Address: 0x%X", moduleName, baseAddr))
            print(string.format("🔬 Scanning Range: 0x%X - 0x%X", baseAddr, maxAddr))
        end

        local ms = createMemScan()

        synchronize(function()
            ms.firstScan(
                soExactValue,
                vtByteArray,
                nil,
                signature,
                nil,
                baseAddr,
                maxAddr,
                scanOptions or "+X+R",
                fsmNotAligned,
                "1",
                true,
                true,
                false,
                false
            )
        end)

        ms.waitTillDone()

        local results = createFoundList(ms)
        results.initialize()

        local addr
        synchronize(function()
            if results.getCount() &gt; 0 then
                addr = results[0]
            end
        end)

        if addr then
            if debugMode then print("🔦 AOB found at: 0x" .. addr) end
        else
            if debugMode then print("💔 AOB not found in " .. moduleName) end
        end

        results.destroy()
        ms.destroy()
        return addr
    end
end

registerLuaFunctionHighlight('AOBScanModule')

--[[
test AOBScanModule()
local aob_addr_str = AOBScanModule("???.exe", "48 8B 05 ?? ?? ?? ?? 33 ED 48 8B 88", "+X+R")
if aob_addr_str then
    print("🔦 Final AOB Address: 0x" .. aob_addr_str)
else
    print("💔 AOB not found in ???.exe")
end
]]--

if not AOBScanModuleN then
    function AOBScanModuleN(moduleName, signature, maxResults, scanOptions)
        local baseAddr = nil
        local maxAddr = 0
        local modList

        synchronize(function()
            modList = enumModules()
        end)

        for _, mod in ipairs(modList) do
            if string.lower(mod.Name) == string.lower(moduleName) then
                baseAddr = mod.Address
                maxAddr = baseAddr + mod.Size
                break
            end
        end

        if not baseAddr then
            if debugMode then print("❗ Error: Module " .. moduleName .. " not found!") end
            return nil
        end

        if debugMode then
            print(string.format("✔️ %s Base Address: 0x%X", moduleName, baseAddr))
            print(string.format("🔬 Scanning Range: 0x%X - 0x%X", baseAddr, maxAddr))
        end

        local ms = createMemScan()

        synchronize(function()
            ms.firstScan(
                soExactValue,
                vtByteArray,
                nil,
                signature,
                nil,
                baseAddr,
                maxAddr,
                scanOptions or "+X+R",
                fsmNotAligned,
                "1",
                true,
                true,
                false,
                false
            )
        end)

        ms.waitTillDone()

        local results = createFoundList(ms)
        results.initialize()

        local addrs = {}
        synchronize(function()
            local count = results.getCount()
            for i = 0, math.min(maxResults - 1, count - 1) do
                table.insert(addrs, results[i])
                if debugMode then
                    print(string.format("🔦 AOB[%d] found at: 0x%s", i + 1, results[i]))
                end
            end
        end)

        if #addrs == 0 and debugMode then
            print("💔 AOB not found in " .. moduleName)
        end

        results.destroy()
        ms.destroy()

        return addrs
    end
end

registerLuaFunctionHighlight('AOBScanModuleN')


-- 搜尋並取出最多5筆結果
--[[
local list = AOBScanModuleN("GameModule.exe", "12 34 56 ?? 78", 5)

if list then
    for i, addr in ipairs(list) do
        print(string.format("地址 %d: 0x%s", i, addr))
    end
end
]]--


-- Lua scripts that table checkbox will not be checked with "NO_ACTIVATE" in comment/script body
if not onMemRecPostExecute then
    function onMemRecPostExecute(memoryrecord, newState, succeeded)
        if memoryrecord.Type == vtAutoAssembler and memoryrecord.Script:find("NO_ACTIVATE") and newState and succeeded then
            synchronize(function()
                memoryrecord.disableWithoutExecute()
            end)
        end
    end
end

-- Memory record IDs now allowed to be 'locked'
IDs = {999999, 9999999}

-- Determine event trigger sequence
if not contains then
    function contains(table, val)
       for i = 1, #table do
          if table[i] == val then
             return true
          end
       end
       return false
    end
end

if not onMemRecPreExecute then
    function onMemRecPreExecute(memoryrecord, newstate)
        if contains(IDs, memoryrecord.ID) and newstate then
            synchronize(function()
                if not memoryrecord.OnActivate then
                    memoryrecord.OnActivate = function(memoryrecord, before, currentstate)
                        return false
                    end
                end
            end)
        end
    end
end

-- Utility Functions
-- Clear lua engine log
if not clearLuaLog then
    function clearLuaLog()
        synchronize(function()
          getLuaEngine().MenuItem5.doClick()
        end)
    end
end
registerLuaFunctionHighlight('clearLuaLog')

-- Close lua engine log
if not closeLuaEngine then
    function closeLuaEngine()
        synchronize(function()
          getLuaEngine().Close()
        end)
    end
end
registerLuaFunctionHighlight('closeLuaEngine')

-- Clear lua engine log &amp; close lua engine
if not closeLuaEngine2 then
    function closeLuaEngine2()
        synchronize(function()
          getLuaEngine().MenuItem5.doClick()
          getLuaEngine().Close()
        end)
    end
end
registerLuaFunctionHighlight('closeLuaEngine2')

if not getProcessNameFromPID then
	function getProcessNameFromPID(pid)
	  local sl = createStringList()
	  getProcessList(sl)
	  local hexPid = string.format("%X", pid):upper()

	  for i = 0, sl.Count - 1 do
		local entry = sl[i]
		local hexid, name = entry:match("^(%x+)%-(.+)$")
		if hexid and name then
		  if tonumber(hexid, 16) == pid then
			return name
		  end
		end
	  end
	  return "(unknown)"
	end
end
registerLuaFunctionHighlight('getProcessNameFromPID')

if not printProcessInfo then
	function printProcessInfo()
	  local pid = getOpenedProcessID()
	  local name = getProcessNameFromPID(pid)
	  print(string.format("📎 Attached to process: %s (PID: %d / 0x%X)", name, pid, pid))
	end
end
registerLuaFunctionHighlight('printProcessInfo')

if not dumpProcessListAndFindPID then
	function dumpProcessListAndFindPID()
	  local pid = getOpenedProcessID()
	  print(string.format("💭 Current PID: %d / 0x%X", pid, pid))

	  local sl = createStringList()
	  getProcessList(sl)

	  print("🧾 Dumping process list:")
	  for i = 0, sl.Count - 1 do
		local entry = sl[i]
		print(string.format("[%d] %s", i, entry))

		-- 嘗試解析並比對 PID
		local name, hexid = entry:match("(.+)%-(%x+)$")
		if name and hexid then
		  local parsed = tonumber(hexid, 16)
		  if parsed == pid then
			print("🔦 Match found in process list:")
			print(string.format("Name: %s | PID: %s (0x%s)", name, parsed, hexid))
		  end
		end
	  end
	end
end
registerLuaFunctionHighlight('dumpProcessListAndFindPID')

if not toHex32 then
	function toHex32(num)
		local hexstr = "0123456789ABCDEF"
		local result = ""
		if num &lt; 0 then
			num = (num + (1 &lt;&lt; 32)) % (1 &lt;&lt; 32) -- 轉成32-bit補數
		end
		for i = 1, 8 do -- 32-bit 一共8個hex位
			local n = num &amp; 0xF -- 取最低4 bit
			result = hexstr:sub(n + 1, n + 1) .. result
			num = num &gt;&gt; 4 -- 右移4 bit
		end
		return result
	end
end
registerLuaFunctionHighlight('toHex32')

if not toHex then
	function toHex(num)
		local hexstr = "0123456789ABCDEF"
		local result = ""
		if num &lt; 0 then
			num = (num + (1 &lt;&lt; 64)) % (1 &lt;&lt; 64)  -- 轉成64-bit補數
		end
		for i = 1, 16 do -- 每4 bit 一個 hex字，64-bit總共16個hex位
			local n = num &amp; 0xF -- 取最低4bit
			result = hexstr:sub(n + 1, n + 1) .. result
			num = num &gt;&gt; 4 -- 右移4bit
		end
		return result
	end
end	
registerLuaFunctionHighlight('toHex')

synchronize(function() AddressList.Header.OnSectionClick = nil end)
--[[
[DISABLE]
{$lua}

if AOBScanModule then
    AOBScanModule = nil
end
if onMemRecPostExecute then
    onMemRecPostExecute = nil
end
if onMemRecPreExecute then
    onMemRecPreExecute = nil
end
if clearLuaLog then
    clearLuaLog = nil
end
if closeLuaEngine then
    closeLuaEngine = nil
end
if closeLuaEngine2 then
    closeLuaEngine2 = nil
end
]]--
</LuaScript>
</CheatTable>
