ID:1452273
 
(See the best response by Magicsofa.)
Warning: There is a lot of it.

Code:
            EarthWall()
set name = "Earth Wall"
set category = "Combat"

if(!src.UseCheck(usr)) return

var/turf/T1
var/turf/T2
var/turf/T3

var/Walls/Clay/C1
var/Walls/Clay/C2
var/Walls/Clay/C3
var/Walls/Clay/C4

switch(usr.dir)
if(NORTH)
T1 = get_step(usr, usr.dir)
T2 = get_step(T1, turn(usr.dir, 90))
T3 = get_step(T1, turn(usr.dir, -90))
C1 = new /Walls/Clay/T
C2 = new C1.type
C3 = new C1.type

if(NORTHEAST)
T1 = get_step(usr, NORTH)
T2 = get_step(usr, NORTHEAST)
T3 = get_step(usr, EAST)
C1 = new /Walls/Clay/T
C2 = new /Walls/Clay/TR
C3 = new /Walls/Clay/R
C4 = new /Walls/Clay/TR2

if(EAST)
T1 = get_step(usr, usr.dir)
T2 = get_step(T1, turn(usr.dir, 90))
T3 = get_step(T1, turn(usr.dir, -90))
C1 = new /Walls/Clay/R
C2 = new C1.type
C3 = new C1.type

if(SOUTHEAST)
T1 = get_step(usr, EAST)
T2 = get_step(usr, SOUTHEAST)
T3 = get_step(usr, SOUTH)
C1 = new /Walls/Clay/R
C2 = new /Walls/Clay/BR
C3 = new /Walls/Clay/B
C4 = new /Walls/Clay/BR2

if(SOUTH)
T1 = get_step(usr, usr.dir)
T2 = get_step(T1, turn(usr.dir, 90))
T3 = get_step(T1, turn(usr.dir, -90))
C1 = new /Walls/Clay/B
C2 = new C1.type
C3 = new C1.type

if(SOUTHWEST)
T1 = get_step(usr, SOUTH)
T2 = get_step(usr, SOUTHWEST)
T3 = get_step(usr, WEST)
C1 = new /Walls/Clay/B
C2 = new /Walls/Clay/BL
C3 = new /Walls/Clay/L
C4 = new /Walls/Clay/BL2

if(WEST)
T1 = get_step(usr, usr.dir)
T2 = get_step(T1, turn(usr.dir, 90))
T3 = get_step(T1, turn(usr.dir, -90))
C1 = new /Walls/Clay/L
C2 = new C1.type
C3 = new C1.type

if(NORTHWEST)
T1 = get_step(usr, WEST)
T2 = get_step(usr, NORTHWEST)
T3 = get_step(usr, NORTH)
C1 = new /Walls/Clay/L
C2 = new /Walls/Clay/TL
C3 = new /Walls/Clay/T
C4 = new /Walls/Clay/TL2

C1.Move(T1)
C2.Move(T2)
if(!isnull(C4)) C4.Move(T2)
else
usr << "C4 is null"
C3.Move(T3)


Problem description:
Using it while facing NEWS works fine. However, using it while facing NW will throw a null.Move() error, with C3 being "null". I'm pretty sure I set it properly. In the other directions (SE, SW, and NW) there is always a wall piece missing, And it's not always the same one. It's either C3 or C4. I figured that if it were the same one each time, there would be an issue with Move() returning 0 due to Cross(). But it's not always the same, so I don't know what to think. I've broken the code down to as explicit as I can to try to fix this error, but nothing seems to work. I've used debugging statements to check for null variables, none.
Best response
I'm not really sure why C3 is null. But I'm wondering, are all those different Clay types just for different directions? Because turfs can use the dir var too. But then I realized that you seem to have created a new datum, Walls. Or does it have the parent_type set to mob or obj?
It has parent_type set to obj, and yeah, they're for different directions, but the main reason was so I didn't have to fiddle around with bounding boxes for each one.
I made a few changes
                C1.Move(T1)
C2.Move(T2)
var/loopcounter = 0
if(!isnull(C4))
while(!C4.Move(T2))
loopcounter ++
if(loopcounter >= 100)
usr << "Unable to move C4"
break

loopcounter = 0
while(!C3.Move(T3))
loopcounter ++
if(loopcounter >= 100)
usr << "Unable to move C3"
break


I did fix the C3 is null issue, but I keep getting incomplete walls. There seems to be a problem with move, something is preventing it from moving. I know that the walls are dense, but that shouldn't prevent them from being moved. Because I got the NE one to work perfectly. Any ideas?
It seems I was not careful enough with my bounding boxes, Cross() did was it was supposed to do and denied movement. Just my stupidity here, sorry folks.
You could just set the loc directly, and soft-code any collision checks or whatever