Adding to the Spellbook Pt II

Discussion in 'General Modification' started by Kuraylon, Jun 7, 2005.

Remove all ads!
  1. Allyx

    Allyx Master Crafter Global Moderator Supporter

    Joined:
    Dec 2, 2004
    Messages:
    5,001
    Likes Received:
    250
    Errr.... no.... not really, but thanks for the effort - my scripting knowledge is less than minimal!

    So let me see if I got this right....

    If I want to make the spell greater dispelling, I copy dispel magic (rename it), and add a global variable like this?




    from toee import *



    from utilities import *


    greater dispelling = +20




    Then somewhere at the bottom i'd add...




    def blast(): global greater dispelling


    Would that add +20 to the caster level check for the spell caster? Is that right?


     
    Last edited: Jul 9, 2005
  2. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    Okay, obviously I didn't make any sense:)

    first all the stuff in my previous post was to help you with delayed blast fireball. You only need the global variables to store the values from the spell fields in the OnSpellEffect function so you can use them in the blast function to do your actual spell damage when that function is called by the game at the time you set in your call to game.timevent_add. The blast function is only necessary because you need a function to be called after the delay. In the case of greater dispelling you wouldn't need to create any global variables and you wouldn't need to create any new functions. You would just do all your stuff in the OnSpellEffect function(oops my bad. some spells scripts don't have the OnSpellEffect function defined. A quick check seems to indicate that these are the projectile spells. In that case the proper place to do the spell stuff is seems to be the OnEndProjectile functionl.This is the case with Fireball. Sorry if this caused any confusion :blush: )

    A few other things:
    variable names can contain letters, underscores and numbers(but cannot begin with numbers) nothing else. In particular they cannot contain spaces so your variable 'greater dispelling' would become something like 'greater_dispelling';

    the plus sign is unnecessary when assigning a value to a variable, in the absence of a minus sign the plus is assumed. It may actually be an error to include the '+'. Not sure, never done it;

    python is picky about how your script is laid out. after a function definition you have to have a newline and the stuff in the function has to be indented.

    Darmagon
     
    Last edited: Jul 10, 2005
  3. Cujo

    Cujo Mad Hatter Veteran

    Joined:
    Apr 4, 2005
    Messages:
    3,636
    Likes Received:
    1
    ok if you can tell this is suposed to make zuggy, cuthbert, iuz, plants and aberrations not counted as targets for the spell but it doesn't work they're still targeted :anger:

    Does anyone have any idea how to make it work?
     
  4. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    after each if line put the line:

    Code:
    remove_list.append( target_item.obj )
    and make sure to indent these lines. using a tab is easiest.
    after all that add:

    Code:
    spell.target_list.remove_list( remove_list )
    and remove the comment signifiers from in front of the lines for plants and aberrations. A number sign (#) indicates that what follows it on the line is a comment and that the python interpreter should ignore it.

    What you are doing in your code is adding things to the list of things to be removed from the target list later on with a call to the function spell.target_list.remove_list(). the name of the list of things you want to remove doesn't have to be remove_list. it could be any valid python variable name so long as you have initialized the variable with the statement
    Code:
    variable_name = [] 
    where "variable_name" is whatever name you want to use.

    NB: as I pointed out in my last post here, python really cares about format. In fact, things like indentation of lines in a code block are essential for the interpreter to know what it should do. Instead of trying to explain it further I will just give you the code that should do what you want:

    Code:
    remove_list = []
    
    for target_item in spell.target_list:
    
            #print "target=", target_item.obj
            tar = target_item.obj
            if tar.name == 14265 or tar.name == 14266 or tar.name == 14267:
                    remove_list.append( target_item.obj )
            if target_item.obj.is_category_type( mc_type_plant ):
                    remove_list.append( target_item.obj )
            if target_item.obj.is_category_type( mc_type_aberration ):
                    remove_list.append( target_item.obj )
    spell.target_list.remove_list( remove_list )
    notice that I have commented out the print line. it isn't necessary for your script to work. Also notice the indentations, they have to be there for this to work correctly.

    Anyway that should do it for you.

    Darmagon
     
  5. Cujo

    Cujo Mad Hatter Veteran

    Joined:
    Apr 4, 2005
    Messages:
    3,636
    Likes Received:
    1
    Interstestng, but if spell.target_list.remove_list( remove_list ) is put after the remove target list the spell doesn't go, it doesn't even make a new .pyc , if that line is put at the end of the script just before spell.spell_end( spell.id ) the spell works but ingnores the remove list. the first time I tryed I had spell.target_list.remove_list( remove_list ) twice so I took out the last one and the spell still didn't work :anger:

    whats the deal with variable_name = [] ?
    how does that work?
     
  6. Cujo

    Cujo Mad Hatter Veteran

    Joined:
    Apr 4, 2005
    Messages:
    3,636
    Likes Received:
    1
    now this is what I think is funny, if I use the spell against zuggy, she and everyone else dies, but if I go load game and go to wil'o wisps then no one dies at all. same py no changes between tests. code for entire spell;

    Code:
    from toee import *
    
    def OnBeginSpellCast( spell ):
    	print "Bane OnBeginSpellCast"
    	print "spell.target_list=", spell.target_list
    	print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level
    	game.particles( "sp-enchantment-conjure", spell.caster )
    
    def	OnSpellEffect( spell ):
    	print "Bane OnSpellEffect"
    
    	variable_name = []
    
    	spell.duration = 1
    	spell.dc = 200
    	game.particles( 'sp-Bane', spell.caster )
    
    	for target_item in spell.target_list:
    
    		#print "target=", target_item.obj
    		tar = target_item.obj
    		if tar.name == 14265 or tar.name == 14266 or tar.name == 14267:
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_plant ):
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_aberration ):
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_undead ):
    			remove_list.append( target_item.obj )
    
    		if not target_item.obj.saving_throw( spell.dc, D20_Save_Fortitude, D20STD_F_NONE, spell.caster, D20A_CAST_SPELL ):
    
    			# saving throw unsuccessful
    			target_item.obj.float_mesfile_line( 'mes\\spell.mes', 30002 )
    			target_item.obj.float_mesfile_line( 'mes\\spell.mes', 20047 )
    
    			target_item.obj.critter_kill_by_effect()
    
    		else:
    
    			# saving throw successful
    			target_item.obj.float_mesfile_line( 'mes\\spell.mes', 30001 )
    
    			game.particles( 'Fizzle', target_item.obj )
    			remove_list.append( target_item.obj )
    
    	spell.target_list.remove_list( remove_list )
    	spell.spell_end( spell.id )
    
    def OnBeginRound( spell ):
    	print "Bane OnBeginRound"
    
    def OnEndSpellCast( spell ):
    	print "Bane OnEndSpellCast"
    oh btw I remember that undead can "live" with no heads as well so thats added now.
     
  7. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    not sure what you mean by that :)
    that's because, presumably, you have already done all the spell stuff before that when all the objects still hadn't been removed from the list:)
    which may have caused an error wherein the function was trying to remove things from the list which had already been removed from the list. depending upon how the game developers implemented the remove list function it may have caused the inerpreter to abort when it was asked to do this. and that may be your problem here (although I don't think so.) to avoid this let me amend the code a bit:

    Code:
    remove_list = []
    
    for target_item in spell.target_list:
    
            #print "target=", target_item.obj
            tar = target_item.obj
            if tar.name == 14265 or tar.name == 14266 or tar.name == 14267:
                    remove_list.append( target_item.obj )
            elif target_item.obj.is_category_type( mc_type_plant ):
                    remove_list.append( target_item.obj )
            elif target_item.obj.is_category_type( mc_type_aberration ):
                    remove_list.append( target_item.obj )
    spell.target_list.remove_list( remove_list )
    
    that part of my post was just meant to point out that you can create your own variables in a script. in this case a variable named "variable_name" is created and initialized as an empty list (the "=[]" part). You don't need to include it in your script.

    Anyway, other than that, I don't know what to say. This setup should work (it works for me) provided you have the protos numbers right and provided that you haven't done something else somewhere in your script that would make it not work somehow.

    EDIT: okay now i see you are initializing "variable_name" but using "remove_list"
    if you change the line "variable_name = []" to "remove_list = []" it should clear things up. ( apparently while i was writing this post you were writing your own.)

    EDIT 2: oops, nope you still have problems there and sorry but I don't have the time right now or i will be late for work. it will have to wait until tomorrow.:)


    Darmagon
     
    Last edited: Jul 13, 2005
  8. Cujo

    Cujo Mad Hatter Veteran

    Joined:
    Apr 4, 2005
    Messages:
    3,636
    Likes Received:
    1
    ok let me sum up whats happening, the spell is suposed to kill everyone but the caster, except, things without heads, the undead and gods.
    Code:
    		if target_item.obj.is_category_type( mc_type_undead ):
    			remove_list.append( target_item.obj )
    spell.target_list.remove_list( remove_list )
    ...the spell doesn't work, no *.pyc created.
    Code:
    	spell.target_list.remove_list( remove_list )
    	spell.spell_end( spell.id )
    
    def OnBeginRound( spell ):
    	print "Bane OnBeginRound"
    
    ...Spell works but...
    Code:
    	for target_item in spell.target_list:
    
    		#print "target=", target_item.obj
    		tar = target_item.obj
    		if tar.name == 14265 or tar.name == 14266 or tar.name == 14267:
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_plant ):
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_aberration ):
    			remove_list.append( target_item.obj )
    		if target_item.obj.is_category_type( mc_type_undead ):
    			remove_list.append( target_item.obj )
    if vs zuggy, the spell kills everyone but the caster (not suposed to happen, zuggy's mean to live unharmed)
    if vs wil'o wisps, no one dies (also not ment to happen, wisps sposed to live, else spose to die.)
     
    Last edited: Jul 13, 2005
  9. Drifter

    Drifter Established Member

    Joined:
    Dec 24, 2004
    Messages:
    118
    Likes Received:
    1
    Main mistake is,
    obj.name == # checks for protos Column22, not the description.mes #.
    So when checking Iuz, don't use 14266, but 8042. And so on.

    Anyway, this OnSpellEffect section worked for me...
    Code:
    def OnSpellEffect( spell ):
    
    	remove_list = []
    	spell.duration = 1
    	spell.dc = 200
    	game.particles( 'sp-Bane', spell.caster )
    	
    	for target_item in spell.target_list:
    		tar = target_item.obj
    		if (tar.name == 8064) or (tar.name == 8042) or (tar.name == 8043):
    			remove_list.append( tar )
    		elif tar.is_category_type( mc_type_plant ):
    			remove_list.append( tar )
    		elif tar.is_category_type( mc_type_aberration ):
    			remove_list.append( tar )
    		elif tar.is_category_type( mc_type_undead ):
    			remove_list.append( tar )
    		elif not tar.saving_throw( spell.dc, D20_Save_Fortitude, D20STD_F_NONE, spell.caster, D20A_CAST_SPELL ):
    			tar.float_mesfile_line( 'mes\\spell.mes', 30002 )
    			tar.float_mesfile_line( 'mes\\spell.mes', 20047 )
    			tar.critter_kill_by_effect()
    		else:
    			tar.float_mesfile_line( 'mes\\spell.mes', 30001 )
    			game.particles( 'Fizzle', tar )
    			remove_list.append( tar )
    	spell.target_list.remove_list( remove_list )
    	spell.spell_end( spell.id )
    
     
    Last edited: Jul 13, 2005
  10. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    well you led me a merry chase and when I went to post my solution it seems drifter beat me to the punch. Anyway column 22 of the proto is the name field (as drifter already mentioned). I found this out by first typing in the console:

    Code:
    x=game.obj_create(14266, game.party[0],location)
    after which I typed
    Code:
    x.name
    which came up 8042. then I went to the protos and searched for 8042 and there it was in column 22 of the row for Iuz.

    Anway I think I have a *cough* better *cough*solution for you than drifter's. given that you want the saving throw to be failed in all cases you might as while omit the saving throw function altogether. Also there is no reason to use the remove_list() function as you can just do it this way all in one pass:

    Code:
    def OnBeginSpellCast( spell ):
    	print "Bane OnBeginSpellCast"
    	print "spell.target_list=", spell.target_list
    	print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level
    	game.particles( "sp-enchantment-conjure", spell.caster )
    
    def	OnSpellEffect( spell ):
    	print "Bane OnSpellEffect"
    
    
    	spell.duration = 1	
    	game.particles( 'sp-Bane', spell.caster )
    	
    
    	for target_item in spell.target_list:		
    		tar = target_item.obj
    		if tar.name == 8064:  
    			pass
    		elif tar.name == 8042:
    			pass
    		elif tar.name == 8043:
    			pass
    		elif tar.is_category_type( mc_type_plant ):
    			pass
    		elif tar.is_category_type( mc_type_aberration ):
    			pass
    		elif tar.is_category_type( mc_type_undead ):
    			pass
    		elif tar == spell.caster:
    			pass
    		else:
    			target_item.obj.critter_kill_by_effect()	
    	spell.spell_end( spell.id )
    
    def OnBeginRound( spell ):
    	print "Bane OnBeginRound"
    
    def OnEndSpellCast( spell ):
    	print "Bane OnEndSpellCast"
    You could do the whole exclusion thing on one if line without the elifs and the pass's using ors but it would get pretty confusing that way.

    EDIT: with no disrespect towards drifter meant, his script won't work as you are still removing things from the targetl list after you have already killed them
     
    Last edited: Jul 13, 2005
  11. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    While I am here and have a little time, I guess an explanation is in order. I know I said above that I would have a substantial new spell release done by the end of the weekend. but it is Stampede time in Calgary AB Canada, the greatest outdoor show on earth as they say. Anyway some friends came in to stay for the weekend and I ended up stampeding all weekend. In short, pretty much, I was drunk all weekend and in no shape for any kind of modding work. If I happen to have posted anything during those days I am very sorry, it wasn't intentional and it won't happen again ( at least until there is another really good excuse to party:))

    Darmagon
     
  12. Drifter

    Drifter Established Member

    Joined:
    Dec 24, 2004
    Messages:
    118
    Likes Received:
    1
    Well, practically the code I posted isn't mine but yours... As I just copypasted from some earlier post in this thread, fixed a couple of mistakes and cleaned up naming. Then stuffed the result in some .py and tested on a group spawned critters with a positive result. So... ;)

    Worked fine.
    Whether is it the best solution or no is another question. Which I wasn't aiming at anyway.
     
    Last edited: Jul 13, 2005
  13. darmagon

    darmagon stumbler in the dark

    Joined:
    Mar 22, 2005
    Messages:
    295
    Likes Received:
    0
    My Bad....
    I am stupid and I am sorry. Drifter's script does work. The only excuse I can offer for myself is tiredness from overwork and too much of a good thing on the weekend. Amazing what a good day's sleep does for one's perception:)

    Darmagon
     
  14. Cujo

    Cujo Mad Hatter Veteran

    Joined:
    Apr 4, 2005
    Messages:
    3,636
    Likes Received:
    1
    well in the end the spell is drifters one, it was darmagons one but then I wanted to add more float text lines to the non dieing people, and I could understand where to put them in in drifters one, also I don't mind if some makes a +200 foritude save and lives, cos if they not a god, they're definitly on their way.

    try my mod with the spell.mes included and have a laugh when you try the gods.

    oh btw I also added oozes as well, I keep finding things with no heads.
     
  15. Shiningted

    Shiningted I want my goat back Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,655
    Likes Received:
    352
    If an Ettin is standing half-in and half out of the area of effect and only loses one head, is t a mortal wound? Severed jugular and all? Or does it fight better for being pissed off AND able to focus more singularly on the moment?

    Ok, I am just stirring :lalala: long day at werk.
     
Our Host!