Haste Effects Overriding Improved Haste Fix (Previously Blackrazor Revision)
Abel
Member Posts: 785
Original post:
I did not expect that this little 'fix' would actually prove larger (though not much).
Now, it's not only WeiDU but it also potentially fix issues that are not directly related to Blackrazor.
However, it's not perfect! The features:
- Patches all spells (even in your override) that use the Improved Haste effect
- Adds an Immunity to Haste (all kinds) for the duration of the spell
Yes, it may seem little but it's a nightmare to code!
Now, the limit is since you're immune to all Haste effects, if you cast a spell with Improved Haste effect on a character that is immune, it obviously won't affect him/her. So you'd have to wait until the spell ends to renew the effect. Although I'm not sure if in the base game when you cast a spell over the same one it overrides its effect.
I tested it and it works! Unfortunately, it seems if you use an already written spell (like Improved Haste) on a current game, it doesn't (I used a scroll when I noticed that). So I guess you would have to erase the spell and scribe it again. Ugh!
Also, why didn't I patch Haste effect spells too? Well, the problem with the Haste effect is that it has two types. One for simple Haste, the other for Improved Haste. Unfortunately, when adding an Immunity to this effect, you can't choose to what type it applies. No, Bioware didn't think it could help to make a separate effect for Improved Haste. Ugh!
So, simply extract the files to your main folder (C:\Program Files (x86)\Baldur's Gate II Enhanced Edition\Data\00783) and run the setup. Patched files will be mentioned in the window.
On a side note, it seems my attached file are regularly disappearing?! So, just for history sake I will attach again the old mod.
And for those who are interested, the code below.
It's far from neat so I would welcome any comment.
I spent hours debugging it. Especially figuring out the feature block offsets that are inconveniently set at header level while index is set at extended header level. I don't get the logic... Fortunately, even when IESDP descriptions fail you, there's still Near Infinity and its ability to display offsets.
It has always saddened me that my preferred sword doesn't work well with Improved Haste, my preferred spell. So, I made two Blackrazor revised versions that you can use: link. Quick and plain edits with the fabulous DLTCEP! Just place the .itm file of your choice in your override folder (C:\Program Files (x86)\Baldur's Gate II Enhanced Edition\Data\00783\override).
- 1st version simply replaces the Haste effect by Improved Haste.
In my opinion, this is the most 'faithful' revision.
This effect overrides previous Haste effects on the character for the duration (20s). So, Hasted characters will benefit from Improved Haste and Improved Hasted character won't witness any change.
- 2nd version emulates the Haste effect by providing, as per spell description:
* x2 speed movement (not cumulative with boots of speed)
* -2 initiative (actually -2 to weapon speed factor which I guess is not the same but closest I could find)
* +1 attack per round
This revision I find more powerful because you can stack its effects with (Improved) Haste.
Maybe not ideal solutions but the most reasonable I could come up with. Feel free to report/suggest anything.
- 1st version simply replaces the Haste effect by Improved Haste.
In my opinion, this is the most 'faithful' revision.
This effect overrides previous Haste effects on the character for the duration (20s). So, Hasted characters will benefit from Improved Haste and Improved Hasted character won't witness any change.
- 2nd version emulates the Haste effect by providing, as per spell description:
* x2 speed movement (not cumulative with boots of speed)
* -2 initiative (actually -2 to weapon speed factor which I guess is not the same but closest I could find)
* +1 attack per round
This revision I find more powerful because you can stack its effects with (Improved) Haste.
Maybe not ideal solutions but the most reasonable I could come up with. Feel free to report/suggest anything.
I did not expect that this little 'fix' would actually prove larger (though not much).
Now, it's not only WeiDU but it also potentially fix issues that are not directly related to Blackrazor.
However, it's not perfect! The features:
- Patches all spells (even in your override) that use the Improved Haste effect
- Adds an Immunity to Haste (all kinds) for the duration of the spell
Yes, it may seem little but it's a nightmare to code!
Now, the limit is since you're immune to all Haste effects, if you cast a spell with Improved Haste effect on a character that is immune, it obviously won't affect him/her. So you'd have to wait until the spell ends to renew the effect. Although I'm not sure if in the base game when you cast a spell over the same one it overrides its effect.
I tested it and it works! Unfortunately, it seems if you use an already written spell (like Improved Haste) on a current game, it doesn't (I used a scroll when I noticed that). So I guess you would have to erase the spell and scribe it again. Ugh!
Also, why didn't I patch Haste effect spells too? Well, the problem with the Haste effect is that it has two types. One for simple Haste, the other for Improved Haste. Unfortunately, when adding an Immunity to this effect, you can't choose to what type it applies. No, Bioware didn't think it could help to make a separate effect for Improved Haste. Ugh!
So, simply extract the files to your main folder (C:\Program Files (x86)\Baldur's Gate II Enhanced Edition\Data\00783) and run the setup. Patched files will be mentioned in the window.
On a side note, it seems my attached file are regularly disappearing?! So, just for history sake I will attach again the old mod.
And for those who are interested, the code below.
It's far from neat so I would welcome any comment.
I spent hours debugging it. Especially figuring out the feature block offsets that are inconveniently set at header level while index is set at extended header level. I don't get the logic... Fortunately, even when IESDP descriptions fail you, there's still Near Infinity and its ability to display offsets.
BACKUP ~abel_imphaste_fix/backup~
AUTHOR ~Abel, http://forum.baldursgate.com/messages/add/Abel~
BEGIN ~Haste Effects Overriding Improved Haste Fix~
REQUIRE_PREDICATE (GAME_IS ~tob bgee bg2ee~) ~Fine!~
//A variable we'll use later
OUTER_SET incnum = 0
//Will check every spell even in the override folder
COPY_EXISTING_REGEXP GLOB ~.*\.spl~ ~override~
//Spells must be 0x72 at least
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
//Get the value of the Extended Header offset
READ_LONG 0x64 xheadoff
//Get the value of the Extended Header count (number of Extended Header)
READ_SHORT 0x68 xheadcnt
//Warning! Offset for Feature Block is from Header, not from Extended Header
//So, get the value of the Feature Block Table (spell effects of all Extended Headers) offset
READ_LONG 0x6a fblocktaboff
//As long as there's an header we haven't checked (0x28 or 40 per header)
FOR (h = 0; h < xheadcnt; h = h + 1) BEGIN
//Get the value of the Feature Block count (number of spell effects) of this Extended Header
READ_SHORT (h * 0x28 + (xheadoff + 0x1e)) fblockcnt
//Get the value of the Feature Block TABLE Index of this Extended Header
READ_SHORT (h * 0x28 + (xheadoff + 0x20)) fblocktabin
//Get the value of the Feature Block offset FOR this Extended Header
//Warning! Each Feature Block is 0x30 long
SET fblockoff = (fblocktabin * 0x30) + fblocktaboff
//As long as there's a block we haven't checked (0x30 or 48 per block)
//PATCH_PRINT ~xheadoff %xheadoff% - h %h% - fblocktabin %fblocktabin%~
FOR (b = fblockcnt; b > 0; b = b - 1) BEGIN
//Get the value of the opcode and param2 of this Feature Block
READ_SHORT ((b - 1) * 0x30 + fblockoff) opcode
READ_LONG (fblockoff + 0x8) param2
//PATCH_PRINT ~b %b% - fblockoff %fblockoff% - fblockcnt %fblockcnt% - opcode %opcode% - param2 %param2%~
//If Improved Haste opcode is detected
//Warning! Opcodes are in decimal value! WTF IESDP?!
PATCH_IF ((opcode = 16) AND (param2 = 1)) BEGIN
//Get all other offsets values of this Feature Block
READ_BYTE (fblockoff + 0x2) target
READ_BYTE (fblockoff + 0x3) power
READ_LONG (fblockoff + 0x4) param1
READ_BYTE (fblockoff + 0xc) timing
READ_BYTE (fblockoff + 0xd) resist
READ_LONG (fblockoff + 0xe) duration
READ_BYTE (fblockoff + 0x12) prob1
READ_BYTE (fblockoff + 0x13) prob2
READ_ASCII (fblockoff + 0x14) resource
READ_LONG (fblockoff + 0x1c) dicenum
READ_LONG (fblockoff + 0x20) dicetype
READ_LONG (fblockoff + 0x24) savetype
READ_LONG (fblockoff + 0x28) savebonus
READ_LONG (fblockoff + 0x2c) unknown
//Update the value of the Feature Block count offset of this Extended Header
WRITE_SHORT (h * 0x28 + (xheadoff + 0x1e)) (fblockcnt + 1)
//Increment the value of the Feature Block TABLE Index of the NEXT Extended Header
//Warning! Use a variable to keep tracks of all incrementation
SET incnum = incnum + 1
READ_SHORT ((h + 1) * 0x28 + (xheadoff + 0x20)) nextfblocktabin
WRITE_SHORT ((h + 1) * 0x28 + (xheadoff + 0x20)) (nextfblocktabin + incnum)
//Add a new Feature Block
SET newfblockoff = fblockoff + fblockcnt * 0x30
INSERT_BYTES newfblockoff 0x30
//PATCH_PRINT ~newfblockoff %newfblockoff% - resource %resource% nextfblocktabin %nextfblocktabin% incnum %incnum%~
//Set its opcode to protect from Haste opcode
WRITE_LONG newfblockoff 101
WRITE_LONG (newfblockoff + 0x8) 16
//Copy all offsets values we got except opcode and param2
WRITE_BYTE (newfblockoff + 0x2) target
WRITE_BYTE (newfblockoff + 0x3) power
WRITE_LONG (newfblockoff + 0x4) param1
WRITE_BYTE (newfblockoff + 0xc) timing
WRITE_BYTE (newfblockoff + 0xd) resist
WRITE_LONG (newfblockoff + 0xe) duration
WRITE_BYTE (newfblockoff + 0x12) prob1
WRITE_BYTE (newfblockoff + 0x13) prob2
WRITE_EVALUATED_ASCII (newfblockoff + 0x14) ~%resource%~
WRITE_LONG (newfblockoff + 0x1c) dicenum
WRITE_LONG (newfblockoff + 0x20) dicetype
WRITE_LONG (newfblockoff + 0x24) savetype
WRITE_LONG (newfblockoff + 0x28) savebonus
WRITE_LONG (newfblockoff + 0x2c) unknown
//Close the loop
SET b = 0
//Print resource file patched
PATCH_PRINT ~Patched %SOURCE_RES%~
END
END
END
END
BUT_ONLY_IF_IT_CHANGES
Post edited by Abel on
3
Comments
One question: I want to make my Blackrazor completely black. Right now the flames are on the grey-ish scale. What is the gradient number for black? (Equipping Effect: change colour by palette)?
So about your question, I made a quick search on the IESDP and I found this. Hope it helps !
I see there are two others in the item file.
Don't know if that would work though. I never tried it myself!
I've never given much attention to it, but if there's an actual item that comes close to what you want, maybe you should try to imitate its effects. Just guessing there
There is quillon and grip there only, I'm afraid. The core and the flames are both considered location 21 (major part of the blade).
Actually, since Lathlaer bumped this thread I had another idea that could be even closer to the original.
The normal version uses the Haste opcode which leads to the various problems mentioned above.
Another possibility would be to replace it by the opcode that casts a spell on specified target (like Foebane).
In that case, it would be the Haste spell. I looked for an existing version that would cast it on the user only (not the party). I was able to find one that I guess is used by various items. Problem is the duration is 48 instead of 20 which means a slightly modified version would be needed.
Thing is, I'm not really sure how Haste spells interact with other resources that use effects like free action, slow and really anything that affects movement. A new spell would need to take those into account.
Finally, and it's also a bug, when you cast a Haste spell on a Whirlwinded character, it screws with the number of attacks.
Another behavior I thing is unintended is that the level drain and the positive effects aren't simultaneous. My guess is that the game rolls a different random number for each target. I don't see how that could be modified.
All in all, it's feasible but it would need some time and tinkering, especially with WeiDU that I'm only beginning to understand.
if i understand everything correctly, this is what happens when the blackrazor's special ability is activated - the wielder is hasted, but this haste effect overrides the already existing improved haste?
i have used blackrazor moderately and i think i have noticed this but im not 100% sure (just 95%)
if that's the case, this is a bug!
haste must not override improved haste in any instance.
any solution to that is welcome - both your versions are just fine and the third proposed version (spontaneously cast spell, like foebane) is the best one!
the duration issue is microscopically minor.
--- if i got everything right, you should make a bug report. if you don't, i'll do it
in ee, free action disables subsequent haste/slow and removes previous haste/slow
haste dispels slow (they nullify each other so neither persists)
the haste effect coming from blacrazor should also obey these rules.
It's good you asked this question, because I actually think there could be an easier way to do this.
Since as you well said it's a problem of one effect overriding others, why not just protect against it for the duration of the overridden effects?
So, we could just add an effect to Improved Haste and Whirlwind abilities: By setting it to protect from opcode #16, I think it would solve everything. It would need testing of course, but I think that could work.
I believe I reported it already and you know it's a very ancient and known bug. Some have tried to fix it, but I've never found in a satisfactory manner...
it's been reported more recently and already registered
http://forum.baldursgate.com/discussion/28624/7402-core-blackrazor-removes-extra-attacks-from-improved-haste-and-greater-whirlwind-hla
your solution seems correct, you could post it to that thread, it might prove helpful
The mod is done!
I edited my original post and uploaded the files.
Finally, you can increase your Strength and heal yourself while under Improved Haste !