ID:150243
 
A couple things things. First I can get the doors to open, but they will not close; also when I try opening an open door, the door is re-opened instead of supplying the "Door already opened" message. Next, using this code i'm assuming that in the future, by opening one door, it will open all of them. I am looking to fix both of these problems, so if you have any suggestion I would be please to take them.

obj
door
icon = 'door.dmi'
icon_state = "closed"
density = 1
opacity = 1
proc
CheckOpen(door)
if (src.icon_state == "closed")
door = 0
else
door = 1
..(door)
verb
open()
set src in view(1)
var/door
CheckOpen(door)
if (!door)
icon_state = "open"
density = 0
opacity = 0
usr << "You opened the door."
oview() << "[usr] opened the door."
else
usr << "The door is already opened."
close()
set src in view(1)
var/door
CheckOpen(door)
if (door)
icon_state = "closed"
density = 1
opacity = 1
usr << "You closed the door."
oview() << "[usr] closed the door."
else
usr << "The door is already closed."
All I can say, with my jaw hanging limp like this, is your code is royally screwy. It's so far from anything logical it's mind-boggling--but it'd work if DM worked a completely different way.

Here are the suspect lines of code:

proc
CheckOpen(door)
if (src.icon_state == "closed")
door = 0
else
door = 1
..(door)

verb
open()
set src in view(1)
var/door
CheckOpen(door)
if (!door)

The reason I'm aghast is that this is just so totally wrong; sending a scalar variable like a number to a proc, having the proc modify it, and expecting the modification to be carried back into the caller is something that works with only references and pointers--the sorts of concepts found in C++ and Visual Basic. In most languages, however, including DM, the value you pass is a copy, and the only time changes can carry back is if you're sending an object or a list whose contents are changed.

Now, in CheckOpen, you're modifying "door" as if it's supposed to do something; but it doesn't, because you're modifying a copy of the variable, and the copy only belongs to the current proc. The call to ..(door) is useless, because there's no CheckOpen proc for a regular obj.

Because the whole pointer/reference thing is completely inane, these three lines won't work:

var/door
CheckOpen(door)
if (!door)

Since you're not assigning anything to var/door, it assumes it's null, or 0. CheckOpen(door) does nothing, because a copy of door is sent to the proc, which modifies the copy and then tries to call a nonexistent obj/proc/CheckOpen(door). So if(!door) will always be true. Likewise, if(door) in the following proc is always false.

I guess the assumption of reference passing makes sense if you come from a Visual Basic background, but the way you rely on it like that is really bizarre; I think even most people who aren't aware that a copy is being passed would still think in a function mentality, of using CheckOpen to return a value and using that returned value in the if() statement. It looks to me like the reference thing is a very bad habit you must have picked up somewhere.

To fix your code, you need to change the procs as follows:
proc
CheckOpen()
if (src.icon_state == "closed")
return 0
else
return 1

Or, more simply:
proc
CheckOpen()
return (src.icon_state != "closed")

To fix the verb:
verb
open()
set src in view(1)
if(!CheckOpen(door))
...

That ought to get you back on track.

Lummox JR
In response to Lummox JR
yes my entire BYOND loginc got thrown out the window the last time i was completely massacred by an experianced (or at least i certainly hope fo) BYOND programmer. in any case i'll work through this massacre as, after skimming it, it appears helpful. Thank you very much for your reply (i'm not being sarcastic by the way) i'm going to go finish reading it now. :)

Still very tired.

EDIT: Yup it was very helpful thanks. :) Nothing like a good verbal beat down when your tired ;)

2nd EDIT: I remember why I passed that copy now... I was just doing random things to stop all the errors in my holy code (not "God-like code" but "code full of holes). Last time i tried to make a program I sent the stats to some proc to create a new character or something. I think it was Lexy(?) who verbally kicked my @$$ but i'm not sure.

3rd and FINAL EDIT: I get an error not that the variable door doesn't exist. It's probably just my insanity that keeps me from seeing a problem so here:

obj
door
icon = 'door.dmi'
icon_state = "closed"
density = 1
opacity = 1
proc
CheckOpen()
return (src.icon_state != "closed")
..()
verb
open()
set src in view(1)
if (!CheckOpen(door)) //Line 85
In response to Evilkevkev
verb
open()
set src in view(1)
if (!CheckOpen(door)) //Line 85

After looking up "arguments" and getting shifted to "named arguments" I realized that the arg "door" was amazingly useless, just like this post.

Tired and going to be very soon.
In response to Evilkevkev
Evilkevkev wrote:
3rd and FINAL EDIT: I get an error not that the variable door doesn't exist. It's probably just my insanity that keeps me from seeing a problem so here:

This one's my fault. I left in the door part in the call to CheckOpen:

if (!CheckOpen(door)) //Line 85

Just get rid of "door" there.

BTW, the call to ..() in CheckOpen() can go.

Lummox JR
In response to Evilkevkev
Here is a rather easy door code that I use, I hope it helps you out a little.
obj
     Door
          icon = 'Door.dmi'
          icon_state = "Closed"
          density = 1
          verb
               Close_Door()
                    set src in view(1)
                    if(src.icon_state == "Open")
                         src.icon_state = "Closed"
                         src.density = 1
                    else
                         usr << "This door is closed, duh!"
               Open_Door()
                    set src in view(1)
                    if(src.icon_state == "Closed")
                         src.icon_state = "Open"
                         src.density = 0
                    else
                         usr << "This door is already open!"

Happy Thanksgiving!!
In response to Bingis
I LOVE THANKSGIVING ^_^
In response to Bingis
Hehe, that'll perfect!

You can compress it to one verb if you wanted!
turf/door
icon = 'door.dmi'
icon_state = "closed"
density = 1 //starts out closed
verb
open_close() //you could choose a better name
set src in oview()
if(icon_state = "closed") //if it's already closed
icon_state = "open" //open it
density = 0
return //prevent it from auto-closing again because of the following check
if(icon_state = "open")
icon_state = "closed"
density = 1
return

Should work. :p
In response to Vortezz
This was what I originally wanted. Thanks for the tip!

Evilkevkev