ID:158888
 
How do you create an object that multiple people can enter and you can control?
Like a four doored car.
Like this:
var/Car/C = new


(Please be more specific - like what exactly are you having trouble expressing your idea)
In response to GhostAnime
How do I get

mob
people

Into

obj
cars

?

In response to Kokomo0020
Either make a list of the people inside the car, or just use the car's contents list.
Make a verb a person can use to get in the car, and move the person into the car's contents.
I don't remember if being in an object's contents gives you a black screen. If it does, change the person's client's perspective to the eye, and change the eye's location to the car.

obj/car
verb/GetIn() //The verb to get into the car.
set src in oview(1,src) //Can only use it when you're adjacent to the car, and not when inside it.
usr.loc=src //Move usr into src's contents.
if(usr.client) //If usr has a client(in case you want NPCs in a car for any reason, NPCs don't have clients and it would cause a null.var error)
usr.client.perspective=EYE_PERSPECTIVE //Change the client's perspective to the eye
usr.client.eye=src //Change the eye to the car
In response to Kaiochao
If your loc is an obj, you don't get a black screen. I have something for this I wrote a while ago for basically the same question. I fixed a couple stupid mistakes, and here it is:

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
Garthor wrote:
If your loc is an obj, you don't get a black screen.

(Provided that that obj is actually linked to the map)
To expand, whenever you're inside a movable that is on the map, you don't get a black screen, but you see that movable on the map (as if your eye was set to it). The same thing in a situation when multiple movables are nested; for example, if there's a mob on the map that has an obj in it, and your mob is inside that obj, you see that first mob on the map.

The only situations where you'll get a black screen as a direct result from movement is when you're relocated to null, an empty* area, or a movable that isn't eventually contained by a map object (e.g. a mob whose loc is null, or an obj whose loc is that same mob).

*: If you're located to an area that isn't empty (meaning it contains at least one turf), you're just put at the first turf of that area, so in that case your loc isn't actually an area but a turf, so you see the map as normally.

EDIT: Rewrote the post for better clarification.
The really abstract answer is that there's a whole lot of different ways you can do it, but you will want to invent a way that's appropriate to your game.

Basically, I'd break down what you're asking for like this:

How do you create an object...

Answer received - lets move on to the actual question.

...that multiple people can enter...

Well, the good news is that multiple people can enter objects by default. Objects are like turfs in that things can be placed inside of them by simply using Move() to move them there. If the object's .Enter() is programmed to allow it, or the object or player mob is not dense (density = 0), then in they will go. If you wanted to limit it to only 4 people entering that object, the code most logically would go on the car object's .Enter() proc.

They might even be able to see outside of the object at that point (I forget if so) but if their maps just go black, you can temporary set the affected player's client.eye to be the object and client.perspective to equal EYE_PERSPECTIVE. Then when they leave the car, set the client.eye back to client.mob and client.perspective back to MOB_PERSPECTIVE.

This is just one possible implementation. Again, it depends on what you really want your game to do. You could potentially have it teleport the players to a map that serves as their car - that way you can see the car interior - but how important is that to your design, really? Dynamic map handling is possible (especially if you leverage a good library like Lummox JR's Swap Map) but it's a big hassle that should really be used by your game well in order to go that far.

...and you can control?

Here, we're basically talking about your control interface. Basically, when a player is in the car, you want them to take control over it (in such a way only one player can control it) and now that player will basically have access to the appropriate verbs that move the car.

It's actually a lot easier than it sounds. You just create some procs or verbs on the car that govern changes to its movement and then set up a means to access those verbs/procs. Off the top of my head, the easiest way to do so would be to put the verbs on players and hide the verbs when the player is not driving a car. An even easier implementation is just to override the client.NORTH() and other such procs to behave differently if the player is currently designated as a driver of a car.

Overall, what we have here isn't so much a coding problem as it is understanding how to conceptualize the relationship from code to reality. My advice: keep practicing, and before long you'll be able to come up with solutions even more elegant than I can.
In response to Kaioken
If you're going to "correct" what I wrote, at least do it correctly. I mean, you immediately disagreed with yourself:

If loc.loc.loc... eventually reaches a turf, you don't get a black screen (assuming you aren't blind, and there's something to see). Being in an area (not on one of its turfs, but your loc actually being that area) will give a black screen as well.
In response to Geldonyetich
Great reply there; "How do you create an object that multiple people can enter and you can control?" is indeed a really abstract and vague question.

Geldonyetich wrote:
They might even be able to see outside of the object at that point (I forget if so)

[link]

Off the top of my head, the easiest way to do so would be to put the verbs on players and hide the verbs when the player is not driving a car.

You mean "remove", not hide, right? As verbs can be hidden while still accessible. Anyway, the easier solution is to have the verbs just not available by default (by putting them on a container datum that isn't used anyway) and add them to a player when he's in the car. That way you don't need to bother removing them from a new player mob. f.ex.:
VERB_CONTAINER_NODE //this dummy type is never used to create objects \
(of course, you'll want a shorter/better name...)

parent_type = /mob/player //*see comment after code
Car/verb
Leave_Car()
...
Become_Driver()
...
obj/car
Entered(mob/player/M)
if(istype(M))
M.verbs += typesof(/VERB_CONTAINER_NODE/Car/verb) //add all car verbs
if(M is the driver)
M.verbs -= /VERB_CONTAINER_NODE/Car/verb/Become_Driver
..()
Exited(mob/player/M)
if(istype(M))
M.verbs -= typesof(/VERB_CONTAINER_NODE/Car/verb)
..()

*: I defined the dummy verb container type as a /mob/player type for a specific reason: this lets you use 'src' properly (easily) inside the verbs under it. Because 'src' is always defined of a type of the node the proc is on, if you use a regular datum you won't be able to use mob properties on src without re-typecasting it.

An even easier implementation is just to override the client.NORTH() and other such procs to behave differently if the player is currently designated as a driver of a car.

That is only for car movement control - for other actions (like shown above), you can use verbs like discussed.
In response to Garthor
Garthor wrote:
If you're going to "correct" what I wrote

Of course, I didn't correct what you said, I simply expanded on it. For example, to show the behavior isn't obj-specific.

I mean, you immediately disagreed with yourself

I didn't see anything quite like that, but I see how it could be misleading in a certain way (though your statement about objs is the same), so I'll reword it entirely. Thanks for da tip-off.

Being in an area (not on one of its turfs, but your loc actually being that area) will give a black screen as well.

If that area is "off-map" (doesn't contain any turfs), then of course, naturally - there isn't anything to see. I thought that was obvious, but I'll cover that in my edited post.
(If a movable is relocated into an area that has turfs in it, it's impossible for its loc to be that area anyway - it's just put onto the first turf in the area, so no black screen.)
In response to Kaioken
Kaioken wrote:
If that area is "off-map" (doesn't contain any turfs), then of course, naturally - there isn't anything to see. I thought that was obvious, but I'll cover that in my edited post.
(If a movable is relocated into an area that has turfs in it, it's impossible for its loc to be that area anyway - it's just put onto the first turf in the area, so no black screen.)

PEDANTRY, GO!

A turf can be added AFTER you move the mob into the area, and the mob won't be relocated to the turf. Alternatively, the mob could fail to Enter() every turf in the area.
In response to Garthor
One can always find niche cases (an empty area would normally be meant to be left empty, etc), so good job to you, but I think my edited post covered them anyway; you get to see The Void if your loc is set directly to an area, etc.