This commit is contained in:
Timothy Teakettle
2020-06-10 23:14:25 +01:00
parent 8ec5672b85
commit 4c55e86da7
74 changed files with 1495 additions and 386 deletions

View File

@@ -27,6 +27,7 @@
s.set_up(3, 1, src)
s.start()
mineEffect(victim)
SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED)
triggered = 1
qdel(src)
@@ -50,6 +51,18 @@
if(isliving(victim))
victim.DefaultCombatKnockdown(stun_time)
/obj/effect/mine/shrapnel
name = "shrapnel mine"
var/shrapnel_type = /obj/projectile/bullet/shrapnel
var/shrapnel_magnitude = 3
/obj/effect/mine/shrapnel/mineEffect(mob/victim)
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
/obj/effect/mine/shrapnel/sting
name = "stinger mine"
shrapnel_type = /obj/projectile/bullet/pellet/stingball
/obj/effect/mine/kickmine
name = "kick mine"

View File

@@ -185,16 +185,15 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
. = ..()
// this proc says it's for initializing components, but we're initializing elements too because it's you and me against the world >:)
if(embedding)
AddElement(/datum/element/embed, embedding)
else if(GLOB.embedpocalypse)
embedding = EMBED_POINTY
AddElement(/datum/element/embed, embedding)
name = "pointy [name]"
else if(GLOB.stickpocalypse)
embedding = EMBED_HARMLESS
AddElement(/datum/element/embed, embedding)
name = "sticky [name]"
if(!LAZYLEN(embedding))
if(GLOB.embedpocalypse)
embedding = EMBED_POINTY
name = "pointy [name]"
else if(GLOB.stickpocalypse)
embedding = EMBED_HARMLESS
name = "sticky [name]"
updateEmbedding()
if(GLOB.rpg_loot_items)
AddComponent(/datum/component/fantasy)
@@ -923,7 +922,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
return
/obj/item/proc/unembedded()
return
if(item_flags & DROPDEL)
QDEL_NULL(src)
return TRUE
/**
* Sets our slowdown and updates equipment slowdown of any mob we're equipped on.
@@ -940,10 +941,132 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(var_name == NAMEOF(src, slowdown))
set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior.
/**
* Does the current embedding var meet the criteria for being harmless? Namely, does it have a pain multiplier and jostle pain mult of 0? If so, return true.
*
*/
/obj/item/proc/is_embed_harmless()
///Does the current embedding var meet the criteria for being harmless? Namely, does it have a pain multiplier and jostle pain mult of 0? If so, return true.
/obj/item/proc/isEmbedHarmless()
if(embedding)
return (!embedding["pain_mult"] && !embedding["jostle_pain_mult"])
return !isnull(embedding["pain_mult"]) && !isnull(embedding["jostle_pain_mult"]) && embedding["pain_mult"] == 0 && embedding["jostle_pain_mult"] == 0
///In case we want to do something special (like self delete) upon failing to embed in something, return true
/obj/item/proc/failedEmbed()
if(item_flags & DROPDEL)
QDEL_NULL(src)
return TRUE
/**
* tryEmbed() is for when you want to try embedding something without dealing with the damage + hit messages of calling hitby() on the item while targetting the target.
*
* Really, this is used mostly with projectiles with shrapnel payloads, from [/datum/element/embed/proc/checkEmbedProjectile], and called on said shrapnel. Mostly acts as an intermediate between different embed elements.
*
* Arguments:
* * target- Either a body part, a carbon, or a closed turf. What are we hitting?
* * forced- Do we want this to go through 100%?
*/
/obj/item/proc/tryEmbed(atom/target, forced=FALSE, silent=FALSE)
if(!isbodypart(target) && !iscarbon(target) && !isclosedturf(target))
return
if(!forced && !LAZYLEN(embedding))
return
if(SEND_SIGNAL(src, COMSIG_EMBED_TRY_FORCE, target, forced, silent))
return TRUE
failedEmbed()
///For when you want to disable an item's embedding capabilities (like transforming weapons and such), this proc will detach any active embed elements from it.
/obj/item/proc/disableEmbedding()
SEND_SIGNAL(src, COMSIG_ITEM_DISABLE_EMBED)
return
///For when you want to add/update the embedding on an item. Uses the vars in [/obj/item/embedding], and defaults to config values for values that aren't set. Will automatically detach previous embed elements on this item.
/obj/item/proc/updateEmbedding()
if(!islist(embedding) || !LAZYLEN(embedding))
return
AddElement(/datum/element/embed,\
embed_chance = (!isnull(embedding["embed_chance"]) ? embedding["embed_chance"] : EMBED_CHANCE),\
fall_chance = (!isnull(embedding["fall_chance"]) ? embedding["fall_chance"] : EMBEDDED_ITEM_FALLOUT),\
pain_chance = (!isnull(embedding["pain_chance"]) ? embedding["pain_chance"] : EMBEDDED_PAIN_CHANCE),\
pain_mult = (!isnull(embedding["pain_mult"]) ? embedding["pain_mult"] : EMBEDDED_PAIN_MULTIPLIER),\
remove_pain_mult = (!isnull(embedding["remove_pain_mult"]) ? embedding["remove_pain_mult"] : EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER),\
rip_time = (!isnull(embedding["rip_time"]) ? embedding["rip_time"] : EMBEDDED_UNSAFE_REMOVAL_TIME),\
ignore_throwspeed_threshold = (!isnull(embedding["ignore_throwspeed_threshold"]) ? embedding["ignore_throwspeed_threshold"] : FALSE),\
impact_pain_mult = (!isnull(embedding["impact_pain_mult"]) ? embedding["impact_pain_mult"] : EMBEDDED_IMPACT_PAIN_MULTIPLIER),\
jostle_chance = (!isnull(embedding["jostle_chance"]) ? embedding["jostle_chance"] : EMBEDDED_JOSTLE_CHANCE),\
jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\
pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\
embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD))
return TRUE

View File

@@ -8,10 +8,11 @@
var/duration = 300
/obj/item/grenade/antigravity/prime()
. = ..()
update_mob()
for(var/turf/T in view(range,src))
T.AddElement(/datum/element/forced_gravity, forced_value)
addtimer(CALLBACK(T, /datum/.proc/_RemoveElement, list(forced_value)), duration)
qdel(src)
resolve()

View File

@@ -178,6 +178,7 @@
if(stage != READY)
return FALSE
. = ..()
var/list/datum/reagents/reactants = list()
for(var/obj/item/reagent_containers/glass/G in beakers)
reactants += G.reagents

View File

@@ -15,6 +15,7 @@
var/segment_chance = 35
/obj/item/grenade/clusterbuster/prime()
. = ..()
update_mob()
var/numspawned = rand(min_spawned,max_spawned)
var/again = 0
@@ -29,7 +30,7 @@
new payload_spawner(drop_location(), payload, numspawned)//Launches payload
playsound(src, prime_sound, 75, 1, -3)
qdel(src)
resolve()
//////////////////////
//Clusterbang segment
@@ -62,7 +63,7 @@
/obj/item/grenade/clusterbuster/segment/prime()
new payload_spawner(drop_location(), payload, rand(min_spawned,max_spawned))
playsound(src, prime_sound, 75, 1, -3)
qdel(src)
resolve()
//////////////////////////////////
//The payload spawner effect

View File

@@ -5,6 +5,7 @@
item_state = "emp"
/obj/item/grenade/empgrenade/prime()
. = ..()
update_mob()
empulse(src, 4, 10)
qdel(src)
resolve()

View File

@@ -7,6 +7,7 @@
var/flashbang_range = 7 //how many tiles away the mob will be stunned.
/obj/item/grenade/flashbang/prime()
. = ..()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
@@ -15,7 +16,7 @@
playsound(flashbang_turf, 'sound/weapons/flashbang.ogg', 100, TRUE, 8, 0.9)
new /obj/effect/dummy/lighting_obj (flashbang_turf, LIGHT_COLOR_WHITE, (flashbang_range + 2), 4, 2)
flashbang_mobs(flashbang_turf, flashbang_range)
qdel(src)
resolve()
/obj/item/grenade/flashbang/proc/flashbang_mobs(turf/source, range)
var/list/banged = get_hearers_in_view(range, source)
@@ -42,3 +43,194 @@
var/distance = get_dist(get_turf(M), source)
if(M.flash_act(affect_silicon = 1))
M.DefaultCombatKnockdown(max(200/max(1,distance), 60))
/obj/item/grenade/stingbang
name = "stingbang"
icon_state = "timeg"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
var/flashbang_range = 1 //how many tiles away the mob will be stunned.
shrapnel_type = /obj/projectile/bullet/pellet/stingball
shrapnel_radius = 5
custom_premium_price = 700 // mostly gotten through cargo, but throw in one for the sec vendor ;)
/obj/item/grenade/stingbang/mega
name = "mega stingbang"
shrapnel_type = /obj/projectile/bullet/pellet/stingball/mega
shrapnel_radius = 12
/obj/item/grenade/stingbang/prime()
if(iscarbon(loc))
var/mob/living/carbon/C = loc
var/obj/item/bodypart/B = C.get_holding_bodypart_of_item(src)
if(B)
C.visible_message("<b><span class='danger'>[src] goes off in [C]'s hand, blowing [C.p_their()] [B.name] to bloody shreds!</span></b>", "<span class='userdanger'>[src] goes off in your hand, blowing your [B.name] to bloody shreds!</span>")
B.dismember()
. = ..()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
return
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/weapons/flashbang.ogg', 50, TRUE, 8, 0.9)
new /obj/effect/dummy/lighting_obj (flashbang_turf, LIGHT_COLOR_WHITE, (flashbang_range + 2), 2, 1)
for(var/mob/living/M in get_hearers_in_view(flashbang_range, flashbang_turf))
pop(get_turf(M), M)
resolve()
/obj/item/grenade/stingbang/proc/pop(turf/T , mob/living/M)
if(M.stat == DEAD) //They're dead!
return
M.show_message("<span class='warning'>POP</span>", MSG_AUDIBLE)
var/distance = max(0,get_dist(get_turf(src),T))
//Flash
if(M.flash_act(affect_silicon = 1))
M.Paralyze(max(10/max(1,distance), 5))
M.Knockdown(max(100/max(1,distance), 60))
//Bang
if(!distance || loc == M || loc == M.loc) //Stop allahu akbarring rooms with this.
M.Paralyze(20)
M.Knockdown(200)
M.soundbang_act(1, 200, 10, 15)
if(M.apply_damages(10, 10))
to_chat(M, "<span class='userdanger'>The blast from \the [src] bruises and burns you!</span>")
// only checking if they're on top of the tile, cause being one tile over will be its own punishment
// Grenade that releases more shrapnel the more times you use it in hand between priming and detonation (sorta like the 9bang from MW3), for admin goofs
/obj/item/grenade/primer
name = "rotfrag grenade"
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases shrapnel shards."
icon_state = "timeg"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
var/rots_per_mag = 3 /// how many times we need to "rotate" the charge in hand per extra tile of magnitude
shrapnel_type = /obj/projectile/bullet/shrapnel
var/rots = 1 /// how many times we've "rotated" the charge
/obj/item/grenade/primer/attack_self(mob/user)
. = ..()
if(active)
user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE)
rots++
user.changeNext_move(CLICK_CD_RAPID)
/obj/item/grenade/primer/prime()
shrapnel_radius = round(rots / rots_per_mag)
. = ..()
resolve()
/obj/item/grenade/primer/stingbang
name = "rotsting"
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases stingballs."
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
rots_per_mag = 2
shrapnel_type = /obj/projectile/bullet/pellet/stingball

View File

@@ -51,9 +51,10 @@
preprime(user, null, FALSE)
/obj/item/grenade/iedcasing/prime() //Blowing that can up
. = ..()
update_mob()
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
qdel(src)
resolve()
/obj/item/grenade/iedcasing/examine(mob/user)
. = ..()

View File

@@ -18,10 +18,30 @@
var/display_timer = 1
var/clumsy_check = GRENADE_CLUMSY_FUMBLE
var/sticky = FALSE
// I moved the explosion vars and behavior to base grenades because we want all grenades to call [/obj/item/grenade/proc/prime] so we can send COMSIG_GRENADE_PRIME
///how big of a devastation explosion radius on prime
var/ex_dev = 0
///how big of a heavy explosion radius on prime
var/ex_heavy = 0
///how big of a light explosion radius on prime
var/ex_light = 0
///how big of a flame explosion radius on prime
var/ex_flame = 0
// dealing with creating a [/datum/component/pellet_cloud] on prime
/// if set, will spew out projectiles of this type
var/shrapnel_type
/// the higher this number, the more projectiles are created as shrapnel
var/shrapnel_radius
var/shrapnel_initialized
/obj/item/grenade/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] primes [src], then eats it! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(shrapnel_type && shrapnel_radius)
shrapnel_initialized = TRUE
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time, delayoverride)
preprime(user, det_time)
user.transferItemToLoc(src, user, TRUE)//>eat a grenade set to 5 seconds >rush captain
sleep(det_time)//so you dont die instantly
@@ -96,6 +116,14 @@
var/turf/T = get_turf(src)
log_game("Grenade detonation at [AREACOORD(T)], location [loc]")
if(shrapnel_type && shrapnel_radius && !shrapnel_initialized) // add a second check for adding the component in case whatever triggered the grenade went straight to prime (badminnery for example)
shrapnel_initialized = TRUE
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
SEND_SIGNAL(src, COMSIG_GRENADE_PRIME)
if(ex_dev || ex_heavy || ex_light || ex_flame)
explosion(loc, ex_dev, ex_heavy, ex_light, flame_range = ex_flame)
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
@@ -137,3 +165,13 @@
/obj/item/proc/grenade_prime_react(obj/item/grenade/nade)
return
/// Don't call qdel() directly on the grenade after it booms, call this instead so it can still resolve its pellet_cloud component if it has shrapnel, then the component will qdel it
/obj/item/grenade/proc/resolve()
if(shrapnel_type)
moveToNullspace()
else
qdel(src)

View File

@@ -124,7 +124,7 @@
I.throw_range = max(1, (I.throw_range - 3))
if(I.embedding)
I.embedding["embed_chance"] = 0
I.AddElement(/datum/element/embed, I.embedding)
I.updateEmbedding()
target.add_overlay(plastic_overlay, TRUE)
if(!nadeassembly)
@@ -158,7 +158,7 @@
shout_syndicate_crap(user)
explosion(user,0,2,0) //Cheap explosion imitation because putting prime() here causes runtimes
user.gib(1, 1)
qdel(src)
resolve()
/obj/item/grenade/plastic/update_icon_state()
if(nadeassembly)
@@ -210,6 +210,7 @@
/obj/item/grenade/plastic/c4/prime()
if(QDELETED(src))
return
. = ..()
var/turf/location
if(target)
if(!QDELETED(target))
@@ -221,7 +222,7 @@
location = get_turf(src)
if(location)
explosion(location,0,0,3)
qdel(src)
resolve()
/obj/item/grenade/plastic/c4/attack(mob/M, mob/user, def_zone)
return

View File

@@ -18,6 +18,7 @@
return ..()
/obj/item/grenade/smokebomb/prime()
. = ..()
update_mob()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
smoke.set_up(4, src)
@@ -28,4 +29,4 @@
var/damage = round(30/(get_dist(B,src)+1))
B.take_damage(damage, BURN, "melee", 0)
sleep(80)
qdel(src)
resolve()

View File

@@ -8,6 +8,7 @@
var/deliveryamt = 1 // amount of type to deliver
/obj/item/grenade/spawnergrenade/prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
. = ..()
update_mob()
if(spawner_type && deliveryamt)
// Make a quick flash
@@ -19,7 +20,7 @@
// Spawn some hostile syndicate critters and spread them out
spawn_and_random_walk(spawner_type, T, deliveryamt, walk_chance=50, admin_spawn=((flags_1 & ADMIN_SPAWNED_1) ? TRUE : FALSE))
qdel(src)
resolve()
/obj/item/grenade/spawnergrenade/manhacks
name = "viscerator delivery grenade"

View File

@@ -4,27 +4,45 @@
icon = 'icons/obj/grenade.dmi'
icon_state = "syndicate"
item_state = "flashbang"
ex_dev = 1
ex_heavy = 2
ex_light = 4
ex_flame = 2
/obj/item/grenade/syndieminibomb/prime()
. = ..()
update_mob()
explosion(src.loc,1,2,4,flame_range = 2)
qdel(src)
resolve()
/obj/item/grenade/syndieminibomb/concussion
name = "HE Grenade"
desc = "A compact shrapnel grenade meant to devastate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
icon_state = "concussion"
ex_heavy = 2
ex_light = 3
ex_flame = 3
/obj/item/grenade/syndieminibomb/concussion/prime()
update_mob()
explosion(src.loc,0,2,3,flame_range = 3)
qdel(src)
/obj/item/grenade/syndieminibomb/concussion/frag
/obj/item/grenade/frag
name = "frag grenade"
desc = "Fire in the hole."
desc = "An anti-personnel fragmentation grenade, this weapon excels at killing soft targets by shredding them with metal shrapnel."
icon_state = "frag"
shrapnel_type = /obj/projectile/bullet/shrapnel
shrapnel_radius = 4
ex_heavy = 1
ex_light = 3
ex_flame = 4
/obj/item/grenade/frag/mega
name = "FRAG grenade"
desc = "An anti-everything fragmentation grenade, this weapon excels at killing anything any everything by shredding them with metal shrapnel."
shrapnel_type = /obj/projectile/bullet/shrapnel/mega
shrapnel_radius = 12
/obj/item/grenade/frag/prime()
. = ..()
update_mob()
resolve()
/obj/item/grenade/gluon
desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
@@ -37,6 +55,7 @@
var/stamina_damage = 30
/obj/item/grenade/gluon/prime()
. = ..()
update_mob()
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
radiation_pulse(src, rad_damage)
@@ -47,4 +66,4 @@
for(var/mob/living/carbon/L in T)
L.adjustStaminaLoss(stamina_damage)
L.adjust_bodytemperature(-230)
qdel(src)
resolve()

View File

@@ -54,7 +54,7 @@
if(attack_verb_on.len)
attack_verb = attack_verb_on
if(embedding)
AddElement(/datum/element/embed, embedding)
updateEmbedding()
icon_state = icon_state_on
w_class = w_class_on
else
@@ -65,7 +65,7 @@
if(attack_verb_off.len)
attack_verb = attack_verb_off
if(embedding)
RemoveElement(/datum/element/embed, embedding)
updateEmbedding()
icon_state = initial(icon_state)
w_class = initial(w_class)
total_mass = initial(total_mass)

View File

@@ -0,0 +1,68 @@
/obj/item/shrapnel // frag grenades
name = "shrapnel shard"
embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=4, embed_chance_turf_mod=-100)
custom_materials = list(/datum/material/iron=50)
armour_penetration = -20
icon = 'icons/obj/shards.dmi'
icon_state = "large"
w_class = WEIGHT_CLASS_TINY
item_flags = DROPDEL
/obj/item/shrapnel/stingball // stingbang grenades
name = "stingball"
embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100)
icon_state = "tiny"
/obj/item/shrapnel/bullet // bullets
name = "bullet"
icon = 'icons/obj/ammo.dmi'
icon_state = "s-casing"
item_flags = NONE
/obj/item/shrapnel/bullet/c38 // .38 round
name = "\improper .38 bullet"
/obj/item/shrapnel/bullet/c38/dumdum // .38 DumDum round
name = "\improper .38 DumDum bullet"
embedding = list(embed_chance=70, fall_chance=7, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10, embed_chance_turf_mod=-100)
/obj/projectile/bullet/shrapnel
name = "flying shrapnel shard"
damage = 9
range = 10
armour_penetration = -30
dismemberment = 5
ricochets_max = 2
ricochet_chance = 40
shrapnel_type = /obj/item/shrapnel
ricochet_incidence_leeway = 60
hit_stunned_targets = TRUE
/obj/projectile/bullet/shrapnel/mega
name = "flying shrapnel hunk"
range = 25
dismemberment = 10
ricochets_max = 4
ricochet_chance = 90
ricochet_decay_chance = 0.9
/obj/projectile/bullet/pellet/stingball
name = "stingball pellet"
damage = 3
stamina = 8
ricochets_max = 4
ricochet_chance = 66
ricochet_decay_chance = 1
ricochet_decay_damage = 0.9
ricochet_auto_aim_angle = 10
ricochet_auto_aim_range = 2
ricochet_incidence_leeway = 0
shrapnel_type = /obj/item/shrapnel/stingball
/obj/projectile/bullet/pellet/stingball/mega
name = "megastingball pellet"
ricochets_max = 6
ricochet_chance = 110
/obj/projectile/bullet/pellet/stingball/on_ricochet(atom/A)
hit_stunned_targets = TRUE // ducking will save you from the first wave, but not the rebounds

View File

@@ -27,7 +27,7 @@
if(do_after(user, 30, target=I))
I.embedding = conferred_embed
I.AddElement(/datum/element/embed, I.embedding)
I.updateEmbedding()
to_chat(user, "<span class='notice'>You finish wrapping [I] with [src].</span>")
use(1)
I.name = "[prefix] [I.name]"

View File

@@ -512,16 +512,16 @@
new /obj/item/grenade/smokebomb(src)
new /obj/item/grenade/empgrenade(src)
new /obj/item/grenade/empgrenade(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)

View File

@@ -275,6 +275,16 @@
for(var/i in 1 to 7)
new /obj/item/grenade/flashbang(src)
obj/item/storage/box/stingbangs
name = "box of stingbangs (WARNING)"
desc = "<B>WARNING: These devices are extremely dangerous and can cause severe injuries or death in repeated use.</B>"
icon_state = "secbox"
illustration = "flashbang"
/obj/item/storage/box/stingbangs/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/grenade/stingbang(src)
/obj/item/storage/box/flashes
name = "box of flashbulbs"
desc = "<B>WARNING: Flashes can cause serious eye damage, protective eyewear is required.</B>"

View File

@@ -297,7 +297,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
force = 2
throwforce = 20 //This is never used on mobs since this has a 100% embed chance.
throw_speed = 4
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0)
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
armour_penetration = 40
w_class = WEIGHT_CLASS_SMALL
sharpness = IS_SHARP
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)

View File

@@ -74,7 +74,8 @@
/obj/bullet_act(obj/item/projectile/P)
. = ..()
playsound(src, P.hitsound, 50, 1)
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(P.suppressed != SUPPRESSED_VERY)
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)

View File

@@ -323,3 +323,8 @@
/obj/proc/rnd_crafted(obj/machinery/rnd/production/P)
return
/obj/handle_ricochet(obj/projectile/P)
. = ..()
if(. && ricochet_damage_mod)
take_damage(P.damage * ricochet_damage_mod, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) // pass along ricochet_damage_mod damage to the structure for the ricochet

View File

@@ -9,6 +9,8 @@
var/mob/living/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
layer = BELOW_OBJ_LAYER
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.5
/obj/structure/Initialize()
if (!armor)

View File

@@ -38,6 +38,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
var/hitsound = 'sound/effects/Glasshit.ogg'
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_flags = RAD_PROTECT_CONTENTS
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.4
/// Electrochromatic status
var/electrochromatic_status = NOT_ELECTROCHROMATIC
@@ -525,6 +527,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
explosion_block = 1
glass_type = /obj/item/stack/sheet/rglass
rad_insulation = RAD_HEAVY_INSULATION
ricochet_chance_mod = 0.8
/obj/structure/window/reinforced/spawner/east
dir = EAST
@@ -690,6 +693,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
level = 3
glass_type = /obj/item/stack/sheet/titaniumglass
glass_amount = 2
ricochet_chance_mod = 0.9
/obj/structure/window/shuttle/narsie_act()
add_atom_colour("#3C3434", FIXED_COLOUR_PRIORITY)