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
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
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:
Overlapping tiles (Maps like Golrand Execution Site and Lionel Castle.)
Maps that are longer than 0x0f (Test this with Max AoE)
Test this AoE before, after or in conjunction with other skillsets (Math Skill in particular. Use it as a secondary.)
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.
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 0017b8f8branch if not Weapon Range 0017b8ec: 00458021 addu r16,r2,r5r16 = attacker unit data pointer 0017b8f0: 35290020 ori r9,r9,0x0020r9 = Weapon Range Flag (0x0020) 0017b8f4: 32310039 andi r17,r17,0x0039remove everything but Top Down and Random Fire
Title: Re: Dokurider's Custom AoEs
Post by: 3lric on May 27, 2014, 04:10:29 pm
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
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
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.
00179a20: 00000000: 27bdffe0 addiu r29,r29,-0x0020 00000004: 00803821 addu r7,r4,r0Caster 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,r2Caster 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,0x0002Check for Frog 00000038: 00001812 mflo r3 0000003c: 10400002 beq r2,r0,0x00000048If Caster is Frogged 00000040: 02032821 addu r5,r16,r3Caster Y * Max X + Caster X 00000044: 00002021 addu r4,r0,r0Right Hand is empty 00000048: 308300ff andi r3,r4,0x00ffRh weapon/frog = r3 0000004c: 340200ff ori r2,r0,0x00ff 00000050: 14620006 bne r3,r2,0x0000006cIf 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,0x00000070If Caster has a Lh weapon 00000064: 308200ff andi r2,r4,0x00ff 00000068: 00002021 addu r4,r0,r0Left Hand is empty 0000006c: 308200ff andi r2,r4,0x00ffr2 = weapon 00000070: 2c420080 sltiu r2,r2,0x0080 00000074: 14400002 bne r2,r0,0x00000080Is 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,0x3ab8Get Weapon data 0000008c: 00822021 addu r4,r4,r2point 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,r2Get Caster tile 000000a0: 24420500 addiu r2,r2,0x0500 000000a4: 00621821 addu r3,r3,r2Get 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,0x0001r4 = 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,0x00c0Is Weapon Striking/Lunging? 000000c8: 10400005 beq r2,r0,0x000000e0Branch if false 000000cc: 00e02021 addu r4,r7,r0Save Caster data to r4 000000d0: 0c05e6d6 jal 0x00179b58jump to ? 000000d4: 00c02821 addu r5,r6,r0Save Weapon Attack Flags 000000d8: 0805e6ce j 0x00179b38Jump to last jal 000000dc: 00000000 nop 000000e0: 30c20020 andi r2,r6,0x0020Is Weapon Direct? 000000e4: 10400009 beq r2,r0,0x0000010cbranch if false 000000e8: 01002021 addu r4,r8,r0Store Weapon Range 000000ec: 0c05e546 jal 0x00179518Limit Range to Map Function 000000f0: 00002821 addu r5,r0,r0 000000f4: 02002021 addu r4,r16,r0Save Caster X 000000f8: 02202821 addu r5,r17,r0Save Caster Y 000000fc: 0c05e509 jal 0x00179424Remove Close Range Routine 00000100: 34060002 ori r6,r0,0x0002 00000104: 0805e6ce j 0x00179b38jump to last jal 00000108: 00000000 nop 0000010c: 00e02021 addu r4,r7,r0Save Caster data 00000110: 0c05e62c jal 0x001798b0jump to ? 00000114: 01002821 addu r5,r8,r0save Weapon Range 00000118: 0c05e761 jal 0x00179d84jump 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.
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,0x0017950cEnd if Y is negative 00179438: 00004021 addu r8,r0,r0r8 = Y counter 0017943c: 00a8102a slt r2,r5,r8If Caster Y < Y Counter 00179440: 14400002 bne r2,r0,0x0017944cBranch if true 00179444: 01054823 subu r9,r8,r5Y Counter - Caster Y = r9 00179448: 00a84823 subu r9,r5,r8Caster 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,0x001794f4go to Y counter++ if negative 0017945c: 00003821 addu r7,r0,r0r7 = X Counter 00179460: 0087102a slt r2,r4,r7If Caster X < X Counter 00179464: 14400002 bne r2,r0,0x00179470Branch if true 00179468: 00e41023 subu r2,r7,r4r2 = X Counter - Caster X 0017946c: 00871023 subu r2,r4,r7r2 = Caster X - X Counter 00179470: 01221021 addu r2,r9,r2Caster Y- + Caster X- = r2 00179474: 00c2102a slt r2,r6,r2if Caster-Counter Sum > 2 00179478: 14400018 bne r2,r0,0x001794dcskip 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,r2Y Counter * Max X 00179490: 00001812 mflo r3 00179494: 00671821 addu r3,r3,r7Y 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,r2Y Counter * Max X 001794bc: 24e20100 addiu r2,r7,0x0100r2 = 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,0x0001X Counter ++ 001794e8: 00e2102a slt r2,r7,r2If X Counter < Max X 001794ec: 1440ffdd bne r2,r0,0x00179464Branch back if True 001794f0: 0087102a slt r2,r4,r7If Caster X < X Counter 001794f4: 3c02800e lui r2,0x800e 001794f8: 90424ea0 lbu r2,0x4ea0(r2)r2 = Max Map Y 001794fc: 25080001 addiu r8,r8,0x0001Y Counter++ 00179500: 0102102a slt r2,r8,r2If Y Counter < Max Y 00179504: 1440ffce bne r2,r0,0x00179440Branch Back if true 00179508: 00a8102a slt r2,r5,r8If 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.
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
...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
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.
<---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,r2r16 = caster panel 0017a400: 26640001 addiu r4,r19,0x0001r4 = range 0017a404: 24420500 addiu r2,r2,0x0500 0017a408: 00628821 addu r17,r3,r2r17 = 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,0x0020Weapon Range flag 0017a420: 10400006 beq r2,r0,0x0017a43cbranch if false 0017a424: 02602021 addu r4,r19,r0r4 = range 0017a428: 0c05e688 jal 0x00179a20Weapon Range Routine 0017a42c: 02802021 addu r4,r20,r0r4 = Caster ID data 0017a430: a2000000 sb r0,0x0000(r16)Remove Range from Caster Panel 0017a434: 0805e911 j 0x0017a444Calculate tiles hit by ability 0017a438: a2200000 sb r0,0x0000(r17)Remove Range from Caster Panel+ 0017a43c: 0c05e546 jal 0x00179518Generate Range Routine 0017a440: 00002821 addu r5,r0,r0r5 = 0 0017a444: 32420001 andi r2,r18,0x0001If Can't Target Self 0017a448: 10400002 beq r2,r0,0x0017a454Branch if False 0017a44c: 32420010 andi r2,r18,0x0010If Vertical Fixed 0017a450: a2a00000 sb r0,0x0000(r21)Remove Caster Panel from Range 0017a454: 10400003 beq r2,r0,0x0017a464Branch if False 0017a458: 02c02021 addu r4,r22,r0r4 = Caster X 0017a45c: 0c05e9ef jal 0x0017a7bcVertical Fixed Routine 0017a460: 02e02821 addu r5,r23,r0r5 = Caster Y 0017a464: 32420008 andi r2,r18,0x0008If Vertical Fixed 0017a468: 10400005 beq r2,r0,0x0017a480Branch if False 0017a46c: 33c400ff andi r4,r30,0x00ffr4 = Height Value if Non Zero (Negative?) 0017a470: 93a70030 lbu r7,0x0030(r29)r7 = load vertical from stack 0017a474: 00003021 addu r6,r0,r0r6 = 0 0017a478: 0c05e4a9 jal 0x001792a4Vertical Tolerance Formula 0017a47c: 00e02821 addu r5,r7,r0r5 = Vertical 0017a480: 93a70028 lbu r7,0x0028(r29)r7 = Load AoE from Stack 0017a484: 00000000 nop 0017a488: 10e00006 beq r7,r0,0x0017a4a4Branch 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,0x0020If Direct/Stop at Obstacle 0017a49c: 10400004 beq r2,r0,0x0017a4b0Branch if False 0017a4a0: 324200c0 andi r2,r18,0x00c0If Unknown Flags 0x80/0x40 (!!!) 0017a4a4: 0c05e497 jal 0x0017925cClear Data from Untargetable Tiles 0017a4a8: 00000000 nop 0017a4ac: 324200c0 andi r2,r18,0x00c0If Unknown Flags 0x80/0x40 (!!!) 0017a4b0: 10400003 beq r2,r0,0x0017a4c0Branch if False 0017a4b4: 02802021 addu r4,r20,r0r4 = Caster Data 0017a4b8: 0c05e9b7 jal 0x0017a6dcEvaluate Unknown Flags 0x80/0x40 (!!!) 0017a4bc: 02402821 addu r5,r18,r0r5 = Ability Flags 1 0017a4c0: 324200d0 andi r2,r18,0x00d0If Unknown Flags 0x80/0x40 or Vertical Fixed 0017a4c4: 14400005 bne r2,r0,0x0017a4dcBranch if True 0017a4c8: 00000000 nop 0017a4cc: 0c05e96f jal 0x0017a5bcIdentify Cross Sections 0017a4d0: 00000000 nop 0017a4d4: 0805e939 j 0x0017a4e4 0017a4d8: 00000000 nop 0017a4dc: 0c05e993 jal 0x0017a64cIdentify 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,r0r17 = Caster Data 0017a6e8: afb7002c sw r23,0x002c(r29) 0017a6ec: 30b70080 andi r23,r5,0x0080r23 = Unknown Flag 1 0017a6f0: afb60028 sw r22,0x0028(r29) 0017a6f4: 30b60040 andi r22,r5,0x0040r22 = Unknown Flag 2 0017a6f8: afb3001c sw r19,0x001c(r29) 0017a6fc: 00009821 addu r19,r0,r0r19 = Counter 0017a700: afb40020 sw r20,0x0020(r29) 0017a704: 34140001 ori r20,r0,0x0001r20 = 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,0x00ffr2 = 0x00ff 0017a724: 10620015 beq r3,r2,0x0017a77cBranch if Unit ID(Caster) doesn't exist (FF)? 0017a728: 02202021 addu r4,r17,r0r4 = Caster Data 0017a72c: 922201ba lbu r2,0x01ba(r17)r2 = Modified ENTD Flags 0017a730: 00000000 nop 0017a734: 02a28026 xor r16,r21,r2r16 = ENTD Flags 0017a738: 0c060428 jal 0x001810a0Get Unit Tile ID 0017a73c: 02009021 addu r18,r16,r0r18 = ENTD Flags 0017a740: 00021880 sll r3,r2,0x02r3 = Caster Tile ID 0017a744: 00621821 addu r3,r3,r2 0017a748: 3c028019 lui r2,0x8019 0017a74c: 24422dd8 addiu r2,r2,0x2dd8r2 = Tile Grid Data (0x192dd8) 0017a750: 12e00005 beq r23,r0,0x0017a768If Unknown Flag = False 0017a754: 00621821 addu r3,r3,r2r3 = Caster Tile Data 0017a758: 32020030 andi r2,r16,0x0030r2 = Red or Blue Flag 0017a75c: 14400002 bne r2,r0,0x0017a768Branch if Red or Blue Team 0017a760: 00000000 nop 0017a764: a0740001 sb r20,0x0001(r3)Caster Tile is Targeted 0017a768: 12c00004 beq r22,r0,0x0017a77cIf Unknown Flag 2 = False 0017a76c: 32420030 andi r2,r18,0x0030r2 = Red or Blue Team 0017a770: 10400002 beq r2,r0,0x0017a77cBranch if neither Team 0017a774: 00000000 nop 0017a778: a0740001 sb r20,0x0001(r3)Caster Tile is Targeted 0017a77c: 26730001 addiu r19,r19,0x0001Counter++ 0017a780: 2a620015 slti r2,r19,0x0015If Counter < 0x0015 0017a784: 1440ffe5 bne r2,r0,0x0017a71cBranch 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?
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
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,0x00ffr4 = Caster X 0017a7c0: 30a500ff andi r5,r5,0x00ff r5 = Caster Y 0017a7c4: 00a05021 addu r10,r5,r0r10 = Caster Y 0017a7c8: 2406ffe1 addiu r6,r0,-0x001fr6 = -0x001f 0017a7cc: 3c0c8019 lui r12,0x8019 0017a7d0: 258c2dd8 addiu r12,r12,0x2dd8r12 = Tile Grid Data (0x192dd8) 0017a7d4: 258d0500 addiu r13,r12,0x0500r13 = 0x1932d8 (?) 0017a7d8: 340b0001 ori r11,r0,0x0001r11 = True 0017a7dc: 3c08800e lui r8,0x800e 0017a7e0: 91084e9c lbu r8,0x4e9c(r8)r8 = Max Map X 0017a7e4: 00000000 nop 0017a7e8: 01480018 mult r10,r8Caster Y * Max X 0017a7ec: 00864821 addu r9,r4,r6r9 = Caster X - 0x001f 0017a7f0: 00001012 mflo r2 0017a7f4: 00491821 addu r3,r2,r9r3 = (Caster Y * Max X) + (Caster X - 0x001f) 0017a7f8: 00031080 sll r2,r3,0x02 0017a7fc: 00433821 addu r7,r2,r3r7 = Tile ID 0017a800: 0520000a bltz r9,0x0017a82cBranch if Caster X -0x1f is negative 0017a804: 00ec1821 addu r3,r7,r12r3 = Current Tile Data 0017a808: 0128102a slt r2,r9,r8If Caster X- < Max X 0017a80c: 10400007 beq r2,r0,0x0017a82cBranch if False 0017a810: 00000000 nop 0017a814: 90620000 lbu r2,0x0000(r3)r2 = Current Tile's Range 0017a818: 00000000 nop 0017a81c: 10400003 beq r2,r0,0x0017a82cBranch if no Range 0017a820: 00ed1021 addu r2,r7,r13r2 = 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,0x0001r6++ 0017a830: 28c20020 slti r2,r6,0x0020if r6 < 0x20 0017a834: 1440ffe9 bne r2,r0,0x0017a7dcBranch if True 0017a838: 00804821 addu r9,r4,r0r9 = Caster X 0017a83c: 2406ffe1 addiu r6,r0,-0x001fr6 = -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,0x0001r7 = 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,r9r3 = (Caster Y - 0x001f) * Max X + Caster X 0017a868: 00031080 sll r2,r3,0x02r2 = Tile ID 0017a86c: 00432021 addu r4,r2,r3r4 = Tile ID + Tile ID 0017a870: 0540000d bltz r10,0x0017a8a8Branch if (Caster Y - 0x001f) is negative 0017a874: 00881821 addu r3,r4,r8r3 = 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,r2If (Caster Y - 0x001f) < Max Y 0017a888: 10400007 beq r2,r0,0x0017a8a8Branch if False 0017a88c: 00000000 nop 0017a890: 90620000 lbu r2,0x0000(r3)r2 = Current Tile's Range 0017a894: 00000000 nop 0017a898: 10400003 beq r2,r0,0x0017a8a8Branch if Range = 0 0017a89c: 008b1021 addu r2,r4,r11r2 = 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,0x0001r6++ 0017a8ac: 28c20020 slti r2,r6,0x0020If r6 < 0x20 0017a8b0: 1440ffe7 bne r2,r0,0x0017a850Branch 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.
Only a few mod makers will actually use your hack
Even fewer will actually want to test it
Even fewer will report bugs
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
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.
001557fc: 06002632 andi r6,r17,0x0006False if flagged as Cone (Linear + Tri) 00155800: 09004610 beq r2,r6,0x00155828Branch if Cone AoE 00155804: 00000234 ori r2,r0,0x0000r2 = Cone AoE 00155808: 02000234 ori r2,r0,0x0002 0015580c: 0600C210 beq r6,r2,0x00155828Branch if Tri Linear AoE 00155810: 03000534 ori r5,r0,0x0003r5 = 3 (Tri Linear Value) 00155814: 04000234 ori r2,r0,0x0004 00155818: 0300C210 beq r6,r2,0x00155828Branch if Linear AoE 0015581c: 01000534 ori r5,r0,0x0001r5 = 1 (Linear Value) 00155820: FF000234 ori r2,r0,0x00ffr2 = -1 (No Value) 00155824: 00000534 ori r5,r0,0x0000 00155828: 0800E003 jr r31 0015582c: 00002F24 addiu r15,r1,0x0000r15 = Target Tile Vertical
0015588c: 2A103202 slt r2,r17,r18 00155890: 04004010 beq r2,r0,0x001558a4Branch if Unit X >= Target X is not true 00155894: 01001334 ori r19,r0,0x0001Direction = +X 00155898: 5856050C jal 0x00155960Cone Generation Routine 0015589c: 00000000 nop 001558a0: 3A560508 j 0x001558e8 001558a4: 2A105102 slt r2,r18,r17 001558a8: 04004010 beq r2,r0,0x001558bcBranch if Target X >= Unit X is not true 001558ac: FF001334 ori r19,r0,0x00ffDirection = -X 001558b0: 5856050C jal 0x00155960Cone Generation Routine 001558b4: 00000000 nop 001558b8: 3A560508 j 0x001558e8 001558bc: 2A101402 slt r2,r16,r20 001558c0: 04004010 beq r2,r0,0x001558d4Branch if Unit Y >= Target Y is not true 001558c4: 00011334 ori r19,r0,0x0100Direction = +Y 001558c8: 5856050C jal 0x00155960Cone Generation Routine 001558cc: 00000000 nop 001558d0: 3A560508 j 0x001558e8 001558d4: 2A109002 slt r2,r20,r16 001558d8: 18004010 beq r2,r0,0x0015593cEnd if Target Y >= Unit Y is not true 001558dc: 00FF1334 ori r19,r0,0xff00Direction = -Y 001558e0: 5856050C jal 0x00155960Cone Generation Routine 001558e4: 00000000 nop
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,r0Initialize Row Counter 00155964: 19800B3C lui r11,0x8019 00155968: D82D6B25 addiu r11,r11,0x2dd8r11 = Tile Data Pointer 0015596c: 01000A34 ori r10,r0,0x0001r10 = True 00155970: 3400A68F lw r6,0x0034(r29)r6 = AoE 00155974: 62004006 bltz r18,0x00155af0Branch 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,0x00155af0Branch if X >= Max X 0015598c: 00000000 nop 00155990: 5B008006 bltz r20,0x00155af0Branch 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,0x00155af0Branch if Y >= Max Y
001559a8: 18000302 mult r16,r3Y * Max X 001559ac: 12100000 mflo r2 001559b0: 21205100 addu r4,r2,r17Tile 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,0x00ffr8 = -1 001559bc: 24106802 and r2,r19,r8Get X Direction from Direction Variable 001559c0: 0F004010 beq r2,r0,0x001559f0Branch to Y if no X Direction obtained 001559c4: 00000000 nop
-X Direction
001559c8: 05000215 bne r8,r2,0x001559d0Branch if r2 =/= -X Direction 001559cc: FFFF2126 addiu r1,r17,0xffffCurrent X - 1 001559d0: 48002004 bltz r1,0x00155ae4Proceed to Next Row if the current Target X = -1 001559d4: 00000000 nop 001559d8: 7D560508 j 0x001559f4Go To Tile Coordinates Modify Function 001559dc: FFFF0224 addiu r2,r0,0xffffr2 = -1
+X Direction
001559e0: 9C4E6390 lbu r3,0x4e9c(r3)Load Map Max X 001559e4: 01002126 addiu r1,r17,0x0001Current X + 1 001559e8: 42006110 beq r3,r1,0x00155ae4End if current Target X is Max X 001559ec: 00000000 nop 001559f0: 01000220 addi r2,r0,0x0001r2 = 1
======================== Y Direction Sub Routine ========================
00155a00: 02121300 srl r2,r19,0x0008Get Y Direction from Direction Variable 00155a04: 3E004010 beq r2,r0,0x00155af0End if no Y Direction obtained 00155a08: FFFF0126 addiu r1,r16,0xffffCurrent Y - 1
00155a14: 37002004 bltz r1,0x00155ae4End 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 0x00155a44Jump to Modify Tile Coordinate Function 00155a24: 22180300 sub r3,r0,r3r3 = -Max X (-Y)
+Y Direction
00155a28: A04E6390 lbu r3,0x4ea0(r3)Load Max Y 00155a2c: 01000126 addiu r1,r16,0x0001Current Y + 1 00155a30: 30007010 beq r3,r16,0x00155ae4Branch 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
00155a4c: 22480700 sub r9,r0,r7Initialize Row Size Counter 00155a50: 25288000 or r5,r4,r0Initialize Secondary Tile Coordinate <-Row Size Subloop Begins Here-> 00155a54: FF000334 ori r3,r0,0x00ff 00155a58: 24106302 and r2,r19,r3Get X Direction from Direction Variable 00155a5c: 0E004010 beq r2,r0,0x00155a88Branch if X Direction was not obtained 00155a60: 0E80033C lui r3,0x800e
Y Row
00155a64: 20100902 add r2,r16,r9 00155a68: 20004004 bltz r2,0x00155adcBranch if Y Size is negative 00155a6c: A04E6390 lbu r3,0x4ea0(r3)Load Max Y 00155a70: 00000000 nop 00155a74: 1F006210 beq r3,r2,0x00155ae4Branch 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,r9Max X * Row Size Counter 00155a8c: 12180000 mflo r3 00155a90: B0560508 j 0x00155ac0Jump to Save Tile 00155a94: 20288300 add r5,r4,r3Modify Secondary Tile Coordinate
X Row 00155a98: 02121300 srl r2,r19,0x0008Get X Direction from Direction Variable 00155a9c: 18004010 beq r2,r0,0x00155af0End if no X Direction obtained 00155aa0: 00000000 nop 00155aa4: 20102902 add r2,r17,r9 00155aa8: 10004004 bltz r2,0x00155adcBranch if X Size is negative 00155aac: 9C4E6390 lbu r3,0x4e9c(r3)Load Map Max X 00155ab0: 00000000 nop 00155ab4: 0F006210 beq r3,r2,0x00155ae4Branch if X Size = Max X 00155ab8: 00000000 nop 00155abc: 20288900 add r5,r4,r9Modify Secondary Tile Coordinate
"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
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,0x0017a760Branch if not from Targeting Routine (From AoE routine) 0017a710: 8000A230 andi r2,r5,0x0080 0017a714: 1D004010 beq r2,r0,0x0017a78cBranch 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,r0r3 = Target Height 0017a740: 21886002 addu r17,r19,r0r17 = AoE 0017a744: 39E6050C jal 0x001798e4Calculate 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,0x0027Load instructions (14400027) 0017a758: 389943AC sw r3,0x9938(r2)Restore Close Range Branch from Arc Routine 0017a75c: E5E90508 j 0x0017a794Exit Routine 0017a760: 4000A230 andi r2,r5,0x0040 0017a764: 09004010 beq r2,r0,0x0017a78cBranch if not Arc Range 0017a768: 25288000 or r5,r4,r0r5 = Ability Range 0017a76c: 3899C0AC sw r0,0x9938(r6) 0017a770: 2CE6050C jal 0x001798b0Calculate Arc Range Routine 0017a774: 25208002 or r4,r20,r0r4 = Caster Unit Data 0017a778: 1880023C lui r2,0x8018 0017a77c: 4014033C lui r3,0x1440 0017a780: 27006324 addiu r3,r3,0x0027Load instructions (14400027) 0017a784: E5E90508 j 0x0017a794 0017a788: 389943AC sw r3,0x9938(r2)Restore Close Range Branch from Arc Routine 0017a78c: 46E5050C jal 0x00179518Store 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 nopReturn 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 0x0017b4a0Invalidate AoE panels routine (In the Weapon Targeting Routine [0017ac90]) to 0017af40: 00000000 nop[deleted]
0017babc: 31220020 andi r2,r9,0x0020Weapon Ranged check 0017bac0: 1440000e bne r2,r0,0x 0017bafcbranch 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.
==================================================================================================================================== Targeting/AoE Main Routine(0x0017b874) ====================================================================================================================================
Original Code 0017b9fc: 326300ff andi r3,r19,0x00ffr3 = ability AoE 0017ba00: 340200ff ori r2,r0,0x00ff 0017ba04: 1462000c bne r3,r2,0x 0017ba38Branch 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,0x0001Counter++ 0017ba24: 28820200 slti r2,r4,0x0200Do for all tiles 0017ba28: 1440fffb bne r2,r0,0x 0017ba18 0017ba2c: 24630005 addiu r3,r3,0x0005tile counter++ 0017ba30: 0805eebf j 0x 0017bafcskip following routine 0017ba34: 00000000 nop
New Code 0017b9fc: addu r4,r0,r0Clear r4 0017ba00: andi r2,r17,0x4000Get Math Skill Flag 0017ba04: lui r3,0x8018 0017ba08: addiu r3,r3,0xba28 0017ba0c: sh r0,0x0000(r3)Clear space 0017ba10: beq r2,r0,0x0017ba38Branch if no Math Flag 0017ba14: nop 0017ba18: xori r17,r17,0x00c0Add 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 0x0017ba38Save Math Skill Flag for later 0017ba24: nop 0017ba28: nop [save Math Flag here] 0017ba2c: nop[save Ability ID here] 0017ba30: nop 0017ba34: nop
New Code 0017bb60: lui r7,0x8018 0017bb64: jal 0x0017bc78Hit ally/enemy routine 0017bb68: addiu r7,r7,0xba28Load Math Skill Flag
==================================================================================================================================== Check if Ally/Enemy can be targeted Routine(0x0017bc78) ====================================================================================================================================
Original Code 0017bc90: 00e0b821 addu r23,r7,r0r23 = 255 AoE check
New Code 0017bc90: lhu r23,0x0000(r7)r23 = Math Flag
New Code r3 = Tile Data (0x80192dd8) r4 = True r23 = Math Skill
00179204: addiu r2,r2,0xba2c 00179208: sll r4,r4,0x10Code 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: nopMust be empty for another routine I made 00179218: jr r31 0017921c: lui r3,0x8019 00179220: beq r23,r0,0x00179254Exit 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,0x0001True if No AoE 00179234: sltiu r20,r20,0x0001True if No Unit ID 00179238: addu r2,r2,r20 0017923c: bne r2,r0,0x179248Do not Target Panel if panel does not have a unit on it and isn't apart of AoE 00179240: addiu r16,r16,0x0001Tile Counter++ 00179244: sb r4,0x0001(r3)Target Tile Panel 00179248: slti r2,r16,0x0200 0017924c: bne r2,r0,0x00179228Loop for all 0x200 panels 00179250: addiu r3,r3,0x0005Tile 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.
0017a598: a0800000 sb r0,0x0000(r4)Remove Caster Panel from targeting
New Code:
0017a598: 00000000 nopCode is deleted
Original Code:
0017a5a0: a0600000 sb r0,0x0000(r3)Remove High Caster Panel from targeting
New Code:
0017a5a0: 00000000 nopCode 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.
0017bb0c: andi r4,r9,0x0080Look for Flag 1 0017bb10: jal 0x0017a6dcAlways Target Caster Routine 0017bb14: lui r18,0x8019
0017a6dc: beq r4,r0,0x0017Branch if Target Caster 0017a6e0: addiu r18,r18,0x2dd8Load Map Data 0017a6e4: ori r2,r0,0x0001Target Caster = True 0017a6e8: addu r3,r3,r18r3 = Caster Tile 0017a6ec: sb r2,0x0000(r3)Target Caster Tile 0017a6f0: j 0x0017a6fcExit Subroutine 0017a6f4: andi r2,r17,0x0001Check Ability Flag 1 for Ignore Caster 0017a6f8: ori r2,r0,0x0000Ignore 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
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,0x0018604cBranch if Abilities Element isn't being powered FC573F8C lw r31,0x57fc(r1) ...
00187010: 3c108019 lui r16,0x8019 00187014: 921038f7 lbu r16,0x38f7(r16)
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,0x00155820Branch 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.
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:
The Ability ID is less than 0x0170. This excludes Jump, Throw and Item.
The Ability is not using Weapon Range, so it does not increase the range of Attack, Charge or anything of the sort.
The Ability's range is 2 or greater.
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.
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,0x00153354Exit if Ability is 0x170 or greater (Throw, Jump and Item) 00153320: 2000E730 andi r7,r7,0x0020 00153324: 0B00E014 bne r7,r0,0x00153354Exit if Weapon Range 00153328: 0400D632 andi r22,r22,0x0004 0015332c: 0900C012 beq r22,r0,0x00153354Exit if no Range + 2 (Jump + 3) 00153330: 0200632E sltiu r3,r19,0x0002 00153334: 07006014 bne r3,r0,0x00153354Exit if Range is less than 2 00153338: FF000334 ori r3,r0,0x00ff 0015333c: 05006312 beq r19,r3,0x00153354Exit if Range is 255 00153340: FE000334 ori r3,r0,0x00fe 00153344: 02006312 beq r19,r3,0x00153350Increase Range by 1 if 254 Range 00153348: 01000334 ori r3,r0,0x0001 0015334c: 02000334 ori r3,r0,0x0002 00153350: 21986302 addu r19,r19,r3Range + 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,0x0015337cReload Ability Range if Weapon Range 0015336c: 00000234 ori r2,r0,0x0000Makes 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,0x001533acExit 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,0x001533acExit if Range is less than 2 00153390: 00000000 nop 00153394: FF000234 ori r2,r0,0x00ff 00153398: 04004410 beq r2,r4,0x001533acExit if Range is 255 0015339c: FE000234 ori r2,r0,0x00fe 001533a0: 02004410 beq r2,r4,0x001533ac 001533a4: 01008424 addiu r4,r4,0x0001Range + 1 (Increases 254 to 255) 001533a8: 01008424 addiu r4,r4,0x0001Range + 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:
Correctly informs the AI that Throw Item range is 4 and not Move Range
Correctly informs the AI that Jump's CT is 50/SPD. I still have no idea what the original code was trying to do.
Correctly informs the AI about the existence of Weapon Elemental skills and that one can use them to heal themselves.
Correctly uses the correct flags for Short Charge and Non Charge (0x08 and 04 respectively, the original code was using 0x80 and 0x40, Monster Skill and Defend, a typo?) AND correctly calculates the new CT for short charge
AI will no longer wake up sleeping units with Jump.
AI will no longer add Protect/Shell/Wall/Reflect/Faith/Float while in critical
AI will now add Protect/Shell/Wall when at 50% HP. You may also use the hack that makes the AI use those status at any HP level (except critical), which is not recommended.
The AI will now use stat effecting skills 100% of the time. Previously, the AI would give itself a 50/50 chance of using stat skills. That being said, the AI has a very low priority on stat boosting skills to begin with, so usage rates will only increase slightly.
Optional hack: The AI will now use Reraise at any HP level. This is not a recommended hack.
Optional hack: The AI will now use Regen at any HP level. This is not a recommended hack.
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 bne r3,r0,0x00188500Auto 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.
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
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
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%).
Fetches current team Golem amount
Fetches the average HP of every unit that was in play. This value was determined at the very start of the battle and does not change at all. This value is capped at 255 HP/0xff.
Shifts current Golem by 7 (multiples by 128/0x80 for the unfamiliar)
Divides (curGolem * 128) by the team average
Adds this amount to the running priority total.
Repeat for every unit on that team
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:
Fetches current Golem amount
Divides Golem amount by 8 (shifts down by 3). 999 HP produces 0x7c, which is at least somewhat in line with normal priority values.
Divides that amount by 5, the number of units on an average player team.
Adds that amount to the running Priority total
Repeat for every unit on that team, which if there are only 5 units, ends up being about the current shifted down Golem amount.
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.