Jump to content

Staff of the Magi


Recommended Posts

LOTS of fixes for the SotM. Dispel on hit really wasn't working, many of the equipped effects could be dispelled, and it wasn't providing protection from evil. I've included a few more fixes from devSin here as well.

 

Rather than including all of the effects from spell trap, the staff now calls a special version of the spell which we clone from the original and change the duration. Both patches are below.

 

// SotM needs a lot of rebuilding--dispel effects don't work in melee, several effects are
// mistargeted or dispellable, etc.
COPY_EXISTING ~staf11.itm~ ~override~
 READ_LONG  0x64 "abil_off"
 READ_SHORT 0x68 "abil_num"
 READ_LONG  0x6a "fx_off"
 READ_SHORT 0x70 "fx_num"
 SET "loops" = "%fx_num%"
 WHILE ("%loops%" > 0) BEGIN
   SET "loops" = ("%loops%" - 1)
   READ_SHORT ("%fx_off%" +        ("%loops%" * 0x30)) "type"
   READ_LONG  ("%fx_off%" + 0x08 + ("%loops%" * 0x30)) "icon"
   PATCH_IF ("%type%" = 101) BEGIN // immunity to charm
     WRITE_BYTE ("%fx_off%" + 0x0d + ("%loops%" * 0x30)) 0 // no dispel/bypass resistance
   END
   PATCH_IF (("%type%" = 139) OR ("%type%" = 141)) BEGIN // lighting effects, display string
     WRITE_BYTE ("%fx_off%" + 0x02 + ("%loops%" * 0x30)) 1 // target: self
     WRITE_BYTE ("%fx_off%" + 0x0d + ("%loops%" * 0x30)) 0 // no dispel/bypass resistance
   END
   PATCH_IF (("%type%" = 142) OR ("%icon%" = 28)) BEGIN // display protection from magic icon
     WRITE_LONG  ("%fx_off%" + 0x08 + ("%loops%" * 0x30)) 52 // mind shield
   END
 END
 INSERT_BYTES  ("%fx_off%"       ) 0x30
   WRITE_SHORT ("%fx_off%"       ) 100 // protection from creatue type
   WRITE_LONG  ("%fx_off%" + 0x04) 9   // summoned demon
   WRITE_LONG  ("%fx_off%" + 0x08) 7   // gender
 INSERT_BYTES  ("%fx_off%"       ) 0x30
   WRITE_SHORT ("%fx_off%"       ) 219 // protection from creatue type
   WRITE_LONG  ("%fx_off%" + 0x04) 3   // mask_evil
   WRITE_LONG  ("%fx_off%" + 0x08) 8   // from align.ids
 SET "loops" = 2
 WHILE ("%loops%" > 2) BEGIN
   SET "loops" = ("%loops%" - 1)
   WRITE_BYTE ("%fx_off%" + 0x02 + ("%loops%" * 0x30)) 1   // target: self
   WRITE_BYTE ("%fx_off%" + 0x0c + ("%loops%" * 0x30)) 2   // instant/while equipped
   WRITE_BYTE ("%fx_off%" + 0x12 + ("%loops%" * 0x30)) 100 // probability
 END
 SET "delta" = 2
 WRITE_SHORT 0x70 ("%fx_num%" + "%delta%") // updates global fx total
 SET "loops" = "%abil_num%"
 WHILE ("%loops%" < "%abil_num%") BEGIN
   SET "delta1" = 0
   READ_BYTE  ("%abil_off%" +        ("%loops%" * 0x38)) "type"
   READ_ASCII ("%abil_off%" + 0x04 + ("%loops%" * 0x38)) "icon"
   READ_SHORT ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) "abil_fx_num"
   READ_SHORT ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) "abil_fx_idx"
   SET "abil_fx_idx" = ("%abil_fx_idx%" + "%delta%")
   WRITE_SHORT  ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) "%abil_fx_idx%"
   PATCH_IF ("%type%" = 1) BEGIN // melee
     DELETE_BYTES ("%fx_off%" + (0x30 * "%abil_fx_idx%")) (0x30 * "%abil_fx_num%") // removes all old effects
     SET "delta1" = (6 - "%fx_num%")
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30   // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 139    // display string
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2      // target: preset target
       SAY         ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) #14056 // ~Dispel Effects~
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 3      // dispel/bypass resistance
       WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * "%abil_fx_idx%")) 1      // duration
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100    // probability
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30 // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 240  // remove icon 2
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2    // target: preset target
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 48   // feeblemind
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * "%abil_fx_idx%")) 1    // instant/permanent until death
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2    // not dispel/not bypass resistance
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100  // probability
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30 // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 77   // cure feeblemindedness
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2    // target: preset target
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * "%abil_fx_idx%")) 1    // instant/permanent until death
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2    // not dispel/not bypass resistance
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100  // probability
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30      // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 215       // play 3d effect
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2         // target: preset target
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 1         // play over target
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 3         // dispel/bypass resistance
       WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * "%abil_fx_idx%")) 1         // duration
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100       // probability
       WRITE_ASCII ("%fx_off%" + 0x14 + (0x30 * "%abil_fx_idx%")) ~spdisma~ // vvc file
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30       // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 177        // use eff file
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2          // target: preset target
       WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) 7          // illusionary
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 7          // gender
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * "%abil_fx_idx%")) 1          // instant/permanent until death
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2          // not dispel/not bypass resistance
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100        // probability
       WRITE_ASCII ("%fx_off%" + 0x14 + (0x30 * "%abil_fx_idx%")) ~destself~ // eff file
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30 // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 58   // dispel effects
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2    // target: preset target
       WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) 30   // level
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 2    // use specific level
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * "%abil_fx_idx%")) 1    // instant/permanent until death
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2    // not dispel/not bypass resistance
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100  // probability
   END
   PATCH_IF (("%type%" = 3) AND ("%icon%" STRING_COMPARE_CASE "spwi902b" = 0)) BEGIN // magical, spell trap
     DELETE_BYTES ("%fx_off%" + (0x30 * "%abil_fx_idx%")) (0x30 * "%abil_fx_num%") // removes all old effects
     SET "delta1" = (1 - "%fx_num%")
     INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30     // new effect
       WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 146      // cast spell
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 1        // target: self
       WRITE_BYTE  ("%fx_off%" + 0x03 + (0x30 * "%abil_fx_idx%")) 9        // level
       WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) 10       // cast at level
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 1        // cast instantly
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2        // not dispel/not bypass resistance
       WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * "%abil_fx_idx%")) 2400     // duration
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100      // probability
       WRITE_ASCII ("%fx_off%" + 0x14 + (0x30 * "%abil_fx_idx%")) ~staf11~ // spell
   END
   SET "abil_fx_num" = ("%abil_fx_num%" + "%delta1%")
   WRITE_SHORT  ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) "%abil_fx_num%"
   SET "delta" = ("%delta%" + "%delta1%")
   SET "loops" = ("%loops%" + 1)
 END

 

And the custom spell trap:

 

// create custom spell trap for SotM
COPY_EXISTING ~spwi902.spl~ ~override/staf11.spl~
 READ_LONG  0x64 "abil_off"
 READ_SHORT 0x68 "abil_num"
 READ_LONG  0x6a "fx_off"
 PATCH_IF ("%abil_num%" > 0) BEGIN
   READ_SHORT ("%abil_off%" + 0x1e + (("%abil_num%" - 1) * 0x28)) "abil_fx_num"
   READ_SHORT ("%abil_off%" + 0x20 + (("%abil_num%" - 1) * 0x28)) "abil_fx_idx"
   SET "last_fx" = ("%abil_fx_num%" + "%abil_fx_idx%")
 END ELSE BEGIN
   READ_SHORT 0x70 "last_fx"
 END
 WHILE ("%last_fx%" > 0) BEGIN
   SET "last_fx" = ("%last_fx%" - 1)
   READ_BYTE ("%fx_off%" + 0x0c + ("%last_fx%" * 0x30)) "timing"
   READ_LONG ("%fx_off%" + 0x0e + ("%last_fx%" * 0x30)) "duration"
   PATCH_IF (("%timing%" = 0) AND ("%duration%" > 5)) BEGIN // if instant/limited for more than one round
     WRITE_LONG ("%fx_off%" + 0x0e + ("%last_fx%" * 0x30)) 2400
   END
 END

Link to comment

I thought the consensus was that the Staff of the Magi worked fine. I rebuilt it because it had too many effects, and it was easier to copy the improved Illasera's bow of unholy dispel than add the 30 or so effects they used in SoA items to dispel on hit. As far as I remember, the dispel on hit worked fine in the original item.

Link to comment
I thought the consensus was that the Staff of the Magi worked fine. I rebuilt it because it had too many effects, and it was easier to copy the improved Illasera's bow of unholy dispel than add the 30 or so effects they used in SoA items to dispel on hit. As far as I remember, the dispel on hit worked fine in the original item.

Oh. Well, shit. :bday:

 

It does look nicer now.

Link to comment

It's a hell of a lot faster now, too. The item had so many on-equip and ability effects that it caused a delay when the item was equipped and/or selected, which really sucked. DG's dispel effects never fail, however, and there is no need to remove all 30 variants of Shocking Grasp, for instance.

 

Also, I can't tell if you mirrored that here, but I removed the colorglow (in general, there isn't a single item in the game with an equipping effect that introduces a colorglow to the object). My staff is better in every way than the default, but it isn't really a bug fix.

 

The separate spell was the absolute only way I could figure out how to have the Spell Trap dispellable. I'm still sour about it, but there doesn't seem to be a better solution. I suppose Kish can come and say it's not a bug, and then the staff patch can just be omitted entirely.

Link to comment

Hehe. Yeah, I saw the removal of the colorglow and omitted it from this, but I think it goes along with the Protection from Evil thing. It's not necessary either way, but I think by now having the colorglow is expected from players.

Link to comment

Archived

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

×
×
  • Create New...