Help with script - spell affecting a door


#1

I’m trying to write a script that is to destroy a door, after a character casts a spell on it. I wanted to use the spell Dispel magic and I started with something like this:

void main()
{
	
	object oDoor = OBJECT_SELF;     
	object oStarget  = GetSpellTargetObject();
	int iSpell = GetSpellId();    
	       		
    
	if (oStarget == oDoor) 
	{                                       	
 	
		if (iSpell = SPELL_DISPEL_MAGIC)
		{
		DestroyObject(oDoor, 0.5);
		}

	
	}
	
		
}

I placed this script upon the “On Spell Cast At Script” slot on the door. It doesn’t work at all however. I think it might have to do with the spell not being directly aimed at the door, but it dispels the magic in an area where the door is.

Maybe someone knows how to do this?


#2

Ok, so I tested with the spell Fireball instead and that worked if I changed the script to this:

void main()
{
	
	object oDoor = OBJECT_SELF;     
	int iSpell = GetSpellId();    
	       		           	
 	
		if (iSpell = SPELL_FIREBALL)
		{
		DestroyObject(oDoor, 0.5);
		}	

}

Still, it would be great if this could work with Dispel Magic (and also another spell that I had in mind) instead…


#3

You were on the right path. You need to get the spell that was cast. You were trying to get the spell id, but not putting in the spell that had been cast. Try GetLastSpell() instead… Also, this script will only fire if the Door is effected by the cast spell, so the oSTarget should be OBJECT_SELF - the door is calling this script.
//
if (GetLastSpell() == SPELL_DISPEL_MAGIC)
{
DestroyObject(OBJECT_SELF, 0.5);
}
//


#4

Hmmm. I didn’t get it to work. I tried with this. Is this what you meant Mannast?

void main()
{
	 	
	object oDoor = OBJECT_SELF;     
	object oStarget  = GetSpellTargetObject();

	if (oStarget == oDoor) 
	{                                       	
 	
		if (GetLastSpell() == SPELL_DISPEL_MAGIC)
		{
		DestroyObject(OBJECT_SELF, 0.5);
		}
	
	}
		
}

#5

I was able to throw it in toolset and try it myself. However, I see what you mean by how you can’t target the door directly, so GetSpellTargetObject() won’t return the door. Maybe the door also needs a magic effect on it to be effected by the Dispel Magic? If I get a chance, I’ll play with this.


#6

The GetSpellTargetObject() NWScript command returns the object at which the caller’s last spell was cast.

The caller is the door. It won’t cast any spell (obviously).


#7

Aqvilinus: Ah, that explains a few things…


#8

But what function is it one should use then instead of GetSpellTargetObject?


#9

Maybe it’s enough with just this?

void main()
{
	if (GetLastSpell() == SPELL_DISPEL_MAGIC)
		{
		DestroyObject(OBJECT_SELF, 0.5);
		}
}

#10

Yes, it should be. The OnSpellCastAt event script fires only when you actually hit the object with a spell, so no need for extra checks.


#11

Still, it doesn’t seem to work because you can’t cast that spell on the door directly…So, how do you get around that? Do you have to have an enchanted door, and how do you do that in that case? Maybe with a magical item in its inventory or something perhaps?


#12

AFAIK, it should work with AOE spells too, that’s really strange… Try adding some debug messages.

void main()
{
	SendMessageToPC(GetFirstPC(FALSE), "Running the script...");

	if (GetLastSpell() == SPELL_DISPEL_MAGIC)
	{
		SendMessageToPC(GetFirstPC(FALSE), "The correct spell was found");
		DestroyObject(OBJECT_SELF, 0.5);
	}
}

#13

Tried it and I get no messages at all so…


#14

the stock DispelMagic AoE [nw_s0_dismagic] cycles over these object-types:

OBJECT_TYPE_CREATURE | OBJECT_TYPE_AREA_OF_EFFECT | OBJECT_TYPE_PLACEABLE

 
idk, you could try customizing the spellscript and add OBJECT_TYPE_DOOR …


something similar comes up in one of the SoZ mini-dungeons. A door needs Darkness cast on it to open. So the developers start a dialog in the door’s OnFailToOpen, and a node checks if PcSpeaker has some form of Darkness available and if so, and player chooses that node, Darkness is decremented by a dialog-script (and the door opens)

player never actually casts the spell …


#15

Hmmm, interesting. How do you customize the spellscript in that case? Is it by tampering with a 2da file perhaps?

I would rather it doesn’t happen through a dialog…


#16

Yeah, I came to the same conclusion… The OnSpellCastAt script fires for a given object only when you call explicitly EventSpellCastAt() for this object inside a spellscript. Since the door objects are skipped in the loop, this event never happens.


#17

hm, here’s a thought: why don’t you try putting an Ipoint or other invisible placeable at the same spot as the door (walkable etc.)

Use the placeable’s OnSpellCastAt at to trigger whatever should happen to the door


#18

Yes, I actually thought of the same thing. Will try it.


#19

Thank you Mannast, Aqvilinus and kevL_s for helping me out!

It worked like you said, kevL_s. Now, I have another problem. The whole thing was to work like this. You have to cast Dispel Magic and Sound Burst on the door for it to be destroyed.

Somehow, in game the game wont recognize the Sound Burst spell. I can’t understand why. Here’s how my script looks at the moment (with debug messages, and that’s how I noticed it):

void main()
{
	
	SendMessageToPC(GetFirstPC(FALSE), "Running the script...");

	object oDoor = GetObjectByTag("door_out");

	if (GetLastSpell() == SPELL_DISPEL_MAGIC)
		{	
		SendMessageToPC(GetFirstPC(FALSE), "The dispel spell was found");
		SetLocalInt(oDoor,"dispel",TRUE);
		}
	
	if (GetLastSpell() == SPELL_SOUND_BURST)	
		{
		SendMessageToPC(GetFirstPC(FALSE), "The sound spell was found");
		SetLocalInt(oDoor,"sound",TRUE);
		}
		
	if (GetLocalInt(oDoor,"dispel") && GetLocalInt(oDoor,"sound"))
		{
		SendMessageToPC(GetFirstPC(FALSE), "Destroying the door now");
		DestroyObject(oDoor, 0.5);
		}

}

The game recognizes the Dispel Magic spell, no problem there, but not the Sound Burst spell.


#20

SoundBurst loops over creatures only … now methinks you’ve got a problem

edit: oh /heh/ replace the placeable with a scripthidden creature with no AI scripts except OnSpellCastAt … leave it’s AI on ofc

(or somethin like that)