[(BG2, BGEE) Bug] Barbarian rage, berserker enrage fixes (0824)
Barbarian rage is supposed to grant a +2 save bonus against spells, but is currently imposing a -2 penalty.
Berserker enrage was not actually protecting against stun, despite it being in the description of the ability. While in the 'cool down' period, the THAC0 penalty was being applied but not reflected in the character sheet. The cool down was also using the same name as the actual enrage, implying enrage had been cast when it was ending.
Both these spells will need to be touched again by the immunity batches fix.
BERSERKER: Berserkers are warriors in tune with their animalistic side and, during combat, can achieve an ecstatic state of mind that will enable them to fight longer, harder and more savagely than any humanoid has a right to. Berserkers tend to be barbarian-like in nature, but not always. Sometimes it is a conscious choice that a warrior in training makes. Regardless, opponents on the battlefield will be unsettled when they see the savage elements of the berserker's personality. This class is common amongst dwarves, known to them as 'battleragers'.
Advantages:
- May use 'enrage' ability once per day per 4 levels. The enraged state lasts for 60 seconds.
- While enraged: +2 to hit, +2 damage, -2 AC
- While enraged: immune to Charm, Confusion, Fear, Feeblemind, Hold, Imprisonment, Level Drain, Maze, Stun and Sleep.
- While enraged: gains 15 hit points. These hit points are temporary, and are taken away at the end of the berserk spree, possibly killing the berserker.
Disadvantages:
- Becomes winded after berserking. While winded receives penalties of -2 to hit, -2 to damage and +2 to armor class.
- Cannot specialize (two proficiency points) in ranged weapons (bows, crossbows, slings, or darts)~ []
BARBARIAN: A barbarian can be an excellent warrior. While not as disciplined or as skilled as a normal fighter, the barbarian can willingly be thrown into a berserker rage, becoming a tougher and stronger opponent.
Advantages:
- Moves at 2 points faster than the normal character movement rate
- Immunity to backstab
- Can Rage once per day per every 4 levels (starts at 1st level with one use). Rage gives +4 to constitution and strength for 5 rounds. Gives a 2 point armor class penalty and +2 to saves vs magic (for 5 rounds). Rage also gives immunity to all charm, hold, fear, maze, confusion, stun, sleep and level drain spells.
- At 11th level the barbarian gains 10% resistance to slashing, piercing, crushing and missile damage, and gains a further +5% to this at levels 15 and 19.
- The barbarian rolls D12 for hit points instead of a fighter's D10.
Disadvantages:
- Cannot wear full plate or plate mail armors.
- Cannot specialize in weapons past normal specialization (two proficiency points.)
Berserker enrage was not actually protecting against stun, despite it being in the description of the ability. While in the 'cool down' period, the THAC0 penalty was being applied but not reflected in the character sheet. The cool down was also using the same name as the actual enrage, implying enrage had been cast when it was ending.
Both these spells will need to be touched again by the immunity batches fix.
// barbarian rage should be granting bonus to save v spell, not penaltyWhere'd the stickied string fix thread go? The descriptions for both need to be updated as well. Barbarian rage protects against sleep and stun but these aren't mentioned in the description. Enrage has undocumented protections against confusion, level drain, and feeblemind.
// removing stun icons & effects; see fx batches for the rest
COPY_EXISTING ~spcl152.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"
SET "abil_fx_idx" = ("%abil_fx_idx%" + "%fx_delta%")
WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) "%abil_fx_idx%"
FOR (index2 = 0 ; index2 < abil_fx_num ; index2 = index2 + 1) BEGIN
READ_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "opcode"
READ_ASCII ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "spell"
PATCH_IF ("%opcode%" = 37) BEGIN // save v magic
READ_ASCII ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "clone" (48) // clone effect
WRITE_LONG ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 2 // should be a +2 bonus not -2 penalty
SET "index2" = ("%abil_fx_num%" - 1) // kills loop, advances insert point to right before last effect
FOR (index3 = 0 ; index3 < 2 ; index3 = index3 + 1) BEGIN
INSERT_BYTES ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0x30 // new effect
WRITE_EVALUATED_ASCII ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "%clone%" #48 // use spell immunity as template
END
// write in opcodes and parameters for new effects
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 46 // opcode: unstun
WRITE_BYTE ("%fx_off%" + 0x0c + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 1 // timing: instant/permanent
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%" + 1))) 240 // opcode: remove icon
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%index2%" + 1))) 55 // icon: stun
SET "fx_delta" = ("%fx_delta%" + 2)
WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) ("%abil_fx_num%" + 2)
END
END
END
BUT_ONLY_IF_IT_CHANGES
// enrage's effects misordering prevents immunity to level drain strings; missing listed immunity to stun
COPY_EXISTING ~spcl321.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"
SET "abil_fx_idx" = ("%abil_fx_idx%" + "%fx_delta%")
WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) "%abil_fx_idx%"
FOR (index2 = 0 ; index2 < abil_fx_num ; index2 = index2 + 1) BEGIN
READ_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "opcode"
READ_ASCII ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "spell"
PATCH_IF (("%opcode%" = 206) AND ("%spell%" STRING_COMPARE_CASE "spcl321" = 0)) BEGIN // immunity to itself
READ_ASCII ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "clone" (48) // clone effect
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 240 // change to remove icon
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 55 // stun icon
SET "index2" = "%abil_fx_num%" // kills loop, advances insert point to last effect
FOR (index3 = 0 ; index3 < 4 ; index3 = index3 + 1) BEGIN
INSERT_BYTES ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0x30 // new effect
WRITE_EVALUATED_ASCII ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "%clone%" #48 // use spell immunity as template
END
// write in opcodes and parameters for new effects
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%" + 0))) 169 // opcode: prevent portrait icon
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%index2%" + 0))) 55 // icon: stun
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%" + 1))) 101 // opcode: immunity to effect
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%index2%" + 1))) 45 // effect: stun
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%" + 2))) 46 // opcode: unstun
WRITE_BYTE ("%fx_off%" + 0x0c + (0x30 * ("%abil_fx_idx%" + "%index2%" + 2))) 1 // timing: instant/permanent
SET "fx_delta" = ("%fx_delta%" + 4)
WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) ("%abil_fx_num%" + 4)
END
END
END
BUT_ONLY_IF_IT_CHANGES
// enrage cooldown--suppress name from dialogue window and making THAC0 penalty appear in the window
COPY_EXISTING ~spcl321d.spl~ ~override~
WRITE_LONG NAME1 0xffffffff
WRITE_LONG NAME2 0xffffffff
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
READ_LONG 0x6a "fx_off"
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"
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 "hitwindd" = 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%"))) 0xfffffffe // value (-2)
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%"))) 30 // 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
SET "loops" = "%abil_fx_num%"
END
END
END
BUT_ONLY_IF_IT_CHANGES
BERSERKER: Berserkers are warriors in tune with their animalistic side and, during combat, can achieve an ecstatic state of mind that will enable them to fight longer, harder and more savagely than any humanoid has a right to. Berserkers tend to be barbarian-like in nature, but not always. Sometimes it is a conscious choice that a warrior in training makes. Regardless, opponents on the battlefield will be unsettled when they see the savage elements of the berserker's personality. This class is common amongst dwarves, known to them as 'battleragers'.
Advantages:
- May use 'enrage' ability once per day per 4 levels. The enraged state lasts for 60 seconds.
- While enraged: +2 to hit, +2 damage, -2 AC
- While enraged: immune to Charm, Confusion, Fear, Feeblemind, Hold, Imprisonment, Level Drain, Maze, Stun and Sleep.
- While enraged: gains 15 hit points. These hit points are temporary, and are taken away at the end of the berserk spree, possibly killing the berserker.
Disadvantages:
- Becomes winded after berserking. While winded receives penalties of -2 to hit, -2 to damage and +2 to armor class.
- Cannot specialize (two proficiency points) in ranged weapons (bows, crossbows, slings, or darts)~ []
BARBARIAN: A barbarian can be an excellent warrior. While not as disciplined or as skilled as a normal fighter, the barbarian can willingly be thrown into a berserker rage, becoming a tougher and stronger opponent.
Advantages:
- Moves at 2 points faster than the normal character movement rate
- Immunity to backstab
- Can Rage once per day per every 4 levels (starts at 1st level with one use). Rage gives +4 to constitution and strength for 5 rounds. Gives a 2 point armor class penalty and +2 to saves vs magic (for 5 rounds). Rage also gives immunity to all charm, hold, fear, maze, confusion, stun, sleep and level drain spells.
- At 11th level the barbarian gains 10% resistance to slashing, piercing, crushing and missile damage, and gains a further +5% to this at levels 15 and 19.
- The barbarian rolls D12 for hit points instead of a fighter's D10.
Disadvantages:
- Cannot wear full plate or plate mail armors.
- Cannot specialize in weapons past normal specialization (two proficiency points.)
Post edited by Bhryaen on
2
Comments
EDIT: Missing strings is in BGEE > B and I re-stickied it.
[EDIT] Potentially fixed - @CamDawg 's fix has been applied.
Have the description problems been relocated so I can move this to Found and Fixed?
The Barbarian description is fixed, but the Berserker is currently using the wrong string (but I think I've read this already somewhere).
- SPCL152 (Barbarian Rage)
1. Save v spell bonus now a 2 rather than -2.
2. (Damn, now NI is rendering the Disable display string as a code rather than the actual string.)
-SPCL321 (Berserker Enrage)
1. Includes:
a. Immunity to effect: Power Word, Stun; Stun; Paralyze
b. Cure stun
2. Cooldown period THAC0... Curses, foiled again...
@CamDawg
How does the cooldown work? I was anticipating seeing two sets of "AC bonus," "THAC0 bonus," "Dam bonus," one with the regular +2's that are instant, temporary, then another with -2's on a delayed, temporary Timing Mode. But there's only the one.
Maybe once the Berserker state ends another spell is cast (spcl321d.spl?) on the Berserker to give the penalties? Regardless, the issue was that the THAC0 penalty wasn't being reflected on the Records page, so that can be tested just by waiting for the Berserk state to wear off and checking the record page.