Jump to content

Improved Invisibilities


Recommended Posts

Improved Invisibility has issues. All of the various flavors save Mass Invisibility are missing their +4 save bonuses, and they're not supposed to stack with one another. This patch corrects these issues. The branching down in the new effect addition section gets complex because the spell immunities need to be ordered such that the spell's self-immunity is last.

 

// improved invisibility is missing +4 save bonuses and should not be able to stack with itself
COPY_EXISTING ~spdr401.spl~ ~override~ // improved invis (stalker)
             ~spin544.spl~ ~override~ // improved invis (innate)
             ~spin698.spl~ ~override~ // improved invis (innate)
             ~spwi405.spl~ ~override~ // improved invis (mage)
             ~spwi505.spl~ ~override~ // shadow door (mage) (does not receive bonuses)
             ~spwi721.spl~ ~override~ // mass invisibility (does not receive bonuses)
 PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN // protects against invalid files
   READ_LONG  0x64 "abil_off"
   READ_SHORT 0x68 "abil_num"
   READ_LONG  0x6a "fx_off"
   SET "loops" = 0
   SET "delta" = 0
   PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi505" = 0) BEGIN
     SET "basedur" = 54
   END ELSE
   PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi721" = 0) BEGIN
     SET "basedur" = 84
   END ELSE BEGIN
     SET "basedur" = 60
   END
   WHILE ("%loops%" < "%abil_num%") BEGIN
     READ_SHORT ("%abil_off%" + 0x1e + (0x28 * "%loops%")) "abil_fx_num"
     READ_SHORT ("%abil_off%" + 0x20 + (0x28 * "%loops%")) "abil_fx_idx"
     SET "abil_fx_idx" = ("%abil_fx_idx%" + "%delta%")
     WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%loops%")) "%abil_fx_idx%"
     SET "new_fx"  = 11
     WHILE ("%new_fx%" > 0) BEGIN
       SET "new_fx"  = ("%new_fx%" - 1)
       INSERT_BYTES  ("%fx_off%" +        (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 0x30
       PATCH_IF ("%new_fx%" > 4) BEGIN
         WRITE_SHORT ("%fx_off%" +        (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 206 // spell immunity
         PATCH_IF ("%new_fx%" = 10) BEGIN
           WRITE_EVALUATED_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~%SOURCE_RES%~ // last immunity is always self
         END ELSE
         PATCH_IF ("%new_fx%" = 9) BEGIN
           PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spin544" = 0) BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spdr401~ // last immunity is always self
           END ELSE BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spin544~ // last immunity is always self
           END
         END ELSE
         PATCH_IF ("%new_fx%" = 8) BEGIN
           PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spin698" = 0) BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spdr401~ // last immunity is always self
           END ELSE BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spin698~ // last immunity is always self
           END
         END ELSE
         PATCH_IF ("%new_fx%" = 7) BEGIN
           PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi505" = 0) BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spdr401~ // last immunity is always self
           END ELSE BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spwi505~ // last immunity is always self
           END
         END ELSE
         PATCH_IF ("%new_fx%" = 6) BEGIN
           PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi405" = 0) BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spdr401~ // last immunity is always self
           END ELSE BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spwi405~ // last immunity is always self
           END
         END ELSE BEGIN
           PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi721" = 0) BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spdr401~ // last immunity is always self
             SET "delta1" = 6
             SET "new_fx" = 0 // kills loop so save bonuses not added
           END ELSE BEGIN
             WRITE_ASCII  ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ~spwi721~ // last immunity is always self
             SET "delta1" = 11
             PATCH_IF ("%SOURCE_RES%" STRING_COMPARE_CASE "spwi721" = 0) BEGIN
               SET "delta1" = 6
               SET "new_fx" = 0 // kills loop so save bonuses not added
             END
           END
         END
       END ELSE BEGIN
         WRITE_SHORT ("%fx_off%" +        (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) (33 + "%new_fx%") // save vs x
         WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 4 // save bonus
       END
         WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 2 // preset target
         WRITE_BYTE  ("%fx_off%" + 0x03 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 4 // power
         WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 3 // dispel/bypass
         WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) ("%basedur%" + ("%loops%" * 6))   // duration
         WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * ("%abil_fx_num%" + "%abil_fx_idx%"))) 100 // probability
     END
     SET "delta" = ("%delta%" + "%delta1%")
     WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%loops%")) ("%abil_fx_num%" + "%delta1%")
     SET "loops" = ("%loops%" + 1)
   END
 END
 BUT_ONLY_IF_IT_CHANGES

 

@devSin--I noticed you did not add Protection from Spell opcodes foe SPIN544 and SPIN698; what am I missing?

Link to comment

I try to cut SPINs a little slack. I have no idea when/where or even if they're used; I don't want to run the risk of breaking something or changing the behavior, so I concentrate on only covering the cases where the player could possibly be affected. Which means protecting in all spells against the PC versions, and then just preventing the PC versions themselves from being cumulative.

 

That, and after writing the 200 lines my patch for this occupies, I really didn't give a shit about them (still don't). But the first reason sounds better.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...