News:

11 March 2016 - Forum Rules

Main Menu

FF1 Dynamic Action Patch Re-Jiggered

Started by Jiggers, July 27, 2019, 11:14:56 AM

Previous topic - Next topic

Jiggers

Based off the work originally done by CaptainMuscles - https://www.romhacking.net/hacks/1769/

And another thanks to Disch for his disassembly work that makes doing these things both fun and fast!

Edit: Several bugs fixed since the original post!

This link is to a Google Drive folder. In the folder are 6 files:
* 2 versions of Bank C.asm for use with Disch's Disassembly
* A stand-alone Dynamic Action ReJiggered patch, one with normal enemy regen, one with bonus enemy regen
* A version of the Dynamic Action ReJiggered patch to be merged with FF Restored, one with normal enemy regen, one with bonus enemy regen - note that due to overlapping edits, these two take out FF Restored's ability to have enemy damaged by the poison ailment. If you tweak spells in your own rom to inflict the poison ailment on enemies, it will have no effect, like in the original game. These two are addendums to FF Restored! Patch Restored in first, then one of these.

https://drive.google.com/open?id=14CImXsgmcxyqwl87ClSNJOZITlQxKxdQ

The aim of this was to fix the bugs and quirks of the original. I've done a bit of testing so far to catch those game-freezing bugs and other anomalies, but some weird things might have slipped through.

Running needs to be stress-tested, due to the triple RTS I had to put in. On some turns, a successful run would say "Close call" then continue the battle, while others would actually run from it. I've confirmed this is due to the original double RTS skipping back to the @NextTurn part of DoBattleRound, as the same issue was found when defeating all enemies--the battle would just continue on. But it only did this half the time, so a triple RTS might end up being just as bad in some cases?




Gameplay Effects:
Enemy roster and command menu only opens up when a character can act.
Character does not step back until they perform an action.
Pressing B while choosing a command will only reset the cursor, nothing else.
Player poison effect happens at the end of their action, instead of all poisoned players getting damaged at the end of the battle round.
Enemy regeneration effect happens at the end of their action, instead of all regenerating enemies regenerating at the end of a battle round.
If a character is muted, trying to pick an action other than Fight or Run will result in a brief "Silenced" message popping up.

Code notes:
I've done my best to make sure the original game's addresses are intact, with the most notable exception being "InputCharacterBattleCommand", where I put the NOPs above it rather than below, so that the space might be used without interrupting the flow into "Battle_MainMenu_APressed"--and since the routine above it needed to be extended by 2 bytes anyway.
Stepping back has been added to the Running Attempt routine, and some useless code has been NOP'd out to make room for that, as well as a triple RTS to fix a bug I made.
Enemy regeneration has been shortened to not loop through all enemies.1
BacktrackBattleCommand has been almost entirely replaced by a check to see if a character is muted. Battle_MainMenu_APressed has been given a JSR to this check, moving the first half of it it upward 3 bytes.
Just about the entirety of UndoCharacterBattleCommand has been replaced with more robust Turn taking routines:

For Players:
* A check has been added to make sure a player is alive (not stoned or dead) before even drawing commands for their turn.
* If alive, draw roster box, command box, get input, and perform their action.
* Check if the battle is over - does a double RTS out of the PlayerTurn routine, so requires another check to double RTS out of the BattleRound routine.
* If not over, apply poison.
* Update character HP and status.
* Return and check again if the battle is over.

For Enemies:
* Do their turn as normal
* Update character HP and status
* Check if the battle is over (player died or enemy died of confusion) (this was causing a bug and is not needed)
* Apply regeneration to enemy
* Return and check again if the battle is over.


1On Enemy Regeneration:

First, does Enemy regeneration still work? I haven't tested it without the loop code.

Second, regenerative enemies gain 3 HP per turn. They include Catman, Troll, Seatroll, Phantom, Vampire, WzVamp, WzOgre, WrWolf, WarMech. By the time you encounter them, 3 HP is laughable (with maybe the exception of the WrWolf.)

I've included a second patch that allows all regenerative enemies to regain their 3 HP after every enemy action. So a WrWolf with a backup of 5 wolves would gain 18 HP per round.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

I would test this right now if I had any idea how to patch ROMS on my phone.

KingMike

Can you patch on a PC and transfer to the phone?
"My watch says 30 chickens" Google, 2018

Vanya

Sorry for the late reply.
I couldn't at the time cause my pc imploded.
I just got a new windows disk on Friday, so I'll be able to get back up and running in the next couple of days.

lexluthermiester

Quote from: KingMike on July 31, 2019, 12:58:17 PM
Can you patch on a PC and transfer to the phone?
Can't think of any reason why not.

redmagejoe

This is a great patch. This coupled with Final Fantasy Restored really breathes new life into the classic iteration of the game. This addresses my only issue with the original game even after all the bug fixes and polishing patches: Ineffective attacks.

Googie

Thanks for doing this, Jiggers! I'm gonna patch this over Final Fantasy Restored like redmagejoe did, this is gonna be cool...  :D

redmagejoe

Still some bugs that need to be ironed out. I can't tell you precisely how it happened, but half my party being poisoned was involved. My two poisoned allies died, leaving only the 3rd and 4th slot ones alive. They ended up getting wiped while trying to auto-attack their way out of a group of 5, and when they wiped, I jarringly got the victory music, "Monsters perished" message, and " P" of exp and I think the normal amount of Gil. I went back to the world map with a fully dead party, and when I next got into a battle, the game crashed.

Jiggers

#8
Ooh, thanks for finding that! The good news is I was able to re-create it, too. Dying of poison works ok, but having an enemy kill you seems to do it... Gonna test a few more scenarios and then figure out where its going wrong. Will edit this post with an update if I can fix it in the next hour or so!

Edit: Found it. While I have it checking for the end of battle after the enemy's turn but before applying regeneration... it increments the battle win toggle by 1 (player lost)... then regenerates the enemy, and checks again... incrementing it to 2 (player won). :P Will upload the fix once I figure out the best way to do it. I suppose it doesn't need to check for battle end before doing regeneration...

Edit 2: Links in the first post updated!

To edit the bank_C,asm file yourself, just look for "TakeTurnEnemy:", cut out the "JSR BattleTurnEnd_CheckForBattleEnd", and add 3 more NOPs below it.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

redmagejoe

Is it safe to apply this over my current version with no incompatibilities (layer it on top of the previous bugged-patched version) or were the changes significant enough that I should repatch from scratch?

Jiggers

I have very little idea how .ips patches work on things already patched! I have very little idea how they work in general.

If its going to see the 11 bytes that were changed and fix them to be like the new version and not mess with anything else, then, yeah, it should be safe! Probably!
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Chicken Knife

I just applied this hack after seeing those kinks having been worked out. I love it! Great work so far.

It would be really amazing to be able to play FF3 NES this way as well. Have you given it any thought?

Jiggers

Nope! I'd love to, now that I have given it some thought... But it would require someone else to work on a disassembly a bit. I don't think I'd need it as thorough as Disch's FF1 is, but it would need to be in a way I can understand and tinker with easily. Just getting the one bank where the main battle code is should be enough, if all the necessary parts are in one bank...

I've only been able to do work on FF1 because of such a well-documented breakdown of what everything in its code does, and 2 years of absorbing it into my dreams. So even with a fresh disassembly of FF3's battle code, it would take me a few weeks to really understand what its doing and what needs changing. I'd be willing to try it, but getting the hex into ASM format just frustrates me; I've tried several different programs already.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

redmagejoe

FF1 and FF2 definitely benefit from this, though I'm not sure it's really "necessary" for 3. I'm pretty sure 3 was the first game to do away with "Ineffective" because your characters re-acquire targets as became the norm for the series from that point on. Not that there's anything wrong with working on it for its own sake, but I'm not sure the impetus for it is as strong as FF1 and FF2.

Regardless, do what you gonna do! :thumbsup:

daman.tm

I've used the dynamic action patches on a clean FF1 rom and afterwards I patched the FF Restored hack.
Haven't noticed any problems yet, but can't say I've tested much.

Great work Jiggers!

Bregalad

Quote from: redmagejoe on August 19, 2019, 06:36:23 PM
FF1 and FF2 definitely benefit from this, though I'm not sure it's really "necessary" for 3. I'm pretty sure 3 was the first game to do away with "Ineffective" because your characters re-acquire targets as became the norm for the series from that point on. Not that there's anything wrong with working on it for its own sake, but I'm not sure the impetus for it is as strong as FF1 and FF2.

Regardless, do what you gonna do! :thumbsup:
FF3 is as far as I know the only game in the entiere series where the battles are round-based, but where the characters redirects attacks. From FF4 until FF9 the active-time-battle system is activated, so that it can be possible to target an ennemy who is going to be dead when the character actually attacks it, but the likelyhood is much lower, and that happens only if the player deliberatedly enter his orders at a faster rate than the animation plays on-screen.

In Squaresoft's game library, as far I know only the Romancing SaGa series continues to be round-based and re-targets ennemies automatically, like FF3.

Jiggers

Hey! I submitted it to the queue! I went with Improvement instead of Addendum, because I don't know if it will work patched over the original Dynamic Action Patch on the site...

Thanks to everyone having fun with it so far!
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Cyneprepou4uk

I don't get it, what's that double or tripple or whatever rts means? Are you writting 3 rts in a row and hope it will fix something or what?

Jiggers

I can try to explain that better. Lesse...

RTS is when you return from a subroutine. So there's 2 bytes that act as the return address and get put into the stack. When you DON'T want to return to where the subroutine began, you can pull those bytes off the stack, then the next RTS will return to the previous 2 bytes. Its a way to break out of a loop. Normally when you run in FF1, it breaks out of the battle loop by pulling 2 bytes, then doing an RTS, which Disch calls a double-RTS in his notes. Because I added an extra subroutine when players take a turn, original double-RTS to break out of the battle loop was only breaking out of the player's turn loop. So I have it pull 2 more bytes off the stack, causing it to break out of 2 loops in order to end the battle if running is successful!

So it kind of goes something like this:
Overworld/Dungeon loop > Battle loop > Player Turn loop > Running subroutine: Run fails > return to Player Turn Loop > return to Battle loop > next turn

Overworld/Dungeon loop > Battle loop > Player Turn loop > Running subroutine: Run succeeds > delete return to Player Turn Loop > delete return to Battle loop > Return to Overworld/Dungeon loop

What was confusing was that sometimes, before I added this, the run was successful... meaning that it only needed the original double-RTS to return to the Overworld/Dungeon gameplay... I couldn't get it to do anything weird while running after I added it in, though.

But without it, it would say the run was successful, then the battle would continue.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.