Files
CHOMPStation2/code/modules/vehicles/cargo_train.dm
Zuhayr f93ea6a78f Tweaks to previous commits.
More tweaks to IPC fixes.
Merge resolution/compile fixes.

Further work on properly integrating, updating and fixing prosthetic options.

Repathed internal organs to organ/internal.

More work on full synthetics, changelings, overheating.

Working on getting organs to qdel properly and spawn properly when robotized.

Finalized some overheating values, added remaining prosthetic icons.

Finalizing the testing version of the full prosthetic bodies branch.

Added suit cyclers to the autolathe and map.

Fixing runtime errors.

Fixing errors.

Changelog.

Replacing limb and organ strings with constants.

Prevented brainless species from becoming full cyborgs.

Fixed issues with brain/MMIs renaming themselves inappropriately.

Various fixes and oversights.
2015-12-24 21:13:40 +10:30

372 lines
11 KiB
Plaintext

/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/cell/high(src)
key = new(src)
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/engine/Move(var/turf/destination)
if(on && cell.charge < charge_use)
turn_off()
update_stats()
if(load && is_train_head())
load << "The drive motor briefly whines, then drones to a stop."
if(is_train_head() && !on)
return 0
//space check ~no flying space trains sorry
if(on && istype(destination, /turf/space))
return 0
return ..()
/obj/vehicle/train/cargo/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob)
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)
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
..()
//cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead
/obj/vehicle/train/cargo/bullet_act(var/obj/item/projectile/Proj)
if(buckled_mob && prob(70))
buckled_mob.bullet_act(Proj)
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/cell/C, var/mob/living/carbon/human/H)
return
/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/weapon/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(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_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 [H.name] ([H.ckey])</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
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 [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])</font>")
msg_admin_attack("[D.name] ([D.ckey]) ran over [H.name] ([H.ckey]). (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
else
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</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
if(!istype(usr, /mob/living/carbon/human))
return
user << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
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 = "Vehicle"
set src in view(0)
if(!istype(usr, /mob/living/carbon/human))
return
if(on)
usr << "The engine is already running."
return
turn_on()
if (on)
usr << "You start [src]'s engine."
else
if(cell.charge < charge_use)
usr << "[src] is out of power."
else
usr << "[src]'s engine won't start."
/obj/vehicle/train/cargo/engine/verb/stop_engine()
set name = "Stop engine"
set category = "Vehicle"
set src in view(0)
if(!istype(usr, /mob/living/carbon/human))
return
if(!on)
usr << "The engine is already stopped."
return
turn_off()
if (!on)
usr << "You stop [src]'s engine."
/obj/vehicle/train/cargo/engine/verb/remove_key()
set name = "Remove key"
set category = "Vehicle"
set src in view(0)
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 there are any items you don't want to be able to interact with, add them to this check
// ~no more shielded, emitter armed death trains
if(istype(C, /obj/machinery))
load_object(C)
else
..()
if(load)
return 1
/obj/vehicle/train/cargo/engine/load(var/atom/movable/C)
if(!istype(C, /mob/living/carbon/human))
return 0
return ..()
//Load the object "inside" the trolley and add an overlay of it.
//This prevents the object from being interacted with until it has
// been unloaded. A dummy object is loaded instead so the loading
// code knows to handle it correctly.
/obj/vehicle/train/cargo/trolley/proc/load_object(var/atom/movable/C)
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
var/datum/vehicle_dummy_load/dummy_load = new()
load = dummy_load
if(!load)
return
dummy_load.actual_load = C
C.forceMove(src)
if(load_item_visible)
C.pixel_x += load_offset_x
C.pixel_y += load_offset_y
C.layer = layer
overlays += C
//we can set these back now since we have already cloned the icon into the overlay
C.pixel_x = initial(C.pixel_x)
C.pixel_y = initial(C.pixel_y)
C.layer = initial(C.layer)
/obj/vehicle/train/cargo/trolley/unload(var/mob/user, var/direction)
if(istype(load, /datum/vehicle_dummy_load))
var/datum/vehicle_dummy_load/dummy_load = load
load = dummy_load.actual_load
dummy_load.actual_load = null
qdel(dummy_load)
overlays.Cut()
..()
//-------------------------------------------
// Latching/unlatching procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T))
return 0
//if we are attaching a trolley to an engine we don't care what direction
// it is in and it should probably be attached with the engine in the lead
if(istype(T, /obj/vehicle/train/cargo/trolley))
T.attach_to(src, user)
else
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)
//-------------------------------------------------------
// 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