/obj/item/gun/ballistic/revolver name = "\improper .357 revolver" desc = "A suspicious revolver. Uses .357 ammo." //usually used by syndicates icon_state = "revolver" mag_type = /obj/item/ammo_box/magazine/internal/cylinder casing_ejector = FALSE /obj/item/gun/ballistic/revolver/Initialize() . = ..() if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) verbs -= /obj/item/gun/ballistic/revolver/verb/spin /obj/item/gun/ballistic/revolver/chamber_round(spin = 1) if(spin) chambered = magazine.get_round(1) else chambered = magazine.stored_ammo[1] /obj/item/gun/ballistic/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj) ..() chamber_round(1) /obj/item/gun/ballistic/revolver/attackby(obj/item/A, mob/user, params) . = ..() if(.) return var/num_loaded = magazine.attackby(A, user, params, 1) if(num_loaded) to_chat(user, "You load [num_loaded] shell\s into \the [src].") playsound(user, 'sound/weapons/bulletinsert.ogg', 60, 1) A.update_icon() update_icon() chamber_round(0) /obj/item/gun/ballistic/revolver/attack_self(mob/living/user) var/num_unloaded = 0 chambered = null while (get_ammo() > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) CB.forceMove(drop_location()) CB.bounce_away(FALSE, NONE) num_unloaded++ if (num_unloaded) to_chat(user, "You unload [num_unloaded] shell\s from [src].") else to_chat(user, "[src] is empty!") /obj/item/gun/ballistic/revolver/verb/spin() set name = "Spin Chamber" set category = "Object" set desc = "Click to spin your revolver's chamber." var/mob/M = usr if(M.stat || !in_range(M,src)) return if(do_spin()) usr.visible_message("[usr] spins [src]'s chamber.", "You spin [src]'s chamber.") else verbs -= /obj/item/gun/ballistic/revolver/verb/spin /obj/item/gun/ballistic/revolver/proc/do_spin() var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine . = istype(C) if(.) C.spin() chamber_round(0) /obj/item/gun/ballistic/revolver/can_shoot() return get_ammo(0,0) /obj/item/gun/ballistic/revolver/get_ammo(countchambered = 0, countempties = 1) var/boolets = 0 //mature var names for mature people if (chambered && countchambered) boolets++ if (magazine) boolets += magazine.ammo_count(countempties) return boolets /obj/item/gun/ballistic/revolver/examine(mob/user) . = ..() . += "[get_ammo(0,0)] of those are live rounds." /obj/item/gun/ballistic/revolver/detective name = "\improper .38 Mars Special" desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds." icon_state = "detective" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 obj_flags = UNIQUE_RENAME unique_reskin = list("Default" = "detective", "Leopard Spots" = "detective_leopard", "Black Panther" = "detective_panther", "Gold Trim" = "detective_gold", "The Peacemaker" = "detective_peacemaker" ) var/list/safe_calibers /obj/item/gun/ballistic/revolver/detective/Initialize() . = ..() safe_calibers = magazine.caliber /obj/item/gun/ballistic/revolver/detective/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, stam_cost = 0) if(chambered && !(chambered.caliber in safe_calibers)) if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 playsound(user, fire_sound, 50, 1) to_chat(user, "[src] blows up in your face!") user.take_bodypart_damage(0,20) user.dropItemToGround(src) return FALSE ..() /obj/item/gun/ballistic/revolver/detective/screwdriver_act(mob/living/user, obj/item/I) if(..()) return TRUE if("38" in magazine.caliber) to_chat(user, "You begin to reinforce the barrel of [src]...") if(magazine.ammo_count()) afterattack(user, user) //you know the drill user.visible_message("[src] goes off!", "[src] goes off in your face!") return TRUE if(I.use_tool(src, user, 30)) if(magazine.ammo_count()) to_chat(user, "You can't modify it!") return TRUE magazine.caliber = list("357") desc = "The barrel and chamber assembly seems to have been modified." to_chat(user, "You reinforce the barrel of [src]. Now it will fire .357 rounds.") else to_chat(user, "You begin to revert the modifications to [src]...") if(magazine.ammo_count()) afterattack(user, user) //and again user.visible_message("[src] goes off!", "[src] goes off in your face!") return TRUE if(I.use_tool(src, user, 30)) if(magazine.ammo_count()) to_chat(user, "You can't modify it!") return magazine.caliber = list("38") desc = initial(desc) to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.") return TRUE /obj/item/gun/ballistic/revolver/mateba name = "\improper Unica 6 auto-revolver" desc = "A retro high-powered autorevolver typically used by officers of the New Russia military. Uses .357 ammo." icon_state = "mateba" /obj/item/gun/ballistic/revolver/golden name = "\improper Golden revolver" desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo." icon_state = "goldrevolver" fire_sound = 'sound/weapons/resonator_blast.ogg' recoil = 8 pin = /obj/item/firing_pin /obj/item/gun/ballistic/revolver/nagant name = "\improper Nagant revolver" desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo." icon_state = "nagant" can_suppress = TRUE mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762 // A gun to play Russian Roulette! // You can spin the chamber to randomize the position of the bullet. /obj/item/gun/ballistic/revolver/russian name = "\improper Russian revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism requiring you to spin the chamber before each trigger pull." icon_state = "russianrevolver" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 var/spun = FALSE /obj/item/gun/ballistic/revolver/russian/do_spin() . = ..() spun = TRUE /obj/item/gun/ballistic/revolver/russian/Initialize() . = ..() do_spin() spun = TRUE update_icon() /obj/item/gun/ballistic/revolver/russian/attackby(obj/item/A, mob/user, params) ..() if(get_ammo() > 0) spin() spun = TRUE update_icon() A.update_icon() return /obj/item/gun/ballistic/revolver/russian/attack_self(mob/user) if(!spun) spin() spun = TRUE return ..() /obj/item/gun/ballistic/revolver/russian/afterattack(atom/target, mob/living/user, flag, params) . = ..(null, user, flag, params) if(flag) if(!(target in user.contents) && ismob(target)) if(user.a_intent == INTENT_HARM) // Flogging action return if(isliving(user)) if(!can_trigger_gun(user)) return if(target != user) if(ismob(target)) to_chat(user, "A mechanism prevents you from shooting anyone but yourself!") return if(ishuman(user)) var/mob/living/carbon/human/H = user if(!spun) to_chat(user, "You need to spin \the [src]'s chamber first!") return spun = FALSE if(chambered) var/obj/item/ammo_casing/AC = chambered if(AC.fire_casing(user, user)) playsound(user, fire_sound, 50, 1) var/zone = check_zone(user.zone_selected) var/obj/item/bodypart/affecting = H.get_bodypart(zone) if(zone == BODY_ZONE_HEAD || zone == BODY_ZONE_PRECISE_EYES || zone == BODY_ZONE_PRECISE_MOUTH) shoot_self(user, affecting) else user.visible_message("[user.name] cowardly fires [src] at [user.p_their()] [affecting.name]!", "You cowardly fire [src] at your [affecting.name]!", "You hear a gunshot!") chambered = null return user.visible_message("*click*") playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/ballistic/revolver/russian/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, stam_cost = 0) add_fingerprint(user) playsound(src, "gun_dry_fire", 30, TRUE) user.visible_message("[user.name] tries to fire \the [src] at the same time, but only succeeds at looking like an idiot.", "\The [src]'s anti-combat mechanism prevents you from firing it at the same time!") /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = BODY_ZONE_HEAD) user.apply_damage(300, BRUTE, affecting) user.visible_message("[user.name] fires [src] at [user.p_their()] head!", "You fire [src] at your head!", "You hear a gunshot!") /obj/item/gun/ballistic/revolver/russian/soul name = "cursed Russian revolver" desc = "To play with this revolver requires wagering your very soul." /obj/item/gun/ballistic/revolver/russian/soul/shoot_self(mob/living/user) ..() var/obj/item/soulstone/anybody/SS = new /obj/item/soulstone/anybody(get_turf(src)) if(!SS.transfer_soul("FORCE", user)) //Something went wrong qdel(SS) return user.visible_message("[user.name]'s soul is captured by \the [src]!", "You've lost the gamble! Your soul is forfeit!") ///////////////////////////// // DOUBLE BARRELED SHOTGUN // ///////////////////////////// /obj/item/gun/ballistic/revolver/doublebarrel name = "double-barreled shotgun" desc = "A true classic." icon_state = "dshotgun" item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/internal/shot/dual sawn_desc = "Omar's coming!" obj_flags = UNIQUE_RENAME unique_reskin = list("Default" = "dshotgun", "Dark Red Finish" = "dshotgun-d", "Ash" = "dshotgun-f", "Faded Grey" = "dshotgun-g", "Maple" = "dshotgun-l", "Rosewood" = "dshotgun-p" ) /obj/item/gun/ballistic/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) chamber_round() if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter)) sawoff(user) if(istype(A, /obj/item/melee/transforming/energy)) var/obj/item/melee/transforming/energy/W = A if(W.active) sawoff(user) /obj/item/gun/ballistic/revolver/doublebarrel/attack_self(mob/living/user) var/num_unloaded = 0 while (get_ammo() > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null CB.forceMove(drop_location()) CB.update_icon() num_unloaded++ if (num_unloaded) to_chat(user, "You break open \the [src] and unload [num_unloaded] shell\s.") else to_chat(user, "[src] is empty!") ///////////////////////////// // IMPROVISED SHOTGUN // ///////////////////////////// /obj/item/gun/ballistic/revolver/doublebarrel/improvised name = "improvised shotgun" desc = "A shoddy break-action breechloaded shotgun. Its lacklustre construction shows in its lesser effectiveness." icon_state = "ishotgun" item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM // prevents shooting 2 at once, but doesn't require 2 hands force = 10 slot_flags = null mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm just here for the gasoline." unique_reskin = null projectile_damage_multiplier = 0.9 var/slung = FALSE /obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/stack/cable_coil) && !sawn_off) if(A.use_tool(src, user, 0, 10, skill_gain_mult = EASY_USE_TOOL_MULT)) slot_flags = ITEM_SLOT_BACK to_chat(user, "You tie the lengths of cable to the shotgun, making a sling.") slung = TRUE update_icon() else to_chat(user, "You need at least ten lengths of cable if you want to make a sling!") /obj/item/gun/ballistic/revolver/doublebarrel/improvised/update_icon() ..() if(slung) icon_state += "sling" /obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawoff(mob/user) . = ..() if(. && slung) //sawing off the gun removes the sling new /obj/item/stack/cable_coil(get_turf(src), 10) slung = 0 update_icon() /obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn name = "sawn-off improvised shotgun" desc = "The barrel and stock have been sawn and filed down; it can fit in backpacks. You wont want to shoot two of these at once if you value your wrists." icon_state = "ishotgun" item_state = "gun" w_class = WEIGHT_CLASS_NORMAL sawn_off = TRUE slot_flags = ITEM_SLOT_BELT /obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course. clumsy_check = 0 /obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user) if((HAS_TRAIT(user, TRAIT_CLUMSY)) || (user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))) return ..() if(process_fire(user, user, FALSE, null, BODY_ZONE_HEAD)) user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!") user.emote("scream") user.drop_all_held_items() user.DefaultCombatKnockdown(80) // -------------- HoS Modular Weapon System ------------- // ---------- Code originally from VoreStation ---------- /obj/item/gun/ballistic/revolver/mws name = "MWS-01 'Big Iron'" desc = "Modular Weapons System" icon = 'icons/obj/guns/projectile.dmi' icon_state = "mws" fire_sound = 'sound/weapons/Taser.ogg' mag_type = /obj/item/ammo_box/magazine/mws_mag spawnwithmagazine = FALSE recoil = 0 var/charge_sections = 6 /obj/item/gun/ballistic/revolver/mws/examine(mob/user) . = ..() . += "Alt-click to remove the magazine." /obj/item/gun/ballistic/revolver/mws/shoot_with_empty_chamber(mob/living/user as mob|obj) process_chamber(user) if(!chambered || !chambered.BB) to_chat(user, "*click*") playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/ballistic/revolver/mws/process_chamber(mob/living/user) if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... var/obj/item/ammo_casing/mws_batt/shot = chambered if(shot.cell.charge >= shot.e_cost) shot.chargeshot() else for(var/B in magazine.stored_ammo) var/obj/item/ammo_casing/mws_batt/other_batt = B if(istype(other_batt,shot) && other_batt.cell.charge >= other_batt.e_cost) switch_to(other_batt, user) break update_icon() /obj/item/gun/ballistic/revolver/mws/proc/switch_to(obj/item/ammo_casing/mws_batt/new_batt, mob/living/user) if(ishuman(user)) if(chambered && new_batt.type == chambered.type) to_chat(user,"[src] is now using the next [new_batt.type_name] power cell.") else to_chat(user,"[src] is now firing [new_batt.type_name].") chambered = new_batt update_icon() /obj/item/gun/ballistic/revolver/mws/attack_self(mob/living/user) if(!chambered) return var/list/stored_ammo = magazine.stored_ammo if(stored_ammo.len == 1) return //silly you. //Find an ammotype that ISN'T the same, or exhaust the list and don't change. var/our_slot = stored_ammo.Find(chambered) for(var/index in 1 to stored_ammo.len) var/true_index = ((our_slot + index - 1) % stored_ammo.len) + 1 // Stupid ONE BASED lists! var/obj/item/ammo_casing/mws_batt/next_batt = stored_ammo[true_index] if(chambered != next_batt && !istype(next_batt, chambered.type) && next_batt.cell.charge >= next_batt.e_cost) switch_to(next_batt, user) break /obj/item/gun/ballistic/revolver/mws/AltClick(mob/living/user) .=..() if(magazine) user.put_in_hands(magazine) magazine.update_icon() if(magazine.ammo_count()) playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, 1) else playsound(src, "gun_remove_empty_magazine", 70, 1) magazine = null to_chat(user, "You pull the magazine out of [src].") if(chambered) chambered = null update_icon() /obj/item/gun/ballistic/revolver/mws/update_overlays() .=..() if(!chambered) return var/obj/item/ammo_casing/mws_batt/batt = chambered var/batt_color = batt.type_color //Used many times //Mode bar var/image/mode_bar = image(icon, icon_state = "[initial(icon_state)]_type") mode_bar.color = batt_color . += mode_bar //Barrel color var/mutable_appearance/barrel_color = mutable_appearance(icon, "[initial(icon_state)]_barrel", color = batt_color) barrel_color.alpha = 150 . += barrel_color //Charge bar var/ratio = can_shoot() ? CEILING(clamp(batt.cell.charge / batt.cell.maxcharge, 0, 1) * charge_sections, 1) : 0 for(var/i = 0, i < ratio, i++) var/mutable_appearance/charge_bar = mutable_appearance(icon, "[initial(icon_state)]_charge", color = batt_color) charge_bar.pixel_x = i . += charge_bar