diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 2811168f..1b923389 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -636,11 +636,24 @@
/datum/crafting_recipe/wheelchair
name = "Wheelchair"
result = /obj/vehicle/ridden/wheelchair
- reqs = list(/obj/item/stack/sheet/plasteel = 2,
+ reqs = list(/obj/item/stack/sheet/metal = 10,
/obj/item/stack/rods = 8)
time = 100
category = CAT_MISC
+/datum/crafting_recipe/motorized_wheelchair
+ name = "Motorized Wheelchair"
+ result = /obj/vehicle/ridden/wheelchair/motorized
+ reqs = list(/obj/item/stack/sheet/metal = 10,
+ /obj/item/stack/rods = 8,
+ /obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ parts = list(/obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
+ time = 200
+ category = CAT_MISC
+
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
result = /obj/item/twohanded/rcl/ghetto
diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm
new file mode 100644
index 00000000..873ae7ac
--- /dev/null
+++ b/code/modules/vehicles/motorized_wheelchair.dm
@@ -0,0 +1,168 @@
+/obj/vehicle/ridden/wheelchair/motorized
+ name = "motorized wheelchair"
+ desc = "A chair with big wheels. It seems to have a motor in it."
+ max_integrity = 150
+ var/speed = 2
+ var/power_efficiency = 1
+ var/power_usage = 100
+ var/panel_open = FALSE
+ var/list/required_parts = list(/obj/item/stock_parts/manipulator,
+ /obj/item/stock_parts/manipulator,
+ /obj/item/stock_parts/capacitor)
+ var/obj/item/stock_parts/cell/power_cell
+
+/obj/vehicle/ridden/wheelchair/motorized/CheckParts(list/parts_list)
+ ..()
+ refresh_parts()
+
+/obj/vehicle/ridden/wheelchair/motorized/proc/refresh_parts()
+ speed = 1 // Should never be under 1
+ for(var/obj/item/stock_parts/manipulator/M in contents)
+ speed += M.rating
+ for(var/obj/item/stock_parts/capacitor/C in contents)
+ power_efficiency = C.rating
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * delay_multiplier) / speed
+
+/obj/vehicle/ridden/wheelchair/motorized/obj_destruction(damage_flag)
+ var/turf/T = get_turf(src)
+ for(var/atom/movable/A in contents)
+ A.forceMove(T)
+ //if(isliving(A))
+ // var/mob/living/L = A
+ // L.update_mobility()
+ ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/driver_move(mob/living/user, direction)
+ if(istype(user))
+ if(!canmove)
+ return FALSE
+ if(!power_cell)
+ to_chat(user, "There seems to be no cell installed in [src].")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ if(power_cell.charge < power_usage / max(power_efficiency, 1))
+ to_chat(user, "The display on [src] blinks 'Out of Power'.")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ if(user.get_num_arms() < arms_required)
+ to_chat(user, "You don't have enough arms to operate the motor controller!")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ power_cell.use(power_usage / max(power_efficiency, 1))
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/set_move_delay(mob/living/user)
+ return
+
+/obj/vehicle/ridden/wheelchair/motorized/post_buckle_mob(mob/living/user)
+ . = ..()
+ density = TRUE
+
+/obj/vehicle/ridden/wheelchair/motorized/post_unbuckle_mob()
+ . = ..()
+ density = FALSE
+
+/obj/vehicle/ridden/wheelchair/motorized/attack_hand(mob/living/user)
+ if(power_cell && panel_open)
+ power_cell.update_icon()
+ user.put_in_hands(power_cell)
+ power_cell = null
+ to_chat(user, "You remove the power cell from [src].")
+ return
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
+ I.play_tool_sound(src)
+ panel_open = !panel_open
+ user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel on [src].", "You [panel_open ? "open" : "close"] the maintenance panel.")
+ return
+ if(panel_open)
+ if(istype(I, /obj/item/stock_parts/cell))
+ if(power_cell)
+ to_chat(user, "There is a power cell already installed.")
+ else
+ I.forceMove(src)
+ power_cell = I
+ to_chat(user, "You install the [I].")
+ refresh_parts()
+ return
+ if(istype(I, /obj/item/stock_parts))
+ var/obj/item/stock_parts/B = I
+ var/P
+ for(var/obj/item/stock_parts/A in contents)
+ for(var/D in required_parts)
+ if(ispath(A.type, D))
+ P = D
+ break
+ if(istype(B, P) && istype(A, P))
+ if(B.get_part_rating() > A.get_part_rating())
+ B.forceMove(src)
+ user.put_in_hands(A)
+ user.visible_message("[user] replaces [A] with [B] in [src].", "You replace [A] with [B].")
+ break
+ refresh_parts()
+ return
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/wrench_act(mob/living/user, obj/item/I)
+ 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(), 8)
+ new /obj/item/stack/sheet/metal(drop_location(), 10)
+ var/turf/T = get_turf(src)
+ for(var/atom/movable/A in contents)
+ A.forceMove(T)
+ //if(isliving(A))
+ // var/mob/living/L = A
+ // L.update_mobility()
+ qdel(src)
+ return TRUE
+
+/obj/vehicle/ridden/wheelchair/motorized/examine(mob/user)
+ . = ..()
+ if((obj_flags & EMAGGED) && panel_open)
+ . += "There is a bomb under the maintenance panel."
+ . += "There is a small screen on it, [(in_range(user, src) || isobserver(user)) ? "[power_cell ? "it reads:" : "but it is dark."]" : "but you can't see it from here."]"
+ if(!power_cell || (!in_range(user, src) && !isobserver(user)))
+ return
+ . += "Speed: [speed]"
+ . += "Energy efficiency: [power_efficiency]"
+ . += "Power: [power_cell.charge] out of [power_cell.maxcharge]"
+
+/obj/vehicle/ridden/wheelchair/motorized/Bump(atom/movable/M)
+ . = ..()
+ // Here is the shitty emag functionality.
+ if(obj_flags & EMAGGED && (istype(M, /turf/closed) || isliving(M)))
+ explosion(src, -1, 1, 3, 2, 0)
+ visible_message("[src] explodes!!")
+ return
+ // If the speed is higher than delay_multiplier throw the person on the wheelchair away
+ if(M.density && speed > delay_multiplier && has_buckled_mobs())
+ var/mob/living/H = buckled_mobs[1]
+ var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
+ unbuckle_mob(H)
+ H.throw_at(throw_target, 2, 3)
+ H.Knockdown(100)
+ H.adjustStaminaLoss(40)
+ if(isliving(M))
+ var/mob/living/D = M
+ throw_target = get_edge_target_turf(D, pick(GLOB.cardinals))
+ D.throw_at(throw_target, 2, 3)
+ D.Knockdown(80)
+ D.adjustStaminaLoss(35)
+ visible_message("[src] crashes into [M], sending [H] and [D] flying!")
+ else
+ visible_message("[src] crashes into [M], sending [H] flying!")
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+
+/obj/vehicle/ridden/wheelchair/motorized/emag_act(mob/user)
+ if((obj_flags & EMAGGED) || !panel_open)
+ return
+ to_chat(user, "A bomb appears in [src], what the fuck?")
+ obj_flags |= EMAGGED
diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm
index 137242c5..2eb1a2ad 100644
--- a/code/modules/vehicles/wheelchair.dm
+++ b/code/modules/vehicles/wheelchair.dm
@@ -1,4 +1,4 @@
-/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic) Then ported by Fermis from tg!
+/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic)
name = "wheelchair"
desc = "A chair with big wheels. It looks like you can move in this on your own."
icon = 'icons/obj/vehicles.dmi'
@@ -9,7 +9,8 @@
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
+ // Run speed delay is multiplied with this for vehicle move delay.
+ var/delay_multiplier = 6.7
/obj/vehicle/ridden/wheelchair/Initialize()
. = ..()
@@ -42,16 +43,19 @@
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) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
+ set_move_delay(user)
return ..()
+/obj/vehicle/ridden/wheelchair/proc/set_move_delay(mob/living/user)
+ 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) * delay_multiplier) / min(user.get_num_arms(), 2)
+
/obj/vehicle/ridden/wheelchair/Moved()
. = ..()
cut_overlays()
- playsound(src, 'sound/effects/roll.ogg', 75, 1)
+ playsound(src, 'sound/effects/roll.ogg', 75, TRUE)
if(has_buckled_mobs())
handle_rotation_overlayed()
@@ -69,6 +73,7 @@
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.")
diff --git a/tgstation.dme b/tgstation.dme
index 1679844e..16a4cf1e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2811,6 +2811,7 @@
#include "code\modules\vehicles\atv.dm"
#include "code\modules\vehicles\bicycle.dm"
#include "code\modules\vehicles\lavaboat.dm"
+#include "code\modules\vehicles\motorized_wheelchair.dm"
#include "code\modules\vehicles\pimpin_ride.dm"
#include "code\modules\vehicles\ridden.dm"
#include "code\modules\vehicles\scooter.dm"