mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 20:47:10 +01:00
Ports and Adapts TGUI strip panel from TG (#24618)
* part 1 * these also * fuckin nuke it * more * more stuff * more crap * wow * holy fucking shit, it works * thats a start * oops * fubing bundle * hahah brrrrr * I LITERALLY ADDED IT BACK, FUCK OFF GIT * yeah more changes * hide abstract * blamo * thats enough for today * old code begone * goodbye can_strip * nearly there * finally * fuckin finally * review * tgui * unbreak shit * fix OD * okay, that should fix the last thing * remove hover on nodrop, fix early interacting
This commit is contained in:
@@ -52,6 +52,13 @@
|
||||
/mob/proc/get_multitool(if_active=0)
|
||||
return null
|
||||
|
||||
/mob/proc/put_in_hand(obj/item/I, slot)
|
||||
switch(slot)
|
||||
if(SLOT_HUD_LEFT_HAND)
|
||||
return put_in_l_hand(I)
|
||||
if(SLOT_HUD_RIGHT_HAND)
|
||||
return put_in_r_hand(I)
|
||||
|
||||
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_l_hand(obj/item/W, skip_blocked_hands_check = FALSE)
|
||||
if(!put_in_hand_check(W, skip_blocked_hands_check))
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
icon_state = "alien_s"
|
||||
|
||||
butcher_results = list(/obj/item/food/snacks/monstermeat/xenomeat = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
@@ -16,6 +14,13 @@
|
||||
pass_flags = PASSTABLE
|
||||
hud_type = /datum/hud/alien
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list(
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize(mapload)
|
||||
if(name == "alien")
|
||||
@@ -26,19 +31,13 @@
|
||||
AddSpell(new /datum/spell/alien_spell/regurgitate)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_alien_humanoid_items)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Process_Spacemove(check_drift = 0)
|
||||
if(..())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/emp_act(severity)
|
||||
if(r_store)
|
||||
r_store.emp_act(severity)
|
||||
if(l_store)
|
||||
l_store.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/ex_act(severity)
|
||||
..()
|
||||
|
||||
@@ -75,29 +74,6 @@
|
||||
. = ..()
|
||||
. += alien_movement_delay
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[SLOT_HUD_LEFT_HAND]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[SLOT_HUD_RIGHT_HAND]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[SLOT_HUD_HEAD]'>[(head && !(head.flags&ABSTRACT)) ? html_encode(head) : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[UID()];item=[SLOT_HUD_OUTER_SUIT]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? html_encode(wear_suit) : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Pouches:</B></td><td><A href='?src=[UID()];item=pockets'>[((l_store && !(l_store.flags&ABSTRACT)) || (r_store && !(r_store.flags&ABSTRACT))) ? "Full" : "<font color=grey>Empty</font>"]</A>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
..(I, cuff_break = 1)
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
//unequip
|
||||
/mob/living/carbon/alien/humanoid/unEquip(obj/item/I, force, silent = FALSE)
|
||||
. = ..()
|
||||
if(!. || !I)
|
||||
return
|
||||
|
||||
if(I == r_store)
|
||||
r_store = null
|
||||
update_inv_pockets()
|
||||
|
||||
else if(I == l_store)
|
||||
l_store = null
|
||||
update_inv_pockets()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/put_in_hands(obj/item/I)
|
||||
if(!I)
|
||||
return FALSE
|
||||
@@ -23,34 +9,9 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_ui(slot_id)
|
||||
var/obj/item/W = get_active_hand()
|
||||
if(W)
|
||||
if(!istype(W)) return
|
||||
switch(slot_id)
|
||||
// if("o_clothing")
|
||||
// if("head")
|
||||
if(SLOT_HUD_LEFT_STORE)
|
||||
if(l_store)
|
||||
return
|
||||
if(W.w_class > WEIGHT_CLASS_NORMAL)
|
||||
return
|
||||
unEquip(W)
|
||||
l_store = W
|
||||
update_inv_pockets()
|
||||
if(SLOT_HUD_RIGHT_STORE)
|
||||
if(r_store)
|
||||
return
|
||||
if(W.w_class > WEIGHT_CLASS_NORMAL)
|
||||
return
|
||||
unEquip(W)
|
||||
r_store = W
|
||||
update_inv_pockets()
|
||||
else
|
||||
if(!W)
|
||||
switch(slot_id)
|
||||
if(SLOT_HUD_OUTER_SUIT)
|
||||
if(wear_suit) wear_suit.attack_alien(src)
|
||||
if(SLOT_HUD_HEAD)
|
||||
if(head) head.attack_alien(src)
|
||||
if(SLOT_HUD_LEFT_STORE)
|
||||
if(l_store) l_store.attack_alien(src)
|
||||
if(SLOT_HUD_RIGHT_STORE)
|
||||
if(r_store) r_store.attack_alien(src)
|
||||
|
||||
@@ -114,15 +114,6 @@
|
||||
overlays_standing[X_HEAD_LAYER] = null
|
||||
update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_pockets()
|
||||
if(l_store)
|
||||
l_store.screen_loc = ui_storage1
|
||||
if(r_store)
|
||||
r_store.screen_loc = ui_storage2
|
||||
update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_r_hand()
|
||||
..()
|
||||
if(r_hand)
|
||||
|
||||
@@ -83,8 +83,5 @@
|
||||
// new damage icon system
|
||||
// now constructs damage icon for each organ from mask * damage field
|
||||
|
||||
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
return FALSE
|
||||
|
||||
@@ -750,84 +750,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
|
||||
if(hud_used?.move_intent)
|
||||
hud_used.move_intent.icon_state = "walking"
|
||||
|
||||
/mob/living/carbon/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><b>Left Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_LEFT_HAND]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td><b>Right Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_RIGHT_HAND]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
|
||||
dat += "<tr><td><b>Back:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_BACK]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</a>"
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
|
||||
dat += " <a href='?src=[UID()];internal=[SLOT_HUD_BACK]'>[internal ? "Disable Internals" : "Set Internals"]</a>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><b>Head:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_HEAD]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
dat += "<tr><td><b>Mask:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_WEAR_MASK]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
var/obj/item/clothing/mask/muzzle/M = wear_mask
|
||||
if(M.security_lock)
|
||||
dat += " <A href='?src=[M.UID()];locked=\ref[src]'>[M.locked ? "Disable Lock" : "Set Lock"]</A>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<tr><td><B>Handcuffed:</B> <A href='?src=[UID()];item=[SLOT_HUD_HANDCUFFED]'>Remove</A></td></tr>"
|
||||
if(legcuffed)
|
||||
dat += "<tr><td><A href='?src=[UID()];item=[SLOT_HUD_LEGCUFFED]'>Legcuffed</A></td></tr>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel
|
||||
if(usr.stat || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.restrained() || !in_range(src, usr))
|
||||
return
|
||||
if(href_list["internal"])
|
||||
var/slot = text2num(href_list["internal"])
|
||||
var/obj/item/ITEM = get_item_by_slot(slot)
|
||||
if(ITEM && istype(ITEM, /obj/item/tank))
|
||||
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>")
|
||||
|
||||
var/no_mask
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask = 1
|
||||
if(no_mask)
|
||||
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY))
|
||||
if(internal)
|
||||
internal = null
|
||||
update_action_buttons_icon()
|
||||
else
|
||||
var/no_mask2
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask2 = 1
|
||||
if(no_mask2)
|
||||
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
|
||||
return
|
||||
internal = ITEM
|
||||
update_action_buttons_icon()
|
||||
|
||||
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>", \
|
||||
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>")
|
||||
|
||||
/mob/living/carbon/get_item_by_slot(slot_id)
|
||||
switch(slot_id)
|
||||
if(SLOT_HUD_BACK)
|
||||
@@ -1391,3 +1313,19 @@ so that different stomachs can handle things in different ways VB*/
|
||||
for(var/obj/item/organ/internal/IO in internal_organs)
|
||||
if(IO.dna?.real_name == oldname)
|
||||
IO.dna.real_name = newname
|
||||
|
||||
/// Returns TRUE if an air tank compatible mask or breathing tube is equipped.
|
||||
/mob/living/carbon/proc/can_breathe_internals()
|
||||
return can_breathe_tube() || can_breathe_mask() || can_breathe_helmet()
|
||||
|
||||
/// Returns TRUE if an air tank compatible helmet is equipped.
|
||||
/mob/living/carbon/proc/can_breathe_helmet()
|
||||
return (isclothing(head) && (head.flags & AIRTIGHT))
|
||||
|
||||
/// Returns TRUE if an air tank compatible mask is equipped.
|
||||
/mob/living/carbon/proc/can_breathe_mask()
|
||||
return (isclothing(wear_mask) && (wear_mask.flags & AIRTIGHT))
|
||||
|
||||
/// Returns TRUE if a breathing tube is equipped.
|
||||
/mob/living/carbon/proc/can_breathe_tube()
|
||||
return get_organ_slot("breathing_tube")
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/datum/strippable_item/mob_item_slot/head
|
||||
key = STRIPPABLE_ITEM_HEAD
|
||||
item_slot = SLOT_HUD_HEAD
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back
|
||||
key = STRIPPABLE_ITEM_BACK
|
||||
item_slot = SLOT_HUD_BACK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/get_alternate_actions(atom/source, mob/user)
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/alternate_action(atom/source, mob/user, action_key)
|
||||
if(!..())
|
||||
return
|
||||
strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask
|
||||
key = STRIPPABLE_ITEM_MASK
|
||||
item_slot = SLOT_HUD_WEAR_MASK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask/get_body_action(atom/source, mob/user)
|
||||
if(!ishuman(source))
|
||||
return
|
||||
var/mob/living/carbon/human/H = source
|
||||
var/obj/item/organ/internal/headpocket/pocket = H.get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
if(istype(pocket) && pocket.held_item)
|
||||
return "dislodge_headpocket"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask/get_alternate_actions(atom/source, mob/user)
|
||||
var/obj/item/clothing/mask/muzzle/muzzle = get_item(source)
|
||||
if(!istype(muzzle))
|
||||
return
|
||||
if(muzzle.security_lock)
|
||||
return "[muzzle.locked ? "dis" : "en"]able_lock"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask/alternate_action(atom/source, mob/user, action_key)
|
||||
if(!..())
|
||||
return
|
||||
// Headpocket dislodging
|
||||
if(action_key == "dislodge_headpocket")
|
||||
var/mob/living/carbon/human/H = source
|
||||
var/obj/item/organ/internal/headpocket/pocket = H.get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
if(!pocket.held_item)
|
||||
return
|
||||
user.visible_message("<span class='danger'>[user] is trying to remove something from [source]'s head!</span>",
|
||||
"<span class='danger'>You start to dislodge whatever's inside [source]'s headpocket!</span>")
|
||||
if(do_mob(user, source, POCKET_STRIP_DELAY))
|
||||
user.visible_message("<span class='danger'>[user] has dislodged something from [source]'s head!</span>",
|
||||
"<span class='danger'>You have dislodged everything from [source]'s headpocket!</span>")
|
||||
pocket.empty_contents()
|
||||
add_attack_logs(user, source, "Stripped of headpocket items", isLivingSSD(source) ? null : ATKLOG_ALL)
|
||||
return
|
||||
|
||||
// Altering a muzzle
|
||||
if(action_key != "enable_lock" && action_key != "disable_lock")
|
||||
return
|
||||
var/obj/item/clothing/mask/muzzle/muzzle = get_item(source)
|
||||
if(!istype(muzzle))
|
||||
return
|
||||
if(!ishuman(user))
|
||||
to_chat(user, "You lack the ability to manipulate the lock.")
|
||||
return
|
||||
|
||||
muzzle.visible_message("<span class='danger'>[user] tries to [muzzle.locked ? "unlock" : "lock"] [source]'s [muzzle.name].</span>", \
|
||||
"<span class='userdanger'>[user] tries to [muzzle.locked ? "unlock" : "lock"] [source]'s [muzzle.name].</span>")
|
||||
if(!do_mob(user, source, POCKET_STRIP_DELAY))
|
||||
return
|
||||
|
||||
var/success = FALSE
|
||||
if(muzzle.locked)
|
||||
success = muzzle.do_unlock(user)
|
||||
else
|
||||
success = muzzle.do_lock(user)
|
||||
|
||||
if(!success)
|
||||
return
|
||||
muzzle.visible_message("<span class='danger'>[user] [muzzle.locked ? "locks" : "unlocks"] [source]'s [muzzle.name].</span>", \
|
||||
"<span class='userdanger'>[user] [muzzle.locked ? "locks" : "unlocks"] [source]'s [muzzle.name].</span>")
|
||||
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs
|
||||
key = STRIPPABLE_ITEM_HANDCUFFS
|
||||
item_slot = SLOT_HUD_HANDCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/should_show(atom/source, mob/user)
|
||||
if(!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.handcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to handcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs
|
||||
key = STRIPPABLE_ITEM_LEGCUFFS
|
||||
item_slot = SLOT_HUD_LEGCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/should_show(atom/source, mob/user)
|
||||
if(!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.legcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to legcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/// A strippable item for a hand
|
||||
/datum/strippable_item/hand
|
||||
|
||||
/// Which hand?
|
||||
var/which_hand
|
||||
|
||||
/datum/strippable_item/hand/get_item(atom/source)
|
||||
if(!ismob(source))
|
||||
return null
|
||||
|
||||
var/mob/mob_source = source
|
||||
return mob_source.get_item_by_slot(which_hand)
|
||||
|
||||
/datum/strippable_item/hand/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
if(!equipping.mob_can_equip(mob_source, which_hand, TRUE))
|
||||
to_chat(user, "<span class='warning'>\The [equipping] doesn't fit in that place!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
|
||||
if(mob_source.get_item_by_slot(which_hand))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
INVOKE_ASYNC(source, TYPE_PROC_REF(/mob, put_in_hand), equipping, which_hand)
|
||||
|
||||
/datum/strippable_item/hand/finish_unequip(atom/source, mob/user)
|
||||
var/obj/item/item = get_item(source)
|
||||
if(isnull(item))
|
||||
return FALSE
|
||||
|
||||
if(!ismob(source))
|
||||
return FALSE
|
||||
|
||||
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(finish_unequip_mob), item, source, user)
|
||||
|
||||
/datum/strippable_item/hand/left
|
||||
key = STRIPPABLE_ITEM_LHAND
|
||||
which_hand = SLOT_HUD_LEFT_HAND
|
||||
|
||||
/datum/strippable_item/hand/right
|
||||
key = STRIPPABLE_ITEM_RHAND
|
||||
which_hand = SLOT_HUD_RIGHT_HAND
|
||||
@@ -399,24 +399,6 @@
|
||||
l_ear,
|
||||
)
|
||||
|
||||
// humans have their pickpocket gloves, so they get no message when stealing things
|
||||
/mob/living/carbon/human/stripPanelUnequip(obj/item/what, mob/who, where)
|
||||
var/is_silent = 0
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G))
|
||||
is_silent = G.pickpocket
|
||||
|
||||
..(what, who, where, silent = is_silent)
|
||||
|
||||
// humans have their pickpocket gloves, so they get no message when stealing things
|
||||
/mob/living/carbon/human/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
var/is_silent = 0
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G))
|
||||
is_silent = G.pickpocket
|
||||
|
||||
..(what, who, where, silent = is_silent)
|
||||
|
||||
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = FALSE)
|
||||
return dna.species.can_equip(I, slot, disable_warning, src)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
UpdateAppearance()
|
||||
GLOB.human_list += src
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_HUMAN, 1, -6)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_human_items)
|
||||
RegisterSignal(src, COMSIG_BODY_TRANSFER_TO, PROC_REF(mind_checks))
|
||||
|
||||
/**
|
||||
@@ -278,143 +279,6 @@
|
||||
if(!. && istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
|
||||
. = wear_suit
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) || get_organ_slot("breathing_tube")
|
||||
var/list/obscured = check_obscured_slots()
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><b>Left Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_LEFT_HAND]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td><b>Right Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_RIGHT_HAND]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
|
||||
dat += "<tr><td><b>Back:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_BACK]'>[(back && !(back.flags&ABSTRACT)) ? html_encode(back) : "<font color=grey>Empty</font>"]</a>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/tank))
|
||||
dat += " <a href='?src=[UID()];internal=[SLOT_HUD_BACK]'>[internal ? "Disable Internals" : "Set Internals"]</a>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><b>Head:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_HEAD]'>[(head && !(head.flags&ABSTRACT)) ? html_encode(head) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
var/obj/item/organ/internal/headpocket/C = get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
if(C)
|
||||
if(SLOT_HUD_WEAR_MASK in obscured)
|
||||
dat += "<tr><td><font color=grey> ↳<b>Headpocket:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
if(C.held_item)
|
||||
dat += "<tr><td> ↳<b>Headpocket:</b></td><td><a href='?src=[UID()];dislodge_headpocket=1'>Dislodge Items</a></td></tr>"
|
||||
else
|
||||
dat += "<tr><td> ↳<b>Headpocket:</b></td><td><font color=grey>Empty</font></td></tr>"
|
||||
|
||||
if(SLOT_HUD_WEAR_MASK in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Mask:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Mask:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_WEAR_MASK]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? html_encode(wear_mask) : "<font color=grey>Empty</font>"]</a>"
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
var/obj/item/clothing/mask/muzzle/M = wear_mask
|
||||
if(M.security_lock)
|
||||
dat += " <a href='?src=[M.UID()];locked=\ref[src]'>[M.locked ? "Disable Lock" : "Set Lock"]</a>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
if(!issmall(src))
|
||||
if(SLOT_HUD_GLASSES in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Eyes:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Eyes:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_GLASSES]'>[(glasses && !(glasses.flags&ABSTRACT)) ? html_encode(glasses) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(SLOT_HUD_LEFT_EAR in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Left Ear:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Left Ear:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_LEFT_EAR]'>[(l_ear && !(l_ear.flags&ABSTRACT)) ? html_encode(l_ear) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(SLOT_HUD_RIGHT_EAR in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Right Ear:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Right Ear:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_RIGHT_EAR]'>[(r_ear && !(r_ear.flags&ABSTRACT)) ? html_encode(r_ear) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><b>Exosuit:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_OUTER_SUIT]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? html_encode(wear_suit) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
if(wear_suit)
|
||||
dat += "<tr><td> ↳<b>Suit Storage:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_SUIT_STORE]'>[(s_store && !(s_store.flags&ABSTRACT)) ? html_encode(s_store) : "<font color=grey>Empty</font>"]</a>"
|
||||
if(has_breathable_mask && istype(s_store, /obj/item/tank))
|
||||
dat += " <a href='?src=[UID()];internal=[SLOT_HUD_SUIT_STORE]'>[internal ? "Disable Internals" : "Set Internals"]</a>"
|
||||
dat += "</td></tr>"
|
||||
else
|
||||
dat += "<tr><td><font color=grey> ↳<b>Suit Storage:</b></font></td></tr>"
|
||||
|
||||
if(SLOT_HUD_SHOES in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Shoes:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Shoes:</b></td><td><a href='?src=[UID()];item=[html_encode(SLOT_HUD_SHOES)]'>[(shoes && !(shoes.flags&ABSTRACT)) ? html_encode(shoes) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(SLOT_HUD_GLOVES in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Gloves:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Gloves:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_GLOVES]'>[(gloves && !(gloves.flags&ABSTRACT)) ? html_encode(gloves) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(SLOT_HUD_BELT in obscured)
|
||||
dat += "<tr><td><b>Belt:</b></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Belt:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_BELT]'>[(belt && !(belt.flags&ABSTRACT)) ? html_encode(belt) : "<font color=grey>Empty</font>"]</a>"
|
||||
|
||||
if(has_breathable_mask && istype(belt, /obj/item/tank))
|
||||
dat += " <a href='?src=[UID()];internal=[SLOT_HUD_BELT]'>[internal ? "Disable Internals" : "Set Internals"]</a>"
|
||||
dat += "</td></tr>"
|
||||
|
||||
if(SLOT_HUD_JUMPSUIT in obscured)
|
||||
dat += "<tr><td><font color=grey><b>Uniform:</b></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><b>Uniform:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_JUMPSUIT]'>[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? html_encode(w_uniform) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (SLOT_HUD_JUMPSUIT in obscured))
|
||||
dat += "<tr><td><font color=grey> ↳<b>Pockets:</b></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<b>ID:</b></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<b>Suit Sensors:</b></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<b>PDA:</b></font></td></tr>"
|
||||
else
|
||||
// Pockets
|
||||
dat += "<tr><td> ↳<b>Pockets:</b></td><td><a href='?src=[UID()];pockets=left'>"
|
||||
if(l_store && internal && l_store == internal)
|
||||
dat += "[l_store]"
|
||||
else if(l_store && !(l_store.flags&ABSTRACT))
|
||||
dat += "Left (Full)"
|
||||
else
|
||||
dat += "<font color=grey>Left (Empty)</font>"
|
||||
dat += "</a> <a href='?src=[UID()];pockets=right'>"
|
||||
if(r_store && internal && r_store == internal)
|
||||
dat += "[r_store]"
|
||||
else if(r_store && !(r_store.flags&ABSTRACT))
|
||||
dat += "Right (Full)"
|
||||
else
|
||||
dat += "<font color=grey>Right (Empty)</font>"
|
||||
dat += "</a></td></tr>"
|
||||
dat += "<tr><td> ↳<b>ID:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_WEAR_ID]'>[(wear_id && !(wear_id.flags&ABSTRACT)) ? html_encode(wear_id) : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td> ↳<b>PDA:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_WEAR_PDA]'>[(wear_pda && !(wear_pda.flags&ABSTRACT)) ? "Full" : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
dat += "<tr><td> ↳<b>Suit Sensors:</b></td><td><a href='?src=[UID()];set_sensor=1'>[U.has_sensor >= 2 ? "</a><font color=grey>--SENSORS LOCKED--</font>" : "Set Sensors</a>"]</td></tr>"
|
||||
|
||||
if(U.accessories.len)
|
||||
dat += "<tr><td> ↳<a href='?src=[UID()];strip_accessory=1'>Remove Accessory</a></td></tr>"
|
||||
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<tr><td><b>Handcuffed:</b> <a href='?src=[UID()];item=[SLOT_HUD_HANDCUFFED]'>Remove</a></td></tr>"
|
||||
if(legcuffed)
|
||||
dat += "<tr><td><b>Legcuffed:</b> <a href='?src=[UID()];item=[SLOT_HUD_LEGCUFFED]'>Remove</a></td></tr>"
|
||||
|
||||
dat += {"</table>
|
||||
<a href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</a>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 540)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
// Get rank from ID, ID inside PDA, PDA, ID in wallet, etc.
|
||||
/mob/living/carbon/human/proc/get_authentification_rank(if_no_id = "No id", if_no_job = "No job")
|
||||
var/obj/item/card/id/id = wear_id?.GetID()
|
||||
@@ -589,12 +453,6 @@
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
if(!usr.stat && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) && !usr.restrained() && in_range(src, usr))
|
||||
var/thief_mode = 0
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(G && G.pickpocket)
|
||||
thief_mode = 1
|
||||
|
||||
if(href_list["embedded_object"])
|
||||
var/obj/item/organ/external/L = locate(href_list["embedded_limb"]) in bodyparts
|
||||
@@ -618,81 +476,6 @@
|
||||
clear_alert("embeddedobject")
|
||||
return
|
||||
|
||||
if(href_list["item"])
|
||||
var/slot = text2num(href_list["item"])
|
||||
if(slot in check_obscured_slots())
|
||||
to_chat(usr, "<span class='warning'>You can't reach that! Something is covering it.</span>")
|
||||
return
|
||||
|
||||
if(href_list["pockets"])
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? SLOT_HUD_RIGHT_STORE : SLOT_HUD_LEFT_STORE)
|
||||
var/obj/item/pocket_item = (pocket_id == SLOT_HUD_RIGHT_STORE ? r_store : l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
|
||||
var/delay_denominator = 1
|
||||
if(pocket_item && !(pocket_item.flags&ABSTRACT))
|
||||
if(pocket_item.flags & NODROP)
|
||||
to_chat(usr, "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>")
|
||||
to_chat(usr, "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>")
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
to_chat(usr, "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>")
|
||||
delay_denominator = 4
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster
|
||||
if(pocket_item)
|
||||
if(pocket_item == (pocket_id == SLOT_HUD_RIGHT_STORE ? r_store : l_store)) //item still in the pocket we search
|
||||
unEquip(pocket_item)
|
||||
if(thief_mode)
|
||||
usr.put_in_hands(pocket_item)
|
||||
add_attack_logs(usr, src, "Stripped of [pocket_item]", isLivingSSD(src) ? null : ATKLOG_ALL)
|
||||
else
|
||||
if(place_item)
|
||||
usr.unEquip(place_item)
|
||||
equip_to_slot_if_possible(place_item, pocket_id, FALSE, TRUE)
|
||||
add_attack_logs(usr, src, "Equipped with [place_item]", isLivingSSD(src) ? null : ATKLOG_ALL)
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
else
|
||||
// Display a warning if the user mocks up if they don't have pickpocket gloves.
|
||||
if(!thief_mode)
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
add_attack_logs(usr, src, "Attempted strip of [pocket_item]", isLivingSSD(src) ? null : ATKLOG_ALL)
|
||||
|
||||
if(href_list["set_sensor"])
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
U.set_sensors(usr)
|
||||
|
||||
if(href_list["dislodge_headpocket"])
|
||||
usr.visible_message("<span class='danger'>[usr] is trying to remove something from [src]'s head!</span>",
|
||||
"<span class='danger'>You start to dislodge whatever's inside [src]'s headpocket!</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY))
|
||||
usr.visible_message("<span class='danger'>[usr] has dislodged something from [src]'s head!</span>",
|
||||
"<span class='danger'>You have dislodged everything from [src]'s headpocket!</span>")
|
||||
var/obj/item/organ/internal/headpocket/C = get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
C.empty_contents()
|
||||
add_attack_logs(usr, src, "Stripped of headpocket items", isLivingSSD(src) ? null : ATKLOG_ALL)
|
||||
|
||||
if(href_list["strip_accessory"])
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
if(U.accessories.len)
|
||||
var/obj/item/clothing/accessory/A = U.accessories[1]
|
||||
if(!thief_mode)
|
||||
usr.visible_message("<span class='danger'>\The [usr] starts to take off \the [A] from \the [src]'s [U]!</span>", \
|
||||
"<span class='danger'>You start to take off \the [A] from \the [src]'s [U]!</span>")
|
||||
|
||||
if(do_mob(usr, src, 40) && A && U.accessories.len)
|
||||
if(!thief_mode)
|
||||
usr.visible_message("<span class='danger'>\The [usr] takes \the [A] off of \the [src]'s [U]!</span>", \
|
||||
"<span class='danger'>You take \the [A] off of \the [src]'s [U]!</span>")
|
||||
U.detach_accessory(A, usr)
|
||||
|
||||
if(href_list["criminal"])
|
||||
try_set_criminal_status(usr)
|
||||
if(href_list["secrecord"])
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
#define INTERNALS_TOGGLE_DELAY (4 SECONDS)
|
||||
#define POCKET_EQUIP_DELAY (1 SECONDS)
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list(
|
||||
/datum/strippable_item/mob_item_slot/head,
|
||||
/datum/strippable_item/mob_item_slot/back,
|
||||
/datum/strippable_item/mob_item_slot/mask,
|
||||
/datum/strippable_item/mob_item_slot/eyes,
|
||||
/datum/strippable_item/mob_item_slot/left_ear,
|
||||
/datum/strippable_item/mob_item_slot/right_ear,
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit,
|
||||
/datum/strippable_item/mob_item_slot/suit,
|
||||
/datum/strippable_item/mob_item_slot/gloves,
|
||||
/datum/strippable_item/mob_item_slot/feet,
|
||||
/datum/strippable_item/mob_item_slot/suit_storage,
|
||||
/datum/strippable_item/mob_item_slot/id,
|
||||
/datum/strippable_item/mob_item_slot/pda,
|
||||
/datum/strippable_item/mob_item_slot/belt,
|
||||
/datum/strippable_item/mob_item_slot/pocket/left,
|
||||
/datum/strippable_item/mob_item_slot/pocket/right,
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
/datum/strippable_item/mob_item_slot/eyes
|
||||
key = STRIPPABLE_ITEM_EYES
|
||||
item_slot = SLOT_HUD_GLASSES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit
|
||||
key = STRIPPABLE_ITEM_JUMPSUIT
|
||||
item_slot = SLOT_HUD_JUMPSUIT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/get_alternate_actions(atom/source, mob/user)
|
||||
var/list/multiple_options = list()
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if(!istype(jumpsuit))
|
||||
return null
|
||||
if(jumpsuit.has_sensor)
|
||||
multiple_options |= "suit_sensors"
|
||||
if(length(jumpsuit.accessories))
|
||||
multiple_options |= "remove_accessory"
|
||||
return multiple_options
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/alternate_action(atom/source, mob/user, action_key)
|
||||
if(!..())
|
||||
return
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if(!istype(jumpsuit))
|
||||
return
|
||||
if(action_key == "suit_sensors")
|
||||
jumpsuit.set_sensors(user)
|
||||
return
|
||||
|
||||
if(action_key != "remove_accessory")
|
||||
return
|
||||
if(!length(jumpsuit.accessories))
|
||||
return
|
||||
var/obj/item/clothing/accessory/A = jumpsuit.accessories[1]
|
||||
if(!in_thief_mode(user))
|
||||
user.visible_message("<span class='danger'>[user] starts to take off [A] from [source]'s [jumpsuit]!</span>", \
|
||||
"<span class='danger'>You start to take off [A] from [source]'s [jumpsuit]!</span>")
|
||||
|
||||
if(!do_mob(user, source, POCKET_STRIP_DELAY))
|
||||
return
|
||||
if(QDELETED(A) || !(A in jumpsuit.accessories))
|
||||
return
|
||||
|
||||
if(!in_thief_mode(user))
|
||||
user.visible_message("<span class='danger'>[user] takes [A] off of [source]'s [jumpsuit]!</span>", \
|
||||
"<span class='danger'>You take [A] off of [source]'s [jumpsuit]!</span>")
|
||||
jumpsuit.detach_accessory(A, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/left_ear
|
||||
key = STRIPPABLE_ITEM_L_EAR
|
||||
item_slot = SLOT_HUD_LEFT_EAR
|
||||
|
||||
/datum/strippable_item/mob_item_slot/right_ear
|
||||
key = STRIPPABLE_ITEM_R_EAR
|
||||
item_slot = SLOT_HUD_RIGHT_EAR
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit
|
||||
key = STRIPPABLE_ITEM_SUIT
|
||||
item_slot = SLOT_HUD_OUTER_SUIT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/gloves
|
||||
key = STRIPPABLE_ITEM_GLOVES
|
||||
item_slot = SLOT_HUD_GLOVES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet
|
||||
key = STRIPPABLE_ITEM_FEET
|
||||
item_slot = SLOT_HUD_SHOES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage
|
||||
key = STRIPPABLE_ITEM_SUIT_STORAGE
|
||||
item_slot = SLOT_HUD_SUIT_STORE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/get_alternate_actions(atom/source, mob/user)
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/alternate_action(atom/source, mob/user, action_key)
|
||||
if(!..())
|
||||
return
|
||||
strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/id
|
||||
key = STRIPPABLE_ITEM_ID
|
||||
item_slot = SLOT_HUD_WEAR_ID
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pda
|
||||
key = STRIPPABLE_ITEM_PDA
|
||||
item_slot = SLOT_HUD_WEAR_PDA
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pda/get_obscuring(atom/source)
|
||||
return isnull(get_item(source)) \
|
||||
? STRIPPABLE_OBSCURING_NONE \
|
||||
: STRIPPABLE_OBSCURING_HIDDEN
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt
|
||||
key = STRIPPABLE_ITEM_BELT
|
||||
item_slot = SLOT_HUD_BELT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/get_alternate_actions(atom/source, mob/user)
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/alternate_action(atom/source, mob/user, action_key)
|
||||
if(!..())
|
||||
return
|
||||
strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket
|
||||
/// Which pocket we're referencing. Used for visible text.
|
||||
var/pocket_side
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_obscuring(atom/source)
|
||||
return isnull(get_item(source)) \
|
||||
? STRIPPABLE_OBSCURING_NONE \
|
||||
: STRIPPABLE_OBSCURING_HIDDEN
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_equip_delay(obj/item/equipping)
|
||||
return POCKET_EQUIP_DELAY // Equipping is 4 times as fast as stripping
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if(!. && !in_thief_mode(user))
|
||||
warn_owner(source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_unequip(atom/source, mob/user)
|
||||
var/obj/item/item = get_item(source)
|
||||
if(isnull(item))
|
||||
return FALSE
|
||||
|
||||
to_chat(user, "<span class='notice'>You try to empty [source]'s [pocket_side] pocket.</span>")
|
||||
|
||||
add_attack_logs(user, source, "Attempting pickpocketing of [item]")
|
||||
item.add_fingerprint(user)
|
||||
|
||||
var/result = start_unequip_mob(item, source, user, POCKET_STRIP_DELAY)
|
||||
|
||||
if(!result && !in_thief_mode(user))
|
||||
warn_owner(source)
|
||||
|
||||
return result
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/proc/warn_owner(atom/owner)
|
||||
to_chat(owner, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/finish_unequip(atom/source, mob/user)
|
||||
var/obj/item/item = get_item(source)
|
||||
. = ..()
|
||||
if(in_thief_mode(user))
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), item)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/left
|
||||
key = STRIPPABLE_ITEM_LPOCKET
|
||||
item_slot = SLOT_HUD_LEFT_STORE
|
||||
pocket_side = "left"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/right
|
||||
key = STRIPPABLE_ITEM_RPOCKET
|
||||
item_slot = SLOT_HUD_RIGHT_STORE
|
||||
pocket_side = "right"
|
||||
|
||||
/proc/get_strippable_alternate_action_internals(obj/item/item, atom/source)
|
||||
if(!iscarbon(source))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
if(carbon_source.can_breathe_internals() && istype(item, /obj/item/tank))
|
||||
if(carbon_source.internal != item)
|
||||
return "enable_internals"
|
||||
else
|
||||
return "disable_internals"
|
||||
|
||||
/proc/strippable_alternate_action_internals(obj/item/item, atom/source, mob/user)
|
||||
var/obj/item/tank/tank = item
|
||||
if(!istype(tank))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
if(!istype(carbon_source))
|
||||
return
|
||||
|
||||
if(!carbon_source.can_breathe_internals())
|
||||
return
|
||||
|
||||
carbon_source.visible_message(
|
||||
"<span class='danger'>[user] tries to [(carbon_source.internal != item) ? "open" : "close"] the valve on [source]'s [item.name].</span>",
|
||||
"<span class='userdanger'>[user] tries to [(carbon_source.internal != item) ? "open" : "close"] the valve on your [item.name].</span>",
|
||||
)
|
||||
|
||||
if(!do_mob(user, carbon_source, INTERNALS_TOGGLE_DELAY))
|
||||
return
|
||||
|
||||
if(carbon_source.internal == item)
|
||||
carbon_source.internal = null
|
||||
else if(!QDELETED(item))
|
||||
carbon_source.internal = item
|
||||
|
||||
carbon_source.update_action_buttons_icon()
|
||||
|
||||
carbon_source.visible_message(
|
||||
"<span class='danger'>[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name].</span>",
|
||||
"<span class='userdanger'>[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on your [item.name].</span>",
|
||||
)
|
||||
|
||||
|
||||
#undef INTERNALS_TOGGLE_DELAY
|
||||
#undef POCKET_EQUIP_DELAY
|
||||
@@ -839,51 +839,6 @@
|
||||
/mob/living/proc/check_ear_prot()
|
||||
return
|
||||
|
||||
/**
|
||||
* Returns the name override, if any, for the slot somebody is trying to strip
|
||||
*/
|
||||
/mob/living/proc/get_strip_slot_name_override(slot)
|
||||
switch(slot)
|
||||
if(SLOT_HUD_WEAR_PDA)
|
||||
return "PDA"
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
|
||||
/mob/living/stripPanelUnequip(obj/item/what, mob/who, where, silent = 0)
|
||||
var/item_name = get_strip_slot_name_override(where) || what.name
|
||||
if(what.flags & NODROP)
|
||||
to_chat(src, "<span class='warning'>You can't remove \the [item_name], it appears to be stuck!</span>")
|
||||
return
|
||||
if(!silent)
|
||||
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [item_name].</span>", \
|
||||
"<span class='userdanger'>[src] tries to remove [who]'s [item_name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
if(do_mob(src, who, what.strip_delay))
|
||||
if(what && what == who.get_item_by_slot(where) && Adjacent(who))
|
||||
who.unEquip(what)
|
||||
if(silent)
|
||||
put_in_hands(what)
|
||||
add_attack_logs(src, who, "Stripped of [what]")
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// Override if a certain mob should be behave differently when placing items (can't, for example)
|
||||
/mob/living/stripPanelEquip(obj/item/what, mob/who, where, silent = 0)
|
||||
what = get_active_hand()
|
||||
if(what && (what.flags & NODROP))
|
||||
to_chat(src, "<span class='warning'>You can't put \the [what.name] on [who], it's stuck to your hand!</span>")
|
||||
return
|
||||
if(what)
|
||||
if(!what.mob_can_equip(who, where, 1))
|
||||
to_chat(src, "<span class='warning'>\The [what.name] doesn't fit in that place!</span>")
|
||||
return
|
||||
if(!silent)
|
||||
visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>")
|
||||
if(do_mob(src, who, what.put_on_delay))
|
||||
if(what && Adjacent(who) && !(what.flags & NODROP))
|
||||
unEquip(what)
|
||||
who.equip_to_slot_if_possible(what, where, FALSE, TRUE)
|
||||
add_attack_logs(src, who, "Equipped [what]")
|
||||
|
||||
/mob/living/singularity_act()
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
|
||||
@@ -46,7 +46,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
|
||||
see_invisible = SEE_INVISIBLE_LIVING_AI
|
||||
see_in_dark = 8
|
||||
can_strip = FALSE
|
||||
hud_type = /datum/hud/ai
|
||||
hat_offset_y = 3
|
||||
is_centered = TRUE
|
||||
@@ -244,6 +243,10 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/Initialize(mapload)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(src, TRAIT_CAN_STRIP, TRAIT_GENERIC)
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
GLOB.ai_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
has_unlimited_silicon_privilege = TRUE
|
||||
sentience_type = SENTIENCE_ARTIFICIAL
|
||||
status_flags = 0 // No default canpush
|
||||
can_strip = FALSE
|
||||
hud_type = /datum/hud/bot
|
||||
|
||||
speak_emote = list("states")
|
||||
@@ -248,6 +247,7 @@
|
||||
diag_hud_set_botstat()
|
||||
diag_hud_set_botmode()
|
||||
|
||||
REMOVE_TRAIT(src, TRAIT_CAN_STRIP, TRAIT_GENERIC)
|
||||
|
||||
/mob/living/simple_animal/bot/med_hud_set_health()
|
||||
return // We use a different hud
|
||||
@@ -908,9 +908,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
/mob/living/simple_animal/bot/proc/openedDoor(obj/machinery/door/D)
|
||||
frustration = 0
|
||||
|
||||
/mob/living/simple_animal/bot/show_inv()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/proc/show_controls(mob/M)
|
||||
users |= M
|
||||
var/dat = ""
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
//corgi's stippable items
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
/datum/strippable_item/corgi_head,
|
||||
/datum/strippable_item/corgi_back,
|
||||
/datum/strippable_item/pet_collar
|
||||
)))
|
||||
|
||||
/datum/strippable_item/corgi_head
|
||||
key = STRIPPABLE_ITEM_HEAD
|
||||
|
||||
/datum/strippable_item/corgi_head/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
|
||||
return corgi_source.inventory_head
|
||||
|
||||
/datum/strippable_item/corgi_head/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(source, TYPE_PROC_REF(/mob/living/simple_animal/pet/dog/corgi, place_on_head), equipping, user)
|
||||
|
||||
/datum/strippable_item/corgi_head/finish_unequip(atom/source, mob/user)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), corgi_source.inventory_head)
|
||||
corgi_source.inventory_head = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/datum/strippable_item/pet_collar
|
||||
key = STRIPPABLE_ITEM_PET_COLLAR
|
||||
|
||||
/datum/strippable_item/pet_collar/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet_source = source
|
||||
if(!istype(pet_source))
|
||||
return
|
||||
|
||||
return pet_source.pcollar
|
||||
|
||||
/datum/strippable_item/pet_collar/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(!istype(equipping, /obj/item/petcollar))
|
||||
to_chat(user, "<span class='warning'>That's not a collar.</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/pet_collar/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
var/mob/living/simple_animal/pet_source = source
|
||||
if(!istype(pet_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(source, TYPE_PROC_REF(/mob/living/simple_animal, add_collar), equipping, user)
|
||||
|
||||
/datum/strippable_item/pet_collar/finish_unequip(atom/source, mob/user)
|
||||
var/mob/living/simple_animal/pet_source = source
|
||||
if(!istype(pet_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(pet_source, TYPE_PROC_REF(/mob/living/simple_animal, remove_collar), user.drop_location(), user)
|
||||
|
||||
|
||||
/datum/strippable_item/corgi_back
|
||||
key = STRIPPABLE_ITEM_BACK
|
||||
|
||||
/datum/strippable_item/corgi_back/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
|
||||
return corgi_source.inventory_back
|
||||
|
||||
/datum/strippable_item/corgi_back/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
if(!ispath(equipping.dog_fashion, /datum/dog_fashion/back))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi = source
|
||||
to_chat(user, "<span class='warning'>You set [equipping] on [source]'s back, but it falls off!</span>")
|
||||
INVOKE_ASYNC(equipping, TYPE_PROC_REF(/atom/movable, forceMove), source.drop_location())
|
||||
if(prob(25))
|
||||
step_rand(equipping)
|
||||
var/old_dir = corgi.dir
|
||||
corgi.spin(7, 1)
|
||||
corgi.setDir(old_dir)
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(equipping, TYPE_PROC_REF(/atom/movable, forceMove), corgi_source)
|
||||
corgi_source.inventory_back = equipping
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/datum/strippable_item/corgi_back/finish_unequip(atom/source, mob/user)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if(!istype(corgi_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), corgi_source.inventory_back)
|
||||
corgi_source.inventory_back = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
@@ -75,8 +75,12 @@
|
||||
animal_species = /mob/living/simple_animal/pet/dog
|
||||
collar_type = "corgi"
|
||||
hud_type = /datum/hud/corgi
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_back
|
||||
///Currently worn item on the head slot
|
||||
var/obj/item/inventory_head = null
|
||||
///Currently worn item on the back slot
|
||||
var/obj/item/inventory_back = null
|
||||
///Item slots that are available for this corgi to equip stuff into
|
||||
var/list/strippable_inventory_slots = list()
|
||||
var/shaved = FALSE
|
||||
var/nofur = FALSE //Corgis that have risen past the material plane of existence.
|
||||
|
||||
@@ -84,6 +88,9 @@
|
||||
. = ..()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/add_strippable_element()
|
||||
AddElement(/datum/element/strippable, length(strippable_inventory_slots) ? create_strippable_list(strippable_inventory_slots) : GLOB.strippable_corgi_items)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Destroy()
|
||||
QDEL_NULL(inventory_head)
|
||||
QDEL_NULL(inventory_back)
|
||||
@@ -159,25 +166,6 @@
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user)
|
||||
if(user.incapacitated() || !Adjacent(user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
|
||||
dat += get_invslot_content()
|
||||
|
||||
var/datum/browser/popup = new(user, "mob[UID()]", "[src]", 440, 250)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/get_invslot_content()
|
||||
var/dat = "<br><b>Head:</b> <a href='?src=[UID()];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</a>"
|
||||
dat += "<br><b>Back:</b> <A href='?src=[UID()];[inventory_back ? "remove_inv=back'>[inventory_back]" : "add_inv=back'>Nothing"]</a>"
|
||||
dat += "<br><b>Collar:</b> <a href='?src=[UID()];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</a>"
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type)
|
||||
var/armorval = 0
|
||||
|
||||
@@ -219,106 +207,6 @@
|
||||
..()
|
||||
update_corgi_fluff()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
|
||||
if(!(iscarbon(usr) || isrobot(usr)) || usr.incapacitated() || !Adjacent(usr))
|
||||
usr << browse(null, "window=mob[UID()]")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
//Removing from inventory
|
||||
if(href_list["remove_inv"])
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if("head")
|
||||
if(inventory_head)
|
||||
if(inventory_head.flags & NODROP)
|
||||
to_chat(usr, "<span class='warning'>\The [inventory_head] is stuck too hard to [src] for you to remove!</span>")
|
||||
return
|
||||
usr.put_in_hands(inventory_head)
|
||||
inventory_head = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
if("back")
|
||||
if(inventory_back)
|
||||
if(inventory_back.flags & NODROP)
|
||||
to_chat(usr, "<span class='warning'>\The [inventory_head] is stuck too hard to [src] for you to remove!</span>")
|
||||
return
|
||||
usr.put_in_hands(inventory_back)
|
||||
inventory_back = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
if("collar")
|
||||
if(pcollar)
|
||||
var/the_collar = pcollar
|
||||
unEquip(pcollar)
|
||||
usr.put_in_hands(the_collar)
|
||||
pcollar = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
show_inv(usr)
|
||||
|
||||
//Adding things to inventory
|
||||
else if(href_list["add_inv"])
|
||||
var/add_to = href_list["add_inv"]
|
||||
|
||||
switch(add_to)
|
||||
if("collar")
|
||||
add_collar(usr.get_active_hand(), usr)
|
||||
update_corgi_fluff()
|
||||
|
||||
if("head")
|
||||
place_on_head(usr.get_active_hand(),usr)
|
||||
|
||||
if("back")
|
||||
if(inventory_back)
|
||||
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
|
||||
return
|
||||
else
|
||||
var/obj/item/item_to_add = usr.get_active_hand()
|
||||
|
||||
if(!item_to_add)
|
||||
usr.visible_message("<span class='notice'>[usr] pets [src].</span>", "<span class='notice'>You rest your hand on [src]'s back for a moment.</span>")
|
||||
return
|
||||
|
||||
if(!usr.unEquip(item_to_add))
|
||||
to_chat(usr, "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>")
|
||||
return
|
||||
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic/c4)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,usr,1)
|
||||
return
|
||||
|
||||
//The objects that corgis can wear on their backs.
|
||||
var/allowed = FALSE
|
||||
if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/back))
|
||||
allowed = TRUE
|
||||
|
||||
if(!allowed)
|
||||
to_chat(usr, "<span class='warning'>You set [item_to_add] on [src]'s back, but it falls off!</span>")
|
||||
item_to_add.forceMove(drop_location())
|
||||
if(prob(25))
|
||||
step_rand(item_to_add)
|
||||
for(var/i in list(1,2,4,8,4,8,4,dir))
|
||||
setDir(i)
|
||||
sleep(1)
|
||||
return
|
||||
|
||||
item_to_add.forceMove(src)
|
||||
inventory_back = item_to_add
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
show_inv(usr)
|
||||
else
|
||||
return ..()
|
||||
|
||||
//Corgis are supposed to be simpler, so only a select few objects can actually be put
|
||||
//to be compatible with them. The objects are below.
|
||||
//Many hats added, Some will probably be removed, just want to see which ones are popular.
|
||||
@@ -326,10 +214,6 @@
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic/c4)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,user,1)
|
||||
return
|
||||
|
||||
if(inventory_head)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You can't put more than one hat on [src]!</span>")
|
||||
@@ -643,10 +527,8 @@
|
||||
pass_flags = PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
collar_type = "puppy"
|
||||
strippable_inventory_slots = list(/datum/strippable_item/pet_collar) // Puppies do not have a head or back equipment slot.
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/get_invslot_content()
|
||||
// Puppies do not have a head or back equipment slot.
|
||||
return "<br><B>Collar:</B> <A href='?src=[UID()];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
|
||||
|
||||
/// Tribute to the corgis born in nullspace
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/void
|
||||
@@ -678,19 +560,13 @@
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
strippable_inventory_slots = list(/datum/strippable_item/corgi_back, /datum/strippable_item/pet_collar) //Lisa already has a cute bow!
|
||||
var/turns_since_scan = 0
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/Life()
|
||||
..()
|
||||
make_babies()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/get_invslot_content()
|
||||
// Lisa already has a cute bow! Only back and collar slots available.
|
||||
var/dat = "<br><B>Back:</B> <A href='?src=[UID()];[inventory_back ? "remove_inv=back'>[html_encode(inventory_back)]" : "add_inv=back'>Nothing"]</A>"
|
||||
dat += "<br><B>Collar:</B> <A href='?src=[UID()];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/handle_automated_movement()
|
||||
. = ..()
|
||||
if(!IS_HORIZONTAL(src) && !buckled)
|
||||
|
||||
@@ -109,6 +109,10 @@
|
||||
/obj/machinery/recharge_station, /obj/machinery/smartfridge, \
|
||||
/obj/machinery/computer))
|
||||
|
||||
|
||||
/mob/living/simple_animal/parrot/add_strippable_element()
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_parrot_items)
|
||||
|
||||
/mob/living/simple_animal/parrot/Destroy()
|
||||
GLOB.hear_radio_list -= src
|
||||
return ..()
|
||||
@@ -126,102 +130,6 @@
|
||||
. = status_tab_data
|
||||
status_tab_data[++status_tab_data.len] = list("Held Item:", "[held_item]")
|
||||
|
||||
/*
|
||||
* Inventory
|
||||
*/
|
||||
/mob/living/simple_animal/parrot/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = {"<table>"}
|
||||
|
||||
dat += "<tr><td><b>Headset:</b></td><td><a href='?src=[UID()];[ears?"remove_inv":"add_inv"]=ears'>[(ears && !(ears.flags&ABSTRACT)) ? ears : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
if(can_collar)
|
||||
dat += "<tr><td> </td></tr>"
|
||||
dat += "<tr><td><b>Collar:</b></td><td><a href='?src=[UID()];[pcollar ? "remove_inv" : "add_inv"]=collar'>[(pcollar && !(pcollar.flags&ABSTRACT)) ? pcollar : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/simple_animal/parrot/Topic(href, href_list)
|
||||
//Can the usr physically do this?
|
||||
if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.stat || usr.restrained() || !usr.Adjacent(src))
|
||||
return
|
||||
|
||||
//Is the usr's mob type able to do this?
|
||||
if(ishuman(usr) || isrobot(usr))
|
||||
if(href_list["remove_inv"])
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if("ears")
|
||||
if(ears)
|
||||
if(stat == CONSCIOUS) //DEAD PARROTS SHOULD NOT SPEAK (i hate that this is done in topic)
|
||||
if(length(available_channels))
|
||||
say("[pick(available_channels)]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
else
|
||||
say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
ears.forceMove(loc)
|
||||
ears = null
|
||||
update_speak()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
show_inv(usr)
|
||||
else if(href_list["add_inv"])
|
||||
var/add_to = href_list["add_inv"]
|
||||
if(!usr.get_active_hand())
|
||||
to_chat(usr, "<span class='warning'>You have nothing in your hand to put on its [add_to].</span>")
|
||||
return
|
||||
switch(add_to)
|
||||
if("ears")
|
||||
if(ears)
|
||||
to_chat(usr, "<span class='warning'>It's already wearing something.</span>")
|
||||
return
|
||||
else
|
||||
var/obj/item/item_to_add = usr.get_active_hand()
|
||||
if(!item_to_add)
|
||||
return
|
||||
|
||||
if(!istype(item_to_add, /obj/item/radio/headset))
|
||||
to_chat(usr, "<span class='warning'>This object won't fit.</span>")
|
||||
return
|
||||
|
||||
var/obj/item/radio/headset/headset_to_add = item_to_add
|
||||
|
||||
usr.drop_item()
|
||||
headset_to_add.forceMove(src)
|
||||
ears = headset_to_add
|
||||
to_chat(usr, "You fit the headset onto [src].")
|
||||
|
||||
available_channels.Cut()
|
||||
for(var/ch in headset_to_add.channels)
|
||||
switch(ch)
|
||||
if("Engineering")
|
||||
available_channels.Add(":e")
|
||||
if("Command")
|
||||
available_channels.Add(":c")
|
||||
if("Security")
|
||||
available_channels.Add(":s")
|
||||
if("Science")
|
||||
available_channels.Add(":n")
|
||||
if("Medical")
|
||||
available_channels.Add(":m")
|
||||
if("Mining")
|
||||
available_channels.Add(":d")
|
||||
if("Cargo")
|
||||
available_channels.Add(":q")
|
||||
|
||||
if(headset_to_add.translate_binary)
|
||||
available_channels.Add(":b")
|
||||
update_speak()
|
||||
show_inv(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
* Attack responces
|
||||
*/
|
||||
@@ -292,17 +200,41 @@
|
||||
if(pulledby && stat == CONSCIOUS)
|
||||
icon_state = "parrot_fly"
|
||||
|
||||
/mob/living/simple_animal/parrot/proc/update_available_channels()
|
||||
available_channels.Cut()
|
||||
if(!istype(ears) || QDELETED(ears))
|
||||
return
|
||||
|
||||
for(var/ch in ears.channels)
|
||||
switch(ch)
|
||||
if("Engineering")
|
||||
available_channels.Add(":e")
|
||||
if("Command")
|
||||
available_channels.Add(":c")
|
||||
if("Security")
|
||||
available_channels.Add(":s")
|
||||
if("Science")
|
||||
available_channels.Add(":n")
|
||||
if("Medical")
|
||||
available_channels.Add(":m")
|
||||
if("Mining")
|
||||
available_channels.Add(":d")
|
||||
if("Cargo")
|
||||
available_channels.Add(":q")
|
||||
|
||||
if(ears.translate_binary)
|
||||
available_channels.Add(":b")
|
||||
|
||||
/mob/living/simple_animal/parrot/proc/update_speak()
|
||||
speak.Cut()
|
||||
|
||||
if(available_channels.len && ears)
|
||||
if(ears && length(available_channels))
|
||||
for(var/possible_phrase in clean_speak)
|
||||
//50/50 chance to not use the radio at all
|
||||
speak += "[prob(50) ? pick(available_channels) : ""][possible_phrase]"
|
||||
|
||||
else //If we have no headset or channels to use, dont try to use any!
|
||||
for(var/possible_phrase in clean_speak)
|
||||
speak += possible_phrase
|
||||
return
|
||||
//If we have no headset or channels to use, dont try to use any!
|
||||
speak = clean_speak.Copy()
|
||||
|
||||
/mob/living/simple_animal/parrot/handle_automated_movement()
|
||||
if(pulledby)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
/datum/strippable_item/parrot_headset,
|
||||
/datum/strippable_item/pet_collar
|
||||
)))
|
||||
|
||||
/datum/strippable_item/parrot_headset
|
||||
key = STRIPPABLE_ITEM_PARROT_HEADSET
|
||||
|
||||
/datum/strippable_item/parrot_headset/get_item(atom/source)
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
return istype(parrot_source) ? parrot_source.ears : null
|
||||
|
||||
/datum/strippable_item/parrot_headset/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(!istype(equipping, /obj/item/radio/headset))
|
||||
to_chat(user, "<span class='warning'>[equipping] won't fit!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/parrot_headset/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
var/obj/item/radio/headset/radio = equipping
|
||||
if(!istype(radio))
|
||||
return
|
||||
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if(!istype(parrot_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(equipping, TYPE_PROC_REF(/atom/movable, forceMove), parrot_source)
|
||||
parrot_source.ears = radio
|
||||
parrot_source.update_available_channels()
|
||||
parrot_source.update_speak()
|
||||
|
||||
to_chat(user, "<span class='notice'>You fit [radio] onto [source].</span>")
|
||||
|
||||
/datum/strippable_item/parrot_headset/start_unequip(atom/source, mob/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if(!istype(parrot_source))
|
||||
return
|
||||
|
||||
if(parrot_source.stat == CONSCIOUS) // DEAD PARROTS TELL NO TALES (Finally moved this out of topic, thank god)
|
||||
parrot_source.say("[length(parrot_source.available_channels) ? "[pick(parrot_source.available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/parrot_headset/finish_unequip(atom/source, mob/user)
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if(!istype(parrot_source))
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(parrot_source.ears, TYPE_PROC_REF(/atom/movable, forceMove), parrot_source.drop_location())
|
||||
parrot_source.ears = null
|
||||
parrot_source.update_available_channels()
|
||||
parrot_source.update_speak()
|
||||
@@ -93,7 +93,7 @@
|
||||
var/collar_type
|
||||
/// If the mob can be renamed
|
||||
var/unique_pet = FALSE
|
||||
/// Can add collar to mob or not
|
||||
/// Can add collar to mob or not, use the set_can_collar if you want to change this on runtime
|
||||
var/can_collar = FALSE
|
||||
|
||||
/// Hot simple_animal baby making vars
|
||||
@@ -161,6 +161,7 @@
|
||||
regenerate_icons()
|
||||
if(footstep_type)
|
||||
AddComponent(/datum/component/footstep, footstep_type)
|
||||
add_strippable_element()
|
||||
|
||||
/mob/living/simple_animal/Destroy()
|
||||
/// We need to clear the reference to where we're walking to properly GC
|
||||
@@ -507,18 +508,6 @@
|
||||
current_offspring += 1
|
||||
return new childspawn(target)
|
||||
|
||||
/mob/living/simple_animal/show_inv(mob/user as mob)
|
||||
if(!can_collar)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = "<table><tr><td><b>Collar:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_COLLAR]'>[(pcollar && !(pcollar.flags & ABSTRACT)) ? pcollar : "<font color=grey>Empty</font>"]</a></td></tr></table>"
|
||||
dat += "<a href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 250)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/simple_animal/get_item_by_slot(slot_id)
|
||||
switch(slot_id)
|
||||
if(SLOT_HUD_COLLAR)
|
||||
@@ -658,6 +647,20 @@
|
||||
name = P.tagname
|
||||
real_name = P.tagname
|
||||
|
||||
/mob/living/simple_animal/proc/remove_collar(atom/new_loc, mob/user)
|
||||
if(!pcollar)
|
||||
return
|
||||
|
||||
var/obj/old_collar = pcollar
|
||||
|
||||
unEquip(pcollar)
|
||||
|
||||
if(user)
|
||||
user.put_in_hands(old_collar)
|
||||
|
||||
return old_collar
|
||||
|
||||
|
||||
/mob/living/simple_animal/regenerate_icons()
|
||||
cut_overlays()
|
||||
if(pcollar && collar_type)
|
||||
@@ -681,3 +684,16 @@
|
||||
|
||||
/mob/living/simple_animal/proc/end_dchat_plays()
|
||||
stop_automated_movement = FALSE
|
||||
|
||||
/mob/living/simple_animal/proc/set_can_collar(new_value)
|
||||
can_collar = (new_value ? TRUE : FALSE)
|
||||
if(can_collar)
|
||||
add_strippable_element()
|
||||
return
|
||||
remove_collar(drop_location())
|
||||
RemoveElement(/datum/element/strippable)
|
||||
|
||||
/mob/living/simple_animal/proc/add_strippable_element()
|
||||
if(!can_collar)
|
||||
return
|
||||
AddElement(/datum/element/strippable, create_strippable_list(list(/datum/strippable_item/pet_collar)))
|
||||
|
||||
+3
-46
@@ -39,6 +39,7 @@
|
||||
reset_perspective(src)
|
||||
prepare_huds()
|
||||
update_runechat_msg_location()
|
||||
ADD_TRAIT(src, TRAIT_CAN_STRIP, TRAIT_GENERIC)
|
||||
. = ..()
|
||||
|
||||
/atom/proc/prepare_huds()
|
||||
@@ -602,20 +603,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
client.screen = list()
|
||||
hud_used.show_hud(hud_used.hud_version)
|
||||
|
||||
/mob/proc/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"<table>
|
||||
<tr><td><b>Left Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_LEFT_HAND]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td><b>Right Hand:</b></td><td><a href='?src=[UID()];item=[SLOT_HUD_RIGHT_HAND]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</a></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
dat += {"</table>
|
||||
<a href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</a>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 250)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
|
||||
/mob/verb/examinate(atom/A as mob|obj|turf in view())
|
||||
set name = "Examine"
|
||||
@@ -907,26 +894,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
|
||||
if(href_list["refresh"])
|
||||
if(machine && in_range(src, usr))
|
||||
show_inv(machine)
|
||||
|
||||
if(!usr.incapacitated() && in_range(src, usr))
|
||||
if(href_list["item"])
|
||||
var/slot = text2num(href_list["item"])
|
||||
var/obj/item/what = get_item_by_slot(slot)
|
||||
|
||||
if(what)
|
||||
usr.stripPanelUnequip(what,src,slot)
|
||||
else
|
||||
usr.stripPanelEquip(what,src,slot)
|
||||
|
||||
if(usr.machine == src)
|
||||
if(Adjacent(usr))
|
||||
show_inv(usr)
|
||||
else
|
||||
usr << browse(null,"window=mob\ref[src]")
|
||||
|
||||
if(href_list["flavor_more"])
|
||||
usr << browse(text("<html><meta charset='utf-8'><head><title>[]</title></head><body><tt>[]</tt></body></html>", name, replacetext(flavor_text, "\n", "<br>")), "window=[name];size=500x200")
|
||||
onclose(usr, "[name]")
|
||||
@@ -936,16 +903,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
if(href_list["scoreboard"])
|
||||
usr << browse(GLOB.scoreboard, "window=roundstats;size=500x600")
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Defined in living.dm
|
||||
/mob/proc/stripPanelUnequip(obj/item/what, mob/who)
|
||||
return
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// Defined in living.dm
|
||||
/mob/proc/stripPanelEquip(obj/item/what, mob/who)
|
||||
return
|
||||
|
||||
/mob/MouseDrop(mob/M as mob, src_location, over_location, src_control, over_control, params)
|
||||
if((M != usr) || !istype(M))
|
||||
..()
|
||||
@@ -954,7 +911,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
var/mob/living/L = M
|
||||
if(L.mob_size <= MOB_SIZE_SMALL)
|
||||
return // Stops pAI drones and small mobs (parrots, crabs) from stripping people. --DZD
|
||||
if(!M.can_strip)
|
||||
if(!HAS_TRAIT(M, TRAIT_CAN_STRIP))
|
||||
return
|
||||
if(usr == src)
|
||||
return
|
||||
@@ -965,7 +922,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
return
|
||||
if(isLivingSSD(src) && M.client && M.client.send_ssd_warning(src))
|
||||
return
|
||||
show_inv(usr)
|
||||
SEND_SIGNAL(src, COMSIG_DO_MOB_STRIP, M, usr)
|
||||
|
||||
/mob/proc/can_use_hands()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user