mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 11:37:40 +01:00
Frag grenades now explode into proper projectiles (#24581)
* holy fuck * oops * IPA * no badmins * wow * yeah * no funny
This commit is contained in:
@@ -276,6 +276,44 @@
|
||||
T.color = null
|
||||
T.maptext = ""
|
||||
|
||||
/**
|
||||
* Creates an explosion of shrapnel at a turf.
|
||||
* - /turf/epicenter - where the explosion occurs
|
||||
* - shrapnel_number - the amount of shrapnel to create
|
||||
* - /obj/item/projectile/shrapnel_type - the type of shrapnel bullets to shoot
|
||||
* - chance_to_hit_same_turf - the probability to hit someone on the same turf, doubled for someone lying down
|
||||
*/
|
||||
/proc/create_shrapnel(turf/epicenter, shrapnel_number = 10, obj/item/projectile/shrapnel_type = /obj/item/projectile/bullet/shrapnel, chance_to_hit_same_turf = 50)
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter || !shrapnel_number || !shrapnel_type)
|
||||
return
|
||||
shrapnel_number = min(shrapnel_number, 200) // calm down badmins, no crashing the server
|
||||
|
||||
var/angle_increment = 360 / shrapnel_number
|
||||
var/mob/living/mob_standing_on_turf
|
||||
var/mob/living/mob_lying_on_turf
|
||||
|
||||
for(var/mob/living/M in epicenter) //find a mob at the epicenter. Non-prone mobs take priority
|
||||
if(!IS_HORIZONTAL(M) && !mob_standing_on_turf)
|
||||
mob_standing_on_turf = M
|
||||
else if(!mob_lying_on_turf)
|
||||
mob_lying_on_turf = M
|
||||
|
||||
for(var/i in 1 to shrapnel_number)
|
||||
var/obj/item/projectile/Shrapnel = new shrapnel_type(epicenter)
|
||||
|
||||
// You can't just stand over a shrapnel explosion to avoid it
|
||||
if(mob_standing_on_turf && prob(chance_to_hit_same_turf))
|
||||
Shrapnel.Bump(mob_standing_on_turf, TRUE)
|
||||
continue
|
||||
// If you dive on it, you're even more likely to get hit
|
||||
if(mob_lying_on_turf && prob(2 * chance_to_hit_same_turf))
|
||||
Shrapnel.Bump(mob_lying_on_turf, TRUE)
|
||||
continue
|
||||
|
||||
var/angle = i * angle_increment + rand(-angle_increment / 2, angle_increment / 2)
|
||||
Shrapnel.fire(angle)
|
||||
|
||||
#undef CREAK_DELAY
|
||||
#undef DEVASTATION_PROB
|
||||
#undef HEAVY_IMPACT_PROB
|
||||
|
||||
@@ -1,51 +1,74 @@
|
||||
#define DEFAULT_SHRAPNEL_RANGE 5
|
||||
|
||||
/obj/item/grenade/frag
|
||||
name = "frag grenade"
|
||||
desc = "Fire in the hole."
|
||||
icon_state = "frag"
|
||||
item_state = "grenade"
|
||||
origin_tech = "materials=3;magnets=4"
|
||||
var/range = 5
|
||||
var/max_shrapnel = 4
|
||||
var/embed_prob = 100 //reduced by armor
|
||||
var/embedded_type = /obj/item/embedded/shrapnel
|
||||
var/shrapnel_contained = 20
|
||||
var/embedded_type = /obj/item/projectile/bullet/shrapnel
|
||||
|
||||
/obj/item/grenade/frag/prime()
|
||||
update_mob()
|
||||
var/turf/epicenter = get_turf(src)
|
||||
for(var/mob/living/carbon/human/H in epicenter)
|
||||
if(IS_HORIZONTAL(H)) //grenade is jumped on but get real fucked up
|
||||
embed_shrapnel(H, max_shrapnel)
|
||||
range = 1
|
||||
explosion(loc, 0, 1, range, breach = FALSE)
|
||||
for(var/turf/T in view(range, loc))
|
||||
for(var/mob/living/carbon/human/H in T)
|
||||
var/shrapnel_amount = max_shrapnel - T.Distance(epicenter)
|
||||
if(shrapnel_amount > 0)
|
||||
embed_shrapnel(H, shrapnel_amount)
|
||||
explosion(loc, 0, 1, DEFAULT_SHRAPNEL_RANGE, breach = FALSE)
|
||||
create_shrapnel(loc, shrapnel_contained, shrapnel_type = embedded_type)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/frag/proc/embed_shrapnel(mob/living/carbon/human/H, amount)
|
||||
for(var/i = 0, i < amount, i++)
|
||||
if(prob(embed_prob - ARMOUR_VALUE_TO_PERCENTAGE(H.getarmor(null, BOMB))))
|
||||
var/obj/item/embedded/S = new embedded_type(src)
|
||||
H.hitby(S, skipcatch = 1)
|
||||
S.throwforce = 1
|
||||
S.throw_speed = 1
|
||||
S.sharp = FALSE
|
||||
else
|
||||
to_chat(H, "<span class='warning'>Shrapnel bounces off your armor!</span>")
|
||||
|
||||
/obj/item/embedded/shrapnel
|
||||
/**
|
||||
* Shrapnel that flies through the air and hits you
|
||||
*/
|
||||
/obj/item/projectile/bullet/shrapnel
|
||||
name = "shrapnel"
|
||||
icon_state = "magspear"
|
||||
gender = PLURAL
|
||||
range = DEFAULT_SHRAPNEL_RANGE
|
||||
damage = 1 // 1 damage, to trigger stuff that reacts to damage. Rest of the damage is done through the physical shrapnel
|
||||
var/embed_prob = 100 //reduced by armor
|
||||
var/embedded_type = /obj/item/shrapnel
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/on_hit(atom/target, blocked)
|
||||
. = ..()
|
||||
var/obj/item/new_possible_embed = new embedded_type(get_turf(src)) // drop it on the floor if we hit somethig non-living
|
||||
if(!.)
|
||||
return
|
||||
if(!ishuman(target))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!prob(embed_prob - ARMOUR_VALUE_TO_PERCENTAGE(H.getarmor(null, BOMB))))
|
||||
to_chat(H, "<span class='warning'>Shrapnel bounces off your armor!</span>")
|
||||
return
|
||||
H.try_embed_object(new_possible_embed)
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/on_range()
|
||||
var/obj/item/we_missed = new embedded_type(get_turf(src)) // we missed, lets toss the shrapnel
|
||||
var/range = gaussian(4, 2)
|
||||
if(range > 0)
|
||||
var/atom/i_wasnt_aiming_for_the_truck = get_angle_target_turf(get_turf(src), Angle, range)
|
||||
we_missed.throw_at(i_wasnt_aiming_for_the_truck, 16, 3)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Shrapnel projectiles turn into this after trying to embed
|
||||
*/
|
||||
/obj/item/shrapnel
|
||||
name = "shrapnel"
|
||||
desc = "Metal shards at high velocity, a classic method of blowing your enemies up."
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
throwforce = 10
|
||||
throw_speed = EMBED_THROWSPEED_THRESHOLD
|
||||
icon_state = "shrapnel1"
|
||||
force = 8 // its a sharp piece of metal, but still not very effective
|
||||
gender = PLURAL
|
||||
embed_chance = 100
|
||||
embedded_fall_chance = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
sharp = TRUE
|
||||
hitsound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
/obj/item/embedded/shrapnel/New()
|
||||
..()
|
||||
/obj/item/shrapnel/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = pick("shrapnel1", "shrapnel2", "shrapnel3")
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-8, 8)
|
||||
|
||||
#undef DEFAULT_SHRAPNEL_RANGE
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
if(!in_range(src, user))
|
||||
if(icon == src)
|
||||
. += "<span class='notice'>It's \a [bicon(icon)][src]! If you want any more information you'll need to get closer.</span>"
|
||||
. += "<span class='notice'>It's [p_a()] [bicon(icon)] [name]! If you want any more information you'll need to get closer.</span>"
|
||||
return
|
||||
|
||||
var/celsius_temperature = air_contents.temperature - T0C
|
||||
|
||||
Reference in New Issue
Block a user