diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index d56d8365220..b32baedb76b 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define EMBEDDED_PAIN_CHANCE 15 ///Chance for embedded object to fall out (causing pain but removing the object) #define EMBEDDED_ITEM_FALLOUT 5 -///Chance for an object to embed into somebody when thrown (if it's sharp) +///Chance for an object to embed into somebody when thrown #define EMBED_CHANCE 45 ///Coefficient of multiplication for the damage the item does while embedded (this*item.w_class) #define EMBEDDED_PAIN_MULTIPLIER 2 diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 2e260a8b5f5..13cd7709edf 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -607,10 +607,8 @@ // /obj/projectile signals (sent to the firer) -///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle, hit_limb) +///from base of /obj/projectile/proc/on_hit(), like COMSIG_PROJECTILE_ON_HIT but on the projectile itself and with the hit limb (if any): (atom/movable/firer, atom/target, Angle, hit_limb) #define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit" - #define COMPONENT_PROJECTILE_SELF_ON_HIT_EMBED_SUCCESS (1<<0) - #define COMPONENT_PROJECTILE_SELF_ON_HIT_SELF_DELETE (1<<1) ///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle) #define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" ///from base of /obj/projectile/proc/fire(): (obj/projectile, atom/original_target) @@ -621,8 +619,9 @@ #define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" ///sent to targets during the process_hit proc of projectiles #define COMSIG_PROJECTILE_RANGE_OUT "projectile_range_out" -///sent when trying to force an embed (mainly for projectiles, only used in the embed element) +///from [/obj/item/proc/tryEmbed] sent when trying to force an embed (mainly for projectiles and eating glass) #define COMSIG_EMBED_TRY_FORCE "item_try_embed" + #define COMPONENT_EMBED_SUCCESS (1<<1) ///sent to targets during the process_hit proc of projectiles #define COMSIG_PELLET_CLOUD_INIT "pellet_cloud_init" diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm index 4c55d00c734..ac36ff1762d 100644 --- a/code/datums/components/gunpoint.dm +++ b/code/datums/components/gunpoint.dm @@ -48,7 +48,7 @@ if(target.stat == CONSCIOUS && is_nuclear_operative(shooter) && !is_nuclear_operative(target) && (locate(/obj/item/disk/nuclear) in target.get_contents()) && shooter.client) shooter.client.give_award(/datum/award/achievement/misc/rocket_holdup, shooter) - target.do_alert_animation(target) + target.do_alert_animation() target.playsound_local(target.loc, 'sound/machines/chime.ogg', 50, TRUE) SEND_SIGNAL(target, COMSIG_ADD_MOOD_EVENT, "gunpoint", /datum/mood_event/gunpoint) diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm index 1c6e2fcf9a6..f6ab4e2c914 100644 --- a/code/datums/components/pellet_cloud.dm +++ b/code/datums/components/pellet_cloud.dm @@ -132,15 +132,26 @@ /** * create_blast_pellets() is for when we have a central point we want to shred the surroundings of with a ring of shrapnel, namely frag grenades and landmines. * - * Note that grenades have extra handling for someone throwing themselves/being thrown on top of it, while landmines do not (obviously, it's a landmine!). See [/datum/component/pellet_cloud/proc/handle_martyrs] + * Note that grenades have extra handling for someone throwing themselves/being thrown on top of it, see [/datum/component/pellet_cloud/proc/handle_martyrs] + * Landmines just have a small check for [/obj/effect/mine/shrapnel/var/shred_triggerer], and spawn extra shrapnel for them if so + * + * Arguments: + * * O- Our parent, the thing making the shrapnel obviously (grenade or landmine) + * * punishable_triggerer- For grenade lances or people who step on the landmines (if we shred the triggerer), we spawn extra shrapnel for them in addition to the normal spread */ -/datum/component/pellet_cloud/proc/create_blast_pellets(obj/O, mob/living/lanced_by) +/datum/component/pellet_cloud/proc/create_blast_pellets(obj/O, mob/living/punishable_triggerer) SIGNAL_HANDLER_DOES_SLEEP var/atom/A = parent if(isgrenade(parent)) // handle_martyrs can reduce the radius and thus the number of pellets we produce if someone dives on top of a frag grenade - handle_martyrs(lanced_by) // note that we can modify radius in this proc + handle_martyrs(punishable_triggerer) // note that we can modify radius in this proc + else if(islandmine(parent)) + var/obj/effect/mine/shrapnel/triggered_mine = parent + if(triggered_mine.shred_triggerer && istype(punishable_triggerer)) // free shrapnel for the idiot who stepped on it if we're a mine that shreds the triggerer + pellet_delta += radius // so they don't count against the later total + for(var/i in 1 to radius) + pew(punishable_triggerer, TRUE) if(radius < 1) return @@ -161,18 +172,18 @@ * * Note we track anyone who's alive and client'd when they get shredded in var/list/purple_hearts, for achievement checking later */ -/datum/component/pellet_cloud/proc/handle_martyrs(mob/living/lanced_by) +/datum/component/pellet_cloud/proc/handle_martyrs(mob/living/punishable_triggerer) var/magnitude_absorbed var/list/martyrs = list() var/self_harm_radius_mult = 3 - if(lanced_by && prob(60)) - to_chat(lanced_by, "Your plan to whack someone with a grenade on a stick backfires on you, literally!") + if(punishable_triggerer && prob(60)) + to_chat(punishable_triggerer, "Your plan to whack someone with a grenade on a stick backfires on you, literally!") self_harm_radius_mult = 1 // we'll still give the guy who got hit some extra shredding, but not 3*radius pellet_delta += radius for(var/i in 1 to radius) - pew(lanced_by) // thought you could be tricky and lance someone with no ill effects!! + pew(punishable_triggerer) // thought you could be tricky and lance someone with no ill effects!! for(var/mob/living/body in get_turf(parent)) if(body == shooter) @@ -247,11 +258,11 @@ finalize() /// Minor convenience function for creating each shrapnel piece with circle explosions, mostly stolen from the MIRV component -/datum/component/pellet_cloud/proc/pew(atom/target, spread=0) +/datum/component/pellet_cloud/proc/pew(atom/target, landmine_victim) var/obj/projectile/P = new projectile_type(get_turf(parent)) //Shooting Code: - P.spread = spread + P.spread = 0 P.original = target P.fired_from = parent P.firer = parent // don't hit ourself that would be really annoying @@ -262,6 +273,8 @@ RegisterSignal(P, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PARENT_QDELETING), .proc/pellet_range) pellets += P P.fire() + if(landmine_victim) + P.process_hit(get_turf(target), target) ///All of our pellets are accounted for, time to go target by target and tell them how many things they got hit by. /datum/component/pellet_cloud/proc/finalize() @@ -274,8 +287,8 @@ var/obj/item/bodypart/hit_part if(isbodypart(target)) hit_part = target + target = hit_part.owner if(wound_info_by_part[hit_part]) - target = hit_part.owner var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] var/w_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] var/bw_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 760ac7f5fee..1336704c911 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -153,7 +153,7 @@ if(!limb) limb = C.get_bodypart() - . = payload.tryEmbed(limb) + payload.tryEmbed(limb) // at this point we've created our shrapnel baby and set them up to embed in the target, we can now die in peace as they handle their embed try on their own Detach(P) /** @@ -187,5 +187,4 @@ hit_zone = limb.body_zone C = limb.owner - checkEmbed(I, C, hit_zone, forced=TRUE) - return TRUE + return checkEmbed(I, C, hit_zone, forced=TRUE) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index d162481e66e..10d706da277 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -7,12 +7,36 @@ icon_state = "uglymine" /// We manually check to see if we've been triggered in case multiple atoms cross us in the time between the mine being triggered and it actually deleting, to avoid a race condition with multiple detonations var/triggered = FALSE + /// Can be set to FALSE if we want a short 'coming online' delay, then set to TRUE. Can still be set off by damage + var/armed = TRUE + /// If set, we default armed to FALSE and set it to TRUE after this long from initializing + var/arm_delay +/obj/effect/mine/Initialize() + . = ..() + if(arm_delay) + armed = FALSE + icon_state = "uglymine-inactive" + addtimer(CALLBACK(src, .proc/now_armed), arm_delay) + +/obj/effect/mine/examine(mob/user) + . = ..() + if(!armed) + . += "\tIt appears to be inactive..." + +/// The effect of the mine /obj/effect/mine/proc/mineEffect(mob/victim) to_chat(victim, "*click*") +/// If the landmine was previously inactive, this beeps and displays a message marking it active +/obj/effect/mine/proc/now_armed() + armed = TRUE + icon_state = "uglymine" + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 40, FALSE, -2) + visible_message("\The [src] beeps softly, indicating it is now active.", vision_distance = COMBAT_MESSAGE_RANGE) + /obj/effect/mine/Crossed(atom/movable/AM) - if(triggered || !isturf(loc)) + if(triggered || !isturf(loc) || !armed) return . = ..() @@ -25,16 +49,22 @@ . = ..() triggermine() -/obj/effect/mine/proc/triggermine(mob/victim) - if(triggered) +/// When something sets off a mine +/obj/effect/mine/proc/triggermine(atom/movable/triggerer) + if(triggered) //too busy detonating to detonate again return - visible_message("[victim] sets off [icon2html(src, viewers(src))] [src]!") + if(triggerer) + visible_message("[triggerer] sets off [icon2html(src, viewers(src))] [src]!") + else + visible_message("[icon2html(src, viewers(src))] [src] detonates!") + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(3, 1, src) s.start() - mineEffect(victim) + if(ismob(triggerer)) + mineEffect(triggerer) triggered = TRUE - SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED) + SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED, triggerer) qdel(src) /obj/effect/mine/explosive @@ -51,18 +81,6 @@ name = "stun mine" var/stun_time = 80 -/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/stun/mineEffect(mob/living/victim) if(isliving(victim)) victim.Paralyze(stun_time) @@ -197,3 +215,72 @@ sleep(duration) victim.remove_movespeed_modifier(/datum/movespeed_modifier/yellow_orb) to_chat(victim, "You slow down.") + + +/// These mines spawn pellet_clouds around them when triggered +/obj/effect/mine/shrapnel + name = "shrapnel mine" + /// The type of projectiles we're shooting out of this + var/shrapnel_type = /obj/projectile/bullet/shrapnel + /// Broadly, how many pellets we're spawning, the total is n! - (n-1)! pellets, so don't set it too high. For reference, 15 is probably pushing it at MAX + var/shrapnel_magnitude = 3 + /// If TRUE, we spawn extra pellets to eviscerate the person who stepped on it, otherwise it just spawns a ring of pellets around the tile we're on (making setting it off an offensive move) + var/shred_triggerer = FALSE + +/obj/effect/mine/shrapnel/mineEffect(mob/victim) + return + +/obj/effect/mine/shrapnel/triggermine(atom/movable/AM) + AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude) + return ..() + +/obj/effect/mine/shrapnel/sting + name = "stinger mine" + shrapnel_type = /obj/projectile/bullet/pellet/stingball + +/obj/effect/mine/shrapnel/capspawn + name = "\improper AP mine" + desc = "A defensive landmine filled with 'AP shrapnel', good for defending cramped spaces without breaching hulls. The AP stands for 'Asset Protection', though it's still plenty nasty against any fool who sets it off." + shrapnel_type = /obj/projectile/bullet/pellet/capmine + shrapnel_magnitude = 4 + shred_triggerer = TRUE + arm_delay = 3 SECONDS + light_range = 1.6 + light_power = 2 + light_color = COLOR_VIVID_RED + +/obj/effect/mine/shrapnel/capspawn/now_armed() + . = ..() + set_light_on(TRUE) + +/obj/item/minespawner + name = "landmine deployment device" + desc = "When activated, will deploy an Asset Protection landmine after 3 seconds passes, perfect for high ranking NT officers looking to cover their assets from afar." + icon = 'icons/obj/device.dmi' + icon_state = "beacon" + + var/mine_type = /obj/effect/mine/shrapnel/capspawn + var/active = FALSE + +/obj/item/minespawner/attack_self(mob/user) + . = ..() + if(active) + return + if(iscarbon(user)) + var/mob/living/carbon/user_human = user + user_human.throw_mode_on() + + playsound(src, 'sound/weapons/armbomb.ogg', 70, TRUE) + to_chat(user, "You arm \the [src], causing it to shake! It will deploy in 3 seconds.") + active = TRUE + addtimer(CALLBACK(src, .proc/deploy_mine), 3 SECONDS) + +/// Deploys the mine and deletes itself +/obj/item/minespawner/proc/deploy_mine() + do_alert_animation() + playsound(loc, 'sound/machines/chime.ogg', 30, FALSE, -3) + var/obj/effect/mine/new_mine = new mine_type(get_turf(src)) + visible_message("\The [src] releases a puff of smoke, revealing \a [new_mine]!") + var/obj/effect/particle_effect/smoke/poof = new (get_turf(src)) + poof.lifetime = 3 + qdel(src) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d0dc6475956..889e74f0c9d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -939,13 +939,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(embedding) 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. Returns a bitflag. +///In case we want to do something special (like self delete) upon failing to embed in something. /obj/item/proc/failedEmbed() if(item_flags & DROPDEL) qdel(src) - return COMPONENT_PROJECTILE_SELF_ON_HIT_SELF_DELETE - return NONE - ///Called by the carbon throw_item() proc. Returns null if the item negates the throw, or a reference to the thing to suffer the throw else. /obj/item/proc/on_thrown(mob/living/carbon/user, atom/target) @@ -962,7 +959,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb * * 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. * - * Returns bitflags informing whether the item was able to embed itself, deleted itself in the process, or nothing happened. + * Returns TRUE if it embedded successfully, nothing otherwise * * Arguments: * * target- Either a body part or a carbon. What are we hitting? @@ -975,9 +972,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb return NONE if(SEND_SIGNAL(src, COMSIG_EMBED_TRY_FORCE, target, forced, silent)) - return COMPONENT_PROJECTILE_SELF_ON_HIT_EMBED_SUCCESS - return failedEmbed() - + return COMPONENT_EMBED_SUCCESS + 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() @@ -1036,13 +1032,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb M.apply_damage(max(15, force), BRUTE, BODY_ZONE_HEAD, wound_bonus = 10, sharpness = TRUE) M.losebreath += 2 - switch(tryEmbed(M.get_bodypart(BODY_ZONE_CHEST), TRUE, TRUE)) //and if it embeds in their chest, cause a lot of pain - if(COMPONENT_PROJECTILE_SELF_ON_HIT_SELF_DELETE) - return - if(COMPONENT_PROJECTILE_SELF_ON_HIT_EMBED_SUCCESS) - M.apply_damage(max(25, force*1.5), BRUTE, BODY_ZONE_CHEST, wound_bonus = 7, sharpness = TRUE) - M.losebreath += 6 - discover_after = FALSE + if(tryEmbed(M.get_bodypart(BODY_ZONE_CHEST), TRUE, TRUE)) //and if it embeds successfully in their chest, cause a lot of pain + M.apply_damage(max(25, force*1.5), BRUTE, BODY_ZONE_CHEST, wound_bonus = 7, sharpness = TRUE) + M.losebreath += 6 + discover_after = FALSE + if(QDELETED(src)) // in case trying to embed it caused its deletion (say, if it's DROPDEL) + return if(S?.tastes?.len) //is that blood in my mouth? S.tastes += "iron" diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index a979d7cc5fc..0885fc7c34e 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -57,14 +57,6 @@ shrapnel_type = /obj/projectile/bullet/pellet/stingball/mega shrapnel_radius = 12 -/obj/item/grenade/stingbang/breaker - name = "breakbang" - shrapnel_type = /obj/projectile/bullet/pellet/stingball/breaker - -/obj/item/grenade/stingbang/shred - name = "shredbang" - shrapnel_type = /obj/projectile/bullet/pellet/stingball/shred - /obj/item/grenade/stingbang/prime(mob/living/lanced_by) if(iscarbon(loc)) var/mob/living/carbon/C = loc diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm index 2b1adaab6dd..4145dd0cbcf 100644 --- a/code/game/objects/items/shrapnel.dm +++ b/code/game/objects/items/shrapnel.dm @@ -1,6 +1,5 @@ /obj/item/shrapnel // frag grenades name = "shrapnel shard" - embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=4) custom_materials = list(/datum/material/iron=50) armour_penetration = -20 icon = 'icons/obj/shards.dmi' @@ -11,7 +10,6 @@ /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) icon_state = "tiny" sharpness = SHARP_NONE @@ -21,11 +19,12 @@ icon_state = "s-casing" embedding = null // embedding vars are taken from the projectile itself + /obj/projectile/bullet/shrapnel name = "flying shrapnel shard" damage = 14 range = 20 - armour_penetration = -30 + armour_penetration = -20 dismemberment = 5 ricochets_max = 2 ricochet_chance = 70 @@ -33,7 +32,8 @@ ricochet_incidence_leeway = 60 hit_stunned_targets = TRUE sharpness = SHARP_EDGED - wound_bonus = 40 + wound_bonus = 30 + embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=1) /obj/projectile/bullet/shrapnel/mega name = "flying shrapnel hunk" @@ -55,24 +55,37 @@ ricochet_auto_aim_angle = 10 ricochet_auto_aim_range = 2 ricochet_incidence_leeway = 0 + embed_falloff_tile = -2 shrapnel_type = /obj/item/shrapnel/stingball + embedding = list(embed_chance=55, fall_chance=2, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=3, jostle_pain_mult=3, rip_time=15) /obj/projectile/bullet/pellet/stingball/mega name = "megastingball pellet" ricochets_max = 6 ricochet_chance = 110 -/obj/projectile/bullet/pellet/stingball/breaker - name = "breakbang pellet" - damage = 10 - wound_bonus = 40 - sharpness = SHARP_NONE - -/obj/projectile/bullet/pellet/stingball/shred - name = "shredbang pellet" - damage = 10 - wound_bonus = 30 - sharpness = SHARP_EDGED - /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 + + + +/obj/projectile/bullet/pellet/capmine + name = "\improper AP shrapnel shard" + range = 7 + damage = 8 + stamina = 8 + sharpness = SHARP_EDGED + wound_bonus = 5 + bare_wound_bonus = 5 + ricochets_max = 2 + ricochet_chance = 140 + shrapnel_type = /obj/item/shrapnel/capmine + 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) + wound_falloff_tile = 0 + embed_falloff_tile = 0 + +/obj/item/shrapnel/capmine + name = "\improper AP shrapnel shard" + custom_materials = list(/datum/material/iron=50) + armour_penetration = -30 + diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index b6a80ee5197..17a2ce98c97 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -52,12 +52,13 @@ if(!L.stat) if(!L.incapacitated(ignore_restraints = 1)) L.face_atom(src) - L.do_alert_animation(L) + L.do_alert_animation() playsound(loc, 'sound/machines/chime.ogg', 50, FALSE, -5) -/mob/living/proc/do_alert_animation(atom/A) - var/image/I = image('icons/obj/closet.dmi', A, "cardboard_special", A.layer+1) - flick_overlay_view(I, A, 8) +/// Does the MGS ! animation +/atom/proc/do_alert_animation() + var/image/I = image('icons/obj/closet.dmi', src, "cardboard_special", layer+1) + flick_overlay_view(I, src, 8) I.alpha = 0 animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 460a59ae862..eec33b98bf3 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -42,9 +42,9 @@ missing -= BP.body_zone for(var/obj/item/I in BP.embedded_objects) if(I.isEmbedHarmless()) - msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!\n" + msg += "[t_He] [t_has] [icon2html(I, user)] \a [I] stuck to [t_his] [BP.name]!\n" else - msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n" + msg += "[t_He] [t_has] [icon2html(I, user)] \a [I] embedded in [t_his] [BP.name]!\n" for(var/i in BP.wounds) var/datum/wound/W = i msg += "[W.get_examine_description(user)]\n" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 9c0bc0b88f0..49ba2078bf9 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -144,9 +144,9 @@ missing -= body_part.body_zone for(var/obj/item/I in body_part.embedded_objects) if(I.isEmbedHarmless()) - msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [body_part.name]!\n" + msg += "[t_He] [t_has] [icon2html(I, user)] \a [I] stuck to [t_his] [body_part.name]!\n" else - msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [body_part.name]!\n" + msg += "[t_He] [t_has] [icon2html(I, user)] \a [I] embedded in [t_his] [body_part.name]!\n" for(var/i in body_part.wounds) var/datum/wound/iter_wound = i diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 0b8b9a0172f..fc8a73f62a4 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -373,7 +373,7 @@ ..(gibbed) /mob/living/simple_animal/hostile/proc/summon_backup(distance, exact_faction_match) - do_alert_animation(src) + do_alert_animation() playsound(loc, 'sound/machines/chime.ogg', 50, TRUE, -1) for(var/mob/living/simple_animal/hostile/M in oview(distance, targets_from)) if(faction_check_mob(M, TRUE)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 1d1c1ab9bb6..a6116729221 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -186,8 +186,10 @@ if(isliving(target)) var/mob/living/L = target hit_limb = L.check_limb_hit(def_zone) - if(SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb) & COMPONENT_PROJECTILE_SELF_ON_HIT_SELF_DELETE) - return BULLET_ACT_HIT + SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb) + + if(QDELETED(src)) // in case one of the above signals deleted the projectile for whatever reason + return var/turf/target_loca = get_turf(target) var/hitx @@ -628,10 +630,8 @@ else var/mob/living/L = target if(!direct_target) - var/checking = NONE - if(!hit_stunned_targets) - checking = MOBILITY_USE | MOBILITY_STAND | MOBILITY_MOVE - if(!(L.mobility_flags & checking) || L.stat == DEAD) // If target not able to use items, move and stand - or if they're just dead, pass over. + var/checking = MOBILITY_USE | MOBILITY_STAND | MOBILITY_MOVE + if((!hit_stunned_targets && !(L.mobility_flags & checking)) || L.stat == DEAD) // If target not able to use items, move and stand - or if they're just dead, pass over. return FALSE return TRUE diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index ae3416570eb..01ef0d25a7a 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ