ID:2019315
 
(See the best response by Ter13.)
Problem description:First, I am no coder, so please be gentle...most of the teleports work, but it seems to be in certain area's where it won't work, especially if I put the teleport over multiple or certain objects. I'm also having a problem with walking through walls where objects overlap eachother. For example, I will be able to walk through a wall where a picture is on the wall. It's probably due to some objects being different layers? some are layered 3, 4, and 5...I can walk through objects that aren't overlapping anything in some area's as well, so I have no idea. And yes, they have density set to 1. Any help is appreciated! Thanks!

runtime error right after running the game:
<b>runtime error: Cannot read null.connection
proc name: New (/obj/Teleports/Outs/New)
source file: Objs.dm,32
usr: null
src: lfHouse2a (/obj/Teleports/Outs/OutlfExterior/lfHouse2a)
src.loc: 6c (7,14,3) (/turf/Interior_Objects1/_6c)
call stack:
lfHouse2a (/obj/Teleports/Outs/OutlfExterior/lfHouse2a): New( 6c (7,14,3) (/turf/Interior_Objects1/_6c))
runtime error: Cannot read null.connection
proc name: New (/obj/Teleports/Outs/New)
source file: Objs.dm,32
usr: null
src: lfsecret (/obj/Teleports/Outs/OutlfExterior/lfsecret)
src.loc: 2a (196,139,3) (/turf/water_terrain/Ponds/_2a)
call stack:
lfsecret (/obj/Teleports/Outs/OutExterior/secret): New( 2a (196,139,3) (/turf/water_terrain/Ponds/_2a))
runtime error: Cannot read null.connection
proc name: New (/obj/Teleports/Outs/New)
source file: Objs.dm,32
usr: null
src: Lushleafcave (/obj/Teleports/Outs/OutExterior/Lushleafcave)
src.loc: 3v (206,163,3) (/turf/land_terrain/Cliffs_Ledges/_3v)
call stack:
cave (/obj/Teleports/Outs/OutExterior/cave): New( 3v (206,163,3) (/turf/land_terrain/Cliffs_Ledges/_3v))


runtime error after going through bugged teleport:
runtime error: Cannot read null.loc
proc name: Move (/mob/Player/Move)
source file: Procs.dm,27
usr: (src)
src: Lum (/mob/Player)
src.loc: null
call stack:
Lum (/mob/Player): Move( 6u (19,28,3) (/turf/Interior_Objects1/_6u), 8, null, null, 0)
KING VAIDRO X (/client): West()


Teleport code:
obj
var
door=0
Teleports
density=1

var
connection
Outs
OutlfExterior
lfHouse1
lfHouse1a
lfHouse2
lfHouse2a
lfHouse3
lfcave
lfsecret

OutrwExterior
RwHouse1
RwHouse1a
RwHouse2
RwHouse2a

New()
if(!locate("Outs[name]")) tag="Out[name]"
..()
connection=locate("In[name]")
if(connection:connection==null)
connection:connection=locate(src.x,src.y,src.z)
connection=connection:loc
Ins
InlfInterior
lfHouse1
lfHouse1a
lfHouse2
lfHouse2a
lfHouse3
lfcave
lfsecret

InrwInterior
RwHouse1
RwHouse1a
RwHouse2
RwHouse2a

New()
if(!locate("Ins[name]")) tag="In[name]"
..()
//connection=locate("Out[name]")
//connection=locate(connection:x,connection:y,connection:z)


mob
Player
Bump(obj/O)
..()
if(isturf(O)&&O.door==1)
O.DoorOpen()
if(isobj(O))
if(O.door==1) O.DoorOpen()
if(istype(O,/obj/Teleports)&&src.invisibility==0)
src.loc=O:connection
turf/proc
DoorOpen(time=50)
var/i=icon
src.icon=null
src.door=0
src.density=0
sleep(time)
src.door=1
src.icon=i
src.density=1
obj/proc
DoorOpen(time=50)
var/i=icon
src.icon=null
src.door=0
src.density=0
sleep(time)
src.door=1
src.icon=i
src.density=1


procs. code:
obj/Day_Transition
screen_loc="1,1 to 16,12"
icon='Weather Overlays.dmi'
layer=MOB_LAYER+4
Morning/icon_state="Night to Morning"
Day/icon_state="Morning to Day"
Evening/icon_state="Day to Evening"
Night/icon_state="Evening to Night"
Still_Image
Morning/icon_state="Morning"
Day/icon_state="Day"
Evening/icon_state="Evening"
Night/icon_state="Night"

Screen_Trans
icon='Misc Icons.dmi'
icon_state="Fading"
layer=50

Screen_1/screen_loc="1,1 to 16,12"
Screen_2/screen_loc="screen2:0,0 to 15,11"

proc
Transition(HOUR)
switch(HOUR)
if(0 to 3.9) {Time_Of_Day="Night";Transition.icon_state="0"}
if(4 to 4.9) {Time_Of_Day="Morning";Transition.icon_state="4"}
if(5 to 7.9) {Time_Of_Day="Morning";Transition.icon_state="5"}
if(8 to 9.9) {Time_Of_Day="Morning";Transition.icon_state="8"}
if(10 to 11.9) {Time_Of_Day="Day";Transition.icon_state="10"}
if(12 to 14.9) {Time_Of_Day="Day";Transition.icon_state="12"}
if(15 to 15.9) {Time_Of_Day="Day";Transition.icon_state="15"}
if(16 to 16.9) {Time_Of_Day="Day";Transition.icon_state="16"}
if(17 to 17.9) {Time_Of_Day="Day";Transition.icon_state="17"}
if(18 to 18.9) {Time_Of_Day="Day";Transition.icon_state="18"}
if(19 to 19.9) {Time_Of_Day="Day";Transition.icon_state="19"}
if(20 to 23.9) {Time_Of_Day="Night";Transition.icon_state="20"}

GetTime()
spawn()
while(1)
var/split_hour=text2num(time2text(GMTtoPST()*2,"hh"))
Transition(split_hour)
var/ampm=0
if(split_hour>=12)
ampm=1
if(split_hour>12)split_hour-=12
ServerTime="[split_hour]:[time2text(world.timeofday*2,"mm")] [ampm ? "PM" : "AM"]"
sleep(300)

GMTtoPST()
// return world.timeofday < 252000 ? world.timeofday+612000 : world.timeofday-252000
return world.timeofday < 216000 ? world.timeofday+648000 : world.timeofday-216000 //Daylight Savings

ActivateArea(mob/Player/M)
if(!(M.Location in ActiveAreas))
ActiveAreas+=list(M.Location=list())
ActiveAreas[M.Location]+=M.key
else ActiveAreas[M.Location]+=M.key

DeactivateArea(mob/Player/M)
ActiveAreas[M.Location]-=M.key
if(!length(ActiveAreas[M.Location])) ActiveAreas-=M.Location

Position_Icon(mob/Ref,mob/Pokemon/P,turf/Location,icon/Blend,Path,px=0,py=0)
var
image/Image
list/Images=new
obj/Pokemon_Icons/Icon
if(!Path) return
Icon = new Path(P.Gender,P.Shiny)
if(!Icon.icon) return
var/icon/FF = icon(Icon.icon)
var/dimension_x=FF.Width()
var/dimension_y=FF.Height()
if(!(dimension_x % 32)) dimension_x-=1
if(!(dimension_y % 32)) dimension_y-=1
for(var/Y=1 to round(dimension_y/32)+1)
for(var/X=1 to round(dimension_x/32)+1)
var/obj/o = new
o.layer=9
o.icon=Icon.icon
o.icon_state="[X-1],[Y-1]"
o.pixel_x=Icon.offset_px+px
o.pixel_y=Icon.offset_py+py
if(Blend)
var/icon/I=icon(o.icon,o.icon_state)
var/icon/NewLayer = icon(Blend)
I.Blend(NewLayer,ICON_MULTIPLY)
NewLayer.Blend(I,ICON_MULTIPLY)
o.overlays+=NewLayer
Image=image(o,locate(Location.x-Icon.offset_x+X,Location.y-Icon.offset_y+Y,Location.z))
Images+=Image
Ref << Image
return Images

atom/movable/proc
StepOn(atom/A)
if(A == src) return 1
else return !(density & A.density)
StepOff(atom/A) return 1
SteppedOn(atom/A)
SteppedOff(atom/A)



Best response
             New()
if(!locate("Outs[name]")) tag="Out[name]"
..()
connection=locate("In[name]")
if(connection:connection==null)
connection:connection=locate(src.x,src.y,src.z)
connection=connection:loc


Your problem is restricted to this here.

This thread will help you understand what's happening:

http://www.byond.com/forum/?post=2012623

Give the above thread a quick read and then I'll explain.

...

...

...

Ok, you done?


In the above thread, I mentioned how the world is initialized. Well, objects aren't all initialized at once. What's happening in your example, is that you are trying to locate objects by their tag during the New() of another object. It's almost always going to be guaranteed that one of the two objects you are trying to locate during New() won't actually exist yet.

This means that we need to try a different approach to linking your teleports. Normally, it'd be a good idea to set up teleports during New() like you are doing and store the result of the locate(). In fact, this is a good use for tag, but the two in combination result in failure, as you've found.

Instead, I'd actually recommend creating your own simulation of tag using a global associative list. This will allow us to simply assign teleporters on world initialization without having to actually reference the objects to one another. Of course, this solution has a small problem, in that the global teleporters list will keep any linked teleporters alive. If you want to delete teleporters, you should be safe to do a manual deletion because I've cleared up references in Del(). Del() won't be stupid slow.

var
list/teleporters = list()
obj
teleport
var
id
target_id

New()
if(teleporters[id])
loc = null
else
teleporters[id] = src
..() //may not be necessary here

Del()
if(teleporters[id]==src)
teleporters -= id
loc = null
..() //necessary here

Crossed(mob/ref)
if(target_id&&istype(ref)&&!ref.teleporting) //if the object that crossed this one's bbox is a mob, this teleporter has a target, and the mob isn't already teleporting
var/obj/teleport/lnk = teleporters[target_id] //get the linked teleporter
if(lnk&&lnk.loc) //if the linked teleporter exists and has a valid location
ref.Teleport(lnk.loc,lnk.dir,lnk.step_x,lnk.step_y) //tell the mob to teleport
..() //may not be necessary here

mob
var
teleporting = 0
proc
Teleport(atom/NewLoc,Dir=0,Step_x=0,Step_y=0)
var/odensity = density //this is a hack. It's better to use my ForceMove script
density = 0 //this will ensure that movement succeeds... Provided you haven't changed how cross/enter behavior works too much
teleporting = 1 //this is also a hack, but it does work. This will notify that we shouldn't teleport when we cross the new teleporter we are moving to
Move(NewLoc,Dir,Step_x,Step_y)
teleporting = 0 //turn off teleporting now that we're done
density = odensity //turn density back to what it was before.


There are ways to make this safer and cleaner, but this is the gist of the teleporter. I'm going to post again with a slight cleanup to some of the other stuff you posted to help you out because I'm seeing some other stuff that might help you clean your design up a bit.