Some new spells.

Discussion in 'General Modification' started by dolio, Dec 17, 2010.

Remove all ads!
  1. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    So, I decided to try my hand at writing some spells. I attached the .txt and .py for three of them. However, I seem to have encountered problems.

    The third spell I did was wail of the banshee, and once I got past some boneheaded mistakes, that seems to be working fine now (although, I haven't looked into sound effects yet; a banshee scream would be good).

    First, however, I did enervation and energy drain. Enervation doesn't work quite like P&P, because it just adds temporary negative levels that will eventually become permanent negative levels (and temporary negative levels are kind of bugged; you have to keep saving each day until the level is removed, or you fail).

    I figure that isn't really a big deal, because 1) when the player uses it, they'll be killing whatever they're using it on quickly, so it doesn't matter if the level drain could eventually become permanent; 2) in ToEE, even 'permanent' negative levels can be removed by restoration, so I'm less worried even if the player gets hit.

    Anyhow, this was all working pretty well. And then I went to bed. And this morning, when I started back up, those two spells don't work anymore. And I have no idea why. I'm pretty sure I didn't change either of their scripts (I was just working on wail). I'm baffled. Can anyone spot the error?

    Some other miscelaneous stuff:

    Enervation and energy drain are supposed to give undead temporary hit points when targeted. I tried several temporary hit point effects, but none of them seemed to actually cause the undead to get the hit points (even back when enervation was actually doing something; now it doesn't even apply the particle effects). I've got it applying a false life effect right now, but if someone knows something that might actually work, that'd be good.

    Also, does anyone know how to check for empowered and maximized spells? Most damaging spells call a damage routine (reflex_save_and_damage) which must somehow figure that out, but that isn't going to work for enervation (and it doesn't work for circle of death, presumably). I tried a maximized enervation when it was still working, and only got 3 levels drained instead of 4, so the metamagic must not automatically maximize all dice rolls in the script. But it may be that the spell object records what metamagic is in effect, in which case I could apply it manually. Anyone know?

    Anyhow, I'll keep poking around, and maybe try to implement some additional SRD spells (many of which seem to have been planned, but cut according to the mes files).
     
  2. Gaear

    Gaear Bastard Maestro Administrator

    Joined:
    Apr 27, 2004
    Messages:
    11,029
    Likes Received:
    42
    No attachments found! (You probably need to put them into a .zip to attach here.)

    p.s. - If you ever get this going I would be happy to do the audio for you. I did for most of the other Co8 spells in one fashion or another - audio is my bag.
     
  3. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    Gah! I actually realized my wail of the banshee mistake half way through my post (I was going to ask why it wasn't working as well, but the reasons were silly), so I rebuilt the zip, and forgot to re-attach it.

    Energy drain is lacking any sound as well. Enervation has some (I guess it was the only one that was seriously planned on being in-game), but it seems dubiously appropriate to me. It rather sounds like electricity.
     

    Attached Files:

  4. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    So, I think I've completed banishment, now. And working on it led me to some discoveries.

    While I was testing it, I got quite confused about a successful banishment not typically granting experience points. The same is true of dismissal. And more oddly, finger of death would sometimes grant experience, and sometimes not.

    I finally tracked down the problem, though. It turns out (as far as I can tell) that to be awarded experience, someone in the party must attempt to deal damage to the monster (even if that damage is reduced to 0 by damage reduction). So, if finger of death works on the first try, you get no experience. Similarly for dismissal and banishment. However, if your first finger fails, it does damage, and then if your second finger works, you get experience.

    So, to make banishment work properly (and dismissal, and finger of death, and ...), instead of just calling 'critter_kill_by_effect', you should plink it with a little damage to trigger the experience output. It might be worth having a utility function like:

    Code:
    def slay_critter( caster, critter, id ):
        damage_dice = dice_new( '1d4' )
    
        critter.spell_damage( caster, D20DT_UNSPECIFIED, damage_dice, D20AP_UNSPECIFIED, D20A_CAST_SPELL, id )
        critter.critter_kill_by_effect()
    
    For that matter, the disintegration effect (which apparently uses animate dead to destroy the body; amusing) might be worth wrapping. It's used in at least one other spell: destruction.

    Strictly speaking, I doubt the damage is integral to getting experience (and it may not just be damage, but certain other hostile effects; I don't know), but it probably triggers some defeated-enemies list that I don't otherwise know how to trigger, and I'm guessing no one here does either, since otherwise it'd be in the existing spell scripts.
     
  5. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    Well, I finally figured it out. I had added a "Level Drained!" message to spells.mes. Then, at some point, I reverted back to a default spells.mes, and forgot to add that back in. That was resulting in the script blowing up before any negative levels and such could be applied.

    It'd be nice if there were a way to see the error messages generated by bad scripts. On the other hand, maybe I should also start using some version control for this.

    I do have one question to pose about banishment (and thus, dismissal). The description of the spell says that affected creatures are banished back to their home plane. I implemented this by deleting the object, so the enemies just disappear without leaving any loot. However, this means that you can't, for instance, use it on the node guardians if you want to get the gems they're holding.

    Is this acceptable? I can't recall; are the gems required to get out of the nodes? If that's the case, I guess it'd be possible to check for a few key items (although, I thought the balor would have scripts for dropping equipment while being deleted on death, but I don't see them in the NodeBalor script). Or should I just kill the enemies and leave the body like dismissal does? Or destroy the body but leave the loot like disintegrate?

    I'm open to suggestions.
     
  6. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,613
    Likes Received:
    537
    Heh, known issue :)
    Originally encountered in Holy Word, the fix was the same as you suggested.

    However, note a possible conflict with Death Ward - DW's protective effect simply nullifies the critter_kill_by_effect command.
    Thus, if you cast it on a target with DW, and the target fails its save, it will still be damage. (And I'm not aware of any command that checks for a DW, so you can't condition the damage with that)
    But I suppose if the damage is low enough (e.g. 1d1) it's bearable.

    BTW, in this regard, Holy Word is exempt from the rule, as Death Ward isn't supposed to protect from it. There was even a horribly OP exploit build that made use of it - see here.

    Re. the guardians,
    in ToEE the CRPG you just have a doorway leading out, no gems required. Which is contrary to the P&P module, but then again, the guardians weren't there either, and the gems were held by grues, anyway. So go ahead and destroy() them.
     
    Last edited: Dec 18, 2010
  7. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    So, I spent some time wracking my brain, and I came up with the following potential solution:

    Make the spell do 1d1 sonic damage, but prior to that, given them 10/- sonic resistance (via resist elements) for 1 round. In fact, I'm not certain how all the intricacies of the spells cripts work, but most save-or-dies call 'spell_end( spell.id )'. Would that remove any ongoing effects associated with the spell id (and thus the sonic resistance)?

    Anyhow, that ensures that 0 damage is dealt, which triggers experience gain, and doesn't give you an unfair advantage in the event of death ward.

    However, when trying to test this out, death ward prevented death spells from even being cast on the target. Finger of death just fizzled. Wail of the banshee evidently didn't receive the warded character in the target list (I don't do any special checking). And that's presumably because they have the '[Death]' descriptor. But that's also true of circle of death (although it's currently not correctly marked, and in fact will kill someone with death ward active), destruction, slay living, .... So I wonder if this even matters.

    Edit: It also occurred to me that if all we're worried about is death ward, we could use negative energy damage, since death ward allegedly makes you immune to that. However, that appears to be false in-game currently, as I was able to deal damage with an inflict spell to a death warded character. It also doesn't prevent the level drain I've been using for enervation and energy drain, so I'll have to do something about that.
     
    Last edited: Dec 18, 2010
  8. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    All right. Here is, I think, a fool-proof experience-awarding kill function:

    Code:
    def slay_critter( critter, caster, spell_id ):
    	plink = dice_new( '1d1' )
    
    	is_invulnerable = critter.object_flags_get() & OF_INVULNERABLE
    
    	critter.object_flag_set( OF_INVULNERABLE )
    	critter.spell_damage( caster, D20DT_UNSPECIFIED, plink,
    			      D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell_id )
    
    	# I'd just restore the original flags, but I don't know
    	# what field to obj_set_int.
    	if not is_invulnerable:
    		critter.object_flag_unset( OF_INVULNERABLE )
    
    	critter.critter_kill()
    With the invulnerability flag set, that damage is reduced to 0.

    I also discovered how to check for protection from negative energy effects. Oddly enough, you can't check for a death ward condition with d20_query_has_spell_condition (querying sp_Death_Ward always returns 0). However, if you ask it about sp_Negative_Energy_Protection, it will return affirmative if either death ward or negative energy protection are active.

    However, negative energy protection is another spell that doesn't do its job. I was able to damage a protected character with inflict spells, and grant them negative levels. My enervation/energy drain code now checks for protection in the above mentioned way, but all the inflict spells (and harm, and probably others I'm forgetting) should probably do the same.
     
  9. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    So, this may be old news, but I didn't see it in any of the threads I've read on spell modding by searching....

    In the course of reviewing the .txt files for spells, I managed to crack the meaning of the max_Target field. So I'll document it here, in case:

    For positive numbers n, max_Target: n just means you can have up to n targets (as far as I can tell).

    For non-positive numbers, you can break them up as follows: -ijk

    j and k must be between 0 and 9, but i works if arbitrarily large, I think.

    Now, the number of targets is calculated as (level + k) / (j + 1), and if i is positive, it is capped by that. For some examples:

    0: (level + 0) / (0 + 1) = level, no cap
    -010: (level + 0) / (1 + 1) = level/2, no cap
    -331: (level + 1) / (3 + 1) = 1 + (level - 3)/4, capped at 3 (scorching ray)
    -511: (level + 1) / (1 + 1) = 1 + (level - 1)/2 capped at 5 (magic missile)

    I tried -1000, and it's correctly 1 target/level capped at 10.
     
  10. Kneller1

    Kneller1 Established Member

    Joined:
    Feb 25, 2006
    Messages:
    196
    Likes Received:
    1
    Just a small Role-Playing point to get in the way. The node guardians and other node creatures shouldn't be banished or dismissed as they are already on their "native" plane.
     
  11. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    Well, that can be done, as well. Is that true, though? The node guardians are demons, so their home plane should be somewhere on the abyss, no? Is that where the nodes are? Or are they pocket planes that should be considered the home turf of the guardians or something?

    If the nodes are an alternate plane, then I think the text of banishment can be read to be ineffective there completely (because you only get to banish things while on your home plane).

    It's kind of cheesy to just mass-kill all the enemies in the big node fights anyway. :)
     
    Last edited: Dec 22, 2010
  12. Kneller1

    Kneller1 Established Member

    Joined:
    Feb 25, 2006
    Messages:
    196
    Likes Received:
    1
    The nodes are consider 'partial planes' created by Zug + Iuz and are next to the prime plane. Being 'close' means that magic still works; (unless specificity mentioned by being affected by the elements of the nodes). Whether this applies to the wording of 'home plane' in the banishment spill I don't know.

    Besides:
     
  13. dolio

    dolio Established Member Supporter

    Joined:
    May 30, 2005
    Messages:
    339
    Likes Received:
    81
    I don't know that I buy that the "free-willed, not conjured or summoned" thing matters for banishment (or dismissal). I certainly buy it for dispel magic and protection from evil, because those specifically affect summoned creatures. But banishment I read such that, say, if a group of adventurers plane shifted to the abyss and started killing demons, the demons could cast banishment to send them back to the prime, or wherever they came from.

    But, as I said, I don't have a problem ruling that banishment won't work for the party in the nodes, for a variety of story-ish reasons. And removing a 6/7th level "mass kill anything in the nodes" spell makes them a little more interesting.

    ----

    On an unrelated note: I've got sunburst coded (I don't think there's an appropriate particle effect; if anyone's a wizard with those, I could use one that looks like an 80 foot radius blast of sunlight). It has several categories:

    1. Ordinary creatures, take 6d6 damage
    2. Ordinary creatures that are vulnerable to light, take double 6d6 damage
    3. Undead, fungi, and oozes, take LEVELd6 damage
    4. Things in category 3 that are especially vulnerable to light, save or die

    Quite a bit of that requires picking out individual creatures (undead and oozes are easy). But, it's been too long since I did a full playthrough, and so I can't remember what all to look for. I have the following:

    Code:
    Category 2
    ----------
    
    Category 3
    ----------
    Violet fungi
    Hooting fungi
    Ascomid
    Shrieker
    Phycomid
    Yellow mold
    
    Category 4
    ----------
    Bodak
    I could use input on any other enemies that should be in those groups. Vampires and wights are an obvious choice for category 4, but I'm not sure of the ones in description.mes (one is Thrommel; I'm not sure who the others are, but they seem like non-hostile NPCs of some kind). Also, Zuggtmoy could be argued to be fungi for the purpose of that spell, but I thought I'd ask people's opinions first.
     
    Last edited: Dec 27, 2010
  14. gazra_1971

    gazra_1971 Knights of Legend

    Joined:
    Aug 3, 2010
    Messages:
    818
    Likes Received:
    2
    The following oozes are in the computer game:
    Black Pudding, Crystal Ooze, Gelatinous Cube, Gray Ooze, Green Slime, Ochre Jelly.

    I don't know whether any of the following undead are especially vulnerable to light but they are in the computer game:
    Drelb, Ghast, Ghoul, Groaning Spirit, Mathel (quasi-lich?), Morhg, Seahag, Shadow, Zombie.

    Another player wrote previously in this forum that Prince Thrommel isn't actually a vampire. Apparently an illusion has been cast on him in an attempt to fool the player. Somebody who has the PnP module should check whether this is the case.

    I don't care whether Zuggtmoy is considered a fungi so that the Sunburst spell does more damage to her. I just won't use that spell against her because she is already WAY too easy to kill!
     
  15. Gaear

    Gaear Bastard Maestro Administrator

    Joined:
    Apr 27, 2004
    Messages:
    11,029
    Likes Received:
    42
    Thrommel is not a vampire.

    Dolio, are you using World Builder yet? It has a proto editor that clearly states every creature's type (undead, etc.). It may even have a search function by mc_type, not sure (not looking at it atm).

    Also, if you're interested, vampiricpuppy did a great tutorial on particle effects: http://www.co8.org/forum/showthread.php?t=7317
     
Our Host!