Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Axis & Allies 1942 Online is now available in Early Access! Buy it on Steam. The FAQ is available.
New Premium Module: Tyrants of the Moonsea! Read More
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

[(BGEE, BG2) Bug] Larloch's minor drain, vampiric touch bugs

CamDawgCamDawg Member, Developer Posts: 3,394
edited August 2012 in Fixed
This one's complicated, and straight out of the Fixpack:
Larloch's Minor Drain and Vampiric Touch were healing the caster, even if the target was not affected due to magic resistance. Both spells now only heal the caster if the target is affected. This also fixes an additional bug of Vampiric Touch being able to boost the caster's multiple times through multiple castings, though the description explicitly states this shouldn't happen. This also fixes a damage bug with the innate version of this spell (the one added as a Bhaalspawn ability and used by Foebane on hit) where it did 1d4 damage instead of 4 points, per its description.
So, if you cast LMD (spwi119), this is what happens:
  1. Provide an immunity to the caster to the spell just cast (spwi119), preventing self-casting and preventing the steps 2+
  2. Cast spwi119a on the original target, but this spell is subject to a magic resistance check on the target. A failed MR check then continues on to step 3
  3. If the target fails their MR check, then run the damage on target, bonus HP on caster
For vampiric touch, the HP gain is actually shuffled into a third spell that also provides the timeout to prevent the spell from being re-cast, per the spell description.

It's also old code, so it's full of cruft but functional.
// vamp touch fixes
COPY_EXISTING ~spin106.spl~ ~override/spin106a.spl~ // innate vamp touch
~spin106.spl~ ~override/spin106b.spl~ // innate vamp touch
~spin997.spl~ ~override/spin997a.spl~ // innate vamp touch
~spin997.spl~ ~override/spin997b.spl~ // innate vamp touch
~spwi314.spl~ ~override/spwi314a.spl~ // mage vamp touch
~spwi314.spl~ ~override/spwi314b.spl~ // mage vamp touch
WRITE_LONG NAME1 0xffffffff
WRITE_LONG NAME2 0xffffffff
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
READ_LONG 0x6a "fx_off"
PATCH_IF ("%DEST_RES%" STRING_COMPARE_REGEXP "^.+b$" = 0) BEGIN
SET "self" = 1
END ELSE BEGIN
SET "self" = 0
END
SET "fx_delta" = 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"
SET "abil_fx_idx" = "%abil_fx_idx%" + "%fx_delta%"
WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%index%")) "%abil_fx_idx%"
WRITE_SHORT ("%abil_off%" + 0x26 + (0x28 * "%abil_num%")) 1 // removes projectile
FOR (index2 = 0 ; index2 < abil_fx_num ; index2 = index2 + 1) BEGIN
READ_BYTE ("%fx_off%" + 0x02 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "target"
PATCH_IF ("%target%" = 2) BEGIN // preset target
PATCH_IF ("%self%" = 0) BEGIN
READ_BYTE ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "dispel"
PATCH_IF ("%dispel%" = 1) BEGIN // if dispel/not bypass
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 3 // make dispel/bypass
END ELSE
PATCH_IF ("%dispel%" = 2) BEGIN // if not dispel/not bypass
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0 // make not dispel/bypass
END
END ELSE BEGIN
DELETE_BYTES ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0x30 // delete effect
SET "index2" = "%index2%" - 1
SET "abil_fx_num" = "%abil_fx_num%" - 1
SET "fx_delta" = "%fx_delta%" - 1
END
END ELSE
PATCH_IF ("%target%" = 1) BEGIN // target: self
PATCH_IF ("%self%" = 0) BEGIN // non-self spell
DELETE_BYTES ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0x30 // delete effect
SET "index2" = "%index2%" - 1
SET "abil_fx_num" = "%abil_fx_num%" - 1
SET "fx_delta" = "%fx_delta%" - 1
END ELSE BEGIN
READ_BYTE ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%index2%"))) "opcode"
PATCH_IF ("%opcode%" = 206) BEGIN
WRITE_ASCII ("%fx_off%" + 0x1b + (0x30 * ("%abil_fx_idx%" + "%index2%"))) ~b~ // changes from spwi314 to spwi314b
END
END
END
END
PATCH_IF ("%self%" = 0) BEGIN // if a, insert cast spell b
INSERT_BYTES ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 0x30
WRITE_SHORT ("%fx_off%" + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 146 // cast spell
WRITE_BYTE ("%fx_off%" + 0x02 + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 1 // target self
WRITE_LONG ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) "%min_lev%" // cast at level
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 1 // cast instantly
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 3 // dispel/bypass resistance
WRITE_LONG ("%fx_off%" + 0x0e + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 300 // duration
WRITE_BYTE ("%fx_off%" + 0x12 + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) 100 // probability
WRITE_ASCIIE ("%fx_off%" + 0x14 + (0x30 * ("%abil_fx_idx%" + "%abil_fx_num%"))) ~%SOURCE_RES%b~ // spell
SET "abil_fx_num" = "%abil_fx_num%" + 1
SET "fx_delta" = "%fx_delta%" + 1
END
WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%index%")) "%abil_fx_num%"
END
BUT_ONLY_IF_IT_CHANGES

// larloch minor drain fixes
COPY_EXISTING ~spin104.spl~ ~override/spin104a.spl~ // innate LMD
~spwi119.spl~ ~override/spwi119a.spl~ // mage LMD
WRITE_LONG NAME1 0xffffffff
WRITE_LONG NAME2 0xffffffff
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
READ_LONG 0x6a "fx_off"
READ_SHORT ("%abil_off%" + 0x1e + (0x28 * ("%abil_num%" - 1))) "abil_fx_num"
READ_SHORT ("%abil_off%" + 0x20 + (0x28 * ("%abil_num%" - 1))) "abil_fx_idx"
SET "total_fx" = ("%abil_fx_idx%" + "%abil_fx_num%")
WHILE ("%abil_num%" > 0) BEGIN
SET "abil_num" = ("%abil_num%" - 1)
WRITE_SHORT ("%abil_off%" + 0x26 + (0x28 * "%abil_num%")) 1 // removes projectile
END
WHILE ("%total_fx%" > 0) BEGIN
SET "total_fx" = ("%total_fx%" - 1)
READ_BYTE ("%fx_off%" + 0x0d + (0x30 * "%total_fx%")) "dispel"
PATCH_IF ("%dispel%" = 1) BEGIN // if dispel/not bypass
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * "%total_fx%")) 3 // make dispel/bypass
END ELSE
PATCH_IF ("%dispel%" = 2) BEGIN // if not dispel/not bypass
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * "%total_fx%")) 0 // make not dispel/bypass
END
END
BUT_ONLY_IF_IT_CHANGES

// innate LMD should do fixed damage of 4, not 1d4
COPY_EXISTING ~spin104a.spl~ ~override~
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 (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%" = 12) BEGIN // damage opcode
WRITE_LONG ("%fx_off%" + 0x04 + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 4 // fixed damage
WRITE_LONG ("%fx_off%" + 0x1c + (0x30 * ("%abil_fx_idx%" + "%index2%"))) 0 // number of dice
END
END
END
BUT_ONLY_IF_IT_CHANGES

// makes MR-checking "shell" spell that also eliminates self-cast exploit
COPY_EXISTING ~spin104.spl~ ~override~ // innate LMD
~spin106.spl~ ~override~ // innate vamp touch
~spin997.spl~ ~override~ // innate vamp touch
~spwi119.spl~ ~override~ // mage LMD
~spwi314.spl~ ~override~ // mage vamp touch
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
READ_LONG 0x6a "fx_off"
READ_SHORT 0x70 "fx_num"
PATCH_IF ((~%SOURCE_RES%~ STRING_COMPARE_CASE "spin104" = 0) OR
(~%SOURCE_RES%~ STRING_COMPARE_CASE "spwi119" = 0)) BEGIN
SET "power" = 1
END ELSE BEGIN
SET "power" = 3
END
WHILE ("%abil_num%" > 0) BEGIN
SET "abil_num" = ("%abil_num%" - 1)
READ_SHORT ("%abil_off%" + 0x10 + (0x28 * "%abil_num%")) "level"
READ_SHORT ("%abil_off%" + 0x1e + (0x28 * "%abil_num%")) "abil_fx_num"
WRITE_SHORT ("%abil_off%" + 0x1e + (0x28 * "%abil_num%")) 2
READ_SHORT ("%abil_off%" + 0x20 + (0x28 * "%abil_num%")) "abil_fx_idx"
WRITE_SHORT ("%abil_off%" + 0x20 + (0x28 * "%abil_num%")) ("%abil_num%" * 2)
DELETE_BYTES ("%fx_off%" + (0x30 * "%abil_fx_idx%")) (0x30 * "%abil_fx_num%") // deletes all effects
INSERT_BYTES ("%fx_off%" + (0x30 * "%abil_fx_idx%")) 0x30 // cast actual spell
WRITE_SHORT ("%fx_off%" + (0x30 * "%abil_fx_idx%")) 146 // cast spell
WRITE_BYTE ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 2 // target: preset target
WRITE_BYTE ("%fx_off%" + 0x03 + (0x30 * "%abil_fx_idx%")) "%power%" // power
WRITE_LONG ("%fx_off%" + 0x04 + (0x30 * "%abil_fx_idx%")) "%level%" // cast at level
WRITE_LONG ("%fx_off%" + 0x08 + (0x30 * "%abil_fx_idx%")) 1 // cast instantly
WRITE_BYTE ("%fx_off%" + 0x0c + (0x30 * "%abil_fx_idx%")) 1 // instant/permanent
WRITE_BYTE ("%fx_off%" + 0x0d + (0x30 * "%abil_fx_idx%")) 1 // dispel/not bypass
WRITE_BYTE ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100 // probability
WRITE_EVALUATED_ASCII ("%fx_off%" + 0x14 + (0x30 * "%abil_fx_idx%")) ~%SOURCE_RES%a~ // spell
INSERT_BYTES ("%fx_off%" + (0x30 * "%abil_fx_idx%")) 0x30 // prevent self-casting
WRITE_SHORT ("%fx_off%" + (0x30 * "%abil_fx_idx%")) 206 // spell immunity
WRITE_BYTE ("%fx_off%" + 0x02 + (0x30 * "%abil_fx_idx%")) 1 // target: self
WRITE_BYTE ("%fx_off%" + 0x03 + (0x30 * "%abil_fx_idx%")) 0 // power
WRITE_BYTE ("%fx_off%" + 0x12 + (0x30 * "%abil_fx_idx%")) 100 // probability
WRITE_EVALUATED_ASCII ("%fx_off%" + 0x14 + (0x30 * "%abil_fx_idx%")) ~%SOURCE_RES%~ // spell: self
END
PATCH_IF ("%fx_num%" > 0) BEGIN // eliminates global fx
DELETE_BYTES "%fx_off%" (0x30 * "%fx_num%")
WRITE_SHORT 0x70 0
END
BUT_ONLY_IF_IT_CHANGES

Post edited by Bhryaen on
AndreaColombo

Comments

Sign In or Register to comment.