ID:158153
 
How would I, for example...say you flew into the skies, and were re-located into the skies map, how would you re-locate yourself back to the exact same spot as where you were when you land?
Store the location in a variable, then move back to it.
well, this is the coding for a portal

turf
#1
icon='#1.dmi'
Enter()
usr.loc=locate(X,Y,Z)

#1 is the name of the icon
X,Y,Z is the map coordinates
In response to Darkjohn66
Darkjohn66 wrote:
well, this is the coding for a portal

No it's not. I'm not trying to sound degrading, but that is not even a coding for a portal let alone the coding for a portal. Doing it like that can (and has) caused bugs in games.

Also, I do believe the OP has a situation where an object is at location A and (s)he is successfully relocating it to location B, and later wants to return it to location A.

For portals, the following may be overkill, but it should work well for pretty much any circumstance and is clean and bug-reduced.
portal
var
x;y;z
objectWarp
proc
warp(atom/movable/target)
if(objectWarp)
target.loc = objectWarp // you can add another check in here if you want it to warp to movable's loc instead of into a movable itself
return 1
if(x && y && z)
target.loc = locate(x,y,z)
return 1
return 0

// the following implements a subtype of /turf that acts as a static portal
turf/portal
var/portal/portal
Entered(atom/movable/M) // notice the use of Entered() instead of Enter()
if(portal)
portal.warp(M) // and the lack of usr
toMyHouse
portal = new(1,2,3) // if I remember correctly, you can do this at compile-time like this; don't quote me on it though
backFromMyHouse
portal = new(4,5,6)

And, if you wanted to use this method for the OP's problem, you could implement a subtype of portal.
portal/specialPortalThatTakesYouBackWhereYouStarted
var/list/originalLoc
warp(atom/movable/M)
if(!originalLoc)
originalLoc = new
originalLoc[M] = M.loc
return ..()
proc/returnWarp(atom/movable/M)
M.loc = originalLoc[M]
originalLoc.Remove(M)
if(originalLoc.len == 0)
del(originalLoc)

Then he could use it like this, for example...
turf/warpToSpecialPlace
var/portal/specialPortalThatTakesYouBackWhereYouStarted/portal = new(1,2,3)
Entered(atom/movable/M)
portal.warp(M)
spawn(1000)
portal.returnWarp(M)

// or...
obj/coolWarperThing
var/portal/specialPortalBlahBlah/portal = new(1,2,3)
var/warped = 0
verb/use()
if(!warped)
portal.warp(usr)
else
portal.returnWarp(usr)
warped = !warped

// or whatever

Don't use usr in most things, including Enter(), unless you're sure that's what is appropriate (which it's usually not). Also, Enter() is what checks to see if you are allowed to make a move; use Entered() to do things that are supposed to trigger when a move is successful.

Hope all this helps.
In response to Loduwijk
Thanks for the help, but not exactly what i'm looking for. I'm looking for something that will make it to where you will be Taken EXACTLY back to where you were before you started flying, no matter how much you moved.

EDIT: Nevermind, I understand it now.
In response to Xorbah
My last example addressed that issue. The "portal/specialPortal" keeps track of exactly where you were when you were moved so it can later move you back to the same spot.
In response to Loduwijk
How do I use it, though? It keeps saying that the proc is undefined.

stuff.dm:184:error:movable:undefined var
stuff.dm:184:error:M:undefined var
stuff.dm:184:error:warp:undefined proc
stuff.dm:187:error:M:undefined var
stuff.dm:187:error:M.loc:undefined var
stuff.dm:189:error:movable:undefined var
stuff.dm:189:error:M:undefined var
stuff.dm:189:error:proc/returnWarp:undefined var
stuff.dm:190:error:M.loc:undefined var
stuff.dm:190:error:M:undefined var
stuff.dm:191:error:M:undefined var
stuff.dm:185:if :warning: if statement has no effect
stuff.dm:192:if :warning: if statement has no effect
stuff.dm:182:portal :warning: unused label
stuff.dm:182:backtolocation :warning: unused label
In response to Xorbah
That last example was a use of it. I made a turf/warpToSpecialPlace that used it and an obj/coolWarperThing that used it.

In the following, I'm going to call the special portal "returnTripRelocator" instead of "specialPortalThatTakesYouBackWhereYouStarted" like I did in the previous post.

The following code snippet is the thing that does the relocating, and the second code snippet is an example of how to use it. The "roundTripRelocator" is what handles the "bring me back to exactly where I started"
/**
* this object takes care of all your relocation needs!
* from portals to star trek teleporter consoles to dislocator ray guns
* just make a new one with either x,y,z set to the coordinates you want or targetLoc set to the exact object location you want
* when you want to actually move something, call relocate(thing to be moved)
**/

relocator
var
// use either targetLoc or x,y,z, but not both
// if you use targetLoc, set targetLoc to an object, and youc an warp to it
// example: targetLoc = locate(/area/startPoint)
atom/targetLoc
// if you use x,y,z instead of targetLoc, set it to the coordinates you want to be relocated to
// example: x = 1; y = 2; z = 3
x;y;z

New(x,y,z)
if(istype(x, /atom))
targetLoc = x
else
src.x = x
src.y = y
src.z = z

/**
* relocate() - call this when you want to relocate something using this relocator
* parameters:
* relocateMe - the thing you want moved
* returns: 1 if relocateMe was properly moved, 0 otherwise
**/

proc/relocate(atom/movable/relocateMe)
// if you set a targetLoc, send relocateMe there
if(targetLoc)
relocateMe.loc = targetLoc
return 1
// if you set x,y,z, send relocateMe to those coordinates
if(x && y && z)
relocateMe.loc = locate(x,y,z)
return 1
// neither targetLoc or x,y,z are set; failure
return 0

/**
* roundTripRelocator adds functionality to relocator by keeping track of where things were so it can send them back
* use the same way as relocator, but then call relocateReturn(thing to be returned) when you want to send stuff back
**/

relocator/roundTripRelocator
var
list/originalLocation

relocate(atom/movable/relocateMe)
if(!originalLocation)
originalLocation = new
originalLocation[relocateMe] = relocateMe.loc

/**
* same as relocate(), but sends relocateMe back to where it came from
* returns: 1 on success, 0 on failure (relocateMe wasn't the subject of relocate())
proc/relocateReturn(atom/movable/relocateMe)
if(!(relocateMe in originalLocation))
return 0
relocateMe.loc = originalLocation[relocateMe]
originalLocation.Remove(relocateMe)
if(!originalLocation.len)
del(originalLocation)

The roundTripRelocator is what handles the part you want.

Now, as for an example of using that, I will assume you have a verb for flying, as you didn't specify (at least not that I remember) how the flight is initiated.
var/relocator/roundTripRelocator/flyRelocator

world/New()
flyRelocator = new(1,2,3) // or whatever your coordinates are for the air map

mob
var
flying = 0
verb
fly()
if(!flying)
flyRelocator.relocate(src)
else
flyRelocator.relocateReturn(src)
flying = !flying

Or, if you have a turf that triggers the flight, here's an example for that too. In the following example, you step onto a special turf, it sends you into the fly zone, and you get a "stop flying" verb to click when you want to land, and, when you land, you return to the spot you were on just before you started flying.
turf/flyPad
var
relocator/roundTripRelocator/flyRelocator

New()
flyRelocator = new(1,2,3) // or whatever the coords are

Entered(atom/movable/M)
M.contents.Add(new /obj/flightReturnStone(src))
M << "You have stepped onto a flight pad and bean sent soaring into the air! A magic stone appears in your pocket. Use it to return to the ground."
flyRelocator.relocate(M)

proc/returnRelocate(atom/movable/M)
flyRelocator.returnRelocate(M)

obj/flightReturnStone
var/turf/flyPad/myFlyPad

New(turf/flyPad/myFlyPad)
src.myFlyPad = myFlyPad

verb/stop_flying()
myFlyPad.returnRelocate(usr)
del(src)

You can also do other fun stuff when you set systems up like this. For example, I could override relocate() for the following fun use. The next example does not address your issue directly, but I'm just showing more fun stuff you can do.
relocator/randomRelocator
var/list/targets

// pass to this a list of objects
New(list/targets)
src.targets = targets

relocate(atom/movable/relocateMe)
relocateMe.loc = pick(targets)

turf/crazytown
// crazyTrailOfHistory will warp you to a random place that some person has stood before
crazyTrailOfHistory
var/relocator/randomRelocator/myRelocator

New()
var/list/initialLocations[0]
for(var/client/C)
initialLocations.Add(C.mob.loc)
myRelocator = new(initialLocations)
spawn()
historyTracker()

// adds everyones current locations to randomRelocator every 5 minutes
proc/historyTracker()
while(1)
sleep(3000)
for(var/client/C)
myRelocator.targets.Add(C.mob.loc)
// let's keep the target locations down to 200 just so it doesn't get too crazy
while(myRelocator.targets.len > 200)
myRelocator.targets.Remove(pick(myRelocator.targets))

Entered(atom/movable/M)
myRelocator.relocate(M)
M << "You follow in the footsteps of the past"

// crazyAreas takes you to any one of the /area instances
crazyAreas
var/relocator/randomRelocator/myRelocator

New()
var/list/areas[0]
for(var/area/A)
areas.Add(A)
myRelocator = new(areas)

Entered(atom/movable/M)
myRelocator.relocate(M)

And I had a couple other neat examples in my other post too. When you set stuff up like this, taking advantage of object oriented programming, it's easy to adapt what you make to lots of cool uses. Again, go back to the first two for the examples specifically for what you're doing.
In response to Loduwijk
Loduwijk wrote:
For portals, the following may be overkill, but it should work well for pretty much any circumstance and is clean and bug-reduced.

Shame on you for saying this while that code uses direct modifying of loc (and nothing else) to do movement!
Although you did say "bug-reduced" and not "bug-free", you should still try not to spread a bad practice.