diff --git a/code/game/gamemodes/technomancer/spells/modifier/corona.dm b/code/game/gamemodes/technomancer/spells/modifier/corona.dm
index 74a06855d9..24d571d4c2 100644
--- a/code/game/gamemodes/technomancer/spells/modifier/corona.dm
+++ b/code/game/gamemodes/technomancer/spells/modifier/corona.dm
@@ -26,7 +26,7 @@
on_created_text = "You start to glow very brightly!"
on_expired_text = "Your glow has ended."
- evasion = -2
+ evasion = -30
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/corona/tick()
diff --git a/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm b/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
index 6ead04f30c..6f3b4b892f 100644
--- a/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
+++ b/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
@@ -24,5 +24,5 @@
on_created_text = "You have a repulsion field around you, which will attempt to deflect projectiles."
on_expired_text = "Your repulsion field has expired."
- evasion = 3
+ evasion = 45
stacks = MODIFIER_STACK_EXTEND
\ No newline at end of file
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index bf091e1180..c5840eaed2 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -1,658 +1,681 @@
-/obj/item
- name = "item"
- icon = 'icons/obj/items.dmi'
- w_class = ITEMSIZE_NORMAL
-
- 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 = 0
- var/r_speed = 1.0
- var/health = null
- var/burn_point = null
- var/burning = null
- var/hitsound = null
- var/usesound = null // Like hitsound, but for when used properly and not to kill someone.
- var/storage_cost = null
- var/slot_flags = 0 //This is used to determine on which slots an item can fit.
- var/no_attack_log = 0 //If it's an item we don't want to log attack_logs with, set this to 1
- pass_flags = PASSTABLE
- pressure_resistance = 5
-// causeerrorheresoifixthis
- var/obj/item/master = null
- var/list/origin_tech = null //Used by R&D to determine what research bonuses it grants.
- var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
- var/force = 0
-
- var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
- var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
- 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/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags
-
- var/datum/action/item_action/action = null
- var/action_button_name //It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button.
- var/action_button_is_hands_free = 0 //If 1, bypass the restrained, lying, and stunned checks action buttons normally test for
-
- //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
- //It should be used purely for appearance. For gameplay effects caused by items covering body parts, use body_parts_covered.
- var/flags_inv = 0
- var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
-
- var/item_flags = 0 //Miscellaneous flags pertaining to equippable objects.
-
- //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
- var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
- var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
- var/canremove = 1 //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N
- var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
- var/list/armorsoak = 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/zoomdevicename = null //name used for message when binoculars/scope is used
- var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars.
-
- var/embed_chance = -1 //0 won't embed, and 100 will always embed
-
- var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
-
- //** These specify item/icon overrides for _slots_
-
- var/list/item_state_slots = list() //overrides the default item_state for particular slots.
-
- // Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used.
- // If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question.
- // Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed.
- var/list/item_icons = list()
-
- //** These specify item/icon overrides for _species_
-
- /* Species-specific sprites, concept stolen from Paradise//vg/.
- ex:
- sprite_sheets = list(
- "Tajara" = 'icons/cat/are/bad'
- )
- If index term exists and icon_override is not set, this sprite sheet will be used.
- */
- var/list/sprite_sheets = list()
-
- // 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 = list()
-
- var/toolspeed = 1.0 // This is a multipler on how 'fast' a tool works. e.g. setting this to 0.5 will make the tool work twice as fast.
- var/attackspeed = DEFAULT_ATTACK_COOLDOWN // How long click delay will be when using this, in 1/10ths of a second. Checked in the user's get_attack_speed().
- var/reach = 1 // Length of tiles it can reach, 1 is adjacent.
- var/addblends // Icon overlay for ADD highlights when applicable.
-
-/obj/item/New()
- ..()
- if(embed_chance < 0)
- if(sharp)
- embed_chance = max(5, round(force/w_class))
- else
- embed_chance = max(5, round(force/(w_class*3)))
-
-/obj/item/equipped()
- ..()
- var/mob/living/M = loc
- if(!istype(M))
- return
- M.update_held_icons()
-
-/obj/item/Destroy()
- if(ismob(loc))
- var/mob/m = loc
- m.drop_from_inventory(src)
- m.update_inv_r_hand()
- m.update_inv_l_hand()
- src.loc = null
- return ..()
-
-/obj/item/device
- icon = 'icons/obj/device.dmi'
-
-//Checks if the item is being held by a mob, and if so, updates the held icons
-/obj/item/proc/update_held_icon()
- if(isliving(src.loc))
- var/mob/living/M = src.loc
- if(M.l_hand == src)
- M.update_inv_l_hand()
- else if(M.r_hand == src)
- M.update_inv_r_hand()
-
-/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
-
-//user: The mob that is suiciding
-//damagetype: The type of damage the item will inflict on the user
-//BRUTELOSS = 1
-//FIRELOSS = 2
-//TOXLOSS = 4
-//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(src.loc, /turf) || usr.stat || usr.restrained() )
- return
-
- var/turf/T = src.loc
-
- src.loc = null
-
- src.loc = T
-
-// See inventory_sizes.dm for the defines.
-/obj/item/examine(mob/user, var/distance = -1)
- var/size
- switch(src.w_class)
- if(ITEMSIZE_TINY)
- size = "tiny"
- if(ITEMSIZE_SMALL)
- size = "small"
- if(ITEMSIZE_NORMAL)
- size = "normal-sized"
- if(ITEMSIZE_LARGE)
- size = "bulky"
- if(ITEMSIZE_HUGE)
- size = "huge"
- return ..(user, distance, "", "It is a [size] item.")
-
-/obj/item/attack_hand(mob/living/user as mob)
- if (!user) return
- if (hasorgans(user))
- var/mob/living/carbon/human/H = user
- var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
- if (user.hand)
- temp = H.organs_by_name["l_hand"]
- if(temp && !temp.is_usable())
- user << "You try to move your [temp.name], but cannot!"
- return
- if(!temp)
- user << "You try to use your hand, but realize it is no longer attached!"
- return
- src.pickup(user)
- if (istype(src.loc, /obj/item/weapon/storage))
- var/obj/item/weapon/storage/S = src.loc
- S.remove_from_storage(src)
-
- src.throwing = 0
- if (src.loc == user)
- if(!user.unEquip(src))
- return
- else
- if(isliving(src.loc))
- return
- user.put_in_active_hand(src)
- return
-
-/obj/item/attack_ai(mob/user as mob)
- if (istype(src.loc, /obj/item/weapon/robot_module))
- //If the item is part of a cyborg module, equip it
- if(!isrobot(user))
- return
- var/mob/living/silicon/robot/R = user
- R.activate_module(src)
- R.hud_used.update_robot_modules_display()
-
-/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/storage))
- var/obj/item/weapon/storage/S = W
- if(S.use_to_pickup)
- if(S.collection_mode) //Mode is set to collect all items
- if(isturf(src.loc))
- S.gather_all(src.loc, user)
-
- else if(S.can_be_inserted(src))
- S.handle_item_insertion(src)
- return
-
-/obj/item/proc/talk_into(mob/M as mob, text)
- return
-
-/obj/item/proc/moved(mob/user as mob, old_loc as turf)
- return
-
-// apparently called whenever an item is removed from a slot, container, or anything else.
-/obj/item/proc/dropped(mob/user as mob)
- ..()
- if(zoom)
- zoom() //binoculars, scope, etc
- appearance_flags &= ~NO_CLIENT_COLOR
-
-// called just as an item is picked up (loc is not yet 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/finder as mob)
- 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)
- hud_layerise()
- if(user.client) user.client.screen |= src
- if(user.pulling == src) user.stop_pulling()
- return
-
-//Defines which slots correspond to which slot flags
-var/list/global/slot_flags_enumeration = list(
- "[slot_wear_mask]" = SLOT_MASK,
- "[slot_back]" = SLOT_BACK,
- "[slot_wear_suit]" = SLOT_OCLOTHING,
- "[slot_gloves]" = SLOT_GLOVES,
- "[slot_shoes]" = SLOT_FEET,
- "[slot_belt]" = SLOT_BELT,
- "[slot_glasses]" = SLOT_EYES,
- "[slot_head]" = SLOT_HEAD,
- "[slot_l_ear]" = SLOT_EARS|SLOT_TWOEARS,
- "[slot_r_ear]" = SLOT_EARS|SLOT_TWOEARS,
- "[slot_w_uniform]" = SLOT_ICLOTHING,
- "[slot_wear_id]" = SLOT_ID,
- "[slot_tie]" = SLOT_TIE,
- )
-
-//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.
-//Should probably move the bulk of this into mob code some time, as most of it is related to the definition of slots and not item-specific
-/obj/item/proc/mob_can_equip(M as mob, slot, disable_warning = 0)
- if(!slot) return 0
- if(!M) return 0
-
- if(!ishuman(M)) return 0
-
- var/mob/living/carbon/human/H = M
- var/list/mob_equip = list()
- if(H.species.hud && H.species.hud.equip_slots)
- mob_equip = H.species.hud.equip_slots
-
- if(H.species && !(slot in mob_equip))
- return 0
-
- //First check if the item can be equipped to the desired slot.
- if("[slot]" in slot_flags_enumeration)
- var/req_flags = slot_flags_enumeration["[slot]"]
- if(!(req_flags & slot_flags))
- return 0
-
- //Next check that the slot is free
- if(H.get_equipped_item(slot))
- return 0
-
- //Next check if the slot is accessible.
- var/mob/_user = disable_warning? null : H
- if(!H.slot_is_accessible(slot, src, _user))
- return 0
-
- //Lastly, check special rules for the desired slot.
- switch(slot)
- if(slot_l_ear, slot_r_ear)
- var/slot_other_ear = (slot == slot_l_ear)? slot_r_ear : slot_l_ear
- if( (w_class > ITEMSIZE_TINY) && !(slot_flags & SLOT_EARS) )
- return 0
- if( (slot_flags & SLOT_TWOEARS) && H.get_equipped_item(slot_other_ear) )
- return 0
- if(slot_wear_id)
- if(!H.w_uniform && (slot_w_uniform in mob_equip))
- if(!disable_warning)
- H << "You need a jumpsuit before you can attach this [name]."
- return 0
- if(slot_l_store, slot_r_store)
- if(!H.w_uniform && (slot_w_uniform in mob_equip))
- if(!disable_warning)
- H << "You need a jumpsuit before you can attach this [name]."
- return 0
- if(slot_flags & SLOT_DENYPOCKET)
- return 0
- if( w_class > ITEMSIZE_SMALL && !(slot_flags & SLOT_POCKET) )
- return 0
- if(slot_s_store)
- if(!H.wear_suit && (slot_wear_suit in mob_equip))
- if(!disable_warning)
- H << "You need a suit before you can attach this [name]."
- return 0
- if(!H.wear_suit.allowed)
- if(!disable_warning)
- usr << "You somehow have a suit with no defined allowed items for suit storage, stop that."
- return 0
- if( !(istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed)) )
- return 0
- if(slot_legcuffed) //Going to put this check above the handcuff check because the survival of the universe depends on it.
- if(!istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Putting it here might actually do nothing.
- return 0
- if(slot_handcuffed)
- if(!istype(src, /obj/item/weapon/handcuffs) || istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Legcuffs are a child of handcuffs, but we don't want to use legcuffs as handcuffs...
- return 0 //In theory, this would never happen, but let's just do the legcuff check anyways.
- if(slot_in_backpack) //used entirely for equipping spawned mobs or at round start
- var/allow = 0
- if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))
- var/obj/item/weapon/storage/backpack/B = H.back
- if(B.can_be_inserted(src,1))
- allow = 1
- if(!allow)
- return 0
- if(slot_tie)
- if(!H.w_uniform && (slot_w_uniform in mob_equip))
- if(!disable_warning)
- H << "You need a jumpsuit before you can attach this [name]."
- return 0
- var/obj/item/clothing/under/uniform = H.w_uniform
- if(uniform.accessories.len && !uniform.can_attach_accessory(src))
- if (!disable_warning)
- H << "You already have an accessory of this type attached to your [uniform]."
- return 0
- return 1
-
-/obj/item/proc/mob_can_unequip(mob/M, slot, disable_warning = 0)
- if(!slot) return 0
- if(!M) return 0
-
- if(!canremove)
- return 0
- if(!M.slot_is_accessible(slot, src, disable_warning? null : M))
- return 0
- return 1
-
-/obj/item/verb/verb_pickup()
- set src in oview(1)
- set category = "Object"
- set name = "Pick up"
-
- if(!(usr)) //BS12 EDIT
- return
- if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
- return
- if((!istype(usr, /mob/living/carbon)) || (istype(usr, /mob/living/carbon/brain)))//Is humanoid, and is not a brain
- usr << "You can't pick things up!"
- return
- var/mob/living/carbon/C = usr
- if( usr.stat || usr.restrained() )//Is not asleep/dead and is not restrained
- usr << "You can't pick things up!"
- return
- if(src.anchored) //Object isn't anchored
- usr << "You can't pick that up!"
- return
- if(C.get_active_hand()) //Hand is not full
- usr << "Your hand is full."
- return
- if(!istype(src.loc, /turf)) //Object is on a turf
- usr << "You can't pick that up!"
- return
- //All checks are done, time to pick it up!
- usr.UnarmedAttack(src)
- return
-
-
-//This proc is executed when someone clicks the on-screen UI button. To make the UI button show, set the 'icon_action_button' to the icon_state of the image of the button in screen1_action.dmi
-//The default action is attack_self().
-//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob.
-/obj/item/proc/ui_action_click()
- attack_self(usr)
-
-//RETURN VALUES
-//handle_shield should return a positive value to indicate that the attack is blocked and should be prevented.
-//If a negative value is returned, it should be treated as a special return value for bullet_act() and handled appropriately.
-//For non-projectile attacks this usually means the attack is blocked.
-//Otherwise should return 0 to indicate that the attack is not affected in any way.
-/obj/item/proc/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
- return 0
-
-/obj/item/proc/get_loc_turf()
- var/atom/L = loc
- while(L && !istype(L, /turf/))
- L = L.loc
- return loc
-
-/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
-
- var/mob/living/carbon/human/H = M
- var/mob/living/carbon/human/U = user
- if(istype(H))
- for(var/obj/item/protection in list(H.head, H.wear_mask, H.glasses))
- if(protection && (protection.body_parts_covered & EYES))
- // you can't stab someone in the eyes wearing a mask!
- user << "You're going to need to remove the eye covering first."
- return
-
- if(!M.has_eyes())
- user << "You cannot locate any eyes on [M]!"
- return
-
- if(U.get_accuracy_penalty(U)) //Should only trigger if they're not aiming well
- var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
- if(!hit_zone)
- U.do_attack_animation(M)
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- visible_message("[U] attempts to stab [M] in the eyes, but misses!")
- return
-
- user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG
-
- user.setClickCooldown(user.get_attack_speed())
- user.do_attack_animation(M)
-
- src.add_fingerprint(user)
- //if((CLUMSY in user.mutations) && prob(50))
- // M = user
- /*
- M << "You stab yourself in the eye."
- M.sdisabilities |= BLIND
- M.weakened += 4
- M.adjustBruteLoss(10)
- */
-
- if(istype(H))
-
- var/obj/item/organ/internal/eyes/eyes = H.internal_organs_by_name[O_EYES]
-
- if(H != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("[M] has been stabbed in the eye with [src] by [user].", 1)
- M << "[user] stabs you in the eye with [src]!"
- user << "You stab [M] in the eye with [src]!"
- else
- user.visible_message( \
- "[user] has stabbed themself with [src]!", \
- "You stab yourself in the eyes with [src]!" \
- )
-
- eyes.damage += rand(3,4)
- if(eyes.damage >= eyes.min_bruised_damage)
- if(M.stat != 2)
- if(!(eyes.robotic >= ORGAN_ROBOT)) //robot eyes bleeding might be a bit silly
- M << "Your eyes start to bleed profusely!"
- if(prob(50))
- if(M.stat != 2)
- M << "You drop what you're holding and clutch at your eyes!"
- M.drop_item()
- M.eye_blurry += 10
- M.Paralyse(1)
- M.Weaken(4)
- if (eyes.damage >= eyes.min_broken_damage)
- if(M.stat != 2)
- M << "You go blind!"
- var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD)
- if(affecting.take_damage(7))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(7)
- M.eye_blurry += rand(3,4)
- return
-
-/obj/item/clean_blood()
- . = ..()
- if(blood_overlay)
- overlays.Remove(blood_overlay)
- if(istype(src, /obj/item/clothing/gloves))
- var/obj/item/clothing/gloves/G = src
- G.transfer_blood = 0
-
-/obj/item/reveal_blood()
- if(was_bloodied && !fluorescent)
- fluorescent = 1
- blood_color = COLOR_LUMINOL
- blood_overlay.color = COLOR_LUMINOL
- update_icon()
-
-/obj/item/add_blood(mob/living/carbon/human/M as mob)
- if (!..())
- return 0
-
- if(istype(src, /obj/item/weapon/melee/energy))
- return
-
- //if we haven't made our blood_overlay already
- if( !blood_overlay )
- generate_blood_overlay()
-
- //apply the blood-splatter overlay if it isn't already in there
- if(!blood_DNA.len)
- blood_overlay.color = blood_color
- overlays += blood_overlay
-
- //if this blood isn't already in the list, add it
- if(istype(M))
- if(blood_DNA[M.dna.unique_enzymes])
- return 0 //already bloodied with this blood. Cannot add more.
- blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
- return 1 //we applied blood to the item
-
-/obj/item/proc/generate_blood_overlay()
- if(blood_overlay)
- 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
-
- //not sure if this is worth it. It attaches the blood_overlay to every item of the same type if they don't have one already made.
- for(var/obj/item/A in world)
- if(A.type == type && !A.blood_overlay)
- A.blood_overlay = image(I)
-
-/obj/item/proc/showoff(mob/user)
- for (var/mob/M in view(user))
- M.show_message("[user] holds up [src]. Take a closer look.",1)
-
-/mob/living/carbon/verb/showoff()
- set name = "Show Held Item"
- set category = "Object"
-
- var/obj/item/I = get_active_hand()
- if(I && !I.abstract)
- I.showoff(src)
-
-/*
-For zooming with scope or binoculars. This is called from
-modules/mob/mob_movement.dm if you move you will be zoomed out
-modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
-*/
-//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW
-/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view
-
- var/devicename
-
- if(zoomdevicename)
- devicename = zoomdevicename
- else
- devicename = src.name
-
- var/cannotzoom
-
- if(usr.stat || !(istype(usr,/mob/living/carbon/human)))
- usr << "You are unable to focus through the [devicename]"
- cannotzoom = 1
- else if(!zoom && global_hud.darkMask[1] in usr.client.screen)
- usr << "Your visor gets in the way of looking through the [devicename]"
- cannotzoom = 1
- else if(!zoom && usr.get_active_hand() != src)
- usr << "You are too distracted to look through the [devicename], perhaps if it was in your active hand this might work better"
- cannotzoom = 1
-
- if(!zoom && !cannotzoom)
- if(usr.hud_used.hud_shown)
- usr.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
- usr.client.view = viewsize
- zoom = 1
-
- var/tilesize = 32
- var/viewoffset = tilesize * tileoffset
-
- switch(usr.dir)
- if (NORTH)
- usr.client.pixel_x = 0
- usr.client.pixel_y = viewoffset
- if (SOUTH)
- usr.client.pixel_x = 0
- usr.client.pixel_y = -viewoffset
- if (EAST)
- usr.client.pixel_x = viewoffset
- usr.client.pixel_y = 0
- if (WEST)
- usr.client.pixel_x = -viewoffset
- usr.client.pixel_y = 0
-
- usr.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].")
-
- else
- usr.client.view = world.view
- if(!usr.hud_used.hud_shown)
- usr.toggle_zoom_hud()
- zoom = 0
-
- usr.client.pixel_x = 0
- usr.client.pixel_y = 0
-
- if(!cannotzoom)
- usr.visible_message("[zoomdevicename ? "[usr] looks up from the [src.name]" : "[usr] lowers the [src.name]"].")
-
- return
-
-/obj/item/proc/pwr_drain()
- return 0 // Process Kill
-
-// Used for non-adjacent melee attacks with specific weapons capable of reaching more than one tile.
-// This uses changeling range string A* but for this purpose its also applicable.
-/obj/item/proc/attack_can_reach(var/atom/us, var/atom/them, var/range)
- if(us.Adjacent(them))
- return TRUE // Already adjacent.
- if(AStar(get_turf(us), get_turf(them), /turf/proc/AdjacentTurfsRangedSting, /turf/proc/Distance, max_nodes=25, max_node_depth=range))
- return TRUE
- return FALSE
-
-// Check if an object should ignite others, like a lit lighter or candle.
-/obj/item/proc/is_hot()
- return FALSE
\ No newline at end of file
+/obj/item
+ name = "item"
+ icon = 'icons/obj/items.dmi'
+ w_class = ITEMSIZE_NORMAL
+
+ 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 = 0
+ var/r_speed = 1.0
+ var/health = null
+ var/burn_point = null
+ var/burning = null
+ var/hitsound = null
+ var/usesound = null // Like hitsound, but for when used properly and not to kill someone.
+ var/storage_cost = null
+ var/slot_flags = 0 //This is used to determine on which slots an item can fit.
+ var/no_attack_log = 0 //If it's an item we don't want to log attack_logs with, set this to 1
+ pass_flags = PASSTABLE
+ pressure_resistance = 5
+// causeerrorheresoifixthis
+ var/obj/item/master = null
+ var/list/origin_tech = null //Used by R&D to determine what research bonuses it grants.
+ var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
+ var/force = 0
+
+ var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
+ var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
+ 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/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags
+
+ var/datum/action/item_action/action = null
+ var/action_button_name //It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button.
+ var/action_button_is_hands_free = 0 //If 1, bypass the restrained, lying, and stunned checks action buttons normally test for
+
+ //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
+ //It should be used purely for appearance. For gameplay effects caused by items covering body parts, use body_parts_covered.
+ var/flags_inv = 0
+ var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
+
+ var/item_flags = 0 //Miscellaneous flags pertaining to equippable objects.
+
+ //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
+ var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
+ var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
+ var/canremove = 1 //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N
+ var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ var/list/armorsoak = 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/zoomdevicename = null //name used for message when binoculars/scope is used
+ var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars.
+
+ var/embed_chance = -1 //0 won't embed, and 100 will always embed
+
+ var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
+
+ //** These specify item/icon overrides for _slots_
+
+ var/list/item_state_slots = list() //overrides the default item_state for particular slots.
+
+ // Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used.
+ // If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question.
+ // Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed.
+ var/list/item_icons = list()
+
+ //** These specify item/icon overrides for _species_
+
+ /* Species-specific sprites, concept stolen from Paradise//vg/.
+ ex:
+ sprite_sheets = list(
+ "Tajara" = 'icons/cat/are/bad'
+ )
+ If index term exists and icon_override is not set, this sprite sheet will be used.
+ */
+ var/list/sprite_sheets = list()
+
+ // 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 = list()
+
+ var/toolspeed = 1.0 // This is a multipler on how 'fast' a tool works. e.g. setting this to 0.5 will make the tool work twice as fast.
+ var/attackspeed = DEFAULT_ATTACK_COOLDOWN // How long click delay will be when using this, in 1/10ths of a second. Checked in the user's get_attack_speed().
+ var/reach = 1 // Length of tiles it can reach, 1 is adjacent.
+ var/addblends // Icon overlay for ADD highlights when applicable.
+
+/obj/item/New()
+ ..()
+ if(embed_chance < 0)
+ if(sharp)
+ embed_chance = max(5, round(force/w_class))
+ else
+ embed_chance = max(5, round(force/(w_class*3)))
+
+/obj/item/equipped()
+ ..()
+ var/mob/living/M = loc
+ if(!istype(M))
+ return
+ M.update_held_icons()
+
+/obj/item/Destroy()
+ if(ismob(loc))
+ var/mob/m = loc
+ m.drop_from_inventory(src)
+ m.update_inv_r_hand()
+ m.update_inv_l_hand()
+ src.loc = null
+ return ..()
+
+/obj/item/proc/update_twohanding()
+ update_held_icon()
+
+/obj/item/proc/is_held_twohanded(mob/living/M)
+ var/check_hand
+ if(M.l_hand == src && !M.r_hand)
+ check_hand = BP_R_HAND //item in left hand, check right hand
+ else if(M.r_hand == src && !M.l_hand)
+ check_hand = BP_L_HAND //item in right hand, check left hand
+ else
+ return FALSE
+
+ //would check is_broken() and is_malfunctioning() here too but is_malfunctioning()
+ //is probabilistic so we can't do that and it would be unfair to just check one.
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/hand = H.organs_by_name[check_hand]
+ if(istype(hand) && hand.is_usable())
+ return TRUE
+ return FALSE
+
+
+//Checks if the item is being held by a mob, and if so, updates the held icons
+/obj/item/proc/update_held_icon()
+ if(isliving(src.loc))
+ var/mob/living/M = src.loc
+ if(M.l_hand == src)
+ M.update_inv_l_hand()
+ else if(M.r_hand == src)
+ M.update_inv_r_hand()
+
+/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
+
+//user: The mob that is suiciding
+//damagetype: The type of damage the item will inflict on the user
+//BRUTELOSS = 1
+//FIRELOSS = 2
+//TOXLOSS = 4
+//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(src.loc, /turf) || usr.stat || usr.restrained() )
+ return
+
+ var/turf/T = src.loc
+
+ src.loc = null
+
+ src.loc = T
+
+// See inventory_sizes.dm for the defines.
+/obj/item/examine(mob/user, var/distance = -1)
+ var/size
+ switch(src.w_class)
+ if(ITEMSIZE_TINY)
+ size = "tiny"
+ if(ITEMSIZE_SMALL)
+ size = "small"
+ if(ITEMSIZE_NORMAL)
+ size = "normal-sized"
+ if(ITEMSIZE_LARGE)
+ size = "bulky"
+ if(ITEMSIZE_HUGE)
+ size = "huge"
+ return ..(user, distance, "", "It is a [size] item.")
+
+/obj/item/attack_hand(mob/living/user as mob)
+ if (!user) return
+ if (hasorgans(user))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
+ if (user.hand)
+ temp = H.organs_by_name["l_hand"]
+ if(temp && !temp.is_usable())
+ user << "You try to move your [temp.name], but cannot!"
+ return
+ if(!temp)
+ user << "You try to use your hand, but realize it is no longer attached!"
+ return
+ src.pickup(user)
+ if (istype(src.loc, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/S = src.loc
+ S.remove_from_storage(src)
+
+ src.throwing = 0
+ if (src.loc == user)
+ if(!user.unEquip(src))
+ return
+ else
+ if(isliving(src.loc))
+ return
+ user.put_in_active_hand(src)
+ return
+
+/obj/item/attack_ai(mob/user as mob)
+ if (istype(src.loc, /obj/item/weapon/robot_module))
+ //If the item is part of a cyborg module, equip it
+ if(!isrobot(user))
+ return
+ var/mob/living/silicon/robot/R = user
+ R.activate_module(src)
+ R.hud_used.update_robot_modules_display()
+
+/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/S = W
+ if(S.use_to_pickup)
+ if(S.collection_mode) //Mode is set to collect all items
+ if(isturf(src.loc))
+ S.gather_all(src.loc, user)
+
+ else if(S.can_be_inserted(src))
+ S.handle_item_insertion(src)
+ return
+
+/obj/item/proc/talk_into(mob/M as mob, text)
+ return
+
+/obj/item/proc/moved(mob/user as mob, old_loc as turf)
+ return
+
+// apparently called whenever an item is removed from a slot, container, or anything else.
+/obj/item/proc/dropped(mob/user as mob)
+ ..()
+ if(zoom)
+ zoom() //binoculars, scope, etc
+ appearance_flags &= ~NO_CLIENT_COLOR
+
+// called just as an item is picked up (loc is not yet 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/finder as mob)
+ 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)
+ hud_layerise()
+ if(user.client) user.client.screen |= src
+ if(user.pulling == src) user.stop_pulling()
+ return
+
+//Defines which slots correspond to which slot flags
+var/list/global/slot_flags_enumeration = list(
+ "[slot_wear_mask]" = SLOT_MASK,
+ "[slot_back]" = SLOT_BACK,
+ "[slot_wear_suit]" = SLOT_OCLOTHING,
+ "[slot_gloves]" = SLOT_GLOVES,
+ "[slot_shoes]" = SLOT_FEET,
+ "[slot_belt]" = SLOT_BELT,
+ "[slot_glasses]" = SLOT_EYES,
+ "[slot_head]" = SLOT_HEAD,
+ "[slot_l_ear]" = SLOT_EARS|SLOT_TWOEARS,
+ "[slot_r_ear]" = SLOT_EARS|SLOT_TWOEARS,
+ "[slot_w_uniform]" = SLOT_ICLOTHING,
+ "[slot_wear_id]" = SLOT_ID,
+ "[slot_tie]" = SLOT_TIE,
+ )
+
+//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.
+//Should probably move the bulk of this into mob code some time, as most of it is related to the definition of slots and not item-specific
+/obj/item/proc/mob_can_equip(M as mob, slot, disable_warning = 0)
+ if(!slot) return 0
+ if(!M) return 0
+
+ if(!ishuman(M)) return 0
+
+ var/mob/living/carbon/human/H = M
+ var/list/mob_equip = list()
+ if(H.species.hud && H.species.hud.equip_slots)
+ mob_equip = H.species.hud.equip_slots
+
+ if(H.species && !(slot in mob_equip))
+ return 0
+
+ //First check if the item can be equipped to the desired slot.
+ if("[slot]" in slot_flags_enumeration)
+ var/req_flags = slot_flags_enumeration["[slot]"]
+ if(!(req_flags & slot_flags))
+ return 0
+
+ //Next check that the slot is free
+ if(H.get_equipped_item(slot))
+ return 0
+
+ //Next check if the slot is accessible.
+ var/mob/_user = disable_warning? null : H
+ if(!H.slot_is_accessible(slot, src, _user))
+ return 0
+
+ //Lastly, check special rules for the desired slot.
+ switch(slot)
+ if(slot_l_ear, slot_r_ear)
+ var/slot_other_ear = (slot == slot_l_ear)? slot_r_ear : slot_l_ear
+ if( (w_class > ITEMSIZE_TINY) && !(slot_flags & SLOT_EARS) )
+ return 0
+ if( (slot_flags & SLOT_TWOEARS) && H.get_equipped_item(slot_other_ear) )
+ return 0
+ if(slot_wear_id)
+ if(!H.w_uniform && (slot_w_uniform in mob_equip))
+ if(!disable_warning)
+ H << "You need a jumpsuit before you can attach this [name]."
+ return 0
+ if(slot_l_store, slot_r_store)
+ if(!H.w_uniform && (slot_w_uniform in mob_equip))
+ if(!disable_warning)
+ H << "You need a jumpsuit before you can attach this [name]."
+ return 0
+ if(slot_flags & SLOT_DENYPOCKET)
+ return 0
+ if( w_class > ITEMSIZE_SMALL && !(slot_flags & SLOT_POCKET) )
+ return 0
+ if(slot_s_store)
+ if(!H.wear_suit && (slot_wear_suit in mob_equip))
+ if(!disable_warning)
+ H << "You need a suit before you can attach this [name]."
+ return 0
+ if(!H.wear_suit.allowed)
+ if(!disable_warning)
+ usr << "You somehow have a suit with no defined allowed items for suit storage, stop that."
+ return 0
+ if( !(istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed)) )
+ return 0
+ if(slot_legcuffed) //Going to put this check above the handcuff check because the survival of the universe depends on it.
+ if(!istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Putting it here might actually do nothing.
+ return 0
+ if(slot_handcuffed)
+ if(!istype(src, /obj/item/weapon/handcuffs) || istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Legcuffs are a child of handcuffs, but we don't want to use legcuffs as handcuffs...
+ return 0 //In theory, this would never happen, but let's just do the legcuff check anyways.
+ if(slot_in_backpack) //used entirely for equipping spawned mobs or at round start
+ var/allow = 0
+ if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))
+ var/obj/item/weapon/storage/backpack/B = H.back
+ if(B.can_be_inserted(src,1))
+ allow = 1
+ if(!allow)
+ return 0
+ if(slot_tie)
+ if(!H.w_uniform && (slot_w_uniform in mob_equip))
+ if(!disable_warning)
+ H << "You need a jumpsuit before you can attach this [name]."
+ return 0
+ var/obj/item/clothing/under/uniform = H.w_uniform
+ if(uniform.accessories.len && !uniform.can_attach_accessory(src))
+ if (!disable_warning)
+ H << "You already have an accessory of this type attached to your [uniform]."
+ return 0
+ return 1
+
+/obj/item/proc/mob_can_unequip(mob/M, slot, disable_warning = 0)
+ if(!slot) return 0
+ if(!M) return 0
+
+ if(!canremove)
+ return 0
+ if(!M.slot_is_accessible(slot, src, disable_warning? null : M))
+ return 0
+ return 1
+
+/obj/item/verb/verb_pickup()
+ set src in oview(1)
+ set category = "Object"
+ set name = "Pick up"
+
+ if(!(usr)) //BS12 EDIT
+ return
+ if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
+ return
+ if((!istype(usr, /mob/living/carbon)) || (istype(usr, /mob/living/carbon/brain)))//Is humanoid, and is not a brain
+ usr << "You can't pick things up!"
+ return
+ var/mob/living/carbon/C = usr
+ if( usr.stat || usr.restrained() )//Is not asleep/dead and is not restrained
+ usr << "You can't pick things up!"
+ return
+ if(src.anchored) //Object isn't anchored
+ usr << "You can't pick that up!"
+ return
+ if(C.get_active_hand()) //Hand is not full
+ usr << "Your hand is full."
+ return
+ if(!istype(src.loc, /turf)) //Object is on a turf
+ usr << "You can't pick that up!"
+ return
+ //All checks are done, time to pick it up!
+ usr.UnarmedAttack(src)
+ return
+
+
+//This proc is executed when someone clicks the on-screen UI button. To make the UI button show, set the 'icon_action_button' to the icon_state of the image of the button in screen1_action.dmi
+//The default action is attack_self().
+//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob.
+/obj/item/proc/ui_action_click()
+ attack_self(usr)
+
+//RETURN VALUES
+//handle_shield should return a positive value to indicate that the attack is blocked and should be prevented.
+//If a negative value is returned, it should be treated as a special return value for bullet_act() and handled appropriately.
+//For non-projectile attacks this usually means the attack is blocked.
+//Otherwise should return 0 to indicate that the attack is not affected in any way.
+/obj/item/proc/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+ return 0
+
+/obj/item/proc/get_loc_turf()
+ var/atom/L = loc
+ while(L && !istype(L, /turf/))
+ L = L.loc
+ return loc
+
+/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+
+ var/mob/living/carbon/human/H = M
+ var/mob/living/carbon/human/U = user
+ if(istype(H))
+ for(var/obj/item/protection in list(H.head, H.wear_mask, H.glasses))
+ if(protection && (protection.body_parts_covered & EYES))
+ // you can't stab someone in the eyes wearing a mask!
+ user << "You're going to need to remove the eye covering first."
+ return
+
+ if(!M.has_eyes())
+ user << "You cannot locate any eyes on [M]!"
+ return
+
+ if(U.get_accuracy_penalty(U)) //Should only trigger if they're not aiming well
+ var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
+ if(!hit_zone)
+ U.do_attack_animation(M)
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ visible_message("[U] attempts to stab [M] in the eyes, but misses!")
+ return
+
+ user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
+ M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
+ msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG
+
+ user.setClickCooldown(user.get_attack_speed())
+ user.do_attack_animation(M)
+
+ src.add_fingerprint(user)
+ //if((CLUMSY in user.mutations) && prob(50))
+ // M = user
+ /*
+ M << "You stab yourself in the eye."
+ M.sdisabilities |= BLIND
+ M.weakened += 4
+ M.adjustBruteLoss(10)
+ */
+
+ if(istype(H))
+
+ var/obj/item/organ/internal/eyes/eyes = H.internal_organs_by_name[O_EYES]
+
+ if(H != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("[M] has been stabbed in the eye with [src] by [user].", 1)
+ M << "[user] stabs you in the eye with [src]!"
+ user << "You stab [M] in the eye with [src]!"
+ else
+ user.visible_message( \
+ "[user] has stabbed themself with [src]!", \
+ "You stab yourself in the eyes with [src]!" \
+ )
+
+ eyes.damage += rand(3,4)
+ if(eyes.damage >= eyes.min_bruised_damage)
+ if(M.stat != 2)
+ if(!(eyes.robotic >= ORGAN_ROBOT)) //robot eyes bleeding might be a bit silly
+ M << "Your eyes start to bleed profusely!"
+ if(prob(50))
+ if(M.stat != 2)
+ M << "You drop what you're holding and clutch at your eyes!"
+ M.drop_item()
+ M.eye_blurry += 10
+ M.Paralyse(1)
+ M.Weaken(4)
+ if (eyes.damage >= eyes.min_broken_damage)
+ if(M.stat != 2)
+ M << "You go blind!"
+ var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD)
+ if(affecting.take_damage(7))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(7)
+ M.eye_blurry += rand(3,4)
+ return
+
+/obj/item/clean_blood()
+ . = ..()
+ if(blood_overlay)
+ overlays.Remove(blood_overlay)
+ if(istype(src, /obj/item/clothing/gloves))
+ var/obj/item/clothing/gloves/G = src
+ G.transfer_blood = 0
+
+/obj/item/reveal_blood()
+ if(was_bloodied && !fluorescent)
+ fluorescent = 1
+ blood_color = COLOR_LUMINOL
+ blood_overlay.color = COLOR_LUMINOL
+ update_icon()
+
+/obj/item/add_blood(mob/living/carbon/human/M as mob)
+ if (!..())
+ return 0
+
+ if(istype(src, /obj/item/weapon/melee/energy))
+ return
+
+ //if we haven't made our blood_overlay already
+ if( !blood_overlay )
+ generate_blood_overlay()
+
+ //apply the blood-splatter overlay if it isn't already in there
+ if(!blood_DNA.len)
+ blood_overlay.color = blood_color
+ overlays += blood_overlay
+
+ //if this blood isn't already in the list, add it
+ if(istype(M))
+ if(blood_DNA[M.dna.unique_enzymes])
+ return 0 //already bloodied with this blood. Cannot add more.
+ blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
+ return 1 //we applied blood to the item
+
+/obj/item/proc/generate_blood_overlay()
+ if(blood_overlay)
+ 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
+
+ //not sure if this is worth it. It attaches the blood_overlay to every item of the same type if they don't have one already made.
+ for(var/obj/item/A in world)
+ if(A.type == type && !A.blood_overlay)
+ A.blood_overlay = image(I)
+
+/obj/item/proc/showoff(mob/user)
+ for (var/mob/M in view(user))
+ M.show_message("[user] holds up [src]. Take a closer look.",1)
+
+/mob/living/carbon/verb/showoff()
+ set name = "Show Held Item"
+ set category = "Object"
+
+ var/obj/item/I = get_active_hand()
+ if(I && !I.abstract)
+ I.showoff(src)
+
+/*
+For zooming with scope or binoculars. This is called from
+modules/mob/mob_movement.dm if you move you will be zoomed out
+modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
+*/
+//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW
+/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view
+
+ var/devicename
+
+ if(zoomdevicename)
+ devicename = zoomdevicename
+ else
+ devicename = src.name
+
+ var/cannotzoom
+
+ if(usr.stat || !(istype(usr,/mob/living/carbon/human)))
+ usr << "You are unable to focus through the [devicename]"
+ cannotzoom = 1
+ else if(!zoom && global_hud.darkMask[1] in usr.client.screen)
+ usr << "Your visor gets in the way of looking through the [devicename]"
+ cannotzoom = 1
+ else if(!zoom && usr.get_active_hand() != src)
+ usr << "You are too distracted to look through the [devicename], perhaps if it was in your active hand this might work better"
+ cannotzoom = 1
+
+ if(!zoom && !cannotzoom)
+ if(usr.hud_used.hud_shown)
+ usr.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
+ usr.client.view = viewsize
+ zoom = 1
+
+ var/tilesize = 32
+ var/viewoffset = tilesize * tileoffset
+
+ switch(usr.dir)
+ if (NORTH)
+ usr.client.pixel_x = 0
+ usr.client.pixel_y = viewoffset
+ if (SOUTH)
+ usr.client.pixel_x = 0
+ usr.client.pixel_y = -viewoffset
+ if (EAST)
+ usr.client.pixel_x = viewoffset
+ usr.client.pixel_y = 0
+ if (WEST)
+ usr.client.pixel_x = -viewoffset
+ usr.client.pixel_y = 0
+
+ usr.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].")
+
+ else
+ usr.client.view = world.view
+ if(!usr.hud_used.hud_shown)
+ usr.toggle_zoom_hud()
+ zoom = 0
+
+ usr.client.pixel_x = 0
+ usr.client.pixel_y = 0
+
+ if(!cannotzoom)
+ usr.visible_message("[zoomdevicename ? "[usr] looks up from the [src.name]" : "[usr] lowers the [src.name]"].")
+
+ return
+
+/obj/item/proc/pwr_drain()
+ return 0 // Process Kill
+
+// Used for non-adjacent melee attacks with specific weapons capable of reaching more than one tile.
+// This uses changeling range string A* but for this purpose its also applicable.
+/obj/item/proc/attack_can_reach(var/atom/us, var/atom/them, var/range)
+ if(us.Adjacent(them))
+ return TRUE // Already adjacent.
+ if(AStar(get_turf(us), get_turf(them), /turf/proc/AdjacentTurfsRangedSting, /turf/proc/Distance, max_nodes=25, max_node_depth=range))
+ return TRUE
+ return FALSE
+
+// Check if an object should ignite others, like a lit lighter or candle.
+/obj/item/proc/is_hot()
+ return FALSE
+
+// My best guess as to why this is here would be that it does so little. Still, keep it under all the procs, for sanity's sake.
+/obj/item/device
+ icon = 'icons/obj/device.dmi'
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm
index 7aa29c7932..6631ec25fa 100644
--- a/code/game/objects/items/weapons/material/twohanded.dm
+++ b/code/game/objects/items/weapons/material/twohanded.dm
@@ -29,7 +29,7 @@
/obj/item/weapon/material/twohanded/update_held_icon()
var/mob/living/M = loc
- if(istype(M) && !issmall(M) && M.item_is_in_hands(src) && !M.hands_are_full())
+ if(istype(M) && M.can_wield_item(src) && is_held_twohanded(M))
wielded = 1
force = force_wielded
name = "[base_name] (wielded)"
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index b86471bf84..b0fe0ae096 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -430,6 +430,7 @@
P.icon = initial(copy_projectile.icon)
P.icon_state = initial(copy_projectile.icon_state)
P.pass_flags = initial(copy_projectile.pass_flags)
+ P.fire_sound = initial(copy_projectile.fire_sound)
P.hitscan = initial(copy_projectile.hitscan)
P.step_delay = initial(copy_projectile.step_delay)
P.muzzle_type = initial(copy_projectile.muzzle_type)
@@ -451,12 +452,15 @@
var/obj/item/weapon/gun/copy = ..()
flags_inv = copy.flags_inv
- fire_sound = copy.fire_sound
+ if(copy.fire_sound)
+ fire_sound = copy.fire_sound
+ else
+ fire_sound = null
fire_sound_text = copy.fire_sound_text
- var/obj/item/weapon/gun/energy/E = copy
- if(istype(E))
- copy_projectile = E.projectile_type
+ var/obj/item/weapon/gun/G = copy
+ if(istype(G))
+ copy_projectile = G.projectile_type
//charge_meter = E.charge_meter //does not work very well with icon_state changes, ATM
else
copy_projectile = null
diff --git a/code/modules/mob/_modifiers/cloning.dm b/code/modules/mob/_modifiers/cloning.dm
index a5e8e5e2ba..c3f8827f7b 100644
--- a/code/modules/mob/_modifiers/cloning.dm
+++ b/code/modules/mob/_modifiers/cloning.dm
@@ -15,7 +15,7 @@
outgoing_melee_damage_percent = 0.7 // 30% less melee damage.
disable_duration_percent = 1.25 // Stuns last 25% longer.
slowdown = 1 // Slower.
- evasion = -1 // 15% easier to hit.
+ evasion = -15 // 15% easier to hit.
// Tracks number of deaths, one modifier added per cloning
/datum/modifier/cloned
diff --git a/code/modules/mob/_modifiers/modifiers.dm b/code/modules/mob/_modifiers/modifiers.dm
index 7c005838d1..71b337b1b3 100644
--- a/code/modules/mob/_modifiers/modifiers.dm
+++ b/code/modules/mob/_modifiers/modifiers.dm
@@ -37,9 +37,9 @@
var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand.
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
- var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
+ var/evasion // Positive numbers reduce the odds of being hit. Negative numbers increase the odds.
var/bleeding_rate_percent // Adjusts amount of blood lost when bleeding.
- var/accuracy // Positive numbers makes hitting things with guns easier, negatives make it harder. Each point makes it 15% easier or harder, just like evasion.
+ var/accuracy // Positive numbers makes hitting things with guns easier, negatives make it harder. Every 15% is equal to one tile easier or harder, just like evasion.
var/accuracy_dispersion // Positive numbers make gun firing cover a wider tile range, and therefore more inaccurate. Negatives help negate dispersion penalties.
var/metabolism_percent // Adjusts the mob's metabolic rate, which affects reagent processing. Won't affect mobs without reagent processing.
var/icon_scale_percent // Makes the holder's icon get scaled up or down.
diff --git a/code/modules/mob/_modifiers/traits.dm b/code/modules/mob/_modifiers/traits.dm
index eac919b106..453c17f321 100644
--- a/code/modules/mob/_modifiers/traits.dm
+++ b/code/modules/mob/_modifiers/traits.dm
@@ -43,7 +43,7 @@
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
Regardless, you find it quite difficult to land shots where you wanted them to go."
- accuracy = -1
+ accuracy = -15
accuracy_dispersion = 1
/datum/modifier/trait/high_metabolism
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 187ddcac7e..5c269c7ce2 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -164,12 +164,14 @@ This saves us from having to call add_fingerprint() any time something is put in
else if (W == r_hand)
r_hand = null
if(l_hand)
+ l_hand.update_twohanding()
l_hand.update_held_icon()
update_inv_l_hand()
update_inv_r_hand()
else if (W == l_hand)
l_hand = null
if(r_hand)
+ r_hand.update_twohanding()
r_hand.update_held_icon()
update_inv_l_hand()
update_inv_l_hand()
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index d1deeebffd..a7f85be9a8 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -45,7 +45,7 @@
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
var/lastpuke = 0
- var/evasion = 0 // Makes attacks harder to land. Each number equals 15% more likely to miss. Negative numbers increase hit chance.
+ var/evasion = 0 // Makes attacks harder to land. Negative numbers increase hit chance.
var/force_max_speed = 0 // If 1, the mob runs extremely fast and cannot be slowed.
var/image/dsoverlay = null //Overlay used for darksight eye adjustments
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 0a623059eb..451bac05d6 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -15,6 +15,11 @@
/proc/mob_size_difference(var/mob_size_A, var/mob_size_B)
return round(log(2, mob_size_A/mob_size_B), 1)
+/mob/proc/can_wield_item(obj/item/W)
+ if(W.w_class >= ITEMSIZE_LARGE && issmall(src))
+ return FALSE //M is too small to wield this
+ return TRUE
+
/proc/istiny(A)
if(A && istype(A, /mob/living))
var/mob/living/L = A
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 187adc142e..2a99ca840d 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -18,7 +18,7 @@
if(propname == "mode_name")
name = propvalue
- if(isnull(propvalue))
+ else if(isnull(propvalue))
settings[propname] = gun.vars[propname] //better than initial() as it handles list vars like burst_accuracy
else
settings[propname] = propvalue
@@ -61,13 +61,14 @@
var/recoil = 0 //screen shake
var/silenced = 0
var/muzzle_flash = 3
- var/accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment.
+ var/accuracy = 0 //Accuracy is measured in percents. +15 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -15 means the opposite. launchers are not supported, at the moment.
var/scoped_accuracy = null
var/list/burst_accuracy = list(0) //allows for different accuracies for each shot in a burst. Applied on top of accuracy
var/list/dispersion = list(0)
var/mode_name = null
- var/requires_two_hands
- var/wielded_icon = "gun_wielded"
+ var/projectile_type = /obj/item/projectile //On ballistics, only used to check for the cham gun
+
+ var/wielded_item_state
var/one_handed_penalty = 0 // Penalty applied if someone fires a two-handed gun with one hand.
var/obj/screen/auto_target/auto_target
var/shooting = 0
@@ -104,19 +105,32 @@
verbs -= /obj/item/weapon/gun/verb/give_dna
verbs -= /obj/item/weapon/gun/verb/allow_dna
-/obj/item/weapon/gun/update_held_icon()
- if(requires_two_hands)
+/obj/item/weapon/gun/update_twohanding()
+ if(one_handed_penalty)
var/mob/living/M = loc
if(istype(M))
- if(M.item_is_in_hands(src) && !M.hands_are_full())
+ if(M.can_wield_item(src) && src.is_held_twohanded(M))
name = "[initial(name)] (wielded)"
- item_state = wielded_icon
else
name = initial(name)
- item_state = initial(item_state)
- update_icon(ignore_inhands=1) // In case item_state is set somewhere else.
+ else
+ name = initial(name)
+ update_icon() // In case item_state is set somewhere else.
..()
+/obj/item/weapon/gun/update_held_icon()
+ if(wielded_item_state)
+ var/mob/living/M = loc
+ if(istype(M))
+ if(M.can_wield_item(src) && src.is_held_twohanded(M))
+ item_state_slots[slot_l_hand_str] = wielded_item_state
+ item_state_slots[slot_r_hand_str] = wielded_item_state
+ else
+ item_state_slots[slot_l_hand_str] = initial(item_state)
+ item_state_slots[slot_r_hand_str] = initial(item_state)
+ ..()
+
+
//Checks whether a given mob can use the gun
//Any checks that shouldn't result in handle_click_empty() being called if they fail should go here.
//Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there.
@@ -243,6 +257,7 @@
verbs -= /obj/item/weapon/gun/verb/allow_dna
else
user << "\The [src] is not accepting modifications at this time."
+ ..()
/obj/item/weapon/gun/emag_act(var/remaining_charges, var/mob/user)
if(dna_lock && attached_lock.controller_lock)
@@ -286,6 +301,7 @@
/obj/item/weapon/gun/proc/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0)
if(!user || !target) return
+ if(target.z != user.z) return
add_fingerprint(user)
@@ -307,12 +323,7 @@
next_fire_time = world.time + shoot_time
- var/held_acc_mod = 0
- var/held_disp_mod = 0
- if(requires_two_hands)
- if(user.item_is_in_hands(src) && user.hands_are_full())
- held_acc_mod = held_acc_mod - one_handed_penalty
- held_disp_mod = held_disp_mod - round(one_handed_penalty / 2)
+ var/held_twohanded = (user.can_wield_item(src) && src.is_held_twohanded(user))
//actually attempt to shoot
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
@@ -342,9 +353,7 @@
handle_click_empty(user)
break
- var/acc = burst_accuracy[min(i, burst_accuracy.len)] + held_acc_mod
- var/disp = dispersion[min(i, dispersion.len)] + held_disp_mod
- process_accuracy(projectile, user, target, acc, disp)
+ process_accuracy(projectile, user, target, i, held_twohanded)
if(pointblank)
process_point_blank(projectile, user, target)
@@ -366,10 +375,9 @@
shooting = 0
*/
// We do this down here, so we don't get the message if we fire an empty gun.
- if(requires_two_hands)
- if(user.item_is_in_hands(src) && user.hands_are_full())
- if(one_handed_penalty >= 2)
- user << "You struggle to keep \the [src] pointed at the correct position with just one hand!"
+ if(user.item_is_in_hands(src) && user.hands_are_full())
+ if(one_handed_penalty >= 20)
+ to_chat(user, "You struggle to keep \the [src] pointed at the correct position with just one hand!")
if(reflex)
admin_attack_log(user, target, attacker_message = "fired [src] by reflex.", victim_message = "triggered a reflex shot from [src].", admin_message = "shot [target], who triggered gunfire ([src]) by reflex)")
@@ -483,25 +491,45 @@
//called after successfully firing
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(silenced)
- playsound(user, fire_sound, 10, 1)
- to_chat(user, "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]")
- for(var/mob/living/L in oview(2,user))
- if(L.stat)
- continue
- if(L.blinded)
- to_chat(L, "You hear a [fire_sound_text]!")
- continue
- to_chat(L, "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]")
- else
- playsound(user, fire_sound, 50, 1)
- user.visible_message(
- "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]",
- "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]",
- "You hear a [fire_sound_text]!"
- )
+ if(reflex)
+ user.visible_message(
+ "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""] by reflex!",
+ "You fire \the [src] by reflex!",
+ "You hear a [fire_sound_text]!"
+ )
+ else
+ user.visible_message(
+ "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""]!",
+ "You fire \the [src]!",
+ "You hear a [fire_sound_text]!"
+ )
- if(muzzle_flash)
- set_light(muzzle_flash)
+ if(muzzle_flash)
+ set_light(muzzle_flash)
+
+ if(one_handed_penalty)
+ if(!src.is_held_twohanded(user))
+ switch(one_handed_penalty)
+ if(1 to 15)
+ if(prob(50)) //don't need to tell them every single time
+ to_chat(user, "Your aim wavers slightly.")
+ if(16 to 30)
+ to_chat(user, "Your aim wavers as you fire \the [src] with just one hand.")
+ if(31 to 45)
+ to_chat(user, "You have trouble keeping \the [src] on target with just one hand.")
+ if(46 to INFINITY)
+ to_chat(user, "You struggle to keep \the [src] on target with just one hand!")
+ else if(!user.can_wield_item(src))
+ switch(one_handed_penalty)
+ if(1 to 15)
+ if(prob(50)) //don't need to tell them every single time
+ to_chat(user, "Your aim wavers slightly.")
+ if(16 to 30)
+ to_chat(user, "Your aim wavers as you try to hold \the [src] steady.")
+ if(31 to 45)
+ to_chat(user, "You have trouble holding \the [src] steady.")
+ if(46 to INFINITY)
+ to_chat(user, "You struggle to hold \the [src] steady!")
if(recoil)
spawn()
@@ -530,29 +558,37 @@
damage_mult = 1.5
P.damage *= damage_mult
-/obj/item/weapon/gun/proc/process_accuracy(obj/projectile, mob/living/user, atom/target, acc_mod, dispersion)
+/obj/item/weapon/gun/proc/process_accuracy(obj/projectile, mob/living/user, atom/target, var/burst, var/held_twohanded)
var/obj/item/projectile/P = projectile
if(!istype(P))
return //default behaviour only applies to true projectiles
+ var/acc_mod = burst_accuracy[min(burst, burst_accuracy.len)]
+ var/disp_mod = dispersion[min(burst, dispersion.len)]
+
+ if(one_handed_penalty)
+ if(!held_twohanded)
+ acc_mod += -ceil(one_handed_penalty/2)
+ disp_mod += one_handed_penalty*0.5 //dispersion per point of two-handedness
+
//Accuracy modifiers
P.accuracy = accuracy + acc_mod
- P.dispersion = dispersion
+ P.dispersion = disp_mod
// Certain statuses make it harder to aim, blindness especially. Same chances as melee, however guns accuracy uses multiples of 15.
if(user.eye_blind)
- P.accuracy -= 5
+ P.accuracy -= 75
if(user.eye_blurry)
- P.accuracy -= 2
+ P.accuracy -= 30
if(user.confused)
- P.accuracy -= 3
+ P.accuracy -= 45
//accuracy bonus from aiming
if (aim_targets && (target in aim_targets))
//If you aim at someone beforehead, it'll hit more often.
//Kinda balanced by fact you need like 2 seconds to aim
//As opposed to no-delay pew pew
- P.accuracy += 2
+ P.accuracy += 30
// Some modifiers make it harder or easier to hit things.
for(var/datum/modifier/M in user.modifiers)
@@ -582,17 +618,24 @@
y_offset = rand(-1,1)
x_offset = rand(-1,1)
- return !P.launch_from_gun(target, user, src, target_zone, x_offset, y_offset)
+ var/launched = !P.launch_from_gun(target, user, src, target_zone, x_offset, y_offset)
-//apart of reskins that have two sprites, touching may result in frustration and breaks
-/obj/item/weapon/gun/projectile/colt/detective/attack_hand(var/mob/living/user)
- if(!unique_reskin && loc == user)
- reskin_gun(user)
- return
- ..()
+ if(launched)
+ play_fire_sound(user, P)
+
+ return launched
+
+
+/obj/item/weapon/gun/proc/play_fire_sound(var/mob/user, var/obj/item/projectile/P)
+ var/shot_sound = (istype(P) && P.fire_sound)? P.fire_sound : fire_sound
+ if(silenced)
+ playsound(user, shot_sound, 10, 1)
+ else
+ playsound(user, shot_sound, 50, 1)
//Suicide handling.
/obj/item/weapon/gun/var/mouthshoot = 0 //To stop people from suiciding twice... >.>
+
/obj/item/weapon/gun/proc/handle_suicide(mob/living/user)
if(!ishuman(user))
return
@@ -607,10 +650,11 @@
var/obj/item/projectile/in_chamber = consume_next_projectile()
if (istype(in_chamber))
user.visible_message("[user] pulls the trigger.")
+ var/shot_sound = in_chamber.fire_sound? in_chamber.fire_sound : fire_sound
if(silenced)
- playsound(user, fire_sound, 10, 1)
+ playsound(user, shot_sound, 10, 1)
else
- playsound(user, fire_sound, 50, 1)
+ playsound(user, shot_sound, 50, 1)
if(istype(in_chamber, /obj/item/projectile/beam/lastertag))
user.show_message("You feel rather silly, trying to commit suicide with a toy.")
mouthshoot = 0
@@ -656,7 +700,7 @@
..()
if(firemodes.len > 1)
var/datum/firemode/current_mode = firemodes[sel_mode]
- user << "The fire selector is set to [current_mode.name]."
+ to_chat(user, "The fire selector is set to [current_mode.name].")
/obj/item/weapon/gun/proc/switch_firemodes(mob/user)
if(firemodes.len <= 1)
@@ -667,7 +711,7 @@
sel_mode = 1
var/datum/firemode/new_mode = firemodes[sel_mode]
new_mode.apply_to(src)
- user << "\The [src] is now set to [mode_name]."
+ to_chat(user, "\The [src] is now set to [new_mode.name].")
return new_mode
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 447eefe1b8..207d64e6f6 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -7,8 +7,10 @@
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
var/charge_cost = 240 //How much energy is needed to fire.
+
var/cell_type = /obj/item/weapon/cell/device/weapon
- var/projectile_type = /obj/item/projectile/beam/practice
+ projectile_type = /obj/item/projectile/beam/practice
+
var/modifystate
var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index d7ef652b2f..7fa20d8c5d 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -4,7 +4,7 @@
switch between standard fire and a more efficent but weaker 'suppressive' fire."
icon_state = "laser"
item_state = "laser"
- fire_sound = 'sound/weapons/Laser.ogg'
+ wielded_item_state = "laser-wielded"
fire_delay = 8
slot_flags = SLOT_BELT|SLOT_BACK
w_class = ITEMSIZE_LARGE
@@ -12,8 +12,7 @@
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
matter = list(DEFAULT_WALL_MATERIAL = 2000)
projectile_type = /obj/item/projectile/beam/midlaser
-// requires_two_hands = 1
- one_handed_penalty = 2
+// one_handed_penalty = 30
firemodes = list(
list(mode_name="normal", fire_delay=8, projectile_type=/obj/item/projectile/beam/midlaser, charge_cost = 240),
@@ -23,7 +22,7 @@
/obj/item/weapon/gun/energy/laser/mounted
self_recharge = 1
use_external_power = 1
- requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
+ one_handed_penalty = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
/obj/item/weapon/gun/energy/laser/practice
name = "practice laser carbine"
@@ -43,7 +42,6 @@
icon_state = "retro"
item_state = "retro"
desc = "An older model of the basic lasergun. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
- fire_sound = 'sound/weapons/Laser.ogg'
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
projectile_type = /obj/item/projectile/beam
@@ -79,7 +77,6 @@
item_state = "caplaser"
desc = "A rare weapon, handcrafted by a now defunct specialty manufacturer on Luna for a small fortune. It's certainly aged well."
force = 5
- fire_sound = 'sound/weapons/Laser.ogg'
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
projectile_type = /obj/item/projectile/beam
@@ -95,15 +92,13 @@
flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
icon_state = "lasercannon"
item_state = null
- fire_sound = 'sound/weapons/lasercannonfire.ogg'
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = /obj/item/projectile/beam/heavylaser/cannon
battery_lock = 1
fire_delay = 20
w_class = ITEMSIZE_LARGE
-// requires_two_hands = 1
- one_handed_penalty = 6 // The thing's heavy and huge.
+// one_handed_penalty = 90 // The thing's heavy and huge.
accuracy = 3
charge_cost = 600
@@ -113,7 +108,7 @@
use_external_power = 1
recharge_time = 10
accuracy = 0 // Mounted cannons are just fine the way they are.
- requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
+ one_handed_penalty = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
projectile_type = /obj/item/projectile/beam/heavylaser
charge_cost = 400
fire_delay = 20
@@ -124,7 +119,6 @@
standard photonic beams, resulting in an effective 'anti-armor' energy weapon."
icon_state = "xray"
item_state = "xray"
- fire_sound = 'sound/weapons/eluger.ogg'
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 3, TECH_MAGNET = 2)
projectile_type = /obj/item/projectile/beam/xray
charge_cost = 200
@@ -145,10 +139,10 @@
fire_delay = 35
force = 10
w_class = ITEMSIZE_HUGE // So it can't fit in a backpack.
- accuracy = -3 //shooting at the hip
+ accuracy = -45 //shooting at the hip
scoped_accuracy = 0
// requires_two_hands = 1
- one_handed_penalty = 4 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand.
+// one_handed_penalty = 60 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand.
/obj/item/weapon/gun/energy/sniperrifle/verb/scope()
set category = "Object"
@@ -165,7 +159,6 @@
desc = "Standard issue weapon of the Imperial Guard"
origin_tech = list(TECH_COMBAT = 1, TECH_MAGNET = 2)
matter = list(DEFAULT_WALL_MATERIAL = 2000)
- fire_sound = 'sound/weapons/Laser.ogg'
projectile_type = /obj/item/projectile/beam/lastertag/blue
cell_type = /obj/item/weapon/cell/device/weapon/recharge
battery_lock = 1
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index 048dddfe3f..e7e19b9e02 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -3,7 +3,6 @@
desc = "Another bestseller of Lawson Arms and the FTU, the LAEP90 Perun is a versatile energy based sidearm, capable of switching between low and high capacity projectile settings. In other words: Stun or Kill."
icon_state = "energystun100"
item_state = null //so the human update icon uses the icon_state instead.
- fire_sound = 'sound/weapons/Taser.ogg'
fire_delay = 10 // Handguns should be inferior to two-handed weapons.
projectile_type = /obj/item/projectile/beam/stun/med
@@ -11,8 +10,8 @@
modifystate = "energystun"
firemodes = list(
- list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="energystun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
- list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="energystun", charge_cost = 240),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill", charge_cost = 480),
)
/obj/item/weapon/gun/energy/gun/mounted
@@ -26,7 +25,6 @@
desc = "The FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings."
icon_state = "fm-2tstun100" //May resprite this to be more rifley
item_state = null //so the human update icon uses the icon_state instead.
- fire_sound = 'sound/weapons/Taser.ogg'
charge_cost = 100
force = 8
w_class = ITEMSIZE_LARGE //Probably gonna make it a rifle sooner or later
@@ -37,13 +35,13 @@
modifystate = "fm-2tstun"
// requires_two_hands = 1
- one_handed_penalty = 2
+// one_handed_penalty = 30
firemodes = list(
- list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 100),
- list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'),
- list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 200),
- list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'),
+ list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", charge_cost = 100),
+ list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun"),
+ list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", charge_cost = 200),
+ list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill"),
)
/obj/item/weapon/gun/energy/gun/nuclear
@@ -61,9 +59,9 @@
modifystate = null
// requires_two_hands = 1
- one_handed_penalty = 1 // It's rather bulky, so holding it in one hand is a little harder than with two, however it's not 'required'.
+// one_handed_penalty = 15 // It's rather bulky, so holding it in one hand is a little harder than with two, however it's not 'required'.
firemodes = list(
- list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="nucgunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
- list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="nucgunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="nucgunstun", charge_cost = 240),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="nucgunkill", charge_cost = 480),
)
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm
index 2bcb2db771..6513a00052 100644
--- a/code/modules/projectiles/guns/energy/pulse.dm
+++ b/code/modules/projectiles/guns/energy/pulse.dm
@@ -5,15 +5,14 @@
item_state = null //so the human update icon uses the icon_state instead.
slot_flags = SLOT_BELT|SLOT_BACK
force = 10
- fire_sound='sound/weapons/Laser.ogg'
projectile_type = /obj/item/projectile/beam
charge_cost = 120
sel_mode = 2
firemodes = list(
- list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg', fire_delay=null, charge_cost = 120),
- list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_sound='sound/weapons/Laser.ogg', fire_delay=null, charge_cost = 120),
- list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/gauss_shoot.ogg', fire_delay=null, charge_cost = 240),
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 120),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 120),
+ list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 240),
)
/obj/item/weapon/gun/energy/pulse_rifle/mounted
@@ -39,7 +38,7 @@
charge_cost = 240
firemodes = list(
- list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg', fire_delay=null, charge_cost = 240),
- list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_sound='sound/weapons/Laser.ogg', fire_delay=null, charge_cost = 240),
- list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/gauss_shoot.ogg', fire_delay=null, charge_cost = 480),
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 240),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 240),
+ list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 480),
)
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index beb44e1a3e..8bda4d37ac 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -3,7 +3,6 @@
desc = "The NT Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. Not the best of its type."
icon_state = "ionrifle"
item_state = "ionrifle"
- fire_sound = 'sound/weapons/Laser.ogg'
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 4)
w_class = ITEMSIZE_LARGE
force = 10
@@ -202,12 +201,12 @@ obj/item/weapon/gun/energy/staff/focus
projectile_type = /obj/item/projectile/energy/blue_pellet
cell_type = /obj/item/weapon/cell/device/weapon/recharge
battery_lock = 1
- accuracy = 5 // Suppressive weapons don't work too well if there's no risk of being hit.
+ accuracy = 75 // Suppressive weapons don't work too well if there's no risk of being hit.
burst_delay = 1 // Burst faster than average.
origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6)
firemodes = list(
- list(mode_name="single shot", burst = 1, burst_accuracy = list(5), dispersion = list(0), charge_cost = 24),
- list(mode_name="five shot burst", burst = 5, burst_accuracy = list(5,5,5,5,5), dispersion = list(1,1,1,1,1)),
- list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2))
+ list(mode_name="single shot", burst = 1, burst_accuracy = list(75), dispersion = list(0), charge_cost = 24),
+ list(mode_name="five shot burst", burst = 5, burst_accuracy = list(75,75,75,75,75), dispersion = list(1,1,1,1,1)),
+ list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(75,75,75,75,75,75,75,75,75,75), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
)
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 43bb9e1637..312a6b0648 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -3,7 +3,6 @@
desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T design."
icon_state = "taser"
item_state = null //so the human update icon uses the icon_state instead.
- fire_sound = 'sound/weapons/Taser.ogg'
projectile_type = /obj/item/projectile/beam/stun
/obj/item/weapon/gun/energy/taser/mounted
@@ -22,7 +21,6 @@
desc = "A LAEP20 Zeus. Designed by Lawson Arms and produced under the wing of Hephaestus, several TSCs have been trying to get a hold of the blueprints for half a decade."
icon_state = "stunrevolver"
item_state = "stunrevolver"
- fire_sound = 'sound/weapons/Gunshot.ogg'
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
projectile_type = /obj/item/projectile/energy/electrode/strong
charge_cost = 300
@@ -63,7 +61,6 @@
desc = "The Mars Military Industries MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands."
icon_state = "plasma_stun"
item_state = "plasma_stun"
- fire_sound = 'sound/weapons/blaster.ogg'
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_POWER = 3)
fire_delay = 20
charge_cost = 600
diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm
index ae45454a42..cbce1a7aa1 100644
--- a/code/modules/projectiles/guns/magnetic/magnetic.dm
+++ b/code/modules/projectiles/guns/magnetic/magnetic.dm
@@ -4,7 +4,7 @@
icon_state = "coilgun"
item_state = "coilgun"
icon = 'icons/obj/railgun.dmi'
-// one_handed_penalty = 1
+// one_handed_penalty = 15
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_MAGNET = 4)
w_class = ITEMSIZE_LARGE
@@ -15,7 +15,7 @@
var/obj/item/loaded // Currently loaded object, for retrieval/unloading.
var/load_type = /obj/item/stack/rods // Type of stack to load with.
- var/projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at rod launcher.
+ projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at rod launcher.
var/power_cost = 950 // Cost per fire, should consume almost an entire basic cell.
var/power_per_tick // Capacitor charge per process(). Updated based on capacitor rating.
diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
index 82f10cae24..466fbd3b33 100644
--- a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
+++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
@@ -11,6 +11,8 @@
w_class = ITEMSIZE_HUGE
slot_flags = SLOT_BELT
loaded = /obj/item/weapon/rcd_ammo/large
+ slowdown = 1 // Slowdown equals slowdown_worn, until we decide to import the system to differentiate between held and worn items
+ fire_delay = 1
var/initial_cell_type = /obj/item/weapon/cell/hyper
var/initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
@@ -59,7 +61,9 @@
initial_cell_type = /obj/item/weapon/cell/infinite
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/super
+ fire_delay = 0
+ slowdown = 2
slowdown_held = 3
slowdown_worn = 2
@@ -67,9 +71,9 @@
w_class = ITEMSIZE_NO_CONTAINER
firemodes = list(
- list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=1, burst_accuracy=null, dispersion=null),
- list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
- list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_handed_penalty=2, burst_accuracy=list(0,-1,-1,-1,-2), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=15, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=30, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_handed_penalty=30, burst_accuracy=list(0,-15,-15,-15,-30), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/magnetic/railgun/automatic/examine(var/mob/user)
@@ -82,11 +86,18 @@
desc = "The MI-12 Skadi is a burst fire capable railgun that fires flechette rounds at high velocity. Deadly against armour, but much less effective against soft targets."
icon_state = "flechette_gun"
item_state = "z8carbine"
+
initial_cell_type = /obj/item/weapon/cell/hyper
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
+
+ fire_delay = 0
+
slot_flags = SLOT_BACK
+
+ slowdown = 0
slowdown_held = 0
slowdown_worn = 0
+
power_cost = 100
load_type = /obj/item/weapon/magnetic_ammo
projectile_type = /obj/item/projectile/bullet/magnetic/flechette
@@ -95,6 +106,6 @@
empty_sound = 'sound/weapons/smg_empty_alarm.ogg'
firemodes = list(
- list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=1, burst_accuracy=null, dispersion=null),
- list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=15, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=30, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)),
)
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index f1ff50698f..be37c824bb 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -10,6 +10,7 @@
w_class = ITEMSIZE_NORMAL
matter = list(DEFAULT_WALL_MATERIAL = 1000)
recoil = 1
+ projectile_type = /obj/item/projectile/bullet/pistol/strong //Only used for Cham Guns
var/caliber = ".357" //determines which casings will fit
var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled
diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm
index 39bc6d7ae0..142e688006 100644
--- a/code/modules/projectiles/guns/projectile/automatic.dm
+++ b/code/modules/projectiles/guns/projectile/automatic.dm
@@ -9,16 +9,16 @@
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
slot_flags = SLOT_BELT
ammo_type = /obj/item/ammo_casing/a9mm
+ projectile_type = /obj/item/projectile/bullet/pistol
multi_aim = 1
burst_delay = 2
-// requires_two_hands = 1
- one_handed_penalty = 1
+// one_handed_penalty = 15
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
- list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0))
-// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1,-2,-2), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0))
+// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/projectile/automatic/c20r
@@ -35,11 +35,11 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m10mm
allowed_magazines = list(/obj/item/ammo_magazine/m10mm)
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
-// requires_two_hands = 1
- one_handed_penalty = 2
+// one_handed_penalty = 15
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
..()
@@ -62,13 +62,14 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m545
allowed_magazines = list(/obj/item/ammo_magazine/m545)
+ projectile_type = /obj/item/projectile/bullet/rifle/a545
- one_handed_penalty = 4
+// one_handed_penalty = 30
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
- list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6))
-// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2,-2,-3), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-15,-30), dispersion=list(0.0, 0.6, 0.6))
+// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=6, burst_accuracy=list(0,-15,-30,-30,-45), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/projectile/automatic/sts35/update_icon(var/ignore_inhands)
@@ -93,6 +94,7 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m9mmt/rubber
allowed_magazines = list(/obj/item/ammo_magazine/m9mmt)
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
/obj/item/weapon/gun/projectile/automatic/wt550/update_icon()
..()
@@ -116,15 +118,16 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m762
allowed_magazines = list(/obj/item/ammo_magazine/m762)
+ projectile_type = /obj/item/projectile/bullet/rifle/a762
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
- one_handed_penalty = 4
+// one_handed_penalty = 60
burst_delay = 4
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, use_launcher=null, burst_accuracy=null, dispersion=null),
- list(mode_name="2-round bursts", burst=2, fire_delay=null, move_delay=6, use_launcher=null, burst_accuracy=list(0,-1), dispersion=list(0.0, 0.6)),
+ list(mode_name="2-round bursts", burst=2, fire_delay=null, move_delay=6, use_launcher=null, burst_accuracy=list(0,-15), dispersion=list(0.0, 0.6)),
list(mode_name="fire grenades", burst=null, fire_delay=null, move_delay=null, use_launcher=1, burst_accuracy=null, dispersion=null)
)
@@ -187,8 +190,9 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m545saw
allowed_magazines = list(/obj/item/ammo_magazine/m545saw, /obj/item/ammo_magazine/m545)
+ projectile_type = /obj/item/projectile/bullet/rifle/a545
- one_handed_penalty = 6
+// one_handed_penalty = 90
var/cover_open = 0
@@ -203,8 +207,8 @@
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
- list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
- list(mode_name="short bursts", burst=5, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2)),
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="short bursts", burst=5, move_delay=6, burst_accuracy = list(0,-15,-15,-30,-30), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2))
)
/obj/item/weapon/gun/projectile/automatic/l6_saw/special_check(mob/user)
@@ -260,19 +264,19 @@
w_class = ITEMSIZE_LARGE
force = 10
caliber = "12g"
- fire_sound = 'sound/weapons/shotgun.ogg'
origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 1, TECH_ILLEGAL = 4)
slot_flags = SLOT_BACK
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m12gdrum
allowed_magazines = list(/obj/item/ammo_magazine/m12gdrum)
+ projectile_type = /obj/item/projectile/bullet/shotgun
- one_handed_penalty = 4
+// one_handed_penalty = 60
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0),
- list(mode_name="3-round bursts", burst=3, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.0, 0.6, 0.6))
-// list(mode_name="6-round bursts", burst=6, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2, 1.2)),
+ list(mode_name="3-round bursts", burst=3, move_delay=6, burst_accuracy = list(0,-15,-15,-30,-30), dispersion = list(0.0, 0.6, 0.6))
+// list(mode_name="6-round bursts", burst=6, move_delay=6, burst_accuracy = list(0,-15,-15,-30,-30, -30), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2, 1.2)),
)
/obj/item/weapon/gun/projectile/automatic/as24/update_icon()
@@ -296,7 +300,7 @@
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0),
- list(mode_name="3-round bursts", burst=3, burst_delay=1, fire_delay=4, move_delay=4, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0))
+ list(mode_name="3-round bursts", burst=3, burst_delay=1, fire_delay=4, move_delay=4, burst_accuracy = list(0,-15,-15,-30,-30), dispersion = list(0.6, 1.0, 1.0))
)
/obj/item/weapon/gun/projectile/automatic/mini_uzi/update_icon()
@@ -322,7 +326,7 @@
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0),
- list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0))
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0))
)
/obj/item/weapon/gun/projectile/automatic/p90/update_icon()
@@ -342,7 +346,7 @@
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0),
- list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0))
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0))
)
/obj/item/weapon/gun/projectile/automatic/tommygun/update_icon()
@@ -363,12 +367,13 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m762
allowed_magazines = list(/obj/item/ammo_magazine/m762, /obj/item/ammo_magazine/m762m)
+ projectile_type = /obj/item/projectile/bullet/rifle/a762
- one_handed_penalty = 4
+// one_handed_penalty = 45
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
- list(mode_name="2-round bursts", burst=2, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1), dispersion=list(0.0, 0.6))
+ list(mode_name="2-round bursts", burst=2, fire_delay=null, move_delay=6, burst_accuracy=list(0,-15), dispersion=list(0.0, 0.6))
)
/obj/item/weapon/gun/projectile/automatic/bullpup/update_icon(var/ignore_inhands)
@@ -379,4 +384,5 @@
icon_state = "bullpup"
else
item_state = "bullpup-empty"
- if(!ignore_inhands) update_held_icon()
+ if(!ignore_inhands)
+ update_held_icon()
diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm
index bb6d14d1ee..45e5f1ece5 100644
--- a/code/modules/projectiles/guns/projectile/boltaction.dm
+++ b/code/modules/projectiles/guns/projectile/boltaction.dm
@@ -37,7 +37,7 @@
icon_state = "sawnrifle"
w_class = ITEMSIZE_NORMAL
recoil = 2 // Owch
- accuracy = -1 // You know damn well why.
+ accuracy = -15 // You know damn well why.
item_state = "gun"
slot_flags &= ~SLOT_BACK //you can't sling it on your back
slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not.
diff --git a/code/modules/projectiles/guns/projectile/contender.dm b/code/modules/projectiles/guns/projectile/contender.dm
index 4d840a214b..d5e44ae54a 100644
--- a/code/modules/projectiles/guns/projectile/contender.dm
+++ b/code/modules/projectiles/guns/projectile/contender.dm
@@ -8,6 +8,7 @@
handle_casings = HOLD_CASINGS
max_shells = 1
ammo_type = /obj/item/ammo_casing/a357
+ projectile_type = /obj/item/projectile/bullet/pistol/strong
var/retracted_bolt = 0
load_method = SINGLE_CASING
diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm
index 872059df53..a232956684 100644
--- a/code/modules/projectiles/guns/projectile/pistol.dm
+++ b/code/modules/projectiles/guns/projectile/pistol.dm
@@ -4,10 +4,10 @@
desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 rounds."
magazine_type = /obj/item/ammo_magazine/m45
allowed_magazines = list(/obj/item/ammo_magazine/m45)
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
icon_state = "colt"
caliber = ".45"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
- fire_sound = 'sound/weapons/gunshot3.ogg'
load_method = MAGAZINE
/obj/item/weapon/gun/projectile/colt/update_icon()
@@ -68,14 +68,22 @@
M << "Your gun is now sprited as [choice]. Say hello to your new friend."
return 1
+/*//apart of reskins that have two sprites, touching may result in frustration and breaks
+/obj/item/weapon/gun/projectile/colt/detective/attack_hand(var/mob/living/user)
+ if(!unique_reskin && loc == user)
+ reskin_gun(user)
+ return
+ ..()
+*/
+
/obj/item/weapon/gun/projectile/sec
name = ".45 pistol"
desc = "The NT Mk58 is a cheap, ubiquitous sidearm, produced by a NanoTrasen subsidiary. Found pretty much everywhere humans are. Uses .45 rounds."
icon_state = "secguncomp"
magazine_type = /obj/item/ammo_magazine/m45/rubber
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
caliber = ".45"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
- fire_sound = 'sound/weapons/gunshot3.ogg'
load_method = MAGAZINE
/obj/item/weapon/gun/projectile/sec/update_icon()
@@ -114,6 +122,7 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m45
allowed_magazines = list(/obj/item/ammo_magazine/m45)
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
/obj/item/weapon/gun/projectile/deagle
name = "desert eagle"
@@ -195,10 +204,10 @@
caliber = "9mm"
silenced = 0
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 2)
- fire_sound = 'sound/weapons/gunshot3.ogg'
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/m9mm/compact
allowed_magazines = list(/obj/item/ammo_magazine/m9mm/compact)
+ projectile_type = /obj/item/projectile/bullet/pistol
/obj/item/weapon/gun/projectile/pistol/flash
name = "compact signal pistol"
@@ -291,6 +300,7 @@
load_method = SINGLE_CASING
max_shells = 2
ammo_type = /obj/item/ammo_casing/a357
+ projectile_type = /obj/item/projectile/bullet/pistol/strong
/obj/item/weapon/gun/projectile/luger
name = "\improper P08 Luger"
@@ -299,9 +309,9 @@
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
caliber = "9mm"
load_method = MAGAZINE
- fire_sound = 'sound/weapons/gunshot3.ogg'
magazine_type = /obj/item/ammo_magazine/m9mm/compact
allowed_magazines = list(/obj/item/ammo_magazine/m9mm/compact)
+ projectile_type = /obj/item/projectile/bullet/pistol
/obj/item/weapon/gun/projectile/luger/update_icon()
..()
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 20671d6fd5..b33cf11950 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -8,6 +8,7 @@
handle_casings = CYCLE_CASINGS
max_shells = 6
ammo_type = /obj/item/ammo_casing/a357
+ projectile_type = /obj/item/projectile/bullet/pistol/strong
var/chamber_offset = 0 //how many empty chambers in the cylinder until you hit a round
/obj/item/weapon/gun/projectile/revolver/verb/spin_cylinder()
@@ -154,6 +155,7 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
handle_casings = CYCLE_CASINGS
max_shells = 7
ammo_type = /obj/item/ammo_casing/cap
+ projectile_type = /obj/item/projectile/bullet/pistol/strong
/obj/item/weapon/gun/projectile/revolver/judge
name = "\"The Judge\""
@@ -162,10 +164,10 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
caliber = "12g"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 4)
max_shells = 5
- fire_sound = 'sound/weapons/shotgun.ogg'
recoil = 2 // ow my fucking hand
- accuracy = -1 // smooth bore + short barrel = shit accuracy
+ accuracy = -15 // smooth bore + short barrel = shit accuracy
ammo_type = /obj/item/ammo_casing/a12g
+ projectile_type = /obj/item/projectile/bullet/shotgun
// ToDo: Remove accuracy debuf in exchange for slightly injuring your hand every time you fire it.
/obj/item/weapon/gun/projectile/revolver/lemat
@@ -176,9 +178,9 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
handle_casings = CYCLE_CASINGS
max_shells = 9
- fire_sound = 'sound/weapons/gunshot3.ogg'
caliber = ".38"
ammo_type = /obj/item/ammo_casing/a38
+ projectile_type = /obj/item/projectile/bullet/pistol
var/secondary_max_shells = 1
var/secondary_caliber = "12g"
var/secondary_ammo_type = /obj/item/ammo_casing/a12g
@@ -208,7 +210,6 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
if(caliber && secondary_caliber)
caliber = secondary_caliber
- fire_sound = 'sound/weapons/shotgun.ogg'
if(ammo_type && secondary_ammo_type)
ammo_type = secondary_ammo_type
@@ -225,7 +226,6 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
if(caliber && secondary_caliber)
caliber = initial(caliber)
- fire_sound = initial(fire_sound)
if(ammo_type && secondary_ammo_type)
ammo_type = initial(ammo_type)
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 2fb6f04abb..087543091d 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -12,8 +12,8 @@
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
load_method = SINGLE_CASING|SPEEDLOADER
ammo_type = /obj/item/ammo_casing/a12g/beanbag
+ projectile_type = /obj/item/projectile/bullet/shotgun
handle_casings = HOLD_CASINGS
- fire_sound = 'sound/weapons/shotgun.ogg'
var/recentpump = 0 // to prevent spammage
var/action_sound = 'sound/weapons/shotgunpump.ogg'
@@ -106,7 +106,7 @@
slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not.
name = "sawn-off shotgun"
desc = "Omar's coming!"
- user << "You shorten the barrel of \the [src]!"
+ to_chat(user, "You shorten the barrel of \the [src]!")
else
..()
diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm
index 183de3cf17..230e2b4d50 100644
--- a/code/modules/projectiles/guns/projectile/sniper.dm
+++ b/code/modules/projectiles/guns/projectile/sniper.dm
@@ -11,13 +11,14 @@
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
caliber = "14.5mm"
recoil = 5 //extra kickback
- fire_sound = 'sound/weapons/sniper.ogg' // extra boom
handle_casings = HOLD_CASINGS
load_method = SINGLE_CASING
max_shells = 1
ammo_type = /obj/item/ammo_casing/a145
- accuracy = -5
- scoped_accuracy = 5
+ projectile_type = /obj/item/projectile/bullet/rifle/a145
+ accuracy = -75
+ scoped_accuracy = 75
+// one_handed_penalty = 90
var/bolt_open = 0
/obj/item/weapon/gun/projectile/heavysniper/update_icon()
@@ -79,10 +80,10 @@
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
caliber = "7.62mm"
load_method = MAGAZINE
- accuracy = -3 //shooting at the hip
+ accuracy = -45 //shooting at the hip
scoped_accuracy = 0
// requires_two_hands = 1
- one_handed_penalty = 4 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand.
+// one_handed_penalty = 60 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand.
fire_sound = 'sound/weapons/SVD_shot.ogg'
magazine_type = /obj/item/ammo_magazine/m762svd
allowed_magazines = list(/obj/item/ammo_magazine/m762svd)
diff --git a/code/modules/projectiles/guns/vox.dm b/code/modules/projectiles/guns/vox.dm
index ecc8a1a904..631d255f77 100644
--- a/code/modules/projectiles/guns/vox.dm
+++ b/code/modules/projectiles/guns/vox.dm
@@ -56,23 +56,23 @@
desc = "A vicious alien beam weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
icon_state = "darkcannon"
item_state = "darkcannon"
- fire_sound = 'sound/weapons/eLuger.ogg'
w_class = ITEMSIZE_HUGE
charge_cost = 300
projectile_type = /obj/item/projectile/beam/stun/darkmatter
cell_type = /obj/item/weapon/cell/device/weapon/recharge
battery_lock = 1
- accuracy = 2
+ accuracy = 30
firemodes = list(
- list(mode_name="stunning", burst=1, fire_delay=null, move_delay=null, burst_accuracy=list(2), dispersion=null, projectile_type=/obj/item/projectile/beam/stun/darkmatter, charge_cost = 300),
- list(mode_name="focused", burst=1, fire_delay=null, move_delay=null, burst_accuracy=list(2), dispersion=null, projectile_type=/obj/item/projectile/beam/darkmatter, charge_cost = 600),
+ list(mode_name="stunning", burst=1, fire_delay=null, move_delay=null, burst_accuracy=list(30), dispersion=null, projectile_type=/obj/item/projectile/beam/stun/darkmatter, charge_cost = 300),
+ list(mode_name="focused", burst=1, fire_delay=null, move_delay=null, burst_accuracy=list(30), dispersion=null, projectile_type=/obj/item/projectile/beam/darkmatter, charge_cost = 600),
list(mode_name="scatter burst", burst=8, fire_delay=null, move_delay=4, burst_accuracy=list(0, 0, 0, 0, 0, 0, 0, 0), dispersion=list(3, 3, 3, 3, 3, 3, 3, 3, 3), projectile_type=/obj/item/projectile/energy/darkmatter, charge_cost = 300),
)
/obj/item/projectile/beam/stun/darkmatter
name = "dark matter wave"
icon_state = "darkt"
+ fire_sound = 'sound/weapons/eLuger.ogg'
nodamage = 1
taser_effect = 1
agony = 55
@@ -86,6 +86,7 @@
/obj/item/projectile/beam/darkmatter
name = "dark matter bolt"
icon_state = "darkb"
+ fire_sound = 'sound/weapons/eLuger.ogg'
damage = 35
armor_penetration = 35
damage_type = BRUTE
@@ -101,6 +102,7 @@
/obj/item/projectile/energy/darkmatter
name = "dark matter pellet"
icon_state = "dark_pellet"
+ fire_sound = 'sound/weapons/eLuger.ogg'
damage = 20
armor_penetration = 35
damage_type = BRUTE
@@ -117,7 +119,6 @@
desc = "A vicious alien sound weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
icon_state = "noise"
item_state = "noise"
- fire_sound = 'sound/effects/basscannon.ogg'
w_class = ITEMSIZE_HUGE
cell_type = /obj/item/weapon/cell/device/weapon/recharge
battery_lock = 1
@@ -133,6 +134,7 @@
/obj/item/projectile/sonic
name = "sonic pulse"
icon_state = "sound"
+ fire_sound = 'sound/effects/basscannon.ogg'
damage = 5
armor_penetration = 30
damage_type = BRUTE
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 2040b0a778..f844ac0475 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -69,6 +69,8 @@
var/tracer_type
var/impact_type
+ var/fire_sound
+
var/vacuum_traversal = 1 //Determines if the projectile can exist in vacuum, if false, the projectile will be deleted if it enters vacuum.
var/datum/plot_vector/trajectory // used to plot the path of the projectile
@@ -177,7 +179,7 @@
return
//roll to-hit
- miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier + round(15*target_mob.get_evasion()), 0)
+ miss_modifier = max(15*(distance-2) - accuracy + miss_modifier + target_mob.get_evasion(), 0)
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss
var/result = PROJECTILE_FORCE_MISS
@@ -192,7 +194,7 @@
//hit messages
if(silenced)
- target_mob << "You've been hit in the [parse_zone(def_zone)] by \the [src]!"
+ to_chat(target_mob, "You've been hit in the [parse_zone(def_zone)] by \the [src]!")
else
visible_message("\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index 32dce8e3b9..6fee571544 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -1,6 +1,7 @@
/obj/item/projectile/beam
name = "laser"
icon_state = "laser"
+ fire_sound = 'sound/weapons/Laser.ogg'
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 40
damage_type = BURN
@@ -21,7 +22,6 @@
/obj/item/projectile/beam/practice
name = "laser"
icon_state = "laser"
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
damage_type = BURN
check_armour = "laser"
@@ -32,6 +32,9 @@
icon_state = "laser"
damage = 15
+/obj/item/projectile/beam/smalllaser
+ damage = 25
+
/obj/item/projectile/beam/burstlaser
damage = 30
armor_penetration = 10
@@ -44,6 +47,7 @@
/obj/item/projectile/beam/heavylaser
name = "heavy laser"
icon_state = "heavylaser"
+ fire_sound = 'sound/weapons/lasercannonfire.ogg'
damage = 60
armor_penetration = 30
light_range = 3
@@ -62,6 +66,7 @@
/obj/item/projectile/beam/xray
name = "xray beam"
icon_state = "xray"
+ fire_sound = 'sound/weapons/eluger.ogg'
damage = 25
armor_penetration = 50
light_color = "#00CC33"
@@ -83,8 +88,9 @@
/obj/item/projectile/beam/pulse
name = "pulse"
icon_state = "u_laser"
- damage = 50
- armor_penetration = 30
+ fire_sound='sound/weapons/pulse.ogg'
+ damage = 100 //Badmin toy, don't care
+ armor_penetration = 100
light_color = "#0066FF"
muzzle_type = /obj/effect/projectile/laser_pulse/muzzle
@@ -99,6 +105,7 @@
/obj/item/projectile/beam/emitter
name = "emitter beam"
icon_state = "emitter"
+ fire_sound = 'sound/weapons/emitter.ogg'
damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm
light_color = "#00CC33"
@@ -109,7 +116,6 @@
/obj/item/projectile/beam/lastertag/blue
name = "lasertag beam"
icon_state = "bluelaser"
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
no_attack_log = 1
damage_type = BURN
@@ -130,7 +136,6 @@
/obj/item/projectile/beam/lastertag/red
name = "lasertag beam"
icon_state = "laser"
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
no_attack_log = 1
damage_type = BURN
@@ -147,7 +152,6 @@
/obj/item/projectile/beam/lastertag/omni//A laser tag bolt that stuns EVERYONE
name = "lasertag beam"
icon_state = "omnilaser"
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
damage_type = BURN
check_armour = "laser"
@@ -167,6 +171,7 @@
/obj/item/projectile/beam/sniper
name = "sniper beam"
icon_state = "xray"
+ fire_sound = 'sound/weapons/gauss_shoot.ogg'
damage = 50
armor_penetration = 10
light_color = "#00CC33"
@@ -178,6 +183,7 @@
/obj/item/projectile/beam/stun
name = "stun beam"
icon_state = "stun"
+ fire_sound = 'sound/weapons/Taser.ogg'
nodamage = 1
taser_effect = 1
agony = 40
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index a7132fa43b..02eab7e93a 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -1,6 +1,7 @@
/obj/item/projectile/bullet
name = "bullet"
icon_state = "bullet"
+ fire_sound = 'sound/weapons/gunshot/gunshot_strong.ogg'
damage = 60
damage_type = BRUTE
nodamage = 0
@@ -124,6 +125,7 @@
/* short-casing projectiles, like the kind used in pistols or SMGs */
/obj/item/projectile/bullet/pistol
+ fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg'
damage = 20
/obj/item/projectile/bullet/pistol/ap
@@ -142,6 +144,7 @@
armor_penetration = -50
/obj/item/projectile/bullet/pistol/strong //revolvers and matebas
+ fire_sound = 'sound/weapons/gunshot/gunshot_strong.ogg'
damage = 60
/obj/item/projectile/bullet/pistol/rubber //"rubber" bullets
@@ -156,6 +159,7 @@
/obj/item/projectile/bullet/shotgun
name = "slug"
+ fire_sound = 'sound/weapons/gunshot/shotgun.ogg'
damage = 50
armor_penetration = 15
@@ -171,6 +175,7 @@
//Overall less damage than slugs in exchange for more damage at very close range and more embedding
/obj/item/projectile/bullet/pellet/shotgun
name = "shrapnel"
+ fire_sound = 'sound/weapons/gunshot/shotgun.ogg'
damage = 13
pellets = 6
range_step = 1
@@ -180,6 +185,7 @@
//EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used
/obj/item/projectile/bullet/shotgun/ion
name = "ion slug"
+ fire_sound = 'sound/weapons/Laser.ogg'
damage = 15
embed_chance = 0
sharp = 0
@@ -194,10 +200,12 @@
/* "Rifle" rounds */
/obj/item/projectile/bullet/rifle
+ fire_sound = 'sound/weapons/gunshot/gunshot3.ogg'
armor_penetration = 15
penetrating = 1
/obj/item/projectile/bullet/rifle/a762
+ fire_sound = 'sound/weapons/gunshot/gunshot2.ogg'
damage = 35
/obj/item/projectile/bullet/rifle/a762/ap
@@ -232,6 +240,7 @@
SA_vulnerability = SA_ANIMAL
/obj/item/projectile/bullet/rifle/a145
+ fire_sound = 'sound/weapons/gunshot/sniper.ogg'
damage = 80
stun = 3
weaken = 3
@@ -253,11 +262,12 @@
/obj/item/projectile/bullet/burstbullet
name = "exploding bullet"
+ fire_sound = 'sound/effects/Explosion1.ogg'
damage = 20
embed_chance = 0
edge = 1
-/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
+/obj/item/projectile/bullet/burstbullet/on_hit(var/atom/target, var/blocked = 0)
if(isturf(target))
explosion(target, -1, 0, 2)
..()
@@ -309,6 +319,7 @@
/obj/item/projectile/bullet/pistol/cap
name = "cap"
damage_type = HALLOSS
+ fire_sound = null
damage = 0
nodamage = 1
embed_chance = 0
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 8138146163..0cbb96a2e0 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -10,6 +10,7 @@
/obj/item/projectile/energy/flash
name = "chemical shell"
icon_state = "bullet"
+ fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg'
damage = 5
kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
var/flash_range = 0
@@ -47,6 +48,7 @@
//blinds people like the flash round, but can also be used for temporary illumination
/obj/item/projectile/energy/flash/flare
+ fire_sound = 'sound/weapons/gunshot/shotgun.ogg'
damage = 10
flash_range = 1
brightness = 15
@@ -63,6 +65,7 @@
/obj/item/projectile/energy/electrode
name = "electrode"
icon_state = "spark"
+ fire_sound = 'sound/weapons/Gunshot.ogg'
taser_effect = 1
agony = 40
light_range = 2
@@ -81,6 +84,7 @@
/obj/item/projectile/energy/declone
name = "declone"
icon_state = "declone"
+ fire_sound = 'sound/weapons/pulse3.ogg'
nodamage = 1
damage_type = CLONE
irradiate = 40
@@ -106,7 +110,6 @@
agony = 40
stutter = 10
-
/obj/item/projectile/energy/bolt/large
name = "largebolt"
damage = 20
@@ -138,6 +141,7 @@
/obj/item/projectile/energy/phoron
name = "phoron bolt"
icon_state = "energy"
+ fire_sound = 'sound/effects/stealthoff.ogg'
damage = 20
damage_type = TOX
irradiate = 20
@@ -148,6 +152,7 @@
/obj/item/projectile/energy/plasmastun
name = "plasma pulse"
icon_state = "plasma_stun"
+ fire_sound = 'sound/weapons/blaster.ogg'
armor_penetration = 10
kill_count = 4
damage = 5
@@ -187,6 +192,7 @@
/obj/item/projectile/energy/blue_pellet
name = "suppressive pellet"
icon_state = "blue_pellet"
+ fire_sound = 'sound/weapons/Laser.ogg'
damage = 5
armor_penetration = 75
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
diff --git a/code/modules/projectiles/projectile/magnetic.dm b/code/modules/projectiles/projectile/magnetic.dm
index b4a60a55d7..ed16ea208d 100644
--- a/code/modules/projectiles/projectile/magnetic.dm
+++ b/code/modules/projectiles/projectile/magnetic.dm
@@ -2,6 +2,7 @@
/obj/item/projectile/bullet/magnetic
name = "rod"
icon_state = "rod"
+ fire_sound = 'sound/weapons/railgun.ogg'
damage = 65
stun = 1
weaken = 1
@@ -17,6 +18,7 @@
/obj/item/projectile/bullet/magnetic/flechette
name = "flechette"
icon_state = "flechette"
+ fire_sound = 'sound/weapons/rapidslice.ogg'
damage = 20
armor_penetration = 100
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 7a6ecd6c1c..e86ff4c864 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -1,6 +1,7 @@
/obj/item/projectile/ion
name = "ion bolt"
icon_state = "ion"
+ fire_sound = 'sound/weapons/Laser.ogg'
damage = 0
damage_type = BURN
nodamage = 1
@@ -27,12 +28,13 @@
edge = 1
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
- explosion(target, -1, 0, 2)
- return 1
+ explosion(target, -1, 0, 2)
+ ..()
/obj/item/projectile/temp
name = "freeze beam"
icon_state = "ice_2"
+ fire_sound = 'sound/weapons/pulse3.ogg'
damage = 0
damage_type = BURN
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
@@ -105,6 +107,7 @@
/obj/item/projectile/energy/floramut
name = "alpha somatoray"
icon_state = "energy"
+ fire_sound = 'sound/effects/stealthoff.ogg'
damage = 0
damage_type = TOX
nodamage = 1
@@ -148,6 +151,7 @@
/obj/item/projectile/energy/floramut/gene
name = "gamma somatoray"
icon_state = "energy2"
+ fire_sound = 'sound/effects/stealthoff.ogg'
damage = 0
damage_type = TOX
nodamage = 1
@@ -157,6 +161,7 @@
/obj/item/projectile/energy/florayield
name = "beta somatoray"
icon_state = "energy2"
+ fire_sound = 'sound/effects/stealthoff.ogg'
damage = 0
damage_type = TOX
nodamage = 1
diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm
index f6fb5c885c..8c05faa919 100644
--- a/code/modules/xenobio/items/extracts.dm
+++ b/code/modules/xenobio/items/extracts.dm
@@ -896,7 +896,7 @@
on_expired_text = "The spores of goo have faded, and you feel your agility returning to what it was before."
stacks = MODIFIER_STACK_EXTEND
- evasion = 2
+ evasion = 30
slowdown = -1
attack_speed_percent = 0.75
diff --git a/code/modules/xenobio/items/weapons.dm b/code/modules/xenobio/items/weapons.dm
index d06ab9fdd3..ec64773cd3 100644
--- a/code/modules/xenobio/items/weapons.dm
+++ b/code/modules/xenobio/items/weapons.dm
@@ -60,7 +60,7 @@
fire_sound = 'sound/weapons/taser2.ogg'
charge_cost = 120 // Twice as many shots.
projectile_type = /obj/item/projectile/beam/stun/xeno
- accuracy = 2 // Make it a bit easier to hit the slimes.
+ accuracy = 30 // Make it a bit easier to hit the slimes.
description_info = "This gun will stun a slime or other lesser lifeform for about two seconds, if hit with the projectile it fires."
description_fluff = "An easy to use weapon designed by NanoTrasen, for NanoTrasen. This weapon is designed to subdue lesser \
xeno lifeforms at a distance. It is ineffective at stunning larger lifeforms such as humanoids."
diff --git a/sound/weapons/gunshot/gunshot.ogg b/sound/weapons/gunshot/gunshot.ogg
new file mode 100644
index 0000000000..2547b98af9
Binary files /dev/null and b/sound/weapons/gunshot/gunshot.ogg differ
diff --git a/sound/weapons/gunshot/gunshot2.ogg b/sound/weapons/gunshot/gunshot2.ogg
new file mode 100644
index 0000000000..4b26d5e7e6
Binary files /dev/null and b/sound/weapons/gunshot/gunshot2.ogg differ
diff --git a/sound/weapons/gunshot/gunshot3.ogg b/sound/weapons/gunshot/gunshot3.ogg
new file mode 100644
index 0000000000..49c2b0c554
Binary files /dev/null and b/sound/weapons/gunshot/gunshot3.ogg differ
diff --git a/sound/weapons/gunshot/gunshot_pistol.ogg b/sound/weapons/gunshot/gunshot_pistol.ogg
new file mode 100644
index 0000000000..c9d6322992
Binary files /dev/null and b/sound/weapons/gunshot/gunshot_pistol.ogg differ
diff --git a/sound/weapons/gunshot/gunshot_smg.ogg b/sound/weapons/gunshot/gunshot_smg.ogg
new file mode 100644
index 0000000000..5c0000bb32
Binary files /dev/null and b/sound/weapons/gunshot/gunshot_smg.ogg differ
diff --git a/sound/weapons/gunshot/gunshot_strong.ogg b/sound/weapons/gunshot/gunshot_strong.ogg
new file mode 100644
index 0000000000..6794bfa08e
Binary files /dev/null and b/sound/weapons/gunshot/gunshot_strong.ogg differ
diff --git a/sound/weapons/gunshot/shotgun.ogg b/sound/weapons/gunshot/shotgun.ogg
new file mode 100644
index 0000000000..b546fb734f
Binary files /dev/null and b/sound/weapons/gunshot/shotgun.ogg differ
diff --git a/sound/weapons/gunshot/sniper.ogg b/sound/weapons/gunshot/sniper.ogg
new file mode 100644
index 0000000000..3acbece950
Binary files /dev/null and b/sound/weapons/gunshot/sniper.ogg differ