Skip to content

[(BG2, BGEE) Bug] Barbarian rage, berserker enrage fixes (0824)

CamDawgCamDawg Member, Developer Posts: 3,438
edited September 2012 in Fixed
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.
// barbarian rage should be granting bonus to save v spell, not penalty
// 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
Where'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.

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

Comments

  • AndreaColomboAndreaColombo Member Posts: 5,533
    Dropping @Dave's name so that he can add the missing immunities to the description of the Rage ability in the Barbarian sheet.
  • TanthalasTanthalas Member Posts: 6,738
    edited July 2012
    I'll resticky the text update thread. It got unstickied while moving. The thread is in D.

    EDIT: Missing strings is in BGEE > B and I re-stickied it.
  • AndreaColomboAndreaColombo Member Posts: 5,533
    I believe Dave has already fixed the typos in the description of the Barbarian class, so all that is left to do is adding those "unspoken" immunities.
  • DaveDave Member Posts: 200
    Those class descriptions are in a different file from the one I've been editing. I'll mention it to Scott when he returns to the office.
  • SethDavisSethDavis Member Posts: 1,812
    edited July 2012
    checking this one now

    [EDIT] Potentially fixed - @CamDawg 's fix has been applied.

    Have the description problems been relocated so I can move this to Found and Fixed?
  • AndreaColomboAndreaColombo Member Posts: 5,533
    @SethDavis - The descriptions are now fixed and include the previously omitted immunities as per @CamDawg's post.
  • TanthalasTanthalas Member Posts: 6,738
    @AndreaColombo
    The Barbarian description is fixed, but the Berserker is currently using the wrong string (but I think I've read this already somewhere).
  • BhryaenBhryaen Member Posts: 2,874
    Confirmed Fixed:

    - 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.
  • TanthalasTanthalas Member Posts: 6,738
    edited September 2012
    @Bhryaen

    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.
  • CamDawgCamDawg Member, Developer Posts: 3,438
    Bhryaen said:

    Confirmed Fixed:
    @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.

    So, raging casts spcl321, which applies a bunch of instant/limited effects, meaning they simply expire after the duration (1 turn game time, 60 seconds real time). Also in the laundry list of effects are a few delayed effects--15 points of damage and a casting of spcl321d. spcl321d shows the message about rage expiring, applies fatigue, and prevents re-raging for another 30 seconds.
  • TanthalasTanthalas Member Posts: 6,738
    The string has also been fixed now. So this one is good to go.
Sign In or Register to comment.