• Welcome to Final Fantasy Hacktics. Please login or sign up.
 

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Dokurider

1
PSX FFT Hacking / AI and AoE ASMs
June 10, 2020, 07:19:44 pm
Long time no see, FFH. I'm remaking my old ASM thread. This post will contain links to all future ASMs published as well as a current XML of all of my hacks.
Stat and Golem Priority

Dokurider.xml
2
Hey guys, I'm going to spend some time looking into the AI's code. I don't know exactly how far I'll get, but I already have some great results.

Unit Target Priority

Located in: AI End of turn, in between turn, etc. (0019d37c)


AI End of turn, in between turn, etc.


0019d37c: 3c02801a lui r2,0x801a
0019d380: 90420d7b lbu r2,0x0d7b(r2)
0019d384: 27bdffe0 addiu r29,r29,0xffe0
0019d388: afb20018 sw r18,0x0018(r29)
0019d38c: 3c12801a lui r18,0x801a
0019d390: 2652f3c4 addiu r18,r18,0xf3c4
0019d394: afbf001c sw r31,0x001c(r29)
0019d398: afb10014 sw r17,0x0014(r29)
0019d39c: 1040000f beq r2,r0,0x0019d3dc branch if able to act
0019d3a0: afb00010 sw r16,0x0010(r29)

if unable to act

0019d3a4: 3c02801a lui r2,0x801a
0019d3a8: 904202b2 lbu r2,0x02b2(r2) Load ?
0019d3ac: 00000000 nop
0019d3b0: 1040000a beq r2,r0,0x0019d3dc Branch if ? = 0
0019d3b4: 00000000 nop
0019d3b8: 0c0678de jal 0x0019e378 Transfer AI Data to Unit Data
0019d3bc: 34040001 ori r4,r0,0x0001 r4 = 1 (extended transfer)
0019d3c0: 3c03801a lui r3,0x801a
0019d3c4: 906302b2 lbu r3,0x02b2(r3) Load ?
0019d3c8: 34020001 ori r2,r0,0x0001
0019d3cc: 10620062 beq r3,r2,0x0019d558 Branch if ? = 1
0019d3d0: 34020002 ori r2,r0,0x0002
0019d3d4: 106200b7 beq r3,r2,0x0019d6b4 Branch if ? = 2
0019d3d8: 00000000 nop

if able to act

0019d3dc: 0c0076ea jal 0x0001dba8 (Calculate Cycles Passed?)
0019d3e0: 34040001 ori r4,r0,0x0001 r4 = 1
0019d3e4: 284201b9 slti r2,r2,0x01b9
0019d3e8: 14400004 bne r2,r0,0x0019d3fc Branch if Cycles Passed? < 0x1b9
0019d3ec: 00000000 nop
0019d3f0: a2400eee sb r0,0x0eee(r18) Store ? = 0
0019d3f4: 080676d9 j 0x0019db64
0019d3f8: 2402ffff addiu r2,r0,0xffff r2 = -1 (fail)
0019d3fc: 0c067858 jal 0x0019e160 Transfer Unit Data to AI Data
0019d400: 00002021 addu r4,r0,r0 r4 = 0 (Extended transfer)
0019d404: a24019bc sb r0,0x19bc(r18) Store ? = 0
0019d408: 34110014 ori r17,r0,0x0014 Counter = 0x14
0019d40c: 26420014 addiu r2,r18,0x0014 r2 = AI Data Pointer + 0x14
0019d410: a0400e18 sb r0,0x0e18(r2) Store ? = 0
0019d414: 2631ffff addiu r17,r17,0xffff Counter --
0019d418: 0621fffd bgez r17,0x0019d410 Branch if Counter >= 0
0019d41c: 2442ffff addiu r2,r2,0xffff Pointer --
0019d420: 92430014 lbu r3,0x0014(r18) Load ?
0019d424: 340200ff ori r2,r0,0x00ff r2 = FF
0019d428: a6400032 sh r0,0x0032(r18) Store ? = 0
0019d42c: 10600017 beq r3,r0,0x0019d48c Branch if Targeting Flags haven't been set?
0019d430: a2420031 sb r2,0x0031(r18) Store Base Hit%? = 255
0019d434: 9243001d lbu r3,0x001d(r18) Load Skillset
0019d438: 00000000 nop
0019d43c: 10600029 beq r3,r0,0x0019d4e4 Branch if Skillset = 0
0019d440: 34020002 ori r2,r0,0x0002 r2 = 2
0019d444: 1062002a beq r3,r2,0x0019d4f0 Branch if Skillset = Defend
0019d448: 00000000 nop
0019d44c: 2650001c addiu r16,r18,0x001c r16 = Acting Unit's ID Pointer
0019d450: 0c05f0f7 jal 0x0017c3dc Attack Preparation Setup
0019d454: 02002021 addu r4,r16,r0 r4 = Acting Unit's ID Pointer
0019d458: 34030001 ori r3,r0,0x0001
0019d45c: 14430005 bne r2,r3,0x0019d474 Branch if CT = 0
0019d460: 00000000 nop
0019d464: 0c06772f jal 0x0019dcbc              Call AI Ability Processing
0019d468: 02002021 addu r4,r16,r0 r4 = Acting Unit's ID Pointer
0019d46c: 104001b9 beq r2,r0,0x0019db54
0019d470: 00000000 nop
0019d474: 8e4317f8 lw r3,0x17f8(r18) load acting units data
0019d478: 34020001 ori r2,r0,0x0001
0019d47c: 0c0676e0 jal 0x0019db80 0019db80 - 0019dca8
0019d480: a0620188 sb r2,0x0188(r3)
0019d484: 08067538 j 0x0019d4e0
0019d488: 00000000 nop
0019d48c: 0c0676e0 jal 0x0019db80 0019db80 - 0019dca8
0019d490: 00000000 nop
0019d494: 9243001d lbu r3,0x001d(r18)
0019d498: 00000000 nop
0019d49c: 10600011 beq r3,r0,0x0019d4e4
0019d4a0: 34020002 ori r2,r0,0x0002
0019d4a4: 10620012 beq r3,r2,0x0019d4f0
0019d4a8: 00000000 nop
0019d4ac: 2650001c addiu r16,r18,0x001c
0019d4b0: 0c05f0f7 jal 0x0017c3dc
0019d4b4: 02002021 addu r4,r16,r0
0019d4b8: 34030001 ori r3,r0,0x0001
0019d4bc: 14430005 bne r2,r3,0x0019d4d4
0019d4c0: 00000000 nop
0019d4c4: 0c06772f jal 0x0019dcbc 0019dcbc - 0019dd88
0019d4c8: 02002021 addu r4,r16,r0
0019d4cc: 104001a1 beq r2,r0,0x0019db54
0019d4d0: 00000000 nop
0019d4d4: 8e4317f8 lw r3,0x17f8(r18)
0019d4d8: 34020001 ori r2,r0,0x0001
0019d4dc: a0620188 sb r2,0x0188(r3)
0019d4e0: 9243001d lbu r3,0x001d(r18)
0019d4e4: 34020002 ori r2,r0,0x0002
0019d4e8: 14620009 bne r3,r2,0x0019d510
0019d4ec: 00000000 nop
0019d4f0: 92440e2e lbu r4,0x0e2e(r18)
0019d4f4: 0c060f80 jal 0x00183e00                 Another intermediate routine
0019d4f8: 00000000 nop
0019d4fc: 8e4317f8 lw r3,0x17f8(r18)
0019d500: 34020064 ori r2,r0,0x0064
0019d504: a2420031 sb r2,0x0031(r18)
0019d508: 34020001 ori r2,r0,0x0001
0019d50c: a0620188 sb r2,0x0188(r3)
0019d510: 9242001d lbu r2,0x001d(r18)
0019d514: 00000000 nop
0019d518: 14400002 bne r2,r0,0x0019d524
0019d51c: 34020064 ori r2,r0,0x0064
0019d520: a2420031 sb r2,0x0031(r18)
0019d524: 92440e2e lbu r4,0x0e2e(r18)
0019d528: 0c060f1b jal 0x00183c6c                 End of Turn
0019d52c: 00000000 nop
0019d530: 3c028019 lui r2,0x8019
0019d534: 8c42f518 lw r2,-0x0ae8(r2) load in between turn control variable
0019d538: 3c038019 lui r3,0x8019
0019d53c: 8c63f51c lw r3,-0x0ae4(r3) load menu control variable?
0019d540: 3c048019 lui r4,0x8019
0019d544: 8c84f520 lw r4,-0x0ae0(r4) load active units ID?
0019d548: a6400eec sh r0,0x0eec(r18)
0019d54c: ae420ee0 sw r2,0x0ee0(r18)
0019d550: ae430ee4 sw r3,0x0ee4(r18)
0019d554: ae440ee8 sw r4,0x0ee8(r18)

? = 1

0019d558: 0c0076ea jal 0x0001dba8 0001dba8 - 0001dcec
0019d55c: 34040001 ori r4,r0,0x0001
0019d560: 28420139 slti r2,r2,0x0139
0019d564: 1040016c beq r2,r0,0x0019db18 Exit if
0019d568: 00000000 nop
0019d56c: 96420eec lhu r2,0x0eec(r18)
0019d570: 00000000 nop
0019d574: 24420001 addiu r2,r2,0x0001
0019d578: a6420eec sh r2,0x0eec(r18)
0019d57c: 96420eec lhu r2,0x0eec(r18)
0019d580: 00000000 nop
0019d584: 2c420100 sltiu r2,r2,0x0100
0019d588: 10400041 beq r2,r0,0x0019d690
0019d58c: 00000000 nop
0019d590: 0c0609fc jal 0x001827f0
0019d594: 00002021 addu r4,r0,r0
0019d598: 00408821 addu r17,r2,r0
0019d59c: 3225ff00 andi r5,r17,0xff00
0019d5a0: 323100ff andi r17,r17,0x00ff
0019d5a4: 001110c0 sll r2,r17,0x03
0019d5a8: 00511023 subu r2,r2,r17
0019d5ac: 00021180 sll r2,r2,0x06
0019d5b0: 3c038019 lui r3,0x8019
0019d5b4: 246308cc addiu r3,r3,0x08cc
0019d5b8: 00438021 addu r16,r2,r3
0019d5bc: 3402ff00 ori r2,r0,0xff00
0019d5c0: 10a20033 beq r5,r2,0x0019d690
0019d5c4: 34020300 ori r2,r0,0x0300
0019d5c8: 14a20005 bne r5,r2,0x0019d5e0
0019d5cc: 34020200 ori r2,r0,0x0200
0019d5d0: 0c062f82 jal 0x0018be08
0019d5d4: 02202021 addu r4,r17,r0
0019d5d8: 08067590 j 0x0019d640
0019d5dc: 00008821 addu r17,r0,r0
0019d5e0: 14a2000d bne r5,r2,0x0019d618
0019d5e4: 34020100 ori r2,r0,0x0100
0019d5e8: 0c06772f jal 0x0019dcbc 0019dcbc - 0019dd88
0019d5ec: 2604016e addiu r4,r16,0x016e
0019d5f0: 1040014f beq r2,r0,0x0019db30
0019d5f4: 340200ff ori r2,r0,0x00ff
0019d5f8: a202015d sb r2,0x015d(r16) store no ability CT
0019d5fc: 92020058 lbu r2,0x0058(r16) load statii
0019d600: 920301bb lbu r3,0x01bb(r16) load status infliction
0019d604: 304200f6 andi r2,r2,0x00f6 remove performing/charging
0019d608: 306300f6 andi r3,r3,0x00f6 remove performing/charging
0019d60c: a2020058 sb r2,0x0058(r16) store new status
0019d610: 0806758f j 0x0019d63c
0019d614: a20301bb sb r3,0x01bb(r16) store new status infliction
0019d618: 14a20008 bne r5,r2,0x0019d63c
0019d61c: 00002021 addu r4,r0,r0
0019d620: 0c067c57 jal 0x0019f15c 0019f15c - 0019f254
0019d624: 02202821 addu r5,r17,r0
0019d628: 10400003 beq r2,r0,0x0019d638
0019d62c: 02511821 addu r3,r18,r17
0019d630: 34020001 ori r2,r0,0x0001
0019d634: a0620e18 sb r2,0x0e18(r3)
0019d638: a2000186 sb r0,0x0186(r16) store turn over
0019d63c: 00008821 addu r17,r0,r0
0019d640: 340400ff ori r4,r0,0x00ff
0019d644: 3c038019 lui r3,0x8019
0019d648: 246308cc addiu r3,r3,0x08cc
0019d64c: 00608021 addu r16,r3,r0
0019d650: 92020001 lbu r2,0x0001(r16) load unit ID
0019d654: 00000000 nop
0019d658: 10440006 beq r2,r4,0x0019d674 branch if doesn't exist
0019d65c: 00000000 nop
0019d660: 92020058 lbu r2,0x0058(r16) load status
0019d664: 00000000 nop
0019d668: 30420009 andi r2,r2,0x0009
0019d66c: 14400006 bne r2,r0,0x0019d688 branch if charging/performing
0019d670: 34020015 ori r2,r0,0x0015
0019d674: 26310001 addiu r17,r17,0x0001
0019d678: 2a220015 slti r2,r17,0x0015
0019d67c: 1440fff3 bne r2,r0,0x0019d64c branch if counter < 0x15
0019d680: 260301c0 addiu r3,r16,0x01c0 next unit
0019d684: 34020015 ori r2,r0,0x0015
0019d688: 1622ffb3 bne r17,r2,0x0019d558 branch if counter != 0x15
0019d68c: 00000000 nop
0019d690: 8e420ee0 lw r2,0x0ee0(r18)
0019d694: 8e430ee4 lw r3,0x0ee4(r18)
0019d698: 8e440ee8 lw r4,0x0ee8(r18)
0019d69c: 3c018019 lui r1,0x8019
0019d6a0: ac22f518 sw r2,-0x0ae8(r1)
0019d6a4: 3c018019 lui r1,0x8019
0019d6a8: ac23f51c sw r3,-0x0ae4(r1)
0019d6ac: 3c018019 lui r1,0x8019
0019d6b0: ac24f520 sw r4,-0x0ae0(r1)

? = 2 (Starting turn?) Unit Priority Routine (The lower, the better)

0019d6b4: 0c0076ea jal 0x0001dba8 Derive RNG from Frame Data?
0019d6b8: 34040001 ori r4,r0,0x0001
0019d6bc: 284201b9 slti r2,r2,0x01b9 (I assume 0x01ff is the highest value?)
0019d6c0: 14400005 bne r2,r0,0x0019d6d8 Branch if you pleased the Frame RNG gods today
0019d6c4: 3c030100 lui r3,0x0100
0019d6c8: 0c067858 jal 0x0019e160 Transfer Unit Data to AI Data
0019d6cc: 34040001 ori r4,r0,0x0001
0019d6d0: 080676c9 j 0x0019db24 Basically Exit Routine (Is this why sometimes units will just skip turns?)
0019d6d4: 34020002 ori r2,r0,0x0002 (A 70/511(13.7%) chance of being screwed by the RNG in Arena lol)
0019d6d8: 8e420cb4 lw r2,0x0cb4(r18)
0019d6dc: 00000000 nop
0019d6e0: 00431024 and r2,r2,r3
0019d6e4: 10400048 beq r2,r0,0x0019d808 Skip Loop if r2 =/= 0x01000000
0019d6e8: 00008821 addu r17,r0,r0
0019d6ec: 00003021 addu r6,r0,r0
0019d6f0: 3405182c ori r5,r0,0x182c
0019d6f4: 02452021 addu r4,r18,r5 r4 = AI decision data
0019d6f8: 3c028019 lui r2,0x8019
0019d6fc: 244208cc addiu r2,r2,0x08cc
0019d700: 90830004 lbu r3,0x0004(r4) load AI settings?
0019d704: 00c28021 addu r16,r6,r2
0019d708: 306300f8 andi r3,r3,0x00f8 remove Unit needs Reviving/Unstoning, Unit is Jumping
0019d70c: a0830004 sb r3,0x0004(r4) store new flags
0019d710: 92020058 lbu r2,0x0058(r16) load status
0019d714: 00000000 nop
0019d718: 30420020 andi r2,r2,0x0020
0019d71c: 10400007 beq r2,r0,0x0019d73c branch if if not dead
0019d720: 00000000 nop
0019d724: 9202005a lbu r2,0x005a(r16) load status
0019d728: 00000000 nop
0019d72c: 30420020 andi r2,r2,0x0020
0019d730: 14400002 bne r2,r0,0x0019d73c branch if reraise
0019d734: 34620001 ori r2,r3,0x0001 add Need Revive flag
0019d738: a0820004 sb r2,0x0004(r4) store new AI setting
0019d73c: 92020059 lbu r2,0x0059(r16)
0019d740: 00000000 nop
0019d744: 30420080 andi r2,r2,0x0080
0019d748: 10400005 beq r2,r0,0x0019d760 branch if not petrified
0019d74c: 00000000 nop
0019d750: 90820004 lbu r2,0x0004(r4) load AI settings
0019d754: 00000000 nop
0019d758: 34420002 ori r2,r2,0x0002 add Need UnPetrifed flag
0019d75c: a0820004 sb r2,0x0004(r4) store flag
0019d760: 92020058 lbu r2,0x0058(r16)
0019d764: 00000000 nop
0019d768: 30420004 andi r2,r2,0x0004
0019d76c: 10400005 beq r2,r0,0x0019d784 branch if not jumping
0019d770: 00000000 nop
0019d774: 90820004 lbu r2,0x0004(r4)
0019d778: 00000000 nop
0019d77c: 34420004 ori r2,r2,0x0004 Unit is Jumping Flag
0019d780: a0820004 sb r2,0x0004(r4) store flag
0019d784: 90830004 lbu r3,0x0004(r4)
0019d788: 00000000 nop
0019d78c: 30620080 andi r2,r3,0x0080
0019d790: 14400016 bne r2,r0,0x0019d7ec Next Unit if unit is Charging/Performing?
0019d794: 00000000 nop
0019d798: 92020059 lbu r2,0x0059(r16)
0019d79c: 00000000 nop
0019d7a0: 30420080 andi r2,r2,0x0080
0019d7a4: 14400011 bne r2,r0,0x0019d7ec Next Unit if petrified
0019d7a8: 00000000 nop
0019d7ac: 92020058 lbu r2,0x0058(r16)
0019d7b0: 00000000 nop
0019d7b4: 30420020 andi r2,r2,0x0020
0019d7b8: 10400006 beq r2,r0,0x0019d7d4 branch if not dead
0019d7bc: 00000000 nop
0019d7c0: 9202005a lbu r2,0x005a(r16)
0019d7c4: 00000000 nop
0019d7c8: 30420020 andi r2,r2,0x0020
0019d7cc: 10400007 beq r2,r0,0x0019d7ec Next Unit if No Reraise
0019d7d0: 00000000 nop
0019d7d4: 9202005c lbu r2,0x005c(r16)
0019d7d8: 00000000 nop
0019d7dc: 30420001 andi r2,r2,0x0001
0019d7e0: 14400002 bne r2,r0,0x0019d7ec Next Unit if death-sentenced
0019d7e4: 34620080 ori r2,r3,0x0080 Unit needs to be dealt with flag
0019d7e8: a0820004 sb r2,0x0004(r4) store new flags
0019d7ec: 24c601c0 addiu r6,r6,0x01c0 Unit Data Pointer++
0019d7f0: 26310001 addiu r17,r17,0x0001 Unit Counter++
0019d7f4: 2a220015 slti r2,r17,0x0015
0019d7f8: 1440ffbe bne r2,r0,0x0019d6f4 perform for all units
0019d7fc: 24a50010 addiu r5,r5,0x0010 Unit AI Data++
0019d800: 080676d5 j 0x0019db54
0019d804: 00000000 nop
0019d808: 0c06772b jal 0x0019dcac 0019dcac - 0019dcb8
0019d80c: 00000000 nop
0019d810: 3c0c8019 lui r12,0x8019
0019d814: 258c3de0 addiu r12,r12,0x3de0
0019d818: 3c0d801a lui r13,0x801a
0019d81c: 8dadf3c0 lw r13,-0x0c40(r13)
0019d820: 02404821 addu r9,r18,r0 r9 = Unit AI
0019d824: 02405021 addu r10,r18,r0 r10 = Unit AI
0019d828: 00005821 addu r11,r0,r0

<Unit Priority Loop>
0019d82c: 9145198c lbu r5,0x198c(r10) load units battle ID?
0019d830: 340200ff ori r2,r0,0x00ff
0019d834: 10a2009c beq r5,r2,0x0019daa8 branch if doesn't exist
0019d838: 00002821 addu r5,r0,r0 r5 = Current Status Loop Counter
0019d83c: 3c028019 lui r2,0x8019
0019d840: 244208cc addiu r2,r2,0x08cc
0019d844: 01628021 addu r16,r11,r2 r16 = unit data
0019d848: 01204021 addu r8,r9,r0 r8 = Unit AI
0019d84c: 00003021 addu r6,r0,r0

0019d850: 96070028 lhu r7,0x0028(r16) load current HP
0019d854: 9602002a lhu r2,0x002a(r16) load max HP
0019d858: 000739c0 sll r7,r7,0x07 current HP * 80
0019d85c: 00e2001a div r7,r2 current HP * 80 / maxHP
0019d860: 00003812 mflo r7 r7 = Unit Target Priority Value (curHP% of 0x80)

0019d864: 04a10002 bgez r5,0x0019d870 Branch if this isn't first status loop (the Blank Status)
0019d868: 00a01021 addu r2,r5,r0 r2 = Current Status Loop Counter
0019d86c: 24a20007 addiu r2,r5,0x0007 r2 = 7 (To counteract negative loops??)
0019d870: 000210c3 sra r2,r2,0x03 Status ID / 8
0019d874: 02021821 addu r3,r16,r2 Get Unit Current Status
0019d878: 90630058 lbu r3,0x0058(r3) load Current Status 1, 2, 3, 4, or 5
0019d87c: 000210c0 sll r2,r2,0x03 {0,1,2,3,4} * 8
0019d880: 00a21023 subu r2,r5,r2 r2 = Status ID - {0,10,18,20,28}
0019d884: 00431804 sllv r3,r3,r2 Will always equal 0x80 if Status in question is present
0019d888: 30630080 andi r3,r3,0x0080
0019d88c: 1060003b beq r3,r0,0x0019d97c Next Status if Current Status not present
0019d890: 00000000 nop
0019d894: 92020059 lbu r2,0x0059(r16) load Current Status 2
0019d898: 3c01801a lui r1,0x801a
0019d89c: 00260821 addu r1,r1,r6
0019d8a0: 8424f308 lh r4,-0x0cf8(r1) load Status Modifers for Target Priority Value
0019d8a4: 30420014 andi r2,r2,0x0014
0019d8a8: 14400006 bne r2,r0,0x0019d8c4 Branch if Confuse/Blood Suck
0019d8ac: 00000000 nop
0019d8b0: 9202005c lbu r2,0x005c(r16) load Current Status 5
0019d8b4: 00000000 nop
0019d8b8: 30420020 andi r2,r2,0x0020
0019d8bc: 10400003 beq r2,r0,0x0019d8cc branch if not Charmed
0019d8c0: 24a3fff6 addiu r3,r5,0xfff6 Exclude Blank to Invite statuses
0019d8c4: 0481002d bgez r4,0x0019d97c Branch if Status Target Priority is not negative (Blood Suck/Confuse is zero)
0019d8c8: 24a3fff6 addiu r3,r5,0xfff6 Exclude Blank to Invite statuses
0019d8cc: 2c62001c sltiu r2,r3,0x001c
0019d8d0: 10400029 beq r2,r0,0x0019d978 Branch and add zero to the Target Priority if Blank to Invite (Reflect/DS as well)
0019d8d4: 00031080 sll r2,r3,0x02 (Status ID - 9) * 4
0019d8d8: 004c1021 addu r2,r2,r12
0019d8dc: 8c420000 lw r2,0x0000(r2) Get Jump Address (only 0x1c addresses...)
0019d8e0: 00000000 nop
0019d8e4: 00400008 jr r2
0019d8e8: 00000000 nop

Blind             
0019d8ec: 91021839 lbu r2,0x1839(r8) Evade Mod (# evadeable (physical?) abilities ")
0019d8f0: 08067641 j 0x0019d904
0019d8f4: 00820018 mult r4,r2 Status Target Value * Evade Mod

Silence
0019d8f8: 91021838 lbu r2,0x1838(r8) Load Silence Blocking Mod
0019d8fc: 00000000 nop
0019d900: 00820018 mult r4,r2 Status Target Value * Silence Mod
0019d904: 00001012 mflo r2
0019d908: 0441001b bgez r2,0x0019d978 Increase Unit Target Priority Value and go to next status
0019d90c: 00022083 sra r4,r2,0x02 Status Target Value / 4
0019d910: 24420003 addiu r2,r2,0x0003 Status Target Value + 3
0019d914: 0806765e j 0x0019d978 Subtract from Target Value and Next Status
0019d918: 00022083 sra r4,r2,0x02 Status Target Value / 4

Confusion/Charm/Blood Suck
0019d91c: 9202005b lbu r2,0x005b(r16) load Current Status 4
0019d920: 00000000 nop
0019d924: 30420006 andi r2,r2,0x0006
0019d928: 14400006 bne r2,r0,0x0019d944 branch if slow/stop
0019d92c: 000417c2 srl r2,r4,0x1f Status Target Value / 0x1f
0019d930: 9202005c lbu r2,0x005c(r16) load Current Status 5
0019d934: 00000000 nop
0019d938: 3042001c andi r2,r2,0x001c
0019d93c: 1040000e beq r2,r0,0x0019d978 Modify Target Value and next status if not sleep/don't move/act
0019d940: 000417c2 srl r2,r4,0x1f Status Target Value / 0x1f
0019d944: 00821021 addu r2,r4,r2 Status Target Value + {0 if positive, 1 if negative}
0019d948: 0806765e j 0x0019d978
0019d94c: 00022043 sra r4,r2,0x01 Status Target Value + {0,1} / 4

Slow/Stop/Sleep/Don't Move/Don't Act
0019d950: 92020059 lbu r2,0x0059(r16) load Current Status 2
0019d954: 00000000 nop
0019d958: 30420014 andi r2,r2,0x0014
0019d95c: 14400007 bne r2,r0,0x0019d97c Add nothing to Target Priority; next status if confuse/blood suck
0019d960: 00000000 nop
0019d964: 9202005c lbu r2,0x005c(r16) load Current Status 5
0019d968: 00000000 nop
0019d96c: 30420020 andi r2,r2,0x0020
0019d970: 14400002 bne r2,r0,0x0019d97c Add nothing to Target Priority; next status if charm
0019d974: 00000000 nop

Everything Else:
0019d978: 00e43821 addu r7,r7,r4 Add Status Target Value to Unit Target Priority
0019d97c: 24a50001 addiu r5,r5,0x0001 Next Status
0019d980: 28a20028 slti r2,r5,0x0028
0019d984: 1440ffb7 bne r2,r0,0x0019d864 loop until all statuses are looked for
0019d988: 24c60002 addiu r6,r6,0x0002 Next Status Target Value (Halfword)

0019d98c: 92020006 lbu r2,0x0006(r16) load gender
0019d990: 00000000 nop
0019d994: 30420020 andi r2,r2,0x0020
0019d998: 14400010 bne r2,r0,0x0019d9dc branch if monster
0019d99c: 00000000 nop

0019d9a0: 9142198c lbu r2,0x198c(r10) load unit battle ID?
0019d9a4: 00002821 addu r5,r0,r0
0019d9a8: 00021180 sll r2,r2,0x06
0019d9ac: 004d3021 addu r6,r2,r13 r6 = unit AI extended status data
0019d9b0: 02051021 addu r2,r16,r5 r2 = unit data
0019d9b4: 00c51821 addu r3,r6,r5 r3 = unit AI extended status data
0019d9b8: 9044001a lbu r4,0x001a(r2) load Head slot equipment
0019d9bc: 90620036 lbu r2,0x0036(r3) load helmet
0019d9c0: 00000000 nop
0019d9c4: 14820002 bne r4,r2,0x0019d9d0 branch if items are missing (Broken/Stolen)
0019d9c8: 24a50001 addiu r5,r5,0x0001
0019d9cc: 24e70033 addiu r7,r7,0x0033 Unit Target Priority Value + 0x33 if information matches (Target is not as desirable to target)
0019d9d0: 28a20007 slti r2,r5,0x0007
0019d9d4: 1440fff7 bne r2,r0,0x0019d9b4 Look for missing Helmet, Armor, Acc., R Weapon, R Shield, L Weapon and L Shield
0019d9d8: 02051021 addu r2,r16,r5 r2 = next unit data

0019d9dc: 9604002e lhu r4,0x002e(r16) load max MP
0019d9e0: 00000000 nop
0019d9e4: 10800014 beq r4,r0,0x0019da38 branch if unit has no MP
0019d9e8: 00000000 nop
0019d9ec: 9606002c lhu r6,0x002c(r16) load current MP
0019d9f0: 91231836 lbu r3,0x1836(r9) Load Lowest MP Cost
0019d9f4: 00c01021 addu r2,r6,r0
0019d9f8: 00063180 sll r6,r6,0x06 CurMP * 40
0019d9fc: 0043102b sltu r2,r2,r3 r2 = curMP < Lowest MP Cost
0019da00: 00c4001a div r6,r4 (CurMP * 40) / Max MP
0019da04: 00003012 mflo r6
0019da08: 10400002 beq r2,r0,0x0019da14 Branch if unit doesn't have enough MP to cast spells.
0019da0c: 00000000 nop
0019da10: 00063042 srl r6,r6,0x01 curMP% / 4
0019da14: 91221837 lbu r2,0x1837(r9) MP Using Ability Mod
0019da18: 00000000 nop
0019da1c: 00c20018 mult r6,r2 (curMP% / 10) * MP Mod
0019da20: 00001012 mflo r2 Caster Hate
0019da24: 04410003 bgez r2,0x0019da34 Branch if no spell unit has uses MP
0019da28: 00023083 sra r6,r2,0x02 Caster Hate / 4
0019da2c: 24420003 addiu r2,r2,0x0003 Caster Hate + 3
0019da30: 00023083 sra r6,r2,0x02 Caster Hate + 3 / 4
0019da34: 00e63821 addu r7,r7,r6 Add Caster Hate to Target Priority Value

0019da38: 92020005 lbu r2,0x0005(r16) load ENTD flags
0019da3c: 00000000 nop
0019da40: 000210c2 srl r2,r2,0x03 flags / 8
0019da44: 30420006 andi r2,r2,0x0006 Get Team
0019da48: 3c018019 lui r1,0x8019
0019da4c: 00220821 addu r1,r1,r2
0019da50: 9426f5f4 lhu r6,-0x0a0c(r1) Load Current? Team Golem Amount
0019da54: 92430e17 lbu r3,0x0e17(r18) Load average max hp of team
0019da58: 00c02821 addu r5,r6,r0
0019da5c: 000631c0 sll r6,r6,0x07 CurGolem * 80
0019da60: 00c3001a div r6,r3 CurGolem * 80 / Average Team HP
0019da64: 00001812 mflo r3 Golem Fear
0019da68: 00521021 addu r2,r2,r18
0019da6c: 94420e3c lhu r2,0x0e3c(r2) load Max? Team Golem Amount
0019da70: 00000000 nop
0019da74: 00a2282b sltu r5,r5,r2 CurGolem <  MaxGolem?
0019da78: 10a00002 beq r5,r0,0x0019da84 -1 to Priority if Golem is undamaged
0019da7c: 00e33821 addu r7,r7,r3 Add Golem Hate to Target Priority Value (Big mistake, has no real value when it's added to everyone)
0019da80: 24e7ffff addiu r7,r7,0xffff Target Priority - 1

0019da84: 91221834 lbu r2,0x1834(r9) Load Enemy Flag
0019da88: 00000000 nop
0019da8c: 10400002 beq r2,r0,0x0019da98 Branch if not Enemy
0019da90: 00000000 nop
0019da94: 00073823 subu r7,r0,r7 Invert Target Priority

0019da98: 96420032 lhu r2,0x0032(r18) Load Current Unit Target Priority Value
0019da9c: 00000000 nop
0019daa0: 00471021 addu r2,r2,r7 Add/Subtract from current Target Priority
0019daa4: a6420032 sh r2,0x0032(r18) Save New Unit Target Priority Value

0019daa8: 25290010 addiu r9,r9,0x0010 Unit AI Data++
0019daac: 254a0001 addiu r10,r10,0x0001 Unit AI++
0019dab0: 26310001 addiu r17,r17,0x0001 Unit++
0019dab4: 2a220015 slti r2,r17,0x0015
0019dab8: 1440ff5c bne r2,r0,0x0019d82c Loop for all units
0019dabc: 256b01c0 addiu r11,r11,0x01c0 Unit Data++
</Unit Priority loop>

0019dac0: 92420000 lbu r2,0x0000(r18) Load Skillset
0019dac4: 3c018006 lui r1,0x8006
0019dac8: 00220821 addu r1,r1,r2
0019dacc: 90235cb4 lbu r3,0x5cb4(r1) load action menu byte
0019dad0: 34020002 ori r2,r0,0x0002
0019dad4: 1462000b bne r3,r2,0x0019db04 branch if not weapon inventory
0019dad8: 3402017e ori r2,r0,0x017e
0019dadc: 86430002 lh r3,0x0002(r18) load ability ID
0019dae0: 00000000 nop
0019dae4: 10620007 beq r3,r2,0x0019db04 branch if ability = throw shuriken
0019dae8: 34020189 ori r2,r0,0x0189
0019daec: 10620005 beq r3,r2,0x0019db04 branch if ability = throw ball (So both will be spammed?)
0019daf0: 00000000 nop
0019daf4: 92420031 lbu r2,0x0031(r18) load base hit%
0019daf8: 00000000 nop
0019dafc: 00021042 srl r2,r2,0x01 base hit/2
0019db00: a2420031 sb r2,0x0031(r18) store new base hit%
0019db04: 0c0678de jal 0x0019e378 Transfer AI Data to Unit Data
0019db08: 00002021 addu r4,r0,r0
0019db0c: a24019b7 sb r0,0x19b7(r18)
0019db10: 080676d9 j 0x0019db64 jump to end, return r2 = 0x01
0019db14: 34020001 ori r2,r0,0x0001
</2 >

0019db18: 0c067858 jal 0x0019e160
0019db1c: 34040001 ori r4,r0,0x0001
0019db20: 34020001 ori r2,r0,0x0001
0019db24: a2420eee sb r2,0x0eee(r18)
0019db28: 080676d9 j 0x0019db64 jump to end, return r2=0xffff
0019db2c: 2402ffff addiu r2,r0,0xffff

<End>
0019db30: 8e420ee0 lw r2,0x0ee0(r18)
0019db34: 8e430ee4 lw r3,0x0ee4(r18)
0019db38: 8e440ee8 lw r4,0x0ee8(r18)
0019db3c: 3c018019 lui r1,0x8019
0019db40: ac22f518 sw r2,-0x0ae8(r1)
0019db44: 3c018019 lui r1,0x8019
0019db48: ac23f51c sw r3,-0x0ae4(r1)
0019db4c: 3c018019 lui r1,0x8019
0019db50: ac24f520 sw r4,-0x0ae0(r1)
0019db54: 0c0678de jal 0x0019e378                 Transfer AI Data to Unit Data
0019db58: 00002021 addu r4,r0,r0
0019db5c: a24019b7 sb r0,0x19b7(r18)
0019db60: 00001021 addu r2,r0,r0 return r2 = 0x00
0019db64: 8fbf001c lw r31,0x001c(r29)
0019db68: 8fb20018 lw r18,0x0018(r29)
0019db6c: 8fb10014 lw r17,0x0014(r29)
0019db70: 8fb00010 lw r16,0x0010(r29)
0019db74: 27bd0020 addiu r29,r29,0x0020
0019db78: 03e00008 jr r31
0019db7c: 00000000 nop

*Note: The entire routine isn't done yet, but the subroutine I'm about to talk about will prove very interesting and is documented.

Summary:
Target Value Formula

(HP Value[curHP * 128 / maxHP] + Total Status Values + (51 * # of items broken up to 7) + Caster Hate [(curMP% / 16) * # MP using Abilities, 0 if not enough MP] + Golem Fear [CurGolem * 128 / Average Team HP (- 1 if Golem not damaged)]) * (-1 if unit is Enemy, 1 if ally)




HP Value goes from 0% to 128%. Multiply by 25/32 to get 0% - 100%.

This is the formula that the AI uses the determine how much priority an individual unit gets.

The more negative the value, the higher on the enemy target priority that unit becomes. The lower the target's HP, the more of a target that unit becomes, which makes sense. However there most likely is a threshold and the unit will be ignored if it gets too negative.

I assume that the Priority Value is interpreted as effective curHP%. So if a unit has -50% effective curHP%, the AI assumes that unit is pretty incapacitated and will ignore them for a unit that has 5% effective curHP%. However, units in critical are flagged and singled out, so the AI doesn't ignore units with no HP left but a ton of non-fatal statuses.

Units that are Petrified, Dead with no Reraise, Death Sentenced, and Charging/Performing skip giving a Target Value at all. Charging and Performing do not need to contribute to Priority because they already have their own routines to processes them. Same goes for Dead and Petrify.

Now, what exactly, does the AI do with this Target Value next, I've yet to determine.


Observations:

You didn't make a sacrifice to the RNG gods today, I'm just gonna sit and spin my wheels instead
0019d6b4: 0c0076ea jal 0x0001dba8 Derive RNG from Frame Data?
0019d6b8: 34040001 ori r4,r0,0x0001
0019d6bc: 284201b9 slti r2,r2,0x01b9 (I assume 0x01ff is the highest value?)
0019d6c0: 14400005 bne r2,r0,0x0019d6d8 Branch if you pleased the Frame RNG gods today
0019d6c4: 3c030100 lui r3,0x0100
0019d6c8: 0c067858 jal 0x0019e160 Transfer Unit Data to AI Data
0019d6cc: 34040001 ori r4,r0,0x0001
0019d6d0: 080676c9 j 0x0019db24 Basically Exit Routine (Is this why sometimes units will just skip turns?)
0019d6d4: 34020002 ori r2,r0,0x0002 (A 70/511(13.7%) chance of being screwed by the RNG in Arena lol)


This confuses me a bit, but no matter how you slice it, it does seem that the AI will occasionally skip assigning units a Target Value at all or basically decide not to do anything at all this turn. The odds of that happening is pretty small because while this might be a 13.7% of that happening every time you come here, the AI comes to this routine several times. So it's more like a .13X% very tiny chance of that happening. Still, giving the amount of decisions the AI makes just per battle, it can and has been observed to happen.


Blind and Silence gain more value to the AI the more abilities you have that are Evadable/Silenceable
Blind             
0019d8ec: 91021839 lbu r2,0x1839(r8) Evade Mod (# evadeable (physical?) abilities ")
0019d8f0: 08067641 j 0x0019d904
0019d8f4: 00820018 mult r4,r2 Status Target Value * Evade Mod {0-4}

Silence
0019d8f8: 91021838 lbu r2,0x1838(r8) Load Silence Blocking Mod
0019d8fc: 00000000 nop
0019d900: 00820018 mult r4,r2 Status Target Value * Silence Mod {0-4}
0019d904: 00001012 mflo r2
0019d908: 0441001b bgez r2,0x0019d978 Increase Unit Target Priority Value and go to next status
0019d90c: 00022083 sra r4,r2,0x02 Status Target Value / 4
0019d910: 24420003 addiu r2,r2,0x0003 Status Target Value + 3
0019d914: 0806765e j 0x0019d978 Subtract from Target Value and Next Status
0019d918: 00022083 sra r4,r2,0x02 Status Target Value / 4


This is probably why the AI doesn't seem to like adding Blind a lot in Arena, or even at all. The AI doesn't take into an account just how much damage a unit can actually do. Attack, even if they deal a truck load of damage, is only one skill to the AI. It cannot tell the immediate difference between a White Mage with Healing Staff and a Berserk Cursed Ring Two Handed Main Gauche killer. Since there aren't too many physically evadable skills in the game, the AI just tends to not want to use Blind all that much it seems, only ever adding -12.5% priority at one time. So simply having no abilities at all is apparently just as good as Blind Immunity. The AI looks at the percentage of units with P-Ev, not the total.

It should be a different story for Silence, but I only ever seen the AI cast Silence as an interrupt, not ever by itself to debuff, even though it's desire to should be much higher, right?


Units become bigger targets the more equips they lose
0019d9a0: 9142198c lbu r2,0x198c(r10) load unit battle ID?
0019d9a4: 00002821 addu r5,r0,r0
0019d9a8: 00021180 sll r2,r2,0x06
0019d9ac: 004d3021 addu r6,r2,r13 r6 = unit AI extended status data
0019d9b0: 02051021 addu r2,r16,r5 r2 = unit data
0019d9b4: 00c51821 addu r3,r6,r5 r3 = unit AI extended status data
0019d9b8: 9044001a lbu r4,0x001a(r2) load Head slot equipment
0019d9bc: 90620036 lbu r2,0x0036(r3) load helmet
0019d9c0: 00000000 nop
0019d9c4: 14820002 bne r4,r2,0x0019d9d0 branch if items are missing (Broken/Stolen)
0019d9c8: 24a50001 addiu r5,r5,0x0001
0019d9cc: 24e70033 addiu r7,r7,0x0033 Unit Target Priority Value + 0x33 if information matches (Target is not as desirable to target)
0019d9d0: 28a20007 slti r2,r5,0x0007
0019d9d4: 1440fff7 bne r2,r0,0x0019d9b4 Look for missing Helmet, Armor, Acc., R Weapon, R Shield, L Weapon and L Shield
0019d9d8: 02051021 addu r2,r16,r5 r2 = next unit data

Seems pretty straight forward. The more stuff you lose, the bigger of a target you become. What is a bit surprising is that all items lost are treated equal. In practice however, you also lose Max HP for losing Armor anyways, so you become an even bigger target than normal.


The AI really fucking hates Mages
0019d9dc: 9604002e lhu r4,0x002e(r16) load max MP
0019d9e0: 00000000 nop
0019d9e4: 10800014 beq r4,r0,0x0019da38 branch if unit has no MP
0019d9e8: 00000000 nop
0019d9ec: 9606002c lhu r6,0x002c(r16) load current MP
0019d9f0: 91231836 lbu r3,0x1836(r9) Load Lowest MP Cost
0019d9f4: 00c01021 addu r2,r6,r0
0019d9f8: 00063180 sll r6,r6,0x06 CurMP * 40
0019d9fc: 0043102b sltu r2,r2,r3 r2 = curMP < Lowest MP Cost
0019da00: 00c4001a div r6,r4 (CurMP * 40) / Max MP
0019da04: 00003012 mflo r6
0019da08: 10400002 beq r2,r0,0x0019da14 Branch if unit doesn't have enough MP to cast spells.
0019da0c: 00000000 nop
0019da10: 00063042 srl r6,r6,0x01 curMP% / 2
0019da14: 91221837 lbu r2,0x1837(r9) MP Using Ability Mod
0019da18: 00000000 nop
0019da1c: 00c20018 mult r6,r2 (curMP% / 20) * MP Mod {0-4}
0019da20: 00001012 mflo r2 Caster Hate
0019da24: 04410003 bgez r2,0x0019da34 Branch if no spell this unit has uses MP
0019da28: 00023083 sra r6,r2,0x02 Caster Hate / 4
0019da2c: 24420003 addiu r2,r2,0x0003 Caster Hate + 3
0019da30: 00023083 sra r6,r2,0x02 Caster Hate + 3 / 4
0019da34: 00e63821 addu r7,r7,r6 Add Caster Hate to Target Priority Value


The AI puts priority on units that have lots of mana and can cast a variety of spells. So if you ever wondered why they gun after your weak little mages all the time, this is why. The price these guys can gain can get stupid high at time, just take your MP, divide by 16, and multiply it by your number of spells to get a grasp on just how much the AI hates spellcasters.
Robe of Lords might as well be a giant Kick Me sign.
The AI takes into account the percentage of spells with MP costs.


Golem is complete cancer
0019da38: 92020005 lbu r2,0x0005(r16) load ENTD flags
0019da3c: 00000000 nop
0019da40: 000210c2 srl r2,r2,0x03 flags / 8
0019da44: 30420006 andi r2,r2,0x0006 Get Team
0019da48: 3c018019 lui r1,0x8019
0019da4c: 00220821 addu r1,r1,r2
0019da50: 9426f5f4 lhu r6,-0x0a0c(r1) Load Current? Team Golem Amount
0019da54: 92430e17 lbu r3,0x0e17(r18) Load average max hp of team
0019da58: 00c02821 addu r5,r6,r0
0019da5c: 000631c0 sll r6,r6,0x07 CurGolem * 80
0019da60: 00c3001a div r6,r3 CurGolem * 80 / Average Team HP
0019da64: 00001812 mflo r3 Golem Fear
0019da68: 00521021 addu r2,r2,r18
0019da6c: 94420e3c lhu r2,0x0e3c(r2) load Max? Team Golem Amount
0019da70: 00000000 nop
0019da74: 00a2282b sltu r5,r5,r2 CurGolem <  MaxGolem?
0019da78: 10a00002 beq r5,r0,0x0019da84 -1 to Priority if Golem is undamaged
0019da7c: 00e33821 addu r7,r7,r3 Add Golem Hate to Target Priority Value (Big mistake, has no real value when it's added to everyone)
0019da80: 24e7ffff addiu r7,r7,0xffff Target Priority - 1

To clarify, this is not exactly why the AI drops everything it's doing to break Golem and makes the AI retarded. However, this is not really helping at all. You can clearly see the fault in adding the same amount of priority value to all units in a team. it's useless at best. Nuke this section please.



Finally, here are the Status Target Priority Values.

Status Priority Values (19f308)
Values, I assume, are interpreted as curHP%, thus, each status is +/- effective curHP.
0x0058: Current Statuses 1
0x80 - 0% (0000)
0x40 - Crystal -150% -c0(ff40)
0x20 - Dead -150% -c0(ff40)
0x10 - Undead -30.5% -27(ffd9)
0x08 - Charging 0% (0000)
0x04 - Jump 0% (0000)
0x02 - Defending 0% (0000)
0x01 - Performing 0% (0000)
0x0059: Current Statuses 2
0x80 - Petrify -90.6% -74(ff8c)
0x40 - Invite -180.4% -e7(ff19)
0x20 - Darkness -50% [-40(ffc0) * Evadable abilities] + 3 / 4
0x10 - Confusion -50% -40(ffc0) (+1 / 4 if slow/stop/sleep/don't move/act/)
0x08 - Silence -70.3% [-5a(ffa6) * Silence abilities] + 3 / 4
0x04 - Blood Suck -90.6% -74(ff8c) (+1 / 4 if slow/stop/sleep/don't move/act/)
0x02 - Cursed 0%(0000)
0x01 - Treasure -150% -c0(ff40)
0x005a: Current Statuses 3
0x80 - Oil -5.5% -7(fff9)
0x40 - Float 9.4% c(000c)
0x20 - Reraise 39.8% 33(0033)
0x10 - Transparent 29.7% 26(0026)
0x08 - Berserk -30.5% -27(ffd9)
0x04 - Chicken -20.3% -1a(ffe6)
0x02 - Frog -40.6% -34(ffcc)
0x01 - Critical -25% -20(ffe0)
0x005b: Current Statuses 4
0x80 - Poison -20.3% -1a(ffe6)
0x40 - Regen 19.5% 19(0019)
0x20 - Protect 19.5% 19(0019)
0x10 - Shell 19.5% 19(0019)
0x08 - Haste 14.8% 13(0013)
0x04 - Slow -30.5% -27(ffd9) 0 if Confusion/Charm/Blood Suck
0x02 - Stop -70.3% -5a(ffa6) 0 if Confusion/Charm/Blood Suck
0x01 - Wall 50% 40(0040)
0x005c: Current Statuses 5
0x80 - Faith 4.7% 6(0006)
0x40 - Innocent -5.5% -7(fff9)
0x20 - Charm -50% -40(ffc0) (+1 / 4 if slow/stop/sleep/don't move/act/)
0x10 - Sleep -30.5% -27(ffd9) 0 if Confusion/Charm/Blood Suck
0x08 - Don't Move -30.5% -27(ffd9) 0 if Confusion/Charm/Blood Suck
0x04 - Don't Act -50% -40(ffc0) 0 if Confusion/Charm/Blood Suck
0x02 - Reflect 19.5% 19(0019)
0x01 - Death Sentence -80.5% -67(ff99)
3
It seems it only works when it wants to. Sometimes it'll dump it right, but most of the time it'll just give me nothing at all or unusable garbage. And don't get me started on trying to calculate the size (it doesn't help I've just been guessing so far).
4
PSX FFT Hacking / Dokurider's Custom AoEs
April 21, 2014, 04:41:48 pm
This project will be delving into making custom AoEs. Thanks to SA's notes, I've determined how the game makes Linear/Tri Attack AoE, more or less. With this knowledge, I can make the Cone AoE everyone's been wanting so bad. Here's how it works:

I've noticed that aside from 255, most AoEs don't top over 15, or 2 for that matter. So I decided I could use that unused data as flag data for custom AoEs. To access these AoEs, edit the AoE value to 0x8x, 0x4x, 0x2x, 0x1x, or 0x0x (128 + x, 64 + x, 32 + x, 16 + x, or 0 + x, respectively), X being the actual size of the AoE. For instance, if you wanted a Cone AoE with a size of 3, you would change your AoE to 128 (0x80), then add 3 to make it 131 (0x83). X can only go from 0 to 15 now, but if you make X = 15, or 0x0f, it automatically becomes map wide AoE.

With this code, up to 15 (F0) AoEs can technically be implemented, but only so many can be coded at once due to space concerns, and I doubt anyone would want more than two AoEs. After I reroute Linear/Tri Attack AoE into this code, I'm open to making one more custom AoE, then I'm moving on to my next project. After I create the full version of this code, there will be two free flags to use (Linear/Tri Attack coincidently), one of which I'll be using myself.


8x: Cone
4x: ????
2x: Linear
1x: Tri Attack
xf: AoE = 254

[youtube]c_kzZM27-G4[youtube]


Oh and when implementing this code, be sure to use the Kanji Space Nopper first. You also need to patch in my Target Unit Only hack because this hack uses the space that hack made.


Here is the current list of hacks I've made.
5
Help! / How do use ANDI to check if a flag is on?
March 27, 2014, 03:26:37 pm
It was either here or Final Fantasy Tactics Hacking, so idk.

So I'm on the cusp of making my very first hack. I'm trying to turn the 255 AoE check into something I can toggle in FFTP by attaching to a unused flag. I've identified all the code that governs this check, I just some help in figuring out how to intelligently use ANDI to my purposes.

For an example, in the targeting routine, ability flag 2 is ANDI'd against 0x0006 to see if the attack is a linear AoE or not.

Ideally, I wanted to use the Math Skill flag for this check, since most patches ban that skill, but the Targeting Routine doesn't load that flag, so I'm going to have to piggyback on some of the (hopefully) blank flags.

I could just attach this hack to the Top Down Targeting Flag if worst comes to worst, because it's such a rare map feature to have tiles above other tiles...
6
FFT Arena / Lore Rework
September 24, 2013, 04:44:18 pm
One type of skill I always wanted to have was a skillset that took in the layout of the map very heavily. It was rather racking to come up with a mechanic that would force terrain consideration but I, with the help of fdc, came up with the idea of repurposing the Truth/Random Fire mechanics to make a terrain focused skillset.

In 1.3, Truth/Untruth was turned from one of the most laughable and weak skillsets in the game to one of the scariest and strongest skillsets in the game. How did this happen? It was pretty simple really: 1.3 just decreased the Vertical Tolerance. That way, it was easier to invalidate panels, thus concentrating onto less panels for a devastating attack. It made Truth a very strategic skillset, making players find areas they can easily box enemies into to maximize damage potential. It was so effective, especially when it came to boss slaying, that it had to be nerfed in subsequent patches.

I would like to bring this sensibility to the Lore skillset, that is, a skillset that is directly affected by the terrain. Right now, Lore's map skills are very static and do exactly the same thing, only via different elements. This has the effect of making Lore harder to counter then it should be, because all you have to do is take another map lore and you're good to go for hitting the enemy from across the map. It steps on Life Song/Wiznaibus' role by healing and damaging everyone at the same time and in the right hands, can be absolutely devastating, especially with the Mime buff incoming.

So what I propose to alleviate this problem is to combine Map Lores and Truth together, by making large AoE Truth/Random Fire spells. What this will do is make Lore overall a much more terrain oriented class, capable of being dynamic and powerful, while at the same time still fulfilling the role Lore had originally set out to fill.

Damage formula = F_MA * Y
All spells are of the Random Unit and Random Fire property unless specified.
===========================================================================

Prism Tribute: Weapon Elemental, 254 AoE, 255 Vertical, 0 Range, Y = 4, No Random Fire, 6 CT, 15 MP, Unevadable

Als Magna: Holy, 3 Range, 5 Vertical, 3 AoE, Y = 6, 5 CT, 30 MP, 6 Hits, Always Hit Caster

Prospero Tempest: Wind, 4 Range, 4 Vertical, 2 AoE, Y = 4, 5 CT, 30 MP, 4 Hits

Rime Bolt: Ice, 5 Range, 2 Vert, 1 AoE, Y = 5, 4 CT, 20 MP, 5 Hits, Random Space

Maelstrom: Water, 1 Range, 255 Vertical, 3 AoE, Y = 7, No Random Fire, 4 CT, 15 MP, Unevadable, No Reflect

Earth Dragon: Earth, 3 Range, 0 Vertical, 2 AoE, Y = 4, 5 CT, 30 MP, 6 Hits

Phoenix Bond: Fire, 3 Range, 0 AoE, Y = 5, 4 Hits, 4 CT, 12 MP, Always Hit Caster

Hex: Random Add: Poison, Blind, Silence, Don't Act, Don't Move; 10 Range, 0 AoE, F_MA + 40%, 4 CT, 10 MP, No Random Fire


"But wouldn't having large AoE mean these Truth/Random Fire skills be hitting a lot of empty space, y'know, like Truth usually does?"
Yes it would, but we have devised a way to stop Random Fire from firing onto empty spaces. Basically, a table(or offset idk) exists in FFT that limits AoE to just units, which is exclusively used for the Song/Dances. By routing these skills into that table, Random Fire will only fire onto units. Of course, this requires some ASM'ing, so this may take a while to come to fruition. Otherwise, it's actually pretty different from Truth this way.

"Wouldn't Random Fire combined with Target Units Only allow for one unit to get potentially peppered with instances? At least with normal Random Fire, it had a chance of hitting empty space unless you were in a bad spot."
It is a possibility, but it has been mitigated as much as possible. All Map Lores except for one(Rime Bolt doesn't count) that I have proposed, will always take the caster into consideration as a target, thereby making the average hit ratio 2:2 worse case scenario. 

"But what about my old Lore Teams? Are they good as scrapped?"
Don't worry about having to scrap your old Lore Builds; Prism Tribute has consolidated all of the old Map Lores into one handy skill. But it also locks you into an element unless you dip into the other Terrain Lores. You can all thank its Weapon Elemental attribute for that.

"F_(PA + MA)/2? What gives, hombre?"
Basically, it's a way to stop MA stacking, which is what I felt was a problem with the old Lore. It also has the wonderful side effect of opening Lore to more unorthodox users. Scholars are well suited for Lore right now anyways, given their high PA for a mage. All it would require is a slight PAM bump to make them perfect for it. Of course, Scholars are planned for a retool anyways. Of course, this is going to take more ASM, but this shouldn't be too difficult.

"What about monsters? Wasn't the Scholar slated to become a Monster Nanny and Babysitter Beastmaster class?"
I feel this is a more subtle and less rigid method of being a Beastmaster class because Monsters, whenever they are introduced, would benefit greatly from the elemental nature of the skillset, being Elemental beings themselves.

"What effect would Mimes have on these skillsets?"
Mimes would actually have a difficult time with these new skillsets. Prism Tribute is completely cut off from them because they can't hold weapons at all, thereby just hitting everyone on the field. The rest would still be hard to Mime well because they are so sensitive to positioning. Making Lore unmimeable is no longer necessary.

"Why send Mad Science to Time Mage?"
Because I feel it would do the most good there. No other skillset can take it, yet I feel it's a worthwhile skill and should still exist.

"'Dark Whisper'? That name sucks."
All skills are open to be renamed.

"Speaking of, what's with Dark Whisper, anyways?"
Dark Whisper represents Lore's high ranged game without stepping on Comet/Dia. Instead of dealing damage, it just randomly adds statuses. Keeping with Lore's theme of terrain consideration, Dark Whisper stops at obstacles, making its effectiveness depend on the map.
7
FFT Arena / Notable and Memorable Arena Videos
July 01, 2013, 11:15:25 pm
I had a realization recently that many newcomers and returning contestants aren't up to date on the latest strategies that have been in development since the release of 138. All of the videos released so far are all scattered in the Arena Video Discussion topic, with 138's video being spread out over 40 pages as of this writing. Naturally, that's going to be difficult for some people to sort through of what's going on.

So I propose that we place what is felt to be the most notable and memorable videos of 138. Basically, any videos that you really liked or felt that were significant in highlighting significant/popular strategies in Arena. Videos that you'd feel that someone that is new or returning should watch. Doing this will help get them up to speed faster on how to proceed with their own teams or to better put strategies in upcoming videos into a better context.

Here's a list I put together quickly just to get things started:

FFT Arena 1.38b - Accidently (First video of 138. That seems pretty notable)
FFT Arena 1.38c - Dienasty (Second video of 138.)
FFT Arena 1.38c Mania 1
FFT Arena 1.38d - CT5Holy (Ele Break)
FFT Arena 1.38d Rivalries - CT5Holy vs Otabo
FFT Arena 1.38d Rivalries - DarkxFatal vs Malroth
FFT Arena 1.38d Trifecta Series - DomieV (Famous Knights)
FFT Arena 1.38d Mania 2
FFT Arena 1.38d Mania 3
CT5's Cruel Concoction vs Barren's High Risk, High Reward)

Also Video Recorders, please post your Arena Playlists if you have them. Or really, anyone can post a playlist as long as it's Arena, I suppose.
http://www.youtube.com/playlist?list=PLRmVvmRPSWWAcU6lO-PBZNlI16P4tPu71
8
Spam / INFERNO COP YEAH
January 22, 2013, 12:33:26 am
http://youtu.be/gy0E-1MD0bw

In this crime ridden city, corruption and decay is the way of life. Every day, murders, rapes, and robberies wear on the hopeless spirit of the city, feeding the ever spiraling chaos the downtrodden city is plunged into nightly. It's a meat grinder that crushes and squeezes victims and the innocent apart and spits them back out as monsters and criminals. The hand of justice cannot even make a fist, much less get a grip on the horrors of the urban jungle. This city cannot be saved, not by itself. Only one man can, only man cares, only one man sees the humanity within the twisting and seething mass within the city's dark heart, and that man is:

Inferno Cop
9
The city of Dorter was about to begin its first day of spring doing what Dorter does best, trading. Fish was fresh and supple, fruit and vegetable colored the stalls, and the smell of freshly baked bread wafted throughout the market. The Farmer and Baker markets once again this year command the eyes of the customers now trickling into the streets. They also command the eye of a force more sinister than mere thieves.

In the woods surrounding Dorter, a horde of goblins plan the first raid of the spring. It has been a long and cold winter and their foodstuffs have been depleted; they all look forward to breaking their winter fast. Camouflaged in leaves and brush, they use telescopes swiped from humans in previous raids to spy upon a blissfully unaware public. The younger goblins are impatient and are asking the older goblins to start the raid immediately. They are particularly enthusiastic to begin so they can try out the new weapons they've been training with all winter.

They received them at the tail end of last fall when goblin traders, both coming from foreign tribes around Ivalice and their own returning from trading with other tribes throughout the land. It was a miracle so many came. Usually, only 2 or 3 make it from Mandalia, occasionally, a foreigner from Germinas Peak, or Barius Valley comes, and rarely do the ones they send out make it back.

Yes, this year, never has a tribe of goblins been this well armed before. Despite their arsenal, the older goblins tell the younger ones to stay put. They have seen many raids before, and the most productive raids happen just before the most humans are out. They sit and watch silently as the shadows shorten and the bustle of the human city increases.

The market was now packed with humans, cavorting and carrying on in their nasally and squeaky gibberish. How do they carry those freakishly large heads on those glass necks of theirs? Or walk on those twiggy legs all day? Humans crush and break like dead trees. The goblins gathered their weapons and armor, and gave them a final look over. Then, a select few armed with spears jumped up on their chocobos and on the elder's signal, charged the market.

The food stalls mostly lay deeper in the market area, mostly to delay the yearly goblin raids and to minimize the damage they do. In order to get to them, the goblins have to charge through the rest of the marketplace. It was a minor inconvenient at best. As they charged the stalls, they let out their goblin war cry, banging on their shields, and swinging their spears wildly to send the panicking humans fleeing, making their way to the food markets, occasionally cutting down one of the slower or unlucky humans to complete their threat.

The guards that were present didn't dare strike at the raiders, opting instead to evacuate everyone out of the area until reinforcements arrived. Try as they might, the guards could not prevent the streets from being congested with the crowd, slowing down the evacuation and more importantly, preventing the Dorter Guard from getting to the goblins.

Despite the bulk of the city guard were trapped behind panicking citizens, it did not stop the more agile members of the guard, bounding from rooftop to rooftop over the crowd, while the archers scrambled to their crow's nests, and searched the city below them for the goblin intruders. Spotting them, they took up their Ice bows and fired at will at the goblins coming in after the mounted goblins.

The goblins, anticipating the barrage of icy arrows, raise their shields to cover them from the blizzard arrow storm. The arrows make a deep plunk as they hit the crudely made wooden shields. Only a few arrows manage to slip through and bury themselves into some of the raiders' flesh. Despite their thick hide stopping the arrow itself from dealing serious damage to their muscles, the unforgiving cold rapidly drained their life force.

The older goblins knew they had to get to cover and quickly before the archers picked them off. They led the horde to the shadows of the various buildings that populated the city sector and between and into the tight and complex walkways of the stalls. With the threat of icy arrows reduced, they can now get to pillage the food stalls. They pulled out their bags and started stuffing everything they could get their hands on, taking turns to watch the skies and streets for threats. And then, here came the first wave of guards, jumping off the buildings and throwing an icy barrage of knives, was the Dorter's Rooftop Patrol.

The pillagers blocked most of the volley and proceeded to ready their own projectiles, rocks half the size of a human head. They put them into their rough looking slings and flung them at the guards with wall cratering force. This was not a new tactics to the guards as deftly dodged and deflected them with their capes, moving in to cut these beasts to ribbons with their short blades and knives. However, they did not expect one of the goblins to be pulling out a crossbow and shoot them. It caught one of the rooftop guards below the collarbone, the force of the bolt blasted him against the wall he just jumped down from.

Despite the surprise of such advanced technology from the goblins, they bravely closed the gap and clashed with the raiders, slashing and weaving through their shields. Even with a combination of arrow fire and guards remaining on the rooftops to harass the plunderers with more freezing projectiles, they easily withstood and repelled the attacks. Patrol opted to play defensive until the main bulk of the guard arrives, aiming to distract and hold their attention, their knives and short blades only leaving light scratches against their tough skin. As they dodged and weaved though their attacks, they noticed that the crossbow wasn't their only un-goblinlike technology.

They wielded metal swords, axes and spears, crafted with a finesse no goblin was ever capable of. A few even had full metal armor and shields. It was a stark contrast with the crude and crooked weapons the goblins traditional made: wooden clubs, some with bits of sharp flint and rarely, obsidian hammered into them; misshapen spears not out of place from the Stone Age; slings fashioned out of grass or wool; and the occasional stone sword and axehead. There was no mistake to be made here; these new weapons of theirs were made by man.

And they used them quite well; their efficient cutting edges combined with the goblin's monstrous strength, devastated any human it made contact with. The elder raiders instinctively knew it was time to make their escape. There was no way they could take on what was coming for them. They did not fear the burly knights wielding icy swords or the flying leaps of the dragoons, no, they feared the wiry people cloaked in darkness and pointy hats. And there, in the very distance, they were, coming up from behind their armored brethren.

The goblins immediately retreated upon seeing the main force coming up to them, taking their ill gotten gain and handing them to their mounted goblins. They couldn't have retreated at a sooner time, then did the Geomancers and other light units seemingly came out of thin air; the humans had almost surrounded them. As they made a beeline towards the safety of the forest, the Geomancers barraged them with stone and dirt bursting out of the ground.

The pillagers dared not stop, as mounted wizards and knights were gaining on them rapidly. The goblins were starting to drop. Arrows impaling them, an ice dart too many, the earth consuming them in stone or dazing them, sending them reeling into the pursuing forces, who skewered the unfortunate creatures with a vengeance. As they neared the edge of the wood, the head of the mounted force had caught up with them.

At the very tip of the force was the captain of the guard, readying his Ice Brand to launch a holy smiting on these disgusting little monsters and behind him and other knights, were the wizards they feared so much, now in range to channel a powered Blizzara. The captain swung down his sword and an aura of absolute power roared straight ahead of him. Each goblin it hit, a phantasmal pillar of cold exploded to the heavens, and a pathetic cry of a goblin followed all but the last one, a particularly tough goblin, barely managing to stay on his feet. Then, the wizard raised his cold rod to the sky and immediately an avalanche of ice smashed down on a unlucky few, ice exploding from their bodies, ripping and freezing their little bodies to bloody pieces. A well charged shot of one of the archers pierced one of the goblin's ribcage, traveling through its core, just barely sticking out of the other side. It sent him hurdling to the ground like a rag doll.

In spite of the series of terrific attacks, the goblins finally made it to the safety of their wood, the guard stopping just before the forest began. The guard had no problem letting them go as their hasty retreat meant they could not cover their little tracks this time and they would led a trail directly to their tribe. After a few moments more to make sure they really left, they let out a collective sigh of relief.

The captain dismounted his chocobo and walked up to one of the dying goblins, its life force ebbing away all over the ground and through the giant ice shard sticking out of him. He adjusted his glasses, picked up its metal sword and inspected it. It was a sword for a goblin, but a short blade for a human. Its fine grain edge and while it looked plain and basic by human standards, its consistent shape was downright elegant compared to the twisted and crude shapes of goblin clubs and swords. This was indeed forged with human precision. "It looks like, the Goblins have gone from the Ice Age," adjusting his glasses again, "to the Iron Age." he uttered.
10
RP Forum / The Monster Hunter Guild Discussion
July 09, 2012, 07:16:20 pm
This is the discussion thread for the Monster Hunter Guild RP. It is a freeform FFT RP, set, uh. You will be working for the Monster Hunter Guild to preempt monster swarms and keep monster populations down, kill marked monsters, or marks and just deal with other monster related problems in general. This RP will have a focus on action and fighting, so bring your A game.

RULES:

1) I am the boss. Rather, I'm the head of the Monster Hunter Guild. What I say goes and you work for me. Failure to comply will result in anything from a warning, to death and finally, to termination of employment.

2) All Guild hopefuls must submit an application (via Post Mailing or PM) to me. I will determine if you are a good fit for our organization. Criteria for consideration include, but are not limited to:
- Job Diversity. Teams tend not to do well when they suffer from overlapping/redundant roles. The application process will weed out job and role redundancies.
- Combat effectiveness. Undead Bards with Charge +2 are not necessary. We need effective setups for the tasks at hand.
- A willingness to get the job done. Ninnies need not apply, nor do I hire broken men.
- Personality. Showing some color is encouraged and very much appreciated in the application process. That being said, I don't want to hear your life story about how your mother wouldn't let you suck her tit after age 5 or whatever else dramatic misfortunes befell you. You aren't going to impress me with your tragic village-burnt-to-the-ground backstory. Keep it brief and simple.
- Qualifications. You will have to do better then being some shlub commoner/peasant that one time almost beat a immature Chocobo 2 on 1.
- Elite Classes. We do not hire elite classes such as Holy Swordsmen. If the need for one arises, we will request one from one of the various armies around Ivalice.
- Jobs outside of the Ivalician Standard Catalog will be considered after a through review. (Custom Classes). Blue and Red Mages are open with welcome arms.
- Monster experience is not necessary, but a plus. We will teach on the job.

And some other stuff like references or criminal records or some other shit like that. I don't know, I don't really look at that stuff or anything. Just kick some ass and you'll be fine.

3) You may bring your own weapons, but rare weapons will have to be considered on a case by case basis. Weapon Insurance gets really finicky about having to cover multiple rare weapons, especially on one person. Otherwise, we will provide the weapons and armor necessary for the jobs at hand.

4) You may apply multiple times.

5) Sexual Harassment in the workplace is a serious issue. All reports of Sexual Harassment will be taken serious and will always be investigated. If any individual is found to have committed an act of unwanted sexual attention, they will be killed and/or immediately terminated from employment.

Once I evaluate your application, I will post it here and you can start when I give you all an assignment. I will assign your task once I receive at least 6 applicants.

**This thread bares no relation to Monster Hunter© series owned by Capcom. All rights reserved.
11
The Lounge / Meet the Pyro/Pyromania update (TF2)
June 25, 2012, 07:14:41 pm
http://www.teamfortress.com/pyromania/

So, at long last, the final Meet the Class video will be upon us on Wednesday. Being that the Pyro is my favorite class, I have waited for this day since 2007. Day 1 brings us a new gamemode, something about a nuke and monkeys, idk.