/obj/item name = "item" icon = 'icons/obj/items.dmi' var/movement_speed_mod = 0 var/icon_old = null 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 = 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 var/burn_output = 1500 //how hot should it burn var/burn_type = 0 // 0 = ash, 1 = melt var/burning = null var/hitsound = 'sound/weapons/genhit1.ogg' var/w_class = 3.0 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 pressure_resistance = 50 var/obj/item/master = null var/numattacks = 1 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/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 = 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? onMaterialChanged() ..() if (istype(src.material)) stamina_damage = initial(stamina_damage) + (material.hasProperty(PROP_COMPRESSIVE) ? round(material.getProperty(PROP_COMPRESSIVE) / 8) : -4) stamina_crit_chance = initial(stamina_crit_chance) + (material.hasProperty(PROP_HARDNESS) ? round(material.getProperty(PROP_HARDNESS) / 8) : -5) force = material.hasProperty(PROP_HARDNESS) ? round(material.getProperty(PROP_HARDNESS) / 3) : force burn_point = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : burn_point burn_output = initial(burn_output) + (100 * src.material.getProperty(PROP_FLAMMABILITY)) + (100 * src.material.getProperty(PROP_ENERGY)) burn_possible = src.material.getProperty(PROP_FLAMMABILITY) ? 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) 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) ..() /obj/item/proc/Eat(var/mob/M as mob, var/mob/user) if (!src.edible) return 0 if (!iscarbon(M) && !istype(M, /mob/living/critter)) return 0 if (M == user) M.visible_message("[M] takes a bite of [src]!",\ "You take a bite of [src]!") if (src.reagents && src.reagents.total_volume) src.reagents.reaction(M, INGEST) spawn (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 (10) // 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 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.reagents && src.reagents.total_volume) src.reagents.reaction(M, INGEST) spawn (5) // Necessary. src.reagents.trans_to(M, src.reagents.total_volume) playsound(M.loc, "sound/items/eatfood.ogg", rand(10, 50), 1) spawn (10) // 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(0) var/my_dir = the_dir var/my_time = rand(80,110) var/my_range = 3 spawn(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") /*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(0) var/my_dir = the_dir var/my_time = rand(80,110) var/my_range = 3 spawn(my_time) qdel(C) for(var/b=0, b 0 && 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) sleep(15) 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) // Marquesas: this will give paper an average lifetime of 6 seconds while burning. if (prob(40)) if (src.health > 4) src.health /= 2 else src.health-- if (src.health <= 0 && src.burning) if (burn_type == 1) new /obj/decal/cleanable/molten_item(get_turf(src)) else new /obj/decal/cleanable/ash(get_turf(src)) if (istype(src,/obj/item/parts/human_parts)) src:holder = null qdel(src) return 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") return /obj/item/temperature_expose(datum/gas_mixture/air, temperature, volume) if (src.burn_possible && !src.burning) if ((temperature > 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() /obj/item/proc/change_stack_amount(var/diff) amount += diff if (diff) if (amount > 0) update_stack_appearance() else spawn(0) qdel(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) return istype(O, stack_type) return src.type == O.type /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) /obj/item/Bump(mob/M as mob) spawn( 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/zippo) && W:lit) src.combust() if (W.burning) src.combust() else ..(W, user) else ..(W, user) /obj/item/proc/process() processing_items.Remove(src) return null /obj/item/proc/attack_self() 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/verb/pick_up() set name = "Pick Up" set src in oview(1) set category = "Local" if (!iscarbon(usr)) return if (!istype(src.loc, /turf) || usr.stat || usr.restrained() || usr.equipped()) return if (!can_reach(usr, src)) return src.attack_hand(usr) /obj/item/get_desc() var/t switch(src.w_class) if (1.0) t = "tiny" if (2.0) t = "small" if (3.0) t = "normal-sized" if (4.0) t = "bulky" if (5.0) t = "huge" else if (usr.bioHolder.HasEffect("clumsy") && prob(50)) t = "funny-looking" return "It is a [t] item." /obj/item/attack_hand(mob/user as mob) var/checkloc = src.loc while(checkloc && !istype(checkloc,/turf)) if (istype(checkloc,/mob/living) && checkloc != user) return checkloc = checkloc:loc src.throwing = 0 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 else //src.pickup(user) //This is called by the later put_in_hand() call if (user.pulling == src) user.pulling = null if (!user) return var/atom/oldloc = src.loc src.set_loc(user) // this is to fix some bugs with storage items if (istype(oldloc, /obj/item/storage)) oldloc:hud:remove_item(src) // ugh if (src in bible_contents) bible_contents.Remove(src) // UNF for (var/obj/item/storage/bible/bible in world) bible.hud.remove_item(src) user.put_in_hand_or_drop(src) if (src.artifact) if (src.ArtifactSanityCheck()) src.ArtifactTouched(user) /obj/item/proc/attack(mob/M as mob, mob/user as mob, def_zone) if (!M || !user) // not sure if this is the right thing... return if (src.edible && (ishuman(M) || istype(M, /mob/living/critter))) if (!src.Eat(M, user)) 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 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 (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 viewers(world.view, user)) if (prob(8) && V.traitHolder && V.traitHolder.hasTrait("nervous")) if (M != V) V.emote("scream") V.stunned += 3 var/datum/attackResults/msgs = new(user) msgs.clear(M) msgs.played_sound = src.hitsound msgs.affecting = affecting msgs.logs = list() msgs.logc("attacks %target% with [src] ([type], object name: [initial(name)])") var/power = src.force var/attack_resistance = M.check_attack_resistance(src) if (attack_resistance) power = 0 if (istext(attack_resistance)) msgs.show_message_target(attack_resistance) msgs.visible_message_target(user.item_attack_message(M, src, hit_area)) if (damtype == "fire" || damtype == "burn") msgs.damage_type = DAMAGE_BURN else msgs.damage_type = hit_type var/armor_mod = 0 if (d_zone == "head") armor_mod = M.get_head_armor_modifier() else if (d_zone == "chest") armor_mod = M.get_chest_armor_modifier() power -= armor_mod if (w_class > STAMINA_MIN_WEIGHT_CLASS) msgs.stamina_target -= max(stamina_damage - armor_mod, 0) if (prob(STAMINA_CRIT_CHANCE)) msgs.stamina_crit = 1 msgs.played_sound = "sound/misc/critpunch.ogg" msgs.visible_message_target("... and lands a devastating hit!") if(M.traitHolder && M.traitHolder.hasTrait("deathwish")) power *= 2 if(user.traitHolder && user.traitHolder.hasTrait("glasscannon")) power *= 2 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 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(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() var/turf/T = loc if (!istype(T)) 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) ..() /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