dylbill Posted February 6, 2021 Share Posted February 6, 2021 Hmm, I'm not sure, maybe you do have to wait until it's 3d loaded. Another idea, is to still use the OnLoad event on an object where that event is firing, and move all of your objects with that event. Link to comment Share on other sites More sharing options...
FuryoftheStars Posted February 7, 2021 Author Share Posted February 7, 2021 Could I still have this main quest with the confirmation dialog and use it to populate a global var with the playerâs response, and then use a reference alias quest for the individual objects whoâs scripts check this var? In this way I can still move the objects (including the ones that arenât firing any of the normal objectreference events) and only have it done if the player confirms this is what they want. Iâm also wondering if thereâs any way to differentiate between a player adding this mod mid play through vs starting a new game? Link to comment Share on other sites More sharing options...
FuryoftheStars Posted February 7, 2021 Author Share Posted February 7, 2021 Ok, actually, I think Iâve thought of a way to solve the âis this being installed mid play throughâ. Just check the xyz coords of the objects. If theyâre not correct, then prompt the player. Link to comment Share on other sites More sharing options...
dylbill Posted February 7, 2021 Share Posted February 7, 2021 Ok, actually, I think Iâve thought of a way to solve the âis this being installed mid play throughâ. Just check the xyz coords of the objects. If theyâre not correct, then prompt the player.That should work fine :thumbsup: Link to comment Share on other sites More sharing options...
FuryoftheStars Posted February 7, 2021 Author Share Posted February 7, 2021 (edited) Is there a trigger condition for quests for when you enter certain cells? A bit of experimentation reveals that if I wait until I'm inside of the hearthfire home before popping my message (for now, I'm just setting a 30 sec delay to give me time to get inside with the current save I have), then enable the object, TranslateTo will work. I can also check the object's enable condition and save this to a bool prior to enabling it for the move, that way once I'm done moving it, I can re-disable it (and actually, I'm noticing I need to disable/re-enable anyway to update the collision box, so really, I'm disabling regardless, then checking the bool to see if I should re-enable). MoveToMyEditorLocation still does not work and in fact I just noticed it's throwing an error of "cannot be moved" into the papyrus log for that method. I did notice in SSEEdit that the chandeliers and horker head are flagged as persistent, which lead me to googling around and finding some posts by Arthmoor on the AFK Mods forums talking about different levels of persistence and that in some cases of "fully" persistent objects, even script methods of moving objects wouldn't work. *shrug*https://www.afkmods.com/index.php?/topic/3669-overhauling-the-weapon-rack-scripts/page/21/&tab=comments#comment-148158 If a reference is selected as a Papyrus script property, everything changes. Now you're back to the classic definition of persistence. These references are maintained in memory at all times, and cannot be moved. Sometimes even scripts are incapable of repositioning them. With a new twist too. The positioning data is baked into the save game from the moment the game starts and therefore no such object can ever be relocated. It makes no difference what type of script it is either.(Note that in that quote snippet, it's movement via the CK and mods Arthmoor is talking about except where specifically mentioning scripts.) Anyway, if quests can trigger by the player entering a certain cell, then I can just split this into 3 quests, 1 for each home, then run down the list of objects using the technique I detailed above. I'd considered looking into arrays and papyrus's equivalent to for loops so I could cut down on the number of property vars I need to write into the script (and hopefully avoid having to edit the script any time a change is made where another object's location needs to be updated or one no longer needs it), but in order to do that, I'd also need to create a matrix array for the xyz coords (to feed into TranslateTo) and I'm not sure if I want to go down that road, yet (assuming papyrus can even do that).... Edited February 7, 2021 by FuryoftheStars Link to comment Share on other sites More sharing options...
dylbill Posted February 7, 2021 Share Posted February 7, 2021 Instead of using a quest then, I would suggest using a triggerbox placed at the in door of the interior cell, and using OnTriggerEnter. Since you are editing the cell anyway by moving the items, I would suggest putting X-Markers or duplicated HF objects that are Initially disabled and using MoveTo, to move the vanilla objects to their markers. Something like this: Message Property HFModInstallMsg Auto ObjectReference Property HorkerHead Auto ObjectReference Property HorkerHeadMarker Auto ObjectReference Property AnotherHFRef Auto ObjectReference Property AnotherHFRefMarker Auto Actor Property PlayerRef Auto Bool Property Done = False Auto Hidden Auto State Waiting Event OnTriggerEnter(ObjectReference akActionRef) If akActionRef == PlayerRef && Done == False Done = True GoToState("Done") Utility.Wait(1) If HFModInstallMsg.Show() == 1 If HorkerHead != None && HorkerHead.IsDeleted() == False HorkerHead.Moveto(HorkerHeadMarker) Endif If AnotherHFRef != None && AnotherHFRef.IsDeleted() == False AnotherHFRef.Moveto(AnotherHFRefMarker) Endif Endif Utility.Wait(1) Self.Disable() ;Disable this triggerbox so OnTriggerEnter won't fire any more. Endif EndEvent EndState State Done Event OnTriggerEnter(ObjectReference akActionRef) ;do nothing EndEvent EndState Link to comment Share on other sites More sharing options...
FuryoftheStars Posted February 8, 2021 Author Share Posted February 8, 2021 (edited) Thanks! (EDIT: Bleh, nevermind on the below. I suppose it'd still be good info to know, but I'm realizing at the moment that the usage of the array where I'm trying to use it is actually over complicating things, so I'm switching methods.) So I'm working through this and went ahead and bit the bullet to learn arrays and looping with papyrus (I still need the xyz coords as I want to do a quick check to see if the objects are already in their correct positions. If they are, there's no sense in popping the message to the player or doing anything else). One question I have on them: can you assign the full array of values to the variable in one go? Rather than writing out individual If checks on each object's xyz coords, I'm popping them into an array defined in script during runtime and then looping on it real quick with a bool to break early if need. This is what I have at the moment that'll compile (this is just a snippet): float[] xyzCoords = new float[3] xyzCoords[0] = ObjectArray[i].GetPositionX() xyzCoords[1] = ObjectArray[i].GetPositionY() xyzCoords[2] = ObjectArray[i].GetPositionZ() In other languages, this is doable in one line, though I suppose due to the nature of just declaring the array I can't do that in papyrus. But can I combine the 3 assignments into one line? Again, in other languages, I could do something like this: float[] xyzCoords = new float[3] xyzCoords = {ObjectArray[i].GetPositionX(), ObjectArray[i].GetPositionY(), ObjectArray[i].GetPositionZ()} However, this won't compile for papyrus. I've tried wrapping the values in {}, [], and (). Do I need to use something other than a comma? Or am I stuck with having to assign each element on their own line? Edited February 8, 2021 by FuryoftheStars Link to comment Share on other sites More sharing options...
dylbill Posted February 8, 2021 Share Posted February 8, 2021 I'm pretty sure in papyrus you have to do it in multiple lines. If your markers are in the same positions as the vanilla items should be, then you don't need to use an array, you can just compare the positions of the marker and vanilla object. Scriptname TM_ObjectRefScript extends ObjectReference Message Property HFModInstallMsg Auto ObjectReference Property HorkerHead Auto ObjectReference Property HorkerHeadMarker Auto ObjectReference Property AnotherHFRef Auto ObjectReference Property AnotherHFRefMarker Auto Actor Property PlayerRef Auto Bool Property Done = False Auto Hidden Auto State Waiting Event OnTriggerEnter(ObjectReference akActionRef) If akActionRef == PlayerRef && Done == False Done = True GoToState("Done") Utility.Wait(1) If HorkerHead.GetPositionX() != HorkerHeadMarker.GetPositionX() || HorkerHead.GetPositionY() != HorkerHeadMarker.GetPositionY() \ || HorkerHead.GetPositionZ() != HorkerHeadMarker.GetPositionZ() If HFModInstallMsg.Show() == 1 If HorkerHead != None && HorkerHead.IsDeleted() == False HorkerHead.Moveto(HorkerHeadMarker) Endif If AnotherHFRef != None && AnotherHFRef.IsDeleted() == False AnotherHFRef.Moveto(AnotherHFRefMarker) Endif Endif Endif Utility.Wait(1) Self.Disable() ;Disable this triggerbox so OnTriggerEnter won't fire any more. Endif EndEvent EndState State Done Event OnTriggerEnter(ObjectReference akActionRef) ;do nothing EndEvent EndState Link to comment Share on other sites More sharing options...
FuryoftheStars Posted February 8, 2021 Author Share Posted February 8, 2021 Thanks. Yeah, I realized the mistake I was making and ended up doing this (by the way, how do you do spoiler tags in these forums?): bool NeedsUpdating = False int i = 0 While i < ObjectArray.Length && !NeedsUpdating If ObjectArray[i].GetPositionX() != XCoordArray[i] || ObjectArray[i].GetPositionY() != YCoordArray[i] || ObjectArray[i].GetPositionZ() != ZCoordArray[i] NeedsUpdating = True EndIf EndWhile Oh, one more question. If statements with multiple conditions. Does papyrus evaluate all of the conditions regardless, or will it shortcut out if the first condition it evaluates false? IE: If NeedsUpdating && ConfirmationMessage.Show() == 1 If "NeedsUpdating" is False, will it still attempt to evaluate the next condition (causing the message box to show), or will it shortcut out and skip the message box? I've seen both ways between the languages I've used. Link to comment Share on other sites More sharing options...
dylbill Posted February 8, 2021 Share Posted February 8, 2021 You know, I'm actually not sure about that, it'd be easy enough to test though. The spoiler tags are [spoiler*] and [/spoiler*] without the *. If it turns out it still shows the message, you can always put them on separate lines. If needsUpdating If ConfirmationMessage.Show() == 1 Link to comment Share on other sites More sharing options...
Recommended Posts