Files
vgstation13/code/game/objects/items.dm
MadmanMartian 2910873f88 Pick up verb sanity (#24310)
* The pick up verb now only takes into account objects in your surroundings, rather than an object inside yourself

Also only shows objects that you can actually pick up

* Changes the function names so it's more descriptive

Removes the verb arguments, as they were being abused to instantly pick up tasers apparently

* good lord I almost removed right click-> pick up
2019-10-02 09:26:59 +02:00

1460 lines
48 KiB
Plaintext

/obj/item
name = "item"
icon = 'icons/obj/items.dmi'
var/image/blood_overlay = null //this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
var/abstract = FALSE
var/item_state = null
var/list/inhand_states = list("left_hand" = 'icons/mob/in-hand/left/items_lefthand.dmi', "right_hand" = 'icons/mob/in-hand/right/items_righthand.dmi')
var/r_speed = 1.0
var/health = null
var/hitsound = null
var/armor_penetration = 0 // Chance from 0 to 100 to reduce absorb by one, and then rolls the same value. Check living_defense.dm
var/w_class = W_CLASS_MEDIUM
var/attack_delay = 10 //Delay between attacking with this item, in 1/10s of a second (default = 1 second)
flags = FPRINT
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
var/clothing_flags = 0
var/obj/item/offhand/wielded = null
pass_flags = PASSTABLE
pressure_resistance = 5
// causeerrorheresoifixthis
var/obj/item/master = null
var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags
var/heat_conductivity = 0.5 // how conductive an item is to heat a player (ie how quickly someone will lose heat) on a scale of 0 - 1. - 1 is fully conductive, 0 is fully insulative, this is a range, not binary.
//If this is set, The item will make an action button on the player's HUD when picked up.
//Since any item can now be a piece of clothing, this has to be put here so all items share it.
var/_color = null
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
//var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible
var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets)
var/permeability_coefficient = 1 // for chemicals/diseases
siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) - 0 is not conductive, 1 is conductive - this is a range, not binary
var/slowdown = NO_SLOWDOWN // How much each piece of clothing is slowing you down. Works as a MULTIPLIER, i.e. 0.8 slowdown makes you go 20% faster, 1.5 slowdown makes you go 50% slower.
var/canremove = TRUE //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N
var/cant_drop = FALSE //If 1, can't drop it from hands!
var/cant_drop_msg = " sticks to your hand!"
var/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
var/armor_absorb = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers.
var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
var/list/species_fit = null //This object has a different appearance when worn by these species
var/surgery_speed = 1 //When this item is used as a surgery tool, multiply the delay of the surgery step by this much.
var/nonplant_seed_type
var/list/attack_verb // used in attack() to say how something was attacked "[x] [z.attack_verb] [y] with [z]". Present tense.
var/shrapnel_amount = 0 // How many pieces of shrapnel it disintegrates into.
var/shrapnel_type = null
var/shrapnel_size = 1
var/list/actions = list() //list of /datum/action's that this item has.
var/list/actions_types = list() //list of paths of action datums to give to the item on New().
var/vending_cat = null// subcategory for vending machines.
var/list/dynamic_overlay[0] //For items which need to slightly alter their on-mob appearance while being worn.
var/restraint_resist_time = 0 //When set, allows the item to be applied as restraints, which take this amount of time to resist out of
var/restraint_apply_time = 3 SECONDS
var/restraint_apply_sound = null
var/icon/wear_override = null //Worn state override used when wearing this object on your head/uniform/glasses/etc slot, for making a more procedurally generated icon
var/hides_identity = HIDES_IDENTITY_DEFAULT
var/datum/daemon/daemon
var/list/datum/disease2/disease/virus2 = list()
var/sterility = 0// 0 to 100. increase chances of preventing disease spread.
var/image/pathogen
/obj/item/proc/return_thermal_protection()
return return_cover_protection(body_parts_covered) * (1 - heat_conductivity)
/obj/item/New()
..()
for(var/path in actions_types)
new path(src)
/obj/item/Destroy()
infected_items -= src
if (pathogen)
for (var/mob/L in science_goggles_wearers)
if (L.client)
L.client.images -= pathogen
pathogen = null
if(istype(loc, /mob))
var/mob/H = loc
H.drop_from_inventory(src) // items at the very least get unequipped from their mob before being deleted
if(hasvar(src, "holder"))
src:holder = null
for(var/x in actions)
qdel(x)
/* BROKEN, FUCK BYOND
if(hasvar(src, "my_atom"))
src:my_atom = null*/
..()
/* Species-specific sprite sheets for inventory sprites
Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
*/
//var/list/sprite_sheets_obj = null
/obj/item/device
icon = 'icons/obj/device.dmi'
/obj/item/proc/is_hidden_identity()
switch(hides_identity)
if(HIDES_IDENTITY_ALWAYS)
return TRUE
if(HIDES_IDENTITY_DEFAULT)
return is_slot_hidden(body_parts_covered, HIDEFACE)
/obj/item/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if(3.0)
if (prob(5))
qdel(src)
return
else
return
/obj/item/blob_act()
..()
qdel(src)
/obj/item/Topic(href, href_list)
.=..()
if(href_list["close"])
return
if(usr.incapacitated())
return TRUE
if (!usr.dexterity_check())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return TRUE
if (!in_range(src, usr))
return TRUE
add_fingerprint(usr)
add_hiddenprint(usr)
return FALSE
/obj/item/proc/restock() //used for borg recharging
return
/obj/item/projectile_check()
return PROJREACT_OBJS
//user: The mob that is suiciding
//damagetype: The type of damage the item will inflict on the user
//SUICIDE_ACT_BRUTELOSS = 1
//SUICIDE_ACT_FIRELOSS = 2
//SUICIDE_ACT_TOXLOSS = 4
//SUICIDE_ACT_OXYLOSS = 8
//Output a creative message and then return the damagetype done
/obj/item/proc/suicide_act(mob/user)
return
/obj/item/verb/move_to_top()
set name = "Move To Top"
set category = "Object"
set src in oview(1)
if(!istype(loc, /turf) || usr.isUnconscious() || usr.restrained())
return
var/turf/T = loc
forceMove(null)
forceMove(T)
/obj/item/examine(mob/user, var/size = "", var/show_name = TRUE)
if(!size)
switch(w_class)
if(W_CLASS_TINY)
size = "tiny"
if(W_CLASS_SMALL)
size = "small"
if(W_CLASS_MEDIUM)
size = "normal-sized"
if(W_CLASS_LARGE)
size = "bulky"
if(W_CLASS_HUGE to INFINITY)
size = "huge"
//if (clumsy_check(usr) && prob(50)) t = "funny-looking"
var/pronoun
if (gender == PLURAL)
pronoun = "They are"
else
pronoun = "It is"
size = " [pronoun] a [size] item."
..(user, size, show_name)
if(price && price > 0)
to_chat(user, "You read '[price] space bucks' on the tag.")
if((cant_drop != FALSE) && user.is_holding_item(src)) //Item can't be dropped, and is either in left or right hand!
to_chat(user, "<span class='danger'>It's stuck to your hands!</span>")
if(daemon && daemon.flags & DAEMON_EXAMINE)
daemon.examine(user)
/obj/item/attack_ai(mob/user as mob)
..()
if(isMoMMI(user))
var/in_range = in_range(src, user) || loc == user
if(in_range)
if(src == user:tool_state)
return FALSE
attack_hand(user)
else if(isrobot(user))
if(!istype(loc, /obj/item/weapon/robot_module))
return
var/mob/living/silicon/robot/R = user
R.activate_module(src)
R.hud_used.update_robot_modules_display()
/obj/item/attack_hand(var/mob/user)
if (!user)
return
if (istype(loc, /obj/item/weapon/storage))
//If the item is in a storage item, take it out.
var/obj/item/weapon/storage/S = loc
if(!S.remove_from_storage(src, user))
return
throwing = FALSE
if (loc == user)
if(src == user.get_inactive_hand())
if(flags & TWOHANDABLE)
return wield(user)
if(!user.put_in_hand_check(src, user.get_active_hand()))
return
//canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N
if(!canremove)
return
user.u_equip(src,FALSE)
else
if(isliving(loc))
return
//user.next_move = max(user.next_move+2,world.time + 2)
add_fingerprint(user)
if(can_pickup(user) && !user.put_in_active_hand(src))
forceMove(get_turf(user))
//transfers diseases between the mob and the item
disease_contact(user)
/obj/item/requires_dexterity(mob/user)
return TRUE
/obj/item/attack_paw(mob/user as mob)
if (istype(loc, /obj/item/weapon/storage))
for(var/mob/M in range(1, loc))
if (M.s_active == loc)
if (M.client)
M.client.screen -= src
throwing = FALSE
if (loc == user)
if(!user.put_in_hand_check(src, user.get_active_hand()))
return
//canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N
if(istype(src, /obj/item/clothing) && !src:canremove)
return
else
user.u_equip(src,0)
else
if(istype(loc, /mob/living))
return
//user.next_move = max(user.next_move+2,world.time + 2)
user.put_in_active_hand(src)
return
// Due to storage type consolidation this should get used more now.
// I have cleaned it up a little, but it could probably use more. -Sayu
/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
return ..()
/obj/item/proc/talk_into(var/datum/speech/speech, var/channel=null)
return
/obj/item/proc/moved(mob/user as mob, old_loc as turf)
return
/obj/item/proc/dropped(mob/user as mob)
reset_plane_and_layer()
if(wielded)
unwield(user)
for(var/X in actions)
var/datum/action/A = X
A.Remove(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, 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.
/obj/item/proc/prepickup(mob/user)
return
// called after an item is picked up (loc has already changed)
/obj/item/proc/pickup(mob/user)
return
// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
/obj/item/proc/on_exit_storage(obj/item/weapon/storage/S as obj)
return
// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item.
/obj/item/proc/on_enter_storage(obj/item/weapon/storage/S as obj)
return
// called when "found" in pockets and storage items. Returns 1 if the search should end.
/obj/item/proc/on_found(mob/wearer, mob/finder)
return
// called after an item is placed in an equipment slot
// user is mob that equipped it
// slot uses the slot_X defines found in setup.dm
// for items that can be placed in multiple slots
// note this isn't called during the initial dressing of a player
/obj/item/proc/equipped(var/mob/user, var/slot, hand_index = 0)
if(cant_drop) //Item can't be dropped
if(hand_index) //Item was equipped in a hand slot
to_chat(user, "<span class='notice'>\The [src][cant_drop_msg]</span>")
for(var/X in actions)
var/datum/action/A = X
if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
return
/obj/item/proc/item_action_slot_check(slot, mob/user)
return 1
// called after an item is unequipped or stripped
/obj/item/proc/unequipped(mob/user, var/from_slot = null)
for(var/x in actions)
var/datum/action/A = x
A.Remove(user)
return
//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't.
//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 CANNOT_EQUIP
if(!M)
return CANNOT_EQUIP
if(wielded)
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)
if(!disable_warning)
to_chat(M, "<span class='danger'>It's stuck to your hands!</span>")
return CANNOT_EQUIP
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]!")
if(!(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You're too fat to wear the [name].</span>")
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.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL)) //Use the body's base species
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fit over your bulky exterior!</span>")
return CANNOT_EQUIP
else //Organ's species is different from body
if(OE.species.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fit over your bulky exterior!</span>")
return CANNOT_EQUIP
switch(slot)
if(slot_wear_mask)
if( !(slot_flags & SLOT_MASK) )
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.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL)) //Use the body's base species
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your thick head!</span>")
return CANNOT_EQUIP
else //Organ's species is different from body
if(OE.species.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your thick head!</span>")
return CANNOT_EQUIP
if(H.wear_mask)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.wear_mask.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_back)
if( !(slot_flags & SLOT_BACK) )
return CANNOT_EQUIP
if(H.back)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.back.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_wear_suit)
if( !(slot_flags & SLOT_OCLOTHING) )
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.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL)) //Use the body's base species
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky exterior!</span>")
return CANNOT_EQUIP
else //Organ's species is different from body
if(OE.species.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky exterior!</span>")
return CANNOT_EQUIP
if(H.wear_suit)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.wear_suit.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_gloves)
if( !(slot_flags & SLOT_GLOVES) )
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.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL)) //Use the body's base species
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky fingers!</span>")
return CANNOT_EQUIP
else //Organ's species is different from body
if(OE.species.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky fingers!</span>")
return CANNOT_EQUIP
if(H.gloves)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.gloves.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_shoes)
if( !(slot_flags & SLOT_FEET) )
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.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL)) //Use the body's base species
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky feet!</span>")
return CANNOT_EQUIP
else //Organ's species is different from body
if(OE.species.anatomy_flags & IS_BULKY && !(clothing_flags & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='warning'>You can't get \the [src] to fasten around your bulky feet!</span>")
return CANNOT_EQUIP
if(H.shoes)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.shoes.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_belt)
if(!H.w_uniform)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [name].</span>")
return CANNOT_EQUIP
if( !(slot_flags & SLOT_BELT) )
return CANNOT_EQUIP
if(H.belt)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.belt.canremove && !istype(H.belt, /obj/item/weapon/storage/belt))
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_glasses)
if( !(slot_flags & SLOT_EYES) )
return CANNOT_EQUIP
if(H.glasses)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.glasses.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_head)
if( !(slot_flags & SLOT_HEAD) )
return CANNOT_EQUIP
if(H.head)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.head.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_ears)
if( !(slot_flags & SLOT_EARS) )
return CANNOT_EQUIP
if(H.ears)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.ears.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
/* In case it's ever unfucked.
if(slot_ears)
if( !(slot_flags & SLOT_EARS) )
return CANNOT_EQUIP
if( (slot_flags & SLOT_TWOEARS) && H.r_ear )
return CANNOT_EQUIP
if(H.l_ear)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.l_ear.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
if( w_class < W_CLASS_SMALL )
return CAN_EQUIP
return CAN_EQUIP
if(slot_r_ear)
if( !(slot_flags & SLOT_EARS) )
return CANNOT_EQUIP
if( (slot_flags & SLOT_TWOEARS) && H.l_ear )
return CANNOT_EQUIP
if(H.r_ear)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.r_ear.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
if( w_class < W_CLASS_SMALL )
return CAN_EQUIP
return CAN_EQUIP
*/
if(slot_w_uniform)
if( !(slot_flags & SLOT_ICLOTHING) )
return CANNOT_EQUIP
if(H.w_uniform)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.w_uniform.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_wear_id)
if(!H.w_uniform)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [name].</span>")
return CANNOT_EQUIP
if( !(slot_flags & SLOT_ID) )
return CANNOT_EQUIP
if(H.wear_id)
if(automatic)
if(H.check_for_open_slot(src))
return CANNOT_EQUIP
if(H.wear_id.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_l_store)
if(!H.w_uniform)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [name].</span>")
return CANNOT_EQUIP
if(slot_flags & SLOT_DENYPOCKET)
return
if(automatic)
if(H.l_store)
return CANNOT_EQUIP
else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) )
return CAN_EQUIP
else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) )
if(H.l_store)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CAN_EQUIP
if(slot_r_store)
if(!H.w_uniform)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [name].</span>")
return CANNOT_EQUIP
if(slot_flags & SLOT_DENYPOCKET)
return
if(automatic)
if(H.r_store)
return CANNOT_EQUIP
else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) )
return CAN_EQUIP
else if( w_class <= W_CLASS_SMALL || (slot_flags & SLOT_POCKET) )
if(H.r_store)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CAN_EQUIP
if(slot_s_store)
if(!H.wear_suit)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a suit before you can attach this [name].</span>")
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 CANNOT_EQUIP
if(w_class > W_CLASS_MEDIUM && !H.wear_suit.allowed.len)
if(!disable_warning)
to_chat(usr, "The [name] is too big to attach.")
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 CANNOT_EQUIP
if(H.s_store.canremove)
return CAN_EQUIP_BUT_SLOT_TAKEN
else
return CANNOT_EQUIP
else
return CAN_EQUIP
return CANNOT_EQUIP
if(slot_handcuffed)
if(H.handcuffed)
return CANNOT_EQUIP
if (H.mutual_handcuffs)
return CANNOT_EQUIP
if(!istype(src, /obj/item/weapon/handcuffs))
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_legcuffed)
if(H.legcuffed)
return CANNOT_EQUIP
if(!istype(src, /obj/item/weapon/legcuffs))
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.storage_slots && w_class <= B.fits_max_w_class)
return CAN_EQUIP
if(B.contents.len < B.storage_slots && w_class <= B.fits_max_w_class)
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.canWearMasks)
return CANNOT_EQUIP
if(MO.wear_mask)
return CANNOT_EQUIP
if( !(slot_flags & SLOT_MASK) )
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.canWearBack)
return CANNOT_EQUIP
if(MO.back)
return CANNOT_EQUIP
if( !(slot_flags & SLOT_BACK) )
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)
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(ishologram(M))
//START HOLOGRAM
var/mob/living/simple_animal/hologram/advanced/HM = M
switch(slot)
if(slot_head)
if(HM.head)
return CANNOT_EQUIP
if(!(slot_flags & SLOT_HEAD) )
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_w_uniform)
if(HM.w_uniform)
return CANNOT_EQUIP
if(!(slot_flags & SLOT_ICLOTHING) )
return CANNOT_EQUIP
return CAN_EQUIP
if(slot_wear_suit)
if(HM.wear_suit)
return CANNOT_EQUIP
if(!(slot_flags & SLOT_OCLOTHING) )
return CANNOT_EQUIP
return CAN_EQUIP
return CANNOT_EQUIP //Unsupported slot
//END HOLOGRAM
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 CANNOT_EQUIP
return CAN_EQUIP
return CANNOT_EQUIP //Unsupported slot
//END MOMMI
else if(ismartian(M))
//why
var/mob/living/carbon/complex/martian/MA = M
switch(slot)
if(slot_head)
if(MA.head)
return CANNOT_EQUIP
return CAN_EQUIP
return CANNOT_EQUIP
else if(isgrinch(M))
//START GRINCH
var/mob/living/simple_animal/hostile/gremlin/grinch/G = M
switch(slot)
if(slot_back)
if(G.back)
return CANNOT_EQUIP
if(!(slot_flags & SLOT_BACK) )
return CANNOT_EQUIP
return CAN_EQUIP
return CANNOT_EQUIP //Unsupported slot
//END GRINCH
/obj/item/can_pickup(mob/living/user, var/actually_picking_up = TRUE, var/silent = FALSE)
if(!(user) || !isliving(user)) //BS12 EDIT
return FALSE
if(actually_picking_up && prepickup(user))
return FALSE
if(user.incapacitated() || !Adjacent(user))
return FALSE
if((!iscarbon(user) && !isMoMMI(user)) && !ishologram(user) && !isgrinch(user) || isbrain(user)) //Is not a carbon being, MoMMI, advanced hologram, or is a brain
if(!silent)
to_chat(user, "You can't pick things up!")
return FALSE
if(anchored) //Object isn't anchored
if(!silent)
to_chat(user, "<span class='warning'>You can't pick that up!</span>")
return FALSE
if(!istype(loc, /turf) && !is_holder_of(user, src)) //Object is not on a turf
if(!silent)
to_chat(user, "<span class='warning'>You can't pick that up!</span>")
return FALSE
return TRUE
/obj/item/verb_pickup(mob/living/user)
//set src in oview(1)
//set category = "Object"
//set name = "Pick up"
if(!can_pickup(user))
return FALSE
if(user.get_active_hand())
to_chat(user, "<span class='warning'>Your [user.get_index_limb_name(user.active_hand)] is full.</span>")
return
//All checks are done, time to pick it up!
if(isMoMMI(user))
// Otherwise, we get MoMMIs changing their own laws.
if(istype(src,/obj/item/weapon/aiModule))
to_chat(src, "<span class='warning'>Your firmware prevents you from picking up [src]!</span>")
return
if(user.get_active_hand() == null)
user.put_in_hands(src)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/h_user = user
if(h_user.can_use_hand())
attack_hand(h_user)
else
attack_stump(h_user)
if(istype(user, /mob/living/carbon/alien))
attack_alien(user)
if(istype(user, /mob/living/carbon/monkey))
attack_paw(user)
return
//Used in twohanding
/obj/item/proc/wield(mob/user, var/inactive = FALSE)
if(!user.can_wield(src))
user.show_message("You can't wield \the [src] as it's too heavy.")
return
if(!wielded)
wielded = getFromPool(/obj/item/offhand)
//Long line ahead, let's break that up!
//
//((user.get_active_hand() in list(null, src)) && user.put_in_inactive_hand(wielded))
//By default this proc assumes that the wielded item is held in the ACTIVE hand!
//(user.get_active_hand() in list(null, src)) is the part which checks whether the ACTIVE hand is either nothing, or the wielded item. Otherwise, abort!
//The second half is the same, except that the proc assumes that the wielded item is held in the INACTIVE hand. So the INACTIVE hand is checked for holding either nothing or wielded item.
//if(((user.get_active_hand() in list(null, src)) && user.put_in_inactive_hand(wielded)) || (!inactive && ((user.get_inactive_hand() in list(null, src)) && user.put_in_active_hand(wielded))))
for(var/i = TRUE to user.held_items.len)
if(user.held_items[i])
continue
if(user.active_hand == i)
continue
if(user.put_in_hand(i, wielded))
wielded.attach_to(src)
update_wield(user)
return TRUE
unwield(user)
return
/obj/item/proc/unwield(mob/user)
if(flags & MUSTTWOHAND && src in user)
user.drop_from_inventory(src)
if(istype(wielded))
wielded.wielding = null
user.u_equip(wielded,1)
if(wielded)
returnToPool(wielded)
wielded = null
update_wield(user)
/obj/item/proc/update_wield(mob/user)
/obj/item/proc/IsShield()
return FALSE
//Called when the item blocks an attack. Return 1 to stop the hit, return 0 to let the hit go through
/obj/item/proc/on_block(damage, atom/movable/blocked)
if(ismob(loc))
if (IsShield() < blocked.ignore_blocking)
return FALSE
if (prob(50 - round(damage / 3)))
visible_message("<span class='borange'>[loc] blocks \the [blocked] with \the [src]!</span>")
if(isatommovable(blocked))
var/atom/movable/M = blocked
M.throwing = FALSE
return TRUE
return FALSE
/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/eye_protection = H.get_body_part_coverage(EYES)
if(eye_protection)
to_chat(user, "<span class='warning'>You're going to need to remove that [eye_protection] first.</span>")
return
var/mob/living/carbon/monkey/Mo = M
if(istype(Mo) && ( \
(Mo.wear_mask && Mo.wear_mask.body_parts_covered & EYES) \
))
// you can't stab someone in the eyes wearing a mask!
to_chat(user, "<span class='warning'>You're going to need to remove that mask first.</span>")
return
if(!M.has_eyes())
to_chat(user, "<span class='warning'>You cannot locate any eyes on [M]!</span>")
return
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)])</font>"
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)])</font>"
msg_admin_attack("ATTACK: [user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)])") //BS12 EDIT ALG
log_attack("<font color='red'> [user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)])</font>")
if(!iscarbon(user))
M.LAssailant = null
else
M.LAssailant = user
add_fingerprint(user)
//if(clumsy_check(user) && prob(50))
// M = user
/*
to_chat(M, "<span class='warning'>You stab yourself in the eye.</span>")
M.sdisabilities |= BLIND
M.AdjustKnockdown(4)
M.adjustBruteLoss(10)
*/
if(istype(M, /mob/living/carbon/human))
var/datum/organ/internal/eyes/eyes = H.internal_organs_by_name["eyes"]
if(M != user)
user.do_attack_animation(M, src)
for(var/mob/O in (viewers(M) - user - M))
O.show_message("<span class='danger'>[user] stabs [M] in the eye with \the [src].</span>", 1)
to_chat(M, "<span class='userdanger'>[user] stabs you in the eye with \the [src]!</span>")
to_chat(user, "<span class='attack'>You stab [M] in the eye with \the [src]!</span>")
else
user.visible_message( \
"<span class='attack'>[user] stabs themself with \the [src]!</span>", \
"<span class='userdanger'>You stab yourself in the eyes with \the [src]!</span>" \
)
eyes.damage += rand(3,4)
if(eyes.damage >= eyes.min_bruised_damage)
if(M.stat != 2)
if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly
to_chat(M, "<span class='warning'>Your eyes start to bleed profusely!</span>")
if(prob(50))
if(M.stat != 2)
to_chat(M, "<span class='warning'>You drop what you're holding and clutch at your eyes!</span>")
M.drop_item()
M.eye_blurry += 10
M.Paralyse(1)
M.Knockdown(4)
M.Stun(4)
if (eyes.damage >= eyes.min_broken_damage)
if(M.stat != 2)
to_chat(M, "<span class='warning'>You go blind!</span>")
var/datum/organ/external/affecting = M:get_organ(LIMB_HEAD)
if(affecting.take_damage(7))
M:UpdateDamageIcon(1)
else
M.take_organ_damage(7)
M.eye_blurry += rand(3,4)
return
/obj/item/clean_blood()
. = ..()
remove_disease2()
if (blood_overlay)
overlays.Remove(blood_overlay)
if (had_blood)
clear_luminol()
if (istype(src, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = src
G.transfer_blood = 0
/obj/item/add_blood(var/mob/living/carbon/human/M)
if (!..())
return FALSE
if(istype(src, /obj/item/weapon/melee/energy))
return
//if we haven't made our blood_overlay already
if(!blood_overlays[type])
generate_blood_overlay()
if(!blood_overlay)
blood_overlay = blood_overlays[type]
else
overlays.Remove(blood_overlay)
//apply the blood-splatter overlay if it isn't already in there, else it updates it.
blood_overlay.color = blood_color
overlays += blood_overlay
//if this blood isn't already in the list, add it
if(!M)
return
if (M.virus2?.len)
var/list/blood_diseases = filter_disease_by_spread(M.virus2,required = SPREAD_BLOOD)
if (blood_diseases?.len)
for (var/ID in blood_diseases)
var/datum/disease2/disease/D = blood_diseases[ID]
infect_disease2(D, notes="(Blood, coming from [M])")
if (isliving(loc))
var/mob/living/L = loc
infection_attempt(L,D)//Wear gloves when doing surgery or beating that catbeast to death!
if(blood_DNA[M.dna.unique_enzymes])
return FALSE //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
had_blood = TRUE
return TRUE //we applied blood to the item
var/global/list/image/blood_overlays = list()
/obj/item/proc/generate_blood_overlay()
if(blood_overlays[type])
return
var/icon/I = new /icon(icon, icon_state)
I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD) //fills the icon_state with white (except where it's transparent)
I.Blend(new /icon('icons/effects/blood.dmi', "itemblood"),ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
blood_overlays[type] = image(I)
/obj/item/apply_luminol()
if(!..())
return FALSE
if(!blood_overlays[type]) //Blood overlay generation if it lacks one.
generate_blood_overlay()
if(blood_overlay)
overlays.Remove(blood_overlay)
else
blood_overlay = blood_overlays[type]
var/image/luminol_overlay = blood_overlay
luminol_overlay.color = LIGHT_COLOR_CYAN
overlays += luminol_overlay
var/obj/effect/decal/cleanable/blueglow/BG
if(istype(had_blood,/obj/effect/decal/cleanable/blueglow))
BG = had_blood
BG.set_light(1,2,LIGHT_COLOR_BLUE)
else
had_blood = null
BG = new /obj/effect/decal/cleanable/blueglow(src)
had_blood = BG
/obj/item/clear_luminol()
if(!..())
return FALSE
if(istype(had_blood,/obj/effect/decal/cleanable/blueglow))
var/obj/effect/decal/cleanable/blueglow/BG
BG = had_blood
BG.set_light(0)
/obj/item/proc/showoff(mob/user)
if(abstract)
return
for (var/mob/M in view(user))
M.show_message("[user] holds up [src]. <a HREF='?src=\ref[M];lookitem=\ref[src]'>Take a closer look.</a>",1)
/mob/living/carbon/verb/showoff()
set name = "Show Held Item"
set category = "Object"
if(attack_delayer.blocked())
return
delayNextAttack(SHOW_HELD_ITEM_AND_POINTING_DELAY)
var/obj/item/I = get_active_hand()
if(I)
I.showoff(src)
// /vg/ Affects wearers.
/obj/item/proc/OnMobLife(var/mob/holder)
return
/obj/item/proc/OnMobDeath(var/mob/holder)
return
//handling the pulling of the item for singularity
/obj/item/singularity_pull(S, current_size)
if(flags & INVULNERABLE)
return
spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(anchored)
if(current_size >= STAGE_FIVE)
anchored = FALSE
else
return
if(current_size >= STAGE_FOUR)
//throw_at(S, 14, 3)
step_towards(src,S)
sleep(1)
step_towards(src,S)
else if(current_size > STAGE_ONE)
step_towards(src,S)
else
..()
//Gets the rating of the item, used in stuff like machine construction.
/obj/item/proc/get_rating()
return FALSE
// Like the above, but used for RPED sorting of parts.
/obj/item/proc/rped_rating()
return get_rating()
/obj/item/kick_act(mob/living/carbon/human/H) //Kick items around!
if(anchored || w_class > W_CLASS_MEDIUM + H.get_strength())
H.visible_message("<span class='danger'>[H] attempts to kick \the [src]!</span>", "<span class='danger'>You attempt to kick \the [src]!</span>")
if(prob(70))
to_chat(H, "<span class='danger'>Dumb move! You strain a muscle.</span>")
H.apply_damage(rand(1,4), BRUTE, pick(LIMB_RIGHT_LEG, LIMB_LEFT_LEG, LIMB_RIGHT_FOOT, LIMB_LEFT_FOOT))
return
var/kick_dir = get_dir(H, src)
if(H.loc == loc)
kick_dir = H.dir
var/turf/T = get_edge_target_turf(loc, kick_dir)
var/kick_power = max((H.get_strength() * 10 - (w_class ** 2)), 1) //The range of the kick is (strength)*10. Strength ranges from 1 to 3, depending on the kicker's genes. Range is reduced by w_class^2, and can't be reduced below 1.
H.visible_message("<span class='danger'>[H] kicks \the [src]!</span>", "<span class='danger'>You kick \the [src]!</span>")
if(kick_power > 6) //Fly in an arc!
spawn()
var/original_pixel_y = pixel_y
animate(src, pixel_y = original_pixel_y + WORLD_ICON_SIZE, time = 10, easing = CUBIC_EASING)
while(loc)
if(!throwing)
animate(src, pixel_y = original_pixel_y, time = 5, easing = ELASTIC_EASING)
break
sleep(5)
Crossed(H) //So you can't kick shards while naked without suffering
throw_at(T, kick_power, 1)
/obj/item/animationBolt(var/mob/firer)
new /mob/living/simple_animal/hostile/mimic/copy(loc, src, firer, duration=SPELL_ANIMATION_TTL)
/obj/item/proc/is_worn(mob/user)
var/mob/living/carbon/monkey/Mo = user
var/mob/living/carbon/human/H = user
if(!istype(H) && !istype(Mo))
return FALSE
var/mob/M = user
for(var/bit = 0 to 15)
bit = 1 << bit
if(bit & slot_flags)
if(M.get_item_by_flag(bit) == src)
return TRUE
/obj/item/proc/get_shrapnel_projectile()
if(shrapnel_type)
return new shrapnel_type(src)
else
return FALSE
// IMPORTANT DISTINCTION FROM MouseWheel:
// This one gets called when the player scrolls his mouse while this is in their active hand!
/obj/item/proc/MouseWheeled(var/mob/user, var/delta_x, var/delta_y, var/params)
return
/obj/item/send_to_past(var/duration)
..()
var/static/list/resettable_vars = list(
"health",
"canremove",
"cant_drop")
reset_vars_after_duration(resettable_vars, duration)
spawn(duration + 1)
hud_layerise()
/obj/item/proc/restraint_apply_intent_check(mob/user)
if(user.a_intent == I_GRAB)
return TRUE
/obj/item/proc/restraint_apply_check(mob/living/carbon/M, mob/user)
if(!istype(M))
return
if(!restraint_apply_intent_check(user))
return
if(!user.dexterity_check())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(M.handcuffed)
return
M.attack_log += text("\[[time_stamp()]] <span style='color: orange'>Has been restrained (attempt) by [user.name] ([user.ckey]) with \the [src].</span>")
user.attack_log += text("\[[time_stamp()]] <span style='color: red'>Attempted to restrain [M.name] ([M.ckey]) with \the [src].</span>")
if(!iscarbon(user))
M.LAssailant = null
else
M.LAssailant = user
log_attack("[user.name] ([user.ckey]) Attempted to restrain [M.name] ([M.ckey]) with \the [src].")
return TRUE
/obj/item/proc/attempt_apply_restraints(mob/living/carbon/C, mob/user)
if(!istype(C)) //Sanity doesn't hurt, right ?
return FALSE
if(ishuman(C))
var/mob/living/carbon/human/H = C
if (!H.has_organ_for_slot(slot_handcuffed))
to_chat(user, "<span class='danger'>\The [C] needs at least two wrists before you can cuff them together!</span>")
return FALSE
if(restraint_apply_sound)
playsound(src, restraint_apply_sound, 30, 1, -2)
user.visible_message("<span class='danger'>[user] is trying to restrain \the [C] with \the [src]!</span>",
"<span class='danger'>You try to restrain \the [C] with \the [src]!</span>")
if(do_after(user, C, restraint_apply_time))
if(C.handcuffed || C.mutual_handcuffs)
to_chat(user, "<span class='notice'>\The [C] is already handcuffed.</span>")
return FALSE
feedback_add_details("handcuffs", "[name]")
if(clumsy_check(user) && prob(50))
to_chat(user, "<span class='warning'>Uh... how is this done?!</span>")
C = user
user.visible_message("<span class='danger'>\The [user] has restrained \the [C] with \the [src]!</span>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has restrained [C.name] ([C.ckey]) with \the [src].</font>")
C.attack_log += text("\[[time_stamp()]\] <font color='red'>Restrained with \the [src] by [user.name] ([user.ckey])</font>")
log_attack("[user.name] ([user.ckey]) has restrained [C.name] ([C.ckey]) with \the [src]")
var/obj/item/cuffs = src
if(istype(src, /obj/item/weapon/handcuffs/cyborg)) //There's GOT to be a better way to check for this.
cuffs = new /obj/item/weapon/handcuffs/cyborg(get_turf(user))
else
user.drop_from_inventory(cuffs)
C.equip_to_slot(cuffs, slot_handcuffed)
cuffs.on_restraint_apply(C)
return TRUE
/obj/item/proc/on_restraint_removal(var/mob/living/carbon/C) //Needed for syndicuffs
return
/obj/item/proc/on_restraint_apply(var/mob/living/carbon/C)
return
//Called when user clicks on an object while looking through a camera (passed to the proc as [eye])
/obj/item/proc/remote_attack(atom/target, mob/user, atom/movable/eye)
return
/obj/item/proc/recyclable() //Called by RnD machines, for added object-specific sanity.
return TRUE
/obj/item/proc/on_mousedrop_to_inventory_slot()
return
/obj/item/proc/can_be_stored(var/obj/item/weapon/storage/S)
return TRUE
/obj/item/MouseDropFrom(var/obj/over_object)
if(istype(loc, /obj/item/weapon/storage) && !usr.incapacitated()) //This is the code for re-ordering items inside a storage item via mouse drag and drop.
if(loc == over_object.loc) //Swapping to another object in the same storage item
var/obj/item/weapon/storage/storageobj = loc
if(usr in storageobj.is_seeing)
//Almost none of BYOND's list procs work with contents because contents is a snowflake list and BYOND hates you, so enter the kludge.
//And yes, this is Lummox-sanctioned kludge: http://www.byond.com/forum/?post=271125
var/temp_index = storageobj.contents.Find(over_object)
var/list/temp_contents = storageobj.contents.Copy()
temp_contents -= src
temp_contents.Insert(temp_index, src)
storageobj.contents = temp_contents
storageobj.orient2hud(usr)
return
else if(istype(over_object, /obj/abstract/screen/storage)) //Drag and dropped to an empty slot inside the storage item
//Since contents are always ordered to the left we assume the user wants to move this item to the rightmost slot possible.
var/obj/abstract/screen/storage/screenobj = over_object
var/obj/item/weapon/storage/storageobj = screenobj.master
if(storageobj == loc && usr in storageobj.is_seeing)
//If anybody knows a better way to move ourselves to the end of a list, that actually works with BYOND's finickity handling of the contents list, then you are a greater man than I
storageobj.contents -= src
storageobj.contents += src
storageobj.orient2hud(usr)
return
if(!istype(over_object, /obj/abstract/screen/inventory))
return ..()
if(!ishuman(usr) && !ismonkey(usr))
return ..()
if(!usr.is_wearing_item(src) || !canremove)
return ..()
if(usr.incapacitated())
return ..()
var/obj/abstract/screen/inventory/OI = over_object
on_mousedrop_to_inventory_slot()
if(OI.hand_index && usr.put_in_hand_check(src, OI.hand_index) && !src.prepickup(usr))
usr.u_equip(src, TRUE)
usr.put_in_hand(OI.hand_index, src)
add_fingerprint(usr)
/obj/item/proc/pre_throw()
return
/**
Attempt to heat this object from a presumed heat source.
@args:
A: Atom: The source of the heat
user: mob: Whomever may be trying to heat this object
@return:
TRUE if succesful
FALSE if not succesful
NULL if override not defined
**/
/obj/item/proc/attempt_heating(atom/A, mob/user)
return
/obj/item/proc/recharger_process(var/obj/machinery/recharger/charger)
return
/obj/item/proc/is_screwdriver(var/mob/user)
return FALSE
//This proc will be called when the person holding or equipping it talks.
/obj/item/proc/affect_speech(var/datum/speech/speech, var/mob/living/L)
return
/////// DISEASE STUFF //////////////////////////////////////////////////////////////////////////
/obj/item/clothing/suitable_colony()
return pressure_resistance > ONE_ATMOSPHERE
//Called by attack_hand(), transfers diseases between the mob and the item
/obj/item/proc/disease_contact(var/mob/living/M,var/bodypart = null)
//first let's try to infect them with our viruses
for (var/ID in virus2)
var/datum/disease2/disease/D = virus2[ID]
infection_attempt(M,D,bodypart)
if (!bodypart)//no bodypart specified? that should mean we're being held.
bodypart = HANDS
//secondly, do they happen to carry contact-spreading viruses themselves?
var/list/contact_diseases = filter_disease_by_spread(M.virus2,required = SPREAD_CONTACT | SPREAD_COLONY)
if (contact_diseases?.len)
//if so are their hands protected?
var/block = M.check_contact_sterility(bodypart)
for (var/ID in contact_diseases)
var/datum/disease2/disease/D = contact_diseases[ID]
if(attempt_colony(src,D,"from being touched by [M]"))
else if(!block)
infect_disease2(D, notes="(Contact, from being touched by [M])")
//spreading of blood-spreading diseases to items is handled by add_blood()
//Called by disease_contact(), trying to infect people who pick us up
/obj/item/proc/infection_attempt(var/mob/living/perp,var/datum/disease2/disease/D,var/bodypart = null)
if (!istype(D))
return
if(attempt_colony(perp,D,"from picking up \a [src]"))
return
if (src in perp.held_items)
bodypart = HANDS
if (bodypart)
var/block = perp.check_contact_sterility(bodypart)
var/bleeding = perp.check_bodypart_bleeding(bodypart)
if (!block)
if (D.spread & SPREAD_CONTACT)
perp.infect_disease2(D, notes="(Contact, from picking up \a [src])")
else if (bleeding && (D.spread & SPREAD_BLOOD))//if we're covered with a blood-spreading disease, we may infect people with bleeding hands.
perp.infect_disease2(D, notes="(Blood, from picking up \a [src])")