mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 03:02:54 +00:00
Adds fragmentation grenades
Adds a fragmentation grenade item that launches a shower of projectiles in all directions when detonated.
This commit is contained in:
@@ -699,6 +699,7 @@
|
|||||||
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
|
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
|
#include "code\game\objects\items\weapons\grenades\emgrenade.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\fragmentation.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\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"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, turf/aimloc)
|
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, turf/aimloc)
|
||||||
var/obj/item/projectile/P = A
|
var/obj/item/projectile/P = A
|
||||||
P.shot_from = src
|
P.shot_from = src.name
|
||||||
P.original = target
|
P.original = target
|
||||||
P.starting = P.loc
|
P.starting = P.loc
|
||||||
P.current = P.loc
|
P.current = P.loc
|
||||||
|
|||||||
109
code/game/objects/items/weapons/grenades/fragmentation.dm
Normal file
109
code/game/objects/items/weapons/grenades/fragmentation.dm
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//Fragmentation grenade projectile
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment
|
||||||
|
damage = 6
|
||||||
|
range_step = 2
|
||||||
|
|
||||||
|
base_spread = 0 //hit any target zone randomly
|
||||||
|
spread_step = 0
|
||||||
|
|
||||||
|
//step_delay = 10
|
||||||
|
silenced = 1
|
||||||
|
//hitscan = 1
|
||||||
|
muzzle_type = null
|
||||||
|
|
||||||
|
/obj/item/projectile/bullet/pellet/fragment/Move()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
//Allow mobs that are prone close to the starting turf a chance to get hit, too
|
||||||
|
|
||||||
|
if(. && isturf(loc))
|
||||||
|
var/distance = get_dist(loc, starting)
|
||||||
|
var/chance = max(100 - (distance - 1)*20, 0)
|
||||||
|
if(prob(chance))
|
||||||
|
for(var/mob/living/M in loc)
|
||||||
|
if(Bump(M)) //Bump will make sure we don't hit a mob multiple times
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/frag
|
||||||
|
name = "fragmentation grenade"
|
||||||
|
desc = "A military fragmentation grenade, designed to explode in a deadly shower of fragments."
|
||||||
|
|
||||||
|
var/num_fragments = 7 //fragments per projectile
|
||||||
|
var/fragment_damage = 15
|
||||||
|
var/damage_step = 1 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
|
||||||
|
|
||||||
|
var/silenced = 0
|
||||||
|
|
||||||
|
//Higher values means projectile spread is more even but more projectiles are created.
|
||||||
|
//The actual number of projectile objects is spread_range*8
|
||||||
|
var/spread_range = 4 //32 projectiles. With spread_range=4 and num_fragments=7, a frag grenade produces 224 fragments.
|
||||||
|
|
||||||
|
#define LOCATE_COORDS(X, Y, Z) locate(between(1, X, world.maxx), between(1, Y, world.maxy), Z)
|
||||||
|
/obj/item/weapon/grenade/frag/prime()
|
||||||
|
..()
|
||||||
|
|
||||||
|
var/turf/O = get_turf(src)
|
||||||
|
if(!O) return
|
||||||
|
|
||||||
|
explosion(O, -1, 1, 2, 1, 0)
|
||||||
|
|
||||||
|
for(var/i in -spread_range to spread_range)
|
||||||
|
var/turf/T1 = LOCATE_COORDS(O.x+i, O.y+spread_range, O.z)
|
||||||
|
launch_projectile(O, T1)
|
||||||
|
|
||||||
|
var/turf/T2 = LOCATE_COORDS(O.x+i, O.y-spread_range, O.z)
|
||||||
|
launch_projectile(O, T2)
|
||||||
|
|
||||||
|
for(var/j in 1-spread_range to spread_range-1)
|
||||||
|
var/turf/T1 = LOCATE_COORDS(O.x+spread_range, O.y+j, O.z)
|
||||||
|
launch_projectile(O, T1)
|
||||||
|
|
||||||
|
var/turf/T2 = LOCATE_COORDS(O.x-spread_range, O.y+j, O.z)
|
||||||
|
launch_projectile(O, T2)
|
||||||
|
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/grenade/frag/proc/launch_projectile(var/turf/source, var/turf/target)
|
||||||
|
var/obj/item/projectile/bullet/pellet/fragment/P = new(src)
|
||||||
|
|
||||||
|
P.damage = fragment_damage
|
||||||
|
P.pellets = num_fragments
|
||||||
|
P.range_step = damage_step
|
||||||
|
P.silenced = silenced
|
||||||
|
P.shot_from = src.name
|
||||||
|
|
||||||
|
var/location = loc //store our current loc since qdel will move the grenade to nullspace
|
||||||
|
spawn(0)
|
||||||
|
P.launch(target)
|
||||||
|
if(!isturf(location))
|
||||||
|
P.Bump(location)
|
||||||
|
for(var/atom/movable/AM in source)
|
||||||
|
P.Bump(AM)
|
||||||
|
|
||||||
|
/*
|
||||||
|
//the vector system doesn't play well with very large angle offsets, so generate projectiles along each of the 8 directions
|
||||||
|
var/subarc_width = 45/(num_projectiles*2)
|
||||||
|
var/fragments_per_projectile = round(num_fragments / (num_projectiles*8))
|
||||||
|
|
||||||
|
for(var/launch_dir in alldirs)
|
||||||
|
var/turf/target = get_edge_target_turf(T, launch_dir)
|
||||||
|
for(var/i in 1 to num_projectiles)
|
||||||
|
//keep the trajectory centered in the 45 deg arc
|
||||||
|
var/launch_angle = (i-0.5)*subarc_width - 22.5
|
||||||
|
|
||||||
|
var/obj/item/projectile/bullet/pellet/fragment/P = new(src)
|
||||||
|
|
||||||
|
if(dispersion)
|
||||||
|
P.dispersion = (subarc_width)/9 //randomly disperse within the projectile arc, so that there aren't any predictable blind spots
|
||||||
|
P.damage = fragment_damage
|
||||||
|
P.pellets = fragments_per_projectile
|
||||||
|
P.range_step = damage_step
|
||||||
|
P.silenced = silenced
|
||||||
|
|
||||||
|
P.shot_from = src.name
|
||||||
|
spawn(0)
|
||||||
|
P.Move(T) //so that we hit people in the starting turf
|
||||||
|
P.launch(target, ran_zone(), angle_offset = launch_angle)
|
||||||
|
*/
|
||||||
|
qdel(src)
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
var/yo = null
|
var/yo = null
|
||||||
var/xo = null
|
var/xo = null
|
||||||
var/current = null
|
var/current = null
|
||||||
var/obj/shot_from = null // the object which shot us
|
var/shot_from = "" // name of the object which shot us
|
||||||
var/atom/original = null // the target clicked (not necessarily where the projectile is headed). Should probably be renamed to 'target' or something.
|
var/atom/original = null // the target clicked (not necessarily where the projectile is headed). Should probably be renamed to 'target' or something.
|
||||||
var/turf/starting = null // the projectile's starting turf
|
var/turf/starting = null // the projectile's starting turf
|
||||||
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
p_y = between(0, p_y + rand(-radius, radius), world.icon_size)
|
p_y = between(0, p_y + rand(-radius, radius), world.icon_size)
|
||||||
|
|
||||||
//called to launch a projectile
|
//called to launch a projectile
|
||||||
/obj/item/projectile/proc/launch(atom/target, var/target_zone, var/x_offset=0, var/y_offset=0)
|
/obj/item/projectile/proc/launch(atom/target, var/target_zone, var/x_offset=0, var/y_offset=0, var/angle_offset=0)
|
||||||
var/turf/curloc = get_turf(src)
|
var/turf/curloc = get_turf(src)
|
||||||
var/turf/targloc = get_turf(target)
|
var/turf/targloc = get_turf(target)
|
||||||
if (!istype(targloc) || !istype(curloc))
|
if (!istype(targloc) || !istype(curloc))
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
def_zone = target_zone
|
def_zone = target_zone
|
||||||
|
|
||||||
spawn()
|
spawn()
|
||||||
setup_trajectory(curloc, targloc, x_offset, y_offset) //plot the initial trajectory
|
setup_trajectory(curloc, targloc, x_offset, y_offset, angle_offset) //plot the initial trajectory
|
||||||
process()
|
process()
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
loc = get_turf(user) //move the projectile out into the world
|
loc = get_turf(user) //move the projectile out into the world
|
||||||
|
|
||||||
firer = user
|
firer = user
|
||||||
shot_from = launcher
|
shot_from = launcher.name
|
||||||
silenced = launcher.silenced
|
silenced = launcher.silenced
|
||||||
|
|
||||||
return launch(target, target_zone, x_offset, y_offset)
|
return launch(target, target_zone, x_offset, y_offset)
|
||||||
@@ -173,7 +173,8 @@
|
|||||||
result = target_mob.bullet_act(src, def_zone)
|
result = target_mob.bullet_act(src, def_zone)
|
||||||
|
|
||||||
if(result == PROJECTILE_FORCE_MISS)
|
if(result == PROJECTILE_FORCE_MISS)
|
||||||
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
if(!silenced)
|
||||||
|
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
//hit messages
|
//hit messages
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
damage = 20
|
damage = 20
|
||||||
//icon_state = "bullet" //TODO: would be nice to have it's own icon state
|
//icon_state = "bullet" //TODO: would be nice to have it's own icon state
|
||||||
var/pellets = 4 //number of pellets
|
var/pellets = 4 //number of pellets
|
||||||
var/range_step = 2 //effective pellet count decreases every few tiles
|
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
|
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
|
var/spread_step = 10 //higher means the pellets spread more across body parts with distance
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@
|
|||||||
if (..()) hits++
|
if (..()) hits++
|
||||||
def_zone = old_zone //restore the original zone the projectile was aimed at
|
def_zone = old_zone //restore the original zone the projectile was aimed at
|
||||||
|
|
||||||
|
//world << "[src]: hitting [target_mob], [hits] of [pellets] hits."
|
||||||
pellets -= hits //each hit reduces the number of pellets left
|
pellets -= hits //each hit reduces the number of pellets left
|
||||||
if (hits >= total_pellets || pellets <= 0)
|
if (hits >= total_pellets || pellets <= 0)
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
Reference in New Issue
Block a user