Jump to content

Teleport spell to a disappearing object


Recommended Posts

The disappearing object is the Dwemer Skyship by Mr_siika. I have flight controls working and it's all good except my teleport to deck spell. It works fine if you're within the default 5 x 5 (uGridsToLoad=5) grid matrix but outside of that the teleport takes you to the location (on the ground) but the ship is missing. Cast the spell again and the ship is back and you're on deck as intended. It seems to me theoretically you could make it all happen in one shot. I see discussion that I need to disable the ship on one frame and then enable and moveto on the next frame.

What are the basics on how to do that?

This is what is working except needing to be cast twice for long teleports.

scn a1ccTeleportShipScript

Begin ScriptEffectStart

a1ccDwemerHomeRef.disable
BridgeDoorRef.disable
CaptainsDoorRef.disable
a1ccRopeLadderUpRef.disable
MiddleLadderRef.disable
a1ccRopeLadderDownRef.disable
BridgeDoorDeckMarkerRef.disable
CaptainDoorDeckMarkerRef.disable

ccDummyRef.moveto a1ccDwemerHomeRef, 0, 0, 375
a1ccDwemerHomeRef.moveto ccDummyRef, 0, 0, -375
BridgeDoorRef.moveto ccDummyRef, 0, 0, -375
CaptainsDoorRef.moveto ccDummyRef, 0, 0, -375
a1ccRopeLadderUpRef.moveto ccDummyRef, 0, 0, -375
MiddleLadderRef.moveto ccDummyRef, 0, 0, -375
a1ccRopeLadderDownRef.moveto ccDummyRef, 0, 0, -375

a1ccDwemerHomeRef.enable
BridgeDoorRef.enable
CaptainsDoorRef.enable
a1ccRopeLadderUpRef.enable
MiddleLadderRef.enable
a1ccRopeLadderDownRef.enable
BridgeDoorDeckMarkerRef.enable
CaptainDoorDeckMarkerRef.enable

player.moveTo BridgeDoorDeckMarkerRef

End

Begin Gamemode

END
Begin ScriptEffectFinish
End

Thanks

Link to comment
Share on other sites

Hmm, this is quite new territory to me, too. But going by some observations from moving things around in my own mods, maybe try putting the "enable" lines after the "player.MoveTo"?

Could be the game's a little laggy and doesn't finish enabling things that aren't in the same cell.

 

Another idea could be waiting a frame or 2 between enabling and moving the player to the enabled thing, e.g. by putting the "player.MoveTo" line into the GameMode block. (It should trigger only after the ScriptEffectStart block. Otherwise use a ScriptEffectUpdate block perhaps.)

 

I'm not quite sure what the "move dummy to home, then move home to dummy, with different offsets each" deal is about, but maybe it's just for grounding, setting the ship's location in the sky at a constant height from whatever current ground level.

Link to comment
Share on other sites

Thanks for the reply. It's good to bounce some ideas back and forth.

 

I tried "putting the "enable" lines after the "player.MoveTo"?" and then after the second cast you are still on the ground and up above you see the two doors and nothing else. That shows you how bizarre it is.

 

I tried putting the enable and moveto in a ScriptEffectUpdate block and it works the same except it's really slow and I get a black screen for at least a full second.

 

I'm hoping to get figured out how to do the "wait a frame" and know for sure what was executed in what frame so I'll know if that worked, or maybe it didn't really wait a frame. You say if I add a GameMode block in the teleport script it will run on the next frame? I've tried that. If you know for sure that would run on the next frame then doing the enable and moveto on the next frame doesn't do the trick maybe and I'm barking up the wrong tree. I've tried setting a shipScript.variable in the teleport script and then having the ship script GameMode block do the enable and moveto when the variable is set ( same result ) but I still don't know if that happened on the next frame or not.

 

I haven't found an in depth description of the purpose of the division of the ScriptEffectStart, ScriptEffectUpdate, and ScriptEffectFinish blocks. Do they indeed run on successive frames or what? There is the spell duration and I've been using 0 but I've tried 1 sec and get the same result.

 

The dummy is a DummyRat. It's talked about here: https://cs.elderscrolls.com/index.php?title=Teleport_Recall. The DummyRat is how you make an activator or static object move around without disappearing. The ship model has the zero point at the bottom of the hull and the deck is 375 units up. The rat has to be on deck therefore the offset. When the ship disappears the rat falls to the ground so you have to put the rat back on deck. When the ship is moving the rat is moving exactly with it except for the offset. They stay together exactly with setpos commands but every 500 frames you have to do a "ship.moveto rat" and that's the trick that keeps the ship from disappearing after crossing a certain number of cells. The 500 could be more or less depending on how fast the ship is moving. If you do the moveto every frame it kills your fps. You could probably do a moveto player but this method of flying ship allows the player to move around on the deck while the ship is moving so you use the invisible dummy rat.

 

Thanks

Link to comment
Share on other sites

When stuff moves, the collisions will not follow on static objects when moving them with scripts. I made many scripts that diable and enable stuff to let the collisions to update and it works best if there is 0.3 seconds or more between the disable and the enable. here is a video example of me refilling my racks with bottles as the Principe is the same. it is 0.3 seconds between every bottle.



So I would move all that code to a quest that I call from the spell or set the spell to 1s and disable the objest at the Begin ScriptEffectStart and enable it at the Begin ScriptEffectFinish and that will leave the object disabled for 1s which is more than enough. I came to the conclusion that 0.3s is required after many days testing those bloody bottles...
Link to comment
Share on other sites

I tried your suggestion "set the spell to 1s and disable the object at the Begin ScriptEffectStart and enable it at the Begin ScriptEffectFinish" and it worked the same with two casts required, just took a little longer and I saw the spell icon in the upper right corner for the 1s duration. What happens when I have walked 8 cells distance from the ship is I cast once and get a loading screen with the loading bar and then I'm at the location but on the ground and no ship. Then I cast again and get another loading screen with the loading bar and then I end up on the deck with the ship back. Maybe that should tell me what is going on and what I need to do but I don't understand the exact mechanics of the unloading and loading. There seems to be a difference in what is unloaded depending on if you walk 8 cells away from the ship or if you go through the Chorrol gate and come back out. The ship is right outside the Chorrol gate. Go through the gate, come back out, and the ship is gone but one cast brings back the ship and puts you on deck. Walk 8 cells away and two casts are required. Fast travel to Skingrad from the ship location and only one cast is needed. If I knew exactly what is that difference . . . I'm thinking with the 1s duration between the disable and the enable that should be a good 60 frames, right? And that isn't doing the trick.

 

Your bottle moving demo is interesting. I've seen that when I was searching on how to move stuff. Have you done anything with these parameters in your nifs? Maybe you know the skinny on this.

 

bhkCollisionObject
>bhkRigidBody

MO_SYS_FIXED -->changed to--> MO_SYS_KEYFRAMED
OL_STATIC -->changed to--> OL_ANIM_STATIC

 

For the things I'm moving they don't work at all without those changes. It seems like the collision is moving with visible part frame by frame for me but I don't know for sure. It just effectively works for me.

 

Thanks

Link to comment
Share on other sites

A wild guess is that when the cell where the ship is gets unloaded, it will not update the ship immediate as the ship was not there in the first place as it is placed in another cell with CS right? So as long as the ship is in the cell it was added too, this problem will not occur?

 

I do have a similar problem with my rats and bandits I add to dungeons as it only work properly if I wait some time before I let my rats to spawn the bandits that are supposed to be there and I made a lot of testing until I got it to work to 100%. I add a RND to the rats, let them wait for 2-4 seconds until they spawn the bandits and disappears. I tested loads of variants, put several days into solving the problem with my bloody bandits.

 

This is the way this game works. Stuff that should work, does not, until we do stuff in a specific order and time it right. The game was made for low memory computers 2006 and it takes time until a cell is 100% workable, as it is not obviously when we ener it, special with stuff that is NOT added to it with CS, as all that stuff will get loaded before the loading screen disappears but the rest might not. In your case, I bet it is the collision for the ship that are not in the right spot as it is the collision boxes that we interupt with.

 

I guess you need 3 stages, and not 2. You cant move within the same Frame as you enable the object so this is what you need to do.

  1. Disable the object
  2. Wait 0.3s
  3. Enable the object
  4. Wait 0.3s
  5. Move to it

And you MUST BE in that cell when you do it, otherwise it is pointless as it will not enable nor disable the objects if they are 8 cells away. If you enable an object, it will not pop up until you get to that cell and you need to disable it, wait 0.3s and enable it and then you can interact with it. This is just how this bloody game works... I do have scratched my head bloody for days, trying to go around this and failed.

 

What you can try is to add a rat to the ship, let it stand at the deck and use a moveto it and see what happens. An invisible rat with a package that makes it stand still at the editor location as you add it with CS and disable it as it does not need to be active to port to it. Xmarker rats are superior any other Xmarker as I have been writing about in my WIP... :wink: The Static Xmarkers does NOT LIKE to get moved with scripts, specially not to SI, as then they disappears completely, well they end up in Tamriel at the same coordinates you used in SI... Rats or whatever creature but use rats.... :wink: They are 100% reliable

Edited by Pellape
Link to comment
Share on other sites

"A wild guess is that when the cell where the ship is gets unloaded, it will not update the ship immediate as the ship was not there in the first place as it is placed in another cell with CS right? So as long as the ship is in the cell it was added too, this problem will not occur?" Yes, exactly. The ship is placed in the CS at the waterfront. It has been flown to Chorrol for this particular testing.

 

How do I do the wait 0.3s?

 

"And you MUST BE in that cell when you do it, otherwise it is pointless as it will not enable nor disable the objects if they are 8 cells away." That makes sense and seems like the crux of it except why does it work after fast traveling to Skingrad. You have to be at the ship location when you fast travel though. I think you have to walk 8 cells away before problem starts and maybe for those cases having to teleport twice isn't that bad. I still want to figure it out though.

 

The ship does have a rat. Look at this part again ( The dummy is a DummyRat. . . . ). Is that what you're talking about?

 

Thanks

Edited by chambcra
Link to comment
Share on other sites

You wait 0.3s with this script as seconds is a float and I think 1s is divided into 100.

Scn TimerSCR

Float Seconds

Begin GameMode

Set Seconds to GetSecondsPassed

If ( Seconds < 0.3 )
Return
Endif

DO YOUR STUFF HERE

Set Seconds to 0

End

Link to comment
Share on other sites

I add a GameMode block to my teleport script with that timer in it?

 

Or I call TimerSCR from my teleport script?

 

Is this effectively a while loop?

If ( Seconds < 0.3 )
Return
Endif

The GameMode block keeps running every frame until it the if is false and it reaches the End?

 

Thanks

Link to comment
Share on other sites

The GameMode block is a while loop that runs infinitely. But if it's a quest, it won't necessarily run "every frame". On objects though it mostly does.

 

The "return" breaks the 1 iteration of the loop and jumps to the next, not executing any of the code thereafter.

 

There's something missing here though, if this is meant to be a timer.

GetSecondsPassed always returns the number of seconds (also fractions of), which passed since the last run of the block. It could be < 0.3 sometimes, but it doesn't have to ever reach that mark necessarily, depending on game performance, FPS etc.

To make this a timer there should be something that counts as well, either add or remove GetSecondsPassed to or from another variable and check this variable as the sum of elapsed seconds over multiple block runs for reaching the goal.

Starting at X and deducting GetSecondsPassed will give you a count down, aiming to reach 0. Starting at 0 and adding GetSecondsPassed will count the total time the block has already run without doing its part. Both can be used for a timer.

 

BUT, and that's a big one, make absolutely sure there's a "do run" or "finished" condition. Else the timer will start over again, if like in the example above you reset its count at the end of the conditional code.

 

 

And you can't exactly "call" another script from inside your script. The timer either needs to be part of your block or conditionally counting down in another quest script, which is controlled through variables, which can be set inside your script. ("<quest-name>.<variable-name>" can be used to make a variable accessible from everywhere, similar to a global.)

Link to comment
Share on other sites

  • Recently Browsing   0 members

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