From 342a8d04c7f103aba8fe5602170e70ee6076d5f6 Mon Sep 17 00:00:00 2001 From: JoanRisu Date: Sat, 17 Sep 2016 20:38:45 -0700 Subject: [PATCH] Adjusting some fluff items and adding in the security train for testing and further coding. (#560) --- code/modules/vehicles/Securitrain_vr.dm | 423 ++++++++++++++++++ .../vore/fluffstuff/custom_boxes_vr.dm | 4 + .../vore/fluffstuff/custom_clothes_vr.dm | 12 +- icons/obj/vehicles_vr.dmi | Bin 7994 -> 8866 bytes 4 files changed, 436 insertions(+), 3 deletions(-) create mode 100644 code/modules/vehicles/Securitrain_vr.dm diff --git a/code/modules/vehicles/Securitrain_vr.dm b/code/modules/vehicles/Securitrain_vr.dm new file mode 100644 index 00000000000..b3698560d64 --- /dev/null +++ b/code/modules/vehicles/Securitrain_vr.dm @@ -0,0 +1,423 @@ +//This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here. +//I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu + +/obj/vehicle/train/securiengine + name = "Security Cart" + desc = "A ridable electric car designed for pulling trolleys as well as personal transport." + icon = 'icons/obj/vehicles_vr.dmi' + icon_state = "paddywagon" + on = 0 + powered = 1 + locked = 0 + move_delay = 0.5 + + //Health stuff + health = 100 + maxhealth = 100 + fire_dam_coeff = 0.6 + brute_dam_coeff = 0.5 + + load_item_visible = 1 + load_offset_x = 0 + mob_offset_y = 7 + + var/car_limit = 0 //how many cars an engine can pull before performance degrades. This should be 0 to prevent trailers from unhitching. + active_engines = 1 + var/obj/item/weapon/key/securitrain/key + var/siren = 0 //This is for eventually getting the siren sprite to work. + +/obj/item/weapon/key/securitrain + name = "The Security Cart key" + desc = "The Security Cart Key used to start it." + icon = 'icons/obj/vehicles_vr.dmi' + icon_state = "securikey" + w_class = 1 + +/obj/vehicle/train/securitrolley + name = "Train trolley" + desc = "A trolly designed to transport security personnel or prisoners." + icon = 'icons/obj/vehicles_vr.dmi' + icon_state = "paddy_trailer" + anchored = 0 + passenger_allowed = 1 + locked = 0 + + load_item_visible = 1 + load_offset_x = 0 + load_offset_y = 4 + mob_offset_y = 8 + +/obj/vehicle/train/securitrolley/cargo + name = "Train trolley" + desc = "A trolley designed to transport security equipment to a scene." + icon = 'icons/obj/vehicles_vr.dmi' + icon_state = "secitemcarrierbot" + passenger_allowed = 0 //Stick a man inside the box. :v + load_item_visible = 0 //The load is supposed to be invisible. + +//------------------------------------------- +// Standard procs +//------------------------------------------- +/obj/vehicle/train/securiengine/New() + ..() + cell = new /obj/item/weapon/cell/high(src) + key = new(src) + var/image/I = new(icon = 'icons/obj/vehicles_vr.dmi', icon_state = null, layer = src.layer + 0.2) //over mobs + overlays += I + turn_off() //so engine verbs are correctly set + +/obj/vehicle/train/securiengine/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/securitrolley/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("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") + else + ..() + +/obj/vehicle/train/securiengine/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/key/securitrain)) + if(!key) + user.drop_item() + W.forceMove(src) + key = W + verbs += /obj/vehicle/train/securiengine/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/securitrolley/bullet_act(var/obj/item/projectile/Proj) + if(buckled_mob && prob(70)) + buckled_mob.bullet_act(Proj) + return + ..() + +/obj/vehicle/train/securitrolley/update_icon() + if(open) + icon_state = initial(icon_state) + "_open" + else + icon_state = initial(icon_state) + +/obj/vehicle/train/securitrolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) + return + +/obj/vehicle/train/securiengine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) + ..() + update_stats() + +/obj/vehicle/train/securiengine/remove_cell(var/mob/living/carbon/human/H) + ..() + update_stats() + +/obj/vehicle/train/securiengine/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/securitrolley/Bump(atom/Obstacle) + if(!lead) + return //so people can't knock others over by pushing a trolley around + ..() + +//------------------------------------------- +// Train procs +//------------------------------------------- +/obj/vehicle/train/securiengine/turn_on() + if(!key) + return + else + ..() + update_stats() + + verbs -= /obj/vehicle/train/securiengine/verb/stop_engine + verbs -= /obj/vehicle/train/securiengine/verb/start_engine + + if(on) + verbs += /obj/vehicle/train/securiengine/verb/stop_engine + else + verbs += /obj/vehicle/train/securiengine/verb/start_engine + +/obj/vehicle/train/securiengine/turn_off() + ..() + + verbs -= /obj/vehicle/train/securiengine/verb/stop_engine + verbs -= /obj/vehicle/train/securiengine/verb/start_engine + + if(!on) + verbs += /obj/vehicle/train/securiengine/verb/start_engine + else + verbs += /obj/vehicle/train/securiengine/verb/stop_engine + +/obj/vehicle/train/securitrolley/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/securitrolley/RunOver(var/mob/living/carbon/human/H) + ..() + attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + +/obj/vehicle/train/securiengine/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("\red \The [src] ran over [H]!") + attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])") + msg_admin_attack("[D.name] ([D.ckey]) ran over [H.name] ([H.ckey]). (JMP)") + else + attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + + +//------------------------------------------- +// Interaction procs +//------------------------------------------- +/obj/vehicle/train/securiengine/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/securiengine/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/securiengine/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/securiengine/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/securiengine/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/securiengine/verb/remove_key + +//------------------------------------------- +// Loading/unloading procs +//------------------------------------------- +/obj/vehicle/train/securitrolley/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/securiengine/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/securitrolley/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/securitrolley/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/securiengine/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/securitrolley)) + T.attach_to(src, user) + if (istype(T, /obj/vehicle/train/securitrolley/cargo)) + 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/securiengine/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.5 //makes cargo trains 10% slower than running when not overweight + +/obj/vehicle/train/securitrolley/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 + +//----------------------------------------------------- +//Update layer stuff +// +//This is supposed to update the layers and put the mob in the correct spot. +//Pls help squirrel get this to work. ;m; +//----------------------------------------------------- +/obj/vehicle/train/securiengine/proc/update_layer() + if(dir == SOUTH) + layer = FLY_LAYER + else + layer = OBJ_LAYER + +/obj/vehicle/train/securiengine/proc/update_mob() + if(buckled_mob) + buckled_mob.set_dir(dir) + switch(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 diff --git a/code/modules/vore/fluffstuff/custom_boxes_vr.dm b/code/modules/vore/fluffstuff/custom_boxes_vr.dm index d66de51a4ef..8f47d57d96b 100644 --- a/code/modules/vore/fluffstuff/custom_boxes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_boxes_vr.dm @@ -81,6 +81,10 @@ new /obj/item/weapon/sword/fluff/joanaria(src) new /obj/item/weapon/flame/lighter/zippo/fluff/joan(src) new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src) + new /obj/item/clothing/head/helmet/space/fluff/joan(src) + new /obj/item/clothing/suit/space/fluff/joan(src) + + //joanrisu:Katarina Eine /obj/item/weapon/storage/backpack/dufflebag/sec/fluff/Katarina diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index dc13fcea657..8cb7d3cac2f 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -668,9 +668,15 @@ /obj/item/clothing/suit/space/fluff/joan name = "Joan's Combat Spacesuit" desc = "A customized combat spacesuit made for a certain squirrely Commissioned Officer, tail slot included. \ - On the right shoulder, the United Federation's Emblem sits proudly. On the left, there are faded indications \ - that there were different ranks painted on and off. On the collar where the suit is softer is a rectangular \ - name-tag with the name 'Joan' on it. There are indications that the suit has seen combat." + On the right shoulder, the United Federation's Emblem sits proudly with a Rose weaving through it. \ + On the left, there are faded indications that there were different ranks painted on and off. On the collar \ + where the suit is softer is a rectangular name-tag with the name 'Joan' on it. There are indications that the \ + suit has seen combat." + + armor = list(melee = 80, bullet = 50, laser = 35, energy = 15, bomb = 70, bio = 100, rad = 50) //These values were taken from the combat rigs and adjusted to be weaker than said rigs. + slowdown = 0 + allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton) + w_class = 3 icon = 'icons/vore/custom_clothes_vr.dmi' icon_state = "joansuit" diff --git a/icons/obj/vehicles_vr.dmi b/icons/obj/vehicles_vr.dmi index 6fa5ae5e08f8ff51f9910379f0b66b9df28a1bd6..a685e7c69731bb0b1e68d6a79af9ea2f34ba8c01 100644 GIT binary patch literal 8866 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 z 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