Qhimm.com Forums

Final Fantasy Forums => Scripting and Reverse Engineering => Topic started by: quantumpencil on 2018-12-02 19:12:48

Title: Do FFVII actors have half/weak masks accessible via AI script?
Post by: quantumpencil on 2018-12-02 19:12:48
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

Title: Re: Do FFVII actors have half/weak masks accessible via AI script?
Post by: NFITC1 on 2018-12-03 13:22:35
Off the bat I can say have a look at how Diamond Weapon handles it. It selectively turns on and off its magic/physical immunities for limits.
Title: Re: Do FFVII actors have half/weak masks accessible via AI script?
Post by: quantumpencil on 2018-12-03 13:37:04
Yep, it sets its physical immune flag based on the performed actions action index (turns it off for 3, which is limit) which tells me that global variables like 2120, 2050, etc are set prior to pre-turn scripts.

My issue is that in order to half/double (or otherwise scale) damage taken based on the element of the previous action, I actually need to double or half the attackers level instead of the targets, diamond mutates his own flags.

So I need some way to get the index of the actor who used the attack during pre-turn which is being executed, if that was the case I could just do:

Pre-Turn
If self.soaked_bit_on{
    If 2120 bitAnd 8192 { ## was bolt attack  check
         If not already halved (will store this var in my global clock actor so its the same for all actors, and keep multiple actors from messing with it){
               temp = self.previous_attacker.level
               self.previous_attacker.level = temp/2           
         }     
    }
}

I can then unset the already_halved far and re-assign the attackers correct level in the counter script to achieve the desired effect.


EDIT: Actually, that will cause damage to be doubled for all targets if even one target is soaked, in the event that an attack hits more than one target =(

Is there a pointer table in the exe to the various formulas with actor/target stats in specific registers/fixed addresses for the jump, so that one could find an empty block and create a wrapper around base damage calculation which still performed the calculation according to the pointer, but did something like...

If target level = 255, bit-shift right the base_damage
if target level = 254, bit-shift left the base_damage.


EDIT: I've disassembled the exe, and with help from NFTC1, found the relevant routine. I have successful redirected the function in the exe to a (non functioning) custom function at run-time, so The damage formulas reference a context pointer for most stats/checks, so they have more or less global access to battle state making this much easier. I'm now confident I can implement this as described above with a bit more work tracing the formula calls to make sure my custom functions are referencing the arguments correctly.