hawke1133 Posted April 12, 2011 Author Share Posted April 12, 2011 GetFirstRef and GetNextRef are designed to be used together within a single run of a single script. GetFirstRef is what resets the search. Whenever you use it, you will start over, no matter what you have done before.GetNextRef, of course, keeps returning the next reference until (1) there is no more references of that type to return or (2) you reset the process by using GetFirstRef again. If you use them in different scripts (GetFirstRef in one script and GetNextRef on another) or in different frames (GetFirstRef in one frame and GetNextRef in the next) the results are unpredictable, as many other scripts from many other mods may have used them in between. Hope this helps understanding them.Clear as mud! lol Thanks. I do understand. Just keep them in the same script, otherwise the values will be incorrect (corrupted) depending on the last call to these functions. Now I need to figure out how to pull the data off the array via index (manually walking the index) and use a tempref.moveto player (and other tricks.)Any advice? I have a variable sized array and the index counter is captured (during the filling of the array) just for this purpose.Almost got it working. Thanks for all the help! Link to comment Share on other sites More sharing options...
QQuix Posted April 12, 2011 Share Posted April 12, 2011 (edited) array_var actors array_var entry ref tempref . . . foreach entry <- actors let tempref := *entry if <whatever> tempref.moveto playerref endif loop or, for Array type arrays let ix := -1 while ( ix += 1 ) < ar_size actors let tempref := actors[ix] if <whatever> tempref.moveto playerref endif loop Edited April 12, 2011 by QQuix Link to comment Share on other sites More sharing options...
hawke1133 Posted April 13, 2011 Author Share Posted April 13, 2011 array_var actors array_var entry ref tempref . . . foreach entry <- actors let tempref := *entry if <whatever> tempref.moveto playerref endif loop or, for Array type arrays let ix := -1 while ( ix += 1 ) < ar_size actors let tempref := actors[ix] if <whatever> tempref.moveto playerref endif loopLogic, oh sweet logic! Thanks a bunch. I almost had it working but the "while (xvar) . . . loop" logic was screwed up! Thanks again! (I really need to learn my write out my logic and analyze it before dumping it into code!) One other thing. The logic behind the "let ix := -1 while ( ix += 1 ) . . . " It took me a minute to understand why it was done. But I see why. Now that you folks have basically wrote my code for me. My deepest thanks. I can definitely tell that scripting (and modding in general) is going to be a fun challenge. Hopefully, I will learn enough to return the favor (to the community) and build some good mods. Thank you QQuix and the rest who have helped. (And Stryker879, I STILL keep doing the error of "Let x :=y" in my code. I will try to remember to put a space after the ":=" lol) I will post my completed code and a brief "what it does" when I have it is working. (Hopefully!) Last question on this topic and then I will shut up. lol In the event I can get some decent code built out, should I release "code snippets" as a modders resource? Link to comment Share on other sites More sharing options...
Astymma Posted April 13, 2011 Share Posted April 13, 2011 ... logic was screwed up! Thanks again! (I really need to learn my write out my logic and analyze it before dumping it into code!) ... Something I tell to any programmers I am mentoring is to write the entire application as comments before ever writing a line of code. It will reveal most logic errors immediately and will often demonstrate the worthiness of the methodology you have chosen. It also has the advantage of making your code pre-documented and MUCH easier to come back to at a later date and figure out what the heck was going on. Link to comment Share on other sites More sharing options...
Striker879 Posted April 13, 2011 Share Posted April 13, 2011 Thank you for the kind mention hawke1133, but my contribution is almost of a 'punctuation' level compared to fg109's and particularly QQuix's. That you are able to grasp the logic behind the "let ix := -1 while ( ix += 1 ) tells me we aren't in the same league ... I'm still completely lost on seeing how QQuix's first draft edition of fg109's original post is able to do the same job. I ran into the same problem years back when I tried to learn C++. I'm able to "Hello world" and write basic stuff. All the "Learn C++" books I bought would eventually venture into areas where even stepping through the code and watching variables change in the watch window wouldn't help me get my head around 'how' it worked. In truly elegant code like QQuix's, there's a level of abstraction or something going on that works on a plane I'm unable to fathom. If I try my hand at scripting, you'll see my "Help" posts here, don't worry. Link to comment Share on other sites More sharing options...
hawke1133 Posted April 13, 2011 Author Share Posted April 13, 2011 Thank you for the kind mention hawke1133, but my contribution is almost of a 'punctuation' level compared to fg109's and particularly QQuix's. That you are able to grasp the logic behind the "let ix := -1 while ( ix += 1 ) tells me we aren't in the same league ... I'm still completely lost on seeing how QQuix's first draft edition of fg109's original post is able to do the same job. I ran into the same problem years back when I tried to learn C++. I'm able to "Hello world" and write basic stuff. All the "Learn C++" books I bought would eventually venture into areas where even stepping through the code and watching variables change in the watch window wouldn't help me get my head around 'how' it worked. In truly elegant code like QQuix's, there's a level of abstraction or something going on that works on a plane I'm unable to fathom. If I try my hand at scripting, you'll see my "Help" posts here, don't worry.(I know I am should snip posts, but this is worth it.)Here is the logic behind the "let ix := -1 while ( ix += 1 ) != ar_size "array"this "while" loop increments ix by one in the first statement of the block. In an array, your first "index" starts at 0. So to start filling an array at 0, you set the counter to -1 and the first run of the loop, ix becomes 0 (before it reaches an array command) and on the next run, it is 1 and so on. Pretty cool, as far as I am concerned. Link to comment Share on other sites More sharing options...
QQuix Posted April 13, 2011 Share Posted April 13, 2011 Since you guys seem interested . . . What I did was pretty much apply some cosmetic tricks/improvements on fg109's script: 1) Instead of using an additional variable (DoOnce) to initialize the array, I used the array itself, since array_vars ARE set to zero until you initialize them. 2) Instead of walking the array to see if the NPC was already there, if used ar_find, which does exactly the same thing. 3) instead of keeping an index to add a new NPC to the array, I used ar_append All in all, it is the same script . . . just different. The "while ( ix += 1 )" thing came from an example scruggsywuggsy the ferret (one of the OBSE developers) posted long time ago. As hawke1133 explained, it takes advantage of the fact that the operation within parenthesis takes precedence and is evaluated first and, by the time the "while" is evaluated, the variable ix already has the new value. I also thought it was elegant and adopted it. A couple of other uses: Walk an array backwards: let ix := ar_size MyArray while ( ix += -1 ) >= 0 . . . loop Do something a number of times (not array related): let n := 5 while ( n += -1 ) >= 0 ; loops n times . . . Loop hawke1133, releasing one's work as moder resource if a personal decision, no questions asked.Myself, I release all my mods mentioning that the scripts are free to take (no big deal, anyway, since most of my mods are proof of concepts with the sole purpose of presenting the scripts to whomever may be interested) Link to comment Share on other sites More sharing options...
hawke1133 Posted May 6, 2011 Author Share Posted May 6, 2011 One last question on this and I post my code and then go and play in the corner quietly. lolI had gotten the code to work fine. Now I need to expand it. Here is the problem.I need to set create and array of the array Actors so that Actors[index][index_size_4]i.e. when I append the refid to the array, I need 4 (actual size to be determined) internal index slots for status checks.I know that - let Array := ar_Constuct Arraylet Array[0] := ar_Construct arraywill give me what I need partially.What I need is to set the inner array size to 4 on the creation of the array.That way I can just use this if actor == 0 let actor := ar_Construct Array let actor[0] := ar_Construct Array let actor[0][0] := ar_Resize actor [0][0] 4 ;syntax?Am I correct in my assumption that this would carry over in an append function?(ar_append tempref actor[index+1] [size_4] ?) That way the arrays are already built and I can use them immediately.Would the code I added work? Or am I barking up the wrong tree. (In case anyone is interested, I am working with pihwht on his Train The Player addon for muggervamp. lol) Link to comment Share on other sites More sharing options...
fg109 Posted May 6, 2011 Share Posted May 6, 2011 I think the correct syntax is justar_Resize actor[0] 4 For the append function, I think it'sar_Append actor[0] "whatever you want as the new element in the array" However, if you use the resize function, then I don't think you should be using the append function. When you use the resize function for actor[0], that would give you actor[0][0], actor[0][1], actor[0][2], and actor[0][3], all of which are equal to 0. Then when you use the append function, you create actor[0][4], which will be equal to whatever you wanted to append. Basically, just stick with the append function and forget about the resize function. That is, unless you want your actor[0] array to have 4 zero values at the front. And something I just thought of. Right after you use ar_Construct, I think an array element is added so the append function might not work as you want it to. For example... let temparr := ar_Construct Array ar_append temparr 512 I think 512 will end up being temparr[1] while temparr[0] stays as 0. Link to comment Share on other sites More sharing options...
QQuix Posted May 7, 2011 Share Posted May 7, 2011 I am not really sure of what you need, so I will assume you want to keep a set of data/information/attribute/status/whatever for each actor. In this case, I would use what I call an array-object: an array that stores everything I need to know about an object (in this case the object is an actor) Let's say, as an example (and not a good one, I am afraid), that you want to keep the actor Reference, Name, Health and Age. You may build an "Actor" array like this:Let Actor := ar_Construct stringmap (I, personally, prefer stringmaps, but this could be an array) Let Actor["Ref"] := tempref Let Actor["Name"] := tempref.getname Let Actor["Heath"] := tempref.GetCurrentHealth Let Actor["Age"] := tempref.getage (as if there were such a function) This way, you have an array representing an actor and this array might be appended to the "Actors" array in a GetFirst/NextRef loop.Problem is that ar_find could not be used to find a similar array in the Actors array (it is not built that way), so I wuld create two "Actors" arrays: one for the refs and one for the attributes.Something like: Let ActorsStats := ar_Construct array Let ActorsRefs := ar_Construct array . . . let tempref := GetFirstRef 69 while tempref if <whatever filters you may want to aplly> if eval (ar_find tempref ActorsRefs) < 0 ;=== Current NPC not in array yet == ar_append ActorsRefs tempref Let Actor := ar_Construct stringmap Let Actor["Ref"] := tempref Let Actor["Name"] := tempref.getname Let Actor["Heath"] := tempref.GetCurrentHealth Let Actor["Age"] := tempref.getAge ar_append ActorsStats Actor endif endif let tempref := GetNextRef loop Of course, there many other approaches to the same problem and the best one (if any) depends of what exactly you want to do. fg109, no, ar_construct creates an empty array (ar_size = 0), so when you first append something, it becomes Array[0] and ar_size turns to 1. Link to comment Share on other sites More sharing options...
Recommended Posts