Merge pull request #8507 from Thalpy/Wheelchairs
Adds Hoverchairs and the paraplegic trait.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
. += "---"
|
||||
|
||||
@@ -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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(. && (owner.stat > DEAD))
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
|
||||
/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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
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, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(. && (owner.stat > DEAD))
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/r_leg/digitigrade
|
||||
name = "right digitigrade leg"
|
||||
|
||||
@@ -31,6 +31,19 @@
|
||||
occupant_actions = list()
|
||||
generate_actions()
|
||||
|
||||
/obj/vehicle/examine(mob/user)
|
||||
..()
|
||||
if(resistance_flags & ON_FIRE)
|
||||
to_chat(user, "<span class='warning'>It's on fire!</span>")
|
||||
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, "<span class='warning'>It's falling apart!</span>")
|
||||
|
||||
/obj/vehicle/proc/is_key(obj/item/I)
|
||||
return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE
|
||||
|
||||
|
||||
@@ -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, "<span class='warning'>You don't have enough legs to operate the pedals!</span>")
|
||||
unbuckle_mob(M)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
@@ -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, "<span class='warning'>You don't have enough arms to operate the wheels!</span>")
|
||||
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, "<span class='notice'>You begin to detach the wheels...</span>")
|
||||
if(I.use_tool(src, user, 40, volume=50))
|
||||
to_chat(user, "<span class='notice'>You detach the wheels and deconstruct the chair.</span>")
|
||||
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 ..()
|
||||
Reference in New Issue
Block a user