Jump to content

2 OBSE array questions (and 2 "General")


hawke1133

Recommended Posts

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

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

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

Logic, 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

... 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

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

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

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

  • 4 weeks later...

One last question on this and I post my code and then go and play in the corner quietly. lol

I 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 Array

let Array[0] := ar_Construct array

will 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

I think the correct syntax is just

ar_Resize actor[0] 4

 

For the append function, I think it's

ar_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

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

  • Recently Browsing   0 members

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