As some of you may know, I've never been happy with the poison status in vanilla FFVII. 1/32 Max HP damage per turn just doesn't cut it in the endgame, when many monsters can be KOed in one or two hits anyway.
The usual solution is to add the 'dual drain' status to all poison-inflicting attacks and spells. This makes poison much more dangerous. But it has three main disadvantages:
1. Modifying *every* enemy and player attack is
very time-consuming. And if you want to switch back, you have to be
very thorough.
2. Just adding the status to poison attacks isn't enough - you now have to modify enemy status immunities (many creatures are vulnerable to the one status but not another). Again, this takes a lot of time.
3. You can't inflict your dual-drain status via added effect, because you can't give materia a dual-drain status affinity. Boo!
But do not despair! There is another way - to create an AI script that automatically gives poisoned creatures the dual-drain status, and removes it when they're cured. Here's the AI script:
12 0000
02 20E0
90
12 0020
61 0001
90
12 0040
02 0000
02 0020
35
90
02 0040
70 002E
12 0040
10 401B
80
02 0040
00 4003
80
90
02 0020
61 8000
45
70 0045
12 0020
02 0020
60 02
32
90
72 000E
73
The idea is to put this into Vincent's preTurn-counter and general-counter scripts, then link other characters to Vincent's scripts with the preBattle code
60 07
75
73
Now, poisoned characters and creatures will immediately take the Seizure status. The only potential bug is if a character has a counter ability, in which case, the seizure status will be delayed until another battle actor takes an action.
What if I want a disease status, rather than seizure / dual-drain?Oh, that's simple. Use the code
12 0000
02 20E0
90
12 0020
61 0001
90
12 0040
02 0000
02 0020
35
90
02 0040
70 002E
12 0040
10 42A9
80
02 0040
00 4003
80
90
02 0020
61 8000
45
70 0045
12 0020
02 0020
60 02
32
90
72 000E
73
That should work just fine.
And if I want to link any statuses?Then replace the values in the following:
12 0000
02 20E0
90
12 0020
61 0001
90
12 0040
02 0000
02 0020
35
90
02 0040
70 002E
12 0040
10 ADDRESS OF STATUS TO ADD (E.G. DUAL-DRAIN)
80
02 0040
00 ADDRESS OF STATUS THAT TRIGGERS IT (E.G. POISON)
80
90
02 0020
61 8000
45
70 0045
12 0020
02 0020
60 02
32
90
72 000E
73
So if you wanted to give Flag:PhysicalImmune to anyone with Flag:Defending (so Defend blocks *all* non-magic damage), you'd substitute the values 4028 and 4025 respectively, etc. etc.
How is this script any different to older ones?This isn't the first time this has been attempted (see
http://forums.qhimm.com/index.php?topic=11861.25). The problem with those attempts is that they attempted to directly set allActors.dualDrain = allActors.poison by simply copying a word of one status mask to another, which the battle engine doesn't support. The result was typically a buggy script where all creatures would suffer dualDrain if *any* were poisoned. Not good. Instead, this script directly iterates through all battle actors and sets statuses individually.
How does it do that?The idea is simple. We put the AllUnitsMask in a local variable, then we perform a bitwise AND on it with an iterator that's logically shifted to the left with every loop (by multiplying by two). That means that every loop, we get a unitmask that points to each actor in the battle. If the mask isn't empty, we copy the unit's poison status to its dual-drain status. We don't do that for units that don't exist, because that might invoke glitches (probably not, but better safe than sorry).
Here's an annotated AI script:
12 0000
02 20E0
90 Put a mask of all actors in LocalVar 0000
12 0020
61 0001
90 Start our iterator (LocalVar 0020) at 1
12 0040
02 0000
02 0020
35 Bitwise operation to cycle through bits in the LocalVar 0000, one at a time
90
02 0040
70 002E If there's an active bit in the current position...
12 0040
10 401B
80 Get the address of currentActor.dualDrain...
02 0040
00 4003
80 And currentActor.poison...
90 ... and finally make currentActor.dualDrain = currentActor.poison
02 0020
61 8000
45
70 0045 If the iterator is at 0x8000 (which means one 1 and fifteen 0s), exit
12 0020
02 0020
60 02
32
90 If not, double the iterator (which effectively applies a left shift) and go again
72 000E Loops
73 End of script!
I've encountered a problem! Help!...then post your issue here and I'll update the script if I can fix it.
Other than that, enjoy!