Jump to content

Does Dispel Magic work properly?


Guest amanasleep

Recommended Posts

Guest amanasleep

Recently somebody casually mentioned to me in a forum that Dispel Magic does not work as per it's spell description:

 

A dispel magic removes magical effects upon anyone within the area.  This 
 includes effects given from spells, potions and certain magical items such as 
 wands.  It does not, however, affect enchanted magical items or spell 
 protections such as Spell Turning, and Spell Deflection.  The chance of the 
 dispel succeeding is determined by the level of the caster and the level of 
 the magic being dispelled. The base chance of successfully dispelling is 50%.
 For every level that the caster of the dispel magic is above the original
 caster, his chance of success increases by 5%.  For every level that the
 caster of dispel magic is below the original caster, his chance of success
 decreases by 10%.  However, despite the difference in levels, there is always
 at least a 1% chance of success or failure. Thus, if a caster is 10 levels
 higher than the magic he is trying to dispel, there is only a 1% chance of
 failure.  Similarly if the caster is 4 levels lower than the magic he is
 trying to dispel, there is only a 10% chance of success.  Intuitively, this
 spell is almost useless if the target is 5 or more levels higher than the
 caster.

 Note:  while this spell dispels the individual effects of grease, web,
 stinking cloud and other such spells, it does not dispel the area of effect.

 

They claim that although the spell will work as described when a higher level caster attempts a dispel against a lower level caster effect, the actual probability of a lower level caster affecting any higher level caster effect with dispel magic is either zero or close to zero.

 

I have no mod skills, so I decided to do some front end testing.

 

I tested BG2 NPC's of caster level 12 and level 13. 13 vs. 12 dispeled effects every time. 12 vs. 13 was not able to dispel any effects after many different castings of dispel magic. I used Stone Skin in my testing, as I know that some other effects (like mirror images and anything in the enchanted weapon slot) are automatically dispelled.

 

This preliminary test suggests that Dispel Magic works at 100% when the caster is higher level, and 0% when lower level than the effect.

 

Can anybody confirm whether this behavior is:

 

A) an actual bug in Dispel (and presumably Remove) Magic?

B) not a bug because my testing is flawed?

C) not a bug because it is working as intended?

D) not a bug because my result was just unlucky?

Link to comment

(All of the following only applies to the patched ToB version. I have no idea if the other versions work the same.)

 

This is roughly how the dispel effect works:

      1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20
1:   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120  125  130  135  140  145
2:   31   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120  125  130  135  140
3:   21   22   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120  125  130  135
4:   11   12   13   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120  125  130
5:    1    2    3    4   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120  125
6:   -9   -8   -7   -6   -5   50   55   60   65   70   75   80   85   90   95  100  105  110  115  120
7:  -19  -18  -17  -16  -15  -14   50   55   60   65   70   75   80   85   90   95  100  105  110  115
8:  -29  -28  -27  -26  -25  -24  -23   50   55   60   65   70   75   80   85   90   95  100  105  110
9:  -39  -38  -37  -36  -35  -34  -33  -32   50   55   60   65   70   75   80   85   90   95  100  105
10:  -49  -48  -47  -46  -45  -44  -43  -42  -41   50   55   60   65   70   75   80   85   90   95  100
11:  -59  -58  -57  -56  -55  -54  -53  -52  -51  -50   50   55   60   65   70   75   80   85   90   95
12:  -69  -68  -67  -66  -65  -64  -63  -62  -61  -60  -59   50   55   60   65   70   75   80   85   90
13:  -79  -78  -77  -76  -75  -74  -73  -72  -71  -70  -69  -68   50   55   60   65   70   75   80   85
14:  -89  -88  -87  -86  -85  -84  -83  -82  -81  -80  -79  -78  -77   50   55   60   65   70   75   80
15:  -99  -98  -97  -96  -95  -94  -93  -92  -91  -90  -89  -88  -87  -86   50   55   60   65   70   75
16: -109 -108 -107 -106 -105 -104 -103 -102 -101 -100  -99  -98  -97  -96  -95   50   55   60   65   70
17: -119 -118 -117 -116 -115 -114 -113 -112 -111 -110 -109 -108 -107 -106 -105 -104   50   55   60   65
18: -129 -128 -127 -126 -125 -124 -123 -122 -121 -120 -119 -118 -117 -116 -115 -114 -113   50   55   60
19: -139 -138 -137 -136 -135 -134 -133 -132 -131 -130 -129 -128 -127 -126 -125 -124 -123 -122   50   55
20: -149 -148 -147 -146 -145 -144 -143 -142 -141 -140 -139 -138 -137 -136 -135 -134 -133 -132 -131   50

I've converted the value, so it now shows the chance that the dispel will work. Rows are caster_level, columns are dispel_level.

 

So yes, your chance to dispel a higher level effect is nearly always zero. But a higher level dispel shouldn't always be successful. (I guess you got unlucky there. Could also be the random number generator.)

 

Here comes an exe patch to fix the issue:

/Edit: Adjusted to fix the issue discussed below.

BACKUP dispel_fix
AUTHOR me

BEGIN ~Fix dispel effect~
INSTALL_BY_DEFAULT

OUTER_PATCH_SAVE orig_bytes_1 ~~ BEGIN
INSERT_BYTES 0x000 0xe
WRITE_LONG   0x000 0x8b0ac06b
WRITE_LONG   0x004 0xe1811c4d
WRITE_LONG   0x008 0x000000ff
WRITE_SHORT  0x00c 0xc12b
END

OUTER_PATCH_SAVE patch_bytes_1 ~~ BEGIN
INSERT_BYTES 0x000 0xe
WRITE_LONG   0x000 0x811c4d8b
WRITE_LONG   0x004 0x0000ffe1
WRITE_LONG   0x008 0x6bc12b00
WRITE_SHORT  0x00c 0x0ac0
END

OUTER_PATCH_SAVE orig_bytes_2 ~~ BEGIN
INSERT_BYTES 0x000 0x12
WRITE_LONG   0x000 0x7ff4553b
WRITE_LONG   0x004 0x18458b0d
WRITE_LONG   0x008 0x0000ff25
WRITE_LONG   0x00c 0x63f88300
WRITE_SHORT  0x010 0x097e
END

OUTER_PATCH_SAVE patch_bytes_2 ~~ BEGIN
INSERT_BYTES 0x000 0x12
WRITE_LONG   0x000 0x7463fa83
WRITE_LONG   0x004 0x18458b0d
WRITE_LONG   0x008 0x0000ff25
WRITE_LONG   0x00c 0xf4453b00
WRITE_SHORT  0x010 0x097c
END

COPY bgmain.exe bgmain.exe
READ_ASCII 0x00143f42 target_bytes_1 ELSE 0 (0xe)
READ_ASCII 0x00143f97 target_bytes_2 ELSE 0 (0x12)
PATCH_IF (~%target_bytes_1%~ STRING_EQUAL ~%orig_bytes_1%~)
	 AND (~%target_bytes_2%~ STRING_EQUAL ~%orig_bytes_2%~)
THEN BEGIN
	WRITE_ASCIIE 0x00143f42 ~%patch_bytes_1%~ (0xe)
	WRITE_ASCIIE 0x00143f97 ~%patch_bytes_2%~ (0x12)
END ELSE PATCH_PRINT ~Target bytes don't match. Aborting ...~
BUT_ONLY

 

And this should fix the mirror image effect (#119), which currently doesn't copy the caster level to #159. So you are always dispelling against caster level 0.

BACKUP mirrorimage_fix
AUTHOR me

BEGIN ~Fix mirror image effect to keep caster level~
INSTALL_BY_DEFAULT

OUTER_PATCH_SAVE orig_bytes_1 ~~ BEGIN
INSERT_BYTES 0x000 0x1e
WRITE_LONG   0x000 0x8bfc558b
WRITE_LONG   0x004 0x488bd445
WRITE_LONG   0x008 0x484a8948
WRITE_LONG   0x00c 0x8bfc558b
WRITE_LONG   0x010 0x888bd445
WRITE_LONG   0x014 0x000000cc
WRITE_LONG   0x018 0x00cc8a89
WRITE_SHORT  0x01c 0x0000
END

OUTER_PATCH_SAVE patch_bytes_1 ~~ BEGIN
INSERT_BYTES 0x000 0x1e
WRITE_LONG   0x000 0x8bd4558b
WRITE_LONG   0x004 0x4889484a
WRITE_LONG   0x008 0x70c08348
WRITE_LONG   0x00c 0x8b70c283
WRITE_LONG   0x010 0x4889544a
WRITE_LONG   0x014 0x5c4a8b54
WRITE_LONG   0x018 0x905c4889
WRITE_SHORT  0x01c 0x9090
END

COPY bgmain.exe bgmain.exe
READ_ASCII 0x00121184 target_bytes_1 ELSE 0 (0x1e)
PATCH_IF (~%target_bytes_1%~ STRING_EQUAL ~%orig_bytes_1%~)
THEN BEGIN
	WRITE_ASCIIE 0x00121184 ~%patch_bytes_1%~ (0x1e)
END ELSE PATCH_PRINT ~Target bytes don't match. Aborting ...~
BUT_ONLY

Link to comment

Taimon I think I'm going to build a statue in your honor. Can I add these fixes to SR V3? :)

 

Looking at the "Mirror Image not always dispelled" thing I've started to dream a .exe patch that would be utterly great imo.

 

Can you do the same to make items created via spell (such as touch spells, Melf Minute Meteors, BBoD, ...) not always dispelled? They currently are dispelled with a 100% chance even by a 1st level caster. If you can make them not affected at all is even better for me as that would allow me to fix all shapeshifting abilities once and for all! :rolleyes:

 

 

P.S I'm also curious about this: "And this should fix the mirror image effect (#119), which currently doesn't copy the caster level to #159. So you are always dispelling against caster level 0". Within SR instead of using (119) I directly use (159) because it allows me to select the exact number of images. Does your statement means that the problem was (119) while (159) on its own is ok?

Link to comment
Guest temujin_

Jeezus.

 

Taimon is truly the unrivaled, consummate cognoscente of the entire realm of modding. There can be no more doubt!

 

 

how do you do it, Taimon? how do you go about venturing into this unknown world of EXE patching/disassembling and find and fix things in the blink of an eye? HOW???!!! :rolleyes:

 

 

I'm amazed.

Link to comment
Guest amanasleep

WOW!!!!!!!

:rolleyes::):D :D

 

I honestly thought it would turn out to be something caused by my install or testing setup, and not an honest-to-goodness bug in vanilla. That is pretty major. I am really looking forward to using dispel correctly now. I think that this will have a significant and positive impact on gameplay for everybody, since I know a lot of people despair of trying to dispel in combat (they assume that the target must be >5 levels higher, when they might only have been 1). Conversely, this makes lower level AI casters more formidable, as they now have a chance to affect the party.

 

My testing was not especially extensive. Since the higher level test is better than 50/50, it's definitely plausible that I got lucky 10 times in a row. Since my initial test I have gotten results in normal play that show higher level dispel is not automatic (1st dispel attempt fail, 2nd success, then checked CRE to verify that target was lower level).

 

I assume these patches will be in the next Fixpack version. Is there an ETA on that?

 

Along with Demivrgvs, I'd like to see the fix where dispel no longer automatically affects magically created weapons including shapechange/polymorph claws, as it produces weird exploits where you can polymorph into a creature with beneficial attacks, etc. and then dispel the claws intentionally (or the AI does it for you) allowing you to continue to attack with an equipped weapon.

 

I believe dispel also automatically takes out Project Image clones (although this kind of perversely balances them) and maybe some other things as well.

 

Once again, thank you thank you thank you.

Link to comment

Cool stuff, but I need to check on a few things because I think there is the possibility that folks may think this works on all distributed BGMain.exe - they tend not to read the whole statement, and you say right up front this is for ToB (and your distribution)

 

Taimon, this works with ToB's .exe - how can we find out if there are significant differences between the .exe distributions of SoA, EasyTutu, the .exe after Ascension64's charm fix, etc? What about the OS X BGMain.exe?

 

I see that you have the failsafe set, but I strongly suspect that folks are going to want a universal fix.

Link to comment

Now, the only thing we need to fix with the spell is to make it's power level 3 instead of (1)0, and then make the table more dispelling at any level.

 

Why, cause the spell can dispel a 10th level spell as easily as the 1st if the caster was the same, which is a bit off in my mind, but that's a tweak, not a fix...

Link to comment
Can I add these fixes to SR V3?

I already told you my IE stuff is free for all. :rolleyes:

Go ahead, but I'd suggest some more testing.

 

Can you do the same to make items created via spell (such as touch spells, Melf Minute Meteors, BBoD, ...) not always dispelled?

No idea, haven't look at it yet.

 

Does your statement means that the problem was (119) while (159) on its own is ok?

Yes!

 

Taimon is [...]

You are forgetting all the other people that contributed to the IESDP. It made reversing so much easier.

And this feels more like hacking than modding.

 

I assume these patches will be in the next Fixpack version.

I don't think the Fixpack will include exe hacks. (But that's up to the Fixpack devs.)

 

how can we find out if there are significant differences between the .exe distributions of SoA, EasyTutu, the .exe after Ascension64's charm fix, etc?

Do it like Asc64 does: Take a little more context at the target offset and do some pattern matching in a specific region.

 

What about the OS X BGMain.exe?

Nope.

 

Taimon, is it possible to gather all of your tweaks and fixes somewhere together? It's not likely Bioware is going to choke it with lawsuits, the game is 10 years old already.

You never know. :)

Link to comment
Guest amanasleep
(All of the following only applies to the patched ToB version. I have no idea if the other versions work the same.)

 

This is roughly how the dispel effect works:

base_chance = 50
if (caster_level <= dispel_level)
chance = base_chance + 5 * (caster_level - dispel_level)
else
chance = base_chance + 10 * caster_level - dispel_level

rand = rand(0,100)  // [0;99]
if (rand == 0)	  -> no dispel
if (rand > chance)  -> dispel
else				-> no dispel

Looks like someone forgot the brackets ...

caster_level is the caster level of the effect that should be dispelled. And dispel_level is obviously the level of the dispel, so either the caster level of the dispeller or param1 of the dispel effect.

 

Hm, correct me if I'm wrong, but looking at the formula above, it does not seem that it will provide the 1% minimum chance of success even if the brackets are correctly applied.

 

If: Caster Level = 5 and Dispel Level =15 then Caster Level <= Dispel Level

 

So: Chance = 50 + 5 * (5 - 20) = -25

 

Since Random has values from 0-99, and rand == 0 -> no dispel, and rand > chance -> dispel, there is a 99% chance of dispel and 1% chance of no dispel. This is true for all values of chance from -infinity to 0.

 

If: Caster Level =15 and Dispel Level = 5 then Caster Level > Dispel Level

 

So: Chance = 50 +10 * (15 - 5) = 150

 

In this case, no possible values of Random > Chance, so there is a 100% chance of no dispel. This is true for all values of chance > 98.

Link to comment
If: Caster Level =15 and Dispel Level = 5 then Caster Level > Dispel Level

 

So: Chance = 50 +10 * (15 - 5) = 150

If: Caster Level = 5 and Dispel Level =15 then Caster Level <= Dispel Level then it goes with:
chance = base_chance + 10 * caster_level - dispel_level
So it's:

50 + 15 * 10 - 5 = 195... :rolleyes:

 

So perhaps it should be the other way around:

 

If Caster Level > Dispel Level, chance = base_chance + 5 * (caster_level - dispel_level)

While;

If Caster Level < Dispel Level, chance = base_chance + 10 * caster_level - dispel_level

 

So with CL= 10, and DL= 15

If Caster Level < Dispel Level, chance = base_chance + 10 * caster_level - dispel_level

=> 50 + 10*10 -15 = 135 = 100

 

And with CL= 15, and DL= 10

If Caster Level > Dispel Level, chance = base_chance + 5 * (caster_level - dispel_level)

=> 50 + 5 * (15 - 10) = 50 +5*5 = 75

:)

 

This goes all as it should cause the caster level is the one that's is tried to be dispelled, and the dispel level is the dispel's character level.

Link to comment
Guest Guest
Taimon is [...]

You are forgetting all the other people that contributed to the IESDP. It made reversing so much easier.

And this feels more like hacking than modding.

I didn't forget anyone. :rolleyes:

 

While it's true that several others contributed to IESDP, there were only very, very few (in nearly a decade!) that boldly dared to reverse engineer the .exe, and even they didn't do it as quickly and swiftly the way you do. You don't have to be so modest. Anyway, I wasn't meaning to put them down (they were the pioneers after all); it's just you do all these fascinating things that makes me wonder whether your brain is far too evolved for this generation. headscratch130.gif

 

 

But you've opened a Pandora's box now.

 

Soon, you'll have many asking you to "unlock/disable/change" certain aspects of the game.

 

 

 

 

(Personally, I'd love to see the no. of kits per class raised a little higher.)

Link to comment
So it's:

50 + 15 * 10 - 5 = 195...

 

So perhaps it should be the other way around:

The higher the 'Chance' value is the lower the rate of success is:

rand = rand(0,100) // [0;99]

 

if (rand > chance) -> dispel

Link to comment
Hm, correct me if I'm wrong, but looking at the formula above, it does not seem that it will provide the 1% minimum chance of success even if the brackets are correctly applied.

I agree.

There is an additional check in the exe that I did left out in my report, because I don't think it can happen at all:

if (rand == 0)	  -> no dispel
if (rand > chance)  -> dispel
if (rand > 99)	  -> dispel
else				-> no dispel

Since max(rand) is 99, there is no way that rand can be greater than 99. I guess the programmer thought rand(0, 100) gives values in the range of 0..100 or 1..100 instead of the actual 0..99.

That also explains why he choose "rand > chance" (unbalanced if chance == 50) instead of "rand >= chance".

So I'm changing this to:

if (rand == 0)	  -> no dispel
if (rand == 99)	 -> dispel
if (rand >= chance) -> dispel
else				-> no dispel

Updated the patch in my first post.

I also made a mistake in the previous patch, were I was referencing the wrong variable. That's what you get when you only deal with numbers instead of names.

 

Soon, you'll have many asking you to "unlock/disable/change" certain aspects of the game.

That's what I fear. :rolleyes:

(Personally, I'd love to see the no. of kits per class raised a little higher.)

Sounds like GUI stuff, which I'm not touching for the moment.

 

 

By the way, you'd be surprised how many people do this reverse engineering stuff, especially in the computer security branch. It's not as hard as most people think it is. (But it really takes time.)

 

Small anecdote:

I came across a bug, that's highly unlikely to happen, but I spotted it in the exe and tried to "produce" it.

Give your character a bag of holding and put an item inside. Now trigger a GiveItem action (#15) on your character that gives that item to someone else. Lastly, advance the level of your character to ToB range, so that he gains new innate abilities. (He has to have more than 10 after that. If he already had more than 10, he has to have more than 20.)

Your game should crash now. :)

Link to comment

Archived

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

×
×
  • Create New...