Guest tomm434 Posted December 23, 2014 Posted December 23, 2014 You need to use If Blah.IsFormValid == 1
asdf0 Posted December 23, 2014 Posted December 23, 2014 You need to use If Blah.IsFormValid == 1 "Blah" isn't my variable, it's just the scope of the variable which is called ref. So if anything, it should be Blah.ref.IsFormValid but that also gives a syntax error.
DoctaSax Posted December 23, 2014 Posted December 23, 2014 if(IsReference Blah.ref == 0) isn't NV scripting lingo. You declare the variable first before you start the script block, then only use the name ref Blah Begin someBlockType if IsReference Blah
prideslayer Posted December 23, 2014 Posted December 23, 2014 You need to use If Blah.IsFormValid == 1 No no no.. If it's not valid, that's just going to crash. if (IsFormValid someRefVar) ; it is endif if (0 == IsFormValid someRefVar) ; it is not endif if(IsReference Blah.ref == 0) isn't NV scripting lingo. You declare the variable first before you start the script block, then only use the name ref Blah Begin someBlockType if IsReference Blah Also this. The normal boilerplate is basically something like this: scn someScript ref myRef Begin GameMode ; some stuff is here setting/getting myRef if (IsFormValid myRef) if (IsReference myRef) ; myRef is fully valid, proceed. else ; myRef is a valid form, but not a valid ref. It might be a basetype ; or some other form type, but not a reference. endif else ; myRef is entirely invalid. endif End
Swyke Posted December 23, 2014 Posted December 23, 2014 As I understand it, asdf0's variable is named 'ref' and 'blah' is (for example) the QuestScript where the variable is declared. And in his example he wants to check the variable outside the original script (so he has to write blah.ref ... or better 'QuestScript.TestRef') and this doesn't work as it should? So maybe you have to go the long way and have to write something like this? (Im not on my modding computer) ref CheckREF let CheckREF := QuestScript.TestREF if (IsFormValid CheckREF ... ???
prideslayer Posted December 23, 2014 Posted December 23, 2014 Yes, I'd do that first. It's just easier to read and maintain. "let myRef := Blah.ref" as a first line in my example boilerplate above.
Guest tomm434 Posted December 23, 2014 Posted December 23, 2014 No no no.. If it's not valid, that's just going to crash. Wait wait wait - does that mean that this code If MyRef.GetType !=0 will crush too if MyRef Doesn't exist in any form?
prideslayer Posted December 23, 2014 Posted December 23, 2014 No no no.. If it's not valid, that's just going to crash. Wait wait wait - does that mean that this code If MyRef.GetType !=0 will crush too if MyRef Doesn't exist in any form? Yes, probably. GetType may be special, but it's best to never take chances. If there's any chance that a ref may be invalid, use IsReference with an argument -- not as a member function of the ref.
DoctaSax Posted December 23, 2014 Posted December 23, 2014 Rule of thumb is only use reference syntax with a function if there is an actual reference there.
prideslayer Posted December 23, 2014 Posted December 23, 2014 I only use that syntax if I check first as described, or if I'm working on a reference I know is valid -- e.g. playerRef, or something else hardcoded as a ref. Never on random ref vars without validating them first, and usually not even then. Too much chance of it going wrong, especially in frame-split scripts where you might check it at the start -- then it turns up invalid in the next stage of the script a few frames later. Of course sexout sometimes breaks this rule in a few larger scripts I need to fix (sometimes checked/set in one frame, used later without rechecking).
DoctaSax Posted December 23, 2014 Posted December 23, 2014 Eh, I don't always check if a previously captured ref is still valid either - I catch up when I think of it. What I meant though was that because a lot of scripters start out using actor/ref functions first (entry-level functions like getav, additem etc), they get used to ref syntax, and then try to apply it to forms that can never be refs (races, quests, formlists etc), especially if passed to a ref var. Functions like IsFormValid & IsReference already imply you don't know if it's gonna be a reference, so object syntax is the only way to go. GetType is in the same area.
Guest tomm434 Posted December 23, 2014 Posted December 23, 2014 Thanks - I'll use object syntax from now on!
prideslayer Posted December 23, 2014 Posted December 23, 2014 The whole ref method syntax and implied ref syntax were huge mistakes on beths part. It's best to just ignore them. Also, slap whatever oblivion wiki person wrote that this is bad: set self to GetSelf self.someBlah and this is 'better' someBlah ; implied ref That person got that exactly backwards and wrong. The first method is the better method. Being more explicit is never 'bad'. You have to do some checking when it comes to getself vs. getcontainer but it's a small price to pay for code that Just Works no matter where you put it. --------- As an aside, from an OOP standpoint, "ref.foo" is perfect "object syntax." I would call them function syntax and method syntax. someFunc(someRef); -- function syntax, you call it like a procedure/function in a non OOP language. someRef.someFunc(); -- method syntax, you call it like a class/object method. That said.. just avoid using the latter unless you have no choice. It's not any shorter to type, and the very real pitfalls outweigh the perceived (but mostly not real) benefits. GECKScript isn't an OOP language, and pretending that it is just leads to even more heartache (and heartburn, and headache). Edit: disclaimer... this in no way applies to skyrim. Papyrus is in fact an OOP language, more or less.
Guest Posted December 23, 2014 Posted December 23, 2014 Wait wait wait - does that mean that this code If MyRef.GetType !=0 will crush too if MyRef Doesn't exist in any form? EDIT: no wait, it was if GetType MyREF, my bad Being more explicit is never 'bad'. You have to do some checking when it comes to getself vs. getcontainer but it's a small price to pay for code that Just Works no matter where you put it.NV vanilla does it very often. It uses explicit ref even when it's obvious than an implict would still work. I guess they think like you
prideslayer Posted December 23, 2014 Posted December 23, 2014 It's the "right way" to do it. Not only is it obvious what the script is doing, it also means it will still work with minimal changes if you copy/paste it somewhere else. Some wiki thing (I think the page for CIOS, I'll go look) said that this is "bad bad bad, don't so it" ref self set self to getself self.cios somespell and said instead to just do cios somespell The second example is much shorter, but the first one is much more robust, and nothing 'bad' about it. The first time I read that, I thought there was some actual technical problem with doing it the first way, they made it sound so bad. There isn't. It works fine, and is reliable. If you need to move that code somewhere else later, like out of a spell script and into a quest script, you only have to change one line (the getself needs to do something else like get an NX var or quest var) and it will still work. If you do it the "wiki recommended" way you have to write all that stuff I wrote in the example anyway so...... yeah. Implicit refs, bad. Method calling syntax, bad. Explicit refs, good. Function calling syntax, good.
prideslayer Posted December 23, 2014 Posted December 23, 2014 Yeah it's in the wiki on the "getself" page in the notes. I'm just going to delete that now. Yay wiki.
prideslayer Posted December 23, 2014 Posted December 23, 2014 annnnnd fixed. How long until an 'edit war' I wonder.
DoctaSax Posted December 23, 2014 Posted December 23, 2014 It's the "right way" to do it. Not only is it obvious what the script is doing, it also means it will still work with minimal changes if you copy/paste it somewhere else. Some wiki thing (I think the page for CIOS, I'll go look) said that this is "bad bad bad, don't so it" ref self set self to getself self.cios somespell and said instead to just do cios somespell The second example is much shorter, but the first one is much more robust, and nothing 'bad' about it. The first time I read that, I thought there was some actual technical problem with doing it the first way, they made it sound so bad. There isn't. It works fine, and is reliable. If you need to move that code somewhere else later, like out of a spell script and into a quest script, you only have to change one line (the getself needs to do something else like get an NX var or quest var) and it will still work. If you do it the "wiki recommended" way you have to write all that stuff I wrote in the example anyway so...... yeah. Implicit refs, bad. Method calling syntax, bad. Explicit refs, good. Function calling syntax, good. I don't really follow how implicit refs are quite so 'bad', considering the only advantage you mention is being able to easily transfer let's say a spell script to a token script. I also don't think keeping things explicit is in any way bad either. What you call method syntax is obviously unavoidable with reference functions - so maybe calling it bad isn't such a good idea either - you wouldn't want people to shy away from a simple MoveTo. Also, dual-syntax ones usually apply to the ref or the base depending on how you call it, and sometimes you'd rather not touch the base, which could be... bad. Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has: GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world).
prideslayer Posted December 24, 2014 Posted December 24, 2014 I don't really follow how implicit refs are quite so 'bad', considering the only advantage you mention is being able to easily transfer let's say a spell script to a token script. What you call method syntax is obviously unavoidable with reference functions - so maybe calling it bad isn't such a good idea either - you wouldn't want people to shy away from a simple MoveTo. Also, dual-syntax ones usually apply to the ref or the base depending on how you call it, and sometimes you'd rather not touch the base, which could be... bad. Well they're "lazy" and as a developer, I find that "bad". The advantage of being easier to transport also makes potential problems more obvious. A "simple moveto" (I assume something like just "moveto playerref" is what you mean) only looks simple, but it's effectively doing the same thing as the longer code. If you see that longer code when you're working on it, you may recognize more quickly that it's wrong in another context. It may not be as apparent with just the one liner. I'd absolutely want people to "shy away" (as in "never use") such a "simple moveto." Not using shortcuts is a habit I've formed over working in a lot of different languages and on different projects. Sooner or later they lead to problems that aren't always easy to find. I advocate the "if (1 == somevar)" rather than "if (somevar == 1)" syntax for the same reason, even though the technical reason behind it doesn't apply to geckscript. Good code is cross-platform. Good coding technique is, as well. Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has: GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world). I have no idea, but it sounds bogus, like much of what's been copied over from the oblivion wiki. Speaking of that, some weeks or months back they changed the layout of that wiki or something. Every link on every GECK wiki page that goes to an oblivion wiki page is broken.
astymma Posted December 24, 2014 Posted December 24, 2014 I've always followed a simple rule, and YES, it's because when I started programming we were still storing everything on magnetic tape or punch cards, but that rule is a good one to follow: Explicit is always preferred to implicit. Implicit code was created to promote elegance NOT functionality. IMO, elegance is vastly overrated... it's elegance that confuses people who are inexperienced. When you write code like... MoveTo PlayerREF ...vs. code that says: ref rSelf set rSelf to GetSelf rSelf.MoveTo PlayerREF ...you run into various problems which aren't obvious at a glance. The first example is relying on implicit compiler/interpreter behavior. If that behavior changes, the code runs differently. The first example depends on the programmer understanding that implicit compiler/interpreter behavior to understand the code itself. The first example is NOT self-documenting and thus is harder to debug at first glance. I can tell you from experience, and I mean 30+ years of it, IMPLICIT bugs are the hardest bugs to find, especially if they're the result of implicit compiler/interpreter behavior changing. EXPLICIT code is self-documenting... the above second example is very clear as to what it does, the code itself documents what it's doing. It is easier to find bugs in explicit code, usually at first glance. And... I'm preaching at this point, so I'll stop... besides, you get the idea... EDIT: Or... I coulda "liked" Pride's posts... meh.
DoctaSax Posted December 24, 2014 Posted December 24, 2014 With the moveto comment, I no longer referred to implicit refs, but this: someFunc(someRef); -- function syntax, you call it like a procedure/function in a non OOP language.someRef.someFunc(); -- method syntax, you call it like a class/object method. in combination with: Implicit refs, bad.Method calling syntax, bad.Explicit refs, good.Function calling syntax, good. which in the context of this thread, geck scripting, seems to warn people off using reference syntax at all, including when you have no choice in the matter as with ref functions like moveto
asdf0 Posted December 24, 2014 Posted December 24, 2014 As I understand it, asdf0's variable is named 'ref' and 'blah' is (for example) the QuestScript where the variable is declared. And in his example he wants to check the variable outside the original script (so he has to write blah.ref ... or better 'QuestScript.TestRef') and this doesn't work as it should?That's exactly it. Anyway, I "solved" it; instead of if(IsReference Blah.ref == 0) set Blah.ref to 0 endifwhich can't be compiled I now have ref tempRef set tempRef to Blah.ref if(IsReference tempRef == 0) set Blah.ref to 0 endifand everything is working great. Different problem: I have some scripts that add creatures to new factions (and sometimes remove them from these new factions later) during gameplay, and I've noticed that most creature enemies (e.g. Deathclaws) are "allied" to the player (GetFactionRelation player -> 2). The weird thing is that once I remove their original faction (e.g. DeathclawFaction; 00021474 in FalloutNV.esm) with RemoveFromFaction, then their faction relation to the player is immediately reset to the correct value (which is 0) but none of the loaded mods alter DeathclawFaction or PlayerFaction in any way (I checked with FNVEdit) and of course Deathclaws are not normally allied to the player or vice versa. Just in case, I checked whether the player had been erroneously added to DeathclawFaction (which is the only faction DeathclawFaction is allied with) but of course that wasn't the case. So what is going on here? Edit: Also, is there an in-depth explanation on faction relations somewhere? My understanding is that when the player is involved, the friendlier of the two relations is applied to both directions; i.e. "player.GetFactionRelation enemy" will always return the same value as "enemy.GetFactionRelation player". But I don't know if this is true.
prideslayer Posted December 24, 2014 Posted December 24, 2014 which in the context of this thread, geck scripting, seems to warn people off using reference syntax at all, including when you have no choice in the matter as with ref functions like moveto Ah no, I did say to not use it unless you have no choice. If you have no choice, go ahead.
Guest luthienanarion Posted December 24, 2014 Posted December 24, 2014 Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has: GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world). I have no idea, but it sounds bogus, like much of what's been copied over from the oblivion wiki. In my experience, this is correct: GetSelf will not return a dynamically-generated reference. However, PlaceAtMe returns a reference to the created object. In order to do something with a PlaceAtMe-created object: let refVar := someRef.PlaceAtMe someObject 1 This is outlined in the wiki page, as I recall.
Guest Posted January 2, 2015 Posted January 2, 2015 As in game effect, AddSpell inside a script will visualize on top left corner the string called sAddItemToSpellList. I would like to remove it, but it doesn't allow some "1" extra parameter like it happens for AddItem for example. However, if I simply set the string to no characters, I will see the empty box effect on top left. Someone has an idea on which path I should take to solve it? EDIT: this was very bad explained. AddSpell MySpell This script will let a box appearing on top left, with the word "added" on it. This word comes from the ini setting sAddItemToSpellList. I would like to remove the whole box, but I can't simply put that ini setting to an empty string because the box will still appear (an empty box) and I don't want it. But on the other side, it's not like for AddItem, where I can put some extra parameter to mask the message on top left. Someone has an idea on how I could solve this?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now