diff --git a/code/ZAS/_gas_mixture.dm b/code/ZAS/_gas_mixture.dm index 2a90ebb00e3..b4321fa41ba 100644 --- a/code/ZAS/_gas_mixture.dm +++ b/code/ZAS/_gas_mixture.dm @@ -1168,3 +1168,27 @@ What are the archived variables for? update_values() return 1 + +/datum/gas_mixture/proc/english_contents_list() + var/all_contents = list() + if(oxygen) + all_contents += "Oxygen" + if(nitrogen) + all_contents += "Nitrogen" + if(carbon_dioxide) + all_contents += "CO2" + if(toxins) + all_contents += "Plasma" + if(locate(/datum/gas/sleeping_agent) in trace_gases) + all_contents += "N2O" + return english_list(all_contents) + +/datum/gas_mixture/proc/loggable_contents() + var/naughty_stuff = list() + if(toxins) + naughty_stuff += "Plasma" + if(carbon_dioxide) + naughty_stuff += "CO2" + if(locate(/datum/gas/sleeping_agent) in trace_gases) + naughty_stuff += "N2O" + return english_list(naughty_stuff, nothing_text = "") diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 5222d773697..a7e52e3c406 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -1,3 +1,4 @@ +#define HTMLTAB "    " /* * Holds procs designed to help with filtering text * Contains groups: diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index e5974bf5407..b28d5e7961f 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -1,6 +1,5 @@ /datum/hud/proc/monkey_hud(var/ui_style='icons/mob/screen1_old.dmi') - - + var/mob/living/carbon/monkey/MO = mymob //sorry src.adding = list() src.other = list() @@ -142,41 +141,36 @@ using.layer = 19 src.adding += using - mymob.m_suitclothesbg = getFromPool(/obj/screen) - mymob.m_suitclothesbg.icon = ui_style - mymob.m_suitclothesbg.icon_state = "center" - mymob.m_suitclothesbg.name = "uniform" - mymob.m_suitclothesbg.screen_loc = ui_monkey_uniform + if(MO.canWearClothes) + inv_box = getFromPool(/obj/screen/inventory) + inv_box.name = "i_clothing" + inv_box.dir = SOUTH + inv_box.icon = ui_style + inv_box.slot_id = slot_w_uniform + inv_box.icon_state = "center" + inv_box.screen_loc = ui_monkey_uniform + inv_box.layer = 19 + src.adding += inv_box - mymob.m_suitclothes = getFromPool(/obj/screen) - mymob.m_suitclothes.icon = 'icons/mob/monkey.dmi' - mymob.m_suitclothes.icon_state = "none" - mymob.m_suitclothes.name = "uniform" - mymob.m_suitclothes.screen_loc = ui_monkey_uniform + if(MO.canWearHats) + inv_box = getFromPool(/obj/screen/inventory) + inv_box.name = "head" + inv_box.icon = ui_style + inv_box.icon_state = "hair" + inv_box.screen_loc = ui_monkey_hat + inv_box.slot_id = slot_head + inv_box.layer = 19 + src.adding += inv_box - mymob.m_hatbg = getFromPool(/obj/screen) - mymob.m_hatbg.icon = ui_style - mymob.m_hatbg.icon_state = "hair" - mymob.m_hatbg.name = "hat" - mymob.m_hatbg.screen_loc = ui_monkey_hat - - mymob.m_hat = getFromPool(/obj/screen) - mymob.m_hat.icon = 'icons/obj/clothing/hats.dmi' - mymob.m_hat.icon_state = "none" - mymob.m_hat.name = "hat" - mymob.m_hat.screen_loc = ui_monkey_hat - - mymob.m_glassesbg = getFromPool(/obj/screen) - mymob.m_glassesbg.icon = ui_style - mymob.m_glassesbg.icon_state = "glasses" - mymob.m_glassesbg.name = "glasses" - mymob.m_glassesbg.screen_loc = ui_monkey_glasses - - mymob.m_glasses = getFromPool(/obj/screen) - mymob.m_glasses.icon = 'icons/obj/clothing/glasses.dmi' - mymob.m_glasses.icon_state = "none" - mymob.m_glasses.name = "glasses" - mymob.m_glasses.screen_loc = ui_monkey_glasses + if(MO.canWearGlasses) + inv_box = getFromPool(/obj/screen/inventory) + inv_box.name = "eyes" + inv_box.icon = ui_style + inv_box.icon_state = "glasses" + inv_box.screen_loc = ui_monkey_glasses + inv_box.slot_id = slot_glasses + inv_box.layer = 19 + src.adding += inv_box inv_box = getFromPool(/obj/screen/inventory) inv_box.name = "mask" @@ -279,7 +273,7 @@ mymob.client.reset_screen() - mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.m_hatbg, mymob.m_hat, mymob.m_suitclothesbg, mymob.m_suitclothes, mymob.m_glassesbg, mymob.m_glasses, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach ) + mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach ) mymob.client.screen += src.adding + src.other return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index f7c74159daf..ecb70c5ec51 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -341,100 +341,7 @@ if("internal") if(iscarbon(usr)) var/mob/living/carbon/C = usr - if(!C.stat && !C.stunned && !C.paralysis && !C.restrained()) - if(C.internal) - C.internal = null - to_chat(C, "No longer running on internals.") - if(C.internals) - C.internals.icon_state = "internal0" - else - if(!istype(C.wear_mask, /obj/item/clothing/mask)) - to_chat(C, "You are not wearing a mask.") - return 1 - else - var/list/nicename = null - var/list/tankcheck = null - var/breathes = "oxygen" //default, we'll check later - var/list/contents = list() - - if(ishuman(C)) - var/mob/living/carbon/human/H = C - breathes = H.species.breath_type - nicename = list ("suit", "back", "belt", "left pocket", "right pocket") //Hands are added below - tankcheck = list (H.s_store, C.back, H.belt, H.l_store, H.r_store) - - else - nicename = list("back") - tankcheck = list(C.back) - - tankcheck = tankcheck + C.held_items - for(var/i = 1 to C.held_items.len) - nicename.Add(C.get_index_limb_name(i)) - - for(var/i=1, i bestcontents) - best = i - bestcontents = contents[i] - - - //We've determined the best container now we set it as our internals - - if(best) - to_chat(C, "You are now running on internals from [tankcheck[best]] on your [nicename[best]].") - C.internal = tankcheck[best] - - - if(C.internal) - if(C.internals) - C.internals.icon_state = "internal1" - else - to_chat(C, "You don't have a[breathes=="oxygen" ? "n oxygen" : addtext(" ",breathes)] tank.") + C.toggle_internals(usr) if("act_intent") usr.a_intent_change("right") if("help") @@ -650,32 +557,6 @@ if("Toggle Gun Mode") usr.client.ToggleGunMode() - if("uniform") - if(ismonkey(usr)) - var/mob/living/carbon/monkey/M = usr - if(M.canWearClothes) - if (!M.get_active_hand()) - M.wearclothes(null) - else if (istype(M.get_active_hand(), /obj/item/clothing/monkeyclothes)) - M.wearclothes(M.get_active_hand()) - - if("hat") - if(ismonkey(usr)) - var/mob/living/carbon/monkey/M = usr - if(M.canWearHats) - if (!M.get_active_hand()) - M.wearhat(null) - else if (istype(M.get_active_hand(), /obj/item/clothing/head)) - M.wearhat(M.get_active_hand()) - - if("glasses") - if(ismonkey(usr)) - var/mob/living/carbon/monkey/M = usr - if(M.canWearGlasses) - if (!M.get_active_hand()) - M.wearglasses(null) - else if (istype(M.get_active_hand(), /obj/item/clothing/glasses)) - M.wearglasses(M.get_active_hand()) else return 0 return 1 diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 0becfde93f6..1247da4e710 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1067,12 +1067,9 @@ return cultist.unlock_from() if (cultist.handcuffed) - cultist.handcuffed.loc = cultist.loc - cultist.handcuffed.handcuffs_remove(cultist) + cultist.drop_from_inventory(cultist.handcuffed) if (cultist.legcuffed) - cultist.legcuffed.loc = cultist.loc - cultist.legcuffed = null - cultist.update_inv_legcuffed() + cultist.drop_from_inventory(cultist.legcuffed) if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) cultist.u_equip(cultist.wear_mask, 1) if(istype(cultist.loc, /obj/structure/closet)) @@ -1320,13 +1317,9 @@ var/mob/living/carbon/monkey/K = user K.visible_message(" The rune disappears with a flash of red light, [K] now looks like the cutest of all followers of Nar-Sie...", \ "You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor. Might not offer much protection due to its size though.") - if(!istype(K.uniform, /obj/item/clothing/monkeyclothes/cultrobes)) - var/obj/item/clothing/monkeyclothes/cultrobes/CR = new /obj/item/clothing/monkeyclothes/cultrobes(user.loc) - K.wearclothes(CR) - if(!istype(K.hat, /obj/item/clothing/head/culthood/alt)) - var/obj/item/clothing/head/culthood/alt/CH = new /obj/item/clothing/head/culthood/alt(user.loc) - K.wearhat(CH) - K.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(K), slot_back) + K.equip_to_slot_or_drop(new /obj/item/clothing/monkeyclothes/cultrobes, slot_w_uniform) + K.equip_to_slot_or_drop(new /obj/item/clothing/head/culthood/alt, slot_head) + K.equip_to_slot_or_drop(new /obj/item/weapon/storage/backpack/cultpack, slot_back) K.put_in_hands(new /obj/item/weapon/melee/cultblade(K)) return else @@ -1350,11 +1343,9 @@ var/mob/living/carbon/monkey/K = M K.visible_message(" The rune disappears with a flash of red light, [K] now looks like the cutest of all followers of Nar-Sie...", \ "You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor. Might not offer much protection due to its size though.") - var/obj/item/clothing/monkeyclothes/cultrobes/CR = new /obj/item/clothing/monkeyclothes/cultrobes(loc) - K.wearclothes(CR) - var/obj/item/clothing/head/culthood/alt/CH = new /obj/item/clothing/head/culthood/alt(loc) - K.wearhat(CH) - K.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(K), slot_back) + K.equip_to_slot_or_drop(new /obj/item/clothing/monkeyclothes/cultrobes, slot_w_uniform) + K.equip_to_slot_or_drop(new /obj/item/clothing/head/culthood/alt, slot_head) + K.equip_to_slot_or_drop(new /obj/item/weapon/storage/backpack/cultpack, slot_back) K.put_in_hands(new /obj/item/weapon/melee/cultblade(K)) else if(isconstruct(M)) var/construct_class diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 76959e5c1ec..49aa68f38e1 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -346,8 +346,6 @@ return . if(href_list["toggle"]) - var/datum/gas/sleeping_agent/S = locate() in src.air_contents.trace_gases - if (valve_open) if (holding) investigation_log(I_ATMOS, "had its valve closed by [key_name(usr)], stopping transfer into \the [holding].") @@ -357,28 +355,21 @@ if (holding) investigation_log(I_ATMOS, "had its valve OPENED by [key_name(usr)], starting transfer into \the [holding]") else - var/list/contents_l=list() - if(src.air_contents.toxins > 0) - contents_l += "Plasma" - if(src.air_contents.carbon_dioxide > 0) - contents_l += "CO2" - if(istype(S)) - contents_l += "N2O" - var/contents_str = english_list(contents_l) - investigation_log(I_ATMOS, "had its valve OPENED by [key_name(usr)], starting transfer into the air ([contents_str])") - if(contents_l.len>0) - message_admins("[usr.real_name] ([formatPlayerPanel(usr,usr.ckey)]) opened a canister that contains [contents_str] at [formatJumpTo(loc)]!") - log_admin("[usr]([ckey(usr.key)]) opened a canister that contains [contents] at [loc.x], [loc.y], [loc.z]") + var/naughty_stuff = air_contents.loggable_contents() + investigation_log(I_ATMOS, "had its valve OPENED by [key_name(usr)], starting transfer into the air ([naughty_stuff])") + if(naughty_stuff) + message_admins("[usr.real_name] ([formatPlayerPanel(usr,usr.ckey)]) opened a canister that contains [naughty_stuff] at [formatJumpTo(loc)]!") + log_admin("[usr]([ckey(usr.key)]) opened a canister that contains [naughty_stuff] at [loc.x], [loc.y], [loc.z]") valve_open = !valve_open if (href_list["remove_tank"]) - var/datum/gas/sleeping_agent/S = locate() in src.air_contents.trace_gases if(holding) if(valve_open) - if(src.air_contents.toxins > 0 || (istype(S))) - message_admins("[usr.real_name] ([formatPlayerPanel(usr,usr.ckey)]) opened a canister that contains \[[src.air_contents.toxins > 0 ? "Toxins" : ""] [istype(S) ? " N2O" : ""]\] at [formatJumpTo(loc)]!") - log_admin("[usr]([ckey(usr.key)]) opened a canister that contains \[[src.air_contents.toxins > 0 ? "Toxins" : ""] [istype(S) ? " N2O" : ""]\] at [loc.x], [loc.y], [loc.z]") + var/naughty_stuff = air_contents.loggable_contents() + if(naughty_stuff) + message_admins("[usr.real_name] ([formatPlayerPanel(usr,usr.ckey)]) opened a canister that contains [naughty_stuff] at [formatJumpTo(loc)]!") + log_admin("[usr]([ckey(usr.key)]) opened a canister that contains [naughty_stuff] at [loc.x], [loc.y], [loc.z]") if(istype(holding, /obj/item/weapon/tank)) holding.manipulated_by = usr.real_name diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 58a1cb61115..39a0af0f2ff 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -240,8 +240,13 @@ if(wielded) unwield(user) +///called when an item is stripped off by another person, called BEFORE it is dropped. return 1 to prevent it from actually being stripped. +/obj/item/proc/before_stripped(mob/wearer as mob, mob/stripper as mob, slot) + if(slot in list(slot_l_store, slot_r_store)) //is in pockets + on_found(wearer, stripper) + ///called when an item is stripped off by another person, called AFTER it is on the ground -/obj/item/proc/stripped(mob/wearer as mob, mob/stripper as mob) +/obj/item/proc/stripped(mob/wearer as mob, mob/stripper as mob, slot) return unequipped(wearer) // called just as an item is picked up (loc is not yet changed). return 1 to prevent the item from being actually picked up. @@ -284,380 +289,442 @@ //If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. //Set disable_warning to 1 if you wish it to not give you outputs. /obj/item/proc/mob_can_equip(mob/M, slot, disable_warning = 0, automatic = 0) - if(!slot) return 0 - if(!M) return 0 + if(!slot) return CANNOT_EQUIP + if(!M) return CANNOT_EQUIP if(wielded) - if(flags & MUSTTWOHAND) - M.show_message("\The [src] is too cumbersome to carry in anything other than your hands.") - else - M.show_message("You have to unwield \the [wielded.wielding] first.") - return 0 + if(!disable_warning) + if(flags & MUSTTWOHAND) + M.show_message("\The [src] is too cumbersome to carry in anything other than your hands.") + else + M.show_message("You have to unwield \the [wielded.wielding] first.") + return CANNOT_EQUIP if(cant_drop > 0) - M << "It's stuck to your hands!" - return 0 + if(!disable_warning) + to_chat(M, "It's stuck to your hands!") + return CANNOT_EQUIP - if(ishuman(M)) + if(ishuman(M)) //Crimes Against OOP: This is first on the list if anybody ever feels like unfucking inventorycode //START HUMAN var/mob/living/carbon/human/H = M if(istype(src, /obj/item/clothing/under) || istype(src, /obj/item/clothing/suit)) if(M_FAT in H.mutations) - testing("[M] TOO FAT TO WEAR [src]!") + //testing("[M] TOO FAT TO WEAR [src]!") if(!(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You're too fat to wear the [name].") - return 0 + return CANNOT_EQUIP for(var/datum/organ/external/OE in get_organs_by_slot(slot, H)) if(!OE.species) //Organ has same species as body if(H.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) //Use the body's base species if(!disable_warning) to_chat(H, "You can't get \the [src] to fit over your bulky exterior!") - return 0 + return CANNOT_EQUIP else //Organ's species is different from body if(OE.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You can't get \the [src] to fit over your bulky exterior!") - return 0 + return CANNOT_EQUIP switch(slot) if(slot_wear_mask) if( !(slot_flags & SLOT_MASK) ) - return 0 + return CANNOT_EQUIP for(var/datum/organ/external/OE in get_organs_by_slot(slot, H)) if(!OE.species) //Organ has same species as body if(H.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) //Use the body's base species if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your thick head!") - return 0 + return CANNOT_EQUIP else //Organ's species is different from body if(OE.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your thick head!") - return 0 + return CANNOT_EQUIP if(H.wear_mask) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.wear_mask.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_back) if( !(slot_flags & SLOT_BACK) ) - return 0 + return CANNOT_EQUIP if(H.back) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.back.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_wear_suit) if( !(slot_flags & SLOT_OCLOTHING) ) - return 0 + return CANNOT_EQUIP for(var/datum/organ/external/OE in get_organs_by_slot(slot, H)) if(!OE.species) //Organ has same species as body if(H.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) //Use the body's base species if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky exterior!") - return 0 + return CANNOT_EQUIP else //Organ's species is different from body if(OE.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky exterior!") - return 0 + return CANNOT_EQUIP if(H.wear_suit) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.wear_suit.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_gloves) if( !(slot_flags & SLOT_GLOVES) ) - return 0 + return CANNOT_EQUIP for(var/datum/organ/external/OE in get_organs_by_slot(slot, H)) if(!OE.species) //Organ has same species as body if(H.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) //Use the body's base species if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky fingers!") - return 0 + return CANNOT_EQUIP else //Organ's species is different from body if(OE.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky fingers!") - return 0 + return CANNOT_EQUIP if(H.gloves) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.gloves.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_shoes) if( !(slot_flags & SLOT_FEET) ) - return 0 + return CANNOT_EQUIP for(var/datum/organ/external/OE in get_organs_by_slot(slot, H)) if(!OE.species) //Organ has same species as body if(H.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) //Use the body's base species if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky feet!") - return 0 + return CANNOT_EQUIP else //Organ's species is different from body if(OE.species.flags & IS_BULKY && !(flags & ONESIZEFITSALL)) if(!disable_warning) to_chat(H, "You can't get \the [src] to fasten around your bulky feet!") - return 0 + return CANNOT_EQUIP if(H.shoes) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.shoes.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_belt) if(!H.w_uniform) if(!disable_warning) to_chat(H, "You need a jumpsuit before you can attach this [name].") - return 0 + return CANNOT_EQUIP if( !(slot_flags & SLOT_BELT) ) - return 0 + return CANNOT_EQUIP if(H.belt) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.belt.canremove && !istype(H.belt, /obj/item/weapon/storage/belt)) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_glasses) if( !(slot_flags & SLOT_EYES) ) - return 0 + return CANNOT_EQUIP if(H.glasses) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.glasses.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_head) if( !(slot_flags & SLOT_HEAD) ) - return 0 + return CANNOT_EQUIP if(H.head) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.head.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_ears) if( !(slot_flags & SLOT_EARS) ) - return 0 + return CANNOT_EQUIP if(H.ears) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.ears.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP /* In case it's ever unfucked. if(slot_ears) if( !(slot_flags & SLOT_EARS) ) - return 0 + return CANNOT_EQUIP if( (slot_flags & SLOT_TWOEARS) && H.r_ear ) - return 0 + return CANNOT_EQUIP if(H.l_ear) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.l_ear.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 + return CANNOT_EQUIP if( w_class < W_CLASS_SMALL ) - return 1 - return 1 + return CAN_EQUIP + return CAN_EQUIP if(slot_r_ear) if( !(slot_flags & SLOT_EARS) ) - return 0 + return CANNOT_EQUIP if( (slot_flags & SLOT_TWOEARS) && H.l_ear ) - return 0 + return CANNOT_EQUIP if(H.r_ear) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.r_ear.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 + return CANNOT_EQUIP if( w_class < W_CLASS_SMALL ) - return 1 - return 1 + return CAN_EQUIP + return CAN_EQUIP */ if(slot_w_uniform) if( !(slot_flags & SLOT_ICLOTHING) ) - return 0 + return CANNOT_EQUIP if(H.w_uniform) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.w_uniform.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_wear_id) if(!H.w_uniform) if(!disable_warning) to_chat(H, "You need a jumpsuit before you can attach this [name].") - return 0 + return CANNOT_EQUIP if( !(slot_flags & SLOT_ID) ) - return 0 + return CANNOT_EQUIP if(H.wear_id) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.wear_id.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_l_store) if(!H.w_uniform) if(!disable_warning) to_chat(H, "You need a jumpsuit before you can attach this [name].") - return 0 + return CANNOT_EQUIP if(slot_flags & SLOT_DENYPOCKET) return if(automatic) if(H.l_store) - return 0 + return CANNOT_EQUIP else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) ) - return 1 + return CAN_EQUIP else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) ) if(H.l_store) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 1 + return CAN_EQUIP if(slot_r_store) if(!H.w_uniform) if(!disable_warning) to_chat(H, "You need a jumpsuit before you can attach this [name].") - return 0 + return CANNOT_EQUIP if(slot_flags & SLOT_DENYPOCKET) return if(automatic) if(H.r_store) - return 0 + return CANNOT_EQUIP else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) ) - return 1 + return CAN_EQUIP else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) ) if(H.r_store) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 1 + return CAN_EQUIP if(slot_s_store) if(!H.wear_suit) if(!disable_warning) to_chat(H, "You need a suit before you can attach this [name].") - return 0 + return CANNOT_EQUIP if(!H.wear_suit.allowed) if(!disable_warning) to_chat(usr, "You somehow have a suit with no defined allowed items for suit storage, stop that.") - return 0 + return CANNOT_EQUIP if(src.w_class > W_CLASS_MEDIUM && !H.wear_suit.allowed.len) if(!disable_warning) to_chat(usr, "The [name] is too big to attach.") - return 0 + return CANNOT_EQUIP if( istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed) ) if(H.s_store) if(automatic) if(H.check_for_open_slot(src)) - return 0 + return CANNOT_EQUIP if(H.s_store.canremove) - return 2 + return CAN_EQUIP_BUT_SLOT_TAKEN else - return 0 + return CANNOT_EQUIP else - return 1 - return 0 + return CAN_EQUIP + return CANNOT_EQUIP if(slot_handcuffed) if(H.handcuffed) - return 0 + return CANNOT_EQUIP if(!istype(src, /obj/item/weapon/handcuffs)) - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_legcuffed) if(H.legcuffed) - return 0 + return CANNOT_EQUIP if(!istype(src, /obj/item/weapon/legcuffs)) - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP if(slot_in_backpack) if (H.back && istype(H.back, /obj/item/weapon/storage/backpack)) var/obj/item/weapon/storage/backpack/B = H.back if(B.contents.len < B.storage_slots && w_class <= B.fits_max_w_class) - return 1 - return 0 - return 0 //Unsupported slot + return CAN_EQUIP + return CANNOT_EQUIP + return CANNOT_EQUIP //Unsupported slot //END HUMAN else if(ismonkey(M)) //START MONKEY var/mob/living/carbon/monkey/MO = M switch(slot) + if(slot_head) + if(!MO.canWearHats) + return CANNOT_EQUIP + if(MO.hat) + return CANNOT_EQUIP + if( !(slot_flags & SLOT_HEAD) ) + return CANNOT_EQUIP + return CAN_EQUIP if(slot_wear_mask) if(MO.wear_mask) - return 0 + return CANNOT_EQUIP if( !(slot_flags & SLOT_MASK) ) - return 0 - return 1 + return CANNOT_EQUIP + return CAN_EQUIP + if(slot_glasses) + if(!MO.canWearGlasses) + return CANNOT_EQUIP + if(MO.glasses) + return CANNOT_EQUIP + if( !(slot_flags & SLOT_EYES) ) + return CANNOT_EQUIP + return CAN_EQUIP + if(slot_w_uniform) + if(!MO.canWearClothes) + return CANNOT_EQUIP + if(MO.uniform) + return CANNOT_EQUIP + if( !(slot_flags & SLOT_ICLOTHING) ) + return CANNOT_EQUIP + return CAN_EQUIP if(slot_back) if(MO.back) - return 0 + return CANNOT_EQUIP if( !(slot_flags & SLOT_BACK) ) - return 0 - return 1 - return 0 //Unsupported slot + return CANNOT_EQUIP + return CAN_EQUIP + return CANNOT_EQUIP //Unsupported slot //END MONKEY + else if(isalienadult(M)) + //START ALIEN HUMANOID + var/mob/living/carbon/alien/humanoid/AH = M + switch(slot) + //Maybe when someone sprites an "alien lying down" version of every exosuit and hat in the game. + /*if(slot_head) + if(AH.head) + return CANNOT_EQUIP + if( !(slot_flags & SLOT_HEAD) ) + return CANNOT_EQUIP + return CAN_EQUIP + if(slot_wear_suit) + if(AH.wear_suit) + return CANNOT_EQUIP + if( !(slot_flags & SLOT_OCLOTHING) ) + return CANNOT_EQUIP + return CAN_EQUIP*/ + if(slot_l_store) + if(slot_flags & SLOT_DENYPOCKET) + return CANNOT_EQUIP + if(AH.l_store) + return CANNOT_EQUIP + if( !(w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET)) ) + return CANNOT_EQUIP + return CAN_EQUIP + if(slot_r_store) + if(slot_flags & SLOT_DENYPOCKET) + return CANNOT_EQUIP + if(AH.r_store) + return CANNOT_EQUIP + if( !(w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET)) ) + return CANNOT_EQUIP + return CAN_EQUIP + return CANNOT_EQUIP //Unsupported slot + //END ALIEN HUMANOID + else if(isMoMMI(M)) //START MOMMI ALSO THIS SO FUCKING SILLY var/mob/living/silicon/robot/mommi/MoM = M switch(slot) if(slot_head) if(MoM.head_state) - return 0 - return 1 - return 0 //Unsupported slot + return CANNOT_EQUIP + return CAN_EQUIP + return CANNOT_EQUIP //Unsupported slot //END MOMMI /obj/item/can_pickup(mob/living/user) diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index b59194cbff6..3a70ea3ad6b 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -5,7 +5,6 @@ icon_state = "dnainjector" var/block=0 var/datum/dna2/record/buf=null - var/s_time = 10.0 throw_speed = 1 throw_range = 5 w_class = W_CLASS_TINY @@ -104,6 +103,24 @@ //if(prob(5)) //trigger_side_effect(M) + if(buf.types & DNA2_BUF_SE) + if(block)// Isolated injector + if (GetState() && block == MONKEYBLOCK && istype(M, /mob/living/carbon/human)) + message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") + log_attack("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") + log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") + else + log_attack("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name]") + log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name]") + else + if (GetState(MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) + message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") + log_attack("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") + log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") + else + log_attack("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") + log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") + spawn(0)//this prevents the collapse of space-time continuum if(user) user.drop_from_inventory(src) @@ -127,90 +144,23 @@ else M.LAssailant = user - if (user) - if (istype(M, /mob/living/carbon/human)) - if(!inuse) - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) - O.source = user - O.target = M - O.item = src - O.s_loc = user.loc - O.t_loc = M.loc - O.place = "dnainjector" - src.inuse = 1 - spawn(50) // Not the best fix. There should be an failure proc, for /effect/equip_e/, which is called when the first initital checks fail - inuse = 0 - M.requests += O - if (buf.types & DNA2_BUF_SE) - if(block)// Isolated injector - //testing("Isolated block [block] injector with contents: [GetValue()]") - if (GetState() && block == MONKEYBLOCK && istype(M, /mob/living/carbon/human) ) - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") - log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name] (MONKEY)") - log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") - else - log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name]") - else - //testing("DNA injector with contents: [english_list(buf.dna.SE)]") - if (GetState(MONKEYBLOCK) && istype(M, /mob/living/carbon/human) ) - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") - log_attack("[key_name(user)] injected [key_name(M)] with the [name] (MONKEY)") - log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") - else - // message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") - log_attack("[key_name(user)] injected [key_name(M)] with the [name]") - else - // message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") - log_attack("[key_name(user)] injected [key_name(M)] with the [name]") + if(inuse) + return 0 - spawn( 0 ) - O.process() - return - else - if(!inuse) + user.visible_message("\The [user] is trying to inject \the [M] with \the [src]!") - for(var/mob/O in viewers(M, null)) - O.show_message(text("[] has been injected with [] by [].", M, src, user), 1) - //Foreach goto(192) - if (!(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey))) - to_chat(user, "Apparently it didn't work.") - return + inuse = 1 + if(!do_after(user, M, 5 SECONDS)) + inuse = 0 //If you've got a better idea on how to not repeat this twice I'd like to hear it + return + inuse = 0 - if (buf.types & DNA2_BUF_SE) - if(block)// Isolated injector - //testing("Isolated block [block] injector with contents: [GetValue()]") - if (GetState() && block == MONKEYBLOCK && istype(M, /mob/living/carbon/human) ) - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") - log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name] (MONKEY)") - log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)") - else - log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name]") - else - //testing("DNA injector with contents: [english_list(buf.dna.SE)]") - if (GetState(MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)") - log_game("[key_name(user)] injected [key_name(M)] with the [name] (MONKEY)") - else - // message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") - log_game("[key_name(user)] injected [key_name(M)] with the [name]") - else -// message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name]") - log_game("[key_name(user)] injected [key_name(M)] with the [name]") - inuse = 1 - inject(M, user)//Now we actually do the heavy lifting. - spawn(50) - inuse = 0 - /* - A user injecting themselves could mean their own transformation and deletion of mob. - I don't have the time to figure out how this code works so this will do for now. - I did rearrange things a bit. - */ - if(user)//If the user still exists. Their mob may not. - if(M)//Runtime fix: If the mob doesn't exist, mob.name doesnt work. - Nodrak - user.show_message(text("You inject [M.name].")) - else - user.show_message(text("You finish the injection.")) - return + M.visible_message("\The [M] has been injected with \the [src] by \the [user].") + if (!istype(M, /mob/living/carbon/human) && !istype(M, /mob/living/carbon/monkey)) + to_chat(user, "Apparently, the DNA injector didn't work...") + return + + inject(M, user) /obj/item/weapon/dnainjector/nofail nofail = MUTCHK_FORCED diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index e72b27443db..517f60760ea 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -30,7 +30,7 @@ return if((M_CLUMSY in user.mutations) && prob(50)) - to_chat(usr, "Uh ... how do those things work?!") + to_chat(usr, "Uh... how do these things work?!") handcuffs_apply(M, user, TRUE) return @@ -44,61 +44,46 @@ else M.LAssailant = user - log_attack("[user.name] ([user.ckey]) Attempted to handcuff [M.name] ([M.ckey])") + log_attack("[user.name] ([user.ckey]) Attempted to handcuff [M.name] ([M.ckey])") handcuffs_apply(M, user) -//Our inventory procs should be able to handle the following, but our inventory code is hot spaghetti bologni, so here we go +//Our inventory procs should be able to handle the following, but our inventory code is hot spaghetti bologni, so here we go //There's no real reason for this to be a separate proc now but whatever /obj/item/weapon/handcuffs/proc/handcuffs_apply(var/mob/living/carbon/C, var/mob/user, var/clumsy = FALSE) if(!istype(C)) //Sanity doesn't hurt, right ? return FALSE if(ishuman(C)) - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human() - O.source = user - O.target = C - O.t_loc = C.loc - O.item = user.get_active_hand() - O.s_loc = user.loc - O.place = "handcuff" - C.requests += O - spawn() - if(istype(src, /obj/item/weapon/handcuffs/cable)) - feedback_add_details("handcuffs", "C") - else - feedback_add_details("handcuffs", "H") - playsound(get_turf(src), cuffing_sound, 30, 1, -2) - O.process() - - else - var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey() - O.source = user - O.target = C - O.item = user.get_active_hand() - O.s_loc = user.loc - O.t_loc = C.loc - O.place = "handcuff" - C.requests += O - spawn() - playsound(get_turf(src), cuffing_sound, 30, 1, -2) - O.process() - -/obj/item/weapon/handcuffs/proc/handcuffs_remove(var/mob/living/carbon/C) - C.handcuffed = null - C.update_inv_handcuffed() - -/obj/item/weapon/handcuffs/cyborg/attack(var/mob/living/carbon/M, var/mob/living/user, var/def_zone) - if (!istype(M) || M.handcuffed) - return FALSE + var/mob/living/carbon/human/H = C + if (!H.has_organ_for_slot(slot_handcuffed)) + to_chat(user, "\The [C] needs at least two wrists before you can cuff them together!") + return playsound(get_turf(src), cuffing_sound, 30, 1, -2) - user.visible_message("[user] is trying to handcuff \the [M]!", - "You try to handcuff \the [M]!") - if(do_after(user, M, 30)) - M.handcuffed = new/obj/item/weapon/handcuffs(M) - M.update_inv_handcuffed() + user.visible_message("[user] is trying to handcuff \the [C]!", + "You try to handcuff \the [C]!") + + if(do_after(user, C, 3 SECONDS)) + if(istype(src, /obj/item/weapon/handcuffs/cable)) + feedback_add_details("handcuffs", "C") + else + feedback_add_details("handcuffs", "H") + + user.visible_message("\The [user] has put \the [src] on \the [C]!") + user.attack_log += text("\[[time_stamp()]\] Has put \the [src] on [C.name] ([C.ckey])") + C.attack_log += text("\[[time_stamp()]\] Handcuffed with \the [src] by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has cuffed [C.name] ([C.ckey]) with \the [src]") + + var/obj/item/weapon/handcuffs/cuffs = src + if(istype(src, /obj/item/weapon/handcuffs/cyborg)) //There's GOT to be a better way to check for this. + cuffs = new(get_turf(user)) + else + user.drop_from_inventory(cuffs) + C.equip_to_slot(cuffs, slot_handcuffed) + +/obj/item/weapon/handcuffs/cyborg +//This space intentionally left blank - return TRUE //Syndicate Cuffs. Disguised as regular cuffs, they are pretty explosive /obj/item/weapon/handcuffs/syndicate @@ -122,13 +107,14 @@ if(slot == slot_handcuffed && mode == SYNDICUFFS_ON_APPLY && !charge_detonated) detonate(1) -/obj/item/weapon/handcuffs/syndicate/handcuffs_remove(mob/living/carbon/C) +/obj/item/weapon/handcuffs/proc/on_remove(var/mob/living/carbon/C) //Needed for syndicuffs + return + +/obj/item/weapon/handcuffs/syndicate/on_remove(mob/living/carbon/C) if(mode == SYNDICUFFS_ON_REMOVE && !charge_detonated) detonate(0) //This handles cleaning up the inventory already return //Don't clean up twice, we don't want runtimes - ..() - //C4 and EMPs don't mix, will always explode at severity 1, and likely to explode at severity 2 /obj/item/weapon/handcuffs/syndicate/emp_act(severity) @@ -171,16 +157,6 @@ explosion(get_turf(src), 0, 1, 3, 0) qdel(src) -/obj/item/weapon/handcuffs/Destroy() - - if(iscarbon(loc)) //Inventory shit - var/mob/living/carbon/C = loc - if(C.handcuffed) - C.handcuffed.loc = C.loc //Standby while we delete this shit - C.drop_from_inventory(src) - - ..() - /obj/item/weapon/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm index fa70edd2f13..00c0e376f05 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implantfreedom.dm @@ -21,26 +21,9 @@ src.uses-- to_chat(source, "You feel a faint click.") if (source.handcuffed) - var/obj/item/weapon/W = source.handcuffed - source.handcuffed.handcuffs_remove(source) - if (source.client) - source.client.screen -= W - if (W) - W.loc = source.loc - dropped(source) - if (W) - W.layer = initial(W.layer) + source.drop_from_inventory(source.handcuffed) if (source.legcuffed) - var/obj/item/weapon/W = source.legcuffed - source.legcuffed = null - source.update_inv_legcuffed() - if (source.client) - source.client.screen -= W - if (W) - W.loc = source.loc - dropped(source) - if (W) - W.layer = initial(W.layer) + source.drop_from_inventory(source.legcuffed) return @@ -66,5 +49,3 @@ mechanisms
life can drive down to only 1 use.
No Implant Specifics"} return dat - - diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 2cee7256f00..cdd42b1af06 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -73,7 +73,7 @@ //Forbid wearing bags with something inside! .=..() if(contents.len && (slot == slot_head)) - return 0 + return CANNOT_EQUIP /obj/item/weapon/storage/bag/plasticbag/can_be_inserted() if(ishuman(loc)) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 770f34b84b1..d53b681d285 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -11,9 +11,9 @@ var/cold_speed_protection = 300 //that cloth allows its wearer to keep walking at normal speed at lower temperatures //BS12: Species-restricted clothing check. -/obj/item/clothing/mob_can_equip(mob/M, slot) +/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = 0, automatic = 0) - . = ..(M, slot, 1) //Default return value. If 1, item can be equipped. If 0, it can't be. + . = ..() //Default return value. If 1, item can be equipped. If 0, it can't be. if(!.) return //Default return value is 0 - don't check for species if(species_restricted && istype(M,/mob/living/carbon/human) && (slot != slot_l_store && slot != slot_r_store)) @@ -55,20 +55,36 @@ wearable = 1 else to_chat(M, "Your misshapen [OE.display_name] prevents you from wearing \the [src].") - return 0 + return CANNOT_EQUIP else if(species_restricted.Find(OE.species.name)) wearable = 1 else to_chat(M, "Your misshapen [OE.display_name] prevents you from wearing \the [src].") - return 0 + return CANNOT_EQUIP if(!wearable) //But we are a species that CAN'T wear it (sidenote: slots 15 and 16 are pockets) to_chat(M, "Your species cannot wear [src].")//Let us know - return 0 + return CANNOT_EQUIP //return ..() +/obj/item/clothing/before_stripped(mob/wearer as mob, mob/stripper as mob, slot) + ..() + if(slot == slot_w_uniform) //this will cause us to drop our belt, ID, and pockets! + for(var/slotID in list(slot_wear_id, slot_belt, slot_l_store, slot_r_store)) + var/obj/item/I = wearer.get_item_by_slot(slotID) + if(I) + I.on_found(stripper) + +/obj/item/clothing/stripped(mob/wearer as mob, mob/stripper as mob, slot) + ..() + if(slot == slot_w_uniform) //this will cause us to drop our belt, ID, and pockets! + for(var/slotID in list(slot_wear_id, slot_belt, slot_l_store, slot_r_store)) + var/obj/item/I = wearer.get_item_by_slot(slotID) + if(I) + I.stripped(stripper) + //Ears: headsets, earmuffs and tiny objects /obj/item/clothing/ears name = "ears" @@ -436,33 +452,43 @@ BLIND // can't see anything for(var/obj/item/clothing/accessory/A in accessories) to_chat(user, "\A [A] is clipped to it.") -/obj/item/clothing/under/proc/set_sensors(mob/usr as mob) - var/mob/M = usr - if (istype(M, /mob/dead/)) return - if (usr.incapacitated()) return +/obj/item/clothing/under/proc/set_sensors(mob/user as mob) + if(user.incapacitated()) return if(has_sensor >= 2) - to_chat(usr, "The controls are locked.") + to_chat(user, "The controls are locked.") return 0 if(has_sensor <= 0) - to_chat(usr, "This suit does not have any sensors.") + to_chat(user, "This suit does not have any sensors.") return 0 var/list/modes = list("Off", "Binary sensors", "Vitals tracker", "Tracking beacon") var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes - if(get_dist(usr, src) > 1) - to_chat(usr, "You have moved too far away.") + if(get_dist(user, src) > 1) + to_chat(user, "You have moved too far away.") return sensor_mode = modes.Find(switchMode) - 1 - switch(sensor_mode) - if(0) - to_chat(usr, "You disable your suit's remote sensing equipment.") - if(1) - to_chat(usr, "Your suit will now report whether you are live or dead.") - if(2) - to_chat(usr, "Your suit will now report your vital lifesigns.") - if(3) - to_chat(usr, "Your suit will now report your vital lifesigns as well as your coordinate position.") + if(is_holder_of(user, src)) + switch(sensor_mode) //i'm sure there's a more compact way to write this but c'mon + if(0) + to_chat(user, "You disable your suit's remote sensing equipment.") + if(1) + to_chat(user, "Your suit will now report whether you are live or dead.") + if(2) + to_chat(user, "Your suit will now report your vital lifesigns.") + if(3) + to_chat(user, "Your suit will now report your vital lifesigns as well as your coordinate position.") + else + switch(sensor_mode) + if(0) + to_chat(user, "You disable the suit's remote sensing equipment.") + if(1) + to_chat(user, "The suit sensors will now report whether the wearer is live or dead.") + if(2) + to_chat(user, "The suit sensors will now report the wearer's vital lifesigns.") + if(3) + to_chat(user, "The suit sensors will now report the wearer's vital lifesigns as well as their coordinate position.") + return switchMode /obj/item/clothing/under/verb/toggle() set name = "Toggle Suit Sensors" diff --git a/code/modules/clothing/masks/stone.dm b/code/modules/clothing/masks/stone.dm index 30b42553a1b..d589390d676 100644 --- a/code/modules/clothing/masks/stone.dm +++ b/code/modules/clothing/masks/stone.dm @@ -15,11 +15,11 @@ /obj/item/clothing/mask/stone/mob_can_equip(mob/M, slot, disable_warning = 0, automatic = 0) if(spikes_out) to_chat(M, "You can't get the mask over your face with its stone spikes in the way!") - return 0 + return CANNOT_EQUIP else if(!istype(M, /mob/living/carbon/human)) to_chat(M, "You can't seem to get the mask to fit correctly over your face.") - return 0 + return CANNOT_EQUIP else return ..() @@ -68,4 +68,4 @@ qdel(src) /obj/item/clothing/mask/stone/infinite //this mask can be used any number of times - infinite = 1 \ No newline at end of file + infinite = 1 diff --git a/code/modules/clothing/monkeyclothes/monkeyclothes.dm b/code/modules/clothing/monkeyclothes/monkeyclothes.dm index 2badcdee35a..b79d5fb360c 100644 --- a/code/modules/clothing/monkeyclothes/monkeyclothes.dm +++ b/code/modules/clothing/monkeyclothes/monkeyclothes.dm @@ -10,15 +10,22 @@ throw_range = 5 w_class = W_CLASS_MEDIUM flags = FPRINT + slot_flags = SLOT_ICLOTHING body_parts_covered = FULL_BODY +/obj/item/clothing/monkeyclothes/mob_can_equip(mob/M, slot, disable_warning = 0, automatic = 0) + . = ..() //Default return value. If 1, item can be equipped. If 0, it can't be. + if(!.) return //Well if it already can't be equipped, we've got nothing else to do here folks, time to call it quits + + if(!ismonkey(M)) + if(!disable_warning) + to_chat(M, "These clothes won't fit.") + return CANNOT_EQUIP + /obj/item/clothing/monkeyclothes/attack(mob/living/carbon/C as mob, mob/user as mob) //I thought I'd give people a fast way to put clothes on monkey. if(ismonkey(C)) //They can do it by opening the monkey's "show inventory" like you'd do for an human as well. var/mob/living/carbon/monkey/M = C - if(M.canWearClothes) - M.wearclothes(src) - return - else + if(!M.equip_to_slot_if_possible(src, slot_w_uniform)) to_chat(user, "Those clothes won't fit.") return ..() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 09409600bf4..ee2cb9436a7 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -1,6 +1,38 @@ +/* + * NOTE FROM SOMEBODY WHO DID SOME HOUSEKEEPING AROUND THIS ASS-CODE + * There's absolutely no documentation on most of this so I'd like to write this down to help you get a grasp of how this works and how redundant it all is. + * Let's assume you live in a horrible horrible universe where nobody coded inventory datums yet. Damn. Now let's say you want your new mob to be able to wear a jumpsuit. + * + * First thing the mob needs is a variable for the inventory slot, like var/obj/item/w_uniform = null. Start by the most awful part and modify /obj/item/proc/mob_can_equip() + * to account for your mob. It has a switch for every slot, and jumpsuits go in under slot_w_uniform, so probably just copypaste how monkeys do it. + * + * Good, now the item thinks the mob can equip it. Now the mob has to be ACTUALLY be able to equip it. Go and modify or create mob/your_mob/equip_to_slot(). Again, it's a switch of + * all slots. You'll see that that proc also handles the icon refreshing, so you have to create mob/your_mob/update_inv_w_uniform() as well. Good luck there because iconcode is also ass. + * + * You can't do anything with the jumpsuit yet though, you need to add it to mob/your_mob/get_item_by_slot() for most things to work. + * Small detail: Your mob cannot unequip their jumpsuit yet. You need to add it to mob/your_mob/u_equip() + * Oh yeah, you need to add the new variable for the jumpsuit to mob/your_mob/get_all_slots(). I know, I know, this is why we need inventory datums. + * + * Okay, so your mob still has no HUD element for their inventory slot. That takes a /obj/screen/inventory... beats me how most of it works, but you do need to have it point to + * slot_id = slot_w_uniform and define a new screen_loc for it. I would advise you to just look at code/_onclick/hud/monkey.dm and do the ol' monkey see, monkey do. + * When you click on that obj/screen/inventory, it calls attack_ui() which by default will just call equip_to_slot_if_possible(item, slot_id) + * At this point I think you need to handle some UI shitcode in mob/your_mob/update_inv_w_uniform(), something like w_uniform.screen_loc = the_screen_loc_you_defined_earlier + * + * For other players to be able to strip and forcibly put on the uniform on your mob, you need to give it a fancy mob/your_mob/show_inv(), and put HREF links that you'll pick up + * in mob/your_mob/Topic() that finally point to handle_strip_slot(). If you search for (href_list["item"]) I'm sure you'll be able to figure this out. + * + * Good luck. + * + * So, a list of all methods used: + * /obj/item/proc/mob_can_equip() -> mob/equip_to_slot() -> update_inv_[slot]() + * get_item_by_slot(), u_equip(), get_all_slots() + * obj/screen/inventory -> ??? -> attack_ui()? -> equip_to_slot_if_possible() -> ??????? -> update_inv_[slot]()? + * show_inv() -> Topic() -> handle_strip_slot() + */ + #define is_valid_hand_index(index) ((index > 0) && (index <= held_items.len)) -//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc +//These procs handle putting stuff in your hand. It's probably best to use these rather than setting l_hand = ...etc //as they handle all relevant stuff like adding it to the player's screen and updating their overlays. //Returns the thing in our active hand @@ -126,15 +158,12 @@ if(!is_valid_hand_index(index) || !is_valid_hand_index(active_hand)) return 0 - if(held_items[index]) - return 0 - if(!put_in_hand_check(W, index)) return 0 if(W.prepickup(src)) return 0 - + W.forceMove(src) held_items[index] = W W.layer = 20 @@ -157,13 +186,16 @@ /mob/proc/put_in_r_hand(var/obj/item/W) return put_in_hand(GRASP_RIGHT_HAND, W) -/mob/proc/put_in_hand_check(var/obj/item/W) +/mob/proc/put_in_hand_check(var/obj/item/W, index) if(lying) //&& !(W.flags & ABSTRACT)) return 0 if(!isitem(W)) return 0 + if(held_items[index]) + return 0 + if(W.flags & MUSTTWOHAND) if(!W.wield(src, 1)) to_chat(src, "You need both hands to pick up \the [W].") @@ -215,7 +247,7 @@ return 0 -/mob/proc/drop_from_inventory(var/obj/item/W) +/mob/proc/drop_from_inventory(var/obj/item/W) //I'm fairly sure the entirety of this proc is redundant and can be replaced by just u_equip(W,1) if(W) if(client) client.screen -= W u_equip(W,1) @@ -308,7 +340,7 @@ if(client) client.screen -= W if(dropped) - W.loc = loc + W.forceMove(loc) W.dropped(src) if(W) W.layer = initial(W.layer) @@ -340,6 +372,18 @@ equipped -= list(get_active_hand(), get_inactive_hand()) return equipped +//inventory slots which would be hidden by other clothing items. currently only used for humans because fuck you +/mob/proc/check_obscured_slots() + return null + +//currently only used for humans because fuck you +/mob/proc/has_organ(name) + return TRUE + +//currently only used for humans because fuck you +/mob/proc/has_organ_for_slot(slot) + return TRUE + /mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, act_on_fail = EQUIP_FAILACTION_DELETE) // since byond doesn't seem to have pointers, this seems like the best way to do this :/ //warning: icky code var/equipped = 0 @@ -429,3 +473,47 @@ . = I.GetID() if(.) break + +/mob/proc/slotID2slotname(slot_id) + switch (slot_id) + if (slot_back) + return "back" + if (slot_wear_mask) + return "face" + if (slot_handcuffed) + return "hands" + if (slot_belt) + return "belt" + if (slot_wear_id) + return "jumpsuit" + if (slot_ears) + return "ears" + if (slot_glasses) + return "face" + if (slot_gloves) + return "hands" + if (slot_head) + return "head" + if (slot_shoes) + return "feet" + if (slot_wear_suit) + return "suit" + if (slot_w_uniform) + return "uniform" + if (slot_l_store) + return "left pocket" + if (slot_r_store) + return "right pocket" + if (slot_s_store) + return "suit storage" + if (slot_in_backpack) + return "backpack" + if (slot_legcuffed) + return "ankles" + else + return "" + +//Returns 1 if the item is part of the mob's built-in modules, and thus shouldn't be dropped or recycled or whatever. +//Currently only used for silicons, but I guess you could use this for robot arms with built-in tools or something +/mob/proc/is_in_modules(var/obj/item/W) + return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index f110cf7e0f8..fbf96ccf748 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -206,23 +206,26 @@ switch(M.a_intent) if(I_HELP) - if(health > 0) + if(health >= config.health_threshold_crit) help_shake_act(M) + return 1 else - if(M.health >= -75.0) - if(((M.head && M.head.flags & 4) || ((M.wear_mask && !( M.wear_mask.flags & 32 )) || ((head && head.flags & 4) || (wear_mask && !( wear_mask.flags & 32)))))) - to_chat(M, "Remove that mask!") - return - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human() - O.source = M - O.target = src - O.s_loc = M.loc - O.t_loc = loc - O.place = "CPR" - requests += O - spawn(0) - O.process() - return + if(M.check_body_part_coverage(MOUTH)) + to_chat(M, "Remove your [M.get_body_part_coverage(MOUTH)]!") + return 0 + + if (!cpr_time) + return 0 + + M.visible_message("\The [M] is trying perform CPR on \the [src]!") + + cpr_time = 0 + if(do_after(M, src, 3 SECONDS)) + adjustOxyLoss(-min(getOxyLoss(), 7)) + M.visible_message("\The [M] performs CPR on \the [src]!") + to_chat(src, "You feel a breath of fresh air enter your lungs. It feels good.") + to_chat(M, "Repeat at least every 7 seconds.") + cpr_time = 1 if(I_GRAB) if(M == src) @@ -325,21 +328,33 @@ In all, this is a lot like the monkey code. /N /mob/living/carbon/alien/humanoid/var/temperature_resistance = T0C+75 /mob/living/carbon/alien/humanoid/show_inv(mob/user as mob) - user.set_machine(src) + var/pickpocket = user.isGoodPickpocket() var/dat = {"
[name]


"} for(var/i = 1 to held_items.len) //Hands var/obj/item/I = held_items[i] - dat += "[capitalize(get_index_limb_name(i))] [(I && !I.abstract) ? I : "Empty"]
" + dat += "[capitalize(get_index_limb_name(i))] [makeStrippingButton(I)]
" + + dat += "
Head: [makeStrippingButton(head)]" + dat += "
Exosuit: [makeStrippingButton(wear_suit)]" + if(pickpocket) + dat += "
Left pouch: [(l_store && !(src.l_store.abstract)) ? l_store : "Left (Empty)"]" + dat += " [(r_store && !(src.r_store.abstract)) ? r_store : "Right (Empty)"]" + else + dat += "
Right pouch: [(l_store && !(src.l_store.abstract)) ? "Left (Full)" : "Left (Empty)"]" + dat += " [(r_store && !(src.r_store.abstract)) ? "Right (Full)" : "Right (Empty)"]" + dat += "
Close
" - dat+={"
Head: [(head ? text("[]", head) : "Nothing")] -
(Exo)Suit: [(wear_suit ? text("[]", wear_suit) : "Nothing")] -
Empty Pouches -
Close -
"} user << browse(dat, text("window=mob\ref[src];size=340x480")) onclose(user, "mob\ref[src]") return + +/mob/living/carbon/alien/humanoid/Topic(href, href_list) + . = ..() + if(href_list["pockets"]) //href_list "pockets" would be "left" or "right" + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) + return + handle_strip_pocket(usr, href_list["pockets"]) diff --git a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm index 0c5a42a2a98..299d0e6eef6 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm @@ -1,3 +1,45 @@ +/mob/living/carbon/alien/humanoid/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1) + if(!slot) return + if(!istype(W)) return + + if(src.is_holding_item(W)) + src.u_equip(W) + + switch(slot) + if(slot_head) + src.head = W + update_inv_head(redraw_mob) + if(slot_wear_suit) + src.wear_suit = W + update_inv_wear_suit(redraw_mob) + if(slot_l_store) + src.l_store = W + update_inv_pockets(redraw_mob) + if(slot_r_store) + src.r_store = W + update_inv_pockets(redraw_mob) + else + to_chat(usr, "You are trying to equip this item to an unsupported inventory slot. How the heck did you manage that? Stop it...") + return + + W.layer = 20 + W.equipped(src, slot) + W.forceMove(src) + if(client) client.screen |= W + +// Return the item currently in the slot ID +/mob/living/carbon/alien/humanoid/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_wear_suit) + return wear_suit + if(slot_head) + return head + if(slot_l_store) + return l_store + if(slot_r_store) + return r_store + return null + //unequip /mob/living/carbon/alien/humanoid/u_equip(obj/item/W as obj, dropped = 1) if(!W) return 0 @@ -29,8 +71,9 @@ if(success) if (client) client.screen -= W + W.forceMove(loc) + W.unequipped() if(dropped) - W.loc = loc W.dropped(src) if(W) W.layer = initial(W.layer) @@ -68,4 +111,4 @@ if(slot_l_store) if(l_store) l_store.attack_alien(src) if(slot_r_store) - if(r_store) r_store.attack_alien(src) \ No newline at end of file + if(r_store) r_store.attack_alien(src) diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index c975b91a8a0..55bb561a8bf 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -58,21 +58,19 @@ // else client.screen -= hud_used.other //Not used client.screen |= contents - - +//These update icons are essentially derelict and unused /mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1) if(wear_suit) var/t_state = wear_suit.item_state if(!t_state) t_state = wear_suit.icon_state - var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2") - var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]") + //var/image/lying = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi'), "icon_state" = "[t_state]") + var/image/standing = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi'), "icon_state" = "[t_state]") if(wear_suit.blood_DNA && wear_suit.blood_DNA.len) - var/t_suit = "suit" - if( istype(wear_suit, /obj/item/clothing/suit/armor) ) - t_suit = "armor" - lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood2") - standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood") + //lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood") + var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[wear_suit.blood_overlay_type]blood") + bloodsies.color = wear_suit.blood_color + standing.overlays += bloodsies //TODO wear_suit.screen_loc = ui_alien_oclothing @@ -80,10 +78,10 @@ drop_from_inventory(handcuffed) drop_hands() - overlays_lying[X_SUIT_LAYER] = lying + //overlays_lying[X_SUIT_LAYER] = lying overlays_standing[X_SUIT_LAYER] = standing else - overlays_lying[X_SUIT_LAYER] = null + //overlays_lying[X_SUIT_LAYER] = null overlays_standing[X_SUIT_LAYER] = null if(update_icons) update_icons() @@ -92,10 +90,10 @@ if (head) var/t_state = head.item_state if(!t_state) t_state = head.icon_state - var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2") - var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]") + var/image/lying = image(((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi'), "icon_state" = "[t_state]") + var/image/standing = image(((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi'), "icon_state" = "[t_state]") if(head.blood_DNA && head.blood_DNA.len) - lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood2") + lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood") standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood") head.screen_loc = ui_alien_head overlays_lying[X_HEAD_LAYER] = lying diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index b0d8d52403f..0946734a877 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -187,23 +187,7 @@ switch(M.a_intent) if(I_HELP) - if(health > 0) - help_shake_act(M) - else - if(M.health >= -75.0) - if ((M.head && M.head.flags & 4) || (M.wear_mask && !( M.wear_mask.flags & 32 )) ) - to_chat(M, "Remove that mask!") - return - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human() - O.source = M - O.target = src - O.s_loc = M.loc - O.t_loc = loc - O.place = "CPR" - requests += O - spawn(0) - O.process() - return + help_shake_act(M) if(I_GRAB) if(M == src) @@ -309,4 +293,4 @@ /mob/living/carbon/alien/larva/reset_layer() if(stat == DEAD) - layer = MOB_LAYER //unhide \ No newline at end of file + layer = MOB_LAYER //unhide diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 86ddd23cc73..e121ed05966 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -396,56 +396,8 @@ return 1 return -/mob/living/carbon/u_equip(obj/item/W as obj, dropped = 1) - var/success = 0 - if(!W) return 0 - else if (W == handcuffed) - handcuffed.handcuffs_remove(src) - success = 1 - - else if (W == legcuffed) - legcuffed = null - success = 1 - update_inv_legcuffed() - else - ..() - if(success) - if (W) - if (client) - client.screen -= W - if(dropped) - W.loc = loc - W.dropped(src) - if(W) - W.layer = initial(W.layer) - - return -/* /mob/living/carbon/show_inv(mob/living/carbon/user as mob) user.set_machine(src) - var/dat = {" -
[name]
-

-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))] -
[(internal ? text("Remove Internal") : "")] -
Empty Pockets -
Refresh -
Close -
"} - user << browse(dat, text("window=mob\ref[src];size=325x500")) - onclose(user, "mob\ref[src]") - return -*/ - - -/mob/living/carbon/show_inv(mob/living/carbon/user as mob) - user.set_machine(src) - var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) - var/TAB = "    " var/dat = "" if(handcuffed) @@ -453,16 +405,15 @@ else for(var/i = 1 to held_items.len) //Hands var/obj/item/I = held_items[i] - dat += "[capitalize(get_index_limb_name(i))] [(I && !I.abstract) ? I : "Empty"]
" + dat += "[capitalize(get_index_limb_name(i))] [makeStrippingButton(I)]
" - dat += "
Back: [(back && !(src.back.abstract)) ? back : "Empty"]" - if(has_breathable_mask && istype(back, /obj/item/weapon/tank)) - dat += "
[TAB]↳[internal ? "Disable Internals" : "Set Internals"]" + dat += "
Back: [makeStrippingButton(back)]" dat += "
" - - dat += "
Mask: [(wear_mask && !(src.wear_mask.abstract)) ? wear_mask : "Empty"]" + dat += "
Mask: [makeStrippingButton(wear_mask)]" + if(has_breathing_mask()) + dat += "
[HTMLTAB]↳Internals: [src.internal ? "On" : "Off"] (Toggle)" dat += {"
@@ -473,9 +424,27 @@ popup.set_content(dat) popup.open() +/mob/living/carbon/Topic(href, href_list) + ..() + if (href_list["mach_close"]) + var/t1 = text("window=[]", href_list["mach_close"]) + unset_machine() + src << browse(null, t1) + if(href_list["hands"]) + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) + return + handle_strip_hand(usr, text2num(href_list["hands"])) //href_list "hands" is the hand index, not the item itself. example, GRASP_LEFT_HAND + else if(href_list["item"]) + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) + return + handle_strip_slot(usr, text2num(href_list["item"])) //href_list "item" would actually be the item slot, not the item itself. example: slot_head + else if(href_list["internals"]) + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) + return + set_internals(usr) //generates realistic-ish pulse output based on preset levels /mob/living/carbon/proc/get_pulse(var/method) //method 0 is for hands, 1 is for machines, more accurate diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index bc7f39dffd0..2bcdbe41a68 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -341,118 +341,8 @@ /mob/living/carbon/human/var/co2overloadtime = null -/mob/living/carbon/human/var/temperature_resistance = T0C+75 +/mob/living/carbon/human/var/temperature_resistance = T0C+75 //but why is this here -/* -/mob/living/carbon/human/show_inv(mob/user as mob) - var/obj/item/clothing/gloves/G - var/pickpocket = 0 - var/list/obscured = check_obscured_slots() - if(ishuman(user) && user:gloves) - G = user:gloves - pickpocket = G.pickpocket - user.set_machine(src) - var/dat = {" -
[name]
-

-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] -
Gloves: [(gloves ? gloves : "Nothing")] -
Eyes: [(glasses ? glasses : "Nothing")] -
Ears: [(ears ? ears : "Nothing")] -
Head: [(head ? head : "Nothing")] -
Shoes: [(shoes ? shoes : "Nothing")] -
Belt: [(belt ? belt : "Nothing")] -
Uniform: [(w_uniform ? w_uniform : "Nothing")] -
(Exo)Suit: [(wear_suit ? wear_suit : "Nothing")] -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
ID: [(wear_id ? wear_id : "Nothing")] -
Suit Storage: [(s_store ? s_store : "Nothing")] -
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))] -
[(legcuffed ? text("Legcuffed") : text(""))] -
[(internal ? text("Remove Internal") : "")] -
Remove Splints -

Left Pocket ([l_store ? (pickpocket ? l_store.name : "Full") : "Empty"]) -
Right Pocket ([r_store ? (pickpocket ? r_store.name : "Full") : "Empty"]) -
Refresh -
Close -
"} - user << browse(dat, text("window=mob\ref[src];size=340x480")) - onclose(user, "mob\ref[src]") - return -*/ - - -/mob/living/carbon/human/show_inv(mob/user) - user.set_machine(src) - var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) - var/list/obscured = check_obscured_slots() - var/TAB = "    " - var/dat - - for(var/i = 1 to held_items.len) //Hands - var/obj/item/I = held_items[i] - dat += "[capitalize(get_index_limb_name(i))] [(I && !I.abstract) ? I : "Empty"]
" - - dat += "
Back: [(back && !(src.back.abstract)) ? back : "Empty"]" - if(has_breathable_mask && istype(back, /obj/item/weapon/tank)) - dat += "
[TAB]↳[internal ? "Disable Internals" : "Set Internals"]" - dat += "
" - dat += "
Head: [(head && !(src.head.abstract)) ? head : "Empty"]" - if(slot_wear_mask in obscured) - dat += "
Mask: Obscured by [head]" - else - dat += "
Mask: [(wear_mask && !(src.wear_mask.abstract)) ? wear_mask : "Empty"]" - if(slot_glasses in obscured) - dat += "
Eyes: Obscured by [head]" - else - dat += "
Eyes: [(glasses && !(src.glasses.abstract)) ? glasses : "Empty"]" - if(slot_ears in obscured) - dat += "
Ears: Obscured by [head]" - else - dat += "
Ears: [(ears && !(src.ears.abstract)) ? ears : "Empty"]" - dat += "
" - dat += "
Exosuit: [(wear_suit && !(src.wear_suit.abstract)) ? wear_suit : "Empty"]" - if(wear_suit) - dat += "
[TAB]↳Suit Storage: [(s_store && !(src.s_store.abstract)) ? s_store : "Empty"]" - if(has_breathable_mask && istype(s_store, /obj/item/weapon/tank)) - dat += "
[TAB][TAB]↳[internal ? "Disable Internals" : "Set Internals"]" - if(slot_shoes in obscured) - dat += "
Shoes: Obscured by [wear_suit]" - else - dat += "
Shoes: [(shoes && !(src.shoes.abstract)) ? shoes : "Empty"]" - if(slot_gloves in obscured) - dat += "
Gloves: Obscured by [wear_suit]" - else - dat += "
Gloves: [(gloves && !(src.gloves.abstract)) ? gloves : "Empty"]" - if(slot_w_uniform in obscured) - dat += "
Uniform: Obscured by [wear_suit]" - else - dat += "
Uniform: [(w_uniform && !(src.w_uniform.abstract)) ? w_uniform : "Empty"]" - if(w_uniform) - dat += "
[TAB]↳Belt: [(belt && !(src.belt.abstract)) ? belt : "Empty"]" - if(has_breathable_mask && istype(belt, /obj/item/weapon/tank)) - dat += "
[TAB][TAB]↳[internal ? "Disable Internals" : "Set Internals"]" - if(ishuman(user) && istype(user:gloves, /obj/item/clothing/gloves/black/thief)) - dat += "
[TAB]↳Pockets: [(l_store && !(src.l_store.abstract)) ? l_store : "Left (Empty)"]" - dat += " [(r_store && !(src.r_store.abstract)) ? r_store : "Right (Empty)"]" - else - dat += "
[TAB]↳Pockets: [(l_store && !(src.l_store.abstract)) ? "Left (Full)" : "Left (Empty)"]" - dat += " [(r_store && !(src.r_store.abstract)) ? "Right (Full)" : "Right (Empty)"]" - dat += "
[TAB]↳ID: [(wear_id && !(src.wear_id.abstract)) ? wear_id : "Empty"]" - dat += "
" - if(handcuffed) - dat += "
Handcuffed: Remove" - if(legcuffed) - dat += "
Legcuffed: Remove" - dat += {" -
-
Close - "} - var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 340, 500) - popup.set_content(dat) - popup.open() // called when something steps onto a human // this could be made more general, but for now just handle mulebot /mob/living/carbon/human/Crossed(var/atom/movable/AM) @@ -545,152 +435,97 @@ return ..(shock_damage, source, siemens_coeff, def_zone) -/mob/living/carbon/human/proc/num2slotname(slot_id) - switch (slot_id) - if (slot_back) - return "back" - if (slot_wear_mask) - return "mask" - if (slot_handcuffed) - return "handcuffed" - if (slot_belt) - return "belt" - if (slot_wear_id) - return "id" - if (slot_ears) - return "ears" - if (slot_glasses) - return "eyes" - if (slot_gloves) - return "gloves" - if (slot_head) - return "head" - if (slot_shoes) - return "shoes" - if (slot_wear_suit) - return "suit" - if (slot_w_uniform) - return "uniform" - if (slot_l_store) - return "l_store" - if (slot_r_store) - return "r_store" - if (slot_s_store) - return "s_store" - if (slot_in_backpack) - return "in_backpack" - if (slot_legcuffed) - return "h_store" - else - return "" - /mob/living/carbon/human/hear_radio_only() if(!ears) return 0 return is_on_ears(/obj/item/device/radio/headset/headset_earmuffs) +/mob/living/carbon/human/show_inv(mob/user) + user.set_machine(src) + var/pickpocket = usr.isGoodPickpocket() + var/list/obscured = check_obscured_slots() + var/dat + + for(var/i = 1 to held_items.len) //Hands + var/obj/item/I = held_items[i] + dat += "[capitalize(get_index_limb_name(i))] [makeStrippingButton(I)]
" + + dat += "
Back: [makeStrippingButton(back)]" + dat += "
" + dat += "
Head: [makeStrippingButton(head)]" + if(slot_wear_mask in obscured) + dat += "
Mask: Obscured by [head]" + else + dat += "
Mask: [makeStrippingButton(wear_mask)]" + if(has_breathing_mask()) + dat += "
[HTMLTAB]↳Internals: [src.internal ? "On" : "Off"] (Toggle)" + if(slot_glasses in obscured) + dat += "
Eyes: Obscured by [head]" + else + dat += "
Eyes: [makeStrippingButton(glasses)]" + if(slot_ears in obscured) + dat += "
Ears: Obscured by [head]" + else + dat += "
Ears: [makeStrippingButton(ears)]" + dat += "
" + dat += "
Exosuit: [makeStrippingButton(wear_suit)]" + if(wear_suit) + dat += "
[HTMLTAB]↳Suit Storage: [makeStrippingButton(s_store)]" + if(slot_shoes in obscured) + dat += "
Shoes: Obscured by [wear_suit]" + else + dat += "
Shoes: [makeStrippingButton(shoes)]" + if(slot_gloves in obscured) + dat += "
Gloves: Obscured by [wear_suit]" + else + dat += "
Gloves: [makeStrippingButton(gloves)]" + if(slot_w_uniform in obscured) + dat += "
Uniform: Obscured by [wear_suit]" + else + dat += "
Uniform: [makeStrippingButton(w_uniform)]" + if(w_uniform) + dat += "
[HTMLTAB]↳ Set suit sensors" + dat += "
[HTMLTAB]↳Belt: [makeStrippingButton(belt)]" + if(pickpocket) + dat += "
[HTMLTAB]↳Pockets: [(l_store && !(src.l_store.abstract)) ? l_store : "Left (Empty)"]" + dat += " [(r_store && !(src.r_store.abstract)) ? r_store : "Right (Empty)"]" + else + dat += "
[HTMLTAB]↳Pockets: [(l_store && !(src.l_store.abstract)) ? "Left (Full)" : "Left (Empty)"]" + dat += " [(r_store && !(src.r_store.abstract)) ? "Right (Full)" : "Right (Empty)"]" + dat += "
[HTMLTAB]↳ID: [makeStrippingButton(wear_id)]" + dat += "
" + if(handcuffed) + dat += "
Handcuffed: Remove" + if(legcuffed) + dat += "
Legcuffed: Remove" + dat += {" +
+
Close + "} + var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 340, 500) + popup.set_content(dat) + popup.open() + /mob/living/carbon/human/Topic(href, href_list) - var/pickpocket = 0 - var/able = (!usr.incapacitated() && in_range(src, usr) && Adjacent(usr)) - - if(href_list["item"]) - if (!able) return - var/slot = href_list["item"] - var/obj/item/place_item = usr.get_active_hand() - var/obj/item/id_item = src.wear_id - - var/list/obscured_slots = new/list() - - for (var/obscured_slot_num in check_obscured_slots()) - var/slot_name = num2slotname(obscured_slot_num) - - if (slot_name != "") - obscured_slots += slot_name - - if (slot in obscured_slots) - to_chat(usr, "You can't reach that. Something is covering it.") + ..() //Slot stripping, hand stripping, and internals setting in /mob/living/carbon/Topic() + if(href_list["id"]) + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) return - else - if(isanimal(usr)) return //Animals can't do that - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) - if(ishuman(usr) && usr:gloves) - var/obj/item/clothing/gloves/G = usr:gloves - pickpocket = G.pickpocket - O.source = usr - O.target = src - O.item = usr.get_active_hand() - O.s_loc = usr.loc - O.t_loc = loc - O.place = href_list["item"] - O.pickpocket = pickpocket //Stealthy - requests += O -// to_chat(world, O.place) - if(O.place == "id") - if(id_item) - to_chat(usr, "You try to take [src]'s ID.") - else if(place_item && place_item.mob_can_equip(src, slot_wear_id, 1)) - to_chat(usr, "You try to place [place_item] on [src].") + handle_strip_id(usr) - if(do_mob(usr, src, HUMAN_STRIP_DELAY)) - if(id_item) - u_equip(id_item,0) - if(pickpocket) usr.put_in_hands(id_item) - else - if(place_item) - usr.u_equip(place_item,1) - equip_to_slot_if_possible(place_item, slot_wear_id, 0, 1) - // Update strip window - if(in_range(src, usr)) - show_inv(usr) - - else if(!pickpocket) - // Display a warning if the user mocks up - to_chat(src, "You feel your ID being fumbled with!") - else - spawn( 0 ) - O.process() - spawn(HUMAN_STRIP_DELAY) if(in_range(src, usr)) show_inv(usr) - return - else if(href_list["pockets"]) - if (!able) return - var/pocket_side = href_list["pockets"] - var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store) - var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store) - var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty - if(isanimal(usr)) return //Animals can't do that - if(ishuman(usr) && (usr:gloves)) - var/obj/item/clothing/gloves/G = usr:gloves - pickpocket = G.pickpocket - - if(pocket_item) - to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") - else if(place_item && place_item.mob_can_equip(src, pocket_id, 1)) - to_chat(usr, "You try to place [place_item] into [src]'s [pocket_side] pocket.") - else + else if(href_list["pockets"]) //href_list "pockets" would be "left" or "right" + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) return + handle_strip_pocket(usr, href_list["pockets"]) - if(do_mob(usr, src, HUMAN_STRIP_DELAY)) - if(pocket_item) - u_equip(pocket_item,1) - pocket_item.stripped(src,usr) - if(pickpocket) usr.put_in_hands(pocket_item) - else - if(place_item) - usr.u_equip(place_item,1) - equip_to_slot_if_possible(place_item, pocket_id, 0, 1) - // Update strip window - if(in_range(src, usr)) - show_inv(usr) + else if(href_list["sensors"]) + if(usr.incapacitated() || !Adjacent(usr)|| isanimal(usr)) + return + toggle_sensors(usr) - else if(!pickpocket) - // Display a warning if the user mocks up - to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") else if (href_list["refresh"]) if((machine)&&(in_range(src, usr))) show_inv(machine) - else if (href_list["mach_close"]) - var/t1 = text("window=[]", href_list["mach_close"]) - unset_machine() - src << browse(null, t1) + else if (href_list["criminal"]) if(hasHUD(usr,"security")) var/perpname = "wot" @@ -935,9 +770,7 @@ else if (href_list["lookmob"]) var/mob/M = locate(href_list["lookmob"]) usr.examination(M) - else - ..() - return + /** * Returns a number between -1 to 2. * TODO: What's the default return value? @@ -963,6 +796,10 @@ /mob/living/carbon/human/IsAdvancedToolUser() return 1//Humans can use guns and such +/mob/living/carbon/human/isGoodPickpocket() + var/obj/item/clothing/gloves/G = gloves + if(istype(G)) + return G.pickpocket /mob/living/carbon/human/abiotic(var/full_body = 0) for(var/obj/item/I in held_items) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 377f711c917..7e52f692e0f 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -233,19 +233,22 @@ to_chat(M, "Remove your [M.get_body_part_coverage(MOUTH)]!") return 0 if(src.check_body_part_coverage(MOUTH)) - to_chat(M, "Remove his [src.get_body_part_coverage(MOUTH)]!") + to_chat(M, "Remove their [src.get_body_part_coverage(MOUTH)]!") return 0 - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human() - O.source = M - O.target = src - O.s_loc = M.loc - O.t_loc = loc - O.place = "CPR" - requests += O - spawn(0) - O.process() - return 1 + if (!cpr_time) + return 0 + + M.visible_message("\The [M] is trying perform CPR on \the [src]!") + + cpr_time = 0 + if(do_after(M, src, 3 SECONDS)) + adjustOxyLoss(-min(getOxyLoss(), 7)) + M.visible_message("\The [M] performs CPR on \the [src]!") + to_chat(src, "You feel a breath of fresh air enter your lungs. It feels good.") + to_chat(M, "Repeat at least every 7 seconds.") + cpr_time = 1 + if(I_GRAB) if(M == src || anchored) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 0eb1a8b138f..21dc34aa4d7 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -55,7 +55,7 @@ s_store) return filter -/mob/living/carbon/human/proc/check_obscured_slots() +/mob/living/carbon/human/check_obscured_slots() var/list/obscured = list() if(wear_suit) @@ -162,12 +162,12 @@ return s_store return null -/mob/living/carbon/human/proc/has_organ(name) +/mob/living/carbon/human/has_organ(name) var/datum/organ/external/O = organs_by_name[name] return O.is_existing() -/mob/living/carbon/human/proc/has_organ_for_slot(slot) +/mob/living/carbon/human/has_organ_for_slot(slot) switch(slot) if(slot_back) return has_organ("chest") @@ -286,8 +286,11 @@ success = 1 update_inv_back() else if (W == handcuffed) - handcuffed.handcuffs_remove(src) + if(handcuffed.on_remove(src)) //If this returns 1, then the unquipping action was interrupted + return 0 + handcuffed = null success = 1 + update_inv_handcuffed() else if (W == legcuffed) legcuffed = null success = 1 @@ -301,14 +304,65 @@ if (W) if (client) client.screen -= W - W.loc = loc + W.forceMove(loc) W.unequipped() - if(dropped) W.dropped(src) + if(dropped) + W.dropped(src) if(W) W.layer = initial(W.layer) update_action_buttons() return 1 +//This is a SAFE proc. Use this instead of equip_to_slot()! +//set del_on_fail to have it delete W if it fails to equip +//set disable_warning to disable the 'you are unable to equip that' warning. +//unset redraw_mob to prevent the mob from being redrawn at the end. +/mob/living/carbon/human/equip_to_slot_if_possible(obj/item/W as obj, slot, act_on_fail = 0, disable_warning = 0, redraw_mob = 1, automatic = 0) + switch(W.mob_can_equip(src, slot, disable_warning, automatic)) + if(CANNOT_EQUIP) + switch(act_on_fail) + if(EQUIP_FAILACTION_DELETE) + qdel(W) + W = null + if(EQUIP_FAILACTION_DROP) + W.forceMove(get_turf(src)) //Should this be using drop_from_inventory instead? + else + if(!disable_warning) + to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING + + return 0 + if(CAN_EQUIP) + equip_to_slot(W, slot, redraw_mob) + if(CAN_EQUIP_BUT_SLOT_TAKEN) + var/in_the_hand = (is_holding_item(W)) + var/obj/item/wearing = get_item_by_slot(slot) + if(wearing) + if(!in_the_hand) //if we aren't holding it, the proc is abstract so get rid of it + switch(act_on_fail) + if(EQUIP_FAILACTION_DELETE) + qdel(W) + if(EQUIP_FAILACTION_DROP) + W.forceMove(get_turf(src)) //Should this be using drop_from_inventory instead? + return + + if(drop_item(W)) + if(!put_in_active_hand(wearing)) + equip_to_slot(wearing, slot, redraw_mob) + switch(act_on_fail) + if(EQUIP_FAILACTION_DELETE) + qdel(W) + else + if(!disable_warning && act_on_fail != EQUIP_FAILACTION_DROP) + to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING + + return + else + equip_to_slot(W, slot, redraw_mob) + u_equip(wearing,0) + put_in_active_hand(wearing) + if(s_store && !s_store.mob_can_equip(src, slot_s_store, 1)) + u_equip(s_store,1) + return 1 //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() @@ -388,510 +442,9 @@ W.layer = 20 W.equipped(src, slot) - W.loc = src + W.forceMove(src) if(client) client.screen |= W - -/obj/effect/equip_e - name = "equip e" - var/mob/source = null - var/s_loc = null //source location - var/t_loc = null //target location - var/obj/item/item = null - - var/place = null - var/hand_index = 1 - - var/pickpocket = null - -/obj/effect/equip_e/human - name = "human" - var/mob/living/carbon/human/target = null - -/obj/effect/equip_e/human/Destroy() - if(target) - target.requests -= src - ..() - -/obj/effect/equip_e/monkey - name = "monkey" - var/mob/living/carbon/monkey/target = null - -/obj/effect/equip_e/monkey/Destroy() - if(target) - target.requests -= src - ..() - -/obj/effect/equip_e/process() - return - -/obj/effect/equip_e/proc/done() - return - -/obj/effect/equip_e/New() - if (!ticker) - qdel(src) - spawn(100) - qdel(src) - ..() - return - - -/obj/effect/equip_e/human/process() - if (item) - item.add_fingerprint(source) - else - switch(place) - if("mask") - if (!( target.wear_mask )) - qdel(src) - if("hand") - if (!( target.held_items[hand_index] )) - qdel(src) - if("suit") - if (!( target.wear_suit )) - qdel(src) - if("uniform") - if (!( target.w_uniform )) - qdel(src) - if("back") - if (!( target.back )) - qdel(src) - if("syringe") - return - if("pill") - return - if("fuel") - return - if("drink") - return - if("dnainjector") - return - if("handcuff") - if (!( target.handcuffed )) - qdel(src) - if("id") - if ((!( target.wear_id ) || !( target.w_uniform ))) - qdel(src) - if("splints") - var/count = 0 - for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.organs_by_name[organ] - if(o.status & ORGAN_SPLINTED) - count = 1 - break - if(count == 0) - qdel(src) - return - - - - if("internal") - if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal ))) - qdel(src) - - if("internal1") - if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.belt, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal ))) - qdel(src) - - if("internal2") - if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.s_store, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal ))) - qdel(src) - - - var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel") - if ((item && !( L.Find(place) ))) - if(isrobot(source) && place != "handcuff") - qdel(src) - for(var/mob/O in viewers(target, null)) - O.show_message("[source] is trying to put [item.gender == PLURAL ? "\the [item]" : "\a [item]"] on [target]", 1) - else - var/message=null - switch(place) - if("syringe") - message = "[source] is trying to inject [target]!" - if("pill") - message = "[source] is trying to force [target] to swallow [item]!" - if("drink") - message = "[source] is trying to force [target] to swallow a gulp of [item]!" - if("dnainjector") - message = "[source] is trying to inject [target] with the [item]!" - if("mask") - target.attack_log += text("\[[time_stamp()]\] Had their mask removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) mask") - if(target.wear_mask && !target.wear_mask.canremove) - message = "[source] fails to take off \a [target.wear_mask] from [target]'s head!" - return - else - message = "[source] is trying to take off \a [target.wear_mask] from [target]'s head!" - if("hand") - target.attack_log += text("\[[time_stamp()]\] Has had their [target.get_index_limb_name(hand_index)] item ([target.held_items[hand_index]]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) [target.get_index_limb_name(hand_index)] item ([target.held_items[hand_index]])") - message = "[source] is trying to take off \a [target.held_items[hand_index]] from [target]'s [target.get_index_limb_name(hand_index)]!" - if("gloves") - target.attack_log += text("\[[time_stamp()]\] Has had their gloves ([target.gloves]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) gloves ([target.gloves])") - if(target.gloves && !target.gloves.canremove) - message = "[source] fails to take off \a [target.gloves] from [target]'s hands!" - return - else - message = "[source] is trying to take off the [target.gloves] from [target]'s hands!" - if("eyes") - target.attack_log += text("\[[time_stamp()]\] Has had their eyewear ([target.glasses]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) eyewear ([target.glasses])") - if(target.glasses && !target.glasses.canremove) - message = "[source] fails to take off \a [target.glasses] from [target]'s eyes!" - return - else - message = "[source] is trying to take off the [target.glasses] from [target]'s eyes!" - if("ears") - target.attack_log += text("\[[time_stamp()]\] Has had their ear item ([target.ears]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) ear item ([target.ears])") - if(target.ears && !target.ears.canremove) - message = "[source] fails to take off \a [target.ears] from [target]'s ears!" - return - else - message = "[source] is trying to take off the [target.ears] from [target]'s ears!" - if("head") - target.attack_log += text("\[[time_stamp()]\] Has had their hat ([target.head]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) hat ([target.head])") - if(target.head && !target.head.canremove) - message = "[source] fails to take off \a [target.head] from [target]'s head!" - return - else - message = "[source] is trying to take off the [target.head] from [target]'s head!" - if("shoes") - target.attack_log += text("\[[time_stamp()]\] Has had their shoes ([target.shoes]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) shoes ([target.shoes])") - if(target.shoes && !target.shoes.canremove) - message = "[source] fails to take off \a [target.shoes] from [target]'s feet!" - return - else - message = "[source] is trying to take off the [target.shoes] from [target]'s feet!" - if("belt") - target.attack_log += text("\[[time_stamp()]\] Has had their belt item ([target.belt]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) belt item ([target.belt])") - if(!pickpocket) - message = "[source] is trying to take off the [target.belt] from [target]'s belt!" - else - to_chat(source, "You try to take off the [target.belt] from [target]'s belt!") - if("suit") - target.attack_log += text("\[[time_stamp()]\] Has had their suit ([target.wear_suit]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) suit ([target.wear_suit])") - if(target.wear_suit && !target.wear_suit.canremove) - message = "[source] fails to take off \a [target.wear_suit] from [target]'s body!" - return - else - message = "[source] is trying to take off \a [target.wear_suit] from [target]'s body!" - if("back") - target.attack_log += text("\[[time_stamp()]\] Has had their back item ([target.back]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) back item ([target.back])") - message = "[source] is trying to take off \a [target.back] from [target]'s back!" - if("handcuff") - target.attack_log += text("\[[time_stamp()]\] Was unhandcuffed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to unhandcuff [target.name]'s ([target.ckey])") - message = "[source] is trying to unhandcuff [target]!" - if("legcuff") - target.attack_log += text("\[[time_stamp()]\] Was unlegcuffed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to unlegcuff [target.name]'s ([target.ckey])") - message = "[source] is trying to unlegcuff [target]!" - if("uniform") - target.attack_log += text("\[[time_stamp()]\] Has had their uniform ([target.w_uniform]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) uniform ([target.w_uniform])") - for(var/obj/item/I in list(target.l_store, target.r_store)) - if(I.on_found(source)) - return - if(target.w_uniform && !target.w_uniform.canremove) - message = "[source] fails to take off \a [target.w_uniform] from [target]'s body!" - return - else - message = "[source] is trying to take off \a [target.w_uniform] from [target]'s body!" - if("s_store") - target.attack_log += text("\[[time_stamp()]\] Has had their suit storage item ([target.s_store]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) suit storage item ([target.s_store])") - message = "[source] is trying to take off \a [target.s_store] from [target]'s suit!" - if("pockets") - target.attack_log += text("\[[time_stamp()]\] Has had their pockets emptied by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to empty [target.name]'s ([target.ckey]) pockets") - for(var/obj/item/I in list(target.l_store, target.r_store)) - if(I.on_found(source)) - return - message = "[source] is trying to empty [target]'s pockets." - if("CPR") - if (!target.cpr_time) - qdel(src) - target.cpr_time = 0 - message = "[source] is trying perform CPR on [target]!" - if("id") - target.attack_log += text("\[[time_stamp()]\] Has had their ID ([target.wear_id]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) ID ([target.wear_id])") - if(!pickpocket) - message = "[source] is trying to take off [target.wear_id] from [target]'s uniform!" - else - to_chat(source, "You try to take off [target.wear_id] from [target]'s uniform!") - if("internal") - target.attack_log += text("\[[time_stamp()]\] Has had their internals toggled by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to toggle [target.name]'s ([target.ckey]) internals") - if (target.internal) - message = "[source] is trying to remove [target]'s internals" - else - message = "[source] is trying to set on [target]'s internals." - - if("internal1") - target.attack_log += text("\[[time_stamp()]\] Has had their internals toggled by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to toggle [target.name]'s ([target.ckey]) internals") - if (target.internal) - message = "[source] is trying to remove [target]'s internals" - else - message = "[source] is trying to set on [target]'s internals." - - if("internal2") - target.attack_log += text("\[[time_stamp()]\] Has had their internals toggled by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to toggle [target.name]'s ([target.ckey]) internals") - if (target.internal) - message = "[source] is trying to remove [target]'s internals" - else - message = "[source] is trying to set on [target]'s internals." - if("splints") - message = text("[] is trying to remove []'s splints!", source, target) - - for(var/mob/M in viewers(target, null)) - M.show_message(message, 1) - if(do_after(source, target, HUMAN_STRIP_DELAY)) - done() - return - return - -/* -This proc equips stuff (or does something else) when removing stuff manually from the character window when you click and drag. -It works in conjuction with the process() above. -This proc works for humans only. Aliens stripping humans and the like will all use this proc. Stripping monkeys or somesuch will use their version of this proc. -The first if statement for "mask" and such refers to items that are already equipped and un-equipping them. -The else statement is for equipping stuff to empty slots. -!canremove refers to variable of /obj/item/clothing which either allows or disallows that item to be removed. -It can still be worn/put on as normal. -*/ -/obj/effect/equip_e/human/done() //TODO: And rewrite this :< ~Carn - target.cpr_time = 1 - if(isanimal(source)) return //animals cannot strip people - if(!source || !target) return //Target or source no longer exist - if(source.loc != s_loc) return //source has moved - if(target.loc != t_loc) return //target has moved - if(!source.Adjacent(target)) return //Use a proxi! - - if(item) - if(source.get_active_hand() != item) return //Swapped hands / removed item from the active one - if(item.cant_drop > 0) return //Item can't be dropped - - if ((source.restrained() || source.stat)) return //Source restrained or unconscious / dead - - var/slot_to_process - var/strip_item //this will tell us which item we will be stripping - if any. - - switch(place) //here we go again... - if("mask") - slot_to_process = slot_wear_mask - if (target.wear_mask && target.wear_mask.canremove) - strip_item = target.wear_mask - if("gloves") - slot_to_process = slot_gloves - if (target.gloves && target.gloves.canremove) - strip_item = target.gloves - if("eyes") - slot_to_process = slot_glasses - if (target.glasses) - strip_item = target.glasses - if("belt") - slot_to_process = slot_belt - if (target.belt) - strip_item = target.belt - if("s_store") - slot_to_process = slot_s_store - if (target.s_store) - strip_item = target.s_store - if("head") - slot_to_process = slot_head - if (target.head && target.head.canremove) - strip_item = target.head - if("ears") - slot_to_process = slot_ears - if (target.ears) - strip_item = target.ears - if("shoes") - slot_to_process = slot_shoes - if (target.shoes && target.shoes.canremove) - strip_item = target.shoes - if("hand") - if (istype(target, /obj/item/clothing/suit/straight_jacket)) - qdel(src) - return - - slot_to_process = null - if (target.held_items[hand_index]) - strip_item = target.held_items[hand_index] - if("uniform") - slot_to_process = slot_w_uniform - if(target.w_uniform && target.w_uniform.canremove) - strip_item = target.w_uniform - if("suit") - slot_to_process = slot_wear_suit - if (target.wear_suit && target.wear_suit.canremove) - strip_item = target.wear_suit - if("id") - slot_to_process = slot_wear_id - if (target.wear_id) - strip_item = target.wear_id - if("back") - slot_to_process = slot_back - if (target.back) - strip_item = target.back - if("handcuff") - slot_to_process = slot_handcuffed - if (target.handcuffed) - strip_item = target.handcuffed - if("legcuff") - slot_to_process = slot_legcuffed - if (target.legcuffed) - strip_item = target.legcuffed - if("splints") - for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) - var/datum/organ/external/o = target.get_organ(organ) - if (o && o.status & ORGAN_SPLINTED) - var/obj/item/W = new /obj/item/stack/medical/splint(amount=1) - o.status &= ~ORGAN_SPLINTED - if (W) - W.loc = target.loc - W.layer = initial(W.layer) - W.add_fingerprint(source) - if("CPR") - if ((target.health > config.health_threshold_dead && target.health < config.health_threshold_crit)) - var/suff = min(target.getOxyLoss(), 7) - target.adjustOxyLoss(-suff) - target.updatehealth() - for(var/mob/O in viewers(source, null)) - O.show_message("[source] performs CPR on [target]!", 1) - to_chat(target, "You feel a breath of fresh air enter your lungs. It feels good.") - to_chat(source, "Repeat at least every 7 seconds.") - if("dnainjector") - var/obj/item/weapon/dnainjector/S = item - if(S) - S.add_fingerprint(source) - if (!( istype(S, /obj/item/weapon/dnainjector) )) - S.inuse = 0 - qdel(src) - S.inject(target, source) - if (S.s_time >= world.time + 30) - S.inuse = 0 - qdel(src) - S.s_time = world.time - for(var/mob/O in viewers(source, null)) - O.show_message("[source] injects [target] with the DNA Injector!", 1) - S.inuse = 0 - if("pockets") - slot_to_process = slot_l_store - strip_item = target.l_store //We'll do both - if("internal") - if (target.internal) - target.internal.add_fingerprint(source) - target.internal = null - if (target.internals) - target.internals.icon_state = "internal0" - else - if (!( istype(target.wear_mask, /obj/item/clothing/mask) )) - return - else - if (istype(target.back, /obj/item/weapon/tank)) - target.internal = target.back - else if (istype(target.s_store, /obj/item/weapon/tank)) - target.internal = target.s_store - else if (istype(target.belt, /obj/item/weapon/tank)) - target.internal = target.belt - if (target.internal) - for(var/mob/M in viewers(target, 1)) - M.show_message("[target] is now running on internals.", 1) - target.internal.add_fingerprint(source) - if (target.internals) - target.internals.icon_state = "internal1" - - - - if("internal1") - if (target.internal) - target.internal.add_fingerprint(source) - target.internal = null - if (target.internals) - target.internals.icon_state = "internal0" - else - if (!( istype(target.wear_mask, /obj/item/clothing/mask) )) - return - else - if (istype(target.belt, /obj/item/weapon/tank)) - target.internal = target.belt - - if (target.internal) - for(var/mob/M in viewers(target, 1)) - M.show_message("[target] is now running on internals.", 1) - target.internal.add_fingerprint(source) - if (target.internals) - target.internals.icon_state = "internal1" - - - if("internal2") - if (target.internal) - target.internal.add_fingerprint(source) - target.internal = null - if (target.internals) - target.internals.icon_state = "internal0" - else - if (!( istype(target.wear_mask, /obj/item/clothing/mask) )) - return - else - if (istype(target.s_store, /obj/item/weapon/tank)) - target.internal = target.s_store - - if (target.internal) - for(var/mob/M in viewers(target, 1)) - M.show_message("[target] is now running on internals.", 1) - target.internal.add_fingerprint(source) - if (target.internals) - target.internals.icon_state = "internal1" - - if(strip_item) //Stripping an item from the mob - - var/obj/item/W = strip_item - if((W.cant_drop > 0) && (target.is_holding_item(W))) //If item we're trying to take off can't be dropped AND is in target's hand(s): - to_chat(source, "\The [W] is stuck to \the [target]!") - return - - target.u_equip(W,1) - if (target.client) - target.client.screen -= W - if (W) - W.loc = target.loc - W.layer = initial(W.layer) - //W.dropped(target) - W.stripped(target,source) - W.add_fingerprint(source) - - else //Putting an item on the mob - - if(slot_to_process) //Putting on an equipment slot - if(item && target.has_organ_for_slot(slot_to_process)) - if(item.mob_can_equip(target, slot_to_process, 0)) - source.u_equip(item,1) - - target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1) - source.update_icons() - target.update_icons() - else if(hand_index) //Putting in hand - if(target.put_in_hand(hand_index, item)) - source.u_equip(item) - - if(source && target) - if(source.machine == target) - target.show_inv(source) - qdel(src) - /mob/living/carbon/human/get_multitool(var/active_only=0) if(istype(get_active_hand(),/obj/item/device/multitool)) return get_active_hand() diff --git a/code/modules/mob/living/carbon/internals.dm b/code/modules/mob/living/carbon/internals.dm new file mode 100644 index 00000000000..3aa74198aef --- /dev/null +++ b/code/modules/mob/living/carbon/internals.dm @@ -0,0 +1,68 @@ +/mob/living/carbon/proc/has_breathing_mask() + return istype(wear_mask, /obj/item/clothing/mask) + +/mob/living/carbon/proc/internals_candidates() //These are checked IN ORDER. + return get_all_slots() + held_items + +/mob/living/carbon/human/internals_candidates() //Humans have a lot of slots, so let's give priority to some of them + var/list/priority = list(s_store, back, belt, l_store, r_store) + return priority | get_all_slots() | held_items //| operator ensures there are no duplicates + +/mob/living/carbon/proc/get_internals_tank() + for(var/obj/item/weapon/tank/T in internals_candidates()) + //We found a tank! + if(istype(T, /obj/item/weapon/tank/jetpack)) //Oh... But it's a jetpack... We'll use it if we have to, but let's see if we find something better first + if(!.) //We already had another jetpack + . = T + continue + else //It's the real deal! + return T + +// Set internals on or off. +/mob/living/carbon/proc/toggle_internals(var/mob/living/user, var/obj/item/weapon/tank/T) + if(internal) + internal.add_fingerprint(user) + internal = null + if(internals) //This is the HUD icon, these variables have WAY too similar names + internals.icon_state = "internal0" + if(user != src) + if(!user.isGoodPickpocket()) + visible_message("\The [user] shuts off \the [src]'s internals!") + user.attack_log += text("\[[time_stamp()]\] Has disabled [src.name]'s ([src.ckey]) internals.") + src.attack_log += text("\[[time_stamp()]\] Internals disabled by [user.name] ([user.ckey]).") + log_attack("[user.name] ([user.ckey]) has disabled [src.name]'s ([src.ckey]) internals.") + else + to_chat(user, "No longer running on internals.") + return 1 + else + if(!has_breathing_mask()) + if(user != src) + to_chat(user, "\The [src] is not wearing a breathing mask.") + else + to_chat(user, "You are not wearing a breathing mask.") + return + if(!T || !T.Adjacent()) //We can be given a specific tank to connect to + T = get_internals_tank() + if(!T) + var/breathes = "oxygen" + if(ishuman(src)) + var/mob/living/carbon/human/H = src + breathes = H.species.breath_type + if(user != src) + to_chat(user, "\The [src] does not have \an [breathes] tank.") + else + to_chat(user, "You don't have \an [breathes] tank.") + internal = T + T.add_fingerprint(user) + if(internals) + internals.icon_state = "internal1" + if(user != src) + var/gas_contents = T.air_contents.english_contents_list() + if(!user.isGoodPickpocket()) + to_chat(user, "\The [user] has enabled [src]'s internals.") + user.attack_log += text("\[[time_stamp()]\] Has enabled [src.name]'s ([src.ckey]) internals (Gas contents: [gas_contents]).") + src.attack_log += text("\[[time_stamp()]\] Internals enabled by [user.name] ([user.ckey]) (Gas contents: [gas_contents]).") + log_attack("[user.name] ([user.ckey]) has enabled [src.name]'s ([src.ckey]) internals (Gas contents: [gas_contents]).") + else + to_chat(src, "You are now running on internals from \the [T].") + return 1 diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 30a71998dc7..6e73ca3bd64 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -10,6 +10,34 @@ return legcuffed return null +/mob/living/carbon/u_equip(obj/item/W as obj, dropped = 1) + var/success = 0 + if(!W) return 0 + else if (W == handcuffed) + if(handcuffed.on_remove(src)) //If this returns 1, then the unquipping action was interrupted + return 0 + handcuffed = null + success = 1 + update_inv_handcuffed() + else if (W == legcuffed) + legcuffed = null + success = 1 + update_inv_legcuffed() + else + ..() + if(success) + if (W) + if (client) + client.screen -= W + W.forceMove(loc) + W.unequipped() + if(dropped) + W.dropped(src) + if(W) + W.layer = initial(W.layer) + + return + /mob/living/carbon/get_all_slots() return list(handcuffed, legcuffed, @@ -22,4 +50,4 @@ equipped -= list(handcuffed, legcuffed, back) - return equipped \ No newline at end of file + return equipped diff --git a/code/modules/mob/living/carbon/martian/martian.dm b/code/modules/mob/living/carbon/martian/martian.dm index 907cef5b380..c7943ed9a3a 100644 --- a/code/modules/mob/living/carbon/martian/martian.dm +++ b/code/modules/mob/living/carbon/martian/martian.dm @@ -94,8 +94,9 @@ if (W) if(client) client.screen -= W + W.forceMove(loc) + W.unequipped() if(dropped) - W.forceMove(loc) W.dropped(src) if(W) W.layer = initial(W.layer) @@ -114,4 +115,5 @@ W.layer = 20 W.equipped(src, slot) - W.loc = src \ No newline at end of file + W.forceMove(src) + if(client) client.screen |= W diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index e7705eed116..a0b62082ebc 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -1,199 +1,101 @@ -/obj/effect/equip_e/monkey/process() - if (item) - item.add_fingerprint(source) - if (!( item )) - switch(place) - if("head") - if (!( target.wear_mask )) - qdel(src) - return - if("hand") - if (!( target.held_items[hand_index] )) - qdel(src) - return - if("back") - if (!( target.back )) - qdel(src) - return - if("handcuff") - if (!( target.handcuffed )) - qdel(src) - return - if("internal") - if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal ))) - qdel(src) - return - - if (item) - if(isrobot(source) && place != "handcuff") - var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel") - if(!(L.Find(place))) - qdel(src) - return - for(var/mob/O in viewers(target, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("[] is trying to put a [] on []", source, item, target), 1) - else - var/message = null - switch(place) - if("mask") - if(istype(target.wear_mask, /obj/item/clothing)&&!target.wear_mask:canremove) - message = text("[] fails to take off \a [] from []'s body!", source, target.wear_mask, target) - else - message = text("[] is trying to take off \a [] from []'s head!", source, target.wear_mask, target) - if("hand") - message = text("[] is trying to take off a [] from []'s []!", source, target.held_items[hand_index], target, target.get_index_limb_name(hand_index)) - if("back") - message = text("[] is trying to take off a [] from []'s back!", source, target.back, target) - if("handcuff") - message = text("[] is trying to unhandcuff []!", source, target) - if("internal") - if (target.internal) - message = text("[] is trying to remove []'s internals", source, target) - else - message = text("[] is trying to set on []'s internals.", source, target) - else - for(var/mob/M in viewers(target, null)) - M.show_message(message, 1) - spawn( 30 ) - done() - return - return - -/obj/effect/equip_e/monkey/done() - if(!source || !target) return - if(source.loc != s_loc) return - if(target.loc != t_loc) return - if(!source.Adjacent(target)) return - if(item && source.get_active_hand() != item) return - if ((source.restrained() || source.stat)) return - switch(place) - if("mask") - if (target.wear_mask) - if(istype(target.wear_mask, /obj/item/clothing)&& !target.wear_mask:canremove) - return - var/obj/item/W = target.wear_mask - target.u_equip(W,1) - if (target.client) - target.client.screen -= W - if (W) - W.loc = target.loc - //W.dropped(target) - W.layer = initial(W.layer) - W.add_fingerprint(source) - else - if (istype(item, /obj/item/clothing/mask)) - source.drop_item(item, force_drop = 1) - loc = target - item.layer = 20 - target.wear_mask = item - item.loc = target - if("hand") - if (target.held_items[hand_index]) - var/obj/item/W = target.held_items[hand_index] - target.u_equip(W,1) - if (target.client) - target.client.screen -= W - if (W) - W.loc = target.loc - W.layer = initial(W.layer) - //W.dropped(target) - W.add_fingerprint(source) - else - if (istype(item, /obj/item)) - source.drop_item(item, force_drop = 1) - target.put_in_hand(hand_index, item) - loc = target - item.dropped(source) - if("back") - if (target.back) - var/obj/item/W = target.back - target.u_equip(W,1) - if (target.client) - target.client.screen -= W - if (W) - W.loc = target.loc - //W.dropped(target) - W.layer = initial(W.layer) - W.add_fingerprint(source) - else - if ((istype(item, /obj/item) && item.slot_flags & SLOT_BACK )) - source.drop_item(item, force_drop = 1) - loc = target - item.layer = 20 - target.back = item - item.loc = target - if("handcuff") - if (target.handcuffed) - var/obj/item/W = target.handcuffed - target.u_equip(W,1) - if (target.client) - target.client.screen -= W - if (W) - W.loc = target.loc - //W.dropped(target) - W.layer = initial(W.layer) - W.add_fingerprint(source) - else - if (istype(item, /obj/item/weapon/handcuffs)) - source.drop_item(item, force_drop = 1) - target.handcuffed = item - item.loc = target - if("internal") - if (target.internal) - target.internal.add_fingerprint(source) - target.internal = null - else - if (target.internal) - target.internal = null - if (!( istype(target.wear_mask, /obj/item/clothing/mask) )) - return - else - if (istype(target.back, /obj/item/weapon/tank)) - target.internal = target.back - target.internal.add_fingerprint(source) - for(var/mob/M in viewers(target, 1)) - if ((M.client && !( M.blinded ))) - M.show_message(text("[] is now running on internals.", target), 1) - else - source.regenerate_icons() - target.regenerate_icons() - qdel(src) - return - - - //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() //set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc. /mob/living/carbon/monkey/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1) if(!slot) return if(!istype(W)) return - if(W == get_active_hand()) - u_equip(W,0) + if(src.is_holding_item(W)) + src.u_equip(W) switch(slot) if(slot_back) src.back = W - W.equipped(src, slot) update_inv_back(redraw_mob) + if(slot_head) + src.hat = W + update_inv_hat(redraw_mob) + if(slot_w_uniform) + src.uniform = W + update_inv_uniform(redraw_mob) + if(slot_glasses) + src.glasses = W + update_inv_glasses(redraw_mob) if(slot_wear_mask) src.wear_mask = W - W.equipped(src, slot) update_inv_wear_mask(redraw_mob) if(slot_handcuffed) src.handcuffed = W update_inv_handcuffed(redraw_mob) if(slot_legcuffed) src.legcuffed = W - W.equipped(src, slot) update_inv_legcuffed(redraw_mob) if(slot_in_backpack) W.loc = src.back else - to_chat(usr, "You are trying to eqip this item to an unsupported inventory slot. How the heck did you manage that? Stop it...") + to_chat(usr, "You are trying to equip this item to an unsupported inventory slot. How the heck did you manage that? Stop it...") return W.layer = 20 + W.equipped(src, slot) + W.forceMove(src) + if(client) client.screen |= W - return \ No newline at end of file +// Return the item currently in the slot ID +/mob/living/carbon/monkey/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_back) + return back + if(slot_w_uniform) + return uniform + if(slot_head) + return hat + if(slot_wear_mask) + return wear_mask + if(slot_glasses) + return glasses + if(slot_handcuffed) + return handcuffed + if(slot_legcuffed) + return legcuffed + return null + +/mob/living/carbon/monkey/get_all_slots() + return list( + back, + uniform, + hat, + wear_mask, + glasses, + handcuffed, + legcuffed) + +/mob/living/carbon/monkey/u_equip(obj/item/W as obj, dropped = 1) + var/success = 0 + if(!W) return 0 + + if(W == hat) + hat = null + success = 1 + update_inv_hat() + else if(W == glasses) + glasses = null + success = 1 + update_inv_glasses() + else if(W == uniform) + uniform = null + success = 1 + update_inv_uniform() + else + ..() + if(success) + if (W) + if (client) + client.screen -= W + W.forceMove(loc) + W.unequipped() + if(dropped) + W.dropped(src) + if(W) + W.layer = initial(W.layer) + + return diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 1c4c7a760ef..34f5bef35c0 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -632,21 +632,6 @@ /mob/living/carbon/monkey/proc/handle_regular_hud_updates() - - - if(!canWearHats && m_hatbg) - if(m_hatbg.icon_state != "blank") - m_hatbg.icon_state = "blank" - - if(!canWearClothes && m_suitclothesbg) - if(m_suitclothesbg.icon_state != "blank") - m_suitclothesbg.icon_state = "blank" - - if(!canWearGlasses && m_glassesbg) - if(m_glassesbg.icon_state != "blank") - m_glassesbg.icon_state = "blank" - - if (stat == 2 || (M_XRAY in mutations)) sight |= SEE_TURFS sight |= SEE_MOBS diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 5ab72a90870..b89355a9239 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -143,55 +143,6 @@ ///mob/living/carbon/monkey/diona/New() //Moved to it's duplicate declaration modules\mob\living\carbon\monkey\diona.dm -/mob/living/carbon/monkey/show_inv(mob/living/carbon/user as mob) - user.set_machine(src) - var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) - var/TAB = "    " - - var/dat - - for(var/i = 1 to held_items.len) //Hands - var/obj/item/I = held_items[i] - dat += "[capitalize(get_index_limb_name(i))] [(I && !I.abstract) ? I : "Empty"]
" - - dat += "
Back: [(back && !(src.back.abstract)) ? back : "Empty"]" - if(has_breathable_mask && istype(back, /obj/item/weapon/tank)) - dat += "
[TAB]↳[internal ? "Disable Internals" : "Set Internals"]" - - dat += "
" - - if(canWearHats) - if(hat) - dat += "
Headwear: [hat] (Remove)" - else - dat += "
Headwear: Empty" - - dat += "
Mask: [(wear_mask && !(src.wear_mask.abstract)) ? wear_mask : "Empty"]" - - if(canWearGlasses) - if(glasses) - dat += "
Glasses: [glasses] (Remove)" - else - dat += "
Glasses: Empty" - - if(canWearClothes) - if(uniform) - dat += "
Uniform: [uniform] (Remove)" - else - dat += "
Uniform: Empty" - - if(handcuffed) - dat += "
Handcuffed: Remove" - - dat += {" -
-
Close - "} - - var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 340, 500) - popup.set_content(dat) - popup.open() - /mob/living/carbon/monkey/movement_delay() var/tally = 0 if(reagents) @@ -213,139 +164,43 @@ return tally+config.monkey_delay +/mob/living/carbon/monkey/show_inv(mob/living/carbon/user as mob) + user.set_machine(src) -/mob/living/carbon/monkey/proc/wearhat(var/obj/item/clothing/head/H as obj) - if(H) - if(istype(H)) - var/obj/item/clothing/head/oldhat = null - if(hat) - oldhat = hat - hat = null - hat = H - usr.drop_item(hat, src, 1) - regenerate_icons() - if (oldhat) - usr.put_in_hands(oldhat) - else - if(hat) - usr.put_in_hands(hat) - hat = null - regenerate_icons() + var/dat -/mob/living/carbon/monkey/proc/wearclothes(var/obj/item/clothing/monkeyclothes/C as obj) - if(C) - if(istype(C)) - var/obj/item/clothing/monkeyclothes/olduniform = null - if(uniform) - olduniform = uniform - uniform = null - uniform = C - usr.drop_item(uniform, src, 1) - regenerate_icons() - if (olduniform) - usr.put_in_hands(olduniform) - else - if(uniform) - usr.put_in_hands(uniform) - uniform = null - regenerate_icons() + for(var/i = 1 to held_items.len) //Hands + var/obj/item/I = held_items[i] + dat += "[capitalize(get_index_limb_name(i))] [makeStrippingButton(I)]
" -/mob/living/carbon/monkey/proc/wearglasses(var/obj/item/clothing/glasses/G as obj) - if(G) - if(istype(G)) - var/obj/item/clothing/glasses/oldglasses = null - if(glasses) - oldglasses = glasses - glasses = null - glasses = G - usr.drop_item(glasses, src, 1) - regenerate_icons() - if (oldglasses) - usr.put_in_hands(oldglasses) - else - if(glasses) - usr.put_in_hands(glasses) - glasses = null - regenerate_icons() + dat += "
Back: [makeStrippingButton(back)]" -/mob/living/carbon/monkey/Topic(href, href_list) - ..() - if (href_list["mach_close"]) - var/t1 = text("window=[]", href_list["mach_close"]) - unset_machine() - src << browse(null, t1) - if ((href_list["item"] && !( usr.stat ) && !( usr.restrained() ) && in_range(src, usr) )) - var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( ) - O.source = usr - O.target = src - O.item = usr.get_active_hand() - O.s_loc = usr.loc - O.t_loc = loc - O.place = href_list["item"] - requests += O - spawn( 0 ) - O.process() - return - if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) - return - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("uniform") - if(uniform) - uniform.loc = src.loc - uniform = null - regenerate_icons() - else - to_chat(usr, "He has no uniform to remove.") - return - if("hat") - if(hat) - hat.loc = src.loc - hat = null - regenerate_icons() - else - to_chat(usr, "He has no hat to remove") - return - if("glasses") - if(glasses) - glasses.loc = src.loc - glasses = null - regenerate_icons() - else - to_chat(usr, "He has no glasses to remove") - return - show_inv(usr) - else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) - return + dat += "
" - var/add_to = href_list["add_inv"] - if(!usr.get_active_hand()) - to_chat(usr, "You have nothing in your hand to put on him.") - return - switch(add_to) - if("uniform") - if(uniform) - to_chat(usr, "He's already wearing something.") - return - else - wearclothes(usr.get_active_hand()) - if("hat") - if(hat) - to_chat(usr, "He's already wearing something.") - return - else - wearhat(usr.get_active_hand()) - if("glasses") - if(glasses) - to_chat(usr, "He's already wearing something.") - return - else - wearglasses(usr.get_active_hand()) - show_inv(usr) - ..() - return + if(canWearHats) + dat += "
Headwear: [makeStrippingButton(hat)]" + + dat += "
Mask: [makeStrippingButton(wear_mask)]" + if(has_breathing_mask()) + dat += "
[HTMLTAB]↳Internals: [src.internal ? "On" : "Off"] (Toggle)" + + if(canWearGlasses) + dat += "
Glasses: [makeStrippingButton(glasses)]" + + if(canWearClothes) + dat += "
Uniform: [makeStrippingButton(uniform)]" + + if(handcuffed) + dat += "
Handcuffed: Remove" + + dat += {" +
+
Close + "} + + var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 340, 500) + popup.set_content(dat) + popup.open() //mob/living/carbon/monkey/bullet_act(var/obj/item/projectile/Proj)taken care of in living @@ -755,4 +610,4 @@ if(lying) layer = MOB_LAYER - 0.1 //so we move under bedsheets else - layer = MOB_LAYER \ No newline at end of file + layer = MOB_LAYER diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index a72176b6f27..6d9888264a6 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -54,6 +54,7 @@ var/t_state = uniform.item_state if(!t_state) t_state = uniform.icon_state overlays_standing[M_UNIFORM_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = t_state) + uniform.screen_loc = ui_monkey_uniform else overlays_standing[M_UNIFORM_LAYER] = null if(update_icons) update_icons() @@ -63,6 +64,7 @@ if(hat) var/t_state = hat.icon_state overlays_standing[M_HAT_LAYER] = image("icon" = 'icons/mob/monkey_head.dmi', "icon_state" = t_state) + hat.screen_loc = ui_monkey_hat else overlays_standing[M_HAT_LAYER] = null if(update_icons) update_icons() @@ -71,6 +73,7 @@ if(hat) var/t_state = hat.icon_state overlays_standing[M_HAT_LAYER] = image("icon" = 'icons/mob/monkey_head.dmi', "icon_state" = t_state, "pixel_y" = -7) + hat.screen_loc = ui_monkey_hat else overlays_standing[M_HAT_LAYER] = null if(update_icons) update_icons() @@ -79,6 +82,7 @@ if(hat) var/t_state = hat.icon_state overlays_standing[M_HAT_LAYER] = image("icon" = 'icons/mob/monkey_head.dmi', "icon_state" = t_state, "pixel_y" = -12) + hat.screen_loc = ui_monkey_hat else overlays_standing[M_HAT_LAYER] = null if(update_icons) update_icons() @@ -89,6 +93,7 @@ if(glasses) var/t_state = glasses.icon_state overlays_standing[M_GLASSES_LAYER] = image("icon" = 'icons/mob/monkey_eyes.dmi', "icon_state" = t_state) + glasses.screen_loc = ui_monkey_glasses else overlays_standing[M_GLASSES_LAYER] = null if(update_icons) update_icons() @@ -192,24 +197,6 @@ if(client) client.screen |= contents - if(m_hat) - if(hat) - m_hat.icon_state = hat.icon_state - else - m_hat.icon_state = "none" - - if(m_suitclothes) - if(uniform) - m_suitclothes.icon_state = uniform.icon_state - else - m_suitclothes.icon_state = "none" - - if(m_glasses) - if(glasses) - m_glasses.icon_state = glasses.icon_state - else - m_glasses.icon_state = "none" - //Call when target overlay should be added/removed /mob/living/carbon/monkey/update_targeted(var/update_icons=1) if (targeted_by && target_locked) diff --git a/code/modules/mob/living/carbon/stripping.dm b/code/modules/mob/living/carbon/stripping.dm new file mode 100644 index 00000000000..dea3e0ac8f5 --- /dev/null +++ b/code/modules/mob/living/carbon/stripping.dm @@ -0,0 +1,276 @@ +/proc/makeStrippingButton(var/obj/item/I) //Not actually the stripping button, just what's written on it + if(!istype(I) || I.abstract) + return "Empty" + else + return I + +//This proc is unsafe, it assumes that the mob is holding the item, that the item can be removed, etc. +/mob/living/carbon/proc/strip_item_from(var/mob/living/user, var/obj/item/target_item, var/slot = null, var/pickpocket = FALSE) + var/temp_loc = target_item.loc //do_mob will make sure nobody goes anywhere, including the item to be placed, but sadly it doesn't keep track of the item to be stripped + + target_item.add_fingerprint(user) //We don't need to be successful in order to get our prints on the thing + + if(do_mob(user, src, HUMAN_STRIP_DELAY)) //Fails if the user moves, changes held item, is incapacitated, etc. + if(temp_loc != target_item.loc) //This will also fail if the item to strip went anywhere, necessary because do_mob() doesn't keep track of it. + return + + if(target_item.before_stripped(src, user, slot)) //If this returns 1, then the stripping process was interrupted! + return + + drop_from_inventory(target_item) + target_item.stripped(src, user) + if(pickpocket) + user.put_in_hands(target_item) + + return TRUE + +//This proc is unsafe, it assumes that the mob has the given slot free, that the item can be put there etc. +/mob/living/carbon/proc/reversestrip_into_slot(var/mob/living/user, var/slot, var/pickpocket = FALSE) + var/obj/item/held = user.get_active_hand() + + if(do_mob(user, src, HUMAN_STRIP_DELAY)) //Fails if the user moves, changes held item, is incapacitated, etc. + if(held.mob_can_equip(src, slot, disable_warning = 1)) + user.drop_from_inventory(held) + src.equip_to_slot(held, slot) //Not using equip_to_slot_if_possible() because we want to check that the guy can wear this before dropping it + + return TRUE + +//This proc is unsafe, it assumes hand stuff. +/mob/living/carbon/proc/reversestrip_into_hand(var/mob/living/user, var/index, var/pickpocket = FALSE) + var/obj/item/held = user.get_active_hand() + + if(do_mob(user, src, HUMAN_STRIP_DELAY)) //Fails if the user moves, changes held item, is incapacitated, etc. + if(src.put_in_hand_check(held, index)) + user.drop_from_inventory(held) + src.put_in_hand(index, held) + + return TRUE + +/mob/living/carbon/proc/handle_strip_slot(var/mob/living/user, var/slot) + if(slot in src.check_obscured_slots()) //Ideally they wouldn't even get the button to do this, but they could have an outdated menu or something + to_chat(user, "You can't reach that, something is covering it.") + return + + var/obj/item/held = user.get_active_hand() + var/obj/item/target_item = src.get_item_by_slot(slot) + var/pickpocket = user.isGoodPickpocket() + + + if(istype(target_item) && !target_item.abstract) //We want the player to be able to strip someone while holding an item in their hands, for convenience and because otherwise people will bitch about it. + if(!target_item.canremove || src.is_in_modules(target_item)) + to_chat(user, "You can't seem to be able to take that off!") + return + + if(!pickpocket) + visible_message("\The [user] is trying to remove \a [target_item] from \the [src]'s [src.slotID2slotname(slot)]!") + + if(strip_item_from(user, target_item, slot, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has stripped \a [target_item] from [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] Has had \a [target_item] stripped from their [src.slotID2slotname(slot)] by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has stripped \a [target_item] from [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to strip \a [target_item] from [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to strip \a [target_item] from this mob's [src.slotID2slotname(slot)]") + log_attack("[user.name] ([user.ckey]) has failed to strip \a [target_item] from [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + + else if(istype(held) && !held.abstract) + if(held.cant_drop > 0 || user.is_in_modules(held)) + to_chat(user, "You can't seem to be able to let go of \the [held].") + return + if(!held.mob_can_equip(src, slot, disable_warning = 1)) //This also checks for the target being too fat for the clothing item and such + to_chat(user, "You can't put that there!") //Ideally we could have a more descriptive message since this can fail for a variety of reasons, but whatever + return + if(!src.has_organ_for_slot(slot)) + to_chat(user, "\The [src] has no [src.slotID2slotname(slot)].") //blunt + return + + if(!pickpocket) + visible_message("\The [user] is trying to put \a [held] on \the [src]!") + + if(reversestrip_into_slot(user, slot, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has put \a [held] into [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] Has had \a [held] put into their [src.slotID2slotname(slot)] by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has put \a [held] into [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to place \a [held] into [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to place \a [held] into this mob's [src.slotID2slotname(slot)]") + log_attack("[user.name] ([user.ckey]) has failed to place \a [held] into [src.name]'s [src.slotID2slotname(slot)] ([src.ckey])") + +/mob/living/carbon/proc/handle_strip_hand(var/mob/living/user, var/index) + if(!index || !isnum(index)) return + + var/obj/item/held = user.get_active_hand() + var/obj/item/target_item = src.held_items[index] + var/pickpocket = user.isGoodPickpocket() + + if(istype(target_item) && !target_item.abstract) + if(target_item.cant_drop > 0 || src.is_in_modules(target_item)) + to_chat(user, "\a [target_item] is stuck to \the [src]!") + return + + if(!pickpocket) + visible_message("\The [user] is trying to take \a [target_item] from \the [src]'s [src.get_index_limb_name(index)]!") + + if(strip_item_from(user, target_item, null, pickpocket)) //slot is null since it's a hand index + user.attack_log += text("\[[time_stamp()]\] Has stripped \a [target_item] from [src.name] ([src.ckey])'s [src.get_index_limb_name(index)]") + src.attack_log += text("\[[time_stamp()]\] Has had \a [target_item] stripped from their [src.get_index_limb_name(index)] by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has stripped \a [target_item] from [user.name]'s ([src.ckey])'s [src.get_index_limb_name(index)]") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to strip \a [target_item] from [src.name]'s ([src.ckey]) [src.get_index_limb_name(index)]") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to strip \a [target_item] from this mob's [src.get_index_limb_name(index)]") + log_attack("[user.name] ([user.ckey]) has failed to strip \a [target_item] from [src.name]'s ([src.ckey]) [src.get_index_limb_name(index)]") + + else if(istype(held) && !held.abstract) + if(held.cant_drop > 0 || user.is_in_modules(held)) + to_chat(user, "You can't seem to be able to let go of \the [held].") + return + + if(!src.put_in_hand_check(held, index)) + to_chat(user, "\The [src] cannot hold [held]!") + return + + if(!pickpocket) + visible_message("\The [user] is trying to put \a [held] on \the [src]'s [src.get_index_limb_name(index)]!") + + if(reversestrip_into_hand(user, index, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has put \a [held] into [src.name]'s ([src.ckey]) [src.get_index_limb_name(index)]") + src.attack_log += text("\[[time_stamp()]\] Has had \a [held] put into their [src.get_index_limb_name(index)] by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has put \a [held] into [src.name]'s ([src.ckey]) [src.get_index_limb_name(index)]") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to place \a [held] into [src.name]'s ([src.ckey]) [src.get_index_limb_name(index)]") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to place \a [held] into this mob's [src.get_index_limb_name(index)]") + log_attack("[user.name] ([user.ckey]) has failed to place \a [held] into [src.name]'s '([src.ckey]) [src.get_index_limb_name(index)]") + +/mob/living/carbon/proc/handle_strip_id(var/mob/living/user) + var/obj/item/id_item = src.get_item_by_slot(slot_wear_id) + var/obj/item/place_item = user.get_active_hand() + var/pickpocket = user.isGoodPickpocket() + + if(id_item && !id_item.abstract) + if(!id_item.canremove) + to_chat(user, "You can't seem to be able to take that off!") + return + + to_chat(user, "You try to take [src]'s ID.") + + if(strip_item_from(user, id_item, slot_wear_id, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has pickpocketed \a [id_item] from [src.name]'s ([src.ckey]) ID slot.") + src.attack_log += text("\[[time_stamp()]\] Has had \a [id_item] pickpocketed by [user.name] ([user.ckey]) from their ID slot.") + log_attack("[user.name] ([user.ckey]) has pickpocketed \a [id_item] from [src.name]'s ([src.ckey]) ID slot.") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to pickpocket \a [id_item] from [src.name]'s ([src.ckey]) ID slot.") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to pickpocket \a [id_item] from this mob's ID slot.") + log_attack("[user.name] ([user.ckey]) has failed to pickpocket \a [id_item] from [src.name]'s ([src.ckey]) ID slot.") + if(!pickpocket) // Display a warning if the user mocks up. Unless they're just that good of a pickpocket. + to_chat(src, "You feel your ID being fumbled with!") + else if(place_item && !place_item.abstract) + if(place_item.cant_drop > 0 || user.is_in_modules(place_item)) + to_chat(user, "You can't seem to be able to let go of \the [place_item].") + return + if(!place_item.mob_can_equip(src, slot_wear_id, disable_warning = 1)) + to_chat(user, "You can't put that there!") + return + + to_chat(user, "You try to place [place_item] on [src].") + + if(reversestrip_into_slot(user, slot_wear_id, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has reverse-pickpocketed \a [place_item] into [src.name]'s ([src.ckey]) ID slot.") + src.attack_log += text("\[[time_stamp()]\] Has had \a [place_item] reverse-pickpocketed into their ID slot by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has reverse-pickpocketed \a [place_item] into [src.name]'s ([src.ckey]) ID slot.") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to reverse-pickpocket \a [place_item] into [src.name]'s ([src.ckey]) ID slot.") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to reverse-pickpocket \a [place_item] into this mob's ID slot.") + log_attack("[user.name] ([user.ckey]) has failed to reverse-pickpocket \a [place_item] into [src.name]'s ([src.ckey]) ID slot.") + +/mob/living/carbon/proc/handle_strip_pocket(var/mob/living/user, var/pocket_side) + var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store) + var/obj/item/pocket_item = get_item_by_slot(pocket_id) + var/obj/item/place_item = user.get_active_hand() + var/pickpocket = user.isGoodPickpocket() + + if(pocket_item && !pocket_item.abstract) + if(!pocket_item.canremove) + to_chat(user, "You can't seem to be able to take that off!") + return + + to_chat(user, "You try to empty [src]'s [pocket_side] pocket.") + + if(strip_item_from(user, pocket_item, pocket_id, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has pickpocketed \the [pocket_item] from [src.name]'s ([src.ckey]) [pocket_side] pocket.") + src.attack_log += text("\[[time_stamp()]\] Has had \the [pocket_item] pickpocketed by [user.name] ([user.ckey]) from their [pocket_side] pocket.") + log_attack("[user.name] ([user.ckey]) has pickpocketed \the [pocket_item] from [src.name]'s ([src.ckey]) [pocket_side] pocket.") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to pickpocket \the [pocket_item] from [src.name]'s ([src.ckey]) [pocket_side] pocket.") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to pickpocket \the [pocket_item] from this mob's [pocket_side] pocket.") + log_attack("[user.name] ([user.ckey]) has failed to pickpocket \the [pocket_item] from [src.name]'s ([src.ckey]) [pocket_side] pocket.") + if(!pickpocket) // Display a warning if the user mocks up. Unless they're just that good of a pickpocket. + to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") + else if(place_item && !place_item.abstract) + if(place_item.cant_drop > 0 || user.is_in_modules(place_item)) + to_chat(user, "You can't seem to be able to let go of \the [place_item].") + return + if(!place_item.mob_can_equip(src, pocket_id, disable_warning = 1)) + to_chat(user, "You can't put that there!") + return + + to_chat(user, "You try to place [place_item] on [src]'s [pocket_side] pocket.") + + if(reversestrip_into_slot(user, pocket_id, pickpocket)) + user.attack_log += text("\[[time_stamp()]\] Has reverse-pickpocketed \a [place_item] into [src.name]'s ([src.ckey]) [pocket_side] pocket.") + src.attack_log += text("\[[time_stamp()]\] Has had \a [place_item] reverse-pickpocketed into their [pocket_side] pocket by [user.name] ([user.ckey])") + log_attack("[user.name] ([user.ckey]) has reverse-pickpocketed \a [place_item] into [src.name]'s ([src.ckey]) [pocket_side] pocket.") + show_inv(user) + else + user.attack_log += text("\[[time_stamp()]\] Has failed to reverse-pickpocket \a [place_item] into [src.name]'s ([src.ckey]) [pocket_side] pocket.") + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to reverse-pickpocket \a [place_item] into this mob's [pocket_side] pocket.") + log_attack("[user.name] ([user.ckey]) has failed to reverse-pickpocket \a [place_item] into [src.name]'s ([src.ckey]) [pocket_side] pocket.") + +// Modify the current target sensor level. +/mob/living/carbon/human/proc/toggle_sensors(var/mob/living/user) + var/obj/item/clothing/under/suit = w_uniform + if(!suit) + to_chat(user, "\The [src] is not wearing a suit.") + return + if(!suit.has_sensor) + to_chat(user, "\The [src]'s suit does not have sensors.") + return + if(suit.has_sensor >= 2) + to_chat(user, "\The [src]'s suit sensor controls are locked.") + return + if(!user.isGoodPickpocket()) + visible_message("\The [user] is trying to set [src]'s suit sensors.", "\The [user] is trying to set your suit sensors!") + if(do_mob(user, src, HUMAN_STRIP_DELAY)) + var/newmode = suit.set_sensors(user) + if(newmode) + src.attack_log += text("\[[time_stamp()]\] Has had their sensors set to [newmode] by [user.name] ([user.ckey])") + user.attack_log += text("\[[time_stamp()]\] Set [src.name]'s suit sensors ([src.ckey]).") + log_attack("[user.name] ([user.ckey]) has set [src.name]'s suit sensors ([src.ckey]) to [newmode].") + else + src.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) has failed to set this mob's suit sensors.") + user.attack_log += text("\[[time_stamp()]\] Has failed to set [src.name]'s ([src.ckey]) suit sensors.") + log_attack("[user.name] ([user.ckey]) has failed to set [src.name]'s ([src.ckey]) suit sensors.") + +// Set internals on or off. +/mob/living/carbon/proc/set_internals(var/mob/living/user) + if(!has_breathing_mask()) + to_chat(user, "\The [src] is not wearing a breathing mask.") + return + + var/obj/item/weapon/tank/T = src.get_internals_tank() + if(!T) + to_chat(user, "\The [src] does not have a tank to connect to.") + return + + if(!user.isGoodPickpocket()) + visible_message("\The [user] is trying to set [src]'s internals.", "\The [user] is trying to set your internals!") + + if(do_mob(user, src, HUMAN_STRIP_DELAY)) + src.toggle_internals(user, T) + show_inv(user) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 60cb1452a03..3f0f74e5c91 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -961,8 +961,10 @@ Thanks. CM.visible_message("[CM] manages to break the handcuffs!", "You successfuly break your handcuffs.") CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - qdel(CM.handcuffed) - CM.handcuffed.handcuffs_remove(CM) + var/obj/item/weapon/handcuffs/cuffs = CM.handcuffed + CM.drop_from_inventory(cuffs) + if(!cuffs.gcDestroyed) //If these were not qdel'd already (exploding cuffs, anyone?) + qdel(cuffs) else to_chat(CM, "Your cuff breaking attempt was interrupted.") @@ -982,8 +984,7 @@ Thanks. CM.visible_message("[CM] manages to remove [HC]!", "You successfuly remove [HC].", self_drugged_message="You successfully regain control of your hands.") - CM.handcuffed.loc = usr.loc - CM.handcuffed.handcuffs_remove(CM) + CM.drop_from_inventory(HC) else CM.simple_message("Your uncuffing attempt was interrupted.", "Your attempt to regain control of your hands was interrupted. Damn it!") diff --git a/code/modules/mob/living/silicon/mommi/inventory.dm b/code/modules/mob/living/silicon/mommi/inventory.dm index d5c6c86f4b9..24973cc759b 100644 --- a/code/modules/mob/living/silicon/mommi/inventory.dm +++ b/code/modules/mob/living/silicon/mommi/inventory.dm @@ -11,7 +11,7 @@ /mob/living/silicon/robot/mommi/get_equipped_items() return head_state -/mob/living/silicon/robot/mommi/proc/is_in_modules(obj/item/W, var/permit_sheets=0) +/mob/living/silicon/robot/mommi/is_in_modules(obj/item/W, var/permit_sheets=0) if(istype(W, src.module.emag.type)) return src.module.emag // Exact matching for stacks (so we can load machines) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 1aaef4bf8ea..e300ce46876 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -15,6 +15,10 @@ /mob/living/silicon/robot/get_equipped_items() return get_all_slots() +//May need work +/mob/living/silicon/robot/is_in_modules(var/obj/item/W) + return (W in module.modules) + /mob/living/silicon/robot/proc/uneq_module(const/obj/item/module) if(!istype(module)) return 0 @@ -246,4 +250,4 @@ /mob/living/silicon/robot/before_take_item(var/obj/item/W) ..() if(W.loc == src.module) - src.module.modules -= W //maybe fix the cable issues. \ No newline at end of file + src.module.modules -= W //maybe fix the cable issues. diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 46ed38199a9..0fa5f8b6603 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -323,3 +323,6 @@ /mob/living/silicon/earprot() return 1 + +/mob/living/silicon/show_inv(mob/user) + return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index af1ccb4f561..d102642c953 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -498,8 +498,8 @@ var/global/obj/screen/fuckstat/FUCK = new if(W) W.attack_hand(src) - if(ishuman(src) && W == src:head) - src:update_hair() + /*if(ishuman(src) && W == src:head) //AAAAAUGH + src:update_hair()*/ /mob/proc/put_in_any_hand_if_possible(obj/item/W as obj) for(var/index = 1 to held_items.len) @@ -507,90 +507,43 @@ var/global/obj/screen/fuckstat/FUCK = new return 1 return 0 -//This is a SAFE proc. Use this instead of equip_to_splot()! +//This is a SAFE proc. Use this instead of equip_to_slot()! //set del_on_fail to have it delete W if it fails to equip //set disable_warning to disable the 'you are unable to equip that' warning. //unset redraw_mob to prevent the mob from being redrawn at the end. /mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, act_on_fail = 0, disable_warning = 0, redraw_mob = 1, automatic = 0) if(!istype(W)) return 0 - if(ishuman(src)) - var/mob/living/carbon/human/H = src - switch(W.mob_can_equip(src, slot, disable_warning, automatic)) - if(0) - switch(act_on_fail) - if(EQUIP_FAILACTION_DELETE) - qdel(W) - W = null - if(EQUIP_FAILACTION_DROP) - W.loc=get_turf(src) // I think. - else - if(!disable_warning) - to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING - return 0 - if(1) - equip_to_slot(W, slot, redraw_mob) - if(2) - var/in_the_hand = (is_holding_item(W)) - var/obj/item/wearing = get_item_by_slot(slot) - if(wearing) - if(!in_the_hand) //if we aren't holding it, the proc is abstract so get rid of it - switch(act_on_fail) - if(EQUIP_FAILACTION_DELETE) - qdel(W) - if(EQUIP_FAILACTION_DROP) - W.loc=get_turf(src) // I think. - return + if(!W.mob_can_equip(src, slot, disable_warning)) + switch(act_on_fail) + if(EQUIP_FAILACTION_DELETE) + qdel(W) + W = null + if(EQUIP_FAILACTION_DROP) + W.forceMove(get_turf(src)) //Should this be using drop_from_inventory instead? + else + if(!disable_warning) + to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING - if(drop_item(W)) - if(!(put_in_active_hand(wearing))) - equip_to_slot(wearing, slot, redraw_mob) - switch(act_on_fail) - if(EQUIP_FAILACTION_DELETE) - qdel(W) - else - if(!disable_warning && act_on_fail != EQUIP_FAILACTION_DROP) - to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING + return 0 - return - else - equip_to_slot(W, slot, redraw_mob) - u_equip(wearing,0) - put_in_active_hand(wearing) - if(H.s_store && !H.s_store.mob_can_equip(src, slot_s_store, 1)) - u_equip(H.s_store,1) - return 1 - else - if(!W.mob_can_equip(src, slot, disable_warning)) - switch(act_on_fail) - if(EQUIP_FAILACTION_DELETE) - qdel(W) - W = null - if(EQUIP_FAILACTION_DROP) - W.loc=get_turf(src) // I think. - else - if(!disable_warning) - to_chat(src, "You are unable to equip that.")//Only print if act_on_fail is NOTHING - - return 0 - - equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. - return 1 + equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. + return 1 //This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. //In most cases you will want to use equip_to_slot_if_possible() /mob/proc/equip_to_slot(obj/item/W as obj, slot) return -//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. +//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the round starts and when events happen and such. /mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) return equip_to_slot_if_possible(W, slot, EQUIP_FAILACTION_DELETE, 1, 0) -//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. +//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the round starts and when events happen and such. /mob/proc/equip_to_slot_or_drop(obj/item/W as obj, slot) return equip_to_slot_if_possible(W, slot, EQUIP_FAILACTION_DROP, 1, 0) -// Convinience proc. Collects crap that fails to equip either onto the mob's back, or drops it. +// Convenience proc. Collects crap that fails to equip either onto the mob's back, or drops it. // Used in job equipping so shit doesn't pile up at the start loc. /mob/living/carbon/human/proc/equip_or_collect(var/obj/item/W, var/slot) if(!equip_to_slot_or_drop(W, slot)) @@ -859,24 +812,25 @@ var/list/slot_equipment_priority = list( \ /mob/proc/show_inv(mob/user as mob) user.set_machine(src) - var/dat = {" -
[name]
-

-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")]"} + var/dat = "" + dat += "
[name]
" + dat += "

" + dat += "
Mask: [makeStrippingButton(wear_mask)]" for(var/i = 1 to held_items.len) //Hands var/obj/item/I = held_items[i] - dat += "[capitalize(get_index_limb_name(i))] [(I && !I.abstract) ? I : "Empty"]
" + dat += "[capitalize(get_index_limb_name(i))] [makeStrippingButton(I)]
" + + dat += "
Back: [makeStrippingButton(back)]" + + dat += "
" dat += {" -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
[(internal ? text("Remove Internal") : "")] -
Empty Pockets -
Refresh
Close
"} - user << browse(dat, text("window=mob[];size=325x500", name)) - onclose(user, "mob\ref[src]") + var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 325, 500) + popup.set_content(dat) + popup.open() return /mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag) @@ -990,7 +944,7 @@ var/list/slot_equipment_priority = list( \ if(isVentCrawling()) to_chat(src, "Not while we're vent crawling!") return - + var/obj/item/W = get_held_item_by_index(active_hand) if(W) W.attack_self(src) @@ -1543,6 +1497,8 @@ var/list/slot_equipment_priority = list( \ /mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check return 0 +/mob/proc/isGoodPickpocket() //If the mob gets bonuses when pickpocketing and such. Currently only used for humans with the Pickpocket's Gloves. + return 0 /mob/proc/Stun(amount) if(status_flags & CANSTUN) diff --git a/code/modules/power/antimatter/fuel.dm b/code/modules/power/antimatter/fuel.dm index b7caf82adc5..0e12dea51dc 100644 --- a/code/modules/power/antimatter/fuel.dm +++ b/code/modules/power/antimatter/fuel.dm @@ -84,6 +84,7 @@ /obj/item/weapon/fuel/attack(mob/M as mob, mob/user as mob) if (user != M) + //If you come from the distant future and happen to find this unincluded and derelict file, you may be wondering what this is. In truth, it's better that you don't know. var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) O.source = user O.target = M diff --git a/code/setup.dm b/code/setup.dm index df728caf836..cd90bf099eb 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -979,6 +979,11 @@ var/default_colour_matrix = list(1,0,0,0,\ #define EQUIP_FAILACTION_DELETE 1 #define EQUIP_FAILACTION_DROP 2 +//mob_can_equip flags +#define CANNOT_EQUIP 0 +#define CAN_EQUIP 1 +#define CAN_EQUIP_BUT_SLOT_TAKEN 2 + // Vampire power defines #define VAMP_REJUV 1 #define VAMP_GLARE 2 diff --git a/html/changelogs/9600bauds_striprip.yml b/html/changelogs/9600bauds_striprip.yml new file mode 100644 index 00000000000..f02ce883bc7 --- /dev/null +++ b/html/changelogs/9600bauds_striprip.yml @@ -0,0 +1,45 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscdel (general deleting of nice things) +# rscadd (general adding of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: 9600bauds + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# There needs to be a space after the - and before the prefix. Don't use tabs anywhere in this file. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# If you're using characters such as # ' : - or the like in your changelog, surround the entire change with quotes as shown in the second example. These quotes don't show up on the changelog once it's merged and prevent errors. +# SCREW ANY OF THIS UP AND IT WON'T WORK. +changes: +- experiment: "The following changes required a lot of rewriting and refactoring of old-ass code. I've tested this as best as I could, but if you notice any bugs still, please don't hesitate to make a bug report!" +- rscadd: "Trying to put an item in the wrong slot via the stripping menu now gives an explicit error message, so as to not waste your time." +- tweak: "Buffed the Pickpocket's Gloves: Their effects now apply to all storage slots, not just ID and pockets." +- rscadd: "You can now toggle someone's suit sensors via the stripping menu, without having to remove their jumpsuit." +- tweak: "There is now one unified option to toggle other people's internals via the stripping menu, which is available even if they have a tank in their pockets or hands." +- tweak: "Simplified the way toggling internals chooses a tank: It will now simply look in your suit storage, then back, then belt, then pockets, then hands. It will also only take internals from a jetpack as last option." +- bugfix: "Fixed items in your pocket slots not applying their on_found() effects (e.g. mousetraps) when stripped individually, only when your jumpsuit was stripped." +- bugfix: "Fixed items in your pocket slots not applying their on_stripped() effects (e.g. SPS) when your jumpsuit was stripped, only individually." +- rscdel: "Removes the ability to perform CPR on alien larvas. Sorry guys." +- bugfix: "Accidentally fixed bug where you could spam CPR and do CPR multiple times at the same time in the same mob. Sorry guys." \ No newline at end of file diff --git a/vgstation13.dme b/vgstation13.dme index bb178139c9c..c718c56e3f2 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -1271,9 +1271,11 @@ #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\give.dm" +#include "code\modules\mob\living\carbon\internals.dm" #include "code\modules\mob\living\carbon\inventory.dm" #include "code\modules\mob\living\carbon\shock.dm" #include "code\modules\mob\living\carbon\species.dm" +#include "code\modules\mob\living\carbon\stripping.dm" #include "code\modules\mob\living\carbon\update_icons.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" #include "code\modules\mob\living\carbon\alien\death.dm"