diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 4b42595b48..1d1dda6d99 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -54,6 +54,10 @@
#define BODYPART_ORGANIC 1
#define BODYPART_ROBOTIC 2
+#define BODYPART_NOT_DISABLED 0
+#define BODYPART_DISABLED_DAMAGE 1
+#define BODYPART_DISABLED_PARALYSIS 2
+
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 12e222e1ef..b42cbb8f00 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -108,7 +108,13 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
+#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
+#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
+#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
+#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
+ //non-mob traits
+#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
#define TRAIT_AGEUSIA "ageusia"
@@ -130,6 +136,7 @@
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
#define TRAIT_NYMPHO "nymphomania"
#define TRAIT_MASO "masochism"
+#define TRAIT_PARA "paraplegic"
#define TRAIT_EMPATH "empath"
#define TRAIT_FRIENDLY "friendly"
#define TRAIT_ASSBLASTUSA "assblastusa"
diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm
index e790e539c8..d094c162d7 100644
--- a/code/datums/brain_damage/severe.dm
+++ b/code/datums/brain_damage/severe.dm
@@ -60,18 +60,68 @@
/datum/brain_trauma/severe/paralysis
name = "Paralysis"
- desc = "Patient's brain can no longer control its motor functions."
+ desc = "Patient's brain can no longer control part of its motor functions."
scan_desc = "cerebral paralysis"
- gain_text = "You can't feel your body anymore!"
- lose_text = "You can feel your limbs again!"
+ gain_text = ""
+ lose_text = ""
+ var/paralysis_type
+ var/list/paralysis_traits = list()
+ //for descriptions
-/datum/brain_trauma/severe/paralysis/on_life()
- owner.Knockdown(200, ignore_canknockdown = TRUE)
+/datum/brain_trauma/severe/paralysis/New(specific_type)
+ if(specific_type)
+ paralysis_type = specific_type
+ if(!paralysis_type)
+ paralysis_type = pick("full","left","right","arms","legs","r_arm","l_arm","r_leg","l_leg")
+ var/subject
+ switch(paralysis_type)
+ if("full")
+ subject = "your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
+ if("left")
+ subject = "the left side of your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_L_LEG)
+ if("right")
+ subject = "the right side of your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG)
+ if("arms")
+ subject = "your arms"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM)
+ if("legs")
+ subject = "your legs"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
+ if("r_arm")
+ subject = "your right arm"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_ARM)
+ if("l_arm")
+ subject = "your left arm"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM)
+ if("r_leg")
+ subject = "your right leg"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_LEG)
+ if("l_leg")
+ subject = "your left leg"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_LEG)
+
+ gain_text = "You can't feel [subject] anymore!"
+ lose_text = "You can feel [subject] again!"
+
+/datum/brain_trauma/severe/paralysis/on_gain()
..()
+ for(var/X in paralysis_traits)
+ ADD_TRAIT(owner, X, "trauma_paralysis")
+ owner.update_disabled_bodyparts()
/datum/brain_trauma/severe/paralysis/on_lose()
- owner.SetKnockdown(0)
..()
+ for(var/X in paralysis_traits)
+ REMOVE_TRAIT(owner, X, "trauma_paralysis")
+ owner.update_disabled_bodyparts()
+
+/datum/brain_trauma/severe/paralysis/paraplegic
+ //can_gain = FALSE maybe breaks.
+ paralysis_type = "legs"
+ resilience = TRAUMA_RESILIENCE_ABSOLUTE
/datum/brain_trauma/severe/narcolepsy
name = "Narcolepsy"
@@ -203,4 +253,4 @@
/datum/brain_trauma/severe/pacifism/on_lose()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT)
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index 43be1fa2a7..bbf38c822a 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -187,6 +187,41 @@
to_chat(quirk_holder, "Your antagonistic nature has caused you to renounce your pacifism.")
qdel(src)
+/datum/quirk/paraplegic
+ name = "Paraplegic"
+ desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!"
+ value = -3
+ mob_trait = TRAIT_PARA
+ human_only = TRUE
+ gain_text = null // Handled by trauma.
+ lose_text = null
+ medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
+
+/datum/quirk/paraplegic/add()
+ var/datum/brain_trauma/severe/paralysis/paraplegic/T = new()
+ var/mob/living/carbon/human/H = quirk_holder
+ H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
+
+/datum/quirk/paraplegic/on_spawn()
+ if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
+ quirk_holder.buckled.unbuckle_mob(quirk_holder)
+
+ var/turf/T = get_turf(quirk_holder)
+ var/obj/structure/chair/spawn_chair = locate() in T
+
+ var/obj/vehicle/ridden/wheelchair/wheels = new(T)
+ if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
+ wheels.setDir(spawn_chair.dir)
+
+ wheels.buckle_mob(quirk_holder)
+
+ // During the spawning process, they may have dropped what they were holding, due to the paralysis
+ // So put the things back in their hands.
+
+ for(var/obj/item/I in T)
+ if(I.fingerprintslast == quirk_holder.ckey)
+ quirk_holder.put_in_hands(I)
+
/datum/quirk/poor_aim
name = "Poor Aim"
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
@@ -208,8 +243,12 @@
var/slot_string = "limb"
/datum/quirk/prosthetic_limb/on_spawn()
- var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/mob/living/carbon/human/H = quirk_holder
+ var/limb_slot
+ if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced
+ limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
+ else
+ limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
var/obj/item/bodypart/prosthetic
switch(limb_slot)
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index dbff7988c1..2f26c1e200 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -641,6 +641,15 @@
/obj/item/assembly/igniter = 1)
category = CAT_MISC
+
+/datum/crafting_recipe/wheelchair
+ name = "Wheelchair"
+ result = /obj/vehicle/ridden/wheelchair
+ reqs = list(/obj/item/stack/sheet/plasteel = 2,
+ /obj/item/stack/rods = 8)
+ time = 100
+ category = CAT_MISC
+
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
result = /obj/item/twohanded/rcl/ghetto
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fb09de7ec2..51ee5b372b 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -895,6 +895,11 @@
var/obj/item/organ/I = X
I.Insert(src)
+/mob/living/carbon/proc/update_disabled_bodyparts()
+ for(var/B in bodyparts)
+ var/obj/item/bodypart/BP = B
+ BP.update_disabled()
+
/mob/living/carbon/vv_get_dropdown()
. = ..()
. += "---"
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index 9204de3d08..3c80737b31 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -21,7 +21,7 @@
var/held_index = 0 //are we a hand? if so, which one!
var/is_pseudopart = FALSE //For limbs that don't really exist, eg chainsaws
- var/disabled = FALSE //If TRUE, limb is as good as missing
+ var/disabled = BODYPART_NOT_DISABLED //If disabled, limb is as good as missing
var/body_damage_coeff = 1 //Multiplier of the limb's damage that gets applied to the mob
var/stam_damage_coeff = 0.5
var/brutestate = 0
@@ -189,7 +189,7 @@
if(stamina > DAMAGE_PRECISION)
owner.update_stamina()
consider_processing()
- check_disabled()
+ update_disabled()
return update_bodypart_damage_state()
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
@@ -209,7 +209,7 @@
if(owner && updating_health)
owner.updatehealth()
consider_processing()
- check_disabled()
+ update_disabled()
return update_bodypart_damage_state()
//Returns total damage.
@@ -220,7 +220,24 @@
return total
//Checks disabled status thresholds
-/obj/item/bodypart/proc/check_disabled()
+
+//Checks disabled status thresholds
+/obj/item/bodypart/proc/update_disabled()
+ set_disabled(is_disabled())
+
+/obj/item/bodypart/proc/is_disabled()
+ if(HAS_TRAIT(owner, TRAIT_PARALYSIS))
+ return BODYPART_DISABLED_PARALYSIS
+ if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER))
+ . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled
+ if((get_damage(TRUE) >= max_damage))
+ return BODYPART_DISABLED_DAMAGE
+ if(disabled && (get_damage(TRUE) <= (max_damage * 0.5)))
+ return BODYPART_NOT_DISABLED
+ else
+ return BODYPART_NOT_DISABLED
+
+/obj/item/bodypart/proc/check_disabled() //This might be depreciated and should be safe to remove.
if(!can_dismember() || HAS_TRAIT(owner, TRAIT_NODISMEMBER))
return
if(!disabled && (get_damage(TRUE) >= max_damage))
@@ -228,7 +245,8 @@
else if(disabled && (get_damage(TRUE) <= (max_damage * 0.5)))
set_disabled(FALSE)
-/obj/item/bodypart/proc/set_disabled(new_disabled = TRUE)
+
+/obj/item/bodypart/proc/set_disabled(new_disabled)
if(disabled == new_disabled)
return
disabled = new_disabled
@@ -601,13 +619,27 @@
px_y = 0
stam_heal_tick = 2
-/obj/item/bodypart/l_arm/set_disabled(new_disabled = TRUE)
- ..()
- if(disabled)
- to_chat(owner, "Your [name] is too damaged to function!")
- owner.emote("scream")
+/obj/item/bodypart/l_arm/is_disabled()
+ if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM))
+ return BODYPART_DISABLED_PARALYSIS
+ return ..()
+
+/obj/item/bodypart/l_arm/set_disabled(new_disabled)
+ . = ..()
+ if(disabled == new_disabled)
+ return
+ if(disabled == BODYPART_DISABLED_DAMAGE)
+ if(owner.stat > UNCONSCIOUS)
+ owner.emote("scream")
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "Your [name] is too damaged to function!")
if(held_index)
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
+ else if(disabled == BODYPART_DISABLED_PARALYSIS)
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "You can't feel your [name]!")
+ if(held_index)
+ owner.dropItemToGround(owner.get_item_for_held_index(held_index))
if(owner.hud_used)
var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"]
if(L)
@@ -652,18 +684,33 @@
stam_heal_tick = 2
max_stamina_damage = 50
-/obj/item/bodypart/r_arm/set_disabled(new_disabled = TRUE)
- ..()
- if(disabled)
- to_chat(owner, "Your [name] is too damaged to function!")
- owner.emote("scream")
+/obj/item/bodypart/r_arm/is_disabled()
+ if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM))
+ return BODYPART_DISABLED_PARALYSIS
+ return ..()
+
+/obj/item/bodypart/r_arm/set_disabled(new_disabled)
+ . = ..()
+ if(disabled == new_disabled)
+ return
+ if(disabled == BODYPART_DISABLED_DAMAGE)
+ if(owner.stat > UNCONSCIOUS)
+ owner.emote("scream")
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "Your [name] is too damaged to function!")
if(held_index)
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
+ else if(disabled == BODYPART_DISABLED_PARALYSIS)
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "You can't feel your [name]!")
+ if(held_index)
+ owner.dropItemToGround(owner.get_item_for_held_index(held_index))
if(owner.hud_used)
var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"]
if(R)
R.update_icon()
+
/obj/item/bodypart/r_arm/monkey
icon = 'icons/mob/animal_parts.dmi'
icon_state = "default_monkey_r_arm"
@@ -700,11 +747,24 @@
stam_heal_tick = 2
max_stamina_damage = 50
-/obj/item/bodypart/l_leg/set_disabled(new_disabled = TRUE)
- ..()
- if(disabled)
- to_chat(owner, "Your [name] is too damaged to function!")
- owner.emote("scream")
+/obj/item/bodypart/l_leg/is_disabled()
+ if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
+ return BODYPART_DISABLED_PARALYSIS
+ return ..()
+
+/obj/item/bodypart/l_leg/set_disabled(new_disabled)
+ . = ..()
+ if(disabled == new_disabled)
+ return
+ if(disabled == BODYPART_DISABLED_DAMAGE)
+ if(owner.stat > UNCONSCIOUS)
+ owner.emote("scream")
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "Your [name] is too damaged to function!")
+ else if(disabled == BODYPART_DISABLED_PARALYSIS)
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "You can't feel your [name]!")
+
/obj/item/bodypart/l_leg/digitigrade
name = "left digitigrade leg"
@@ -747,11 +807,23 @@
max_stamina_damage = 50
stam_heal_tick = 2
-/obj/item/bodypart/r_leg/set_disabled(new_disabled = TRUE)
- ..()
- if(disabled)
- to_chat(owner, "Your [name] is too damaged to function!")
- owner.emote("scream")
+/obj/item/bodypart/r_leg/is_disabled()
+ if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
+ return BODYPART_DISABLED_PARALYSIS
+ return ..()
+
+/obj/item/bodypart/r_leg/set_disabled(new_disabled)
+ . = ..()
+ if(disabled == new_disabled)
+ return
+ if(disabled == BODYPART_DISABLED_DAMAGE)
+ if(owner.stat > UNCONSCIOUS)
+ owner.emote("scream")
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "Your [name] is too damaged to function!")
+ else if(disabled == BODYPART_DISABLED_PARALYSIS)
+ if(. && (owner.stat > DEAD))
+ to_chat(owner, "You can't feel your [name]!")
/obj/item/bodypart/r_leg/digitigrade
name = "right digitigrade leg"
diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm
index be59a6df65..54bc03bcf3 100644
--- a/code/modules/vehicles/_vehicle.dm
+++ b/code/modules/vehicles/_vehicle.dm
@@ -31,6 +31,19 @@
occupant_actions = list()
generate_actions()
+/obj/vehicle/examine(mob/user)
+ ..()
+ if(resistance_flags & ON_FIRE)
+ to_chat(user, "It's on fire!")
+ var/healthpercent = obj_integrity/max_integrity * 100
+ switch(healthpercent)
+ if(50 to 99)
+ to_chat(user, "It looks slightly damaged.")
+ if(25 to 50)
+ to_chat(user, "It appears heavily damaged.")
+ if(0 to 25)
+ to_chat(user, "It's falling apart!")
+
/obj/vehicle/proc/is_key(obj/item/I)
return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE
diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm
index 25a337bc22..8fe7322579 100644
--- a/code/modules/vehicles/ridden.dm
+++ b/code/modules/vehicles/ridden.dm
@@ -4,8 +4,8 @@
max_buckled_mobs = 1
buckle_lying = FALSE
default_driver_move = FALSE
- var/legs_required = 2
- var/arms_requires = 0 //why not?
+ var/legs_required = 1
+ var/arms_required = 0 //why not?
/obj/vehicle/ridden/Initialize()
. = ..()
@@ -31,6 +31,9 @@
/obj/vehicle/ridden/post_buckle_mob(mob/living/M)
add_occupant(M)
+ if(M.get_num_legs() < legs_required)
+ to_chat(M, "You don't have enough legs to operate the pedals!")
+ unbuckle_mob(M)
return ..()
/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm
new file mode 100644
index 0000000000..a5ba06e6fb
--- /dev/null
+++ b/code/modules/vehicles/wheelchair.dm
@@ -0,0 +1,110 @@
+/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic) Then ported by Fermis from tg!
+ name = "wheelchair"
+ desc = "A chair with big wheels. It looks like you can move in this on your own."
+ icon = 'icons/obj/vehicles.dmi'
+ icon_state = "wheelchair"
+ layer = OBJ_LAYER
+ max_integrity = 100
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo
+ legs_required = 0 //You'll probably be using this if you don't have legs
+ canmove = TRUE
+ density = FALSE //Thought I couldn't fix this one easily, phew
+ arms_required = 1
+
+/obj/vehicle/ridden/wheelchair/Initialize()
+ . = ..()
+ var/datum/component/riding/D = LoadComponent(/datum/component/riding)
+ D.vehicle_move_delay = 0
+ D.set_vehicle_dir_layer(SOUTH, OBJ_LAYER)
+ D.set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER)
+ D.set_vehicle_dir_layer(EAST, OBJ_LAYER)
+ D.set_vehicle_dir_layer(WEST, OBJ_LAYER)
+
+/obj/vehicle/ridden/wheelchair/ComponentInitialize() //Since it's technically a chair I want it to have chair properties
+ . = ..()
+ AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null)
+
+/obj/vehicle/ridden/wheelchair/obj_destruction(damage_flag)
+ new /obj/item/stack/rods(drop_location(), 1)
+ new /obj/item/stack/sheet/metal(drop_location(), 1)
+ ..()
+
+/obj/vehicle/ridden/wheelchair/Destroy()
+ if(has_buckled_mobs())
+ var/mob/living/carbon/H = buckled_mobs[1]
+ unbuckle_mob(H)
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/driver_move(mob/living/user, direction)
+ if(istype(user))
+ if(canmove && (user.get_num_arms() < arms_required))
+ to_chat(user, "You don't have enough arms to operate the wheels!")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ //1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
+ //if that made no sense this simply makes the wheelchair speed change along with movement speed delay
+ D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / min(user.get_num_arms(), 2)
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/Moved()
+ . = ..()
+ cut_overlays()
+ playsound(src, 'sound/effects/roll.ogg', 75, 1)
+ if(has_buckled_mobs())
+ handle_rotation_overlayed()
+
+
+/obj/vehicle/ridden/wheelchair/post_buckle_mob(mob/living/user)
+ . = ..()
+ handle_rotation_overlayed()
+
+/obj/vehicle/ridden/wheelchair/post_unbuckle_mob()
+ . = ..()
+ cut_overlays()
+
+/obj/vehicle/ridden/wheelchair/setDir(newdir)
+ ..()
+ handle_rotation(newdir)
+
+/obj/vehicle/ridden/wheelchair/wrench_act(mob/living/user, obj/item/I) //Attackby should stop it attacking the wheelchair after moving away during decon
+ to_chat(user, "You begin to detach the wheels...")
+ if(I.use_tool(src, user, 40, volume=50))
+ to_chat(user, "You detach the wheels and deconstruct the chair.")
+ new /obj/item/stack/rods(drop_location(), 6)
+ new /obj/item/stack/sheet/metal(drop_location(), 4)
+ qdel(src)
+ return TRUE
+
+/obj/vehicle/ridden/wheelchair/proc/handle_rotation(direction)
+ if(has_buckled_mobs())
+ handle_rotation_overlayed()
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(direction)
+
+/obj/vehicle/ridden/wheelchair/proc/handle_rotation_overlayed()
+ cut_overlays()
+ var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir)
+ add_overlay(V)
+
+
+
+/obj/vehicle/ridden/wheelchair/proc/can_be_rotated(mob/living/user)
+ return TRUE
+
+/obj/vehicle/ridden/wheelchair/proc/can_user_rotate(mob/living/user)
+ var/mob/living/L = user
+ if(istype(L))
+ if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return FALSE
+ if(isobserver(user) && CONFIG_GET(flag/ghost_interaction))
+ return TRUE
+ return FALSE
+
+/obj/vehicle/ridden/wheelchair/the_whip/driver_move(mob/living/user, direction)
+ if(istype(user))
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / user.get_num_arms()
+ return ..()
diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi
index 5e3757cedd..67079de3e2 100644
Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 37df11d40c..8e33f39524 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2773,6 +2773,7 @@
#include "code\modules\vehicles\speedbike.dm"
#include "code\modules\vehicles\vehicle_actions.dm"
#include "code\modules\vehicles\vehicle_key.dm"
+#include "code\modules\vehicles\wheelchair.dm"
#include "code\modules\vehicles\cars\car.dm"
#include "code\modules\vehicles\cars\clowncar.dm"
#include "code\modules\vending\_vending.dm"