[GBP: NO UPDATE] Fixes xeno surgery (#19119)

* Fixes optable

* Xeno surgery works again, but at what cost?
This commit is contained in:
Luc
2022-09-25 12:47:09 -04:00
committed by GitHub
parent b5357494c4
commit e2e15d5579
7 changed files with 161 additions and 47 deletions
+1 -1
View File
@@ -273,7 +273,7 @@
#define isnewplayer(A) (istype((A), /mob/new_player))
#define isorgan(A) (istype((A), /obj/item/organ/external))
#define hasorgans(A) (ishuman(A))
#define hasorgans(A) (iscarbon(A))
#define is_admin(user) (check_rights(R_ADMIN, 0, (user)) != 0)
+6 -6
View File
@@ -8,7 +8,7 @@
use_power = IDLE_POWER_USE
idle_power_usage = 1
active_power_usage = 5
var/mob/living/carbon/human/patient
var/mob/living/carbon/patient
var/obj/machinery/computer/operating/computer
buckle_lying = -1
var/no_icon_updates = FALSE //set this to TRUE if you don't want the icons ever changing
@@ -64,13 +64,13 @@
* Updates the `patient` var to be the mob occupying the table
*/
/obj/machinery/optable/proc/update_patient()
var/mob/living/carbon/human/M = locate(/mob/living/carbon/human, loc)
if(M && IS_HORIZONTAL(M))
patient = M
var/mob/living/carbon/C = locate(/mob/living/carbon, loc)
if(C && IS_HORIZONTAL(C))
patient = C
else
patient = null
if(!no_icon_updates)
if(patient && patient.pulse)
if(C && C.pulse)
icon_state = "table2-active"
else
icon_state = "table2-idle"
@@ -107,7 +107,7 @@
set name = "Climb On Table"
set category = "Object"
set src in oview(1)
if(usr.stat || !ishuman(usr) || usr.restrained() || !check_table())
if(usr.stat || !iscarbon(usr) || usr.restrained() || !check_table())
return
take_patient(usr, usr)
+10 -4
View File
@@ -64,7 +64,7 @@
/obj/machinery/computer/operating/ui_data(mob/user)
var/list/data = list()
var/mob/living/carbon/human/occupant
var/mob/living/carbon/occupant
if(table)
occupant = table.patient
data["hasOccupant"] = occupant ? 1 : 0
@@ -111,11 +111,12 @@
occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32
if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits))
var/mob/living/carbon/human/H = occupant
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
occupantData["hasBlood"] = 1
occupantData["bloodLevel"] = round(occupant.blood_volume)
occupantData["bloodMax"] = occupant.max_blood
occupantData["bloodPercent"] = round(100*(occupant.blood_volume/occupant.max_blood), 0.01) //copy pasta ends here
occupantData["bloodMax"] = H.max_blood
occupantData["bloodPercent"] = round(100*(occupant.blood_volume/H.max_blood), 0.01) //copy pasta ends here
occupantData["bloodType"] = occupant.dna.blood_type
if(length(occupant.surgeries))
@@ -198,7 +199,12 @@
if(isNewPatient)
atom_say("New patient detected, loading stats")
atom_say("[table.patient], [table.patient.dna.blood_type] blood, [patientStatus]")
var/blood_type_msg
if(ishuman(table.patient))
blood_type_msg = table.patient.dna.blood_type
else
blood_type_msg = "\[ERROR: UNKNOWN\]"
atom_say("[table.patient], [blood_type_msg] blood, [patientStatus]")
SStgui.update_uis(src)
patientStatusHolder = table.patient.stat
currentPatient = table.patient
+1 -1
View File
@@ -263,7 +263,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
/obj/item/attack_hand(mob/user as mob, pickupfireoverride = FALSE)
if(!user) return 0
if(hasorgans(user))
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"]
if(user.hand)
@@ -91,7 +91,7 @@
/obj/effect/hallucination/fake_item/attack_hand(mob/living/user)
if(user != target)
return
if(hasorgans(user))
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"]
if(user.hand)
+4 -4
View File
@@ -1,4 +1,4 @@
/mob/living/carbon/human
/mob/living/carbon
var/last_pain_message = ""
var/next_pain_time = 0
@@ -7,7 +7,7 @@
*
* Returns TRUE if the mob can feel pain, FALSE otherwise
*/
/mob/living/carbon/human/proc/can_feel_pain()
/mob/living/carbon/proc/can_feel_pain()
if(stat >= UNCONSCIOUS)
return FALSE
if(reagents.has_reagent("morphine"))
@@ -21,7 +21,7 @@
// partname is the name of a body part
// amount is a num from 1 to 100
/mob/living/carbon/human/proc/pain(partname, amount)
/mob/living/carbon/proc/pain(partname, amount)
if(!can_feel_pain())
return
if(world.time < next_pain_time)
@@ -41,7 +41,7 @@
// message is the custom message to be displayed
/mob/living/carbon/human/proc/custom_pain(message)
/mob/living/carbon/proc/custom_pain(message)
if(!can_feel_pain())
return
+138 -30
View File
@@ -50,9 +50,18 @@
/datum/surgery/organ_manipulation/alien
name = "Alien Organ Manipulation"
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)
requires_bodypart = FALSE // xenos just don't have "bodyparts"
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
target_mobtypes = list(/mob/living/carbon/alien/humanoid)
steps = list(/datum/surgery_step/saw_carapace,/datum/surgery_step/cut_carapace, /datum/surgery_step/retract_carapace,/datum/surgery_step/proxy/manipulate_organs,)
steps = list(
/datum/surgery_step/saw_carapace,
/datum/surgery_step/cut_carapace,
/datum/surgery_step/retract_carapace,
/datum/surgery_step/proxy/manipulate_organs/alien,
/datum/surgery_step/generic/seal_carapace
)
/datum/surgery/organ_manipulation/can_start(mob/user, mob/living/carbon/target)
@@ -122,11 +131,49 @@
/datum/surgery/intermediate/bleeding
)
// have to redefine all of these because xenos don't technically have bodyparts.
/datum/surgery/intermediate/manipulate/extract/xeno
requires_bodypart = FALSE
/datum/surgery/intermediate/manipulate/implant/xeno
requires_bodypart = FALSE
/datum/surgery/intermediate/manipulate/mend/xeno
requires_bodypart = FALSE
/datum/surgery/intermediate/manipulate/clean/xeno
requires_bodypart = FALSE
/datum/surgery_step/proxy/manipulate_organs/alien
name = "Manipulate Organs Xeno (proxy)"
branches = list(
/datum/surgery/intermediate/manipulate/extract/xeno,
/datum/surgery/intermediate/manipulate/implant/xeno,
/datum/surgery/intermediate/manipulate/mend/xeno,
/datum/surgery/intermediate/manipulate/clean/xeno
)
// Internal surgeries.
/datum/surgery_step/internal
can_infect = TRUE
blood_level = SURGERY_BLOODSPREAD_HANDS
/**
* Get an internal list of organs for a zone (or an external organ).
*
* Helper function since we end up calling this a ton to work with carbons
*/
/datum/surgery_step/internal/proc/get_organ_list(target_zone, mob/living/carbon/target, obj/item/organ/external/affected)
var/list/organs
if(affected && istype(affected))
organs = affected.internal_organs
else
organs = target.get_organs_zone(target_zone)
return organs
/datum/surgery_step/internal/manipulate_organs/mend
name = "mend organs"
allowed_tools = list(
@@ -146,7 +193,7 @@
return tool_name
/datum/surgery_step/internal/manipulate_organs/mend/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
/datum/surgery_step/internal/manipulate_organs/mend/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/tool_name = get_tool_name(tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -157,8 +204,9 @@
var/any_organs_damaged = FALSE
var/list/organs = get_organ_list(target_zone, target, affected)
for(var/obj/item/organ/internal/I in affected.internal_organs)
for(var/obj/item/organ/internal/I in organs)
if(I && I.damage)
any_organs_damaged = TRUE
if(!I.is_robotic() && !istype(tool, /obj/item/stack/nanopaste))
@@ -177,8 +225,8 @@
return SURGERY_BEGINSTEP_SKIP
if(affected)
var/mob/living/carbon/human/H = target
H.custom_pain("The pain in your [affected.name] is living hell!")
var/mob/living/carbon/C = target
C.custom_pain("The pain in your [affected.name] is living hell!")
return ..()
@@ -188,7 +236,9 @@
if(!hasorgans(target))
return SURGERY_STEP_INCOMPLETE
for(var/obj/item/organ/internal/I in affected.internal_organs)
var/list/organs = get_organ_list(target_zone, target, affected)
for(var/obj/item/organ/internal/I in organs)
if(I)
I.surgeryize()
if(I && I.damage)
@@ -209,11 +259,12 @@
/datum/surgery_step/internal/manipulate_organs/mend/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(!hasorgans(target))
return SURGERY_STEP_INCOMPLETE
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(
"<span class='warning'> [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with [tool]!</span>",
"<span class='warning'> Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with [tool]!</span>"
"<span class='warning'> [user]'s hand slips, getting messy and tearing the inside of [target]'s [parse_zone(target_zone)] with [tool]!</span>",
"<span class='warning'> Your hand slips, getting messy and tearing the inside of [target]'s [parse_zone(target_zone)] with [tool]!</span>"
)
var/dam_amt = 2
@@ -224,9 +275,12 @@
else if(istype(tool, /obj/item/stack/medical/bruise_pack) || istype(tool, /obj/item/stack/nanopaste))
dam_amt = 5
target.adjustToxLoss(10)
affected.receive_damage(5)
if(affected)
affected.receive_damage(5)
for(var/obj/item/organ/internal/I in affected.internal_organs)
var/list/organs = get_organ_list(target_zone, target, affected)
for(var/obj/item/organ/internal/I in organs)
if(I && I.damage && !(I.tough))
I.receive_damage(dam_amt,0)
@@ -421,26 +475,27 @@
var/obj/item/reagent_containers/C = tool
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_selected)
var/obj/item/organ/external/affected = target.get_organ(user.zone_selected)
for(var/obj/item/organ/internal/I in affected.internal_organs)
if(I)
if(C.reagents.total_volume <= 0) //end_step handles if there is not enough reagent
user.visible_message(
"[user] notices [tool] is empty.",
"You notice [tool] is empty."
)
return SURGERY_BEGINSTEP_SKIP
var/list/organs = get_organ_list(target_zone, target, affected)
var/msg = "[user] starts pouring some of [tool] over [target]'s [I.name]."
var/self_msg = "You start pouring some of [tool] over [target]'s [I.name]."
if(istype(C, /obj/item/reagent_containers/syringe))
msg = "[user] begins injecting [tool] into [target]'s [I.name]."
self_msg = "You begin injecting [tool] into [target]'s [I.name]."
user.visible_message(msg, self_msg)
if(H && affected)
H.custom_pain("Something burns horribly in your [affected.name]!")
for(var/obj/item/organ/internal/I in organs)
if(!I)
continue
if(C.reagents.total_volume <= 0) //end_step handles if there is not enough reagent
user.visible_message(
"[user] notices [tool] is empty.",
"You notice [tool] is empty."
)
return SURGERY_BEGINSTEP_SKIP
var/msg = "[user] starts pouring some of [tool] over [target]'s [I.name]."
var/self_msg = "You start pouring some of [tool] over [target]'s [I.name]."
if(istype(C, /obj/item/reagent_containers/syringe))
msg = "[user] begins injecting [tool] into [target]'s [I.name]."
self_msg = "You begin injecting [tool] into [target]'s [I.name]."
user.visible_message(msg, self_msg)
target.custom_pain("Something burns horribly in your [parse_zone(target_zone)]!")
return ..()
@@ -452,6 +507,8 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/list/organs = get_organ_list(target_zone, target, affected)
var/obj/item/reagent_containers/C = tool
var/datum/reagents/R = C.reagents
var/ethanol = 0 //how much alcohol is in the thing
@@ -467,7 +524,7 @@
spaceacillin = R.get_reagent_amount("spaceacillin")
for(var/obj/item/organ/internal/I in affected.internal_organs)
for(var/obj/item/organ/internal/I in organs)
if(!I) // if you have a null organ I wish you the best
continue
if(I.germ_level < INFECTION_LEVEL_ONE / 2 && !(I.status & ORGAN_DEAD)) // not dead, don't need to inject mito either
@@ -735,4 +792,55 @@
user.visible_message(msg, self_msg)
return SURGERY_STEP_RETRY
// redefine cauterize for every step because of course it relies on get_organ()
/datum/surgery_step/generic/seal_carapace/
name = "seal carapace"
allowed_tools = list(
/obj/item/scalpel/laser = 100,
TOOL_CAUTERY = 100,
/obj/item/clothing/mask/cigarette = 90,
/obj/item/lighter = 60,
TOOL_WELDER = 30
)
time = 2.4 SECONDS
/datum/surgery_step/generic/seal_carapace/proc/zone_name(target_zone)
var/zone = target_zone
if(target_zone == BODY_ZONE_CHEST)
zone = "torso"
else if(target_zone == BODY_ZONE_PRECISE_GROIN)
zone = "lower abdomen"
return zone
/datum/surgery_step/generic/seal_carapace/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/zone = zone_name(target_zone)
user.visible_message(
"[user] is beginning to cauterize the incision on [target]'s [zone] with \the [tool].",
"You are beginning to cauterize the incision on [target]'s [zone] with \the [tool]."
)
target.custom_pain("Your [zone] is being burned!")
return ..()
/datum/surgery_step/generic/seal_carapace/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/zone = zone_name(target_zone)
user.visible_message(
"<span class='notice'>[user] cauterizes the incision on [target]'s [zone] with \the [tool].</span>",
"<span class='notice'>You cauterize the incision on [target]'s [zone] with \the [tool].</span>"
)
return SURGERY_STEP_CONTINUE
/datum/surgery_step/generic/seal_carapace/fail_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/zone = zone_name(target_zone)
user.visible_message(
"<span class='warning'>[user]'s hand slips, leaving a small burn on [target]'s [zone] with \the [tool]!</span>",
"<span class='warning'>Your hand slips, leaving a small burn on [target]'s [zone] with \the [tool]!</span>"
)
target.apply_damage(3, BURN, target_zone)
return SURGERY_STEP_RETRY
#undef MITO_REVIVAL_COST