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