/obj/item name = "item" icon = 'icons/obj/items.dmi' var/icon_old = null var/uses_multiple_icon_states = 0 var/abstract = 0.0 var/force = null var/item_state = null var/damtype = "brute" var/hit_type = DAMAGE_BLUNT // for bleeding system things, options: DAMAGE_BLUNT, DAMAGE_CUT, DAMAGE_STAB in order of how much it affects the chances to increase bleeding throwforce = 1//4 var/r_speed = 1.0 var/health = 4 // burn faster var/burn_point = 15000 // this already exists but nothing uses it??? var/burn_possible = 1 //cogwerks fire project - can object catch on fire - let's have all sorts of shit burn at hellish temps //MBC : im shit. change burn_possible to '2' if you want it to pool itself instead of qdeling when burned var/burn_output = 1500 //how hot should it burn var/burn_type = 0 // 0 = ash, 1 = melt var/burning = null var/burning_last_process = 0 var/hitsound = 'sound/impact_sounds/Generic_Hit_1.ogg' var/w_class = 3.0 // how big they are, determines if they can fit in backpacks and pockets and the like p_class = 1.5 // how hard they are to pull around, determines how much something slows you down while pulling it var/cant_self_remove = 0 //Can't remove from non-hand slots var/cant_other_remove = 0 //Can't be removed from non-hand slots by others var/cant_drop = 0 //Cant' be removed in general. I guess. flags = FPRINT | TABLEPASS var/tool_flags = 0 var/c_flags = null pressure_resistance = 50 var/obj/item/master = null var/amount = 1 var/max_stack = 1 var/stack_type = null // if null, only current type. otherwise uses this var/contraband = 0 //If nonzero, bots consider this a thing people shouldn't be carrying without authorization var/hide_attack = 0 //If 1, hide the attack animation + particles. Used for hiding attacks with silenced .22 and sleepy pen //If 2, play the attack animation but hide the attack particles. var/needOnMouseMove = 0 //If 1, we check all the stuff required for onMouseMove for this. Leave this off unless required. Might cause extra lag. var/image/wear_image = null var/wear_image_icon = 'icons/mob/belt.dmi' var/image/inhand_image = null var/inhand_image_icon = 'icons/mob/inhand/hand_general.dmi' var/arm_icon = "" //set to an icon state in human.dmi minus _s/_l and l_arm_/r_arm_ to allow use as an arm var/over_clothes = 0 //draw over clothes when used as a limb var/override_attack_hand = 1 //when used as an arm, attack with item rather than using attack_hand var/can_hold_items = 0 //when used as an arm, can it hold things? var/stamina_damage = STAMINA_ITEM_DMG //amount of stamina removed from target per hit. var/stamina_cost = STAMINA_ITEM_COST //amount of stamina removed from USER per hit. This cant bring you below 10 points and you will not be able to attack if it would. var/stamina_crit_chance = STAMINA_CRIT_CHANCE //Crit chance when attacking with this. var/list/module_research = null//list() var/module_research_type = null var/module_research_no_diminish = 0 var/edible = 0 // can you eat the thing? var/duration_put = -1 //If set to something other than -1 these will control var/duration_remove = -1 //how long it takes to remove or put the item onto a person. 1/10ths of a second. var/rand_pos = 0 var/useInnerItem = 0 //Should this item use a contained item (in contents) to attack with instead? var/obj/item/holding = null var/two_handed = 0 //Requires both hands. Do not change while equipped. Use proc for that (TBI) var/click_delay = DEFAULT_CLICK_DELAY //Delay before next click after using this. var/combat_click_delay = COMBAT_CLICK_DELAY var/showTooltip = 1 var/showTooltipDesc = 1 var/rarity = ITEM_RARITY_COMMON //Just a little thing to indicate item rarity. RPG fluff. var/datum/item_special/special = null //Contains the datum which executes the items special, if it has one, when used beyond melee range. var/pickup_sfx = 0 //if null, we auto-pick from a list based on w_class var/can_disarm = 0 var/block_hearing_when_worn = HEARING_NORMAL //fuck me mbc why you do this | | ok i did it to reduce type checking in a proc that gets called A LOT and idk what else to do ok help var/obj/item/grab/chokehold = null var/obj/item/grab/special_grab = null proc/setTwoHanded(var/twohanded = 1) //This is the safe way of changing 2-handed-ness at runtime. Use this please. if(ismob(src.loc)) var/mob/L = src.loc return L.updateTwoHanded(src, twohanded) else two_handed = twohanded return 1 proc/buildTooltipContent() var/Tcontent = "" if(showTooltipDesc) Tcontent += capitalize(src.desc) var/extra = src.get_desc(get_dist(src, usr), usr) if(extra) Tcontent += "
" + extra Tcontent += "
" if(rarity >= 4) Tcontent += "
Rare item
" Tcontent += "
Damage: [src.force ? src.force : "0"] dmg, [src.stamina_damage ? src.stamina_damage : "0"] stam, [round((1 / (src.click_delay / 10)), 0.1)] atk/s, [round((1 / (max(src.click_delay,src.combat_click_delay) / 10))*(src.force ? src.force : "0"), 0.1)] DPS
" if(src.properties && src.properties.len) for(var/datum/objectProperty/P in src.properties) Tcontent += "
[P.name]: [P.getTooltipDesc(src, src.properties[P])]" if(special && !istype(special, /datum/item_special/simple)) var/content = resource("images/tooltips/[special.image].png") Tcontent += "

[special.name]: [special.getDesc()]
" return Tcontent MouseEntered(location, control, params) if (showTooltip && usr.client.tooltipHolder) var/show = 1 //If user has tooltips to always show, and the item is in world, and alt key is NOT pressed, deny if (usr.client.preferences.tooltip_option == TOOLTIP_ALWAYS && !(ismob(src.loc) || (src.loc && src.loc.loc && ismob(src.loc.loc))) && !usr.client.check_key(KEY_EXAMINE)) show = 0 var/title = "" if(rarity >= 7) title = "[capitalize(src.name)]" else title = "[capitalize(src.name)]" if(show) var/list/tooltipParams = list( "params" = params, "title" = title, "content" = buildTooltipContent(), "theme" = usr.client.preferences.hud_style == "New" ? "newhud" : "item" ) //If we're over an item that's stored in a container the user has equipped if (istype(src.loc, /obj/item/storage) && src.loc.loc == usr) tooltipParams["flags"] = TOOLTIP_RIGHT usr.client.tooltipHolder.showHover(src, tooltipParams) MouseExited() if(showTooltip && usr.client.tooltipHolder) usr.client.tooltipHolder.hideHover() onMaterialChanged() ..() if (istype(src.material)) force = material.hasProperty("hard") ? force + round(material.getProperty("hard") / 20) : force burn_possible = src.material.getProperty("flammable") > 50 ? 1 : 0 if (src.material.material_flags & MATERIAL_METAL || src.material.material_flags & MATERIAL_CRYSTAL || src.material.material_flags & MATERIAL_RUBBER) burn_type = 1 else burn_type = 0 return /obj/item/New() // this is dumb but it won't let me initialize vars to image() for some reason wear_image = image(wear_image_icon) wear_image.icon_state = icon_state //Why was this null until someone actually wore it? Made manipulation impossible. inhand_image = image(inhand_image_icon) if (src.rand_pos) if (!src.pixel_x) // just in case src.pixel_x = rand(-8,8) if (!src.pixel_y) // same as above src.pixel_y = rand(-8,8) src.setItemSpecial(/datum/item_special/simple) ..() /obj/item/unpooled() ..() src.amount = 1 if (src.burning) if (src.burn_output >= 1000) src.overlays -= image('icons/effects/fire.dmi', "2old") else src.overlays -= image('icons/effects/fire.dmi', "1old") src.burning = 0 /obj/item/pooled() src.amount = 0 src.health = initial(src.health) if (src.burning) if (src.burn_output >= 1000) src.overlays -= image('icons/effects/fire.dmi', "2old") else src.overlays -= image('icons/effects/fire.dmi', "1old") src.burning = 0 if (ismob(src.loc)) var/mob/M = src.loc M.u_equip(src) ..() /obj/item/set_loc(var/newloc as turf|mob|obj in world) if (src.temp_flags & IS_LIMB_ITEM) if (istype(newloc,/obj/item/parts/human_parts/arm/left/item) || istype(newloc,/obj/item/parts/human_parts/arm/right/item)) ..() else return else ..() /obj/item/proc/onMouseDrag(src_object,over_object,src_location,over_location,src_control,over_control,params) if(special) if(istype(usr, /mob/living/carbon/human)) var/mob/living/carbon/human/H = usr if(H.in_throw_mode) return special.onMouseDrag(src_object,over_object,src_location,over_location,src_control,over_control,params) return /obj/item/proc/onMouseDown(atom/target,location,control,params) if(special) if(istype(usr, /mob/living/carbon/human)) var/mob/living/carbon/human/H = usr if(H.in_throw_mode) return special.onMouseDown(target,location,control,params) return /obj/item/proc/onMouseUp(atom/target,location,control,params) if(special) if(istype(usr, /mob/living/carbon/human)) var/mob/living/carbon/human/H = usr if(H.in_throw_mode) return special.onMouseUp(target,location,control,params) return /obj/item/pixelaction(atom/target, params, mob/user, reach) if(special && !reach) special.pixelaction(target,params,user,reach) return 1 ..() //disgusting proc. merge with foods later. PLEASE /obj/item/proc/Eat(var/mob/M as mob, var/mob/user) if (!src.edible && !(src.material && src.material.edible)) return 0 if (!iscarbon(M) && !iscritter(M)) return 0 if (M == user) M.visible_message("[M] takes a bite of [src]!",\ "You take a bite of [src]!") if (src.material && src.material.edible) src.material.triggerEat(M, src) if (src.reagents && src.reagents.total_volume) src.reagents.reaction(M, INGEST) SPAWN_DBG (5) // Necessary. src.reagents.trans_to(M, src.reagents.total_volume/src.amount) playsound(M.loc,"sound/items/eatfood.ogg", rand(10, 50), 1) SPAWN_DBG (10) if (!src || !M || !user) return 0 // Why not, I guess. Adds a bit of flavour (Convair880). if (iswerewolf(M) && istype(src, /obj/item/organ/)) M.show_text("Mmmmm, tasty organs. How refreshing.", "blue") M.HealDamage("All", 5, 5) M.visible_message("[M] finishes eating [src].",\ "You finish eating [src].") user.u_equip(src) qdel(src) return 1 else user.tri_message("[user] tries to feed [M] [src]!",\ user, "You try to feed [M] [src]!",\ M, "[user] tries to feed you [src]!") logTheThing("combat", user, M, "attempts to feed %target% [src] [log_reagents(src)]") if (!do_mob(user, M)) return 0 if (get_dist(user,M) > 1) return 0 user.tri_message("[user] feeds [M] [src]!",\ user, "You feed [M] [src]!",\ M, "[user] feeds you [src]!") logTheThing("combat", user, M, "feeds %target% [src] [log_reagents(src)]") if (src.material && src.material.edible) src.material.triggerEat(M, src) if (src.reagents && src.reagents.total_volume) src.reagents.reaction(M, INGEST) SPAWN_DBG (5) // Necessary. src.reagents.trans_to(M, src.reagents.total_volume) playsound(M.loc, "sound/items/eatfood.ogg", rand(10, 50), 1) SPAWN_DBG (10) if (!src || !M || !user) return 0 // Ditto (Convair880). if (iswerewolf(M) && istype(src, /obj/item/organ/)) M.show_text("Mmmmm, tasty organs. How refreshing.", "blue") M.HealDamage("All", 5, 5) M.visible_message("[M] finishes eating [src].",\ "You finish eating [src].") user.u_equip(src) qdel(src) return 1 /obj/item/proc/take_damage(brute, burn, tox, disallow_limb_loss) // this is a helper for organs and limbs return 0 /obj/item/proc/heal_damage(brute, burn, tox) // this is a helper for organs and limbs return 0 /obj/item/proc/get_damage() // this is a helper for organs and limbs return 0 /obj/item/proc/equipment_click(var/atom/target, var/atom/user) //Is called together with attackby and afterattack on items the MOB is wearing. Only works for mob/living/carbon s. return //Can be treated as afterattack that is called on all equiped items, basically. This is not restricted by LOS or anything //You'll have to check for that yourself if you need it. /* var/icon/overlay = icon('icons/effects/96x96.dmi',"smoke") if (color) overlay.Blend(color,ICON_MULTIPLY) var/image/I = image(overlay) I.pixel_x = -32 I.pixel_y = -32 var/the_dir = NORTH for(var/i=0, i<8, i++) var/obj/chem_smoke/C = new/obj/chem_smoke(location, holder, max_vol) C.overlays += I if (rname) C.name = "[rname] smoke" SPAWN_DBG(0) var/my_dir = the_dir var/my_time = rand(80,110) var/my_range = 3 SPAWN_DBG(my_time) qdel(C) for(var/b=0, b[src] catches on fire!") src.burning = 1 if (src.burn_output >= 1000) src.overlays += image('icons/effects/fire.dmi', "2old") else src.overlays += image('icons/effects/fire.dmi', "1old") processing_items.Add(src) /*if (src.reagents && src.reagents.reagent_list && src.reagents.reagent_list.len) //boutput(world, "[src] is releasing chemsmoke!") //cogwerks note for drsingh: this was causing infinite server-killing problems //someone brought a couple pieces of cheese into chemistry //chlorine trifluoride foam set the cheese on fire causing it to releasee cheese smoke //creating a dozen more cheeses on the floor //which would catch on fire, releasing more cheese smoke //i'm sure you can see where that is going //this will happen with any reagents that create more reagent-containing items on turf reactions var/location = get_turf(src) var/max_vol = reagents.maximum_volume var/rname = reagents.get_master_reagent_name() var/color = reagents.get_master_color(1) var/icon/overlay = icon('icons/effects/96x96.dmi',"smoke") if (color) overlay.Blend(color,ICON_MULTIPLY) var/image/I = image(overlay) I.pixel_x = -32 I.pixel_y = -32 var/the_dir = NORTH for(var/i=0, i<8, i++) var/obj/chem_smoke/C = new/obj/chem_smoke(location, reagents, max_vol) C.overlays += I if (rname) C.name = "[rname] smoke" SPAWN_DBG(0) var/my_dir = the_dir var/my_time = rand(80,110) var/my_range = 3 SPAWN_DBG(my_time) qdel(C) for(var/b=0, b T0C + src.burn_point) && prob(5)) src.combust() if (src.material) src.material.triggerTemp(src, temperature) ..() // call your fucking parents /obj/item/proc/update_stack_appearance() return /obj/item/proc/change_stack_amount(var/diff) amount += diff if (amount > 0) update_stack_appearance() else SPAWN_DBG(0) usr.u_equip(src) pool(src) /obj/item/proc/stack_item(obj/item/other) var/added = 0 if (other != src && check_valid_stack(other)) if (src.amount + other.amount > max_stack) added = max_stack - src.amount else added = other.amount src.change_stack_amount(added) other.change_stack_amount(-added) return added /obj/item/proc/before_stack(atom/movable/O as obj, mob/user as mob) user.visible_message("[user] begins quickly stacking [src]!") /obj/item/proc/after_stack(atom/movable/O as obj, mob/user as mob, var/added) boutput(user, "You finish stacking [src].") /obj/item/proc/failed_stack(atom/movable/O as obj, mob/user as mob, var/added) boutput(user, "You can't hold any more [name] than that!") /obj/item/proc/check_valid_stack(atom/movable/O as obj) if (stack_type) if(!istype(O, stack_type)) return 0 else if(src.type != O.type) return 0 if(O.material && src.material) if(!isSameMaterial(O.material, src.material)) return 0 else if ((O.material && !src.material) || (!O.material && src.material)) return 0 return 1 /obj/item/proc/split_stack(var/toRemove) if(toRemove >= amount) return 0 var/obj/item/P = new src.type(src.loc) if(src.material) P.setMaterial(copyMaterial(src.material)) src.change_stack_amount(-toRemove) P.change_stack_amount(toRemove - P.amount) return P /obj/item/MouseDrop_T(atom/movable/O as obj, mob/user as mob) ..() if (max_stack > 1 && src.loc == user && get_dist(O, user) <= 1 && check_valid_stack(O)) if ( src.amount >= max_stack) failed_stack(O, user) return var/added = 0 var/staystill = user.loc var/stack_result = 0 before_stack(O, user) for(var/obj/item/other in view(1,user)) stack_result = stack_item(other) if (!stack_result) continue else sleep(3) added += stack_result if (user.loc != staystill) break if (src.amount >= max_stack) failed_stack(O, user) return after_stack(O, user, added) #define src_exists_inside_user_or_user_storage (src.loc == user || (istype(src.loc, /obj/item/storage) && src.loc.loc == user)) /obj/item/MouseDrop(atom/over_object, src_location, over_location, params) ..() if (usr.stat || usr.restrained() || !can_reach(usr, src) || usr.getStatusDuration("paralysis") || usr.sleeping || usr.lying || isAIeye(usr) || isAI(usr) || isghostcritter(usr)) return var/on_turf = isturf(src.loc) var/mob/user = usr params = params2list(params) if (isliving(over_object) && isliving(usr) && !istype(src,/obj/item/storage)) //pickup action if (user == over_object) actions.start(new /datum/action/bar/private/icon/pickup(src), user) //else // use laterr, after we improve the 'give' dialog to work with multicontext // if (get_dist(user,over_object) <= 1 && src_exists_inside_usr_or_usr_storage) // user.give_to(over_object) else if (isturf(over_object)) if (on_turf && in_range(over_object,src)) //drag from floor to floor == slide if (istype(over_object,/turf/simulated/floor) || istype(over_object,/turf/unsimulated/floor)) step_to(src,over_object) //this would be cool ha ha h //if (islist(params) && params["icon-y"] && params["icon-x"]) //src.pixel_x = text2num(params["icon-x"]) - 16 //src.pixel_y = text2num(params["icon-y"]) - 16 //animate(src, pixel_x = text2num(params["icon-x"]) - 16, pixel_y = text2num(params["icon-y"]) - 16, time = 30, flags = ANIMATION_END_NOW) return else if (src_exists_inside_user_or_user_storage && !istype(src,/obj/item/storage)) //sorry for the storage check, i dont wanna override their mousedrop and to do it Correcly would be a whole big rewrite usr.drop_from_slot(src) //drag from inventory to floor == drop step_to(src,over_object) var/is_storage = istype(over_object,/obj/item/storage) if (is_storage || istype(over_object, /obj/screen/hud)) if (on_turf && isturf(over_object.loc) && is_storage) try_equip_to_inventory_object(usr, over_object, params) else if (on_turf) actions.start(new /datum/action/bar/private/icon/pickup/then_hud_click(src, over_object, params), usr) else try_equip_to_inventory_object(usr, over_object, params) //equip an item, given an inventory hud object or storage item UI thing /obj/item/proc/try_equip_to_inventory_object(var/mob/user, var/atom/over_object, var/params) var/obj/screen/hud/S = over_object if (istype(S)) if (S.master && istype(S.master,/datum/hud/storage)) var/datum/hud/storage/hud = S.master over_object = hud.master //If dragged into backpack HUD, change over_object to the backpack if (istype(over_object,/obj/item/storage) && over_object != src) var/obj/item/storage/storage = over_object if (istype(storage.loc, /turf)) if (!(in_range(src,user) && in_range(storage,user))) return var/succ = src.try_put_hand_mousedrop(user, storage) if (succ) SPAWN_DBG(1 DECI SECOND) if (user.is_in_hands(src)) storage.attackby(src, user) return if (istype(S)) if (src.cant_self_remove) return if ( !user.restrained() && !user.stat ) var/succ = src.try_put_hand_mousedrop(user) if (succ) SPAWN_DBG(1 DECI SECOND) if (user.is_in_hands(src)) S.sendclick(params, user) #undef src_exists_inside_user_or_user_storage /obj/item/proc/try_put_hand_mousedrop(mob/user) var/oldloc = src.loc if (!src.anchored) if (!user.r_hand || !user.l_hand || (!user.hand && user.r_hand == src) || (user.hand && user.l_hand == src)) if (!user.hand) //big messy ugly bad if() chunk here because we want to prefer active hand if (user.r_hand == src) . = 1 else if (!user.r_hand) user.u_equip(src) . = user.put_in_hand(src, 0) else if (!user.l_hand) user.swap_hand(1) user.u_equip(src) . = user.put_in_hand(src, 1) else if (user.l_hand == src) .= 1 else if (!user.l_hand) user.u_equip(src) . = user.put_in_hand(src, 1) else if (!user.r_hand) user.swap_hand(0) user.u_equip(src) . = user.put_in_hand(src, 0) else user.show_text("You need a free hand to do that!", "blue") .= 0 else user.show_text("This item is anchored to the floor!", "blue") .= 0 if (. == 1) if (istype(oldloc,/obj/item/storage)) var/obj/item/storage/S = oldloc //S.hud.remove_item(src) S.hud.objects -= src // prevents invisible object from failed transfer (item doesn't fit in pockets from backpack for example) /obj/item/Bump(mob/M as mob) SPAWN_DBG( 0 ) ..() return /obj/item/attackby(obj/item/W as obj, mob/user as mob, params) if (src.material) src.material.triggerTemp(src ,1500) if (src.burn_possible && src.burn_point <= 1500) if (istype(W, /obj/item/weldingtool) && W:welding) src.combust() if (istype(W, /obj/item/clothing/head/cakehat) && W:on) src.combust() if (istype(W, /obj/item/device/igniter)) src.combust() else if (istype(W, /obj/item/device/light/zippo) && W:on) src.combust() if (W.burning) src.combust() else ..(W, user) else ..(W, user) /obj/item/proc/process() if (src.burning) if (src.material) src.material.triggerTemp(src, src.burn_output + rand(1,200)) var/turf/T = get_turf(src.loc) if (T) // runtime error fix T.hotspot_expose((src.burn_output + rand(1,200)),5) if (prob(7)) var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread) s.set_up(2, 1, (get_turf(src))) s.start() if (prob(7)) var/datum/effects/system/bad_smoke_spread/smoke = new /datum/effects/system/bad_smoke_spread() smoke.set_up(1, 0, src.loc) smoke.attach(src) smoke.start() if (prob(7)) fireflash(src, 0) if (prob(40)) if (src.health > 4) src.health /= 4 else src.health -= 2 if (src.health <= 0) if (burn_type == 1) make_cleanable( /obj/decal/cleanable/molten_item,get_turf(src)) else make_cleanable( /obj/decal/cleanable/ash,get_turf(src)) if (istype(src,/obj/item/parts/human_parts)) src:holder = null src.combust_ended() if (src.burn_possible == 2) pool(src) else src.overlays.len = 0 qdel(src) return else if (burning_last_process != src.burning) if (src.burn_output >= 1000) src.overlays -= image('icons/effects/fire.dmi', "2old") else src.overlays -= image('icons/effects/fire.dmi', "1old") return processing_items.Remove(src) burning_last_process = src.burning return null /obj/item/proc/attack_self(mob/user) if (src.temp_flags & IS_LIMB_ITEM) if (istype(src.loc,/obj/item/parts/human_parts/arm/left/item)) var/obj/item/parts/human_parts/arm/left/item/I = src.loc I.remove_from_mob() I.set_item(src) else if (istype(src.loc,/obj/item/parts/human_parts/arm/right/item)) var/obj/item/parts/human_parts/arm/right/item/I = src.loc I.remove_from_mob() I.set_item(src) if (special_grab) if(chokehold) chokehold.attack_self(user) return /obj/item/proc/talk_into(mob/M as mob, text, secure, real_name, lang_id) return /obj/item/proc/moved(mob/user as mob, old_loc as turf) return /obj/item/proc/equipped(var/mob/user, var/slot) return /obj/item/proc/unequipped(var/mob/user) return /obj/item/proc/afterattack(atom/target, mob/user, reach, params) return /obj/item/dummy/ex_act() return /obj/item/dummy/blob_act(var/power) return /obj/item/ex_act(severity) switch(severity) if (1.0) if (istype(src,/obj/item/parts/human_parts)) src:holder = null qdel(src) return if (2.0) if (prob(50)) if (istype(src,/obj/item/parts/human_parts)) src:holder = null qdel(src) return if (src.material) src.material.triggerTemp(src ,7500) if (src.burn_possible && !src.burning && src.burn_point <= 7500) src.combust() if (src.artifact) if (!src.ArtifactSanityCheck()) return src.ArtifactStimulus("force", 75) src.ArtifactStimulus("heat", 450) if (3.0) if (prob(5)) if (istype(src,/obj/item/parts/human_parts)) src:holder = null qdel(src) return if (src.material) src.material.triggerTemp(src, 3500) if (src.burn_possible && !src.burning && src.burn_point <= 3500) src.combust() if (src.artifact) if (!src.ArtifactSanityCheck()) return src.ArtifactStimulus("force", 25) src.ArtifactStimulus("heat", 380) else return /obj/item/blob_act(var/power) if (src.artifact) if (!src.ArtifactSanityCheck()) return src.ArtifactStimulus("force", power) src.ArtifactStimulus("carbtouch", 1) return /obj/item/verb/move_to_top() set name = "Move to Top" set src in oview(1) set category = "Local" if (!istype(src.loc, /turf) || usr.stat || usr.restrained() ) return var/turf/T = src.loc src.set_loc(null) src.set_loc(T) /obj/item/interact_verb() set hidden = 1 /obj/item/verb/pick_up() set name = "Pick Up" set src in oview(1) set category = "Local" src.pick_up_by(usr) /obj/item/proc/pick_up_by(var/mob/M) if (world.time < M.next_click) return //fuck youuuuu if (isdead(M) || (!iscarbon(M) && !iscritter(M))) return if (!istype(src.loc, /turf) || !isalive(M) || M.getStatusDuration("paralysis") || M.getStatusDuration("stunned") || M.getStatusDuration("weakened") || M.restrained()) return if (!can_reach(M, src)) return if (issmallanimal(M)) var/mob/living/critter/small_animal = M for (var/datum/handHolder/HH in small_animal.hands) if (istype(HH.limb,/datum/limb/small_critter)) if (M.equipped()) M.drop_item() SPAWN_DBG(1 DECI SECOND) HH.limb.attack_hand(src,M,1) else HH.limb.attack_hand(src,M,1) M.next_click = world.time + src.click_delay return //the verb is PICK-UP, not 'smack this object with that object' if (M.equipped()) M.drop_item() SPAWN_DBG(1 DECI SECOND) src.attack_hand(M) else src.attack_hand(M) M.next_click = world.time + src.click_delay /obj/item/get_desc() var/t switch(src.w_class) if (-INFINITY to 1.0) t = "tiny" if (2.0) t = "small" if (3.0) t = "normal-sized" if (4.0) t = "bulky" if (5.0 to INFINITY) t = "huge" else if (usr && usr.bioHolder && usr.bioHolder.HasEffect("clumsy") && prob(50)) t = "funny-looking" return "It is \an [t] item." /obj/item/attack_hand(mob/user as mob) var/checkloc = src.loc while(checkloc && !istype(checkloc,/turf)) if (isliving(checkloc) && checkloc != user) return 0 checkloc = checkloc:loc src.throwing = 0 if (isobj(src.loc)) var/obj/container = src.loc container.vis_contents -= src if (src.loc == user) if (!cant_self_remove || (!cant_drop && (user.l_hand == src || user.r_hand == src))) user.u_equip(src) else boutput(user, "You can't remove this item.") return 0 else //src.pickup(user) //This is called by the later put_in_hand() call if (user.pulling == src) user.pulling = null if (isturf(src.loc)) pickup_particle(user,src) if (!user) return 0 var/area/MA = get_area(user) var/area/OA = get_area(src) if( OA && MA && OA != MA && OA.blocked ) boutput( user, "You cannot pick up items from outside a restricted area." ) return 0 var/atom/oldloc = src.loc var/atom/oldloc_sfx = src.loc src.set_loc(user) // this is to fix some bugs with storage items if (istype(oldloc, /obj/item/storage)) var/obj/item/storage/S = oldloc S.hud.remove_item(src) // ugh oldloc_sfx = oldloc.loc if (src in bible_contents) bible_contents.Remove(src) // UNF for (var/obj/item/storage/bible/bible in the_very_holy_global_bible_list_amen)//world) LAGCHECK(LAG_LOW) bible.hud.remove_item(src) user.put_in_hand_or_drop(src) if (src.artifact) if (src.ArtifactSanityCheck()) src.ArtifactTouched(user) if (hide_attack != 1) if (pickup_sfx) playsound(oldloc_sfx, pickup_sfx, 56, vary=0.2) else playsound(oldloc_sfx, "sound/items/pickup_[max(min(src.w_class,3),1)].ogg", 56, vary=0.2) return 1 //MBC : I had to move some ItemSpecial number changes here to avoid race conditions. is_special flag passed as an arg; If true we take a look at src.special /obj/item/proc/attack(mob/M as mob, mob/user as mob, def_zone, is_special = 0) if (!M || !user) // not sure if this is the right thing... return if ((src.edible && (ishuman(M) || iscritter(M)) || (src.material && src.material.edible)) && src.Eat(M, user)) return if (surgeryCheck(M, user)) // Check for surgery-specific actions insertChestItem(M, user) // Puting item in patient's chest return if (src.flags & SUPPRESSATTACK) logTheThing("combat", user, M, "uses [src] ([type], object name: [initial(name)]) on %target%") return if (user.mind && user.mind.special_role == "vampthrall" && isvampire(M) && user.is_mentally_dominated_by(M)) boutput(user, "You cannot harm your master!") //This message was previously sent to the attacking item. YEP. return if(user.traitHolder && !user.traitHolder.hasTrait("glasscannon")) if (!user.process_stamina(src.stamina_cost)) logTheThing("combat", user, M, "tries to attack %target% with [src] ([type], object name: [initial(name)]) but is out of stamina") return if (special_grab) if (chokehold) chokehold.attack(M, user, def_zone, is_special) return else if (user.a_intent == INTENT_GRAB) src.try_grab(M, user) return var/obj/item/affecting = M.get_affecting(user, def_zone) var/hit_area var/d_zone if (istype(affecting, /obj/item/organ)) var/obj/item/organ/O = affecting hit_area = parse_zone(O.organ_name) d_zone = O.organ_name else if (istype(affecting, /obj/item/parts)) var/obj/item/parts/P = affecting hit_area = parse_zone(P.slot) d_zone = P.slot else hit_area = parse_zone(affecting) d_zone = affecting if (!M.melee_attack_test(user, d_zone)) logTheThing("combat", user, M, "attacks %target% with [src] ([type], object name: [initial(name)]) but the attack is blocked!") return if(hasProperty("frenzy")) SPAWN_DBG(0) var/frenzy = getProperty("frenzy") click_delay -= frenzy sleep(30) click_delay += frenzy /* if(hasProperty("Momentum")) SPAWN_DBG(0) var/momentum = getProperty("momemtum") force += 5 */ if (src.material) src.material.triggerOnAttack(src, user, M) for (var/atom/A in M) if (A.material) A.material.triggerOnAttacked(A, user, M, src) M.violate_hippocratic_oath() for (var/mob/V in nervous_mobs) if (get_dist(user,V) > 6) continue if (prob(8) && user) if (M != V) V.emote("scream") V.changeStatus("stunned", 3 SECONDS) var/datum/attackResults/msgs = new(user) msgs.clear(M) msgs.affecting = affecting msgs.logs = list() msgs.logc("attacks %target% with [src] ([type], object name: [initial(name)])") var/stam_crit_pow = src.stamina_crit_chance if (prob(stam_crit_pow)) msgs.stamina_crit = 1 msgs.played_sound = "sound/impact_sounds/Generic_Punch_1.ogg" //moved to item_attack_message //msgs.visible_message_target("... and lands a devastating hit!") if (can_disarm) msgs = user.calculate_disarm_attack(M, M.get_affecting(user), 0, 0, 0, is_shove = 1, disarming_item = src) else msgs.msg_group = "[usr]_attacks_[M]_with_[src]" msgs.visible_message_target(user.item_attack_message(M, src, hit_area, msgs.stamina_crit)) msgs.played_sound = src.hitsound var/power = src.force + src.getProperty("searing") if(hasProperty("unstable")) power = rand(power, round(power * getProperty("unstable"))) var/attack_resistance = M.check_attack_resistance(src) if (attack_resistance) power = 0 if (istext(attack_resistance)) msgs.show_message_target(attack_resistance) if (damtype == "fire" || damtype == "burn" || hasProperty("searing")) msgs.damage_type = DAMAGE_BURN else msgs.damage_type = hit_type if(hasProperty("vorpal")) msgs.bleed_always = 1 msgs.bleed_bonus = getProperty("vorpal") var/armor_mod = 0 if (d_zone == "head") armor_mod = M.get_head_armor_modifier() else armor_mod = M.get_chest_armor_modifier() var/pierce_prot = 0 if (d_zone == "head") pierce_prot = M.get_head_pierce_prot() else pierce_prot = M.get_chest_pierce_prot() var/adjusted = max(0, getProperty("piercing") - pierce_prot) if(adjusted) var/prc = ((100 - getProperty("piercing")) / 100) armor_mod = round(armor_mod * prc) if (is_special && src.special) if (src.special.damageMult > 0 && src.special.damageMult != 1) power *= src.special.damageMult power -= armor_mod if (w_class > STAMINA_MIN_WEIGHT_CLASS) var/stam_power = stamina_damage if (is_special && src.special) if(src.special.overrideStaminaDamage >= 0) stam_power = src.special.overrideStaminaDamage //reduce stamina by the same proportion that base damage was reduced //min cap is stam_power/4 so we still cant ignore it entirely if ((power + armor_mod) == 0) //mbc lazy runtime fix stam_power = stam_power / 4 //do the least else stam_power = max( stam_power / 4, stam_power * ( power / (power + armor_mod) ) ) //stam_power -= armor_mod msgs.stamina_target -= max(stam_power, 0) if (is_special && src.special) if(src.special.overrideCrit >= 0) stam_crit_pow = src.special.overrideCrit if(M.is_hulk()) power *= 1.5 if(M.traitHolder && M.traitHolder.hasTrait("deathwish")) power *= 2 if(user.traitHolder && user.traitHolder.hasTrait("glasscannon")) power *= 2 if (ishuman(user)) var/mob/living/carbon/human/H = user H.ensure_bp_list() if (H.blood_pressure["total"] > 585) msgs.visible_message_self("[user] gasps and wheezes from the exertion!") user.losebreath += rand(1,2) msgs.stamina_self -= 10 if(hasProperty("impact")) var/turf/T = get_edge_target_turf(M, get_dir(user, M)) M.throw_at(T, 2, getProperty("impact")) msgs.damage = power msgs.flush() src.add_fingerprint(user) return /obj/item/onVarChanged(variable, oldval, newval) . = 0 switch(variable) if ("color") if (src.wear_image) src.wear_image.color = newval if (src.inhand_image) src.inhand_image.color = newval . = 1 if ("alpha") if (src.wear_image) src.wear_image.alpha = newval if (src.inhand_image) src.inhand_image.alpha = newval . = 1 if ("blend_mode") if (src.wear_image) src.wear_image.blend_mode = newval if (src.inhand_image) src.inhand_image.blend_mode = newval . = 1 if ("icon_state") . = 1 if ("item_state") . = 1 if ("wear_image") . = 1 if ("inhand_image") . = 1 if (. && src.loc && ismob(src.loc)) var/mob/M = src.loc M.update_inhands() /obj/item/proc/attach(var/mob/living/carbon/human/attachee,var/mob/attacher) //if (!src.arm_icon) return //ANYTHING GOES!~! if (src.object_flags & NO_ARM_ATTACH) boutput(attacher, "You try to attach [src] to [attachee]'s stump, but it politely declines!") return var/obj/item/parts/human_parts/arm/new_arm = null if (attacher.zone_sel.selecting == "l_arm") new_arm = new /obj/item/parts/human_parts/arm/left/item(attachee) attachee.limbs.l_arm = new_arm else new_arm = new /obj/item/parts/human_parts/arm/right/item(attachee) attachee.limbs.r_arm = new_arm if (!new_arm) return //who knows new_arm.holder = attachee attacher.remove_item(src) new_arm.remove_stage = 2 new_arm:set_item(src) src.cant_drop = 1 for(var/mob/O in AIviewers(attachee, null)) if (O == (attacher || attachee)) continue if (attacher == attachee) O.show_message("[attacher] attaches [src] to \his own stump!", 1) else O.show_message("[attachee] has [src] attached to \his stump by [attacher].", 1) if (attachee != attacher) boutput(attachee, "[attacher] attaches [src] to your stump. It doesn't look very secure!") boutput(attacher, "You attach [src] to [attachee]'s stump. It doesn't look very secure!") else boutput(attacher, "You attach [src] to your own stump. It doesn't look very secure!") attachee.set_body_icon_dirty() //qdel(src) SPAWN_DBG(rand(150,200)) if (new_arm.remove_stage == 2) new_arm.remove() return /obj/item/proc/handle_other_remove(var/mob/source, var/mob/living/carbon/human/target) //Refactor of the item removal code. Fuck having that shit defined in human.dm >>>>>>:C //Return something true (lol byond) to allow removal //Return something false to disallow return (!cant_other_remove && !cant_drop) /obj/item/disposing() // Clean up circular references disposing_abilities() setItemSpecial(null) var/turf/T = loc if (!istype(T)) if (ismob(src.loc)) var/mob/M = src.loc M.u_equip(src) //mbc GC tooltips (this wont 100% kill tooltip deletions but itll help? if (M.client && M.client.tooltipHolder) for (var/datum/tooltip/tip in M.client.tooltipHolder.tooltips) if (tip.A == src) tip.A = null if (M.client.tooltipHolder.transient) if (M.client.tooltipHolder.transient.A == src) M.client.tooltipHolder.transient.A = null return ..() var/area/Ar = T.loc if (!(locate(/obj/table) in T) && !(locate(/obj/rack) in T)) Ar.sims_score = min(Ar.sims_score + 4, 100) if (event_handler_flags & IS_TRINKET) //slow but fast as i can get for now, rewrite trinket holding later for(var/mob/living/carbon/human/M in mobs) if (M.trinket == src) M.trinket = null if (special_grab) drop_grab() ..() /obj/item/proc/on_spin_emote(var/mob/living/carbon/human/user as mob) if ((user.bioHolder && user.bioHolder.HasEffect("clumsy") && prob(50)) || (user.reagents && prob(user.reagents.get_reagent_amount("ethanol") / 2)) || prob(5)) user.visible_message("[user] fumbles [src]!") src.throw_impact(user) return /obj/item/proc/HY_set_species() return /obj/item/proc/HY_set_mutation() return /obj/item/proc/HY_set_strain() return /obj/item/proc/registered_owner() .= 0 /obj/item/proc/force_drop(var/mob/possible_mob_holder = 0) if (!possible_mob_holder) if (ismob(src.loc)) possible_mob_holder = src.loc if(possible_mob_holder) if (src in possible_mob_holder.equipped_list()) if (possible_mob_holder.equipped() == src) possible_mob_holder.drop_item() else possible_mob_holder.hand = !possible_mob_holder.hand possible_mob_holder.drop_item() possible_mob_holder.hand = !possible_mob_holder.hand /obj/item/proc/dropped(mob/user as mob) if(src.material) src.material.triggerDrop(user, src) if (islist(src.ability_buttons)) for(var/obj/ability_button/B in ability_buttons) B.OnDrop() hide_buttons() clear_mob() if (special_grab) drop_grab() return /obj/item/proc/pickup(mob/user) if(src.material) src.material.triggerPickup(user, src) set_mob(user) show_buttons() return