Generic Questions

Post » Wed Jun 20, 2012 11:43 am

Question 1) Is it possible to create a magic effect that increases all damage output (spell, melee, bow, all damage output) without modifying "skills?" I see a way to modify melee damage easily, but the actor that this effect is going to be on will not necessarily be a melee character, and I don't want to go through and make a new effect for every two magic skills to do "destructionpowermod" ect on. I just want to straight up double an actors damage output for a limited time.


Question 2) Is it possible to retrieve an actor reference in a script, convert its ID to a float, then store it as a global variable, then retrieve it and convert it back in another script? If not, is there a way to somehow dynamically store and retrieve a REFERENCE from two different scripts? (Trying to retrieve the actor reference of whatever NPC you cast a certain spell on last, so that a different spell can "target" that npc without aiming at it.)
User avatar
April
 
Posts: 3479
Joined: Tue Jun 20, 2006 1:33 am

Post » Wed Jun 20, 2012 7:21 am

1. Perks, specifically perk entry points 'Mod Attack Damage', 'Mod Power Attack Damage', and 'Mod Spell Damage'.

2. Do not know if it's possible to convert the ID to a float (well technically it is, since it's just converting hexadecimal to decimal, I just don't know how high you're allowed to go). But it's possible to access properties from another script. So supposing you stored the reference in a property called 'MyRef' inside a script called 'MyQuestScript' for the quest 'MyQuest', you could access it in another script by using '(MyQuest as MyQuestScript).MyRef', where 'MyQuest' would be a quest property in your other script. Or to avoid the casting, just have 'MyQuest' as a 'MyQuestScript' property.
User avatar
Pixie
 
Posts: 3430
Joined: Sat Oct 07, 2006 4:50 am

Post » Wed Jun 20, 2012 7:12 pm

1. Perks, specifically perk entry points 'Mod Attack Damage', 'Mod Power Attack Damage', and 'Mod Spell Damage'.

2. Do not know if it's possible to convert the ID to a float (well technically it is, since it's just converting hexadecimal to decimal, I just don't know how high you're allowed to go). But it's possible to access properties from another script. So supposing you stored the reference in a property called 'MyRef' inside a script called 'MyQuestScript' for the quest 'MyQuest', you could access it in another script by using '(MyQuest as MyQuestScript).MyRef', where 'MyQuest' would be a quest property in your other script. Or to avoid the casting, just have 'MyQuest' as a 'MyQuestScript' property.

So the "attack damage mult" peak value modifier, would that work for all damage? Or are you saying I have to make a perk that I have to add to the target actor oneffectstart and then remove it again oneffectfinish?

Also, any chance you could elaborate on how to set the property from within the script? I have used properties and then set them within the editor, but I want to be able to set the property from within the script, to any reference of an actor (basically this script will be attached to all the reanimate dead spells to get the actor that was reanimated). Then I am going to have a spell that buffs your reanimated undead, but I don't want to have to aim it at the undead, I want to just cast it and have the effect increase the damage the undead deals for 10 seconds.

I was thinking about learning how to do Reference Aliases, and use a quest script, but I am unsure how to do that either.

So could you please explain how the casting would work for that with the properties? I have used casting before, but only to run a function in another script.
User avatar
Steven Hardman
 
Posts: 3323
Joined: Sun Jun 10, 2007 5:12 pm

Post » Wed Jun 20, 2012 8:44 am

The perks would always be in effect. The armsman perks, barbarian perks, and overdraw perks all use 'Mod Attack Damage'. There is no magic effect involved. I don't know if 'Mod Attack Damage' would work for power attacks or magic attacks, but an easy way to check would be to set the multiplier to something like 100 and test it out in the game.

You can set properties from within a script exactly the same way you would set variables from within the script. To use your example, in your reanimate script, you would have something like:

MyQuestScript property MyQuest autoEvent OnEffectStart(Actor akTarget, Actor akCaster)	MyQuest.MyRef = akTargetEndEvent

Then, in your second spell's magic effect script:

MyQuestScript property MyQuest autoActor MyUndeadEvent OnEffectStart(Actor akTarget, Actor akCaster)	MyUndead = MyQuest.MyRefEndEvent

As for the casting, I guess the reason why it's necessary is because an object can carry more than one script. Since properties are unique to each script, you need to specify exactly which script on the reference/quest/etc. that you are referring to. One way to do this is through casting. In the example above, I could have done this as well:

Quest property MyQuest autoActor MyUndeadEvent OnEffectStart(Actor akTarget, Actor akCaster)	MyUndead = (MyQuest as MyQuestScript).MyRefEndEvent
User avatar
MARLON JOHNSON
 
Posts: 3377
Joined: Sun May 20, 2007 7:12 pm

Post » Wed Jun 20, 2012 2:58 pm

I think I understand. Just so I am clear, in these examples you give me, there would be the two activemagiceffect scripts, and a third quest script? Then in the editor, I would manually select the quest that the quest script is attached to for the MyQuest properties on both activemagiceffect scripts?
User avatar
Dalia
 
Posts: 3488
Joined: Mon Oct 23, 2006 12:29 pm

Post » Wed Jun 20, 2012 8:10 pm

Yes.
User avatar
Strawberry
 
Posts: 3446
Joined: Thu Jul 05, 2007 11:08 am

Post » Wed Jun 20, 2012 9:30 am

Thank you very much for your help.
User avatar
Honey Suckle
 
Posts: 3425
Joined: Wed Sep 27, 2006 4:22 pm

Post » Wed Jun 20, 2012 10:21 am

There is actually way to pass any ref to any script you write without the need of a quest. The below example script passes an Actor from one script to another script as an ObjectReference.

In the script that is RECEIVING the passed in variable (Obj Ref, Actor, ActorBase, etc):

Scriptname MyRef extends ObjectReferenceObjectReference Property MyRef AutoFunction SetRef(ObjectReference akObjRef)MyRef = akObjRefEndFunction;do stuff with this passed in variable

In the script that gets the reference and is passing to the previous script:

Scriptname MagicAbility extends activemagiceffectActor Property MyActor AutoEvent OnEffectStart(Actor target, Actor caster)MyActor = target((MyActor as ObjectReference) as MyRef).SetRef(MyActor)

This last line is the most important and also the most confusing. MyActor is an actor, being cast as an object ref, that is in turn being cast as the script called MyRef (the other script in this example). We then run the SetRef() function we created in the other script on this double cast property and assign it to the property MyActor which exists on both scripts.
User avatar
JESSE
 
Posts: 3404
Joined: Mon Jul 16, 2007 4:55 am

Post » Wed Jun 20, 2012 9:20 pm

Since both of those scripts there would be activemagiceffect scripts, wouldn't you need the quest script anyways because activemagiceffect scripts dont run all the time?

Basically, when I cast the reanimate spell, I wont be simultaneously casting the "buff deadguy" spell because I want to cast it later, so when the reanimate spell casts to the other script, nothing will happen because the script that it is casting as doesnt exist because the magic effect only exists when I am casting the other spell?

So you would need the quest script which would be running at all times to hold on to the object reference until it is needed by the second spell?
User avatar
Madeleine Rose Walsh
 
Posts: 3425
Joined: Wed Oct 04, 2006 2:07 am

Post » Wed Jun 20, 2012 8:53 am

And sorry for all the questions, but why does the property MyActor need to exist on the script that is retrieving the reference and then casting it to the other script?

For that matter, I don't see why it is a property at all on either script, why not just have it as a variable?




Edit:
Ok, so far this is my plan.

Some quest that starts when the player loads up the game.

Reanimate dead spells have a new magic effect. This effect has a condition, checks to see if caster has a perk, if true, the effect will land and script will run. The script gets the target as an actor, then casts to the quest script calling a function in this script to store the actor in a variable.

Have a new spell, called Aberration. This spell is learned by the player by picking up the same perk mentioned above, and uses a magic effect that runs a script. This script casts to the quest script calling another function which returns the actor, then checks to see if the actor is dead == false, then does MySpell.cast(Game.Getplayer(), MyUndead), which casts the spell from the player to his reanimated minion.

This third magic effect for MySpell has a script which is the effect that actually has tangible benefits and isn't a bunch of crap that I had to make to circumvent all these scripting limitations.




The only problems I see with this approach, if I am understanding all the casting junk properly to store the actor and retrieve it, is the "cast()" function. I am worried that Cast() may have problems with line of sight (an actor coming between me and my minion, thus "intercepting" the effect, and I also am unclear as to whether the player has to actually "know" the spell being cast with this function. If so, it should be simple enough to add it to the player along with the first spell through the perk, and then hide it in the UI. If the effect can be "intercepted" that seems trickier. A while loop that continuously casts the spell until the actor stored in the quest has the keyword should do the trick, along with a little If statement in the effect that dispels itself if the recipient of the effect is not the same as the actor stored in the quest. That is a lot of work though. I wish there was just a "ApplyMagicEffect()" function for actors or something.
User avatar
pinar
 
Posts: 3453
Joined: Thu Apr 19, 2007 1:35 pm

Post » Wed Jun 20, 2012 4:52 pm

This third magic effect for MySpell has a script which is the effect that actually has tangible benefits and isn't a bunch of crap that I had to make to circumvent all these scripting limitations.

If all three magic effects are attached to the same spell (in your example, MySpell) then you don't need to store the target anywhere.

If you are using OnEffectStart(), then akTarget will be the same target you cast the spell on for every magic effect attached to that spell.

The Cast() funciton casts whatever spell instantly. The only requirement for Cast() is that the source object reference has the ability to cast the spell (under perfect circumstances COULD cast the spell, this is different from KNOWING the spell). It does not play any animation. The only requirement is that if the source is an actor that the actor be facing in the direction the spell is being cast().

http://www.creationkit.com/Cast_-_Spell


As for your question here, "trying to retrieve the actor reference of whatever NPC you cast a certain spell on last, so that a different spell can "target" that npc without aiming at it:"


FIRST Script

Scriptname MagicEffect1 Extends activemagiceffectActor Property MyTarget AutoEvent OnEffectStart(Actor akTarget, Actor akCaster);;does some things on this effect to akTargetMyTarget = akTarget((MyTarget as ObjectReference) as MagicEffect2).SetTarget(MyTarget)EndEvent

Note that this first script won't compile until after the second script has also been compiled as it relies on a function created in the second script.


Your SECOND Magic Effect script (different spell that can "target" that same NPC without aiming at it) will look like this:

Scriptname MagicEffect2 extends activemagiceffectActor Property MyTarget AutoFunction MyRef(Actor akActor)MyTarget = akActorEndFunctionEvent OnEffectStart(Actor akTarget, Actor akCaster)MyTarget.DoStuff() ;; <--- do stuff with the passed target from the first scriptEndEvent

The reason we don't use a variable in this instance is because you need the same property on both scripts in order for this to work.



Here is an example that I am using that works. The first script is the script that GETS the target. The second one receives the target property. I used this because you can't SetAlpha() on an actor using an OnLoad() event, as scripts attached to actors extend ObjectReference, not Actor.


Spoiler

Scriptname RCQSpawnWolf extends activemagiceffect  ActorBase Property Wolf Auto  Actor Property RCQWolfActor Auto  ;; <--- This is the property that is in use by BOTH scripts.GlobalVariable Property RCQWolfCounter AutoEffectShader Property RCQWolfShaderVar AutoEvent OnEffectStart(Actor target, Actor caster)		if(RCQWolfCounter.GetValue() == 0)		RCQWolfActor = Caster.PlaceActorAtMe(Wolf, 4)		((RCQWolfActor as ObjectReference) as RCQWolfShader).SetWolfActor(RCQWolfActor) ;; <-- This casts the ACTOR as an ObjRef as the second script (double casting, it's a little weird) and contains the function created in the second script. I can't use SetWolfActor() unless I call it on the script the function was created on (in this case, the name of the second script is RCQWolfShader). I cast my Actor as an ObjectRef as the second script name. This is extremely important.   	 RCQWolfCounter.SetValue(1)	EndIf		EndEvent

Second script, sets the alpha level of the wolf placed in the first script. Since you can't SetAlpha() on an ObjectReference and the script, which is attached to the ObjectReference, can't call the actor it is attached to, I pass it the actor property from the previous script.

Spoiler

Scriptname RCQWolfShader extends ObjectReference  EffectShader Property RCQWolfSummonFXShader AutoActor Property RCQWolfActor AutoFloat Property AlphaValue = http://forums.bethsoft.com/topic/1361959-generic-questions/0.33 Autobool Property AlphaFade = False AutoFunction SetWolfActor(Actor akActor)	RCQWolfActor = akActor	EndFunction	Event OnLoad()RCQWolfActor.SetAlpha(AlphaValue, AlphaFade)RCQWolfSummonFXShader.Play(self, -1.0)EndEvent

I hope this has made sense... it's a little tricky but once you've mastered this technique it will open up an entirely new world of Papyrus scripting for you. If I have confused you at all, please, feel free to ignore my post. :D


EDIT: Sorry - I misunderstood part of your question. The answer is yes, if you want to be able to call the target of the FIRST magic effect on your SECOND magic effect after the first magic effect has worn off you will have to store it as a property on a quest.
User avatar
Cartoon
 
Posts: 3350
Joined: Mon Jun 25, 2007 4:31 pm


Return to V - Skyrim