Aslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&topic=1883.msg22970e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index6008.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&topic=1883.450e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index6008.html.zx"g^\_OKtext/htmlISO-8859-1gzip0|Tue, 10 Mar 2020 05:32:23 GMT0 0P"g^d Grimoire LD's Notes, Patches, and Hacks (Dark Knight/Paladin Swap In Battle!)

Author Topic: Grimoire LD's Notes, Patches, and Hacks (Dark Knight/Paladin Swap In Battle!)  (Read 78681 times)

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Well, I've come across an interesting realization...

The game only supports 23 (Hex) Commands by default because that is the length of the table. What is interesting about this is that the name table for the commands supports a whopping 1C extra support for Command names! (Not including commands that are used by the game but are not named such as Jump''s Return/Focus' Attack/Twincast Success/

If we could relocate the Command Table we could increase the amount of available commands to a much improved 3F (Decimal 63!) That is up from the default 1D (Decimal 29)

I see no reason not to try my hand at it. If it succeeds that means in combination with my Battle Command Switch Event we could have a much more robust Command system than the original FFIV had.

This would also mean that we'd have to change the locations of the Command Stances, but since they take up only one byte that shouldn't be too difficult.

...

Pointers - Check
Targeting - Check
Timers - Yet to do
Monster AI Bypass Routine - In progress

I'm making good progress, the last hurdle thus far has been the Monster AI Bypass. The game only ever intends the player to use commands from C0-E7, after which the command bytes take on Monster Parameters, for instance if I set my Command to 31 and use it, despite what formula it may have, it will still display a message because of the correlation with the Monster Parameters. My objective now is to force that information to JMP to a new section of data where I can create a conditional on whether a character or a monster is accessing that command (because players never use monster commands and monsters don't use anything else aside from fight.)



 :edit: Grr... After several hours of trying to make a workaround there is just too much linked into the position (animations are the big part) to go beyond the sponsored 27 line. So while I was able to set aside a new section for the pointers, stances, and targeting I couldn't actually use the expanded data in any meaningful way.  Despite coming so close, I am afraid this experiment was a failure.

Here is the information for anyone if they'd like to give it a shot. Maybe I'm missing something really simple.

Location of Command Pointers

08B850

(Change 03B160 to BF 50 BA 08) - New Location of Command Pointers

(Change 02B201 to BF 00 BB 08) - New Location of Command Stances

(Change 038BB3 to BF 80 BB 08) - New Location of Command Targets

Bah, hopefully my next experiment will be more fruitful.

 :edit: Important Note

The bank that the Command Routines are stored is not deadset to 03.

Purely because of...

03/B160   BF 50 BA 08   LDA $08BA50,x[$08:BA86]   A:0036   X:0036   Y:0000   P:envMxdizc
$03/B160   BF 50 BA 08   LDA $08BA50,x[$08:BAA0]   A:0050   X:0050   Y:0000   P:envMxdizc
$03/B164   85 80   STA $80    [$00:0080]   A:0052   X:0050   Y:0000   P:envMxdizc
$03/B166   BF 51 BA 08   LDA $08BA51,x[$08:BAA1]   A:0052   X:0050   Y:0000   P:envMxdizc
$03/B16A   85 81   STA $81    [$00:0081]   A:00E8   X:0050   Y:0000   P:eNvMxdizc
$03/B16C   A9 03   LDA #$03   A:00E8   X:0050   Y:0000   P:eNvMxdizc
$03/B16E   85 82   STA $82    [$00:0082]   A:0003   X:0050   Y:0000   P:envMxdizc

Does it look in Bank 3. We could technically move all of those to a more space-friendly bank if eventually desired.

 :edit:
E8-EF despite being AI Orders don't appear to react strangely like anything above F0 tends to do. So if I can get this working right I can at least get us 2F slots, rather than 1C. While a hit to the thought, it's better than abandoning the idea all together. The oddity in graphics mean very little if the new Commands they have include a couple of Audiovisual Cues of their own.
« Last Edit: March 23, 2015, 09:13:34 PM by Grimoire LD »

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
I was going over this in my head and wondering "where can I find this space that will be needed for these new Command instructions? The 03 Bank is already glutted with an immense amount of data. Then it hit me, I won't Need to confine myself to a bank, the instructions right there show that it uses a variable number of bank. Expanding with a JSR to look for certain amounts beyond a certain range would be the most preferable way to to do this. In fact this could be the ticket for including more table subroutines for a variety of matters. Granted they don't coincide with a natural barrier. Commands are stuck at 3F Max because of the C0+ which is added for any and all commands. Events likewise are tied to their amount of 30 because of 00-CF being reserved for NPC movement.

What is not tied to a known limit though are Spell Subroutines. That number is never used for anything else that we are aware of outside of FF acting as Audiovisual Effect calls, but I think the more proper term for that may be "blank" because those sorts of calls are internally checking the spell number used. Play a Visual Effect Event Instruction should be similarly unbound. It's all a matter of finding a new space for the Tables to support more than their intended max.

I was also wrong about the F0-FF Commands(Except for F0 and F2, they do not function correctly, but I haven't ruled out that those are Timer issues, rather than anything wrong with the Hex assignment.) The F1+ Commands, if they are overwritten within their Command routine this causes no oddities. What this means, for me, is that my custom commands will largely be able to exist alongside the older commands, and while this would ordinarily be worthless because of only so many Command Slots a character would have (3 unique Commands for each character would only be decimal 39 (27 hex) and that''s not taking away slots devoted to magic use. When you factor those in it's a lot less at, decimal 28 (1C hex). So in a normal sense roughly 39-3A Commands is overkill, unless my new hack is taken into account. Imagine this scenario... 3 variants of Dark Wave. One is the traditional Dark Wave, 1/8 HP for low-decent physical damage. This is what Cecil starts with. But say the Training Hall is replaced with the "Command Hall"

Now, using my other Flag Check hack that would look to see if Dark Knight Cecil is in the party through the use of Flags, they will offer a change of command for a low price (might be free, if I can I may include some sort of Quasi-Job system where they may ask for a certain amount of battles fought before you can change command? It's all a little up in the air at the moment)

This would allow Cecil to change up Dark Wave for Combat Boost's Dark Omen, with the added stipulation of turning into a Zombie when used. The third one would be Darkness (Probably truncated down to Dark(Sword)- Which would give him x2 damage for the cost of 1/8 of his HP each time he attacks as a reference to the DS version.

These are all just ideas, but it would give a lot of use and variety to the game if used and balanced accordingly.

My end objective is to give as much room as possible for the determined hacker to fool around with, without the need to expand the Rom.

I'll make a new topic on this to get people's inputs on it to see if they have anything they would like to see expanded.

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Well, the good news is that my plan worked! There are now 3F amount of Command and Pointers and 7D worth of Spell Subroutine Pointers compared to the original 27 and 35. Now it comes to finding empty space for these new routines and that will quickly become a difficulty I would imagine. It's a place like this where an expanded ROM would be most desired, but alas it would break FF4kster compatibility.

There's empty space scattered about the ROM, but now knowing where Text begins and ends, I fear that some of these large swaths of empty information may be reserved for text...

So if anyone knows, could they divulge the locations of Text Locations and Maps? If I know the blank space is not revolving about them, then we should have a large amount of empty space.

 :edit: After a bit of research on the forums I found an old post from JCE3000GT in regards to empty space, and with his hacking document on rb.thundaga.com I also found what these empty spaces were correlated to (if known) and if they were safe to change. The vast majority were and I think I can say that we can create A Lot of new routines without any issue as far as space is concerned...


0001DE55 - 1195 Bytes!
00023C38-23C80
0023C94- 23FFF (A fair amount of Bytes.)
5FD58 - 680 Bytes!
6E3A0-6F25F EBF (3775 Bytes!)
977F0-97FFF - 80F (2063 Bytes!)

To put that into perspective the game uses Bank 03 for the Spell Subroutines and crams them into...
E02C
D388-

CA4 amount of Bytes, The section in Bank D0000 (6E3A0) holds EBF bytes alone more than enough space for any new routines, I would imagine.

Past the Fight Command, Damage Routines, and Spell Routines, the Commands become much more compact and take up maybe 1000 more bytes, which is of course, large, but with space available elsewhere, then there is no worries in terms of space so all of the (mostly useless) original commands can exist alongside brand new ones as the hacker chooses.

This gets rid of any space problem we've ever had as far as Battle is concerned.  There is also a large section of free space around 438B9, but this hack is using a Lot of that space for more table space, mostly.
« Last Edit: March 29, 2015, 02:08:54 AM by Grimoire LD »

Pinkpuff

  • Flan Princess
  • *
  • Posts: 924
  • Find a Megalixir in Unprecedented Crisis!
    • View Profile
It's a place like this where an expanded ROM would be most desired, but alas it would break FF4kster compatibility.

I actually had an idea regarding this issue. It would be somewhat of an undertaking but I could make a config file that contains all the major addresses for data and code that people would be likely to move and then use that instead of hardcoded addresses.

The upside is that it would still work normally on a normal ROM if you change nothing, while at the same time allowing you to expand the rom and/or move things around and still use the editor.

The downside is that if you don't know the correct addresses for some reason or if you make a typo, KABOOM! Also it will take quite a bit of time and effort, meaning that's time and effort not spent on expanding the editor's functionality in other areas.
Let's dance!

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
It's a place like this where an expanded ROM would be most desired, but alas it would break FF4kster compatibility.

I actually had an idea regarding this issue. It would be somewhat of an undertaking but I could make a config file that contains all the major addresses for data and code that people would be likely to move and then use that instead of hardcoded addresses.

The upside is that it would still work normally on a normal ROM if you change nothing, while at the same time allowing you to expand the rom and/or move things around and still use the editor.

The downside is that if you don't know the correct addresses for some reason or if you make a typo, KABOOM! Also it will take quite a bit of time and effort, meaning that's time and effort not spent on expanding the editor's functionality in other areas.

While I was originally in favor of expanding the ROM, finding that extra space helps me immensely as far as the Routines are concerned.

My plan is to change the LDA XX, STA 82's that create dynamic addresses. use that to JSL to (likely the 08 bank area) Load the original Spell Subroutine OR Command Subroutine (due to slightly different data, they would have two similar, but different routines to reach their proper assigned new banks. If the Spell Subroutines read 35 or over, load the new bank's location in A. If it reads below, Load a 03 into A and store that in 82.

For Commands it would look past 27 for the same measures as listed above.

Therefore the new Commands and the old Commands could exist without any conflict and the same goes for the Spell Subroutines. The only that would need to be remembered is that these custom addresses will have to JSL (4 bytes instead of 3 bytes) to reach specific information pertaining to the 03 Bank.

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing Up Summon Spell Space)
« Reply #455 on: March 30, 2015, 07:07:45 PM »
As we all know in FFIV they use an idiotic method of reaching Summons. They use a byte within the valid 6 character names, then jump to the Summon outside of it to display the name and where the image is assigned. They waste 15 Spell Slots with this, seemingly all for the random effect of Asura (this could have been achieved with a unique routine, rather than wasting all of that space!) and a slightly longer name.

With recent talk of having spell names of 6 characters in the editor this seemed the best time to approach this problem.

So I did a little digging and found the answer, it was in a JSR that I called back in the day "unique to Summon Routine".

Code: [Select]
$03/E050 C9 3E CMP #$3E A:004F X:0000 Y:0000 P:eNvMxdizc - Is it Asura?
$03/E052 90 1A BCC $1A    [$E06E] A:004F X:0000 Y:0000 P:envMxdizC - If less than Asura branch.
-----------------------------------------------------------------------------------------------------------------------
$03/E054 C9 3F CMP #$3F A:004F X:0000 Y:0000 P:envMxdizC - Is it Bahamut?
$03/E056 D0 04 BNE $04    [$E05C] A:004F X:0000 Y:0000 P:envMxdizC - If not Bahamut, branch.
-----------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------
$03/E05C A2 00 00 LDX #$0000 A:004F X:0000 Y:0000 P:envMxdizC - Load 0000 into X.
$03/E05F A9 02 LDA #$02 A:004F X:0000 Y:0000 P:envMxdiZC - Load 02 into A.
$03/E061 20 79 83 JSR $8379  [$03:8379] A:0002 X:0000 Y:0000 P:envMxdizC - Jump to Subroutine (RNG between 00-02 to get the random result for Asura)
$03/E064 48 PHA A:0001 X:0000 Y:0000 P:envMxdizc -  - Push A onto Stack.
$03/E065 A9 F8 LDA #$F8 A:0001 X:0000 Y:0000 P:envMxdizc - Load F8 into A.
$03/E067 8D D4 26 STA $26D4  [$7E:26D4] A:00F8 X:0000 Y:0000 P:eNvMxdizc - Store A in Targeting (Target All Allies)
$03/E06A 68 PLA A:00F8 X:0000 Y:0000 P:eNvMxdizc - Pull A from Stack.
$03/E06B 18 CLC A:0001 X:0000 Y:0000 P:envMxdizc - Clear Carry Flag.
--------------------------------------------------------------------------------------------------------------
$03/E06C 69 3E ADC #$3E A:0001 X:0000 Y:0000 P:envMxdizc - Add 3E onto A (3E-40)
$03/E06E 38 SEC A:003F X:0000 Y:0000 P:envMxdizc  - Set Carry Flag
$03/E06F E9 31 SBC #$31 A:003F X:0000 Y:0000 P:envMxdizC - Subtract 31 from A.
$03/E071 18 CLC A:000E X:0000 Y:0000 P:envMxdizC - Clear Carry Flag.
$03/E072 69 4D ADC #$4D A:000E X:0000 Y:0000 P:envMxdizc - Add 4D onto A.
$03/E074 8D D2 26 STA $26D2  [$7E:26D2] A:005B X:0000 Y:0000 P:envMxdizc - That is the Random Asura  (or nomal summon)Action to Perform.

As you can imagine the issue purely comes from this setup. If you null the Storing at the end of the Routine the game will play out That Slot as the chosen summon meaning with the 6 Character Limit throughout the entirety of Spells, you free up the original location of Summons completely. With a slight rewrite Asura doesn't even have to lose her randomness but that math they use for it and making it apply to all Summons was just an idiotic idea when there was only so much Spell Space they had in the first place.

But this does it. Just null $03/E074   8D D2 26   STA $26D2 and you can use those Summon Slots anywhere and anyhow you like.

Pinkpuff

  • Flan Princess
  • *
  • Posts: 924
  • Find a Megalixir in Unprecedented Crisis!
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #456 on: April 08, 2015, 07:45:31 AM »
That's awesome!

I also had an idea for a spell routine I'd like to see (a couple actually ^_^):

Race-specific damage
Something like the "Harm"/"Dia" series from FF1. I was originally trying to achieve this by making a spell that healed all enemies; thus it doesn't hurt non-undeads but does hurt undeads. It just seems a little weird when a spell called "Harm" causes healing, especially if someone unfamiliar with the first game tries to cast it; they'd probably get super confused. Anyway it could be regular damage with a racial bonus, like attacks, or could only deal its damage to monsters of that race and miss on others (like Quake with fliers). Speaking of which...

Earth damage
Instead of the game looking for specific spell indexes, we could have a separate damage routine that causes damage only to non-flying enemies. Perhaps it could even be more generalized by looking at the element index ("damage all enemies that aren't weak to XX").

Full HP heal / Full MP heal (separate routines)
There is a routine for "Fully heal all HP and MP" but Cure 4 seems to have something special about it checking for its particular index that causes it to fully heal only HP, and only when it's single-targeted. It might be useful for hackers in general to have a routine that could fully heal all of either HP or MP but not the other.

Heal status + some HP
There is a routine for damage + add status, why not heal HP + remove status? Something like Chakra from FF5.

Damage + extended byte status
Currently Sap/HP-Leak is the only "extended" status you can add with damage. For that matter it might be nice to have a routine that can add an extended status (or combination thereof?) based on the element/status parameter rather than having one routine for stop, one for reflect, one for count, etc.

That's all I got for now, just trying to brainstorm for ideas. I might have more later ^_^
Let's dance!

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #457 on: April 08, 2015, 12:18:12 PM »
That's awesome!

I also had an idea for a spell routine I'd like to see (a couple actually ^_^):

Race-specific damage
Something like the "Harm"/"Dia" series from FF1. I was originally trying to achieve this by making a spell that healed all enemies; thus it doesn't hurt non-undeads but does hurt undeads. It just seems a little weird when a spell called "Harm" causes healing, especially if someone unfamiliar with the first game tries to cast it; they'd probably get super confused. Anyway it could be regular damage with a racial bonus, like attacks, or could only deal its damage to monsters of that race and miss on others (like Quake with fliers). Speaking of which...

These are all interesting ideas PinkPuff! I love doing requests, as I've said many times "give me a line and I'll follow it to the end."

The only ones I find exception with is "Fully Restore HP & Fully Restore MP" because if that is the goal  why not just make a spell with 255 Power that Cures HP and one that Cures MP? It seems like it would be a waste of two routine slots when the game has a ready made manner of doing so.

As for Dia, I actually made a formula for that Long ago, haha. It was a replacement of Count's formula though.

$03/DBB5   AD 40 27   LDA $2740  [$7E:2740]   A:0003   X:0038   Y:0000   P:envMxdizc - Load Target's Creature Type into A.
$03/DBB8   29 80   AND #$80   A:0080   X:0038   Y:0000   P:eNvMxdizc - Is it Zombie?
$03/DBBA   D0 01   BNE $01    [$DBBD]   A:0080   X:0038   Y:0000   P:eNvMxdizc -If not, branch to 03DBBD.
--------------------------------------------------------------------------------------------
$03/DBBC   60    RTS   A:0000   X:0038   Y:FFFF   P:envMxdiZc - Return.
------------------------------------------------------------------------------------------------
$03/DBBD   20 AF C9   JSR $C9AF  [$03:C9AF]   A:0080   X:0038   Y:0000   P:eNvMxdizc - Jump to Damage Determination.
$03/DBBE   60    RTS   A:0080   X:0038   Y:FFFF   P:envMxdiZc - Return.

But this was done in very slight space. If I were to remake this I would make it so it would not be considered an elemental attack and the Eight Elemental designations would be the Race the formula has to match to deal damage. Adversely it could be no statuses allowed and use the Status designations as the Race matching, which sounds like it would work better as it would allow Elementals to work with it.

Quote
Earth damage
Instead of the game looking for specific spell indexes, we could have a separate damage routine that causes damage only to non-flying enemies. Perhaps it could even be more generalized by looking at the element index ("damage all enemies that aren't weak to XX").

I don't know why I never thought of this... yes this sounds like an easily workable idea. It would also fix the error in Combat Boost where the Gaia Drum doesn't count as an Earth type attack because of the Scholar Cap check. Making it more generalized is also a wonderful idea. Like say a massive Fire Attack "damage all enemies that aren't weak to Ice". Because generally that type of Foe would be Fire. If the Status Designation byte is used for the "If Weak to XX, Skip". that would work best.

Quote
Heal status + some HP
There is a routine for damage + add status, why not heal HP + remove status? Something like Chakra from FF5.

That is another great idea. In theory this is a simple request as you would just set a Jump to the Cure formula and then put another Jump to the "heal status routine".

Quote
Damage + extended byte status
Currently Sap/HP-Leak is the only "extended" status you can add with damage. For that matter it might be nice to have a routine that can add an extended status (or combination thereof?) based on the element/status parameter rather than having one routine for stop, one for reflect, one for count, etc.

That's all I got for now, just trying to brainstorm for ideas. I might have more later ^_^

This could really make it a simpler matter instead of having everything split up as you said... but they are normally split for a reason.

Blink/Reflect/Stop/Count/HP Leak/Covered/Barrier could be condensed into one Routine that use the Elementals  would then jump to the appropriate data so while it would save on the pointer space which could be critical for a hack which doesn't want to expand them but is not adverse to using free space. It could be linked to the Elementals and designate itself from there.

Pinkpuff

  • Flan Princess
  • *
  • Posts: 924
  • Find a Megalixir in Unprecedented Crisis!
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #458 on: April 16, 2015, 05:02:00 AM »
As for Dia, I actually made a formula for that Long ago, haha. It was a replacement of Count's formula though.

$03/DBB5   AD 40 27   LDA $2740  [$7E:2740]   A:0003   X:0038   Y:0000   P:envMxdizc - Load Target's Creature Type into A.
$03/DBB8   29 80   AND #$80   A:0080   X:0038   Y:0000   P:eNvMxdizc - Is it Zombie?
$03/DBBA   D0 01   BNE $01    [$DBBD]   A:0080   X:0038   Y:0000   P:eNvMxdizc -If not, branch to 03DBBD.
--------------------------------------------------------------------------------------------
$03/DBBC   60    RTS   A:0000   X:0038   Y:FFFF   P:envMxdiZc - Return.
------------------------------------------------------------------------------------------------
$03/DBBD   20 AF C9   JSR $C9AF  [$03:C9AF]   A:0080   X:0038   Y:0000   P:eNvMxdizc - Jump to Damage Determination.
$03/DBBE   60    RTS   A:0080   X:0038   Y:FFFF   P:envMxdiZc - Return.

Ok so if I apply this as specified above, the "add Count" routine will instead become "Undead Damage", allowing me to make Harm/Dia spells but breaking any existing Count spells/techniques?

But this was done in very slight space. If I were to remake this I would make it so it would not be considered an elemental attack and the Eight Elemental designations would be the Race the formula has to match to deal damage. Adversely it could be no statuses allowed and use the Status designations as the Race matching, which sounds like it would work better as it would allow Elementals to work with it.

Personally I'd prefer to keep the statuses; usually races and weaknesses match up pretty well (undeads = fire/holy, reptiles = ice, robots = bolt, etc), and even where they don't it just seems more interesting to have f.ex. Undead Damage + Blind, or Undead Damage + Mute, than to have, say, Fire Undead Damage or Ice Undead Damage...

Also, another idea:

Damage based on target's current HP / Damage based on caster's Max HP
The game already has the reverse of these, a routine for damage based on caster's current HP and one for damage based on target's Max HP. But it would be nice to be able to do the opposite sometimes. For example, in my hack, Demi is currently dealing damage equal to target's Max HP / 4. Ideally, it should be dealing target's current HP / 2.

Fixed Damage
Damage that always hits and somehow ignores the normal damage dealing routine that modifies damage based on weaknesses and resistances and such, and instead deals a constant amount of damage no matter what. For example, 1000 Needles from the subsequent FF games. Perhaps the amount can be specified by the Power byte x the Hit byte? So to get 1000 you could have 100 Power and 10 Hit or vice versa. To get Globe199 you could have 100 Power and 100 Hit (presumably the game would apply the usual damage cap to prevent things from going wonkee). You could even have smaller versions for earlier in the game, like "100 Needles" or something. I dunno, might be interesting.

Also, back on the topic of custom event instructions, I thought of something that might be useful in certain contexts:

"Remove spell xx from spell set yy"

In fact, it may not even need to be its own instruction; maybe it could just be a modification of the existing "Add spell" instruction to make it into a sort of "Toggle spell"; so I guess it would first check if the spell is in the set, and if it is, remove it, otherwise add it.

This might be usable to, for example, have an event something like Rydia's Trial from FF4 Advance. She forgets a bunch of summons when you enter and you have to add them back one by one. Or perhaps some kind of event where Tellah forgets a bunch of spells again and has to get them back somehow or something. Just a thought ^_^
Let's dance!

chillyfeez

  • FF4 Hacker
  • *
  • Posts: 1,285
  • Gender: Male
  • Go ahead, ask me about Angel Feathers!
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #459 on: April 16, 2015, 07:28:41 PM »
I made both a Gravity routine (damage based on target's current HP) and a 1000 needles routine (damage in specified multiples of 1000) in my hack. In each case, the spell's "power" works as the variable operand (so there's Gravity 1, 2 and 3; and 1000 Needles and 10000 Needles)
I can dig 'em up for you if you want...

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #460 on: April 16, 2015, 07:59:01 PM »
As for Dia, I actually made a formula for that Long ago, haha. It was a replacement of Count's formula though.

$03/DBB5   AD 40 27   LDA $2740  [$7E:2740]   A:0003   X:0038   Y:0000   P:envMxdizc - Load Target's Creature Type into A.
$03/DBB8   29 80   AND #$80   A:0080   X:0038   Y:0000   P:eNvMxdizc - Is it Zombie?
$03/DBBA   D0 01   BNE $01    [$DBBD]   A:0080   X:0038   Y:0000   P:eNvMxdizc -If not, branch to 03DBBD.
--------------------------------------------------------------------------------------------
$03/DBBC   60    RTS   A:0000   X:0038   Y:FFFF   P:envMxdiZc - Return.
------------------------------------------------------------------------------------------------
$03/DBBD   20 AF C9   JSR $C9AF  [$03:C9AF]   A:0080   X:0038   Y:0000   P:eNvMxdizc - Jump to Damage Determination.
$03/DBBE   60    RTS   A:0080   X:0038   Y:FFFF   P:envMxdiZc - Return.

Ok so if I apply this as specified above, the "add Count" routine will instead become "Undead Damage", allowing me to make Harm/Dia spells but breaking any existing Count spells/techniques?

Yes... it is a bit of a mess and as I've said I have been meaning to redo it. Since I have the basics of the Job hack worked out, I will try to get to your requests in the coming days.
Quote
But this was done in very slight space. If I were to remake this I would make it so it would not be considered an elemental attack and the Eight Elemental designations would be the Race the formula has to match to deal damage. Adversely it could be no statuses allowed and use the Status designations as the Race matching, which sounds like it would work better as it would allow Elementals to work with it.

Personally I'd prefer to keep the statuses; usually races and weaknesses match up pretty well (undeads = fire/holy, reptiles = ice, robots = bolt, etc), and even where they don't it just seems more interesting to have f.ex. Undead Damage + Blind, or Undead Damage + Mute, than to have, say, Fire Undead Damage or Ice Undead Damage...

You make a good point. Status infliction it is then!

Quote
Also, another idea:

Damage based on target's current HP / Damage based on caster's Max HP
The game already has the reverse of these, a routine for damage based on caster's current HP and one for damage based on target's Max HP. But it would be nice to be able to do the opposite sometimes. For example, in my hack, Demi is currently dealing damage equal to target's Max HP / 4. Ideally, it should be dealing target's current HP / 2.

Fixed Damage
Damage that always hits and somehow ignores the normal damage dealing routine that modifies damage based on weaknesses and resistances and such, and instead deals a constant amount of damage no matter what. For example, 1000 Needles from the subsequent FF games. Perhaps the amount can be specified by the Power byte x the Hit byte? So to get 1000 you could have 100 Power and 10 Hit or vice versa. To get Globe199 you could have 100 Power and 100 Hit (presumably the game would apply the usual damage cap to prevent things from going wonkee). You could even have smaller versions for earlier in the game, like "100 Needles" or something. I dunno, might be interesting.

Looks like Chillyfeez has got those handled. I imagine those will be quite simple. I could be wrong though.


Quote
Also, back on the topic of custom event instructions, I thought of something that might be useful in certain contexts:

"Remove spell xx from spell set yy"

In fact, it may not even need to be its own instruction; maybe it could just be a modification of the existing "Add spell" instruction to make it into a sort of "Toggle spell"; so I guess it would first check if the spell is in the set, and if it is, remove it, otherwise add it.

This might be usable to, for example, have an event something like Rydia's Trial from FF4 Advance. She forgets a bunch of summons when you enter and you have to add them back one by one. Or perhaps some kind of event where Tellah forgets a bunch of spells again and has to get them back somehow or something. Just a thought ^_^

I was just thinking about this as well. It was the original idea behind my Job Change hack when it was still a dismal "use as many events as possible!" idea, rather than tying everything directly into equipment. In theory it shouldn't be too difficult. I will need to explore how that event is put together. I feel good about the chances of its success though.


chillyfeez

  • FF4 Hacker
  • *
  • Posts: 1,285
  • Gender: Male
  • Go ahead, ask me about Angel Feathers!
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (Freeing up Summon Spell Space!)
« Reply #461 on: April 16, 2015, 10:41:30 PM »
I remember something weird happening with my 1000 needles routine... I'll have to go back and look again, but I think it didn't work right when the multiple was 1, so I ended up making a 500*[spell power] routine, and spell power was 2 for 1000 needles.
Other than that, these two routines were pretty simple.
The gravity routine is a carbon copy of "damage based on target's max HP" except it draws on current HP.

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (A Working Job System!)
« Reply #462 on: April 27, 2015, 11:31:22 PM »
I have Finally completed my Job Change system! It took a long time, and was a lot of work, but I have everything, and I mean Everything working to my optimum specifications!

This will be a bit different from my other code postings as this will have information from several places in LoROM rather than one place. I was hesitant to post this for several weeks because it had been in a constant state of motion, but this is now working better than I had hoped so here we go.

Changing Job Names -
The way the game changes Jobs in this hack is to look at the Accessory the character has equipped (hitherto known as Jobs in any reference) when the Equip screen is activated or is left.

Code: [Select]
$01/DFC5 B9 32 00 LDA $0032,y[$7E:1072] A:FF00 X:1040 Y:1040 P:envMxdIzc - Load Character's Job into A.
$01/DFC8 D0 04 BNE $04    [$DFCE] A:FF9D X:1040 Y:1040 P:eNvMxdIzc - If not 00, branch.
-------------------------------
$01/DFCA B9 01 00 LDA $0001,y[$7E:1001] A:FF00 X:1000 Y:1000 P:envMxdIZc
$01/DFCD 60 RTS A:FF0B X:1000 Y:1000 P:envMxdIzc
---------------------
$01/DFCE E9 8D SBC #$8D A:FF9D X:1040 Y:1040 P:eNvMxdIzc
$01/DFD0 99 2F 00 STA $002F,y[$7E:106F] A:FF0F X:1040 Y:1040 P:envMxdIzC
$01/DFD3 B9 2F 00 LDA $002F,y[$7E:106F] A:FF0F X:1040 Y:1040 P:envMxdIzC
$01/DFD6 60 RTS A:FF0F X:1040 Y:1040 P:envMxdIzC

(The code being left open like that is to make the text properly read it for the extended Job Names)

Places Commands into Character's Commands in RAM dependent on Job Equipped.

Code: [Select]
$00/FDE5 A9 05 LDA #$05 A:0000 X:0000 Y:0000 P:envMxdIZc - Load 05 into A.
$00/FDE7 85 AB STA $AB    [$00:00AB] A:0005 X:0000 Y:0000 P:envMxdIzc - Store A in AB.
$00/FDE9 A6 FE LDX $FE    [$00:00FE] A:0005 X:0000 Y:0000 P:envMxdIzc - Load X from FE (That is a bit of prior custom code since A6  is not active at this time which ordinarily stores current slot)
$00/FDEB BD 32 20 LDA $2032,x[$7E:2032] A:0005 X:0000 Y:0000 P:envMxdIZc - Load Character's Job.
$00/FDEE D0 04 BNE $04    [$FDF4] A:009F X:0000 Y:0000 P:eNvMxdIzc - If there is a job, branch.
-----------------------------------------------
$00/FDF0 5C A1 8B 03 JMP $038BA1[$03:8BA1] A:001A X:0014 Y:0014 P:envMxdIzC - If no job equipped Jump back to normal routine.
--------------------------------------------
$00/FDF4 A2 00 00 LDX #$0000 A:009F X:0000 Y:0000 P:eNvMxdIzc - Load 0000 into X.
$00/FDF7 E9 9B SBC #$9B A:009F X:0000 Y:0000 P:envMxdIZc - Subtract 9B from Job (to reach actual job commands)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(Looping Point)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
$00/FDF9 F0 08 BEQ $08    [$FE03] A:0003 X:0000 Y:0000 P:envMxdIzC - If 00, branch.
$00/FDFB E8 INX A:0003 X:0000 Y:0000 P:envMxdIzC -  +5 to X
$00/FDFC E8 INX A:0003 X:0001 Y:0000 P:envMxdIzC
$00/FDFDE8 INX A:0003 X:0002 Y:0000 P:envMxdIzC
$00/FDFE E8 INX A:0003 X:0003 Y:0000 P:envMxdIzC
$00/FDFF E8 INX A:0003 X:0004 Y:0000 P:envMxdIzC
$00/FE00 3A DEC A A:0003 X:0005 Y:0000 P:envMxdIzC - -1 from A
$00/FE01 80 F6 BRA $F6    [$FDF9] A:0002 X:0005 Y:0000 P:envMxdIzC - Loop back (In other words this is setting X to the value of the Job''s Commands)
~~~~~~~~~~~~~~~~~~~~~(Looping Point)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$00/FE03 BF 48 FE 0B LDA $0BFE48,x[$0B:FE57] A:0000 X:000F Y:0000 P:envMxdIZC - Load A from New Location of Commands.
$00/FE07 99 03 33 STA $3303,y[$7E:3303] A:0000 X:000F Y:0000 P:envMxdIZC - Store A in RAM Command.
$00/FE0A C9 FF CMP #$FF A:0000 X:000F Y:0000 P:envMxdIZC - Is it Nothing?
$00/FE0C D0 03 BNE $03    [$FE11] A:0000 X:000F Y:0000 P:envMxdIzc - If not, branch.
----------------------------------------------------------
 00/FE0E DA PHX A:001A X:0014 Y:0014 P:envMxdIzC - Push X onto Stack
$00/FE0F 80 06 BRA $06    [$FE17] A:001A X:0014 Y:0014 P:envMxdIzC - Branch Always.
--------------------------------------------------------------
$00/FE11 DA PHX A:0000 X:000F Y:0000 P:envMxdIzc - Push Command onto Stack.
$00/FE12 AA TAX A:0000 X:000F Y:0000 P:envMxdIzc - Transfer Command to A.
$00/FE13 BF 80 BB 08 LDA $08BB80,x[$08:BB80] A:0000 X:0000 Y:0000 P:envMxdIZc - Load A from New Location of Command Timers.
$00/FE17 99 02 33 STA $3302,y[$7E:3302] A:0050 X:0000 Y:0000 P:envMxdIzc - Store A in command Timer. (The first time always assumes the command is Fight)
$00/FE1A FA PLX A:0050 X:0000 Y:0000 P:envMxdIzc - Pull X.
$00/FE1B E8 INX A:0050 X:000F Y:0000 P:envMxdIzc - +1 X
$00/FE1C C8 INY A:0050 X:0010 Y:0000 P:envMxdIzc - +4 Y
$00/FE1D C8 INY A:0050 X:0010 Y:0001 P:envMxdIzc
$00/FE1E C8 INY A:0050 X:0010 Y:0002 P:envMxdIzc
$00/FE1F C8 INY A:0050 X:0010 Y:0003 P:envMxdIzc
$00/FE20 C6 AB DEC $AB    [$00:00AB] A:0050 X:0010 Y:0004 P:envMxdIzc -1 from Command Amount
$00/FE22 A5 AB LDA $AB    [$00:00AB] A:0050 X:0010 Y:0004 P:envMxdIzc - Load Command Amount
$00/FE24 D0 DD BNE $DD    [$FE03] A:0004 X:0010 Y:0004 P:envMxdIzc - Loop if not 00.
---------------------------------------------------------------------------------------
$00/FE26 5C C6 8B 03 JMP $038BC6[$03:8BC6] A:0000 X:0014 Y:0014 P:envMxdIZ - Return to original routine


Next is the largest part and easily my magnum opus of custom hacking... the way the Job System actually works, the progression it takes and uses and the Job Level Up system.

Everything else in this from the Job Names and the Commands has been small fry compared to this!


Job System Progression

This was the crux of the work and I worked and reworked this routine many times over the last few weeks, but I have it Exactly where I want it. Through this I have completely skipped the ordinary means of learning magic (much of the magic learning routine was cannabalized) by Level Up and instead the Level Up Counters are used for Job Tracking Counters. Every Job learns up to Eight Spells and every Job Level gives a random stat gain.

Note (This runs out of the Exp. Routine hence why at the start and end there are some references to that)

Code: [Select]
$00/FE30 85 AF STA $AF    [$00:00AF] A:0000 X:0000 Y:002D P:envMxdiZc - Store 3rd Exp byte in AF.
$00/FE32 48 PHA A:0000 X:0000 Y:002D P:envMxdiZc - Push A
$00/FE33 5A PHY A:0000 X:0000 Y:002D P:envMxdiZc - Push Y.
$00/FE34 BD 32 10 LDA $1032,x[$7E:1032] A:0000 X:0000 Y:002D P:envMxdiZc - Load Character's Job.
$00/FE37 D0 0A BNE $0A    [$FE43] A:009F X:0000 Y:002D P:eNvMxdizc - Branch if Job Present.
--------------------------------------------------
$00/FE38 0A ASL A A:0000 X:0011 Y:002D P:envMxdiZC - x2 A.
$00/FE39 BD 01 10 LDA $1001,x[$7E:1000] A:0000 X:0011 Y:002D P:envMxdiZC - Load Character's Class.
$00/FE3C 29 0F AND #$0F A:0000 X:0011 Y:002D P:envMxdiZC - Get rid of bits.
$00/FE3E 20 A0 FF JSR $FFA0  [$00:FFA0] A:0000 X:0011 Y:002D P:envMxdiZC - Jump to subroutine (See below)
$00/FE41 80 02 BRA $02    [$FE45] A:0000 X:0011 Y:002D P:envMxdiZC - Branch Always.
--------------------------------------------------
$00/FE43 E9 8D SBC #$8D A:009F X:0000 Y:002D P:eNvMxdizc - Subtract 8D to reach 0E+ for the Jobs.
--------------------
$00/FE45 AA TAX A:0011 X:0000 Y:002D P:envMxdizC - Transfer Job to X.
$00/FE46 BD A0 14 LDA $14A0,x[$7E:14B1] A:0011 X:0011 Y:002D P:envMxdizC - Load A from Job Tracker
$00/FE49 C9 FF CMP #$FF A:0000 X:0011 Y:002D P:envMxdiZC - Is it 255?
$00/FE4B F0 03 BEQ $03    [$FE50] A:0000 X:0011 Y:002D P:envMxdizc - If so, branch.
------------------------------------------------------------------------------
$00/FE4D FE A0 14 INC $14A0,x[$7E:14B1] A:0000 X:0011 Y:002D P:envMxdizc +1 to Job Tracker.
------------------------------------------------------------------------------
$00/FE50 BD A0 14 LDA $14A0,x[$7E:14B1] A:0000 X:0011 Y:002D P:envMxdizc - Load Job Tracker into A.
$00/FE53 85 B5 STA $B5    [$00:00B5] A:0001 X:0011 Y:002D P:envMxdizc - Store Job Tracker into Storage.
$00/FE57 BD 32 10 LDA $1032,x[$7E:1032] A:0001 X:0000 Y:002D P:envMxdiZc - Load Job into A.
$00/FE5A F0 06 BEQ $06    [$FE62] A:009F X:0000 Y:002D P:eNvMxdizc - If no Job, branch.
---------------------------------------------------------------------------------------------------
$00/FE5C BD 2F 10 LDA $102F,x[$7E:102F] A:009F X:0000 Y:002D P:eNvMxdizc - Load Job Byte 2 into A.
$00/FE5F 3A DEC A A:0011 X:0000 Y:002D P:envMxdizc - -1 from A.
$00/FE60 80 08 BRA $08    [$FE6A] A:0010 X:0000 Y:002D P:envMxdizc - Branch Always.
------------------------------------------------------------------------------
$00/FE62 BD 01 10 LDA $1001,x[$7E:1001] A:0010 X:0000 Y:002D P:envMxdizc - Load A from Class.
$00/FE65 29 0F AND #$0F A:0010 X:0000 Y:002D P:envMxdizc - Get rid of bits.
$00/FE67 20 A0 FF JSR $FFA0  [$00:FFA0] A:0010 X:0000 Y:002D P:envMxdi - Jump to Subroutine (See below)
-------------------------------------------------------------------------------
$00/FE6A AA TAX A:0010 X:0000 Y:002D P:envMxdizc  - Transfer Job Byte 2 to X.
$00/FE6B A9 00 LDA #$00 A:0010 X:0010 Y:002D P:envMxdizc - Load 00 into A.
$00/FE6D A8 TAY A:0000 X:0010 Y:002D P:envMxdiZc - Transfer A to Y. (Clear A and Y basically)
$00/FE6E C2 30 REP #$30 A:0000 X:0010 Y:0000 P:envMxdiZc - Set A to 16 bit (to hold 4 digits)
~~~~~~~~~~~~~~(Looping Point~~~~~~~~~~~~~~~~~
$00/FE70 E0 00 00 CPX #$0000 A:0000 X:0010 Y:0000 P:envmxdiZc - Is X 0000?
$00/FE73 F0 06 BEQ $06    [$FE7B] A:0000 X:0010 Y:0000 P:envmxdizC - If so, branch
---------------------------------------------------------------------------
$00/FE75 69 0F 00 ADC #$000F A:0000 X:0010 Y:0000 P:envmxdizC - Add 0F (10 actually) into A.
$00/FE78 CA DEX A:0010 X:0010 Y:0000 P:envmxdizc - -1 to X.
$00/FE79 80 F5 BRA $F5    [$FE70] A:0010 X:000F Y:0000 P:envmxdizc - Loop back
(This lets the Job or Class get to the appropriate Job Level Checker)
-------------------------------------------------------------------------------
$00/FE7B AA TAX A:0100 X:0000 Y:0000 P:envmxdiZC  - Transfer Job Level Checker Location into X.
$00/FE7C 7B TDC A:0100 X:0100 Y:0000 P:envmxdizC - Clear A.
$00/FE7D E2 20 SEP #$20 A:0000 X:0100 Y:0000 P:envmxdiZC - Set Processor Status back to 8 Bit.
~~~~~~~~~~~~~~~~(Looping Point)-----------------------------------
$00/FE7F BF 40 C6 0F LDA $0FC640,x[$0F:C740] A:0000 X:0100 Y:0000 P:envMxdiZC - Load A from new Job Level Section
$00/FE83 C5 B5 CMP $B5    [$00:00B5] A:00FF X:0100 Y:0000 P:eNvMxdizC - Does it match the Stored Job Tracker?
$00/FE85 F0 0E BEQ $0E    [$FE95] A:00FF X:0100 Y:0000 P:eNvMxdizC - If so, branch.
$00/FE87 E8 INX A:00FF X:0100 Y:0000 P:eNvMxdizC - +2 to X. (Moves it to the next byte to check)
$00/FE88 E8 INX A:00FF X:0101 Y:0000 P:envMxdizC
$00/FE89 C8 INY A:00FF X:0102 Y:0000 P:envMxdizC - +1 to Y
$00/FE8A C0 08 00 CPY #$0008 A:00FF X:0102 Y:0001 P:envMxdizC - If Y is 0008 (As in its read all available Job Levels) ...
$00/FE8D D0 F0 BNE $F0    [$FE7F] A:00FF X:0102 Y:0001 P:eNvMxdizc - Do not Loop.
----------------------------------------------------------------------------------
$00/FE8F A6 A6 LDX $A6    [$00:00A6] A:00FF X:0110 Y:0008 P:envMxdiZC - Load Slot into A.
$00/FE91 EA NOP A:00FF X:0000 Y:0008 P:envMxdiZC 
$00/FE92 68 PLA A:00FF X:0000 Y:0008 P:envMxdiZC - Return original Exp numbers back into their proper registers
$00/FE93 7A PLY A:002D X:0000 Y:0008 P:envMxdizC
$00/FE94 6B RTL A:002D X:0000 Y:0000 P:envMxdiZC - Return.
(This is read at this time if it fails to find a spell in the Job Level Checker)
------------------------------------------------------------------------------------
$00/FE95 E8 INX A:0001 X:00D0 Y:0000 P:envMxdiZC  - +1 to X.
$00/FE96 BF 40 C6 0F LDA $0FC640,x[$0F:C711] A:0001 X:00D1 Y:0000 P:envMxdizC - Load A from Job Level Checker Spell.
$00/FE9A 48 PHA A:0084 X:00D1 Y:0000 P:eNvMxdizC - Push Spell onto Stack.
$00/FE9B A6 A6 LDX $A6    [$00:00A6] A:0084 X:00D1 Y:0000 P:eNvMxdizC - Load Slot into X.
$00/FE9D 9B TXY A:0084 X:0040 Y:0000 P:envMxdizC - Transfer Slot to Y.
$00/FE9E BD 01 10 LDA $1001,x[$7E:1041] A:0084 X:0040 Y:0040 P:envMxdizC - Load Character's Slot.
$00/FEA1 20 A0 FF JSR $FFA0  [$00:FFA0] A:0001 X:0040 Y:0040 P:envMxdizC - Jump to Subroutine (See Below)
~~~~~~~~~~~~~~~~~~~~~(Looping Point)~~~~~~~~~~~~~~~~~~~~~~
$00/FEA4 E0 00 00 CPX #$0000 A:0001 X:0001 Y:0040 P:envMxdizc - Is X 0000?
$00/FEA7 F0 05 BEQ $05    [$FEAE] A:0001 X:0001 Y:0040 P:envMxdizC - Branch if so.
$00/FEA9 69 16 ADC #$16 A:0001 X:0001 Y:0040 P:envMxdizC - Add 16 (17 with Carry) onto A. (This is 23, the amount of Spells in a Spellbook)
$00/FEAB CA DEX A:0018 X:0001 Y:0040 P:envMxdizc - -1 to X (This reaches the proper spellbook)
$00/FEAC 80 F6 BRA $F6    [$FEA4] A:0018 X:0000 Y:0040 P:envMxdiZc - Loop back.
----------------------------------------------------------------------------------
$00/FEAE AA TAX A:0018 X:0000 Y:0040 P:envMxdiZC  - Transfer A to X.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~(Looping Point)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$00/FEAF BD 60 15 LDA $1560,x[$7E:1578] A:0018 X:0018 Y:0040 P:envMxdizC - Load Spellbook start into A.
$00/FEB2 F0 03 BEQ $03    [$FEB7] A:0084 X:0018 Y:0040 P:eNvMxdizC - Branch if nothing is in this byte.
-------------------------------------------------------------------------------------------------
$00/FEB4 E8 INX A:0084 X:0018 Y:0040 P:eNvMxdizC +1 to X (to reach the next slot)
$00/FEB5 80 F8 BRA $F8    [$FEAF] A:0084 X:0018 Y:0040 P:eNvMxdizC - Loop Back
$00/FEB7 68 PLA A:0084 X:0018 Y:0040 P:eNvMxdizC - Pull Spell from Stack.
$00/FEB8 9D 60 15 STA $1560,x[$7E:1578] A:0084 X:0018 Y:0040 P:eNvMxdizC - Store A in Spellbook.
$00/FEBB 22 11 F1 03 JSL $03F111[$03:F111] A:0084 X:0018 Y:0040 P:eNvMxdizC - Jump to Message & Random Stat Gain Subroutine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/F111 85 FE STA $FE    [$00:00FE] A:0084 X:0018 Y:0040 P:eNvMxdizC - Store Spell in FE.
$03/F113 C2 30 REP #$30 A:0084 X:0018 Y:0040 P:eNvMxdizC - Set A to 16 Bit.
$03/F115 A6 A6 LDX $A6    [$00:00A6] A:0084 X:0018 Y:0040 P:eNvmxdizC - Load X from Slot.
$03/F117 8A TXA A:0084 X:0040 Y:0040 P:envmxdizC - Transfer X to A.
$03/F118 A2 00 00 LDX #$0000 A:0040 X:0040 Y:0040 P:envmxdizC - Load 0000 into X.
~~~~~~~~~~~~~~~~~~~~(Looping Point)~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/F11B C9 00 00 CMP #$0000 A:0040 X:0000 Y:0040 P:envmxdiZC - Is A 0000?
$03/F11E F0 06 BEQ $06    [$F126] A:0040 X:0000 Y:0040 P:envmxdizC - Branch if so.
---------------------------------------------------------------------------------------------
$03/F120 E9 40 00 SBC #$0040 A:0040 X:0000 Y:0040 P:envmxdizC - -40 from A (This lets it reach the appropriate slot for the message subroutine since that uses 00-04 to display the appropriate character's name.)
$03/F123 E8 INX A:0000 X:0000 Y:0040 P:envmxdiZC - +1 to X.
$03/F124 80 F5 BRA $F5    [$F11B] A:0000 X:0001 Y:0040 P:envmxdizC - Loop back.
---------------------------------------------------------------------------------------------
$03/F126 E2 20 SEP #$20 A:0000 X:0001 Y:0040 P:envmxdiZC - Set A back to 8-Bit
$03/F128 8A TXA A:0000 X:0001 Y:0040 P:envMxdiZC - Transfer X to A.
$03/F129 8D 9A 35 STA $359A  [$7E:359A] A:0001 X:0001 Y:0040 P:envMxdizC - Store A in Code Display Byte.
$03/F12C A9 07 LDA #$07 A:0001 X:0001 Y:0040 P:envMxdizC - Load Alert 07 (Unused normally) into A. (Here is it (Character) Job Level Up!)
$03/F12E 8D CA 34 STA $34CA  [$7E:34CA] A:0007 X:0001 Y:0040 P:envMxdizC - Store A in Message Display Bye.
$03/F131 A9 05 LDA #$05 A:0007 X:0001 Y:0040 P:envMxdizC - Load 05 into A (??)
$03/F133 20 85 80 JSR $8085  [$03:8085] A:0005 X:0001 Y:0040 P:envMxdizC - Jump to Message Display Subroutine.
03/F136 A9 23 LDA #$23 A:0000 X:7940 Y:0004 P:envMxdiZC - Load "Learned X" into A.
$03/F138 8D CA 34 STA $34CA  [$7E:34CA] A:0023 X:7940 Y:0004 P:envMxdizC - Store A in Message Display Byte.
$03/F13B A5 FE LDA $FE    [$00:00FE] A:0023 X:7940 Y:0004 P:envMxdizC - Load Spell from Storage.
$03/F13D C9 FF CMP #$FF A:0084 X:7940 Y:0004 P:eNvMxdizC - Is the spell FF (This is used if a character is gaining a Job Level, but Not learning a Spell)
$03/F13F F0 08 BEQ $08    [$F149] A:0084 X:7940 Y:0004 P:eNvMxdizc - If so, branch past.
-------------------------------------------------------
$03/F141 8D 9A 35 STA $359A  [$7E:359A] A:0084 X:7940 Y:0004 P:eNvMxdizc - Store A in Code Display Byte.
$03/F144 A9 05 LDA #$05 A:0084 X:7940 Y:0004 P:eNvMxdizc - Load 05 into A.
$03/F146 20 85 80 JSR $8085  [$03:8085] A:0005 X:7940 Y:0004 P:envMxdizc - Jump to Message Display Subroutine
------------------------------------------------------
$03/F149 A2 00 00 LDX #$0000 A:0000 X:7940 Y:0004 P:envMxdiZC - Load 0000 into X.
$03/F14C A9 04 LDA #$04 A:0000 X:0000 Y:0004 P:envMxdiZC - Load 04 into A.
$03/F14E 20 79 83 JSR $8379  [$03:8379] A:0004 X:0000 Y:0004 P:envMxdizC - RNG these two values.
$03/F151 85 FE STA $FE    [$00:00FE] A:0000 X:0000 Y:0004 P:envMxdizc - Store RNG in Storage.
$03/F153 A5 A6 LDA $A6    [$00:00A6] A:0000 X:0000 Y:0004 P:envMxdizc - Load Slot into A.
$03/F155 65 FE ADC $FE    [$00:00FE] A:0040 X:0000 Y:0004 P:envMxdizc - Add RNG onto Slot.
$03/F157 AA TAX A:0040 X:0000 Y:0004 P:envMxdizc - Transfer A to X. (This lets it reach the proper character's stats)
$03/F158 BD 0F 10 LDA $100F,x[$7E:104F] A:0040 X:0040 Y:0004 P:envMxdizc - Load Character Stat into A.
$03/F15B 1A INC A A:000B X:0040 Y:0004 P:envMxdizc +1 to A.
$03/F15C C9 64 CMP #$64 A:000C X:0040 Y:0004 P:envMxdizc - Is it 100?
$03/F15E D0 02 BNE $02    [$F162] A:000C X:0040 Y:0004 P:eNvMxdizc - If not, branch.
-----------------------------------------------------------------------------------
$03/F160 A9 63 LDA #$63 A:000C X:0040 Y:0004 P:eNvMxdizc - Load 99 into A.
-------------------------------------------------------------
$03/F162 9D 0F 10 STA $100F,x[$7E:104F] A:000C X:0040 Y:0004 P:eNvMxdizc - Store A in Stat.
$03/F165 6B RTL A:000C X:0040 Y:0004 P:eNvMxdizc - Return from Long.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``
$00/FEBF 80 2F BRA $2F    [$FEF0] A:000C X:0040 Y:0004 P:eNvMxdizc - Branch always to 2F.
$00/FEF0 A6 A6 LDX $A6    [$00:00A6] A:000C X:0040 Y:0004 P:eNvMxdizc - Load Slot into X.
$00/FEF2 EA NOP A:000C X:0040 Y:0004 P:envMxdizc - Retrieve Exp. values
$00/FEF3 68 PLA A:000C X:0040 Y:0004 P:envMxdizc
$00/FEF4 7A PLY A:003C X:0040 Y:0004 P:envMxdizc
$00/FEF5 6B RTL A:003C X:0040 Y:0000 P:envMxdiZc - Return from Long

And there you have it! That is probably the Best piece of code I've yet to put together.
One small little addendum, the change to the Jump from Magic Learning to the rest of the Level up Subroutine...

$03/F076   20 C8 F0   JSR $F0C8  [$03:F0C8]   A:0009   X:270F   Y:0000   P:envMxdiz - Jump past most of Magic Learning Subroutine.



Job/Spell Setter Subroutine
(Used for Adult Rydia, Edge, and FuSoYa to reach their proper placements as not to waste space)
Code: [Select]
$00/FFA0 C9 0B CMP #$0B A:0001 X:0040 Y:0040 P:envMxdizC - Is the Class 0B (Adult Rydia)
$00/FFA2 D0 02 BNE $02    [$FFA6] A:0001 X:0040 Y:0040 P:eNvMxdizc - Branch if not.
----------------------------------------------------------------------------------------------
$00/FFA4 A9 02 LDA #$02 A:0001 X:0040 Y:0040 P:eNvMxdizc - Load Child Rydia's Class into A.
-----------------------------------------------------------------------------------------------
$00/FFA6 C9 0C CMP #$0C A:0001 X:0040 Y:0040 P:eNvMxdizc - It is Edge or FuSoYa?
$00/FFA8 90 01 BCC $01    [$FFAB] A:0001 X:0040 Y:0040 P:eNvMxdizc - If not, branch.
-------------------
$00/FFAA 3A DEC A A:0001 X:0040 Y:0040 P:eNvMxdizc -1 to A.
-----------------------
$00/FFAB AA TAX A:0001 X:0040 Y:0040 P:eNvMxdizc - Transfer A to X.
$00/FFAC 60 RTS A:0001 X:0040 Y:0040 P:eNvMxdizc - Return

None of this is experimental or theoretical any longer, I've put together all the pieces I needed and have tested it to a pretty good extent. I may have a demo ready sometime in the future showing this off.

chillyfeez

  • FF4 Hacker
  • *
  • Posts: 1,285
  • Gender: Male
  • Go ahead, ask me about Angel Feathers!
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (A Working Job System!)
« Reply #463 on: April 28, 2015, 12:14:01 AM »
Is there any way for the player to know how close they are to the next job level?
I bet the Status screen could be reworked to include that information. Cuz, you know, I know you want more stuff to do, right?
;)

Also, it looks like jobs now have two bytes of stored data each... Does that mean you've worked out  way for the game to fully keep track of job progression even when the job isn't equipped?

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Grimoire LD's Notes, Patches, and Hacks (A Working Job System!)
« Reply #464 on: April 28, 2015, 12:41:11 AM »
Is there any way for the player to know how close they are to the next job level?
I bet the Status screen could be reworked to include that information. Cuz, you know, I know you want more stuff to do, right?
;)

Also, it looks like jobs now have two bytes of stored data each... Does that mean you've worked out  way for the game to fully keep track of job progression even when the job isn't equipped?

Haha! I... honestly cannot conceive of a way. Because the way it works now is that it just checks the Job Tracker, checks the eight values, if it matches it will earn the spell... now there may be a way actually, now that I think on it... It could work if I do a quick load of the Job Tracker Byte. Do a BCC to see if it the value is above the current Job Level, and store that value... somewhere. But I have no idea how I would do that. The concept of storing specific data of either "Job Level 2 - 14 till Job Level Up" or "Job 18 - Job Lvl Up. 28" is a bit beyond me. I've heard that windows and menus are the worst parts about hacking... anything.

I do suppose the Class Name and the HP/MP in the Status Menu isn't actually necessary and if I can highjack the pointers to all of those I Could have something that works. I'll give that a shot tomorrow then, thanks for the idea!

As for keeping track, oh yes. It was one of my first undertakings. I undid my Commands in RAM as... in the end they ironically served no purpose and moved the pointer back to the original section while adding a new section for the Job Commands separate from Class Commands. So that gave me a bit more free SRAM Space. It is very simple how it works... 31 Jobs now have a byte dedicated for each.

When you win a battle with a Job or nothing equipped to the Accessory Slot your Base Class or your Job will go up by 1. (Actually it goes up in as many levels a character gained in the battle +1, a little side effect which I'm fine with, it helps reach Job Level Ups a little faster).

De-quiping the Job doesn't change the amount that was originally stored in SRAM.

The purpose of the two bytes is to reach certain areas without a lot of complicated math having two is easier for me. 32 is the Accessory/Job Slot and is looked at several times, but the secondary Job Byte, 2F is only looked at in conjunction with 32 and is never looked at on its own since its never corrected until another Job is equipped.