Skip to content

[(BGEE, BG2) Bug] Cone of Cold

CamDawgCamDawg Member, Developer Posts: 3,438
edited August 2012 in Fixed
Internet went out Friday evening and just got restored, so I'm back to spamming spell fixes.

Cone of Cold has a bevy of minor errors. The range is incorrect at level 9, there's no level 10 header (so when cast at level 10, it does damage as if cast at 9) and the save vs. half damage is wonky. Normally for spells with save for half damage, the damage is split into two separate damage opcodes, and on odd damages (i.e. 11d4) it was split 5d4 and 6d4. Sometimes the extra 1d4 would be saveable, sometimes not, so this patch also makes the split consistent throughout all levels of the spell.
// cone of cold missing level 10 ability header, wrong range at level 9, inconsistent save v non-save damage split
COPY_EXISTING ~spwi503.spl~ ~override~
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
READ_LONG 0x6a "fx_off"
READ_SHORT 0x70 "fx_num"
SET "lev10_exist" = 0
SET "new_abil" = 0
FOR (index = 0 ; index < abil_num ; index = index + 1) BEGIN
READ_SHORT ("%abil_off%" + 0x10 + (0x28 * "%index%")) "min_lev"
READ_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) "abil_fx_num"
READ_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) "abil_fx_idx"
PATCH_IF ("%min_lev%" = 1) BEGIN
SET "min_lev" = 9
END
FOR (index2 = 0 ; index2 < abil_fx_num ; index2 = index2 + 1) BEGIN
READ_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "opcode"
PATCH_IF ("%opcode%" = 12) BEGIN // damage
READ_LONG ("%fx_off%" + 0x24 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "save"
PATCH_IF ("%save%" = 0) BEGIN
WRITE_BYTE ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) (("%min_lev%" + 1) / 2) // damage
WRITE_BYTE ("%fx_off%" + 0x1c + (0x30 * ("%abil_fx_idx%" + "%index2%"))) ("%min_lev%" / 2) // damage
END ELSE BEGIN
WRITE_BYTE ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) ("%min_lev%" / 2) // damage
WRITE_BYTE ("%fx_off%" + 0x1c + (0x30 * ("%abil_fx_idx%" + "%index2%"))) (("%min_lev%" + 1) / 2) // damage
END
END
END
PATCH_IF ("%min_lev%" = 9) BEGIN // if first header
WRITE_SHORT ("%abil_off%" + 0x0e + (0x28 * "%index%")) 12 // corrects range
READ_ASCII ("%abil_off%" + (0x28 * "%index%")) "abil_clone" (0x28)
READ_ASCII ("%fx_off%" + (0x30 * ("%abil_fx_idx%"))) "fx_clone" (0x30 * "%abil_fx_num%")
SET "new_fx" = "%abil_fx_num%"
SET "start_fx" = ("%abil_fx_idx%" + "%abil_fx_num%")
SET "insert" = ("%abil_off%" + (0x28 * ("%index%" + 1)))
END ELSE
PATCH_IF ("%min_lev%" = 10) BEGIN
SET "lev10_exist" = 1
END
END
PATCH_IF ("%lev10_exist%" = 0) BEGIN
SET "level" = 10
INSERT_BYTES (("%fx_off%" + (0x28 * "%new_abil%")) + (0x30 * ("%start_fx%" * ("%new_abil%" + 1)))) (0x30 * "%new_fx%")
WRITE_EVALUATED_ASCII (("%fx_off%" + (0x28 * "%new_abil%")) + (0x30 * ("%start_fx%" * ("%new_abil%" + 1)))) "%fx_clone%"
FOR (index2 = 0 ; index2 < new_fx ; index2 = index2 + 1) BEGIN
READ_SHORT (("%fx_off%" + (0x28 * "%new_abil%")) + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) "opcode"
PATCH_IF ("%opcode%" = 12) BEGIN // damage
READ_LONG (("%fx_off%" + (0x28 * "%new_abil%")) + 0x24 + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) "save"
PATCH_IF ("%save%" = 0) BEGIN
WRITE_BYTE (("%fx_off%" + (0x28 * "%new_abil%")) + 0x04 + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) (("%level%" + 1) / 2) // damage
WRITE_BYTE (("%fx_off%" + (0x28 * "%new_abil%")) + 0x1c + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) ("%level%" / 2) // damage
END ELSE BEGIN
WRITE_BYTE (("%fx_off%" + (0x28 * "%new_abil%")) + 0x04 + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) ("%level%" / 2) // damage
WRITE_BYTE (("%fx_off%" + (0x28 * "%new_abil%")) + 0x1c + (0x30 * ("%index2%" + "%start_fx%" + ("%new_abil%" * "%new_fx%")))) (("%level%" + 1) / 2) // damage
END
END
END
INSERT_BYTES ("%insert%" + (0x28 * "%new_abil%")) 0x28
WRITE_EVALUATED_ASCII ("%insert%" + (0x28 * "%new_abil%")) "%abil_clone%"
WRITE_SHORT (("%insert%" + (0x28 * "%new_abil%")) + 0x10) "%level%"
WRITE_SHORT (("%insert%" + (0x28 * "%new_abil%")) + 0x1e) "%new_fx%"
SET "new_abil" = "%new_abil%" + 1
END
PATCH_IF ("%new_abil%" > 0) BEGIN
SET "abil_num" = ("%abil_num%" + "%new_abil%")
WRITE_SHORT 0x68 "abil_num"
WRITE_LONG 0x6a ("%fx_off%" + (0x28 * "%new_abil%"))
// re-index everything
FOR (index = 0 ; index < abil_num ; index = index + 1) BEGIN
WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) "%fx_num%"
READ_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) "abil_fx_num"
SET "fx_num" = "%fx_num%" + "%abil_fx_num%"
END
END
BUT_ONLY_IF_IT_CHANGES
Post edited by Bhryaen on
AndreaColombo

Comments

  • CorianderCoriander Member Posts: 1,667
    This one is going in.
  • NathanNathan Member Posts: 1,007
    Verified, this has been integrated internally and should be present in the next build.
  • GalactygonGalactygon Member, Developer Posts: 412
    Also, the area of effect of the cone is incorrect, which is supposed to be "a cone five feet long and one foot in diameter per level of the caster" as per the description. At the moment CONECOLD.pro is the only projectile used, which is a cone 90 degrees wide and radius of 30' (yards?).

    Desired fix:
    The cone would have an angle of roughly 12 degrees, with an area of effect that changes with the caster level. Either do this with multiple .pro files or add a flag in the area effect header of the .pro file format to enable the caster level to be used as a multiple with the radius.

    Note that narrow area effect projectiles are tricky to target becuse they have to hit the exact coordinate the target is standing on, it is not enough if the projectile area effect overlaps with the foot circle of the creature. Suggestions to this fix:
    a. make the projectile angle a bit wider
    b. change the engine so that area effects overlapping the foot circle is enough (or give some other tolerance)
    c. set the spell to single target rather than area

    -Galactygon
    AndreaColombo
  • CamDawgCamDawg Member, Developer Posts: 3,438
    @Galactygon
    I think we should be able to do this; I'll see what I can bodge together and test. Mods, go ahead and leave the thread here for now, I'll create a new one when I get to it.
    AndreaColombo
  • GalactygonGalactygon Member, Developer Posts: 412
    @CamDawg

    Thanks!

    -G
  • Avenger_teambgAvenger_teambg Member, Developer Posts: 5,862
    I like @Galactygon's idea about a flag for projectile radius modification.
    There is already a flag for repeating explosions by caster level (separate for priest and wizard).
    So another level based flag(s) would fit in. There are also enough flags in the AOE flags bitfield. So this is a "piece of cake".
    AndreaColombo
  • GalactygonGalactygon Member, Developer Posts: 412
    I was thinking about that too - but the existing number of explosions flag ignores the number of explosions at 0x216, which isn't flexible enough if you want say, 5 explosions per level.

    -Galactygon
    AndreaColombo
  • Avenger_teambgAvenger_teambg Member, Developer Posts: 5,862
    Confirmed fixed - checked in editor
  • BhryaenBhryaen Member Posts: 2,874
    edited August 2012
    Cone of Cold has a bevy of minor errors. The range is incorrect at level 9, there's no level 10 header (so when cast at level 10, it does damage as if cast at 9) and the save vs. half damage is wonky. Normally for spells with save for half damage, the damage is split into two separate damage opcodes, and on odd damages (i.e. 11d4) it was split 5d4 and 6d4. Sometimes the extra 1d4 would be saveable, sometimes not, so this patch also makes the split consistent throughout all levels of the spell.
    Confirmed Fixed (?)

    SPWI503-
    1. Range for Spell Ability #0 changed from 8 (BG2) to 12, though the "Minimum level" is set to 1- even in BG2, not 9. Not sure if this bodes ill or no.
    2. A 10th level Spell ability has been added to roster.
    3. All Spell Ability levels have consistently two sections for damage, one automatic, the other that can be Saved against (vs Spells). The extra 1d4 dam for uneven splits has been allotted to the Savable portion.
  • CamDawgCamDawg Member, Developer Posts: 3,438
    Bhryaen said:


    1. Range for Spell Ability #0 changed from 8 (BG2) to 12, though the "Minimum level" is set to 1- even in BG2, not 9. Not sure if this bodes ill or no.
    All spells are like this--on ninth level spells you may see headers 1, 19, 20. The lowest level ability is always set at level 1 so that if a creature is somehow casting (or scripted to force-cast) a spell without the minimum level the spell will still do something.
  • BhryaenBhryaen Member Posts: 2,874
    @CamDawg
    I'll take your word for it. :-) Explains why you wanted a Lvl10 version since the minimum level mage to get the 5th lvl spell is actually 9. So a scroll of this actually casts at the equivalent of Lvl9- i.e. rather than the usual 6th?
  • CamDawgCamDawg Member, Developer Posts: 3,438
    In BG2, yeah, scrolls cast at level 10. It looks like BGEE has moved scroll casting down to level six, presumably for balance.
Sign In or Register to comment.