Deleted19761User Posted May 28, 2021 Share Posted May 28, 2021 (edited) Hey there. I'll try to keep this short winded. Trying to create a portal system that has a recall function when a spell is cast twice. Pseudo Code: Player Casts Spell onSelf (via staff, scroll or spell) Pause briefly to check if Recall Active is True, (Check if a designated spawned VFX portal with a location Marker Attached to it is active somewhere.) If yes, return to Recall point, If no, return to Location01 (home town) On Return to Recall, wait a few seconds then disable/Delete the actor and node (or whatever the best way to remove them is so a clean reference can be made when the spell is cast again.) (Secondary) Also If Recall Active = False, Use PlaceAtMe to drop (spawn VFX/Marker to use as reference point) [Alternative option for use elsewhere: create dialogue window for choices of teleport locale, defined as Loc01, Loc02, Loc03..etc.] I'm aware there's some mods that already exist that have some sort of town portal system but I'd like to actually learn how to properly code this myself, hopefully with some guidance? I've had a programming class but that was now several years ago so my skill writing code is.. creaky and rotted at best, but I've got Notepad++ setup to handle Papyrus. I've also had a gander at DarkFox127's youtube tutorials and have a basic working script thanks to that. Would like to expand it however. DarkFox127's Provided example Code: Scriptname TeleportMe extends ActiveMagicEffect ObjectReference Property LoC01 Auto Event OnEffectStart(Actor akTarget, Actor akCaster) Utility.Wait(1.5) Game.FadeOutGame(False, True, 2.0, 1.0) Game.GetPlayer().MoveTo(Loc01) Game.EnableFastTravel() Game.FastTravel(Loc01) EndEventAs included: the Fast Travel sections are for including followers, which is fine. FadeOutGame is for a loading screen I'm assuming. So if I take that and do something like... Scriptname PortalSystem extends ActiveMagicEffect ObjectReference Property Loc01 Auto {Always a Fixed location like a town} ObjectReference Property Loc02 [Recall Marker & VFX Here?] Event OnEffectStart(Actor akTarget, Actor akCaster) Utility.wait(5) Game.Get.ActorReference() Is enabled / disabled (True, False) ==?!<> { Unsure about correct syntax for this entire IF/Else True/False or Enabled/Disabled Section} If False Game.FadeoutGame (False, True, 2.0, 1.0) Game.GetPlayer() .MoveTo(Loc01) Game.EnableFastTravel() Game.FastTravel(Loc01) If True Game.FadeOutGame(False, True, 2.0, 1.0) Game.GetPlayer() .MoveTo(Loc02) Game.EnableFastTravel() Game.FastTravel(Loc02) EndEvent How do I go about creating the rest? Should I just try "GetCurrentLocation" instead of relying on a spawned actor position? Edited May 28, 2021 by Guest Link to comment Share on other sites More sharing options...
NexusComa2 Posted May 28, 2021 Share Posted May 28, 2021 (edited) This is mine from the Enchanted Ship In a BottleAs far as moving you back on 2nd cast that would be as easy as creating a flag variable ... In my case I test if I was in the ship cell or not. But a simple flag veritable could handle this also.Just make sure to drop a XMarker where you're standing on the 1st cast like my ship code. Int flag = 1 if flag == 1 do this stuff on 1st cast flag = 2else do this stuff on 2nd cast flag = 1endif Keep in mind my ship teleport works off the fact the model ship is equipped or not.The model ship is a armor that goes in an unmentionable place :laugh: ...The armor is enchanted (constant effect) and that triggers the OnEffectStart.When the ship (armor) is removed it triggers OnEffectFinish.Basically works like an enchanted ring. Short and sweet, Player and Followers at the same time ... ;* ModelShip - { Coaded by: NexusComa ... 12/03/2015 };----------------------------------------------------Scriptname Ship00_ModelShipTeleport Extends ActiveMagicEffectCell Property ModelShip AutoObjectReference Property Marking AutoObjectReference Property ModelShipMarker AutoEvent OnEffectStart (Actor Target, Actor Caster) If (Caster.GetParentCell() != ModelShip) Marking.MoveTo(Caster) Caster.MoveTo(ModelShipMarker) Game.EnableFastTravel() Game.FastTravel(ModelShipMarker) EndIfEndEventEvent OnEffectFinish (Actor Target, Actor Caster) Caster.Moveto(Marking) Game.EnableFastTravel() Game.FastTravel(Marking)EndEvent Note: There is a reason the old Mark and Recall spells wasn't added to this game ...Jumping around like this can break the game in some cases. You need to to always go to the same place.You can go there from anyplace but the destination needs to be set permanently.If used like the old Mark and Recall that can be use anyplace it will break the game.Also: If this is used when talking to a NPC they will be transported along with you and your followers. Edited May 28, 2021 by NexusComa2 Link to comment Share on other sites More sharing options...
greyday01 Posted May 28, 2021 Share Posted May 28, 2021 You could have a xmarker start at your target location, at the first cast it moves to where you are , at the second cast it gets moved back to original location. You might need a fixed xmarkerheading there as a target to move your marker back to. Link to comment Share on other sites More sharing options...
NexusComa2 Posted May 28, 2021 Share Posted May 28, 2021 (edited) You just drop an XMarker where you are when you cast the spell. Then use that to port back. You can even leave it there.When you cast the spell from the start again it will move that marker to the spot you're on now and so on. You're basically porting between the two XMarkers.The one you have set always in it's spot and the one you drop/move to where you are when you do the 1st cast. Marking.MoveTo(Caster) The part I was talking about that breaks the game is how this version of the game has messengers. They are spawned and set to run to where you are.If you warp away it needs to be to a game set location or they will just wonder off and not ever complete their task. This can also lead to some delays for them getting to youeven if you do have a game set location as they will try to head to that spot (even if they can't ever get there) Then they will re-aim themselves when you warp back with fast travel.Sometimes they will run a longways so when you return it will then take them longer to get to you. This is why you've never seen a working Mark/Recall spells set mod that don't end up breaking the game. The messengers just wonder off the 2nd time you use mark.One of them errors you don't even see and don't happen at any set time ... lol, Nightmare errors. May not even know you just had an error. You just never see that NPC. Edited May 28, 2021 by NexusComa2 Link to comment Share on other sites More sharing options...
Deleted19761User Posted May 28, 2021 Author Share Posted May 28, 2021 Thank you for the replies! So Mark and Recall obviously break a few radiant quest mechanics. I'd imagine there's maybe a way to pause and redirect them to new player location to keep that from causing any game breaking bugs via a quest state flag or some such? Would be afraid that might end up creating multiple impostors of the normally inescapable messenger. Also: If this is used when talking to a NPC they will be transported along with you and your followers.That's both a hilarious bug and also just "WHY wouldn't you fix this Bethesda?" sort of thing. The destination(s) will always be to fixed locations that never change (primarily cities). The only thing that is ever dynamic is where the player would be teleporting from and back to, to get to them. So it shouldn't in theory be too game breaking unless someone is teleporting around constantly. As for the code i will update this post with what I come up with after some testing and wrapping my brain around this for a bit. Link to comment Share on other sites More sharing options...
NexusComa2 Posted May 28, 2021 Share Posted May 28, 2021 I've tried a few times. Then came to the concision if Bethesda had to cut out Mark & Recall to get it working it's not going to be an easy fix. If even possible.two of the best spell Oblivion had ... considering they had to cut levitate also, I'm sure they had to do it this way. Figured it wasn't worth messing with. The one set end teleports works fine. Only thing I've ever noticed was a delay on a message quest NPC as he had traveled halfway across the map. Link to comment Share on other sites More sharing options...
dylbill Posted May 28, 2021 Share Posted May 28, 2021 To detect if you're near a city marker, you can use GetDistance to detect if you're far enough away. Example: ObjectReference Property Loc01 Auto ;Always a Fixed location like a town ObjectReference Property Loc02 Auto ;Recall Marker & VFX Here? Event OnEffectStart(Actor akTarget, Actor akCaster) Float Distance = Game.GetPlayer().GetDistance(Loc01) If Distance > 5000 ;is the player more than 5000 units away from loc01? Loc02.MoveTo(Game.GetPlayer()) Game.GetPlayer().MoveTo(Loc01) Utility.Wait(1) If Game.GetPlayer().GetDistance(Loc01) >= Distance ;if moveto didn't work, try fast travel. Game.EnableFastTravel() Game.FastTravel(Loc01) Endif Else Distance = Game.GetPlayer().GetDistance(Loc02) Game.GetPlayer().MoveTo(Loc02) Utility.Wait(1) If Game.GetPlayer().GetDistance(Loc02) >= Distance Game.EnableFastTravel() Game.FastTravel(Loc02) Endif Endif EndEvent Link to comment Share on other sites More sharing options...
Deleted19761User Posted May 29, 2021 Author Share Posted May 29, 2021 (edited) ObjectReference Property RecallMarker Auto ObjectReference Property LoC01 Auto WorldSpace Property ExampleWorld Auto Sound Property MagFail Auto Event OnEffectStart (Actor Target, Actor Caster) Float Distance = Game.GetPlayer().GetDistance(Loc01) Utility.Wait(3) ; If (Caster.GetWorldSpace() != ExampleWorld) If Distance > 7000 RecallMarker.MoveTo(Caster) Caster.MoveTo(Loc01) Game.EnableFastTravel() Game.FastTravel(Loc01) EndIf ;If (Caster.GetWorldSpace() == ExampleWorld) If Distance < 7000 Magfail.Play(Caster) debug.messagebox ("You can not cast that spell here.") EndIf Else Distance = Game.Getplayer().GetDistance(Loc02) Get.Getplayer().MoveTo(Loc02) If Game.GetPlayer().GetDistance(Loc02) >= Distance Game.EnableFastTrave() Game.FastTravel(Loc02) EndIf EndIf EndEvent Okay. This "works". The distance check is returning the Message Box correctly. (except even on a successful cast from elsewhere it's still showing the box/playing the sound.) Secondly second cast isn't returning the player to the recall marker. I have commented out doing a world space check instead which I haven't double checked yet if it works. But I also don't think its moving the marker to the player at all? (missing leaving a persistent VFX in place with the marker but I'll get to that after sorting out the primary function) Edited May 29, 2021 by Guest Link to comment Share on other sites More sharing options...
NexusComa2 Posted May 29, 2021 Share Posted May 29, 2021 If distance fails it's coming back as 0 so ... if Distance < 7000 is true ... maybe?I don't see where Loc02 is defined or why it's being used ... As for returning the player to the recall marker ...the part of the code would be in your case: Caster.Moveto(RecallMarker)Game.EnableFastTravel()Game.FastTravel(RecallMarker) Why is distance important ... are you testing everyplace for the closest one?Also you have to use fast travel to bring your followers ... unless you don't want them to port with you.Little lost in your logic ... can you explain what you looking to do totally. Link to comment Share on other sites More sharing options...
dylbill Posted May 29, 2021 Share Posted May 29, 2021 I was thinking if distance is close enough to the city marker, move to the recall marker instead. But yes a better explanation of what you want would be helpful. I would maybe put the recall marker in an empty cell to start to check for first time cast. Cell Property RecallMarkerStartCell Auto ObjectReference Property RecallMarker Auto ObjectReference Property LoC01 Auto Sound Property MagFail Auto Event OnEffectStart (Actor Target, Actor Caster) Float Distance = Game.GetPlayer().GetDistance(Loc01) If RecallMarker.GetParentCell() == RecallMarkerStartCell ;if recallMarker is still in empty start cell, it's a first time cast. RecallMarker.MoveTo(Caster) Caster.MoveTo(Loc01) Game.EnableFastTravel() Game.FastTravel(Loc01) ElseIf Distance > 7000 RecallMarker.MoveTo(Caster) Caster.MoveTo(Loc01) Game.EnableFastTravel() Game.FastTravel(Loc01) Else Caster.Moveto(RecallMarker) Game.EnableFastTravel() Game.FastTravel(RecallMarker) EndIf EndEvent Link to comment Share on other sites More sharing options...
Recommended Posts