/mob/living var/hand = null var/obj/item/l_hand = null var/obj/item/r_hand = null var/obj/item/weapon/back = null//Human/Monkey var/obj/item/weapon/tank/internal = null//Human/Monkey var/obj/item/clothing/mask/wear_mask = null//Carbon /mob/living/equip_to_storage(obj/item/newitem) // Try put it in their backpack if(istype(src.back,/obj/item/weapon/storage)) var/obj/item/weapon/storage/backpack = src.back if(backpack.can_be_inserted(newitem, 1)) newitem.forceMove(src.back) return 1 // Try to place it in any item that can store stuff, on the mob. for(var/obj/item/weapon/storage/S in src.contents) if (S.can_be_inserted(newitem, 1)) newitem.forceMove(S) return 1 return 0 //Returns the thing in our active hand /mob/living/get_active_hand() if(hand) return l_hand else return r_hand //Returns the thing in our inactive hand /mob/living/get_inactive_hand() if(hand) return r_hand else return l_hand //Drops the item in our active hand. TODO: rename this to drop_active_hand or something /mob/living/drop_item(var/atom/Target) var/obj/item/item_dropped = null if (hand) item_dropped = l_hand . = drop_l_hand(Target) else item_dropped = r_hand . = drop_r_hand(Target) if (istype(item_dropped) && !QDELETED(item_dropped) && is_preference_enabled(/datum/client_preference/drop_sounds)) addtimer(CALLBACK(src, .proc/make_item_drop_sound, item_dropped), 1) /mob/proc/make_item_drop_sound(obj/item/I) if(QDELETED(I)) return if(I.drop_sound) playsound(I, I.drop_sound, 25, 0, preference = /datum/client_preference/drop_sounds) //Drops the item in our left hand /mob/living/drop_l_hand(var/atom/Target) return drop_from_inventory(l_hand, Target) //Drops the item in our right hand /mob/living/drop_r_hand(var/atom/Target) return drop_from_inventory(r_hand, Target) /mob/living/proc/hands_are_full() return (r_hand && l_hand) /mob/living/proc/item_is_in_hands(var/obj/item/I) return (I == r_hand || I == l_hand) /mob/living/proc/update_held_icons() if(l_hand) l_hand.update_held_icon() if(r_hand) r_hand.update_held_icon() /mob/living/proc/get_type_in_hands(var/T) if(istype(l_hand, T)) return l_hand if(istype(r_hand, T)) return r_hand return null /mob/living/proc/get_left_hand() return l_hand /mob/living/proc/get_right_hand() return r_hand /mob/living/u_equip(obj/W as obj) if (W == r_hand) r_hand = null update_inv_r_hand() else if (W == l_hand) l_hand = null update_inv_l_hand() else if (W == back) back = null update_inv_back() else if (W == wear_mask) wear_mask = null update_inv_wear_mask() return /mob/living/get_equipped_item(var/slot) switch(slot) if(slot_l_hand) return l_hand if(slot_r_hand) return r_hand if(slot_back) return back if(slot_wear_mask) return wear_mask return null /mob/living/ret_grab(var/list/L, var/mobchain_limit = 5) // We're the first! if(!L) L = list() // Lefty grab! if (istype(l_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = l_hand L |= G.affecting if(mobchain_limit-- > 0) G.affecting?.ret_grab(L, mobchain_limit) // Recurse! They can update the list. It's the same instance as ours. // Righty grab! if (istype(r_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = r_hand L |= G.affecting if(mobchain_limit-- > 0) G.affecting?.ret_grab(L, mobchain_limit) // Same as lefty! // On all but the one not called by us, this will just be ignored. Oh well! return L /mob/living/mode() set name = "Activate Held Object" set category = "Object" set src = usr if(!checkClickCooldown()) return setClickCooldown(1) if(istype(loc,/obj/mecha)) return if(hand) var/obj/item/W = l_hand if (W) W.attack_self(src) update_inv_l_hand() else var/obj/item/W = r_hand if (W) W.attack_self(src) update_inv_r_hand() return /mob/living/abiotic(var/full_body = 0) if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask))) return 1 if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract ))) return 1 return 0 // This handles the drag-open inventory panel. /mob/living/MouseDrop(atom/over_object) var/mob/living/L = over_object if(istype(L) && L != src && L == usr && Adjacent(L)) show_inventory_panel(L) . = ..() /mob/living/proc/show_inventory_panel(mob/user, datum/tgui_state/state) if(!inventory_panel_type) return FALSE if(!inventory_panel) inventory_panel = new inventory_panel_type(src) inventory_panel.tgui_interact(user, null, state) return TRUE // TGUITODO: Don't forget to Destroy() these properly! /datum/inventory_panel var/mob/living/host var/tgui_id = "InventoryPanel" /datum/inventory_panel/New(mob/living/new_host) if(!istype(new_host)) qdel(src) return host = new_host . = ..() /datum/inventory_panel/Destroy() host = null . = ..() /datum/inventory_panel/tgui_host(mob/user) return host.tgui_host() /datum/inventory_panel/tgui_state(mob/user) return GLOB.tgui_physical_state /datum/inventory_panel/tgui_status(mob/user, datum/tgui_state/state) if(!host) return STATUS_CLOSE if(isAI(user)) return STATUS_CLOSE return ..() /datum/inventory_panel/tgui_interact(mob/user, datum/tgui/ui, datum/tgui_state/custom_state) if(!host) qdel(src) return // This looks kinda complicated, but it's just making sure that the correct state is definitely set // before calling open(), so that there isn't any accidental UI closes var/open = FALSE ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, tgui_id, host.name) open = TRUE if(custom_state) ui.set_state(custom_state) if(open) ui.open() return ui /datum/inventory_panel/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = ..() data["slots"] = list() data["slots"].Add(list(list( "name" = "Head (Mask)", "item" = host.wear_mask, "act" = "mask", ))) data["slots"].Add(list(list( "name" = "Left Hand", "item" = host.l_hand, "act" = "l_hand", ))) data["slots"].Add(list(list( "name" = "Right Hand", "item" = host.r_hand, "act" = "r_hand", ))) data["slots"].Add(list(list( "name" = "Back", "item" = host.back, "act" = "back", ))) data["slots"].Add(list(list( "name" = "Pockets", "item" = "Empty Pockets", "act" = "pockets", ))) data["internals"] = host.internals data["internalsValid"] = istype(host.wear_mask, /obj/item/clothing/mask) && istype(host.back, /obj/item/weapon/tank) return data /datum/inventory_panel/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE // If anyone wants the inventory panel to actually work, // add code to handle actions "mask", "l_hand", "r_hand", "back", "pockets", and "internals" here // No mobs other than humans actually supported stripping or putting stuff on before the /datum/inventory_panel was // created, so feature parity demands not adding that and risking breaking stuff /datum/inventory_panel/human tgui_id = "InventoryPanelHuman" /datum/inventory_panel/human/New(mob/living/carbon/human/new_host) if(!istype(new_host)) qdel(src) return return ..() // Let our parent assign the host. /datum/inventory_panel/human/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE var/mob/living/carbon/human/H = host switch(action) if("targetSlot") H.handle_strip(params["slot"], usr) return TRUE /datum/inventory_panel/human/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = list() // We don't inherit TGUI data because humans are soooo different. var/mob/living/carbon/human/H = host // Not my fault if this runtimes, a human inventory panel should never be created without a human attached. var/obj/item/clothing/under/suit = null if(istype(H.w_uniform, /obj/item/clothing/under)) suit = H.w_uniform data["slots"] = list() for(var/entry in H.species.hud.gear) var/list/slot_ref = H.species.hud.gear[entry] if((slot_ref["slot"] in list(slot_l_store, slot_r_store))) continue var/obj/item/thing_in_slot = H.get_equipped_item(slot_ref["slot"]) data["slots"].Add(list(list( "name" = slot_ref["name"], "item" = thing_in_slot, "act" = "targetSlot", "params" = list("slot" = slot_ref["slot"]), ))) data["specialSlots"] = list() if(H.species.hud.has_hands) data["specialSlots"].Add(list(list( "name" = "Left Hand", "item" = H.l_hand, "act" = "targetSlot", "params" = list("slot" = slot_l_hand), ))) data["specialSlots"].Add(list(list( "name" = "Right Hand", "item" = H.r_hand, "act" = "targetSlot", "params" = list("slot" = slot_r_hand), ))) data["internals"] = H.internals data["internalsValid"] = (istype(H.wear_mask, /obj/item/clothing/mask) || istype(H.head, /obj/item/clothing/head/helmet/space)) && (istype(H.back, /obj/item/weapon/tank) || istype(H.belt, /obj/item/weapon/tank) || istype(H.s_store, /obj/item/weapon/tank)) data["sensors"] = FALSE if(istype(suit) && suit.has_sensor == 1) data["sensors"] = TRUE data["handcuffed"] = FALSE if(H.handcuffed) data["handcuffed"] = TRUE data["handcuffedParams"] = list("slot" = slot_handcuffed) data["legcuffed"] = FALSE if(H.legcuffed) data["legcuffed"] = TRUE data["legcuffedParams"] = list("slot" = slot_legcuffed) data["accessory"] = FALSE if(suit && LAZYLEN(suit.accessories)) data["accessory"] = TRUE return data