Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@
#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ"
///from /item/organ/proc/Remove() (/obj/item/organ/)
#define COMSIG_CARBON_LOSE_ORGAN "carbon_lose_organ"
///defined twice, in carbon and human's topics, fired when interacting with a valid embedded_object to pull it out (mob/living/carbon/target, /obj/item, /obj/item/bodypart/L)
#define COMSIG_CARBON_EMBED_RIP "item_embed_start_rip"
///called when removing a given item from a mob, from mob/living/carbon/remove_embedded_object(mob/living/carbon/target, /obj/item)
#define COMSIG_CARBON_EMBED_REMOVAL "item_embed_remove_safe"
///Called when someone attempts to cuff a carbon
#define COMSIG_CARBON_CUFF_ATTEMPTED "carbon_attempt_cuff"
#define COMSIG_CARBON_CUFF_PREVENT (1<<0)
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,6 @@
#define examining_span_normal(msg) span_infoplain(span_italics(msg))
/// For consistent examine span formatting (small size)
#define examining_span_small(msg) span_slightly_smaller(span_infoplain(span_italics(msg)))

/// When a bodypart has something embedded in it
#define COMSIG_BODYPART_ON_EMBEDDED "bodypart_on_embedded"
94 changes: 45 additions & 49 deletions code/datums/components/embedded.dm
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,11 @@

/datum/component/embedded/RegisterWithParent()
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(jostleCheck))
RegisterSignal(parent, COMSIG_CARBON_EMBED_RIP, PROC_REF(ripOut))
RegisterSignal(parent, COMSIG_CARBON_EMBED_REMOVAL, PROC_REF(safeRemove))
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(checkTweeze))
RegisterSignal(parent, COMSIG_MAGIC_RECALL, PROC_REF(magic_pull))

/datum/component/embedded/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_CARBON_EMBED_RIP, COMSIG_CARBON_EMBED_REMOVAL, COMSIG_ATOM_ATTACKBY, COMSIG_MAGIC_RECALL))
UnregisterSignal(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_ATOM_ATTACKBY, COMSIG_MAGIC_RECALL))

/datum/component/embedded/process(seconds_per_tick)
var/mob/living/carbon/victim = parent
Expand Down Expand Up @@ -176,10 +174,11 @@

if(I != weapon || src.limb != limb)
return
var/mob/living/carbon/victim = parent
var/datum/embed_data/embed_data = weapon.get_embed()
var/time_taken = embed_data.rip_time * weapon.w_class * 2 // melbert todo : remove this *2 when other people can rip out things from you
INVOKE_ASYNC(src, PROC_REF(complete_rip_out), victim, I, limb, time_taken)
limb?.open_embed_interface(usr)
// var/mob/living/carbon/victim = parent
// var/datum/embed_data/embed_data = weapon.get_embed()
// var/time_taken = embed_data.rip_time * weapon.w_class * 2 // melbert todo : remove this *2 when other people can rip out things from you
// INVOKE_ASYNC(src, PROC_REF(complete_rip_out), victim, I, limb, time_taken)

/// everything async that ripOut used to do
/datum/component/embedded/proc/complete_rip_out(mob/living/carbon/victim, obj/item/I, obj/item/bodypart/limb, time_taken)
Expand Down Expand Up @@ -241,55 +240,52 @@
if(!istype(victim) || (possible_tweezers.tool_behaviour != TOOL_HEMOSTAT && possible_tweezers.tool_behaviour != TOOL_WIRECUTTER) || user.zone_selected != limb.body_zone)
return

if(weapon != limb.embedded_objects[1]) // just pluck the first one, since we can't easily coordinate with other embedded components affecting this limb who is highest priority
return

if(ishuman(victim)) // check to see if the limb is actually exposed
var/mob/living/carbon/human/victim_human = victim
if(!victim_human.try_inject(user, limb.body_zone, INJECT_CHECK_IGNORE_SPECIES | INJECT_TRY_SHOW_ERROR_MESSAGE))
return TRUE
return COMPONENT_NO_AFTERATTACK

INVOKE_ASYNC(src, PROC_REF(tweezePluck), possible_tweezers, user)
limb.open_embed_interface(user)
return COMPONENT_NO_AFTERATTACK

/// The actual action for pulling out an embedded object with a hemostat
/datum/component/embedded/proc/tweezePluck(obj/item/possible_tweezers, mob/user)
var/mob/living/carbon/victim = parent
var/datum/embed_data/embed_data = weapon.get_embed()
var/self_pluck = (user == victim)
// quality of the tool we're using
var/tweezer_speed = possible_tweezers.toolspeed
// is this an actual piece of medical equipment
var/tweezer_safe = (possible_tweezers.tool_behaviour == TOOL_HEMOSTAT)
var/pluck_time = embed_data.rip_time * (weapon.w_class * 0.3) * (self_pluck ? 1.5 : 1) * tweezer_speed * (tweezer_safe ? 1 : 1.5)

user.visible_message(
span_danger("[user] begins plucking [weapon] from [user == victim ? user.p_their() : "[victim]'s"] [limb.plaintext_zone] with [possible_tweezers]..."),
span_notice("You start plucking [weapon] from [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [possible_tweezers]... (It will take [DisplayTimeText(pluck_time)].)"),
vision_distance = COMBAT_MESSAGE_RANGE
)

playsound(user, 'sound/surgery/hemostat1.ogg', 50, TRUE, falloff_exponent = 12, falloff_distance = 1)
if(!do_after(user, pluck_time, victim))
return
if(QDELETED(src))
return

user.visible_message(
span_danger("[user] plucks [weapon] from [victim]'s [limb.plaintext_zone][tweezer_safe ? "." : ", but hurt [victim.p_them()] in the process."]"),
span_notice("You pluck [weapon] from [victim]'s [limb.plaintext_zone][tweezer_safe ? "." : ", but it's not perfect."]"),
vision_distance = COMBAT_MESSAGE_RANGE,
)

var/obj/item/bodypart/our_limb = limb // because we null after removing

if(!tweezer_safe)
// sure it still hurts but it sucks less
damaging_removal(victim, weapon, limb, (0.4 * possible_tweezers.w_class))
safeRemove(user)

if(length(our_limb.embedded_objects))
victim.attackby(possible_tweezers, user) // loop if we can
// /datum/component/embedded/proc/tweezePluck(obj/item/possible_tweezers, mob/user)
// var/mob/living/carbon/victim = parent
// var/datum/embed_data/embed_data = weapon.get_embed()
// var/self_pluck = (user == victim)
// // quality of the tool we're using
// var/tweezer_speed = possible_tweezers.toolspeed
// // is this an actual piece of medical equipment
// var/tweezer_safe = (possible_tweezers.tool_behaviour == TOOL_HEMOSTAT)
// var/pluck_time = embed_data.rip_time * (weapon.w_class * 0.3) * (self_pluck ? 1.5 : 1) * tweezer_speed * (tweezer_safe ? 1 : 1.5)

// user.visible_message(
// span_danger("[user] begins plucking [weapon] from [user == victim ? user.p_their() : "[victim]'s"] [limb.plaintext_zone] with [possible_tweezers]..."),
// span_notice("You start plucking [weapon] from [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [possible_tweezers]... (It will take [DisplayTimeText(pluck_time)].)"),
// vision_distance = COMBAT_MESSAGE_RANGE
// )

// playsound(user, 'sound/surgery/hemostat1.ogg', 50, TRUE, falloff_exponent = 12, falloff_distance = 1)
// if(!do_after(user, pluck_time, victim))
// return
// if(QDELETED(src))
// return

// user.visible_message(
// span_danger("[user] plucks [weapon] from [victim]'s [limb.plaintext_zone][tweezer_safe ? "." : ", but hurt [victim.p_them()] in the process."]"),
// span_notice("You pluck [weapon] from [victim]'s [limb.plaintext_zone][tweezer_safe ? "." : ", but it's not perfect."]"),
// vision_distance = COMBAT_MESSAGE_RANGE,
// )

// var/obj/item/bodypart/our_limb = limb // because we null after removing

// if(!tweezer_safe)
// // sure it still hurts but it sucks less
// damaging_removal(victim, weapon, limb, (0.4 * possible_tweezers.w_class))
// safeRemove(user)

// if(length(our_limb.embedded_objects))
// victim.attackby(possible_tweezers, user) // loop if we can

/// Called when an object is ripped out of someone's body by magic or other abnormal means
/datum/component/embedded/proc/magic_pull(datum/source, mob/living/caster, obj/marked_item)
Expand Down
Loading
Loading