Author Topic: Disabling Materia split function causes Materia deleting bug  (Read 8810 times)

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
see last post


aka HMPMAX1, HMPMAX2, HMPMX, HMPMAX3
Currently, they all do the same with the exception of HMPMX which also remedies status effects and targets characters not in the active party. the numbered ones refill HP/MP for the active party, the other one is basically the Inn function
I want to change this so HMPMAX1 only affects HP, HMPMAX2 only affects MP, HMPMAX3 affects HP and MP, while HMPMX stays the same

I assume the function is handled in the .exe and hardcoded in some way. Is it feasible ( not gonna bother with 'possible' ) to change this?
On that note, something else.

I want to disable whatever function triggers when a materia hits master and then splits itself. Essentially, I want to stop the split so that specific materia are essentially unique and remain unique / lost forever if you sell / lose / trash / merge them.
« Last Edit: 2012-08-23 10:24:23 by KuugenTheFox »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
aka HMPMAX1, HMPMAX2, HMPMX, HMPMAX3
Currently, they all do the same with the exception of HMPMX which also remedies status effects and targets characters not in the active party. the numbered ones refill HP/MP for the active party, the other one is basically the Inn function
I want to change this so HMPMAX1 only affects HP, HMPMAX2 only affects MP, HMPMAX3 affects HP and MP, while HMPMX stays the same

I assume the function is handled in the .exe and hardcoded in some way. Is it feasible ( not gonna bother with 'possible' ) to change this?

I assume you're talking about field codes? Yes, this is possible and very likely feasible. I don't have the code in front of me so I won't make any guarantees. I do have those functions marked for my ease of access so I'll take a look tomorrow.

I want to disable whatever function triggers when a materia hits master and then splits itself. Essentially, I want to stop the split so that specific materia are essentially unique and remain unique / lost forever if you sell / lose / trash / merge them.

It's possible to do this by a small mod to the exe. That limits the materia you'll have at the end of the game. You'll be limited to only two sets of master materia and limited quantities of unique ones. Not that that'd be a real loss or anything. It does make farming Alls a little less profitable if you keep having to buy them. Again, I have this marked and will take a quick look tomorrow ( unless someone beats me to it).

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
Essentially the function that's run whenever you use a restore point ( think, inside gaea cliff, before shizo ) or an Inn that restores all HP / MP and status.

My overhaul already makes selling master materia kind of useless for money gain. and yes, I mean the field codes. Now I just need to limit down the number of unique materia. Paired with shop and field editing, this makes for some great possibilities.

Maybe I should make an extra topic, but I've been wondering how I would best go about distributing the 'mod' of sorts I made. Essentially, I ran my own string of modifications over a bootleg install ( sure, it would put the mods installed as prerequisite but that's not really breaking a leg ) and now want to share as it's gotten really complex and overhaul-esque.

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
It looks like 3C, 3D, and 3F share the same handler code. If you want to change its function it would need to be rewritten. That doesn't sound bad and might be easier than it sounds. I'll look into that.


As for changing Master Materia Birth, changing 0x006CC19E (that's 0x002CB59E in the exe) from 7D 78 to EB 6E should disable that new materia birth. Oddly, after examining that routine, it looks like it might actually replace certain materia if the inventory is full! It's very strange looking. Has anyone ever noticed this happening?

Aali

  • *
  • Posts: 1196
    • View Profile
Haven't seen it in action but I have heard about that bug before, anyone care to try it out?

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Hmmm vaguely yes.  There is 1 part of the game which accidentally did not come with the "You have too much materia" check.  If you do have too much materia it replaces the last one on the list.  Unless I have somehow conned myself into believing that haha

This isn't the "birth" thing though... this was related to pick up.

edit: Actually, that might be a false memory.  I am not sure anymore.  Let me know if you work it out  :)
« Last Edit: 2012-08-14 15:30:49 by DLPB »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
I'm just going to pseudo-dump an altered Hex-Rays decompile of that method and see if someone can verify if this is what happens:

Code: [Select]
void MasterMatieraBirth( MateriaIndex )
{
  for ( i = 0; i < 200; ++i )
  {
    if ( MateriaInventory[i] == -1 )
    {
      MateriaInventory[i] = MateriaIndex;
      //some unimportant stuff is here.
      return;
    }
  }
  x = 4294967295; //a blank materia entry
  z = 255;  //a blank materia index
  for ( j = 0; j < 200; ++j )
  {
    if ( byte_91AA98[MateriaInventory[j] & 0xFF] < z )
    {
      z = byte_91AA98[MateriaInventory[j] & 0xFF];
      x = MateriaInventory[j];
    }
  }
  for ( k = 0; k < 200; ++k )
  {
    if ( MateriaInventory[k] == x )
    {
      MateriaInventory[k] = MateriaIndex;
      return;
    }
  }
}

It's those bottom loops that look like trouble.
91AA98 is a seemingly random table with odd assortment of byte values:

Code: [Select]
1D 1E 21 22 23 45 2B 24  20 26 27 28 54 2A 46 47
1C 04 3F 55 56 41 09 1F  53 4E 30 32 33 36 38 39
3B 3C 3D 50 0F 10 05 35  3E 2D 3A 4F 48 01 02 03
59 0A 0B 12 0C 0D 0E 13  14 15 16 17 11 1A 18 08
37 19 06 07 1B 40 4B 4C  4D 58 25 29 2C 2E 2F 31
34 42 43 44 49 4A 51 52  57 5A 5B 00 00 00 00 00
(read left-to-right, top-to-bottom)

For those that don't eyeball hex, that's 96 entries (for each of the 96 indexes of materia) between 0 and 91. For all intents, I think we can call this materia priority. The lower the value, the lower the priority. The lowest priority existing materia seems to be "underwater" with a rank of 4. Some dummy materia actually rank higher than that. IF the first loop doesn't encounter an empty slot, then the first instance of the materia with the lowest priority gets replaced.

Aali

  • *
  • Posts: 1196
    • View Profile
Kind-of makes sense, nice of them to remove the most useless materia first. The alternative would be potentially losing your newborn ultima and being stuck with just the mastered copy, unable to breed more of them. Too bad underwater is one of a kind and something you really don't want to lose.

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Yeah, I would expect the cheapest to buy in nearly every shop would be the least priority. That's mostly elementals, healing spells, basic status and a few support materia. The number of materia you can actually buy is less than half of what you can only find one of. I guess the logic behind that is once you max out your materia inventory you've likely got one of everything.

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Yeah that might also explain how my Diving (Underwater) Materia disappeared on one of my old saves years ago.

Antonia

  • *
  • Posts: 49
    • View Profile
Indeed.  I always wondered where that thing went.  :P

Someone should hack the silly thing to a better index.  Set like the all materia (or something equally easy to buy/max) to the lowest one. 

I mean, I'd rather lose my dozen or so all materia than my one and only underwater.  XD

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
Okay, tested the materia birth thing, it works fine. It no longer displays "Materia Master" on the after-battle screen but it does display "Materia level up"
It also no longer splits the materia. I was always annoyed by how you could just grind to 3 KOTR, several Mimic, etc ( no more counter x 8 + mimic x 8 to spam limits, HA! )

thanks for the info NFITC1

now I just need the different restore party functions


I remember that in-menu ( out of battle ) properties of items were also defined in the .exe
is there a list for that? I disable a lot of items in the menu due to them having conflicting ( conflicting with in-battle ) properties. The same holds true for healing magic.

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
Disabling Materia split function causes Materia deleting bug
« Reply #12 on: 2012-08-23 10:23:24 »
Okay, I've run into a very bad bug.
If you disable the Materia splitting, put a materia into a weapon or armor and then change to an armor or weapon that doesn't have the slot available the materia is in, it is permanently lost. It just vanishes instantly and there is no way to get it back. Any ideas on how to solve this?
« Last Edit: 2012-08-23 11:00:46 by KuugenTheFox »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Apparently that function I posted earlier is probably also used in unequipping materia from blank slots. The handling would be the same too. So instead of the change I made earlier, it would be easier to NOP the call that is used in the case of a mastering. I'll let you know later.

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
Would be really cool if you could show me how to fix it because right now I put bright yellow warnings on all the early materia spots because I just realized I lost a dozen materia or so due to this already

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Would be really cool if you could show me how to fix it because right now I put bright yellow warnings on all the early materia spots because I just realized I lost a dozen materia or so due to this already

1. Revert the change I made in this post. This is also partly why I always list "from" values.

2. Disable the Weapon AP materia birth sub call: Change 0x005CAF12 (that's 0x001CA312 in the exe) from E8 68 12 10 00 83 C4 04 to EB 06 90 90 90 90 90 90 (JMPing over the old function call and NOPing the remainder).

3. Disable the Armor AP materia birth sub call: Change 0x005CB0C5 (that's 0x001CA4C5 in the exe) from E8 B5 10 10 00 83 C4 04 to EB 06 90 90 90 90 90 90 (JMPing over the old function call and NOPing the remainder).

Sorry about the whole deleting materia thing. I didn't realize it was the same function call. FFVII is anal about materia equippings. It essentially unequips everything, then reequips it every time something is added. Weapons, armor, and accessory included. A lot of stuff goes on in between when you tell it to equip something and you get input back. Yes, it does it all in one frame, but that's still a lot of function calls flying around.

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
No need to feel sorry. Not like I'm paying you to look into this stuff for me.

Works fine, both things ( unequipping and no materia birth )
thanks a lot NFITC1

Did you have time to look into those field codes I pm'd you about by the way?

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Did you have time to look into those field codes I pm'd you about by the way?

It might be possible. I can wring 8 extra bytes out of that function and a few out of the one before it. It'd be more difficult than just "replace 5 bytes here with this". It's a pretty big shift up and down to make room for a few checks and jumps.

For future ref, the magic byte is CC0890.
« Last Edit: 2012-08-23 20:31:49 by NFITC1 »

Tenko Kuugen

  • Public Enemy
  • *
  • Posts: 1416
    • View Profile
    • Twitter
It might be possible. I can wring 8 extra bytes out of that function and a few out of the one before it. It'd be more difficult than just "replace 5 bytes here with this". It's a pretty big shift up and down to make room for a few checks and jumps.

If it turns so difficult that someone not involved in real coding can't reproduce it, please don't bother. I don't want to be accountable for having wasted your time.