Jump to content

Blade: Offensive Spin missing ThAC0 bonus


Nim

Recommended Posts

Cam, here's the reminder to fix the Blade's Offensive Spin.

 

This is what Baldurdash does:

Blade Offensive Spin Ability Fix adds the missing THAC0 bonus of 2 that's missing from this bard kit's special ability, and the bonus is also now visible in the character sheet when the ability is used. The Throne Of Bhaal update to this Shadows Of Amn fix replaces the Haste effect with a movement rate and attack/round modifier to prevent the suppression of off-hand attacks. Note that the off-hand will still only get one attack/round; this is (so far) unavoidable.

Link to comment

IIRC, the problem with this and some of the kit bonuses is that they're using the HITPLUSn EFF files. The files give a THAC0 vs. Type bonus (vs. a regular THAC0 bonus), which apparently isn't cumulative (i.e., the last-applied effect wins). The THAC0 bonus really is there-- it just isn't the right one.

Link to comment

FIxed as follows. This also adds an immunity to haste effect so it wn't stack.

 

// offensive spin fixes
COPY_EXISTING ~spcl521.spl~ ~override~
 READ_LONG  0x64 "abil_off"
 READ_SHORT 0x68 "abil_num"
 READ_LONG  0x6a "fx_off"
 SET "fx_delta" = 0
 FOR ("index" = 0; "%index%" < "%abil_num%"; "index" = ("%index%" + 1)) BEGIN // fix existing effects
   READ_SHORT  ("%abil_off%" + 0x1e + (0x28 * "%index%")) "abil_fx_num"
   READ_SHORT  ("%abil_off%" + 0x20 + (0x28 * "%index%")) "abil_fx_idx"
   WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) ("%abil_fx_num%" + 2)
   SET "abil_fx_idx" = ("%abil_fx_idx%" + "%fx_delta%")
   WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) ("%abil_fx_idx%")
   FOR (loops = 0; loops < abil_fx_num; loops = loops + 1) BEGIN
     READ_SHORT ("%fx_off%" +        (0x30 * ("%abil_fx_idx%" + "%loops%"))) "opcode"
     READ_ASCII ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) "eff"
     PATCH_IF (("%opcode%" = 177) AND ("%eff%" STRING_COMPARE_CASE "hitplus2" = 0)) BEGIN // replacing eff call with thac0 bonus
       WRITE_SHORT ("%fx_off%" +        (0x30 * ("%abil_fx_idx%" + "%loops%"))) 54  // thac0 bonus
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 1   // target self
       WRITE_BYTE  ("%fx_off%" + 0x03 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // power
       WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 2   // value
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // inc/dec
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // instant/limited
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 2   // not dispel/not bypass
       WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 24  // duration
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 100 // prob 1
       WRITE_BYTE  ("%fx_off%" + 0x13 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // prob 2
       WRITE_LONG  ("%fx_off%" + 0x1c + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // max level
       WRITE_LONG  ("%fx_off%" + 0x20 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // min level
       WRITE_LONG  ("%fx_off%" + 0x24 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // save type
       WRITE_LONG  ("%fx_off%" + 0x28 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // save bonus
     END
     PATCH_IF ("%opcode%" = 16) BEGIN // replacing haste with immunity to haste
       WRITE_SHORT ("%fx_off%" +        (0x30 * ("%abil_fx_idx%" + "%loops%"))) 101 // immunity to effect
       WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 1   // target self
       WRITE_BYTE  ("%fx_off%" + 0x03 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // power
       WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // value
       WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 16  // haste
       WRITE_BYTE  ("%fx_off%" + 0x0c + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // instant/limited
       WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 2   // not dispel/not bypass
       WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 24  // duration
       WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 100 // prob 1
       WRITE_BYTE  ("%fx_off%" + 0x13 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // prob 2
       WRITE_LONG  ("%fx_off%" + 0x1c + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // max level
       WRITE_LONG  ("%fx_off%" + 0x20 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // min level
       WRITE_LONG  ("%fx_off%" + 0x24 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // save type
       WRITE_LONG  ("%fx_off%" + 0x28 + (0x30 * ("%abil_fx_idx%" + "%loops%"))) 0   // save bonus
     END
   END
   INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30 // insert new effect
     WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 126 // movementrate bonus
     WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 1   // target self
     WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) 200 // value
     WRITE_LONG  ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 2   // set to % of
     WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2   // not dispel/not bypass
     WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * "%abil_fx_idx%")) 24  // duration
     WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100 // prob 1
   INSERT_BYTES  ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 0x30 // insert new effect
     WRITE_SHORT ("%fx_off%" +        (0x30 * "%abil_fx_idx%")) 1   // modify attacks per round
     WRITE_BYTE  ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 1   // target self
     WRITE_LONG  ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) 1   // 1 attack per 1 round
     WRITE_BYTE  ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 2   // not dispel/not bypass
     WRITE_LONG  ("%fx_off%" + 0x0e + (0x30 * "%abil_fx_idx%")) 24  // duration
     WRITE_BYTE  ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100 // prob 1
   SET "fx_delta" = ("%fx_delta%" + 2)
 END
 BUT_ONLY_IF_IT_CHANGES

 

Added locally in alpha 6.

Link to comment
This also adds an immunity to haste effect so it won't stack.

The ThAC0 bonus works, the haste immunity partially. If I activate Offensive Spin and then Improved Haste everything is fine. But casting IH first and then OS I get the additional attack from OS and it is also doubled ( 3 ApR base -> 6 ApR after IH-> 8 ApR with IH and OS). Any idea ?

Link to comment

It's probably outside the scope here. In theory, doing a 0 second haste (assuming it's a non-cumulative effect) or applying a free action effect would kill the haste, but it's really a messy hack. The engine just doesn't handle the situation very well (it's easy to provide protection against future effects, but killing current effects with any specificity is a little messy). Unless, of course, one of the unkown opcodes is UnHaste. :)

 

In NWN, they use some bad-ass scripting to get around this, but we're just stuck with the garbage.

Link to comment

Archived

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

×
×
  • Create New...