mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Adds the Surgical Processor upgrade for medical cyborgs, available from exosuit fabricators after 'Cyborg Utilities: Medical' is researched. This upgrade allows medical cyborgs to scan surgery disks, or copy procedures from an operating computer. The cyborg can then initiate scanned procedures. Cyborgs can also now perform surgery steps that have no instrument requirement. Medical cyborgs were generally unable to perform any advanced surgeries outside of some specific circumstances. This update allows cyborgs to make use of the advanced surgeries. Some advanced surgeries have steps that require a hand without any tools; this update allows cyborgs to perform these steps as well. Note that surgeries must be obtained through research or a disk somehow before the cyborgs can scan them.
138 lines
4.9 KiB
Plaintext
138 lines
4.9 KiB
Plaintext
/datum/surgery_step
|
|
var/name
|
|
var/list/implements = list() //format is path = probability of success. alternatively
|
|
var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type.
|
|
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 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
|
|
var/time = 10 //how long does the step take?
|
|
var/repeatable = 0 //can this step be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
|
|
var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob.
|
|
var/require_all_chems = TRUE //any on the list or all on the list?
|
|
|
|
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
|
|
var/success = FALSE
|
|
if(accept_hand)
|
|
if(!tool)
|
|
success = TRUE
|
|
if(iscyborg(user))
|
|
success = TRUE
|
|
|
|
if(accept_any_item)
|
|
if(tool && tool_check(user, tool))
|
|
success = TRUE
|
|
|
|
else if(tool)
|
|
for(var/key in implements)
|
|
var/match = FALSE
|
|
|
|
if(ispath(key) && istype(tool, key))
|
|
match = TRUE
|
|
else if(tool.tool_behaviour == key)
|
|
match = TRUE
|
|
|
|
if(match)
|
|
implement_type = key
|
|
if(tool_check(user, tool))
|
|
success = TRUE
|
|
break
|
|
|
|
if(success)
|
|
if(target_zone == surgery.location)
|
|
if(get_location_accessible(target, target_zone) || surgery.ignore_clothes)
|
|
initiate(user, target, target_zone, tool, surgery, try_to_fail)
|
|
return 1
|
|
else
|
|
to_chat(user, "<span class='warning'>You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!</span>")
|
|
return 1 //returns 1 so we don't stab the guy in the dick or wherever.
|
|
|
|
if(repeatable)
|
|
var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
|
|
if(next_step)
|
|
surgery.status++
|
|
if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery))
|
|
return 1
|
|
else
|
|
surgery.status--
|
|
|
|
if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
|
|
surgery.step_in_progress = 1
|
|
|
|
var/speed_mod = 1
|
|
|
|
if(preop(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 hand or any item step.
|
|
prob_chance = implements[implement_type]
|
|
prob_chance *= surgery.get_propability_multiplier()
|
|
|
|
if((prob(prob_chance) || iscyborg(user)) && chem_check(target) && !try_to_fail)
|
|
if(success(user, target, target_zone, tool, surgery))
|
|
advance = 1
|
|
else
|
|
if(failure(user, target, target_zone, tool, surgery))
|
|
advance = 1
|
|
|
|
if(advance && !repeatable)
|
|
surgery.status++
|
|
if(surgery.status > surgery.steps.len)
|
|
surgery.complete()
|
|
|
|
surgery.step_in_progress = 0
|
|
|
|
|
|
/datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
user.visible_message("[user] begins to perform surgery on [target].", "<span class='notice'>You begin to perform surgery on [target]...</span>")
|
|
|
|
|
|
/datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
user.visible_message("[user] succeeds!", "<span class='notice'>You succeed.</span>")
|
|
return 1
|
|
|
|
/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
user.visible_message("<span class='warning'>[user] screws up!</span>", "<span class='warning'>You screw up!</span>")
|
|
return 0
|
|
|
|
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
|
|
return 1
|
|
|
|
/datum/surgery_step/proc/chem_check(mob/living/carbon/target)
|
|
if(!LAZYLEN(chems_needed))
|
|
return TRUE
|
|
|
|
if(require_all_chems)
|
|
. = TRUE
|
|
for(var/R in chems_needed)
|
|
if(!target.reagents.has_reagent(R))
|
|
return FALSE
|
|
else
|
|
. = FALSE
|
|
for(var/R in chems_needed)
|
|
if(target.reagents.has_reagent(R))
|
|
return TRUE
|
|
|
|
/datum/surgery_step/proc/get_chem_list()
|
|
if(!LAZYLEN(chems_needed))
|
|
return
|
|
var/list/chems = list()
|
|
for(var/R in chems_needed)
|
|
var/datum/reagent/temp = GLOB.chemical_reagents_list[R]
|
|
if(temp)
|
|
var/chemname = temp.name
|
|
chems += chemname
|
|
return english_list(chems, and_text = require_all_chems ? " and " : " or ")
|