øAslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&topic=1519.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index1a0c.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&board=17.100e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index1a0c.html.zx :h^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈà•¤’‚OKtext/htmlISO-8859-1gzip@øÕ’‚ÿÿÿÿÿÿÿÿWed, 11 Mar 2020 01:24:49 GMT0ó°° ®0®P®€§²ð®:h^ÿÿÿÿÿÿÿÿ ’‚ Replacing Command Abilities

Author Topic: Replacing Command Abilities  (Read 2555 times)

LightPhoenix

  • FF5 Hacker
  • *
  • Posts: 130
    • View Profile
Replacing Command Abilities
« on: December 24, 2010, 08:59:54 PM »
(Merry Christmas!)

There are up to six things we have to do in order to replace an ability with a new one:

1) Spell Entry
2) Animation Entry
3) Effect Code (in C2)
4) Animation Code (in C1)
5) Text
6) Job Info

As an example, I will be replacing the command "Pray" with "Psych" and giving it to a Black Mage at JLvl 4.  For simplicity, the ability will function almost exactly like the spell.  The one change will be the MP cost, which will be 0.

Note: I'll be assuming people reading this will be familiar with the basics of the data format.  All that information is on the site here.  Please feel free to share this information.

1) Spell Entry

Many abilities in the game are actually spells that are called via code (see Part 3).  In fact, the code interpreting these is for all intents and purposes identical.  We could simply copy the spell data for Psych to the ability data for Pray, change the MP cost, and skip straight to editing text.  In fact, for this simple change, that's pretty much what we're going to do.  That won't always be the case, as I'll demonstrate with a subsequent example.

So, copy the Psych data to D1/5AE8 (where the Pray ability is located), and change the MP to 0.  Easy!  You'll want to note the ability offset as well, which is 21.

2) Animation Entry

We don't just want our Psych ability to act like Psych, we want it to look like it as well.  Luckily, we're using an animation that already exists, so we don't actually have to do much here.  However, if you wanted to add a new animation, you could do so by editing the animation data table.

We do want to know the offset of our animation though; it's 35.

3) Effect Code

All abilities call a snippet of code that sets up the animation and effect.  This uses indirect addressing; there's a lookup table at C2/4A92 that is a list of addresses.  This maps to the list of command abilities, with one big caveat: subtract one from the ability number to get the offset.  I don't know why they skip ability number 00 (Nothing), but it does.  So, Pray is ability number 21, so we want entry 0x20.  Our Pray code is at C2/1169.  NOTE: If you have InstructrTrepe's function offset list, several of the addresses for the commands are wrong.  I've verified this in code and with breakpoints.  Use the lookup table to be certain.

Here's our Pray code.  I've noted the functions of each subroutine.
Code: [Select]
C2/1169: A9 21        LDA #$21
C2/116B: 20 AA 16     JSR $16AA   Load Ability Parameters
C2/116E: 20 5F 17     JSR $175F   Get Selection
C2/1171: 20 A9 02     JSR $02A9   Separate Enemy/Ally Targets
C2/1174: 20 C2 02     JSR $02C2   Count Targets
C2/1177: A9 21        LDA #$21
C2/1179: 20 FA 16     JSR $16FA   Queue Banner
C2/117C: A9 20        LDA #$20
C2/117E: 20 E1 16     JSR $16E1   Queue Ability Animation
C2/1181: 20 1A 17     JSR $171A   Get Attack Type
C2/1184: 20 35 17     JSR $1735   Increment Effect Counter
C2/1187: 4C E3 98     JMP $98E3   Run Effect

As you can see, there are three functions that take a parameter (16AA, 16FA, 16E1).  We don't need to change the ability or the banner.  Now, you may be thinking we need to change the input for Queue Ability Animation.  It makes sense, right?  Unfortunately, it's also incorrect.  We'll leave it at #20.

4) Animation Code

So why exactly did we leave the input for QAA at #20?  The detailed answer is a little complex, and not strictly necessary to understand for this basic example.  However, that parameter actually indicates the value for a lookup table at C1/8D88, which leads to the following code:
Code: [Select]
C1/9909 20 93 9D    JSR $9D93   
C1/990C A9 0B       LDA #$0B
C1/990E 20 EC 96    JSR $96EC
C1/9911 A2 D8 00    LDX #$00D8 Anim: Pray
C1/9914 20 9C B6    JSR $B69C Run Animation
C1/9917 7B          TDC       
C1/9918 4C EC 96    JMP $96EC    Continue Animations

The important lines are the LDX and subroutine $B69C.  All abilities call bits of code like this, which are animation handlers.  For Pray, this is pretty simple.  Go ahead and change that #00D8 to #0035.

5) Text

This is relatively straight-forward.  Change the ability name at E0/1237; this also changes the text for the menu and the banner.  Change the description at D1/776A, but make sure to keep it at 24 bytes (use padding if needed).  The lookup table for description addresses starts at D1/716C.

If you went on to Part 6, then pulled up the menu, you'd notice that the job level information is still indicating Chemist L4.  Interestingly, this is not text, but a byte value that indicates job and level.  This data is located at C0/F739, and uses the same ability offset.  Bytes 0-4 indicate the job number, and bytes 5-7 indicate the level.  So we go to offset 21 at C0/F75A, which is currently set at #90.  Parsing that code, it's job number 10 (Chemist) and level 4.  We're going to change that to 8A (job A, level 4).

6) Job Info

If you've made it this far, you shouldn't have a problem with this next part.  Calculate or lookup the offset for the job info table (38), go to the data, and change the learned ability to #21.  Now you're ready to go!

LightPhoenix

  • FF5 Hacker
  • *
  • Posts: 130
    • View Profile
Re: Replacing Command Abilities
« Reply #1 on: December 24, 2010, 09:02:17 PM »
Complex Example 1: Dragon Sword

Pray is pretty much the most simple example you can get.  Let's look at something a little more in depth: Dragon Sword.

Let's look at the Effect Code for Dragon Sword:
Code: [Select]
C2/0AA4: 20 5F 17     JSR $175F
C2/0AA7: 20 FE 4A     JSR $4AFE
C2/0AAA: 20 A9 02     JSR $02A9
C2/0AAD: 20 C2 02     JSR $02C2
C2/0AB0: A9 0E        LDA #$0E
C2/0AB2: 20 FA 16     JSR $16FA   Queue Banner
C2/0AB5: A9 0D        LDA #$0D
C2/0AB7: 20 E1 16     JSR $16E1   Queue Ability Animation
C2/0ABA: 20 23 99     JSR $9923
C2/0ABD: A9 71        LDA #$71
C2/0ABF: 20 24 03     JSR $0324   Load Spell Parameters
C2/0AC2: 20 05 17     JSR $1705
C2/0AC5: 20 35 17     JSR $1735   Increment Effect Counter
C2/0AC8: 20 E3 98     JSR $98E3
C2/0ACB: 20 23 99     JSR $9923
C2/0ACE: A9 72        LDA #$72
C2/0AD0: 20 24 03     JSR $0324   Load Spell Parameters
C2/0AD3: 20 05 17     JSR $1705
C2/0AD6: 20 35 17     JSR $1735   Increment Effect Counter
C2/0AD9: 4C E3 98     JMP $98E3

The basics are the same as Pray, but we're actually running TWO spells.  At this point, it should be obvious why some ability commands are basically "empty."  We're actually going to call two spells - one for the HP Drain, and another for the MP Drain.  Obviously we can't do that with one ability data entry.  In fact, in this example the ONLY thing the ability data controls is targeting. 

What about the animation though?  Hopefully the reason we didn't change the input for Psych's QAA is a little more evident now.  Let's look at the animation code:

Code: [Select]
C1/98DF 20 93 9D    JSR $9D93
C1/98E2 A9 0B       LDA #$0B
C1/98E4 20 EC 96    JSR $96EC
C1/98E7 A2 09 01    LDX #$0109   Anim: DSword Dragon
C1/98EA 20 9C B6    JSR $B69C    Run Animation (#109)
C1/98ED A2 0C 01    LDX #$010C   Anim: Dsword Slash
C1/98F0 20 9C B6    JSR $B69C    Run Animation (#10C)
C1/98F3 7B          TDC       
C1/98F4 4C EC 96    JMP $96EC

So not only do we use the effect code to run two effects, we use the animation code to play two animations!

Now it should be apparent why the effect code and animation code matter; we can do more complex stuff that isn't possible with data alteration alone.



Complex Example 2: Item/Salve

Suppose we want an ability, Salve, that allows you to use one item and have it effect all targets (ala Wild Arms).  You can take a look at the Item code starting at C2/0570.  It's quite a bit more complex than either Pray or Dragon Sword.  In fact, it's more complex than many commands in the game.  Luckily, we can cheat a little bit.  There's not a lot of real estate in the C2 bank.  There's some coding work-arounds you can use to free up some, but that's beyond the scope of this post.  Since I hate the Mix command, I'm just going to use its code-space for my Salve command.  Your mileage may vary.

The start of the Item command goes like this:
Code: [Select]
C2/0570: 9C 62 7C     STZ $7C62
C2/0573: 20 23 99     JSR $9923   Get Next Effect Parameter Offset
C2/0576: 20 5F 17     JSR $175F   Get Selection
C2/0579: A6 32        LDX $32

Get Selection does what you'd think it does - it gets the information on the targets.  Instead of altering all the code, what we'll do is copy the first three commands to where Mix is, add our code afterward, and jump back to C2/0579.  As it turns out, the targeting for allies is stored in bytes 4-7 of $66.  So we'll add in our code:

Code: [Select]
C2/1125: 9C 62 7C     STZ $7C62
C2/1128: 20 23 99     JSR $9923   Get Next Effect Parameter Offset
C2/112B: 20 5F 17     JSR $175F   Get Selection
C2/112E: A9 F0        LDA #$F0
C2/1130: 85 66        STA $66
C2/1132: 4C 79 05     JMP $0579

Go ahead and add the ability using the steps above, and try it out.  Sure enough, when you use the command, the item is used on all of your allies.  We're piggy-backing on the Item command to make an "enhanced" function.  Something like this simply isn't possible with data tables alone; you need to get into the code.