List and Sort Targeted Units

From Final Fantasy Hacktics Wiki
Revision as of 20:34, 15 February 2022 by Orkney (talk | contribs) (Orkney moved page 0017d850 - 0017da1c to List and Sort Targeted Units)
Jump to navigation Jump to search
0017d850 - 0017da1c
 
Parameters : r5 = Attacker data pointer
             r4 = Previous routine data pointer (returns the list)
			  
Store : List of targeted units on r4.
       (Unit will be ordered according to their proximity to attacker if 0x8018f4f8 <> 0x00)
--------------------------------------------------------------------------------------------		
0017d850: 27bdff60 addiu r29,r29,-0x00a0    |
0017d854: afb5008c sw r21,0x008c(r29)       |
0017d858: 0080a821 addu r21,r4,r0           |r21 = PR stack = Targeted unit list pointer
0017d85c: afb1007c sw r17,0x007c(r29)       |
0017d860: 00008821 addu r17,r0,r0           |r17 = 0x00 (Targeted unit counter)
0017d864: afb20080 sw r18,0x0080(r29)       |
0017d868: 00009021 addu r18,r0,r0           |r18 = 0x00 (Unit counter)
0017d86c: afb40088 sw r20,0x0088(r29)       |
0017d870: 27b40010 addiu r20,r29,0x0010     |r20 = Stack 0x10  = Proximity data between Attacker abd Target (order of data patch r21 order)
0017d874: afb30084 sw r19,0x0084(r29)       |
0017d878: 00009821 addu r19,r0,r0           |r19 = 0x00 (Next loop unit data offset + 0x1c0 each iteration)
0017d87c: afbf0098 sw r31,0x0098(r29)       |
0017d880: afb70094 sw r23,0x0094(r29)       |
0017d884: afb60090 sw r22,0x0090(r29)       |
0017d888: afb00078 sw r16,0x0078(r29)       |
0017d88c: 90b70047 lbu r23,0x0047(r5)       |r23 = Attacker X coord
0017d890: 90b60048 lbu r22,0x0048(r5)       |r22 = Attacker Y coord
0017d894: 3c028019 lui r2,0x8019            @LOOP through all units
0017d898: 244208cc addiu r2,r2,0x08cc            |r2 = 0x801908cc (start of unit data pointer)
0017d89c: 02628021 addu r16,r19,r2               |r16 = This iteration unit data pointer
0017d8a0: 92030001 lbu r3,0x0001(r16)            |r3 = This Unit ID
0017d8a4: 340200ff ori r2,r0,0x00ff              |r2 = 0x00ff
0017d8a8: 10620042 beq r3,r2,0x0017d9b4          #If Unit ID is not 0x0ff /Else unit doesn't exists , branch to next iteration
0017d8ac: 02402021 addu r4,r18,r0                    |r4 = Unit ID counter
0017d8b0: 0c05ef74 jal 0x0017bdd0                    |-->Check_if_Unit_can_be_Targeted return r2 = 0x01 if this unit is NOT targetable, else 0x00 + Unit tile ID on r5 0x00
0017d8b4: 27a50068 addiu r5,r29,0x0068               |r5 = Stack 0x68 (will received this unit Tile ID - in routine above)
0017d8b8: 1440003e bne r2,r0,0x0017d9b4              #If unit is targetable /Else branch to next iteration
0017d8bc: 00000000 nop                                   | 
0017d8c0: 8fa20068 lw r2,0x0068(r29)                     |r2 = This unit Tile ID
0017d8c4: 00000000 nop                                   |
0017d8c8: 000210c0 sll r2,r2,0x03                        |r2 = This unit Tile ID * 8
0017d8cc: 3c018019 lui r1,0x8019                         |
0017d8d0: 00220821 addu r1,r1,r2                         |r1 = 0x8019 0000 + Tile offset
0017d8d4: 9022f8d1 lbu r2,-0x072f(r1)                    |r2 = This unit tile ID [0x05]   0x8018f8cc (tile data) + 0x05 + Tile offset
0017d8d8: 00000000 nop                                   |
0017d8dc: 30420080 andi r2,r2,0x0080                     |r2 = 0x80 if Tile has green panel flag enabled (unit here is beeing targeted)
0017d8e0: 10400034 beq r2,r0,0x0017d9b4                  #If Unit is targeted /Else branch to next iteration
0017d8e4: 00000000 nop                                       | 
0017d8e8: 3c028019 lui r2,0x8019                             |r2 = 0x8019
0017d8ec: 8c42f4f8 lw r2,-0x0b08(r2)                         |r2 = [8018f4f8] 0x01 if linear ?
0017d8f0: 00000000 nop                                       |
0017d8f4: 1040002b beq r2,r0,0x0017d9a4                      #if [8018f4f8] <> 0x00 (=linear ?) /Else skip re-order loops
0017d8f8: 00000000 nop                                           | 
0017d8fc: 92020047 lbu r2,0x0047(r16)                            |r2 = This unit X coord
0017d900: 00000000 nop                                           |
0017d904: 02e21823 subu r3,r23,r2                                |r3 = Attacker's X coord - This Unit's X coord = [Delta X]
0017d908: 04610002 bgez r3,0x0017d914                            #If [Delta X] is < 0x00
0017d90c: 00000000 nop                                               | 
0017d910: 00031823 subu r3,r0,r3                                     |r3 = positive value of [Delta X]
0017d914: 92020048 lbu r2,0x0048(r16)                            |r2 = This Unit Y coord
0017d918: 00000000 nop                                           |
0017d91c: 02c21023 subu r2,r22,r2                                |r2 = [Delta Y]
0017d920: 04410002 bgez r2,0x0017d92c                            #If [Delta Y] is < 0x00
0017d924: 00002821 addu r5,r0,r0                                 |r5 = 0x00
0017d928: 00021023 subu r2,r0,r2                                     |r2 = positive value of [Delta Y]
0017d92c: 1a20000b blez r17,0x0017d95c                           #If Not first Targeted unit (r17 > 0x00) /Else avoid next loop
0017d930: 00623821 addu r7,r3,r2                                 |r7 = Abs[Delta X] + Abs[Delta Y] = [Attacker proximity]  (since linear) Abs = absolute value
0017d934: 02801821 addu r3,r20,r0                                    |r3 = Proximity list
0017d938: 8c620000 lw r2,0x0000(r3)                                  @LOOP2 r2 = Listed Targeted Unit [Attacker proximity] (change each iteration) Set This Unit offset in targeted list (based on proximity)
0017d93c: 00000000 nop                                                   |
0017d940: 00e2102a slt r2,r7,r2                                          |r2 = 0x01 Main Iteration unit [Attacker proximity] < this Targeted list iteration unit [Attacker proximity]
0017d944: 14400006 bne r2,r0,0x0017d960                                  #If  Main iteration unit is farther than Unit on list /Else exit loop2 with r5 = Offset of the 1st unit on list farther than attacker
0017d948: 28a20014 slti r2,r5,0x0014                                     |r2 = 0x01 if counter < 0x14
0017d94c: 24a50001 addiu r5,r5,0x0001                                        |r5 = list counter + 0x01
0017d950: 00b1102a slt r2,r5,r17                                         |r2 = 0x01 if list counter < Targeted unit counter (number of units on list)
0017d954: 1440fff8 bne r2,r0,0x0017d938                              Λ Loop while there is units left for proximity check
0017d958: 24630004 addiu r3,r3,0x0004                                    |r3 = Proximity list offset counter (+0x04 each iteration)
0017d95c: 28a20014 slti r2,r5,0x0014                             |r2 = 0x01 if list counter < 0x14
0017d960: 1040000c beq r2,r0,0x0017d994                          #if This Unit offset in Targeted unit list  < 0x14 /Else avoid loop 3 (invalid counter, or last unit)
0017d964: 34060014 ori r6,r0,0x0014                              |r6 = 0x14
0017d968: 26840050 addiu r4,r20,0x0050                               |r4 = End of proximity list
0017d96c: 26a30014 addiu r3,r21,0x0014                               |r3 = End of Targeted unit list
0017d970: 9062ffff lbu r2,-0x0001(r3)                                @LOOP 3 r2 = n -1 Listed Targeted Unit (go backward during loop) Reorder units according to their proximity
0017d974: 24c6ffff addiu r6,r6,-0x0001                                   |r6 = unit counter -1
0017d978: a0620000 sb r2,0x0000(r3)                                      |Store n-1 Targeted Unit at offset n (shift unit towards the end of targeted unit list)
0017d97c: 8c82fffc lw r2,-0x0004(r4)                                     |r2 = n-1 Targeted unit [Proximity]
0017d980: 2463ffff addiu r3,r3,-0x0001                                   |r3 = Targeted unit List offset counter (-0x01 each oteration)
0017d984: ac820000 sw r2,0x0000(r4)                                      |Store n-1 Targeted Unit [Proximity] at offset n off proximity data list
0017d988: 00a6102a slt r2,r5,r6                                          |r2 = 0x01 if r5 < r6 (start at 0x14 and decrease each iteration)
0017d98c: 1440fff8 bne r2,r0,0x0017d970                              Λ Loop until the Main Loop unit offset in the Targeted list is reached
0017d990: 2484fffc addiu r4,r4,-0x0004                                   |r4 = Stack offset (-0x04 rach iteration)
0017d994: 00051080 sll r2,r5,0x02                                |r2 = This Unit offset in Targeted List * 4 (= offset for proximity data list)
0017d998: 00541021 addu r2,r2,r20                                |r2 = This unit proximity data list pointer
0017d99c: 0805f66a j 0x0017d9a8                                  >>jump just below keeping r5
0017d9a0: ac470000 sw r7,0x0000(r2)                              |store This Unit [Attacker Proximity] in proximity list
0017d9a4: 02202821 addu r5,r17,r0                            #Else [8018f4f8] = 0x00 r5 = Targeted Unit Counter
0017d9a8: 02a51021 addu r2,r21,r5                            |r2 = Targeted Unit List pointer offset (offset inherited from targeted unit counter)
0017d9ac: a0520000 sb r18,0x0000(r2)                         |Store Unit ID on Targeted Unit List
0017d9b0: 26310001 addiu r17,r17,0x0001                      |r17 = r17 + 0x01 (Targeted Unit counter)
0017d9b4: 26520001 addiu r18,r18,0x0001          |r18 = Unit counter (= unit ID)
0017d9b8: 2a420015 slti r2,r18,0x0015            |r2 = 0x01 if counter < 0x15
0017d9bc: 1440ffb5 bne r2,r0,0x0017d894     Λ Loop while counter < 0x15
0017d9c0: 267301c0 addiu r19,r19,0x01c0          |r19 = Unit Data offset (+0x1c0 each iteration)
0017d9c4: 2a220015 slti r2,r17,0x0015       |r2 = 0x01 if Targeted unit counter < 0x15
0017d9c8: 10400009 beq r2,r0,0x0017d9f0     #If Number of targeted units is valid (<0x15) /Else branch to END
0017d9cc: 02201021 addu r2,r17,r0           |r2 = Number of targeted units
0017d9d0: 340500ff ori r5,r0,0x00ff              |r5 = 0x00ff
0017d9d4: 02351821 addu r3,r17,r21               |r3 = Last unit offset on Targeted unit List
0017d9d8: 26a40015 addiu r4,r21,0x0015           |r4 = Last available offset on targeted unit list
0017d9dc: a0650000 sb r5,0x0000(r3)              @LOOP Store 0xFF on non used offsets
0017d9e0: 24630001 addiu r3,r3,0x0001                |r3 = Targeted unit List offset (+0x01 each iteration)
0017d9e4: 0064102a slt r2,r3,r4                      |r2 = 0x01 while counter < max offset
0017d9e8: 1440fffc bne r2,r0,0x0017d9dc          Λ Loop while max list offset is not reached
0017d9ec: 02201021 addu r2,r17,r0                |r2 = Number of targeted units
0017d9f0: 8fbf0098 lw r31,0x0098(r29)       END
0017d9f4: 8fb70094 lw r23,0x0094(r29)       
0017d9f8: 8fb60090 lw r22,0x0090(r29)       
0017d9fc: 8fb5008c lw r21,0x008c(r29)       
0017da00: 8fb40088 lw r20,0x0088(r29)       
0017da04: 8fb30084 lw r19,0x0084(r29)       
0017da08: 8fb20080 lw r18,0x0080(r29)       
0017da0c: 8fb1007c lw r17,0x007c(r29)       
0017da10: 8fb00078 lw r16,0x0078(r29)       
0017da14: 27bd00a0 addiu r29,r29,0x00a0     
0017da18: 03e00008 jr r31                   
0017da1c: 00000000 nop

Notes

Main Loop - All units
- If Unit ID = 0xff  --> go to next iteration
- If Unit is not targetable  cf. Check_if_Unit_can_be_Targeted  --> go to next iteration
- If Unit is not on a tile with "green panel" flag  --> go to next iteration

If all the above checks are false 
Unit will be added to the List of Targeted Units
If 0x8018f4f8 <> 0x00 Then the units will be ordered according to their proximity to attacker.
(Proximity is Absolute[Attacker X coord - Target X coord] + same thing with Y coord.)
The routine will go through two succesive loops
  - First loop will check listed units until finding a unit farther from attacker than the main loop unit, keeping his position in memory      
  - Second loop will shift all units beyond this position in the list toward the end of the list and then will insert the main loop unit in the loop.

End section :
Last loop while store 0xff in all the non occuped slot in targeted unit list.

Return location

0017d078: Main_ability_loading_routine?
0017e030: Big..._Contains_Hamedo_check