mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-20 15:12:57 +00:00
352 lines
9.3 KiB
Plaintext
352 lines
9.3 KiB
Plaintext
/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 |