ID:1639627
 
(See the best response by Jittai.)
Code:
area
elevator
var
z_level=1;
list/L = list();
proc
findDoor(){
if(L.len == 0)
createList();
for(var/Other/Turfs/door/elevatorDoor/o in L) {
if(o.z == src.z_level) {
return o;
}
}
}
createList()
for(var/Other/Turfs/door/elevatorDoor/o in world) {
if(istype(o.loc.loc,/area/elevator))
L.Add(o);
}
elevator_Panel
parent_type = /obj;
icon = 'Turf.dmi';
icon_state = "elevpanel";
proc
go(var/t) {
var/area/elevator/a = src.loc.getArea();
var/Other/Turfs/door/s = a.findDoor();
s.locked = TRUE;
s.Close();

while(a.z_level != t) {
if(t > a.z_level) { //3-->1, FALSE
a.z_level++;
}
else if(t < a.z_level) { //2--> 1
a.z_level--
}
for(var/mob/M in a) {
if(M.client){
spawn(-1) {
quakeEffect(M,25);
M.loc = locate(M.x,M.y,a.z_level);
}
} else {
spawn(25)
M.loc = locate(M.x,M.y,a.z_level);
}
}
sleep(25);
for(var/obj/o in a) {
if(istype(o,/Other/Turfs/door))
continue;
o.loc = locate(o.x,o.y,a.z_level);
}
viewers() << "Ding! Reached Floor [a.z_level]";
var/Other/Turfs/door/o = a.findDoor();
o.locked = FALSE;
o.Open();
if(a.z_level != t)
o.locked = TRUE;
}
}

console
var/busy = FALSE:
verb
goToLevel() {
set src in view(1);
var/t = input("Which level?","Elevator") as null|anything in list(1,2,3);
if(!t) return;
if(t > 3) return;
else
busy = TRUE;
src.go(text2num(t));
busy = FALSE;
}
panel
icon_state = "switch";
Click()
var/elevator_Panel/console/C = locate();
var/area/elevator/a = C.loc.getArea();
if(usr in a) return;
if(a.z_level != usr.z) {
if(C.busy)
usr << "Sorry, wait for the elevator to stop operations.";
else
viewers() << "Clicked.";
C.busy = TRUE;
C.go(usr.z);
viewers() << "Ding!";
C.busy = FALSE;
} else
usr << "The elevator is here. Go in already.";


Problem description:
Hope someone can take a look at this for me. It's a bit messy and maybe not efficient but it's my elevator system. It works fine going from floor 1 to 2, floor 2 to 3, floor 1 to 3, but coming back down there seems to be problem. Specifically, when it's floor 3 - 1 and I use the goToLevel verb to go to 1 before the door closes, it does everything but stays at floor 3 and repeats forever. And yes the door Open() have sleep() in them.
Since the z_level is 1 by default, is there something making sure it's checked/set properly if by chance it starts on floor 3?

Can you add a "world << "[t]" " in the while() to check the t and make sure it's actually getting a num.
the elevator starts at floor 1, if you're on floor 3 you have to wait til the elevator reaches floor 3
And the issue is if you ride it from 1 to 3, and then back to 1 it gets stuck?

Did the debug message enlighten anything?
Yes the issue is if you ride from 3 to 1 then it stays on 3 but says there's stuff happening.

I decided to put
                if(t > a.z_level) { //3-->1, FALSE
a.z_level++;
viewers() << "Add one. [t]";
}
else if(t < a.z_level) { //2--> 1
a.z_level--
viewers() << "Minus one. [t]";
}

Because I think it was adding one and minusing one which is why it was stuck on floor 3. It turns it was true but what was confusing was it had different values of t.

When I went back and did it, the output was:
Clicked.
Add one. 3
Ding! Reached Floor 2
Add one. 3
Ding! Reached Floor 3
<--- this is when I used the console before the door closed to go to floor 1
Minus one. 1
Add one. 3
Ding! Reached Floor 3
Ding! Reached Floor 3
Well it was -1 and +1, so the net was 0. But that's weird.

You should add [a.z_level] into those debug messages like have "[t] > [a.z_level]" under the first check - perhaps one of the values isn't being stored the way you think it is.

Also, perhaps it's just habit for you but the brackets and semi-colons aren't really needed.
Oh yeah I forgot the brackets aren't needed but they help partition my code better for me I guess?

Also I kinda think I know what's going on. In the while-loop it continues if a.z_level != t so because I press the console before the door closes, the while loop is still going on(see the end of go() proc)) so when I use the console I'm calling another go() but the first go() is still going on. The second go() causes it to -1 but the first go() t = 3, so it says z_level is < 3(it's 2 now) so it raises back to 3. And then repeat?

I think that's what's going on??
I think one alternative solution is for me to prevent players from touch the console in the elevator room if it's busy.

But I wasn't expecting to go() to continue because in my panel code, it doesn't allow the console to have busy=FALSE until go() finishes??
Best response
All you have to do is add a busy check before the while is initiated and un-busy it after it's ended.
Oh crap that's true