Can an Extend MagicEffect script call an Extend Actor script

Post » Tue Jun 19, 2012 3:14 am

I'm attempting to create an OnHit event that applies to every actor in the game (and those added my mods). In the wiki, it says you cannot apply a script to an actor added by a level list, but you can get around that by applying the script to an effect that is applied to a spell that is applied to a race.

It seems in order to do that, the script on the effect must use "extends ActiveMagicEffect"... which is fine except that I don't believe it allows me to use "WornHasKeyword"... but "extends Actor" will let me use that.

So is there a way for a script that extends ActiveMagicEffect to call a script that extends Actor upon the actor that has the magic effect applied to it?

Any suggestions are welcome! Thank you! :-)
User avatar
Rik Douglas
 
Posts: 3385
Joined: Sat Jul 07, 2007 1:40 pm

Post » Tue Jun 19, 2012 8:44 am

The phrase "call a script" isn't correct - using the right terminology it's meaningless - so I'm not really sure what you're asking.

Hopefully you'll find it useful to know that an http://www.creationkit.com/ActiveMagicEffect_Script will receive events events from the http://www.creationkit.com/Actor_Script to which it's attached. So you can, for example, successfully use an http://www.creationkit.com/OnHit_-_ObjectReference event as a native event in a script that extends ActiveMagicEffect.

Cipscis
User avatar
Scared humanity
 
Posts: 3470
Joined: Tue Oct 16, 2007 3:41 am

Post » Tue Jun 19, 2012 1:34 pm

Thank you... I'm quite new to scripting :-P

Yes, I changed from extending an Actor to extending an ActiveMagicEffect because of this issue stated in the wiki...

You may not attach a script to an actor if that actor would be used by a leveled actor list. If an actor is used in a leveled actor list, its "Scripts" section will be disabled.
  • There is a workaround in this in cases where you need actors to be both leveled and scripted - you can create a constant/self magic effect and apply that at the race level. For example, the FXDragonBloodDamageScript handles applying some special blood FX to dragons through combat. Since dragons are used to populate leveled lists, however, we attach this script to AbFXDragonBloodDamage, which is an effect on the AbDragonBloodFX spell. That's then assigned as a special racial ability of the DragonRace. You can look at a similar example in how the WispMothers work, too.

But when I went to save the script, it gives me these errors...

"WornHasKeyword is not a function or does not exist"

and...

"type mismatch on parameter 2 (did you forget a cast?)"


It saved without error when extending an Actor, but simply changing it to extend an ActiveMagicEffect causes that. So I'm guessing that "WornHasKeyword" or casting a spell doesn't work under an OnHit event that is within a script that extends an ActiveMagicEffect. Does that make sense?
User avatar
Motionsharp
 
Posts: 3437
Joined: Sun Aug 06, 2006 1:33 am

Post » Tue Jun 19, 2012 2:40 am

Ah, that's because you're trying to call those functions without specifying an object on which to call them, so the compiler assumes that you're calling them on the "self" object, for which those functions don't exist because it's a different type.

You'll want to use an http://www.creationkit.com/OnEffectStart_-_ActiveMagicEffect event, and extract the information in the "akTarget" parameter. This is the http://www.creationkit.com/Actor_Script on which you want to call those functions.

Cipscis
User avatar
Baby K(:
 
Posts: 3395
Joined: Thu Nov 09, 2006 9:07 pm

Post » Tue Jun 19, 2012 3:12 am

Ah, thank you very much! :-D
Good Sir Cipscis, what would I do without you??? ;-)

If I may ask one thing...
Where would I need to put the OnEffectStart event in my script, and where would I need to end it? Before or after the OnHit event begins?

Also, in order for the "WornHasKeyword" function to work properly, will "Event OnEffectStart(Actor akTarget, Actor akCaster)" automatically set all of the information needed, or will I need to actually need to return any specifics from the event?

I do apologize for being a bother. If there's an example script somewhere that does something similar, I'm sure that would help without causing you or anyone else to have to write out a new example :-)

Thank you again! :-D
User avatar
Grace Francis
 
Posts: 3431
Joined: Wed Jul 19, 2006 2:51 pm

Post » Tue Jun 19, 2012 4:28 am

Events aren't quite like the old scripting system's blocktypes. An event is really just a function, with the only non-semantic difference being that events can't have return values. Some events, however, like http://www.creationkit.com/OnEffectStart_-_ActiveMagicEffect, are native events, which means that the game engine itself will call them on the appropriate objects at the appropriate time.

Since non-declarative code can only be placed within function definitions (including event definitions), native events will always be the entry points to your code. Because events are really just functions, you can put their definitions in any order in your script and it won't change a thing.

You should be able to call http://www.creationkit.com/WornHasKeyword_-_Actor on the "akTarget" parameter inside your OnEffectStart event - the game passes the correct information in when the event is called natively. The only other thing you'll (almost certainly, but depending on how you're doing things) need is a Keyword property for this function's "akKeyword" parameter.

Cipscis
User avatar
Mylizards Dot com
 
Posts: 3379
Joined: Fri May 04, 2007 1:59 pm

Post » Tue Jun 19, 2012 11:29 am

Thank you so much! I got the main script to work! :-D
I do have yet another question, though.

My script is set up in this format...


Scriptname (the start)

Declare/Define variables/properties

Event OnEffectStart
; set variables according to WornHasKeyword
End Event

Event OnHit
; Calculate if a strike is successful or not
End Event

End of script


What I'm wondering is how and where I need to place the "consequences" if a strike is successful. I would like to apply damaging spells/effect on the scripted actor. But I would need to point to the actor again instead of the magic effect, correct? Would I need to use "OnEffectFinish" in order to do so? Would there be any reason not to do so? What would an alternative be? Is there anyway to pass the akTarget into the main script from the OnEffectStart event?

I fear I'm lost on syntax in that, haha! This is my first script ever :-P

I tried to point to OnEffectStart's akTarget inside the OnHit event by using...

"akTarget.WornHasKeyword()"

and also...

"OnEffectStart(akTarget).WornHasKeyword()"


That's why I moved everything that used that function into the actual OnEffectStart event.


EDIT:

Would http://www.creationkit.com/GetTargetActor_-_ActiveMagicEffect() work?
I suppose not if every actor had the same effect?
User avatar
Roberta Obrien
 
Posts: 3499
Joined: Tue Oct 23, 2007 1:43 pm

Post » Tue Jun 19, 2012 12:24 pm

Unlike most programming languages, Papyrus isn't picky about where you declare things...you can declare a variable at the end of the script, and use it at at the beginning, and so on.
User avatar
Jesus Sanchez
 
Posts: 3455
Joined: Sun Oct 21, 2007 11:15 am

Post » Tue Jun 19, 2012 3:35 am

Kageseigi, I found something interesting while messing with detect life, the script I put on it was called for every actor. So if you need to call a script on all the actors around you, you could use a magic effect that has the OnHit event in it. I don't know however if the successful-strike-or-not is going to work since by that time you've already hit them.. You also have to consider the complexity and extra load thats going to be created by running this script on multiple actors.
Event OnEffectStart(Actor caster, Actor target);This condition is only needed if you are giving the effect by hitting them with something, and only want it to run once  if target.HasMagicEffect(thisLifeDetectSpell);the life detect effect would be running on them while they're in the area of effect and shouldnt run twice    GotoState("nullstate")    Dispel()  elseif    ;your code  endifEndEventstate nullstate;define all your events in here null in case they get throughendstate
^^^ this is complete pseudo-code I have to look up every function before I use it because Papyrus has weird grammar > :(


Anyways, hopefully you can get something out of that mess

edit: Actually you probably don't even need that check to see if the effect is active, and it might it to dispel itself over and over if used...
User avatar
Holli Dillon
 
Posts: 3397
Joined: Wed Jun 21, 2006 4:54 am


Return to V - Skyrim