Jump to content

a little more help with my sphere system - AoE spell bugs


subtledoctor

Recommended Posts

There is a nasty bug in my my sphere system: certain AoE spells have their effects multiplied. E.g. in IWDEE I had a druid cast Spike Growth, which is supposed to do 1d4 slashing damage per round. Instead, the spell somehow casts multiple instances of itself (maybe one per enemy?) so every creature takes 1d4 damage about six times per round when they step into the area of effect. So this little 3rd level spell becomes a win-button.

 

I think this has to do with how my mod handles the spell. Certain kits have "focus access" to certain spheres - e.g. a Forest Druid might have focus access to the sphere of Plant, and thus get Spike Growth as a 2nd level spell instead of a 3rd level spell. The way I do this, is to create a new 2nd-level spell with a single effect, using opcode 146 to cast the 3rd-level spell.

 

To create the new 2nd-level spell, I simply clone the original spell (so it has the same icon and everything), use DELETE_EFFECT to remove all of the effects, and then use ADD_SPELL_EFFECT to add the new 146 effect. I copy over the original targeting information at offset 0x9c to make sure that, for instance, the variant Barkskin can be cast on people, and the variant Spike Growth can be cast on an area.

 

But something is going awry. I noticed this effect-multiplication with Spike Growth, and with Cloudburst. I also noticed something weird with my variant of SR's Fire Trap. There, I think it works fine when I target a spot on the floor, btu once I cast it directly at an enemy, and about 7 fire traps shots out, one at each nearby enemy. The enemies were all laid to waste.

 

Does anyone have any idea if this can be solved in an elegant way? (An elegant way meaning, use Weidu to make a new spell that casts the original spell via 146, and have it function for the player exactly like the original spell. I could simply clone the original spell, but that's problematic because the clone won't have an IDS entry; so for instance, a clone of Restoration will fail to solve the Trademeet skinchanger quest.)

 

One thing that pops into my mind is that my current method is using two projectiles - Fire Trap, for instance, uses TRAPGLYP.PRO in the variant spell, and then again in the original spell that gets cast. Maybe that is multiplying the effects? But I'm not sure what to do about that - should the 146 variant use *no* projectile, and if it has none, will the original spell's projectile function properly when it is cast?

 

Any info or wisdom would be appreciated.

Link to comment

Here's the code:

 

COPY_EXISTING ~%spell_res%.spl~ ~override/d5f%spell_num%.spl~ 
     WRITE_LONG 0x34 %flvl%
     READ_BYTE 0x9c spell_target
     LPF DELETE_EFFECT INT_VAR match_probability2=0 END
     LPF ADD_SPELL_EFFECT INT_VAR opcode = 146 target = %spell_target% parameter2 = 1 timing = 9 STR_VAR resource = EVAL ~%spell_res%~ END

%spell_res% and %spell_num% are derived from a RES_NUM_OF_SPELL_NAME on the original spell, and %flvl% is determined elsewhere as one level lower than the the original spell's level (except 1st level spells, which are exempted from this process).

Link to comment

Blech. Removing projectiles from every ability is complicated. The new code looks like this:

COPY_EXISTING ~%spell_res%.spl~ ~override/d5f%spell_num%.spl~ 
     WRITE_LONG 0x34 %flvl%
     READ_LONG 0x64 abil_offset
     READ_SHORT 0x68 "abil_number"
     READ_LONG 0x6a eff_offset
     WHILE ("%abil_number%" > 0) BEGIN
      SET "abil_number" = ("%abil_number%" - 1)
      WRITE_SHORT ("%abil_offset%" + 0x26 + (0x28 * "%abil_number%") 1
     END
     READ_BYTE (%eff_offset% + 0x02) eff_target
     LPF DELETE_EFFECT INT_VAR match_probability2 = 0 END
     LPF ADD_SPELL_EFFECT INT_VAR opcode = 146 target = %eff_target% power = %lvl% parameter2 = 1 timing = 9 STR_VAR resource = EVAL ~%spell_res%~ END

EDIT - ...which gives me a parse error, at the WRITE_SHORT line. Boo.

Link to comment

Only string variables require the explicit variable substitution syntax. For numeric variables you can write

SET "abil_number" = ("%abil_number%" - 1)
WRITE_SHORT ("%abil_offset%" + 0x26 + (0x28 * "%abil_number%")) 1
as

SET abil_number = (abil_number - 1)
WRITE_SHORT (abil_offset + 0x26 + (0x28 * abil_number)) 1
(WeiDU can parse both variants correctly though.)
Link to comment

Thanks, I was VERY tired last night, so missed the closing paren. I used the old-timey phrasing because I was going off CamDawg's old tutorial on item patching.

 

Out of curiosity, do you guys understand better than me how spell targeting works? Here's an example:

 

Cloudburst from IWDification, has its its *ability* target set to "any point within range." Then, in the *effect,* it uses opcode 177 with the target set to "self." Now, this is an AoE spell that is not centered on the caster... so what exactly is that effect target doing?

 

My variant of the spell retains the range, ability target and effect target of the original, so as to keep AoE spells AoE, and touch-based spells touch-based, etc. But that means I have a spell that

- has an ability targeting "any point within range"

- has an effect targeting "self" that uses opcode 146 to cast the Cloudburst .spl

- Cloudburst then has an ability targeting "any point within range"

- ...and an effect targeting "self" that uses opcode 177 to cast an .eff

 

That seems like... well, a lot of places where things could go wrong. I especially worry about targeting "self" with the 146 effect.

Link to comment

I think the IWDification version of the spell uses opcode 177 to call a bunch of invisible creatures to handle the lightning damage. I was looking here at the spell installed by IWDification on BG2EE.

 

I think the IWDEE version of the spell doesn't have to resort to such shenanigans, instead using the new engine to include some of the effcts in the projectile itself (I think). I should say, that I specifically saw this 'effect-multiplication' bug in IWDEE.

 

So I'm hoping that simply removing the projectile from the outer, 'shell' spell (which uses 146 to cast the inner, vanilla spell) fixes the bug. If the lack of a projectile in the outer spell messes up the location targeting, then I might switch to opcode 148 "cast spell at point" per kjeron's suggestion. We'll see.

Link to comment

Damn... this isn't working. I removed the projectile from the outer spell. So now, let's look at SR's 'Fire Trap' as an example. It is a 2nd-level spell at sppr216.spl, and it has seven "abilities" (extended headers, per the IESDP), each with Target = "any point within range (4)" and TRAPGLYP.pro. Each ability has two "effects" (feature blocks, per the IESDP) that use opcode 12 to do fire damage with Target = "preset target (2)"

 

My Fire Mystic has a 1st-level spell, d5f1216.spl, which has 7 abilities; each ability uses Target = "any point within range (4)" but does not use any projectile. Each ability has a single effect, which uses opcode 148 "cast spell at point" to cast sppr216.spl with Target = "preset target (2)"

 

When the Fire Mystic casts the 1st level version of the spell, nothing happens. :( I can't figure it out... it is impossible to use AoE/projectile-based spells via opcode 146/148?

 

EDIT - duh, scrolls do this, so it must work somehow. I'll use them as a reference to see what I'm getting wrong.

Link to comment

Okay, there is still a bit of a problem, with spell range. If you cast a spell within its normal range, it is cast successfully. If you cast a normal spell from beyond its normal range, you will walk toward the target point until you're within range, then cast it.

 

With this kind of opcode 148 'shell' spell, if you cast a spell from outside its range, nothing will happen at all.

Link to comment

Archived

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

×
×
  • Create New...