Talk:GetSelf

From The Elder Scrolls Construction Set Wiki

[edit] Unreliability with Player

Scruggs: To clarify the issue with using getSelf on the player, in the following piece of code:

if ( getSelf != player && getSelf != playerRef )
  message "I am not the player!"
endif

...occassionally the message will be displayed even when the script is run on the player. A workaround for this is to use the code:

if ( getDistance player > 0 )


Any examples when this actually happens? "Occassionally" is a bit vague. Perhaps instead of that generic code above show us the script that actually had that bug?--JOG 13:50, 14 July 2006 (EDT)
Scruggs: "Occassionally" is a bit vague, but the issue is a bit vague, too. I'm speaking in terms of magic effect scripts. The generic code above is used as written in several of my scripts (with various text for the debug message), and all of them at some point have affected my character regardless. When using the getDistance workaround, with no other changes to the script, I have never had the problem occur. I apologize for not being able to explain why the issue occurs, but I can verify that it does.
To find out why is Bethesda's problem the when is the point, without the when, Bethesda will never fix this problem, because they can't reporduce it; I can't either. Magic effects is already one step closer, though it still could be an issue with the area of effect not being 0 or something similar. --JOG 03:09, 15 July 2006 (EDT)
Scruggs: Okay, I'll try to clarify further. I've made several spells in different mods which are cast by activators, either directly at the player or at a different actor. These spells have a radius effect. In cases where I don't want the spell to affect the player, the scriptEffectStart block uses this code:
begin scriptEffectStart
  set targetRef to getSelf
  if ( targetRef != player && targetRef != playerRef )
    message "Target Acquired / Valid Target / Other debug text"
    set validTarget to 1
  else
    dispel spellID
  endif
 end

 begin scriptEffectUpdate
   if ( validTarget )
     ; do stuff that will only affect valid targets
     message "I'm doing stuff."
   endif
 end
The vagueness of the above script is necessary because it illustrates a general issue with various scripts that follow the same form. The issue is, with the use of getSelf and the variable validTarget, there should be no possibility of the player being affected by the spell. As an example, in one script the "do stuff" section adds a potion to the target and then equips it. Given the conditions used, can you think of any reason why the script will sometimes cause my character to equip the potion, other than an issue with the getSelf function or the definition of the player reference?
I'm not the first to notice this issue, either. One discussion on the forums is here: [1]
ShadowDancer 10:31, 15 July 2006 (EDT): Why not just do what Bethesda does? Which is to make the player immune to that magic for the duration of the spell.
You can see this solution in the enchantments UniqueScrollEnStorms, UniqueScrollEnFireNexus, and probably a couple of the others where the area effect would include the player.
Additionally, wouldn't it just be easier to check the TargetRef against Player.GetSelf?
It seems to me that this code is broken. To me it reads that when the script is started, it checks for validation and validation always occurs during the ScriptEffectUpdate block, even if the TargetRef becomes changed. I would honestly have to see the whole coding of the script to say whether or not that happens.
Scruggs: Bethesda's solution is fine for ordinary spell effects, but not for scripted effects. Checking against player.getSelf may well work, but since I'm specifically having issues with using getSelf on the player, I don't trust it to work reliably. It seems more likely that it's not an issue with getSelf per se, as with the reference for the player, which doesn't seem to be defined in the way other references are. See the last post in this topic.
The code is fairly straightforward: When the script first runs, it sets validTarget to 1 only if the target is not the player. Subsequently, the rest of the script only runs if validTarget == 1. The targetRef variable is only used in the scriptEffectStartBlock, which only runs once. The script can be used as written, and will demonstrate this issue, at least in my copy of Oblivion.
ShadowDancer 11:53, 15 July 2006 (EDT): I would think that a 100% magic resistance on self would work nicely to keep the effect from operating on the character (unless you have Script Effect Always Applies checked on the spell). As for the GetSelf being buggy, I honestly haven't run into a problem with it. Then again, I haven't used a if ( targetRef != player && targetRef != playerRef ) either. To me that is the part that seems the most likely to be buggy, especially with the && in there. If either of those variables is false, the player is considered a valid target. What exactly is playerRef. I don't see it defined anywhere and I can't find it on the Wiki. The other thing is that the way that the parenthesis are used could possibly be causing problems (its happened before) and they aren't necessary for this script. My personal opinion is that If TargetRef != Player.GetSelf should be used instead of if ( targetRef != player && targetRef != playerRef ). To me this script looks like it is overly complicated and that is usually where the issues crop up.
Out of curiousity, why are you running the rest of the script in the ScriptEffectUpdate anyway?
OK, I just followed the last link to the topic. PlayerRef is a runtime variable that may or may not be set according to what is stated in that topic. That is most likely your issue in my opinion and if it were me, I would remove that from your if statement so that it just reads as If TargetRef != Player. I bet that will solve the issues you are having. Put a ; in front of the if statement and use the line above right below it. Worst case, you have to go back and take it out of one spell.
Scruggs: You're probably right that the && could easily throw it off. The thing is, I've used various versions of this code - checking for playerRef or player only, or checking for a positive match rather than a negative. PlayerRef is used interchangeably with Player by Bethesda, although player is used more frequently.
The script in this link seems to confirm the issue I'm having - in that case, the only other possibility would be your suggestion that the parentheses are interfering somehow. I'll have to look through the scripts I'm using. If it turns out to be an issue with the code and not the function, I'll remove the note from the page.
If your test-scripts are radius effect cast by an activator then they will run on the activator as well, and a debug-message might fool you.--JOG 12:47, 15 July 2006 (EDT)
Scruggs: Possibly, but having other effects (like drinking a potion) run on the player is a clear indication that something else has gone wrong. For the sake of preventing this discussion from becoming a column of single characters on the right-hand side of the page, I'm going to run some test scripts. I'll post the results here. (Thanks for the input, by the way).
ShadowDancer 13:14, 15 July 2006 (EDT): No prob. I created an area effect spell to add potions to everyone in the area and I could not duplicate the issue so something else must be going on. I even had a bunch of actors around and couldn't duplicate it using my version of the script. It might be something that only happens in certain situations, or it might be that the TargetRef gets messed up someplace in the middle of running. It adds some 130 or so potions though when I do it in the ScriptEffectUpdate block. Maybe it has something to do with the number of items added? The other possibility is that you should just use GetSelf in the if statement along the lines of If GetSelf != Player to bypass the issue. Thats what the other guy did rather than setting a variable to it.

Dragoon Wraith TALK 13:34, 16 July 2006 (EDT): (return to left) (Scruggs, please sign your posts, use ~~~~) I have a script like this:

ref self

[...]

Begin ScriptEffectStart

  set self to GetSelf
  if ( self == player )
    Dispel, "spell's ID"
  endif

[...]

End

And I have never had any problems with it. The upper right-hand corner will flash the "Burden" icon briefly, before the spell is dispelled, but other than that, it works perfectly.

Regarding this piece of code:

if ( targetRef != player && targetRef != playerRef )

That's exactly how that should be written. ( targetRef != player || targetRef != playerRef ) would always be true, because if it was one of those, it would not be the other. My personal preference for parentheses (Oblivion doesn't care as far as I know) for it would be this:

if ( targetRef != player ) && ( targetRef != playerRef )

By the way, does anyone know how the order of operations works with logical operators?

Finally, as for immunizing the player to the spell, I really don't think that's a very clean solution. It is entirely possible for the player to be hit with another spell during the duration of the immunity, which causes an unwanted side-effect.

ShadowDancer 13:47, 16 July 2006 (EDT): I agree about the unwanted side effect. It wouldn't be my first choice on how to handle the situation either. It is how Bethesda chose to deal with area effect damage with the player in that area however. They didn't give 100% magic resistance, but they did make the player immune to the particular type of magic being used (fire, shock, etc) for 2 seconds longer than the spell's damage component duration. I agree that the scripting is correct, however that doesn't explain the reason for the glitch. I am not sure we will ever be able to fully define why the glitch happens from outside of the game's coding. I was trying to offer what seemed like the most probable place for the glitch to occur in the scripting and possible ways to bypass it. My personal preference for parenthesis, if I use them, is the same as yours too.
JOG: The order of operations is described in the If-Page: same as everywhere: first "OR" then "AND". As for the GetisID problem, I still think it's caused by either the spell affecting something else than the player or some strange issue with playerRef
Dragoon Wraith TALK 19:30, 16 July 2006 (EDT): Thank you, JOG, I'd missed that.

Using GetIsReference player solves the above problem. Scruggs 16:52, 12 February 2007 (EST)

Personal tools