Creating my first spell - need major help

Post » Sun Nov 18, 2012 11:31 am

Here's what I'm trying to do

If my spell hits any npc that is a playable race, and my spell is the damage source that kills that npc, then that npc is turned into a dead skeleton.


To make my spell viable, I'll have to somehow transfer the contents of the NPC, before it is disabled, to the newly created skeleton in its place.


The problem is, skyrim scripting makes absolutely no sense to me.

I remember in oblivion you declared references at the top of your script to store those variables


How does it work in skyrim?
Scriptname LichdomDecaySpellScript extends activemagiceffectSpell property LichdomDecaySpell autoObjectReference TargetRef = TargetRef.GetReference

This is what I have so far...a miserable start, I know - it doesn't even compile and I'm not even sure what I'm doing after watching a few tutorials.


I would be very greatful to anyone who would take the time to explain this process as thoroughly as they can. Once I understand it, I'll be better equipped to reproduce the effects in future instances of scripting.

Thank you all in advance
User avatar
Sam Parker
 
Posts: 3358
Joined: Sat May 12, 2007 3:10 am

Post » Sun Nov 18, 2012 3:28 pm

ObjectReference TargetRef = TargetRef.GetReference

This line won't work for two reasons. The first is that it's circular - you're telling the script what TargetRef is, but it needs to know what it is to call TargetRef.GetReference(). (The second, minor problem is that you've missed out those parentheses.)

One thing people tend to miss when they start scripting is that code that does anything has to go in an event. The game will fire these events as appropriate and send information to them in the event parameters. So for a magic effect you typically want to use the OnEffectStart event, like this:

Event OnEffectStart(Actor akTarget, Actor akCaster)   if akCaster == Game.GetPlayer()	  ; more code here to do things with akTarget, including for example	  ; akTarget.RemoveAllItems(MyTempContainer)   endifendEvent

And the caster and target of the magic effect are provided for you, as shown.

It is generally better (faster) to use a PlayerRef property than Game.GetPlayer(), however.
User avatar
luke trodden
 
Posts: 3445
Joined: Sun Jun 24, 2007 12:48 am

Post » Sun Nov 18, 2012 11:14 am

Thank you, that was very helpful and I appreciate it your input, and I kind of understand it a little better, here's what I've got now

Scriptname LichdomDecaySpellScript extends activemagiceffectEvent OnEffectStart(Actor akTarget, Actor aKCaster)If aKCaster == game.GetPlayer()endifendEventEvent OnEffectFinish(Actor akTarget, Actor akCaster)if akTarget.Isdead()endifendevent

My question now is, why doesn't this compile if I do if akTarget.isdead == 1()

As it's written in the code, how do I know what that's even returning? the way it's written, it doesn't really say "do this if it comes back 1, or do this if it comes back 0"

also, if I wanted to store akTarget into a reference variable for later use, how would I do that?

I'm also assuming that when you put (MyTempContainer) after removeallitems, it would put it into a container that I would have to create and place in the game world somewhere called MyTempContainer?
User avatar
Krystal Wilson
 
Posts: 3450
Joined: Wed Jan 17, 2007 9:40 am

Post » Sun Nov 18, 2012 9:26 am

if akTarget.isdead()  ; code for if target is deadendif

The parentheses need to go directly after a function call. (They may have values inside them, if the function takes parameters, but IsDead() does not.)

Secondly, IsDead() returns a boolean value, not an integer. In condition functions in the CK you use 1 as true, 0 as false, but not in Papyrus scripts. If you wanted a negative condition you could use an exclamation mark:


if !akTarget.isdead()  ; code for if target is not deadendif

You can simply assign akTarget to a variable or property. If you want to reuse it later in the same script a variable declared above the events is simplest:

Actor Target

and then in the event

Target = akTarget

I'm also assuming that when you put (MyTempContainer) after removeallitems, it would put it into a container that I would have to create and place in the game world somewhere called MyTempContainer?

Not quite. It would put it into whatever object you had filled the MyTempContainer property on your script with. That object would have to be in the world, but could be called anything you like.
User avatar
Natasha Callaghan
 
Posts: 3523
Joined: Sat Dec 09, 2006 7:44 pm

Post » Sun Nov 18, 2012 7:03 pm

Ok, that makes perfect sense! I also think I understand the property value thing, but now I have another question


I basically have an organic chest that I'm spawning (the skeleton in place of the actor that gets disabled) so, does that have to be placed in the world in order for me to reference it? The spell is going to be fairly spontaneous in its use so dragging one skeleton into the editor isn't going to cut it.

Also, I made my skeleton an actor - but since I dont place him in the world, there's no way to make sure it spawns dead, just like the actor its going to replace. I'd like to let the player choose if he wants to reanimate the skeleton with vanila spells

but I'd also like the skeleton to have the stats of the person whom the skeleton is supposed to belong to (I'd like to change the name of the skeleton if at all possible, so if the player kills Bandit with the Decay spell, he's going to see Bandit's skeleton, not just Generic "skeleton"

here's my code so far, it compiles correctly, but I'm stumped as to how to procede. Is the game going to place this skeleton as the code suggests? If so, how will I reference it to transfer the targets stats to the skeleton, along with the inventory ( will I need to move the inventory to a temporary chest first as suggested earlier?)

Scriptname LichdomDecaySpellScript extends activemagiceffectActor Property LichdomDecaySkeleton  AutoInt OnehandedInt TwohandedInt ArcheryInt DestructionInt ConjurationInt MagickaInt HealthEvent OnEffectStart(Actor akTarget, Actor aKCaster)If aKCaster == game.GetPlayer()endifendEventEvent OnEffectFinish(Actor akTarget, Actor akCaster)if akTarget.Isdead()akTarget.Disable()akTarget.PlaceAtMe(LichdomDecaySkeleton, 1)endifendevent
User avatar
Michael Russ
 
Posts: 3380
Joined: Thu Jul 05, 2007 3:33 am


Return to V - Skyrim