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.


Topics - quantumpencil

Pages: [1]
1
UPDATE: The stated goals here have been achieved. I have a burn effect, displaying the "fire" animation on every tick, working for both enemies and player characters =). Thanks ergo_joe for the help,  looking forward to announcing/sharing some things with all of you soon =D

Starting a new thread for this specific issue. I've successfully gotten a fire-elemental burn effect working, which ticks alongside poison (but is inflicted/removed differently) by hooking into the poison callback and poison data setter that's run in the games main action routine(0x435D81) during the big switch statement on the command that loads data and calculates damage.

I would like to have these ticks display a fire attack. the main current action struct of size 0x260h has fields 0x24 (which is set from ability data to the effect ID toplay) and 0x14 (which the wiki says is the base index for calculating absolute animation indexes from relative ones). Unfortunately setting thes to 0x01B and 0x00 by replacing the poison-preparation function(0x5C9FC0)  respectively does not cause poison (issued via command (0x023) to play the fire animation.

So there are two current goals:

1: This whole mess about relative animation indexes is inconvenient for modding, as it would be great to be able to reuse all animations in any context; So I am going to work on replacing this behavior with a simpler absolute animation index system, so that any command type can use any animation.

2: I want to get the new burn effect to display the Fire 1 animation on tick (Which is probably more difficult than 1, as I recall certain player ability "scripts" call additional affect animations -- and poisons 0x23 command likely has no animation scripts associated -- so it's possible a very simple script which does nothing but display the animation effect itself at the target location will need to be created, if there is no "idle/no actor animation and then display an effect at target location" ability-effect using script currently in the game.)

EDIT 2 - GOOD PROGRESS: Did a bunch of reversing tonight. The scripts in question are actually loaded from the model files, and accessed by a routine which switches on the opcodes in the scripts which lives at 0x41FBA4. This function seems to be holding the a pointer to the script in ebp-14h, which it's setting based on some kind of other switch statement, but I don't quite understand what this is doing currently.

Now I have a much clearer idea of what I'm looking for, if anyone wants to help reverse/knows this. Basically this function gets a pointer to an animation script and runs it. These scripts are loaded up from model files. When the an action is popped of the battle queue and its main action routine is called, there must be a way in which the information about that attack reaches this function for the execution of the animation.

We don't need to fully disassembly 0x41FBA4 right now (it would take a while) to get a ton of power here; If we can just trace how we get from "setting a bunch of fields in the BattleDataContext Ptr" to "Ptr to correct action script is parsed by 0x41FBA4, we can interject code into the process and instead pass a ptr to a custom animation script under-the right conditions (which we can just hold in RAM somwhere).

This would be sufficient for injecting and creating more or less arbitrary in battle animation effects -- we'll just need to figure out a model script which corresponds to magic, and play around with the op-codes until we get it to "only" display an added effect (replace the 1B with 00 and try to shorten the length it's played). Then when-ever the command index is 0x23, run that script =)

2
I've been going through the exe battle routines and have a few questions/observations

1: The routine at 0x5D173F chooses the damage formula to call from a pointer table located at 0x8FF1F8. This same routine calls a sub 0x5DC880 which is quite daunting, but appears to be being passed a "0" and a "1" via the stack (as is standard with cdecl calls like this) and is called both before and after the damage formula pulled from the ability data in this routine is called via function pointer. Interestingly enough I can't see where this argument is used within the sub at 0x5dC880. Due to it's size I'm not totally sure what this sub does,  does but it seems to have some roll in preparing the battle context object pointed to in all damage formulas. Anyone made any substantial progress understanding this big guy?

2: The large data structure which is referenced throughout damage calculation and formula selection (and is pointed to by the pointer at 0x99CE0C) seems to contain a lot of information from my inspection, it contains at the very least attacker/target stats, ability data, and some attack flags like whether or not something crit. Has this data structure pointed to by 0x99CE0C been mapped by anyone in the modding community? I've got myself a little loader/dll injector for redirecting routines, but in order to make the redirected routines (and hopefully expose a C api for redirecting exe routines at runtime) I need a better understanding of this data structure -- it looks rather amorphous, I don't see evidence of a clear ability data struct or anything like that at the offsets which seem to correspond to ability flags (like context_ptr+ 48h, which is definitely ability power, or context_ptr + 6Ch which appears to some flags, one of which is "auto-critical")"

Thank you for your help =)


3
I'm preparing to release a tactical element mod which adds 16 new status effects (mostly elemental) and elemental interactions via (somewhat lengthy and involved) AI scripts.

I've got a hidden actor working as a clock for timing/executing elemental effects (like proper burn/bleed statuses) and via using the 2120 global previous element mask and bitwise operations, this should work both when elemental materia is used to add an element to a weapon strike, or its a normal spell/summon.

Most everything is working, except one piece -- I need to be able to dynamically set an actors elemental weaknesses/resistances (double/half) within the AI script to accomplish my initial vision for this (or otherwise, and likely much more laboriously, boost/reduce damage based on element) Looping through all the bytes it seems proud clod/wall market do not recognize which addresses hold these masks, though they do exist for null/absorb elements. I was wondering if anyone had already figured out if any of the currently unlabeled actor data bytes are half/weak masks.


Example of what I am trying to accomplish:

Use water attack on enemy x, enemy gains the soaked status, which has the following interactions:
next lighting attack does double damage and has a 100% chance to paralyze (provided target is not floating),
next wind attack deals double damage and inflicts the chilled status,
next ice attack instantly freezes the target solid (so they can be shattered),
fire does 1/2 damage and removes the status.


All of this is currently working except for 1/2 fire damage and the multipliers on the lightning/wind effects.


EDIT:

I'm also trying to see if I can do this via stat manipulation

It looks like lowering the level of the target in the pre-target script doesn't affect damage (It's not a factor in damage formulas... too bad not every formula scales like conformer =p), though lowering/raising the level of the attacker prior to damage calculation would scale perfectly. Since I want this to work for both player characters and enemies I can't  lower the level prior to an action in the main script; Is it currently known when the actor values which track previous physical/magical attacker are set? If these can be accurately referenced in pre-action setup script then I could modify the attacker's level conditional on the element of their last attack (in 2120), and then zero out previous/current attacker masks at the end of the counter scripts.

So, tldr; can counter:preTurn scripts access the "2060.41E0" (I think that's it) to get the bit-mask of the user of the attack which is targeting the current actor, but that has not yet executed.

I'll try and check this when I'm back on my desktop which has FFVII set-up to run, hopefully that's the case =p. That would be even better, as it would stack with normal weakness/resistances


4
Hey guys,

I've been getting interested in modding the executable directly, I was wondering where I mind find a description of the community's current cumulative knowledge about its structure? (If such a thing exists). In particular I'm interested in knowing if anyone has bothered to map-out the battle module (figure out it subroutines, so that it can be hacked to do things like process new status ailments, or its handling of elemental weaknesses can be modified?)

Best,

QP

5
I've been trying to implement some new status ailments into a mod I'm working on via character AI. I was wondering if there is a script for "pre-attack" similar to the one enemies have in their own scripts? I saw a few people discussing a pre-attack script online (Particularly Yojimbo, who used it to make a cool poison disease status) but I don't see a pre-attack script in wal-market.

This is how I want to implement Vanish. I want to add general counter scripts that will respond to certain actions by setting a character's 41f0 value to 1. Then, in a pre-turn script that gives the character a 9/10 chance to have 255 physical evade, and add general counter scripts to remove the status by unflagging that index. The game doesn't seem to use the values at 41f0 and later for very much, so it should work if there is a pre-attack script.

Thanks,

QP

EDIT: It seems post-attack script is actually pre-attack script, based on my testing. Zombie, Disease, and Blink are now successfully implemented =D


6
Since the original version of this post, I've gotten much better at handling types using this assembly style programming language (Too used to text editors and loosely typed languages, so most of my hojo script worked fine after I fixed typing problems.)

There are a few outstanding things that annoy me. I was trying to implement a Swallow/Regurgitate mechanic for the Land worm enemy last night using the imprisoned status. I had it counter with an attack that causes imprison and deactivate the target masks script. Then I copied the target mask into self.4300 for later use (I also tried storing in it in a local variable.) Later on, after a counter in main had incremented to five, I instructed it to re-target self.4300 , remove imprison, and re-enable its script.

It just didn't work at all. Despite literally using the same code Carry Armor uses, the land worm constantly seemed to get confused and end up targeting the wrong enemy with regurgitate, as though the script wasn't able to modify the value at self.4300. I understand what a 0x value is, and I've been operating under the assumption that 1x value is an address that stores a 0x value -- but I read through the wiki and there was a mention of scope, so I'm wondering if that may have been my issue.

Can some explain in detail the "scope" of address types 10, 11, 12, and 13? Which ones can be modified during what parts of a script?

Best,

QP

7
Hi all, I'm working on a rewrite of the AI for FFVII and right now I'm working on the first encounter with Reno. I added a main script to the pyramid to make the fight more interesting, here it is:

local var 0100 = 0 (in header script)
0x000   If ( (LocalVar:0100 <= 3) )
0x000   {
0x00F   Display String: "The pyramid is getting harder!"
0x02F   LocalVar:0100 <- LocalVar:0100 + 1
0x039   If ( (LocalVar:0100 == 4) )
0x039   {
0x042   Self.Flag:PhysicalImmune <- 1
0x04C   Self.Flag:MagicalImmune <- 1
0x056   LocalVar:0100 <- 5
0x05C      SCRIPT END

Now the issue is that this script loops forever, but I'd like it only to be active whenever the pyramid is "active." So I tried everything I could think of, and nothing worked. This included:

1: Using the self.enabled mask as a condition (so I nested the entirety of the above loop in a "only do this when self.flag.enabled == 1 condition) which apparently caused the game to hang (so that's out)
2: Using self.death as a condition (even after modifying the pyramid's death counter script to work with it) which just didn't work as apparently the pyramid won't die.

Is there a good known trick for just outright disabling the main loop given in one of the counterscripts or something?

Thanks a ton,

Best,

QP

EDIT: So, I still haven't figured out why the above two approaches don't work (Like why using the enabled conditions causes the game to hang) but I did find a solution. Though it isn't listed on the wiki, http://wiki.qhimm.com/view/FF7/Battle/Battle_Scenes/Battle_AI_Addresses here, 4024 appears to be a flag for whether or not the main script is active, so self.4024 ==0 fixed the problem =)

8
Gameplay Modding / Help with Bizarro Sephiroth's AI
« on: 2014-11-17 02:42:01 »
Hello qhimmers, I've been going through the AI scripts trying to fix some AI bugs. I recently started working on Bizarro's AI and it's been a real doozy. I managed to fix the issue with the Bizarro Sephiroth AI in scene 229 so that he uses the correct attack loop by deleting a bad assignment at 0x097. Right now I'm trying to edit the AI for the encounter in 232, but I can't actually find the bug. Apparently in this scene there should be a bug where Sephiroth is casting Stigma when he's supposed to use Heartless Angel. Obviously I could switch the attacks but that'd be a cop out -- so I'm trying to find the logical error. I expected it to be pretty simple but unless I'm misunderstanding something the code looks *completely* fine to me. Starting with the masks at 0x42E all of the conditions which are being checked seem to be the correct conditions.

Can anyone find the logic error here causing the wrong attack to be triggered?

Thanks in advance.

Pages: [1]