Difference between revisions of "Arc Range Calculation Routine"

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
m (tabs -> spaces)
m (fixed the branches from relative to absolute values)
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
:''ASM duplicate of [[Set initial panels]].''
+
Computes and marks the tiles within range of a longbow attack.
  
<pre>
+
Iterates through all tiles on the map.
00000000: 27bdffd0 addiu r29,r29,-0x0030
+
* If the tile is within 3 squares of the caster, skip.
00000004: afb00020 sw r16,0x0020(r29)
+
* Calculate the height effect on range: <code>[(casterHeight - tileHeight)/4]</code>.
00000008: 00808021 addu r16,r4,r0              r16 = Caster Data
+
* Checks effective distance + height effect against weapon range.
0000000c: afb10024 sw r17,0x0024(r29)
+
* Marks tiles within effective range.
00000010: afbf0028 sw r31,0x0028(r29)
 
00000014: 0c05e5ed jal 0x001797b4              Caster Height from Water Supports and Float
 
00000018: 00a08821 addu r17,r5,r0              r17 = Weapon Range
 
0000001c: 00401821 addu r3,r2,r0                r3 = Height Value (Return)
 
00000020: 920c0047 lbu r12,0x0047(r16)          r12 = Caster X
 
00000024: 3c02800e lui r2,0x800e
 
00000028: 90424ea0 lbu r2,0x4ea0(r2)            r2 = Max Map Y
 
0000002c: 920d0048 lbu r13,0x0048(r16)          r13 = Caster Y
 
00000030: 18400049 blez r2,0x00000158          Exit if Max Y is negative
 
00000034: 00004821 addu r9,r0,r0                r9 = Y Counter
 
00000038: 3c108019 lui r16,0x8019
 
0000003c: 2610f8cc addiu r16,r16,-0x0734        r16 = Tile Data (18f8cc)
 
00000040: 306e00ff andi r14,r3,0x00ff          r14 = Height Value
 
00000044: 322500ff andi r5,r17,0x00ff          r5 = Weapon Range
 
00000048: 340f0001 ori r15,r0,0x0001            r15 = 0x0001
 
0000004c: 01a9102a slt r2,r13,r9                If Caster Y < Y Counter
 
00000050: 14400002 bne r2,r0,0x0000005c        Branch if True
 
00000054: 012d5823 subu r11,r9,r13              r11 = Y Counter - Caster Y
 
00000058: 01a95823 subu r11,r13,r9              r11 = Caster Y - Y Counter
 
0000005c: 3c02800e lui r2,0x800e
 
00000060: 90424e9c lbu r2,0x4e9c(r2)            r2 = Max Map X
 
00000064: 00000000 nop
 
00000068: 18400035 blez r2,0x00000140          Branch if Max X is negative
 
0000006c: 00004021 addu r8,r0,r0                r8 = X Counter
 
00000070: 0188102a slt r2,r12,r8                If Caster X < X Counter
 
00000074: 14400002 bne r2,r0,0x00000080        Branch if true
 
00000078: 010c1023 subu r2,r8,r12              r2 = X Counter - Caster X
 
0000007c: 01881023 subu r2,r12,r8              r2 = Caster X - Counter X
 
00000080: 004b5021 addu r10,r2,r11              r10 = Caster X- + Caster Y-
 
00000084: 29420003 slti r2,r10,0x0003          If Difference(r10) < 3
 
00000088: 14400027 bne r2,r0,0x00000128        Branch if True
 
0000008c: 00000000 nop
 
00000090: 00003821 addu r7,r0,r0                r7 = Tile Counter
 
00000094: 3c02800e lui r2,0x800e
 
00000098: 90424e9c lbu r2,0x4e9c(r2)            r2 = Max Map X
 
0000009c: 00000000 nop
 
000000a0: 01220018 mult r9,r2                  Y Counter * Max X
 
000000a4: 00071a00 sll r3,r7,0x08
 
000000a8: 00001012 mflo r2
 
000000ac: 00621821 addu r3,r3,r2                Y Counter * Max X + Tile Counter
 
000000b0: 00683021 addu r6,r3,r8                r6 = Y Counter * Max X + Tile Counter + X Counter
 
000000b4: 000610c0 sll r2,r6,0x03
 
000000b8: 00501021 addu r2,r2,r16              r2 = Caster Tile Data
 
000000bc: 90430002 lbu r3,0x0002(r2)            Caster Tile's Height
 
000000c0: 90440003 lbu r4,0x0003(r2)            Caster Tile's Height (halves)
 
000000c4: 90420003 lbu r2,0x0003(r2)            Caster Tile's Height (halves)
 
000000c8: 00031840 sll r3,r3,0x01
 
000000cc: 3084001f andi r4,r4,0x001f            Ignore Depth
 
000000d0: 00641821 addu r3,r3,r4                Height + Height(halves)
 
000000d4: 00021142 srl r2,r2,0x05              Ignore Halves
 
000000d8: 00021040 sll r2,r2,0x01             
 
000000dc: 00621821 addu r3,r3,r2                r3 = Height + Halves + Depth
 
000000e0: 306300ff andi r3,r3,0x00ff            r3 = Non Zero Height
 
000000e4: 01c31023 subu r2,r14,r3              r2 = Height(Float/Water Supports) - Height(normal)
 
000000e8: 04410002 bgez r2,0x000000f4          Branch if difference isn't negative
 
000000ec: 00000000 nop
 
000000f0: 24420003 addiu r2,r2,0x0003          r2 = 0x0003
 
000000f4: 00021083 sra r2,r2,0x02
 
000000f8: 01421023 subu r2,r10,r2              r2 = (Caster X- + Caster Y-) - Height
 
000000fc: 00a2102a slt r2,r5,r2                If Weapon Range < Height Value
 
00000100: 14400006 bne r2,r0,0x0000011c        Branch if True
 
00000104: 24e70001 addiu r7,r7,0x0001          Tile Counter++
 
00000108: 00061080 sll r2,r6,0x02             
 
0000010c: 00461021 addu r2,r2,r6                r2 = Current Tile Data
 
00000110: 3c018019 lui r1,0x8019
 
00000114: 00220821 addu r1,r1,r2
 
00000118: a02f2dd8 sb r15,0x2dd8(r1)            AoE = 1 to Current Tile (Tile is apart of Range)
 
0000011c: 28e20002 slti r2,r7,0x0002            If r7 < 2
 
00000120: 1440ffdc bne r2,r0,0x00000094        Branch if True (Repeat for High Tile)
 
00000124: 00000000 nop
 
00000128: 3c02800e lui r2,0x800e
 
0000012c: 90424e9c lbu r2,0x4e9c(r2)            r2 = Max Map X
 
00000130: 25080001 addiu r8,r8,0x0001          X Counter++
 
00000134: 0102102a slt r2,r8,r2                If X Counter < Max X
 
00000138: 1440ffce bne r2,r0,0x00000074        Branch Back if True
 
0000013c: 0188102a slt r2,r12,r8                If Caster X < X Counter
 
00000140: 3c02800e lui r2,0x800e
 
00000144: 90424ea0 lbu r2,0x4ea0(r2)            r2 = Max Map Y
 
00000148: 25290001 addiu r9,r9,0x0001          Y Counter++
 
0000014c: 0122102a slt r2,r9,r2                If Y Counter < Max Y
 
00000150: 1440ffbf bne r2,r0,0x00000050        Branch Back if True
 
00000154: 01a9102a slt r2,r13,r9                If Caster Y < Y Counter
 
00000158: 8fbf0028 lw r31,0x0028(r29)
 
0000015c: 8fb10024 lw r17,0x0024(r29)
 
00000160: 8fb00020 lw r16,0x0020(r29)
 
00000164: 27bd0030 addiu r29,r29,0x0030
 
00000168: 03e00008 jr r31
 
0000016c: 00000000 nop
 
</pre>
 
  
*[[Height vs Water and Float Routine]]
+
Calculate Arc Range
 +
r4 = Caster Data
 +
r5 = Weapon Range
 +
 
 +
001798b0: 27bdffd0 addiu r29,r29,0xffd0            
 +
001798b4: afb00020 sw r16,0x0020(r29)            
 +
001798b8: 00808021 addu r16,r4,r0 r16 = Caster Data       
 +
001798bc: afb10024 sw r17,0x0024(r29)            
 +
001798c0: afbf0028 sw r31,0x0028(r29)            
 +
001798c4: 0c05e5ed jal 0x001797b4 [[Height vs Water and Float Routine]]    
 +
001798c8: 00a08821 addu r17,r5,r0 r17 = Weapon Range       
 +
001798cc: 00401821 addu r3,r2,r0 r3 = Height Value/Depth (Return)       
 +
001798d0: 920c0047 lbu r12,0x0047(r16) r12 = Caster X       
 +
001798d4: 3c02800e lui r2,0x800e            
 +
001798d8: 90424ea0 lbu r2,0x4ea0(r2) r2 = Max Map Y       
 +
001798dc: 920d0048 lbu r13,0x0048(r16) r13 = Caster Y       
 +
001798e0: 18400049 blez r2,0x00179a08 Exit if Max Y is negative     
 +
001798e4: 00004821 addu r9,r0,r0 r9 = Y Counter       
 +
001798e8: 3c108019 lui r16,0x8019            
 +
001798ec: 2610f8cc addiu r16,r16,0xf8cc r16 = Tile Data Array (18f8cc)     
 +
001798f0: 306e00ff andi r14,r3,0x00ff r14 = CasterHeight2 (Caster's effective height, times 2)   
 +
001798f4: 322500ff andi r5,r17,0x00ff r5 = Weapon Range       
 +
001798f8: 340f0001 ori r15,r0,0x0001 r15 = 0x0001         
 +
001798fc: 01a9102a slt r2,r13,r9 If Caster Y < Y Counter     
 +
00179900: 14400002 bne r2,r0,0x0017990c Branch if True         
 +
00179904: 012d5823 subu r11,r9,r13 r11 = Y Counter - Caster Y     
 +
00179908: 01a95823 subu r11,r13,r9 r11 = Caster Y - Y Counter     
 +
0017990c: 3c02800e lui r2,0x800e            
 +
00179910: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X       
 +
00179914: 00000000 nop            
 +
00179918: 18400035 blez r2,0x001799f0 Branch if Max X is negative     
 +
0017991c: 00004021 addu r8,r0,r0 r8 = X Counter       
 +
00179920: 0188102a slt r2,r12,r8 If Caster X < X Counter     
 +
00179924: 14400002 bne r2,r0,0x00179930 Branch if true         
 +
00179928: 010c1023 subu r2,r8,r12 r2 = X Counter - Caster X     
 +
0017992c: 01881023 subu r2,r12,r8 r2 = Caster X - Counter X     
 +
00179930: 004b5021 addu r10,r2,r11 r10 = 2D Distance to Current Position     
 +
00179934: 29420003 slti r2,r10,0x0003 If Distance < 3 (within min range)     
 +
00179938: 14400027 bne r2,r0,0x001799d8 Branch if True (skip this XY position)     
 +
0017993c: 00000000 nop            
 +
00179940: 00003821 addu r7,r0,r0 r7 = Level Counter       
 +
00179944: 3c02800e lui r2,0x800e            
 +
00179948: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X       
 +
0017994c: 00000000 nop            
 +
00179950: 01220018 mult r9,r2 Y Counter * Max X       
 +
00179954: 00071a00 sll r3,r7,0x08            
 +
00179958: 00001012 mflo r2            
 +
0017995c: 00621821 addu r3,r3,r2 Y Counter * Max X + Level Counter   
 +
00179960: 00683021 addu r6,r3,r8 r6 = Y Counter * Max X + Level Counter + X Counter
 +
00179964: 000610c0 sll r2,r6,0x03            
 +
00179968: 00501021 addu r2,r2,r16 r2 = Current Tile Data       
 +
0017996c: 90430002 lbu r3,0x0002(r2) Current Tile's Height (int part)       
 +
00179970: 90440003 lbu r4,0x0003(r2) Current Tile's Height (halves and depth)     
 +
00179974: 90420003 lbu r2,0x0003(r2) Current Tile's Height (halves and depth)     
 +
00179978: 00031840 sll r3,r3,0x01            
 +
0017997c: 3084001f andi r4,r4,0x001f r4 = Height(halves)         
 +
00179980: 00641821 addu r3,r3,r4 r3 = Height*2 + Height(halves)       
 +
00179984: 00021142 srl r2,r2,0x05 r2 = Height(depth)         
 +
00179988: 00021040 sll r2,r2,0x01 r2 = Height(depth) * 2       
 +
0017998c: 00621821 addu r3,r3,r2 r3 = Height*2 + Halves + Depth*2     
 +
00179990: 306300ff andi r3,r3,0x00ff Cast to unsigned byte       
 +
00179994: 01c31023 subu r2,r14,r3 r2 = Caster Height*2 - Tile Height*2     
 +
00179998: 04410002 bgez r2,0x001799a4 If r2 is negative:       
 +
0017999c: 00000000 nop            
 +
001799a0: 24420003 addiu r2,r2,0x0003 > r2 += 0x0003 (causes negatives to round up)   
 +
001799a4: 00021083 sra r2,r2,0x02 r2 = trunc(r2 / 4) (height effect on range)   
 +
001799a8: 01421023 subu r2,r10,r2 r2 = Distance - HeightEffect       
 +
001799ac: 00a2102a slt r2,r5,r2 If Weapon Range < Distance - HeightEffect     
 +
001799b0: 14400006 bne r2,r0,0x001799cc Branch if True (Effective distance is still too high.)   
 +
001799b4: 24e70001 addiu r7,r7,0x0001 Level Counter++         
 +
001799b8: 00061080 sll r2,r6,0x02            
 +
001799bc: 00461021 addu r2,r2,r6 r2 = Current Tile Index       
 +
001799c0: 3c018019 lui r1,0x8019            
 +
001799c4: 00220821 addu r1,r1,r2            
 +
001799c8: a02f2dd8 sb r15,0x2dd8(r1) AoE = 1 to Current Tile (Tile is part of Range) 
 +
001799cc: 28e20002 slti r2,r7,0x0002 If Level Counter < 2       
 +
001799d0: 1440ffdc bne r2,r0,0x00179944 Loop if True (Repeat for High Tile)     
 +
001799d4: 00000000 nop            
 +
001799d8: 3c02800e lui r2,0x800e            
 +
001799dc: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X       
 +
001799e0: 25080001 addiu r8,r8,0x0001 X Counter++         
 +
001799e4: 0102102a slt r2,r8,r2 If X Counter < Max X     
 +
001799e8: 1440ffce bne r2,r0,0x00179924 Loop if True         
 +
001799ec: 0188102a slt r2,r12,r8 If Caster X < X Counter     
 +
001799f0: 3c02800e lui r2,0x800e            
 +
001799f4: 90424ea0 lbu r2,0x4ea0(r2) r2 = Max Map Y       
 +
001799f8: 25290001 addiu r9,r9,0x0001 Y Counter++         
 +
001799fc: 0122102a slt r2,r9,r2 If Y Counter < Max Y     
 +
00179a00: 1440ffbf bne r2,r0,0x00179900 Loop if True         
 +
00179a04: 01a9102a slt r2,r13,r9 If Caster Y < Y Counter     
 +
00179a08: 8fbf0028 lw r31,0x0028(r29)            
 +
00179a0c: 8fb10024 lw r17,0x0024(r29)            
 +
00179a10: 8fb00020 lw r16,0x0020(r29)            
 +
00179a14: 27bd0030 addiu r29,r29,0x0030            
 +
00179a18: 03e00008 jr r31            
 +
00179a1c: 00000000 nop

Latest revision as of 01:19, 30 March 2025

Computes and marks the tiles within range of a longbow attack.

Iterates through all tiles on the map.

  • If the tile is within 3 squares of the caster, skip.
  • Calculate the height effect on range: [(casterHeight - tileHeight)/4].
  • Checks effective distance + height effect against weapon range.
  • Marks tiles within effective range.
Calculate Arc Range
r4 = Caster Data
r5 = Weapon Range
001798b0: 27bdffd0 addiu r29,r29,0xffd0				            
001798b4: afb00020 sw r16,0x0020(r29)				            
001798b8: 00808021 addu r16,r4,r0				r16 = Caster Data         
001798bc: afb10024 sw r17,0x0024(r29)				            
001798c0: afbf0028 sw r31,0x0028(r29)				            
001798c4: 0c05e5ed jal 0x001797b4				Height vs Water and Float Routine      
001798c8: 00a08821 addu r17,r5,r0				r17 = Weapon Range         
001798cc: 00401821 addu r3,r2,r0				r3 = Height Value/Depth (Return)        
001798d0: 920c0047 lbu r12,0x0047(r16)				r12 = Caster X         
001798d4: 3c02800e lui r2,0x800e				            
001798d8: 90424ea0 lbu r2,0x4ea0(r2)				r2 = Max Map Y        
001798dc: 920d0048 lbu r13,0x0048(r16)				r13 = Caster Y         
001798e0: 18400049 blez r2,0x00179a08				Exit if Max Y is negative       
001798e4: 00004821 addu r9,r0,r0				r9 = Y Counter         
001798e8: 3c108019 lui r16,0x8019				            
001798ec: 2610f8cc addiu r16,r16,0xf8cc				r16 = Tile Data Array (18f8cc)       
001798f0: 306e00ff andi r14,r3,0x00ff				r14 = CasterHeight2 (Caster's effective height, times 2)     
001798f4: 322500ff andi r5,r17,0x00ff				r5 = Weapon Range         
001798f8: 340f0001 ori r15,r0,0x0001				r15 = 0x0001          
001798fc: 01a9102a slt r2,r13,r9				If Caster Y < Y Counter       
00179900: 14400002 bne r2,r0,0x0017990c				Branch if True          
00179904: 012d5823 subu r11,r9,r13				r11 = Y Counter - Caster Y      
00179908: 01a95823 subu r11,r13,r9				r11 = Caster Y - Y Counter      
0017990c: 3c02800e lui r2,0x800e				            
00179910: 90424e9c lbu r2,0x4e9c(r2)				r2 = Max Map X        
00179914: 00000000 nop 				            
00179918: 18400035 blez r2,0x001799f0				Branch if Max X is negative       
0017991c: 00004021 addu r8,r0,r0				r8 = X Counter         
00179920: 0188102a slt r2,r12,r8				If Caster X < X Counter       
00179924: 14400002 bne r2,r0,0x00179930				Branch if true          
00179928: 010c1023 subu r2,r8,r12				r2 = X Counter - Caster X      
0017992c: 01881023 subu r2,r12,r8				r2 = Caster X - Counter X      
00179930: 004b5021 addu r10,r2,r11				r10 = 2D Distance to Current Position      
00179934: 29420003 slti r2,r10,0x0003				If Distance < 3 (within min range)      
00179938: 14400027 bne r2,r0,0x001799d8				Branch if True (skip this XY position)      
0017993c: 00000000 nop 				            
00179940: 00003821 addu r7,r0,r0				r7 = Level Counter         
00179944: 3c02800e lui r2,0x800e				            
00179948: 90424e9c lbu r2,0x4e9c(r2)				r2 = Max Map X        
0017994c: 00000000 nop 				            
00179950: 01220018 mult r9,r2					Y Counter * Max X        
00179954: 00071a00 sll r3,r7,0x08				            
00179958: 00001012 mflo r2				            
0017995c: 00621821 addu r3,r3,r2				Y Counter * Max X + Level Counter     
00179960: 00683021 addu r6,r3,r8				r6 = Y Counter * Max X + Level Counter + X Counter
00179964: 000610c0 sll r2,r6,0x03				            
00179968: 00501021 addu r2,r2,r16				r2 = Current Tile Data        
0017996c: 90430002 lbu r3,0x0002(r2)				Current Tile's Height (int part)        
00179970: 90440003 lbu r4,0x0003(r2)				Current Tile's Height (halves and depth)       
00179974: 90420003 lbu r2,0x0003(r2)				Current Tile's Height (halves and depth)       
00179978: 00031840 sll r3,r3,0x01				            
0017997c: 3084001f andi r4,r4,0x001f				r4 = Height(halves)          
00179980: 00641821 addu r3,r3,r4				r3 = Height*2 + Height(halves)        
00179984: 00021142 srl r2,r2,0x05				r2 = Height(depth)          
00179988: 00021040 sll r2,r2,0x01				r2 = Height(depth) * 2        
0017998c: 00621821 addu r3,r3,r2				r3 = Height*2 + Halves + Depth*2      
00179990: 306300ff andi r3,r3,0x00ff				Cast to unsigned byte         
00179994: 01c31023 subu r2,r14,r3				r2 = Caster Height*2 - Tile Height*2      
00179998: 04410002 bgez r2,0x001799a4				If r2 is negative:         
0017999c: 00000000 nop 				            
001799a0: 24420003 addiu r2,r2,0x0003				> r2 += 0x0003 (causes negatives to round up)    
001799a4: 00021083 sra r2,r2,0x02				r2 = trunc(r2 / 4) (height effect on range)    
001799a8: 01421023 subu r2,r10,r2				r2 = Distance - HeightEffect        
001799ac: 00a2102a slt r2,r5,r2					If Weapon Range < Distance - HeightEffect      
001799b0: 14400006 bne r2,r0,0x001799cc				Branch if True (Effective distance is still too high.)    
001799b4: 24e70001 addiu r7,r7,0x0001				Level Counter++           
001799b8: 00061080 sll r2,r6,0x02				            
001799bc: 00461021 addu r2,r2,r6				r2 = Current Tile Index        
001799c0: 3c018019 lui r1,0x8019				            
001799c4: 00220821 addu r1,r1,r2				            
001799c8: a02f2dd8 sb r15,0x2dd8(r1)				AoE = 1 to Current Tile (Tile is part of Range)  
001799cc: 28e20002 slti r2,r7,0x0002				If Level Counter < 2        
001799d0: 1440ffdc bne r2,r0,0x00179944				Loop if True (Repeat for High Tile)      
001799d4: 00000000 nop 				            
001799d8: 3c02800e lui r2,0x800e				            
001799dc: 90424e9c lbu r2,0x4e9c(r2)				r2 = Max Map X        
001799e0: 25080001 addiu r8,r8,0x0001				X Counter++           
001799e4: 0102102a slt r2,r8,r2					If X Counter < Max X       
001799e8: 1440ffce bne r2,r0,0x00179924				Loop if True          
001799ec: 0188102a slt r2,r12,r8				If Caster X < X Counter       
001799f0: 3c02800e lui r2,0x800e				            
001799f4: 90424ea0 lbu r2,0x4ea0(r2)				r2 = Max Map Y        
001799f8: 25290001 addiu r9,r9,0x0001				Y Counter++           
001799fc: 0122102a slt r2,r9,r2					If Y Counter < Max Y       
00179a00: 1440ffbf bne r2,r0,0x00179900				Loop if True          
00179a04: 01a9102a slt r2,r13,r9				If Caster Y < Y Counter       
00179a08: 8fbf0028 lw r31,0x0028(r29)				            
00179a0c: 8fb10024 lw r17,0x0024(r29)				            
00179a10: 8fb00020 lw r16,0x0020(r29)				            
00179a14: 27bd0030 addiu r29,r29,0x0030				            
00179a18: 03e00008 jr r31				            
00179a1c: 00000000 nop