ID:153669
 
Ok, I'm working on putting in a mass_transit system in my game...problem is, I have a rough idea of how to keep all the different Sub_way cars connected, but my mind's not exactly working right now...here's what I have so far:

        Public_Transportation
var/mob/pos
Sub_Way
icon='subway.dmi'
icon_state=""
Front_Car
icon_state="front"
dir=NORTH
owner="Cab"
Move()
..()
for(var/mob/vehicles/Public_Transportation/T in oview(3,src))
spawn()
if(T.owner==src.owner)
if(src.dir==EAST)
T.Move(locate(src.x-T.pos,src.y,src.z))
if(src.dir==WEST)
T.Move(locate(src.x+T.pos,src.y,src.z))
if(src.dir==NORTH)
T.Move(locate(src.x,src.y-src.pos,src.z))
if(src.dir==SOUTH)
T.Move(locate(src.x,src.y+src.pos,src.z))
Middle_Car
icon_state="middle"
owner="Cab"
pos=1
Rear_Car
icon_state="back"
owner="Cab"
pos=2

I haven't tested it yet...but I'm not quite sure it'll work the way I need it to. PLEASE, give your insights or comments...either helpful or otherwise.
Have the first subway car in the bunch pull each other car after the next.

Like:


First car proc:


Pull first car in dir;
Pull second car in dir;
Pull third car in dir;
Pull fourth car in dir;
etc.
Repeat.
This is how I would do it:

The train is only tracked by the "head" of the train. The train head is only aware that it is pulling a single car.

That first car is aware that it is pulled by the head of the train, and it is also aware that it is pulling another car.

That second car is aware that it is being pulled by the first car, and it is aware that it is pulling the last car.

The last car is aware that it is being pulled by the second car.

Then, when the train decides to Move, *it does so immediately*. Then, it tells the car is is pulling to move into its former location. That car is tipped off that it was pulled, so it tells the car that *it* is pulling to move into its location. And so on, until the last car of the train is pulled -- it notices it isn't pulling another train car, so it shrugs and just gets tugged along.

In simple terms, it's recursion. car.Pull() calls the attached car's Pull() command, if a car is attached.
You know you can just do <code>step(src,src.dir)</code> to move src in its current direction, right?
In response to Crispy
AHH, thank you Crispy, and Spuzzum...I joined your two's advice together and made it work ^_^ THANK YOU ALL FOR YOUR SUGGESTION'S!

proc
Pull(mob/C)
var/mob/vehicles/Public_Transportation/Sub_Way/M=C
for(M in oview(10))
if(M.owner==src.owner+1)
step_towards(M,src)
spawn()
M.Pull()
In response to Goku72
More reliable than that would be to have vars referencing the other carriages, instead of numbers (I think that's what Spuzzum meant). With your existing system, if you get two subway trains (is that what they're called??? No subways in Canberra, Australia =) ) next to each other, they'll go haywire.
In response to Crispy
The 'Subway workers' could use a simple verb that references the cars pulling var to the car behind it. Or something.
In response to Hazman
Well, as of now...it works great! All I have to do is have dense objects on the sides of the track, and using a system of Bump() and walk() it stays on course...
In response to Goku72
Hazman mutters under his breath: *Release a library, Release a library, Release a library,* with his fingers crossed.

Worlds says: 'Release a library! Chatters is not online!'
In response to Goku72
This is actually pseudocode about how I was proposing it. The head would then call Pull(next_track_location) and would move along the track. The other cars would all follow.

To prevent breaking up the train, it'd probably be a good idea to set up a uniform pixel_step_size for them.


mob/vehicles/Public_Transportation/Sub_Way
var/mob/vehicles/Public_Transportation/Sub_Way/car/connected

Pull(loc)
var/turf/T = src.loc
src.loc = loc //move to new location
if(connected) connected.Pull(T) //pull connected car into my former location

head
New()
..()
//TODO: Stick in code to build the train -- set connected to the first car, first car sets
// connected to second car, etc.
In response to Spuzzum
My system (though reliable as uhh... something that you can never rely on. The family car) looks a little like this. And no, it doesn't work very well. And I could do with some help getting the trains to actually stop. Nothing calls the Stop() proc yet.
obj
Train_Main
density = 1
icon = 'vehicles.dmi'
icon_state = "main"
var/obj/Train_Section/next
var/move = 1
Move()
if(!move)
return 0
else return ..()
proc/Stop()
world << "Trains stopped!"
move = 0
if(next) next.Stop()
sleep(150)
world << "Trains go!"
move = 1
Goa()
proc/Goa()
if(!move) return 0
var/turf/a
loc = get_step(src,src.dir)
a = locate(x,y,z)
dir = a.dir
if (next) next.Go()
sleep(6)
Goa()
verb/Go()
set src in view(1)
Stop()
..()
verb/Couple()
set src in view(1)
var/a = list()
for(var/obj/Train_Section/b in oview(1))
a += b
next = input(usr,"Please select the train to couple with") in a
Train_Section
density = 1
icon = 'vehicles.dmi'
icon_state = "section"
var/obj/Train_Section/next
proc/Go()
var/turf/a = /turf/Track
loc = get_step(src,src.dir)
a = locate(x,y,z)
dir = a.dir
if(next) next.Go()
proc/Stop()
for(var/mob/M in contents)
M.loc = locate(x+1,y,z)
M << "The train stops and you get out"
M.client.eye = M.client.mob
if(next) next.Stop()
verb/Get_In()
set src in view(1)
usr << "You get into the train."
usr.loc = src
usr.client.eye = src
New()
for(var/obj/Train_Section/a in locate(get_step(src,SOUTH)))
next = a
break