lorenzo19 Posted October 19, 2013 Share Posted October 19, 2013 I have this quest script (1 sec delay, gamemode) that does a ref walk. It works fine until I step out of the megaton player house. Then the script stops running. I got the apple bug fix in it.I am trying to understand the difference between IsValidForm and IsReference. Here's a little background to the situation. I narrowed down the problem to this fragment... Set rTemp to GetFirstRef 0 1 ;find everything - include surrounding cellsLabel 21 if rTemp != 0 Set rTemp2 to rTemp.GBO Set rTemp to Pencil01 Set rTemp to GetNextRef Goto 21 endifThe GBO does it. Stops the script cold. I trapped the ref that doing it. FFEE22. I searched the GECK for that ref and cant find it anywhere. Not in the objects or the cell view windows. Searched every cell in megaton. Have no idea what it is, but it's crashing GBO.I added these two conditions...if IsFormValid rTemp Set rTemp2 to rTemp.GBOendifStill stops the script. Evidentially FFEE22 is a valid form and loaded in memory. If that's true, FFEE22 should not crash GBO.if IsReference rTemp Set rTemp2 to rTemp.GBOendifThat works!But I am trying to understand, to be a better scripter, what the heck is going on. Is this a FOSE bug? Or normal? How can FFEE22 be a valid form but not a reference? What is the real difference between IsValidForm and IsReference? Link to comment Share on other sites More sharing options...
pkleiss Posted October 19, 2013 Share Posted October 19, 2013 (edited) I am trying to understand the difference between IsValidForm and IsReference. IsFormValid (not IsValidForm) identifies a valid object while IsReference identifies a valid reference. Take feral ghouls for example. There is one form, one object, in the GECK for a feral ghoul, but there are many references of them in the game. Think of the form as the master object and the reference as a single copy. If you look at the editor ID of the feral ghoul object in the GECK, you'll never see it in the game, as what is placed in the game are references (copies) of the object, not the object itself. That is why you can't find FFEE22 anywhere in the GECK - the GECK stores objects (forms) not references. So, GBO returns the form (the base object) of a reference. That result can be tested with IsFormValid, but not IsReference. If you want to know what FFEE22 is, use the prid (pick reference by ID) console command and see what happens when you ID it, it may tell you at the top of the console screen. You can the use the moveto player command to make the reference appear next to you, but this might crash the game also, depending on what the reference is. I seem to recall that references that begin with FF are spawns, like the Free Form encounters and the like. I have to ask why you are attempting to ref walk all references? That is crazy. Ref walking is very slow and out in the wastes, there will be hundreds and hundreds of references. The shear number alone might be causing your script to crash and it's just coincidental that it appears to be the GBO command - like the next iteration starts before all of the GBOs have completed from the prior iteration. I could see a ref walk of everything taking more than a second to complete. Regardless, tell me what it is you are trying to do with the ref walk and maybe we can come up with something more efficient. I added these two conditions...if IsFormValid rTemp Set rTemp2 to rTemp.GBOendif The proper use of IsFormValid would be like this, but I don't think it'll work because ref walks return references not objects: if rTemp.IsFormValid Set rTemp2 to rTemp.GBO endifif IsReference rTemp Set rTemp2 to rTemp.GBOendifThat works! Of course that works because a ref walk returns references (and you used it correctly) and IsReference will always be true with references. Note how the description of the IsReference command uses the term 'reference' while the description of the IsFormValid command uses the term 'objects'. As an aid, here is a ref-walk I made that also uses GBO... scn UCSpawnHat2Script Short DoOnce Short Depth Float XPos Float YPos Float ZPos Ref Self Ref Obj Begin GameMode If DoOnce == 0 Set Depth to 3 * (Player.IsInInterior == 0) Set Self to apple Set Self to GetFirstRef 24 Depth 0 ;Armors Label 11 If (self) Set Obj to self.GBO If Obj == UCSpawnHat2 player.moveto self EndIf Set self to apple Set Self to GetNextRef Goto 11 Endif ;self Set DoOnce to 1 disable markfordelete EndIf EndIt is also worth noting, as you can see from this script, that ref variables can store both references and objects. Edited October 19, 2013 by pkleiss Link to comment Share on other sites More sharing options...
lorenzo19 Posted October 19, 2013 Author Share Posted October 19, 2013 Didn't think of trying PRID or moveto. Tried it now and it says 'Item FFEE22 not found' in both cases. K thanks for that explanation. The docs for the two functions both say ref. It gets confusing cause everything in the game is a ref, be it a form or an instance of the form. I am used to object oriented languages where there are classes and instances of a class. Basically I understand that things in the GECK object window are like classes and things in the render window and cell view window are instances. But the docs get confused because everything is a ref. Maybe it might specify and say 'form ref'. But then real instances are also forms. lol. But all that is not necessarily true when it come to carry-able objects. lol. fun fun fun. I tell you why. Cause when I first wrote the ref walk, I specified only activators. I checked against a list of activators in question. (that's why I need OBJ) It worked sort of. It found the sinks but not the water fountain (both vanilla). Water fountains are activators so it should have found them. I changed it to find 'all' and that fixed the problem. Of course, I didn't know about the Apple Bug at the time. Would the apple bug have caused that??? Thanks for the example script. The loop part doesn't seem to be substantially different from mine. I could get rid of the (rTemp != 0). That's kind of redundant. I was wondering though, why you set the depth to 0 for interior cells? Link to comment Share on other sites More sharing options...
pkleiss Posted October 19, 2013 Share Posted October 19, 2013 (edited) Now that i know you are already a programmer, I can skip the basic theory BS...There are no adjacent cells for interiors, so a depth of 0 implies just the active cell - at least that is the way it was taught to me. Depth is really only for exterior cells. In practice, ref walks aren't perfect. They do miss objects on occasion. I spent quite a while working with them in the past. I have a you tube video somewhere showing some of the things I experimented with using ref-walks. Let me see if I can find it...Okay, here it is. The first and third toy use ref-walks. In fact the script I posted is for the teleport gun (the mislabeled first toy). Now that you know about the apple trick, try your script again with just activators and see if you don't get most or all of them. If you aren't getting some, try expanding the depth. Personally, I like 3 for exteriors. I've used that Depth definition in practically all of my ref-walk scripts. I still think checking for all refs is going to be problematic. Edited October 19, 2013 by pkleiss Link to comment Share on other sites More sharing options...
lorenzo19 Posted October 19, 2013 Author Share Posted October 19, 2013 (edited) Yeah that fixed it. It was the Apple bug. My loop now finds the sinks and water fountain when it is set to only find only activators. Funny thing. I went out into the waste around megaton with the loop set to find all. It walked over a thousand refs with the depth only set for 1. I have three different ref walking loops and they all have loop counters, so they exit the loop and display a message if they exceed max iterations. I got them set for 1000 max. Well the one loop I had set to 'find all' exited the loop. hehe. I reset it for 2000 and no premature exit. So that apple bug fix is saving a lot overhead. I don't really need a cell depth more than 1. Don't want my team wandering off too far to find stuff. Using your suggestions and adding my fix, all my ref walking loops are using this format now. Should be bullet proof or close to it. Set rTemp to Pencil01 Set rTemp to GetFirstRef 21 1 ;39 furniture, 201 inv obj, 21 activator, 1 include surrounding cells if exteriorLabel 21 if rTemp if IsReference rTemp ;prevent GBO from stopping the script Set rTemp2 to rTemp.GBO else Set rTemp to Pencil01 Set rTemp to GetNextRef Goto 21 endif ;do stuff Set rTemp to Pencil01 Set rTemp to GetNextRef Goto 21 endif BTW, what is the size of an exterior cell? maybe i do need to expand the cell depth. right now I have the team set to forage no farther than 3000 units. Those are pretty cool toys. I was wondering what the heck that loop was intended for. hehe. So you shoot the hat someplace then move to it. But you cant get the instance reference easily in a script for a inventory object. Maybe you could shoot a midget NPC instead. lol. Edited October 19, 2013 by lorenzo19 Link to comment Share on other sites More sharing options...
lorenzo19 Posted October 20, 2013 Author Share Posted October 20, 2013 I am now testing the ref walkers out in the wasteland and finding all sorts of anomalies. Hope you don't mind I have more questions. I'm a bit confused about the cell depth parameter. In my testing, 0 appears to only walk the one cell I am in. That makes sense. 1, on the other hand I am not certain about. For instance... My walker finds a fire hydrant, 4000 units away, in an adjacent cell. But it wont find a fire hydrant that is also in an adjacent cell and I am standing almost right next to it. Set depth for 2 and that fixes it. But i still would like to understand what is happening. I assumed depth one would walk the cell I am in plus the 8 surrounding cells. But that's not happening. A couple of anomalies, don't really need help with, but just FYI, if you don't know already, or someone reading might be interested. My ref walkers are not bullet proof yet. GetOwner returns 0 for inventory items in a cell that is owned. That means all the inventory items are owned. I don't want my team stealing stuff. So i added an additional test for cell ownership. if PlayerREF.GetParentCellOwner == 0. that fixed it. Then I was walking around and my ref walker pointed me to a stimpak. I went and stood right on it and there was no stimpak. At least not a visible one. I checked the GECK and yeah there is a stimpak there, enabled. But it's enable parent is disabled. So, the stimpak is actually disabled. I not sure if the ref walker will always find all disabled things or just the enabled ones that have disabled parent? It's a moot question really. I just added another test to the ref walker... if GetDisabled == 0, and that fixed it. Just checking if the enable parent is disabled is not good enough and that's more complicated, because the item might be set to be opposite of the enable parent. And there's no function that tests for that, that I could find. Link to comment Share on other sites More sharing options...
pkleiss Posted October 20, 2013 Share Posted October 20, 2013 * Exterior cells are 4096 X 4096 units - if I recall. The forums don't allow for searches spanning back far enough to lookup old threads.* The problem with the teleport gun was that moving to the spawned hat could land the player inside collision. This was especially troublesome in interior cells where the player might appear behind a wall and fall through the void. I never was able to get that toy to work well enough to release it. On a side note, I did try to script an NPC soccer match by using a tiny, invisible NPC (TN). The ball was scripted to center itself on the TN and other NPCs and the player could run into the ball/TN and using collision, scatter the ball around. It sort of worked, but the physics got out of hand some times as the ball could blast off for great distances. It was also kind of funny as the TN still spoke and kept saying stuff related to being bumped into. I can't recall specific quotes, but it was hilarious in context, having a talking soccer ball.* Cell Depth was never well documented. But, if I recall, 0 = the current cell only; 1 = the current cell plus the four adjacent cells (up, down, left and right); Each increase in depth adds all the adjacent cells in the same fashion. The key here is that diagonal cells aren't added with an increase in depth. This means you need a depth of at least 2 to get every cell that touches the current cell. Here is a picture. Each number represents a cell and the value represents what depth is required to include that cell... 2 212 21012 212 2 As you can see, you could be standing right next to a fire hydrant in a cell that is adjacent, but diagonal and you won't 'walk' it unless you have a depth of 2.*And yes, a ref walk will find disabled references, so using getdisabled is a requirement that i use all the time, just not in the sample I gave you before, sorry. You'll also find that the devs placed objects behind or under other collision and forgot about them. So your 'walk' will find objects from time to time that you will not be able to get to. Most of these are static objects though, but not always. You'd be surprised what is floating around in the void of some cells. As an example, there are several cars below the ground in the parking lot next to the red rider bicycle factory - near the outcast outpost added by Aiding the Outcasts DLC. In other examples, I've seen kit pieces floating/sunken outside of interior cells with a boatload of misc objects that had fallen through the geometry and collected on theses bits of loose ground. I think that's it for your questions... Link to comment Share on other sites More sharing options...
lorenzo19 Posted October 20, 2013 Author Share Posted October 20, 2013 (edited) Yeah, that answers a lot. Especially the picture. So, the search expands in a diamond shape rather than a square, like I was thinking. Makes sense now. Not much I can do about unreachable items except delete or move them as I come across them. I suppose its good that the ref walk walk finds disabled items. Could be a use for that. I did some more testing and the walker is working pretty good now. Found a quantum floating in the Potomac under a ruined bridge and a few stimpaks in some radioactive rubble. I not going to declare it bullet proof yet but it getting real close too it. Thanks for the help. That talking soccer ball is hilarious. lol. Accumulating too much energy has been a problem with physics engines for at least ten years. Surprised no one has come up with a fix for that yet. I am doing something similar to your teleport gun. I can carry unconscious followers then drop them. I don't really carry them. They get disabled and I carry the token with their name on it. Well they get dropped in a little bit in front of me, but if I am facing a wall and standing really close they get dropped behind the wall. hehe. Haven't quite figured that one out yet. rActor.MoveTo PlayerREF fXpos fYpos 40. IDK. If anyone is bold enough to drop their teammate into a wall... well. Really funny, while I was developing the script for dropping the unconscious follower, when I dropped them they would jet out about 1000 units and crash into anything that's in their way. lol. It was humorous but not very realistic. That happened because I enabled and moved them in the same frame. Now I enable them. Wait a frame, then move them. It not funny anymore but they get a softer landing. Have you tried using the ZPos parameter to move your player a few units above the hat? or shoot the hat into the air and wait a few frames for it to land? That way you know the hat is on top of the geometry. Be a nice dramatic pause and time for a cool sound effect. Edited October 20, 2013 by lorenzo19 Link to comment Share on other sites More sharing options...
pkleiss Posted October 21, 2013 Share Posted October 21, 2013 If you figure out how to teleport without appearing inside geometry, let me know. That problem is why I gave up on this idea three years ago. The hat isn't shot, but is spawned as a result of a projectile having the option for an explosion upon impact. Think of the hat as that explosion. It's a token, not a projectile. I toyed with several variations to try to figure a way to get the coordinates to exist within the world - to no avail. It's not just a matter of offset translation along any one axis. Sometimes the coordinates need a nudge in the X direction, sometimes Y, sometimes Z. Sometimes it a positive offset, sometimes its negative. Sometimes its a combination. Perhaps there is a way - by determining the LOS back to the player and nudging the coordinates along that line using trig functions. Still, if one hits the ceiling, you'll want a reduction in the Z, while hitting the ground would require an increase in the Z. It's tough to account for everything - which is why I gave up. Another method might include capturing the path of the projectile using a timer and choosing a set of coordinates earlier than the final position. Though I am at a loss on how to accomplish that. Like I said, if you figure it out, let me know... :thumbsup: Link to comment Share on other sites More sharing options...
lorenzo19 Posted October 21, 2013 Author Share Posted October 21, 2013 Does the hat itself end up inside geometry? Or just almost? Link to comment Share on other sites More sharing options...
Recommended Posts