<?xml version='1.0' encoding='utf-8'?>
<CheatTable CheatEngineTableVersion="45">
  <CheatEntries>
    <CheatEntry>
      <ID>1</ID>
      <Description>"Auto-Attach and Version Check"</Description>
      <GroupHeader>1</GroupHeader>
    </CheatEntry>
    <CheatEntry>
      <ID>2</ID>
      <Description>"☕ Fuel the Cheats — Tip Katzy (Toggle to open my Ko-fi page)"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>3</ID>
      <Description>"How to use - Katzy"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>4</ID>
      <Description>"Clear All"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
    </CheatEntry>
    <CheatEntry>
      <ID>10</ID>
      <Description>"[MAIN] Command &amp; Conquer: Red Alert 3"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
      <Options moHideChildren="1" />
      <CheatEntries>
        <CheatEntry>
          <ID>11</ID>
          <Description>"Infinite Money"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>12</ID>
          <Description>"Infinite Power"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>13</ID>
          <Description>"Instant Build"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>18</ID>
          <Description>"Infinite Aircraft Ammo"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>15</ID>
          <Description>"Instant Superweapons, Support Powers and Unit Abilities"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>19</ID>
          <Description>"Invulnerability - Selected Units and Buildings"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>14</ID>
          <Description>"Maximum Commander Rank and 15 Power Points"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>30</ID>
          <Description>"Promote Selected Units - Maximum Veterancy (One Shot)"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
      <CheatEntry>
          <ID>17</ID>
          <Description>"Reveal Map - Full"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>16</ID>
          <Description>"Reveal Map - Visual Only"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        </CheatEntries>
    </CheatEntry>
    <CheatEntry>
      <ID>20</ID>
      <Description>"[MAIN] Command &amp; Conquer: Red Alert 3 - Uprising"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
      <Options moHideChildren="1" />
      <CheatEntries>
        <CheatEntry>
          <ID>21</ID>
          <Description>"Infinite Money"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>22</ID>
          <Description>"Infinite Power"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>23</ID>
          <Description>"Instant Build"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>28</ID>
          <Description>"Infinite Aircraft Ammo"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>25</ID>
          <Description>"Instant Superweapons, Support Powers and Unit Abilities"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>29</ID>
          <Description>"Invulnerability - Selected Units and Buildings"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>24</ID>
          <Description>"Maximum Commander Rank and 15 Power Points"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>40</ID>
          <Description>"Promote Selected Units - Maximum Veterancy (One Shot)"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
      <CheatEntry>
          <ID>27</ID>
          <Description>"Reveal Map - Full"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        <CheatEntry>
          <ID>26</ID>
          <Description>"Reveal Map - Visual Only"</Description>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
[DISABLE]
</AssemblerScript>
        </CheatEntry>
        </CheatEntries>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols />
  <LuaScript>--[[
Table identification: Katzy | Combined RA3 / Uprising v1.23
Original hooks derived from installed Steam executables, with separate layouts.
Installed static streams and RA3 Core5-12 overrides: relevant build costs &lt;=5000
in RA3; Uprising Giga-Fortress 6300; Red Alert button 10000 (EA manual).
Floors: 30000 in both games, explicitly requested by the user.
Money debits retain the actual charge while clamping remaining normal credits.
Do not save/load with temporary resource allowances enabled.
]]
if KatzyRA3 and KatzyRA3.shutdown()==false then
  showMessage('Resume the previous game so its options can finish turning off, then reload this table.')
  return
end
if KatzyRA3Scaffold then KatzyRA3Scaffold.stop(); KatzyRA3Scaffold=nil end
local S={installed={},choices={},stopping=false}
KatzyRA3=S
local configs={
ra3={module="ra3_1.13.game",version="1.13.0.0",hash="11cc17cf58ac14c31c11c9e843046da0",title="Red Alert 3",player=0x8F214C,logic=0x8E21A4,moneyVT=0x865010,energyVT=0x865120,selection=0x8e4bfc,modifierStore=0x8e2184,experience=0x3cc,owner=0x418,objectID=0xdc,modifier=0x36c,selectionHead=0x50,selectionCount=0x5c,scripts={controller=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_controller_hook,ra3_1.13.game,83 ec 2c 53 55 56 8b 35 a4 21 ce 00 85 f6 57 8b f9 89 7c 24 20 bd 01 00 00 00 74 12 81 c6 a0 01 00 00 83 3e 00 75 05 e8)
assert(ra_controller_hook,83 ec 2c 53 55)
alloc(ra_controller_code,0x800,ra_controller_hook)
alloc(ra_state,0x18200)
registersymbol(ra_state)
label(ctl_money_off)
label(ctl_remaining)
label(ctl_floor)
label(ctl_power)
label(ctl_delta)
label(ctl_reveal)
label(reveal_new)
label(reveal_check)
label(reveal_remove)
label(reveal_visual)
label(reveal_finish)
label(ctl_iron)
label(iron_due)
label(iron_each)
label(iron_find)
label(iron_found)
label(iron_check_record)
label(iron_record_loop)
label(iron_record_found)
label(iron_status)
label(iron_record_missing)
label(iron_reconcile_done)
label(iron_remove)
label(iron_failed)
label(iron_finish)
label(iron_lost)
label(iron_drop)
label(iron_next)
label(ctl_veterancy)
label(vet_each)
label(vet_find)
label(vet_found)
label(vet_next)
label(vet_finished)
label(ctl_rank)
label(ctl_rank_points)
label(ctl_rank_granted)
label(ctl_invalid)
label(ctl_done)
label(ra_controller_return)
registersymbol(ra_controller_hook)
ra_state:
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
ra_controller_code:
pushfd
pushad
cmp dword ptr [ra_state+0x1C],1
jne ctl_done
mov eax,[PLAYERGLOBAL]
test eax,eax
je ctl_invalid
mov eax,[eax+0x28]
cmp eax,[ra_state]
jne ctl_invalid
mov ebx,[LOGICGLOBAL]
test ebx,ebx
je ctl_invalid
cmp ebx,[ra_state+0x24]
jne ctl_invalid
mov edx,[ebx+0x50]
cmp edx,[ra_state+0x20]
jb ctl_invalid
mov [ra_state+0x20],edx
mov ebx,[eax+0xE4]
test ebx,ebx
je ctl_invalid
mov ebx,[ebx]
cmp ebx,[ra_state+4]
jne ctl_invalid
mov ecx,[eax+0x74]
cmp ecx,[ra_state+8]
jne ctl_invalid
mov edx,[ra_state+0xC]
cmp edx,[ra_state+0x10]
je ctl_floor
test edx,edx
je ctl_money_off
add dword ptr [ebx+4],ALLOWANCE
add dword ptr [ebx+8],ALLOWANCE
mov dword ptr [ra_state+0x10],1
jmp ctl_power
ctl_money_off:
mov edx,[ebx+4]
sub edx,ALLOWANCE
jnc ctl_remaining
xor edx,edx
ctl_remaining:
mov [ebx+4],edx
sub dword ptr [ebx+8],ALLOWANCE
mov dword ptr [ra_state+0x10],0
jmp ctl_power
ctl_floor:
test edx,edx
je ctl_power
cmp dword ptr [ebx+4],ALLOWANCE
jae ctl_power
mov dword ptr [ebx+4],ALLOWANCE
ctl_power:
xor edx,edx
cmp dword ptr [ra_state+0x14],0
je ctl_delta
mov edx,[ecx+8]
add edx,0x64
sub edx,[ecx+4]
add edx,[ra_state+0x18]
jns ctl_delta
xor edx,edx
ctl_delta:
mov eax,edx
sub edx,[ra_state+0x18]
je ctl_reveal
mov [ra_state+0x18],eax
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
push edx
call POWERADD
fxrstor [esp]
mov esp,ebp
jmp ctl_reveal
ctl_reveal:
mov esi,[SHROUDGLOBAL]
test esi,esi
je ctl_iron
mov esi,[esi+0x28]
test esi,esi
je ctl_iron
mov eax,[esi+0x44]
test eax,eax
je ctl_iron
cmp esi,[ra_state+0x88]
jne reveal_new
cmp eax,[ra_state+0x8C]
je reveal_check
reveal_new:
mov [ra_state+0x88],esi
mov [ra_state+0x8C],eax
mov dword ptr [ra_state+0x80],0
mov dword ptr [ra_state+0x84],0
reveal_check:
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
mov eax,[ra_state+0x3C]
cmp eax,[ra_state+0x80]
je reveal_visual
mov [ra_state+0x80],eax
mov edx,[ra_state]
push dword ptr [edx+0x20]
mov ecx,esi
test eax,eax
je reveal_remove
call REVEALADD
jmp reveal_visual
reveal_remove:
call REVEALOFF
reveal_visual:
mov eax,[ra_state+0x38]
cmp eax,[ra_state+0x84]
je reveal_finish
mov [ra_state+0x84],eax
mov ecx,esi
call REVEALREFRESH
reveal_finish:
fxrstor [esp]
mov esp,ebp
ctl_iron:
cmp dword ptr [ra_state+0xC4],0
je ctl_veterancy
mov eax,[LOGICGLOBAL]
mov eax,[eax+0x50]
mov edx,[ra_state+0xC0]
cmp edx,[ra_state+0xE8]
jne iron_due
cmp eax,[ra_state+0xE4]
jb ctl_veterancy
iron_due:
mov [ra_state+0xE8],edx
add eax,0xF
mov [ra_state+0xE4],eax
mov edi,ra_state+0x200
iron_each:
cmp dword ptr [edi],0
je iron_next
mov eax,[edi+4]
xor edx,edx
mov ebx,[LOGICGLOBAL]
mov ecx,[ebx+0xC4]
test ecx,ecx
je iron_lost
div ecx
mov ebx,[ebx+0xC0]
test ebx,ebx
je iron_lost
mov ebx,[ebx+edx*4]
mov ecx,0x10000
iron_find:
test ebx,ebx
je iron_lost
mov eax,[edi+4]
cmp [ebx],eax
je iron_found
mov ebx,[ebx+8]
dec ecx
jne iron_find
jmp iron_lost
iron_found:
mov esi,[ebx+4]
cmp esi,[edi]
jne iron_lost
mov eax,[esi+0x36C]
test eax,eax
je iron_lost
cmp byte ptr [eax+0xB4],0
jne iron_next
cmp eax,[edi+8]
je iron_check_record
cmp [eax+8],esi
jne iron_lost
mov [edi+8],eax
iron_check_record:
cmp dword ptr [edi+0xC],0
je iron_reconcile_done
mov ebx,[eax+0x28]
mov edx,[eax+0x2C]
cmp edx,ebx
jb iron_next
mov ecx,edx
sub ecx,ebx
cmp ecx,0x10000
ja iron_next
iron_record_loop:
cmp ebx,edx
jae iron_record_missing
cmp dword ptr [ebx],ra_state+0x100
je iron_record_found
add ebx,0x10
jmp iron_record_loop
iron_record_found:
cmp dword ptr [ra_state+0xC0],1
jne iron_reconcile_done
cmp dword ptr [ebx+4],0x3FFFFFFF
je iron_status
mov dword ptr [ebx+4],0x3FFFFFFF
iron_status:
test byte ptr [esi+0x9A],1
jne iron_reconcile_done
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
xor eax,eax
mov [esp+0x200],eax
mov [esp+0x204],eax
mov [esp+0x208],eax
mov [esp+0x20C],eax
mov [esp+0x210],eax
mov [esp+0x214],eax
mov dword ptr [esp+0x218],0x10000
lea eax,[esp+0x200]
push 1
push eax
mov ecx,esi
call IRONSTATUS
fxrstor [esp]
mov esp,ebp
jmp iron_reconcile_done
iron_record_missing:
mov dword ptr [edi+0xC],0
dec dword ptr [ra_state+0xD0]
iron_reconcile_done:
mov eax,[ra_state+0xC0]
cmp eax,[edi+0xC]
je iron_next
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
mov ecx,esi
test eax,eax
je iron_remove
push 0
push ra_state+0x100
call IRONADD
test al,al
je iron_failed
mov dword ptr [edi+0xC],1
inc dword ptr [ra_state+0xD0]
jmp iron_finish
iron_remove:
push ra_state+0x100
call IRONREMOVE
mov dword ptr [edi+0xC],0
dec dword ptr [ra_state+0xD0]
mov dword ptr [edi],0
jmp iron_finish
iron_failed:
inc dword ptr [ra_state+0xD4]
mov dword ptr [edi],0
iron_finish:
fxrstor [esp]
mov esp,ebp
jmp iron_next
iron_lost:
cmp dword ptr [edi+0xC],0
je iron_drop
dec dword ptr [ra_state+0xD0]
mov dword ptr [edi+0xC],0
iron_drop:
mov dword ptr [edi],0
iron_next:
add edi,0x10
mov eax,[ra_state+0xC4]
shl eax,4
add eax,ra_state+0x200
cmp edi,eax
jb iron_each
cmp dword ptr [ra_state+0xC0],0
jne ctl_veterancy
cmp dword ptr [ra_state+0xD0],0
jne ctl_veterancy
mov dword ptr [ra_state+0xC4],0
ctl_veterancy:
cmp dword ptr [ra_state+0xF0],0
je ctl_rank
mov ebp,8
vet_each:
mov eax,[ra_state+0xF4]
cmp eax,[ra_state+0xF0]
jae vet_finished
lea edi,[eax*8+ra_state+0x10200]
inc dword ptr [ra_state+0xF4]
mov eax,[edi+4]
xor edx,edx
mov ebx,[LOGICGLOBAL]
mov ecx,[ebx+0xC4]
test ecx,ecx
je vet_next
div ecx
mov ebx,[ebx+0xC0]
test ebx,ebx
je vet_next
mov ebx,[ebx+edx*4]
mov ecx,0x10000
vet_find:
test ebx,ebx
je vet_next
mov eax,[edi+4]
cmp [ebx],eax
je vet_found
mov ebx,[ebx+8]
dec ecx
jne vet_find
jmp vet_next
vet_found:
mov esi,[ebx+4]
cmp esi,[edi]
jne vet_next
mov eax,[ra_state]
cmp [esi+OWNER],eax
jne vet_next
mov ecx,[esi+EXPERIENCE]
test ecx,ecx
je vet_next
cmp [ecx+0x38],esi
jne vet_next
cmp dword ptr [ecx+0x3C],0
jne vet_next
push ebp
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
push 0
push 1
push 3
call VETERANCY
fxrstor [esp]
mov esp,ebp
pop ebp
vet_next:
dec ebp
jne vet_each
jmp ctl_rank
vet_finished:
mov dword ptr [ra_state+0xF0],0
mov dword ptr [ra_state+0xF4],0
jmp ctl_rank
ctl_rank:
cmp dword ptr [ra_state+0x2C],1
jne ctl_done
mov eax,[ra_state]
mov ecx,[eax+0x1320]
test ecx,ecx
je ctl_done
cmp dword ptr [ecx],TECHVT
jne ctl_done
cmp [ecx+0x28],eax
jne ctl_done
mov edx,[eax+0x10]
test edx,edx
je ctl_done
mov edx,[edx]
test edx,edx
je ctl_done
mov ebx,[edx+0xA8]
test ebx,ebx
je ctl_done
cmp ebx,0x40
ja ctl_done
mov eax,[ecx+0x30]
dec ebx
cmp eax,ebx
ja ctl_done
je ctl_rank_points
mov edx,[edx+0xAC]
test edx,edx
je ctl_done
mov edx,[edx+eax*4]
test edx,edx
je ctl_done
mov edx,[edx]
test edx,edx
je ctl_done
cmp dword ptr [edx+4],0
jle ctl_done
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
cvtsi2ss xmm0,dword ptr [edx+4]
maxss xmm0,dword ptr [ecx+0x2C]
movss [ecx+0x2C],xmm0
push 1
call RANKUP
fxrstor [esp]
mov esp,ebp
jmp ctl_done
ctl_rank_points:
cmp dword ptr [ra_state+0x30],1
je ctl_done
mov eax,0xF
sub eax,[ecx+0x34]
jle ctl_rank_granted
add [ecx+0x34],eax
add [ecx+0x40],eax
ctl_rank_granted:
mov dword ptr [ra_state+0x30],1
jmp ctl_done

ctl_invalid:
mov dword ptr [ra_state+0x1C],0
ctl_done:
popad
popfd
db 83 ec 2c 53 55
jmp ra_controller_return
ra_controller_hook:
jmp ra_controller_code
ra_controller_return:
[DISABLE]
ra_controller_hook:
db 83 ec 2c 53 55
unregistersymbol(ra_controller_hook)
dealloc(ra_controller_code)
unregistersymbol(ra_state)
dealloc(ra_state)
]==],money=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_money_hook,ra3_1.13.game,2b c7 89 46 04 8b 46 0c 8b 0d 4c 21 cf 00 8b 4c 81 30 89 44 24 0c 8b 84 24 cc 00 00 00 89 54 24 14 8b 94 24 d0 00 00 00)
assert(ra_money_hook,2b c7 89 46 04)
alloc(ra_money_code,0x800,ra_money_hook)
label(money_done)
label(ra_money_return)
registersymbol(ra_money_hook)
ra_money_code:
sub eax,edi
pushfd
push edx
cmp esi,[ra_state+4]
jne money_done
cmp dword ptr [ra_state+0x10],1
jne money_done
cmp dword ptr [ra_state+0x1C],1
jne money_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je money_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne money_done
mov edx,[LOGICGLOBAL]
test edx,edx
je money_done
cmp edx,[ra_state+0x24]
jne money_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb money_done
cmp eax,ALLOWANCE
jae money_done
mov eax,ALLOWANCE
money_done:
pop edx
popfd
mov [esi+4],eax
jmp ra_money_return
ra_money_hook:
jmp ra_money_code
ra_money_return:
[DISABLE]
ra_money_hook:
db 2b c7 89 46 04
unregistersymbol(ra_money_hook)
dealloc(ra_money_code)
]==],production=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_production_hook,ra3_1.13.game,57 8b f9 8b 47 08 85 c0 0f 84 87 00 00 00 8b 90 18 04 00 00 85 d2 74 7d 8b 4c 24 08 85 c9 74 75 56 8b 71 0c 83 ee 01 74)
assert(ra_production_hook,57 8b f9 8b 47 08)
alloc(ra_production_code,0x800,ra_production_hook)
label(build_normal)
label(ra_production_return)
registersymbol(ra_production_hook)
ra_production_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[ecx+8]
test edx,edx
je build_normal
mov edx,[edx+OWNER]
cmp edx,[ra_state]
jne build_normal
pop edx
popfd
mov eax,1
ret 4
build_normal:
pop edx
popfd
db 57 8b f9 8b 47 08
jmp ra_production_return
ra_production_hook:
jmp ra_production_code
nop 1
ra_production_return:
[DISABLE]
ra_production_hook:
db 57 8b f9 8b 47 08
unregistersymbol(ra_production_hook)
dealloc(ra_production_code)
]==],construction=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_construction_hook,ra3_1.13.game,8b 44 24 10 8b 54 24 0c 50 8b 44 24 0c 52 8b 54 24 0c 50 52 e8 c7 c9 ff ff db 05 10 85 cb 00 a1 10 85 cb 00 85 c0 7d 06)
assert(ra_construction_hook,8b 44 24 10 8b 54 24 0c)
alloc(ra_construction_code,0x800,ra_construction_hook)
label(build_normal)
label(ra_construction_return)
registersymbol(ra_construction_hook)
ra_construction_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[esp+0xC]
cmp edx,[ra_state]
jne build_normal
pop edx
popfd
mov eax,1
ret 0x10
build_normal:
pop edx
popfd
db 8b 44 24 10 8b 54 24 0c
jmp ra_construction_return
ra_construction_hook:
jmp ra_construction_code
nop 3
ra_construction_return:
[DISABLE]
ra_construction_hook:
db 8b 44 24 10 8b 54 24 0c
unregistersymbol(ra_construction_hook)
dealloc(ra_construction_code)
]==],unpack=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_unpack_hook,ra3_1.13.game,8b d1 85 d2 d9 6c 24 0c 89 54 24 14 89 4e 38 db 44 24 14 7d 06 d8 05 5c 06 bf 00 d8 4c 24 10 8b 15 a4 21 ce 00 8b 52 50)
assert(ra_unpack_hook,8b d1 85 d2 d9 6c 24 0c)
alloc(ra_unpack_code,0x800,ra_unpack_hook)
label(build_normal)
label(ra_unpack_return)
registersymbol(ra_unpack_hook)
ra_unpack_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[ebx+OWNER]
cmp edx,[ra_state]
jne build_normal
mov ecx,1
build_normal:
pop edx
popfd
db 8b d1 85 d2 d9 6c 24 0c
jmp ra_unpack_return
ra_unpack_hook:
jmp ra_unpack_code
nop 3
ra_unpack_return:
[DISABLE]
ra_unpack_hook:
db 8b d1 85 d2 d9 6c 24 0c
unregistersymbol(ra_unpack_hook)
dealloc(ra_unpack_code)
]==],superweapon=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_superweapon_hook,ra3_1.13.game,51 a1 a4 21 ce 00 80 b8 a5 00 00 00 00 56 8b f1 74 17 8b 4e f8 8b 91 90 00 00 00 c1 ea 14 f6 c2 01 75 06 80 7e 30 00 74)
assert(ra_superweapon_hook,51 a1 a4 21 ce 00)
alloc(ra_superweapon_code,0x800,ra_superweapon_hook)
label(super_shared_loop)
label(super_shared_ready)
label(super_local_timer)
label(super_done)
label(ra_superweapon_return)
registersymbol(ra_superweapon_hook)
ra_superweapon_code:
pushfd
pushad
cmp dword ptr [ra_state+0x34],1
jne super_done
cmp dword ptr [ra_state+0x1C],1
jne super_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je super_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne super_done
mov eax,[LOGICGLOBAL]
test eax,eax
je super_done
cmp eax,[ra_state+0x24]
jne super_done
mov eax,[eax+0x50]
cmp eax,[ra_state+0x20]
jb super_done
mov eax,[ecx-8]
test eax,eax
je super_done
cmp [eax+OWNER],edx
jne super_done
mov eax,[ecx-0xC]
test eax,eax
je super_done
mov eax,[eax+8]
test eax,eax
je super_done
mov eax,[eax+8]
test eax,eax
je super_done
test dword ptr [eax+0x1C],0x1000
je super_local_timer
mov eax,[eax]
test eax,eax
je super_done
mov eax,[eax+4]
lea ebx,[edx+0x218]
mov edi,[ebx]
mov esi,0x400
super_shared_loop:
test edi,edi
je super_done
cmp edi,ebx
je super_done
cmp [edi+8],eax
je super_shared_ready
mov edi,[edi]
dec esi
jne super_shared_loop
jmp super_done
super_shared_ready:
mov dword ptr [edi+0xC],0
super_local_timer:
mov dword ptr [ecx+0x20],0
super_done:
popad
popfd
db 51 a1 a4 21 ce 00
jmp ra_superweapon_return
ra_superweapon_hook:
jmp ra_superweapon_code
nop 1
ra_superweapon_return:
[DISABLE]
ra_superweapon_hook:
db 51 a1 a4 21 ce 00
unregistersymbol(ra_superweapon_hook)
dealloc(ra_superweapon_code)
]==],revealnotify=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_revealnotify_hook,ra3_1.13.game,83 ec 18 8b 54 24 20 b8 80 49 94 00 89 04 24 8b 44 24 1c 89 44 24 08 8b 44 24 24 89 44 24 10 33 c9 b8 01 00 00 00 84 05 18 74 cf 00 89 4c 24 04 89 54 24 0c 75 28 09 05 18 74 cf 00 b8 10 74 cf 00 68 70 aa bc 00 89 0d 0c 74 cf 00 a3 10 74 cf 00 a3 14 74 cf 00 e8 7a 80 b8 ff 83 c4 04 8d 0c 24 51 b9 0c 74 cf 00 e8 44 76 f4 ff 83 c4 18 c3 56 57 8b f9 8d 77 04 b8 01 00 00 00 84 05 18 74 cf 00 89 36 89 76 04 c7 07 00 d5 c6 00 75 31 09 05 18 74 cf 00 68 70 aa bc 00 c7 05 0c 74 cf 00)
assert(ra_revealnotify_hook,83 ec 18 8b 54 24 20)
alloc(ra_revealnotify_code,0x800,ra_revealnotify_hook)
label(notify_done)
label(ra_revealnotify_return)
registersymbol(ra_revealnotify_hook)
ra_revealnotify_code:
pushfd
push edx
cmp dword ptr [ra_state+0x38],1
jne notify_done
cmp dword ptr [ra_state+0x1C],1
jne notify_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je notify_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne notify_done
mov edx,[LOGICGLOBAL]
cmp edx,[ra_state+0x24]
jne notify_done
test edx,edx
je notify_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb notify_done
mov dword ptr [esp+0x14],1
notify_done:
pop edx
popfd
db 83 ec 18 8b 54 24 20
jmp ra_revealnotify_return
ra_revealnotify_hook:
jmp ra_revealnotify_code
nop 2
ra_revealnotify_return:
[DISABLE]
ra_revealnotify_hook:
db 83 ec 18 8b 54 24 20
unregistersymbol(ra_revealnotify_hook)
dealloc(ra_revealnotify_code)
]==],revealdraw=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_revealdraw_hook,ra3_1.13.game,8b f8 85 ff 89 44 24 1c 75 09 bf 04 00 00 00 89 7c 24 1c 83 ff 03 89 7c 24 28 0f 8c fd 00 00 00 8b ae 04 02 00 00 85 ed)
assert(ra_revealdraw_hook,8b f8 85 ff 89 44 24 1c)
alloc(ra_revealdraw_code,0x800,ra_revealdraw_hook)
label(draw_done)
label(ra_revealdraw_return)
registersymbol(ra_revealdraw_hook)
ra_revealdraw_code:
pushfd
push edx
cmp dword ptr [ra_state+0x38],1
jne draw_done
cmp dword ptr [ra_state+0x1C],1
jne draw_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je draw_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne draw_done
mov edx,[edx+0x20]
cmp edx,[esp+0x20]
jne draw_done
mov edx,[LOGICGLOBAL]
test edx,edx
je draw_done
cmp edx,[ra_state+0x24]
jne draw_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb draw_done
mov eax,1
draw_done:
pop edx
popfd
db 8b f8 85 ff 89 44 24 1c
jmp ra_revealdraw_return
ra_revealdraw_hook:
jmp ra_revealdraw_code
nop 3
ra_revealdraw_return:
[DISABLE]
ra_revealdraw_hook:
db 8b f8 85 ff 89 44 24 1c
unregistersymbol(ra_revealdraw_hook)
dealloc(ra_revealdraw_code)
]==],ammo=[==[[ENABLE]
define(PLAYERGLOBAL,ra3_1.13.game+0x8F214C)
define(LOGICGLOBAL,ra3_1.13.game+0x8E21A4)
define(POWERADD,ra3_1.13.game+0x4727A0)
define(TECHVT,ra3_1.13.game+0x865180)
define(RANKUP,ra3_1.13.game+0x47E5B0)
define(SHROUDGLOBAL,ra3_1.13.game+0x8EC450)
define(REVEALADD,ra3_1.13.game+0x733650)
define(REVEALOFF,ra3_1.13.game+0x7350D0)
define(REVEALREFRESH,ra3_1.13.game+0x732AD0)
define(IRONADD,ra3_1.13.game+0x307150)
define(IRONREMOVE,ra3_1.13.game+0x3072B0)
define(IRONSTATUS,ra3_1.13.game+0x351090)
define(VETERANCY,ra3_1.13.game+0x385600)
define(EXPERIENCE,0x3CC)
define(OWNER,0x418)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_ammo_hook,ra3_1.13.game,01 46 1c 01 46 24 01 46 2c 83 7e 2c 00 7f 3b 83 7f 04 00 74 26 83 46 28 01 8b 56 18 8b 4f 04 8b 46 14 8b 89 f4 00 00 00)
assert(ra_ammo_hook,01 46 1c 01 46 24)
alloc(ra_ammo_code,0x800,ra_ammo_hook)
label(ammo_normal)
label(ammo_burst)
label(ra_ammo_return)
registersymbol(ra_ammo_hook)
ra_ammo_code:
pushfd
push edx
cmp dword ptr [ra_state+0x90],1
jne ammo_normal
cmp dword ptr [ra_state+0x1C],1
jne ammo_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je ammo_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne ammo_normal
mov edx,[edi+4]
test edx,edx
je ammo_normal
push eax
mov eax,[ra_state]
cmp [edx+OWNER],eax
pop eax
jne ammo_normal
mov edx,[edx+4]
test edx,edx
je ammo_normal
test dword ptr [edx+0xC0],0x4000
je ammo_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je ammo_normal
cmp edx,[ra_state+0x24]
jne ammo_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb ammo_normal
pop edx
popfd
jmp ammo_burst
ammo_normal:
pop edx
popfd
add [esi+0x1C],eax
ammo_burst:
add [esi+0x24],eax
jmp ra_ammo_return
ra_ammo_hook:
jmp ra_ammo_code
nop 1
ra_ammo_return:
[DISABLE]
ra_ammo_hook:
db 01 46 1c 01 46 24
unregistersymbol(ra_ammo_hook)
dealloc(ra_ammo_code)
]==]},hookRvas={controller=0x121e90,money=0x47296e,production=0x31ddc0,construction=0x40c150,unpack=0x3201fc,superweapon=0x314ca0,revealnotify=0x54b9f0,revealdraw=0x16d290,ammo=0x3b9174}},
up={module="ra3ep1_1.1.game",version="1.1.0.0",hash="ea3bbf1ad1e31759f8d4d84c00f81eac",title="Uprising",player=0x905DD4,logic=0x8F5C18,moneyVT=0x875AB8,energyVT=0x875BC0,selection=0x8f8694,modifierStore=0x8f5bf8,experience=0x3dc,owner=0x428,objectID=0xe0,modifier=0x37c,selectionHead=0x54,selectionCount=0x60,scripts={controller=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_controller_hook,ra3ep1_1.1.game,83 ec 2c 53 55 56 8b 35 18 5c cf 00 85 f6 57 8b f9 89 7c 24 20 bd 01 00 00 00 74 12 81 c6 a0 01 00 00 83 3e 00 75 05 e8)
assert(ra_controller_hook,83 ec 2c 53 55)
alloc(ra_controller_code,0x800,ra_controller_hook)
alloc(ra_state,0x18200)
registersymbol(ra_state)
label(ctl_money_off)
label(ctl_remaining)
label(ctl_floor)
label(ctl_power)
label(ctl_delta)
label(ctl_reveal)
label(reveal_new)
label(reveal_check)
label(reveal_remove)
label(reveal_visual)
label(reveal_finish)
label(ctl_iron)
label(iron_due)
label(iron_each)
label(iron_find)
label(iron_found)
label(iron_check_record)
label(iron_record_loop)
label(iron_record_found)
label(iron_status)
label(iron_record_missing)
label(iron_reconcile_done)
label(iron_remove)
label(iron_failed)
label(iron_finish)
label(iron_lost)
label(iron_drop)
label(iron_next)
label(ctl_veterancy)
label(vet_each)
label(vet_find)
label(vet_found)
label(vet_next)
label(vet_finished)
label(ctl_rank)
label(ctl_rank_points)
label(ctl_rank_granted)
label(ctl_invalid)
label(ctl_done)
label(ra_controller_return)
registersymbol(ra_controller_hook)
ra_state:
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
ra_controller_code:
pushfd
pushad
cmp dword ptr [ra_state+0x1C],1
jne ctl_done
mov eax,[PLAYERGLOBAL]
test eax,eax
je ctl_invalid
mov eax,[eax+0x28]
cmp eax,[ra_state]
jne ctl_invalid
mov ebx,[LOGICGLOBAL]
test ebx,ebx
je ctl_invalid
cmp ebx,[ra_state+0x24]
jne ctl_invalid
mov edx,[ebx+0x50]
cmp edx,[ra_state+0x20]
jb ctl_invalid
mov [ra_state+0x20],edx
mov ebx,[eax+0xE4]
test ebx,ebx
je ctl_invalid
mov ebx,[ebx]
cmp ebx,[ra_state+4]
jne ctl_invalid
mov ecx,[eax+0x74]
cmp ecx,[ra_state+8]
jne ctl_invalid
mov edx,[ra_state+0xC]
cmp edx,[ra_state+0x10]
je ctl_floor
test edx,edx
je ctl_money_off
add dword ptr [ebx+4],ALLOWANCE
add dword ptr [ebx+8],ALLOWANCE
mov dword ptr [ra_state+0x10],1
jmp ctl_power
ctl_money_off:
mov edx,[ebx+4]
sub edx,ALLOWANCE
jnc ctl_remaining
xor edx,edx
ctl_remaining:
mov [ebx+4],edx
sub dword ptr [ebx+8],ALLOWANCE
mov dword ptr [ra_state+0x10],0
jmp ctl_power
ctl_floor:
test edx,edx
je ctl_power
cmp dword ptr [ebx+4],ALLOWANCE
jae ctl_power
mov dword ptr [ebx+4],ALLOWANCE
ctl_power:
xor edx,edx
cmp dword ptr [ra_state+0x14],0
je ctl_delta
mov edx,[ecx+8]
add edx,0x64
sub edx,[ecx+4]
add edx,[ra_state+0x18]
jns ctl_delta
xor edx,edx
ctl_delta:
mov eax,edx
sub edx,[ra_state+0x18]
je ctl_reveal
mov [ra_state+0x18],eax
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
push edx
call POWERADD
fxrstor [esp]
mov esp,ebp
jmp ctl_reveal
ctl_reveal:
mov esi,[SHROUDGLOBAL]
test esi,esi
je ctl_iron
mov esi,[esi+0x28]
test esi,esi
je ctl_iron
mov eax,[esi+0x44]
test eax,eax
je ctl_iron
cmp esi,[ra_state+0x88]
jne reveal_new
cmp eax,[ra_state+0x8C]
je reveal_check
reveal_new:
mov [ra_state+0x88],esi
mov [ra_state+0x8C],eax
mov dword ptr [ra_state+0x80],0
mov dword ptr [ra_state+0x84],0
reveal_check:
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
mov eax,[ra_state+0x3C]
cmp eax,[ra_state+0x80]
je reveal_visual
mov [ra_state+0x80],eax
mov edx,[ra_state]
push dword ptr [edx+0x20]
mov ecx,esi
test eax,eax
je reveal_remove
call REVEALADD
jmp reveal_visual
reveal_remove:
call REVEALOFF
reveal_visual:
mov eax,[ra_state+0x38]
cmp eax,[ra_state+0x84]
je reveal_finish
mov [ra_state+0x84],eax
mov ecx,esi
call REVEALREFRESH
reveal_finish:
fxrstor [esp]
mov esp,ebp
ctl_iron:
cmp dword ptr [ra_state+0xC4],0
je ctl_veterancy
mov eax,[LOGICGLOBAL]
mov eax,[eax+0x50]
mov edx,[ra_state+0xC0]
cmp edx,[ra_state+0xE8]
jne iron_due
cmp eax,[ra_state+0xE4]
jb ctl_veterancy
iron_due:
mov [ra_state+0xE8],edx
add eax,0xF
mov [ra_state+0xE4],eax
mov edi,ra_state+0x200
iron_each:
cmp dword ptr [edi],0
je iron_next
mov eax,[edi+4]
xor edx,edx
mov ebx,[LOGICGLOBAL]
mov ecx,[ebx+0xC4]
test ecx,ecx
je iron_lost
div ecx
mov ebx,[ebx+0xC0]
test ebx,ebx
je iron_lost
mov ebx,[ebx+edx*4]
mov ecx,0x10000
iron_find:
test ebx,ebx
je iron_lost
mov eax,[edi+4]
cmp [ebx],eax
je iron_found
mov ebx,[ebx+8]
dec ecx
jne iron_find
jmp iron_lost
iron_found:
mov esi,[ebx+4]
cmp esi,[edi]
jne iron_lost
mov eax,[esi+0x37C]
test eax,eax
je iron_lost
cmp byte ptr [eax+0xB8],0
jne iron_next
cmp eax,[edi+8]
je iron_check_record
cmp [eax+8],esi
jne iron_lost
mov [edi+8],eax
iron_check_record:
cmp dword ptr [edi+0xC],0
je iron_reconcile_done
mov ebx,[eax+0x24]
mov edx,[eax+0x28]
cmp edx,ebx
jb iron_next
mov ecx,edx
sub ecx,ebx
cmp ecx,0x10000
ja iron_next
iron_record_loop:
cmp ebx,edx
jae iron_record_missing
cmp dword ptr [ebx],ra_state+0x100
je iron_record_found
add ebx,0x10
jmp iron_record_loop
iron_record_found:
cmp dword ptr [ra_state+0xC0],1
jne iron_reconcile_done
cmp dword ptr [ebx+4],0x3FFFFFFF
je iron_status
mov dword ptr [ebx+4],0x3FFFFFFF
iron_status:
test byte ptr [esi+0x9A],1
jne iron_reconcile_done
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
xor eax,eax
mov [esp+0x200],eax
mov [esp+0x204],eax
mov [esp+0x208],eax
mov [esp+0x20C],eax
mov [esp+0x210],eax
mov [esp+0x214],eax
mov [esp+0x21C],eax
mov dword ptr [esp+0x218],0x10000
lea eax,[esp+0x200]
push 1
push eax
mov ecx,esi
call IRONSTATUS
fxrstor [esp]
mov esp,ebp
jmp iron_reconcile_done
iron_record_missing:
mov dword ptr [edi+0xC],0
dec dword ptr [ra_state+0xD0]
iron_reconcile_done:
mov eax,[ra_state+0xC0]
cmp eax,[edi+0xC]
je iron_next
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
mov ecx,esi
test eax,eax
je iron_remove
push 0
push ra_state+0x100
call IRONADD
test al,al
je iron_failed
mov dword ptr [edi+0xC],1
inc dword ptr [ra_state+0xD0]
jmp iron_finish
iron_remove:
push ra_state+0x100
call IRONREMOVE
mov dword ptr [edi+0xC],0
dec dword ptr [ra_state+0xD0]
mov dword ptr [edi],0
jmp iron_finish
iron_failed:
inc dword ptr [ra_state+0xD4]
mov dword ptr [edi],0
iron_finish:
fxrstor [esp]
mov esp,ebp
jmp iron_next
iron_lost:
cmp dword ptr [edi+0xC],0
je iron_drop
dec dword ptr [ra_state+0xD0]
mov dword ptr [edi+0xC],0
iron_drop:
mov dword ptr [edi],0
iron_next:
add edi,0x10
mov eax,[ra_state+0xC4]
shl eax,4
add eax,ra_state+0x200
cmp edi,eax
jb iron_each
cmp dword ptr [ra_state+0xC0],0
jne ctl_veterancy
cmp dword ptr [ra_state+0xD0],0
jne ctl_veterancy
mov dword ptr [ra_state+0xC4],0
ctl_veterancy:
cmp dword ptr [ra_state+0xF0],0
je ctl_rank
mov ebp,8
vet_each:
mov eax,[ra_state+0xF4]
cmp eax,[ra_state+0xF0]
jae vet_finished
lea edi,[eax*8+ra_state+0x10200]
inc dword ptr [ra_state+0xF4]
mov eax,[edi+4]
xor edx,edx
mov ebx,[LOGICGLOBAL]
mov ecx,[ebx+0xC4]
test ecx,ecx
je vet_next
div ecx
mov ebx,[ebx+0xC0]
test ebx,ebx
je vet_next
mov ebx,[ebx+edx*4]
mov ecx,0x10000
vet_find:
test ebx,ebx
je vet_next
mov eax,[edi+4]
cmp [ebx],eax
je vet_found
mov ebx,[ebx+8]
dec ecx
jne vet_find
jmp vet_next
vet_found:
mov esi,[ebx+4]
cmp esi,[edi]
jne vet_next
mov eax,[ra_state]
cmp [esi+OWNER],eax
jne vet_next
mov ecx,[esi+EXPERIENCE]
test ecx,ecx
je vet_next
cmp [ecx+0x38],esi
jne vet_next
cmp dword ptr [ecx+0x3C],0
jne vet_next
push ebp
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
push 0
push 1
push 3
call VETERANCY
fxrstor [esp]
mov esp,ebp
pop ebp
vet_next:
dec ebp
jne vet_each
jmp ctl_rank
vet_finished:
mov dword ptr [ra_state+0xF0],0
mov dword ptr [ra_state+0xF4],0
jmp ctl_rank
ctl_rank:
cmp dword ptr [ra_state+0x2C],1
jne ctl_done
mov eax,[ra_state]
mov ecx,[eax+0x1320]
test ecx,ecx
je ctl_done
cmp dword ptr [ecx],TECHVT
jne ctl_done
cmp [ecx+0x28],eax
jne ctl_done
mov edx,[eax+0x10]
test edx,edx
je ctl_done
mov edx,[edx]
test edx,edx
je ctl_done
mov ebx,[edx+0xA8]
test ebx,ebx
je ctl_done
cmp ebx,0x40
ja ctl_done
mov eax,[ecx+0x30]
dec ebx
cmp eax,ebx
ja ctl_done
je ctl_rank_points
mov edx,[edx+0xAC]
test edx,edx
je ctl_done
mov edx,[edx+eax*4]
test edx,edx
je ctl_done
mov edx,[edx]
test edx,edx
je ctl_done
cmp dword ptr [edx+4],0
jle ctl_done
mov ebp,esp
sub esp,0x220
and esp,-0x10
fxsave [esp]
cvtsi2ss xmm0,dword ptr [edx+4]
maxss xmm0,dword ptr [ecx+0x2C]
movss [ecx+0x2C],xmm0
push 1
call RANKUP
fxrstor [esp]
mov esp,ebp
jmp ctl_done
ctl_rank_points:
cmp dword ptr [ra_state+0x30],1
je ctl_done
mov eax,0xF
sub eax,[ecx+0x34]
jle ctl_rank_granted
add [ecx+0x34],eax
add [ecx+0x40],eax
ctl_rank_granted:
mov dword ptr [ra_state+0x30],1
jmp ctl_done

ctl_invalid:
mov dword ptr [ra_state+0x1C],0
ctl_done:
popad
popfd
db 83 ec 2c 53 55
jmp ra_controller_return
ra_controller_hook:
jmp ra_controller_code
ra_controller_return:
[DISABLE]
ra_controller_hook:
db 83 ec 2c 53 55
unregistersymbol(ra_controller_hook)
dealloc(ra_controller_code)
unregistersymbol(ra_state)
dealloc(ra_state)
]==],money=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_money_hook,ra3ep1_1.1.game,2b c7 89 46 04 8b 46 0c 8b 0d d4 5d d0 00 8b 4c 81 30 89 44 24 0c 8b 84 24 cc 00 00 00 89 54 24 14 8b 94 24 d0 00 00 00)
assert(ra_money_hook,2b c7 89 46 04)
alloc(ra_money_code,0x800,ra_money_hook)
label(money_done)
label(ra_money_return)
registersymbol(ra_money_hook)
ra_money_code:
sub eax,edi
pushfd
push edx
cmp esi,[ra_state+4]
jne money_done
cmp dword ptr [ra_state+0x10],1
jne money_done
cmp dword ptr [ra_state+0x1C],1
jne money_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je money_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne money_done
mov edx,[LOGICGLOBAL]
test edx,edx
je money_done
cmp edx,[ra_state+0x24]
jne money_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb money_done
cmp eax,ALLOWANCE
jae money_done
mov eax,ALLOWANCE
money_done:
pop edx
popfd
mov [esi+4],eax
jmp ra_money_return
ra_money_hook:
jmp ra_money_code
ra_money_return:
[DISABLE]
ra_money_hook:
db 2b c7 89 46 04
unregistersymbol(ra_money_hook)
dealloc(ra_money_code)
]==],production=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_production_hook,ra3ep1_1.1.game,57 8b f9 8b 47 08 85 c0 0f 84 87 00 00 00 8b 90 28 04 00 00 85 d2 74 7d 8b 4c 24 08 85 c9 74 75 56 8b 71 0c 83 ee 01 74)
assert(ra_production_hook,57 8b f9 8b 47 08)
alloc(ra_production_code,0x800,ra_production_hook)
label(build_normal)
label(ra_production_return)
registersymbol(ra_production_hook)
ra_production_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[ecx+8]
test edx,edx
je build_normal
mov edx,[edx+OWNER]
cmp edx,[ra_state]
jne build_normal
pop edx
popfd
mov eax,1
ret 4
build_normal:
pop edx
popfd
db 57 8b f9 8b 47 08
jmp ra_production_return
ra_production_hook:
jmp ra_production_code
nop 1
ra_production_return:
[DISABLE]
ra_production_hook:
db 57 8b f9 8b 47 08
unregistersymbol(ra_production_hook)
dealloc(ra_production_code)
]==],construction=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_construction_hook,ra3ep1_1.1.game,8b 44 24 10 8b 54 24 0c 50 8b 44 24 0c 52 8b 54 24 0c 50 52 e8 47 c8 ff ff db 05 90 ce cc 00 a1 90 ce cc 00 85 c0 7d 06)
assert(ra_construction_hook,8b 44 24 10 8b 54 24 0c)
alloc(ra_construction_code,0x800,ra_construction_hook)
label(build_normal)
label(ra_construction_return)
registersymbol(ra_construction_hook)
ra_construction_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[esp+0xC]
cmp edx,[ra_state]
jne build_normal
pop edx
popfd
mov eax,1
ret 0x10
build_normal:
pop edx
popfd
db 8b 44 24 10 8b 54 24 0c
jmp ra_construction_return
ra_construction_hook:
jmp ra_construction_code
nop 3
ra_construction_return:
[DISABLE]
ra_construction_hook:
db 8b 44 24 10 8b 54 24 0c
unregistersymbol(ra_construction_hook)
dealloc(ra_construction_code)
]==],unpack=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_unpack_hook,ra3ep1_1.1.game,8b d1 85 d2 d9 6c 24 0c 89 54 24 14 89 4e 30 db 44 24 14 7d 06 d8 05 c8 ae bf 00 d8 4c 24 10 8b 15 18 5c cf 00 8b 52 50)
assert(ra_unpack_hook,8b d1 85 d2 d9 6c 24 0c)
alloc(ra_unpack_code,0x800,ra_unpack_hook)
label(build_normal)
label(ra_unpack_return)
registersymbol(ra_unpack_hook)
ra_unpack_code:
pushfd
push edx
cmp dword ptr [ra_state+0x1C],1
jne build_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je build_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne build_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je build_normal
cmp edx,[ra_state+0x24]
jne build_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb build_normal
cmp dword ptr [ra_state+0x28],1
jne build_normal
mov edx,[ebx+OWNER]
cmp edx,[ra_state]
jne build_normal
mov ecx,1
build_normal:
pop edx
popfd
db 8b d1 85 d2 d9 6c 24 0c
jmp ra_unpack_return
ra_unpack_hook:
jmp ra_unpack_code
nop 3
ra_unpack_return:
[DISABLE]
ra_unpack_hook:
db 8b d1 85 d2 d9 6c 24 0c
unregistersymbol(ra_unpack_hook)
dealloc(ra_unpack_code)
]==],superweapon=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_superweapon_hook,ra3ep1_1.1.game,51 a1 18 5c cf 00 80 b8 a6 00 00 00 00 56 8b f1 74 17 8b 4e f8 8b 91 90 00 00 00 c1 ea 14 f6 c2 01 75 06 80 7e 30 00 74)
assert(ra_superweapon_hook,51 a1 18 5c cf 00)
alloc(ra_superweapon_code,0x800,ra_superweapon_hook)
label(super_shared_loop)
label(super_shared_ready)
label(super_local_timer)
label(super_done)
label(ra_superweapon_return)
registersymbol(ra_superweapon_hook)
ra_superweapon_code:
pushfd
pushad
cmp dword ptr [ra_state+0x34],1
jne super_done
cmp dword ptr [ra_state+0x1C],1
jne super_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je super_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne super_done
mov eax,[LOGICGLOBAL]
test eax,eax
je super_done
cmp eax,[ra_state+0x24]
jne super_done
mov eax,[eax+0x50]
cmp eax,[ra_state+0x20]
jb super_done
mov eax,[ecx-8]
test eax,eax
je super_done
cmp [eax+OWNER],edx
jne super_done
mov eax,[ecx-0xC]
test eax,eax
je super_done
mov eax,[eax+8]
test eax,eax
je super_done
mov eax,[eax+8]
test eax,eax
je super_done
test dword ptr [eax+0x1C],0x1000
je super_local_timer
mov eax,[eax]
test eax,eax
je super_done
mov eax,[eax+4]
lea ebx,[edx+0x218]
mov edi,[ebx]
mov esi,0x400
super_shared_loop:
test edi,edi
je super_done
cmp edi,ebx
je super_done
cmp [edi+8],eax
je super_shared_ready
mov edi,[edi]
dec esi
jne super_shared_loop
jmp super_done
super_shared_ready:
mov dword ptr [edi+0xC],0
super_local_timer:
mov dword ptr [ecx+0x20],0
super_done:
popad
popfd
db 51 a1 18 5c cf 00
jmp ra_superweapon_return
ra_superweapon_hook:
jmp ra_superweapon_code
nop 1
ra_superweapon_return:
[DISABLE]
ra_superweapon_hook:
db 51 a1 18 5c cf 00
unregistersymbol(ra_superweapon_hook)
dealloc(ra_superweapon_code)
]==],revealnotify=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_revealnotify_hook,ra3ep1_1.1.game,83 ec 18 8b 54 24 20 b8 c0 85 58 00 89 04 24 8b 44 24 1c 89 44 24 08 8b 44 24 24 89 44 24 10 33 c9 b8 01 00 00 00 84 05 d8 b0 d0 00 89 4c 24 04 89 54 24 0c 75 28 09 05 d8 b0 d0 00 b8 d0 b0 d0 00 68 a0 4a bd 00 89 0d cc b0 d0 00 a3 d0 b0 d0 00 a3 d4 b0 d0 00 e8 ea db b7 ff 83 c4 04 8d 0c 24 51 b9 cc b0 d0 00 e8 d4 27 f4 ff 83 c4 18 c3 56 57 8b f9 8d 77 04 b8 01 00 00 00 84 05 d8 b0 d0 00 89 36 89 76 04 c7 07 90 e1 c7 00 75 31 09 05 d8 b0 d0 00 68 a0 4a bd 00 c7 05 cc b0 d0 00)
assert(ra_revealnotify_hook,83 ec 18 8b 54 24 20)
alloc(ra_revealnotify_code,0x800,ra_revealnotify_hook)
label(notify_done)
label(ra_revealnotify_return)
registersymbol(ra_revealnotify_hook)
ra_revealnotify_code:
pushfd
push edx
cmp dword ptr [ra_state+0x38],1
jne notify_done
cmp dword ptr [ra_state+0x1C],1
jne notify_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je notify_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne notify_done
mov edx,[LOGICGLOBAL]
cmp edx,[ra_state+0x24]
jne notify_done
test edx,edx
je notify_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb notify_done
mov dword ptr [esp+0x14],1
notify_done:
pop edx
popfd
db 83 ec 18 8b 54 24 20
jmp ra_revealnotify_return
ra_revealnotify_hook:
jmp ra_revealnotify_code
nop 2
ra_revealnotify_return:
[DISABLE]
ra_revealnotify_hook:
db 83 ec 18 8b 54 24 20
unregistersymbol(ra_revealnotify_hook)
dealloc(ra_revealnotify_code)
]==],revealdraw=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_revealdraw_hook,ra3ep1_1.1.game,8b f8 85 ff 89 44 24 1c 75 09 bf 04 00 00 00 89 7c 24 1c 83 ff 03 89 7c 24 28 0f 8c fd 00 00 00 8b ae 04 02 00 00 85 ed)
assert(ra_revealdraw_hook,8b f8 85 ff 89 44 24 1c)
alloc(ra_revealdraw_code,0x800,ra_revealdraw_hook)
label(draw_done)
label(ra_revealdraw_return)
registersymbol(ra_revealdraw_hook)
ra_revealdraw_code:
pushfd
push edx
cmp dword ptr [ra_state+0x38],1
jne draw_done
cmp dword ptr [ra_state+0x1C],1
jne draw_done
mov edx,[PLAYERGLOBAL]
test edx,edx
je draw_done
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne draw_done
mov edx,[edx+0x20]
cmp edx,[esp+0x20]
jne draw_done
mov edx,[LOGICGLOBAL]
test edx,edx
je draw_done
cmp edx,[ra_state+0x24]
jne draw_done
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb draw_done
mov eax,1
draw_done:
pop edx
popfd
db 8b f8 85 ff 89 44 24 1c
jmp ra_revealdraw_return
ra_revealdraw_hook:
jmp ra_revealdraw_code
nop 3
ra_revealdraw_return:
[DISABLE]
ra_revealdraw_hook:
db 8b f8 85 ff 89 44 24 1c
unregistersymbol(ra_revealdraw_hook)
dealloc(ra_revealdraw_code)
]==],ammo=[==[[ENABLE]
define(PLAYERGLOBAL,ra3ep1_1.1.game+0x905DD4)
define(LOGICGLOBAL,ra3ep1_1.1.game+0x8F5C18)
define(POWERADD,ra3ep1_1.1.game+0x47DFC0)
define(TECHVT,ra3ep1_1.1.game+0x875C20)
define(RANKUP,ra3ep1_1.1.game+0x48A100)
define(SHROUDGLOBAL,ra3ep1_1.1.game+0x8FFF40)
define(REVEALADD,ra3ep1_1.1.game+0x715D70)
define(REVEALOFF,ra3ep1_1.1.game+0x7177F0)
define(REVEALREFRESH,ra3ep1_1.1.game+0x7151F0)
define(IRONADD,ra3ep1_1.1.game+0x314680)
define(IRONREMOVE,ra3ep1_1.1.game+0x3147E0)
define(IRONSTATUS,ra3ep1_1.1.game+0x3622E0)
define(VETERANCY,ra3ep1_1.1.game+0x3985C0)
define(EXPERIENCE,0x3DC)
define(OWNER,0x428)
define(ALLOWANCE,0x7530)
aobscanmodule(ra_ammo_hook,ra3ep1_1.1.game,01 46 1c 01 46 24 01 46 2c 83 7e 2c 00 7f 3b 83 7f 04 00 74 26 83 46 28 01 8b 56 18 8b 4f 04 8b 46 14 8b 89 f8 00 00 00)
assert(ra_ammo_hook,01 46 1c 01 46 24)
alloc(ra_ammo_code,0x800,ra_ammo_hook)
label(ammo_normal)
label(ammo_burst)
label(ra_ammo_return)
registersymbol(ra_ammo_hook)
ra_ammo_code:
pushfd
push edx
cmp dword ptr [ra_state+0x90],1
jne ammo_normal
cmp dword ptr [ra_state+0x1C],1
jne ammo_normal
mov edx,[PLAYERGLOBAL]
test edx,edx
je ammo_normal
mov edx,[edx+0x28]
cmp edx,[ra_state]
jne ammo_normal
mov edx,[edi+4]
test edx,edx
je ammo_normal
push eax
mov eax,[ra_state]
cmp [edx+OWNER],eax
pop eax
jne ammo_normal
mov edx,[edx+4]
test edx,edx
je ammo_normal
test dword ptr [edx+0xC0],0x4000
je ammo_normal
mov edx,[LOGICGLOBAL]
test edx,edx
je ammo_normal
cmp edx,[ra_state+0x24]
jne ammo_normal
mov edx,[edx+0x50]
cmp edx,[ra_state+0x20]
jb ammo_normal
pop edx
popfd
jmp ammo_burst
ammo_normal:
pop edx
popfd
add [esi+0x1C],eax
ammo_burst:
add [esi+0x24],eax
jmp ra_ammo_return
ra_ammo_hook:
jmp ra_ammo_code
nop 1
ra_ammo_return:
[DISABLE]
ra_ammo_hook:
db 01 46 1c 01 46 24
unregistersymbol(ra_ammo_hook)
dealloc(ra_ammo_code)
]==]},hookRvas={controller=0x1274c0,money=0x47e18e,production=0x32d5b0,construction=0x2feb00,unpack=0x32f71c,superweapon=0x323be0,revealnotify=0x55c200,revealdraw=0x1727a0,ammo=0x3ccd34}}
}
local list=getAddressList()
local status=list.getMemoryRecordByID(1)
local mains={ra3=list.getMemoryRecordByID(10),up=list.getMemoryRecordByID(20)}
local hookOrder={'controller','money','production','construction','unpack'}
local hookSizes={controller=5,money=5,production=6,construction=8,unpack=8,superweapon=6,revealnotify=7,revealdraw=8,ammo=6}
local ids={money=1,power=2,instant=3,rank=4,superweapon=5,visual=6,full=7,ammo=8,iron=9}
local flagOffsets={money=0xC,power=0x14,instant=0x28,rank=0x2C,superweapon=0x34,visual=0x38,full=0x3C,ammo=0x90,iron=0xC0}
local function metaOffset(index) return index&lt;=6 and 0x40+(index-1)*8 or 0xA0+(index-7)*8 end
local recoverClosedTable
local suppress=false
local function report(message)
  if not S.recordsRemoved and S.lastStatus~=message then
    status.Description='Auto-Attach and Version Check — '..message
    S.lastStatus=message
  end
end
local function tell(message) showMessage(message) end
local function basename(path) return (path:match('[^/\\]+$') or path):lower() end
local function write(off,value)
  if not S.state or getOpenedProcessID()~=S.pid then return false end
  if readInteger(S.state+off)==value then return true end
  return writeInteger(S.state+off,value) and readInteger(S.state+off)==value
end
local function context()
  if not S.supported or not S.base or getOpenedProcessID()~=S.pid then return end
  local c=configs[S.game]
  local players=readInteger(S.base+c.player)
  local logic=readInteger(S.base+c.logic)
  if not players or players==0 or not logic or logic==0 then return end
  local p=readInteger(players+0x28)
  if not p or p==0 then return end
  local start=readInteger(p+0xE4)
  local ending=readInteger(p+0xE8)
  local energy=readInteger(p+0x74)
  local id=readInteger(p+0x20)
  if not start or start==0 or not ending or ending&lt;start+4 or not energy or energy==0 or not id or id&gt;19 then return end
  local money=readInteger(start)
  if not money or money==0 or readInteger(money)~=S.base+c.moneyVT or readInteger(energy)~=S.base+c.energyVT then return end
  if readInteger(money+0xC)~=id or readInteger(energy+0x1C)~=p then return end
  local frame=readInteger(logic+0x50)
  local cash,cap=readInteger(money+4),readInteger(money+8)
  if not frame or frame==0 or not cash or not cap or cash&lt;0 or cap&lt;0 or cash&gt;1000000000 or cap&gt;1000000000 then return end
  return {p=p,money=money,energy=energy,logic=logic,frame=frame}
end
local function same(a,b)
  return a and b and a.p==b.p and a.money==b.money and a.energy==b.energy and a.logic==b.logic
end
local function owned()
  local c=context()
  return same(c,S.bound) and c.frame&gt;=(readInteger(S.state+0x20) or S.bound.frame)
end
local function sync()
  for name,off in pairs(flagOffsets) do
    if (name~='ammo' or (readInteger(S.state+0x74) or 0)&gt;=13) and (name~='iron' or (readInteger(S.state+0x74) or 0)&gt;=15) and not write(off,S.choices[name] and 1 or 0) then return false end
  end
  return true
end
local function uncheck()
  if S.recordsRemoved then return end
  suppress=true
  for _,main in pairs(mains) do
    for i=0,main.Count-1 do if main.Child[i].Active then main.Child[i].Active=false end end
    if main.Active then main.Active=false end
    main.Collapsed=true
  end
  suppress=false
end
local function run(script,info)
  local ok,a,b=pcall(autoAssemble,script,false,info)
  if not ok or not a then S.lastError=tostring(b or a); return false end
  return true,b
end
local function forgetExited()
  if not next(S.installed) or getProcesslist()[S.pid] then return false end
  for _,kind in ipairs(hookOrder) do unregisterSymbol('ra_'..kind..'_hook') end
  unregisterSymbol('ra_state')
  S.installed={}; S.state=nil; S.bound=nil; S.stopping=false; S.offRequested=false
  S.pid=nil; S.base=nil; S.supported=nil; S.selected=nil; S.choices={}; S.candidate=nil
  uncheck()
  return true
end
local function uninstall()
  if getOpenedProcessID()~=S.pid then return false end
  if S.state and not write(0x1C,0) then return false end
  for index=#hookOrder,1,-1 do
    local kind=hookOrder[index]
    local info=S.installed[kind]
    if info then
      if info.patch and info.original then
        local already=true
        for n,byte in ipairs(info.original) do if readBytes(info.hook+n-1,1)~=byte then already=false; break end end
        if not already then
          for n,byte in ipairs(info.patch) do
            if readBytes(info.hook+n-1,1)~=byte then
              report('Another patch changed the game code; cleanup stopped. Keep this table open')
              return false
            end
          end
          local ok=pcall(writeBytes,info.hook,info.original)
          for n,byte in ipairs(info.original) do if readBytes(info.hook+n-1,1)~=byte then ok=false; break end end
          if not ok then report('Cleanup could not finish. Keep this table open and retry Clear All'); return false end
        end
        unregisterSymbol('ra_'..kind..'_hook')
        if kind=='controller' then unregisterSymbol('ra_state') end
        -- Detached caves stay allocated until process exit: an in-flight game
        -- thread may still be returning through them after the branch is restored.
      elseif not run(configs[S.game].scripts[kind],info) then return false end
      S.installed[kind]=nil
    end
  end
  S.state=nil; S.bound=nil; S.stopping=false; S.offRequested=false; S.candidate=nil
  return true
end
function S.clear()
  if not next(S.installed) and recoverClosedTable then recoverClosedTable() end
  S.selected=nil; S.choices={}
  if forgetExited() then return true end
  if not next(S.installed) then uncheck(); return true end
  if getOpenedProcessID()~=S.pid then report('Return to the original game process to finish cleanup'); return false end
  S.stopping=true
  if S.state and not sync() then return false end
  if S.state and (readInteger(S.state+0x74) or 0)&gt;=17 and not write(0xF0,0) then return false end
  S.offRequested=true; uncheck()
  if S.state and owned() and readInteger(S.state+0x1C)==1 then
    if readInteger(S.state+0x10)~=0 or readInteger(S.state+0x18)~=0 or ((readInteger(S.state+0x74) or 0)&gt;=10 and (readInteger(S.state+0x80)~=0 or readInteger(S.state+0x84)~=0)) or ((readInteger(S.state+0x74) or 0)&gt;=15 and readInteger(S.state+0xD0)~=0) then
      report('All options unticked — resume the game to finish cleanup')
      return false
    end
  end
  return uninstall()
end
local function bind(ctx)
  S.choices.iron=false
  suppress=true; list.getMemoryRecordByID((S.game=='ra3' and 10 or 20)+ids.iron).Active=false; suppress=false
  if not write(0x1C,0) then return false end
  for _,off in ipairs({0x10,0x18,0x30,0x80,0x84,0x88,0x8C,0xC0,0xC4,0xC8,0xD0,0xD4,0xD8,0xE4,0xE8,0xF0,0xF4}) do if not write(off,0) then return false end end
  for off,value in pairs({[0]=ctx.p,[4]=ctx.money,[8]=ctx.energy,[0x20]=ctx.frame,[0x24]=ctx.logic}) do
    if not write(off,value) then return false end
  end
  S.bound=ctx
  return sync() and write(0x1C,1)
end
local function install(ctx)
  for index,kind in ipairs(hookOrder) do
    local ok,info=run(configs[S.game].scripts[kind])
    if not ok then
      S.clear()
      tell('Could not enable the options. Use Clear All, turn off conflicting tables, then try MAIN again.')
      return false
    end
    S.installed[kind]=info
    local hook=getAddressSafe('ra_'..kind..'_hook')
    local allocation=info and info.allocs and info.allocs['ra_'..kind..'_code']
    local displacement=hook and readInteger(hook+1)
    if not allocation or not displacement or readBytes(hook,1)~=0xE9 or
       (hook+5+displacement)%0x100000000~=allocation.address then
      S.clear(); tell('The game did not accept the patch. Turn off conflicting tables and try MAIN again.'); return false
    end
    info.hook=hook; info.patch={}; info.original={}
    local original=configs[S.game].scripts[kind]:match('%[DISABLE%]%s*[^\n]+:%s*db ([^\n]+)')
    for byte in original:gmatch('%x%x') do info.original[#info.original+1]=tonumber(byte,16) end
    for n=1,hookSizes[kind] do info.patch[n]=readBytes(hook+n-1,1) end
    if kind=='controller' then
      S.state=getAddressSafe('ra_state')
      if not S.state then S.clear(); return false end
      if not write(0x74,17) or not write(0x78,S.pid) or not write(0x7C,0x1733524B) then S.clear(); return false end
    end
    if not write(metaOffset(index),hook) or not write(metaOffset(index)+4,allocation.address) then S.clear(); return false end
  end
  if not bind(ctx) then S.clear(); tell('The match changed while preparing the options. Try MAIN again once it is ready.'); return false end
  return true
end
local function updateMatch()
  local ctx=context()
  if S.state and owned() and readInteger(S.state+0x1C)==1 then return sync() end
  if S.state and not write(0x1C,0) then return false end
  -- A missing context or rewound simulation invalidates the previous map even
  -- when the engine reuses its player/resource addresses for the next map.
  S.bound=nil
  if not ctx then S.candidate=nil; report('Selections saved — waiting for a mission or skirmish'); return true end
  -- Menus retain plausible player pointers and a nonzero, stopped frame count.
  -- Wait for the same context to advance before installing or rebinding hooks.
  if not same(ctx,S.candidate) or ctx.frame&lt;=S.candidate.frame then
    S.candidate=ctx; report('Selections saved — waiting for the new map to run'); return true
  elseif not S.state then
    if not install(ctx) then return false end
  elseif not bind(ctx) then return false end
  S.candidate=nil
  report(configs[S.game].title..' | '..S.version..' | Options ready')
  return true
end
recoverClosedTable=function()
  if next(S.installed) or not S.supported then return end
  local c=configs[S.game]
  local hook=S.base+c.hookRvas.controller
  if readBytes(hook,1)~=0xE9 then return end
  local displacement=readInteger(hook+1)
  if not displacement then return end
  local cave=(hook+5+displacement)%0x100000000
  -- Our controller begins PUSHFD/PUSHAD/CMP [state+1C],1.
  if readInteger(cave)~=0x3D83609C then return end
  local operand=readInteger(cave+4)
  if not operand then return end
  local state=operand-0x1C
  if readInteger(state+0x7C)~=0x1733524B or readInteger(state+0x78)~=S.pid then return end
  local recovered={}
  for index,kind in ipairs(hookOrder) do
    local address=(index&lt;=6 or (readInteger(state+0x74) or 0)&gt;=(index&lt;=8 and 10 or 13)) and readInteger(state+metaOffset(index)) or 0
    local target=(index&lt;=6 or (readInteger(state+0x74) or 0)&gt;=(index&lt;=8 and 10 or 13)) and readInteger(state+metaOffset(index)+4) or 0
    local original=c.scripts[kind]:match('%[DISABLE%]%s*[^\n]+:%s*db ([^\n]+)')
    -- v1.7 has the same recovery record but no superweapon hook yet.
    if (kind=='superweapon' or kind=='revealnotify' or kind=='revealdraw' or kind=='ammo') and (not address or address==0) then
      address=S.base+c.hookRvas[kind]
      local n=0
      for byte in original:gmatch('%x%x') do
        if readBytes(address+n,1)~=tonumber(byte,16) then return end
        n=n+1
      end
      target=address+5
    end
    if address~=S.base+c.hookRvas[kind] or not target or target==0 then return end
    local info={hook=address,original={},patch={0xE9}}
    for byte in original:gmatch('%x%x') do info.original[#info.original+1]=tonumber(byte,16) end
    local delta=(target-address-5)%0x100000000
    for n=1,4 do info.patch[n+1]=delta%256; delta=math.floor(delta/256) end
    -- CE may encode NOP 2/3 as one multi-byte instruction, rather than 90s.
    local padding=hookSizes[kind]-5
    local canonical=({[0]={},[1]={0x90},[2]={0x66,0x90},[3]={0x0F,0x1F,0x00}})[padding]
    local compact=true
    for n,byte in ipairs(canonical) do
      if readBytes(address+4+n,1)~=byte then compact=false; break end
    end
    for n=1,padding do info.patch[5+n]=compact and canonical[n] or 0x90 end
    local patched,restored=true,true
    for n=1,hookSizes[kind] do
      local byte=readBytes(address+n-1,1)
      patched=patched and byte==info.patch[n]
      restored=restored and byte==info.original[n]
    end
    if not patched and not restored then return end
    if patched then recovered[kind]=info end
  end
  S.state=state; S.installed=recovered
  S.bound={p=readInteger(state),money=readInteger(state+4),energy=readInteger(state+8),logic=readInteger(state+0x24),frame=readInteger(state+0x20)}
  S.stopping=true
  S.clear()
end
local function attach(requested)
  local found={}
  for pid,name in pairs(getProcesslist()) do
    name=basename(name)
    local game=name:match('^ra3ep1_[%d.]+%.game$') and 'up' or name:match('^ra3_[%d.]+%.game$') and 'ra3'
    if game and (not requested or game==requested) then found[#found+1]={pid=pid,name=name,game=game} end
  end
  local selected
  for _,candidate in ipairs(found) do if candidate.pid==getOpenedProcessID() then selected=candidate; break end end
  if not selected and #found==1 then selected=found[1] end
  if not selected then report(#found&gt;1 and 'Multiple games available — tick the matching MAIN' or 'Waiting for either game'); return false end
  local module
  for _,m in ipairs(enumModules(selected.pid) or {}) do
    if basename(m.Name)==selected.name then module=m; break end
  end
  if not module then return false end
  if getOpenedProcessID()~=selected.pid then openProcess(selected.pid) end
  if getOpenedProcessID()~=selected.pid then return false end
  if S.pid~=selected.pid or S.base~=module.Address or S.name~=selected.name then
    local c=configs[selected.game]
    local _,v=getFileVersion(module.PathToFile)
    S.version=v and string.format('%d.%d.%d.%d',v.major,v.minor,v.release,v.build) or 'Unknown'
    S.supported=selected.name==c.module and S.version==c.version and (md5file(module.PathToFile) or ''):lower()==c.hash
    S.pid=selected.pid; S.game=selected.game; S.name=selected.name; S.base=module.Address
    hookOrder={'controller','money','production','construction','unpack'}
    for _,kind in ipairs({'superweapon','revealnotify','revealdraw','ammo'}) do if c.scripts[kind] then hookOrder[#hookOrder+1]=kind end end
    recoverClosedTable()
  end
  report(configs[S.game].title..' | '..S.version..(S.supported and '' or ' | Features unavailable for this build'))
  return true
end
function S.poll(requested)
  if S.state and S.choices.iron and (readInteger(S.state+0xD4) or 0)~=0 then
    write(0xD4,0)
    report('Some selected objects could not accept Iron Curtain; other targets remain protected')
  end
  forgetExited()
  if S.stopping and not S.clear() then return false end
  if S.selected then
    if not getProcesslist()[S.pid] then S.selected=nil; S.choices={}; uncheck()
    elseif requested and requested~=S.selected then
      if not S.clear() then return false end
    else
      if getOpenedProcessID()~=S.pid then report('Return to the selected game process or use Clear All'); return false end
      return updateMatch()
    end
  end
  return attach(requested)
end
local function captureIron()
  if not S.state or not owned() or readInteger(S.state+0x1C)~=1 then
    tell('Start or resume a map, then select your units or buildings before enabling this option.'); return false
  end
  if readInteger(S.state+0xD0)~=0 or readInteger(S.state+0xC4)~=0 then
    tell('Resume the game briefly to finish removing the previous protection.'); return false
  end
  local c=configs[S.game]
  local selection=readInteger(S.base+c.selection)
  local count=selection and readInteger(selection+c.selectionCount)
  if not count or count&lt;1 or count&gt;4096 then
    tell('Select your units or buildings before enabling this option.'); return false
  end
  local rows,seen={},{}
  local node=readInteger(selection+c.selectionHead)
  for i=1,count do
    if not node or node==0 or node==selection+c.selectionHead then return false end
    local draw=readInteger(node+8)
    local obj=draw and readInteger(draw+0x138)
    if obj and obj~=0 and not seen[obj] and readInteger(obj+c.owner)==S.bound.p then
      local id=readInteger(obj+c.objectID)
      local manager=readInteger(obj+c.modifier)
      if id and id~=0 and manager and manager~=0 then
        rows[#rows+1]={obj,id,manager}; seen[obj]=true
      end
    end
    node=readInteger(node)
  end
  if #rows==0 then tell('No owned units or buildings in the selection can receive this effect.'); return false end
  local store=readInteger(S.base+c.modifierStore)
  local first=store and readInteger(store+0x24)
  local last=store and readInteger(store+0x28)
  if not first or not last or last&lt;first or last-first&gt;0x10000 then return false end
  local source
  for slot=first,last-4,4 do
    local mod=readInteger(slot)
    local def=mod and readInteger(mod)
    local asset=def and readInteger(def)
    if asset and readInteger(asset)==0xC5E07887 and readInteger(asset+4)==0x6516AA2D then source=mod; break end
  end
  if not source then tell('The native Iron Curtain modifier could not be found for this map.'); return false end
  local bytes=readBytes(source,0x84,true)
  if type(bytes)~='table' or #bytes~=0x84 or not writeBytes(S.state+0x100,bytes) then return false end
  for index,row in ipairs(rows) do
    local off=0x200+(index-1)*0x10
    if not write(off,row[1]) or not write(off+4,row[2]) or not write(off+8,row[3]) or not write(off+12,0) then return false end
  end
  return write(0xE4,0) and write(0xD4,0) and write(0xC0,1) and write(0xC4,#rows)
end
local function guarded(callback)
  return function(record,before)
    local ok,result=pcall(callback,record,before)
    if not ok then S.lastError=tostring(result); tell('The game could not be accessed. Use Clear All, then retry once the game is ready.'); return false end
    return result
  end
end
for key,main in pairs(mains) do
  local game=key
  main.OnActivate=guarded(function(_,before)
    if not before or suppress then return true end
    if S.closing then return false end
    if not S.poll(game) then tell(S.stopping and 'Resume the game to finish cleanup, then try MAIN again.' or 'Start the matching game, then try MAIN again.'); return false end
    if not S.supported then tell('These options support the installed Steam Red Alert 3 1.13 and Uprising 1.1 builds. This executable is different.'); return false end
    S.selected=game
    S.candidate=context()
    report('Selections saved — waiting for a mission or skirmish')
    return true
  end)
  main.OnDeactivate=guarded(function(_,before)
    if not before or suppress then return true end
    return S.clear() or S.offRequested==true
  end)
  for feature,offset in pairs(ids) do
    local name=feature
    local rec=list.getMemoryRecordByID((game=='ra3' and 10 or 20)+offset)
    if rec then
    rec.OnActivate=guarded(function(_,before)
      if not before or suppress then return true end
      if S.selected~=game or S.closing or S.stopping then tell('Tick the matching MAIN before choosing an option.'); return false end
      if name=='iron' and not captureIron() then return false end
      if name=='rank' and S.state and not write(0x30,0) then return false end
      if name=='visual' or name=='full' then
        local other=name=='visual' and 'full' or 'visual'
        if S.state and not write(flagOffsets[other],0) then return false end
        S.choices[other]=false
        suppress=true; list.getMemoryRecordByID((game=='ra3' and 10 or 20)+ids[other]).Active=false; suppress=false
      end
      S.choices[name]=true
      if S.state and not write(flagOffsets[name],1) then S.choices[name]=false; return false end
      return true
    end)
    rec.OnDeactivate=guarded(function(_,before)
      if not before or suppress then return true end
      if S.state and not write(flagOffsets[name],0) then return false end
      S.choices[name]=false
      return true
    end)
    end
  end
end
local function oneShot(id,action)
  list.getMemoryRecordByID(id).OnActivate=guarded(function(_,before)
    if before then action(); return false end
    return true
  end)
end
local function grantVeterancy(game)
  if S.selected~=game or S.stopping or S.closing or not S.state or not owned() then
    tell('Tick the matching MAIN and resume a map, then select your units.'); return
  end
  if (readInteger(S.state+0x74) or 0)&lt;17 then tell('Use Clear All, then enable MAIN again to load this option.'); return end
  if readInteger(S.state+0xF0)~=0 then tell('Resume the game briefly to finish the previous promotion.'); return end
  local c=configs[game]
  local selection=readInteger(S.base+c.selection)
  local count=selection and readInteger(selection+c.selectionCount)
  if not count or count&lt;1 or count&gt;4096 then tell('Select your units before using this action.'); return end
  local node=readInteger(selection+c.selectionHead)
  local rows,seen={},{}
  for i=1,count do
    if not node or node==0 or node==selection+c.selectionHead then return end
    local draw=readInteger(node+8)
    local obj=draw and readInteger(draw+0x138)
    if obj and obj~=0 and not seen[obj] and readInteger(obj+c.owner)==S.bound.p then
      local xp=readInteger(obj+c.experience)
      local id=readInteger(obj+c.objectID)
      if id and id~=0 and xp and xp~=0 and readInteger(xp+0x38)==obj and readInteger(xp+0x3C)==0 then
        rows[#rows+1]={obj,id}; seen[obj]=true
      end
    end
    node=readInteger(node)
  end
  if #rows==0 then tell('No selected owned units can receive veterancy.'); return end
  for i,row in ipairs(rows) do
    local off=0x10200+(i-1)*8
    if not write(off,row[1]) or not write(off+4,row[2]) then return end
  end
  if not write(0xF4,0) then return end
  write(0xF0,#rows)
end
oneShot(30,function() grantVeterancy('ra3') end)
oneShot(40,function() grantVeterancy('up') end)
oneShot(2,function() shellExecute('https://ko-fi.com/katzy') end)
oneShot(3,function() showMessage([[Table identification: Katzy.

Start the game, open the table in Cheat Engine and allow its Lua script. Tick the matching MAIN section, then choose your options. Use in single-player missions, skirmishes or Commander’s Challenge. Ordinary options can be selected in the menu and carry over between maps; selected-unit actions require a live match.

Infinite Money
Adds a 30,000-credit allowance. Earnings increase the total; purchases spend the surplus down to the allowance. Turning it off removes the allowance and keeps your unspent normal credits.

Infinite Power
Adds power as needed to keep 100 spare. Turning it off removes the extra power and restores your buildings’ natural supply.

Instant Build
Finishes paid production. Normal prices, prerequisites, placement and factory exit rules still apply. Turning it off restores normal future production; completed items stay completed. Enable before starting production.

Infinite Aircraft Ammo
Stops your aircraft from spending ammunition normally reloaded at an airfield. Empty aircraft need one normal reload first. Firing speed stays normal. Turning it off restores ammunition use.

Instant Superweapons, Support Powers and Unit Abilities
Readies your superweapons, unlocked commander powers and unit abilities. Required buildings, power, unlocks, targets, ability duration and firing rules still apply. Turning it off restores normal recharge for future uses.

Invulnerability - Selected Units and Buildings
Select units and buildings you own in a live match, then enable this option to protect that group using Iron Curtain. Changing selection does not move protection. Turn it off or use Clear All to remove protection; select another group and enable again to change targets. Changing maps clears protection. Protected objects show the red Iron Curtain effect; protection recovers after Time Belt. Turn it off before saving/loading because saved modifiers are not tracked.

Maximum Commander Rank and 15 Power Points
Grants your faction’s maximum commander rank and at least 15 unspent power points once per activation or new map. Choose powers yourself; spending works normally and existing points above 15 are preserved. Granted ranks, points and powers remain for the current match after you turn it off.

Promote Selected Units - Maximum Veterancy (One Shot)
Select units you own in a live match and activate once to grant maximum veterancy to eligible units. Granted ranks remain after Clear All. Units that cannot gain veterancy are skipped. Resume play to apply queued promotions. Clear All cancels unfinished promotions. The checkbox stays unticked and can be used again for another group.

Reveal Map - Full
Grants full map visibility and can trigger discoveries or mission events early. Turning it off cannot undo events already triggered. Use only one Reveal Map mode at a time.

Reveal Map - Visual Only
Shows terrain and objects without granting gameplay sight. Normal scouting, targeting and cloaking rules still apply. Use this mode for campaigns.

Clear All
Turns off the options and MAIN. If paused, resume briefly to let cleanup finish. Turn options off before saving, loading, switching processes manually or replacing the table.]]) end)
oneShot(4,S.clear)
function S.shutdown(closing)
  -- Closing must never depend on another simulation frame. clear() switches
  -- every feature off first; the controller can remove resource allowances on
  -- the next frame without any CE timer or Lua state remaining alive.
  local ok,done=pcall(S.clear)
  if not closing and (not ok or not done) then return false end
  if S.timer then S.timer.destroy(); S.timer=nil end
  if S.closeToken then getMainForm().unregisterCloseCallback(S.closeToken); S.closeToken=nil end
  return true
end
S.closeToken=getMainForm().registerCloseCallback(function(_,action)
  if action==caNone then return action end
  S.shutdown(true)
  return action
end)
S.timer=createTimer(getMainForm(),false)
S.timer.Interval=250
S.timer.OnTimer=function()
  if getAddressList().getMemoryRecordByID(10)~=mains.ra3 then S.recordsRemoved=true; S.shutdown(); return end
  local ok,result=pcall(S.poll)
  if not ok then S.lastError=tostring(result); report('Could not inspect the game — use Clear All before continuing') end
end
S.timer.Enabled=true
S.timer.OnTimer()
</LuaScript>
</CheatTable>