ID:140562
 
Code:
obj/Viper
icon='viper.dmi'
density=1
verb
Get_In()
if(usr.incar == 0)
set src in oview(1)
for(var/obj/Viper/O in usr)
usr.loc=O.loc
O.dir=usr.dir
src.Move(usr)
usr.icon='viper.dmi'
usr.incar = 1
usr.MDelay = 1
usr.inCar2 = 1
else
usr << ""


Problem description:

The code works perfectly, The only issue i currently have is that when a user trys to enter the Car, Instead of goign to the Cars location (1 Space away from the user) the car comes to the users location.

I suspect it's this:
usr.loc=O.loc
O.dir=usr.dir


But all seems fine to me.
Users location goes to Objects location,
Objects direction faces users direction?

Correct me if i'm wrong.
Actually, it's this:

src.Move(usr)


You need to learn either how Move() works, or what the usr and src vars are.

Also, you just just use if(!usr.in_car) rather than if(usr.in_car == 0); it saves time and it makes the game run faster.
In response to Jeff8500
Right.

So any explanation on fixing it?
I understand i got src and usr mixed up but in result of changing that the player now is teleported to the cars location, But the car is still there if the user drives off. Basicly leaving a duplicate. - This code was created quite some time ago, first time back to byond in some time now, and i decided to fix a few bugs.

I could get rid of the duplicate via a del() but what confuses me is how it originally dissapeard before i changed the usr and src around and now doesent.
In response to BEVAN
I didn't notice it at first (I only glanced at the code), but the problem is that you're turning the usr into the car, rather than keeping the car and having the usr get in the car. You should probably scrap the whole thing and start over. Or, you can just delete the duplicate and work around the bad programming.
In response to Jeff8500
Well to be honest i figured this would have been the best method of achiveing what i wanted, But i guess i was wrong?

I couldnt think of another way to do it, But i'll try to figure something out then.

I'd rather not work around it, Since you end up running into more problems later down the line.
In response to BEVAN
Personally, I would probably set their client's eye to the car, then move them to a null location. Then, when then exit, I would move them to where the vehicle is. You could probably also add the mob to the car's contents list, that might work as well (though you would have to be sure to get the mob out of the car if the car is ever deleted, etc.).
In response to Jeff8500
That's a possibility.

Right now i'm currently looking at a way around it, Se if theres anything i can do to make it work.

I worked out that the line usr.move(src) was to put the car into the users inventory so the Get_Out command would still be able to function, and without the move being there, your forever trapped as the car.
In response to BEVAN
No, usr.Move(src) would move usr into src's contents. The most interesting part, I feel, is:

for(var/obj/Viper/O in usr)
usr.loc = O.loc


I was wondering what you thought you were doing here. O.loc is going to be usr, because it's in your contents. Therefore, you are setting usr.loc to usr. Which is just silly.

Again, fundamentally the issue here is that you are not actually driving a car, you are just turning into a car. Why you act confused when the car remains disappears is baffling to me.

Here is something I wrote a while ago for this:

obj
car
icon = 'car.dmi'
density = 1

//the mob currently driving this car
//any variable which stores a reference to a player should be declared as tmp
//saving a reference to a player results in Bad Things
var/tmp/mob/driver

verb
//moves a mob into the car
getin()
set src in oview(1)
if(usr.loc != src)
usr.Move(src)

//moves a mob out of the car
getout()
set src = usr.loc
//for every turf adjacent to the car
for(var/turf/T in orange(src,1))
//attempt to move us to that turf
if(usr.Move(T))
//and if it succeeds, then stop trying (return 1 for success)
return 1
//if all nearby turfs fail, then give an error message
usr << "There's nowhere to get out!"
//return 0 for failure
return 0

//gives up the wheel
relinquish_wheel()
set src = usr.loc
//obviously you can only do this if you're the driver
if(usr == driver)
//make them give up the wheel
driver = null
//let them know about it
usr << "You relinquish the wheel."
//let everybody in the car know about it
contents-usr << "[usr] relinquishes the wheel."
//find somebody else in the car to drive
for(var/mob/M in src-usr)
//we'll just accept the first person we find
//if we were responsible, we'd make sure they had a licence
driver = M
//and, of course, let people know about this change of affairs
M << "You take the wheel!"
contents-M << "[M] has taken the wheel!"
break
else
usr << "You aren't the driver."


//called when something enters the car
Entered(var/mob/M)
//perform the default action
..()
//only act if M is the type we said it was (a mob)
if(istype(M))
//if we don't have a driver
if(!driver)
//then this new mob is the driver
driver = M
//inform them of their newfound powers
M << "You take the wheel!"
//and inform anybody who may be in the car
contents-M << "[M] has taken the wheel!"
//if we do have a driver
else
//inform them of their newfound submissive situation
M << "You get in a passenger's seat."
//and let everybody else know of the situation
contents-M << "[M] has gotten into a passenger's seat."

//called when something exits the car
Exited(var/mob/M)
//perform the default action
..()
//only act if M is the type we said it was (a mob)
if(istype(M))
//let people know that they have left the car
contents << "[M] has left the car."
//if this mob is the driver
if(driver == M)
//then they are no longer the driver
driver = null
//but let's see if we can find a new driver
for(var/mob/Q in src)
//we'll just accept the first person we find
//if we were responsible, we'd make sure they had a licence
driver = Q
//and, of course, let people know about this change of affairs
Q << "You take the wheel!"
contents-Q << "[Q] has taken the wheel!"
break

client/Move(var/loc, var/dir)
//when our mob is in a car, and the driver, we will intercept movement and move the car instead
if(istype(mob.loc, /obj/car))
var/obj/car/C = mob.loc
//if our mob is the driver
if(C.driver == mob)
//then relay our move order to the car
step(C,dir)
//if we aren't in a car
else
//proceed as normal
..()

mob/Del()
//when a mob is deleted, we want to make sure they don't continue being the driver of a car
//this might result in the Driving Dead: Zoombies
//this is not a good thing, so we'll force them to give up the wheel before deleting them

//most straightforward way to do this is to just move them to a null location
//this will call Exited(), which will handle what's needed
Move(null)

//perform the default action, which is quite necessary here
..()
In response to Garthor
thanks for your contribution and aid but just as you posted this i had found out the issue.

Now my player is turned into the car, The player is facing the original car's direction and the player is in the location of the original car.

Just what i wanted.
In response to Garthor
Garthor wrote:
Therefore, you are setting usr.loc to usr. Which is just silly.

That makes me want to try that and see if it lets you put something inside itself! How paradoxical.

Here is something I wrote a while ago for this:

There are a couple of issues with it.
>           //gives up the wheel
> relinquish_wheel()
> if(usr == driver)
> //make them give up the wheel
> driver = null

You should probably check there is actually anyone in the car to relinquish the wheel to, or otherwise, allow retaking the wheel if nobody has it.
Also, a neater solution is to only give this verb to the driver, of course.

>                   for(var/mob/M in src-usr)


Since you can't subtract an atom from another, that has to be src.contents-usr.

//we'll just accept the first person we find

Since you do that, you should just use locate() instead of a loop.

>   //most straightforward way to do this is to just move them to a null location
> Move(null)

Unfortunately, since Move() does not support null as the destination location, that will not work.
Fortunately, here you can get away with just this:
if(istype(src.loc,/obj/car))
var/obj/C = src.loc
src.loc = null
C.Exited(src)

Of course, you may want to do the above globally for robustness, i.e. always call Exited() when a movable is being deleted, to notify its location that it is leaving it, however that's more of a project-wide design decision (and should also go along with calling Entered() in New()).
In response to Kaioken
Thanks. As I said, I wrote that a while ago, so I was bound to have made a few little mistakes like that (especially as those ones specifically are only noticeable with multiple clients).