Lunalle Posted September 21, 2016 Share Posted September 21, 2016 Greetings all. I'm hoping one of the more veteran scripters would clear some confusion up for me. I'm rather new to papyrus, but not to programming in general. Thanks in advance. 1) I'm monitoring the player via a blank quest w/ script attached for various events. However, those scripts extend ReferenceAlias (of the player). I don't fully understand what that means, and I would appreciate some clarification. E.x. are onX triggers only when fired by the player, or seen by the player, or in radius Y of the player etc. 2) To build on that a bit, how would I reference a "this" value from another extender. E.x. if a script extends activemagiceffect then "this" becomes the active magic effect. However, I can't seem to access it in the script attached to the player (extends ReferenceAlias). How would I go about doing so? I've tried "Import ActiveMagicEffect" "ActiveMagicEffect.this" etc. with no success. Cheers Link to comment Share on other sites More sharing options...
mrpwn Posted September 21, 2016 Share Posted September 21, 2016 (edited) 1. ReferenceAlias is kind of a wrapper around the instance of ObjectReference that the alias is filled with. ReferenceAlias receives events available to scripts that extend ObjectReference (and Actor, if the alias is filled with an instance of Actor). However, Self points to the instance of ReferenceAlias and not the instance of ObjectReference or Actor that the alias is filled with. To access the latter requires using the GetReference or GetActorReference functions. Script SomeAlias extends ReferenceAlias Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) ;The ObjectReference/Actor filling this alias was hit by something, let's delete it Self.Delete() ;Won't compile as this ReferenceAlias does not have such a function ObjectReference kRef = Self.GetReference() ;Get the thing that is filling this alias kRef.Delete() ;Delete the thing that is filling this alias EndEvent 2. ActiveMagicEffect is a special case since it is usually very short-lived and you should not try to manipulate an instance of that from another script. An instance of ActiveMagicEffect is volatile and may be terminated at any time by the game engine. Let's say you had a script called MagicalStone, which extends ObjectReference and is attached to a stone object placed somewhere in the game world. You could use a property, which is of the type MagicalStone, in another script to access that specific stone. MagicalStone Property kStoneRef Auto Event SomeEvent() kStoneRef.MoveTo(Game.GetPlayer()) EndEvent The property, kStoneRef, is then filled inside of Creation Kit via the properties window of the second script that you attached to something. Let's say all instances of that stone object had the MagicalStone script, were scattered around the game world, and you wanted to access functions (or other stuff) from any instance of that stone object that is near the player. What you could do is get the nearest instance of such a stone object either as an ObjectReference via e.g. Game.FindClosestReferenceOfTypeFromRef or by filling a ReferenceAlias in a quest. Form Property kStoneBase Auto Event SomeEvent() ObjectReference kStoneRef = Game.FindClosestReferenceOfTypeFromRef(kStoneBase, Game.GetPlayer(), 1024.0) If kStoneRef MagicalStone kMagicalStoneRef = kStoneRef as MagicalStone kMagicalStoneRef.SomeFunction() ;Call non-global functions from MagicalStone on kMagicalStoneRef EndIf EndEvent You can "traverse" the tree of inheritance by casting a variable from one type to another. If scripts A and B are both attached to an object in the game world and extend script ObjectReference, then you can call functions from script B inside of script A by doing a double-cast. Script A extends ObjectReference Event SomeEvent() B kBRef kBRef = Self as B ;Does not work as A does not extend B nor does B extend A kBRef = (Self as ObjectReference) as B ;We get around the issue by going back one step to ObjectReference and then going down another branch to B kBRef.SomeFunction() EndEvent The Import keyword simply allows you to call functions, which have the Global keyword, without prefixing the function call with the imported script's name. ;Case #1 - Script that does not import the Debug script Event SomeEvent() Debug.Notification("Some message") EndEvent ;Case #2 - Script that does import the Debug script Import Debug Event SomeEvent() Notification("Some other message") Debug.Notification("Some other message") ;The "Debug." part is not necessary, but it is still allowed EndEvent ;Case #3 - Script that does import the Debug script, but also has (or inherits) a definition for a function called Notification Import Debug Function Notification(String asText) ;Does something EndFunction Event SomeEvent() Notification("First message") ;This will not compile, because the compiler does not know which definition to use Self.Notification("Second message") ;Uses the definition from this script or an inherited definition Debug.Notification("Third message") ;Uses the definition in the Debug script EndEvent Edited September 21, 2016 by mrpwn Link to comment Share on other sites More sharing options...
Lunalle Posted September 21, 2016 Author Share Posted September 21, 2016 Thank you for that amazing reply. I think my confusion lies in the fact that I am trying to use activemagiceffect, from my "extends ReferenceAlias" script but, as far as I can tell, "activemagiceffect" is not extended by anything, and extends nothing. If I understand correctly, this means there is no way to cast to it. Basically what I want to do is hook when the player casts or gets hit by a spell, and get the details of that spell. I can make a new script extending activemagiceffect, and attach it to every single magiceffect in the CK, but that seems like a horribly inefficient waste of time. Any advice on the best way to proceed? Link to comment Share on other sites More sharing options...
Lunalle Posted September 21, 2016 Author Share Posted September 21, 2016 I think I can get done what I want with SKSE, would appreciate confirmation about the possibility (or not) of hooking activemagiceffect somehow though. :) Link to comment Share on other sites More sharing options...
IsharaMeradin Posted September 21, 2016 Share Posted September 21, 2016 You can use OnHit event to obtain the spells that hit the player. akSource would most likely be for area affect type spells like frenzy or charm. akProjectile would most likely be for targeted spells like ice spike since the spell itself doesn't hit the player. You can use OnSpellCast to obtain the spells that the player uses. Both of these will work on your ReferenceAlias script for the player without need to link to any ActiveMagicEffect scripts. Link to comment Share on other sites More sharing options...
Lunalle Posted September 22, 2016 Author Share Posted September 22, 2016 I hadn't even looked at OnHit yet.... I assumed that fired when <reference> hit something, not when something hit <reference>. Thanks. Link to comment Share on other sites More sharing options...
Recommended Posts