mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Merge pull request #8052 from mwerezak/boolit
New bullet types, projectile refactor
This commit is contained in:
@@ -731,9 +731,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/shield/riot,
|
||||
/obj/item/weapon/shield/riot,
|
||||
/obj/item/weapon/shield/riot,
|
||||
/obj/item/weapon/storage/box/flashbangs,
|
||||
/obj/item/weapon/storage/box/flashbangs,
|
||||
/obj/item/weapon/storage/box/flashbangs,
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/weapon/handcuffs,
|
||||
@@ -742,13 +739,26 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot)
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/weapon/storage/box/flashbangs,
|
||||
/obj/item/weapon/storage/box/beanbags,
|
||||
/obj/item/weapon/storage/box/handcuffs)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Riot gear crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/energyweapons
|
||||
name = "Energy weapons crate"
|
||||
contains = list(/obj/item/weapon/gun/energy/laser,
|
||||
/obj/item/weapon/gun/energy/laser,
|
||||
/obj/item/weapon/gun/energy/gun)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "energy weapons crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/ballistic
|
||||
name = "Ballistic gear crate"
|
||||
@@ -775,13 +785,14 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/shotgunammo
|
||||
name = "Shotgun shells"
|
||||
name = "Ballistic ammunition crate"
|
||||
contains = list(/obj/item/weapon/storage/box/shotgunammo,
|
||||
/obj/item/weapon/storage/box/shotgunammo,
|
||||
/obj/item/weapon/storage/box/shotgunammo)
|
||||
/obj/item/weapon/storage/box/shotgunshells,
|
||||
/obj/item/weapon/storage/box/shotgunshells)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Shotgun shells"
|
||||
containername = "ballistic ammunition crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
|
||||
@@ -224,6 +224,9 @@ update_flag
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
if(Proj.damage)
|
||||
src.health -= round(Proj.damage / 2)
|
||||
healthcheck()
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
category = "Medical"
|
||||
|
||||
/datum/autolathe/recipe/shotgun_blanks
|
||||
name = "ammunition (shotgun, blanks)"
|
||||
name = "ammunition (shotgun, blank)"
|
||||
path = /obj/item/ammo_casing/shotgun/blank
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
@@ -211,11 +211,21 @@
|
||||
path = /obj/item/ammo_casing/shotgun/beanbag
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/shotgun_flash
|
||||
name = "ammunition (shotgun, flash)"
|
||||
path = /obj/item/ammo_casing/shotgun/flash
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/magazine_rubber
|
||||
name = "ammunition (rubber)"
|
||||
path = /obj/item/ammo_magazine/c45r
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/magazine_flash
|
||||
name = "ammunition (flash)"
|
||||
path = /obj/item/ammo_magazine/c45f
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/consolescreen
|
||||
name = "console screen"
|
||||
path = /obj/item/weapon/stock_parts/console_screen
|
||||
@@ -285,14 +295,14 @@
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/shotgun
|
||||
name = "ammunition (shell, shotgun)"
|
||||
name = "ammunition (slug, shotgun)"
|
||||
path = /obj/item/ammo_casing/shotgun
|
||||
hidden = 1
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/shotgun_dart
|
||||
name = "ammunition (dart, shotgun)"
|
||||
path = /obj/item/ammo_casing/shotgun/dart
|
||||
/datum/autolathe/recipe/shotgun_pellet
|
||||
name = "ammunition (shell, shotgun)"
|
||||
path = /obj/item/ammo_casing/shotgun/pellet
|
||||
hidden = 1
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
health -= Proj.damage
|
||||
..()
|
||||
healthcheck()
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
return
|
||||
|
||||
/obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.damage_type == HALLOSS)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
take_damage(Proj.damage)
|
||||
..()
|
||||
@@ -299,7 +299,7 @@
|
||||
popping = 0
|
||||
|
||||
/obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.damage_type == HALLOSS)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
src.health -= Proj.damage
|
||||
..()
|
||||
|
||||
@@ -1083,6 +1083,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy()
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
AM << "<span class='danger'>You tumble out of the destroyed [src.name]!"
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/passenger/Exit(atom/movable/O)
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
name = "\improper LBX AC 10 \"Scattershot\""
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/midbullet
|
||||
projectile = /obj/item/projectile/bullet/pistol/medium
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
fire_volume = 80
|
||||
projectiles = 40
|
||||
@@ -211,7 +211,7 @@
|
||||
name = "\improper Ultra AC 2"
|
||||
icon_state = "mecha_uac2"
|
||||
equip_cooldown = 10
|
||||
projectile = /obj/item/projectile/bullet/weakbullet
|
||||
projectile = /obj/item/projectile/bullet/pistol/medium
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
projectiles = 300
|
||||
projectiles_per_shot = 3
|
||||
|
||||
@@ -506,8 +506,25 @@
|
||||
var/ignore_threshold
|
||||
if(istype(Proj, /obj/item/projectile/beam/pulse))
|
||||
ignore_threshold = 1
|
||||
src.take_damage(Proj.damage,Proj.flag)
|
||||
src.take_damage(Proj.damage, Proj.flag)
|
||||
if(prob(25)) spark_system.start()
|
||||
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold)
|
||||
|
||||
//AP projectiles have a chance to cause additional damage
|
||||
if(Proj.penetrating)
|
||||
var/distance = get_dist(Proj.starting, get_turf(loc))
|
||||
var/hit_occupant = 1 //only allow the occupant to be hit once
|
||||
for(var/i in 1 to min(Proj.penetrating, round(Proj.damage/15)))
|
||||
if(src.occupant && hit_occupant && prob(20))
|
||||
Proj.attack_mob(src.occupant, distance)
|
||||
hit_occupant = 0
|
||||
else
|
||||
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1)
|
||||
|
||||
Proj.penetrating--
|
||||
|
||||
if(prob(15))
|
||||
break //give a chance to exit early
|
||||
|
||||
Proj.on_hit(src)
|
||||
return
|
||||
|
||||
@@ -233,6 +233,21 @@ steam.start() -- spawns the effect
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Illumination
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/effect/smoke/illumination
|
||||
name = "illumination"
|
||||
opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "sparks"
|
||||
|
||||
/obj/effect/effect/smoke/illumination/New(var/newloc, var/brightness=15, var/lifetime=10)
|
||||
time_to_live=lifetime
|
||||
..()
|
||||
SetLuminosity(brightness)
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Bad smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
|
||||
new/obj/effect/effect/smoke/flashbang(src.loc)
|
||||
new/obj/effect/effect/smoke/illumination(src.loc, brightness=15)
|
||||
del(src)
|
||||
return
|
||||
|
||||
proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
|
||||
proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
|
||||
if (locate(/obj/item/weapon/cloaking_device, M)) // Called during the loop that bangs people in lockers/containers and when banging
|
||||
for(var/obj/item/weapon/cloaking_device/S in M) // people in normal view. Could theroetically be called during other explosions.
|
||||
S.active = 0 // -- Polymorph
|
||||
@@ -100,16 +100,6 @@
|
||||
M << "\red Your ears start to ring!"
|
||||
M.update_icons()
|
||||
|
||||
/obj/effect/effect/smoke/flashbang
|
||||
name = "illumination"
|
||||
time_to_live = 10
|
||||
opacity = 0
|
||||
icon_state = "sparks"
|
||||
|
||||
/obj/effect/effect/smoke/flashbang/New()
|
||||
..()
|
||||
SetLuminosity(15)
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
|
||||
desc = "Use of this weapon may constiute a war crime in your area, consult your local captain."
|
||||
name = "clusterbang"
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
new /obj/item/ammo_casing/shotgun/beanbag(src)
|
||||
|
||||
/obj/item/weapon/storage/box/shotgunammo
|
||||
name = "box of shotgun shells"
|
||||
name = "box of shotgun slugs"
|
||||
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."
|
||||
|
||||
New()
|
||||
@@ -162,6 +162,20 @@
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
|
||||
/obj/item/weapon/storage/box/shotgunshells
|
||||
name = "box of shotgun shells"
|
||||
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
new /obj/item/ammo_casing/shotgun/pellet(src)
|
||||
|
||||
/obj/item/weapon/storage/box/flashbangs
|
||||
name = "box of flashbangs (WARNING)"
|
||||
desc = "<B>WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use.</B>"
|
||||
|
||||
@@ -161,6 +161,9 @@
|
||||
del(src)
|
||||
|
||||
/obj/structure/closet/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
health -= Proj.damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
layer = 2
|
||||
var/state = 0
|
||||
var/health = 200
|
||||
var/cover = 50 //how much cover the girder provides against projectiles.
|
||||
|
||||
/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker)
|
||||
if(!damage || !wallbreaker)
|
||||
@@ -14,19 +15,25 @@
|
||||
return 1
|
||||
|
||||
/obj/structure/girder/bullet_act(var/obj/item/projectile/Proj)
|
||||
//Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder)
|
||||
if(Proj.original != src && !prob(cover))
|
||||
return -1 //pass through
|
||||
|
||||
//Tasers and the like should not damage girders.
|
||||
if(Proj.damage_type == HALLOSS || Proj.damage_type == TOX || Proj.damage_type == CLONE)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
if(istype(Proj, /obj/item/projectile/beam))
|
||||
health -= Proj.damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
new /obj/item/stack/sheet/metal(get_turf(src))
|
||||
del(src)
|
||||
var/damage = Proj.damage
|
||||
if(!istype(Proj, /obj/item/projectile/beam))
|
||||
damage *= 0.4 //non beams do reduced damage
|
||||
|
||||
health -= damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
new /obj/item/stack/sheet/metal(get_turf(src))
|
||||
del(src)
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
/obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/wrench) && state == 0)
|
||||
@@ -209,11 +216,13 @@
|
||||
icon_state = "displaced"
|
||||
anchored = 0
|
||||
health = 50
|
||||
cover = 25
|
||||
|
||||
/obj/structure/girder/reinforced
|
||||
icon_state = "reinforced"
|
||||
state = 2
|
||||
health = 500
|
||||
cover = 80
|
||||
|
||||
/obj/structure/cultgirder
|
||||
icon= 'icons/obj/cult.dmi'
|
||||
@@ -222,6 +231,7 @@
|
||||
density = 1
|
||||
layer = 2
|
||||
var/health = 250
|
||||
var/cover = 70
|
||||
|
||||
/obj/structure/cultgirder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker)
|
||||
if(!damage || !wallbreaker)
|
||||
@@ -258,6 +268,14 @@
|
||||
dismantle()
|
||||
|
||||
/obj/structure/cultgirder/bullet_act(var/obj/item/projectile/Proj) //No beam check- How else will you destroy the cult girder with silver bullets?????
|
||||
//Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder)
|
||||
if(Proj.original != src && !prob(cover))
|
||||
return -1 //pass through
|
||||
|
||||
//Tasers and the like should not damage cultgirders.
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
health -= Proj.damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
|
||||
@@ -59,16 +59,33 @@
|
||||
return !density
|
||||
|
||||
/obj/structure/grille/bullet_act(var/obj/item/projectile/Proj)
|
||||
|
||||
if(!Proj) return
|
||||
|
||||
//Tasers and the like should not damage grilles.
|
||||
if(Proj.damage_type == HALLOSS)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
src.health -= Proj.damage*0.2
|
||||
healthcheck()
|
||||
return 0
|
||||
//Flimsy grilles aren't so great at stopping projectiles. However they can absorb some of the impact
|
||||
var/damage = Proj.damage
|
||||
var/passthrough
|
||||
if(damage > 30)
|
||||
passthrough = 1
|
||||
if(prob(20))
|
||||
Proj.damage *= 0.5 //weaken the projectile
|
||||
else
|
||||
//weaker bullets are affected to a greater extent
|
||||
if(prob(20))
|
||||
passthrough = 0
|
||||
else
|
||||
Proj.damage *= 0.5 //weaken the projectile
|
||||
passthrough = 1
|
||||
|
||||
if(passthrough)
|
||||
. = -1
|
||||
damage *= 0.1 //if the bullet passes through then the grille avoids most of the damage
|
||||
|
||||
src.health -= damage*0.2
|
||||
spawn(0) healthcheck() //spawn to make sure we return properly if the grille is deleted
|
||||
|
||||
/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(iswirecutter(W))
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
return 0
|
||||
|
||||
/obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
health -= Proj.damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//wip wip wup
|
||||
/obj/structure/mirror
|
||||
name = "\improper SalonPro Nano-Mirror(TM)"
|
||||
desc = "The leading technology in hair salon products, utilizing nano-machinery to style your hair just right."
|
||||
name = "mirror"
|
||||
desc = "A SalonPro Nano-Mirror(TM) brand mirror! The leading technology in hair salon products, utilizing nano-machinery to style your hair just right."
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
icon_state = "mirror"
|
||||
density = 0
|
||||
@@ -70,6 +70,9 @@
|
||||
|
||||
|
||||
/obj/structure/mirror/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
if(prob(Proj.damage * 2))
|
||||
if(!shattered)
|
||||
shatter()
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
/obj/structure/window/bullet_act(var/obj/item/projectile/Proj)
|
||||
|
||||
//Tasers and the like should not damage windows.
|
||||
if(Proj.damage_type == HALLOSS)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
|
||||
..()
|
||||
@@ -504,4 +504,4 @@
|
||||
if (W.id == src.id || !W.id)
|
||||
spawn( 0 )
|
||||
W.toggle()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -54,18 +54,6 @@
|
||||
step(user.pulling, get_dir(user.pulling.loc, src))
|
||||
return 1
|
||||
|
||||
/turf/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam/pulse))
|
||||
src.ex_act(2)
|
||||
..()
|
||||
return 0
|
||||
|
||||
/turf/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/bullet/gyro))
|
||||
explosion(src, -1, 0, 2)
|
||||
..()
|
||||
return 0
|
||||
|
||||
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
|
||||
if(movement_disabled && usr.ckey != movement_disabled_exception)
|
||||
usr << "\red Movement is admin-disabled." //This is to identify lag problems
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var/obj/item/weapon/rig/suit = H.back
|
||||
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
|
||||
suit.cell.use(250)
|
||||
var/prog_path = text2path(projectile_type)
|
||||
var/prog_path = projectile_type
|
||||
in_chamber = new prog_path(src)
|
||||
return 1
|
||||
return 0
|
||||
@@ -45,7 +45,7 @@
|
||||
var/obj/item/weapon/rig/suit = H.back
|
||||
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
|
||||
suit.cell.use(250)
|
||||
var/prog_path = text2path(projectile_type)
|
||||
var/prog_path = projectile_type
|
||||
in_chamber = new prog_path(src)
|
||||
return 1
|
||||
return 0
|
||||
@@ -24,7 +24,7 @@ emp_act
|
||||
if(!(def_zone in list("chest", "groin")))
|
||||
reflectchance /= 2
|
||||
if(prob(reflectchance))
|
||||
visible_message("\red <B>The [P.name] gets reflected by [src]'s [wear_suit.name]!</B>")
|
||||
visible_message("\red <B>\The [P] gets reflected by \the [src]'s [wear_suit.name]!</B>")
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
@@ -33,12 +33,7 @@ emp_act
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
// redirect the projectile
|
||||
P.original = locate(new_x, new_y, P.z)
|
||||
P.starting = curloc
|
||||
P.current = curloc
|
||||
P.firer = src
|
||||
P.yo = new_y - curloc.y
|
||||
P.xo = new_x - curloc.x
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
@@ -47,9 +42,9 @@ emp_act
|
||||
var/armor = getarmor_organ(organ, "bullet")
|
||||
if((P.embed && prob(20 + max(P.damage - armor, -10))))
|
||||
var/obj/item/weapon/shard/shrapnel/SP = new()
|
||||
(SP.name) = "[P.name] shrapnel"
|
||||
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
|
||||
(SP.loc) = organ
|
||||
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"
|
||||
SP.desc = "[SP.desc] It looks like it was fired from [P.shot_from]."
|
||||
SP.loc = organ
|
||||
organ.embed(SP)
|
||||
|
||||
return (..(P , def_zone))
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
signaler.signal()
|
||||
|
||||
//Stun Beams
|
||||
if(istype(P, /obj/item/projectile/beam/stun) || istype(P, /obj/item/projectile/bullet/stunshot))
|
||||
if(P.taser_effect)
|
||||
stun_effect_act(0, P.agony, def_zone, P)
|
||||
src <<"\red You have been hit by [P]!"
|
||||
del P
|
||||
|
||||
@@ -166,8 +166,8 @@
|
||||
var/reflectchance = 80 - round(P.damage/3)
|
||||
if(prob(reflectchance))
|
||||
adjustBruteLoss(P.damage * 0.5)
|
||||
visible_message("<span class='danger'>The [P.name] gets reflected by [src]'s shell!</span>", \
|
||||
"<span class='userdanger'>The [P.name] gets reflected by [src]'s shell!</span>")
|
||||
visible_message("<span class='danger'>\The [P] was reflected by \the [src]'s shell!</span>", \
|
||||
"<span class='userdanger'>\The [P] was reflected by \the [src]'s shell!</span>")
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
@@ -176,12 +176,7 @@
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
// redirect the projectile
|
||||
P.original = locate(new_x, new_y, P.z)
|
||||
P.starting = curloc
|
||||
P.current = curloc
|
||||
P.firer = src
|
||||
P.yo = new_y - curloc.y
|
||||
P.xo = new_x - curloc.x
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
icon_living = "syndicateranged"
|
||||
casingtype = /obj/item/ammo_casing/a12mm
|
||||
projectilesound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
projectiletype = /obj/item/projectile/bullet/midbullet2
|
||||
projectiletype = /obj/item/projectile/bullet/pistol/medium
|
||||
|
||||
weapon1 = /obj/item/weapon/gun/projectile/automatic/c20r
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 1
|
||||
w_class = 1.0
|
||||
var/caliber = "" //Which kind of guns it can be loaded into
|
||||
var/projectile_type = ""//The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet
|
||||
var/caliber = "" //Which kind of guns it can be loaded into
|
||||
var/projectile_type //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
if(projectile_type)
|
||||
if(ispath(projectile_type))
|
||||
BB = new projectile_type(src)
|
||||
pixel_x = rand(-10.0, 10)
|
||||
pixel_y = rand(-10.0, 10)
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c45f
|
||||
name = "magazine (.45 flash)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45f"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c45r/empty
|
||||
max_ammo = 0
|
||||
|
||||
@@ -56,7 +63,7 @@
|
||||
icon_state = "9x19p"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
max_ammo = 8
|
||||
max_ammo = 10
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm/empty
|
||||
|
||||
@@ -1,113 +1,129 @@
|
||||
/obj/item/ammo_casing/a357
|
||||
desc = "A .357 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = "/obj/item/projectile/bullet"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong
|
||||
|
||||
/obj/item/ammo_casing/a50
|
||||
desc = "A .50AE bullet casing."
|
||||
caliber = ".50"
|
||||
projectile_type = "/obj/item/projectile/bullet"
|
||||
|
||||
/obj/item/ammo_casing/a418
|
||||
desc = "A .418 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = "/obj/item/projectile/bullet/suffocationbullet"
|
||||
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong
|
||||
|
||||
/obj/item/ammo_casing/a75
|
||||
desc = "A .75 bullet casing."
|
||||
desc = "A 20mm bullet casing."
|
||||
caliber = "75"
|
||||
projectile_type = "/obj/item/projectile/bullet/gyro"
|
||||
|
||||
|
||||
/obj/item/ammo_casing/a666
|
||||
desc = "A .666 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = "/obj/item/projectile/bullet/cyanideround"
|
||||
|
||||
projectile_type = /obj/item/projectile/bullet/gyro
|
||||
|
||||
/obj/item/ammo_casing/c38
|
||||
desc = "A .38 bullet casing."
|
||||
caliber = "38"
|
||||
projectile_type = "/obj/item/projectile/bullet/weakbullet"
|
||||
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/rubber
|
||||
|
||||
/obj/item/ammo_casing/c9mm
|
||||
desc = "A 9mm bullet casing."
|
||||
caliber = "9mm"
|
||||
projectile_type = "/obj/item/projectile/bullet/midbullet2"
|
||||
|
||||
projectile_type = /obj/item/projectile/bullet/pistol
|
||||
|
||||
/obj/item/ammo_casing/c45
|
||||
desc = "A .45 bullet casing."
|
||||
caliber = ".45"
|
||||
projectile_type = "/obj/item/projectile/bullet/midbullet"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/medium
|
||||
|
||||
/obj/item/ammo_casing/c45r
|
||||
desc = "A .45 rubber bullet casing."
|
||||
caliber = ".45"
|
||||
projectile_type = "/obj/item/projectile/bullet/weakbullet/rubber"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/rubber
|
||||
|
||||
/obj/item/ammo_casing/c45f
|
||||
desc = "A .45 flash shell casing."
|
||||
caliber = ".45"
|
||||
projectile_type = /obj/item/projectile/energy/flash
|
||||
|
||||
/obj/item/ammo_casing/a12mm
|
||||
desc = "A 12mm bullet casing."
|
||||
caliber = "12mm"
|
||||
projectile_type = "/obj/item/projectile/bullet/midbullet2"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/medium
|
||||
|
||||
|
||||
/obj/item/ammo_casing/shotgun
|
||||
name = "shotgun slug"
|
||||
desc = "A 12 gauge slug."
|
||||
icon_state = "slshell"
|
||||
caliber = "shotgun"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun
|
||||
matter = list("metal" = 12500)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/pellet
|
||||
name = "shotgun shell"
|
||||
desc = "A 12 gauge shell."
|
||||
icon_state = "gshell"
|
||||
caliber = "shotgun"
|
||||
projectile_type = "/obj/item/projectile/bullet"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun
|
||||
matter = list("metal" = 12500)
|
||||
|
||||
|
||||
/obj/item/ammo_casing/shotgun/blank
|
||||
name = "shotgun shell"
|
||||
desc = "A blank shell."
|
||||
icon_state = "blshell"
|
||||
projectile_type = "/obj/item/projectile/bullet/chameleon"
|
||||
projectile_type = /obj/item/projectile/bullet/blank
|
||||
matter = list("metal" = 250)
|
||||
|
||||
|
||||
/obj/item/ammo_casing/shotgun/beanbag
|
||||
name = "beanbag shell"
|
||||
desc = "A weak beanbag shell."
|
||||
desc = "A beanbag shell."
|
||||
icon_state = "bshell"
|
||||
projectile_type = "/obj/item/projectile/bullet/weakbullet/beanbag"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun/beanbag
|
||||
matter = list("metal" = 500)
|
||||
|
||||
|
||||
/obj/item/ammo_casing/shotgun/stunshell
|
||||
name = "stun shell"
|
||||
desc = "A stunning shell."
|
||||
desc = "A 12 gauge taser cartridge."
|
||||
icon_state = "stunshell"
|
||||
projectile_type = "/obj/item/projectile/bullet/stunshot"
|
||||
matter = list("metal" = 2500)
|
||||
projectile_type = /obj/item/projectile/energy/electrode/stunshot
|
||||
matter = list("metal" = 1250, "glass" = 1250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/flash
|
||||
name = "flash shell"
|
||||
desc = "A flash shell used to provide illumination."
|
||||
icon_state = "fshell"
|
||||
projectile_type = /obj/item/projectile/energy/flash/flare
|
||||
matter = list("metal" = 250, "glass" = 250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart
|
||||
name = "shotgun darts"
|
||||
name = "shotgun dart"
|
||||
desc = "A dart for use in shotguns."
|
||||
icon_state = "dart"
|
||||
projectile_type = "/obj/item/projectile/energy/dart"
|
||||
projectile_type = /obj/item/projectile/energy/dart
|
||||
matter = list("metal" = 12500)
|
||||
|
||||
/obj/item/ammo_casing/a762
|
||||
desc = "A 7.62 bullet casing."
|
||||
desc = "A 7.62mm bullet casing."
|
||||
caliber = "a762"
|
||||
projectile_type = "/obj/item/projectile/bullet/a762"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a762
|
||||
|
||||
/obj/item/ammo_casing/a145
|
||||
name = "\improper AP shell casing"
|
||||
desc = "A 14.5mm AP shell."
|
||||
icon_state = "slshell"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a145
|
||||
|
||||
/obj/item/ammo_casing/rocket
|
||||
name = "rocket shell"
|
||||
desc = "A high explosive designed to be fired from a launcher."
|
||||
icon_state = "rocketshell"
|
||||
projectile_type = "/obj/item/missile"
|
||||
projectile_type = /obj/item/missile
|
||||
caliber = "rocket"
|
||||
|
||||
/obj/item/ammo_casing/chameleon
|
||||
name = "chameleon bullets"
|
||||
desc = "A set of bullets for the Chameleon Gun."
|
||||
projectile_type = "/obj/item/projectile/bullet/chameleon"
|
||||
projectile_type = /obj/item/projectile/bullet/chameleon
|
||||
caliber = ".45"
|
||||
|
||||
/obj/item/ammo_casing/a418
|
||||
desc = "A .418 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = /obj/item/projectile/bullet/suffocationbullet
|
||||
|
||||
/obj/item/ammo_casing/a666
|
||||
desc = "A .666 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = /obj/item/projectile/bullet/cyanideround
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
/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
|
||||
|
||||
if(clumsy_check)
|
||||
if(istype(user, /mob/living))
|
||||
var/mob/living/M = user
|
||||
@@ -97,11 +99,6 @@
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
var/turf/curloc = get_turf(user)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if (!istype(targloc) || !istype(curloc))
|
||||
return
|
||||
|
||||
if(!special_check(user))
|
||||
return
|
||||
|
||||
@@ -116,18 +113,6 @@
|
||||
if(!in_chamber)
|
||||
return
|
||||
|
||||
in_chamber.firer = user
|
||||
in_chamber.def_zone = user.zone_sel.selecting
|
||||
if(targloc == curloc)
|
||||
user.bullet_act(in_chamber)
|
||||
del(in_chamber)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(recoil)
|
||||
spawn()
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
if(silenced)
|
||||
playsound(user, fire_sound, 10, 1)
|
||||
else
|
||||
@@ -136,34 +121,46 @@
|
||||
"<span class='warning'>You fire [src][reflex ? "by reflex":""]!</span>", \
|
||||
"You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
|
||||
|
||||
in_chamber.original = target
|
||||
in_chamber.loc = get_turf(user)
|
||||
in_chamber.starting = get_turf(user)
|
||||
in_chamber.shot_from = src
|
||||
user.next_move = world.time + 4
|
||||
in_chamber.silenced = silenced
|
||||
in_chamber.current = curloc
|
||||
in_chamber.yo = targloc.y - curloc.y
|
||||
in_chamber.xo = targloc.x - curloc.x
|
||||
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
if(istype(user, /mob/living/carbon))
|
||||
var/mob/living/carbon/mob = user
|
||||
if(mob.shock_stage > 120)
|
||||
in_chamber.yo += rand(-2,2)
|
||||
in_chamber.xo += rand(-2,2)
|
||||
y_offset = rand(-2,2)
|
||||
x_offset = rand(-2,2)
|
||||
else if(mob.shock_stage > 70)
|
||||
in_chamber.yo += rand(-1,1)
|
||||
in_chamber.xo += rand(-1,1)
|
||||
y_offset = rand(-1,1)
|
||||
x_offset = rand(-1,1)
|
||||
|
||||
var/p_x
|
||||
var/p_y
|
||||
if(params)
|
||||
var/list/mouse_control = params2list(params)
|
||||
if(mouse_control["icon-x"])
|
||||
in_chamber.p_x = text2num(mouse_control["icon-x"])
|
||||
p_x = text2num(mouse_control["icon-x"])
|
||||
if(mouse_control["icon-y"])
|
||||
in_chamber.p_y = text2num(mouse_control["icon-y"])
|
||||
p_y = text2num(mouse_control["icon-y"])
|
||||
|
||||
if(in_chamber)
|
||||
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,
|
||||
px = p_x,
|
||||
py = p_y
|
||||
)
|
||||
|
||||
if(fail) return
|
||||
|
||||
if(recoil)
|
||||
spawn()
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
spawn()
|
||||
if(in_chamber)
|
||||
in_chamber.process()
|
||||
sleep(1)
|
||||
in_chamber = null
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
recoil = 1
|
||||
|
||||
force = 10
|
||||
projectile_type = "/obj/item/projectile/energy/sonic"
|
||||
projectile_type = /obj/item/projectile/energy/sonic
|
||||
cell_type = "/obj/item/weapon/cell/super"
|
||||
fire_delay = 40
|
||||
fire_sound = 'sound/effects/basscannon.ogg'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
|
||||
var/charge_cost = 100 //How much energy is needed to fire.
|
||||
var/cell_type = "/obj/item/weapon/cell"
|
||||
var/projectile_type = "/obj/item/projectile/beam/practice"
|
||||
var/projectile_type = /obj/item/projectile/beam/practice
|
||||
var/modifystate
|
||||
|
||||
emp_act(severity)
|
||||
@@ -30,7 +30,7 @@
|
||||
if(in_chamber) return 1
|
||||
if(!power_supply) return 0
|
||||
if(!power_supply.use(charge_cost)) return 0
|
||||
if(!projectile_type) return 0
|
||||
if(!ispath(projectile_type)) return 0
|
||||
in_chamber = new projectile_type(src)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
|
||||
charge_cost = 100 //How much energy is needed to fire.
|
||||
projectile_type = "/obj/item/projectile/beam/stun"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
origin_tech = "combat=3;magnets=2"
|
||||
modifystate = "energystun"
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
charge_cost = 100
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
user << "\red [src.name] is now set to kill."
|
||||
projectile_type = "/obj/item/projectile/beam"
|
||||
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"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
modifystate = "energystun"
|
||||
update_icon()
|
||||
if(user.l_hand == src)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
force = 10
|
||||
fire_sound = 'sound/weapons/pulse.ogg'
|
||||
charge_cost = 200
|
||||
projectile_type = "/obj/item/projectile/beam/pulse"
|
||||
projectile_type = /obj/item/projectile/beam/pulse
|
||||
cell_type = "/obj/item/weapon/cell/super"
|
||||
var/mode = 2
|
||||
fire_delay = 25
|
||||
@@ -18,19 +18,19 @@
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
projectile_type = /obj/item/projectile/beam/pulse
|
||||
return
|
||||
|
||||
isHandgun()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
charge_cost = 100
|
||||
projectile_type = "/obj/item/projectile/beam/stun"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
cell_type = "/obj/item/weapon/cell/crap"
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/cyborg
|
||||
@@ -47,7 +47,7 @@
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
origin_tech = "combat=3;materials=3;powerstorage=2"
|
||||
charge_cost = 125
|
||||
projectile_type = "/obj/item/projectile/beam/stun"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
cell_type = "/obj/item/weapon/cell"
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
origin_tech = "combat=2;magnets=2;syndicate=5"
|
||||
silenced = 1
|
||||
fire_sound = 'sound/weapons/Genhit.ogg'
|
||||
projectile_type = "/obj/item/projectile/energy/bolt"
|
||||
projectile_type = /obj/item/projectile/energy/bolt
|
||||
cell_type = "/obj/item/weapon/cell/crap"
|
||||
var/charge_tick = 0
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/ninja
|
||||
name = "energy dart thrower"
|
||||
projectile_type = "/obj/item/projectile/energy/dart"
|
||||
projectile_type = /obj/item/projectile/energy/dart
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/largecrossbow
|
||||
name = "Energy Crossbow"
|
||||
@@ -99,4 +99,4 @@
|
||||
w_class = 4.0
|
||||
force = 10
|
||||
matter = list("metal" = 200000)
|
||||
projectile_type = "/obj/item/projectile/energy/bolt/large"
|
||||
projectile_type = /obj/item/projectile/energy/bolt/large
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/obj/item/weapon/gun/projectile
|
||||
name = "revolver"
|
||||
desc = "A classic revolver. Uses 357 ammo"
|
||||
desc = "A classic revolver. Uses .357 ammo"
|
||||
icon_state = "revolver"
|
||||
caliber = "357"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
@@ -16,12 +16,14 @@
|
||||
var/max_shells = 7
|
||||
var/load_method = SPEEDLOADER //0 = Single shells or quick loader, 1 = box, 2 = magazine
|
||||
var/obj/item/ammo_magazine/empty_mag = null
|
||||
|
||||
var/mag_type = null
|
||||
|
||||
/obj/item/weapon/gun/projectile/New()
|
||||
..()
|
||||
for(var/i = 1, i <= max_shells, i++)
|
||||
loaded += new ammo_type(src)
|
||||
if(load_method == MAGAZINE)
|
||||
empty_mag = new mag_type(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "A lightweight, fast firing gun. Uses 9mm rounds."
|
||||
icon_state = "saber" //ugly
|
||||
w_class = 3.0
|
||||
max_shells = 18
|
||||
max_shells = 22
|
||||
caliber = "9mm"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
@@ -14,6 +14,9 @@
|
||||
isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/test
|
||||
name = "test gun"
|
||||
ammo_type = "/obj/item/ammo_casing/a145"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper Uzi"
|
||||
@@ -40,15 +43,8 @@
|
||||
origin_tech = "combat=5;materials=2;syndicate=8"
|
||||
ammo_type = "/obj/item/ammo_casing/a12mm"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
load_method = 2
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
empty_mag = new /obj/item/ammo_magazine/a12mm/empty(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a12mm/empty
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
@@ -80,7 +76,7 @@
|
||||
origin_tech = "combat=5;materials=1;syndicate=2"
|
||||
ammo_type = "/obj/item/ammo_casing/a762"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
load_method = 2
|
||||
load_method = MAGAZINE
|
||||
var/cover_open = 0
|
||||
var/mag_inserted = 1
|
||||
|
||||
|
||||
@@ -19,13 +19,8 @@
|
||||
max_shells = 7
|
||||
caliber = ".50"
|
||||
ammo_type ="/obj/item/ammo_casing/a50"
|
||||
load_method = 2
|
||||
New()
|
||||
..()
|
||||
empty_mag = new /obj/item/ammo_magazine/a50/empty(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a50/empty
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
@@ -59,13 +54,8 @@
|
||||
fire_sound = 'sound/effects/Explosion1.ogg'
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = "/obj/item/ammo_casing/a75"
|
||||
load_method = 2
|
||||
New()
|
||||
..()
|
||||
empty_mag = new /obj/item/ammo_magazine/a75/empty(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a75/empty
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
@@ -89,17 +79,13 @@
|
||||
desc = "A small, easily concealable gun. Uses 9mm rounds."
|
||||
icon_state = "pistol"
|
||||
w_class = 2
|
||||
max_shells = 8
|
||||
max_shells = 10
|
||||
caliber = "9mm"
|
||||
silenced = 0
|
||||
origin_tech = "combat=2;materials=2;syndicate=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
load_method = 2
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/New()
|
||||
..()
|
||||
empty_mag = new /obj/item/ammo_magazine/mc9mm/empty(src)
|
||||
return
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/mc9mm/empty
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
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
|
||||
@@ -77,12 +76,15 @@
|
||||
max_shells = 7
|
||||
caliber = ".45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45r"
|
||||
load_method = 2
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/c45r/empty
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/New()
|
||||
..()
|
||||
empty_mag = new /obj/item/ammo_magazine/c45r/empty(src)
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/flash
|
||||
ammo_type = "/obj/item/ammo_casing/c45f"
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/colt
|
||||
desc = "A cheap Martian knock-off of a Colt M1911."
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
@@ -130,7 +132,7 @@
|
||||
var/num_loaded = 0
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
|
||||
if((load_method == 2) && loaded.len) return
|
||||
if((load_method == MAGAZINE) && loaded.len) return
|
||||
var/obj/item/ammo_magazine/AM = A
|
||||
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
|
||||
if(getAmmo() > 0 || loaded.len >= max_shells)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "shotgun"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"
|
||||
ammo_type = "/obj/item/ammo_casing/shotgun/pellet"
|
||||
var/recentpump = 0 // to prevent spammage
|
||||
var/pumped = 0
|
||||
var/obj/item/ammo_casing/current_shell = null
|
||||
|
||||
@@ -36,8 +36,10 @@
|
||||
var/damage = 10
|
||||
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
|
||||
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
|
||||
var/taser_effect = 0 //If set then the projectile will apply it's agony damage using stun_effect_act() to mobs it hits, and other damage will be ignored
|
||||
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
|
||||
var/projectile_type = "/obj/item/projectile"
|
||||
var/projectile_type = /obj/item/projectile
|
||||
var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate()
|
||||
var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile.
|
||||
//Effects
|
||||
var/stun = 0
|
||||
@@ -50,7 +52,8 @@
|
||||
var/agony = 0
|
||||
var/embed = 0 // whether or not the projectile can embed itself in the mob
|
||||
|
||||
/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0)
|
||||
//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not
|
||||
/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if(blocked >= 2) return 0//Full block
|
||||
if(!isliving(target)) return 0
|
||||
if(isanimal(target)) return 0
|
||||
@@ -58,6 +61,14 @@
|
||||
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY!
|
||||
return 1
|
||||
|
||||
//called when the projectile stops flying because it collided with something
|
||||
/obj/item/projectile/proc/on_impact(var/atom/A)
|
||||
return
|
||||
|
||||
//return 1 if the projectile should be allowed to pass through after all, 0 if not.
|
||||
/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.
|
||||
if(!istype(target) || !istype(user))
|
||||
return 0
|
||||
@@ -70,94 +81,165 @@
|
||||
del(in_chamber) //No need for it anymore
|
||||
return output //Send it back to the gun!
|
||||
|
||||
//called to launch a projectile from a gun
|
||||
/obj/item/projectile/proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0, var/px=null, var/py=null)
|
||||
var/turf/curloc = get_turf(user)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if (!istype(targloc) || !istype(curloc))
|
||||
return 1
|
||||
|
||||
firer = user
|
||||
def_zone = user.zone_sel.selecting
|
||||
|
||||
if(user == target) //Shooting yourself
|
||||
user.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
if(targloc == curloc) //Shooting the ground
|
||||
targloc.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
original = target
|
||||
loc = curloc
|
||||
starting = curloc
|
||||
current = curloc
|
||||
yo = targloc.y - curloc.y + y_offset
|
||||
xo = targloc.x - curloc.x + x_offset
|
||||
if(!isnull(py)) p_y = py
|
||||
if(!isnull(px)) p_x = px
|
||||
|
||||
shot_from = launcher
|
||||
silenced = launcher.silenced
|
||||
|
||||
spawn()
|
||||
process()
|
||||
|
||||
return 0
|
||||
|
||||
//Used to change the direction of the projectile in flight.
|
||||
/obj/item/projectile/proc/redirect(var/new_x, var/new_y, var/atom/starting_loc, var/mob/new_firer=null)
|
||||
original = locate(new_x, new_y, src.z)
|
||||
starting = starting_loc
|
||||
current = starting_loc
|
||||
if(new_firer)
|
||||
firer = src
|
||||
|
||||
yo = new_y - starting_loc.y
|
||||
xo = new_x - starting_loc.x
|
||||
|
||||
//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying.
|
||||
/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier = -30)
|
||||
//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
|
||||
miss_modifier += -30
|
||||
|
||||
//roll to-hit
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*distance, 0))
|
||||
if(!hit_zone)
|
||||
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
||||
return 0
|
||||
|
||||
//set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
|
||||
def_zone = hit_zone
|
||||
|
||||
//hit messages
|
||||
if(silenced)
|
||||
target_mob << "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>"
|
||||
else
|
||||
visible_message("<span class='danger'>\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
|
||||
//admin logs
|
||||
if(istype(firer, /mob))
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
msg_admin_attack("[firer] ([firer.ckey]) shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
else
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
//sometimes bullet_act() will want the projectile to continue flying
|
||||
if (target_mob.bullet_act(src, def_zone) == -1)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == src)
|
||||
return 0 //no
|
||||
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return 0 //cannot shoot yourself
|
||||
|
||||
if(bumped) return 0
|
||||
var/forcedodge = 0 // force the projectile to pass
|
||||
if(bumped)
|
||||
return 0
|
||||
|
||||
var/passthrough = 0 //if the projectile should continue flying
|
||||
var/distance = get_dist(starting,loc)
|
||||
|
||||
bumped = 1
|
||||
if(firer && istype(A, /mob))
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(!istype(A, /mob/living))
|
||||
loc = A.loc
|
||||
return 0// nope.avi
|
||||
|
||||
var/distance = get_dist(starting,loc)
|
||||
var/miss_modifier = -30
|
||||
|
||||
if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
|
||||
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
|
||||
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
|
||||
miss_modifier += -30
|
||||
def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance)
|
||||
|
||||
if(!def_zone)
|
||||
visible_message("\blue \The [src] misses [M] narrowly!")
|
||||
forcedodge = -1
|
||||
if(istype(A, /mob/living))
|
||||
passthrough = !attack_mob(M, distance)
|
||||
else
|
||||
if(silenced)
|
||||
M << "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!"
|
||||
else
|
||||
visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
if(istype(firer, /mob))
|
||||
M.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>[src.type]</b>"
|
||||
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>[src.type]</b>"
|
||||
msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
else
|
||||
M.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[M]/[M.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
if(A)
|
||||
if (!forcedodge)
|
||||
forcedodge = A.bullet_act(src, def_zone) // searches for return value
|
||||
if(forcedodge == -1) // the bullet passes through a dense object!
|
||||
bumped = 0 // reset bumped variable!
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
if(istype(A,/turf))
|
||||
passthrough = 1 //so ghosts don't stop bullets
|
||||
else
|
||||
passthrough = (A.bullet_act(src, def_zone) == -1) //backwards compatibility
|
||||
if(isturf(A))
|
||||
for(var/obj/O in A)
|
||||
O.bullet_act(src)
|
||||
for(var/mob/M in A)
|
||||
M.bullet_act(src, def_zone)
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
attack_mob(M, distance)
|
||||
|
||||
//penetrating projectiles can pass through things that otherwise would not let them
|
||||
if(penetrating > 0)
|
||||
if(on_penetrate(A))
|
||||
passthrough = 1
|
||||
penetrating--
|
||||
|
||||
//the bullet passes through a dense object!
|
||||
if(passthrough)
|
||||
bumped = 0 //reset bumped variable!
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
|
||||
//stop flying
|
||||
on_impact(A)
|
||||
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return prob(95)
|
||||
return prob(95) //ha
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/process()
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
kill_count--
|
||||
spawn while(src)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
del(src)
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
return
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
|
||||
//"Tracing" projectile
|
||||
/obj/item/projectile/test //Used to see if you can hit them.
|
||||
invisibility = 101 //Nope! Can't see me!
|
||||
yo = null
|
||||
|
||||
@@ -105,6 +105,11 @@ var/list/beam_master = list()
|
||||
icon_state = "u_laser"
|
||||
damage = 50
|
||||
|
||||
/obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target))
|
||||
target.ex_act(2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/emitter
|
||||
name = "emitter beam"
|
||||
icon_state = "emitter"
|
||||
@@ -167,5 +172,6 @@ var/list/beam_master = list()
|
||||
name = "stun beam"
|
||||
icon_state = "stun"
|
||||
nodamage = 1
|
||||
taser_effect = 1
|
||||
agony = 40
|
||||
damage_type = HALLOSS
|
||||
|
||||
@@ -8,62 +8,153 @@
|
||||
embed = 1
|
||||
sharp = 1
|
||||
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
/obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet // "rubber" bullets
|
||||
/obj/item/projectile/bullet/on_penetrate(var/atom/A)
|
||||
if(!A) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going
|
||||
|
||||
if(istype(A, /obj/mecha))
|
||||
return 1 //mecha have their own penetration handling
|
||||
|
||||
if(ismob(A))
|
||||
if(iscarbon(A))
|
||||
//squishy mobs absorb KE
|
||||
if (damage <= 20) return 0
|
||||
damage *= 0.7
|
||||
return 1
|
||||
|
||||
if(istype(A, /obj/machinery) || istype(A, /obj/structure))
|
||||
var/chance = 15
|
||||
if(istype(A, /turf/simulated/wall))
|
||||
var/turf/simulated/wall/W = A
|
||||
chance = round(damage/W.damage_cap*100)
|
||||
else if(istype(A, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = A
|
||||
chance = round(damage/D.maxhealth*100)
|
||||
else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder))
|
||||
chance = 100
|
||||
|
||||
if(prob(chance))
|
||||
if(A.opacity)
|
||||
//display a message so that people on the other side aren't so confused
|
||||
A.visible_message("<span class='warning'>\The [src] pierces through \the [A]!")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//For projectiles that actually represent clouds of projectiles
|
||||
/obj/item/projectile/bullet/pellet
|
||||
name = "shrapnel" //'shrapnel' sounds more dangerous (i.e. cooler) than 'pellet'
|
||||
damage = 20
|
||||
//icon_state = "bullet" //TODO: would be nice to have it's own icon state
|
||||
var/pellets = 4 //number of pellets
|
||||
var/range_step = 2 //effective pellet count decreases every few tiles
|
||||
var/base_spread = 90 //lower means the pellets spread more across body parts
|
||||
var/spread_step = 10 //higher means the pellets spread more across body parts with distance
|
||||
|
||||
/obj/item/projectile/bullet/pellet/Bumped()
|
||||
. = ..()
|
||||
bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine.
|
||||
|
||||
/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance)
|
||||
if (pellets < 0) return 1
|
||||
|
||||
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
|
||||
var/total_pellets = max(pellets - pellet_loss, 1)
|
||||
var/spread = max(base_spread - (spread_step*distance), 0)
|
||||
var/hits = 0
|
||||
for (var/i in 1 to total_pellets)
|
||||
//pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability
|
||||
//whether the pellet actually hits the def_zone or a different zone should still be determined by the parent using get_zone_with_miss_chance().
|
||||
var/old_zone = def_zone
|
||||
def_zone = ran_zone(def_zone, spread)
|
||||
if (..()) hits++
|
||||
def_zone = old_zone //restore the original zone the projectile was aimed at
|
||||
|
||||
pellets -= hits //each hit reduces the number of pellets left
|
||||
if (hits >= total_pellets || pellets <= 0)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/* short-casing projectiles, like the kind used in pistols or SMGs */
|
||||
|
||||
/obj/item/projectile/bullet/pistol
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium
|
||||
damage = 25
|
||||
|
||||
/obj/item/projectile/bullet/pistol/strong //revolvers and matebas
|
||||
damage = 60
|
||||
|
||||
/obj/item/projectile/bullet/pistol/rubber //"rubber" bullets
|
||||
name = "rubber bullet"
|
||||
damage = 10
|
||||
agony = 40
|
||||
embed = 0
|
||||
sharp = 0
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/beanbag //because beanbags are not bullets
|
||||
/* shotgun projectiles */
|
||||
|
||||
/obj/item/projectile/bullet/shotgun
|
||||
name = "slug"
|
||||
damage = 60
|
||||
|
||||
/obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets
|
||||
name = "beanbag"
|
||||
damage = 20
|
||||
agony = 60
|
||||
embed = 0
|
||||
sharp = 0
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/rubber
|
||||
name = "rubber bullet"
|
||||
//Should do about 80 damage at 1 tile distance (adjacent), and 50 damage at 3 tiles distance.
|
||||
//Overall less damage than slugs in exchange for more damage at very close range and more embedding
|
||||
/obj/item/projectile/bullet/pellet/shotgun
|
||||
name = "shrapnel"
|
||||
damage = 13
|
||||
pellets = 6
|
||||
range_step = 1
|
||||
spread_step = 10
|
||||
|
||||
/obj/item/projectile/bullet/midbullet
|
||||
damage = 20
|
||||
/* "Rifle" rounds */
|
||||
|
||||
/obj/item/projectile/bullet/midbullet2
|
||||
/obj/item/projectile/bullet/rifle/a762
|
||||
damage = 25
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145
|
||||
damage = 90
|
||||
penetrating = 5
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
/obj/item/projectile/bullet/suffocationbullet//How does this even work?
|
||||
name = "co bullet"
|
||||
damage = 20
|
||||
damage_type = OXY
|
||||
|
||||
|
||||
/obj/item/projectile/bullet/cyanideround
|
||||
name = "poison bullet"
|
||||
damage = 40
|
||||
damage_type = TOX
|
||||
|
||||
|
||||
/obj/item/projectile/bullet/burstbullet//I think this one needs something for the on hit
|
||||
/obj/item/projectile/bullet/burstbullet
|
||||
name = "exploding bullet"
|
||||
damage = 20
|
||||
embed = 0
|
||||
edge = 1
|
||||
|
||||
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target))
|
||||
explosion(target, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/stunshot
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
agony = 80
|
||||
stutter = 10
|
||||
/obj/item/projectile/bullet/blank
|
||||
invisibility = 101
|
||||
damage = 1
|
||||
embed = 0
|
||||
sharp = 0
|
||||
|
||||
/obj/item/projectile/bullet/a762
|
||||
damage = 25
|
||||
|
||||
/obj/item/projectile/bullet/chameleon
|
||||
damage = 1 // stop trying to murderbone with a fake gun dumbass!!!
|
||||
|
||||
@@ -6,6 +6,35 @@
|
||||
flag = "energy"
|
||||
|
||||
|
||||
//releases a very short burst of light on impact, mainly used to blind people
|
||||
/obj/item/projectile/energy/flash
|
||||
name = "shell" //a chemical filled shell or something
|
||||
icon_state = "bullet"
|
||||
damage = 5
|
||||
var/flash_range = 1
|
||||
var/brightness = 5
|
||||
var/light_duration = 10
|
||||
|
||||
/obj/item/projectile/energy/flash/on_impact()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(!istype(T)) return
|
||||
|
||||
src.visible_message("<span class='warning'>\The [src] explodes in a bright flash!</span>")
|
||||
for (var/mob/living/carbon/M in viewers(T, flash_range))
|
||||
if(M.eyecheck() < 1)
|
||||
flick("e_flash", M.flash)
|
||||
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
new/obj/effect/effect/smoke/illumination(src.loc, brightness=max(flash_range*2, brightness), lifetime=light_duration)
|
||||
|
||||
//blinds people like the flash round, but can also be used for temporary illumination
|
||||
/obj/item/projectile/energy/flash/flare
|
||||
damage = 10
|
||||
flash_range = 1
|
||||
brightness = 7 //similar to a flare
|
||||
light_duration = 150
|
||||
|
||||
/obj/item/projectile/energy/electrode
|
||||
name = "electrode"
|
||||
icon_state = "spark"
|
||||
@@ -15,11 +44,16 @@
|
||||
weaken = 10
|
||||
stutter = 10
|
||||
*/
|
||||
taser_effect = 1
|
||||
agony = 40
|
||||
damage_type = HALLOSS
|
||||
//Damage will be handled on the MOB side, to prevent window shattering.
|
||||
|
||||
|
||||
/obj/item/projectile/energy/electrode/stunshot
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
taser_effect = 1
|
||||
agony = 80
|
||||
|
||||
/obj/item/projectile/energy/declone
|
||||
name = "declone"
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if(Proj.damage_type == BRUTE || Proj.damage_type == BURN)
|
||||
if(istype(Proj.firer))
|
||||
message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>).")
|
||||
log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).")
|
||||
|
||||
@@ -26,7 +26,7 @@ datum/chemical_reaction/coolant
|
||||
reagents.add_reagent("coolant",1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if(Proj.damage_type == BRUTE || Proj.damage_type == BURN)
|
||||
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
|
||||
explode()
|
||||
|
||||
|
||||
@@ -114,7 +114,8 @@
|
||||
..()
|
||||
|
||||
/obj/vehicle/bullet_act(var/obj/item/projectile/Proj)
|
||||
health -= Proj.damage
|
||||
if (Proj.damage_type == BRUTE || Proj.damage_type == BURN)
|
||||
health -= Proj.damage
|
||||
..()
|
||||
healthcheck()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user