Merge branch 'guns' into gun-rewrite

Conflicts:
	code/modules/clothing/suits/armor.dm
	code/modules/clothing/under/ties.dm
	code/modules/projectiles/gun.dm
	code/modules/projectiles/guns/energy/laser.dm
	code/modules/projectiles/guns/energy/nuclear.dm
	code/modules/projectiles/guns/energy/pulse.dm
	code/modules/projectiles/guns/energy/special.dm
	code/modules/projectiles/guns/projectile.dm
	code/modules/projectiles/guns/projectile/automatic.dm
	code/modules/projectiles/guns/projectile/launcher.dm
	code/modules/projectiles/guns/projectile/shotgun.dm
This commit is contained in:
mwerezak
2015-02-11 18:08:43 -05:00
37 changed files with 834 additions and 1122 deletions

View File

@@ -874,7 +874,6 @@
#include "code\modules\clothing\spacesuits\rig\modules\computer.dm"
#include "code\modules\clothing\spacesuits\rig\modules\modules.dm"
#include "code\modules\clothing\spacesuits\rig\modules\ninja.dm"
#include "code\modules\clothing\spacesuits\rig\modules\rig_weapons.dm"
#include "code\modules\clothing\spacesuits\rig\modules\utility.dm"
#include "code\modules\clothing\spacesuits\rig\modules\vision.dm"
#include "code\modules\clothing\spacesuits\rig\suits\alien.dm"

View File

@@ -226,7 +226,7 @@
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.set_dir(2)
for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons
if (G.target)
if (G.aim_targets)
mymob.item_use_icon = new /obj/screen/gun/item(null)
if (mymob.client.target_can_click)
mymob.item_use_icon.set_dir(1)

View File

@@ -157,7 +157,7 @@ var/obj/screen/robot_inventory
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.set_dir(2)
for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons
if (G.target)
if (G.aim_targets)
mymob.item_use_icon = new /obj/screen/gun/item(null)
if (mymob.client.target_can_click)
mymob.item_use_icon.set_dir(1)

View File

@@ -26,7 +26,7 @@
if("revolver")
new /obj/item/weapon/gun/projectile(get_turf(H))
if("detective")
new /obj/item/weapon/gun/projectile/detective(get_turf(H))
new /obj/item/weapon/gun/projectile/revolver/detective(get_turf(H))
if("smg")
new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H))
if("nuclear")

View File

@@ -34,10 +34,10 @@
var/obj/item/weapon/gun/energy/taser/G = new /obj/item/weapon/gun/energy/taser(Tsec)
G.power_supply.charge = 0
else if(lasercolor == "b")
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
var/obj/item/weapon/gun/energy/lasertag/blue/G = new (Tsec)
G.power_supply.charge = 0
else if(lasercolor == "r")
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
var/obj/item/weapon/gun/energy/lasertag/red/G = new (Tsec)
G.power_supply.charge = 0
if (prob(50))
new /obj/item/robot_parts/l_leg(Tsec)
@@ -137,11 +137,11 @@
if(7)
switch(lasercolor)
if("b")
if( !istype(W, /obj/item/weapon/gun/energy/laser/bluetag) )
if( !istype(W, /obj/item/weapon/gun/energy/lasertag/blue) )
return
name = "bluetag ED-209 assembly"
if("r")
if( !istype(W, /obj/item/weapon/gun/energy/laser/redtag) )
if( !istype(W, /obj/item/weapon/gun/energy/lasertag/red) )
return
name = "redtag ED-209 assembly"
if("")

View File

@@ -702,10 +702,10 @@ Auto Patrol: []"},
switch(lasercolor)
if("b")
target_suit = /obj/item/clothing/suit/redtag
target_weapon = /obj/item/weapon/gun/energy/laser/redtag
target_weapon = /obj/item/weapon/gun/energy/lasertag/red
if("r")
target_suit = /obj/item/clothing/suit/bluetag
target_weapon = /obj/item/weapon/gun/energy/laser/bluetag
target_weapon = /obj/item/weapon/gun/energy/lasertag/blue
if((istype(perp.r_hand, target_weapon)) || (istype(perp.l_hand, target_weapon)))
threat += 4

View File

@@ -5,13 +5,13 @@
/obj/machinery/porta_turret/tag
// Reasonable defaults, in case someone manually spawns us
var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment.
installation = /obj/item/weapon/gun/energy/laser/redtag
installation = /obj/item/weapon/gun/energy/lasertag/red
/obj/machinery/porta_turret/tag/red
/obj/machinery/porta_turret/tag/blue
lasercolor = "b"
installation = /obj/item/weapon/gun/energy/laser/bluetag
installation = /obj/item/weapon/gun/energy/lasertag/blue
/obj/machinery/porta_turret/tag/New()
..()
@@ -19,8 +19,8 @@
/obj/machinery/porta_turret/tag/weapon_setup(var/obj/item/weapon/gun/energy/E)
switch(E.type)
if(/obj/item/weapon/gun/energy/laser/bluetag)
eprojectile = /obj/item/weapon/gun/energy/laser/bluetag
if(/obj/item/weapon/gun/energy/lasertag/blue)
eprojectile = /obj/item/weapon/gun/energy/lasertag/blue
lasercolor = "b"
req_access = list(access_maint_tunnels, access_theatre)
check_arrest = 0
@@ -30,8 +30,8 @@
check_anomalies = 0
shot_delay = 30
if(/obj/item/weapon/gun/energy/laser/redtag)
eprojectile = /obj/item/weapon/gun/energy/laser/redtag
if(/obj/item/weapon/gun/energy/lasertag/red)
eprojectile = /obj/item/weapon/gun/energy/lasertag/red
lasercolor = "r"
req_access = list(access_maint_tunnels, access_theatre)
check_arrest = 0
@@ -86,13 +86,13 @@
..()
if(lasercolor == "b" && disabled == 0)
if(istype(Proj, /obj/item/weapon/gun/energy/laser/redtag))
if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/red))
disabled = 1
del(Proj) // qdel
sleep(100)
disabled = 0
if(lasercolor == "r" && disabled == 0)
if(istype(Proj, /obj/item/weapon/gun/energy/laser/bluetag))
if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/blue))
disabled = 1
del(Proj) // qdel
sleep(100)
@@ -110,10 +110,10 @@
switch(lasercolor)
if("b")
target_suit = /obj/item/clothing/suit/redtag
target_weapon = /obj/item/weapon/gun/energy/laser/redtag
target_weapon = /obj/item/weapon/gun/energy/lasertag/red
if("r")
target_suit = /obj/item/clothing/suit/bluetag
target_weapon = /obj/item/weapon/gun/energy/laser/bluetag
target_weapon = /obj/item/weapon/gun/energy/lasertag/blue
if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve

View File

@@ -733,7 +733,7 @@
gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge
user << "<span class='notice'>You add [I] to the turret.</span>"
if(istype(installation, /obj/item/weapon/gun/energy/laser/bluetag) || istype(installation, /obj/item/weapon/gun/energy/laser/redtag))
if(istype(installation, /obj/item/weapon/gun/energy/lasertag/blue) || istype(installation, /obj/item/weapon/gun/energy/lasertag/red))
target_type = /obj/machinery/porta_turret/tag
else
target_type = /obj/machinery/porta_turret

View File

@@ -121,7 +121,7 @@
usr << "There's no mounting point for the module!"
return 0
var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
if(!T)

View File

@@ -54,8 +54,8 @@
/obj/structure/closet/lasertag/red/New()
..()
new /obj/item/weapon/gun/energy/laser/redtag(src)
new /obj/item/weapon/gun/energy/laser/redtag(src)
new /obj/item/weapon/gun/energy/lasertag/red(src)
new /obj/item/weapon/gun/energy/lasertag/red(src)
new /obj/item/clothing/suit/redtag(src)
new /obj/item/clothing/suit/redtag(src)
@@ -68,7 +68,7 @@
/obj/structure/closet/lasertag/blue/New()
..()
new /obj/item/weapon/gun/energy/laser/bluetag(src)
new /obj/item/weapon/gun/energy/laser/bluetag(src)
new /obj/item/weapon/gun/energy/lasertag/blue(src)
new /obj/item/weapon/gun/energy/lasertag/blue(src)
new /obj/item/clothing/suit/bluetag(src)
new /obj/item/clothing/suit/bluetag(src)

View File

@@ -261,7 +261,7 @@
new /obj/item/ammo_magazine/c45m/rubber(src)
new /obj/item/ammo_magazine/c45m/rubber(src)
new /obj/item/taperoll/police(src)
new /obj/item/weapon/gun/projectile/detective/semiauto(src)
new /obj/item/weapon/gun/projectile/detective(src)
new /obj/item/clothing/accessory/holster/armpit(src)
return

View File

@@ -1,51 +0,0 @@
//Weapon types intended to be used with rig modules
/obj/item/weapon/gun/energy/lasercannon/mounted/load_into_chamber()
if(in_chamber)
return 1
var/obj/item/rig_module/module = loc
if(!istype(module))
return 0
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/weapon/rig/suit = H.back
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
suit.cell.use(250)
in_chamber = new /obj/item/projectile/beam/heavylaser(src)
return 1
return 0
/obj/item/weapon/gun/energy/gun/mounted/load_into_chamber()
if(in_chamber)
return 1
var/obj/item/rig_module/module = loc
if(!istype(module))
return 0
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/weapon/rig/suit = H.back
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
suit.cell.use(250)
var/prog_path = projectile_type
in_chamber = new prog_path(src)
return 1
return 0
/obj/item/weapon/gun/energy/taser/mounted/load_into_chamber()
if(in_chamber)
return 1
var/obj/item/rig_module/module = loc
if(!istype(module))
return 0
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/weapon/rig/suit = H.back
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
suit.cell.use(250)
var/prog_path = projectile_type
in_chamber = new prog_path(src)
return 1
return 0

View File

@@ -15,7 +15,7 @@
item_state = "bluetag"
blood_overlay_type = "armor"
body_parts_covered = UPPER_TORSO
allowed = list (/obj/item/weapon/gun/energy/laser/bluetag)
allowed = list (/obj/item/weapon/gun/energy/lasertag/blue)
siemens_coefficient = 3.0
/obj/item/clothing/suit/redtag
@@ -25,7 +25,7 @@
item_state = "redtag"
blood_overlay_type = "armor"
body_parts_covered = UPPER_TORSO
allowed = list (/obj/item/weapon/gun/energy/laser/redtag)
allowed = list (/obj/item/weapon/gun/energy/lasertag/red)
siemens_coefficient = 3.0
/*

View File

@@ -1340,22 +1340,21 @@
desc = "A stun baton used for incapacitating targets; there seems to be a bunch of tally marks set into the handle."
///// Deckard .44 - Callum Leamas - Roaper
/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas
/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas
name = "Deckard .44"
desc = "A custom built revolver, based off the semi-popular Detective Special model."
icon = 'icons/obj/custom_items.dmi'
icon_state = "leamas-empty"
ammo_type = /obj/item/ammo_magazine/c38/rubber
/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas/update_icon()
/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/update_icon()
..()
if(loaded.len)
icon_state = "leamas-loaded"
else
icon_state = "leamas-empty"
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/load_ammo(var/obj/item/A, mob/user)
if(istype(A, /obj/item/ammo_magazine))
flick("leamas-reloading",src)
..()

View File

@@ -223,9 +223,9 @@
src.modules += new /obj/item/borg/sight/hud/sec(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
src.modules += new /obj/item/weapon/melee/baton/robot(src)
src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src)
src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src)
src.modules += new /obj/item/taperoll/police(src)
src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src)
return
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R)
@@ -236,7 +236,7 @@
F.icon_state = "flash"
else if(F.times_used)
F.times_used--
var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in src.modules
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules
if(T.power_supply.charge < T.power_supply.maxcharge)
T.power_supply.give(T.charge_cost)
T.update_icon()
@@ -383,11 +383,11 @@
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/mounted(src)
return
/obj/item/weapon/robot_module/drone

View File

@@ -108,7 +108,7 @@
usr << "There's no mounting point for the module!"
return 0
var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
if(!T)

View File

@@ -1,3 +1,4 @@
//Parent gun type. Guns are weapons that can be aimed at mobs and act over a distance
/obj/item/weapon/gun
name = "gun"
desc = "Its a gun. It's pretty terrible, though."
@@ -7,32 +8,32 @@
flags = CONDUCT
slot_flags = SLOT_BELT|SLOT_HOLSTER
matter = list("metal" = 2000)
w_class = 3.0
w_class = 3
throwforce = 5
throw_speed = 4
throw_range = 5
force = 5.0
force = 5
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 = 0 //0 for keep shooting until aim is lowered
// 1 for one bullet after tarrget moves and aim is lowered
var/fire_delay = 6
var/fire_sound = 'sound/weapons/Gunshot.ogg'
var/fire_sound_text = "gunshot"
var/recoil = 0 //screen shake
var/silenced = 0
var/last_fired = 0
//aiming system stuff
var/keep_aim = 1 //1 for keep shooting until aim is lowered
//0 for one bullet after tarrget moves and aim is lowered
var/multi_aim = 0 //Used to determine if you can target multiple people.
var/tmp/list/mob/living/aim_targets //List of who yer targeting.
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/tmp/lock_time = -100
//Returns 1 if the gun is able to be fired
/obj/item/weapon/gun/proc/ready_to_fire()
if(world.time >= last_fired + fire_delay)
last_fired = world.time
@@ -40,24 +41,41 @@
else
return 0
/obj/item/weapon/gun/proc/load_into_chamber()
return 0
//Checks whether a given mob can use the gun
/obj/item/weapon/gun/proc/special_check(var/mob/user)
if(!istype(user, /mob/living))
return 0
if(!user.IsAdvancedToolUser())
return 0
/obj/item/weapon/gun/proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver.
var/mob/living/M = user
if(HULK in M.mutations)
M << "<span class='danger'>Your fingers are much too large for the trigger guard!</span>"
return 0
if((CLUMSY in M.mutations) && prob(40) && can_fire()) //Clumsy handling
var/obj/in_chamber = get_next_projectile()
if(in_chamber)
if(process_projectile(in_chamber, user, user, pick("l_foot", "r_foot")))
handle_post_fire(user, user)
user.visible_message(
"<span class='danger'>[user] shoots \himself in the foot with \the [src]!</span>",
"<span class='danger'>You shoot yourself in the foot with \the [src]!</span>"
)
M.drop_item()
return 0
return 1
/obj/item/weapon/gun/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?
/obj/item/weapon/gun/afterattack(atom/A, mob/living/user, adjacent, params)
if(adjacent) return //A is adjacent, is the user, or is on the user's person
//decide whether to aim or shoot normally
var/aiming = 0
if(user && user.client && !(A in target))
if(user && user.client && !(A in aim_targets))
var/client/C = user.client
//If help intent is on and we have clicked on an eligible target, switch to aim mode automatically
if(user.a_intent == "help" && isliving(A) && !C.gun_mode)
@@ -72,27 +90,16 @@
else
Fire(A,user,params) //Otherwise, fire normally.
/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(!user) return
/obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone)
if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot)
handle_suicide(user)
else if(user.a_intent == "hurt") //point blank shooting
Fire(A, user, pointblank=1)
else
return ..() //Pistolwhippin'
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())
return
if(istype(user, /mob/living))
var/mob/living/M = user
if (HULK in M.mutations)
M << "<span class='danger'>Your fingers are much too large for the trigger guard!</span>"
return
/obj/item/weapon/gun/proc/Fire(atom/target, mob/living/user, params, pointblank=0, reflex=0)
if(!user || !target) return
add_fingerprint(user)
@@ -104,22 +111,70 @@
user << "<span class='warning'>[src] is not ready to fire again!"
return
if(!load_into_chamber()) //CHECK
return click_empty(user)
var/obj/in_chamber = get_next_projectile()
if(!in_chamber)
handle_click_empty(user)
return
user.next_move = world.time + 4
if(process_projectile(in_chamber, user, target, user.zone_sel.selecting, params, pointblank, reflex))
handle_post_fire(user, target, pointblank, reflex)
update_icon()
if(user.hand)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
//returns the next projectile to fire
/obj/item/weapon/gun/proc/get_next_projectile()
return null
//TODO integrate this with gun code better.
//TODO maybe provide user so that subtypes can emit messages if they want?
/obj/item/weapon/gun/proc/can_fire()
return 0
//used by aiming code
/obj/item/weapon/gun/proc/can_hit(atom/target as mob, var/mob/living/user as mob)
if(!special_check(user))
return 2
return 0 //in_chamber.check_fire(target,user)
//called if there was no projectile to shoot
/obj/item/weapon/gun/proc/handle_click_empty(mob/user)
if (user)
user.visible_message("*click click*", "<span class='danger'>*click*</span>")
else
src.visible_message("*click click*")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
//called after successfully firing
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(silenced)
playsound(user, fire_sound, 10, 1)
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"]!")
user.visible_message(
"<span class='danger'>[user] fires [src][pointblank ? " point blank at [target]":""][reflex ? " by reflex":""]!</span>",
"<span class='warning'>You fire [src][reflex ? "by reflex":""]!</span>",
"You hear a [fire_sound_text]!"
)
user.next_move = world.time + 4
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
//does the actual shooting
/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
if(!istype(projectile, /obj/item/projectile))
return 0 //default behaviour only applies to true projectiles
var/obj/item/projectile/P = projectile
//shooting while in shock
var/x_offset = 0
var/y_offset = 0
if(istype(user, /mob/living/carbon))
@@ -131,93 +186,52 @@
y_offset = rand(-1,1)
x_offset = rand(-1,1)
if(in_chamber)
if(params)
in_chamber.set_clickpoint(params)
//Point blank bonus
if(pointblank) P.damage *= 1.3
var/fail = in_chamber.launch(
target = target,
user = user,
launcher = src,
target_zone = user.zone_sel.selecting,
x_offset = x_offset,
y_offset = y_offset
)
//TODO: accuracy modifiers
if(fail) return
if(params)
P.set_clickpoint(params)
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
return !P.launch(target, user, src, target_zone, x_offset, y_offset)
sleep(1)
in_chamber = null
//Suicide handling.
/obj/item/weapon/gun/var/mouthshoot = 0 //To stop people from suiciding twice... >.>
/obj/item/weapon/gun/proc/handle_suicide(mob/living/user)
if(!ishuman(user))
return
var/mob/living/carbon/human/M = user
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]", sharp=1)
user.death()
else
user << "<span class = 'notice'>Ow...</span>"
user.apply_effect(110,AGONY,0)
del(in_chamber)
mouthshoot = 0
return
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
var/obj/item/projectile/in_chamber = get_next_projectile()
if (istype(in_chamber))
user.visible_message("<span class = 'warning'>[user] pulls the trigger.</span>")
if(silenced)
playsound(user, fire_sound, 10, 1)
else
click_empty(user)
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
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>")
if(istype(in_chamber)) in_chamber.damage *= 1.3
Fire(M,user)
return
else if(target && M in target)
Fire(M,user) ///Otherwise, shoot!
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]", sharp=1)
user.death()
else
user << "<span class = 'notice'>Ow...</span>"
user.apply_effect(110,AGONY,0)
del(in_chamber)
mouthshoot = 0
return
else
return ..() //Pistolwhippin'
handle_click_empty(user)
mouthshoot = 0
return

View File

@@ -24,7 +24,6 @@
..()
/obj/item/weapon/gun/launcher/spikethrower/process()
if(spikes < max_spikes && world.time > last_regen + spike_gen_time)
spikes++
last_regen = world.time
@@ -32,7 +31,7 @@
/obj/item/weapon/gun/launcher/spikethrower/examine(mob/user)
..(user)
user << "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining."
user << "It has [spikes] spike\s remaining."
/obj/item/weapon/gun/launcher/spikethrower/update_icon()
icon_state = "spikethrower[spikes]"
@@ -46,21 +45,18 @@
if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis")
user << "\red \The [src] does not respond to you!"
return 0
return 1
return ..()
/obj/item/weapon/gun/launcher/spikethrower/update_release_force()
return
/obj/item/weapon/gun/launcher/spikethrower/load_into_chamber()
if(in_chamber) return 1
if(spikes < 1) return 0
/obj/item/weapon/gun/launcher/spikethrower/can_fire()
return (spikes >= 1)
/obj/item/weapon/gun/launcher/spikethrower/get_next_projectile()
if(spikes < 1) return null
spikes--
in_chamber = new /obj/item/weapon/spike(src)
return 1
/obj/item/weapon/gun/launcher/spikethrower/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
if(..()) update_icon()
return new /obj/item/weapon/spike(src)
//This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites.
/obj/item/weapon/gun/energy/noisecannon
@@ -74,7 +70,7 @@
force = 10
projectile_type = /obj/item/projectile/energy/sonic
cell_type = "/obj/item/weapon/cell/super"
cell_type = /obj/item/weapon/cell/super
fire_delay = 40
fire_sound = 'sound/effects/basscannon.ogg'
@@ -94,10 +90,6 @@
user << "\red \The [src] is far too large for you to pick up."
return
/obj/item/weapon/gun/energy/noisecannon/load_into_chamber() //Does not have ammo.
in_chamber = new projectile_type(src)
return 1
/obj/item/weapon/gun/energy/noisecannon/update_icon()
return

View File

@@ -3,39 +3,79 @@
desc = "A basic energy-based gun."
icon_state = "energy"
fire_sound = 'sound/weapons/Taser.ogg'
fire_sound_text = "laser blast"
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/cell_type = /obj/item/weapon/cell
var/projectile_type = /obj/item/projectile/beam/practice
var/modifystate
var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge
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(!ispath(projectile_type)) return 0
in_chamber = new projectile_type(src)
return 1
//self-recharging
var/self_recharge = 0 //if set, the weapon will recharge itself
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
var/recharge_time = 4
var/charge_tick = 0
/obj/item/weapon/gun/energy/emp_act(severity)
power_supply.use(round(power_supply.maxcharge / severity))
update_icon()
..()
/obj/item/weapon/gun/energy/New()
..()
if(cell_type)
power_supply = new cell_type(src)
power_supply.give(power_supply.maxcharge)
if(self_recharge)
processing_objects.Add(src)
/obj/item/weapon/gun/energy/Del()
if(self_recharge)
processing_objects.Remove(src)
..()
/obj/item/weapon/gun/energy/process()
if(self_recharge) //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 || power_supply.charge >= power_supply.maxcharge)
return 0 // check if we actually need to recharge
if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg...
return 0
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
/obj/item/weapon/gun/energy/get_next_projectile()
if(!power_supply) return null
if(!ispath(projectile_type)) return null
if(!power_supply.use(charge_cost)) return null
return new projectile_type(src)
/obj/item/weapon/gun/energy/proc/get_external_power_supply()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
return R.cell
if(istype(src.loc, /obj/item/rig_module))
var/obj/item/rig_module/module = src.loc
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/weapon/rig/suit = H.back
if(istype(suit))
return suit.cell
return null
/obj/item/weapon/gun/energy/update_icon()
if(charge_meter)
var/ratio = power_supply.charge / power_supply.maxcharge
ratio = round(ratio, 0.25) * 100
if(modifystate)

View File

@@ -5,88 +5,52 @@
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
slot_flags = SLOT_BELT|SLOT_BACK
w_class = 3.0
w_class = 3
force = 10 //it has a stock, might as well give some kind of perk over the egun
matter = list("metal" = 2000)
origin_tech = "combat=3;magnets=2"
projectile_type = /obj/item/projectile/beam
/obj/item/weapon/gun/energy/laser/mounted
self_recharge = 1
use_external_power = 1
/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
/obj/item/weapon/gun/energy/captain
name = "antique laser gun"
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
force = 5
slot_flags = SLOT_BELT
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
self_recharge = 1
/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!"
desc = "With the laser 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"
item_state = "laser"
fire_sound = 'sound/weapons/lasercannonfire.ogg'
origin_tech = "combat=4;materials=3;powerstorage=3"
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = "/obj/item/projectile/beam/heavylaser"
projectile_type = /obj/item/projectile/beam/heavylaser
charge_cost = 250
fire_delay = 20
/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/heavylaser(src)
return 1
return 0
/obj/item/weapon/gun/energy/lasercannon/mounted
self_recharge = 1
use_external_power = 1
recharge_time = 25
/obj/item/weapon/gun/energy/xray
name = "xray laser gun"
@@ -94,82 +58,57 @@ obj/item/weapon/gun/energy/laser/retro
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"
projectile_type = /obj/item/projectile/beam/xray
charge_cost = 50
/obj/item/weapon/gun/energy/sniperrifle
name = "\improper L.W.A.P. sniper rifle"
desc = "A high-power laser rifle fitted with a SMART aiming-system scope."
icon_state = "sniper"
item_state = "laser"
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
force = 10
w_class = 4
zoomdevicename = "scope"
/obj/item/weapon/gun/energy/sniperrifle/verb/scope()
set category = "Object"
set name = "Use Scope"
set popup_menu = 1
zoom()
////////Laser Tag////////////////////
/obj/item/weapon/gun/energy/laser/bluetag
/obj/item/weapon/gun/energy/lasertag
name = "laser tag gun"
item_state = "laser"
desc = "Standard issue weapon of the Imperial Guard"
origin_tech = "combat=1;magnets=2"
self_recharge = 1
matter = list("metal" = 2000)
fire_sound = 'sound/weapons/Laser.ogg'
projectile_type = /obj/item/projectile/beam/lastertag/blue
var/required_vest
/obj/item/weapon/gun/energy/lasertag/special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(!istype(M.wear_suit, required_vest))
M << "\red You need to be wearing your laser tag vest!"
return 0
return ..()
/obj/item/weapon/gun/energy/lasertag/blue
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"
slot_flags = SLOT_BELT|SLOT_HOLSTER
clumsy_check = 0
var/charge_tick = 0
projectile_type = /obj/item/projectile/beam/lastertag/blue
required_vest = /obj/item/clothing/suit/bluetag
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"
/obj/item/weapon/gun/energy/lasertag/red
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"
slot_flags = SLOT_BELT|SLOT_HOLSTER
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
projectile_type = /obj/item/projectile/beam/lastertag/red
required_vest = /obj/item/clothing/suit/redtag

View File

@@ -1,6 +1,6 @@
/obj/item/weapon/gun/energy/gun
name = "energy gun"
desc = "A basic energy-based gun with two settings: Stun and kill."
desc = "An 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'
@@ -12,28 +12,31 @@
var/mode = 0 //0 = stun, 1 = kill
/obj/item/weapon/gun/energy/gun/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/beam/stun
modifystate = "energystun"
update_icon()
if(user.l_hand == src)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
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/beam/stun
modifystate = "energystun"
update_icon()
if(user.l_hand == src)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
/obj/item/weapon/gun/energy/gun/mounted
self_recharge = 1
use_external_power = 1
/obj/item/weapon/gun/energy/gun/nuclear
name = "advanced energy gun"
@@ -41,91 +44,76 @@
icon_state = "nucgun"
origin_tech = "combat=3;materials=5;powerstorage=3"
slot_flags = SLOT_BELT
force = 8
force = 8 //looks heavier than a pistol
self_recharge = 1
var/lightfail = 0
var/charge_tick = 0
New()
..()
processing_objects.Add(src)
//override for failcheck behaviour
/obj/item/weapon/gun/energy/gun/nuclear/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(charge_cost)
update_icon()
return 1
Del()
/obj/item/weapon/gun/energy/gun/nuclear/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
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
/obj/item/weapon/gun/energy/gun/nuclear/proc/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]"
/obj/item/weapon/gun/energy/gun/nuclear/proc/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"
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
/obj/item/weapon/gun/energy/gun/nuclear/proc/update_mode()
if (mode == 0)
overlays += "nucgun-stun"
else if (mode == 1)
overlays += "nucgun-kill"
/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity)
..()
reliability -= round(15/severity)
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()
/obj/item/weapon/gun/energy/gun/nuclear/update_icon()
overlays.Cut()
update_charge()
update_reactor()
update_mode()

View File

@@ -1,6 +1,6 @@
/obj/item/weapon/gun/energy/pulse_rifle
name = "pulse rifle"
desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel."
desc = "A weapon that uses advanced pulse-based beam generation technology to emit powerful laser blasts. Because of its complexity and cost, it is rarely seen in use except by specialists."
icon_state = "pulse"
item_state = null //so the human update icon uses the icon_state instead.
slot_flags = SLOT_BELT|SLOT_BACK
@@ -8,55 +8,46 @@
fire_sound = 'sound/weapons/pulse.ogg'
charge_cost = 200
projectile_type = /obj/item/projectile/beam/pulse
cell_type = "/obj/item/weapon/cell/super"
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 \The [src] is now set to stun."
projectile_type = /obj/item/projectile/beam/stun
if(0)
mode = 1
charge_cost = 100
fire_sound = 'sound/weapons/Laser.ogg'
user << "\red \The [src] 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 \The [name] is now set to DESTROY."
projectile_type = /obj/item/projectile/beam/pulse
return
/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/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/beam/stun
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
/obj/item/weapon/gun/energy/pulse_rifle/mounted
self_recharge = 1
use_external_power = 1
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
name = "pulse destroyer"
desc = "A heavy-duty, pulse-based energy weapon."
desc = "A heavy-duty, pulse-based energy weapon. Because of its complexity and cost, it is rarely seen in use except by specialists."
cell_type = "/obj/item/weapon/cell/infinite"
fire_delay = 10
attack_self(mob/living/user as mob)
user << "\red \The [src] has three settings, and they are all DESTROY."
/obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob)
user << "\red [src.name] has three settings, and they are all DESTROY."
//WHY?
/obj/item/weapon/gun/energy/pulse_rifle/M1911
name = "\improper M1911-P"
desc = "It's not the size of the gun, it's the size of the hole it puts through people."

View File

@@ -9,14 +9,12 @@
flags = CONDUCT
slot_flags = SLOT_BACK
charge_cost = 100
projectile_type = "/obj/item/projectile/ion"
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
if(severity > 2)
return //so it doesn't EMP itself, I guess
..()
/obj/item/weapon/gun/energy/decloner
name = "biological demolecularisor"
@@ -25,59 +23,7 @@
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 = 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
projectile_type = /obj/item/projectile/energy/declone
/obj/item/weapon/gun/energy/floragun
name = "floral somatoray"
@@ -86,55 +32,35 @@ obj/item/weapon/gun/energy/staff
item_state = "obj/item/gun.dmi"
fire_sound = 'sound/effects/stealthoff.ogg'
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/floramut"
projectile_type = /obj/item/projectile/energy/floramut
origin_tech = "materials=2;biotech=3;powerstorage=3"
modifystate = "floramut"
var/charge_tick = 0
self_recharge = 1
var/mode = 0 //0 = mutate, 1 = yield boost
/obj/item/weapon/gun/energy/floragun/New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/floragun/Del()
processing_objects.Remove(src)
..()
/obj/item/weapon/gun/energy/floragun/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/floragun/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"
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"
projectile_type = /obj/item/projectile/energy/floramut
modifystate = "floramut"
update_icon()
return
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag)
if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/tray = target
if(load_into_chamber())
user.visible_message("\red <b> \The [user] fires \the [src] into \the [tray]!</b>")
Fire(target,user)
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag)
//allow shooting into adjacent hydrotrays regardless of intent
if(adjacent_flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics))
user.visible_message("\red <b> \The [user] fires \the [src] into \the [target]!</b>")
Fire(target,user)
return
..()
/obj/item/weapon/gun/energy/meteorgun
@@ -144,32 +70,12 @@ obj/item/weapon/gun/energy/staff
item_state = "c20r"
slot_flags = SLOT_BELT|SLOT_BACK
w_class = 4
projectile_type = "/obj/item/projectile/meteor"
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
self_recharge = 1
recharge_time = 5 //Time it takes for shots to recharge (in ticks)
charge_meter = 0
/obj/item/weapon/gun/energy/meteorgun/pen
name = "meteor pen"
@@ -185,9 +91,49 @@ obj/item/weapon/gun/energy/staff
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"
projectile_type = /obj/item/projectile/beam/mindflayer
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/weapon/gun/energy/toxgun
name = "phoron pistol"
desc = "A specialized firearm designed to fire lethal bolts of phoron."
icon_state = "toxgun"
fire_sound = 'sound/effects/stealthoff.ogg'
w_class = 3.0
origin_tech = "combat=5;phorontech=4"
projectile_type = /obj/item/projectile/energy/phoron
/* Staves */
/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 = CONDUCT
slot_flags = SLOT_BACK
w_class = 4.0
charge_cost = 200
projectile_type = /obj/item/projectile/change
origin_tech = null
self_recharge = 1
charge_meter = 0
/obj/item/weapon/gun/energy/staff/handle_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/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."
@@ -195,7 +141,7 @@ obj/item/weapon/gun/energy/staff/focus
icon_state = "focus"
item_state = "focus"
slot_flags = SLOT_BACK
projectile_type = "/obj/item/projectile/forcebolt"
projectile_type = /obj/item/projectile/forcebolt
/*
attack_self(mob/living/user as mob)
if(projectile_type == "/obj/item/projectile/forcebolt")
@@ -208,37 +154,7 @@ obj/item/weapon/gun/energy/staff/focus
projectile_type = "/obj/item/projectile/forcebolt"
*/
/obj/item/weapon/gun/energy/toxgun
name = "phoron pistol"
desc = "A specialized firearm designed to fire lethal bolts of phoron."
icon_state = "toxgun"
fire_sound = 'sound/effects/stealthoff.ogg'
w_class = 3.0
origin_tech = "combat=5;phorontech=4"
projectile_type = "/obj/item/projectile/energy/phoron"
/obj/item/weapon/gun/energy/sniperrifle
name = "\improper L.W.A.P. sniper rifle"
desc = "A high-power laser rifle 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
force = 10
w_class = 4
zoomdevicename = "scope"
/obj/item/weapon/gun/energy/sniperrifle/verb/scope()
set category = "Object"
set name = "Use Scope"
set popup_menu = 1
zoom()
/* Adminbus guns */
// Serves as a target spotter for the Icarus.
/obj/item/weapon/gun/energy/icarus

View File

@@ -6,38 +6,15 @@
fire_sound = 'sound/weapons/Taser.ogg'
charge_cost = 100
projectile_type = /obj/item/projectile/beam/stun
cell_type = "/obj/item/weapon/cell/crap"
cell_type = /obj/item/weapon/cell/crap
/obj/item/weapon/gun/energy/taser/cyborg
cell_type = "/obj/item/weapon/cell/secborg"
var/charge_tick = 0
var/recharge_time = 10 //Time it takes for shots to recharge (in ticks)
/obj/item/weapon/gun/energy/taser/mounted
self_recharge = 1
use_external_power = 1
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/taser/mounted/cyborg
cell_type = /obj/item/weapon/cell/secborg
recharge_time = 10 //Time it takes for shots to recharge (in ticks)
/obj/item/weapon/gun/energy/stunrevolver
@@ -48,8 +25,7 @@
origin_tech = "combat=3;materials=3;powerstorage=2"
charge_cost = 125
projectile_type = /obj/item/projectile/beam/stun
cell_type = "/obj/item/weapon/cell"
cell_type = /obj/item/weapon/cell
/obj/item/weapon/gun/energy/crossbow
@@ -64,31 +40,9 @@
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
cell_type = /obj/item/weapon/cell/crap
self_recharge = 1
charge_meter = 0
/obj/item/weapon/gun/energy/crossbow/ninja
name = "energy dart thrower"

View File

@@ -9,73 +9,71 @@
origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2"
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = "/obj/item/projectile/temp"
cell_type = "/obj/item/weapon/cell/crap"
projectile_type = /obj/item/projectile/temp
cell_type = /obj/item/weapon/cell/crap
New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/temperature/New()
..()
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
/obj/item/weapon/gun/energy/temperature/Del()
processing_objects.Remove(src)
..()
attack_self(mob/living/user as mob)
user.set_machine(src)
var/temp_text = ""
if(temperature > (T0C - 50))
temp_text = "<FONT color=black>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob)
user.set_machine(src)
var/temp_text = ""
if(temperature > (T0C - 50))
temp_text = "<FONT color=black>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
else
temp_text = "<FONT color=blue>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
var/dat = {"<B>Freeze Gun Configuration: </B><BR>
Current output temperature: [temp_text]<BR>
Target output temperature: <A href='?src=\ref[src];temp=-100'>-</A> <A href='?src=\ref[src];temp=-10'>-</A> <A href='?src=\ref[src];temp=-1'>-</A> [current_temperature] <A href='?src=\ref[src];temp=1'>+</A> <A href='?src=\ref[src];temp=10'>+</A> <A href='?src=\ref[src];temp=100'>+</A><BR>
"}
user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1")
onclose(user, "window=freezegun", src)
/obj/item/weapon/gun/energy/temperature/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
temp_text = "<FONT color=blue>[temperature] ([round(temperature-T0C)]&deg;C) ([round(temperature*1.8-459.67)]&deg;F)</FONT>"
var/dat = {"<B>Freeze Gun Configuration: </B><BR>
Current output temperature: [temp_text]<BR>
Target output temperature: <A href='?src=\ref[src];temp=-100'>-</A> <A href='?src=\ref[src];temp=-10'>-</A> <A href='?src=\ref[src];temp=-1'>-</A> [current_temperature] <A href='?src=\ref[src];temp=1'>+</A> <A href='?src=\ref[src];temp=10'>+</A> <A href='?src=\ref[src];temp=100'>+</A><BR>
"}
src.current_temperature = max(0, src.current_temperature+amount)
if (istype(src.loc, /mob))
attack_self(src.loc)
src.add_fingerprint(usr)
return
user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1")
onclose(user, "window=freezegun", src)
/obj/item/weapon/gun/energy/temperature/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
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)
if(current_temperature != temperature)
var/difference = abs(current_temperature - temperature)
if(difference >= 10)
if(current_temperature < temperature)
temperature -= 10
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
temperature += 10
else
temperature = current_temperature

View File

@@ -1,69 +1,78 @@
#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns
#define EJECT_CASINGS 1 //drop spent casings on the ground after firing
#define CYCLE_CASINGS 2 //experimental: cycle casings, like a revolver. Also works for multibarrelled guns
/obj/item/weapon/gun/projectile
name = "gun"
desc = "A gun that fires bullets."
icon_state = "revolver"
caliber = "357"
origin_tech = "combat=2;materials=2"
w_class = 3
matter = list("metal" = 1000)
recoil = 1
var/eject_casings = 1 //experimental: for guns that don't eject casings, like revolvers.
var/caliber = "357" //determines which casings will fit
var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled
var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine
var/obj/item/ammo_casing/chambered = null
//For SINGLE_CASING or SPEEDLOADER guns
var/max_shells = 0
var/ammo_type = null
var/list/loaded = list()
var/max_shells = 0 //the number of casings that will fit inside
var/ammo_type = null //the type of ammo that the gun comes preloaded with
var/list/loaded = list() //stored ammo
//For MAGAZINE guns
var/magazine_type = null
var/obj/item/ammo_magazine/ammo_magazine = null
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
var/magazine_type = null //the type of magazine that the gun comes preloaded with
var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
var/auto_eject_sound = null
/obj/item/weapon/gun/projectile/New()
..()
if(load_method & (SINGLE_CASING|SPEEDLOADER))
if(ispath(ammo_type) && (load_method & (SINGLE_CASING|SPEEDLOADER)))
for(var/i in 1 to max_shells)
loaded += new ammo_type(src)
if(load_method & MAGAZINE)
if(ispath(magazine_type) && (load_method & MAGAZINE))
ammo_magazine = new magazine_type(src)
update_icon()
//This proc is badly named. There is no "chamber." Would be better to call this get_next_projectile() or something.
/obj/item/weapon/gun/projectile/load_into_chamber()
if(in_chamber)
return 1 //{R}
var/obj/item/ammo_casing/C = null
/obj/item/weapon/gun/projectile/can_fire()
var/obj/item/ammo_casing/C
if(loaded.len)
C = loaded[1] //load next casing.
loaded -= C
C = loaded[1]
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
C = ammo_magazine.stored_ammo[1]
ammo_magazine.stored_ammo -= C
return (C && C.BB)
if(istype(C))
if(eject_casings)
C.loc = get_turf(src) //Eject casing onto ground.
else
//cycle it to the end
if(ammo_magazine)
ammo_magazine.stored_ammo += C
else
loaded += C
/obj/item/weapon/gun/projectile/get_next_projectile()
//store the next ammo_casing in a var so that handle_post_fire() knows which one to eject
//also we might as well remove chambered here, so that we don't have to figure out where it came from later
if(loaded.len)
chambered = loaded[1] //load next casing.
if(handle_casings != HOLD_CASINGS)
loaded -= chambered
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
chambered = ammo_magazine.stored_ammo[1]
if(handle_casings != HOLD_CASINGS)
ammo_magazine.stored_ammo -= chambered
return chambered.BB
if(C.BB)
in_chamber = C.BB
C.BB.loc = src //Set projectile loc to gun.
C.BB = null
return 1
return 0
/obj/item/weapon/gun/projectile/handle_post_fire()
..()
if(chambered)
chambered.BB = null
switch(handle_casings)
if(EJECT_CASINGS) //eject casing onto ground.
chambered.loc = get_turf(src)
if(CYCLE_CASINGS) //cycle the casubg back to the end.
if(ammo_magazine)
ammo_magazine.stored_ammo += chambered
else
loaded += chambered
chambered = null
//Attempts to load A into src, depending on the type of thing being loaded and the load_method
//Maybe this should be broken up into separate procs for each load method?
/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user)
if(istype(A, /obj/item/ammo_magazine))
var/obj/item/ammo_magazine/AM = A
@@ -95,9 +104,6 @@
if(count)
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src]!</span>")
AM.update_icon()
update_icon()
return
else if(istype(A, /obj/item/ammo_casing))
var/obj/item/ammo_casing/C = A
if(!(load_method & SINGLE_CASING) || caliber != C.caliber)
@@ -110,8 +116,9 @@
C.loc = src
loaded.Insert(1, C) //add to the head of the list
user.visible_message("[user] inserts \a [C] into [src].", "<span class='notice'>You insert \a [C] into [src]!</span>")
update_icon()
return
update_icon()
//attempts to unload src
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user)
@@ -120,8 +127,6 @@
user.visible_message("[user] removes [ammo_magazine] from [src].", "<span class='notice'>You remove [ammo_magazine] from [src]!</span>")
ammo_magazine.update_icon()
ammo_magazine = null
update_icon()
else if(loaded.len)
//presumably, if it can be speed-loaded, it can be speed-unloaded.
if(load_method & SPEEDLOADER)
@@ -139,16 +144,15 @@
loaded.len--
user.put_in_hands(C)
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src]!</span>")
update_icon()
else
user << "<span class='warning'>[src] is empty!</span>"
update_icon()
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
load_ammo(A, user)
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
if (target) //TODO replace untargeting with a hotkey
if (aim_targets) //TODO replace untargeting with a hotkey
return ..()
unload_ammo(user)
@@ -164,17 +168,14 @@
/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user)
..()
if(auto_eject && !ammo_magazine.stored_ammo.len)
eject_magazine(user)
//called when the magazine auto-ejects
/obj/item/weapon/gun/projectile/proc/eject_magazine(mob/user)
if(ammo_magazine)
if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len)
ammo_magazine.loc = get_turf(src.loc)
user.visible_message(
"[ammo_magazine] falls out and clatters on the floor!",
"<span class='notice'>[ammo_magazine] falls out and clatters on the floor!</span>"
)
if(auto_eject_sound)
playsound(user, auto_eject_sound, 40, 1)
ammo_magazine = null
update_icon()
@@ -183,10 +184,6 @@
user << "Has [getAmmo()] round\s remaining."
if(ammo_magazine)
user << "It has \a [ammo_magazine] loaded."
// if(in_chamber && !loaded.len)
// user << "However, it has a chambered round."
// if(in_chamber && loaded.len)
// user << "It also has a chambered round." {R}
return
/obj/item/weapon/gun/projectile/proc/getAmmo()
@@ -195,4 +192,6 @@
bullets += loaded.len
if(ammo_magazine && ammo_magazine.stored_ammo)
bullets += ammo_magazine.stored_ammo.len
if(chambered)
bullets += 1
return bullets

View File

@@ -9,8 +9,7 @@
origin_tech = "combat=4;materials=2"
slot_flags = SLOT_BELT
ammo_type = /obj/item/ammo_casing/c9mm
automatic = 1
multi_aim = 1
fire_delay = 0
/obj/item/weapon/gun/projectile/automatic/mini_uzi
@@ -24,7 +23,6 @@
origin_tech = "combat=5;materials=2;syndicate=8"
ammo_type = /obj/item/ammo_casing/c45
/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"
@@ -39,10 +37,7 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/a12mm
auto_eject = 1
/obj/item/weapon/gun/projectile/automatic/c20r/eject_magazine(mob/user)
..()
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
..()

View File

@@ -51,12 +51,11 @@
icon_state = "crossbow"
item_state = "crossbow-solid"
fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise.
ejectshell = 0 // No spent shells.
mouthshoot = 1 // No suiciding with this weapon, causes runtimes.
fire_sound_text = "a solid thunk"
fire_delay = 25
slot_flags = SLOT_BACK
var/obj/item/bolt
var/tension = 0 // Current draw on the bow.
var/max_tension = 5 // Highest possible tension.
var/release_speed = 5 // Speed per unit of tension.
@@ -76,19 +75,25 @@
/obj/item/weapon/gun/launcher/crossbow/update_release_force()
release_force = tension*release_speed
/obj/item/weapon/gun/launcher/crossbow/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
/obj/item/weapon/gun/launcher/crossbow/can_fire()
return (tension && bolt)
if(!..()) return //Only do this on a successful shot.
/obj/item/weapon/gun/launcher/crossbow/get_next_projectile()
return bolt
/obj/item/weapon/gun/launcher/crossbow/handle_post_fire(mob/user, atom/target)
bolt = null
icon_state = "crossbow"
tension = 0
..()
/obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob)
if(tension)
if(in_chamber && in_chamber.loc == src) //Just in case they click it the tick after firing.
user.visible_message("[user] relaxes the tension on [src]'s string and removes [in_chamber].","You relax the tension on [src]'s string and remove [in_chamber].")
in_chamber.loc = get_turf(src)
var/obj/item/weapon/arrow/A = in_chamber
in_chamber = null
if(bolt)
user.visible_message("[user] relaxes the tension on [src]'s string and removes [bolt].","You relax the tension on [src]'s string and remove [bolt].")
bolt.loc = get_turf(src)
var/obj/item/weapon/arrow/A = bolt
bolt = null
A.removed(user)
else
user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.")
@@ -99,7 +104,7 @@
/obj/item/weapon/gun/launcher/crossbow/proc/draw(var/mob/user as mob)
if(!in_chamber)
if(!bolt)
user << "You don't have anything nocked to [src]."
return
@@ -113,7 +118,7 @@
/obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob)
if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed.
if(!bolt || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed.
return
tension++
@@ -127,22 +132,22 @@
spawn(25) increase_tension(user)
/obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob)
if(!in_chamber)
if(!bolt)
if (istype(W,/obj/item/weapon/arrow))
user.drop_item()
in_chamber = W
in_chamber.loc = src
user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].")
bolt = W
bolt.loc = src
user.visible_message("[user] slides [bolt] into [src].","You slide [bolt] into [src].")
icon_state = "crossbow-nocked"
return
else if(istype(W,/obj/item/stack/rods))
var/obj/item/stack/rods/R = W
if (R.use(1))
in_chamber = new /obj/item/weapon/arrow/rod(src)
in_chamber.fingerprintslast = src.fingerprintslast
in_chamber.loc = src
bolt = new /obj/item/weapon/arrow/rod(src)
bolt.fingerprintslast = src.fingerprintslast
bolt.loc = src
icon_state = "crossbow-nocked"
user.visible_message("[user] jams [in_chamber] into [src].","You jam [in_chamber] into [src].")
user.visible_message("[user] jams [bolt] into [src].","You jam [bolt] into [src].")
superheat_rod(user)
return
@@ -169,14 +174,14 @@
..()
/obj/item/weapon/gun/launcher/crossbow/proc/superheat_rod(var/mob/user)
if(!user || !cell || !in_chamber) return
if(!user || !cell || !bolt) return
if(cell.charge < 500) return
if(in_chamber.throwforce >= 15) return
if(!istype(in_chamber,/obj/item/weapon/arrow/rod)) return
if(bolt.throwforce >= 15) return
if(!istype(bolt,/obj/item/weapon/arrow/rod)) return
user << "<span class='notice'>[in_chamber] plinks and crackles as it begins to glow red-hot.</span>"
in_chamber.throwforce = 15
in_chamber.icon_state = "metal-rod-superheated"
user << "<span class='notice'>[bolt] plinks and crackles as it begins to glow red-hot.</span>"
bolt.throwforce = 15
bolt.icon_state = "metal-rod-superheated"
cell.use(500)

View File

@@ -7,78 +7,29 @@
slot_flags = SLOT_BACK
var/release_force = 0
var/fire_sound_text = "a launcher firing"
//Check if we're drawing and if the bow is loaded.
/obj/item/weapon/gun/launcher/load_into_chamber()
return (!isnull(in_chamber))
//Launchers are mechanical, no other impact.
/obj/item/weapon/gun/launcher/emp_act(severity)
return
var/throw_distance = 10
fire_sound_text = "a launcher firing"
//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile.
/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob)
return
return 1
//Override this to avoid a runtime with suicide handling.
/obj/item/weapon/gun/launcher/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
if (M == user && user.zone_sel.selecting == "mouth")
user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it."
return
..()
/obj/item/weapon/gun/launcher/handle_suicide(mob/living/user)
user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it."
return
/obj/item/weapon/gun/launcher/proc/update_release_force()
/obj/item/weapon/gun/launcher/proc/update_release_force(obj/item/projectile)
return 0
/obj/item/weapon/gun/launcher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
/obj/item/weapon/gun/launcher/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
if(!istype(projectile, /obj/item)) return 0
if (!user.IsAdvancedToolUser())
return 0
add_fingerprint(user)
//Make sure target turfs both exist.
var/turf/curloc = get_turf(user)
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return 0
if(!special_check(user))
return 0
if (!ready_to_fire())
if (world.time % 3) //to prevent spam
user << "<span class='warning'>[src] is not ready to fire again!"
return 0
if(!load_into_chamber()) //CHECK
return click_empty(user)
if(!in_chamber)
return 0
update_release_force()
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 [fire_sound_text]!")
in_chamber.loc = get_turf(user)
in_chamber.throw_at(target,10,release_force)
sleep(1)
in_chamber = null
update_icon()
if(user.hand)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
var/obj/item/I = projectile
update_release_force(I)
I.loc = get_turf(user)
I.throw_at(target, throw_distance, release_force, user)
return 1
/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob)

View File

@@ -1,3 +1,21 @@
/obj/item/weapon/gun/projectile/detective
name = "\improper Colt M1911"
desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds."
icon_state = "colt"
caliber = ".45"
origin_tech = "combat=2;materials=2"
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/c45m/rubber
/obj/item/weapon/gun/projectile/detective/flash
name = "\improper Colt M1911 signal pistol"
desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 signal flash rounds."
magazine_type = /obj/item/ammo_magazine/c45m/flash
/obj/item/weapon/gun/projectile/detective/colt
desc = "A cheap Martian knock-off of a Colt M1911."
magazine_type = /obj/item/ammo_magazine/c45m
/obj/item/weapon/gun/projectile/silenced
name = "silenced pistol"
desc = "A small, quiet, easily concealable gun. Uses .45 rounds."
@@ -19,10 +37,6 @@
magazine_type = /obj/item/ammo_magazine/a50
auto_eject = 1
/obj/item/weapon/gun/projectile/deagle/eject_magazine(mob/user)
..()
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
/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"
@@ -32,6 +46,7 @@
desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
icon_state = "deaglecamo"
item_state = "deagleg"
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
@@ -47,10 +62,7 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/a75
auto_eject = 1
/obj/item/weapon/gun/projectile/gyropistol/eject_magazine(mob/user)
..()
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
/obj/item/weapon/gun/projectile/gyropistol/update_icon()
..()

View File

@@ -63,7 +63,6 @@
item_state = "pneumatic-tank"
user.update_icons()
else if(W.w_class <= max_w_class)
var/total_stored = 0
for(var/obj/item/O in src.contents)
total_stored += O.w_class
@@ -80,9 +79,6 @@
/obj/item/weapon/gun/launcher/pneumatic/attack_self(mob/user as mob)
if(contents.len > 0)
var/obj/item/removing = contents[contents.len]
if(removing == in_chamber)
in_chamber = null
removing.loc = get_turf(src)
user.put_in_hands(removing)
user << "You remove [removing] from the hopper."
@@ -90,12 +86,16 @@
user << "There is nothing to remove in \the [src]."
return
/obj/item/weapon/gun/launcher/pneumatic/load_into_chamber()
/obj/item/weapon/gun/launcher/pneumatic/get_next_projectile()
if(!contents.len)
return null
return contents[1]
/obj/item/weapon/gun/launcher/pneumatic/can_fire()
if(!contents.len)
return 0
in_chamber = contents[1]
return !isnull(in_chamber)
var/fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting
return (fire_pressure >= minimum_tank_pressure)
/obj/item/weapon/gun/launcher/pneumatic/examine(mob/user)
if(!..(user, 2))
@@ -107,7 +107,6 @@
user << "Nothing is attached to the tank valve!"
/obj/item/weapon/gun/launcher/pneumatic/special_check(user)
if (!tank)
user << "There is no gas tank in [src]!"
return 0
@@ -117,20 +116,23 @@
user << "There isn't enough gas in the tank to fire [src]."
return 0
return 1
return ..()
/obj/item/weapon/gun/launcher/pneumatic/update_release_force()
if(!in_chamber) return
release_force = ((fire_pressure*tank.volume)/in_chamber.w_class)/force_divisor //projectile speed.
if(release_force >80) release_force = 80 //damage cap.
/obj/item/weapon/gun/launcher/pneumatic/update_release_force(obj/item/projectile)
if(tank)
release_force = ((fire_pressure*tank.volume)/projectile.w_class)/force_divisor //projectile speed.
if(release_force > 80) release_force = 80 //damage cap.
else
release_force = 0
/obj/item/weapon/gun/launcher/pneumatic/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
/obj/item/weapon/gun/launcher/pneumatic/handle_post_fire()
if(tank)
var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100)
var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount)
if(!tank || !..()) return //Only do this on a successful shot.
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)
var/turf/T = get_turf(src.loc)
if(T) T.assume_air(removed)
..()
//Constructable pneumatic cannon.

View File

@@ -4,8 +4,7 @@
icon_state = "revolver"
caliber = "357"
origin_tech = "combat=2;materials=2"
eject_casings = 0
handle_casings = CYCLE_CASINGS
max_shells = 7
ammo_type = /obj/item/ammo_casing/a357
@@ -15,26 +14,23 @@
icon_state = "mateba"
origin_tech = "combat=2;materials=2"
/obj/item/weapon/gun/projectile/detective
/obj/item/weapon/gun/projectile/revolver/detective
name = "revolver"
desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds."
icon_state = "detective"
max_shells = 6
eject_casings = 0
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
if(caliber == initial(caliber) && 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
return ..()
verb/rename_gun()
set name = "Name Gun"
@@ -86,28 +82,9 @@
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
name = "\improper Colt M1911"
desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds."
icon_state = "colt"
caliber = ".45"
eject_casings = 1
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/c45m/rubber
/obj/item/weapon/gun/projectile/detective/semiauto/flash
name = "\improper Colt M1911 signal pistol"
desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 signal flash rounds."
magazine_type = /obj/item/ammo_magazine/c45m/flash
/obj/item/weapon/gun/projectile/detective/semiauto/colt
desc = "A cheap Martian knock-off of a Colt M1911."
magazine_type = /obj/item/ammo_magazine/c45m
/*
// 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 = "\improper Russian revolver"
desc = "A Russian made revolver. Uses .357 ammo. It has a single slot in it's chamber for a bullet."

View File

@@ -1,4 +1,4 @@
/obj/item/weapon/gun/rocketlauncher
/obj/item/weapon/gun/launcher/rocket
name = "rocket launcher"
desc = "MAGGOT."
icon_state = "rocket"
@@ -10,18 +10,19 @@
flags = CONDUCT | USEDELAY
slot_flags = 0
origin_tech = "combat=8;materials=5"
var/projectile = /obj/item/missile
var/missile_speed = 2
var/missile_range = 30
fire_sound = 'sound/effects/bang.ogg'
release_force = 15
throw_distance = 30
var/max_rockets = 1
var/list/rockets = new/list()
/obj/item/weapon/gun/rocketlauncher/examine(mob/user)
/obj/item/weapon/gun/launcher/rocket/examine(mob/user)
if(!..(user, 2))
return
user << "\blue [rockets.len] / [max_rockets] rockets."
/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob)
/obj/item/weapon/gun/launcher/rocket/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()
@@ -32,20 +33,19 @@
else
usr << "\red [src] cannot hold more rockets."
/obj/item/weapon/gun/rocketlauncher/can_fire()
/obj/item/weapon/gun/launcher/rocket/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)
/obj/item/weapon/gun/launcher/rocket/get_next_projectile()
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)
var/obj/item/missile/M = new (src)
M.primed = 1
M.throw_at(target, missile_range, missile_speed,user)
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."
return M
return null
/obj/item/weapon/gun/launcher/rocket/handle_post_fire(mob/user, atom/target)
message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]) at [target].")
log_game("[key_name_admin(user)] used a rocket launcher ([src.name]) at [target].")
..()

View File

@@ -12,40 +12,35 @@
origin_tech = "combat=4;materials=2"
load_method = SINGLE_CASING
ammo_type = /obj/item/ammo_casing/shotgun/pellet
handle_casings = HOLD_CASINGS
var/recentpump = 0 // to prevent spammage
var/pumped = 0
var/obj/item/ammo_casing/current_shell = null
/obj/item/weapon/gun/projectile/shotgun/pump/load_into_chamber()
if(in_chamber)
return 1
return 0
/obj/item/weapon/gun/projectile/shotgun/pump/can_fire()
return (chambered && chambered.BB)
/obj/item/weapon/gun/projectile/shotgun/pump/get_next_projectile()
if(chambered)
return chambered.BB
return null
/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob)
if(world.time >= recentpump + 10)
pump(user)
recentpump = world.time
/obj/item/weapon/gun/projectile/shotgun/pump/getAmmo()
. = ..()
if(current_shell) .++
/obj/item/weapon/gun/projectile/shotgun/pump/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
if(chambered)//We have a shell in the chamber
chambered.loc = get_turf(src)//Eject casing
chambered = null
if(loaded.len)
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
loaded -= AC //Remove casing from loaded list.
chambered = AC
update_icon()
/obj/item/weapon/gun/projectile/shotgun/pump/combat
name = "combat shotgun"
@@ -63,7 +58,7 @@
//SPEEDLOADER because rapid unloading.
//In principle someone could make a speedloader for it, so it makes sense.
load_method = SINGLE_CASING|SPEEDLOADER
eject_casings = 0
handle_casings = CYCLE_CASINGS
max_shells = 2
w_class = 4
force = 10
@@ -88,7 +83,7 @@
w_class = 3
item_state = "gun"
slot_flags &= ~SLOT_BACK //you can't sling it on your back
slot_flags |= SLOT_BELT|SLOT_HOLSTER //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally), or in a holster, why not.
slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not.
name = "sawn-off shotgun"
desc = "Omar's coming!"
user << "<span class='warning'>You shorten the barrel of \the [src]!</span>"

View File

@@ -69,16 +69,16 @@
/obj/item/projectile/proc/on_penetrate(var/atom/A)
return 1
/obj/item/projectile/proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
/obj/item/projectile/proc/check_fire(atom/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
var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test....
trace.target = target
trace.flags = flags //Set the flags...
trace.pass_flags = pass_flags //And the pass flags to that of the real projectile...
trace.firer = user
var/output = trace.process() //Test it!
del(trace) //No need for it anymore
return output //Send it back to the gun!
//sets the click point of the projectile using mouse input params
@@ -141,7 +141,7 @@
//accuracy bonus from aiming
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
if (daddy.aim_targets && original in daddy.aim_targets) //As opposed to no-delay pew pew
miss_modifier += -30
//roll to-hit

View File

@@ -1,10 +1,10 @@
/obj/item/weapon/gun/verb/toggle_firerate()
set name = "Toggle Firerate"
set name = "Toggle Continue Aiming"
set category = "Object"
firerate = !firerate
keep_aim = !keep_aim
if (firerate)
if (keep_aim)
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."
@@ -12,7 +12,7 @@
/obj/item/weapon/gun/verb/lower_aim()
set name = "Lower Aim"
set category = "Object"
if(target)
if(aim_targets)
stop_aim()
usr.visible_message("\blue \The [usr] lowers \the [src]...")
@@ -36,11 +36,11 @@
//Removes lock fro mall targets
/obj/item/weapon/gun/proc/stop_aim()
if(target)
for(var/mob/living/M in target)
if(aim_targets)
for(var/mob/living/M in aim_targets)
if(M)
M.NotTargeted(src) //Untargeting people.
del(target)
del(aim_targets)
//Compute how to fire.....
//Return 1 if a target was found, 0 otherwise.
@@ -49,13 +49,13 @@
if(lock_time > world.time - 2) return
user.set_dir(get_cardinal_dir(src, A))
if(isliving(A) && !(A in target))
if(isliving(A) && !(A in aim_targets))
Aim(A) //Clicked a mob, aim at them
return 1
//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(isliving(M) && (M in view(user)) && !(M in target))
if(isliving(M) && (M in view(user)) && !(M in aim_targets))
Aim(M) //Aha! Aim at them!
return 1
@@ -63,13 +63,13 @@
//Aiming at the target mob.
/obj/item/weapon/gun/proc/Aim(var/mob/living/M)
if(!target || !(M in target))
if(!aim_targets || !(M in aim_targets))
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(aim_targets && !multi_aim) //If they're targeting someone and they have a non multi_aim weapon.
for(var/mob/living/L in aim_targets)
if(L)
L.NotTargeted(src)
del(target)
del(aim_targets)
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>")
@@ -90,29 +90,26 @@
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)
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
usr.set_dir(get_cardinal_dir(src, T))
if (!firerate) // If firerate is set to lower aim after one shot, untarget the target
if (!keep_aim) // If keep_aim 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)
/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
@@ -150,19 +147,19 @@ proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
//Targeting management procs
mob/var
/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)
/mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
if(!I.aim_targets)
I.aim_targets = list(src)
else if(I.multi_aim && I.aim_targets.len < 5) //multi_aim weapon, they can hold down a room.
I.aim_targets += src
else if(I.aim_targets.len >= 5)
if(ismob(I.loc))
I.loc << "You can only target 5 people at once!"
return
@@ -223,43 +220,43 @@ mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
I.last_moved_mob = src
sleep(1)
mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
/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)
I.aim_targets.Remove(src) //De-target them
if(!I.aim_targets.len)
del(I.aim_targets)
var/mob/living/T = I.loc //Remove the targeting icons
if(T && ismob(T) && !I.target)
if(T && ismob(T) && !I.aim_targets)
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()
/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(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
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
/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()
/client/proc/add_gun_icons()
screen += usr.item_use_icon
screen += usr.gun_move_icon
if (target_can_move)
@@ -267,14 +264,14 @@ client/proc/add_gun_icons()
client/proc/remove_gun_icons()
/client/proc/remove_gun_icons()
if(!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
client/verb/ToggleGunMode()
/client/verb/ToggleGunMode()
set hidden = 1
gun_mode = !gun_mode
if(gun_mode)
@@ -288,7 +285,7 @@ client/verb/ToggleGunMode()
usr.gun_setting_icon.icon_state = "gun[gun_mode]"
client/verb/AllowTargetMove()
/client/verb/AllowTargetMove()
set hidden=1
//Changing client's permissions
@@ -310,8 +307,8 @@ client/verb/AllowTargetMove()
//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(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_move)
M << "Your character may now <b>walk</b> at the discretion of their targeter."
if(!target_can_run)
@@ -320,7 +317,7 @@ client/verb/AllowTargetMove()
else
M << "\red <b>Your character will now be shot if they move.</b>"
mob/living/proc/set_m_intent(var/intent)
/mob/living/proc/set_m_intent(var/intent)
if (intent != "walk" && intent != "run")
return 0
m_intent = intent
@@ -346,14 +343,14 @@ client/verb/AllowTargetRun()
//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(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
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()
/client/verb/AllowTargetClick()
set hidden=1
//Changing client's permissions
@@ -370,8 +367,8 @@ client/verb/AllowTargetClick()
//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(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_click)
M << "Your character may now <b>use items</b> at the discretion of their targeter."
else