øAslickproductions.org/forum/index.php?PHPSESSID=q4c29v6tmbbnv0gvgpv2lv9nn7&topic=1891.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index04c0.htmlslickproductions.org/forum/index.php?board=13.160e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index04c0.html.zx“@g^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÀ™dA,OKtext/htmlISO-8859-1gzip8:ÖA,ÿÿÿÿÿÿÿÿTue, 10 Mar 2020 07:40:26 GMT0ó°° ®0®P®€§²ð®’@g^ÿÿÿÿÿÿÿÿéRA, Immune and 99% Evade, Glitch or Design? - Documentation Within

Author Topic: Immune and 99% Evade, Glitch or Design? - Documentation Within  (Read 4673 times)

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Immune and 99% Evade, Glitch or Design? - Documentation Within
« on: October 09, 2013, 12:01:40 AM »
This has always boggled my mind when I first heard about it. What was the expected design of the Immune bit? Was it really supposed to give a character 99% Physical Evade or was it just a code mess that only occurred by chance and a mistaken byte exchange.

Well now, I think I have the answer to that...

$03/9A00   A0 29 00   LDY #$0029   A:0023   X:0003   Y:0023   P:envMxdIZC - Load 29 into A.
$03/9A03   18    CLC   A:0023   X:0003   Y:0029   P:envMxdIzC - Clear Carry Flag.
$03/9A04   A5 AA   LDA $AA    [$00:00AA]   A:0023   X:0003   Y:0029   P:envMxdIzc - Load the Value in AA into A.
$03/9A06   6D 6C 39   ADC $396C  [$7E:396C]   A:0094   X:0003   Y:0029   P:eNvMxdIzc - Add the value from 7E369C into A.
$03/9A09   20 2A 9E   JSR $9E2A  [$03:9E2A]   A:0094   X:0003   Y:0029   P:eNvMxdIzc - Jump to Subroutine.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9E2A   C9 63   CMP #$63   A:0094   X:0003   Y:0029   P:eNvMxdIzc - Is it 63?
$03/9E2C   90 02   BCC $02    [$9E30]   A:0094   X:0003   Y:0029   P:envMxdIzC - If less than 63, branch to 9E30.
$03/9E2E   A9 63   LDA #$63   A:0094   X:0003   Y:0029   P:envMxdIzC - Load 63 into A.
$03/9E30   60    RTS   A:0063   X:0003   Y:0029   P:envMxdIzC - Return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9A0C   91 80   STA ($80),y[$7E:2129]   A:0063   X:0003   Y:0029   P:envMxdIzC - Store A in Evasion.


AA - Is the temporary storing place of Character's evasion. For some reason when an Immune bit item is put on it, it jumps to
94.

When we dig a little deeper...

$03/9987   B5 AD   LDA $AD,x  [$00:00AD]   A:0000   X:0000   Y:0029   P:envMxdIZC - Load AD (+x) into A.
(AD Becomes 80 through the Immune Bit)
$03/9989   30 06   BMI $06    [$9991]   A:0080   X:0000   Y:0029   P:eNvMxdIzC -If it is 80 or above branch to 039991.
----------------------

------------------
$03/9991   05 AA   ORA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Add it to AA
$03/9993   85 AA   STA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Store it in AA.


So now the question becomes... how did AD acquire that 80?

Well we have to go back to the beginning of this process which begins at 039965 it appears...

?Armor Equipping Routine?

Code: [Select]
$03/9965 7B TDC A:0000 X:0005 Y:0030 P:envMxdIZC - Transfer Direct Page
$03/9966 AA TAX A:0000 X:0005 Y:0030 P:envMxdIZC - Transfer A to X.
$03/9967 86 A9 STX $A9    [$00:00A9] A:0000 X:0000 Y:0030 P:envMxdIZC - Store A in A9.
$03/9969 A0 08 00 LDY #$0008 A:0000 X:0000 Y:0030 P:envMxdIZC - Load 0008 into Y
-----------------------------------------------------------(Looping Point)---------------------------------------------------------
$03/996C B1 82 LDA ($82),y[$7E:27F6] A:0000 X:0000 Y:0008 P:envMxdIzC - Load Value from 7E27F6 into A.
$03/996E 95 AD STA $AD,x  [$00:00AD] A:0080 X:0000 Y:0008 P:eNvMxdIzC - Store A in AD.
$03/9970 98 TYA A:0080 X:0000 Y:0008 P:eNvMxdIzC - Transfer Y to A
$03/9971 18 CLC A:0008 X:0000 Y:0008 P:envMxdIzC - Clear Carry Flag.
$03/9972 69 0B ADC #$0B A:0008 X:0000 Y:0008 P:envMxdIzc - Add 0B to A.
$03/9974 A8 TAY A:0013 X:0000 Y:0008 P:envMxdIzc - Transfer A to Y.
$03/9975 E8 INX A:0013 X:0000 Y:0013 P:envMxdIzc - +1 to X.
$03/9976 E0 03 00 CPX #$0003 A:0013 X:0001 Y:0013 P:envMxdIzc - Has it cycled three times?
$03/9979 D0 F1 BNE $F1    [$996C] A:0013 X:0001 Y:0013 P:eNvMxdIzc - Then loop back to 03996C
---------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------
$03/997B AD 6D 39 LDA $396D  [$7E:396D] A:0029 X:0003 Y:0029 P:envMxdIZC - Load 7E396D into A.
$03/997E 85 B0 STA $B0    [$00:00B0] A:0000 X:0003 Y:0029 P:envMxdIZC - Store A in B0.
$03/9980 AD 6E 39 LDA $396E  [$7E:396E] A:0000 X:0003 Y:0029 P:envMxdIZC - Load A from 7E396E.
$03/9983 85 B1 STA $B1    [$00:00B1] A:0000 X:0003 Y:0029 P:envMxdIZC - Store A in B1.
$03/9985 7B TDC A:0000 X:0003 Y:0029 P:envMxdIZC - Transfer Direct Page.
$03/9986 AA TAX A:0000 X:0003 Y:0029 P:envMxdIZC - Transfer A to X.
---------------------------------------------------------(Looping Point)----------------------------------------------------------------
$03/9987 B5 AD LDA $AD,x  [$00:00AD] A:0000 X:0000 Y:0029 P:envMxdIZC - Load A from AD +X.
$03/9989 30 06 BMI $06    [$9991] A:0080 X:0000 Y:0029 P:eNvMxdIzC  - If minus branch to 039991.
------------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------------------------
$03/9991 05 AA ORA $AA    [$00:00AA] A:0080 X:0000 Y:0029 P:eNvMxdIzC - Add 80 to AA
$03/9993 85 AA STA $AA    [$00:00AA] A:0080 X:0000 Y:0029 P:eNvMxdIzC - Store A in AA.
$03/9995 E8 INX A:0080 X:0000 Y:0029 P:eNvMxdIzC - +1 to X
$03/9996 E0 05 00 CPX #$0005 A:0080 X:0001 Y:0029 P:envMxdIzC - Is X 5?
$03/9999 D0 EC BNE $EC    [$9987] A:0080 X:0001 Y:0029 P:eNvMxdIzc - If not loop back to 039987.

7E27F6 is the key. Now this is a section of RAM that is woefully under-explored, but 27F6 must deal with the character slot. The Glass Helm in particular (and likely any immune bit) copies an 80 to there. What 7E2780 and beyond appears to be copies of the character equipment that the characters currently have equipped.

And the final verdict...

It's intended. As idiotic of a decision as it is, the programming doesn't lie, it Specifically looks for an item that is equipped (hence why it searches three times through the character's equipment, interestingly Shields are not included in this search and indeed when they have the Immune bit they are not effected by the 99% evade) for a negative value byte in Elemental Resistance to take it through a special piece of code that...

$03/9987   B5 AD   LDA $AD,x  [$00:00AD]   A:0000   X:0000   Y:0029   P:envMxdIZC - Load A from AD +X.
$03/9989   30 06   BMI $06    [$9991]   A:0080   X:0000   Y:0029   P:eNvMxdIzC  - If minus branch to 039991.
------------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------------------------
$03/9991   05 AA   ORA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Add A to AA
$03/9993   85 AA   STA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Store A in AA.
$03/9995   E8    INX   A:0080   X:0000   Y:0029   P:eNvMxdIzC - +1 to X
$03/9996   E0 05 00   CPX #$0005   A:0080   X:0001   Y:0029   P:envMxdIzC - Is X 5?
$03/9999   D0 EC   BNE $EC    [$9987]   A:0080   X:0001   Y:0029   P:eNvMxdIzc - If not loop back to 039987.

Looks for AA (Evasion) and places it in AA. The only thing I can possibly think of what it may have done was supposed to give the player 99% magic evasion, but that's just as equally dumb. Something here was supposed to give the player 99 of something. Whatever it was, it couldn't have been balanced, that's for certain.

To fix this you change...

$03/9987   B5 AD   LDA $AD,x  [$00:00AD]   A:0000   X:0000   Y:0029   P:envMxdIZC - Load A from AD +X.
$03/9989   30 06   BMI $06    [$9991]   A:0080   X:0000   Y:0029   P:eNvMxdIzC  - If minus branch to 039991.

To...

$03/9987   B5 AD   LDA $AD,x  [$00:00AD]   A:0000   X:0000   Y:0029   P:envMxdIZC - Load A from AD +X.
$03/9989   EA    NOP   A:0080   X:0000   Y:0029   P:eNvMxdIzC - NULL
$03/998A   EA    NOP   A:0080   X:0000   Y:0029   P:eNvMxdIzC - NULL

And that's all it takes. This does not cause any issues as far as I could make out and fixes the 99% problem in its entirety. A more clever hacker could utilize this in a more efficient fashion,  actually redirecting the 80 rather than downright avoiding it.

assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #1 on: October 09, 2013, 01:11:32 AM »
- What's at 03/998B thru 03/9990, for comparison?
- What is 7E/396C?
- How is $AA originally built up from your various pieces' of equipment Evade values?  Is there capping done then, and if so, is it done with 03/9A00?
« Last Edit: October 09, 2013, 02:53:45 AM by assassin »

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #2 on: October 09, 2013, 01:38:52 AM »
A fair point, I wasn't exactly thorough, lets find out...

$03/998B   05 A9   ORA $A9    [$00:00A9]   A:0000   X:0000   Y:0029   P:envMxdIZC - Add the value in A9 into A. (If applicable)
$03/998D   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0029   P:envMxdIZC - Store A9 into A.
$03/998F   80 04   BRA $04    [$9995]   A:0000   X:0000   Y:0029   P:envMxdIZC - Branch to 039995
----------------------

-------------------
$03/9995   E8    INX   A:0000   X:0000   Y:0029   P:envMxdIZC +1 to X
....


7E396D and E both seem to be blank outside of battle and during this routine, Inside of battle they still appear to be blank, so I can't say the only hint given is the Tower of Babil docs which says two bytes away is...

3965-396C Copy of Attacker's main stats (STR, AGI, ???, VIT, WIS, WILL, ???, ???)


It seems to only be read once, but it is read whenever you equip or dequip (or not even change) equipment. And at that time it looks as if the value had already loaded what will be the evasion likely from one of its main sources, before equipping this new item. Where that happens on its own I've had difficulty locating. There does not appear to be any capping done though, which I suppose means in theory that it could overflow, but I may just not have found a "CMP FF, BCC XX" because it would be inapplicable.

assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #3 on: October 09, 2013, 02:16:46 AM »
what's $A9?  is that ever added to anything?  when's it first read after this?

at first, i was thinking that they wanted to have "Immune" guarantee the maximum Evasion value of 99 (because they knew that setting $AA to 128+ would later get Evasion capped to 99).  now for this, they could've skipped the "ORA $AA", and still accomplished what they wanted.

and i figured the bottom 7 bits of $AD,X were just a normal integer.  however, the $A9 code is suggesting they aren't, because it's being treated like a bitfield as well..  except i don't anticipate it ensuring 99 of anything, because $A9 will be under 128.

at this point, i'd say the bottom 7 bits of $AD,X are a list of unknown properties, and the top bit is a switch to control what variable(s) these properties will be applied to.

however, the whole idea of adding a bitfield to an integer, which is what 03/9A00 does, seems wrong.  FF6 does mix and match the two a little (by having a 16-bit value where bits 0-7 are a character's normal HP or MP, then bits 8-9 are flags that select a certain percentage bonus to give to the stat), but FF6 actually has code to interpret this rather than just add things willy nilly.

this makes me think that the FF4 makers didn't want to use $AA in 03/9A00, but some other variable, though that's with the caveat that i know nothing whatsoever about this game. :P  i wonder if you'll find some "complementary" code, where they read some other variable and treat it like a bitfield to do certain things, except the variable was never set in the first place (or maybe it was set as an integer).  then two things would be resolved in a nice, tidy basket.  if only.

that's a bit of speculation.  anyway, i'm with you that something seems suspect here.
« Last Edit: October 09, 2013, 02:55:32 AM by assassin »

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #4 on: October 09, 2013, 10:40:50 AM »
what's $A9?  is that ever added to anything?  when's it first read after this?

at first, i was thinking that they wanted to have "Immune" guarantee the maximum Evasion value of 99 (because they knew that setting $AA to 128+ would later get Evasion capped to 99).  now for this, they could've skipped the "ORA $AA", and still accomplished what they wanted.

and i figured the bottom 7 bits of $AD,X were just a normal integer.  however, the $A9 code is suggesting they aren't, because it's being treated like a bitfield as well..  except i don't anticipate it ensuring 99 of anything, because $A9 will be under 128.

at this point, i'd say the bottom 7 bits of $AD,X are a list of unknown properties, and the top bit is a switch to control what variable(s) these properties will be applied to.

however, the whole idea of adding a bitfield to an integer, which is what 03/9A00 does, seems wrong.  FF6 does mix and match the two a little (by having a 16-bit value where bits 0-7 are a character's normal HP or MP, then bits 8-9 are flags that select a certain percentage bonus to give to the stat), but FF6 actually has code to interpret this rather than just add things willy nilly.

this makes me think that the FF4 makers didn't want to use $AA in 03/9A00, but some other variable, though that's with the caveat that i know nothing whatsoever about this game. :P  i wonder if you'll find some "complementary" code, where they read some other variable and treat it like a bitfield to do certain things, except the variable was never set in the first place (or maybe it was set as an integer).  then two things would be resolved in a nice, tidy basket.  if only.

that's a bit of speculation.  anyway, i'm with you that something seems suspect here.

A9 looks to, oddly be enough, Critical Hit Bonus and before that is A8 in Critical Hit Chance. Which are also stored in character data, so I could easily verify that. What a strange order...

A8 - Critical Hit Chance (A set value held by character to character. Equipping a weapon of any sort doubles the value and equipping a Bow and Arrow triples the value. Noticeably when you have two weapons equipped the game will reset the Critical Hit chance to default)

A9 - Critical Hit Bonus - (A set value held by character to character. Equipping a weapon will add half of the weapon's attack power to the possible highest damage of a Critical Hit.)

AA - ??

That is what it reads by default, but in this routine they may be different...

In the Routine A8 and A9 are set as 00's with only AA being used as a temporary Evasion store-point.

The other 7 bits of AD are Elemental Resistance, Fire, Ice, Bolt, Holy, Dark, Air, Absorb and the game carries them as normal until it reaches the Branch if Minus portion, once it sees that it isn't 80 it leaves that value behind. Though I do have to wonder why it is then saved to A9... instead of AA. Maybe it is an off-by-one error? It wouldn't be the first time that Square had this happen (In this very game!)

Now A9 in this routine's purpose ends here...

$03/999E   A5 A9   LDA $A9    [$00:00A9]   A:0001   X:0005   Y:0025   P:envMxdIzC
$03/99A0   91 80   STA ($80),y[$7E:2125]   A:0001   X:0005   Y:0025   P:envMxdIzC

25     elemental defense (if immunity bit wasn't set)***

Why it has to jump through loops to put the value into 7E2125, I'm not really sure. More interestingly is what happens to the value in AA...

$03/99A3   A5 AA   LDA $AA    [$00:00AA]   A:0001   X:0005   Y:0026   P:envMxdIzC
$03/99A5   91 80   STA ($80),y[$7E:2126]   A:0000   X:0005   Y:0026   P:envMxdIZC

26     elemental defense (if immunity bit was set)***

AA is not only a Temporary Evasion Store but is also where the Immunity Byte value is stored. I think I'm starting to see the picture here... maybe Square did screw up and a haphazard programmer used both AA as an Elemental Immune and Evade byte.

The real issue is that the Elemental Immunity byte is never zeroed out. as the other values in the routine appear to be before going onto their next function.

$03/99AC   64 A9   STZ $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC


This may be the issue. By default in the routine A9 seems to be Zero at this point anyhow. It is a possibility that this is supposed to be STZ AA, which would clear the problematic Immunity=Evade Byte.

I was not thorough enough before. Those bytes I said to null are necessary for applying Elemental Immunity. I think now the object is to find where these are fed into Evasion.

Hmm...

$03/99C2   A5 A9   LDA $A9    [$00:00A9]   A:0026   X:0003   Y:0027   P:envMxdIzC
$03/99C4   0D 74 39   ORA $3974  [$7E:3974]   A:0000   X:0003   Y:0027   P:envMxdIZC
$03/99C7   91 80   STA ($80),y[$7E:2127]   A:0000   X:0003   Y:0027   P:envMxdIZC

27 is defense vs. Creature Types, so little surprise that it wouldn't generate a value in plain equipment.

I really may just have to disassemble this section of data as it is quite sequential.

$03/99DC   AD 67 39   LDA $3967  [$7E:3967]   A:0000   X:0000   Y:0028   P:envMxdIZc
$03/99DF   20 85 84   JSR $8485  [$03:8485]   A:0007   X:0000   Y:0028   P:envMxdIzc
$03/8485   4A    LSR A   A:0007   X:0000   Y:0028   P:envMxdIzc
$03/8486   4A    LSR A   A:0003   X:0000   Y:0028   P:envMxdIzC
$03/8487   4A    LSR A   A:0001   X:0000   Y:0028   P:envMxdIzC
$03/8488   60    RTS   A:0000   X:0000   Y:0028   P:envMxdIZC
$03/99E2   18    CLC   A:0000   X:0000   Y:0028   P:envMxdIZC
$03/99E3   65 E3   ADC $E3    [$00:00E3]   A:0000   X:0000   Y:0028   P:envMxdIZc
$03/99E5   91 80   STA ($80),y[$7E:2128]   A:0000   X:0000   Y:0028   P:envMxdIZc

28 - Defense Multiplier

Now Evasion is calculated in this manner...

$03/9A00   A0 29 00   LDY #$0029   A:0023   X:0003   Y:0023   P:envMxdIZC
$03/9A03   18    CLC   A:0023   X:0003   Y:0029   P:envMxdIzC
$03/9A04   A5 AA   LDA $AA    [$00:00AA]   A:0023   X:0003   Y:0029   P:envMxdIzc
$03/9A06   6D 6C 39   ADC $396C  [$7E:396C]   A:00D1   X:0003   Y:0029   P:eNvMxdIzc
$03/9A09   20 2A 9E   JSR $9E2A  [$03:9E2A]   A:00D1   X:0003   Y:0029   P:eNvMxdIzc
$03/9E2A   C9 63   CMP #$63   A:00D1   X:0003   Y:0029   P:eNvMxdIzc
$03/9E2C   90 02   BCC $02    [$9E30]   A:00D1   X:0003   Y:0029   P:envMxdIzC
$03/9E2E   A9 63   LDA #$63   A:00D1   X:0003   Y:0029   P:envMxdIzC
$03/9E30   60    RTS   A:0063   X:0003   Y:0029   P:envMxdIzC

It is all to do with AA's dual purposes which causes this noticeable problem.


Read one byte of Equipment (Evasion), store it in AA, move on to the next piece of equipment. (Shields are not read here for some reason however)
The real issue may be is that the AA register is never "cleaned" so to speak after putting in the data where it Should (Elemental Immunity) it should then be zeroed and allowed to calculate Evasion on its own merit.

$03/99AC   64 A9   STZ $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99AE   B1 82   LDA ($82),y[$7E:27F3]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B0   05 A9   ORA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B2   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC

This set of bytes here seem unnecessarily exact.  Why would you set a value to Zero, load a new value in, check to see if the value is already there (which it plainly cannot be because you Just Zeroed It) and Store that value. Would it not be as easy to do this...?

$03/99AE   B1 82   LDA ($82),y[$7E:27F3]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B2   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC

Since the value will be overwritten anyhow. This may give use the space we need to fix the Immunity/Evasion byte without impacting anything else.

And finally, truly fixed!

Change this...

$03/99AC   64 A9   STZ $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99AE   B1 82   LDA ($82),y[$7E:27F3]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B0   05 A9   ORA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B2   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC

To this...

$03/99AC   64 A9   STZ $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99AE   B1 82   LDA ($82),y[$7E:27F3]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B0   64 AA   STZ $AA    [$00:00AA]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B2   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC

The reason the game continues to read evasion into it is because it is never properly reset like every other value I've seen thus far in the code (I wonder if this lack of 00 is part of the problem with the Immunities turning into weaknesses when the Immune equipment is removed...)

Now a new verdict...

An oversight, created likely by a hasty programmer that didn't double check their work, tying both Evasion and Elemental Immunity to one byte is fine in practice, but when you don't include the proper cleaning to old values they can cause issues like this.

 :edit: Hmm, it seems as if that set of bytes isn't so useless after all...

$03/99AC   64 A9   STZ $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
-----------------------------------------------------(Looping Point)------------------------------------------------
$03/99AE   B1 82   LDA ($82),y[$7E:27F3]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B0   05 A9   ORA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC
$03/99B2   85 A9   STA $A9    [$00:00A9]   A:0000   X:0000   Y:0005   P:envMxdIZC

Only for the start of this portion is the STZ A9 called to make the value 00, which it could be something else due to earlier variables. Then what these are doing are looking at each instance of armor, checking for Creature Resistance Bytes and adding them to A9 to eventually put into Byte 27 of character data. So I can't use that. I'm not really sure what I can replace to put an STZ AA anywhere.

$03/99EC   18    CLC   A:0000   X:0000   Y:0002   P:envMxdIZc
$03/99ED   B1 82   LDA ($82),y[$7E:27F0]   A:0000   X:0000   Y:0002   P:envMxdIZc
$03/99EF   29 7F   AND #$7F   A:0000   X:0000   Y:0002   P:envMxdIZc
$03/99F1   65 AA   ADC $AA    [$00:00AA]   A:0000   X:0000   Y:0002   P:envMxdIZc
$03/99F3   85 AA   STA $AA    [$00:00AA]   A:0081   X:0000   Y:0002   P:eNvMxdIzc
$03/99F5   98    TYA   A:0081   X:0000   Y:0002   P:eNvMxdIzc
$03/99F6   18    CLC   A:0002   X:0000   Y:0002   P:envMxdIzc
$03/99F7   69 0B   ADC #$0B   A:0002   X:0000   Y:0002   P:envMxdIzc
$03/99F9   A8    TAY   A:000D   X:0000   Y:0002   P:envMxdIzc
$03/99FA   E8    INX   A:000D   X:0000   Y:000D   P:envMxdIzc
$03/99FB   E0 03 00   CPX #$0003   A:000D   X:0001   Y:000D   P:envMxdIzc
$03/99FE   D0 EC   BNE $EC    [$99EC]   A:000D   X:0001   Y:000D   P:eNvMxdIzc

A smart programmer would have put an STZ AA here at the start as they did with other sections before the looping point. But the lack of room and available bytes makes it a bit of a risky game to do so. All it takes is an STZ AA before this point, but I'm not sure where it could go.
« Last Edit: October 09, 2013, 11:15:41 AM by Grimoire LD »

assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #5 on: October 09, 2013, 11:08:11 AM »
Quote
The other 7 bits of AD are Elemental Resistance, Fire, Ice, Bolt, Holy, Dark, Air, Absorb and the game carries them as normal until it reaches the Branch if Minus portion, once it sees that it isn't 80 it leaves that value behind. Though I do have to wonder why it is then saved to A9... instead of AA. Maybe it is an off-by-one error? It wouldn't be the first time that Square had this happen (In this very game!)

Now A9 in this routine's purpose ends here...

$03/999E   A5 A9   LDA $A9    [$00:00A9]   A:0001   X:0005   Y:0025   P:envMxdIzC
$03/99A0   91 80   STA ($80),y[$7E:2125]   A:0001   X:0005   Y:0025   P:envMxdIzC

25     elemental defense (if immunity bit wasn't set)***

Why it has to jump through loops to put the value into 7E2125, I'm not really sure. More interestingly is what happens to the value in AA...

$03/99A3   A5 AA   LDA $AA    [$00:00AA]   A:0001   X:0005   Y:0026   P:envMxdIzC
$03/99A5   91 80   STA ($80),y[$7E:2126]   A:0000   X:0005   Y:0026   P:envMxdIZC

26     elemental defense (if immunity bit was set)***

so $2125 is Elemental Resists (as in reduced damage), and $2126 is Elemental Nullifications (as in zero damage)?

Quote
Read one byte of Equipment (Evasion), store it in AA, move on to the next piece of equipment. (Shields are not read here for some reason however)

where is equipment Evasion being read?  i don't see code for that.  $AD,X was the elemental bits.

and what is $27F3?

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #6 on: October 09, 2013, 11:20:25 AM »
I edited my post above, I was off in my "fix" it won't work optimally, it will create a different kind of glitch where only the Armlet Armor would be considered in Creature Resistances because the value is continually overwritten by the new value because of the addition. it also includes the Evasion - acquiring code.

Indeed, Byte 25 and 26 are Elemental Resistance (Half Damage) and Elemental Immunity (One Damage)

7E27F3 is a slot dependent Armor. In this case it's looking for Creature Resistance Byte, which is what that portion of code loops three times to add into one solid number for multiple creature resistances.


 :edit: Final Fix (I think)

It seems the key to fixing this is changing this at its core. In otherwords instead of loading Elemental Immunity into AA load it into an unused byte like FE appears to be for this routine.

$03/9987   B5 AD   LDA $AD,x  [$00:00AD]   A:0000   X:0000   Y:0029   P:envMxdIZC - Load A from AD +X.
$03/9989   30 06   BMI $06    [$9991]   A:0080   X:0000   Y:0029   P:eNvMxdIzC  - If minus branch to 039991.
------------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------------------------
$03/9991   05 AA   ORA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Add 80 to AA
$03/9993   85 AA   STA $AA    [$00:00AA]   A:0080   X:0000   Y:0029   P:eNvMxdIzC - Store A in AA.
$03/9995   E8    INX   A:0080   X:0000   Y:0029   P:eNvMxdIzC - +1 to X
$03/9996   E0 05 00   CPX #$0005   A:0080   X:0001   Y:0029   P:envMxdIzC - Is X 5?
$03/9999   D0 EC   BNE $EC    [$9987]   A:0080   X:0001   Y:0029   P:eNvMxdIzc - If not loop back to 039987.

Change AA to FE and that should do it for this portion, next...

$03/99A3   A5 AA   LDA $AA    [$00:00AA]   A:0001   X:0005   Y:0026   P:envMxdIzC
$03/99A5   91 80   STA ($80),y[$7E:2126]   A:0000   X:0005   Y:0026   P:envMxdIZC

26     elemental defense (if immunity bit was set)***

Change it to FE and there and it should cause FE to be the new Elemental Immunity Storage.

This looks to be a legitimate fix and I have noticed no problems. Instead of trying to add to the code, it seems like it was just best to work around it.
« Last Edit: October 09, 2013, 11:43:15 AM by Grimoire LD »

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #7 on: October 09, 2013, 12:16:39 PM »
Since we're on the topic of Immunity problems, lets look at x4 Weakness is never removed, eh?

Code: [Select]
$03/9A78 A0 26 00 LDY #$0026 A:0000 X:0003 Y:0020 P:envMxdIzc - Load 0026 into Y
$03/9A7B B1 80 LDA ($80),y[$7E:21A6] A:0000 X:0003 Y:0026 P:envMxdIzc - Load A from Index +Y. (Elemental Immunity Byte)
$03/9A7D 85 A9 STA $A9    [$00:00A9] A:0081 X:0003 Y:0026 P:eNvMxdIzc  - Store A in A9.
$03/9A7F 20 A8 9D JSR $9DA8  [$03:9DA8] A:0081 X:0003 Y:0026 P:eNvMxdIzc - Jump to Subroutine 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
$03/9DA8 29 12 AND #$12 A:0081 X:0003 Y:0026 P:eNvMxdIzc Get rid of inapplicable bits.
$03/9DAA 4A LSR A A:0000 X:0003 Y:0026 P:envMxdIZc - /2 A.
$03/9DAB 85 AA STA $AA    [$00:00AA] A:0000 X:0003 Y:0026 P:envMxdIZc - Store A in AA
$03/9DAD A5 A9 LDA $A9    [$00:00A9] A:0000 X:0003 Y:0026 P:envMxdIZc - Load A9.
$03/9DAF 29 09 AND #$09 A:0081 X:0003 Y:0026 P:eNvMxdIzc - Get rid of inapplicable bits.
$03/9DB1 0A ASL A A:0001 X:0003 Y:0026 P:envMxdIzc - x2 A.
$03/9DB2 05 AA ORA $AA    [$00:00AA] A:0002 X:0003 Y:0026 P:envMxdIzc - Add to AA.
$03/9DB4 60 RTS A:0002 X:0003 Y:0026 P:envMxdIzc - Return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9A82 F0 07 BEQ $07    [$9A8B] A:0002 X:0003 Y:0026 P:envMxdIzc - Branch if 00 to 039A8B
----------------------------------------------------------------------------------------------------------------------------------------
$03/9A84 A0 21 00 LDY #$0021 A:0002 X:0003 Y:0026 P:envMxdIzc - Load 0021 into Y.
$03/9A87 09 80 ORA #$80 A:0002 X:0003 Y:0021 P:envMxdIzc - Add 80 to A (if applicable)
$03/9A89 91 80 STA ($80),y[$7E:21A1] A:0082 X:0003 Y:0021 P:eNvMxdIzc - Store A in 80.
--------------------------------------------------------------------------------------------------------------------
$03/9A8B A0 22 00 LDY #$0022 A:0082 X:0003 Y:0021 P:eNvMxdIzc - Move on from here...

Because of the way the game works it will never decrement any bits that come into the x4 Weakness Byte.


Disabling the Very Weakness is an easy matter. Even setting it to just Weakness is a simple process. Just change this...

$03/9A84   A0 21 00   LDY #$0021   A:0002   X:0003   Y:0026   P:envMxdIzc - Load 0021 into Y.

To this...

$03/9A84   A0 20 00   LDY #$0020   A:0002   X:0003   Y:0026   P:envMxdIzc - Load 0020 into Y.

This will make it so it puts it in the Weakness Byte. While it may not do x4 damage it is still considered a weakness and a check actually exists for this which will overwrite the value rather than continue to store them without any additional changes needed.


assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #8 on: October 09, 2013, 06:28:11 PM »
Quote from: Grimoire LD
This looks to be a legitimate fix and I have noticed no problems. Instead of trying to add to the code, it seems like it was just best to work around it.

good work.  this definitely seems to be the soundest fix for it.

out of curiosity, what is the top bit of $27F0?

------

Quote
Since we're on the topic of Immunity problems, lets look at x4 Weakness is never removed, eh?
...
Because of the way the game works it will never decrement any bits that come into the x4 Weakness Byte.

i'm not following you here.  are you saying "Very Weakness" should never be set, or that it's being set for too long?  does this have anything to do with Immunity?

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #9 on: October 09, 2013, 08:53:32 PM »
Ah, I should clarify that a bit, after finding this section of data I decided to take a closer look...

2780 - List of Equipment Starting from Helmet, Armor, Hand Armor, Weapon, Shield (Equipment Type, Defense, Evasion, Magic Defense, Magic Evade (?/2), Creature Resistance, Equip Index, Bonus Index, Elemental Resistance, Status Byte 1 Resist, Status Byte 2 Resist) 11 (Decimal) Bytes in Total for each piece of equipment. 55 (Decimal) Bytes per character slot then.

On Weapons...

A1 Weapon Bits, A2 Attack Power, A3 Accuracy, A4 Magic Spell, A5 ??, A6 Creature Weakness, A7 Equip Index, A8 Bonus Index, A9 Elemental Attack, AA Status Byte 1, AB Status Byte 2.

So that means that this was looking at the third character's Helmet, and specifically the Evasion byte of that, which makes sense, all things considered. So it doesn't really have any specific bits set. It's just a numerical value in this case.

Very Weakness is only set when one equips a piece of equipment that has a resistance AND they have the Immune bit. So say I have a Fire Shield and the Glass Mask, I would be immune to Ice, but Very Weak to Fire. Normally if I just have a Fire shield I would resist Ice and be weak to fire. I see what they were going for and it would be fine but...

When I remove the Fire Shield, I will no longer have that resistance to Ice, but I will still be Very Weak to Fire because the game never decrements that value properly like it does with ordinary Weakness bytes, hence why I suggested to just move it to the weakness byte. Immunity to one element should not come with such a high price as x4 Weakness, in my opinion in the first place and this prevents the potential problem of being unable to fix the value's issues because of the lack of space.
« Last Edit: October 09, 2013, 09:57:59 PM by Grimoire LD »

assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #10 on: October 09, 2013, 10:59:49 PM »
Quote
Immunity to one element should not come with such a high price as x4 Weakness, in my opinion in the first place and this prevents the potential problem of being unable to fix the value's issues because of the lack of space.

eh, now you're mixing and matching reinterpretation/rebalancing with actual bugfixing.  i bet you could make space for a fix.

a possible optimization is to move "LDY #$0021" before the $9DA8 call at 03/9A7F.  then we can do "INY" at 03/9A8B.  just 2 bytes, but it's a start.  you've found other inefficiencies elsewhere.

where's the code that undoes normal Weakness after an equip change?  does it work by specifically subtracting out the removed equipment's elements, or by zeroing the property, then rebuilding it based on the equipment that's still there?  (my guess is the latter.)

if the game calls 03/9A78 after an unequip, and $21A6 indeed holds the right current value, i'm not sure why $21A1 wouldn't in turn wind up with the right value.  so i'm not entirely following how the bug occurs code-wise, though your explanation makes sense logically.

also, when Immunity turns Weakness into Very Weakness, is the original element still marked in the Weakness variable as well, or does it get cleared from there?

Deathlike2

  • Moderator
  • *
  • Posts: 3,538
  • I'm looking at you, bitch!
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #11 on: October 09, 2013, 11:40:37 PM »
I've already written in my bugs list, but I'll just reiterate problems with the Immune bug.. some of which is covered here, others... not at all.

1) The Glass Mask and the Adamant Armor are most affected by this, as these pieces of equipment use that bit.

2) The Glass Mask in conjunction with ANY element resistant armor does NOTHING to take advantage of this behavior. Don't ask me why... it happens to be the case.

3) The Adamant Armor as designed is the only piece of equipment that uses the Immune Bit correctly. However, it fails to "clear out the bits", making you weak to all elementals... fire and ice makes you twice as vulnerable (Fire and Ice protection elemental bits magnify the damage, see Protect Ring vs Physical Elemental Attacks).

4) FF4 Advance (GBA port) removes the evasion behavior (possibly including the Wonderswan port) indicating the likely "intended" behavior of the max evasion aspect... which is not to have it at all.

5) I still think the 99% evasion was supposed to be for magic evasion, since it is not possible (at least with the game's own equipment and math) to reach 99% magic evasion. It is easier to each 99% evasion with Kain, Cecil, and Edge... with Rosa+Rydia abusing the Shield bug. Any damage that would have been dealt would have been minimal to a wearer of a Glass Mask (why would you need high evasion to do with the highest defensive helmet in the game?) Someone like Rydia would best benefit from a Glass Mask... being able to have the highest Magic Evasion multiplier is appropriate for a Wizard while having increased physical defense. Although the monster has a terrible defense, it is a wizard of both magics...

Anyways, carry on. The Glass Mask is still a terribly useless piece of equipment as currently constituted. I think it was meant to max out out magic evasion of any character in addition to its immunity property, which doesn't work because it doesn't attach to elemental equipment like the Protect Ring.

An "ultimate armor set" would have actually consisted of the Glass Mask, Adamant Armor, and Protect Ring (well, actually, the Crystal Ring is the best loot).
Working on the next Yet To Be Named FF4 "Hardtype" Hack Download Latest: v1.48

Video Demos: #1 #2 #3

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #12 on: October 09, 2013, 11:59:54 PM »
Indeed, I only thought that for the lack of a better alternative I could think of. I didn't put as much effort as I should have into the Bit unsetting as I should have and I should search to see how its calculated for the ordinary weakness byte to compare and possibly repair the x4 weakness byte.

Also I was completely misunderstanding how the Immune bit works (or doesn't work). The only item in the normal game this glitch affects is the Adamant Armor. As it is specifically that a Very Weak value is written only if the Immune bit has other elements attached with it. I'm not sure where I got the idea that Immune stacked with other Elements. Likely from the Likely intentioned portion of the Glass Helm (which is just the Immune bit, which does nothing at all on its own.

This is how Elemental Weakness is removed... (and also explains how it is added.)

Code: [Select]
$03/9A69 A0 25 00 LDY #$0025 A:0000 X:0003 Y:002C P:envMxdIZC - Load 0025 into Y
$03/9A6C B1 80 LDA ($80),y[$7E:20A5] A:0000 X:0003 Y:0025 P:envMxdIzC - Load A from Elemental Resistance.
$03/9A6E 85 A9 STA $A9    [$00:00A9] A:0002 X:0003 Y:0025 P:envMxdIzC - Store A in A9
$03/9A70 20 A8 9D JSR $9DA8  [$03:9DA8] A:0002 X:0003 Y:0025 P:envMxdIzC - Jump to Subroutine (Elemental Weakness Set)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
$03/9DA8 29 12 AND #$12 A:0002 X:0003 Y:0025 P:envMxdIzC - Get rid of bits that are multiple of 12.
$03/9DAA 4A LSR A A:0002 X:0003 Y:0025 P:envMxdIzC - / A by 2.
$03/9DAB 85 AA STA $AA    [$00:00AA] A:0001 X:0003 Y:0025 P:envMxdIzc - Store A in AA
$03/9DAD A5 A9 LDA $A9    [$00:00A9] A:0001 X:0003 Y:0025 P:envMxdIzc - Load A9 into A
$03/9DAF 29 09 AND #$09 A:0002 X:0003 Y:0025 P:envMxdIzc - Get rid of bits...?
$03/9DB1 0A ASL A A:0000 X:0003 Y:0025 P:envMxdIZc - / A by 2.
$03/9DB2 05 AA ORA $AA    [$00:00AA] A:0000 X:0003 Y:0025 P:envMxdIZc - Add this to AA if applicable.
$03/9DB4 60 RTS A:0001 X:0003 Y:0025 P:envMxdIzc - Return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9A73 A0 20 00 LDY #$0020 A:0001 X:0003 Y:0025 P:envMxdIzc - Load 20 into A.
$03/9A76 91 80 STA ($80),y[$7E:20A0] A:0001 X:0003 Y:0020 P:envMxdIzc Store A in 7E2080 +20. (Elemental Weakness Byte)

That is quite markedly different than...

Code: [Select]
$03/9A78 A0 26 00 LDY #$0026 A:0000 X:0003 Y:0020 P:envMxdIzc - Load 0026 into Y
$03/9A7B B1 80 LDA ($80),y[$7E:21A6] A:0000 X:0003 Y:0026 P:envMxdIzc - Load A from Index +Y. (Elemental Immunity Byte)
$03/9A7D 85 A9 STA $A9    [$00:00A9] A:0081 X:0003 Y:0026 P:eNvMxdIzc  - Store A in A9.
$03/9A7F 20 A8 9D JSR $9DA8  [$03:9DA8] A:0081 X:0003 Y:0026 P:eNvMxdIzc - Jump to Subroutine 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
$03/9DA8 29 12 AND #$12 A:0081 X:0003 Y:0026 P:eNvMxdIzc Get rid of inapplicable bits.
$03/9DAA 4A LSR A A:0000 X:0003 Y:0026 P:envMxdIZc - /2 A.
$03/9DAB 85 AA STA $AA    [$00:00AA] A:0000 X:0003 Y:0026 P:envMxdIZc - Store A in AA
$03/9DAD A5 A9 LDA $A9    [$00:00A9] A:0000 X:0003 Y:0026 P:envMxdIZc - Load A9.
$03/9DAF 29 09 AND #$09 A:0081 X:0003 Y:0026 P:eNvMxdIzc - Get rid of inapplicable bits.
$03/9DB1 0A ASL A A:0001 X:0003 Y:0026 P:envMxdIzc - x2 A.
$03/9DB2 05 AA ORA $AA    [$00:00AA] A:0002 X:0003 Y:0026 P:envMxdIzc - Add to AA.
$03/9DB4 60 RTS A:0002 X:0003 Y:0026 P:envMxdIzc - Return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9A82 F0 07 BEQ $07    [$9A8B] A:0002 X:0003 Y:0026 P:envMxdIzc - Branch if 00 to 039A8B
----------------------------------------------------------------------------------------------------------------------------------------
$03/9A84 A0 21 00 LDY #$0021 A:0002 X:0003 Y:0026 P:envMxdIzc - Load 0021 into Y.
$03/9A87 09 80 ORA #$80 A:0002 X:0003 Y:0021 P:envMxdIzc - Add 80 to A (if applicable)
$03/9A89 91 80 STA ($80),y[$7E:21A1] A:0082 X:0003 Y:0021 P:eNvMxdIzc - Store A in 80.
--------------------------------------------------------------------------------------------------------------------

Oh what a fool I've been! The answer was so simple!

$03/9A82   F0 07   BEQ $07    [$9A8B]   A:0002   X:0003   Y:0026   P:envMxdIzc - Branch if 00 to 039A8B 

Completely useless, it does nothing but Prevent the byte from being rewritten. It is the singular cause of the bug and nulling it does nothing adverse. Other armor types don't interfere with it as the specifications for where it is drawn is still the same Elemental Immunity Byte. So the easiest answer is...

$03/9A82   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc
$03/9A83   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc

That will keep the x4 weakness and while it will keep the "Very Weak to" 80 stores in Very Weak, an 80 on its own does nothing and is not necessary to worry about.

I can't believe I missed such a simple solution, oh well. That should do it, hehe.


As seen above it ordinarily just takes the removed equipment's elemental weakness in the same way it puts it on. Loads its specific byte and adds or removes the appropriate byte.

Yes, I thought that the first time DeathLike2, but I found the cause of why it was writing 99 evasion into... well evasion. It was an uncleared value (80 of the Immunity bit, that gets added to Evasion, and finally is truncated down 63.) because Square didn't clean the value that contained it by the time it reached evasion. I fixed this by switching what byte stores the immunity byte for depositing later. Thereby leaving the appropriate byte clean for use by the time it reaches evasion.

assassin

  • Bane of Retards
  • *
  • Posts: 1,033
  • space bears are not gentle!
    • View Profile
    • My Barren Webpage
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #13 on: October 10, 2013, 12:37:20 AM »
Quote
Oh what a fool I've been! The answer was so simple!

$03/9A82   F0 07   BEQ $07    [$9A8B]   A:0002   X:0003   Y:0026   P:envMxdIzc - Branch if 00 to 039A8B

Completely useless, it does nothing but Prevent the byte from being rewritten. It is the singular cause of the bug and nulling it does nothing adverse. Other armor types don't interfere with it as the specifications for where it is drawn is still the same Elemental Immunity Byte. So the easiest answer is...

$03/9A82   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc
$03/9A83   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc

That will keep the x4 weakness and while it will keep the "Very Weak to" 80 stores in Very Weak, an 80 on its own does nothing and is not necessary to worry about.

very nice.  can $21A1 normally have any of the bottom bits set if the top bit is clear?  if so, what happens?

as for Glass Helm/Mask, retooling it would definitely involve changing the order of things.  and if it were to make you Very Weak to the "opposite" of anything you Resisted, would it also have the decency to bump up all such Resists to Immunities?  doing one without the other seems a bit asymmetrical.  it'd be like having dirty bathwater without actually having a baby, or however that expression goes.

-----

EDIT:

Quote
As it is specifically that a Very Weak value is written only if the Immune bit has other elements attached with it. I'm not sure where I got the idea that Immune stacked with other Elements.

so to be sure, Immunity will give Very Weak for "opposites" of Immune elements, but it won't do anything to transform Weak elements into Very Weak?  or can gear with Immune transform Fire Shield's Fire weakness into severe Fire weakness, as written earlier?

iow, is $21A1 (as shown in your earlier post) the Very Weak elements, or is it a preliminary value that generates Very Weak after combining with normal Weak?
« Last Edit: October 10, 2013, 09:02:42 AM by assassin »

Grimoire LD

  • FF4 Hacker
  • *
  • Posts: 1,684
    • View Profile
Re: Immune and 99% Evade, Glitch or Design? - Documentation Within
« Reply #14 on: October 10, 2013, 09:45:31 AM »
Quote
Oh what a fool I've been! The answer was so simple!

$03/9A82   F0 07   BEQ $07    [$9A8B]   A:0002   X:0003   Y:0026   P:envMxdIzc - Branch if 00 to 039A8B

Completely useless, it does nothing but Prevent the byte from being rewritten. It is the singular cause of the bug and nulling it does nothing adverse. Other armor types don't interfere with it as the specifications for where it is drawn is still the same Elemental Immunity Byte. So the easiest answer is...

$03/9A82   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc
$03/9A83   EA    NOP   A:0010   X:0003   Y:0026   P:envMxdIzc

That will keep the x4 weakness and while it will keep the "Very Weak to" 80 stores in Very Weak, an 80 on its own does nothing and is not necessary to worry about.

Quote
very nice.  can $21A1 normally have any of the bottom bits set if the top bit is clear?  if so, what happens?

as for Glass Helm/Mask, retooling it would definitely involve changing the order of things.  and if it were to make you Very Weak to anything you Resisted, would it also have the decency to bump up all such Resists to Immunities?  doing one without the other seems a bit asymmetrical.  it'd be like having dirty bathwater without actually having a baby, or however that expression goes.

Yep, it works perfectly. The reason it works this way is because every armor will be going through the "Does the Armor cause Very Weak?" instead of only Armor that have 00 in that regards, so an 80 will be put regardless because it... hmm... well this is interesting. I just tested it and it does nothing. That 80 is completely superfluous on characters. The x4 Weakness just comes by virtue of being in that byte rather than the one next to it, nothing to do with the 80 value, so we can freely erase that +80 part. Since it does nothing.

-----

EDIT:

Quote
As it is specifically that a Very Weak value is written only if the Immune bit has other elements attached with it. I'm not sure where I got the idea that Immune stacked with other Elements.

Quote
so to be sure, Immunity will give Very Weak for "opposites" of Immune elements, but it won't do anything to transform Weak elements into Very Weak?  or can gear with Immune transform Fire Shield's Ice weakness into severe Ice weakness, as written earlier?

iow, is $21A1 (as shown in your earlier post) the Very Weak elements, or is it a preliminary value that generates Very Weak after combining with normal Weak?

I was wrong, I'm not really sure why I thought that was the case, likely because it is the way Absorb works. My above example would have worked if I said Cursed Ring instead of Glass Mask, that is what I was thinking about, Equipment with an Absorb Element partners with initial Elemental Values (because they share the same byte) the reason Immune doesn't partner with initial values is because the two bytes are never read with one another.

To make it clear...

1 - Fire
2 - Ice
4 - Bolt
8 - Dark
10 - Holy
20 - Air
40 - Absorb
80 - Immune.

Immune is never written into the normal elemental resistance byte because it is an 80 and a BMI somewhere says it is placed in the Elemental Immunity Byte, not that the Immunity Bit does anything outside of being stored in its own byte. Weakness and Very Weak are kept separate with Very Weak taking precedence where applicable. The Immunity Byte draws its own set of values in Character Byte 21 and so it ignores already laid out weaknesses.

This is where the issue comes in. How do you get one to recognize the other without throwing off the other? The routine says this...

$03/9A78   A0 26 00   LDY #$0026   A:0000   X:0003   Y:0020   P:envMxdIzc - Load 0026 into Y
$03/9A7B   B1 80   LDA ($80),y[$7E:21A6]   A:0000   X:0003   Y:0026   P:envMxdIzc - Load A from Index +Y. (Elemental Immunity Byte)
$03/9A7D   85 A9   STA $A9    [$00:00A9]   A:0081   X:0003   Y:0026   P:eNvMxdIzc  - Store A in A9.
$03/9A7F   20 A8 9D   JSR $9DA8  [$03:9DA8]   A:0081   X:0003   Y:0026   P:eNvMxdIzc - Jump to Subroutine 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
$03/9DA8   29 12   AND #$12   A:0081   X:0003   Y:0026   P:eNvMxdIzc Get rid of inapplicable bits.
$03/9DAA   4A    LSR A   A:0000   X:0003   Y:0026   P:envMxdIZc - /2 A.
$03/9DAB   85 AA   STA $AA    [$00:00AA]   A:0000   X:0003   Y:0026   P:envMxdIZc - Store A in AA
$03/9DAD   A5 A9   LDA $A9    [$00:00A9]   A:0000   X:0003   Y:0026   P:envMxdIZc - Load A9.
$03/9DAF   29 09   AND #$09   A:0081   X:0003   Y:0026   P:eNvMxdIzc - Get rid of inapplicable bits.
$03/9DB1   0A    ASL A   A:0001   X:0003   Y:0026   P:envMxdIzc - x2 A.
$03/9DB2   05 AA   ORA $AA    [$00:00AA]   A:0002   X:0003   Y:0026   P:envMxdIzc - Add to AA.
$03/9DB4   60    RTS   A:0002   X:0003   Y:0026   P:envMxdIzc - Return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$03/9A82   F0 07   BEQ $07    [$9A8B]   A:0002   X:0003   Y:0026   P:envMxdIzc - Branch if 00 to 039A8B
----------------------------------------------------------------------------------------------------------------------------------------
$03/9A84   A0 21 00   LDY #$0021   A:0002   X:0003   Y:0026   P:envMxdIzc - Load 0021 into Y.
$03/9A87   09 80   ORA #$80   A:0002   X:0003   Y:0021   P:envMxdIzc - Add 80 to A (if applicable)
$03/9A89   91 80   STA ($80),y[$7E:21A1]   A:0082   X:0003   Y:0021   P:eNvMxdIzc - Store A in 80.
--------------------------------------------------------------------------------------------------------------------

Would switching it from 26 to 25 do the trick? Or wouldn't that create an effect that whenever any element goes through there it would create a x4 Weakness? I'm a little flummoxed on how to proceed from there.