Arc Range Calculation Routine
Jump to navigation
Jump to search
- ASM duplicate of Set initial panels.
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: 00000000: 27bdffd0 addiu r29,r29,-0x0030 00000004: afb00020 sw r16,0x0020(r29) 00000008: 00808021 addu r16,r4,r0 r16 = Caster Data 0000000c: afb10024 sw r17,0x0024(r29) 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 Array (18f8cc) 00000040: 306e00ff andi r14,r3,0x00ff r14 = CasterHeight2 (Caster's effective height, times 2) 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 = 2D Distance to Current Position 00000084: 29420003 slti r2,r10,0x0003 If Distance < 3 (within min range) 00000088: 14400027 bne r2,r0,0x00000128 Branch if True (skip this XY position) 0000008c: 00000000 nop 00000090: 00003821 addu r7,r0,r0 r7 = Level 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 + Level Counter 000000b0: 00683021 addu r6,r3,r8 r6 = Y Counter * Max X + Level Counter + X Counter 000000b4: 000610c0 sll r2,r6,0x03 000000b8: 00501021 addu r2,r2,r16 r2 = Current Tile Data 000000bc: 90430002 lbu r3,0x0002(r2) Current Tile's Height (int part) 000000c0: 90440003 lbu r4,0x0003(r2) Current Tile's Height (halves and depth) 000000c4: 90420003 lbu r2,0x0003(r2) Current Tile's Height (halves and depth) 000000c8: 00031840 sll r3,r3,0x01 000000cc: 3084001f andi r4,r4,0x001f r4 = Height(halves) 000000d0: 00641821 addu r3,r3,r4 r3 = Height*2 + Height(halves) 000000d4: 00021142 srl r2,r2,0x05 r2 = Height(depth) 000000d8: 00021040 sll r2,r2,0x01 r2 = Height(depth) * 2 000000dc: 00621821 addu r3,r3,r2 r3 = Height*2 + Halves + Depth*2 000000e0: 306300ff andi r3,r3,0x00ff Cast to unsigned byte 000000e4: 01c31023 subu r2,r14,r3 r2 = Caster Height*2 - Tile Height*2 000000e8: 04410002 bgez r2,0x000000f4 If r2 is negative: 000000ec: 00000000 nop 000000f0: 24420003 addiu r2,r2,0x0003 > r2 += 0x0003 (causes negatives to round up) 000000f4: 00021083 sra r2,r2,0x02 r2 = trunc(r2 / 4) (height effect on range) 000000f8: 01421023 subu r2,r10,r2 r2 = Distance - HeightEffect 000000fc: 00a2102a slt r2,r5,r2 If Weapon Range < Distance - HeightEffect 00000100: 14400006 bne r2,r0,0x0000011c Branch if True (Effective distance is still too high.) 00000104: 24e70001 addiu r7,r7,0x0001 Level Counter++ 00000108: 00061080 sll r2,r6,0x02 0000010c: 00461021 addu r2,r2,r6 r2 = Current Tile Index 00000110: 3c018019 lui r1,0x8019 00000114: 00220821 addu r1,r1,r2 00000118: a02f2dd8 sb r15,0x2dd8(r1) AoE = 1 to Current Tile (Tile is part of Range) 0000011c: 28e20002 slti r2,r7,0x0002 If Level Counter < 2 00000120: 1440ffdc bne r2,r0,0x00000094 Loop 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 Loop 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 Loop 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