mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 03:02:54 +00:00
Adds a new subset of grenades that shoot projectiles
This commit is contained in:
@@ -1,36 +1,3 @@
|
|||||||
//obj/item/weapon/grenade/explosive
|
|
||||||
//desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
|
|
||||||
//name = "frag grenade"
|
|
||||||
//icon = 'icons/obj/grenade.dmi'
|
|
||||||
//det_time = 50
|
|
||||||
//icon_state = "frggrenade"
|
|
||||||
//origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 3)
|
|
||||||
|
|
||||||
//obj/item/weapon/grenade/explosive/prime()
|
|
||||||
// ..()
|
|
||||||
//spawn(0)
|
|
||||||
//explosion(src.loc,-1,-1,2) //If you're within two tiles of the grenade, you get hit twice, which tends to do 50+ brute and cause fractures.
|
|
||||||
//explosion(src.loc,-1,-1,3) //This is preferable to increasing the severity, so we don't decap with frags.
|
|
||||||
//qdel(src)
|
|
||||||
//return
|
|
||||||
|
|
||||||
//Explosive grenade projectile, borrowed from fragmentation grenade code.
|
|
||||||
/obj/item/projectile/bullet/pellet/fragment
|
|
||||||
damage = 10
|
|
||||||
armor_penetration = 30
|
|
||||||
range_step = 2 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
|
|
||||||
|
|
||||||
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
|
|
||||||
spread_step = 20
|
|
||||||
|
|
||||||
silenced = 1 //embedding messages are still produced so it's kind of weird when enabled.
|
|
||||||
no_attack_log = 1
|
|
||||||
muzzle_type = null
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/fragment/strong
|
|
||||||
damage = 15
|
|
||||||
armor_penetration = 20
|
|
||||||
|
|
||||||
/obj/item/weapon/grenade/explosive
|
/obj/item/weapon/grenade/explosive
|
||||||
name = "fragmentation grenade"
|
name = "fragmentation grenade"
|
||||||
desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
|
desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
|
||||||
@@ -56,6 +23,21 @@
|
|||||||
src.fragmentate(O, num_fragments, spread_range, fragment_types)
|
src.fragmentate(O, num_fragments, spread_range, fragment_types)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/explosive/proc/on_explosion(var/turf/O)
|
||||||
|
if(explosion_size)
|
||||||
|
explosion(O, -1, -1, explosion_size, round(explosion_size/2), 0)
|
||||||
|
|
||||||
|
// Waaaaay more pellets
|
||||||
|
/obj/item/weapon/grenade/explosive/frag
|
||||||
|
name = "fragmentation grenade"
|
||||||
|
desc = "A military fragmentation grenade, designed to explode in a deadly shower of fragments."
|
||||||
|
icon_state = "frag"
|
||||||
|
loadable = null
|
||||||
|
|
||||||
|
fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
|
||||||
|
num_fragments = 200 //total number of fragments produced by the grenade
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/obj/proc/fragmentate(var/turf/T=get_turf(src), var/fragment_number = 30, var/spreading_range = 5, var/list/fragtypes=list(/obj/item/projectile/bullet/pellet/fragment/))
|
/obj/proc/fragmentate(var/turf/T=get_turf(src), var/fragment_number = 30, var/spreading_range = 5, var/list/fragtypes=list(/obj/item/projectile/bullet/pellet/fragment/))
|
||||||
set waitfor = 0
|
set waitfor = 0
|
||||||
@@ -81,20 +63,3 @@
|
|||||||
P.attack_mob(M, 0, 25) //you're holding a grenade, dude!
|
P.attack_mob(M, 0, 25) //you're holding a grenade, dude!
|
||||||
else
|
else
|
||||||
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
|
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/grenade/explosive/proc/on_explosion(var/turf/O)
|
|
||||||
if(explosion_size)
|
|
||||||
explosion(O, -1, -1, explosion_size, round(explosion_size/2), 0)
|
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/grenade/explosive/frag
|
|
||||||
name = "fragmentation grenade"
|
|
||||||
desc = "A military fragmentation grenade, designed to explode in a deadly shower of fragments."
|
|
||||||
icon_state = "frag"
|
|
||||||
loadable = null
|
|
||||||
|
|
||||||
fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
|
|
||||||
num_fragments = 200 //total number of fragments produced by the grenade
|
|
||||||
|
|
||||||
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
var/active = 0
|
var/active = 0
|
||||||
var/det_time = 50
|
var/det_time = 50
|
||||||
var/loadable = 1
|
var/loadable = TRUE
|
||||||
var/arm_sound = 'sound/weapons/armbomb.ogg'
|
var/arm_sound = 'sound/weapons/armbomb.ogg'
|
||||||
|
|
||||||
/obj/item/weapon/grenade/proc/clown_check(var/mob/living/user)
|
/obj/item/weapon/grenade/proc/clown_check(var/mob/living/user)
|
||||||
|
|||||||
75
code/game/objects/items/weapons/grenades/projectile.dm
Normal file
75
code/game/objects/items/weapons/grenades/projectile.dm
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/obj/item/weapon/grenade/shooter
|
||||||
|
name = "projectile grenade" // I have no idea what else to call this, but the base type should never be used
|
||||||
|
icon_state = "frggrenade"
|
||||||
|
item_state = "grenade"
|
||||||
|
|
||||||
|
var/list/projectile_types = list(/obj/item/projectile/bullet/pistol/rubber) // What sorts of projectiles might we make?
|
||||||
|
|
||||||
|
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
|
||||||
|
var/spread_range = 7
|
||||||
|
|
||||||
|
loadable = FALSE
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/shooter/detonate()
|
||||||
|
..()
|
||||||
|
|
||||||
|
var/turf/O = get_turf(src)
|
||||||
|
if(!O)
|
||||||
|
return
|
||||||
|
|
||||||
|
src.launch_many_projectiles(O, spread_range, projectile_types)
|
||||||
|
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/shooter/rubber
|
||||||
|
name = "rubber pellet grenade"
|
||||||
|
desc = "An anti-riot grenade that fires a cloud of rubber projectiles upon detonation."
|
||||||
|
projectile_types = list(/obj/item/projectile/bullet/pistol/rubber)
|
||||||
|
|
||||||
|
// Exists mostly so I don't have to copy+paste the sprite vars to a billion things
|
||||||
|
/obj/item/weapon/grenade/shooter/energy
|
||||||
|
icon_state = "flashbang"
|
||||||
|
item_state = "flashbang"
|
||||||
|
spread_range = 3 // Because dear god
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/shooter/energy/laser
|
||||||
|
name = "laser grenade"
|
||||||
|
desc = "A horrifically dangerous rave in a can."
|
||||||
|
projectile_types = list(/obj/item/projectile/beam/midlaser)
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/shooter/energy/flash
|
||||||
|
name = "flash grenade"
|
||||||
|
desc = "A grenade that creates a large number of flashes upon detonation."
|
||||||
|
projectile_types = list(/obj/item/projectile/energy/flash)
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/shooter/energy/tesla
|
||||||
|
name = "tesla grenade"
|
||||||
|
projectile_types = list(/obj/item/projectile/beam/chain_lightning/lesser)
|
||||||
|
|
||||||
|
|
||||||
|
// This is just fragmentate, but less specific. Don't know how to make either of them less awful, at the moment
|
||||||
|
/obj/proc/launch_many_projectiles(var/turf/T=get_turf(src), var/spreading_range = 5, var/list/projectiletypes=list(/obj/item/projectile/bullet/pistol/rubber))
|
||||||
|
set waitfor = 0
|
||||||
|
var/list/target_turfs = getcircle(T, spreading_range)
|
||||||
|
|
||||||
|
for(var/turf/O in target_turfs)
|
||||||
|
sleep(0)
|
||||||
|
var/shot_type = pick(projectiletypes)
|
||||||
|
|
||||||
|
var/obj/item/projectile/P = new shot_type(T)
|
||||||
|
P.shot_from = src.name
|
||||||
|
|
||||||
|
P.launch(O)
|
||||||
|
|
||||||
|
//Make sure to hit any mobs in the source turf
|
||||||
|
for(var/mob/living/M in T)
|
||||||
|
//lying on a frag grenade while the grenade is on the ground causes you to absorb most of the shrapnel.
|
||||||
|
//you will most likely be dead, but others nearby will be spared the fragments that hit you instead.
|
||||||
|
if(M.lying && isturf(src.loc))
|
||||||
|
P.attack_mob(M, 0, 5)
|
||||||
|
else if(!M.lying && src.loc != get_turf(src)) //if it's not on the turf, it must be in the mob!
|
||||||
|
P.attack_mob(M, 0, 25) //you're holding a grenade, dude!
|
||||||
|
else
|
||||||
|
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
|
||||||
@@ -674,32 +674,3 @@ var/list/global/tank_gauge_cache = list()
|
|||||||
/obj/item/device/tankassemblyproxy/HasProximity(atom/movable/AM as mob|obj)
|
/obj/item/device/tankassemblyproxy/HasProximity(atom/movable/AM as mob|obj)
|
||||||
if(src.assembly)
|
if(src.assembly)
|
||||||
src.assembly.HasProximity(AM)
|
src.assembly.HasProximity(AM)
|
||||||
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/fragment/tank
|
|
||||||
name = "metal fragment"
|
|
||||||
damage = 9 //Big chunks flying off.
|
|
||||||
range_step = 2 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
|
|
||||||
|
|
||||||
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
|
|
||||||
spread_step = 20
|
|
||||||
|
|
||||||
armor_penetration = 20
|
|
||||||
|
|
||||||
silenced = 1
|
|
||||||
no_attack_log = 1
|
|
||||||
muzzle_type = null
|
|
||||||
pellets = 3
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/fragment/tank/small
|
|
||||||
name = "small metal fragment"
|
|
||||||
damage = 6
|
|
||||||
armor_penetration = 5
|
|
||||||
pellets = 5
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/fragment/tank/big
|
|
||||||
name = "large metal fragment"
|
|
||||||
damage = 17
|
|
||||||
armor_penetration = 10
|
|
||||||
range_step = 5 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
|
|
||||||
pellets = 1
|
|
||||||
@@ -62,66 +62,6 @@
|
|||||||
|
|
||||||
return 0
|
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 //projectile will lose a fragment each time it travels this distance. Can be a non-integer.
|
|
||||||
var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
|
|
||||||
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/proc/get_pellets(var/distance)
|
|
||||||
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
|
|
||||||
return max(pellets - pellet_loss, 1)
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
|
||||||
if (pellets < 0) return 1
|
|
||||||
|
|
||||||
var/total_pellets = get_pellets(distance)
|
|
||||||
var/spread = max(base_spread - (spread_step*distance), 0)
|
|
||||||
|
|
||||||
//shrapnel explosions miss prone mobs with a chance that increases with distance
|
|
||||||
var/prone_chance = 0
|
|
||||||
if(!base_spread)
|
|
||||||
prone_chance = max(spread_step*(distance - 2), 0)
|
|
||||||
|
|
||||||
var/hits = 0
|
|
||||||
for (var/i in 1 to total_pellets)
|
|
||||||
if(target_mob.lying && target_mob != original && prob(prone_chance))
|
|
||||||
continue
|
|
||||||
|
|
||||||
//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
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/get_structure_damage()
|
|
||||||
var/distance = get_dist(loc, starting)
|
|
||||||
return ..() * get_pellets(distance)
|
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pellet/Move()
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
//If this is a shrapnel explosion, allow mobs that are prone to get hit, too
|
|
||||||
if(. && !base_spread && isturf(loc))
|
|
||||||
for(var/mob/living/M in loc)
|
|
||||||
if(M.lying || !M.CanPass(src, loc)) //Bump if lying or if we would normally Bump.
|
|
||||||
if(Bump(M)) //Bump will make sure we don't hit a mob multiple times
|
|
||||||
return
|
|
||||||
|
|
||||||
/* short-casing projectiles, like the kind used in pistols or SMGs */
|
/* short-casing projectiles, like the kind used in pistols or SMGs */
|
||||||
|
|
||||||
/obj/item/projectile/bullet/pistol
|
/obj/item/projectile/bullet/pistol
|
||||||
|
|||||||
106
code/modules/projectiles/projectile/pellets.dm
Normal file
106
code/modules/projectiles/projectile/pellets.dm
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
//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 //projectile will lose a fragment each time it travels this distance. Can be a non-integer.
|
||||||
|
var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
|
||||||
|
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/proc/get_pellets(var/distance)
|
||||||
|
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
|
||||||
|
return max(pellets - pellet_loss, 1)
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||||
|
if (pellets < 0) return 1
|
||||||
|
|
||||||
|
var/total_pellets = get_pellets(distance)
|
||||||
|
var/spread = max(base_spread - (spread_step*distance), 0)
|
||||||
|
|
||||||
|
//shrapnel explosions miss prone mobs with a chance that increases with distance
|
||||||
|
var/prone_chance = 0
|
||||||
|
if(!base_spread)
|
||||||
|
prone_chance = max(spread_step*(distance - 2), 0)
|
||||||
|
|
||||||
|
var/hits = 0
|
||||||
|
for (var/i in 1 to total_pellets)
|
||||||
|
if(target_mob.lying && target_mob != original && prob(prone_chance))
|
||||||
|
continue
|
||||||
|
|
||||||
|
//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
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/get_structure_damage()
|
||||||
|
var/distance = get_dist(loc, starting)
|
||||||
|
return ..() * get_pellets(distance)
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/Move()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
//If this is a shrapnel explosion, allow mobs that are prone to get hit, too
|
||||||
|
if(. && !base_spread && isturf(loc))
|
||||||
|
for(var/mob/living/M in loc)
|
||||||
|
if(M.lying || !M.CanPass(src, loc)) //Bump if lying or if we would normally Bump.
|
||||||
|
if(Bump(M)) //Bump will make sure we don't hit a mob multiple times
|
||||||
|
return
|
||||||
|
|
||||||
|
//Explosive grenade projectile, borrowed from fragmentation grenade code.
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment
|
||||||
|
damage = 10
|
||||||
|
armor_penetration = 30
|
||||||
|
range_step = 2 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
|
||||||
|
|
||||||
|
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
|
||||||
|
spread_step = 20
|
||||||
|
|
||||||
|
silenced = 1 //embedding messages are still produced so it's kind of weird when enabled.
|
||||||
|
no_attack_log = 1
|
||||||
|
muzzle_type = null
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment/strong
|
||||||
|
damage = 15
|
||||||
|
armor_penetration = 20
|
||||||
|
|
||||||
|
// Tank rupture fragments
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment/tank
|
||||||
|
name = "metal fragment"
|
||||||
|
damage = 9 //Big chunks flying off.
|
||||||
|
range_step = 2 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
|
||||||
|
|
||||||
|
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
|
||||||
|
spread_step = 20
|
||||||
|
|
||||||
|
armor_penetration = 20
|
||||||
|
|
||||||
|
silenced = 1
|
||||||
|
no_attack_log = 1
|
||||||
|
muzzle_type = null
|
||||||
|
pellets = 3
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment/tank/small
|
||||||
|
name = "small metal fragment"
|
||||||
|
damage = 6
|
||||||
|
armor_penetration = 5
|
||||||
|
pellets = 5
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment/tank/big
|
||||||
|
name = "large metal fragment"
|
||||||
|
damage = 17
|
||||||
|
armor_penetration = 10
|
||||||
|
range_step = 5 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
|
||||||
|
pellets = 1
|
||||||
@@ -981,6 +981,7 @@
|
|||||||
#include "code\game\objects\items\weapons\grenades\explosive.dm"
|
#include "code\game\objects\items\weapons\grenades\explosive.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\flashbang.dm"
|
#include "code\game\objects\items\weapons\grenades\flashbang.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\grenade.dm"
|
#include "code\game\objects\items\weapons\grenades\grenade.dm"
|
||||||
|
#include "code\game\objects\items\weapons\grenades\projectile.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\smokebomb.dm"
|
#include "code\game\objects\items\weapons\grenades\smokebomb.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\spawnergrenade.dm"
|
#include "code\game\objects\items\weapons\grenades\spawnergrenade.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\supermatter.dm"
|
#include "code\game\objects\items\weapons\grenades\supermatter.dm"
|
||||||
@@ -2166,6 +2167,7 @@
|
|||||||
#include "code\modules\projectiles\projectile\energy.dm"
|
#include "code\modules\projectiles\projectile\energy.dm"
|
||||||
#include "code\modules\projectiles\projectile\force.dm"
|
#include "code\modules\projectiles\projectile\force.dm"
|
||||||
#include "code\modules\projectiles\projectile\magnetic.dm"
|
#include "code\modules\projectiles\projectile\magnetic.dm"
|
||||||
|
#include "code\modules\projectiles\projectile\pellets.dm"
|
||||||
#include "code\modules\projectiles\projectile\special.dm"
|
#include "code\modules\projectiles\projectile\special.dm"
|
||||||
#include "code\modules\projectiles\targeting\targeting_client.dm"
|
#include "code\modules\projectiles\targeting\targeting_client.dm"
|
||||||
#include "code\modules\projectiles\targeting\targeting_gun.dm"
|
#include "code\modules\projectiles\targeting\targeting_gun.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user