[WIP] Custom Game Settings (FF7)

  • Thread starter Thread starter Wutai Clan
  • Start date Start date
Status
Not open for further replies.
Another request, while I think about it : allowing three party members to participate in the Battle Square ^^

EDIT:

And actually, if you need more ideas, you can look at the edited part of reply #43, in this thread. Granted, these ideas come from FFVI (and I bet most of them would be doable through AI editing), but I wonder, for example, what could be done to the status effects themselves.
Oh yeah, and expanding the list of items / weapons / armors / accessories. I would love this.
 
Last edited:
Another request, while I think about it : allowing three party members to participate in the Battle Square ^^

EDIT:

And actually, if you need more ideas, you can look at the edited part of reply #43, in this thread. Granted, these ideas come from FFVI (and I bet most of them would be doable through AI editing), but I wonder, for example, what could be done to the status effects themselves.
Oh yeah, and expanding the list of items / weapons / armors / accessories. I would love this.
Well, I spent most of the last couple days working on a new hooking technique, it's actually, more like a dynamic patch, than a hook. Anyways, now that I've learned how to do that, I should be able to accomplish a lot of cool stuff.

I'll do what I can to make the request happen, but I can't promise anything, I mainly wanted an idea of what parts of the code I should focus on decoding.
 
I see. Oh, and I also know that many people, myself included, would love to increase the damage from the Poison status (something like 25% MaxHP would be cool, so it finally becomes a threat). I'm done this time, promise  :P
 
I see. Oh, and I also know that many people, myself included, would love to increase the damage from the Poison status (something like 25% MaxHP would be cool, so it finally becomes a threat). I'm done this time, promise  :P
It's cool, I don't mind the request, it helps me figure out what to work on, I just wanted to make sure you guys know, the best I can do, is try.
 
Hey, in case you haven't noticed, I update the second post, on the first page with stuff of interest, I just added a few battle variables I decoded. (So even if I'm not making new post, you can always check that post for possible new additions\updates.)

Working on decoding the battle system a bit, and I added a new feature for setting custom random battle rates. (It still needs work, interferes with Chocobo Lure, seems that Enemy Away\Enemy Lure\Chocobo Lure, and random battles are handled by the same function. So I'll need to re-write my hook to account for that once, I figure out which part of the code I patched handles it.)

Also, I need to write a new function into the games memory space, so it can access the games variables as if it were original game code. So, if you know how to dynamically allocate a function into a code cave within the game, let me know, I need to be able to do this for some advanced stuff. (I might be able to Google it, but, it might be hard to find, since I don't know the proper terminology.)

Basically, I want to inject a function, then hook it, so I can use it to access the games data, just like the game does.
 
Last edited:
Wall Market can edit all items & magics (as well as the commands, materias, initial data and equipment), but their in-battle effects only. Sadly, as far as I know, no one found how to edit their field / triangle menu data, yet. If you could find out how to do this, that would make a lot of people happy, myself included :)
Oh, I know how to do it. I've known for a while. It's just it'd be nearly impossible to do it safely other that what Wutai Clan's trying to do. I pointed out the function that handles the Items. That's all there is to it.

Wutai Clan:
I thought I already gave you the DamageHP/MP functions. I guess I didn't. I didn't have DamageMP listed although I was almost sure I had found it before.

DamageHP is 0x6CB9D2. Takes FormationSlot and Amount to damage as parameters. Both are DWords. This is called by some field scripts like running into the spikes in Cave of the Gi.
DamageMP is 0x6CBB27 and takes same parameters. I think this is used when performing magic from the menu.

GetItemCount is 0x6CBF57. Takes Item Index as a parameter and returns the item's listing as it is in the inventory ((Count << 9) + Item Index). Not much of a stretch from there to get the count.
 
@NFITC1, Thanks, I'll have to get them tested, and update the list, etc,. :)

@Kranmer, the post on the first page with all the update info, contains a few entries marked as variables, you can use those for trainer options, they are proper values for memory editing, pointers in memory editing, are really the addresses of the variables in the .exe..(Also, all my values are obtained with a retail v1.02 .exe, so if you have any .exe patches(YAMP), it could interfere with the values, this project will pretty much require an unmodified .exe to work 100% as intended.(It could be unstable otherwise, since I might end up patching code, that is somewhere else in your game, causing crashes, bugs, etc,.))

Well, thanks to both of you for the help, feel free to contribute with anything you don't see on my list, I'm just decoding at random, to get a clearer picture of what does what, and implementing new stuff as it becomes possible.

----

Edit: Can you explain what this formula means?

Code: [Select]
Code:
((Count << 9) + Item Index)
----

Edit: I've tried various ways to make a working formula that always gives me the correct results, I can't seem to figure it out. ???
 
Last edited:
Edit: Can you explain what this formula means?

Code: [Select]
Code:
((Count << 9) + Item Index)
<< is the SHL you've been asking about somewhere on the board. So... Having an item record, to get the actual count, you do a SHR (by 9 bits) and that means dividing by 512.

So a 0x0601 (1537 in decimal and 0000011000000001 in binary) means (/ is an integer-division, % is the modulus)
 - 1537 / 512 = 3 - actual count
 - 1537 % 512 = 1 - item id (might be a potion, don't remember)

A quicker way - you get the higher byte (in our example - 0x06) and divide it be 2, discarding the remainder. 6 / 2= 3.

dziugo
 
<< is the SHL you've been asking about somewhere on the board. So... Having an item record, to get the actual count, you do a SHR (by 9 bits) and that means dividing by 512.

So a 0x0601 (1537 in decimal and 0000011000000001 in binary) means (/ is an integer-division, % is the modulus)
 - 1537 / 512 = 3 - actual count
 - 1537 % 512 = 1 - item id (might be a potion, don't remember)

A quicker way - you get the higher byte (in our example - 0x06) and divide it be 2, discarding the remainder. 6 / 2= 3.

dziugo
Thanks for taking time to help out. :)

Anyways, that formula isn't working either, here are a few examples taken by checking my current inventory.

Code: [Select]
Code:
Item = Potion x99Slot = 0 [0 Based]Value = 50,688 [Decimal]Result = 50,688 / 512 = 99 [Correct]Item = Ether x8Slot = 1 [0 Based]Value = 25,089 [Decimal]Result = 25,089 / 512 = 49 [Wrong]Item = Phoenix Down x46Slot = 2 [0 Based]Value = 65,535 [Decimal]Result = 65,535 / 512 = 127 [Wrong]
 
Last edited:
65535 (or 0xFFFF) is a slot-empty indicator, so you've most likely mixed the indexes.
 
65535 (or 0xFFFF) is a slot-empty indicator, so you've most likely mixed the indexes.
Well, the only thing I can think of, is that the inventory is an array, and it works like a stack, ie, they are listed in the order you obtained them. If that's the case, I would have to enumerate the entire inventory, and examine it's contents, rather than looking at individual items.

I didn't mix up the indexes, I'm capable of counting. 0, 1, 2, 3, etc,. :P
 
You've read the value from different index, so you've mixed it up ;)

If that function is backed up with a save-map then it's an array. Empty line is a 0xFFFF, it shows up in order you see it in-game. Just calculate counts for first 10 items and see where they are in-game.
 
You've read the value from different index, so you've mixed it up ;)

If that function is backed up with a save-map then it's an array. Empty line is a 0xFFFF, it shows up in order you see it in-game. Just calculate counts for first 10 items and see where they are in-game.
Hey, not my fault the game uses a weird system. :)

I know potions are the first item I obtained, and the calculation works for index 0.

I'll investigate more thoroughly later, I'm still not fully awake.

What do you know about the Savemap data in the .exe, is it arranged like it is on the Wiki, or is that just how it get's written to a save file. I'm hoping to figure out where the game is drawing it's data from, so I can access it without having to worry about the current game mode. (world\battle\field)

Or is it just a bunch of loose globals that the savemap grabs when it needs to save?

---

Basically, having to have battle\world\field versions of functions, isn't going to be any fun to maintain, I may just re-write how the game works after I figure it out a bit better. (I could probably get the .Net framework loaded, and use generic list, etc,. Just let my DLL act as the data manager for the whole game. Not an easy task, would require rewriting a large chunk of the game, but totally worth the effort, if I can pull it off.)
 
Last edited:
The save map always exists in memory in the same structure as in the wiki. When you save, the game just takes a whole, contiguous chunk out of the memory and dumps it into a file and calls that the save file. In memory, this starts at 0xDBFD38 and just goes through the entire savemap structure byte-for-byte. No reorganizing or look-ups required.

As for the items, yes they're basically a stack. When you get an item, the game will loop through the entire inventory array looking for the index of the items Code: [Select]
Code:
ItemSlot[x] bAND 1FFh
  looking for the index of that item. If it finds it, it just adds one to its quantity Code: [Select]
Code:
ItemSlot[x] = ItemSlot[x] bAND 1FFh + ( ItemSlot[x] bAND FE00h + 200h )  'adds one to the quantity
and moves on with life. If it doesn't find the item index it creates a new item in the first unused slot it comes to
Code: [Select]
Code:
for ( int x = 0; x < 320; x ++{     If (ItemSlot[x] = FFFFh     {          ItemSlot[x] = NewItemIndex + 200h;          break;     }}
To find the count of the item you want you'll have to loop through the entire structure looking for the index you're querying. The game won't store an item if you have 99 of them and it won't have multiple entries. You can cheat to give yourself 500 Megalixers if you wanted.

Moral of the story is the item you want to find the count of could be anywhere in the inventory and you might have to look through the entire thing to find it.
 
The save map always exists in memory in the same structure as in the wiki. When you save, the game just takes a whole, contiguous chunk out of the memory and dumps it into a file and calls that the save file. In memory, this starts at 0xDBFD38 and just goes through the entire savemap structure byte-for-byte. No reorganizing or look-ups required.
Awesome, I'm going to have to check it out, and see how it lines up across modes(ie, will it stay in synch with battle\world mode, or does it synch up during mode changes, etc,.), regardless, this is good info to have, even if I can't use it how I wanted to, I'm sure it will be useful. :)

As for the items, yes they're basically a stack. When you get an item, the game will loop through the entire inventory array looking for the index of the items Code: [Select]
Code:
ItemSlot[x] bAND 1FFh
  looking for the index of that item. If it finds it, it just adds one to its quantity Code: [Select]
Code:
ItemSlot[x] = ItemSlot[x] bAND 1FFh + ( ItemSlot[x] bAND FE00h + 200h )  'adds one to the quantity
and moves on with life. If it doesn't find the item index it creates a new item in the first unused slot it comes to
Code: [Select]
Code:
for ( int x = 0; x < 320; x ++{     If (ItemSlot[x] = FFFFh     {          ItemSlot[x] = NewItemIndex + 200h;          break;     }}
To find the count of the item you want you'll have to loop through the entire structure looking for the index you're querying. The game won't store an item if you have 99 of them and it won't have multiple entries. You can cheat to give yourself 500 Megalixers if you wanted.

Moral of the story is the item you want to find the count of could be anywhere in the inventory and you might have to look through the entire thing to find it.
Alright, makes sense.

I'll have to play around with it, see if I can't come up with some functions to make it a bit easier to work with. (There are numerous ways to handle this, it's a matter of figuring out what works best, and is easiest to work with from my DLL.)

Thanks for the info, I appreciate it. :)
 
Just some extra info:
STITM
CKITM
Functions are already there, so all that is left is to use them ;)

Reading through the Field Script Opcodes is a good idea. Reading through them while checking the disassembly is a great way to expand your knowledge about inner workings of FF7. It'll take a big amount of time, but it's worth it (and you'll admit it only after you've done it ;)).

And to be a technical purist - inventory does not work like a stack! You can clear/replace items in the middle of it, so it's basically a random-access array (or just "an array").
 
Just some extra info:
STITM
CKITM
Functions are already there, so all that is left is to use them ;)

Reading through the Field Script Opcodes is a good idea. Reading through them while checking the disassembly is a great way to expand your knowledge about inner workings of FF7. It'll take a big amount of time, but it's worth it (and you'll admit it only after you've done it ;)).

And to be a technical purist - inventory does not work like a stack! You can clear/replace items in the middle of it, so it's basically a random-access array (or just "an array").
Thanks, I'll check it out. :)

Also, I wasn't saying it was a stack, or exactly like a stack, I was saying it seemed to behave similarly to one. :P

(Btw, the functions I'm hooking, are what those call, I can see scripts execute a number of the functions, like, during scripted events, you can see RestoreHPMP being called in my log. But, I may be able to find new functions using those, would certainly be quicker, if I can figure out how it relates, ie, how they look up the real underlying function.)

----

Edit: Well, I think I found the script opcode list in the .exe, but they are pretty much scrambled like everything else, it does narrow down the list of functions to test, but there seems to be quite a few of them(50+).
 
Last edited:
Edit: Well, I think I found the script opcode list in the .exe, but they are pretty much scrambled like everything else, it does narrow down the list of functions to test, but there seems to be quite a few of them(50+).
Where is that? I haven't done much field script work so I don't know what to look for. I could probably help you interpret some of them.
 
Where is that? I haven't done much field script work so I don't know what to look for. I could probably help you interpret some of them.
I checked it out better, and it wasn't what I thought..

It starts here [0x009055A0] and goes on for some time, it just list function calls, possibly an export table\lookup table\etc,. ?

What I would like, are the functions that give you EXP\GIL\AP after battle, I'm thinking about adding [Battle Reward Multiplier] options to the .ini, so you can do something like.

[Battle Reward Multiplier]
Enabled = true
GIL = 1 // No change
EXP = 2 // 2x EXP
AP = 5 // 5x AP

I'm also working on a fix for the random battle rate patch, I'm thinking, I can just patch each instruction, it basically checks your inventory, and sets the rate based on whether or not you have certain items(enemy away\lure), their mastery level, etc,. (So any place it sets the value, I can just patch it to the value in the .ini file.)

I'm still trying to find the function that gets triggered when you first "click" an inventory item, I need to intercept that call, figure out what item you selected, and if it's a potion\ether\etc, apply my patches to their restorative values. (After I get that done, I'll probably do a release.)

So if you want to find those battle reward functions, or look for that menu function, or try to find any of the opcode functions(that we don't already have), etc, that would be helpful, this is a huge undertaking, so any help is appreciated. :)

The faster we get stuff decoded, the sooner we can start getting new stuff implemented, and, there aren't very many limits to what can be done, if, I have enough data to understand the systems involved.
 
What I would like, are the functions that give you EXP\GIL\AP after battle, I'm thinking about adding [Battle Reward Multiplier] options to the .ini, so you can do something like.

[Battle Reward Multiplier]
Enabled = true
GIL = 1 // No change
EXP = 2 // 2x EXP
AP = 5 // 5x AP
I'm not certain that will work. When an enemy is defeated, it just adds its rewards to the overall battle rewards totals. After the battle ends it spreads those points between the active members in the battle party. There are no parameters involved. I can tell you what memory addresses those values reside at, but they're not fully populated until the battle is over.
 
Status
Not open for further replies.
Back
Top