Jump to content

Moving objects via script (TranslateTo)


FuryoftheStars

Recommended Posts

Woohoo, everything most things seem to be working so far. :) Course, I forgot to put in a "i += 1" into my while loops, so it was kind of funny seeing the first chandelier just flickering in and out of existence. :P (Annnnd there seems to be a bug with the compiler software I'm using. Won't compile "i += 1", though it will compile "i =+ 1", even though that syntax doesn't actually work. Oh well. Writing out the full thing of "i = i + 1" for now.)

 

And this...

If False && NeedsUpdating && ConfirmationMessage.Show() == 1
...still resulted in the message box showing, so I guess that answers that question. :) Oh well, multi-line it is!

 

 

Ok, another hurdle! (In case you can't tell, I'm writing this post as I go and try things and encounter new issues, then fix them....). The end table and book under the wall mounted horker head on the 2nd floor of the main hall... they're enabled via the mannequin next to them rather than directly like the chandeliers and horker head. In the CK, I can add them as objects to the script and everything looks fine there, but when the script actually runs, it's saying the object is "None" and (expectedly given no object) throws errors when attempting to do anything with them. What gives?

Edited by FuryoftheStars
Link to comment
Share on other sites

I

 

 


Ok, another hurdle! (In case you can't tell, I'm writing this post as I go and try things and encounter new issues, then fix them....). The end table and book under the wall mounted horker head on the 2nd floor of the main hall... they're enabled via the mannequin next to them rather than directly like the chandeliers and horker head. In the CK, I can add them as objects to the script and everything looks fine there, but when the script actually runs, it's saying the object is "None" and (expectedly given no object) throws errors when attempting to do anything with them. What gives?

 

 

I'm not sure why that would be. If the property is filled it should be working. Maybe it has something to do with the HF scripts. I'd look at the mannequin's attached scripts to see. Also, that's weird that i += 1 doesn't work, I've never had problems with that.

Link to comment
Share on other sites

Ok, I'll try some testing at some point to see if I can figure that out. I'm pretty sure it's not the HF script that's causing issues as it's the same script as used by the chandeliers and horker head. Only thing that's really different is that the book and end table are enabled via a set Enable Parent (pointing to the mannequin), and that there is no Reference Editor ID name filled in (it has a hex ref id, just not a plain text one). Filling something into this does not solve it on an already existing save, though. I'll try a couple bouts with it on new play throughs and see what I get.

 

And the i+=1 thing, yeah, I dunno. It seems to work today for some reason. May have been some kind of weird bug in the CK/compiler? Maybe if I'd shut the CK down and retried it would've worked? *shrug*

Edited by FuryoftheStars
Link to comment
Share on other sites

Yeah, that was what I was using, but I had the CK open in the background for most of the day, closing and reopening seldomly, so I don't know if that could have interfered somehow (I reported the issue to the SSEScript mod page and the author responded saying his software still uses the game's compiler for actually compiling).

 

 

 

Ok, so I did some testing on these objects that are coming back None. If I start a new game, they don't do this. I'm wondering if this is related to these objects not being persistent previously and thus, if you haven't built the mannequin yet, don't actually exist yet? Even though they get flagged persistent by this mod now, I don't think it takes effect until they're enabled (or a new game is started).

 

Additionally, I can't actually enable/disable these objects directly even when they do exist. The Enable Parent setting seems to override this, so I have to enable/disable the mannequin instead. Not a huge deal, I was able to work through that by adding another array (that I populate in the CK with the object's Enable Parent, if there is one) and duplicating the main working part of the code with the minor changes of enabling/disabling the object specified by the new array, while performing the TranslateTo on the object in the original array.

 

Are there search tools/features I can make use of in the script? Maybe once I enable the mannequin and the table and book are created, I can search the cell for them and then do the needed work? Or, assuming that once created the table and book keep the same ref id # as visible in the CK, I can pass their id #s themselves to the script (rather than the object reference) and somehow pull their object reference with that? I don't know what's available to me at this point, but I feel like there's gotta be something (the HF script is somehow able to enable its objects with just a part id # being passed to it rather than an object reference).

Link to comment
Share on other sites

Took a bit of a hiatus. :tongue:

 

Here's my (current) final version of the script that seems to be working. If interested, let me know if you see anything in there that sticks out as maybe needing to be changed.

 

 

 

Scriptname HFAUpdateObjectLocationTriggerScript extends ObjectReference

ObjectReference[] Property ObjectArray Auto ;Our array of objects we want to move
ObjectReference[] Property EnableParentObjectArray Auto ;For those objects we want to move that have Enable Parents, store the Enable Parents here (avoids requiring SKSE)(We can't enable/disable an object with an Enable Parent, so we have to enable/disable the Parent instead)
float[] Property XCoordArray Auto ;Our destination X coordinates for the objects we're moving
float[] Property YCoordArray Auto ;Our destination Y coordinates for the objects we're moving
float[] Property ZCoordArray Auto ;Our destination Z coordinates for the objects we're moving

Message Property UpdateObjectsMessage Auto ;Our confirmation message we pop on the player to see if they want the objects moved

Actor Property PlayerRef Auto ;Reference for the player

;Primary function for actually moving the objects
Function HFAMoveObjectFunction(int i) ;We pass in the integer we're using for the array index
    ;This first block is merely a convenience setup so we don't have to have 2 identical blocks of code with different variables
    ObjectReference ObjToEnableDisable = None
    If EnableParentObjectArray[i] == None ;If our object we're moving doesn't have an Enable Parent...
        ObjToEnableDisable = ObjectArray[i] ;...then we set the object we're going to enable/disable to our object we're moving...
    Else
        ObjToEnableDisable = EnableParentObjectArray[i] ;...otherwise, it's the Enable Parent.
    EndIf
    
    bool IsItEnabled = ObjToEnableDisable.IsEnabled() ;Save object's enable state so we can set it back when done
    If !IsItEnabled ;If it is disabled, enable it.  We can't move it while disabled
        ObjToEnableDisable.Enable()
    EndIf
    
    ;Wait until the Object's 3D model is loaded (we can't move it while the 3D model is not loaded)
    int counter = 0 ;I'm including a counter "just in case" so we don't loop indefinitely
    While !ObjectArray[i].Is3dLoaded() && counter < 50 ;Break at counter = 50 at 0.1 sec per count means we'll wait at most 5 secs
        Utility.Wait(0.1)
        counter += 1
    EndWhile
    
    ;Move the object, keeping original orientation
    ObjectArray[i].TranslateTo(XCoordArray[i], YCoordArray[i], ZCoordArray[i], ObjectArray[i].GetAngleX(), ObjectArray[i].GetAngleY(), ObjectArray[i].GetAngleZ(), 99999.0, 99999.0)
    
    Utility.Wait(0.1)
    ObjToEnableDisable.Disable() ;The collision block of objects we move don't update unless we disable/re-enable it (why??)
    Utility.Wait(0.1)
    If IsItEnabled ;But we're only going to re-enable through here if it was enabled in the first place
        ObjToEnableDisable.Enable()
    EndIf
EndFunction

Auto State Waiting
    Event OnTriggerEnter(ObjectReference akActionRef)
        Debug.Trace("HFAID - Event OnTriggerEnter")
        If akActionRef == PlayerRef ;Make sure it only triggers if it's the player going through
            GoToState("Done") ;This essentially disables the script from subsequent executions.  Putting it this early allows us to stop the player from accidentially triggering it again while it's still running
            Utility.Wait(1)
            
            ;Check see if any of our objects are not at the xyz coords we want.  If they're all good, there's no sense in going through the rest
            bool NeedsUpdating = False
            int i = 0
            While i < ObjectArray.Length && !NeedsUpdating
                If ObjectArray[i] != None ;Well, it shouldn't ever be, but I've run into weird glitches before.  Unfortunately, if it is None, there's nothing we can do about it from here.
                    If ObjectArray[i].IsDeleted() ;Check first to see if the object has been deleted.  If it has, then we want to look into replacing it
                        Debug.Trace("HFAID - Object " + ObjectArray[i] + " was deleted")
                        NeedsUpdating = True
                    ElseIf ObjectArray[i].GetPositionX() != XCoordArray[i] || ObjectArray[i].GetPositionY() != YCoordArray[i] || ObjectArray[i].GetPositionZ() != ZCoordArray[i]
                        Debug.Trace("HFAID - Object " + ObjectArray[i] + " needs updating")
                        NeedsUpdating = True
                    EndIf
                EndIf
                i += 1
            EndWhile
            Debug.Trace("HFAID - Needs updating: " + NeedsUpdating)
            
            If NeedsUpdating ;If it needs updating...
                If UpdateObjectsMessage.Show() == 1 ;Show our message to the player.  Selecting "Yes" gives us a value of 1
                    i = 0
                    While i < ObjectArray.Length
                        Debug.Trace("HFAID - Working on object #" + i + ": " + ObjectArray[i])
                        If ObjectArray[i] != None ;Again, it shouldn't ever be None, but....
                            If ObjectArray[i].IsDeleted() ;If it's been deleted, then we're going to want to place a new object to take its place and move to the new location.
                                If ObjectArray[i].IsDisabled() ;Enable the deleted object in case there are other objects with it set as an Enable Parent (we're assuming the player disabled it in addition to deleting it).
                                    ObjectArray[i].Enable()
                                EndIf
                                
                                ;Create and place the new object, replacing our original in the array with it (for feeding through our move function)
                                Form OurBaseObject = ObjectArray[i].GetBaseObject()
                                ObjectArray[i] = ObjectArray[i].PlaceAtMe(OurBaseObject)
                            EndIf
                            HFAMoveObjectFunction(i) ;Move the object
                            Debug.Trace("HFAID - Completed object")
                        EndIf
                        i += 1
                    EndWhile
                EndIf
            EndIf
            
            Utility.Wait(1)
            Self.Disable() ;And here we're disabling the triggerbox itself so this script won't even attempt to fire anymore
            Debug.Trace("HFAID - Script end")
        EndIf
    EndEvent
EndState

State Done
EndState

 

 

 

 

Thanks for all your help on this!!

 

Edit: Aaaand I should probably make sure to take out all the Debug.Trace lines (delete or comment out) for the actual packaged mod. :P

Edited by FuryoftheStars
Link to comment
Share on other sites

  • Recently Browsing   0 members

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