mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-26 02:02:39 +00:00
* Refactors Mutations * traits * more work * styling fix * yet even more work * oh hush * almost there * it continues yet further * and that's genetics done * and that's it folks * last bit and golem fixup * oof * oops * tweaks and fixes * styling
225 lines
7.2 KiB
Plaintext
225 lines
7.2 KiB
Plaintext
///Datum Surgery Helpers//
|
|
/datum/surgery
|
|
var/name
|
|
var/status = 1
|
|
var/list/steps = list()
|
|
/*
|
|
var/eyes = 0
|
|
var/face = 0
|
|
var/appendix = 0
|
|
var/ribcage = 0
|
|
var/head_reattach = 0 //Steps in a surgery
|
|
*/
|
|
|
|
var/can_cancel = 1
|
|
var/step_in_progress = 0
|
|
var/list/in_progress = list() //Actively performing a Surgery
|
|
var/location = "chest" //Surgery location
|
|
var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs
|
|
var/list/possible_locs = list() //Multiple locations -- c0
|
|
var/obj/item/organ/organ_ref //Operable body part
|
|
var/current_organ = "organ"
|
|
var/list/allowed_mob = list(/mob/living/carbon/human)
|
|
|
|
/datum/surgery/proc/can_start(mob/user, mob/living/carbon/target)
|
|
// if 0 surgery wont show up in list
|
|
// put special restrictions here
|
|
return 1
|
|
|
|
|
|
/datum/surgery/proc/next_step(mob/user, mob/living/carbon/target)
|
|
if(step_in_progress) return
|
|
|
|
var/datum/surgery_step/S = get_surgery_step()
|
|
if(S)
|
|
if(S.try_op(user, target, user.zone_selected, user.get_active_hand(), src))
|
|
return 1
|
|
return 0
|
|
|
|
/datum/surgery/proc/get_surgery_step()
|
|
var/step_type = steps[status]
|
|
return new step_type
|
|
|
|
|
|
/datum/surgery/proc/complete(mob/living/carbon/human/target)
|
|
target.surgeries -= src
|
|
qdel(src)
|
|
|
|
|
|
|
|
/* SURGERY STEPS */
|
|
/datum/surgery_step
|
|
var/priority = 0 //steps with higher priority would be attempted first
|
|
|
|
// type path referencing tools that can be used for this step, and how well are they suited for it
|
|
var/list/allowed_tools = null
|
|
var/implement_type = null
|
|
|
|
// duration of the step
|
|
var/time = 10
|
|
|
|
var/name
|
|
var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
|
|
var/accept_any_item = 0
|
|
|
|
// evil infection stuff that will make everyone hate me
|
|
var/can_infect = 0
|
|
//How much blood this step can get on surgeon. 1 - hands, 2 - full body.
|
|
var/blood_level = 0
|
|
|
|
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
var/success = 0
|
|
if(accept_hand)
|
|
if(!tool)
|
|
success = 1
|
|
if(accept_any_item)
|
|
if(tool && tool_quality(tool))
|
|
success = 1
|
|
else
|
|
for(var/path in allowed_tools)
|
|
if(istype(tool, path))
|
|
implement_type = path
|
|
if(tool_quality(tool))
|
|
success = 1
|
|
|
|
if(success)
|
|
if(target_zone == surgery.location)
|
|
initiate(user, target, target_zone, tool, surgery)
|
|
return 1//returns 1 so we don't stab the guy in the dick or wherever.
|
|
return 0
|
|
|
|
/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
if(!can_use(user, target, target_zone, tool, surgery))
|
|
return
|
|
surgery.step_in_progress = 1
|
|
|
|
var/speed_mod = 1
|
|
|
|
if(begin_step(user, target, target_zone, tool, surgery) == -1)
|
|
surgery.step_in_progress = 0
|
|
return
|
|
|
|
if(tool)
|
|
speed_mod = tool.toolspeed
|
|
|
|
if(do_after(user, time * speed_mod, target = target))
|
|
var/advance = 0
|
|
var/prob_chance = 100
|
|
|
|
if(implement_type) //this means it isn't a require nd or any item step.
|
|
prob_chance = allowed_tools[implement_type]
|
|
prob_chance *= get_location_modifier(target)
|
|
|
|
|
|
if(!ispath(surgery.steps[surgery.status], /datum/surgery_step/robotics))//Repairing robotic limbs doesn't hurt, and neither does cutting someone out of a rig
|
|
if(ishuman(target))
|
|
var/mob/living/carbon/human/H = target //typecast to human
|
|
prob_chance *= get_pain_modifier(H)//operating on conscious people is hard.
|
|
|
|
if(prob(prob_chance) || isrobot(user))
|
|
if(end_step(user, target, target_zone, tool, surgery))
|
|
advance = 1
|
|
else
|
|
if(fail_step(user, target, target_zone, tool, surgery))
|
|
advance = 1
|
|
|
|
if(advance)
|
|
surgery.status++
|
|
if(surgery.status > surgery.steps.len)
|
|
surgery.complete(target)
|
|
|
|
surgery.step_in_progress = 0
|
|
|
|
//returns how well tool is suited for this step
|
|
/datum/surgery_step/proc/tool_quality(obj/item/tool)
|
|
for(var/T in allowed_tools)
|
|
if(istype(tool,T))
|
|
return allowed_tools[T]
|
|
return 0
|
|
|
|
// Checks if this step applies to the user mob at all
|
|
/datum/surgery_step/proc/is_valid_target(mob/living/carbon/human/target)
|
|
if(!hasorgans(target))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
// checks whether this step can be applied with the given user and target
|
|
/datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
|
|
return 1
|
|
|
|
// does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too
|
|
/datum/surgery_step/proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
|
|
if(ishuman(target))
|
|
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
|
if(can_infect && affected)
|
|
spread_germs_to_organ(affected, user, tool)
|
|
if(ishuman(user) && !(istype(target,/mob/living/carbon/alien)) && prob(60))
|
|
var/mob/living/carbon/human/H = user
|
|
if(blood_level)
|
|
H.bloody_hands(target,0)
|
|
if(blood_level > 1)
|
|
H.bloody_body(target,0)
|
|
return
|
|
|
|
// does stuff to end the step, which is normally print a message + do whatever this step changes
|
|
/datum/surgery_step/proc/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
|
|
return
|
|
|
|
// stuff that happens when the step fails
|
|
/datum/surgery_step/proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
|
|
return null
|
|
|
|
/proc/spread_germs_to_organ(obj/item/organ/E, mob/living/carbon/human/user, obj/item/tool)
|
|
if(!istype(user) || !istype(E) || E.is_robotic() || E.sterile)
|
|
return
|
|
|
|
var/germ_level = user.germ_level
|
|
|
|
//germ spread from surgeon touching the patient
|
|
if(user.gloves)
|
|
germ_level = user.gloves.germ_level
|
|
E.germ_level = max(germ_level, E.germ_level)
|
|
spread_germs_by_incision(E, tool) //germ spread from environement to patient
|
|
|
|
/proc/spread_germs_by_incision(obj/item/organ/external/E,obj/item/tool)
|
|
if(!istype(E, /obj/item/organ/external))
|
|
return
|
|
|
|
var/germs = 0
|
|
|
|
for(var/mob/living/carbon/human/H in view(2, E.loc))//germs from people
|
|
if(AStar(E.loc, H.loc, /turf/proc/Distance, 2, simulated_only = 0))
|
|
if(!HAS_TRAIT(H, TRAIT_NOBREATH) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions
|
|
germs += H.germ_level * 0.25
|
|
|
|
for(var/obj/effect/decal/cleanable/M in view(2, E.loc))//germs from messes
|
|
if(AStar(E.loc, M.loc, /turf/proc/Distance, 2, simulated_only = 0))
|
|
germs++
|
|
|
|
if(tool && tool.blood_DNA && tool.blood_DNA.len) //germs from blood-stained tools
|
|
germs += 30
|
|
|
|
if(E.internal_organs.len)
|
|
germs = germs / (E.internal_organs.len + 1) // +1 for the external limb this eventually applies to; let's not multiply germs now.
|
|
for(var/obj/item/organ/internal/O in E.internal_organs)
|
|
if(!O.is_robotic())
|
|
O.germ_level += germs
|
|
|
|
E.germ_level += germs
|
|
|
|
/proc/sort_surgeries()
|
|
var/gap = GLOB.surgery_steps.len
|
|
var/swapped = 1
|
|
while(gap > 1 || swapped)
|
|
swapped = 0
|
|
if(gap > 1)
|
|
gap = round(gap / 1.247330950103979)
|
|
if(gap < 1)
|
|
gap = 1
|
|
for(var/i = 1; gap + i <= GLOB.surgery_steps.len; i++)
|
|
var/datum/surgery_step/l = GLOB.surgery_steps[i] //Fucking hate
|
|
var/datum/surgery_step/r = GLOB.surgery_steps[gap+i] //how lists work here
|
|
if(l.priority < r.priority)
|
|
GLOB.surgery_steps.Swap(i, gap + i)
|
|
swapped = 1
|