mirror of
https://github.com/Aurorastation/Aurora-Old.git
synced 2026-08-26 14:16:21 +01:00
Initial Commit
This commit is contained in:
@@ -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"
|
||||
@@ -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'
|
||||
@@ -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)]°C) ([round(temperature*1.8-459.67)]°F)</FONT>"
|
||||
else
|
||||
temp_text = "<FONT color=blue>[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°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
|
||||
@@ -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>"
|
||||
@@ -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
|
||||
@@ -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>"
|
||||
Reference in New Issue
Block a user