Jump to content

Rings of Fire, Earth, and Air Control


Recommended Posts

Another BD recode with devSin fixes. BD reports the Ring of Fire Control is missing the save bonus for charm elementals, but it's also mis-targeted, has poor range, and does not recharge after resting.

 

To handle the target issue, devSin introduces eff targeting at class: fire elemental. The eff appears to be set up to be called from pretty much any of the elemental control rings, as it appears the ring28 fixes use it as well. I've changed the eff name to use a prefix. :bday: At any rate, here's the actual patch:

 

// fire control ring has screwy charm effect; changed to use eff targeting on class fire elemental
COPY_EXISTING ~ring27.itm~ ~override~
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 WHILE ("%abil_num%" > 0) BEGIN // looks for melee ability header
   SET "abil_num" = ("%abil_num%" - 1)
   READ_BYTE  ("%abil_off%" +        ("%abil_num%" * 0x38)) "type"
   READ_SHORT ("%abil_off%" + 0x04 + ("%abil_num%" * 0x38)) "icon"
   PATCH_IF (("%type%" = 3) AND ("%icon%" STRING_COMPARE_CASE "spwi104b" = 0)) BEGIN // charm effect
     WRITE_SHORT ("%abil_off%" + 0x08 + ("%abil_num%" * 0x38)) 2 // range
     WRITE_BYTE  ("%abil_off%" + 0x27 + ("%abil_num%" * 0x38)) 8 // recharges after rest
     READ_SHORT  ("%abil_off%" + 0x1e + ("%abil_num%" * 0x38)) "abil_fx_num"
     READ_SHORT  ("%abil_off%" + 0x20 + ("%abil_num%" * 0x38)) "abil_fx_idx"
     WHILE ("%abil_fx_num%" > 0) BEGIN // searches through fx for slow effect
       SET "abil_fx_num" = ("%abil_fx_num%" - 1)
       READ_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) "fx_type"
       PATCH_IF ("%fx_type%" = 5) BEGIN // charm > use eff
         WRITE_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 177 // use eff
         WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 187 // fire elemental
         WRITE_SHORT ("%fx_off%" + 0x08 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 5   // class
         WRITE_ASCII ("%fx_off%" + 0x14 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) ~cdcmelem~ // new eff
         WRITE_LONG  ("%fx_off%" + 0x24 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 1   // save v spells
         WRITE_LONG  ("%fx_off%" + 0x28 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 2   // save bonus
       END
     END
   END
 END
 BUT_ONLY_IF_IT_CHANGES

Link to comment

Ring of Air Control has virtually the same fix as Fire Control. As such, I've combined it with the above code and then it gets patched a second time to account for the missing save bonus on the improved invisibility ability. This supplants the code above.

 

// fire and air control ring has screwy charm effects; changed to use eff targeting on class fire/air elemental
COPY_EXISTING ~ring27.itm~ ~override~
             ~ring28.itm~ ~override~
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 WHILE ("%abil_num%" > 0) BEGIN // looks for melee ability header
   SET "abil_num" = ("%abil_num%" - 1)
   READ_BYTE  ("%abil_off%" +        ("%abil_num%" * 0x38)) "type"
   READ_ASCII ("%abil_off%" + 0x04 + ("%abil_num%" * 0x38)) "icon"
   PATCH_IF (("%type%" = 3) AND 
            (("%icon%" STRING_COMPARE_CASE "spwi104b" = 0) OR      // fire control charm
             ("%icon%" STRING_COMPARE_CASE "sppr204b" = 0))) BEGIN // air control charm
   BEGIN // charm effect
     WRITE_SHORT ("%abil_off%" + 0x08 + ("%abil_num%" * 0x38)) 2 // range
     WRITE_BYTE  ("%abil_off%" + 0x27 + ("%abil_num%" * 0x38)) 8 // recharges after rest
     READ_SHORT  ("%abil_off%" + 0x1e + ("%abil_num%" * 0x38)) "abil_fx_num"
     READ_SHORT  ("%abil_off%" + 0x20 + ("%abil_num%" * 0x38)) "abil_fx_idx"
     WHILE ("%abil_fx_num%" > 0) BEGIN // searches through fx for slow effect
       SET "abil_fx_num" = ("%abil_fx_num%" - 1)
       READ_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) "fx_type"
       PATCH_IF ("%fx_type%" = 5) BEGIN // charm > use eff
         WRITE_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 177 // use eff
         PATCH_IF ("ring27.itm" STRING_COMPARE_CASE ~%SOURCE_FILE%~ = 0) BEGIN // fire control ring
           WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 187 // fire elemental
         END ELSE BEGIN // air control
           WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 186 // air elemental
         END
         WRITE_SHORT ("%fx_off%" + 0x08 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 5   // class
         WRITE_ASCII ("%fx_off%" + 0x14 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) ~cdcmelem~ // new eff
         WRITE_LONG  ("%fx_off%" + 0x24 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 1   // save v spells
         WRITE_LONG  ("%fx_off%" + 0x28 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 2   // save bonus
       END
     END
   END
 END
 BUT_ONLY_IF_IT_CHANGES
 
// air control ring, adding new effects
COPY_EXISTING ~ring28.itm~ ~override~
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 SET "loops" = 0
 SET "fx_new" = 0
 WHILE ("%abil_num%" > "%loops%") BEGIN // finds insert point and adjusts indices
   READ_SHORT  ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) "abil_fx_idx"
   WRITE_SHORT ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) ("%abil_fx_idx%" + "%fx_new%")
   READ_ASCII  ("%abil_off%" + 0x04 + ("%loops%" * 0x38)) "icon"
   PATCH_IF ("%icon%" STRING_COMPARE_CASE "spwi405b" = 0) BEGIN // invisibiity ability
     SET "fx_new" = 5
     SET "fx_insert" = ("%fx_off%" + ("%abil_fx_idx%" * 0x30))
     READ_SHORT  ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) "abil_fx_num"
     WRITE_SHORT ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) ("%abil_fx_num%" + "%fx_new%")
   END
   SET "loops" = ("%loops%" + 1)
 END
 WHILE ("%fx_new"% > 0) BEGIN
   SET "fx_new" = ("%fx_new%" - 1)
   INSERT_BYTES  ("%fx_insert%"       ) 0x30       // new effect
     WRITE_SHORT ("%fx_insert%"       ) ("%loops%" + 33) // save bonuses
     WRITE_BYTE  ("%fx_insert%" + 0x02) 1     // target:self
     WRITE_BYTE  ("%fx_insert%" + 0x03) 4     // power
     WRITE_LONG  ("%fx_insert%" + 0x04) 4     // value
     WRITE_BYTE  ("%fx_insert%" + 0x0d) 2     // dispel/not bypass
     WRITE_LONG  ("%fx_insert%" + 0x0e) 60    // duration
     WRITE_BYTE  ("%fx_insert%" + 0x12) 100   // probability
 END
 BUT_ONLY_IF_IT_CHANGES

Link to comment

And in the "why didn't I see this coming" category, the ring of earth control also needs the same charm effect fix. It also has extraneous save bonus effects that need to be disabled. This code supplants the stuff above.

 

// fire/air/earth control ring has screwy charm effects; changed to use eff targeting on class fire/air/earth elemental
COPY_EXISTING ~ring27.itm~ ~override~
             ~ring28.itm~ ~override~
             ~ring29.itm~ ~override~
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 WHILE ("%abil_num%" > 0) BEGIN // looks for melee ability header
   SET "abil_num" = ("%abil_num%" - 1)
   READ_BYTE  ("%abil_off%" +        ("%abil_num%" * 0x38)) "type"
   READ_ASCII ("%abil_off%" + 0x04 + ("%abil_num%" * 0x38)) "icon"
   PATCH_IF (("%type%" = 3) AND 
            (("%icon%" STRING_COMPARE_CASE "spwi104b" = 0) OR      // fire control charm
             ("%icon%" STRING_COMPARE_CASE "sppr204b" = 0))) BEGIN // air control charm
   BEGIN // charm effect
     WRITE_SHORT ("%abil_off%" + 0x08 + ("%abil_num%" * 0x38)) 2 // range
     WRITE_BYTE  ("%abil_off%" + 0x27 + ("%abil_num%" * 0x38)) 8 // recharges after rest
     READ_SHORT  ("%abil_off%" + 0x1e + ("%abil_num%" * 0x38)) "abil_fx_num"
     READ_SHORT  ("%abil_off%" + 0x20 + ("%abil_num%" * 0x38)) "abil_fx_idx"
     WHILE ("%abil_fx_num%" > 0) BEGIN // searches through fx for slow effect
       SET "abil_fx_num" = ("%abil_fx_num%" - 1)
       READ_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) "fx_type"
       PATCH_IF ("%fx_type%" = 5) BEGIN // charm > use eff
         WRITE_SHORT ("%fx_off%" +        (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 177 // use eff
         PATCH_IF ("ring27.itm" STRING_COMPARE_CASE ~%SOURCE_FILE%~ = 0) BEGIN // fire control ring
           WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 187 // fire elemental
         END
         PATCH_IF ("ring28.itm" STRING_COMPARE_CASE ~%SOURCE_FILE%~ = 0) BEGIN // air control
           WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 186 // air elemental
         END
         PATCH_IF ("ring29.itm" STRING_COMPARE_CASE ~%SOURCE_FILE%~ = 0) BEGIN // earth control
           WRITE_LONG  ("%fx_off%" + 0x04 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 188 // earth elemental
         END
         WRITE_SHORT ("%fx_off%" + 0x08 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 5   // class
         WRITE_ASCII ("%fx_off%" + 0x14 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) ~cdcmelem~ // new eff
         WRITE_LONG  ("%fx_off%" + 0x24 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 1   // save v spells
         WRITE_LONG  ("%fx_off%" + 0x28 + (("%abil_fx_idx%" + "%abil_fx_num%") * 0x30)) 2   // save bonus
       END
     END
   END
 END
 BUT_ONLY_IF_IT_CHANGES
 
// air control ring, adding new effects
COPY_EXISTING ~ring28.itm~ ~override~
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 SET "loops" = 0
 SET "fx_new" = 0
 WHILE ("%abil_num%" > "%loops%") BEGIN // finds insert point and adjusts indices
   READ_SHORT  ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) "abil_fx_idx"
   WRITE_SHORT ("%abil_off%" + 0x20 + ("%loops%" * 0x38)) ("%abil_fx_idx%" + "%fx_new%")
   READ_ASCII  ("%abil_off%" + 0x04 + ("%loops%" * 0x38)) "icon"
   PATCH_IF ("%icon%" STRING_COMPARE_CASE "spwi405b" = 0) BEGIN // invisibiity ability
     SET "fx_new" = 5
     SET "fx_insert" = ("%fx_off%" + ("%abil_fx_idx%" * 0x30))
     READ_SHORT  ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) "abil_fx_num"
     WRITE_SHORT ("%abil_off%" + 0x1e + ("%loops%" * 0x38)) ("%abil_fx_num%" + "%fx_new%")
   END
   SET "loops" = ("%loops%" + 1)
 END
 WHILE ("%fx_new"% > 0) BEGIN
   SET "fx_new" = ("%fx_new%" - 1)
   INSERT_BYTES  ("%fx_insert%"       ) 0x30       // new effect
     WRITE_SHORT ("%fx_insert%"       ) ("%loops%" + 33) // save bonuses
     WRITE_BYTE  ("%fx_insert%" + 0x02) 1     // target:self
     WRITE_BYTE  ("%fx_insert%" + 0x03) 4     // power
     WRITE_LONG  ("%fx_insert%" + 0x04) 4     // value
     WRITE_BYTE  ("%fx_insert%" + 0x0d) 2     // dispel/not bypass
     WRITE_LONG  ("%fx_insert%" + 0x0e) 60    // duration
     WRITE_BYTE  ("%fx_insert%" + 0x12) 100   // probability
 END
 BUT_ONLY_IF_IT_CHANGES

// disables erroneous save effects from earth control ring
COPY_EXISTING ~ring29.itm~ ~override~
 READ_LONG   0x6a "fx_off"
 READ_SHORT  0x70 "fx_num"
 WHILE ("%fx_num%" > 0) BEGIN
   SET "fx_num" = ("%fx_num%" - 1)
   READ_BYTE ("%fx_off%" +        ("%fx_num%" * 0x30)) "type"
   PATCH_IF (("%type%" > 32) AND ("%type%" < 38)) BEGIN // save bonuses
     WRITE_BYTE ("%fx_off%" + 0x12 + ("%fx_num%" * 0x30)) 0 // probability: 0
   END
 END
 BUT_ONLY_IF_IT_CHANGES

Link to comment

Archived

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

×
×
  • Create New...