Files
Bubberstation/code/game/objects/items/surgery_tray.dm
nevimer 6e9f2ccfc0 Merge remote-tracking branch 'tgstation/master' into upstream-12-15
# Conflicts:
#	.github/workflows/compile_all_maps.yml
#	.github/workflows/run_integration_tests.yml
#	_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
#	code/_onclick/hud/credits.dm
#	code/controllers/subsystem/networks/id_access.dm
#	code/datums/diseases/advance/advance.dm
#	code/datums/diseases/advance/symptoms/heal.dm
#	code/game/machinery/doors/door.dm
#	code/game/objects/structures/crates_lockers/closets/secure/medical.dm
#	code/game/objects/structures/crates_lockers/closets/secure/security.dm
#	code/modules/antagonists/malf_ai/malf_ai_modules.dm
#	code/modules/jobs/job_types/_job.dm
#	code/modules/loadout/categories/accessories.dm
#	code/modules/loadout/loadout_helpers.dm
#	code/modules/loadout/loadout_items.dm
#	code/modules/loadout/loadout_preference.dm
#	code/modules/mob/living/silicon/robot/robot_defense.dm
#	code/modules/mod/mod_theme.dm
#	code/modules/projectiles/ammunition/energy/laser.dm
#	code/modules/reagents/reagent_containers/cups/drinks.dm
#	code/modules/shuttle/mobile_port/variants/supply.dm
#	code/modules/surgery/organs/internal/eyes/_eyes.dm
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_heretic.png
#	icons/hud/screen_full.dmi
2025-12-15 18:12:29 -05:00

270 lines
9.1 KiB
Plaintext

/**
* Surgery Trays
* A storage object that displays tools in its contents based on tier, better tools are more visible.
* Can be folded up and carried. Click it to draw a random tool.
*/
/obj/item/surgery_tray
name = "surgery tray"
desc = "A Deforest brand medical cart. It is a folding model, meaning the wheels on the bottom can be retracted and the body used as a tray."
icon = 'icons/obj/medical/medicart.dmi'
icon_state = "tray"
w_class = WEIGHT_CLASS_BULKY
slowdown = 1
item_flags = SLOWS_WHILE_IN_HAND
pass_flags = NONE
custom_materials = list(/datum/material/silver = SHEET_MATERIAL_AMOUNT, /datum/material/iron = SHEET_MATERIAL_AMOUNT)
/// If true we're currently portable
var/is_portable = TRUE
/// List of contents to populate with in populatecontents()
var/list/starting_items = list()
/// Fills the tray with items it should contain on creation
/obj/item/surgery_tray/proc/populate_contents()
for(var/obj in starting_items)
new obj(src)
update_appearance(UPDATE_ICON)
return
/obj/item/surgery_tray/Initialize(mapload, effect_spawner = FALSE)
. = ..()
AddElement(/datum/element/drag_pickup)
create_storage(storage_type = /datum/storage/surgery_tray)
populate_contents()
register_context()
set_tray_mode(is_portable)
/obj/item/surgery_tray/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
context[SCREENTIP_CONTEXT_LMB] = "Take a random tool"
context[SCREENTIP_CONTEXT_RMB] = "Take a specific tool"
return CONTEXTUAL_SCREENTIP_SET
/obj/item/surgery_tray/update_icon_state()
. = ..()
icon_state = is_portable ? "tray" : "medicart"
/obj/item/surgery_tray/update_desc()
. = ..()
if(is_portable)
desc = "The wheels and bottom storage of this medical cart have been stowed away, \
leaving a cumbersome tray in its place."
else
desc = initial(desc)
/obj/item/surgery_tray/examine(mob/living/carbon/human/user)
. = ..()
. += is_portable \
? span_notice("You can click and drag it to yourself to pick it up, then use it in your hand to make it a cart!") \
: span_notice("You can click and drag it to yourself to turn it into a tray!")
. += span_notice("The top is <b>screwed</b> on.")
/obj/item/surgery_tray/update_overlays()
. = ..()
// assoc list of all overlays, key = the item generating the overlay, value = the overlay string
var/list/surgery_overlays = list()
// assoc list of tool behaviors to fastest toolspeed of that type we already have
// easy way for us to check if there are any lower quality tools within
var/list/recorded_tool_speeds = list()
// handle drapes separately so they're always on the bottom
if (locate(/obj/item/surgical_drapes) in contents)
. += "drapes"
// compile all the overlays from items inside us
for(var/obj/item/surgery_tool in src)
// the overlay we will use if we want to display this one
var/actual_overlay = surgery_tool.get_surgery_tool_overlay(tray_extended = !is_portable)
if (isnull(actual_overlay))
continue // nothing to see here
// if we don't have tool behaviour then just record the overlay
if(!length(surgery_tool.get_all_tool_behaviours()))
surgery_overlays[surgery_tool] = actual_overlay
continue
// if we have at least one tool behaviour, check if we already recorded a faster one
for (var/surgery_tool_type in surgery_tool.get_all_tool_behaviours())
var/highest_speed = LAZYACCESS(recorded_tool_speeds, surgery_tool_type) || INFINITY // bigger number = slower
if(surgery_tool.toolspeed > highest_speed)
continue
// the existing tool was worse than us, ditch it
surgery_overlays -= surgery_tool_type
LAZYSET(recorded_tool_speeds, surgery_tool_type, surgery_tool.toolspeed)
surgery_overlays[surgery_tool_type] = actual_overlay
for(var/surgery_tool in surgery_overlays)
. |= surgery_overlays[surgery_tool]
///Sets the surgery tray's deployment state. Silent if user is null.
/obj/item/surgery_tray/proc/set_tray_mode(new_mode, mob/user)
is_portable = new_mode
density = !is_portable
if(user)
user.visible_message(span_notice("[user] [is_portable ? "retracts" : "extends"] [src]'s wheels."), span_notice("You [is_portable ? "retract" : "extend"] [src]'s wheels."))
if(is_portable)
interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
passtable_on(src, type)
RemoveElement(/datum/element/noisy_movement)
else
interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
passtable_off(src, type)
AddElement(/datum/element/noisy_movement)
update_appearance()
/obj/item/surgery_tray/equipped(mob/user, slot, initial)
. = ..()
if(!is_portable)
set_tray_mode(TRUE, user)
/obj/item/surgery_tray/attack_self(mob/user, modifiers)
. = ..()
if(.)
return
var/turf/open/placement_turf = get_turf(user)
if(isgroundlessturf(placement_turf) || isclosedturf(placement_turf))
balloon_alert(user, "can't deploy!")
return TRUE
if(!user.transferItemToLoc(src, placement_turf))
balloon_alert(user, "tray stuck!")
return TRUE
set_tray_mode(FALSE, user)
return
/obj/item/surgery_tray/attack_hand(mob/living/user)
if(!user.can_perform_action(src, NEED_HANDS))
return ..()
if(!length(contents))
balloon_alert(user, "empty!")
else
var/obj/item/grabbies = pick(contents)
if(atom_storage.remove_single(user, grabbies, drop_location()))
user.put_in_hands(grabbies)
return TRUE
/obj/item/surgery_tray/screwdriver_act_secondary(mob/living/user, obj/item/tool)
. = ..()
tool.play_tool_sound(src)
to_chat(user, span_notice("You begin taking apart [src]."))
if(!tool.use_tool(src, user, 1 SECONDS))
return
deconstruct(TRUE)
to_chat(user, span_notice("[src] has been taken apart."))
/obj/item/surgery_tray/dump_contents()
var/atom/drop_point = drop_location()
for(var/atom/movable/tool as anything in contents)
tool.forceMove(drop_point)
/obj/item/surgery_tray/atom_deconstruct(disassembled = TRUE)
dump_contents()
new /obj/item/stack/rods(drop_location(), 2)
new /obj/item/stack/sheet/mineral/silver(drop_location())
/obj/item/surgery_tray/deployed
is_portable = FALSE
/obj/item/surgery_tray/full
starting_items = list(
/obj/item/blood_filter,
/obj/item/bonesetter,
/obj/item/cautery,
/obj/item/circular_saw,
/obj/item/clothing/suit/toggle/labcoat/hospitalgown, // BUBBER EDIT CHANGE - Original: /obj/item/clothing/mask/surgical
/obj/item/hemostat,
/obj/item/storage/pill_bottle/lidocaine, // BUBBER EDIT CHANGE - Original: /obj/item/razor/surgery
/obj/item/retractor,
/obj/item/scalpel,
/obj/item/stack/medical/bone_gel,
/obj/item/stack/sticky_tape/surgical,
/obj/item/surgical_drapes,
/obj/item/surgicaldrill,
/obj/item/reagent_containers/medigel/sterilizine, // BUBBER EDIT CHANGE
)
/obj/item/surgery_tray/full/deployed
is_portable = FALSE
/obj/item/surgery_tray/full/morgue
name = "autopsy tray"
desc = "A Deforest brand surgery tray, made for use in morgues. It is a folding model, \
meaning the wheels on the bottom can be extended outwards, making it a cart."
starting_items = list(
/obj/item/blood_filter/cruel,
/obj/item/bonesetter/cruel,
/obj/item/cautery/cruel,
/obj/item/circular_saw/cruel,
/obj/item/clothing/mask/surgical,
/obj/item/hemostat/cruel,
/obj/item/razor/surgery,
/obj/item/retractor/cruel,
/obj/item/scalpel/cruel,
/obj/item/stack/medical/bone_gel,
/obj/item/stack/sticky_tape/surgical,
/obj/item/surgical_drapes,
/obj/item/surgicaldrill/cruel,
/obj/item/autopsy_scanner // BUBBER EDIT ADDITION
)
/obj/item/surgery_tray/full/morgue/deployed
is_portable = FALSE
/// Surgery tray with advanced tools for debug
/obj/item/surgery_tray/full/advanced
starting_items = list(
/obj/item/scalpel/advanced,
/obj/item/retractor/advanced,
/obj/item/cautery/advanced,
/obj/item/surgical_drapes,
/obj/item/reagent_containers/medigel/sterilizine,
/obj/item/bonesetter,
/obj/item/blood_filter,
/obj/item/shears,
/obj/item/stack/medical/bone_gel,
/obj/item/stack/sticky_tape/surgical,
/obj/item/clothing/mask/surgical,
)
/obj/effect/spawner/surgery_tray
name = "surgery tray spawner"
icon = 'icons/obj/medical/medicart.dmi'
icon_state = "tray"
/// Tray to usually spawn in.
var/tray_to_spawn = /obj/item/surgery_tray
/// Toolbox to sometimes replace the above tray with.
var/rare_toolbox_replacement = /obj/item/storage/toolbox/medical
/// Chance for replacement
var/toolbox_chance = 1
/obj/effect/spawner/surgery_tray/Initialize(mapload)
. = ..()
if(prob(toolbox_chance))
new rare_toolbox_replacement(loc)
return
new tray_to_spawn(loc, TRUE)
/obj/effect/spawner/surgery_tray/full
name = "full surgery tray spawner"
icon_state = "tray"
tray_to_spawn = /obj/item/surgery_tray/full
rare_toolbox_replacement = /obj/item/storage/toolbox/medical/full
/obj/effect/spawner/surgery_tray/full/deployed
name = "full deployed tray spawner"
icon_state = "medicart"
tray_to_spawn = /obj/item/surgery_tray/full
/obj/effect/spawner/surgery_tray/full/morgue
name = "full autopsy tray spawner"
icon_state = "tray"
tray_to_spawn = /obj/item/surgery_tray/full/morgue
rare_toolbox_replacement = /obj/item/storage/toolbox/medical/coroner
toolbox_chance = 3 // tray is rarer, so toolbox is more common
/obj/effect/spawner/surgery_tray/full/morgue/deployed
name = "full deployed autopsy tray spawner"
icon_state = "medicart"
tray_to_spawn = /obj/item/surgery_tray/full/morgue/deployed