davidlallen Posted March 6, 2011 Share Posted March 6, 2011 I have a set of six machines, each with a terminal and an output tray. When the player does the right thing with the terminal, a terminal script runs and creates a different item at each machine. The item is supposed to appear in the output tray. Sometimes this works, sometimes it doesn't, so I need to figure out a different approach. When it doesn't work, the item appears in an unexpected location, sometimes at the player's feet, sometimes stuck inside the machine itself. Then it may go flying away, or be wedged along an edge of the machine, or some other bad problem. Here is the useful bit of the terminal script: ref rPart ref rFab ref rItem ; choose proper part based on which terminal if getisreference TDGFabCoreRef set rPart to TDGPartCentralCore ... check for the other five machines ... else set rPart to TDGPartLimbActivator endif ; get position for drop set rFab to getlinkedref set TDGGenQuest.iLevel8X to rFab.getpos x set TDGGenQuest.iLevel8Y to rFab.getpos y set TDGGenQuest.iLevel8Z to rFab.getpos z + 128 ; drop item and set position set rItem to placeatme rPart 1 rItem.setpos x TDGGenQuest.iLevel8X rItem.setpos y TDGGenQuest.iLevel8Y rItem.setpos z TDGGenQuest.iLevel8Z The "placeatme" wiki entry says you should not use other commands in the same frame as placeatme. But sometimes the items shows up in the correct location above the output tray, which is the linked reference of the terminal. A terminal script does not allow "begin gamemode" so I cannot conveniently wait a frame, and then move it. Since there are six machines, I can't cheat with one quest script; it has no way to know which item is needed. How can I arrange to consistently move this item to the output tray after creating it? Link to comment Share on other sites More sharing options...
kert349 Posted March 6, 2011 Share Posted March 6, 2011 Why doesnt terminal allow "begin gamemode" ? I belive i have used it. anyway placeatme has been unreliable in my use too. why not just add the item inside a container? Link to comment Share on other sites More sharing options...
davidlallen Posted March 6, 2011 Author Share Posted March 6, 2011 Un-named scripts, like terminals or packages or dialog result scripts, don't have any "begin". Also I have learned (in this thread) that local variables should never be used in these scripts due to memory corruption. So I don't think a "begin gamemode" in a terminal script would work, since I would need a local timer variable. The container is a good idea, but it's a bit more of a change, because of some other things in my mod. I'll keep that idea on the back burner for a little while. Is there a way to trigger a script and pass variables? I need to set the rPart and rItem when I still have access to the terminal item, but then I need to wait a frame. Link to comment Share on other sites More sharing options...
kert349 Posted March 6, 2011 Share Posted March 6, 2011 (edited) You should set some quest variable in the terminal script to tell some "quest script" to do something like so, in terminal:set Quest.Dosomething to 1 set Quest.myArg to getselfthen in quest script: short Dosomething ref myArg begin gamemode if Quest.Dosomething == 1 set Quest.Dosomething to 0 ; Code to do something here... endif end Edited March 6, 2011 by kert349 Link to comment Share on other sites More sharing options...
blove Posted March 6, 2011 Share Posted March 6, 2011 Place a disabled item from the beginning and only enable it when needed like the bobblehead stands? Link to comment Share on other sites More sharing options...
rickerhk Posted March 7, 2011 Share Posted March 7, 2011 Waiting a few frames after the PlaceAtMe, before doing SetPos functions, is important if you want consistent results. So using the terminal result script to trigger variables in a fast quest or object script is what you need to do this.If you don't want any doubt as to how many frames you have to wait, you can use the condition: if placedItemREF.HasLoaded3D == 1 Before using SetPOS functions. Link to comment Share on other sites More sharing options...
davidlallen Posted March 7, 2011 Author Share Posted March 7, 2011 You should set some quest variable in the terminal script to tell some "quest script" to do somethingThanks, that is working. It is *almost* like calling a subroutine. But, in case you ever had two calls active at the same time, there is no way to know what would happen. @ blove, that is a good solution for a single item. But in my case, the item could be fabricated multiple times, so I need placeatme. @ rickerhk, the wiki page on hasloaded3d is basically empty. I am not quite sure what it is testing. Is it testing to see if the model is loaded off disk and rendered? For example, the same type of thing that "begin onload" checks? Then it could be that some instance of the model is already rendered, in which case this would immediately return true. In my case, a previous item could be fabricated and sitting there, when I fabricate a second one. Is this testing for the completion of "placeatme", which seems a little different from loading? In my current approach, I have simply set the quest update delay to 0.1 sec and made sure "setpos" comes on the second call to the script. Does this seem safe enough? Link to comment Share on other sites More sharing options...
rickerhk Posted March 7, 2011 Share Posted March 7, 2011 But, in case you ever had two calls active at the same time, there is no way to know what would happen.There is only one script thread in the running game so your call to the script will be able to 'clean up' before the next call to it. If you have multiple objects that need servicing, then you should give them their own set of variables in the script. @ rickerhk, the wiki page on hasloaded3d is basically empty. I am not quite sure what it is testing. Is it testing to see if the model is loaded off disk and rendered? For example, the same type of thing that "begin onload" checks? Then it could be that some instance of the model is already rendered, in which case this would immediately return true.In my case, a previous item could be fabricated and sitting there, when I fabricate a second one. Is this testing for the completion of "placeatme", which seems a little different from loading? You would be testing the specific reference that you obtained with PlaceAtme to see if it's has finished loading it's 3D info into the gameworld/current cell. I'm pretty sure but not verified that the 'On Load' script block and 3D loading are not necessarily synchronized, since you can have a whole cell of objects loading 3D at the same time, but the scripts on them are running sequentially. I've used hasloaded3d on actors when moving them into a cell to make sure they are rendered before doing something like applying a special effect on them. But maybe it's overkill for just testing PlaceAtMe. But that's me - script overkill ;) In my current approach, I have simply set the quest update delay to 0.1 sec and made sure "setpos" comes on the second call to the script. Does this seem safe enough? I'm doing it this way and it works fine. Link to comment Share on other sites More sharing options...
davidlallen Posted March 7, 2011 Author Share Posted March 7, 2011 There is only one script thread in the running game so your call to the script will be able to 'clean up' before the next call to it. If you have multiple objects that need servicing, then you should give them their own set of variables in the script.There is only one instance of a quest. Suppose I attach this quest script to an object which has several instances, and the quest script has a timer to sequence several actions and runs for a few seconds. Suppose the user activates several instances in quick succession. The quest variables will be overwritten and something very unpredictable will happen. So this technique must be used cautiously. I've used hasloaded3d on actors when moving them into a cell to make sure they are rendered before doing something like applying a special effect on them. But maybe it's overkill for just testing PlaceAtMe. But that's me - script overkill ;)For an actor, there is likely only one instance. For an object which has several instances, one may already be loaded and rendered in this cell. Then does the function instantly return true, or does it wait until the placeatme of this instance is done? Link to comment Share on other sites More sharing options...
rickerhk Posted March 7, 2011 Share Posted March 7, 2011 There is only one instance of a quest. Suppose I attach this quest script to an object which has several instances, and the quest script has a timer to sequence several actions and runs for a few seconds. Suppose the user activates several instances in quick succession. The quest variables will be overwritten and something very unpredictable will happen. So this technique must be used cautiously.In this case it may be better to use an object script on the spawned item so they can each have their own timer and variables. For an actor, there is likely only one instance. For an object which has several instances, one may already be loaded and rendered in this cell. Then does the function instantly return true, or does it wait until the placeatme of this instance is done?You are getting the specific reference of the item when you run: set rItem to placeatme rPart 1 rItem is not a baseID, because base forms are never loaded in the game world. Just references to base forms.rItem.Hasloaded3D refers only to that instance of the base object. Link to comment Share on other sites More sharing options...
Recommended Posts