Final Fantasy Hacktics

Modding => PSX FFT Hacking => Topic started by: Dokurider on April 21, 2014, 04:41:48 pm

Title: Dokurider's Custom AoEs
Post by: Dokurider on 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. (http://ffhacktics.com/smf/index.php?topic=10381.msg218982#msg218982)
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 06, 2014, 02:16:48 pm
Oh. Crap.

Finally looked up a description of Abyssal Blade's AoE. I got it upside down. Well, I know what I'm doing this week. It shouldn't be too hard now that I've gotten the hang of how the game stores tile data and how to call them up. It just looks like a modified Linear AoE. To be fair, there's like no videos of WoTL.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on May 06, 2014, 04:17:48 pm
Nice friggin work! Hehe, if you make a linear target, perpendicular AoE, I have a perfect Flame Wall effect to go with it :P

Since you're off and running in ASM euphoria (finally knowing how to do shit), if you document any routines that aren't posted on the Wiki, feel free to post them. All the red-linked ones I have, I just haven't posted the notes since nobody has been ASMing for like a year or 2. If you need any, I can provide them.

Edit: Btw, you should definitely set a breakpoint on those two targeting flags and see how the AI uses them before you repurpose them.
Title: Re: Dokurider's Custom AoEs
Post by: Pride on May 06, 2014, 05:59:59 pm
Have you tested to see if the AI can properly use the custom AOEs? I could check the offsets to see if they're in the AI section but that would require some effort that I do not have after work at this moment.
Title: Re: Dokurider's Custom AoEs
Post by: Timbo on May 07, 2014, 02:00:07 pm
Conic AoEs. My mouth is watering.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 07, 2014, 03:08:10 pm
Quote from: Choto on May 06, 2014, 04:17:48 pm
Nice friggin work! Hehe, if you make a linear target, perpendicular AoE, I have a perfect Flame Wall effect to go with it :P

Not sure if I understand what you mean. Pictures please?

Quote
Since you're off and running in ASM euphoria (finally knowing how to do shit), if you document any routines that aren't posted on the Wiki, feel free to post them. All the red-linked ones I have, I just haven't posted the notes since nobody has been ASMing for like a year or 2. If you need any, I can provide them.

Eh, I didn't really blaze any trails into the unknown making this hack. I can however give a more detailed explanation on the code I used to make this hack, if only to help future users better understand how to make their own AoEs.
Quote
Edit: Btw, you should definitely set a breakpoint on those two targeting flags and see how the AI uses them before you repurpose them.

I don't think it'll be a problem because you have to flag the corresponding AI flag for Linear/Tri Attack skills anyways. I'm pretty sure the AI doesn't reference ability data, only its corresponding AI flags. Still, wouldn't hurt to make sure anyways.

Quote from: Pride on May 06, 2014, 05:59:59 pm
Have you tested to see if the AI can properly use the custom AOEs? I could check the offsets to see if they're in the AI section but that would require some effort that I do not have after work at this moment.

I replaced Gafgarion's Night Sword with this skill and he seemed to use it just fine. I would be surprised if he didn't though because I'm pretty sure the AI just looks at what tiles are being targeted. I think as long as it not too bizarre, like Etna's Sexy Beam AoE bizarre, and you AI flag it properly, I think the AI should use it just fine.

My running theory right now is that the AI flags on the ability allow the AI to preemptively position themselves so they can attack more effectively (line yourself up with your target, you idiot, in the case of Linear).
Title: Re: Dokurider's Custom AoEs
Post by: Choto on May 07, 2014, 07:40:11 pm
Posting a picture of what I meant. Don't bother though. I wouldn't even get around to using it anytime soon. Maybe if other patchmakers want it, but I don't want you to put the effort in for me.

Good point with the AI flags... That'll be pretty sweet if it works nicely. With the routines thing I just meant in the future if you continue hacking. I think you're the first new person to learn ASM since rfh...and the last one before that was me like 3 years ago lol. It's nice to see somebody prove that ASM isn't impossible to learn.

BTW, save the code for the other cone shape. Maybe we can work more of them in some way.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 14, 2014, 02:37:11 pm
Progress Report

Okay, so I have to throw out or heavily rewrite my current code. It's gotten waaaaay too convoluted. Like "Holy shit, it's actively using 15 registers." convoluted. So instead of trying to directly emulate it, I'm just going to reproduce it's functionality.

How A.B. works in WotL:

00000
000
   o
   u

0 = AoE
o = Tile that has be targeted
u = unit
r = Range

Now here's how I'm going to do it:

00o00
   000
RR0RR
RRRuRRR

Crude, but it works. It works like my original (and backwards) Cone AoE: limit AoE by Target X/Y. If tile's X/Y is past that point, it's not apart of the AoE.

It's a shame I can't think of an efficient way of generating this Cone AoE. I chose to try to generate it strip by strip, but it's gotten so complicated I couldn't keep up with it. It's going to take another week to get this working. Sorry about that  :cry:

Quote from: Choto on May 07, 2014, 07:40:11 pm
Posting a picture of what I meant. Don't bother though. I wouldn't even get around to using it anytime soon. Maybe if other patchmakers want it, but I don't want you to put the effort in for me.

BTW, save the code for the other cone shape. Maybe we can work more of them in some way.


Hmm, that...might be doable. Don't quote me on that.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on May 14, 2014, 03:02:56 pm
Quote from: Dokurider on May 14, 2014, 02:37:11 pm
Progress Report


Inefficient or not, if it works without breaking anything it'll be a very nice breakthrough. Looking forward to a testable product.

Quote from: Dokurider on May 14, 2014, 02:37:11 pm
It's going to take another week to get this working. Sorry about that  :cry:


Never apologize for making something new and useful, no matter how long it takes. Anyone that gets all in a twist over something like this taking a long time to make obviously doesn't understand the kind of work that goes into it.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on May 15, 2014, 08:09:50 am
Could you post any annotated code that you have? I'm interested to see exactly how they/you store the info. Also could you mention what routines your tapping into?

And yeah, no worries about time frames. Just have fun with it :)
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 20, 2014, 03:20:24 pm


So, yeah...
This isn't 100% complete yet, not technically. I need you guys to rigorously and methodically test the crap out of this hack. Here's a list of things I know I need feedback on:



To do:
Make the AoE resize itself properly when bordering the sides of the map.

Otherwise, enjoy.

Quote from: Choto on May 15, 2014, 08:09:50 am
Could you post any annotated code that you have? I'm interested to see exactly how they/you store the info. Also could you mention what routines your tapping into?

Yeah, I can go through all the routines I looked at and referenced in SA's notes tonight and comment on them.

Attached are Dokurider4.xml (the hack itself), and Cone_AoE_2.txt (the code itself, with mostly complete annotations).
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 27, 2014, 03:40:02 pm
Huh, I thought making honest to god Abyssal Blade Conic AoE would generate a little more excitement. Oh well.

For my next hack, I want to allow Self Attacking. That is, Attacking yourself. It's kinda tricky, I'm still trying to parse down exactly why you can't. If I can only find out at what point is Range used. Too bad trying to find when Ability Attributes are loaded isn't easy because they get saved to the stack and used that way instead. (and foiling Ctrl+F 'xfbf0')

In any case, while I was looking for that, I think I might have found what the Normal Attack flag actually does. It actually determines whether Golem intercepts it or not. It seems really dumb when you could have just checked the units' action menu or anything else besides wasting an entire flag. It's possible it could do something else: I only found this check out of sheer luck when I Ctrl+F'd '0x0008'.

I tested this out this morning, slapped it on Repeating Fist, and Fire and yes it does work. It does allow Golem to stop those attacks. It just doesn't display the Golem intercept animation which is what threw me initially.

This...might have some interesting balance implications. Just take off Normal Attack off of Attack and tada! No more Golem breaking the AI. Or attach it to abilities that can deal a great deal of damage and the problem with Golem goes away.

I wonder though? I know the AI prioritizes destroying Golem, but does it prioritize destroying it with Attack? Or just destroying it period? Another thing to look into when I look at Status AI next.

Oh yeah, and one more thing, Choto:

Code (Targeting Routine) Select

0017b8d0: 90690003 lbu r9,0x0003(r3) ability flags 1
0017b8d4: 90710004 lbu r17,0x0004(r3) ability flags 2
0017b8d8: 90640006 lbu r4,0x0006(r3) ability flags 4
0017b8dc: 90730001 lbu r19,0x0001(r3) load aoe
0017b8e0: 90750002 lbu r21,0x0002(r3) load verticle
0017b8e4: 30840020 andi r4,r4,0x0020
0017b8e8: 10800003 beq r4,r0,0x 0017b8f8 branch  if not Weapon Range
0017b8ec: 00458021 addu r16,r2,r5 r16 =  attacker unit data pointer
0017b8f0: 35290020 ori r9,r9,0x0020 r9 = Weapon Range Flag (0x0020)
0017b8f4: 32310039 andi r17,r17,0x0039 remove everything but Top Down and Random Fire
Title: Re: Dokurider's Custom AoEs
Post by: 3lric on May 27, 2014, 04:10:29 pm
Quote from: Dokurider on May 27, 2014, 03:40:02 pm
Huh, I thought making honest to god Abyssal Blade Conic AoE would generate a little more excitement. Oh well.


It's not a matter of excitement Doku, its a matter of the fact that a lot of the people on the forum are to afraid to even
look in this section, as I am. Mostly due the the wizardry that goes on here and my lack of understanding any of it :P

None the less, awesome work on these man! I will definitely put these to good use one way or another!
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 27, 2014, 04:20:02 pm
Yeah thanks. Let me know if you have any problems with any of them.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on May 27, 2014, 05:59:10 pm
Quote from: Dokurider on May 27, 2014, 03:40:02 pm
Huh, I thought making honest to god Abyssal Blade Conic AoE would generate a little more excitement. Oh well.


Please don't get discouraged by the lack of fanfare over your work here, Doku. This is amazing stuff and I'm sure it will get used for something equally amazing. Keep up the good work. I know someone out there is chomping at the bit to go and let Dark Knights run amok on their PSX. ^_^
Title: Re: Dokurider's Custom AoEs
Post by: 3lric on May 27, 2014, 06:06:08 pm
Yes mam, someone certainly is.
Title: Re: Dokurider's Custom AoEs
Post by: Timbo on May 27, 2014, 08:07:19 pm
Wait, not only did you code Abyssal Wave, but you fixed Golem too? Fantastic Work. I have a question. Can you set any distance you want on the cone? I'm thinking about changing the dragons breath attacks to 2 square cones.
Title: Re: Dokurider's Custom AoEs
Post by: RavenOfRazgriz on May 27, 2014, 08:12:59 pm
Normal Attack also controls whether the attack is intercepted by Hamedo.

I discovered what the flag did a long time ago when making Jot5 Chapter 1 but forgot to actually tell anyone about it.  But yes, it controls Golem, Hamedo, and maybe something else, it's hard to remember back to like 2012 when I noticed what it did.  (This is relevant if you use Choto's hack that "nerfs" Hamedo, since you can make it effective against more attacks to compensate if you wish.)
Title: Re: Dokurider's Custom AoEs
Post by: Timbo on May 27, 2014, 08:38:15 pm
Hamedo support vs Golem skill. The Hamedo hack makes counter useless and Golem has an effect so... I choose Golem. Thanks Dokurider.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on May 27, 2014, 10:42:33 pm
It would not be difficult for one to edit which ability Counter uses and repurpose it into Counter: _____. I didn't think about that overshadowing of Counter with that hack. Collateral damage! =)
Title: Re: Dokurider's Custom AoEs
Post by: RavenOfRazgriz on May 27, 2014, 11:01:06 pm
Hamedo doesn't make Counter useless.  Countergrasp is also its own flag, so you can make it possible to trigger "Counter" against any damaging attack that happens to be inside your weapon range, while Hamedo with Choto's fix can filll the role of old-Counter by triggering against those types of attacks with a pre-emptive strike.  Considering many people consider Counter to be a lackluster Support, this is a change that both makes Counter more relevant and gives Hamedo more overall utility.

What makes things useless is lacking the imagination to properly diversify things.
Title: Re: Dokurider's Custom AoEs
Post by: Xifanie on May 28, 2014, 01:44:12 am
A Conic AoE is definitely great, yet rather limited to breath type attacks. Still, great work on that. I could see some use of weapon range abilities able to have an AoE. It would allow for exploding arrows, and some kind of "barrage" ability with a gun shooting multiple times at random in a given AoE. The range parameter of the skill could add or remove targeting distance of the weapon.

Of course, those are my own ideas and I'm not making a mod, so... :v
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on May 28, 2014, 01:49:13 am
Quote from: Xifanie on May 28, 2014, 01:44:12 am
...some kind of "barrage" ability with a gun...


Two words: Shotgun Blast.
Title: Re: Dokurider's Custom AoEs
Post by: Timbo on May 28, 2014, 10:57:22 am
Three words for D&D fans. Cone of Cold.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on May 28, 2014, 04:13:30 pm
Quote from: Jack of All Trades on May 28, 2014, 10:57:22 am
Three words for D&D fans. Cone of Cold.


If you want another three words, I think this might be what Xifanie's "barrage" translates to: Spray and Pray. :D

...which, come to think of it, would be really about perfect for any multi-hit formula with Random Hits flagged. Just set the number of hits to something ridiculous like 50 and don't have it animate misses...toss on something like a Knife Hand animation...hmmm.


Edit: Hey, Doku...I tried to make something work with this and all it did was crash on me despite various settings for the skill in question, almost always with illegal op code errors. PM me with what relevant info you'd need for troubleshooting and I'll collect it for you.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 30, 2014, 04:20:39 pm
So, like I said, I've been looking into how Range is generated so I can allow for Self Attacking. It was an interesting evening last night, so here's what I got so far.


Set panels affected by ability?
0017a290: 27bdff98 addiu r29,r29,0xff98
0017a294: 27a50010 addiu r5,r29,0x0010
0017a298: afbf0064 sw r31,0x0064(r29)
0017a29c: afbe0060 sw r30,0x0060(r29)
0017a2a0: afb7005c sw r23,0x005c(r29)
0017a2a4: afb60058 sw r22,0x0058(r29)
0017a2a8: afb50054 sw r21,0x0054(r29)
0017a2ac: afb40050 sw r20,0x0050(r29)
0017a2b0: afb3004c sw r19,0x004c(r29)
0017a2b4: afb20048 sw r18,0x0048(r29)
0017a2b8: afb10044 sw r17,0x0044(r29)
0017a2bc: 0c01788b jal 0x0005e22c
0017a2c0: afb00040 sw r16,0x0040(r29)
0017a2c4: 93a30010 lbu r3,0x0010(r29) get caster id
0017a2c8: 00000000 nop
0017a2cc: 000310c0 sll r2,r3,0x03
0017a2d0: 00431023 subu r2,r2,r3
0017a2d4: 00021180 sll r2,r2,0x06
0017a2d8: 3c038019 lui r3,0x8019
0017a2dc: 246308cc addiu r3,r3,0x08cc load unit data
0017a2e0: 0043a021 addu r20,r2,r3 get caster data
0017a2e4: 87a30012 lh r3,0x0012(r29) load ability id?
0017a2e8: 00000000 nop
0017a2ec: 000310c0 sll r2,r3,0x03
0017a2f0: 00431023 subu r2,r2,r3
0017a2f4: 00021040 sll r2,r2,0x01
0017a2f8: 3c038006 lui r3,0x8006
0017a2fc: 2463fbf0 addiu r3,r3,0xfbf0 load ability flags
0017a300: 00431021 addu r2,r2,r3
0017a304: 90470001 lbu r7,0x0001(r2) load effect area
0017a308: 90530000 lbu r19,0x0000(r2) load range
0017a30c: a3a70028 sb r7,0x0028(r29) save AoE to stack
0017a310: 90470002 lbu r7,0x0002(r2) load verticle
0017a314: 90520003 lbu r18,0x0003(r2) load flags 1
0017a318: a3a70030 sb r7,0x0030(r29) save vertical to stack
0017a31c: 90420006 lbu r2,0x0006(r2) load flags 4
0017a320: 00000000 nop
0017a324: a3a20038 sb r2,0x0038(r29) save flags 4 to stack
0017a328: 92960047 lbu r22,0x0047(r20) load caster x coordinate
0017a32c: 92970048 lbu r23,0x0048(r20) load caster y coordinate
0017a330: 0c060428 jal 0x001810a0 map location calc
0017a334: 02802021 addu r4,r20,r0
0017a338: 00402821 addu r5,r2,r0 save target tile id?
0017a33c: 000510c0 sll r2,r5,0x03
0017a340: 3c038019 lui r3,0x8019
0017a344: 2463f8cc addiu r3,r3,0xf8cc load tile data
0017a348: 00431021 addu r2,r2,r3
0017a34c: 3c068019 lui r6,0x8019
0017a350: 24c62dd8 addiu r6,r6,0x2dd8 load panel grid pointer
0017a354: 90430003 lbu r3,0x0003(r2) load height halves + depths
0017a358: 3c04800e lui r4,0x800e
0017a35c: 90844e9c lbu r4,0x4e9c(r4) load map max X
0017a360: 3063001f andi r3,r3,0x001f ignore depth data
0017a364: 02e40018 mult r23,r4 caster y * max x
0017a368: 90440002 lbu r4,0x0002(r2) load tile height
0017a36c: 90420003 lbu r2,0x0003(r2) load height halves + depths
0017a370: 00042040 sll r4,r4,0x01
0017a374: 00832021 addu r4,r4,r3 height + depth
0017a378: 00021142 srl r2,r2,0x05
0017a37c: 00021040 sll r2,r2,0x01
0017a380: 0082f021 addu r30,r4,r2 height + depth + height + depth = frame pointer?
0017a384: 00051880 sll r3,r5,0x02
0017a388: 00651821 addu r3,r3,r5
0017a38c: 0066a821 addu r21,r3,r6 save target tile?
0017a390: 326300ff andi r3,r19,0x00ff r3 = Range
0017a394: 00001012 mflo r2 get Caster Y * max X
0017a398: 00562821 addu r5,r2,r22 + caster x
0017a39c: 340200ff ori r2,r0,0x00ff
0017a3a0: 1462000b bne r3,r2,0x0017a3d0 don't branch if range = 255
0017a3a4: 00002021 addu r4,r0,r0
0017a3a8: 34050001 ori r5,r0,0x0001
0017a3ac: 00c01821 addu r3,r6,r0

<---Loop--> If Range = 255
0017a3b0: a0650000 sb r5,0x0000(r3) all panels are apart of range
0017a3b4: a0600001 sb r0,0x0001(r3) no panels are targeted
0017a3b8: 24840001 addiu r4,r4,0x0001 counter++
0017a3bc: 28820200 slti r2,r4,0x0200
0017a3c0: 1440fffb bne r2,r0,0x0017a3b0
0017a3c4: 24630005 addiu r3,r3,0x0005
<---Loop--->

0017a3c8: 0805e912 j 0x0017a448
0017a3cc: 32420001 andi r2,r18,0x0001

<---Loop--> Else:
0017a3d0: 00c01821 addu r3,r6,r0
0017a3d4: a0600000 sb r0,0x0000(r3) no panels are apart of the aoe
0017a3d8: a0600001 sb r0,0x0001(r3) no panels are yellow
0017a3dc: 24840001 addiu r4,r4,0x0001
0017a3e0: 28820200 slti r2,r4,0x0200
0017a3e4: 1440fffb bne r2,r0,0x0017a3d4
0017a3e8: 24630005 addiu r3,r3,0x0005
<---Loop--->

0017a3ec: 00051880 sll r3,r5,0x02
0017a3f0: 00651821 addu r3,r3,r5
0017a3f4: 3c028019 lui r2,0x8019
0017a3f8: 24422dd8 addiu r2,r2,0x2dd8
0017a3fc: 00628021 addu r16,r3,r2 r16 = caster panel
0017a400: 26640001 addiu r4,r19,0x0001 r4 = range
0017a404: 24420500 addiu r2,r2,0x0500
0017a408: 00628821 addu r17,r3,r2 r17 = caster panel + 500? (high AoE?)
0017a40c: 34020001 ori r2,r0,0x0001
0017a410: a2040000 sb r4,0x0000(r16) save range to caster panel
0017a414: a2240000 sb r4,0x0000(r17) save range to caster panel+
0017a418: a2020001 sb r2,0x0001(r16) caster panel is targeted
0017a41c: 32420020 andi r2,r18,0x0020 Weapon Range flag
0017a420: 10400006 beq r2,r0,0x0017a43c branch if false
0017a424: 02602021 addu r4,r19,r0 r4 = range
0017a428: 0c05e688 jal 0x00179a20 Weapon Range Routine
0017a42c: 02802021 addu r4,r20,r0 r4 = Caster ID data
0017a430: a2000000 sb r0,0x0000(r16)
0017a434: 0805e911 j 0x0017a444 Calculate tiles hit by ability
0017a438: a2200000 sb r0,0x0000(r17)
0017a43c: 0c05e546 jal 0x00179518
0017a440: 00002821 addu r5,r0,r0
0017a444: 32420001 andi r2,r18,0x0001
0017a448: 10400002 beq r2,r0,0x0017a454
0017a44c: 32420010 andi r2,r18,0x0010
0017a450: a2a00000 sb r0,0x0000(r21)
0017a454: 10400003 beq r2,r0,0x0017a464
0017a458: 02c02021 addu r4,r22,r0
0017a45c: 0c05e9ef jal 0x0017a7bc some map calculation
0017a460: 02e02821 addu r5,r23,r0
0017a464: 32420008 andi r2,r18,0x0008
0017a468: 10400005 beq r2,r0,0x0017a480
0017a46c: 33c400ff andi r4,r30,0x00ff
0017a470: 93a70030 lbu r7,0x0030(r29)
0017a474: 00003021 addu r6,r0,r0
0017a478: 0c05e4a9 jal 0x001792a4 check vert tolerance and if tiles can be chosen
0017a47c: 00e02821 addu r5,r7,r0
0017a480: 93a70028 lbu r7,0x0028(r29)
0017a484: 00000000 nop
0017a488: 10e00006 beq r7,r0,0x0017a4a4
0017a48c: 00000000 nop
0017a490: 93a70038 lbu r7,0x0038(r29)
0017a494: 00000000 nop
0017a498: 30e20020 andi r2,r7,0x0020
0017a49c: 10400004 beq r2,r0,0x0017a4b0
0017a4a0: 324200c0 andi r2,r18,0x00c0
0017a4a4: 0c05e497 jal 0x0017925c check vert tolerance and if tiles can be chosen?
0017a4a8: 00000000 nop
0017a4ac: 324200c0 andi r2,r18,0x00c0
0017a4b0: 10400003 beq r2,r0,0x0017a4c0
0017a4b4: 02802021 addu r4,r20,r0
0017a4b8: 0c05e9b7 jal 0x0017a6dc
0017a4bc: 02402821 addu r5,r18,r0
0017a4c0: 324200d0 andi r2,r18,0x00d0
0017a4c4: 14400005 bne r2,r0,0x0017a4dc
0017a4c8: 00000000 nop
0017a4cc: 0c05e96f jal 0x0017a5bc
0017a4d0: 00000000 nop
0017a4d4: 0805e939 j 0x0017a4e4
0017a4d8: 00000000 nop
0017a4dc: 0c05e993 jal 0x0017a64c
0017a4e0: 00000000 nop
0017a4e4: 8fbf0064 lw r31,0x0064(r29)
0017a4e8: 8fbe0060 lw r30,0x0060(r29)
0017a4ec: 8fb7005c lw r23,0x005c(r29)
0017a4f0: 8fb60058 lw r22,0x0058(r29)
0017a4f4: 8fb50054 lw r21,0x0054(r29)
0017a4f8: 8fb40050 lw r20,0x0050(r29)
0017a4fc: 8fb3004c lw r19,0x004c(r29)
0017a500: 8fb20048 lw r18,0x0048(r29)
0017a504: 8fb10044 lw r17,0x0044(r29)
0017a508: 8fb00040 lw r16,0x0040(r29)
0017a50c: 27bd0068 addiu r29,r29,0x0068
0017a510: 03e00008 jr r31
0017a514: 00000000 nop


It's not done yet as I've been documenting the Weapon Range Routine.


00179a20:
00000000: 27bdffe0 addiu r29,r29,-0x0020
00000004: 00803821 addu r7,r4,r0 Caster ID = r7
00000008: afbf0018 sw r31,0x0018(r29)
0000000c: afb10014 sw r17,0x0014(r29)
00000010: afb00010 sw r16,0x0010(r29)
00000014: 90f10048 lbu r17,0x0048(r7) Caster Y
00000018: 3c02800e lui r2,0x800e
0000001c: 90424e9c lbu r2,0x4e9c(r2) Max Map X
00000020: 00000000 nop
00000024: 02220018 mult r17,r2 Caster Y * Max X
00000028: 90e4001d lbu r4,0x001d(r7) Caster Right hand Weapon
0000002c: 90e2005a lbu r2,0x005a(r7) Caster Cur. Status 3
00000030: 90f00047 lbu r16,0x0047(r7) Caster X
00000034: 30420002 andi r2,r2,0x0002 Check for Frog
00000038: 00001812 mflo r3
0000003c: 10400002 beq r2,r0,0x00000048 If Caster is Frogged
00000040: 02032821 addu r5,r16,r3 Caster Y * Max X + Caster X
00000044: 00002021 addu r4,r0,r0 Right Hand is empty
00000048: 308300ff andi r3,r4,0x00ff Rh weapon/frog = r3
0000004c: 340200ff ori r2,r0,0x00ff
00000050: 14620006 bne r3,r2,0x0000006c If Caster has a Rh weapon
00000054: 00000000 nop
00000058: 90e4001f lbu r4,0x001f(r7) Caster Left Hand Weapon
0000005c: 00000000 nop
00000060: 14830003 bne r4,r3,0x00000070 If Caster has a Lh weapon
00000064: 308200ff andi r2,r4,0x00ff
00000068: 00002021 addu r4,r0,r0 Left Hand is empty
0000006c: 308200ff andi r2,r4,0x00ff r2 = weapon
00000070: 2c420080 sltiu r2,r2,0x0080
00000074: 14400002 bne r2,r0,0x00000080 Is item in hand a weapon?
00000078: 00051880 sll r3,r5,0x02
0000007c: 00002021 addu r4,r0,r0
00000080: 000420c0 sll r4,r4,0x03
00000084: 3c028006 lui r2,0x8006
00000088: 24423ab8 addiu r2,r2,0x3ab8 Get Weapon data
0000008c: 00822021 addu r4,r4,r2 point to weapon in hand
00000090: 00651821 addu r3,r3,r5
00000094: 3c028019 lui r2,0x8019
00000098: 24422dd8 addiu r2,r2,0x2dd8
0000009c: 00622821 addu r5,r3,r2 Get Caster tile
000000a0: 24420500 addiu r2,r2,0x0500
000000a4: 00621821 addu r3,r3,r2 Get Caster tile + 500 (high tile?)
000000a8: 34020001 ori r2,r0,0x0001
000000ac: 90880000 lbu r8,0x0000(r4) Get Weapon Range(r8)
000000b0: 90860001 lbu r6,0x0001(r4) Get Weapon Attack Flags(r6)
000000b4: 25040001 addiu r4,r8,0x0001 r4 = Range + 1
000000b8: a0a40000 sb r4,0x0000(r5) Save Weapon Range to Caster Panel
000000bc: a0640000 sb r4,0x0000(r3) Save Weapon Range to Caster Panel+
000000c0: a0a20001 sb r2,0x0001(r5) Caster panel is targeted
000000c4: 30c200c0 andi r2,r6,0x00c0 Is Weapon Striking/Lunging?
000000c8: 10400005 beq r2,r0,0x000000e0 Branch if false
000000cc: 00e02021 addu r4,r7,r0 Save Caster data to r4
000000d0: 0c05e6d6 jal 0x00179b58 jump to ?
000000d4: 00c02821 addu r5,r6,r0 Save Weapon Attack Flags
000000d8: 0805e6ce j 0x00179b38 Jump to last jal
000000dc: 00000000 nop
000000e0: 30c20020 andi r2,r6,0x0020 Is Weapon Direct?
000000e4: 10400009 beq r2,r0,0x0000010c branch if false
000000e8: 01002021 addu r4,r8,r0 Store Weapon Range
000000ec: 0c05e546 jal 0x00179518 Limit Range to Map Function
000000f0: 00002821 addu r5,r0,r0
000000f4: 02002021 addu r4,r16,r0 Save Caster X
000000f8: 02202821 addu r5,r17,r0 Save Caster Y
000000fc: 0c05e509 jal 0x00179424 Remove Close Range Routine
00000100: 34060002 ori r6,r0,0x0002
00000104: 0805e6ce j 0x00179b38 jump to last jal
00000108: 00000000 nop
0000010c: 00e02021 addu r4,r7,r0 Save Caster data
00000110: 0c05e62c jal 0x001798b0 jump to ?
00000114: 01002821 addu r5,r8,r0 save Weapon Range
00000118: 0c05e761 jal 0x00179d84 jump to ?
0000011c: 00000000 nop
00000120: 8fbf0018 lw r31,0x0018(r29)
00000124: 8fb10014 lw r17,0x0014(r29)
00000128: 8fb00010 lw r16,0x0010(r29)
addiu r29,r29,0x0020
jr r31
nop


Stupid pSX binary dumping...Not finished yet either as I have to finish documenting the last couple routines (hindered by aforementioned lack of binary dumping). Too bad, that when things were getting interesting.

Like this little tidbit for instance:


Remove Close Range Routine
r4 = Caster X
r5 = Caster Y
r6 = 2
00179424: 27bdfff0 addiu r29,r29,0xfff0
00179428: 3c02800e lui r2,0x800e
0017942c: 90424ea0 lbu r2,0x4ea0(r2) r2 = Max Map Y
00179430: 00000000 nop
00179434: 18400035 blez r2,0x0017950c End if Y is negative
00179438: 00004021 addu r8,r0,r0 r8 = Y counter
0017943c: 00a8102a slt r2,r5,r8 If Caster Y < Y Counter
00179440: 14400002 bne r2,r0,0x0017944c Branch if true
00179444: 01054823 subu r9,r8,r5 Y Counter - Caster Y = r9
00179448: 00a84823 subu r9,r5,r8 Caster Y - Y Counter = r9
0017944c: 3c02800e lui r2,0x800e
00179450: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X
00179454: 00000000 nop
00179458: 18400026 blez r2,0x001794f4 go to Y counter++ if negative
0017945c: 00003821 addu r7,r0,r0 r7 = X Counter
00179460: 0087102a slt r2,r4,r7 If Caster X < X Counter
00179464: 14400002 bne r2,r0,0x00179470 Branch if true
00179468: 00e41023 subu r2,r7,r4 r2 = X Counter - Caster X
0017946c: 00871023 subu r2,r4,r7 r2 = Caster X - X Counter
00179470: 01221021 addu r2,r9,r2 Caster Y- + Caster X- = r2
00179474: 00c2102a slt r2,r6,r2 if Caster-Counter Sum > 2
00179478: 14400018 bne r2,r0,0x001794dc skip AoE blanking if true
0017947c: 00000000 nop
00179480: 3c02800e lui r2,0x800e
00179484: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X
00179488: 00000000 nop
0017948c: 01020018 mult r8,r2 Y Counter * Max X
00179490: 00001812 mflo r3
00179494: 00671821 addu r3,r3,r7 Y Counter * Max X + X Counter
00179498: 00031080 sll r2,r3,0x02
0017949c: 00431021 addu r2,r2,r3
001794a0: 3c018019 lui r1,0x8019
001794a4: 00220821 addu r1,r1,r2
001794a8: a0202dd8 sb r0,0x2dd8(r1) Blank Counter Low Tile's AoE data
001794ac: 3c02800e lui r2,0x800e
001794b0: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X
001794b4: 00000000 nop
001794b8: 01020018 mult r8,r2 Y Counter * Max X
001794bc: 24e20100 addiu r2,r7,0x0100 r2 = X Counter + 0x0100
001794c0: 00001812 mflo r3
001794c4: 00621821 addu r3,r3,r2
001794c8: 00031080 sll r2,r3,0x02
001794cc: 00431021 addu r2,r2,r3
001794d0: 3c018019 lui r1,0x8019
001794d4: 00220821 addu r1,r1,r2
001794d8: a0202dd8 sb r0,0x2dd8(r1) Blank Counter High Tile's AoE data
001794dc: 3c02800e lui r2,0x800e
001794e0: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X
001794e4: 24e70001 addiu r7,r7,0x0001 X Counter ++
001794e8: 00e2102a slt r2,r7,r2 If X Counter < Max X
001794ec: 1440ffdd bne r2,r0,0x00179464 Branch back if True
001794f0: 0087102a slt r2,r4,r7 If Caster X < X Counter
001794f4: 3c02800e lui r2,0x800e
001794f8: 90424ea0 lbu r2,0x4ea0(r2) r2 = Max Map Y
001794fc: 25080001 addiu r8,r8,0x0001 Y Counter++
00179500: 0102102a slt r2,r8,r2 If Y Counter < Max Y
00179504: 1440ffce bne r2,r0,0x00179440 Branch Back if true
00179508: 00a8102a slt r2,r5,r8 If Caster Y < Y Counter
0017950c: 27bd0010 addiu r29,r29,0x0010
00179510: 03e00008 jr r31
00179514: 00000000 nop

Yep, this is the routine that removes the inner range from ranged weapons like Bows and Books and stuff. Interesting how it does it. This is complete by the way.

Celdia's PM reminded me of something I tried with Weapon Range. I actually *did* managed to hack it so it allowed abilities to have AoE (it currently doesn't). Yeah, Weapon Range. AoE.

All I had to do was:

0017babc: 31220020 andi r2,r9,0x0020
to
0017babc: 31220020 andi r2,r0,0x0000

Yep. That's it. Only problem? The AoE was there, but you couldn't actually hit anyone with *any* of the highlighted tiles except the actual targeted tile! Weirdest thing. I'm pretty sure my current work will uncover why that was.

Quote from: Jack of All Trades on May 27, 2014, 08:07:19 pm
Wait, not only did you code Abyssal Wave, but you fixed Golem too? Fantastic Work. I have a question. Can you set any distance you want on the cone? I'm thinking about changing the dragons breath attacks to 2 square cones.


I keep forgetting to responding. I didn't fix Golem, I just found, or refound, reminded Raven to speak up? Anyways, yes, Conic AoE works at any range, and any AoE.

You can also use Conic AoE to make a boss skill, like say this (http://youtu.be/quxJkvr_7MA?t=2m15s) for instance. Cluster around the boss so you can't wipe your whole party in one shot.

I just need to remind everyone that you must change AoE to 128 + actual AoE if you want to use Conic. 64 + AoE if you want to use Linear again, and 32 + AoE if you want to use Tri Attack.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on May 30, 2014, 05:45:18 pm
Quote from: Dokurider on May 30, 2014, 04:20:39 pm
Quotecode code code

Uhhh....
Quote from: Dokurider on May 30, 2014, 04:20:39 pm
Yep, this is the routine that removes the inner range from ranged weapons like Bows and Books and stuff.
(http://i.somethingawful.com/images/emot-dance.gif)
Quote from: Dokurider on May 30, 2014, 04:20:39 pm
Weapon Range. AoE.
(http://i.somethingawful.com/forumsystem/emoticons/emot-aaa.gif)

...I would like to subscribe to your newsletter, sir.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 30, 2014, 05:54:19 pm
Oh yeah one more thing. The Cone AoE hack is standalone. It no longer needs the Target Unit Hack to work. It doesn't even need the Kanji Space hack anyone technically, but best do that anyways to be safe.
Title: Re: Dokurider's Custom AoEs
Post by: Timbo on May 30, 2014, 07:03:09 pm
Huzzah. Standalone cone hack. Woo!
Title: Re: Dokurider's Custom AoEs
Post by: RavenOfRazgriz on May 30, 2014, 07:47:04 pm
Quote from: Dokurider on May 30, 2014, 05:54:19 pmIt doesn't even need the Kanji Space hack anyone technically, but best do that anyways to be safe.
Nothing ever "needs" the Kanji Space Nopper, all that hack does is make it easier for an ASMer to see how large their workspace is.  If you're not actively ASM hacking or working on a team where someone is you should never need to apply it unless the person making the ASM did something particularly brain-dead.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on May 30, 2014, 08:25:36 pm
idk why psx disassembled like that... but take this. It's a disassembly of scus and battle.bin (and also another file with World.bin and Wldcore). So all you need to do is ctrl-F the address you're looking for and it will take you right to the routine. Then you can copypaste it wherever you want. Just convenient
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 02, 2014, 03:25:35 pm
So, I spent the weekend annotating code. Made some interesting discoveries.

Range Routine
0017a290: 27bdff98 addiu r29,r29,0xff98
0017a294: 27a50010 addiu r5,r29,0x0010
0017a298: afbf0064 sw r31,0x0064(r29)
0017a29c: afbe0060 sw r30,0x0060(r29)
0017a2a0: afb7005c sw r23,0x005c(r29)
0017a2a4: afb60058 sw r22,0x0058(r29)
0017a2a8: afb50054 sw r21,0x0054(r29)
0017a2ac: afb40050 sw r20,0x0050(r29)
0017a2b0: afb3004c sw r19,0x004c(r29)
0017a2b4: afb20048 sw r18,0x0048(r29)
0017a2b8: afb10044 sw r17,0x0044(r29)
0017a2bc: 0c01788b jal 0x0005e22c
0017a2c0: afb00040 sw r16,0x0040(r29)
0017a2c4: 93a30010 lbu r3,0x0010(r29) get caster id
0017a2c8: 00000000 nop
0017a2cc: 000310c0 sll r2,r3,0x03
0017a2d0: 00431023 subu r2,r2,r3
0017a2d4: 00021180 sll r2,r2,0x06
0017a2d8: 3c038019 lui r3,0x8019
0017a2dc: 246308cc addiu r3,r3,0x08cc load unit data
0017a2e0: 0043a021 addu r20,r2,r3 get caster data
0017a2e4: 87a30012 lh r3,0x0012(r29) load ability id?
0017a2e8: 00000000 nop
0017a2ec: 000310c0 sll r2,r3,0x03
0017a2f0: 00431023 subu r2,r2,r3
0017a2f4: 00021040 sll r2,r2,0x01
0017a2f8: 3c038006 lui r3,0x8006
0017a2fc: 2463fbf0 addiu r3,r3,0xfbf0 load ability flags
0017a300: 00431021 addu r2,r2,r3
0017a304: 90470001 lbu r7,0x0001(r2) load effect area
0017a308: 90530000 lbu r19,0x0000(r2) load range
0017a30c: a3a70028 sb r7,0x0028(r29) save AoE to stack
0017a310: 90470002 lbu r7,0x0002(r2) load verticle
0017a314: 90520003 lbu r18,0x0003(r2) load flags 1
0017a318: a3a70030 sb r7,0x0030(r29) save vertical to stack
0017a31c: 90420006 lbu r2,0x0006(r2) load flags 4
0017a320: 00000000 nop
0017a324: a3a20038 sb r2,0x0038(r29) save flags 4 to stack
0017a328: 92960047 lbu r22,0x0047(r20) load caster x coordinate
0017a32c: 92970048 lbu r23,0x0048(r20) load caster y coordinate
0017a330: 0c060428 jal 0x001810a0 map location calc
0017a334: 02802021 addu r4,r20,r0
0017a338: 00402821 addu r5,r2,r0 save target tile id?
0017a33c: 000510c0 sll r2,r5,0x03
0017a340: 3c038019 lui r3,0x8019
0017a344: 2463f8cc addiu r3,r3,0xf8cc load tile data
0017a348: 00431021 addu r2,r2,r3
0017a34c: 3c068019 lui r6,0x8019
0017a350: 24c62dd8 addiu r6,r6,0x2dd8 load panel grid pointer
0017a354: 90430003 lbu r3,0x0003(r2) load height halves + depths
0017a358: 3c04800e lui r4,0x800e
0017a35c: 90844e9c lbu r4,0x4e9c(r4) load map max X
0017a360: 3063001f andi r3,r3,0x001f ignore depth data
0017a364: 02e40018 mult r23,r4 caster y * max x
0017a368: 90440002 lbu r4,0x0002(r2) load tile height
0017a36c: 90420003 lbu r2,0x0003(r2) load height halves
0017a370: 00042040 sll r4,r4,0x01
0017a374: 00832021 addu r4,r4,r3 height + halves
0017a378: 00021142 srl r2,r2,0x05 r2 = Depth(Ignore Halves)
0017a37c: 00021040 sll r2,r2,0x01
0017a380: 0082f021 addu r30,r4,r2 height + halves + depth = frame pointer(r30)???
0017a384: 00051880 sll r3,r5,0x02
0017a388: 00651821 addu r3,r3,r5
0017a38c: 0066a821 addu r21,r3,r6 save target tile?
0017a390: 326300ff andi r3,r19,0x00ff r3 = Range
0017a394: 00001012 mflo r2 get Caster Y * max X
0017a398: 00562821 addu r5,r2,r22 + caster x
0017a39c: 340200ff ori r2,r0,0x00ff
0017a3a0: 1462000b bne r3,r2,0x0017a3d0 don't branch if range = 255
0017a3a4: 00002021 addu r4,r0,r0
0017a3a8: 34050001 ori r5,r0,0x0001
0017a3ac: 00c01821 addu r3,r6,r0

<---Loop--> If Range = 255
0017a3b0: a0650000 sb r5,0x0000(r3) all panels are apart of aoe
0017a3b4: a0600001 sb r0,0x0001(r3) no panels are yellow
0017a3b8: 24840001 addiu r4,r4,0x0001 counter++
0017a3bc: 28820200 slti r2,r4,0x0200
0017a3c0: 1440fffb bne r2,r0,0x0017a3b0
0017a3c4: 24630005 addiu r3,r3,0x0005
<---Loop--->

0017a3c8: 0805e912 j 0x0017a448
0017a3cc: 32420001 andi r2,r18,0x0001

<---Loop--> Else:
0017a3d0: 00c01821 addu r3,r6,r0
0017a3d4: a0600000 sb r0,0x0000(r3) no panels are apart of the aoe
0017a3d8: a0600001 sb r0,0x0001(r3) no panels are yellow
0017a3dc: 24840001 addiu r4,r4,0x0001
0017a3e0: 28820200 slti r2,r4,0x0200
0017a3e4: 1440fffb bne r2,r0,0x0017a3d4
0017a3e8: 24630005 addiu r3,r3,0x0005
<---Loop--->

0017a3ec: 00051880 sll r3,r5,0x02
0017a3f0: 00651821 addu r3,r3,r5
0017a3f4: 3c028019 lui r2,0x8019
0017a3f8: 24422dd8 addiu r2,r2,0x2dd8
0017a3fc: 00628021 addu r16,r3,r2 r16 = caster panel
0017a400: 26640001 addiu r4,r19,0x0001 r4 = range
0017a404: 24420500 addiu r2,r2,0x0500
0017a408: 00628821 addu r17,r3,r2 r17 = caster panel + 500? (high AoE?)
0017a40c: 34020001 ori r2,r0,0x0001
0017a410: a2040000 sb r4,0x0000(r16) save range to caster panel
0017a414: a2240000 sb r4,0x0000(r17) save range to caster panel+
0017a418: a2020001 sb r2,0x0001(r16) caster panel is targeted
0017a41c: 32420020 andi r2,r18,0x0020 Weapon Range flag
0017a420: 10400006 beq r2,r0,0x0017a43c branch if false
0017a424: 02602021 addu r4,r19,r0 r4 = range
0017a428: 0c05e688 jal 0x00179a20 Weapon Range Routine
0017a42c: 02802021 addu r4,r20,r0 r4 = Caster ID data
0017a430: a2000000 sb r0,0x0000(r16) Remove Range from Caster Panel
0017a434: 0805e911 j 0x0017a444 Calculate tiles hit by ability
0017a438: a2200000 sb r0,0x0000(r17) Remove Range from Caster Panel+
0017a43c: 0c05e546 jal 0x00179518 Generate Range Routine
0017a440: 00002821 addu r5,r0,r0 r5 = 0
0017a444: 32420001 andi r2,r18,0x0001 If Can't Target Self
0017a448: 10400002 beq r2,r0,0x0017a454 Branch if False
0017a44c: 32420010 andi r2,r18,0x0010 If Vertical Fixed
0017a450: a2a00000 sb r0,0x0000(r21) Remove Caster Panel from Range
0017a454: 10400003 beq r2,r0,0x0017a464 Branch if False
0017a458: 02c02021 addu r4,r22,r0 r4 = Caster X
0017a45c: 0c05e9ef jal 0x0017a7bc Vertical Fixed Routine
0017a460: 02e02821 addu r5,r23,r0 r5 = Caster Y
0017a464: 32420008 andi r2,r18,0x0008 If Vertical Fixed
0017a468: 10400005 beq r2,r0,0x0017a480 Branch if False
0017a46c: 33c400ff andi r4,r30,0x00ff r4 = Height Value if Non Zero (Negative?)
0017a470: 93a70030 lbu r7,0x0030(r29) r7 = load vertical from stack
0017a474: 00003021 addu r6,r0,r0 r6 = 0
0017a478: 0c05e4a9 jal 0x001792a4 Vertical Tolerance Formula
0017a47c: 00e02821 addu r5,r7,r0 r5 = Vertical
0017a480: 93a70028 lbu r7,0x0028(r29) r7 = Load AoE from Stack
0017a484: 00000000 nop
0017a488: 10e00006 beq r7,r0,0x0017a4a4 Branch if AoE = 0
0017a48c: 00000000 nop
0017a490: 93a70038 lbu r7,0x0038(r29) r7 = Load Ability Flags 4
0017a494: 00000000 nop
0017a498: 30e20020 andi r2,r7,0x0020 If Direct/Stop at Obstacle
0017a49c: 10400004 beq r2,r0,0x0017a4b0 Branch if False
0017a4a0: 324200c0 andi r2,r18,0x00c0 If Unknown Flags 0x80/0x40 (!!!)
0017a4a4: 0c05e497 jal 0x0017925c Clear Data from Untargetable Tiles
0017a4a8: 00000000 nop
0017a4ac: 324200c0 andi r2,r18,0x00c0 If Unknown Flags 0x80/0x40 (!!!)
0017a4b0: 10400003 beq r2,r0,0x0017a4c0 Branch if False
0017a4b4: 02802021 addu r4,r20,r0 r4 = Caster Data
0017a4b8: 0c05e9b7 jal 0x0017a6dc Evaluate Unknown Flags 0x80/0x40 (!!!)
0017a4bc: 02402821 addu r5,r18,r0 r5 = Ability Flags 1
0017a4c0: 324200d0 andi r2,r18,0x00d0 If Unknown Flags 0x80/0x40 or Vertical Fixed
0017a4c4: 14400005 bne r2,r0,0x0017a4dc Branch if True
0017a4c8: 00000000 nop
0017a4cc: 0c05e96f jal 0x0017a5bc Identify Cross Sections
0017a4d0: 00000000 nop
0017a4d4: 0805e939 j 0x0017a4e4
0017a4d8: 00000000 nop
0017a4dc: 0c05e993 jal 0x0017a64c Identify Cross Sections (Clone)
0017a4e0: 00000000 nop
0017a4e4: 8fbf0064 lw r31,0x0064(r29)
0017a4e8: 8fbe0060 lw r30,0x0060(r29)
0017a4ec: 8fb7005c lw r23,0x005c(r29)
0017a4f0: 8fb60058 lw r22,0x0058(r29)
0017a4f4: 8fb50054 lw r21,0x0054(r29)
0017a4f8: 8fb40050 lw r20,0x0050(r29)
0017a4fc: 8fb3004c lw r19,0x004c(r29)
0017a500: 8fb20048 lw r18,0x0048(r29)
0017a504: 8fb10044 lw r17,0x0044(r29)
0017a508: 8fb00040 lw r16,0x0040(r29)
0017a50c: 27bd0068 addiu r29,r29,0x0068
0017a510: 03e00008 jr r31
0017a514: 00000000 nop

I'm not sure what the significance of 0x1a23d8 (192dd8 + 500) or what it's used for, but it comes up quite often. Also Unknown Flags 1 and 2!!! Finally, we can find out once and for all what these flags do. Let's look at this routine right now:


Expand Range from Ally/Enemy (Nonfunctioning)
r4 = Caster Data
r5 = Ability Flags 1

0017a6dc: 27bdffc8 addiu r29,r29,-0x0038
0017a6e0: afb10014 sw r17,0x0014(r29)
0017a6e4: 00808821 addu r17,r4,r0 r17 = Caster Data
0017a6e8: afb7002c sw r23,0x002c(r29)
0017a6ec: 30b70080 andi r23,r5,0x0080 r23 = Unknown Flag 1
0017a6f0: afb60028 sw r22,0x0028(r29)
0017a6f4: 30b60040 andi r22,r5,0x0040 r22 = Unknown Flag 2
0017a6f8: afb3001c sw r19,0x001c(r29)
0017a6fc: 00009821 addu r19,r0,r0 r19 = Counter
0017a700: afb40020 sw r20,0x0020(r29)
0017a704: 34140001 ori r20,r0,0x0001 r20 = True
0017a708: afbf0030 sw r31,0x0030(r29)
0017a70c: afb50024 sw r21,0x0024(r29)
0017a710: afb20018 sw r18,0x0018(r29)
0017a714: afb00010 sw r16,0x0010(r29)
0017a718: 92350005 lbu r21,0x0005(r17) r21 = ENTD flags
0017a71c: 92230001 lbu r3,0x0001(r17) r3 = Unit ID
0017a720: 340200ff ori r2,r0,0x00ff r2 = 0x00ff
0017a724: 10620015 beq r3,r2,0x0017a77c Branch if Unit ID(Caster) doesn't exist (FF)?
0017a728: 02202021 addu r4,r17,r0 r4 = Caster Data
0017a72c: 922201ba lbu r2,0x01ba(r17) r2 = Modified ENTD Flags
0017a730: 00000000 nop
0017a734: 02a28026 xor r16,r21,r2 r16 = ENTD Flags
0017a738: 0c060428 jal 0x001810a0 Get Unit Tile ID
0017a73c: 02009021 addu r18,r16,r0 r18 = ENTD Flags
0017a740: 00021880 sll r3,r2,0x02 r3 = Caster Tile ID
0017a744: 00621821 addu r3,r3,r2
0017a748: 3c028019 lui r2,0x8019
0017a74c: 24422dd8 addiu r2,r2,0x2dd8 r2 = Tile Grid Data (0x192dd8)
0017a750: 12e00005 beq r23,r0,0x0017a768 If Unknown Flag = False
0017a754: 00621821 addu r3,r3,r2 r3 = Caster Tile Data
0017a758: 32020030 andi r2,r16,0x0030 r2 = Red or Blue Flag
0017a75c: 14400002 bne r2,r0,0x0017a768 Branch if Red or Blue Team
0017a760: 00000000 nop
0017a764: a0740001 sb r20,0x0001(r3) Caster Tile is Targeted
0017a768: 12c00004 beq r22,r0,0x0017a77c If Unknown Flag 2 = False
0017a76c: 32420030 andi r2,r18,0x0030 r2 = Red or Blue Team
0017a770: 10400002 beq r2,r0,0x0017a77c Branch if neither Team
0017a774: 00000000 nop
0017a778: a0740001 sb r20,0x0001(r3) Caster Tile is Targeted
0017a77c: 26730001 addiu r19,r19,0x0001 Counter++
0017a780: 2a620015 slti r2,r19,0x0015 If Counter < 0x0015
0017a784: 1440ffe5 bne r2,r0,0x0017a71c Branch Back if True
0017a788: 00000000 nop
0017a78c: 8fbf0030 lw r31,0x0030(r29)
0017a790: 8fb7002c lw r23,0x002c(r29)
0017a794: 8fb60028 lw r22,0x0028(r29)
0017a798: 8fb50024 lw r21,0x0024(r29)
0017a79c: 8fb40020 lw r20,0x0020(r29)
0017a7a0: 8fb3001c lw r19,0x001c(r29)
0017a7a4: 8fb20018 lw r18,0x0018(r29)
0017a7a8: 8fb10014 lw r17,0x0014(r29)
0017a7ac: 8fb00010 lw r16,0x0010(r29)
0017a7b0: 27bd0038 addiu r29,r29,0x0038
0017a7b4: 03e00008 jr r31
0017a7b8: 00000000 nop

I...uh, um, what? It seems this Routine does nothing at all. Unless I missed something, this routine only loops right back onto the caster and only the caster.
I'm not well versed in ENTD, but I'm thinking this routine *was* supposed to go through and target every Team Allied Unit. Exactly what Targeted means in the context of Range, I have no real clue.  The Caster's Tile is targeted, does that mean that it's...supposed to generate range from other units or something? But that was true, then why does it loop 0x15 times? You're only allowed to have 0x0f units. I have no clue about anything except this was most likely broken deliberately. Any guesses?

Cross Section Identification 

0017a5bc: 00003021 addu r6,r0,r0 r6 = 0
0017a5c0: 00002821 addu r5,r0,r0 r5 = 0
0017a5c4: 3407003f ori r7,r0,0x003f r7 = 0x003f
0017a5c8: 3c038019 lui r3,0x8019
0017a5cc: 2463f8cc addiu r3,r3,-0x0734 r3 = Tile Data (0x18f8cc)
0017a5d0: 3c048019 lui r4,0x8019
0017a5d4: 24842dd8 addiu r4,r4,0x2dd8 r4 = Tile Grid Data (0x192dd8)
0017a5d8: 90820000 lbu r2,0x0000(r4) r2 = Tile's Range
0017a5dc: 00000000 nop
0017a5e0: 1040000f beq r2,r0,0x0017a620 Branch if Range = 0
0017a5e4: 00000000 nop
0017a5e8: 90620006 lbu r2,0x0006(r3) r2 = Load Select/Targetable
0017a5ec: 00000000 nop
0017a5f0: 30420001 andi r2,r2,0x0001 If Tile is Unselectable
0017a5f4: 1440000a bne r2,r0,0x0017a620 Branch if True
0017a5f8: 00000000 nop
0017a5fc: 90620000 lbu r2,0x0000(r3) r2 = Load Cross Section
0017a600: 00000000 nop
0017a604: 3042003f andi r2,r2,0x003f If Cross Section
0017a608: 10470005 beq r2,r7,0x0017a620 Branch if True
0017a60c: 00000000 nop
0017a610: 90620005 lbu r2,0x0005(r3) r2 = Load 5th byte (?)
0017a614: 24c60001 addiu r6,r6,0x0001 r6++
0017a618: 0805e98b j 0x0017a62c
0017a61c: 34420040 ori r2,r2,0x0040 r2 = 0x0040
0017a620: 90620005 lbu r2,0x0005(r3) r2 = Load 5th byte (?)
0017a624: 00000000 nop
0017a628: 304200bf andi r2,r2,0x00bf r2 = 0x00bf
0017a62c: a0620005 sb r2,0x0005(r3) Save 0x40 (Cross Section) or 0xbf
0017a630: 24630008 addiu r3,r3,0x0008 Next Tile
0017a634: 24a50001 addiu r5,r5,0x0001 r5++
0017a638: 28a20200 slti r2,r5,0x0200 If r5 < 0x200
0017a63c: 1440ffe6 bne r2,r0,0x0017a5d8 Branch Back
0017a640: 24840005 addiu r4,r4,0x0005 Next Tile
0017a644: 03e00008 jr r31
0017a648: 00c01021 addu r2,r6,r0 r2 = 0x200

Anyone know what a Cross Section is?

Cross Section Identification 2

0017a64c: 00003021 addu r6,r0,r0 r6 = 0
0017a650: 00002821 addu r5,r0,r0 r5 = Loop Counter
0017a654: 3407003f ori r7,r0,0x003f r7 = If Cross Section
0017a658: 3c038019 lui r3,0x8019
0017a65c: 2463f8cc addiu r3,r3,-0x0734 r3 = Tile Data (18f8cc)
0017a660: 3c048019 lui r4,0x8019
0017a664: 24842dd8 addiu r4,r4,0x2dd8 r4 = Tile Grid Data (192dd8)
0017a668: 90820001 lbu r2,0x0001(r4) r2 = Load Tile Targeted
0017a66c: 00000000 nop
0017a670: 1040000f beq r2,r0,0x0017a6b0 Branch if not targeted
0017a674: 00000000 nop
0017a678: 90620006 lbu r2,0x0006(r3) Load Tile Unselectable
0017a67c: 00000000 nop
0017a680: 30420001 andi r2,r2,0x0001 If Tile is Unselectable
0017a684: 1440000a bne r2,r0,0x0017a6b0 Branch if True
0017a688: 00000000 nop
0017a68c: 90620000 lbu r2,0x0000(r3) Load Tile Geomancy
0017a690: 00000000 nop
0017a694: 3042003f andi r2,r2,0x003f If Tile = Cross Section
0017a698: 10470005 beq r2,r7,0x0017a6b0 Branch if not Cross Section
0017a69c: 00000000 nop
0017a6a0: 90620005 lbu r2,0x0005(r3) Load ?
0017a6a4: 24c60001 addiu r6,r6,0x0001 r6++
0017a6a8: 0805e9af j 0x0017a6bc
0017a6ac: 34420040 ori r2,r2,0x0040 5th byte = 0x0040
0017a6b0: 90620005 lbu r2,0x0005(r3) Load ?
0017a6b4: 00000000 nop
0017a6b8: 304200bf andi r2,r2,0x00bf 5th byte = 0x00bf
0017a6bc: a0620005 sb r2,0x0005(r3) Save 0x0040 or 0x00bf to 5th byte
0017a6c0: 24630008 addiu r3,r3,0x0008 Next Tile
0017a6c4: 24a50001 addiu r5,r5,0x0001 Loop Counter++
0017a6c8: 28a20200 slti r2,r5,0x0200 If Loop Counter < 0x0200
0017a6cc: 1440ffe6 bne r2,r0,0x0017a668 Branch Back if True
0017a6d0: 24840005 addiu r4,r4,0x0005 Next Tile
0017a6d4: 03e00008 jr r31
0017a6d8: 00c01021 addu r2,r6,r0 r2 = Number of loops

Can you spot the difference? Neither can I.

You can find the rest of all the routines I annotated starting from here at the FFH wiki. (http://ffhacktics.com/wiki/Set_panels_affected_by_ability%3F)

Quote from: Choto on May 30, 2014, 08:25:36 pm
idk why psx disassembled like that... but take this. It's a disassembly of scus and battle.bin (and also another file with World.bin and Wldcore). So all you need to do is ctrl-F the address you're looking for and it will take you right to the routine. Then you can copypaste it wherever you want. Just convenient

It disassembled like that because I was being sloppy. But thanks. This'll be a great help and it'll save me some time.

And for Celdia, here's my fftpatch I used in testing. Use it, see if it still crashes. I can't get my game to crash though, even after using Weapon Strike/Range.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on June 02, 2014, 05:52:12 pm
Tried your fftp, Doku. The only change is now I get an unhandled exception error that actually crashes the emulator entirely instead of just freezing the game. I don't know what I'm doing differently from you here, but I can't get it to work.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on June 02, 2014, 07:36:55 pm
Ok.. i'll try to shed some light on what I can.

First, be aware that andi r2, r2, 0xbf removes the 0x40 flag. (0xff - 0x40 = 0xbf). This is commonly referred to as "masking bits". You AND the byte with whatever bits you want to stay, and the rest get set to 0. Conversely, ori r2, r2, 0x40 adds the 0x40 flag. (0x00 + 0x40 = 0x40). Only one of the previous operations are done in the routines you mentioned per loop, so either the flag is being added or removed to each tile.

The 0x80192dd8 + 0x500 is pointing to the higher plane of panels (for when there's a bridge or something). So each panel has 0x05 bytes of data in that section and there are 0x10 X and 0x10 Y. 5*0x10*0x10 = 0x500 bytes of data for each plane of tiles. (Theoretically, there are 0x10 by 0x10 panels for each plane... if you had a map with a higher and lower panel at each location on the map, the game needs to account for this and there would be 0x500 + 0x500 tiles total.) Conveniently, say you need to find the bridge panel in Zirekile Falls. Find its lower panel location (0x192dd8 + whatever) and add 0x500, and you'll have the location for the bridge panel. Sorry if that was mad confusing.

Ya 0x17a6dc routines seems borked. I'm not quite sure what they intended but it could very easily be repurposed to target all allies and target all enemies. r23 seems to have meant to be the Team Indicator (target allies or target enemies). Maybe they realized they could just make 255 aoe and the target ally/target enemy flags.

In any case, Free space for us!

I marked up the first cross section routine. It seems to either store or remove the 0x40 flag in 0x05 of tile data (0x182fcc) based on wether or not a tile type is found for that panel. Then it returns the number of tiles with tile type ID's not equal to 0.

0017a5bc: 00003021 addu r6,r0,r0            r6 = 0
0017a5c0: 00002821 addu r5,r0,r0            r5 = 0
0017a5c4: 3407003f ori r7,r0,0x003f            r7 = 0x003f
0017a5c8: 3c038019 lui r3,0x8019
0017a5cc: 2463f8cc addiu r3,r3,-0x0734         r3 = Tile Data (0x18f8cc)
0017a5d0: 3c048019 lui r4,0x8019
0017a5d4: 24842dd8 addiu r4,r4,0x2dd8         r4 = Tile Grid Data (0x192dd8)
0017a5d8: 90820000 lbu r2,0x0000(r4)         r2 = Tile's Range
0017a5dc: 00000000 nop
0017a5e0: 1040000f beq r2,r0,0x0017a620         Branch if Range = 0 (tile not considered)
0017a5e4: 00000000 nop
0017a5e8: 90620006 lbu r2,0x0006(r3)         r2 = Load Select/Targetable
0017a5ec: 00000000 nop
0017a5f0: 30420001 andi r2,r2,0x0001         If Tile is Unselectable
0017a5f4: 1440000a bne r2,r0,0x0017a620         Branch if True
0017a5f8: 00000000 nop
0017a5fc: 90620000 lbu r2,0x0000(r3)         r2 = Load tile type
0017a600: 00000000 nop
0017a604: 3042003f andi r2,r2,0x003f         Mask off higher bits (those tile type ID's are not used)
0017a608: 10470005 beq r2,r7,0x0017a620         Branch if no tile type found
0017a60c: 00000000 nop
0017a610: 90620005 lbu r2,0x0005(r3)         r2 = Load 5th byte (?)
0017a614: 24c60001 addiu r6,r6,0x0001         counter++
0017a618: 0805e98b j 0x0017a62c
0017a61c: 34420040 ori r2,r2,0x0040            add 0x0040 flag (some targeting thing?)
0017a620: 90620005 lbu r2,0x0005(r3)         r2 = Load 5th byte (?)
0017a624: 00000000 nop
0017a628: 304200bf andi r2,r2,0x00bf         r2 = 0x00bf (remove 0x40 flag)
0017a62c: a0620005 sb r2,0x0005(r3)            save original value either WITH 0x40 or WITHOUT 0x40
0017a630: 24630008 addiu r3,r3,0x0008         Next Tile
0017a634: 24a50001 addiu r5,r5,0x0001         r5++ (Do for all tiles on this plane)
0017a638: 28a20200 slti r2,r5,0x0200         If r5 < 0x200
0017a63c: 1440ffe6 bne r2,r0,0x0017a5d8         Branch Back
0017a640: 24840005 addiu r4,r4,0x0005         Next Tile
0017a644: 03e00008 jr r31
0017a648: 00c01021 addu r2,r6,r0            r2 = number of tiles found (r6 is only incremented if 0x05 in 0x182fcc data is not 0


Still have no clue what that does because I'm not sure about that 0x40 flag. It must have something to do with targeting. That's wierd I thought I knew what that flag was.... anyway onto the next one:

Cross Section Identification 2
0017a64c: 00003021 addu r6,r0,r0               r6 = 0
0017a650: 00002821 addu r5,r0,r0               r5 = Loop Counter
0017a654: 3407003f ori r7,r0,0x003f               r7 = 0x3f
0017a658: 3c038019 lui r3,0x8019
0017a65c: 2463f8cc addiu r3,r3,-0x0734            r3 = Tile Data (18f8cc)
0017a660: 3c048019 lui r4,0x8019
0017a664: 24842dd8 addiu r4,r4,0x2dd8            r4 = Tile Grid Data (192dd8)
0017a668: 90820001 lbu r2,0x0001(r4)            r2 = Load Tile Targeted
0017a66c: 00000000 nop
0017a670: 1040000f beq r2,r0,0x0017a6b0            Branch if not targeted
0017a674: 00000000 nop
0017a678: 90620006 lbu r2,0x0006(r3)            Load Tile Unselectable
0017a67c: 00000000 nop
0017a680: 30420001 andi r2,r2,0x0001            If Tile is Unselectable
0017a684: 1440000a bne r2,r0,0x0017a6b0            Branch if True
0017a688: 00000000 nop
0017a68c: 90620000 lbu r2,0x0000(r3)            Load Tile Type
0017a690: 00000000 nop
0017a694: 3042003f andi r2,r2,0x003f            mask off higher unused bits
0017a698: 10470005 beq r2,r7,0x0017a6b0            Branch if no valid tile ID found
0017a69c: 00000000 nop
0017a6a0: 90620005 lbu r2,0x0005(r3)            Load targeting flags?
0017a6a4: 24c60001 addiu r6,r6,0x0001            number of targeted tiles++
0017a6a8: 0805e9af j 0x0017a6bc
0017a6ac: 34420040 ori r2,r2,0x0040               add 0x40 flag
0017a6b0: 90620005 lbu r2,0x0005(r3)            Load targeting flags
0017a6b4: 00000000 nop
0017a6b8: 304200bf andi r2,r2,0x00bf            remove 0x40 flag
0017a6bc: a0620005 sb r2,0x0005(r3)               save flags either WITH 0x40 or WITHOUT 0x40
0017a6c0: 24630008 addiu r3,r3,0x0008            Next Tile
0017a6c4: 24a50001 addiu r5,r5,0x0001            Do for all tiles on this plane
0017a6c8: 28a20200 slti r2,r5,0x0200            If Loop Counter < 0x0200
0017a6cc: 1440ffe6 bne r2,r0,0x0017a668            Branch Back if True
0017a6d0: 24840005 addiu r4,r4,0x0005            Next Tile
0017a6d4: 03e00008 jr r31
0017a6d8: 00c01021 addu r2,r6,r0               r2 = Number of targeted tiles found


The only difference with this routine is this line:
0017a668: 90820001 lbu r2,0x0001(r4)            r2 = Load Tile Targeted

So I think that the first routine counts the number of Targetable (red) panels and returns that number after giving them the 0x40 flag. The second counts the number of Targeted (YELLOW) panels and returns that number after giving them the 0x40 flag.

So I guess the 0x40 flag means "Targeted or Targetable"? That's all I got.

Also, holy fuckin thanks for adding those routines on the wiki!
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 03, 2014, 04:12:22 pm
Don't despair yet, Celdia. I'm working on an update for Conic AoE. I wanted to release it today because it was supposed to be some simple changes (proper resizing when against a border, etc.), but I got bogged down by my own retarded mistakes. I'll see if I can release it tomorrow.

QuoteThe 0x80192dd8 + 0x500 is pointing to the higher plane of panels (for when there's a bridge or something). So each panel has 0x05 bytes of data in that section and there are 0x10 X and 0x10 Y. 5*0x10*0x10 = 0x500 bytes of data for each plane of tiles. (Theoretically, there are 0x10 by 0x10 panels for each plane... if you had a map with a higher and lower panel at each location on the map, the game needs to account for this and there would be 0x500 + 0x500 tiles total.) Conveniently, say you need to find the bridge panel in Zirekile Falls. Find its lower panel location (0x192dd8 + whatever) and add 0x500, and you'll have the location for the bridge panel. Sorry if that was mad confusing.


Actually, I understand higher panels all too well. No, what I was trying to get at was why use +0x500 when it could have just +0x100 just as easily.

QuoteSo I think that the first routine counts the number of Targetable (red) panels and returns that number after giving them the 0x40 flag. The second counts the number of Targeted (YELLOW) panels and returns that number after giving them the 0x40 flag.

So I guess the 0x40 flag means "Targeted or Targetable"? That's all I got.

One of them is the ending routine for Vertical Threshold/Unknown Flag 1 and 2 and the other is for all the rest. I'm thinking it's some kind of setup for parsing.

While I was experimenting around, I tried to give another skill Linear AoE. While the AoE did come out linear, the range wasn't. I think this means that Linear Range is actually hardcoded to slots instead of being directly tied to the Linear Flag and the shape of the AoE itself. This means that Choto's Flame Wall (as well as easily dealing with Conic AoE's directional nightmare) is genuinely a possibility.

EDIT:
http://finalfantasy.wikia.com/wiki/Lionel_Castle#Lionel_Castle_Oratory
Is...that cross...supposed to be the alleged Cross Section?
faceinhands.jpg
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on June 03, 2014, 11:59:22 pm
Quote from: Dokurider on June 03, 2014, 04:12:22 pm
http://finalfantasy.wikia.com/wiki/Lionel_Castle#Lionel_Castle_Oratory
Is...that cross...supposed to be the alleged Cross Section?
faceinhands.jpg


Actually, if you meant the cross statue behind the altar, that comes up as Furniture. Cross Section is shown in the picture here.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 04, 2014, 02:05:45 pm
Attached is the updated Conic AoE. Removed a possible conflict, AoE now properly resizes when against the map border, and a general slim down of the code. It should also be able to handle map sizes larger than 0x000f now. See if this version works for you, Celdia. If it doesn't, tell me the map, and secondary you are using.

To do:
Fix resizing issue when Caster is far away from the border
Deal with Cone AoE targeting untargetable tiles
Find out what happens when you use the AoE off of higher elevation.


I made a really interesting discovery today, one that some, maybe many, people already know about, but I sure as hell didn't.


Vertical Fixed Routine
r4 = Caster X
r5 = Caster Y
0017a7bc: 308400ff andi r4,r4,0x00ff r4 = Caster X
0017a7c0: 30a500ff andi r5,r5,0x00ff                r5 = Caster Y
0017a7c4: 00a05021 addu r10,r5,r0 r10 = Caster Y
0017a7c8: 2406ffe1 addiu r6,r0,-0x001f r6 = -0x001f
0017a7cc: 3c0c8019 lui r12,0x8019
0017a7d0: 258c2dd8 addiu r12,r12,0x2dd8 r12 = Tile Grid Data (0x192dd8)
0017a7d4: 258d0500 addiu r13,r12,0x0500 r13 = 0x1932d8 (?)
0017a7d8: 340b0001 ori r11,r0,0x0001 r11 = True
0017a7dc: 3c08800e lui r8,0x800e
0017a7e0: 91084e9c lbu r8,0x4e9c(r8) r8 = Max Map X
0017a7e4: 00000000 nop
0017a7e8: 01480018 mult r10,r8 Caster Y * Max X
0017a7ec: 00864821 addu r9,r4,r6 r9 = Caster X - 0x001f
0017a7f0: 00001012 mflo r2
0017a7f4: 00491821 addu r3,r2,r9 r3 = (Caster Y * Max X) + (Caster X - 0x001f)
0017a7f8: 00031080 sll r2,r3,0x02
0017a7fc: 00433821 addu r7,r2,r3 r7 = Tile ID
0017a800: 0520000a bltz r9,0x0017a82c Branch if Caster X -0x1f is negative
0017a804: 00ec1821 addu r3,r7,r12 r3 = Current Tile Data
0017a808: 0128102a slt r2,r9,r8 If Caster X- < Max X
0017a80c: 10400007 beq r2,r0,0x0017a82c Branch if False
0017a810: 00000000 nop
0017a814: 90620000 lbu r2,0x0000(r3) r2 = Current Tile's Range
0017a818: 00000000 nop
0017a81c: 10400003 beq r2,r0,0x0017a82c Branch if no Range
0017a820: 00ed1021 addu r2,r7,r13 r2 = Tile ID + 0x500
0017a824: a06b0001 sb r11,0x0001(r3) Current Tile = Targeted
0017a828: a04b0001 sb r11,0x0001(r2) Current Tile + 0x500 = Targeted
0017a82c: 24c60001 addiu r6,r6,0x0001 r6++
0017a830: 28c20020 slti r2,r6,0x0020 if r6 < 0x20
0017a834: 1440ffe9 bne r2,r0,0x0017a7dc Branch if True
0017a838: 00804821 addu r9,r4,r0 r9 = Caster X
0017a83c: 2406ffe1 addiu r6,r0,-0x001f r6 = -0x001f
0017a840: 3c088019 lui r8,0x8019                   
0017a844: 25082dd8 addiu r8,r8,0x2dd8               r8 = Tile Grid Data (0x192dd8)
0017a848: 250b0500 addiu r11,r8,0x0500              r11 = 0x1932d8 (?)
0017a84c: 34070001 ori r7,r0,0x0001 r7 = True
0017a850: 3c02800e lui r2,0x800e
0017a854: 90424e9c lbu r2,0x4e9c(r2) r2 = Max Map X
0017a858: 00a65021 addu r10,r5,r6                   r10 = Caster Y - 0x001f
0017a85c: 01420018 mult r10,r2                      (Caster Y - 0x001f) * Max X
0017a860: 00001012 mflo r2
0017a864: 00491821 addu r3,r2,r9 r3 = (Caster Y - 0x001f) * Max X + Caster X
0017a868: 00031080 sll r2,r3,0x02 r2 = Tile ID
0017a86c: 00432021 addu r4,r2,r3 r4 = Tile ID + Tile ID
0017a870: 0540000d bltz r10,0x0017a8a8 Branch if (Caster Y - 0x001f) is negative
0017a874: 00881821 addu r3,r4,r8 r3 = Current Tile Data
0017a878: 3c02800e lui r2,0x800e
0017a87c: 90424ea0 lbu r2,0x4ea0(r2) r2 = Max Map Y
0017a880: 00000000 nop
0017a884: 0142102a slt r2,r10,r2 If (Caster Y - 0x001f) < Max Y
0017a888: 10400007 beq r2,r0,0x0017a8a8 Branch if False
0017a88c: 00000000 nop
0017a890: 90620000 lbu r2,0x0000(r3) r2 = Current Tile's Range
0017a894: 00000000 nop
0017a898: 10400003 beq r2,r0,0x0017a8a8 Branch if Range = 0
0017a89c: 008b1021 addu r2,r4,r11 r2 = Current Tile Data + 0x500
0017a8a0: a0670001 sb r7,0x0001(r3) Current Tile = Targeted
0017a8a4: a0470001 sb r7,0x0001(r2) Current Tile + 0x500 = Targeted
0017a8a8: 24c60001 addiu r6,r6,0x0001 r6++
0017a8ac: 28c20020 slti r2,r6,0x0020 If r6 < 0x20
0017a8b0: 1440ffe7 bne r2,r0,0x0017a850 Branch Back if True
0017a8b4: 00000000 nop
0017a8b8: 03e00008 jr r31
0017a8bc: 00000000 nop

Notice anything odd about this routine? That for a routine that's supposed to handle, y'know, vertical, it, at no point, even considers vertical. You see, through some experimentation last night, I actually found that Vertical Fixed actually determines whether a skill has Linear AoE. wat? It's confirmed after I made Cure Linear and gave Earth Slash normal range. I'm not even sure if this flag even handles vertical anymore.

So, when you guys play around with Cone AoE and give a range over 1, please flag it as 'Vertical Fixed', because that's what I originally coded for.

QuoteCross Section

Ooohhh. That makes much more sense.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on June 04, 2014, 04:28:44 pm
Gave it a go. Still hanging when I try to select a target tile, but the error output is a LOT goddamned shorter now. Also tried swapping between my .fftp and yours to see if there was any difference but the error comes out the same, as seen below. First try was Chemist with Battle Skill secondary, 2nd try was Battle Skill alone with no secondary. All testing was done at Doguola Pass, from about the middle of the map, with no targeting tiles outside of the bounds of the map.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 04, 2014, 05:46:02 pm
I wish someone else was trying this out so I'd have a better idea of what's happening here. What bios are you using?
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 04, 2014, 06:03:25 pm
Actually I have a more productive idea.  In fftp, go to slot 0183 in ENTD, make your changes to Ramza, then start a new game. If THAT doesn't work, then make a save state and send it to me and I'll download it tomorrow.
Title: Re: Dokurider's Custom AoEs
Post by: Xifanie on June 04, 2014, 06:53:14 pm
Doing a simple hex search flipping the bytes of the errors, I was able to easily deduct that you are branching to 0x80158748, which seems to be kanji space, but wasn't overwritten with your code.
Your code writes more to like... 0x8014F568

And really, I've made many many hacks if you didn't notice. If you want things to work, you have to make sure everything on your end first, which I doubt you did.

This whole thing is also stuff that I could never hope to understand.



Welcome to ASM hacking.

Also congrats, I ran your .xml through my MIPS analyzer, which detects most (but not all) console freezing bugs, and it returned 0 errors. \o/
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 04, 2014, 09:35:58 pm
Except it is working on my end, flawlessly. I'm looking at my game running it right now (posting from a phone; can't see images btw) with zero errors whatsoever. I just don't understand why Celdia is getting errors running the exact same code I uploaded this morning (which I tested before heading out to the computer lab) that is now running right in front of me with no issues. I Just don't know, bra, but I'm doing everything I can think of to troubleshoot.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on June 04, 2014, 10:38:32 pm
savestate --> step through it with a debugger to see what command its crashing at. It's pretty much the quickest way to figure out why and where something's crashing.

Celdia, I'm assuming you tried the hack by itself to rule out a conflict right?
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on June 05, 2014, 12:34:13 am
The hack by itself has some interesting effects:

- Normal attacks are unaffected.
- Skills, for the most part seem unaffected.
- Queklain attempting to act crashes the game, sending it into a loop of errors that I didn't bother to screenshot.
- Dance and Sing do literally nothing. They show no active targets when selected and they play no animation I assume because they aren't going to hit anyone. Amusingly, the Dancing unit does stop dancing long enough to punch at empty air while the Singing unit just continues his normal singing animation throughout.

Again, this is applying the Cone AoE Final2 hack and nothing else. Without modifying anything with FFTP in some fashion though, I don't have any way to really test the conic AoE. I'm going to try modifying Ramza at ENTD 0183 as suggested and starting a new game to see what effect that has, if any. Will edit this post with results.

EDIT: Doku, this is the weirdest hack, ever. And I use ALMA, ffs.

So, modifying Ramza and starting a new game [I decided to actually modify his Ch2 Squire skillset instead of the ENTD itself,] this hack works seemingly as-expected. I used Wave Around since that was your test skill initially, set for 3/131/1 and it gave me no problems at all. Some of the potential AoEs possible from selecting different tiles was interesting, so I looked deeper and tried my original idea. I chose a different skill [Head Break] and gave it 5/133/3 which resulted in more interesting changes. The targeting worked fine for the first 3 tiles out from Ramza, forming a 5-tile cone originating from the selected tile. But selecting the 4th and 5th tiles out caused the AoE to start from Ramza and spread to end of the map. On Orbonne, this results in a total AoE of Cone-8. Which, by the way, also works. I tried some more modifications and then I went to apply a change to the skill name I'd been working with to use for a quick demo video...and when Gaffy tried to move I got this:
(http://i.imgur.com/0l4Y3Sq.png)


I don't even know. So I started over from scratch, applied just Cone Final2 and my Patcher changes and it went back to functioning fine. Even tested my old .fftp for its changes and had no problems. It's looking like my changes in Tactext may have been the culprit after all this which while making me look like the fool still possibly reveals a different problem with the hack.

Pre-Edit: Just applied the Tactext change again, which is literally ONE skill name being lengthened, and it crashes. So, I've located the source of the error in my case. But if this hack can't be used with any text changes, I don't see it going too far. I'll keep checking in here for updates though.
Title: Re: Dokurider's Custom AoEs
Post by: Choto on June 05, 2014, 12:32:53 pm
The gaffy thing sounds like an AI issue. Try setting Rama to auto battle. They do some calculations to find max and min range attacks
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 05, 2014, 04:21:12 pm
QuoteFFTactext

Oh of course. FFTactext overwrites text space, and this hack is saved in, wait for it, text space, albeit space that isn't supposed to be used in the NTSC-U, Kanji Space. Did you apply FFTactext before you patched, or after and what skill did you change?

Quoteused Wave Around since that was your test skill initially, set for 3/131/1 and it gave me no problems at all. Some of the potential AoEs possible from selecting different tiles was interesting, so I looked deeper and tried my original idea. I chose a different skill [Head Break] and gave it 5/133/3 which resulted in more interesting changes. The targeting worked fine for the first 3 tiles out from Ramza, forming a 5-tile cone originating from the selected tile. But selecting the 4th and 5th tiles out caused the AoE to start from Ramza and spread to end of the map. On Orbonne, this results in a total AoE of Cone-8. Which, by the way, also works.


That is actually the result of an oversight. I've known about it for a while now and I'm going to fix it next version. I foolishly tied the border logic to the Caster, which causes it to resize to where the caster is, which was okay initially because I was only using it in conjunction with 1 Range. But by using massive Ranges, this flaw becomes pretty obvious, especially if you're halfway across the map.

QuoteDance and Sing do literally nothing. They show no active targets when selected and they play no animation I assume because they aren't going to hit anyone. Amusingly, the Dancing unit does stop dancing long enough to punch at empty air while the Singing unit just continues his normal singing animation throughout.

Also makes sense. Dance and Sing's abilities are at 255 AoE, which the hack interprets as "Cone AoE". Cone AoE doesn't work if you have 0 Range, or if you don't select a target, thus, no AoE. In order to have Dance/Sing (and Galaxy Stop) work normally, just set it to 0x0f or 15 AoE.

This report is pretty grim. Worst case scenario is that Kanji Space is being used by the various events and yet unknown to me arcane functions and code (god help me if it's pointer data) in the game, meaning I may not be able to have it there. I might just have to find some other space to place this hack. As of now, this hack requires 0xEF lines of code, and the next update is only going to expand on that and I only know of two routines I can write over. The best I can do in the meantime is to press on and just finish the code and hope one day I can find enough space to fit it into the game. I'm still looking at and documenting code for other hacks I want to develop, so prospect of that happening isn't impossible and can even happen sooner rather than later.

In any case, I thank you for your time and patience, Celdia, Choto, Xifanie, Elric, and yes, even you, Jack of All Trades.

QuoteEDIT: Doku, this is the weirdest hack, ever. And I use ALMA, ffs.

lol.
It may end up not as weird anymore if the Unknown Flags of Ability Flags 1 can be verified as being truly and utterly useless/nonfunctioning. Then I can just use those and drop the whole AoE as a flag thing.
Title: Re: Dokurider's Custom AoEs
Post by: Celdia on June 05, 2014, 10:24:00 pm
Ha! Order of operations! Of course!

By patching Cone Final2 last, my text changes are still applied and the hack works fine. So at least this can be used without crashing things so long as that is accounted for. I don't know why I didn't think about this before, especially with me running into a very similar problem testing something else recently. -_-;;
Title: Re: Dokurider's Custom AoEs
Post by: Glain on June 06, 2014, 12:22:15 am
There's still something weird about this, isn't there?  If you have to patch one first, then the other, that would imply that something is being overwritten.  I don't recall Tactext normally patching over kanji space...

Does kanji space really start all the way back at 0x0014f334 RAM?  That's too far back to even be in the allocated space.
Title: Re: Dokurider's Custom AoEs
Post by: Xifanie on June 06, 2014, 04:26:20 am
Glain's got a point there.

http://ffhacktics.com/wiki/Font

Characters STARTS at 0x000E92AC BATTLE.BIN / 0x8014E614 Memory
"Kanji" (still hiragana) starts at 0x000E9284 BATTLE.BIN / 0x80150284 Memory

Very important things to know:
- Never EVER overwrite single byte characters, They're used by tactext to combine characters for better compression. Like "th" being a one byte character.
- Early Kanji space is used by my hacks. http://ffhacktics.com/wiki/Allocated_space

You're currently overwriting starting from character 0x60.
So yeah, tactext breaking your hack isn't surprising at all.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 06, 2014, 03:20:08 pm
I see. I shall start work this weekend.
Title: Re: Dokurider's Custom AoEs
Post by: LastingDawn on June 07, 2014, 05:59:28 pm
Great work on figuring out a lot more about the range Dokurider! By chance were you looking into "Weapon Cast" AoE's at all? Or is that pretty much hardcoded to be a single target no matter what?
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 12, 2014, 10:41:30 pm
Quote from: LastingDawn on June 07, 2014, 05:59:28 pm
Great work on figuring out a lot more about the range Dokurider! By chance were you looking into "Weapon Cast" AoE's at all? Or is that pretty much hardcoded to be a single target no matter what?

Weapon cast? You mean like procs? Or getting AoE out of Weapon Range? Because if it's the latter, then yeah, it is hardcoded as single target only. I will look into it, but right now my hands are full with this hack.
Speaking of:

I don't really understand why Kanji Space Nopper NOPs 0x14f334 or character 0x60 if it's going to cause tactext trouble. Or where they never meant to be compatible to begin with?
Title: Re: Dokurider's Custom AoEs
Post by: Xifanie on June 12, 2014, 11:49:16 pm
whoo~ Raven blaming time, my favourite time of the day \o/
Title: Re: Dokurider's Custom AoEs
Post by: RavenOfRazgriz on June 12, 2014, 11:56:23 pm
Quote from: Xifanie on June 12, 2014, 11:49:16 pm
whoo~ Raven blaming time, my favourite time of the day \o/


Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on December 21, 2016, 05:33:38 pm
k, I'm back

I'll add pictures later on.



Cone AoE (v2)
Version 1.09
Creates Cone AoE. Enable this on any skill by flagging both Linear and Tri Direction AoE flags. Uses Kanji Space. Uses lines 0x1557fc - 0x155b04. 194 Lines. Does not work with Direct/Stop at Obstacle or Weapon Range, as neither does Linear/Tri AoE. Does not work with Auto Target, so give it a non-zero range. Don't even think about targeting yourselves, you derps. Designed to emulate Linear/Tri's behaviors including being dependent on the caster panel to be generated.
0017bb24: Targeting Routine (0x0017b874)

0017bb24: 06000234 ori r2,r0,0x0006
0017bb28: FF55050C jal 0x001557fc
0017bb2c: 00000000 nop
0017bb30: 02004014 bne r2,r0,0x0017bb3c
0017bb34: 1000A427 addiu r4,r29,0x0010 Needed for Ally/Enemy Targeting Routine
0017bb38: 0C56050C jal 0x00155830 Cone Generation Routine
0017bb3c: 00000000 nop
0017bb40: 0300A010 beq r5,r0,0x0017bb50 Branch if not flagged as Linear/Tri
0017bb44: C0003032 andi r16,r17,0x00c0
0017bb48: 9AEF050C jal 0x0017be68 Linear/Tri Generation Routine
0017bb4c: 00000000 nop

========================================================

Morbol Virus Depth Check (0x00179204)

00179214: 00004126 addiu r1,r18,0x0000 Saves Target Tile Vertical

========================================================

001557fc: Parse Linear AoE Flags Routine

001557fc: 06002632 andi r6,r17,0x0006 False if flagged as Cone (Linear + Tri)
00155800: 09004610 beq r2,r6,0x00155828 Branch if Cone AoE
00155804: 00000234 ori r2,r0,0x0000 r2 = Cone AoE
00155808: 02000234 ori r2,r0,0x0002
0015580c: 0600C210 beq r6,r2,0x00155828 Branch if Tri Linear AoE
00155810: 03000534 ori r5,r0,0x0003 r5 = 3 (Tri Linear Value)
00155814: 04000234 ori r2,r0,0x0004
00155818: 0300C210 beq r6,r2,0x00155828 Branch if Linear AoE
0015581c: 01000534 ori r5,r0,0x0001 r5 = 1 (Linear Value)
00155820: FF000234 ori r2,r0,0x00ff r2 = -1 (No Value)
00155824: 00000534 ori r5,r0,0x0000
00155828: 0800E003 jr r31
0015582c: 00002F24 addiu r15,r1,0x0000 r15 = Target Tile Vertical

========================================================================

00155830: AoE Flagging Routine

r5 = IsLinear/Tri? (1,3,0)
r15 = Target Tile Vertical
r16 = Unit Y
r17 = Unit X
r18 = Target X
r19 = Direction
r20 = Target Y
r21 = Vertical


00155830: C0FFBD27 addiu r29,r29,-0x0040 Pointer Memory - 40
00155834: 1000A527 addiu r5,r29,0x0010
00155838: 3C00BFAF sw r31,0x003c(r29)
0015583c: 3800B4AF sw r20,0x0038(r29)
00155840: 3400B3AF sw r19,0x0034(r29)
00155844: 3000B2AF sw r18,0x0030(r29)
00155848: 2C00B1AF sw r17,0x002c(r29)
0015584c: 8B78010C jal 0x0005e22c Transfer Attacker/Self ID Routine
00155850: 2800B0AF sw r16,0x0028(r29)
00155854: 1000A393 lbu r3,0x0010(r29) Load Attacker/Self ID
00155858: 1C00B287 lh r18,0x001c(r29) Load Target X
0015585c: 2000B487 lh r20,0x0020(r29) Load Target Y
00155860: 01000234 ori r2,r0,0x0001 r2 = 1
00155864: 1980013C lui r1,0x8019
00155868: F8F422AC sw r2,-0x0b08(r1) Linear Attack = True
0015586c: C0100300 sll r2,r3,0x03
00155870: 23104300 subu r2,r2,r3
00155874: 80110200 sll r2,r2,0x06
00155878: 1980033C lui r3,0x8019
0015587c: CC086324 addiu r3,r3,0x08cc Load Unit Data
00155880: 21104300 addu r2,r2,r3
00155884: 47005190 lbu r17,0x0047(r2) Load Unit's X
00155888: 48005090 lbu r16,0x0048(r2) Load Unit's Y

0015588c: 2A103202 slt r2,r17,r18
00155890: 04004010 beq r2,r0,0x001558a4 Branch if Unit X >= Target X is not true
00155894: 01001334 ori r19,r0,0x0001 Direction = +X
00155898: 5856050C jal 0x00155960 Cone Generation Routine
0015589c: 00000000 nop
001558a0: 3A560508 j 0x001558e8
001558a4: 2A105102 slt r2,r18,r17
001558a8: 04004010 beq r2,r0,0x001558bc Branch if Target X >= Unit X is not true
001558ac: FF001334 ori r19,r0,0x00ff Direction = -X
001558b0: 5856050C jal 0x00155960 Cone Generation Routine
001558b4: 00000000 nop
001558b8: 3A560508 j 0x001558e8
001558bc: 2A101402 slt r2,r16,r20
001558c0: 04004010 beq r2,r0,0x001558d4 Branch if Unit Y >= Target Y is not true
001558c4: 00011334 ori r19,r0,0x0100 Direction = +Y
001558c8: 5856050C jal 0x00155960 Cone Generation Routine
001558cc: 00000000 nop
001558d0: 3A560508 j 0x001558e8
001558d4: 2A109002 slt r2,r20,r16
001558d8: 18004010 beq r2,r0,0x0015593c End if Target Y >= Unit Y is not true
001558dc: 00FF1334 ori r19,r0,0xff00 Direction = -Y
001558e0: 5856050C jal 0x00155960 Cone Generation Routine
001558e4: 00000000 nop

001558e8: 21200000 addu r4,r0,r0 Tile Counter = 0
001558ec: 1980033C lui r3,0x8019
001558f0: D82D6324 addiu r3,r3,0x2dd8
001558f4: 01006290 lbu r2,0x0001(r3) Load Tile Targeted? Flag
001558f8: 00000000 nop
001558fc: 03004014 bne r2,r0,0x0015590c Branch if Tile is Targeted?
00155900: 00000000 nop
00155904: 44560508 j 0x00155910
00155908: 000060A0 sb r0,0x0000(r3) AoE = 0
0015590c: 010060A0 sb r0,0x0001(r3) Tile Targeted? = False
00155910: 01008424 addiu r4,r4,0x0001 Counter ++
00155914: 00028228 slti r2,r4,0x0200
00155918: F6FF4014 bne r2,r0,0x001558f4 Branch if Counter < 0x200
0015591c: 05006324 addiu r3,r3,0x0005 Pointer += 5

00155920: 00000000 nop [deleted line]
00155924: 2C00B18F lw r17,0x002c(r29)
00155928: FF00E431 andi r4,r15,0x00ff
0015592c: 2128A002 addu r5,r21,r0
00155930: 42311100 srl r6,r17,0x05
00155934: A9E4050C jal 0x001792a4 check vertical tolerance + if tiles can be chosen
00155938: 0100C630 andi r6,r6,0x0001 Top Down Targeting Flag

0015593c: 3C00BF8F lw r31,0x003c(r29)
00155940: 3800B48F lw r20,0x0038(r29)
00155944: 3400B38F lw r19,0x0034(r29)
00155948: 3000B28F lw r18,0x0030(r29)
0015594c: 2C00B18F lw r17,0x002c(r29)
00155950: 2800B08F lw r16,0x0028(r29)
00155954: 4000BD27 addiu r29,r29,0x0040 Pointer + 40
00155958: 0800E003 jr r31
0015595c: 25280000 or r5,r0,r0 Is Linear/Tri? = False

====================================================================



00155960: Cone Attack Tile Calculation

r4 = Tile Coordinate
r5 = Secondary Tile Coordinate
r6 = AoE
r7 = Row Counter
r8 = 0xffffffff (Also used as Temporary High Tile Coordinate)
r9 = Row Width Counter
r10 = 0x0001 (True)
r16 = Unit Y (Treated as Current Y)
r17 = Unit X (Treated as Current X)
r18 = Target X
r20 = Target Y
r19 = Direction


00155960: 21380000 addu r7,r0,r0 Initialize Row Counter
00155964: 19800B3C lui r11,0x8019
00155968: D82D6B25 addiu r11,r11,0x2dd8 r11 = Tile Data Pointer
0015596c: 01000A34 ori r10,r0,0x0001 r10 = True
00155970: 3400A68F lw r6,0x0034(r29) r6 = AoE
00155974: 62004006 bltz r18,0x00155af0 Branch if X is negative
00155978: 0E80033C lui r3,0x800e
0015597c: 9C4E6390 lbu r3,0x4e9c(r3) Load Map Max X
00155980: 00000000 nop
00155984: 2A104302 slt r2,r18,r3
00155988: 5D004010 beq r2,r0,0x00155af0 Branch if X >= Max X
0015598c: 00000000 nop
00155990: 5B008006 bltz r20,0x00155af0 Branch if Y is negative
00155994: 0E80023C lui r2,0x800e
00155998: A04E4290 lbu r2,0x4ea0(r2) Load Map Max Y
0015599c: 00000000 nop
001559a0: 2A108202 slt r2,r20,r2
001559a4: 56004010 beq r2,r0,0x00155af0 Branch if Y >= Max Y

001559a8: 18000302 mult r16,r3 Y * Max X
001559ac: 12100000 mflo r2
001559b0: 21205100 addu r4,r2,r17 Tile ID = Y * Max X + X

<-Row Length Main Loop Starts Here->
========================
X Direction Sub Routine
========================

001559b4: 0E80083C lui r3,0x800e
001559b8: FF000834 ori r8,r0,0x00ff r8 = -1
001559bc: 24106802 and r2,r19,r8 Get X Direction from Direction Variable
001559c0: 0F004010 beq r2,r0,0x001559f0 Branch to Y if no X Direction obtained
001559c4: 00000000 nop

-X Direction

001559c8: 05000215 bne r8,r2,0x001559d0 Branch if r2 =/= -X Direction
001559cc: FFFF2126 addiu r1,r17,0xffff Current X - 1
001559d0: 48002004 bltz r1,0x00155ae4 Proceed to Next Row if the current Target X = -1
001559d4: 00000000 nop
001559d8: 7D560508 j 0x001559f4 Go To Tile Coordinates Modify Function
001559dc: FFFF0224 addiu r2,r0,0xffff r2 = -1


+X Direction

001559e0: 9C4E6390 lbu r3,0x4e9c(r3) Load Map Max X
001559e4: 01002126 addiu r1,r17,0x0001 Current X + 1
001559e8: 42006110 beq r3,r1,0x00155ae4 End if current Target X is Max X
001559ec: 00000000 nop
001559f0: 01000220 addi r2,r0,0x0001 r2 = 1

001559f4: 20882202 add r17,r17,r2 Current Target X++
001559f8: 93560508 j 0x00155a4c Go to Row Generation Subroutine
001559fc: 20208200 add r4,r4,r2 Tile Coordinates is modified(+/-)

========================
Y Direction Sub Routine
========================

00155a00: 02121300 srl r2,r19,0x0008 Get Y Direction from Direction Variable
00155a04: 3E004010 beq r2,r0,0x00155af0 End if no Y Direction obtained
00155a08: FFFF0126 addiu r1,r16,0xffff Current Y - 1

-Y Direction

00155a0c: 06000215 bne r8,r2,0x00155a18 Branch if r2 =/= 0x00ff
00155a10: 00000000 nop

00155a14: 37002004 bltz r1,0x00155ae4 End Routine if the current Target Y = -1
00155a18: FFFF0224 addiu r2,r0,0xffff
00155a1c: 9C4E6390 lbu r3,0x4e9c(r3) Get Max X
00155a20: 91560508 j 0x00155a44 Jump to Modify Tile Coordinate Function
00155a24: 22180300 sub r3,r0,r3 r3 = -Max X (-Y)

+Y Direction

00155a28: A04E6390 lbu r3,0x4ea0(r3) Load Max Y
00155a2c: 01000126 addiu r1,r16,0x0001 Current Y + 1
00155a30: 30007010 beq r3,r16,0x00155ae4 Branch if current Target Y is greater than Max Y
00155a34: 00000000 nop
00155a38: 0E80033C lui r3,0x800e
00155a3c: 9C4E6390 lbu r3,0x4e9c(r3) Get Max X
00155a40: 01000234 ori r2,r0,0x0001

00155a44: 20800202 add r16,r16,r2 Current Target Y++
00155a48: 20208300 add r4,r4,r3 Tile Coordinates++

========================
Row Generation Subroutine
========================

What direction are we going?
If X direction, then make Y rows, and vice versa

r7 = Row Counter
r9 = Row Size Counter
r6 = AoE
r9 = r0 - r7
r9++ until r9 = r7
r7++ until r7 = r6

r20 = Target Y
r18 = Target X
r5 = Secondary Tile Coordinate

========================================================================================

00155a4c: 22480700 sub r9,r0,r7 Initialize Row Size Counter
00155a50: 25288000 or r5,r4,r0 Initialize Secondary Tile Coordinate
<-Row Size Subloop Begins Here->
00155a54: FF000334 ori r3,r0,0x00ff
00155a58: 24106302 and r2,r19,r3 Get X Direction from Direction Variable
00155a5c: 0E004010 beq r2,r0,0x00155a88 Branch if X Direction was not obtained
00155a60: 0E80033C lui r3,0x800e

Y Row

00155a64: 20100902 add r2,r16,r9
00155a68: 20004004 bltz r2,0x00155adc Branch if Y Size is negative
00155a6c: A04E6390 lbu r3,0x4ea0(r3) Load Max Y
00155a70: 00000000 nop
00155a74: 1F006210 beq r3,r2,0x00155ae4 Branch if Y Size = Max Y
00155a78: 00000000 nop
00155a7c: 0E80033C lui r3,0x800e
00155a80: 9C4E6390 lbu r3,0x4e9c(r3) Load Map Max X
00155a84: 00000000 nop
00155a88: 18006900 mult r3,r9 Max X * Row Size Counter
00155a8c: 12180000 mflo r3
00155a90: B0560508 j 0x00155ac0 Jump to Save Tile
00155a94: 20288300 add r5,r4,r3 Modify Secondary Tile Coordinate

X Row

00155a98: 02121300 srl r2,r19,0x0008 Get X Direction from Direction Variable
00155a9c: 18004010 beq r2,r0,0x00155af0 End if no X Direction obtained
00155aa0: 00000000 nop
00155aa4: 20102902 add r2,r17,r9
00155aa8: 10004004 bltz r2,0x00155adc Branch if X Size is negative
00155aac: 9C4E6390 lbu r3,0x4e9c(r3) Load Map Max X
00155ab0: 00000000 nop
00155ab4: 0F006210 beq r3,r2,0x00155ae4 Branch if X Size = Max X
00155ab8: 00000000 nop
00155abc: 20288900 add r5,r4,r9 Modify Secondary Tile Coordinate

Save Tile

00155ac0: 80100500 sll r2,r5,0x02 ID * 4
00155ac4: 21104500 addu r2,r2,r5 ID * 5
00155ac8: 21184B00 addu r3,r2,r11
00155acc: 00006AA0 sb r10,0x0000(r3) Store Low Tile's AoE = True
00155ad0: 01006AA0 sb r10,0x0001(r3) Store Low Tile Targeted? = True
00155ad4: 0001A824 addiu r8,r5,0x0100 Tile ID + 0x100
00155ad8: 80100800 sll r2,r8,0x02 ID * 4
00155adc: 21104800 addu r2,r2,r8 ID * 5
00155ae0: 21184B00 addu r3,r2,r11
00155ae4: 00006AA0 sb r10,0x0000(r3) Store High Tile's AoE = True
00155ae8: 01006AA0 sb r10,0x0001(r3) Store High Tile Targeted? = True
00155aec: D9FF2715 bne r9,r7,0x00155a44 Branch if Size Counter = Row Counter else loop
00155af0: 01002921 addi r9,r9,0x0001 Size Counter++
00155af4: 2210C700 sub r2,r6,r7
00155af8: AEFF401C bgtz r2,0x001559a4 Finish if Row Counter has exceeded AoE else loop
00155afc: 0100E724 addiu r7,r7,0x0001 Row Counter++
00155b00: 0800E003 jr r31
00155b04: 00000000 nop



"Arcing" AoE and Range
Version 1.1
Feeds AoE/Range generation through the Arc Range Routine (001798b0), creating an AoE/Range that gains size from height/2
Uses Ability Flags 1 Unknown Flags 0x80 and 0x40.
Removes and overwrites the coding otherwise attached to the Unknown Ability Flags (0017a6dc) known so far. Does not use Kanji Space.
0x80 - Arcing AoE
0x40 - Arcing Range
Old:

0017bac8: 00002821 addu r5,r0,r0
0017bacc: 26620001 addiu r2,r19,0x0001
0017bad0: a1020000 sb r2,0x0000(r8) store aoe + 1
0017bad4: 0c05e546 jal 0x00179518 Store surrounding panels AoE value
0017bad8: a0e20000 sb r2,0x0000(r7) store aoe + 1

New:
0017bac8: 0680053C lui r5,0x8006
0017bacc: 01006226 addiu r2,r19,0x0001
0017bad0: 000002A1 sb r2,0x0000(r8)
0017bad4: B7E9050C jal 0x0017a6dc Arc Range/AoE Routine


Old:

0017a43c: 0c05e546 jal 0x00179518 Calculate Tiles Hit by Ability
0017a440: 00002821 addu r5,r0,r0 r5 = 0

New:

0017a43c: B7E9050C jal 0x0017a6dc Arc Range/AoE Routine
0017a440: 0680053C lui r5,0x8006

Old:

0017a4a0: 324200c0 andi r2,r18,0x00c0 If Unknown Flags 0x80/0x40 (!!!)
0017a4a4: 0c05e497 jal 0x0017925c Clear Some stuff for Untargetable Terrain
0017a4a8: 00000000 nop
0017a4ac: 324200c0 andi r2,r18,0x00c0 If Unknown Flags 0x80/0x40 (!!!)
0017a4b0: 10400003 beq r2,r0,0x0017a4c0 Branch if False
0017a4b4: 02802021 addu r4,r20,r0 r4 = Caster Data
0017a4b8: 0c05e9b7 jal 0x0017a6dc Target Ally/Enemy with Range Routine
0017a4bc: 02402821 addu r5,r18,r0 r5 = Ability Flags 1
0017a4c0: 324200d0 andi r2,r18,0x00d0 If Unknown Flags 0x80/0x40 or Vertical Fixed
0017a4c4: 14400005 bne r2,r0,0x0017a4dc Branch if True

New:

0017a4a0: 00000000 nop
0017a4a4: 97E4050C jal 0x0017925c Clear Some stuff for Untargetable Terrain
0017a4a8: 00000000 nop [Deleted]
0017a4ac: 00000000 nop
0017a4b0: 00000000 nop
0017a4b4: 00000000 nop
0017a4b8: 00000000 nop
0017a4bc: 21208002 addu r4,r20,r0
0017a4c0: 10004232 andi r2,r18,0x0010
0017a4c4: 05004014 bne r2,r0,0x0017a4dc Branch if Vertical Fixed


Arc Range/AoE Routine

0017a6dc: F0FBA524 addiu r5,r5,0xfbf0
0017a6e0: 1200A287 lh r2,0x0012(r29)           r2 = Used Ability ID
0017a6e4: C0180200 sll r3,r2,0x03
0017a6e8: 23186200 subu r3,r3,r2
0017a6ec: 40180300 sll r3,r3,0x01
0017a6f0: 2128A300 addu r5,r5,r3
0017a6f4: 1880063C lui r6,0x8018
0017a6f8: A8A7DFAC sw r31,0xa7a8(r6) Save return address
0017a6fc: A8A7C280 lb r2,0xa7a8(r6) Load last two bytes of Return Address' instructions
0017a700: FF004230 andi r2,r2,0x00ff
0017a704: DC000334 ori r3,r0,0x00dc
0017a708: 0300A580 lb r5,0x0003(r5) Load Ability Flags 1
0017a70c: 14004314 bne r2,r3,0x0017a760 Branch if not from Targeting Routine (From AoE routine)
0017a710: 8000A230 andi r2,r5,0x0080
0017a714: 1D004010 beq r2,r0,0x0017a78c Branch if not Arc AoE
0017a718: 4CA7C324 addiu r3,r6,0xa74c
0017a71c: 2000AD93 lbu r13,0x0020(r29) r13 = Target Y
0017a720: 1C00AC93 lbu r12,0x001c(r29) r12 = Target X
0017a724: 0E80023C lui r2,0x800e
0017a728: D0FFBD27 addiu r29,r29,-0x0030
0017a72c: 2000B0AF sw r16,0x0020(r29)
0017a730: 2400B1AF sw r17,0x0024(r29)
0017a734: 2800A3AF sw r3,0x0028(r29) Save Return Address
0017a738: 3899C0AC sw r0,0x9938(r6) Remove Close Range Branch from Arc routine
0017a73c: 21184002 addu r3,r18,r0 r3 = Target Height
0017a740: 21886002 addu r17,r19,r0 r17 = AoE
0017a744: 39E6050C jal 0x001798e4 Calculate Arc AoE Routine (Jump to later on in the routine)
0017a748: A04E4290 lbu r2,0x4ea0(r2) r2 = Max Map Y
0017a74c: 1880023C lui r2,0x8018
0017a750: 4014033C lui r3,0x1440
0017a754: 27006324 addiu r3,r3,0x0027 Load instructions (14400027)
0017a758: 389943AC sw r3,0x9938(r2) Restore Close Range Branch from Arc Routine
0017a75c: E5E90508 j 0x0017a794 Exit Routine
0017a760: 4000A230 andi r2,r5,0x0040
0017a764: 09004010 beq r2,r0,0x0017a78c Branch if not Arc Range
0017a768: 25288000 or r5,r4,r0 r5 = Ability Range
0017a76c: 3899C0AC sw r0,0x9938(r6)
0017a770: 2CE6050C jal 0x001798b0 Calculate Arc Range Routine
0017a774: 25208002 or r4,r20,r0 r4 = Caster Unit Data
0017a778: 1880023C lui r2,0x8018
0017a77c: 4014033C lui r3,0x1440
0017a780: 27006324 addiu r3,r3,0x0027 Load instructions (14400027)
0017a784: E5E90508 j 0x0017a794
0017a788: 389943AC sw r3,0x9938(r2) Restore Close Range Branch from Arc Routine
0017a78c: 46E5050C jal 0x00179518 Store surrounding panels AoE value (Normal function)
0017a790: 21280000 addu r5,r0,r0
0017a794: 1880023C lui r2,0x8018
0017a798: A8A75F8C lw r31,0xa7a8(r2) Load old return address
0017a79c: 00000000 nop
0017a7a0: 0800E003 jr r31
0017a7a4: 00000000 nop
0017a7a8: 00000000 nop Return Address here



Reenables Unknown Flags 1 and 2
Speaking of the Unknown Ability Flags, this hack restores their functionality that was deliberately disabled by Square. Enables you to target any ally or any enemy on the map.
No notes because there really isn't much to it. It's literally a single line.


Weapon Range now accepts AoE
Version -1.0
I'm releasing this against my better judgement. Enables the use of Weapon Ranged AoE. It might also enable Direct/Stop at Obstacle AoE as well. Won't crash your game, but it's interactions with AoE might cause your brain to crash if I'm reading the Weapon Strike/Direct routines correctly. Still current doing research on the matter, but feel free to be a guinea pig.
0017af40: 0c05ed28 jal 0x0017b4a0 Invalidate AoE panels routine (In the Weapon Targeting Routine [0017ac90])
to
0017af40: 00000000 nop [deleted]

0017babc: 31220020 andi r2,r9,0x0020 Weapon Ranged check
0017bac0: 1440000e bne r2,r0,0x 0017bafc branch if so
to
0017bac0: 00000000 nop [deleted]



Clear Yellow Panels not occupied by a unit.
Version 2.0
Overwrites Morbol AoE Depth Routine. Takes the 255 AoE check and modifies it to target only tiles with units in them. Good for Random Fire Skills. Saves Ability ID to unused lines for future Ability ID hardcoding. Enable this on an ability by flagging it as a Math Skill.

Don't Target Empty Space Routine

====================================================================================================================================
Targeting/AoE Main Routine(0x0017b874)
====================================================================================================================================

Original Code:
0017b8d0: 90690003 lbu r9,0x0003(r3) Load ability flags 1
0017b8d4: 90710004 lbu r17,0x0004(r3) Load ability flags 2
0017b8d8: 90640006 lbu r4,0x0006(r3) Load ability flags 4

New Code
0017b8d4: lhu r17,0x0004(r3) Load Ability Flags 2 and 3

====================================================================================================================================

Original Code
0017bae4: 00113142 srl r6,r17,0x05 Parse down Ability Flag 2 to Top Down Targeting Flag

New Code
0017bae4: andi r6,r17,0x00e0 Parse Ability Flag 2 to Hit Ally/Enemy

====================================================================================================================================

Original Code
0017baec: 30c60001 andi r6,r6,0x0001 Keep Top Down Targeting Flag

New Code
0017baec: andi r6,r6,0x0020 Keep Top Down Targeting Flag

====================================================================================================================================

Original Code
0017baf4: 0c05e481 jal 0x00179204 moldball virus depth check
0017baf8: 00000000 nop

New Code
0017baf4: jal 0x00179204 moldball virus depth check
0017baf8: lui r2,0x8018

====================================================================================================================================

Original Code
0017b9fc: 326300ff andi r3,r19,0x00ff r3 = ability AoE
0017ba00: 340200ff ori r2,r0,0x00ff
0017ba04: 1462000c bne r3,r2,0x 0017ba38 Branch if ability AoE isn't 0xff
0017ba08: 00002021 addu r4,r0,r0
0017ba0c: 34050001 ori r5,r0,0x0001
0017ba10: 3c038019 lui r3,0x8019
0017ba14: 24632dd8 addiu r3,r3,0x2dd8
0017ba18: a0650000 sb r5,0x0000(r3) store highlight panel for targeting
0017ba1c: a0600001 sb r0,0x0001(r3) store panel not targeted
0017ba20: 24840001 addiu r4,r4,0x0001 Counter++
0017ba24: 28820200 slti r2,r4,0x0200 Do for all tiles
0017ba28: 1440fffb bne r2,r0,0x 0017ba18
0017ba2c: 24630005 addiu r3,r3,0x0005 tile counter++
0017ba30: 0805eebf j 0x 0017bafc skip following routine
0017ba34: 00000000 nop

New Code
0017b9fc: addu r4,r0,r0 Clear r4
0017ba00: andi r2,r17,0x4000 Get Math Skill Flag
0017ba04: lui r3,0x8018
0017ba08: addiu r3,r3,0xba28
0017ba0c: sh r0,0x0000(r3) Clear space
0017ba10: beq r2,r0,0x0017ba38 Branch if no Math Flag
0017ba14: nop
0017ba18: xori r17,r17,0x00c0 Add Ignore Ally/Enemy Flag if Math Skill (Reverses the effects of a later routine)
0017ba1c: sh r2,0x0000(r3) Jump to Tile Initialization
0017ba20: j 0x0017ba38 Save Math Skill Flag for later
0017ba24: nop
0017ba28: nop                           [save Math Flag here]
0017ba2c: nop [save Ability ID here]
0017ba30: nop
0017ba34: nop                             

====================================================================================================================================

Original Code
0017bb40: 323000c0 andi r16,r17,0x00c0 Keep Hit Ally/Enemy Flags

New Code
0017bb40: andi r16,r17,0x40c0 Keep Hit Ally/Enemy and Math Skill Flag

====================================================================================================================================

Original Code
0017bb60: 3a6700ff xori r7,r19,0x00ff
0017bb64: 0c05ef1e jal 0x0017bc78 Hit ally/enemy routine
0017bb68: 2ce70001 sltiu r7,r7,0x0001

New Code
0017bb60: lui r7,0x8018
0017bb64: jal 0x0017bc78 Hit ally/enemy routine
0017bb68: addiu r7,r7,0xba28 Load Math Skill Flag

====================================================================================================================================
Check if Ally/Enemy can be targeted Routine(0x0017bc78)
====================================================================================================================================

Original Code
0017bc90: 00e0b821 addu r23,r7,r0 r23 = 255 AoE check

New Code
0017bc90: lhu r23,0x0000(r7) r23 = Math Flag

====================================================================================================================================

Original Code
0017bd68: 32e200ff andi r2,r23,0x00ff
0017bd6c: 1440000c bne r2,r0,0x 0017bda0 Branch if AoE = 255
0017bd70: 00008021 addu r16,r0,r0 Tile Counter = 0
0017bd74: 34040001 ori r4,r0,0x0001 Tile Targeted? = True
0017bd78: 3c038019 lui r3,0x8019
0017bd7c: 24632dd8 addiu r3,r3,0x2dd8

New Code
0017bd68: addu r16,r0,r0 Tile Counter = 0
0017bd6c: ori r4,r0,0x0001 Tile Targeted? = True
0017bd70: jal 0x0017921c
0017bd74: nop
0017bd78: bne r23,r2,0x0017bda0
0017bd7c: nop

====================================================================================================================================
Morbol Virus Depth Check (0x00179204)
====================================================================================================================================

Original Code
00179204: 00042400 sll r4,r4,0x10
00179208: 00042403 sra r4,r4,0x10
0017920c: 34020149 ori r2,r0,0x0149 r2 = Moldball Virus
00179210: 14820010 bne r4,r2,0x 00179254 Branch if ID != Moldball Virus
00179214: 00000000 nop
00179218: 00002821 addu r5,r0,r0 Counter = 0
0017921c: 3c048019 lui r4,0x8019
00179220: 24842dd8 addiu r4,r4,0x2dd8 r4 = ? Tile Data Pointer
00179224: 3c038019 lui r3,0x8019
00179228: 2463f8cc addiu r3,r3,0xf8cc r3 = Tile Data Pointer
0017922c: 90620003 lbu r2,0x0003(r3) Load Tile's Halves + Depth
00179230: 00000000 nop
00179234: 304200e0 andi r2,r2,0x00e0
00179238: 10400002 beq r2,r0,0x 00179244 Branch if Depth > 1
0017923c: 24630008 addiu r3,r3,0x0008 Tile Data Pointer += 8
00179240: a0800000 sb r0,0x0000(r4) Store AoE = 0
00179244: 24a50001 addiu r5,r5,0x0001 Counter ++
00179248: 28a20200 slti r2,r5,0x0200
0017924c: 1440fff7 bne r2,r0,0x 0017922c Branch if Counter < 0x200
00179250: 24840005 addiu r4,r4,0x0005 ? Tile Data Pointer += 5
00179254: 03e00008 jr r31
00179258: 00000000 nop

New Code
r3 = Tile Data (0x80192dd8)
r4 = True
r23 = Math Skill

00179204: addiu r2,r2,0xba2c
00179208: sll r4,r4,0x10 Code still needs a parsed Ability ID
0017920c: sra r4,r4,0x10
00179210: sh r4,0x0000(r2) Save Ability ID to (0x0017ba28)(For some future code)
00179214: nop Must be empty for another routine I made
00179218: jr r31
0017921c: lui r3,0x8019
00179220: beq r23,r0,0x00179254 Exit if no Math Skill
00179224: addiu r3,r3,0x2dd8
00179228: lbu r2,0x0000(r3) Load AoE saved on Tile
0017922c: lbu r20,0x0002(r3) Load Unit ID
00179230: sltiu r2,r2,0x0001 True if No AoE
00179234: sltiu r20,r20,0x0001 True if No Unit ID
00179238: addu r2,r2,r20
0017923c: bne r2,r0,0x179248 Do not Target Panel if panel does not have a unit on it and isn't apart of AoE
00179240: addiu r16,r16,0x0001 Tile Counter++
00179244: sb r4,0x0001(r3) Target Tile Panel
00179248: slti r2,r16,0x0200
0017924c: bne r2,r0,0x00179228 Loop for all 0x200 panels
00179250: addiu r3,r3,0x0005 Tile ID++
00179254: jr r31
00179258: ori r2,r0,0x4000

====================================================================================================================================



Enable Attacks on Yourself (Strike/Lunge Weapon)
Version 0.0
Allows units to target themselves with Attack. Only works with Strike/Lunge flagged Weapons.
Attack Self with Weapon Description

Original Code:

0017a598: a0800000 sb r0,0x0000(r4) Remove Caster Panel from targeting


New Code:

0017a598: 00000000 nop Code is deleted




Original Code:

0017a5a0: a0600000 sb r0,0x0000(r3) Remove High Caster Panel from targeting


New Code:

0017a5a0: 00000000 nop Code is deleted


Current Issues:

*This hack only applies to Strike/Lunge Weapons. Ranged units currently cannot attack themselves.


Notes:

Healing weapons do indeed heal on self attack.

HP Drain weapons also absorbs on self dealt damage.



Caster is always apart of AoE
Version -1.0
Removes the code from Unknown Flag 1 and 2 (0x80 and 0x40) of Ability Flags 1. This hack makes it so an ability will always target (make a yellow square under) the caster in addition to the targeted panel or panels. Enable this property with Unknown Flag 1. Unknown Flag 2 is non-functional. I can also upload an alternate version that checks for Ability IDs instead if requested.
0017bb04: 00021880 sll r3,r2,0x02
0017bb08: 00621821 addu r3,r3,r2
0017bb0c: 3c128019 lui r18,0x8019
0017bb10: 26522dd8 addiu r18,r18,0x2dd8
0017bb14: 32220001 andi r2,r17,0x0001

to

0017bb0c: andi r4,r9,0x0080 Look for Flag 1
0017bb10: jal 0x0017a6dc Always Target Caster Routine
0017bb14: lui r18,0x8019


0017a6dc: beq r4,r0,0x0017 Branch if Target Caster
0017a6e0: addiu r18,r18,0x2dd8 Load Map Data
0017a6e4: ori r2,r0,0x0001 Target Caster = True
0017a6e8: addu r3,r3,r18 r3 = Caster Tile
0017a6ec: sb r2,0x0000(r3) Target Caster Tile
0017a6f0: j 0x0017a6fc Exit Subroutine
0017a6f4: andi r2,r17,0x0001 Check Ability Flag 1 for Ignore Caster
0017a6f8: ori r2,r0,0x0000 Ignore Caster Tile = False
0017a6fc: jr r31
0017a700: nop
0017a704:
0017a708:
0017a70c:
0017a710:
0017a6dc:
0017a6dc:



F_MA Damage formula accepts Weapon Elemental (for one ability)
Version -1.2
Faith Magical Damage Formula accepts Weapon Elemental when ability ID = 165(Currently Maelstrom in Arena).
00185ffc: 3c028019 lui r2,0x8019
00186000: 8c422d94 lw r2,0x2d94(r2) Load Attacker's Data
00186004: 3c038019 lui r3,0x8019
00186008: 906338f7 lbu r3,0x38f7(r3) Load Abilities Element
0018600c: 90420071 lbu r2,0x0071(r2) Load Attacker's Elemental Strenghtened
00186010: 00000000 nop
00186014: 00431024 and r2,r2,r3
00186018: 1040000c beq r2,r0,0x0018604c Branch if Abilities Element isn't being powered
0018601c: 00000000 nop
00186020: 3c038019 lui r3,0x8019
00186024: 846338ce lh r3,0x38ce(r3) Load XA
00186028: 00000000 nop
0018602c: 00031080 sll r2,r3,0x02 XA * 4
00186030: 00431021 addu r2,r2,r3 XA * 5
00186034: 04410002 bgez r2,0x00186040 Branch if XA > 0
00186038: 00000000 nop
0018603c: 24420003 addiu r2,r2,0x0003 XA + 3
00186040: 00021083 sra r2,r2,0x02 XA * 5 / 4 (increase XA by 25%)
00186044: 3c018019 lui r1,0x8019
00186048: a42238ce sh r2,0x38ce(r1) Store new XA
0018604c: 03e00008 jr r31
00186050: 00000000 nop

========================================================================================================

00185ffc: 3c028019 lui r2,0x8019
00186000: 8c422d94 lw r2,0x2d94(r2) Load Attacker's Data
00186004: 3c038019 lui r3,0x8019
00186008: 906338f7 lbu r3,0x38f7(r3) Load Abilities Element
0018600c: 90420071 lbu r2,0x0071(r2) Load Attacker's Elemental Strenghtened
00186010: 00000000 nop
00186014: 00431024 and r2,r2,r3

to

11EFFC(+67000):
1580013C lui r1,0x8015
FC573FAC sw r31,0x57fc(r1)
0056050C jal 0x00155800
00000000 nop
25802000 or r16,r1,r0
1580013C lui r1,0x8015
24108300 and r2,r4,r3
1040000c beq r2,r0,0x0018604c Branch if Abilities Element isn't being powered
FC573F8C lw r31,0x57fc(r1)

...

00187010: 3c108019 lui r16,0x8019
00187014: 921038f7 lbu r16,0x38f7(r16)

to

120010(+67000):
0056050C jal 0x00155800
00000000 nop

...

Weapon Ele for F_MA damage Routine (0x1557fc)
EE7FC(+67000)
00000000 nop
1980013C lui r1,0x8019
D6382394 lhu r3,0x38d6(r1) Load Ability ID
942D248C lw r4,0x2d94(r1) Load Attacker's Data
65010134 ori r1,r0,0x0165
03006114 bne r3,r1,0x00155820 Branch if not the correct Ability ID
1980013C lui r1,0x8019
09560508 j 0x155824
04392390 lbu r3,0x3904(r1) Load Weapon's Element
F7382390 lbu r3,0x38f7(r1) Load Abilities Element
71008490 lbu r4,0x0071(r4) Load Attacker's Elemental Strengthened
25080002 or r1,r16,r0
25806000 or r16,r3,r0
0800E003 jr r31
00000000 nop





As always, the XMLs are attached to this post and notes are provided in spoilers above. Make sure you are using the latest version of FFTPatcher, or at least 489 or later. Let me know if you find any bugs, contacting me through this site or finding me on Steam.

EDIT: Thanks Firefox for crashing and wiping out my message, I'm switching back to Opera after this.
Title: Re: Dokurider's Custom AoEs
Post by: Jumza on December 21, 2016, 07:47:39 pm
:o Awesome stuff! Glad you released it all, I was so excited after I saw your videos :)
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on December 21, 2016, 11:32:59 pm
I just confirmed that the AI will hit itself with it's own weapon, (if it's allowed to) if it heals them.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on January 14, 2017, 04:42:32 pm
AI Two Swords Range Fix

If your patch uses Two Swordable weapons of differing ranges, then you want this hack. Current in Vanilla, the AI will overwrite the top weapon range with the bottom weapon range. Not a problem at all in Vanilla, but is a problem if your weapon on the top hand is longer than the one in the bottom hand.
What you'll end up seeing, if you are using a ranged weapon with a melee weapon, is that the AI will think their range is that of the bottom weapon range and attempt to get in range and move right next to the guy, realize they aren't in range anymore, and are forced to find a target they can attack instead or use an ability.

This hack swaps the top and bottom weapon processing order around so that the bottom range is overwritten by the top weapon range, thus knowing the correct attack range.

Original Code:
0019a3c4: 9245001d lbu r5,0x001d(r18) Load Unit's RH Weapon
0019a3c8: 0c06694b jal 0x 0019a52c Store Weapon? Attack Data
0019a3cc: 27a60010 addiu r6,r29,0x0010 r6 = Pointer to stack
0019a3d0: 02002021 addu r4,r16,r0 r4 = ? AI Pointer
0019a3d4: 9245001f lbu r5,0x001f(r18) Load Unit's LH Weapon
0019a3d8: 0c06694b jal 0x 0019a52c Store Weapon? Attack Data
0019a3dc: 27a60010 addiu r6,r29,0x0010 r6 = Pointer to stack


New Code:

0019a3c4: 9245001f lbu r5,0x001f(r18) Load Unit's LH Weapon
0019a3c8: 0c06694b jal 0x 0019a52c Store Weapon? Attack Data
0019a3cc: 27a60010 addiu r6,r29,0x0010 r6 = Pointer to stack
0019a3d0: 02002021 addu r4,r16,r0 r4 = ? AI Pointer
0019a3d4: 9245001d lbu r5,0x001d(r18) Load Unit's RH Weapon
0019a3d8: 0c06694b jal 0x 0019a52c Store Weapon? Attack Data
0019a3dc: 27a60010 addiu r6,r29,0x0010 r6 = Pointer to stack


Not much to it, really. With this hack you can make whatever weapon Two Swordable to your heart's content and the AI will use it correctly provided you are putting the range most weapon in your top hand.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on February 28, 2017, 11:53:45 pm
New Movement: Range + 2

Replaces Jump + 3. This movement skill will increase the range (red squares) of any ability provided:



This ability will not overflow. At 254 Range, it will add +1 Range instead and at 255 Range, it will do nothing.

The AI is aware of this change and should expand their target acquisitioning accordingly.

Oh and this hack does not come with any text changes. You have to do that yourselves.

Known Bugs: The game will still display Jump + 3 adding Jump while being selected to be added to a unit in the Formation Screen. The Unit Data Screen however wiil still correctly display that Jump + 3 did not add any Jump at all once added to the unit. It has no mechanical impact on the game.
lol idk where display code is.



Range + 2 (Normal Version)

Old:
0005c950: 10400002 beq r2,r0,0x0005c95c Branch if Unit doesn't have Jump + 3
0005c954: 30a2ffff andi r2,r5,0xffff
0005c958: 24630003 addiu r3,r3,0x0003 Jump += 3

0017a304: 90470001 lbu r7,0x0001(r2)        load AoE
0017a308: 90530000 lbu r19,0x0000(r2)       load Range
0017a30c: a3a70028 sb r7,0x0028(r29)        save AoE to stack

00195ce0: 90620000 lbu r2,0x0000(r3) Load Ability's Range
00195ce4: 00000000 nop
00195ce8: a2020004 sb r2,0x0004(r16) Store Range = Ability's Range


New:
0005c958: 00000000 nop [deleted Jump + 3]

0017a304: C04C050C jal 0x00153300 Range + 2
0017a308: 00000000 nop
0017a30c: 00000000 nop

00195ce0: D74C050C jal 0x0015335c AI Range + 2
00195ce4: 00000000 nop
00195ce8: 00000000 nop

00153300: 01004790 lbu r7,0x0001(r2)        load AoE
00153304: 00005390 lbu r19,0x0000(r2)       load Range
00153308: 2800A7A3 sb r7,0x0028(r29)        save AoE to stack
0015330c: 03004790 lbu r7,0x0003(r2)        load Ability Flags 1
00153310: 1200A387 lh r3,0x0012(r29)        Load Ability ID
00153314: 93009692 lbu r22,0x0093(r20) Load Movement 1
00153318: 7001632C sltiu r3,r3,0x0170
0015331c: 0D006010 beq r3,r0,0x00153354 Exit if Ability is 0x170 or greater (Throw, Jump and Item)
00153320: 2000E730 andi r7,r7,0x0020
00153324: 0B00E014 bne r7,r0,0x00153354 Exit if Weapon Range
00153328: 0400D632 andi r22,r22,0x0004
0015332c: 0900C012 beq r22,r0,0x00153354 Exit if no Range + 2 (Jump + 3)
00153330: 0200632E sltiu r3,r19,0x0002
00153334: 07006014 bne r3,r0,0x00153354 Exit if Range is less than 2
00153338: FF000334 ori r3,r0,0x00ff
0015333c: 05006312 beq r19,r3,0x00153354 Exit if Range is 255
00153340: FE000334 ori r3,r0,0x00fe
00153344: 02006312 beq r19,r3,0x00153350 Increase Range by 1 if 254 Range
00153348: 01000334 ori r3,r0,0x0001
0015334c: 02000334 ori r3,r0,0x0002
00153350: 21986302 addu r19,r19,r3 Range + 2
00153354: 0800E003 jr r31
00153358: 00000000 nop

0015335c: 03006290 lbu r2,0x0003(r3) Load Ability Flags
00153360: 00000000 nop
00153364: 20004230 andi r2,r2,0x0020
00153368: 04004014 bne r2,r0,0x0015337c Reload Ability Range if Weapon Range
0015336c: 00000234 ori r2,r0,0x0000 Makes branch always jump
00153370: 93004292 lbu r2,0x0093(r18) Load Unit's Movement 1
00153374: 00000000 nop
00153378: 04004230 andi r2,r2,0x0004
0015337c: 0B004010 beq r2,r0,0x001533ac Exit if no Range + 2 (Jump + 3)
00153380: 00006490 lbu r4,0x0000(r3) Load Ability's Range
00153384: 00000000 nop
00153388: 0200822C sltiu r2,r4,0x0002
0015338c: 07004014 bne r2,r0,0x001533ac Exit if Range is less than 2
00153390: 00000000 nop
00153394: FF000234 ori r2,r0,0x00ff
00153398: 04004410 beq r2,r4,0x001533ac Exit if Range is 255
0015339c: FE000234 ori r2,r0,0x00fe
001533a0: 02004410 beq r2,r4,0x001533ac
001533a4: 01008424 addiu r4,r4,0x0001 Range + 1 (Increases 254 to 255)
001533a8: 01008424 addiu r4,r4,0x0001 Range + 2 (1 + 1)
001533ac: 0800E003 jr r31
001533b0: 040004A2 sb r4,0x0004(r16) Store Range = Ability's Range



As always, let me know if you find anything glitches or bugs.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on March 08, 2017, 09:31:39 pm
So I just finished uploading every AI routine I've documented so far.  (http://ffhacktics.com/w/index.php?limit=100&title=Special%3AContributions&contribs=user&target=Dokurider&namespace=&tagfilter=&hideMinor=1&year=2017&month=-1)Some are okay, but many of them are from my early research and thus are spotty and lacking in understanding like some of the later works. However, know this: I am no where near done working not just on AI research, but on formatting and notes. They will all look something like this when I'm finished. (http://ffhacktics.com/wiki/Find_Peril_Most_Unit_(00198b04))

Anyways, I hope you all take some time to look through what has been uploaded and I hope they help you all in your endeavors. As always, feel free to drop me any questions or concerns. Thank you.
Title: Re: Dokurider's Custom AoEs
Post by: nitwit on March 11, 2017, 05:19:39 am
Effective AI would make vanilla absurdly difficult.  Great job!
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on April 10, 2017, 03:37:24 pm
Today I have some very basic AI fixes. I tested some of them, but they're such simplistic one line changes, they really shouldn't fail. Be sure to look at the descriptions of each hack because some of them will conflict if you aren't paying attention, but it should be pretty obvious which ones do.

I also recommend against implementing some of these hacks into your patch because they may end up making the AI overall worse rather than better. I only added them just so that people can mess around with it and at the end of the day, it's your call.

These changes are:



EDIT: Oh and I threw in my AI Two Swords fix as well.
Title: Re: Dokurider's Custom AoEs
Post by: Xifanie on April 10, 2017, 04:43:32 pm
Someone is actually using my spreadsheet.
I... so happy...
Title: Re: Dokurider's Custom AoEs
Post by: Pride on April 10, 2017, 05:51:22 pm
 I'm using it too : )
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on April 11, 2017, 03:43:46 am
Oh here's a late one I just made tonight, but it's too interesting to hold onto.

These hacks allow the AI to see it's own procs. Yes you heard that right. What's more, I have two versions for the community to use because I wasn't sure which method to use.

Version 1 makes the AI assume procs work 100% of the time.



001884d0: 3c038019 lui r3,0x8019
001884d4: 8c63f5fc lw r3,-0x0a04(r3)                      Load Simulation Byte
001884d8: 34020002 ori r2,r0,0x0002
001884dc: 10620008 beq r3,r2,0x00188500 Auto Succeed Proc Roll if Simulation = Display (Ignore results of roll)

Changed to:

001884d0: 3c038019 lui r3,0x8019
001884d4: 8c63f5fc lw r3,-0x0a04(r3)                      Load Simulation Byte
001884d8: 34020002 ori r2,r0,0x0002
001884dc: 10620008 bne r3,r0,0x00188500 Auto Succeed Proc Roll if Simulation = AI or Display (Ignore results of roll)



Version 2 makes the AI factor in proc rates. So in Vanilla, it will check it's own proc 0x0013% of the time.


001884c8: 0c061da4 jal 0x00187690 # Conditional Status Proc Roll (19%) Inner Routine
001884cc: 00000000 nop

Changed to:

001884c8: 0c061da4 jal 0x00187690 # Conditional Status Proc Roll (19%) Inner Routine
001884cc: 02000434 ori r4,r0,0x0002               r4 = Simulation Byte




00187690: 3c028019 lui r2,0x8019
00187694: 8c42f5fc lw r2,-0x0a04(r2)              Load Simulation Byte
00187698: 27bdffe8 addiu r29,r29,0xffe8
0018769c: 1440000d bne r2,r0,0x001876d4       Skip Proc Roll if Simulation = Display or AI

Changed to:

00187690: 3c028019 lui r2,0x8019
00187694: 8c42f5fc lw r2,-0x0a04(r2)              Load Simulation Byte
00187698: 27bdffe8 addiu r29,r29,0xffe8
0018769c: 0D004410 beq r2,r4,0x001876d4       Skip Proc Roll if Simulation = Display or AI



Both have their disadvantages and advantages and I will let the users decide which one they want to use.

I don't have video proof, but I can offer how I determined with certainty that these hacks work:

I set up a Thief with Punch Arts and Martial Arts with a modified Dagger that procs Wave Fist that is also flagged for all elements. I did same for all offensive Punch Arts except for Secret Fist. Secret Fist and Steal Heart I unflagged their Add Status property and flagged them for Target Ally use, ensuring they will never get used.

So versus a Woodsman, under normal circumstances, the AI will only ever consider using Attack on the the target. Indeed, this was the case, with the only setbacks coming from when the proc triggered and healed the tree.

When I activated Version 1, the AI refused to attack the target at all, finally seeing the proc and not wanting to attack at all. It spent the rest of the battle running away. When I deactivated the hack, the AI immediately resumed attacking the tree.

When I activated Version 2, the AI attacked the target, but sometimes it would randomly run away, as I predicted it would. When I increased the proc rate, this behavior intensified, constantly running away like the Version 1 hack, but occasionally attacking.


In either case, this hack leaves much to be desired. I would lean more towards Version 1, but I offer both. In the future, I would like to reduce the amount of damage/status priority that the procs cause by proc rate%. Something along those lines.
Title: Re: Dokurider's Custom AoEs
Post by: nitwit on April 14, 2017, 01:02:19 am
So the AI needs to take into account how much healing would be done and how often it could happen in order for it to act intelligently?  If the amount of healing over say 8 attacks is less than the damage you'd deal (both at a given proc rate), there's no reason not to attack.

Does the AI set attacks that have any possibility of healing as least priority?  Given that you won't often have a situation where the AI has so few options, it might be acceptable to have sub-optimal behavior.

Or the AI can be maximally conservative and never take that risk, in which case elemental defenses becomes a way of removing options for enemies or herding them towards PCs with vulnerability or weaknesses to their strongest abilities... it's something else to consider.  How could you exploit a maximally conservative AI?
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on April 14, 2017, 10:37:40 am
Quote from: nitwit on April 14, 2017, 01:02:19 am
So the AI needs to take into account how much healing would be done and how often it could happen in order for it to act intelligently?  If the amount of healing over say 8 attacks is less than the damage you'd deal (both at a given proc rate), there's no reason not to attack.

Does the AI set attacks that have any possibility of healing as least priority?  Given that you won't often have a situation where the AI has so few options, it might be acceptable to have sub-optimal behavior.

Or the AI can be maximally conservative and never take that risk, in which case elemental defenses becomes a way of removing options for enemies or herding them towards PCs with vulnerability or weaknesses to their strongest abilities... it's something else to consider.  How could you exploit a maximally conservative AI?


I should have mentioned that the sheer amount of damage (healing) this proc did was absurd: 400+ damage vs 100 damage just with the weapon alone. So the only conclusion you should be drawing from this is how the AI reacts to being able to see their own procs.

I would really just recommend messing around with it yourselves. Even if I recorded a video, it's not an easy concept to understand or explain in a few sentences.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on April 30, 2017, 10:52:34 pm
Today, I have a couple of new hacks and one update for everyone, but I don't have enough to detail how they work today.

The first and main feature hack now reverses the Critical AI's distance feature. Instead of moving away from allies healers, the AI will instead move closer to them. Yes, in fact, this was in the game this whole time, I just turned in one with one line of code. For a better explanation, check the hack description or wait until I post an in-depth explanation.

The second hack is actually an update. It's a much more efficient fix for the Stat Usage hack. It's still has little appreciable effect on actual usage unless paired with the next and last hack.

Lastly, this Low Priority Hack allows for abilities that have no real AI handling to be used by the AI in place of doing nothing. This mostly applies to Stat Boosting abilities, such as Accumulate. In Vanilla, the AI will only use Accumulate with this hack because it, Yell and Scream have the same priority, but Accumulate is the first added to the data bank, so it only uses Accumulate unless not learned.

Shoot me any questions, and I'll answer them a little later on in the week.

EDIT: Attached the correct file...
Title: Re: Dokurider's Custom AoEs
Post by: LohikaarmeX on May 07, 2017, 09:50:36 pm
Really amazing work here. I can see that the AI fixes gonna make the game more enjoyable.

But i got a question about the Cone AoE

Let's say that i want to make a skill, like a sword slash that goes all horizontal range (Not like Holy Explosion).

Something like this

P T T T P               P= Panel
     P                    T= Target
     P                    C= Caster
     P
     C



Can i make it with this hack?
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 07, 2017, 10:49:36 pm
The Cone AoE hack only makes Cone AoE.
I have no issues with you modifying it, in which case then yes, it can be (heavily) modified to become what you described.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 09, 2017, 02:53:34 pm
Today I have some more AI Movement hacks.

The first hack changes the AI's primary tendency from move away from their targets during Post Action, to remaining close to the target.

The second hack changes the way the Post Movement Decision Routine processes panels. That way, both the Pre and Post Action Movement Routines are more likely to arrive at the same conclusion. This means that the AI is more likely to stay in place and less likely to move around unnecessarily.

Combine the two hacks and you have an AI that moves around less. I find the results surprisingly underwhelming. The AI just end up smashed together in the middle of the map. Then again, the end results are probably more impactful vs human players.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on May 12, 2017, 10:40:12 am


Okay lemme explain now.

The game has three modes of simulation. The first mode is the real one. What it uses to do actual damage and statuses to actual units. The second mode is the AI simulation, and the third is for the damage display billboard (before you make an attack). The two non real modes often manipulates anything that is based on chance to either auto succeed or auto fail. In the case of AI mode, the manipulation goes further than that, at least, when it comes to Reactions.

The AI mode denies access to even starting reactions to begin with, with one major exception, which I'll get to in a minute. Fortunately, this is a one line check and is easily disabled to allows the AI to see and take into account Reactions.

However, there is a few caveats. For one, which caught me offguard, is that the Reaction routine doesn't inherently check if the target is dead. What ends up happening, is that dead targets can react. I haven't observed them being able to damage their killers, but they can add Reraise to themselves at least, which is very annoying. So I had to replace the mode check with a dead check.

Why was this originally allowed, you ask? Because Dead units can and do react. How? Reflect. Reflect is coded as a reaction. It is the only reaction in the game that the AI is allowed to see and think about, and it is the only Reaction that dead units are allowed to perform. They allowed this so that Reflecting off of Dead units was possible.

Secondly, the AI is pretty strict about reactions. If it's a result that they can quantify, like Auto Potion, they will abide by it by sheer arithmetic. If they cannot deal enough damage to overcome Auto Potion, then they will not attack that target with damage at all, unless it's fatal damage. Which, for the most part, is good. However, the same principal applies to other Reactions like Counter. If they cannot outdeal the damage they will take back, they will not attack a Counter unit.

Even Dragon Spirit can make a target untargetable by anything that can't overcome the priority value that Reraise provides. Of course, once it's triggered, it's open season on the Dragon Spirit unit. And mind you, Priority Value is proportional to the target's HP, so the more HP the target has, the more damage a unit has to have to be allowed to attack a target. So you might end up with a nightmare scenario with a single unit that's considered untargetable by any single AI enemy unit in play.

And yes, the AI does take into consideration taking fatal damage. In fact, it'll avoid taking damage that would push it into critical or near critical.

There are many more reaction interactions that this hack opens up. I will leave finding them up to the community. In the mean time, I will note that it's not perfect, but most of the issue lies with the AI's priority system, which needs an overhaul. Unlike most of the hacks I've published on the AI so far, this will not be a one line change. The priority system is the core of the AI. It is the base of which the AI functions off of. And it must be rewritten extensively. As a result, I will be saving that rewrite for last. Until then, I'll will be fixing and exploring other AI issues.

As always, try it out and let me know of any bugs. Thank you.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 09, 2017, 06:39:57 pm
Confusion Hack and Status Effect Priority Value Workbook

I have two hacks for you guys today.

1. The first hack allows the AI to target Confused units. More specifically, Confused units are now considered Active Units, they are no longer treated the same way that Death Sentenced units are treated. However, there is an additional barrier to the AI's targeting of Confused units.

Recall that in the Reaction hack, the AI will not target Dragon Spirit units unless it can deal more damage than Reraise is valued to grant that target. The same principle applies here as well. The AI must deal over 50% damage to consider damaging a Confused unit. This can be very difficult for some team setups, so the next step would be to lower Confusion's Priority Value, which brings us to our next hack.

2. I had Raven create an Excel sheet that allows anyone to edit the Priority Values of all Status Effects. That way, you can lower Confusion's value to something more manageable so that the AI can reliably break Confusion on units. You can also increase Oil's priority value so that the AI will want to add and cure it often.

In summary, if you wish to use the Confusion hack, it's strongly advised to change Confusion's priority value as well.

RIP SSCC runs. Please forward your praises to Raven.
Title: Re: Dokurider's Custom AoEs
Post by: nitwit on June 11, 2017, 10:38:31 pm
Quote from: Dokurider on May 09, 2017, 02:53:34 pm
Today I have some more AI Movement hacks.

The first hack changes the AI's primary tendency from move away from their targets during Post Action, to remaining close to the target.

The second hack changes the way the Post Movement Decision Routine processes panels. That way, both the Pre and Post Action Movement Routines are more likely to arrive at the same conclusion. This means that the AI is more likely to stay in place and less likely to move around unnecessarily.

Combine the two hacks and you have an AI that moves around less. I find the results surprisingly underwhelming. The AI just end up smashed together in the middle of the map. Then again, the end results are probably more impactful vs human players.

Maybe you should attach different AI movement tendencies to different AI "roles" (similar to auto-battle)?

Also how does this mesh with the other AI hacks that increase the AI awareness of various things?  Second-order effects may not be visible with one hack alone, but with multiple ones you can make a truly ferocious AI.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 25, 2017, 02:02:07 pm
Quote from: nitwit on June 11, 2017, 10:38:31 pm
Maybe you should attach different AI movement tendencies to different AI "roles" (similar to auto-battle)?

That more or less how it already works. Critical/Cowardly and Default have different movement patterns. Protective and Aggressive have the same patterns as Default, but since they tunnel vision on one unit, they tend to move differently anyways.

QuoteAlso how does this mesh with the other AI hacks that increase the AI awareness of various things?  Second-order effects may not be visible with one hack alone, but with multiple ones you can make a truly ferocious AI.

Honestly, I haven't really tried them all out at once yet. That is my ultimate goal though.

Anyways...

Golem AI fixes

Here's how the AI currently handles Golem in Vanilla. Remember that Priority is a function of HP. Statuses are given a set Priority value for how much damage this effect is equivalent to (Protect/Shell are given +20% because they reduce damage by 20%).

This formula only works until mid/late game, when even on the most fragile of units, HP values easily exceed 255 HP. What ends up happening is that Golem ends up with double or almost triple the priority its supposed to have, per unit. Even if Golem Priority was divided properly, Golem would still have an absurdly high priority compared to the average effect. It would be roughly priority valued at +100% per unit, which it is technically, but because the effect is shared amongst the team, it's more like +20% for the average 5 man party. It should not be valued at the same amount as a unit's actual HP, which I think was the intent and thus the core mistake in making the Golem handling routine.

However, that's not the worst part. The absolutely worst part, is that any damage done to Golem, to even a single unit, is interpreted as happening to every unit on that team.
It works like this because it actually is effecting every unit on the team. You deal damage to Golem, you reduce that amount for the entire team. From the AI's standpoint, you are dealing damage to the entire team.
So what happens when the AI sees it can deal damage to an already overvalued effect and it also effects every enemy unit on the field with a single no cost action? Why, the AI is going to attempt to damage Golem every single time. The way the game has it handled, the AI sees damaging Golem as more valuable than dealing actual damage. This effect is strong, it even overpowers the AI's desire to finish off critical units. Small wonder why Golem breaks the AI so hard.




I have two fixes for you guys today.

The first fix simply blanks this entire routine outright. You can use this fix if you are dissatisfied with the second actual fix or you are not using Golem in your patch at all.

The second fix is an actual, if rudimentary, fix. It now handles Golem like thus:

Of course the obvious problem with this fix is that if you have more than 5 units on a team, the golem amount is still going to high. Not as absurdly high as it was, but still high. One can argue that is a good thing, because an 11 man team with Golem on top of it is a dire threat.
However, the idea of fixing Golem is to encourage the AI to use other attacks to bypass Golem instead of dropping everything to try to remove Golem. Making it too high of value was what was causing the problem in the first place.

So yes, I'm not satisfied with my current fix. The idea fix would be making Golem Priority = (curGolemHP * 40) / (Team Total HP). Team Total HP is just that, the sum of every unit's max HP on a team. For an example, assuming curGolem is 999, and every unit's HP is also 999 with 11 units, you would end up with +5% priority per unit. This seems rather small, but remember that because the AI sees that it effects every unit on the field, that effect adds up. Furthermore, the AI also understands that it is not dealing actual damage when it is hitting Golem.

Having Golem being seen as a small amount that nevertheless prevents certain attacks from dealing real damage achieves our desired goal: discourages, but still allows for Golem breaking, but for the most part, encourages bypassing Golem.

Because adding up the Team's Total HP every time I want to calculate Golem is a serious drain on the CPU cycle, leading to very long "thinking" times. Golem handling is in one of the most frequently used routines of the entire AI process. This routine, which already goes through every unit on the field, is used to process the effect of every action on every possible unit. It seriously adds up.

So the only sane way of using a Team Total HP is to create the value beforehand and then reference it as needed. The only issue is that I don't have a real space to do this aside from Kanji Space. The Average Unit HP (of all units, not just that team btw), is set once and then never changes and even then, it's caps out at 255 HP because it is a single byte and only has a single byte of space allotted to it. I don't know what, if anything, uses the spaces before and after.

I always strive to avoid using Kanji Space, so I can't implement this solution right now until I'm know I can use those spaces.


So yeah, it's not the perfect solution, but it's a start. It should, at the very least, make it so that the enemy AI doesn't go nuts when Golem hits the field anymore and has a reasonable response. This destroys yet another way the player frequently cheesed the AI. I strongly recommend this hack for PvE patches.

Here is a video of this hack in action:
Title: Re: Dokurider's Custom AoEs
Post by: nitwit on June 27, 2017, 03:52:25 am
If you never use Golem and remove it from the game (and you want to optimize) how much code could you cut out of the game?  And your list isn't correctly formatted.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on June 27, 2017, 09:06:00 am
Quote from: nitwit on June 27, 2017, 03:52:25 am
If you never use Golem and remove it from the game (and you want to optimize) how much code could you cut out of the game?  And your list isn't correctly formatted.

Oh thanks for the catch.
It might make the AI think cycle go a touch faster, I'm not sure at all. I think after I take a look at how the Song/Dance/Math AI works. I'll probably start optimizing the AI.
Title: Re: Dokurider's Custom AoEs
Post by: Dokurider on July 18, 2017, 03:41:16 pm
Hey guys, I have some updated and new code for you guys today. But first,


Stat Abilities vs the Wait Command

The AI assigns a Priority Value to not taking an action or Waiting. That value is the accumulation of every unit's current HP, MP, statuses, and whatever else. This value is the initial threshold that every ability has to beat in order to even be considered for usage by the AI. Abilities that are have worse or equal values will not be considered. Being equal to the Wait command is the problem for Stat Abilities.

As I've explained before, the AI does not have coding to handle Stat Abilities when it comes to assigning them Priority. Therefore, it has equal value to simply waiting and is not considered for usage by the AI, with one major exception.

The stat abilities of Songs and Dance are used with a rare consistency when it comes to the AI. This is owed to the combination of being Ignore Range, bypassing a great deal of usage checks and and special code that adds priority to stat spells outside of the normal priority routine.

This code is accessed in very specific ways, the most common being charging a spell, either planning to or currently doing so.

0019de10: 92620000 lbu r2,0x0000(r19)        Load Ability's AI Behavior Flags
0019de14: 00000000 nop
0019de18: 30420008 andi r2,r2,0x0008
0019de1c: 10400003 beq r2,r0,0x0019de2c        Branch if Ability doesn't have Stat Changes
0019de20: 34170001 ori r23,r0,0x0001        r23 = Target Priority - 1
0019de24: 341e0003 ori r30,r0,0x0003        r30 = Target Priority + 3
0019de28: 34170004 ori r23,r0,0x0004        r23 = Target Priority - 4


What is in r23 doesn't ultimately matter because it's locked behind impossible conditions and even if it wasn't, it would still only have an effect on a handful of skills in the game. From both looking at the code and in my testing, this routine is called three times, so for calculating Priority, multiply desired result by three.


Without that code, the Stat Performances would not be used at all. It was a fast way to make sure the AI used every Song and Dance ability. However, this came with a downside seen when the unit gets it's turn and very visible once you push the user into higher speeds. The AI will cancel it's own song/dance once it gets it's turn. Once the AI starts to get faster than the CT of it's Song/Dance, it will constantly restart the song/dance, preventing them from ever actually casting the spell. This does not effect normal spells, or even non-stat songs/dances. Wiznaibus and Life Song will work just fine, no matter what speed you are.

First, let me explain how the AI normally resumes spells. The AI gets it's turn, gets the value for Wait and then the value for whatever spell it was already casting. It will see that the effect that just waiting (and letting the spell go off) vs restarting the spell casting has the same value. And since the AI will only use abilities that are better priority wise, it will not restart the spell, and choose to wait, letting the spell go off. This is all well and good until you get to Stat Abilities with a CT. The Wait Command doesn't go into the routine that gives the Stat Abilities it's priority because it technically doesn't follow any of the requirements to get in. But restarting the Stat Ability does. So therefore, the Wait Command is lesser than just restarting the Stat Ability, so it gets restarted.

In order to fix this behavior, the code that gives Priority to Stat abilities must be present in the main Priority routine in order to be counted. This is what my hack I give to you today does. Not only does it fix the Song/Dance Restart bug, but it also naturally gives the AI an incentive to use other non CT Stat Abilities like Accumulate and Yell. I even added an extra Golem fix to bypass the Golem Calculation if there is no Golem present, for slightly faster decision making.

This both the Stat Ability AI fix and the same Golem fix I published above with one additional change.

The only issue that remains with Stat Song/Dance is that the AI will instead switch from stat skill to stat skill. The Priority code I gave them does not give any distinguish beyond "are they stat abilities?" Therefore, the AI will see them all as equal and given that the Stat Abilities are also dictated by randomness, will freely switch between abilities if it interrupts it's own song/dance. But it will definitely not restart it's own performance if it happens to land on the spell it was already using.

Strongly recommended hack for all patches.