Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Husbjörn

Pages: 1 [2]
26
I have been trying to reverse engineer the battle abilities / skills from FFX and have made decent progress with regards to stats (power, calculation formulas, mp cost, etc.), flags (targets, elements, types, stealing, menu usability), names / descriptions, status infliction / removal rates and visual animations. There are still about 20 bytes of data per skill I haven't been able to decipher however. Also, there doesn't really seem to be much, if any, information on this available online for whatever reason, but I'm pretty sure there are people around who do posess this knowledge judging by youtube videos of "hacks" etc. If not, I'd be happy to share what I've found out.

Anyway, on to my question at hand.
It appears that the visual animations for skills have camera and character animations built-in (though as for the character's casting animation it seems this can sometimes, but not always, be changed by setting byte 25 in the skill data). Unfortunately this has the end result that most animations used for enemy skills tend to have the camera shift away from the targets and focus solely on the caster for the entire duration of the animation, which naturally isn't desirable. I was wondering if anybody know of a way to get around this (if indeed there is one without needing to find and modify the individual animation data itself). I have so far come up with nothing which is rather off-putting.

27
An enemy called TrickPlay does this action called Gold Mountain that increases dropped gil by 800 every time it does it. I don't think there's another example in all of the vanilla game that does this for gil or EXP, but both should be possible.

Ah yes I remember that one, though I don't think I ever realized that increased the dropped gil. That's pretty cool!

28
Missed opportunity indeed!
Out of curiosity, does any encounter have a non-static gil reward? (I haven't actually played through the game in ages).

29
Haha, I see. I wasn't aware of such a typo in the battle square, might have to go re-explore now.

As for the actual topic in question it unfortunately doesn't seem like the AP value can be changed from a script; I used the following to brute force change most any non-animation related actor value and still it stays the same:
Code: [Select]
12 2060
11 4048
80
60 01
90
12 2060
11 4050
80
60 01
90
12 2060
11 4058
80
60 01
90
12 2060
11 4068
80
60 01
90
12 2060
11 4070
80
60 01
90
12 2060
11 4078
80
60 01
90
12 2060
11 4090
80
60 01
90
12 2060
11 4098
80
60 01
90
12 2060
11 40A0
80
60 01
90
12 2060
11 40A8
80
60 01
90
12 2060
11 40B0
80
60 01
90
12 2060
11 40B8
80
60 01
90
12 2060
11 40C0
80
60 01
90
12 2060
11 40C8
80
60 01
90
12 2060
11 40D0
80
60 01
90
12 2060
11 40D8
80
60 01
90
12 2060
11 40E0
80
60 01
90
12 2060
11 40E8
80
60 01
90
12 2060
11 40F0
80
60 01
90
12 2060
11 40F8
80
60 01
90
12 2060
11 4100
80
60 01
90
12 2060
11 4108
80
60 01
90
12 2060
11 4110
80
60 01
90
12 2060
11 4118
80
60 01
90
12 2060
11 4120
80
60 01
90
12 2060
11 4128
80
60 01
90
12 2060
11 4130
80
60 01
90
12 2060
11 4138
80
60 01
90
12 2060
11 4140
80
60 01
90
12 2060
11 4148
80
60 01
90
12 2060
11 4150
80
60 01
90
12 2060
11 4158
80
60 01
90
12 2060
11 4160
80
60 01
90
12 2060
11 4168
80
60 01
90
12 2060
11 4170
80
60 01
90
12 2060
11 4178
80
60 01
90
12 2060
11 4180
80
60 01
90
12 2060
11 4188
80
60 01
90
12 2060
11 4190
80
60 01
90
12 2060
11 4198
80
60 01
90
12 2060
11 41A0
80
60 01
90
12 2060
11 41A8
80
60 01
90
12 2060
11 41B0
80
60 01
90
12 2060
11 41B8
80
60 01
90
12 2060
11 41C0
80
60 01
90
12 2060
11 41C8
80
60 01
90
12 2060
11 41D0
80
60 01
90
12 2060
11 41D8
80
60 01
90
12 2060
11 41E0
80
60 01
90
12 2060
11 41E8
80
60 01
90
12 2060
11 41F0
80
60 01
90
12 2060
11 41F8
80
60 01
90
12 2060
11 4200
80
60 01
90
12 2060
11 4208
80
60 01
90
12 2060
11 4210
80
60 01
90
12 2060
11 4218
80
60 01
90
12 2060
11 4220
80
60 01
90
12 2060
11 4228
80
60 01
90
12 2060
11 4230
80
60 01
90
12 2060
11 4238
80
60 01
90
12 2060
11 4240
80
60 01
90
12 2060
11 4248
80
60 01
90
12 2060
11 4250
80
60 01
90
12 2060
11 4258
80
60 01
90
12 2060
11 4260
80
60 01
90
12 2060
11 4268
80
60 01
90
12 2060
11 4270
80
60 01
90
12 2060
11 4278
80
60 01
90
12 2060
11 4280
80
60 01
90
12 2060
11 4288
80
60 01
90
12 2060
11 4290
80
60 01
90
12 2060
11 4298
80
60 01
90
12 2060
11 42A0
80
60 01
90
12 2060
11 42A8
80
60 01
90
12 2060
11 42B0
80
60 01
90
12 2060
11 42B8
80
60 01
90
12 2060
11 42C0
80
60 01
90
12 2060
11 42C8
80
60 01
90
12 2060
11 42D0
80
60 01
90
12 2060
11 42D8
80
60 01
90
12 2060
11 42E0
80
60 01
90
12 2060
11 42E8
80
60 01
90
12 2060
11 42F0
80
60 01
90
12 2060
11 42F8
80
60 01
90
12 2060
11 4300
80
60 01
90
12 2060
11 4308
80
60 01
90
12 2060
11 4310
80
60 01
90
12 2060
11 4318
80
60 01
90
12 2060
11 4320
80
60 01
90
12 2060
11 4328
80
60 01
90
12 2060
11 4330
80
60 01
90
12 2060
11 4338
80
60 01
90
12 2060
11 4340
80
60 01
90
12 2060
11 4348
80
60 01
90
12 2060
11 4350
80
60 01
90
12 2060
11 4358
80
60 01
90
12 2060
11 4360
80
60 01
90
12 2060
11 4368
80
60 01
90
12 2060
11 4370
80
60 01
90
12 2060
11 4378
80
60 01
90
12 2060
11 4380
80
60 01
90
12 2060
11 4388
80
60 01
90
12 2060
11 4390
80
60 01
90
12 2060
11 4398
80
60 01
90
12 2060
11 43A0
80
60 01
90
12 2060
11 43A8
80
60 01
90
12 2060
11 43B0
80
60 01
90
12 2060
11 43B8
80
60 01
90
12 2060
11 43C0
80
60 01
90
12 2060
11 43C8
80
60 01
90
12 2060
11 43D0
80
60 01
90
12 2060
11 43D8
80
60 01
90
12 2060
11 43E0
80
60 01
90
12 2060
11 43E8
80
60 01
90
12 2060
11 43F0
80
60 01
90
12 2060
11 43F8
80
60 01
90
73

Might have to go off the course then...  ;)

30
I noticed that the experience and gil rewards for defeating an enemy can be altered by changing its 0x42e0 and 0x42c0 values.
this page similarly suggests that tha AP value resides at offset 0x42b0.
It however turned out that changing this value has no discernible effect at all. I first thought that it might be that something else has the final say in what the AP value will be, but upon checking the value stored at Actor<word>[0x42b0] with the following simple counter script, it appears that this isn't even set to the actor's AP value as set in scene.bin at all:


0000| 02    2060        # Push self mask value
0003| 02    42B0        # Push AP reward offset value
0006| 80                # Resolve AP reward value of self and push it onto the top of the stack (as a 16-bit word)
0007| 61    03E8        # Push constant 16-bit word value (1000; corresponds to actor AP value set in scene.bin)
000A| 40                # Push true if the top values of the stack (popped) are equal, or false otherwise
000B| 70    0015        # Jump to offset if the values were not equal
000E| 93    "Equal\0"
0015| 93    "Not equal\0"
0026| 73


Memory scanning further reveals that the actual location of the AP value once loaded into RAM is always 15 bytes prior to the gil value, which is 4 bytes wide and followed immediately by the EXP value, occupying another 4 bytes. It is off course possible that the actual memory used by the process does not reflect the actor-data offsets used by the 0x80 instruction and no, altering the value at Actor<word>[0x4248] does not change the AP value either.


Is the memory offset suggested by the above wiki link incorrect or is something else at play here? Any thoughts or theories?

Edit: and what the heck, when previewing this post I notice that it automatically shows "off course" as "off course" even though it doesn't say that in the textarea I submitted? Some easter egg trolling?  ::)
Edit 2: apparently it happens in the final post as well; just to be clear "of course" is spelled with an "of" not an "off", unless you want the whole meaning changed... x)

31
Yeah, I figured as much.
No particular reason, just considering whether it would be possible for any possible future situation, but it's quite likely you would never have a need to do that. I'm still kind of new to this and I like to know what is available in the tool set so to say.

32
Ah, so that's how it goes... quite confusing indeed, I would probably not have guessed that. Thanks a lot for clearing it up.

Regarding the lists, I take that to mean that you cannot explicitly create one from within an AI script then, since all your pushes will have an automatic data type set and you cannot set this to the list/item identifier?
I suppose you could work around this by temporarily changing some actor values, having the battle engine populate a list with those values and then reset them to their previous values though, is this what you were implying with this quote?
Quote
If you know how each opcode handles values on the stack it's completely possible to construct it at any point in the program flow. I've done it lots of times.


Again, thanks for the rundown :)

33
I wonder if someone would be able to elaborate on exactly how the "select greatest / least from list" instructions (opcodes 0x84 and 0x85) work?
Let's take an example of trying to select an opponent with the lowest HP to illustrate my point:


02    20b0                # Push current actor's active enemy mask
03    4160                # Push offset to HP value of (target) actor(s) as given in the above mask
80                        # Pop last two values from the stack and push a list of all HP values for the current actor's active enemies
85                        # Select the lowest value(s?) from the list at the top of the stack


I would have assumed that the above would push a 16-bit mask onto the stack with the bit corresponding to the enemy actor with the lowest HP set.
This does not seem to be the case however as more than one bit seems to be set. I could kind of understand if this happened if two actors had the same health which also happened to be the lowest but that is not the case. I then thought that it might push the actual index corresponding to the bit to be set instead (such that it for example pushes 3 for actor 3, rather than a 0%0010 mask) but that doesn't seem to be it either. The last possibility I can imagine is that it pushes the actual lowest HP value, but if this was the case what good is the instruction? While it would be possible to get the actual lowest HP value if we knew the actor to whom it belonged, the same cannot be done in reverse.
Or am I missing the point of these instructions entirely?


Another kind of associated question while we're at it, are lists on the stack formed in some way that they can be manually constructed (or read) by pushing / popping values / addresses or are they their own thing beyond manual control from a script perspective? I am guessing the latter since they tend to be described merely as "datatype 2X".

34
Random thought: of the built in formula, X5 is pretty simple [base of Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22) - which doesn't take many things into account].

I haven't tried it but off the top of my head, wouldn't X4 [MaxHP * (Strength / 32)] be better for that?
You could just set the strength to 32 and then perform whatever damage calculation you like in your script, temporarily store it to the using actor's max hp, perform the attack and then reset the maximum hp back to its original value.

About Conformer, would a minor quality of life update to allow empty / comment-only lines inside functions be a possibility in the not too remote future?
Awesome initiative on that project regardless, I was pondering writing a simple compiler for the battle scripts myself but... well, I would probably never have gotten around to it so great that someone did  ;D

35
Ah, thanks guys, your topic on the ab format was really helpful NFITC1 :)
It would seem I might have to go the hard way of extracting models, adding custom animations and re-import them to give some of the early enemies in the game useful general purpose animations such as "cast spell", or "use item" for humanoids. That's a bit of a setback but it should at least be possible.

@Sega Chief: Thanks, I'm mainly focusing on the predefined enemies at the moment but I might get around to messing with the characters sooner or later so that list will come in handy then.
As for how they are structured, I've noticed that certain enemy actors (such as Diamond Weapon IIRC) have spread out working animation indicies (it is possible this is caused by a wraparound if only a nybble is actually read for it however, I don't recall the exact indices as I was just incrementing the value step by step with a memory scanner).

36
I've begun looking into modifying some FFVII battle scenes for fun on my free time and have run into a bit of an annoyance with actor animation indices (as in the actual animations performed on the actor's mesh such as "physical attack", "throw", "cast", etc.).
It would seem that these aren't structured in any particular way; some models have a set of valid ID's at 1 .. 5 or something, then there are a bunch of id's that will freeze the battle if they are used and then there can be a usable one again at id 220. Since trial and error for every individual actor gets extremely tedious with 255 possible indices and the fact that the game will freeze once you happen upon an invalid one, forcing a complete restart to investigate the next probable fail-id, I was wondering if it is known where this animation is available (it would make sense that the game is aware of valid indices in one form or another)? My guess would be that it might be stored in the xxda files in battle.lgp but I haven't been able to find any specifications on the format of those. I'd try to dig in and see what I can find out myself but those files are dauntingly large and I see little reason to reinvent the wheel as it were if this information is perhaps already known.

Pages: 1 [2]