Skip to content

Commit

Permalink
Ports hotswappable robot limbs quirk from NovaSector (#411)
Browse files Browse the repository at this point in the history
  • Loading branch information
siliconOpossum authored Feb 4, 2024
1 parent 07c2514 commit d6bedbd
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 6 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@

/// If the mob enters shock, they will have +1 cure condition (helps cure it faster)
#define TRAIT_ABATES_SHOCK "shock_abated"

/// The trait that determines if someone has the robotic limb reattachment quirk.
#define TRAIT_ROBOTIC_LIMBATTACHMENT "trait_robotic_limbattachment" // Sticking this here because Melbert told me to
6 changes: 5 additions & 1 deletion code/modules/surgery/bodyparts/_bodyparts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,11 @@

if(ishuman(victim))
var/mob/living/carbon/human/human_victim = victim
if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT))
// NON-MODULE CHANGE START
if (!HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) && !(bodytype & BODYTYPE_ROBOTIC)) //if we're trying to attach something that's not robotic, and we don't have the generic trait, end out
return
if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) || HAS_TRAIT(victim, TRAIT_ROBOTIC_LIMBATTACHMENT))
// NON-MODULE CHANGE END
if(!human_victim.get_bodypart(body_zone))
user.temporarilyRemoveItemFromInventory(src, TRUE)
if(!try_attach_limb(victim))
Expand Down
1 change: 1 addition & 0 deletions maplestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -6446,6 +6446,7 @@
#include "maplestation_modules\code\modules\research\machinery\_production.dm"
#include "maplestation_modules\code\modules\research\techweb\_research.dm"
#include "maplestation_modules\code\modules\research\techweb\all_nodes.dm"
#include "maplestation_modules\code\modules\robotic_limb_detach\robot_limb_detach_quirk.dm"
#include "maplestation_modules\code\modules\surgery\organs\augments_arms.dm"
#include "maplestation_modules\code\modules\surgery\organs\autosurgeon.dm"
#include "maplestation_modules\code\modules\surgery\organs\ears.dm"
Expand Down
11 changes: 6 additions & 5 deletions maplestation_modules/code/datums/pain/pain.dm
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@

body_zones[new_limb.body_zone] = new_limb

if(special)
if(special || (HAS_TRAIT(source, TRAIT_ROBOTIC_LIMBATTACHMENT) && (new_limb.bodytype & BODYTYPE_ROBOTIC)))
new_limb.pain = 0
else
adjust_bodypart_pain(new_limb.body_zone, new_limb.pain)
Expand All @@ -152,10 +152,11 @@
body_zones -= bad_zone
UnregisterSignal(lost_limb, COMSIG_QDELETING)

if(!QDELETED(parent) && !special)
var/limb_removed_pain = (dismembered ? PAIN_LIMB_DISMEMBERED : PAIN_LIMB_REMOVED)
adjust_bodypart_pain(BODY_ZONE_CHEST, limb_removed_pain)
adjust_bodypart_pain(BODY_ZONES_MINUS_CHEST, limb_removed_pain / 3)
if(!QDELETED(parent))
if(!special && !(HAS_TRAIT(source, TRAIT_ROBOTIC_LIMBATTACHMENT) && (lost_limb.bodytype & BODYTYPE_ROBOTIC)))
var/limb_removed_pain = (dismembered ? PAIN_LIMB_DISMEMBERED : PAIN_LIMB_REMOVED)
adjust_bodypart_pain(BODY_ZONE_CHEST, limb_removed_pain)
adjust_bodypart_pain(BODY_ZONES_MINUS_CHEST, limb_removed_pain / 3)

if(!QDELETED(lost_limb))
lost_limb.pain = initial(lost_limb.pain)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/datum/quirk/robot_limb_detach
name = "Cybernetic Limb Mounts"
desc = "You are able to detach and reattach any installed robotic limbs with very little effort."
gain_text = span_notice("Internal sensors report limb disengagement protocols are ready and waiting.")
lose_text = span_notice("ERROR: LIMB DISENGAGEMENT PROTOCOLS OFFLINE.")
medical_record_text = "Patient bears quick-attach and release limb joint cybernetics."
value = 0
mob_trait = TRAIT_ROBOTIC_LIMBATTACHMENT
icon = FA_ICON_HANDSHAKE_SIMPLE_SLASH
quirk_flags = QUIRK_HUMAN_ONLY
/// The action we add with this quirk in add(), used for easy deletion later
var/datum/action/cooldown/added_action

/datum/quirk/robot_limb_detach/add(client/client_source)
var/mob/living/carbon/human/human_holder = quirk_holder
var/datum/action/cooldown/robot_self_amputation/limb_action = new()
limb_action.Grant(human_holder)
added_action = limb_action

/datum/quirk/robot_limb_detach/remove()
QDEL_NULL(added_action)

/datum/action/cooldown/robot_self_amputation
name = "Detach a robotic limb"
desc = "Disengage one of your robotic limbs from your cybernetic mounts. Requires you to not be restrained or otherwise under duress."
button_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "autotomy"

cooldown_time = 1 SECONDS
check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_HANDS_BLOCKED | AB_CHECK_INCAPACITATED

var/list/exclusions = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)

/datum/action/cooldown/robot_self_amputation/proc/detaching_check(mob/living/carbon/human/target, obj/item/bodypart/limb_to_detach)
return !QDELETED(limb_to_detach) && limb_to_detach.owner == target

/datum/action/cooldown/robot_self_amputation/Activate(mob/living/carbon/human/target)
if(!ishuman(target))
return

if(HAS_TRAIT(target, TRAIT_NODISMEMBER))
to_chat(target, span_warning("ERROR: LIMB DISENGAGEMENT PROTOCOLS OFFLINE. Seek out a maintenance technician."))
return


var/list/robot_parts = list()
for (var/obj/item/bodypart/possible_part as anything in target.bodyparts)
if ((possible_part.bodytype & BODYTYPE_ROBOTIC) && !(possible_part.body_zone in exclusions)) //only robot limbs and only if they're not crucial to our like, ongoing life, you know?
robot_parts += possible_part

if (!length(robot_parts))
to_chat(target, "ERROR: Limb disengagement protocols report no compatible cybernetics currently installed. Seek out a maintenance technician.")
return

var/obj/item/bodypart/limb_to_detach = tgui_input_list(target, "Limb to detach", "Cybernetic Limb Detachment", sort_names(robot_parts))
if (QDELETED(src) || QDELETED(target) || QDELETED(limb_to_detach) || limb_to_detach.owner != target)
return

if (length(limb_to_detach.wounds) >= 1)
target.balloon_alert(target, "can't detach wounded limbs!")
playsound(target, 'sound/machines/buzz-sigh.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
return
var/leg_check = IGNORE_USER_LOC_CHANGE
if (istype(limb_to_detach, /obj/item/bodypart/leg))
leg_check = NONE

target.balloon_alert(target, "detaching limb...")
playsound(target, 'sound/items/rped.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
target.visible_message(span_notice("[target] shuffles [target.p_their()] [limb_to_detach.name] forward, actuators hissing and whirring as [target.p_they()] disengage[target.p_s()] the limb from its mount..."))

if(do_after(target, 1 SECONDS, timed_action_flags = leg_check, extra_checks = CALLBACK(src, PROC_REF(detaching_check), target, limb_to_detach)))
StartCooldown()
target.visible_message(span_notice("With a gentle twist, [target] finally pries [target.p_their()] [limb_to_detach.name] free from its socket."))
limb_to_detach.drop_limb()
target.put_in_hands(limb_to_detach)
target.balloon_alert(target, "limb detached!")
if(prob(5))
playsound(target, 'sound/items/champagne_pop.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
else
playsound(target, 'sound/items/deconstruct.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
else
target.balloon_alert(target, "interrupted!")
playsound(target, 'sound/machines/buzz-sigh.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
return TRUE

0 comments on commit d6bedbd

Please sign in to comment.