Skip to content

Commit

Permalink
disable old & enable new surgery_step
Browse files Browse the repository at this point in the history
  • Loading branch information
intercepti0n committed Oct 11, 2023
1 parent 7534d21 commit f027e32
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 40 deletions.
18 changes: 5 additions & 13 deletions baystation12.dme
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
#include "code\_helpers\spawn_sync.dm"
#include "code\_helpers\sql.dm"
#include "code\_helpers\storage.dm"
#include "code\_helpers\surgery.dm"
#include "code\_helpers\text.dm"
#include "code\_helpers\text_processor.dm"
#include "code\_helpers\text_sql_encoding.dm"
Expand Down Expand Up @@ -450,6 +451,10 @@
#include "code\datums\supplypacks\security.dm"
#include "code\datums\supplypacks\supply.dm"
#include "code\datums\supplypacks\supplypack.dm"
#include "code\datums\surgery\_defines.dm"
#include "code\datums\surgery\surgery_item.dm"
#include "code\datums\surgery\surgery_status.dm"
#include "code\datums\surgery\surgery_step.dm"
#include "code\datums\trading\_trading_defines.dm"
#include "code\datums\trading\ai.dm"
#include "code\datums\trading\armor.dm"
Expand Down Expand Up @@ -2801,19 +2806,6 @@
#include "code\modules\splash_text\splash_text.dm"
#include "code\modules\supermatter\setup_supermatter.dm"
#include "code\modules\supermatter\supermatter.dm"
#include "code\modules\surgery\_defines.dm"
#include "code\modules\surgery\bones.dm"
#include "code\modules\surgery\encased.dm"
#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
#include "code\modules\surgery\implant.dm"
#include "code\modules\surgery\limb_reattach.dm"
#include "code\modules\surgery\metroids.dm"
#include "code\modules\surgery\organs_internal.dm"
#include "code\modules\surgery\other.dm"
#include "code\modules\surgery\robotics.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\~defines.dm"
#include "code\modules\synthesized_instruments\echo_editor.dm"
#include "code\modules\synthesized_instruments\env_editor.dm"
#include "code\modules\synthesized_instruments\event_manager.dm"
Expand Down
45 changes: 45 additions & 0 deletions code/_helpers/surgery.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/proc/sort_surgeries()
var/gap = length(GLOB.surgery_steps)
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 <= length(GLOB.surgery_steps); 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

//check if mob is lying down on something we can operate him on.
/proc/can_operate(mob/living/carbon/M, mob/living/carbon/user)
var/turf/T = get_turf(M)
if(locate(/obj/machinery/optable, T))
. = TRUE
if(locate(/obj/structure/bed, T))
. = TRUE
if(locate(/obj/structure/table, T))
. = TRUE
if(locate(/obj/effect/rune/, T))
. = TRUE

if(M == user)
var/hitzone = check_zone(user.zone_sel.selecting)
var/list/badzones = list(BP_HEAD)
if(user.hand)
badzones += BP_L_ARM
badzones += BP_L_HAND
else
badzones += BP_R_ARM
badzones += BP_R_HAND
if(hitzone in badzones)
return FALSE

/proc/agjust_organ_image(obj/item/organ/O)
var/image/I = image(icon = O.icon, icon_state = O.icon_state)
I.overlays = O.overlays
I.pixel_y = -5
return I
24 changes: 0 additions & 24 deletions code/_helpers/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -945,30 +945,6 @@ var/global/list/common_tools = list(
/obj/item/clothing/mask/smokable/cigarette/can_puncture()
return lit

//check if mob is lying down on something we can operate him on.
/proc/can_operate(mob/living/carbon/M, mob/living/carbon/user)
var/turf/T = get_turf(M)
if(locate(/obj/machinery/optable, T))
. = TRUE
if(locate(/obj/structure/bed, T))
. = TRUE
if(locate(/obj/structure/table, T))
. = TRUE
if(locate(/obj/effect/rune/, T))
. = TRUE

if(M == user)
var/hitzone = check_zone(user.zone_sel.selecting)
var/list/badzones = list(BP_HEAD)
if(user.hand)
badzones += BP_L_ARM
badzones += BP_L_HAND
else
badzones += BP_R_ARM
badzones += BP_R_HAND
if(hitzone in badzones)
return FALSE

/proc/reverse_direction(dir)
switch(dir)
if(NORTH)
Expand Down
8 changes: 5 additions & 3 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@ avoid code duplication. This includes items that may sometimes act as a standard

/mob/living/attackby(obj/item/I, mob/user)
if(!ismob(user))
return 0
if(can_operate(src, user) && I.do_surgery(src, user)) //Surgery
return 1
return FALSE

if(can_operate(src, user) && I.do_surgery(src, user))
return TRUE

return I.attack(src, user, user.zone_sel.selecting)

/mob/living/carbon/human/attackby(obj/item/I, mob/user)
Expand Down
23 changes: 23 additions & 0 deletions code/datums/surgery/_defines.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// Causes hands to become bloody.
#define BLOODY_HANDS (1 << 0)
/// Causes body to become bloody.
#define BLOODY_BODY (1 << 1)

/// Delta multiplier for all surgeries, ranges from 0.9 to 1.1.
#define SURGERY_DURATION_DELTA rand(9, 11) / 10

#define SURGERY_FAILURE -1
#define SURGERY_BLOCKED -2

#define CUT_DURATION 30
#define AMPUTATION_DURATION 125
#define CLAMP_DURATION 35
#define RETRACT_DURATION 25
#define CAUTERIZE_DURATION 35
#define GLUE_BONE_DURATION 35
#define BONE_MEND_DURATION 40
#define SAW_DURATION 50
#define DRILL_DURATION 70
#define ATTACH_DURATION 50
#define ORGAN_FIX_DURATION 35
#define CONNECT_DURATION 50
17 changes: 17 additions & 0 deletions code/datums/surgery/surgery_item.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/obj/item/proc/do_surgery(mob/living/carbon/target, mob/living/user)
if (!istype(target))
return FALSE

if (user.a_intent == I_HURT)
return FALSE

var/zone = user.zone_sel.selecting
if(zone in target.surgery_status.ongoing_steps)
to_chat(user, SPAN("warning", "You can't operate on this area while surgery is already in progress."))
return TRUE

for(var/datum/surgery_step/S in GLOB.surgery_steps)
if(S.do_step(user, target, src, zone))
return TRUE

return FALSE
18 changes: 18 additions & 0 deletions code/datums/surgery/surgery_status.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/datum/surgery_status
/**
* List of zones where surgery steps are currently performed.
*/
var/list/ongoing_steps = list()
/**
* Associative list of string -> type, where string is zone name and
* type is a reference to an operated organ.
*/
var/list/operated_organs = list()

/datum/surgery_status/proc/start_surgery(obj/item/organ/target_organ, target_zone)
LAZYADD(ongoing_steps, target_zone)
LAZYADDASSOC(operated_organs, target_zone, target_organ)

/datum/surgery_status/proc/stop_surgery(target_zone)
LAZYREMOVE(ongoing_steps, target_zone)
LAZYREMOVE(operated_organs, target_zone)
138 changes: 138 additions & 0 deletions code/datums/surgery/surgery_step.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/datum/surgery_step
var/can_infect = FALSE
var/accessible = FALSE
var/delicate = FALSE
var/blood_level = 0
var/shock_level = 0
var/priority = 0
var/duration = 0
var/list/allowed_tools = null

/// tool check -> organ selection -> organ checks -> surgery init -> orher stuff
/datum/surgery_step/proc/do_step(atom/user, mob/living/carbon/human/target, obj/item/tool, target_zone)
if(!check_tool(tool))
return FALSE

if(accessible && !check_clothing(target, target_zone))
return FALSE

var/obj/item/organ/target_organ = target.get_organ(pick_organ_tag(user, target, target_zone))
if(!check_organ(target, target_organ, tool, target_zone))
return FALSE

// At this point we can access selected organ via `surgery_status`.
target.surgery_status.start_surgery(target_organ, target_zone)
initiate(user, target, tool, target_zone)
target.surgery_status.stop_surgery(target_zone)

target.update_surgery()

return TRUE

/datum/surgery_step/proc/check_tool(obj/item/tool)
var/bool = (tool.type in allowed_tools)
return bool

/datum/surgery_step/proc/check_clothing(mob/living/carbon/target, target_zone)
var/list/clothes = get_target_clothes(target, target_zone)
for(var/obj/item/clothing/C in clothes)
if(C.body_parts_covered & body_part_flags[target_zone])
return FALSE
return TRUE

/datum/surgery_step/proc/check_organ(mob/living/carbon/human/target, obj/item/organ/target_organ, obj/item/tool, target_zone)
if(!istype(target_organ))
return FALSE

return TRUE

/datum/surgery_step/proc/pick_organ_tag(atom/user, mob/living/carbon/target, target_zone)
return target_zone

/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone)
var/obj/item/target_organ = target.surgery_status.operated_organs[target_zone]
if(can_infect && target_organ)
spread_germs_to_organ(user, target_organ)

if(ishuman(user) && prob(60))
var/mob/living/carbon/human/H = user
if(blood_level & BLOODY_HANDS)
H.bloody_hands(target, 0)
if(blood_level & BLOODY_BODY)
H.bloody_body(target, 0)

if(shock_level)
target.shock_stage = max(target.shock_stage, shock_level)

var/success_chance = calc_success_chance(user, target, tool)
var/surgery_duration = SURGERY_DURATION_DELTA * duration * tool.surgery_speed
if(prob(success_chance) && do_mob(user, target, surgery_duration))
success(user, target, tool, target_zone)
else
failure(user, target, tool, target_zone)

/datum/surgery_step/proc/spread_germs_to_organ(mob/living/carbon/human/user, obj/item/organ/external/target_organ)
if(!istype(user) || !istype(target_organ))
return

var/germ_level = user.germ_level
var/obj/item/clothing/gloves/G = user.gloves
if(istype(G) && !(G.clipped && prob(75)))
germ_level = G.germ_level

target_organ.germ_level = max(germ_level, target_organ.germ_level)

/datum/surgery_step/proc/calc_success_chance(mob/living/user, mob/living/carbon/human/target, obj/item/tool, target_zone)
. = allowed_tools[tool.type]
if(user == target)
. -= 10

if(ishuman(user))
var/mob/living/carbon/human/H = user
. -= round(H.shock_stage * 0.5)
if(H.eye_blurry)
. -= 20
if(H.eye_blind)
. -= 60

if(delicate)
if(ishuman(user) && user?.slurring)
. -= 10
if(!target.lying)
. -= 30

var/turf/T = get_turf(target)
if(locate(/obj/machinery/optable, T))
. -= 0
else if(locate(/obj/structure/bed, T))
. -= 5
else if(locate(/obj/structure/table, T))
. -= 10
else if(locate(/obj/effect/rune/, T))
. -= 10

. = max(., 0)

/datum/surgery_step/proc/success(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone)
pass()

/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone)
pass()

/datum/surgery_step/proc/announce_preop(mob/living/user, self_message, blind_message)
user.visible_message(
self_message,
blind_message
)

/datum/surgery_step/proc/announce_success(mob/living/user, self_message, blind_message)
user.visible_message(
SPAN("notice", self_message),
SPAN("notice", blind_message)
)

/datum/surgery_step/proc/announce_failure(mob/living/user, self_message, blind_message)
user.visible_message(
SPAN("warning", self_message),
SPAN("warning", blind_message)
)

0 comments on commit f027e32

Please sign in to comment.