Initial Commit

This commit is contained in:
skull132
2014-03-11 09:03:52 +02:00
commit a8d9450c7e
3486 changed files with 415920 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
/obj/item/ammo_casing
name = "bullet casing"
desc = "A bullet casing."
icon = 'icons/obj/ammo.dmi'
icon_state = "s-casing"
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
throwforce = 1
w_class = 1.0
var/caliber = "" //Which kind of guns it can be loaded into
var/projectile_type = ""//The bullet type to create when New() is called
var/obj/item/projectile/BB = null //The loaded bullet
New()
..()
if(projectile_type)
BB = new projectile_type(src)
pixel_x = rand(-10.0, 10)
pixel_y = rand(-10.0, 10)
dir = pick(cardinal)
//Boxes of ammo
/obj/item/ammo_magazine
name = "ammo box (.357)"
desc = "A box of ammo"
icon_state = "357"
icon = 'icons/obj/ammo.dmi'
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
item_state = "syringe_kit"
m_amt = 50000
throwforce = 2
w_class = 1.0
throw_speed = 4
throw_range = 10
var/list/stored_ammo = list()
var/ammo_type = "/obj/item/ammo_casing"
var/max_ammo = 7
var/multiple_sprites = 0
New()
for(var/i = 1, i <= max_ammo, i++)
stored_ammo += new ammo_type(src)
update_icon()
update_icon()
if(multiple_sprites)
icon_state = "[initial(icon_state)]-[stored_ammo.len]"
desc = "There are [stored_ammo.len] shell\s left!"
@@ -0,0 +1,138 @@
/obj/item/ammo_magazine/a357
name = "ammo box (.357)"
desc = "A box of .357 ammo"
icon_state = "357"
ammo_type = "/obj/item/ammo_casing/a357"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/c38
name = "speed loader (.38)"
icon_state = "38"
ammo_type = "/obj/item/ammo_casing/c38"
max_ammo = 6
multiple_sprites = 1
/obj/item/ammo_magazine/c45m
name = "magazine (.45)"
icon_state = "45"
ammo_type = "/obj/item/ammo_casing/c45"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/c45/empty
max_ammo = 0
/obj/item/ammo_magazine/c45r
name = "magazine (.45 rubber)"
icon_state = "45"
ammo_type = "/obj/item/ammo_casing/c45r"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/c45r/empty
max_ammo = 0
/obj/item/ammo_magazine/a418
name = "ammo box (.418)"
icon_state = "418"
ammo_type = "/obj/item/ammo_casing/a418"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/a666
name = "ammo box (.666)"
icon_state = "666"
ammo_type = "/obj/item/ammo_casing/a666"
max_ammo = 4
multiple_sprites = 1
/obj/item/ammo_magazine/mc9mm
name = "magazine (9mm)"
icon_state = "9x19p"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/c9mm"
max_ammo = 8
multiple_sprites = 1
/obj/item/ammo_magazine/mc9mm/empty
max_ammo = 0
/obj/item/ammo_magazine/c9mm
name = "Ammunition Box (9mm)"
icon_state = "9mm"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/c9mm"
max_ammo = 30
/obj/item/ammo_magazine/c45
name = "Ammunition Box (.45)"
icon_state = "9mm"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/c45"
max_ammo = 30
/obj/item/ammo_magazine/a12mm
name = "magazine (12mm)"
icon_state = "12mm"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/a12mm"
max_ammo = 20
multiple_sprites = 1
/obj/item/ammo_magazine/a12mm/empty
name = "magazine (12mm)"
icon_state = "12mm"
ammo_type = "/obj/item/ammo_casing/12mm"
max_ammo = 0
/obj/item/ammo_magazine/a50
name = "magazine (.50)"
icon_state = "50ae"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/a50"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_magazine/a50/empty
name = "magazine (.50)"
icon_state = "50ae"
ammo_type = "/obj/item/ammo_casing/a50"
max_ammo = 0
/obj/item/ammo_magazine/a75
name = "ammo magazine (.75)"
icon_state = "75"
ammo_type = "/obj/item/ammo_casing/a75"
multiple_sprites = 1
max_ammo = 8
/obj/item/ammo_magazine/a75/empty
name = "ammo magazine (.75)"
icon_state = "75"
ammo_type = "/obj/item/ammo_casing/a75"
max_ammo = 0
/obj/item/ammo_magazine/a762
name = "magazine (a762)"
icon_state = "a762"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/a762"
max_ammo = 50
multiple_sprites = 1
/obj/item/ammo_magazine/a762/empty
name = "magazine (a762)"
icon_state = "a762"
ammo_type = "/obj/item/ammo_casing/a762"
max_ammo = 0
multiple_sprites = 1
@@ -0,0 +1,107 @@
/obj/item/ammo_casing/a357
desc = "A .357 bullet casing."
caliber = "357"
projectile_type = "/obj/item/projectile/bullet"
/obj/item/ammo_casing/a50
desc = "A .50AE bullet casing."
caliber = ".50"
projectile_type = "/obj/item/projectile/bullet"
/obj/item/ammo_casing/a418
desc = "A .418 bullet casing."
caliber = "357"
projectile_type = "/obj/item/projectile/bullet/suffocationbullet"
/obj/item/ammo_casing/a75
desc = "A .75 bullet casing."
caliber = "75"
projectile_type = "/obj/item/projectile/bullet/gyro"
/obj/item/ammo_casing/a666
desc = "A .666 bullet casing."
caliber = "357"
projectile_type = "/obj/item/projectile/bullet/cyanideround"
/obj/item/ammo_casing/c38
desc = "A .38 bullet casing."
caliber = "38"
projectile_type = "/obj/item/projectile/bullet/weakbullet"
/obj/item/ammo_casing/c9mm
desc = "A 9mm bullet casing."
caliber = "9mm"
projectile_type = "/obj/item/projectile/bullet/midbullet2"
/obj/item/ammo_casing/c45
desc = "A .45 bullet casing."
caliber = ".45"
projectile_type = "/obj/item/projectile/bullet/midbullet"
/obj/item/ammo_casing/c45r
desc = "A .45 rubber bullet casing."
caliber = ".45"
projectile_type = "/obj/item/projectile/bullet/weakbullet"
/obj/item/ammo_casing/a12mm
desc = "A 12mm bullet casing."
caliber = "12mm"
projectile_type = "/obj/item/projectile/bullet/midbullet2"
/obj/item/ammo_casing/shotgun
name = "shotgun shell"
desc = "A 12 gauge shell."
icon_state = "gshell"
caliber = "shotgun"
projectile_type = "/obj/item/projectile/bullet"
m_amt = 12500
/obj/item/ammo_casing/shotgun/blank
name = "shotgun shell"
desc = "A blank shell."
icon_state = "blshell"
projectile_type = ""
m_amt = 250
/obj/item/ammo_casing/shotgun/beanbag
name = "beanbag shell"
desc = "A weak beanbag shell."
icon_state = "bshell"
projectile_type = "/obj/item/projectile/bullet/weakbullet"
m_amt = 500
/obj/item/ammo_casing/shotgun/stunshell
name = "stun shell"
desc = "A stunning shell."
icon_state = "stunshell"
projectile_type = "/obj/item/projectile/bullet/stunshot"
m_amt = 2500
/obj/item/ammo_casing/shotgun/dart
name = "shotgun darts"
desc = "A dart for use in shotguns."
icon_state = "dart"
projectile_type = "/obj/item/projectile/energy/dart"
m_amt = 12500
/obj/item/ammo_casing/a762
desc = "A 7.62 bullet casing."
caliber = "a762"
projectile_type = "/obj/item/projectile/bullet/a762"
/obj/item/ammo_casing/rocket
name = "rocket shell"
desc = "A high explosive designed to be fired from a launcher."
icon_state = "rocketshell"
projectile_type = "/obj/item/missile"
caliber = "rocket"
+228
View File
@@ -0,0 +1,228 @@
/obj/item/weapon/gun
name = "gun"
desc = "Its a gun. It's pretty terrible, though."
icon = 'icons/obj/gun.dmi'
icon_state = "detective"
item_state = "gun"
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
m_amt = 2000
w_class = 3.0
throwforce = 5
throw_speed = 4
throw_range = 5
force = 5.0
origin_tech = "combat=1"
attack_verb = list("struck", "hit", "bashed")
var/fire_sound = 'sound/weapons/Gunshot.ogg'
var/obj/item/projectile/in_chamber = null
var/caliber = ""
var/silenced = 0
var/recoil = 0
var/ejectshell = 1
var/clumsy_check = 1
var/tmp/list/mob/living/target //List of who yer targeting.
var/tmp/lock_time = -100
var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.>
var/automatic = 0 //Used to determine if you can target multiple people.
var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person.
var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them.
var/firerate = 1 // 0 for one bullet after tarrget moves and aim is lowered,
//1 for keep shooting until aim is lowered
var/fire_delay = 6
var/last_fired = 0
proc/ready_to_fire()
if(world.time >= last_fired + fire_delay)
last_fired = world.time
return 1
else
return 0
proc/load_into_chamber()
return 0
proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver.
return 1
emp_act(severity)
for(var/obj/O in contents)
O.emp_act(severity)
/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(flag) return //It's adjacent, is the user, or is on the user's person
if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this?
if(user && user.client && user.client.gun_mode && !(A in target))
PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at.
else
Fire(A,user,params) //Otherwise, fire normally.
/obj/item/weapon/gun/proc/isHandgun()
return 1
/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this
//Exclude lasertag guns from the CLUMSY check.
if(clumsy_check)
if(istype(user, /mob/living))
var/mob/living/M = user
if ((CLUMSY in M.mutations) && prob(50))
M << "<span class='danger'>[src] blows up in your face.</span>"
M.take_organ_damage(0,20)
M.drop_item()
del(src)
return
if (!user.IsAdvancedToolUser())
user << "\red You don't have the dexterity to do this!"
return
if(istype(user, /mob/living))
var/mob/living/M = user
if (HULK in M.mutations)
M << "\red Your meaty finger is much too large for the trigger guard!"
return
if(ishuman(user))
if(user.dna && user.dna.mutantrace == "adamantine")
user << "\red Your metal fingers don't fit in the trigger guard!"
return
add_fingerprint(user)
var/turf/curloc = get_turf(user)
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return
if(!special_check(user))
return
if (!ready_to_fire())
if (world.time % 3) //to prevent spam
user << "<span class='warning'>[src] is not ready to fire again!"
return
if(!load_into_chamber()) //CHECK
return click_empty(user)
if(!in_chamber)
return
in_chamber.firer = user
in_chamber.def_zone = user.zone_sel.selecting
if(targloc == curloc)
user.bullet_act(in_chamber)
del(in_chamber)
update_icon()
return
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='warning'>[user] fires [src][reflex ? " by reflex":""]!</span>", \
"<span class='warning'>You fire [src][reflex ? "by reflex":""]!</span>", \
"You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
in_chamber.original = target
in_chamber.loc = get_turf(user)
in_chamber.starting = get_turf(user)
in_chamber.shot_from = src
user.next_move = world.time + 4
in_chamber.silenced = silenced
in_chamber.current = curloc
in_chamber.yo = targloc.y - curloc.y
in_chamber.xo = targloc.x - curloc.x
if(istype(user, /mob/living/carbon))
var/mob/living/carbon/mob = user
if(mob.shock_stage > 120)
in_chamber.yo += rand(-2,2)
in_chamber.xo += rand(-2,2)
else if(mob.shock_stage > 70)
in_chamber.yo += rand(-1,1)
in_chamber.xo += rand(-1,1)
if(params)
var/list/mouse_control = params2list(params)
if(mouse_control["icon-x"])
in_chamber.p_x = text2num(mouse_control["icon-x"])
if(mouse_control["icon-y"])
in_chamber.p_y = text2num(mouse_control["icon-y"])
spawn()
if(in_chamber)
in_chamber.process()
sleep(1)
in_chamber = null
update_icon()
if(user.hand)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
/obj/item/weapon/gun/proc/can_fire()
return load_into_chamber()
/obj/item/weapon/gun/proc/can_hit(var/mob/living/target as mob, var/mob/living/user as mob)
return in_chamber.check_fire(target,user)
/obj/item/weapon/gun/proc/click_empty(mob/user = null)
if (user)
user.visible_message("*click click*", "\red <b>*click*</b>")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
else
src.visible_message("*click click*")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
//Suicide handling.
if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot)
mouthshoot = 1
M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...")
if(!do_after(user, 40))
M.visible_message("\blue [user] decided life was worth living")
mouthshoot = 0
return
if (load_into_chamber())
user.visible_message("<span class = 'warning'>[user] pulls the trigger.</span>")
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
if(istype(in_chamber, /obj/item/projectile/beam/lastertag))
user.show_message("<span class = 'warning'>You feel rather silly, trying to commit suicide with a toy.</span>")
mouthshoot = 0
return
in_chamber.on_hit(M)
if (in_chamber.damage_type != HALLOSS)
user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]")
user.death()
else
user << "<span class = 'notice'>Ow...</span>"
user.apply_effect(110,AGONY,0)
del(in_chamber)
mouthshoot = 0
return
else
click_empty(user)
mouthshoot = 0
return
if (load_into_chamber())
//Point blank shooting if on harm intent or target we were targeting.
if(user.a_intent == "hurt")
user.visible_message("\red <b> \The [user] fires \the [src] point blank at [M]!</b>")
in_chamber.damage *= 1.3
Fire(M,user)
return
else if(target && M in target)
Fire(M,user) ///Otherwise, shoot!
return
else
return ..() //Pistolwhippin'
+44
View File
@@ -0,0 +1,44 @@
/obj/item/weapon/gun/energy
icon_state = "energy"
name = "energy gun"
desc = "A basic energy-based gun."
fire_sound = 'sound/weapons/Taser.ogg'
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
var/charge_cost = 100 //How much energy is needed to fire.
var/cell_type = "/obj/item/weapon/cell"
var/projectile_type = "/obj/item/projectile/beam/practice"
var/modifystate
emp_act(severity)
power_supply.use(round(power_supply.maxcharge / severity))
update_icon()
..()
New()
..()
if(cell_type)
power_supply = new cell_type(src)
else
power_supply = new(src)
power_supply.give(power_supply.maxcharge)
return
load_into_chamber()
if(in_chamber) return 1
if(!power_supply) return 0
if(!power_supply.use(charge_cost)) return 0
if(!projectile_type) return 0
in_chamber = new projectile_type(src)
return 1
update_icon()
var/ratio = power_supply.charge / power_supply.maxcharge
ratio = round(ratio, 0.25) * 100
if(modifystate)
icon_state = "[modifystate][ratio]"
else
icon_state = "[initial(icon_state)][ratio]"
@@ -0,0 +1,172 @@
/obj/item/weapon/gun/energy/laser
name = "laser gun"
desc = "a basic weapon designed kill with concentrated energy bolts"
icon_state = "laser"
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
w_class = 3.0
m_amt = 2000
origin_tech = "combat=3;magnets=2"
projectile_type = "/obj/item/projectile/beam"
/obj/item/weapon/gun/energy/laser/practice
name = "practice laser gun"
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
projectile_type = "/obj/item/projectile/beam/practice"
clumsy_check = 0
obj/item/weapon/gun/energy/laser/retro
name ="retro laser"
icon_state = "retro"
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
/obj/item/weapon/gun/energy/laser/captain
icon_state = "caplaser"
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
force = 10
origin_tech = null
var/charge_tick = 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
update_icon()
return 1
/obj/item/weapon/gun/energy/laser/cyborg/load_into_chamber()
if(in_chamber)
return 1
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
R.cell.use(100)
in_chamber = new/obj/item/projectile/beam(src)
return 1
return 0
/obj/item/weapon/gun/energy/lasercannon
name = "laser cannon"
desc = "With the L.A.S.E.R. cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
icon_state = "lasercannon"
fire_sound = 'sound/weapons/lasercannonfire.ogg'
origin_tech = "combat=4;materials=3;powerstorage=3"
projectile_type = "/obj/item/projectile/beam/heavylaser"
fire_delay = 20
isHandgun()
return 0
/obj/item/weapon/gun/energy/lasercannon/cyborg/load_into_chamber()
if(in_chamber)
return 1
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
R.cell.use(250)
in_chamber = new/obj/item/projectile/beam(src)
return 1
return 0
/obj/item/weapon/gun/energy/xray
name = "xray laser gun"
desc = "A high-power laser gun capable of expelling concentrated xray blasts."
icon_state = "xray"
fire_sound = 'sound/weapons/laser3.ogg'
origin_tech = "combat=5;materials=3;magnets=2;syndicate=2"
projectile_type = "/obj/item/projectile/beam/xray"
charge_cost = 50
////////Laser Tag////////////////////
/obj/item/weapon/gun/energy/laser/bluetag
name = "laser tag gun"
icon_state = "bluetag"
desc = "Standard issue weapon of the Imperial Guard"
projectile_type = "/obj/item/projectile/beam/lastertag/blue"
origin_tech = "combat=1;magnets=2"
clumsy_check = 0
var/charge_tick = 0
special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
update_icon()
return 1
/obj/item/weapon/gun/energy/laser/redtag
name = "laser tag gun"
icon_state = "redtag"
desc = "Standard issue weapon of the Imperial Guard"
projectile_type = "/obj/item/projectile/beam/lastertag/red"
origin_tech = "combat=1;magnets=2"
clumsy_check = 0
var/charge_tick = 0
special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
update_icon()
return 1
@@ -0,0 +1,127 @@
/obj/item/weapon/gun/energy/gun
name = "energy gun"
desc = "A basic energy-based gun with two settings: Stun and kill."
icon_state = "energystun100"
item_state = null //so the human update icon uses the icon_state instead.
fire_sound = 'sound/weapons/Taser.ogg'
charge_cost = 100 //How much energy is needed to fire.
projectile_type = "/obj/item/projectile/energy/electrode"
origin_tech = "combat=3;magnets=2"
modifystate = "energystun"
var/mode = 0 //0 = stun, 1 = kill
attack_self(mob/living/user as mob)
switch(mode)
if(0)
mode = 1
charge_cost = 100
fire_sound = 'sound/weapons/Laser.ogg'
user << "\red [src.name] is now set to kill."
projectile_type = "/obj/item/projectile/beam"
modifystate = "energykill"
if(1)
mode = 0
charge_cost = 100
fire_sound = 'sound/weapons/Taser.ogg'
user << "\red [src.name] is now set to stun."
projectile_type = "/obj/item/projectile/energy/electrode"
modifystate = "energystun"
update_icon()
/obj/item/weapon/gun/energy/gun/nuclear
name = "Advanced Energy Gun"
desc = "An energy gun with an experimental miniaturized reactor."
icon_state = "nucgun"
origin_tech = "combat=3;materials=5;powerstorage=3"
var/lightfail = 0
var/charge_tick = 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
if((power_supply.charge / power_supply.maxcharge) != 1)
if(!failcheck()) return 0
power_supply.give(100)
update_icon()
return 1
proc
failcheck()
lightfail = 0
if (prob(src.reliability)) return 1 //No failure
if (prob(src.reliability))
for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
if (src in M.contents)
M << "\red Your gun feels pleasantly warm for a moment."
else
M << "\red You feel a warm sensation."
M.apply_effect(rand(3,120), IRRADIATE)
lightfail = 1
else
for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES
if (src in M.contents)
M << "\red Your gun's reactor overloads!"
M << "\red You feel a wave of heat wash over you."
M.apply_effect(300, IRRADIATE)
crit_fail = 1 //break the gun so it stops recharging
processing_objects.Remove(src)
update_icon()
return 0
update_charge()
if (crit_fail)
overlays += "nucgun-whee"
return
var/ratio = power_supply.charge / power_supply.maxcharge
ratio = round(ratio, 0.25) * 100
overlays += "nucgun-[ratio]"
update_reactor()
if(crit_fail)
overlays += "nucgun-crit"
return
if(lightfail)
overlays += "nucgun-medium"
else if ((power_supply.charge/power_supply.maxcharge) <= 0.5)
overlays += "nucgun-light"
else
overlays += "nucgun-clean"
update_mode()
if (mode == 0)
overlays += "nucgun-stun"
else if (mode == 1)
overlays += "nucgun-kill"
emp_act(severity)
..()
reliability -= round(15/severity)
update_icon()
overlays.Cut()
update_charge()
update_reactor()
update_mode()
@@ -0,0 +1,90 @@
/obj/item/weapon/gun/energy/pulse_rifle
name = "pulse rifle"
desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel."
icon_state = "pulse"
item_state = null //so the human update icon uses the icon_state instead.
force = 10
fire_sound = 'sound/weapons/pulse.ogg'
charge_cost = 200
projectile_type = "/obj/item/projectile/beam/pulse"
cell_type = "/obj/item/weapon/cell/super"
var/mode = 2
fire_delay = 25
attack_self(mob/living/user as mob)
switch(mode)
if(2)
mode = 0
charge_cost = 100
fire_sound = 'sound/weapons/Taser.ogg'
user << "\red [src.name] is now set to stun."
projectile_type = "/obj/item/projectile/energy/electrode"
if(0)
mode = 1
charge_cost = 100
fire_sound = 'sound/weapons/Laser.ogg'
user << "\red [src.name] is now set to kill."
projectile_type = "/obj/item/projectile/beam"
if(1)
mode = 2
charge_cost = 200
fire_sound = 'sound/weapons/pulse.ogg'
user << "\red [src.name] is now set to DESTROY."
projectile_type = "/obj/item/projectile/beam/pulse"
return
isHandgun()
return 0
/obj/item/weapon/gun/energy/pulse_rifle/cyborg/load_into_chamber()
if(in_chamber)
return 1
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
R.cell.use(charge_cost)
in_chamber = new/obj/item/projectile/beam(src)
return 1
return 0
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
name = "pulse destroyer"
desc = "A heavy-duty, pulse-based energy weapon."
cell_type = "/obj/item/weapon/cell/infinite"
attack_self(mob/living/user as mob)
user << "\red [src.name] has three settings, and they are all DESTROY."
/obj/item/weapon/gun/energy/pulse_rifle/M1911
name = "m1911-P"
desc = "It's not the size of the gun, it's the size of the hole it puts through people."
icon_state = "m1911-p"
cell_type = "/obj/item/weapon/cell/infinite"
isHandgun()
return 1
/obj/item/weapon/gun/energy/pulse_rifle/USP38
name = "USP-38"
desc = "The standard issue sidearm for NanoTrasen Naval Security, adorned with a metallic NT stamp."
icon_state = "usp"
mode = 0
attack_self(mob/living/user as mob)
switch(mode)
if(1)
mode = 0
charge_cost = 100
fire_sound = 'sound/weapons/Taser.ogg'
user << "\red [src.name] is now set to stun."
projectile_type = "/obj/item/projectile/energy/electrode/instant"
if(0)
mode = 1
charge_cost = 100
fire_sound = 'sound/weapons/Laser.ogg'
user << "\red [src.name] is now set to kill."
projectile_type = "/obj/item/projectile/beam"
return
@@ -0,0 +1,258 @@
/obj/item/weapon/gun/energy/ionrifle
name = "ion rifle"
desc = "A man portable anti-armor weapon designed to disable mechanical threats"
icon_state = "ionrifle"
fire_sound = 'sound/weapons/Laser.ogg'
origin_tech = "combat=2;magnets=4"
w_class = 4.0
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK
charge_cost = 100
projectile_type = "/obj/item/projectile/ion"
/obj/item/weapon/gun/energy/ionrifle/emp_act(severity)
if(severity <= 2)
power_supply.use(round(power_supply.maxcharge / severity))
update_icon()
else
return
/obj/item/weapon/gun/energy/decloner
name = "biological demolecularisor"
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
icon_state = "decloner"
fire_sound = 'sound/weapons/pulse3.ogg'
origin_tech = "combat=5;materials=4;powerstorage=3"
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/declone"
obj/item/weapon/gun/energy/staff
name = "staff of change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
icon = 'icons/obj/gun.dmi'
icon_state = "staffofchange"
item_state = "staffofchange"
fire_sound = 'sound/weapons/emitter.ogg'
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK
w_class = 4.0
charge_cost = 200
projectile_type = "/obj/item/projectile/change"
origin_tech = null
clumsy_check = 0
var/charge_tick = 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(200)
return 1
update_icon()
return
click_empty(mob/user = null)
if (user)
user.visible_message("*fizzle*", "\red <b>*fizzle*</b>")
else
src.visible_message("*fizzle*")
playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1)
/obj/item/weapon/gun/energy/staff/animate
name = "staff of animation"
desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
projectile_type = "/obj/item/projectile/animate"
charge_cost = 100
/obj/item/weapon/gun/energy/floragun
name = "floral somatoray"
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
icon_state = "floramut100"
item_state = "obj/item/gun.dmi"
fire_sound = 'sound/effects/stealthoff.ogg'
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/floramut"
origin_tech = "materials=2;biotech=3;powerstorage=3"
modifystate = "floramut"
var/charge_tick = 0
var/mode = 0 //0 = mutate, 1 = yield boost
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
update_icon()
return 1
attack_self(mob/living/user as mob)
switch(mode)
if(0)
mode = 1
charge_cost = 100
user << "\red The [src.name] is now set to increase yield."
projectile_type = "/obj/item/projectile/energy/florayield"
modifystate = "florayield"
if(1)
mode = 0
charge_cost = 100
user << "\red The [src.name] is now set to induce mutations."
projectile_type = "/obj/item/projectile/energy/floramut"
modifystate = "floramut"
update_icon()
return
/obj/item/weapon/gun/energy/meteorgun
name = "meteor gun"
desc = "For the love of god, make sure you're aiming this the right way!"
icon_state = "riotgun"
item_state = "c20r"
w_class = 4
projectile_type = "/obj/item/projectile/meteor"
charge_cost = 100
cell_type = "/obj/item/weapon/cell/potato"
clumsy_check = 0 //Admin spawn only, might as well let clowns use it.
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in ticks)
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
update_icon()
return
/obj/item/weapon/gun/energy/meteorgun/pen
name = "meteor pen"
desc = "The pen is mightier than the sword."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "pen"
item_state = "pen"
w_class = 1
/obj/item/weapon/gun/energy/mindflayer
name = "mind flayer"
desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon."
icon_state = "xray"
projectile_type = "/obj/item/projectile/beam/mindflayer"
fire_sound = 'sound/weapons/Laser.ogg'
obj/item/weapon/gun/energy/staff/focus
name = "mental focus"
desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out."
icon = 'icons/obj/wizard.dmi'
icon_state = "focus"
item_state = "focus"
projectile_type = "/obj/item/projectile/forcebolt"
/*
attack_self(mob/living/user as mob)
if(projectile_type == "/obj/item/projectile/forcebolt")
charge_cost = 200
user << "\red The [src.name] will now strike a small area."
projectile_type = "/obj/item/projectile/forcebolt/strong"
else
charge_cost = 100
user << "\red The [src.name] will now strike only a single person."
projectile_type = "/obj/item/projectile/forcebolt"
*/
/obj/item/weapon/gun/energy/toxgun
name = "plasma pistol"
desc = "A specialized firearm designed to fire lethal bolts of toxins."
icon_state = "toxgun"
fire_sound = 'sound/effects/stealthoff.ogg'
w_class = 3.0
origin_tech = "combat=5;plasmatech=4"
projectile_type = "/obj/item/projectile/energy/plasma"
/obj/item/weapon/gun/energy/sniperrifle
name = "L.W.A.P. Sniper Rifle"
desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope."
icon = 'icons/obj/gun.dmi'
icon_state = "sniper"
fire_sound = 'sound/weapons/marauder.ogg'
origin_tech = "combat=6;materials=5;powerstorage=4"
projectile_type = "/obj/item/projectile/beam/sniper"
slot_flags = SLOT_BACK
charge_cost = 250
fire_delay = 35
w_class = 4.0
var/zoom = 0
/obj/item/weapon/gun/energy/sniperrifle/dropped(mob/user)
user.client.view = world.view
/*
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.
*/
/obj/item/weapon/gun/energy/sniperrifle/verb/zoom()
set category = "Object"
set name = "Use Sniper Scope"
set popup_menu = 0
if(usr.stat || !(istype(usr,/mob/living/carbon/human)))
usr << "You are unable to focus down the scope of the rifle."
return
if(!zoom && global_hud.darkMask[1] in usr.client.screen)
usr << "Your welding equipment gets in the way of you looking down the scope"
return
if(!zoom && usr.get_active_hand() != src)
usr << "You are too distracted to look down the scope, perhaps if it was in your active hand this might work better"
return
if(usr.client.view == world.view)
if(!usr.hud_used.hud_shown)
usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in
usr.button_pressed_F12(1)
usr.client.view = 12
zoom = 1
else
usr.client.view = world.view
if(!usr.hud_used.hud_shown)
usr.button_pressed_F12(1)
zoom = 0
usr << "<font color='[zoom?"blue":"red"]'>Zoom mode [zoom?"en":"dis"]abled.</font>"
return
@@ -0,0 +1,109 @@
/obj/item/weapon/gun/energy/taser
name = "taser gun"
desc = "A small, low capacity gun used for non-lethal takedowns."
icon_state = "taser"
item_state = null //so the human update icon uses the icon_state instead.
fire_sound = 'sound/weapons/Taser.ogg'
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/electrode/high"
cell_type = "/obj/item/weapon/cell/crap"
/obj/item/weapon/gun/energy/taser/cyborg
name = "taser gun"
desc = "A small, low capacity gun used for non-lethal takedowns."
icon_state = "taser"
fire_sound = 'sound/weapons/Taser.ogg'
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/electrode/high"
cell_type = "/obj/item/weapon/cell/secborg"
var/charge_tick = 0
var/recharge_time = 10 //Time it takes for shots to recharge (in ticks)
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process() //Every [recharge_time] ticks, recharge a shot for the cyborg
charge_tick++
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(!power_supply) return 0 //sanity
if(power_supply.charge >= power_supply.maxcharge) return 0 // check if we actually need to recharge
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
R.cell.use(charge_cost) //Take power from the borg...
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
/obj/item/weapon/gun/energy/stunrevolver
name = "stun revolver"
desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger."
icon_state = "stunrevolver"
fire_sound = 'sound/weapons/Gunshot.ogg'
origin_tech = "combat=3;materials=3;powerstorage=2"
charge_cost = 125
projectile_type = "/obj/item/projectile/energy/electrode"
cell_type = "/obj/item/weapon/cell"
/obj/item/weapon/gun/energy/crossbow
name = "mini energy-crossbow"
desc = "A weapon favored by many of the syndicates stealth specialists."
icon_state = "crossbow"
w_class = 2.0
item_state = "crossbow"
m_amt = 2000
origin_tech = "combat=2;magnets=2;syndicate=5"
silenced = 1
fire_sound = 'sound/weapons/Genhit.ogg'
projectile_type = "/obj/item/projectile/energy/bolt"
cell_type = "/obj/item/weapon/cell/crap"
var/charge_tick = 0
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(100)
return 1
update_icon()
return
/obj/item/weapon/gun/energy/crossbow/largecrossbow
name = "Energy Crossbow"
desc = "A weapon favored by syndicate infiltration teams."
w_class = 4.0
force = 10
m_amt = 200000
projectile_type = "/obj/item/projectile/energy/bolt/large"
@@ -0,0 +1,80 @@
/obj/item/weapon/gun/energy/temperature
name = "temperature gun"
icon_state = "freezegun"
fire_sound = 'sound/weapons/pulse3.ogg'
desc = "A gun that changes temperatures."
var/temperature = T20C
var/current_temperature = T20C
charge_cost = 100
origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2"
projectile_type = "/obj/item/projectile/temp"
cell_type = "/obj/item/weapon/cell/crap"
New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
attack_self(mob/living/user as mob)
user.set_machine(src)
var/temp_text = ""
if(temperature > (T0C - 50))
temp_text = "<FONT color=black>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
else
temp_text = "<FONT color=blue>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
var/dat = {"<B>Freeze Gun Configuration: </B><BR>
Current output temperature: [temp_text]<BR>
Target output temperature: <A href='?src=\ref[src];temp=-100'>-</A> <A href='?src=\ref[src];temp=-10'>-</A> <A href='?src=\ref[src];temp=-1'>-</A> [current_temperature] <A href='?src=\ref[src];temp=1'>+</A> <A href='?src=\ref[src];temp=10'>+</A> <A href='?src=\ref[src];temp=100'>+</A><BR>
"}
user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1")
onclose(user, "window=freezegun", src)
Topic(href, href_list)
if (..())
return
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
if(amount > 0)
src.current_temperature = min(500, src.current_temperature+amount)
else
src.current_temperature = max(0, src.current_temperature+amount)
if (istype(src.loc, /mob))
attack_self(src.loc)
src.add_fingerprint(usr)
return
process()
switch(temperature)
if(0 to 100) charge_cost = 1000
if(100 to 250) charge_cost = 500
if(251 to 300) charge_cost = 100
if(301 to 400) charge_cost = 500
if(401 to 500) charge_cost = 1000
if(current_temperature != temperature)
var/difference = abs(current_temperature - temperature)
if(difference >= 10)
if(current_temperature < temperature)
temperature -= 10
else
temperature += 10
else
temperature = current_temperature
return
+121
View File
@@ -0,0 +1,121 @@
#define SPEEDLOADER 0
#define FROM_BOX 1
#define MAGAZINE 2
/obj/item/weapon/gun/projectile
desc = "A classic revolver. Uses 357 ammo"
name = "revolver"
icon_state = "revolver"
caliber = "357"
origin_tech = "combat=2;materials=2"
w_class = 3.0
m_amt = 1000
recoil = 1
var/ammo_type = "/obj/item/ammo_casing/a357"
var/list/loaded = list()
var/max_shells = 7
var/load_method = SPEEDLOADER //0 = Single shells or quick loader, 1 = box, 2 = magazine
var/obj/item/ammo_magazine/empty_mag = null
/obj/item/weapon/gun/projectile/New()
..()
for(var/i = 1, i <= max_shells, i++)
loaded += new ammo_type(src)
update_icon()
return
/obj/item/weapon/gun/projectile/load_into_chamber()
if(in_chamber)
return 1 //{R}
if(!loaded.len)
return 0
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
loaded -= AC //Remove casing from loaded list.
if(isnull(AC) || !istype(AC))
return 0
AC.loc = get_turf(src) //Eject casing onto ground.
if(AC.BB)
AC.desc += " This one is spent." //descriptions are magic - only when there's a projectile in the casing
in_chamber = AC.BB //Load projectile into chamber.
AC.BB.loc = src //Set projectile loc to gun.
return 1
return 0
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
var/num_loaded = 0
if(istype(A, /obj/item/ammo_magazine))
if((load_method == MAGAZINE) && loaded.len) return
var/obj/item/ammo_magazine/AM = A
if(AM.stored_ammo.len <= 0)
user << "<span class='warning'>The magazine is empty!</span>"
return
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
if(loaded.len >= max_shells)
break
if(AC.caliber == caliber && loaded.len < max_shells)
AC.loc = src
AM.stored_ammo -= AC
loaded += AC
num_loaded++
if(load_method == MAGAZINE)
user.remove_from_mob(AM)
empty_mag = AM
empty_mag.loc = src
if(istype(A, /obj/item/ammo_casing) && load_method == SPEEDLOADER)
var/obj/item/ammo_casing/AC = A
if(AC.caliber == caliber && loaded.len < max_shells)
user.drop_item()
AC.loc = src
loaded += AC
num_loaded++
if(num_loaded)
user << "\blue You load [num_loaded] shell\s into the gun!"
A.update_icon()
update_icon()
return
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
if (target)
return ..()
if (loaded.len)
if (load_method == SPEEDLOADER)
var/obj/item/ammo_casing/AC = loaded[1]
loaded -= AC
AC.loc = get_turf(src) //Eject casing onto ground.
user << "\blue You unload shell from \the [src]!"
if (load_method == MAGAZINE)
var/obj/item/ammo_magazine/AM = empty_mag
for (var/obj/item/ammo_casing/AC in loaded)
AM.stored_ammo += AC
loaded -= AC
AM.loc = get_turf(src)
empty_mag = null
update_icon()
AM.update_icon()
user << "\blue You unload magazine from \the [src]!"
else
user << "\red Nothing loaded in \the [src]!"
/obj/item/weapon/gun/projectile/examine()
..()
usr << "Has [getAmmo()] round\s remaining."
// if(in_chamber && !loaded.len)
// usr << "However, it has a chambered round."
// if(in_chamber && loaded.len)
// usr << "It also has a chambered round." {R}
return
/obj/item/weapon/gun/projectile/proc/getAmmo()
var/bullets = 0
for(var/obj/item/ammo_casing/AC in loaded)
if(istype(AC))
bullets += 1
return bullets
@@ -0,0 +1,146 @@
/obj/item/weapon/gun/projectile/automatic //Hopefully someone will find a way to make these fire in bursts or something. --Superxpdude
name = "submachine gun"
desc = "A lightweight, fast firing gun. Uses 9mm rounds."
icon_state = "saber" //ugly
w_class = 3.0
max_shells = 18
caliber = "9mm"
origin_tech = "combat=4;materials=2"
ammo_type = "/obj/item/ammo_casing/c9mm"
automatic = 1
fire_delay = 0
isHandgun()
return 0
/obj/item/weapon/gun/projectile/automatic/mini_uzi
name = "Uzi"
desc = "A lightweight, fast firing gun, for when you want someone dead. Uses .45 rounds."
icon_state = "mini-uzi"
w_class = 3.0
max_shells = 16
caliber = ".45"
origin_tech = "combat=5;materials=2;syndicate=8"
ammo_type = "/obj/item/ammo_casing/c45"
isHandgun()
return 1
/obj/item/weapon/gun/projectile/automatic/c20r
name = "\improper C-20r SMG"
desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp"
icon_state = "c20r"
item_state = "c20r"
w_class = 3.0
max_shells = 20
caliber = "12mm"
origin_tech = "combat=5;materials=2;syndicate=8"
ammo_type = "/obj/item/ammo_casing/a12mm"
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
load_method = 2
New()
..()
empty_mag = new /obj/item/ammo_magazine/a12mm/empty(src)
update_icon()
return
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
..()
if(!loaded.len && empty_mag)
empty_mag.loc = get_turf(src.loc)
empty_mag = null
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
update_icon()
return
update_icon()
..()
if(empty_mag)
icon_state = "c20r-[round(loaded.len,4)]"
else
icon_state = "c20r"
return
/obj/item/weapon/gun/projectile/automatic/l6_saw
name = "\improper L6 SAW"
desc = "A rather traditionally made light machine gun with a pleasantly lacquered wooden pistol grip. Has 'Aussec Armoury- 2531' engraved on the reciever"
icon_state = "l6closed100"
item_state = "l6closedmag"
w_class = 4
slot_flags = 0
max_shells = 50
caliber = "a762"
origin_tech = "combat=5;materials=1;syndicate=2"
ammo_type = "/obj/item/ammo_casing/a762"
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
load_method = 2
var/cover_open = 0
var/mag_inserted = 1
/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob)
cover_open = !cover_open
user << "<span class='notice'>You [cover_open ? "open" : "close"] [src]'s cover.</span>"
update_icon()
/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon()
icon_state = "l6[cover_open ? "open" : "closed"][mag_inserted ? round(loaded.len, 25) : "-empty"]"
/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays
if(cover_open)
user << "<span class='notice'>[src]'s cover is open! Close it before firing!</span>"
else
..()
update_icon()
/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user as mob)
if(loc != user)
..()
return //let them pick it up
if(!cover_open || (cover_open && !mag_inserted))
..()
else if(cover_open && mag_inserted)
//drop the mag
empty_mag = new /obj/item/ammo_magazine/a762(src)
empty_mag.stored_ammo = loaded
empty_mag.icon_state = "a762-[round(loaded.len, 10)]"
empty_mag.desc = "There are [loaded.len] shells left!"
empty_mag.loc = get_turf(src.loc)
user.put_in_hands(empty_mag)
empty_mag = null
mag_inserted = 0
loaded = list()
update_icon()
user << "<span class='notice'>You remove the magazine from [src].</span>"
/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob)
if(!cover_open)
user << "<span class='notice'>[src]'s cover is closed! You can't insert a new mag!</span>"
return
else if(cover_open && mag_inserted)
user << "<span class='notice'>[src] already has a magazine inserted!</span>"
return
else if(cover_open && !mag_inserted)
mag_inserted = 1
user << "<span class='notice'>You insert the magazine!</span>"
update_icon()
..()
/* The thing I found with guns in ss13 is that they don't seem to simulate the rounds in the magazine in the gun.
Afaik, since projectile.dm features a revolver, this would make sense since the magazine is part of the gun.
However, it looks like subsequent guns that use removable magazines don't take that into account and just get
around simulating a removable magazine by adding the casings into the loaded list and spawning an empty magazine
when the gun is out of rounds. Which means you can't eject magazines with rounds in them. The below is a very
rough and poor attempt at making that happen. -Ausops */
@@ -0,0 +1,205 @@
/obj/item/weapon/arrow
name = "bolt"
desc = "It's got a tip for you - get the point?"
icon = 'icons/obj/weapons.dmi'
icon_state = "bolt"
item_state = "bolt"
flags = FPRINT | TABLEPASS
throwforce = 8
w_class = 3.0
sharp = 1
/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart.
return
/obj/item/weapon/arrow/quill
name = "vox quill"
desc = "A wickedly barbed quill from some bizarre animal."
icon = 'icons/obj/weapons.dmi'
icon_state = "quill"
item_state = "quill"
throwforce = 5
/obj/item/weapon/arrow/rod
name = "metal rod"
desc = "Don't cry for me, Orithena."
icon_state = "metal-rod"
/obj/item/weapon/arrow/rod/removed(mob/user)
if(throwforce == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow.
user << "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow."
var/obj/item/weapon/shard/shrapnel/S = new()
S.loc = get_turf(src)
src.Del()
/obj/item/weapon/crossbow
name = "powered crossbow"
desc = "A 2557AD twist on an old classic. Pick up that can."
icon = 'icons/obj/weapons.dmi'
icon_state = "crossbow"
item_state = "crossbow-solid"
w_class = 5.0
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT | SLOT_BACK
w_class = 3.0
var/tension = 0 // Current draw on the bow.
var/max_tension = 5 // Highest possible tension.
var/release_speed = 5 // Speed per unit of tension.
var/mob/living/current_user = null // Used to see if the person drawing the bow started drawing it.
var/obj/item/weapon/arrow = null // Nocked arrow.
var/obj/item/weapon/cell/cell = null // Used for firing special projectiles like rods.
/obj/item/weapon/crossbow/attackby(obj/item/W as obj, mob/user as mob)
if(!arrow)
if (istype(W,/obj/item/weapon/arrow))
user.drop_item()
arrow = W
arrow.loc = src
user.visible_message("[user] slides [arrow] into [src].","You slide [arrow] into [src].")
icon_state = "crossbow-nocked"
return
else if(istype(W,/obj/item/stack/rods))
var/obj/item/stack/rods/R = W
R.use(1)
arrow = new /obj/item/weapon/arrow/rod(src)
arrow.fingerprintslast = src.fingerprintslast
arrow.loc = src
icon_state = "crossbow-nocked"
user.visible_message("[user] haphazardly jams [arrow] into [src].","You jam [arrow] into [src].")
if(cell)
if(cell.charge >= 500)
user << "<span class='notice'>[arrow] plinks and crackles as it begins to glow red-hot.</span>"
arrow.throwforce = 15
arrow.icon_state = "metal-rod-superheated"
cell.use(500)
return
if(istype(W, /obj/item/weapon/cell))
if(!cell)
user.drop_item()
W.loc = src
cell = W
user << "<span class='notice'>You jam [cell] into [src] and wire it to the firing coil.</span>"
if(arrow)
if(istype(arrow,/obj/item/weapon/arrow/rod) && arrow.throwforce < 15 && cell.charge >= 500)
user << "<span class='notice'>[arrow] plinks and crackles as it begins to glow red-hot.</span>"
arrow.throwforce = 15
arrow.icon_state = "metal-rod-superheated"
cell.use(500)
else
user << "<span class='notice'>[src] already has a cell installed.</span>"
else if(istype(W, /obj/item/weapon/screwdriver))
if(cell)
var/obj/item/C = cell
C.loc = get_turf(user)
cell = null
user << "<span class='notice'>You jimmy [cell] out of [src] with [W].</span>"
else
user << "<span class='notice'>[src] doesn't have a cell installed.</span>"
else
..()
/obj/item/weapon/crossbow/attack_self(mob/living/user as mob)
if(tension)
if(arrow)
user.visible_message("[user] relaxes the tension on [src]'s string and removes [arrow].","You relax the tension on [src]'s string and remove [arrow].")
var/obj/item/weapon/arrow/A = arrow
A.loc = get_turf(src)
A.removed(user)
arrow = null
else
user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.")
tension = 0
icon_state = "crossbow"
else
draw(user)
/obj/item/weapon/crossbow/proc/draw(var/mob/user as mob)
if(!arrow)
user << "You don't have anything nocked to [src]."
return
if(user.restrained())
return
current_user = user
user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].")
tension = 1
spawn(25) increase_tension(user)
/obj/item/weapon/crossbow/proc/increase_tension(var/mob/user as mob)
if(!arrow || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed.
return
tension++
icon_state = "crossbow-drawn"
if(tension>=max_tension)
tension = max_tension
usr << "[src] clunks as you draw the string to its maximum tension!"
else
user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!")
spawn(25) increase_tension(user)
/obj/item/weapon/crossbow/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if (istype(target, /obj/item/weapon/storage/backpack ))
src.dropped()
return
else if (target.loc == user.loc)
return
else if (locate (/obj/structure/table, src.loc))
return
else if(target == user)
return
if(!tension)
user << "You haven't drawn back the bolt!"
return 0
if (!arrow)
user << "You have no arrow nocked to [src]!"
return 0
else
spawn(0) Fire(target,user,params)
/obj/item/weapon/crossbow/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
add_fingerprint(user)
var/turf/curloc = get_turf(user)
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return
user.visible_message("<span class='danger'>[user] releases [src] and sends [arrow] streaking toward [target]!</span>","<span class='danger'>You release [src] and send [arrow] streaking toward [target]!</span>")
var/obj/item/weapon/arrow/A = arrow
A.loc = get_turf(user)
A.throw_at(target,10,tension*release_speed)
arrow = null
tension = 0
icon_state = "crossbow"
/obj/item/weapon/crossbow/dropped(mob/user)
if(arrow)
var/obj/item/weapon/arrow/A = arrow
A.loc = get_turf(src)
A.removed(user)
arrow = null
tension = 0
icon_state = "crossbow"
@@ -0,0 +1,152 @@
/obj/item/weapon/gun/projectile/silenced
name = "silenced pistol"
desc = "A small, quiet, easily concealable gun. Uses .45 rounds."
icon_state = "silenced_pistol"
w_class = 3.0
max_shells = 12
caliber = ".45"
silenced = 1
origin_tech = "combat=2;materials=2;syndicate=8"
ammo_type = "/obj/item/ammo_casing/c45"
/obj/item/weapon/gun/projectile/deagle
name = "desert eagle"
desc = "A robust handgun that uses .50 AE ammo"
icon_state = "deagle"
force = 14.0
max_shells = 7
caliber = ".50"
ammo_type ="/obj/item/ammo_casing/a50"
load_method = 2
New()
..()
empty_mag = new /obj/item/ammo_magazine/a50/empty(src)
update_icon()
return
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
..()
if(!loaded.len && empty_mag)
empty_mag.loc = get_turf(src.loc)
empty_mag = null
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
update_icon()
return
/obj/item/weapon/gun/projectile/deagle/gold
desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
icon_state = "deagleg"
item_state = "deagleg"
/obj/item/weapon/gun/projectile/deagle/camo
desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
icon_state = "deaglecamo"
item_state = "deagleg"
/obj/item/weapon/gun/projectile/gyropistol
name = "gyrojet pistol"
desc = "A bulky pistol designed to fire self propelled rounds"
icon_state = "gyropistol"
max_shells = 8
caliber = "75"
fire_sound = 'sound/effects/Explosion1.ogg'
origin_tech = "combat=3"
ammo_type = "/obj/item/ammo_casing/a75"
load_method = 2
New()
..()
empty_mag = new /obj/item/ammo_magazine/a75/empty(src)
update_icon()
return
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
..()
if(!loaded.len && empty_mag)
empty_mag.loc = get_turf(src.loc)
empty_mag = null
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
update_icon()
return
update_icon()
..()
if(empty_mag)
icon_state = "gyropistolloaded"
else
icon_state = "gyropistol"
return
/obj/item/weapon/gun/projectile/pistol
name = "\improper Stechtkin pistol"
desc = "A small, easily concealable gun. Uses 9mm rounds."
icon_state = "pistol"
w_class = 2
max_shells = 8
caliber = "9mm"
silenced = 0
origin_tech = "combat=2;materials=2;syndicate=2"
ammo_type = "/obj/item/ammo_casing/c9mm"
load_method = 2
/obj/item/weapon/gun/projectile/pistol/New()
..()
empty_mag = new /obj/item/ammo_magazine/mc9mm/empty(src)
return
/obj/item/weapon/gun/projectile/pistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
..()
if(!loaded.len && empty_mag)
empty_mag.loc = get_turf(src.loc)
empty_mag = null
return
/obj/item/weapon/gun/projectile/pistol/attack_hand(mob/user as mob)
if(loc == user)
if(silenced)
if(user.l_hand != src && user.r_hand != src)
..()
return
user << "<span class='notice'>You unscrew [silenced] from [src].</span>"
user.put_in_hands(silenced)
silenced = 0
w_class = 2
update_icon()
return
..()
/obj/item/weapon/gun/projectile/pistol/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/silencer))
if(user.l_hand != src && user.r_hand != src) //if we're not in his hands
user << "<span class='notice'>You'll need [src] in your hands to do that.</span>"
return
user.drop_item()
user << "<span class='notice'>You screw [I] onto [src].</span>"
silenced = I //dodgy?
w_class = 3
I.loc = src //put the silencer into the gun
update_icon()
return
..()
/obj/item/weapon/gun/projectile/pistol/update_icon()
..()
if(silenced)
icon_state = "pistol-silencer"
else
icon_state = "pistol"
/obj/item/weapon/silencer
name = "silencer"
desc = "a silencer"
icon = 'icons/obj/gun.dmi'
icon_state = "silencer"
w_class = 2
@@ -0,0 +1,140 @@
/obj/item/weapon/storage/pneumatic
name = "pneumatic cannon"
desc = "A large gas-powered cannon."
icon = 'icons/obj/gun.dmi'
icon_state = "pneumatic"
item_state = "pneumatic"
w_class = 5.0
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
max_w_class = 3
max_combined_w_class = 20
var/obj/item/weapon/tank/tank = null // Tank of gas for use in firing the cannon.
var/obj/item/weapon/storage/tank_container = new() // Something to hold the tank item so we don't accidentally fire it.
var/pressure_setting = 10 // Percentage of the gas in the tank used to fire the projectile.
var/possible_pressure_amounts = list(5,10,20,25,50) // Possible pressure settings.
var/minimum_tank_pressure = 10 // Minimum pressure to fire the gun.
var/cooldown = 0 // Whether or not we're cooling down.
var/cooldown_time = 50 // Time between shots.
var/force_divisor = 400 // Force equates to speed. Speed/5 equates to a damage multiplier for whoever you hit.
// For reference, a fully pressurized oxy tank at 50% gas release firing a health
// analyzer with a force_divisor of 10 hit with a damage multiplier of 3000+.
/obj/item/weapon/storage/pneumatic/verb/set_pressure() //set amount of tank pressure.
set name = "Set valve pressure"
set category = "Object"
set src in range(0)
var/N = input("Percentage of tank used per shot:","[src]") as null|anything in possible_pressure_amounts
if (N)
pressure_setting = N
usr << "You dial the pressure valve to [pressure_setting]%."
/obj/item/weapon/storage/pneumatic/verb/eject_tank() //Remove the tank.
set name = "Eject tank"
set category = "Object"
set src in range(0)
if(tank)
usr << "You twist the valve and pop the tank out of [src]."
tank.loc = usr.loc
tank = null
icon_state = "pneumatic"
item_state = "pneumatic"
usr.update_icons()
else
usr << "There's no tank in [src]."
/obj/item/weapon/storage/pneumatic/attackby(obj/item/W as obj, mob/user as mob)
if(!tank && istype(W,/obj/item/weapon/tank))
user.drop_item()
tank = W
tank.loc = src.tank_container
user.visible_message("[user] jams [W] into [src]'s valve and twists it closed.","You jam [W] into [src]'s valve and twist it closed.")
icon_state = "pneumatic-tank"
item_state = "pneumatic-tank"
user.update_icons()
else
..()
/obj/item/weapon/storage/pneumatic/examine()
set src in view()
..()
if (!(usr in view(2)) && usr!=src.loc) return
usr << "The valve is dialed to [pressure_setting]%."
if(tank)
usr << "The tank dial reads [tank.air_contents.return_pressure()] kPa."
else
usr << "Nothing is attached to the tank valve!"
/obj/item/weapon/storage/pneumatic/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if (istype(target, /obj/item/weapon/storage/backpack ))
return
else if (target.loc == user.loc)
return
else if (locate (/obj/structure/table, src.loc))
return
else if(target == user)
return
if (length(contents) == 0)
user << "There's nothing in [src] to fire!"
return 0
else
spawn(0) Fire(target,user,params)
/obj/item/weapon/storage/pneumatic/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
if (length(contents) > 0)
if(user.a_intent == "hurt")
user.visible_message("\red <b> \The [user] fires \the [src] point blank at [M]!</b>")
Fire(M,user)
return
else
Fire(M,user)
return
/obj/item/weapon/storage/pneumatic/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
if (!tank)
user << "There is no gas tank in [src]!"
return 0
if (cooldown)
user << "The chamber hasn't built up enough pressure yet!"
return 0
add_fingerprint(user)
var/turf/curloc = get_turf(user)
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return
var/fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting
if (fire_pressure < minimum_tank_pressure)
user << "There isn't enough gas in the tank to fire [src]."
return 0
var/obj/item/object = contents[1]
var/speed = ((fire_pressure*tank.volume)/object.w_class)/force_divisor //projectile speed.
if(speed>80) speed = 80 //damage cap.
user.visible_message("<span class='danger'>[user] fires [src] and launches [object] at [target]!</span>","<span class='danger'>You fire [src] and launch [object] at [target]!</span>")
src.remove_from_storage(object,user.loc)
object.throw_at(target,10,speed)
var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100)
var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount)
user.loc.assume_air(removed)
cooldown = 1
spawn(cooldown_time)
cooldown = 0
user << "[src]'s gauge informs you it's ready to be fired again."
@@ -0,0 +1,189 @@
/obj/item/weapon/gun/projectile/detective
desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds."
name = "revolver"
icon_state = "detective"
max_shells = 6
caliber = "38"
origin_tech = "combat=2;materials=2"
ammo_type = "/obj/item/ammo_casing/c38"
special_check(var/mob/living/carbon/human/M)
if(caliber == initial(caliber))
return 1
if(prob(70 - (loaded.len * 10))) //minimum probability of 10, maximum of 60
M << "<span class='danger'>[src] blows up in your face.</span>"
M.take_organ_damage(0,20)
M.drop_item()
del(src)
return 0
return 1
verb/rename_gun()
set name = "Name Gun"
set category = "Object"
set desc = "Click to rename your gun. If you're the detective."
var/mob/M = usr
if(!M.mind) return 0
if(!M.mind.assigned_role == "Detective")
M << "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>"
return 0
var/input = stripped_input(usr,"What do you want to name the gun?", ,"", MAX_NAME_LEN)
if(src && input && !M.stat && in_range(M,src))
name = input
M << "You name the gun [input]. Say hello to your new friend."
return 1
attackby(var/obj/item/A as obj, mob/user as mob)
..()
if(istype(A, /obj/item/weapon/screwdriver))
if(caliber == "38")
user << "<span class='notice'>You begin to reinforce the barrel of [src].</span>"
if(loaded.len)
afterattack(user, user) //you know the drill
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='danger'>[src] goes off in your face!</span>")
return
if(do_after(user, 30))
if(loaded.len)
user << "<span class='notice'>You can't modify it!</span>"
return
caliber = "357"
desc = "The barrel and chamber assembly seems to have been modified."
user << "<span class='warning'>You reinforce the barrel of [src]! Now it will fire .357 rounds.</span>"
else if (caliber == "357")
user << "<span class='notice'>You begin to revert the modifications to [src].</span>"
if(loaded.len)
afterattack(user, user) //and again
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='danger'>[src] goes off in your face!</span>")
return
if(do_after(user, 30))
if(loaded.len)
user << "<span class='notice'>You can't modify it!</span>"
return
caliber = "38"
desc = initial(desc)
user << "<span class='warning'>You remove the modifications on [src]! Now it will fire .38 rounds.</span>"
/obj/item/weapon/gun/projectile/detective/semiauto
desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds."
name = "\improper Colt M1911"
icon_state = "colt"
max_shells = 7
caliber = ".45"
ammo_type = "/obj/item/ammo_casing/c45r"
load_method = 2
/obj/item/weapon/gun/projectile/detective/semiauto/New()
..()
empty_mag = new /obj/item/ammo_magazine/c45r/empty(src)
return
/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
..()
if(!loaded.len && empty_mag)
empty_mag.loc = get_turf(src.loc)
empty_mag = null
user << "<span class='notice'>The Magazine falls out and clatters on the floor!</span>"
return
/obj/item/weapon/gun/projectile/mateba
name = "mateba"
desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357
icon_state = "mateba"
origin_tech = "combat=2;materials=2"
// A gun to play Russian Roulette!
// You can spin the chamber to randomize the position of the bullet.
/obj/item/weapon/gun/projectile/russian
name = "Russian Revolver"
desc = "A Russian made revolver. Uses .357 ammo. It has a single slot in it's chamber for a bullet."
max_shells = 6
origin_tech = "combat=2;materials=2"
/obj/item/weapon/gun/projectile/russian/New()
Spin()
update_icon()
/obj/item/weapon/gun/projectile/russian/proc/Spin()
for(var/obj/item/ammo_casing/AC in loaded)
del(AC)
loaded = list()
var/random = rand(1, max_shells)
for(var/i = 1; i <= max_shells; i++)
if(i != random)
loaded += i // Basically null
else
loaded += new ammo_type(src)
/obj/item/weapon/gun/projectile/russian/attackby(var/obj/item/A as obj, mob/user as mob)
if(!A) return
var/num_loaded = 0
if(istype(A, /obj/item/ammo_magazine))
if((load_method == 2) && loaded.len) return
var/obj/item/ammo_magazine/AM = A
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
if(getAmmo() > 0 || loaded.len >= max_shells)
break
if(AC.caliber == caliber && loaded.len < max_shells)
AC.loc = src
AM.stored_ammo -= AC
loaded += AC
num_loaded++
break
A.update_icon()
if(num_loaded)
user.visible_message("<span class='warning'>[user] loads a single bullet into the revolver and spins the chamber.</span>", "<span class='warning'>You load a single bullet into the chamber and spin it.</span>")
else
user.visible_message("<span class='warning'>[user] spins the chamber of the revolver.</span>", "<span class='warning'>You spin the revolver's chamber.</span>")
if(getAmmo() > 0)
Spin()
update_icon()
return
/obj/item/weapon/gun/projectile/russian/attack_self(mob/user as mob)
user.visible_message("<span class='warning'>[user] spins the chamber of the revolver.</span>", "<span class='warning'>You spin the revolver's chamber.</span>")
if(getAmmo() > 0)
Spin()
/obj/item/weapon/gun/projectile/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj)
if(!loaded.len)
user.visible_message("\red *click*", "\red *click*")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(isliving(target) && isliving(user))
if(target == user)
var/datum/organ/external/affecting = user.zone_sel.selecting
if(affecting == "head")
var/obj/item/ammo_casing/AC = loaded[1]
if(!load_into_chamber())
user.visible_message("\red *click*", "\red *click*")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(!in_chamber)
return
var/obj/item/projectile/P = new AC.projectile_type
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='danger'>[user.name] fires [src] at \his head!</span>", "<span class='danger'>You fire [src] at your head!</span>", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
if(!P.nodamage)
user.apply_damage(300, BRUTE, affecting) // You are dead, dead, dead.
return
..()
@@ -0,0 +1,53 @@
/obj/item/weapon/gun/rocketlauncher
var/projectile
name = "rocket launcher"
desc = "MAGGOT."
icon_state = "rocket"
item_state = "rocket"
w_class = 4.0
throw_speed = 2
throw_range = 10
force = 5.0
flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
slot_flags = 0
origin_tech = "combat=8;materials=5"
projectile = /obj/item/missile
var/missile_speed = 2
var/missile_range = 30
var/max_rockets = 1
var/list/rockets = new/list()
/obj/item/weapon/gun/rocketlauncher/examine()
set src in view()
..()
if (!(usr in view(2)) && usr!=src.loc) return
usr << "\blue [rockets.len] / [max_rockets] rockets."
/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/ammo_casing/rocket))
if(rockets.len < max_rockets)
user.drop_item()
I.loc = src
rockets += I
user << "\blue You put the rocket in [src]."
user << "\blue [rockets.len] / [max_rockets] rockets."
else
usr << "\red [src] cannot hold more rockets."
/obj/item/weapon/gun/rocketlauncher/can_fire()
return rockets.len
/obj/item/weapon/gun/rocketlauncher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
if(rockets.len)
var/obj/item/ammo_casing/rocket/I = rockets[1]
var/obj/item/missile/M = new projectile(user.loc)
playsound(user.loc, 'sound/effects/bang.ogg', 50, 1)
M.primed = 1
M.throw_at(target, missile_range, missile_speed)
message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]).")
log_game("[key_name_admin(user)] used a rocket launcher ([src.name]).")
rockets -= I
del(I)
return
else
usr << "\red [src] is empty."
@@ -0,0 +1,137 @@
/obj/item/weapon/gun/projectile/shotgun/pump
name = "shotgun"
desc = "Useful for sweeping alleys."
icon_state = "shotgun"
item_state = "shotgun"
max_shells = 4
w_class = 4.0
force = 10
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK
caliber = "shotgun"
origin_tech = "combat=4;materials=2"
ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"
var/recentpump = 0 // to prevent spammage
var/pumped = 0
var/obj/item/ammo_casing/current_shell = null
isHandgun()
return 0
load_into_chamber()
if(in_chamber)
return 1
return 0
attack_self(mob/living/user as mob)
if(recentpump) return
pump()
recentpump = 1
spawn(10)
recentpump = 0
return
proc/pump(mob/M as mob)
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
pumped = 0
if(current_shell)//We have a shell in the chamber
current_shell.loc = get_turf(src)//Eject casing
current_shell = null
if(in_chamber)
in_chamber = null
if(!loaded.len) return 0
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
loaded -= AC //Remove casing from loaded list.
current_shell = AC
if(AC.BB)
in_chamber = AC.BB //Load projectile into chamber.
update_icon() //I.E. fix the desc
return 1
/obj/item/weapon/gun/projectile/shotgun/pump/combat
name = "combat shotgun"
icon_state = "cshotgun"
max_shells = 8
origin_tech = "combat=5;materials=2"
ammo_type = "/obj/item/ammo_casing/shotgun"
//this is largely hacky and bad :( -Pete
/obj/item/weapon/gun/projectile/shotgun/doublebarrel
name = "double-barreled shotgun"
desc = "A true classic."
icon_state = "dshotgun"
item_state = "shotgun"
max_shells = 2
w_class = 4.0
force = 10
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK
caliber = "shotgun"
origin_tech = "combat=3;materials=1"
ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"
New()
for(var/i = 1, i <= max_shells, i++)
loaded += new ammo_type(src)
update_icon()
return
load_into_chamber()
// if(in_chamber)
// return 1 {R}
if(!loaded.len)
return 0
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
loaded -= AC //Remove casing from loaded list.
AC.desc += " This one is spent."
if(AC.BB)
in_chamber = AC.BB //Load projectile into chamber.
AC.BB.loc = src //Set projectile loc to gun.
return 1
return 0
attack_self(mob/living/user as mob)
if(!(locate(/obj/item/ammo_casing/shotgun) in src) && !loaded.len)
user << "<span class='notice'>\The [src] is empty.</span>"
return
for(var/obj/item/ammo_casing/shotgun/shell in src) //This feels like a hack. //don't code at 3:30am kids!!
if(shell in loaded)
loaded -= shell
shell.loc = get_turf(src.loc)
user << "<span class='notice'>You break \the [src].</span>"
update_icon()
attackby(var/obj/item/A as obj, mob/user as mob)
if(istype(A, /obj/item/ammo_casing) && !load_method)
var/obj/item/ammo_casing/AC = A
if(AC.caliber == caliber && (loaded.len < max_shells) && (contents.len < max_shells)) //forgive me father, for i have sinned
user.drop_item()
AC.loc = src
loaded += AC
user << "<span class='notice'>You load a shell into \the [src]!</span>"
A.update_icon()
update_icon()
if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
user << "<span class='notice'>You begin to shorten the barrel of \the [src].</span>"
if(loaded.len)
afterattack(user, user) //will this work?
afterattack(user, user) //it will. we call it twice, for twice the FUN
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
return
if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY
icon_state = "sawnshotgun"
w_class = 3.0
item_state = "gun"
slot_flags &= ~SLOT_BACK //you can't sling it on your back
slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
name = "sawn-off shotgun"
desc = "Omar's coming!"
user << "<span class='warning'>You shorten the barrel of \the [src]!</span>"
+203
View File
@@ -0,0 +1,203 @@
/*
#define BRUTE "brute"
#define BURN "burn"
#define TOX "tox"
#define OXY "oxy"
#define CLONE "clone"
#define ADD "add"
#define SET "set"
*/
/obj/item/projectile
name = "projectile"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bullet"
density = 1
unacidable = 1
anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots.
flags = FPRINT | TABLEPASS
pass_flags = PASSTABLE
mouse_opacity = 0
var/bumped = 0 //Prevents it from hitting more than one guy at once
var/def_zone = "" //Aiming at
var/mob/firer = null//Who shot it
var/silenced = 0 //Attack message
var/yo = null
var/xo = null
var/current = null
var/obj/shot_from = null // the object which shot us
var/atom/original = null // the original target clicked
var/turf/starting = null // the projectile's starting turf
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
var/p_x = 16
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
var/damage = 10
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
var/projectile_type = "/obj/item/projectile"
var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile.
//Effects
var/stun = 0
var/weaken = 0
var/paralyze = 0
var/irradiate = 0
var/stutter = 0
var/eyeblur = 0
var/drowsy = 0
var/agony = 0
var/embed = 0 // whether or not the projectile can embed itself in the mob
proc/on_hit(var/atom/target, var/blocked = 0)
if(blocked >= 2) return 0//Full block
if(!isliving(target)) return 0
if(isanimal(target)) return 0
var/mob/living/L = target
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY!
return 1
proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
if(!istype(target) || !istype(user))
return 0
var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test....
in_chamber.target = target
in_chamber.flags = flags //Set the flags...
in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile...
in_chamber.firer = user
var/output = in_chamber.process() //Test it!
del(in_chamber) //No need for it anymore
return output //Send it back to the gun!
Bump(atom/A as mob|obj|turf|area)
if(A == firer)
loc = A.loc
return 0 //cannot shoot yourself
if(bumped) return 0
var/forcedodge = 0 // force the projectile to pass
bumped = 1
if(firer && istype(A, /mob))
var/mob/M = A
if(!istype(A, /mob/living))
loc = A.loc
return 0// nope.avi
var/distance = get_dist(starting,loc)
var/miss_modifier = -30
if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
miss_modifier += -30
def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance)
if(!def_zone)
visible_message("\blue \The [src] misses [M] narrowly!")
forcedodge = -1
else
if(silenced)
M << "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!"
else
visible_message("\red [A.name] is hit by the [src.name] 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
if(istype(firer, /mob))
M.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>[src.type]</b>"
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>[src.type]</b>"
msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
else
M.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[M]/[M.ckey]</b> with a <b>[src]</b>"
msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
if(A)
if (!forcedodge)
forcedodge = A.bullet_act(src, def_zone) // searches for return value
if(forcedodge == -1) // the bullet passes through a dense object!
bumped = 0 // reset bumped variable!
if(istype(A, /turf))
loc = A
else
loc = A.loc
permutated.Add(A)
return 0
if(istype(A,/turf))
for(var/obj/O in A)
O.bullet_act(src)
for(var/mob/M in A)
M.bullet_act(src, def_zone)
density = 0
invisibility = 101
del(src)
return 1
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
if(istype(mover, /obj/item/projectile))
return prob(95)
else
return 1
process()
if(kill_count < 1)
del(src)
kill_count--
spawn while(src)
if((!( current ) || loc == current))
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
del(src)
return
step_towards(src, current)
sleep(1)
if(!bumped && !isturf(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original)
sleep(1)
return
/obj/item/projectile/test //Used to see if you can hit them.
invisibility = 101 //Nope! Can't see me!
yo = null
xo = null
var/target = null
var/result = 0 //To pass the message back to the gun.
Bump(atom/A as mob|obj|turf|area)
if(A == firer)
loc = A.loc
return //cannot shoot yourself
if(istype(A, /obj/item/projectile))
return
if(istype(A, /mob/living))
result = 2 //We hit someone, return 1!
return
result = 1
return
process()
var/turf/curloc = get_turf(src)
var/turf/targloc = get_turf(target)
if(!curloc || !targloc)
return 0
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
target = targloc
while(src) //Loop on through!
if(result)
return (result - 1)
if((!( target ) || loc == target))
target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge
step_towards(src, target)
var/mob/living/M = locate() in get_turf(src)
if(istype(M)) //If there is someting living...
return 1 //Return 1
else
M = locate() in get_step(src,target)
if(istype(M))
return 1
@@ -0,0 +1,13 @@
/obj/item/projectile/animate
name = "bolt of animation"
icon_state = "ice_1"
damage = 0
damage_type = BURN
nodamage = 1
flag = "energy"
/obj/item/projectile/animate/Bump(var/atom/change)
if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects))
var/obj/O = change
new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer)
..()
@@ -0,0 +1,171 @@
var/list/beam_master = list()
//Use: Caches beam state images and holds turfs that had these images overlaid.
//Structure:
//beam_master
// icon_states/dirs of beams
// image for that beam
// references for fired beams
// icon_states/dirs for each placed beam image
// turfs that have that icon_state/dir
/obj/item/projectile/beam
name = "laser"
icon_state = "laser"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 40
damage_type = BURN
flag = "laser"
eyeblur = 4
var/frequency = 1
process()
var/reference = "\ref[src]" //So we do not have to recalculate it a ton
var/first = 1 //So we don't make the overlay in the same tile as the firer
spawn while(src) //Move until we hit something
if((!( current ) || loc == current)) //If we pass our target
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
del(src) //Delete if it passes the world edge
return
step_towards(src, current) //Move~
if(kill_count < 1)
del(src)
kill_count--
if(!bumped && !isturf(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original)
if(!first) //Add the overlay as we pass over tiles
var/target_dir = get_dir(src, current) //So we don't call this too much
//If the icon has not been added yet
if( !("[icon_state][target_dir]" in beam_master) )
var/image/I = image(icon,icon_state,10,target_dir) //Generate it.
beam_master["[icon_state][target_dir]"] = I //And cache it!
//Finally add the overlay
src.loc.overlays += beam_master["[icon_state][target_dir]"]
//Add the turf to a list in the beam master so they can be cleaned up easily.
if(reference in beam_master)
var/list/turf_master = beam_master[reference]
if("[icon_state][target_dir]" in turf_master)
var/list/turfs = turf_master["[icon_state][target_dir]"]
turfs += loc
else
turf_master["[icon_state][target_dir]"] = list(loc)
else
var/list/turfs = list()
turfs["[icon_state][target_dir]"] = list(loc)
beam_master[reference] = turfs
else
first = 0
cleanup(reference)
return
Del()
cleanup("\ref[src]")
..()
proc/cleanup(reference) //Waits .3 seconds then removes the overlay.
src = null //we're getting deleted! this will keep the code running
spawn(3)
var/list/turf_master = beam_master[reference]
for(var/laser_state in turf_master)
var/list/turfs = turf_master[laser_state]
for(var/turf/T in turfs)
T.overlays -= beam_master[laser_state]
return
/obj/item/projectile/beam/practice
name = "laser"
icon_state = "laser"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
damage_type = BURN
flag = "laser"
eyeblur = 2
/obj/item/projectile/beam/heavylaser
name = "heavy laser"
icon_state = "heavylaser"
damage = 40
/obj/item/projectile/beam/xray
name = "xray beam"
icon_state = "xray"
damage = 30
/obj/item/projectile/beam/pulse
name = "pulse"
icon_state = "u_laser"
damage = 50
/obj/item/projectile/beam/deathlaser
name = "death laser"
icon_state = "heavylaser"
damage = 60
/obj/item/projectile/beam/emitter
name = "emitter beam"
icon_state = "emitter"
damage = 30
/obj/item/projectile/beam/lastertag/blue
name = "lasertag beam"
icon_state = "bluelaser"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
damage_type = BURN
flag = "laser"
on_hit(var/atom/target, var/blocked = 0)
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/M = target
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
M.Weaken(5)
return 1
/obj/item/projectile/beam/lastertag/red
name = "lasertag beam"
icon_state = "laser"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 0
damage_type = BURN
flag = "laser"
on_hit(var/atom/target, var/blocked = 0)
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/M = target
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
M.Weaken(5)
return 1
/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
flag = "laser"
on_hit(var/atom/target, var/blocked = 0)
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/M = target
if((istype(M.wear_suit, /obj/item/clothing/suit/bluetag))||(istype(M.wear_suit, /obj/item/clothing/suit/redtag)))
M.Weaken(5)
return 1
/obj/item/projectile/beam/sniper
name = "sniper beam"
icon_state = "xray"
damage = 60
stun = 5
weaken = 5
stutter = 5
@@ -0,0 +1,56 @@
/obj/item/projectile/bullet
name = "bullet"
icon_state = "bullet"
damage = 60
damage_type = BRUTE
nodamage = 0
flag = "bullet"
embed = 1
on_hit(var/atom/target, var/blocked = 0)
if (..(target, blocked))
var/mob/living/L = target
shake_camera(L, 3, 2)
/obj/item/projectile/bullet/weakbullet // "rubber" bullets
damage = 10
stun = 5
weaken = 5
embed = 0
/obj/item/projectile/bullet/midbullet
damage = 20
stun = 5
weaken = 5
/obj/item/projectile/bullet/midbullet2
damage = 25
/obj/item/projectile/bullet/suffocationbullet//How does this even work?
name = "co bullet"
damage = 20
damage_type = OXY
/obj/item/projectile/bullet/cyanideround
name = "poison bullet"
damage = 40
damage_type = TOX
/obj/item/projectile/bullet/burstbullet//I think this one needs something for the on hit
name = "exploding bullet"
damage = 20
/obj/item/projectile/bullet/stunshot
name = "stunshot"
damage = 5
stun = 10
weaken = 10
stutter = 10
embed = 0
/obj/item/projectile/bullet/a762
damage = 25
@@ -0,0 +1,96 @@
/obj/item/projectile/change
name = "bolt of change"
icon_state = "ice_1"
damage = 0
damage_type = BURN
nodamage = 1
flag = "energy"
on_hit(var/atom/change)
wabbajack(change)
/obj/item/projectile/change/proc/wabbajack (mob/M as mob in living_mob_list)
if(istype(M, /mob/living) && M.stat != DEAD)
if(M.monkeyizing) return
if(M.has_brain_worms()) return //Borer stuff - RR
M.monkeyizing = 1
M.canmove = 0
M.icon = null
M.overlays.Cut()
M.invisibility = 101
if(istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/Robot = M
if(Robot.mmi) del(Robot.mmi)
else
for(var/obj/item/W in M)
if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
del(W)
continue
W.layer = initial(W.layer)
W.loc = M.loc
W.dropped(M)
var/mob/living/new_mob
var/randomize = pick("monkey","robot","slime","xeno","human")
switch(randomize)
if("monkey")
new_mob = new /mob/living/carbon/monkey(M.loc)
new_mob.universal_speak = 1
if("robot")
new_mob = new /mob/living/silicon/robot(M.loc)
new_mob.gender = M.gender
new_mob.invisibility = 0
new_mob.job = "Cyborg"
var/mob/living/silicon/robot/Robot = new_mob
Robot.mmi = new /obj/item/device/mmi(new_mob)
Robot.mmi.transfer_identity(M) //Does not transfer key/client.
if("slime")
if(prob(50)) new_mob = new /mob/living/carbon/slime/adult(M.loc)
else new_mob = new /mob/living/carbon/slime(M.loc)
new_mob.universal_speak = 1
if("xeno")
var/alien_caste = pick("Hunter","Sentinel","Drone","Larva")
switch(alien_caste)
if("Hunter") new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
if("Sentinel") new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
if("Drone") new_mob = new /mob/living/carbon/alien/humanoid/drone(M.loc)
else new_mob = new /mob/living/carbon/alien/larva(M.loc)
new_mob.universal_speak = 1
if("human")
new_mob = new /mob/living/carbon/human(M.loc)
if(M.gender == MALE)
new_mob.gender = MALE
new_mob.name = pick(first_names_male)
else
new_mob.gender = FEMALE
new_mob.name = pick(first_names_female)
new_mob.name += " [pick(last_names)]"
new_mob.real_name = new_mob.name
var/datum/preferences/A = new() //Randomize appearance for the human
A.randomize_appearance_for(new_mob)
var/mob/living/carbon/human/H = new_mob
var/newspecies = pick(all_species)
H.set_species(newspecies)
else
return
for (var/obj/effect/proc_holder/spell/S in M.spell_list)
new_mob.spell_list += new S.type
new_mob.a_intent = "hurt"
if(M.mind)
M.mind.transfer_to(new_mob)
else
new_mob.key = M.key
new_mob << "<B>Your form morphs into that of a [randomize].</B>"
del(M)
return new_mob
@@ -0,0 +1,87 @@
/obj/item/projectile/energy
name = "energy"
icon_state = "spark"
damage = 0
damage_type = BURN
flag = "energy"
/obj/item/projectile/energy/electrode
name = "electrode"
icon_state = "spark"
nodamage = 1
/*
stun = 10
weaken = 10
stutter = 10
*/
agony = 50
damage_type = HALLOSS
//Damage will be handled on the MOB side, to prevent window shattering.
/obj/item/projectile/energy/declone
name = "declone"
icon_state = "declone"
nodamage = 1
damage_type = CLONE
irradiate = 40
/obj/item/projectile/energy/dart
name = "dart"
icon_state = "toxin"
damage = 5
damage_type = TOX
weaken = 5
/obj/item/projectile/energy/bolt
name = "bolt"
icon_state = "cbbolt"
damage = 10
damage_type = TOX
nodamage = 0
weaken = 10
stutter = 10
/obj/item/projectile/energy/bolt/large
name = "largebolt"
damage = 20
/obj/item/projectile/energy/neurotoxin
name = "neuro"
icon_state = "neurotoxin"
damage = 5
damage_type = TOX
weaken = 5
/obj/item/projectile/energy/plasma
name = "plasma bolt"
icon_state = "energy"
damage = 20
damage_type = TOX
irradiate = 20
/obj/item/projectile/energy/electrode/instant
name = "electrode"
icon_state = "spark"
nodamage = 1
stun = 10
weaken = 10
stutter = 10
/obj/item/projectile/energy/electrode/high
name = "electrode"
icon_state = "spark"
nodamage = 1
/*
stun = 10
weaken = 10
stutter = 10
*/
agony = 70
damage_type = HALLOSS
@@ -0,0 +1,30 @@
/obj/item/projectile/forcebolt
name = "force bolt"
icon = 'icons/obj/projectiles.dmi'
icon_state = "ice_1"
damage = 20
flag = "energy"
embed = 1
/obj/item/projectile/forcebolt/strong
name = "force bolt"
/obj/item/projectile/forcebolt/on_hit(var/atom/target, var/blocked = 0)
var/obj/T = target
var/throwdir = get_dir(firer,target)
T.throw_at(get_edge_target_turf(target, throwdir),10,10)
return 1
/*
/obj/item/projectile/forcebolt/strong/on_hit(var/atom/target, var/blocked = 0)
// NONE OF THIS WORKS. DO NOT USE.
var/throwdir = null
for(var/mob/M in hearers(2, src))
if(M.loc != src.loc)
throwdir = get_dir(src,target)
M.throw_at(get_edge_target_turf(M, throwdir),15,1)
return ..()
*/
@@ -0,0 +1,140 @@
/obj/item/projectile/ion
name = "ion bolt"
icon_state = "ion"
damage = 0
damage_type = BURN
nodamage = 1
flag = "energy"
on_hit(var/atom/target, var/blocked = 0)
empulse(target, 1, 1)
return 1
/obj/item/projectile/bullet/gyro
name ="explosive bolt"
icon_state= "bolter"
damage = 50
flag = "bullet"
on_hit(var/atom/target, var/blocked = 0)
explosion(target, -1, 0, 2)
return 1
/obj/item/projectile/temp
name = "freeze beam"
icon_state = "ice_2"
damage = 0
damage_type = BURN
nodamage = 1
flag = "energy"
var/temperature = 300
on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob
if(istype(target, /mob/living))
var/mob/M = target
M.bodytemperature = temperature
return 1
/obj/item/projectile/meteor
name = "meteor"
icon = 'icons/obj/meteor.dmi'
icon_state = "smallf"
damage = 0
damage_type = BRUTE
nodamage = 1
flag = "bullet"
Bump(atom/A as mob|obj|turf|area)
if(A == firer)
loc = A.loc
return
sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits
if(src)//Do not add to this if() statement, otherwise the meteor won't delete them
if(A)
A.meteorhit(src)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
for(var/mob/M in range(10, src))
if(!M.stat && !istype(M, /mob/living/silicon/ai))\
shake_camera(M, 3, 1)
del(src)
return 1
else
return 0
/obj/item/projectile/energy/floramut
name = "alpha somatoray"
icon_state = "energy"
damage = 0
damage_type = TOX
nodamage = 1
flag = "energy"
on_hit(var/atom/target, var/blocked = 0)
var/mob/living/M = target
// if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //Plantmen possibly get mutated and damaged by the rays.
if(ishuman(target))
var/mob/living/carbon/human/H = M
if((H.species.flags & IS_PLANT) && (M.nutrition < 500))
if(prob(15))
M.apply_effect((rand(30,80)),IRRADIATE)
M.Weaken(5)
for (var/mob/V in viewers(src))
V.show_message("\red [M] writhes in pain as \his vacuoles boil.", 3, "\red You hear the crunching of leaves.", 2)
if(prob(35))
// for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan
// V.show_message("\red [M] is mutated by the radiation beam.", 3, "\red You hear the snapping of twigs.", 2)
if(prob(80))
randmutb(M)
domutcheck(M,null)
else
randmutg(M)
domutcheck(M,null)
else
M.adjustFireLoss(rand(5,15))
M.show_message("\red The radiation beam singes you!")
// for (var/mob/V in viewers(src))
// V.show_message("\red [M] is singed by the radiation beam.", 3, "\red You hear the crackle of burning leaves.", 2)
else if(istype(target, /mob/living/carbon/))
// for (var/mob/V in viewers(src))
// V.show_message("The radiation beam dissipates harmlessly through [M]", 3)
M.show_message("\blue The radiation beam dissipates harmlessly through your body.")
else
return 1
/obj/item/projectile/energy/florayield
name = "beta somatoray"
icon_state = "energy2"
damage = 0
damage_type = TOX
nodamage = 1
flag = "energy"
on_hit(var/atom/target, var/blocked = 0)
var/mob/M = target
// if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //These rays make plantmen fat.
if(ishuman(target)) //These rays make plantmen fat.
var/mob/living/carbon/human/H = M
if((H.species.flags & IS_PLANT) && (M.nutrition < 500))
M.nutrition += 30
else if (istype(target, /mob/living/carbon/))
M.show_message("\blue The radiation beam dissipates harmlessly through your body.")
else
return 1
/obj/item/projectile/beam/mindflayer
name = "flayer ray"
on_hit(var/atom/target, var/blocked = 0)
if(ishuman(target))
var/mob/living/carbon/human/M = target
M.adjustBrainLoss(20)
M.hallucination += 20
+383
View File
@@ -0,0 +1,383 @@
/obj/item/weapon/gun/verb/toggle_firerate()
set name = "Toggle Firerate"
set category = "Object"
firerate = !firerate
if (firerate == 0)
loc << "You will now continue firing when your target moves."
else
loc << "You will now only fire once, then lower your aim, when your target moves."
/obj/item/weapon/gun/verb/lower_aim()
set name = "Lower Aim"
set category = "Object"
if(target)
stop_aim()
usr.visible_message("\blue \The [usr] lowers \the [src]...")
//Clicking gun will still lower aim for guns that don't overwrite this
/obj/item/weapon/gun/attack_self()
lower_aim()
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(mob/user as mob)
stop_aim()
if (user.client)
user.client.remove_gun_icons()
return ..()
/obj/item/weapon/gun/equipped(var/mob/user, var/slot)
if (slot != slot_l_hand && slot != slot_r_hand)
stop_aim()
if (user.client)
user.client.remove_gun_icons()
return ..()
//Removes lock fro mall targets
/obj/item/weapon/gun/proc/stop_aim()
if(target)
for(var/mob/living/M in target)
if(M)
M.NotTargeted(src) //Untargeting people.
del(target)
//Compute how to fire.....
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
//Lets not spam it.
if(lock_time > world.time - 2) return
.
if(ismob(A) && isliving(A) && !(A in target))
Aim(A) //Clicked a mob, aim at them
else //Didn't click someone, check if there is anyone along that guntrace
var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob.
if(M && isliving(M) && M in view(user) && !(M in target))
Aim(M) //Aha! Aim at them!
else if(!ismob(M) || (ismob(M) && !(M in view(user)))) //Nope! They weren't there!
Fire(A,user,params) //Fire like normal, then.
usr.dir = get_cardinal_dir(src, A)
//Aiming at the target mob.
/obj/item/weapon/gun/proc/Aim(var/mob/living/M)
if(!target || !(M in target))
lock_time = world.time
if(target && !automatic) //If they're targeting someone and they have a non automatic weapon.
for(var/mob/living/L in target)
if(L)
L.NotTargeted(src)
del(target)
usr.visible_message("\red <b>[usr] turns \the [src] on [M]!</b>")
else
usr.visible_message("\red <b>[usr] aims \a [src] at [M]!</b>")
M.Targeted(src)
//HE MOVED, SHOOT HIM!
/obj/item/weapon/gun/proc/TargetActed(var/mob/living/T)
var/mob/living/M = loc
if(M == T) return
if(!istype(M)) return
if(src != M.equipped())
stop_aim()
return
M.last_move_intent = world.time
if(can_fire())
var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
if(firing_check == 1)
Fire(T,usr, reflex = 1)
else if(!told_cant_shoot)
M << "\red They can't be hit from here!"
told_cant_shoot = 1
spawn(30)
told_cant_shoot = 0
else
click_empty(M)
usr.dir = get_cardinal_dir(src, T)
if (!firerate) // If firerate is set to lower aim after one shot, untarget the target
T.NotTargeted(src)
//Yay, math!
#define SIGN(X) ((X<0)?-1:1)
proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
//bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]."
var/turf/T
var/mob/living/M
if(X1==X2)
if(Y1==Y2) return 0 //Light cannot be blocked on same tile
else
var/s = SIGN(Y2-Y1)
Y1+=s
while(1)
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
Y1+=s
else
var
m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
signX = SIGN(X2-X1)
signY = SIGN(Y2-Y1)
if(X1<X2) b+=m
while(1)
var/xvert = round(m*X1+b-Y1)
if(xvert) Y1+=signY //Line exits tile vertically
else X1+=signX //Line exits tile horizontally
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
return 0
//Targeting management procs
mob/var
list/targeted_by
target_time = -100
last_move_intent = -100
last_target_click = -5
target_locked = null
mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
if(!I.target)
I.target = list(src)
else if(I.automatic && I.target.len < 5) //Automatic weapon, they can hold down a room.
I.target += src
else if(I.target.len >= 5)
if(ismob(I.loc))
I.loc << "You can only target 5 people at once!"
return
else
return
for(var/mob/living/K in viewers(usr))
K << 'sound/weapons/TargetOn.ogg'
if(!targeted_by) targeted_by = list()
targeted_by += I
I.lock_time = world.time + 20 //Target has 2 second to realize they're targeted and stop (or target the opponent).
src << "((\red <b>Your character is being targeted. They have 2 seconds to stop any click or move actions.</b> \black While targeted, they may \
drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map objects (floors and walls are fine), their items \
(other than a weapon to de-target), or moving will result in being fired upon. \red The aggressor may also fire manually, \
so try not to get on their bad side.\black ))"
if(targeted_by.len == 1)
spawn(0)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locking")
overlays += target_locked
spawn(0)
sleep(20)
if(target_locked)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locked")
update_targeted()
//Adding the buttons to the controler person
var/mob/living/T = I.loc
if(T)
if(T.client)
T.client.add_gun_icons()
else
I.lower_aim()
return
if(m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0)
src << "\red Your move intent is now set to walk, as your targeter permits it." //Self explanitory.
set_m_intent("walk")
//Processing the aiming. Should be probably in separate object with process() but lasy.
while(targeted_by && T.client)
if(last_move_intent > I.lock_time + 10 && !T.client.target_can_move) //If target moved when not allowed to
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
else if(last_move_intent > I.lock_time + 10 && !T.client.target_can_run && m_intent == "run") //If the target ran while targeted
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
if(last_target_click > I.lock_time + 10 && !T.client.target_can_click) //If the target clicked the map to pick something up/shoot/etc
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
sleep(1)
mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
if(!I.silenced)
for(var/mob/living/M in viewers(src))
M << 'sound/weapons/TargetOff.ogg'
targeted_by -= I
I.target.Remove(src) //De-target them
if(!I.target.len)
del(I.target)
var/mob/living/T = I.loc //Remove the targeting icons
if(T && ismob(T) && !I.target)
T.client.remove_gun_icons()
if(!targeted_by.len)
del target_locked //Remove the overlay
del targeted_by
spawn(1) update_targeted()
mob/living/Move()
. = ..()
for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view.
var/mob/living/M = G.loc
if(!(M in view(src)))
NotTargeted(G)
for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s
if(G.target)
for(var/mob/living/M in G.target)
if(M && !(M in view(src)))
M.NotTargeted(G)
//If you move out of range, it isn't going to still stay locked on you any more.
client/var
target_can_move = 0
target_can_run = 0
target_can_click = 0
gun_mode = 0
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
client/proc/add_gun_icons()
if (!usr.item_use_icon)
usr.item_use_icon = new /obj/screen/gun/item(null)
usr.item_use_icon.icon_state = "no_item[target_can_click]"
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
if (!usr.gun_move_icon)
usr.gun_move_icon = new /obj/screen/gun/move(null)
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
if (target_can_move && !usr.gun_run_icon)
usr.gun_run_icon = new /obj/screen/gun/run(null)
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
screen += usr.item_use_icon
screen += usr.gun_move_icon
if (target_can_move)
screen += usr.gun_run_icon
client/proc/remove_gun_icons()
if(isnull(usr)) return 1 // Runtime prevention on N00k agents spawning with SMG
screen -= usr.item_use_icon
screen -= usr.gun_move_icon
if (target_can_move)
screen -= usr.gun_run_icon
del usr.gun_move_icon
del usr.item_use_icon
del usr.gun_run_icon
client/verb/ToggleGunMode()
set hidden = 1
gun_mode = !gun_mode
if(gun_mode)
usr << "You will now take people captive."
add_gun_icons()
else
usr << "You will now shoot where you target."
for(var/obj/item/weapon/gun/G in usr)
G.stop_aim()
remove_gun_icons()
if(usr.gun_setting_icon)
usr.gun_setting_icon.icon_state = "gun[gun_mode]"
client/verb/AllowTargetMove()
set hidden=1
//Changing client's permissions
target_can_move = !target_can_move
if(target_can_move)
usr << "Target may now walk."
usr.gun_run_icon = new /obj/screen/gun/run(null) //adding icon for running permission
screen += usr.gun_run_icon
else
usr << "Target may no longer move."
target_can_run = 0
del(usr.gun_run_icon) //no need for icon for running permission
//Updating walking permission button
if(usr.gun_move_icon)
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in usr)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_move)
M << "Your character may now <b>walk</b> at the discretion of their targeter."
if(!target_can_run)
M << "\red Your move intent is now set to walk, as your targeter permits it."
M.set_m_intent("walk")
else
M << "\red <b>Your character will now be shot if they move.</b>"
mob/living/proc/set_m_intent(var/intent)
if (intent != "walk" && intent != "run")
return 0
m_intent = intent
if(hud_used)
if (hud_used.move_intent)
hud_used.move_intent.icon_state = intent == "walk" ? "walking" : "running"
client/verb/AllowTargetRun()
set hidden=1
//Changing client's permissions
target_can_run = !target_can_run
if(target_can_run)
usr << "Target may now run."
else
usr << "Target may no longer run."
//Updating running permission button
if(usr.gun_run_icon)
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_run)
M << "Your character may now <b>run</b> at the discretion of their targeter."
else
M << "\red <b>Your character will now be shot if they run.</b>"
client/verb/AllowTargetClick()
set hidden=1
//Changing client's permissions
target_can_click = !target_can_click
if(target_can_click)
usr << "Target may now use items."
else
usr << "Target may no longer use items."
if(usr.item_use_icon)
usr.item_use_icon.icon_state = "no_item[target_can_click]"
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_click)
M << "Your character may now <b>use items</b> at the discretion of their targeter."
else
M << "\red <b>Your character will now be shot if they use items.</b>"