diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 182b2107df113bfdeba0b0b405c5fb136df71d3d..aa18fb016f98a77cae643118f4146e0693b7f53e 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -696,6 +696,9 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list( close(1) return TRUE //no afterattack call + + if(istype(C, /obj/item/large_shrapnel)) + return FALSE //trigger afterattack call else return ..() diff --git a/code/game/objects/items/shards.dm b/code/game/objects/items/shards.dm index 42ba74ad91f195509abdbb50ff6ef8010c83ffe8..d89eb6960cbb5e2cae04c85fd3c60f43b6785664 100644 --- a/code/game/objects/items/shards.dm +++ b/code/game/objects/items/shards.dm @@ -72,6 +72,128 @@ // on_embed is called from projectile.dm, bullet_act(obj/item/projectile/P). // on_embedded_movement is called from human.dm, handle_embedded_objects(). +/obj/item/large_shrapnel/proc/on_embedded_movement(var/mob/living/embedded_mob) + return + +/obj/item/large_shrapnel/proc/on_embed(var/mob/embedded_mob, var/obj/limb/target_organ) + return + +/obj/item/large_shrapnel/at_rocket_dud + name = "unexploded anti-tank rocket" + icon = 'icons/obj/items/weapons/guns/ammo.dmi' + icon_state = "custom_rocket_no_fuel" + desc = "An undetonated anti-tank rocket that probably hit something soft. You really shouldn't drop this..." + matter = list("metal" = 11250) //same as custom warhead + w_class = SIZE_LARGE + force = 20 + throw_range = 5 + sharp = IS_SHARP_ITEM_BIG + edge = 1 + var/damage_on_move = 2 + var/vehicle_slowdown_time = 5 SECONDS + var/throw_channel = 2 SECONDS + var/detonating = 0 + var/thrown = 0 + var/cause = null + +/obj/item/large_shrapnel/at_rocket_dud/dropped(mob/user) + . = ..() + + spawn(1) + if(!detonating && !thrown && !cause && prob(50)) + cause = "accidental" + visible_message(SPAN_DANGER("You hear the click of a mechanism triggering inside [src] as [user] drops it. Uh oh.")) + manual_detonate(get_turf(src), user) + cause = null + +/obj/item/large_shrapnel/at_rocket_dud/try_to_throw(var/mob/living/user) + to_chat(user, SPAN_NOTICE("You heft [src] up, preparing to throw it.")) + user.visible_message(SPAN_DANGER("[user] strains to lift up [src]. It looks like they're trying to throw it!")) + throw_range = 5 + throw_channel = 2 SECONDS + if(HAS_TRAIT(user, TRAIT_SUPER_STRONG)) + throw_range = 8 + throw_channel = 1 SECONDS + if(!do_after(user, throw_channel, INTERRUPT_ALL, BUSY_ICON_HOSTILE)) + to_chat(user, SPAN_WARNING("Your attempt to throw [src] was interrupted!")) + return FALSE + cause = "manually triggered" + thrown = 1 + return TRUE + +/obj/item/large_shrapnel/at_rocket_dud/launch_impact(var/atom/hit_atom) + . = ..() + var/datum/launch_metadata/LM = src.launch_metadata + var/user = LM.thrower + if(!detonating && prob(50)) + cause = "manually triggered" + visible_message(SPAN_DANGER("You hear the click of a mechanism triggering inside [src]. Uh oh.")) + vehicle_impact(hit_atom, user) + manual_detonate(hit_atom, user, 0) + return + cause = null + thrown = 0 + +/obj/item/large_shrapnel/at_rocket_dud/afterattack(var/atom/target, var/mob/user, var/proximity_flag, var/click_parameters) + if(!detonating && (user.a_intent == INTENT_HARM) && proximity_flag && (istype(target, /obj/vehicle) || istype(target, /obj/structure) || istype(target, /turf))) + cause = "manually triggered" + vehicle_impact(target, user) + manual_detonate(target, user) + return + cause = null + +/obj/item/large_shrapnel/at_rocket_dud/attack(var/mob/living/M, var/mob/living/user) + . = ..() + if(!detonating && (user.a_intent == INTENT_HARM) && istype(M, /mob/living/carbon)) + cause = "manually triggered" + manual_detonate(M, user) + return + cause = null + +/obj/item/large_shrapnel/at_rocket_dud/proc/vehicle_impact(var/atom/T, var/mob/U) + if(istype(T, /obj/vehicle/multitile)) + var/obj/vehicle/multitile/M = T + M.next_move = world.time + vehicle_slowdown_time + playsound(M, 'sound/effects/meteorimpact.ogg', 35) + M.at_munition_interior_explosion_effect(cause_data = create_cause_data("Anti-Tank Rocket", U)) + M.interior_crash_effect() + M.ex_act(1000, get_dir(U, T), create_cause_data("Anti-Tank Rocket", U)) + return TRUE + return FALSE + +/obj/item/large_shrapnel/at_rocket_dud/proc/manual_detonate(var/atom/target, var/mob/living/user, var/melee = 1, var/direction = null) + detonating = 1 + if(user && (cause == "manually triggered")) + user.visible_message(SPAN_DANGER("[user] [melee?"slams [src] into":"throws [src] at"] [target]!")) + if((!direction) && target && user) + direction = get_dir(user, target) + cell_explosion(get_turf(target), 200, 150, EXPLOSION_FALLOFF_SHAPE_LINEAR, direction, create_cause_data("[cause] UXO detonation", user)) + qdel(src) + +/obj/item/large_shrapnel/at_rocket_dud/on_embed(var/mob/embedded_mob, var/obj/limb/target_organ) + if(!ishuman(embedded_mob)) + return + var/mob/living/carbon/human/H = embedded_mob + if(H.species.flags & NO_SHRAPNEL) + return + if(istype(target_organ)) + target_organ.embed(src) + +/obj/item/large_shrapnel/at_rocket_dud/on_embedded_movement(var/mob/living/embedded_mob) + if(!ishuman(embedded_mob)) + return + var/mob/living/carbon/human/H = embedded_mob + if(H.species.flags & NO_SHRAPNEL) + return + var/obj/limb/organ = embedded_organ + if(istype(organ)) + organ.take_damage(damage_on_move, 0, 0, no_limb_loss = TRUE) + embedded_mob.pain.apply_pain(damage_on_move) + if(prob(5)) + to_chat(embedded_mob, SPAN_DANGER("The [src] sticking out of you jostles roughly against your innards! Oh no.")) + embedded_mob.visible_message(SPAN_DANGER("The [src] sticking out of [embedded_mob] suddenly explodes!")) + cell_explosion(get_turf(embedded_mob), 200, 150, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, create_cause_data("accidental UXO detonation", embedded_mob)) + /obj/item/shard/shrapnel name = "shrapnel" icon_state = "shrapnel" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index d50d3a0aa1a9d41bf2f28c23c8ac194ba0b67dcf..9ef64d48aac322a4ddb4ee32e09436f7dbdba892 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1002,6 +1002,9 @@ for(var/obj/item/W in embedded_items) var/obj/limb/organ = W.embedded_organ // Check if shrapnel + if(istype(W, /obj/item/large_shrapnel)) + var/obj/item/large_shrapnel/embedded = W + embedded.on_embedded_movement(src) if(istype(W, /obj/item/shard/shrapnel)) var/obj/item/shard/shrapnel/embedded = W embedded.on_embedded_movement(src) diff --git a/code/modules/projectiles/ammo_datums.dm b/code/modules/projectiles/ammo_datums.dm index a5f9de7341841f3e15df4361ac180c1b09e409e1..abfd98f9b9153b4e652337da8dcea3cee1932f14 100644 --- a/code/modules/projectiles/ammo_datums.dm +++ b/code/modules/projectiles/ammo_datums.dm @@ -1888,6 +1888,8 @@ name = "anti-tank rocket" damage = 100 var/vehicle_slowdown_time = 5 SECONDS + shrapnel_chance = 5 + shrapnel_type = /obj/item/large_shrapnel/at_rocket_dud /datum/ammo/rocket/ap/anti_tank/on_hit_obj(obj/O, obj/item/projectile/P) if(istype(O, /obj/vehicle/multitile)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index f12f0f937229757ce35286399fdc03b581dcb10f..e2cd563e309549f19a17d9c2f13704afe174eede 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -928,6 +928,9 @@ P.ammo.on_embed(src, organ) var/obj/item/shard/shrapnel/new_embed = new P.ammo.shrapnel_type + var/obj/item/large_shrapnel/large_embed = new P.ammo.shrapnel_type + if(istype(large_embed)) + large_embed.on_embed(src, organ) if(istype(new_embed)) var/found_one = FALSE for(var/obj/item/shard/shrapnel/S in embedded_items)