This commit is contained in:
Aurorablade
2016-04-07 00:48:27 -04:00
parent a669d0fac4
commit b58006db4e
21 changed files with 522 additions and 1496 deletions

View File

@@ -525,8 +525,8 @@ var/list/turret_icons
for(var/obj/spacepod/SP in view(7,src))
assess_and_assign(SP.occupant, targets, secondarytargets)
for(var/obj/vehicle/train/T in view(7,src))
assess_and_assign(T.load, targets, secondarytargets)
for(var/obj/vehicle/T in view(7,src))
assess_and_assign(T.buckled_mob, targets, secondarytargets)
for(var/mob/living/C in view(7,src)) //loops through all living lifeforms in view
assess_and_assign(C, targets, secondarytargets)

View File

@@ -1,219 +1,3 @@
//old style PIMP-CART
/obj/structure/stool/bed/chair/janicart
name = "janicart"
desc = "A brave janitor cyborg gave its life to produce such an amazing combination of speed and utility."
icon = 'icons/obj/vehicles.dmi'
icon_state = "pussywagon"
anchored = 0
density = 1
var/obj/item/weapon/storage/bag/trash/mybag = null
var/callme = "pimpin' ride" //how do people refer to it?
var/move_delay = 0
var/floorbuffer = 0
var/keytype = /obj/item/key/janitor
/obj/structure/stool/bed/chair/janicart/New()
handle_rotation()
/obj/structure/stool/bed/chair/janicart/Move(a, b, flag)
..()
if(floorbuffer)
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
if (istype(tile, /turf/simulated/floor))
var/turf/simulated/floor/F = tile
F.dirt = 0
for(var/A in tile)
if(istype(A, /obj/effect))
if(is_cleanable(A))
qdel(A)
/obj/structure/stool/bed/chair/janicart/examine(mob/user)
..()
if(floorbuffer)
to_chat(user, "It has been upgraded with a floor buffer.")
/obj/structure/stool/bed/chair/janicart/attackby(obj/item/I, mob/user, params)
if(istype(I, keytype))
to_chat(user, "Hold [I] in one of your hands while you drive this [callme].")
else if(istype(I, /obj/item/weapon/storage/bag/trash))
if(keytype == /obj/item/key/janitor)
if(!user.drop_item())
return
to_chat(user, "<span class='notice'>You hook the trashbag onto the [callme].</span>")
I.loc = src
mybag = I
else if(istype(I, /obj/item/janiupgrade))
if(keytype == /obj/item/key/janitor)
floorbuffer = 1
qdel(I)
to_chat(user, "<span class='notice'>You upgrade the [callme] with the floor buffer.</span>")
update_icon()
/obj/structure/stool/bed/chair/janicart/update_icon()
overlays.Cut()
if(mybag)
overlays += "cart_garbage"
if(floorbuffer)
overlays += "cart_buffer"
/obj/structure/stool/bed/chair/janicart/attack_hand(mob/user)
if(mybag)
mybag.loc = get_turf(user)
user.put_in_hands(mybag)
mybag = null
update_icon()
else
..()
/obj/structure/stool/bed/chair/janicart/relaymove(mob/user, direction)
if(user.stat || user.stunned || user.weakened || user.paralysis)
unbuckle_mob()
if(istype(user.l_hand, keytype) || istype(user.r_hand, keytype))
if(!Process_Spacemove(direction) || !has_gravity(src.loc) || move_delay || !isturf(loc))
return
step(src, direction)
update_mob()
handle_rotation()
if(istype(src.loc, /turf/simulated))
var/turf/simulated/T = src.loc
if(T.wet == TURF_WET_LUBE) //Lube! Fall off!
playsound(src, 'sound/misc/slip.ogg', 50, 1, -3)
buckled_mob.Stun(7)
buckled_mob.Weaken(7)
unbuckle_mob()
step(src, dir)
move_delay = 1
spawn(2)
move_delay = 0
else
to_chat(user, "<span class='notice'>You'll need the keys in one of your hands to drive this [callme].</span>")
/obj/structure/stool/bed/chair/janicart/Bump(atom/A)
if(buckled_mob && istype(A, /obj/machinery/door))
A.Bumped(buckled_mob)
/obj/structure/stool/bed/chair/janicart/user_buckle_mob(mob/living/M, mob/user)
if(user.incapacitated()) //user can't move the mob on the janicart's turf if incapacitated
return
for(var/atom/movable/A in get_turf(src)) //we check for obstacles on the turf.
if(A.density)
if(A != src && A != M)
return
M.loc = loc //we move the mob on the janicart's turf before checking if we can buckle.
..()
update_mob()
/obj/structure/stool/bed/chair/janicart/unbuckle_mob()
if(buckled_mob)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
..()
/obj/structure/stool/bed/chair/janicart/handle_rotation()
if((dir == SOUTH) || (dir == WEST) || (dir == EAST))
layer = FLY_LAYER
else
layer = OBJ_LAYER
if(buckled_mob)
if(buckled_mob.loc != loc)
buckled_mob.buckled = null //Temporary, so Move() succeeds.
buckled_mob.buckled = src //Restoring
update_mob()
/obj/structure/stool/bed/chair/janicart/proc/update_mob()
if(buckled_mob)
buckled_mob.dir = dir
switch(dir)
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 7
if(WEST)
buckled_mob.pixel_x = 12
buckled_mob.pixel_y = 7
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -12
buckled_mob.pixel_y = 7
/obj/structure/stool/bed/chair/janicart/bullet_act(obj/item/projectile/Proj)
if(buckled_mob)
buckled_mob.bullet_act(Proj)
/obj/item/key
name = "key"
desc = "A small grey key."
icon = 'icons/obj/vehicles.dmi'
icon_state = "key"
w_class = 1
/obj/item/key/janitor
desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"."
icon_state = "keyjanitor"
/obj/item/key/security
desc = "A keyring with a small steel key, and a rubber stun baton accessory."
icon_state = "keysec"
/obj/item/key/ambulance
name = "ambulance key"
desc = "A keyring with a small steel key, and tag with a red cross on it."
icon_state = "keydoc"
/obj/item/key/snowmobile
name = "snowmobile key"
desc = "A keyring with a small steel key, and tag with a red cross on it; clearly it's not implying you're going to the hospital for this..."
icon_state = "keydoc" //get a better icon, sometime.
/obj/item/janiupgrade
name = "floor buffer upgrade"
desc = "An upgrade for mobile janicarts."
icon = 'icons/obj/vehicles.dmi'
icon_state = "upgrade"
/obj/structure/stool/bed/chair/janicart/secway
name = "secway"
desc = "A brave security cyborg gave its life to help you look like a complete tool."
icon = 'icons/obj/vehicles.dmi'
icon_state = "secway"
callme = "secway"
keytype = /obj/item/key/security
/obj/structure/stool/bed/chair/janicart/secway/update_mob()
if(buckled_mob)
buckled_mob.dir = dir
buckled_mob.pixel_y = 4
/obj/structure/stool/bed/chair/janicart/ambulance
name = "ambulance"
desc = "For getting to patients in a hurry--or running them over."
icon = 'icons/obj/vehicles.dmi'
icon_state = "docwagon"
callme = "ambulance"
keytype = /obj/item/key/ambulance
/obj/structure/stool/bed/chair/janicart/secway/snowmobile
name = "red snowmobile"
desc = "Wheeeeeeeeeeee."
icon = 'icons/obj/vehicles.dmi'
icon_state = "snowmobile"
callme = "snowmobile"
/obj/structure/stool/bed/chair/janicart/secway/snowmobile/blue
name = "blue snowmobile"
icon_state = "bluesnowmobile"
////////////////////////////////////////////////////////////////////////////////////////////////
//TG style Janicart
/obj/structure/janitorialcart

View File

@@ -0,0 +1,55 @@
/obj/vehicle/ambulance
name = "ambulance"
desc = "what the paramedic uses to run over people to take to medbay."
icon_state = "docwagon2"
keytype = /obj/item/key/ambulance
/obj/item/key/ambulance
name = "ambulance key"
desc = "A keyring with a small steel key, and tag with a red cross on it."
icon_state = "keydoc"
/obj/vehicle/ambulance/handle_vehicle_offsets()
..()
if(buckled_mob)
switch(buckled_mob.dir)
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 7
if(WEST)
buckled_mob.pixel_x = 13
buckled_mob.pixel_y = 7
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -13
buckled_mob.pixel_y = 7
/obj/vehicle/ambulance/attackby(obj/item/I, mob/user, params)
//add ambulance bed hookup here
..()
/obj/vehicle/ambulance/RunOver(var/mob/living/carbon/human/H)
var/mob/living/carbon/human/D = buckled_mob
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts))
visible_message("<span class='warning'> \The [src] ran over [H]!</span>")
msg_admin_attack("[key_name_admin(D)] ran over [key_name_admin(H)]")
/obj/structure/stool/bed/amb_trolley
name = "ambulance train trolley"
icon = 'icons/vehicles/CargoTrain.dmi'
icon_state = "ambulance"
anchored = 0
/obj/structure/stool/bed/amb_trolley/MouseDrop(obj/over_object as obj)
..()

View File

@@ -0,0 +1,80 @@
/obj/vehicle/atv
name = "all-terrain vehicle"
desc = "An all-terrain vehicle built for traversing rough terrain with ease. One of the few old-earth technologies that are still relevant on most planet-bound outposts."
icon = 'icons/vehicles/4wheeler.dmi'
icon_state = "fourwheel"
keytype = /obj/item/key
generic_pixel_x = 0
generic_pixel_y = 4
vehicle_move_delay = 1
var/static/image/atvcover = null
/obj/vehicle/atv/New()
..()
if(!atvcover)
atvcover = image("icons/vehicles/4wheeler.dmi", "4wheeler_north")
atvcover.layer = MOB_LAYER + 0.1
obj/vehicle/atv/post_buckle_mob(mob/living/M)
if(buckled_mob)
overlays += atvcover
else
overlays -= atvcover
/obj/vehicle/atv/handle_vehicle_layer()
if(dir == SOUTH)
layer = MOB_LAYER+0.1
else
layer = OBJ_LAYER
//TURRETS!
/obj/vehicle/atv/turret
var/obj/machinery/gun_turret/vehicle_turret/turret = null
/obj/machinery/gun_turret/vehicle_turret
name = "mounted turret"
scan_range = 7
density = 0
/obj/vehicle/atv/turret/New()
..()
turret = new(loc)
//turret.base = src
/obj/vehicle/atv/turret/handle_vehicle_layer()
if(dir == SOUTH)
layer = MOB_LAYER+0.1
else
layer = OBJ_LAYER
if(turret)
if(dir == NORTH)
turret.layer = MOB_LAYER+0.1
else
turret.layer = OBJ_LAYER
/obj/vehicle/atv/turret/handle_vehicle_offsets()
..()
if(turret)
turret.loc = loc
switch(dir)
if(NORTH)
turret.pixel_x = 0
turret.pixel_y = 4
if(EAST)
turret.pixel_x = -12
turret.pixel_y = 4
if(SOUTH)
turret.pixel_x = 0
turret.pixel_y = 4
if(WEST)
turret.pixel_x = 12
turret.pixel_y = 4

View File

@@ -0,0 +1,91 @@
//PIMP-CART
/obj/vehicle/janicart
name = "janicart (pimpin' ride)"
desc = "A brave janitor cyborg gave its life to produce such an amazing combination of speed and utility."
icon_state = "pussywagon"
keytype = /obj/item/key/janitor
var/obj/item/weapon/storage/bag/trash/mybag = null
var/floorbuffer = 0
/obj/vehicle/janicart/handle_vehicle_offsets()
..()
if(buckled_mob)
switch(buckled_mob.dir)
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -12
buckled_mob.pixel_y = 7
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 7
if(WEST)
buckled_mob.pixel_x = 12
buckled_mob.pixel_y = 7
/obj/item/key/janitor
desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"."
icon_state = "keyjanitor"
/obj/item/janiupgrade
name = "floor buffer upgrade"
desc = "An upgrade for mobile janicarts."
icon = 'icons/obj/vehicles.dmi'
icon_state = "upgrade"
/obj/vehicle/janicart/Move(atom/OldLoc, Dir)
..()
if(floorbuffer)
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
/obj/vehicle/janicart/examine(mob/user)
..()
if(floorbuffer)
user << "It has been upgraded with a floor buffer."
/obj/vehicle/janicart/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/storage/bag/trash))
if(keytype == /obj/item/key/janitor)
if(!user.drop_item())
return
user << "<span class='notice'>You hook the trashbag onto \the [name].</span>"
I.loc = src
mybag = I
else if(istype(I, /obj/item/janiupgrade))
if(keytype == /obj/item/key/janitor)
floorbuffer = 1
qdel(I)
user << "<span class='notice'>You upgrade \the [name] with the floor buffer.</span>"
update_icon()
..()
/obj/vehicle/janicart/update_icon()
overlays.Cut()
if(mybag)
overlays += "cart_garbage"
if(floorbuffer)
overlays += "cart_buffer"
/obj/vehicle/janicart/attack_hand(mob/user)
if(..())
return 1
else if(mybag)
mybag.loc = get_turf(user)
user.put_in_hands(mybag)
mybag = null
update_icon()

View File

@@ -0,0 +1,30 @@
/obj/vehicle/motorcycle
name = "motorcycle"
desc = "A fast and highly maneuverable vehicle."
icon = 'icons/vehicles/motorcycle.dmi'
icon_state = "motorcycle_4dir"
generic_pixel_x = 0
generic_pixel_y = 4
vehicle_move_delay = 1
var/static/image/bikecover = null
/obj/vehicle/motorcycle/New()
..()
if(!bikecover)
bikecover = image("icons/vehicles/motorcycle.dmi", "motorcycle_overlay_4d")
bikecover.layer = MOB_LAYER + 0.1
obj/vehicle/motorcycle/post_buckle_mob(mob/living/M)
if(buckled_mob)
overlays += bikecover
else
overlays -= bikecover
/obj/vehicle/motorcycle/handle_vehicle_layer()
if(dir == SOUTH)
layer = MOB_LAYER+0.1
else
layer = OBJ_LAYER

View File

@@ -0,0 +1,12 @@
/obj/vehicle/secway
name = "secway"
desc = "A brave security cyborg gave its life to help you look like a complete tool."
icon_state = "secway"
keytype = /obj/item/key/security
generic_pixel_x = 0
generic_pixel_y = 4
/obj/item/key/security
desc = "A keyring with a small steel key, and a rubber stun baton accessory."
icon_state = "keysec"

View File

@@ -0,0 +1,17 @@
/obj/vehicle/snowmobile
name = "red snowmobile"
desc = "Wheeeeeeeeeeee."
icon = 'icons/obj/vehicles.dmi'
icon_state = "snowmobile"
keytype = /obj/item/key/snowmobile
generic_pixel_x = 0
generic_pixel_y = 4
/obj/vehicle/snowmobile/blue
name = "blue snowmobile"
icon_state = "bluesnowmobile"
/obj/item/key/snowmobile
name = "snowmobile key"
desc = "A keyring with a small steel key, and tag with a red cross on it; clearly it's not implying you're going to the hospital for this..."
icon_state = "keydoc" //get a better icon, sometime.

View File

@@ -0,0 +1,64 @@
/obj/vehicle/space/speedbike
name = "Speedbike"
icon = 'icons/obj/bike.dmi'
icon_state = "speedbike_blue"
layer = OBJ_LAYER
keytype = null
vehicle_move_delay = 0
var/overlay_state = "cover_blue"
var/image/overlay = null
var/datum/effect/system/ion_trail_follow/space_trail/ion_trail
/obj/vehicle/space/speedbike/New()
..()
overlay = image("icons/obj/bike.dmi", overlay_state)
overlay.layer = MOB_LAYER + 0.1
overlays += overlay
ion_trail = new /datum/effect/system/ion_trail_follow/space_trail()
ion_trail.set_up(src)
ion_trail.start()
/obj/effect/overlay/temp/speedbike_trail
name = "speedbike trails"
icon_state = "ion_fade"
duration = 20
randomdir = 0
/obj/effect/overlay/temp/speedbike_trail/New(loc,move_dir)
..()
dir = move_dir
/obj/vehicle/space/speedbike/Move(newloc,move_dir)
if(buckled_mob)
new /obj/effect/overlay/temp/speedbike_trail(loc)
. = ..()
/obj/vehicle/space/speedbike/handle_vehicle_layer()
switch(dir)
if(NORTH,SOUTH)
pixel_x = -16
pixel_y = -16
if(EAST,WEST)
pixel_x = -18
pixel_y = 0
/obj/vehicle/space/speedbike/handle_vehicle_offsets()
if(buckled_mob)
buckled_mob.dir = dir
switch(dir)
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = -8
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -10
buckled_mob.pixel_y = 5
if(WEST)
buckled_mob.pixel_x = 10
buckled_mob.pixel_y = 5
/obj/vehicle/space/speedbike/red
icon_state = "speedbike_red"
overlay_state = "cover_red"

View File

@@ -0,0 +1,47 @@
/obj/vehicle/car
name = "sports car"
desc = "A very luxurious vehicle."
icon = 'icons/vehicles/sportscar.dmi'
icon_state = "sportscar"
generic_pixel_x = 0
generic_pixel_y = 4
vehicle_move_delay = 1
var/static/image/carcover = null
/obj/vehicle/car/New()
..()
if(!carcover)
carcover = image("icons/vehicles/sportscar.dmi", "sportscar_cover")
carcover.layer = MOB_LAYER + 0.1
/obj/vehicle/car/post_buckle_mob(mob/living/M)
if(buckled_mob)
overlays += carcover
else
overlays -= carcover
/obj/vehicle/car/handle_vehicle_offsets()
..()
if(buckled_mob)
switch(buckled_mob.dir)
if(NORTH)
buckled_mob.pixel_x = 2
buckled_mob.pixel_y = 20
if(EAST)
buckled_mob.pixel_x = 20
buckled_mob.pixel_y = 23
if(SOUTH)
buckled_mob.pixel_x = 20
buckled_mob.pixel_y = 27
if(WEST)
buckled_mob.pixel_x = 34
buckled_mob.pixel_y = 10
/obj/vehicle/car/handle_vehicle_layer()
if(dir == SOUTH)
layer = MOB_LAYER+0.1
else
layer = OBJ_LAYER

View File

@@ -1,240 +0,0 @@
/obj/vehicle/train
name = "train"
dir = 4
move_delay = 2
health = 100
maxhealth = 100
fire_dam_coeff = 0.7
brute_dam_coeff = 0.5
var/passenger_allowed = 1
var/active_engines = 0
var/train_length = 0
var/obj/vehicle/train/lead
var/obj/vehicle/train/tow
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/initialize()
for(var/obj/vehicle/train/T in orange(1, src))
latch(T)
/obj/vehicle/train/Move()
var/old_loc = get_turf(src)
if(..())
if(tow)
tow.Move(old_loc)
return 1
else
if(lead)
unattach()
return 0
/obj/vehicle/train/can_move()
if(!is_train_head())
return 1 //towed objects do not need power to Move()
if(!..())
return 0
return 1
/obj/vehicle/train/Bump(atom/Obstacle)
if(!istype(Obstacle, /atom/movable))
return
var/atom/movable/A = Obstacle
if(!A.anchored)
var/turf/T = get_step(A, dir)
if(isturf(T))
A.Move(T) //bump things away when hit
if(ismob(load) && istype(Obstacle, /obj/machinery/door))
Obstacle.Bumped(load)
if(emagged)
if(istype(A, /mob/living))
var/mob/living/M = A
visible_message("\red [src] knocks over [M]!")
M.apply_effects(5, 5) //knock people down if you hit them
M.apply_damages(22 / move_delay) // and do damage according to how fast the train is going
if(istype(load, /mob/living/carbon/human))
var/mob/living/D = load
to_chat(D, "\red You hit [M]!")
msg_admin_attack("[key_name_admin(D)] hit [key_name_admin(M)] with [src].")
//-------------------------------------------
// Vehicle procs
//-------------------------------------------
/obj/vehicle/train/explode()
if (tow)
tow.unattach()
unattach()
..()
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/relaymove(mob/user, direction)
var/turf/T = get_step_to(src, get_step(src, direction))
if(!T)
to_chat(user, "You can't find a clear area to step onto.")
return 0
if(user != load)
if(user in src) //for handling players stuck in src - this shouldn't happen - but just in case it does
user.forceMove(T)
return 1
return 0
unload(user, direction)
to_chat(user, "\blue You climb down from [src].")
return 1
/obj/vehicle/train/MouseDrop_T(var/atom/movable/C, mob/user as mob)
if(user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !user.canmove))
return
if(istype(C,/obj/vehicle/train))
latch(C, user)
else
if(!load(C))
to_chat(user, "\red You were unable to load [C] on [src].")
/obj/vehicle/train/attack_hand(mob/user as mob)
if(user.stat || user.restrained() || !Adjacent(user))
return 0
if(user != load && (user in src))
user.forceMove(loc) //for handling players stuck in src
else if(load)
unload(user) //unload if loaded
else if(!load && !user.buckled)
load(user) //else try climbing on board
else
return 0
/obj/vehicle/train/verb/unlatch_v()
set name = "Unlatch"
set desc = "Unhitches this train from the one in front of it."
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
return
unattach(usr)
//-------------------------------------------
// Latching/unlatching procs
//-------------------------------------------
//attempts to attach src as a follower of the train T
/obj/vehicle/train/proc/attach_to(obj/vehicle/train/T, mob/user)
if (get_dist(src, T) > 1)
to_chat(user, "\red [src] is too far away from [T] to hitch them together.")
return
if (lead)
to_chat(user, "\red [src] is already hitched to something.")
return
if (T.tow)
to_chat(user, "\red [T] is already towing something.")
return
//check for cycles.
var/obj/vehicle/train/next_car = T
while (next_car)
if (next_car == src)
to_chat(user, "\red That seems very silly.")
return
next_car = next_car.lead
//latch with src as the follower
lead = T
T.tow = src
dir = lead.dir
if(user)
to_chat(user, "\blue You hitch [src] to [T].")
update_stats()
//detaches the train from whatever is towing it
/obj/vehicle/train/proc/unattach(mob/user)
if (!lead)
to_chat(user, "\red [src] is not hitched to anything.")
return
lead.tow = null
lead.update_stats()
lead = null
update_stats()
/obj/vehicle/train/proc/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T))
return 0
var/T_dir = get_dir(src, T) //figure out where T is wrt src
if(dir == T_dir) //if car is ahead
src.attach_to(T, user)
else if(reverse_direction(dir) == T_dir) //else if car is behind
T.attach_to(src, user)
//returns 1 if this is the lead car of the train
/obj/vehicle/train/proc/is_train_head()
if (lead)
return 0
return 1
//-------------------------------------------------------
// Stat update procs
//
// Used for updating the stats for how long the train is.
// These are useful for calculating speed based on the
// size of the train, to limit super long trains.
//-------------------------------------------------------
/obj/vehicle/train/update_stats()
//first, seek to the end of the train
var/obj/vehicle/train/T = src
while(T.tow)
//check for cyclic train.
if (T.tow == src)
lead.tow = null
lead.update_stats()
lead = null
update_stats()
return
T = T.tow
//now walk back to the front.
var/active_engines = 0
var/train_length = 0
while(T)
train_length++
if (powered && on)
active_engines++
T.update_car(train_length, active_engines)
T = T.lead
/obj/vehicle/train/proc/update_car(var/train_length, var/active_engines)
return

View File

@@ -1,282 +0,0 @@
/obj/vehicle/train/ambulance/engine
name = "ambulance train tug"
desc = "A ridable electric car designed for pulling ambulance trolleys."
icon = 'icons/obj/vehicles.dmi'
icon_state = "docwagon2" //mulebot icons until I get some proper icons
on = 0
powered = 1
locked = 0
layer = MOB_LAYER + 0.1
load_item_visible = 1
load_offset_x = 0
load_offset_y = 7
var/car_limit = 3 //how many cars an engine can pull before performance degrades
active_engines = 1
var/obj/item/key/ambulance/key
/obj/vehicle/train/ambulance/trolley
name = "ambulance train trolley"
icon = 'icons/vehicles/CargoTrain.dmi'
icon_state = "ambulance"
anchored = 0
passenger_allowed = 1
locked = 0
load_item_visible = 1
load_offset_x = 1
load_offset_y = 7
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/ambulance/engine/New()
..()
cell = new /obj/item/weapon/stock_parts/cell/high
key = new()
/obj/vehicle/train/ambulance/engine/Move()
. = ..()
handle_rotation()
update_mob()
/obj/vehicle/train/ambulance/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(open && istype(W, /obj/item/weapon/wirecutters))
passenger_allowed = !passenger_allowed
user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>")
else
..()
/obj/vehicle/train/ambulance/engine/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/key/ambulance))
if(!key)
user.drop_item()
key = W
W.loc = src
verbs += /obj/vehicle/train/ambulance/engine/verb/remove_key
return
..()
/obj/vehicle/train/ambulance/update_icon()
if(open)
//icon_state = "mulebot-hatch"
icon_state = initial(icon_state)
else
icon_state = initial(icon_state)
/obj/vehicle/train/ambulance/engine/Emag(mob/user as mob)
..()
flick("mulebot-emagged", src)
/obj/vehicle/train/ambulance/trolley/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H)
return
/obj/vehicle/train/ambulance/engine/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/ambulance/engine/remove_cell(var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/ambulance/engine/Bump(atom/Obstacle)
var/obj/machinery/door/D = Obstacle
var/mob/living/carbon/human/H = load
if(istype(D) && istype(H))
D.Bumped(H) //a little hacky, but hey, it works, and repects access rights
..()
/obj/vehicle/train/ambulance/trolley/Bump(atom/Obstacle)
if(!lead)
return //so people can't knock others over by pushing a trolley around
..()
/obj/vehicle/train/ambulance/engine/handle_rotation()
if(dir == SOUTH)
layer = FLY_LAYER
else
layer = OBJ_LAYER
/obj/vehicle/train/ambulance/engine/proc/update_mob()
if(load)
load.dir = dir
switch(dir)
if(SOUTH)
load.pixel_x = 0
load.pixel_y = 7
if(WEST)
load.pixel_x = 13
load.pixel_y = 7
if(NORTH)
load.pixel_x = 0
load.pixel_y = 4
if(EAST)
load.pixel_x = -13
load.pixel_y = 7
//-------------------------------------------
// Train procs
//-------------------------------------------
/obj/vehicle/train/ambulance/engine/turn_on()
if(!key)
return
else
..()
update_stats()
/obj/vehicle/train/ambulance/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts))
/obj/vehicle/train/ambulance/trolley/RunOver(var/mob/living/carbon/human/H)
..()
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
/obj/vehicle/train/ambulance/engine/RunOver(var/mob/living/carbon/human/H)
..()
if(is_train_head() && istype(load, /mob/living/carbon/human))
var/mob/living/carbon/human/D = load
to_chat(D, "\red \b You ran over [H]!")
visible_message("<B>\red \The [src] ran over [H]!</B>")
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)], driven by [key_name(D)]</font>")
msg_admin_attack("[key_name_admin(D)] ran over [key_name_admin(H)]")
else
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)]</font>")
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/ambulance/engine/relaymove(mob/user, direction)
if(user != load)
return 0
if(is_train_head())
if(direction == reverse_direction(dir) && tow) //can reverse with no tow
return 0
if(Move(get_step(src, direction)))
return 1
return 0
else
return ..()
/obj/vehicle/train/ambulance/engine/examine(mob/user)
if(..(user, 1))
to_chat(user, "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition.")
/obj/vehicle/train/ambulance/engine/verb/check_power()
set name = "Check power level"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!cell)
to_chat(usr, "There is no power cell installed in [src].")
return
to_chat(usr, "The power meter reads [round(cell.percent(), 0.01)]%")
/obj/vehicle/train/ambulance/engine/verb/start_engine()
set name = "Start engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(on)
to_chat(usr, "The engine is already running.")
return
turn_on()
if (on)
to_chat(usr, "You start [src]'s engine.")
else
if(cell.charge < charge_use)
to_chat(usr, "[src] is out of power.")
else
to_chat(usr, "[src]'s engine won't start.")
/obj/vehicle/train/ambulance/engine/verb/stop_engine()
set name = "Stop engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!on)
to_chat(usr, "The engine is already stopped.")
return
turn_off()
if (!on)
to_chat(usr, "You stop [src]'s engine.")
/obj/vehicle/train/ambulance/engine/verb/remove_key()
set name = "Remove key"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!key || (load && load != usr))
return
if(on)
turn_off()
key.loc = usr.loc
if(!usr.get_active_hand())
usr.put_in_hands(key)
key = null
verbs -= /obj/vehicle/train/ambulance/engine/verb/remove_key
//-------------------------------------------
// Loading/unloading procs
//-------------------------------------------
/obj/vehicle/train/ambulance/trolley/load(var/atom/movable/C)
if(ismob(C) && !passenger_allowed)
return 0
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !ismob(C))
return 0
return ..()
/obj/vehicle/train/ambulance/engine/load(var/atom/movable/C)
if(!ismob(C))
return 0
return ..()
//-------------------------------------------------------
// Stat update procs
//
// Update the trains stats for speed calculations.
// The longer the train, the slower it will go. car_limit
// sets the max number of cars one engine can pull at
// full speed. Adding more cars beyond this will slow the
// train proportionate to the length of the train. Adding
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/ambulance/engine/proc/update_move_delay()
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += 1+config.run_speed //base reference speed
move_delay *= 1.05

View File

@@ -1,32 +0,0 @@
/obj/vehicle/train/cargo/engine/fourwheeler //make this hold passengers
name = "fourwheeler"
desc = "A fast and highly maneuverable vehicle."
icon = 'icons/vehicles/4wheeler.dmi'
icon_state = "fourwheel"
emagged = 0
mob_offset_y = 6
load_offset_x = 0
health = 200
charge_use = 0
/obj/vehicle/train/cargo/engine/fourwheeler/proc/update_dir_fourwheel_overlays()
overlays = null
if(src.dir == NORTH||SOUTH)
if(src.dir == NORTH)
var/image/I = new(icon = 'icons/vehicles/4wheeler.dmi', icon_state = "4wheeler_north", layer = src.layer + 0.2) //over mobs
overlays += I
else if(src.dir == SOUTH)
var/image/I = new(icon = 'icons/vehicles/4wheeler.dmi', icon_state = "4wheeler_south", layer = src.layer + 0.2) //over mobs
overlays += I
/obj/vehicle/train/cargo/engine/fourwheeler/New()
..()
update_dir_fourwheel_overlays()
/obj/vehicle/train/cargo/engine/fourwheeler/Move()
..()
update_dir_fourwheel_overlays()
/obj/vehicle/train/cargo/engine/fourwheeler/handle_rotation()
update_dir_fourwheel_overlays()
..()

View File

@@ -1,35 +0,0 @@
/obj/vehicle/train/cargo/engine/motorcycle
name = "motorcycle"
desc = "A fast and highly maneuverable vehicle."
icon = 'icons/vehicles/motorcycle.dmi'
icon_state = "motorcycle_4dir"
emagged = 0
mob_offset_y = 6
load_offset_x = 0
health = 100
charge_use = 0
/obj/vehicle/train/cargo/engine/motorcycle/proc/update_dir_motorcycle_overlays()
overlays = null
if(src.dir == NORTH||SOUTH)
if(src.dir == NORTH)
var/image/I = new(icon = 'icons/vehicles/motorcycle.dmi', icon_state = "motorcycle_overlay_n", layer = src.layer + 0.2) //over mobs
overlays += I
else if(src.dir == SOUTH)
var/image/I = new(icon = 'icons/vehicles/motorcycle.dmi', icon_state = "motorcycle_overlay_s", layer = src.layer + 0.2) //over mobs
overlays += I
else
var/image/I = new(icon = 'icons/vehicles/motorcycle.dmi', icon_state = "motorcycle_overlay_side", layer = src.layer + 0.2) //over mobs
overlays += I
/obj/vehicle/train/cargo/engine/motorcycle/New()
..()
update_dir_motorcycle_overlays()
/obj/vehicle/train/cargo/engine/motorcycle/Move()
..()
update_dir_motorcycle_overlays()
/obj/vehicle/train/cargo/engine/motorcycle/handle_rotation()
update_dir_motorcycle_overlays() //this goes first, because vehicle/handle_rotation() just returns
..()

View File

@@ -1,52 +0,0 @@
//rename to sportscar if you need
//mostly, my changes just update the C.pixel_ y and x on every iteration of the overlay update proc, since default vehicle code //only does that upon entering. Watch the weird formatting pastebin introduces.
/obj/vehicle/train/cargo/engine/sportscar
name = "sports car"
desc = "A very luxurious vehicle."
icon = 'icons/vehicles/sportscar.dmi'
icon_state = "sportscar"
emagged = 0
health = 100
charge_use = 0
bound_width = 64
bound_height = 64
movable = 0
/obj/vehicle/train/cargo/engine/sportscar/proc/update_dir_sportscar_overlays()
var/atom/movable/C = src.load
src.overlays = null
if(src.dir == NORTH||SOUTH||WEST)
if(src.dir == NORTH)
var/image/I = new(icon = 'icons/vehicles/sportscar.dmi', icon_state = "sportscar_north", layer = src.layer + 0.2) //over mobs
src.overlays += I
src.mob_offset_x = 2
src.mob_offset_y = 20
else if(src.dir == SOUTH)
var/image/I = new(icon = 'icons/vehicles/sportscar.dmi', icon_state = "sportscar_south", layer = src.layer + 0.2) //over mobs
overlays += I
src.mob_offset_x = 20
src.mob_offset_y = 27
else if(src.dir == WEST)
src.mob_offset_x = 34
src.mob_offset_y = 10
var/image/I = new(icon = 'icons/vehicles/sportscar.dmi', icon_state = "sportscar_west", layer = src.layer + 0.2) //over mobs
src.overlays += I
else if(src.dir == EAST)
var/image/I = new(icon = 'icons/vehicles/sportscar.dmi', icon_state = "sportscar_east", layer = src.layer + 0.2) //over mobs
src.mob_offset_x = 20
src.mob_offset_y = 23
src.overlays += I
if(ismob(C))
C.pixel_y = src.mob_offset_y
C.pixel_x = src.mob_offset_x
/obj/vehicle/train/cargo/engine/sportscar/New()
..()
update_dir_sportscar_overlays()
/obj/vehicle/train/cargo/engine/sportscar/Move()
..()
update_dir_sportscar_overlays()

View File

@@ -1,282 +0,0 @@
/obj/vehicle/train/cargo/engine
name = "cargo train tug"
desc = "A ridable electric car designed for pulling cargo trolleys."
icon = 'icons/obj/vehicles.dmi'
icon_state = "cargo_engine"
on = 0
powered = 1
locked = 0
load_item_visible = 1
load_offset_x = 0
mob_offset_y = 7
var/car_limit = 3 //how many cars an engine can pull before performance degrades
active_engines = 1
var/obj/item/weapon/key/cargo_train/key
/obj/item/weapon/key/cargo_train
name = "key"
desc = "A keyring with a small steel key, and a yellow fob reading \"Choo Choo!\"."
icon = 'icons/obj/vehicles.dmi'
icon_state = "train_keys"
w_class = 1
/obj/vehicle/train/cargo/trolley
name = "cargo train trolley"
icon = 'icons/obj/vehicles.dmi'
icon_state = "cargo_trailer"
anchored = 0
passenger_allowed = 0
locked = 0
load_item_visible = 1
load_offset_x = 0
load_offset_y = 4
mob_offset_y = 8
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/New()
..()
cell = new /obj/item/weapon/stock_parts/cell/high
key = new()
var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
overlays += I
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/cargo/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(open && istype(W, /obj/item/weapon/wirecutters))
passenger_allowed = !passenger_allowed
user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>")
else
..()
/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/key/cargo_train))
if(!key)
user.drop_item()
W.forceMove(src)
key = W
verbs += /obj/vehicle/train/cargo/engine/verb/remove_key
return
..()
/obj/vehicle/train/cargo/update_icon()
if(open)
icon_state = initial(icon_state) + "_open"
else
icon_state = initial(icon_state)
/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H)
return
/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/cargo/engine/remove_cell(var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/cargo/engine/Bump(atom/Obstacle)
var/obj/machinery/door/D = Obstacle
var/mob/living/carbon/human/H = load
if(istype(D) && istype(H))
D.Bumped(H) //a little hacky, but hey, it works, and respects access rights
..()
/obj/vehicle/train/cargo/trolley/Bump(atom/Obstacle)
if(!lead)
return //so people can't knock others over by pushing a trolley around
..()
//-------------------------------------------
// Train procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/turn_on()
if(!key)
return
else
..()
update_stats()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(on)
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
/obj/vehicle/train/cargo/engine/turn_off()
..()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(!on)
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
/obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts))
/obj/vehicle/train/cargo/trolley/RunOver(var/mob/living/carbon/human/H)
..()
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)]</font>")
/obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H)
..()
if(is_train_head() && istype(load, /mob/living/carbon/human))
var/mob/living/carbon/human/D = load
to_chat(D, "\red \b You ran over [H]!")
visible_message("<B>\red \The [src] ran over [H]!</B>")
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)], driven by [key_name(D)]</font>")
msg_admin_attack("[key_name_admin(D)] ran over [key_name_admin(H)]")
else
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)]</font>")
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/relaymove(mob/user, direction)
if(user != load)
return 0
if(is_train_head())
if(direction == reverse_direction(dir) && tow)
return 0
if(Move(get_step(src, direction)))
return 1
return 0
else
return ..()
/obj/vehicle/train/cargo/engine/examine(mob/user)
if(!..(user, 1))
return
to_chat(user, "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition.")
to_chat(user, "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%")
/obj/vehicle/train/cargo/engine/verb/start_engine()
set name = "Start engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(on)
to_chat(usr, "The engine is already running.")
return
turn_on()
if (on)
to_chat(usr, "You start [src]'s engine.")
else
if(cell.charge < charge_use)
to_chat(usr, "[src] is out of power.")
else
to_chat(usr, "[src]'s engine won't start.")
/obj/vehicle/train/cargo/engine/verb/stop_engine()
set name = "Stop engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!on)
to_chat(usr, "The engine is already stopped.")
return
turn_off()
if (!on)
to_chat(usr, "You stop [src]'s engine.")
/obj/vehicle/train/cargo/engine/verb/remove_key()
set name = "Remove key"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!key || (load && load != usr))
return
if(on)
turn_off()
key.loc = usr.loc
if(!usr.get_active_hand())
usr.put_in_hands(key)
key = null
verbs -= /obj/vehicle/train/cargo/engine/verb/remove_key
//-------------------------------------------
// Loading/unloading procs
//-------------------------------------------
/obj/vehicle/train/cargo/trolley/load(var/atom/movable/C)
if(ismob(C) && !passenger_allowed)
return 0
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human))
return 0
..()
if(load)
return 1
/obj/vehicle/train/cargo/engine/load(var/atom/movable/C)
if(!istype(C, /mob/living/carbon/human))
return 0
return ..()
//-------------------------------------------------------
// Stat update procs
//
// Update the trains stats for speed calculations.
// The longer the train, the slower it will go. car_limit
// sets the max number of cars one engine can pull at
// full speed. Adding more cars beyond this will slow the
// train proportionate to the length of the train. Adding
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/cargo/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
//Update move delay
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/cargo/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
if(!lead && !tow)
anchored = 0
else
anchored = 1

View File

@@ -1,375 +1,142 @@
/obj/vehicle
name = "vehicle"
desc = "A basic vehicle, vroom"
icon = 'icons/obj/vehicles.dmi'
layer = MOB_LAYER + 0.1 //so it sits above objects including mobs
icon_state = "fuckyou"
density = 1
anchored = 1
animate_movement=1
light_range = 3
anchored = 0
can_buckle = 1
buckle_lying = 0
var/keytype = null //item typepath, if non-null an item of this type is needed in your hands to drive this vehicle
var/next_vehicle_move = 0 //used for move delays
var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower
var/auto_door_open = TRUE
var/attack_log = null
var/on = 0
var/health = 0 //do not forget to set health for your vehicle!
var/maxhealth = 0
var/fire_dam_coeff = 1.0
var/brute_dam_coeff = 1.0
var/open = 0 //Maint panel
var/locked = 1
var/stat = 0
var/emagged = 0
var/powered = 0 //set if vehicle is powered and should use fuel when moving
var/move_delay = 1 //set this to limit the speed of the vehicle
var/movable = 1
var/obj/item/weapon/stock_parts/cell/cell
var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
var/load_offset_x = 0 //pixel_x offset for item overlay
var/load_offset_y = 0 //pixel_y offset for item overlay
var/mob_offset_x = 0 //pixel_x offset for mob overlay
var/mob_offset_y = 0 //pixel_y offset for mob overlay
//Pixels
var/generic_pixel_x = 0 //All dirs show this pixel_x for the driver
var/generic_pixel_y = 0 //All dirs shwo this pixel_y for the driver
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/New()
..()
//spawn the cell you want in each vehicle
handle_vehicle_layer()
/obj/vehicle/Move()
if(can_move())
var/init_anc = anchored
anchored = 0
if(!..())
anchored = init_anc
return 0
anchored = init_anc
if(on && powered)
cell.use(charge_use)
if(load)
load.forceMove(loc)// = loc
load.dir = dir
return 1
//APPEARANCE
/obj/vehicle/proc/handle_vehicle_layer()
if(dir != NORTH)
layer = MOB_LAYER+0.1
else
return 0
/obj/vehicle/proc/can_move()
if(world.time <= l_move_time + move_delay)
return 0
if(!on || !powered)
return 0
if(on && powered && cell.charge < charge_use)
turn_off()
return 0
if(istype(loc, /turf/space))
return 0
return 1
layer = OBJ_LAYER
/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/hand_labeler))
return
if(istype(W, /obj/item/weapon/screwdriver))
if(!locked)
open = !open
update_icon()
to_chat(user, "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>")
else if(istype(W, /obj/item/weapon/crowbar) && cell && open)
remove_cell(user)
//Override this to set your vehicle's various pixel offsets
//if they differ between directions, otherwise use the
//generic variables
/obj/vehicle/proc/handle_vehicle_offsets()
if(buckled_mob)
buckled_mob.dir = dir
buckled_mob.pixel_x = generic_pixel_x
buckled_mob.pixel_y = generic_pixel_y
else if(istype(W, /obj/item/weapon/stock_parts/cell) && !cell && open)
insert_cell(W, user)
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/T = W
if(T.welding)
if(health < maxhealth)
if(open)
health = min(maxhealth, health+10)
user.visible_message("\red [user] repairs [src]!","\blue You repair [src]!")
else
to_chat(user, "<span class='notice'>Unable to repair with the maintenance panel closed.</span>")
else
to_chat(user, "<span class='notice'>[src] does not need a repair.</span>")
else
to_chat(user, "<span class='notice'>Unable to repair while [src] is off.</span>")
else if(hasvar(W,"force") && hasvar(W,"damtype"))
switch(W.damtype)
if("fire")
health -= W.force * fire_dam_coeff
if("brute")
health -= W.force * brute_dam_coeff
..()
healthcheck()
else
..()
/obj/vehicle/emag_act(user as mob)
if(!emagged)
Emag(user)
/obj/vehicle/attack_animal(var/mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0) return
health -= M.melee_damage_upper
src.visible_message("\red <B>[M] has [M.attacktext] [src]!</B>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>")
if(prob(10))
new /obj/effect/decal/cleanable/blood/oil(src.loc)
healthcheck()
/obj/vehicle/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
/obj/vehicle/blob_act()
src.health -= rand(20,40)*fire_dam_coeff
healthcheck()
/obj/vehicle/update_icon()
return
/obj/vehicle/ex_act(severity)
switch(severity)
if(1.0)
explode()
return
if(2.0)
health -= rand(5,10)*fire_dam_coeff
health -= rand(10,20)*brute_dam_coeff
healthcheck()
return
if(3.0)
if (prob(50))
health -= rand(1,5)*fire_dam_coeff
health -= rand(1,5)*brute_dam_coeff
healthcheck()
//KEYS
/obj/vehicle/proc/keycheck(mob/user)
if(keytype)
if(istype(user.l_hand, keytype) || istype(user.r_hand, keytype))
return 1
else
return 1
return 0
/obj/item/key
name = "key"
desc = "A small grey key."
icon = 'icons/obj/vehicles.dmi'
icon_state = "key"
w_class = 1
//BUCKLE HOOKS
/obj/vehicle/unbuckle_mob(force = 0)
if(buckled_mob)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
. = ..()
/obj/vehicle/user_buckle_mob(mob/living/M, mob/user)
if(user.incapacitated())
return
for(var/atom/movable/A in get_turf(src))
if(A.density)
if(A != src && A != M)
return
return
M.loc = get_turf(src)
..()
handle_vehicle_offsets()
/obj/vehicle/emp_act(severity)
var/was_on = on
stat |= EMPED
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc )
pulse2.icon = 'icons/effects/effects.dmi'
pulse2.icon_state = "empdisable"
pulse2.name = "emp sparks"
pulse2.anchored = 1
pulse2.dir = pick(cardinal)
spawn(10)
pulse2.delete()
if(on)
turn_off()
spawn(severity*300)
stat &= ~EMPED
if(was_on)
turn_on()
//MOVEMENT
/obj/vehicle/relaymove(mob/user, direction)
if(user.incapacitated())
unbuckle_mob()
/obj/vehicle/attack_ai(mob/user as mob)
return
if(keycheck(user))
if(!Process_Spacemove(direction) || world.time < next_vehicle_move || !isturf(loc)) return
next_vehicle_move = world.time + vehicle_move_delay
/obj/vehicle/proc/handle_rotation()
return
step(src, direction)
//-------------------------------------------
// Vehicle procs
//-------------------------------------------
/obj/vehicle/proc/turn_on()
if(stat)
return 0
if(powered && cell.charge < charge_use)
return 0
on = 1
set_light(initial(light_range))
update_icon()
return 1
if(buckled_mob)
if(buckled_mob.loc != loc)
buckled_mob.buckled = null //Temporary, so Move() succeeds.
buckled_mob.buckled = src //Restoring
/obj/vehicle/proc/turn_off()
on = 0
set_light(0)
update_icon()
handle_vehicle_layer()
handle_vehicle_offsets()
else
user << "<span class='notice'>You'll need the keys in one of your hands to drive \the [name].</span>"
/obj/vehicle/proc/Emag(mob/user as mob)
emagged = 1
if(locked)
locked = 0
to_chat(user, "<span class='warning'>You bypass [src]'s controls.</span>")
/obj/vehicle/Move(NewLoc,Dir=0,step_x=0,step_y=0)
..()
handle_vehicle_layer()
handle_vehicle_offsets()
/obj/vehicle/proc/explode()
src.visible_message("\red <B>[src] blows apart!</B>", 1)
var/turf/Tsec = get_turf(src)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/cable_coil/cut(Tsec)
/obj/vehicle/attackby(obj/item/I, mob/user, params)
if(keytype && istype(I, keytype))
user << "Hold [I] in one of your hands while you drive \the [name]."
if(cell)
cell.forceMove(Tsec)
cell.update_icon()
cell = null
//stuns people who are thrown off a train that has been blown up
if(istype(load, /mob/living))
var/mob/living/M = load
M.apply_effects(5, 5)
unload()
new /obj/effect/gibspawner/robot(Tsec)
new /obj/effect/decal/cleanable/blood/oil(src.loc)
qdel(src)
/obj/vehicle/proc/healthcheck()
if(health <= 0)
explode()
/obj/vehicle/proc/powercheck()
if(!cell && !powered)
return 0
if(!cell && powered)
turn_off()
return 0
if(cell.charge < charge_use)
turn_off()
return 0
if(cell && powered)
turn_on()
return 1
/obj/vehicle/proc/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H)
if(cell)
return
if(!istype(C))
return
H.unEquip(C)
C.forceMove(src)
cell = C
powercheck()
to_chat(usr, "<span class='notice'>You install [C] in [src].</span>")
/obj/vehicle/proc/remove_cell(var/mob/living/carbon/human/H)
if(!cell)
return
to_chat(usr, "<span class='notice'>You remove [cell] from [src].</span>")
cell.forceMove(get_turf(H))
H.put_in_hands(cell)
cell = null
powercheck()
/obj/vehicle/Bump(atom/movable/M)
. = ..()
if(auto_door_open)
if(istype(M, /obj/machinery/door) && buckled_mob)
M.Bumped(buckled_mob)
/obj/vehicle/proc/RunOver(var/mob/living/carbon/human/H)
return //write specifics for different vehicles
//-------------------------------------------
// Loading/unloading procs
//
// Set specific item restriction checks in
// the vehicle load() definition before
// calling this parent proc.
//-------------------------------------------
/obj/vehicle/proc/load(var/atom/movable/C)
//define allowed items for loading in specific vehicle definitions
if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly.
return 0
if(load || C.anchored)
return 0
/obj/vehicle/Process_Spacemove(direction)
if(has_gravity(src))
return 1
// if a create/closet, close before loading
var/obj/structure/closet/crate = C
if(istype(crate))
crate.close()
if(pulledby)
return 1
C.forceMove(loc)
C.dir = dir
C.anchored = 1
return 0
load = C
/obj/vehicle/space
pressure_resistance = INFINITY
if(load_item_visible)
if(ismob(C) && mob_offset_x != 0 && mob_offset_y != 0) //if the offset is not set, use load offset
C.pixel_x += mob_offset_x
C.pixel_y += mob_offset_y
else
C.pixel_x += load_offset_x
C.pixel_y += load_offset_y
C.layer = layer + 0.1 //so it sits above the vehicle
if(ismob(C))
var/mob/M = C
M.buckled = src
M.update_canmove()
return 1
/obj/vehicle/proc/unload(var/mob/user, var/direction)
if(!load)
return
var/turf/dest = null
//find a turf to unload to
if(direction) //if direction specified, unload in that direction
dest = get_step(src, direction)
else if(user) //if a user has unloaded the vehicle, unload at their feet
dest = get_turf(user)
if(!dest)
dest = get_step_to(src, get_step(src, turn(dir, 90))) //try unloading to the side of the vehicle first if neither of the above are present
//if these all result in the same turf as the vehicle or nullspace, pick a new turf with open space
if(!dest || dest == get_turf(src))
var/list/options = new()
for(var/test_dir in alldirs)
var/new_dir = get_step_to(src, get_step(src, test_dir))
if(new_dir && load.Adjacent(new_dir))
options += new_dir
if(options.len)
dest = pick(options)
else
dest = get_turf(src) //otherwise just dump it on the same turf as the vehicle
if(!isturf(dest)) //if there still is nowhere to unload, cancel out since the vehicle is probably in nullspace
return 0
load.forceMove(dest)
load.dir = get_dir(loc, dest)
load.anchored = initial(load.anchored)
load.pixel_x = initial(load.pixel_x)
load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer)
if(ismob(load))
var/mob/M = load
M.buckled = null
M.anchored = initial(M.anchored)
M.update_canmove()
load = null
return 1
//-------------------------------------------------------
// Stat update procs
//-------------------------------------------------------
/obj/vehicle/proc/update_stats()
return
/obj/vehicle/space/Process_Spacemove(direction)
return 1