Jump to content

Extending and Including Confusion


Lunalle

Recommended Posts

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

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 by mrpwn
Link to comment
Share on other sites

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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...