Vampiric Touch

Discussion in 'General Modification' started by Raaagh, Aug 14, 2004.

Remove all ads!
  1. Raaagh

    Raaagh Member

    Joined:
    Dec 4, 2003
    Messages:
    46
    Likes Received:
    0
    Since Vampiric Touch was broken (doesn't give you hitpoints), I was spending some time trying to fix it tonight, and here's the results.

    (Please rename to .py and place in the data\scr folder)

    Note that you need to add a line in spell.mes:

    {30020} {Touch attack missed!}

    It's currently in version 0.1 because of the following:

    1) This spell is unfair right now. Currently, you can drain hit points and keep them infinitely. I haven't figured out a way to remove the hitpoints yet.
    2) The touch attack used is done from the ranged touch attack function, which grants dex bonuses to the attack.
    3) You can't hold the charge infinitely, like other touch charge spells. (actually, I'm not sure about this ruling, but PHB 176 seems to indicate so) The spell, as of now, must be performed at touch range and is instantaneous.
     

    Attached Files:

  2. Raaagh

    Raaagh Member

    Joined:
    Dec 4, 2003
    Messages:
    46
    Likes Received:
    0
    You will need this fix too. It fixes the range and targets for Vampiric Touch. Please place in data\rules\spells

    Actually, I found that ToEE now recognizes files in the root directory too!! Gave me a heart attack when I tried to reverse my changes and just moved the files into the root directory. :roll:
     

    Attached Files:

  3. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Nice to see you back Raaagh. :)
    The touch spells have always been problematic so it's really nice to see something done to fix them.

    First off, you can upload files as .zip format instead of .txt
    Sometimes changing the extension may result in loss of function.

    You mentioned that Vampiric Touch currently uses ranged touch attack function, which grants dex bonuses to the attack. Is this also the case for Ghoul Touch and Chill Touch? It should be melee touch attack by the rules.
    Cure/Inflict spells require a melee touch attack IIRC, while an example of a ranged touch attack would be Ray of Enfeeblement or Jaer's balls of fire. I believe these are implemented correctly, so maybe we can figure out something by checking the code for these other spells.

    I'll check on the changes when I can. I'm just very busy presently and can spend virtually no time on mods. :(

    Btw any leads on that spawning stuff we were working on a long time ago? I've gotten an invisible creature to spawn as a placeholder for a tome (see Making a Tome thread). Would be great to get that settled and it would fix a few bugs too like Romag not spawning properly near Hedrack(?)
     
  4. Raaagh

    Raaagh Member

    Joined:
    Dec 4, 2003
    Messages:
    46
    Likes Received:
    0
    Oh, no. The current touch spells are using a held charge thing that is accessed by the menu. However, the Vampiric Touch effect is broken, so I had to kind of "brute force" a Vampiric Touch spell. Hence the perform_touch_attack function, which is used by all of the ranged touch attack spells.

    As for the spawning thing, I thought of something a few days ago on the idea. Perhaps it was based on an invisible axis which is determined by how the character is facing.
     
  5. Raaagh

    Raaagh Member

    Joined:
    Dec 4, 2003
    Messages:
    46
    Likes Received:
    0
    Oh, and I forgot to add above: currently the spell does not give you the same amount of hitpoints compared to the damage.
     
  6. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    After going through the code, I think I understand things better now. I can see some of the code is roughly similar to Cure/Inflict spells.

    Regarding the line:
    dice.number = (min(10,(spell.caster_level)/2))

    Could we drop the first pair of brackets for the terms on the right. It doesn't seem to serve much function. Also have you tested with odd numbers for spell.caster_level? I'm a bit worried that the game may not truncate decimals for "spell.caster_level" properly or it may round up the figure wrongly.

    Could you explain a little regarding these 2 lines:
    attack_successful = spell.caster.perform_touch_attack( target.obj )
    if attack_successful == 1 or attack_successful == 2:

    I can see that Ray of Enfeeblement seems to have similar lines but I'm not quite sure how they work.

    I see you have basically cracked touch spells and can simulate them in a .py file without needing to access the original Vampiric Touch code in the exe which is flawed. Details on how Vampiric Touch currently works without your fix is given by Smirg here:
    http://www.ataricommunity.com/forums/showthread.php?&threadid=388146&perpage=30&pagenumber=2

    I was also wondering if we could fix Shocking Grasp. The bug here is that the damage is currently d8 instead of d6

    Following your example, we could code it as:

    dice = dice_new("1d6")
    dice.number = min(5,(spell.caster_level)/2)

    shock_damage = dice

    spell.duration = 1
    target = spell.target_list[0]

    if not (target.obj == spell.caster):

    attack_successful = spell.caster.perform_touch_attack( target.obj )

    if attack_successful == 1 or attack_successful == 2:

    target.obj.spell_damage( spell.caster, D20DT_ELECTRICITY, shock_damage, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id )

    else:
    target.obj.float_mesfile_line( 'mes\\spell.mes', 30020 )

    game.particles( 'Fizzle', target.obj )
    spell.target_list.remove_target( target.obj )

    #target.obj.condition_add_with_args( 'sp-Shocking Grasp', spell.id, spell.duration, 0 )
    target.partsys_id = game.particles( 'sp-Shocking Grasp', target.obj )


    Don't know how the +3 bonus on attack rolls for wearing metal armor can be coded though for Shocking Grasp.

    Ghoul Touch may also merit looking at. According to the rules the charge for these spells should be held indefinitely as long as another spell is not cast. I hope fiddling with spell.duration does not disrupt this. (I notice the original duration for Shocking Grasp is 0)

    Finally regarding the temporary hps for Vampiric Touch (which is supposed to last an hour), does spell.caster.spell_heal() function provide excess hps over the initial score? Does resting take away the excess hps?

    Good to see progress in this area and hope to get those touch spells corrected soon. :D
     
  7. Raaagh

    Raaagh Member

    Joined:
    Dec 4, 2003
    Messages:
    46
    Likes Received:
    0
    Eh? I tested Shocking Grasp a few days ago and it was d6. Let me check again. :)

    And yeah, I was reading the official bug thread back on the atari forums. (I'm mike_the_EE, by the way) My original fix was to just remove the targetting when casting the spell. Then I realized that it dealt incorrect damage and didn't give back hitpoints, so I wanted to fix that too.

    And concerning the dice rolls, I might have to look at how Flame Strike codes its damage, since Python has an annoying habit of recalling the function every single time if I declared "damage = dice" before and used "damage" later. Currently, Flame Strike declares a damage dice, then another damage placeholder with 0d0, then takes half of the previous dice damage as the bonus.

    And regarding the spell_heal, it currently doesn't grant hps above your maximum, which is really annoying.

    As for spell.duration, that seems to be used for the duration of the effect of Vampiric Touch -- as in, if you drained the hps and how long it would stay. I was testing spell.duration along with spell_heal, and sad to say that it doesn't take away the hps when spell.duration runs out. :(

    I'll hopefully do more work on it tonight.
     
  8. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Any progress here? Would be nice to include these fixes as well as Scorching Ray by moebius2778 in a future update.
     
  9. Nomad_Wanderer

    Nomad_Wanderer Established Member Veteran

    Joined:
    Sep 25, 2003
    Messages:
    305
    Likes Received:
    0
    Which is being collected as we speak.. I'd like to put something out to the community by the middle of October....

    I think we should try to get a release together "no matter what" every 3 months or so.


    (of course I hope we have enough items to release something every 45 days or so)
     
  10. moebius2778

    moebius2778 Member Veteran

    Joined:
    Sep 19, 2004
    Messages:
    59
    Likes Received:
    0
    I did some playing around, and it appears that if you do a target.condition_add_with_args( 'sp-Vampiric Touch', spell.id, spell.duration, x ), then it'll give the target x temporary hit points due to vampiric touch. So that's how you get the extra hit points.

    Unfortunately, it also treats this like a touch attack which means the next attack you make will remove the condition.

    Furthermore, according to the spell description you gain a number of hit points equal to the damage you dealt... hmm... I was going to complain that spell_damage_with_reduction doesn't actually tell you how many hitpoints of damage you did, but it just occurred to me that you can do this instead:

    spell.duration = 600
    old_hp = target.obj.stat_level_get( stat_hp_current )
    target.obj.spell_damage( spell.caster, D20DT_NEGATIVE_ENERGY, dice, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id )
    new_hp = target.obj.stat_level_get( stat_hp_current )
    damage = old_hp - new_hp
    if damage > (old_hp + 10):
    damage = old_hp + 10
    spell.caster.condition_add_with_args( 'sp-Vampiric Touch', spell.id, spell.duration, damage )

    ...also, from what I can see, an attack_successful of 2 is a critical hit, which means you should have a line that says dice.num = 2 in that case. Apparently critical hits on touch attacks do double damage. Go figure.

    Anyways, if the 'sp-Vampiric Touch' condition can be changed to not act as a touch attack, that'll fix Vampiric Touch.

    Err, and I guess it'll still be using the dex modifier for the touch attack.

    And once I get all the bugs out of that chunk of code, it works beau... well, it works. Of course, this does assume that nothing else damages the target inbetween the spell_damage call and the new_hp check. And that it won't go screwy if the target dies due to the damage.
     

    Attached Files:

  11. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Tested the new py file for Vampiric Touch.
    Cast on himself (Sorc) - nothing happened

    Cast on another person (PC) - inflicted 4d6 points of negative energy damage (correct since my Sorc is level 9)
    Tab appears above Sorc's portrait (duration: 600)
    Checked Sorc's hps - still at 20/46

    Cast again on another person - damage confirmed as correct but no drained hps. Sorc's hps - still at 20/46.

    The touch attack also appears to use the Dex modif (like ranged touch attacks), though it is supposed to use Str modif.


    The original code was:
    target_item.obj.condition_add_with_args( 'sp-Vampiric Touch', spell.id, spell.duration, 0 )

    Noticed you substituted spell.caster for target_item.obj
    Any problems here?
     
  12. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Quoting 3.5e SRD:
    Ghoul Touch
    Necromancy
    Level: Sor/Wiz 2
    Components: V, S, M
    Casting Time: 1 standard action
    Range: Touch
    Target: Living humanoid touched
    Duration: 1d6+2 rounds
    Saving Throw: Fortitude negates
    Spell Resistance: Yes
    Imbuing you with negative energy, this spell allows you to paralyze a single living humanoid for the duration of the spell with a successful melee touch attack.
    Additionally, the paralyzed subject exudes a carrion stench that causes all living creatures (except you) in a 10-foot-radius spread to become sickened (Fortitude negates). A neutralize poison spell removes the effect from a sickened creature, and creatures immune to poison are unaffected by the stench.
    Material Component: A small scrap of cloth taken from clothing worn by a ghoul, or a pinch of earth from a ghoul's lair.


    Problems with ToEE implementation:
    1)The Fort saving throw currently doesn't seem to work even though it is made. In other words a successful saving throw will still result in paralysis (so it's a 100% success hold person so long as the melee touch attack connects).
    Suggested fix: Add an additional line to check for Fort

    2)The spell doesn't seem to check for "Living Humanoid" criteria. I was able to paralyze a Drelb (outsider) and also able to paralyze an Ochre Jelly (ooze).
    Suggested fix: Add an additional line to check for Living Humanoid

    if target.obj.is_category_type( mc_type_humanoid ):
    if target.obj.saving_throw_spell( spell.dc, D20_Save_Fortitude, D20STD_F_NONE, spell.caster, spell.id ):


    EDIT: After reading up a little and referring to a few threads, it appears that "humanoid" refers only to types which are strictly classified as humanoid. If there are no objections, I'll be taking off "monstrous humanoid" then as that is considered a separate category.

    duration: can't be easily checked but seems ok. After about 4 or 5 rounds, a Troll paralyzed by my Sorc, reverted to normal and started attacking as usual.

    The carrion stench and sickened effect is certainly implemented.

    When a paralyzed Ooze is hit by an edged weapon, it splits, leaving the original Ooze still paralyzed but the new Ooze is mobile.

    Thoughts?
     
  13. moebius2778

    moebius2778 Member Veteran

    Joined:
    Sep 19, 2004
    Messages:
    59
    Likes Received:
    0
    re:

    Vampiric Touch:

    Actually, if you mouse over the Vampiric Touch spell flag thing on your caster, you'll notice that it says "Temp HPs: <damage done>" after casting Vampiric Touch on someone. Also, if you take damage, the Temp HPs will act as a damage reduction.

    Unfortunately, this will have the incorrect behaviour if you get hit by a Vampiric Touch spell, since you'll do less damage due to damage reduction.

    On the other hand, that means that False Life is also broken, since that's what False Life does. And unfortunately, False Life calculates the number of Temp HPs gained internally, so using False Life to simulate Vampiric Touch's HP gain is right out. Well, right out unless a lot of temple.dll hacking goes on. Hmm...

    As for Ghoul Touch:

    You might be able to modify the OnSpellStruck function - I'm not completely clear as to how much you can actually mess with the effects of the spell from there. Might be worth looking into though. Probably the correct way to handle Vampiric Touch as well.
     
  14. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Re: re:

    Ah, I see. Was thinking the hps would be added straightaway to the caster. If you look at Aid, that does give some additional hps too but IIRC the number of temp hps is also calculated internally.
    :(
    I feel adding the temp hps straightaway is easier to see rather than making it act as a damage reduction but if we can't get the hps to fade away after an hour then I'd favor your implementation. If you download the Raaagh's modifications above for Vampiric Touch, you'll see that the extra hps are applied directly but don't fade away after 1 hour.

    I really appreciate your efforts in deciphering the dll but I think certain things which can be just tackled with Python code should be done that way. For starters, I think its slightly easier to debug, in case we run into problems.
    Of course we may need some dll work for Vampiric Touch after all, since it's pretty badly broken.

    I believe adding this to the script before Ghoul Touch is called should do the trick:
    if target.obj.is_category_type( mc_type_humanoid ):
    if target.obj.saving_throw_spell( spell.dc, D20_Save_Fortitude, D20STD_F_NONE, spell.caster, spell.id ):

    The first "if" will check for category
    The second "if" will check for a Fort saving throw

    Will test it more these few days. Also confirmed that Shocking Grasp is currently d8 (should be d6 damage).
    Might be pretty busy though...

    Meanwhile, you could also try and see whether we can try to meddle with feats by dll hacking (probably start a new thread on it though). For starters, Power Attack is supposed to be selectable only at Str 13 but currently can be selected at Str 12.
    I was wondering if it just involves changing a variable (provided we know where that is in the dll) then we could do it.
     
  15. zhuge

    zhuge Established Member Veteran

    Joined:
    Sep 27, 2003
    Messages:
    484
    Likes Received:
    0
    Did a bit more testing and I think not being able to hold the charge is Ok, if it is cast instantly. And the temp hps are Ok as well, though not immediately obvious, they do fade after an hour.
    So I guess the main problem left is with using Dex as the modifier for the touch attack.

    I guess it also means if we want to change Shocking Grasp from d8 to d6 damage, we'll also have to use Dex as the modifier for the touch attack. :(

    I can't see any way around this, short of hacking the dll as you've already mentioned, so I think we'll use your file. May not be 100% accurate but it sure is a big improvement over the original broken Vampiric Touch, which didn't even do proper damage.

    Also looked at Slay Living which is also supposed to use a melee touch attack but is also uses:
    target.obj.spell_damage
    ...without any checks beforehand (for melee or ranged) which means it's an autohit... much like the cure spells and heal/harm.
    Come to think of it, it doesn't even check whether the target is "living"... but that adding that conditional should be easy.
     
Our Host!