diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
index 6feb378515..eab08815f3 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
@@ -227,7 +227,7 @@
/area/ruin/unpowered/xenonest)
"ba" = (
/obj/structure/stone_tile/slab,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bb" = (
/obj/structure/stone_tile/cracked{
@@ -241,7 +241,7 @@
dir = 8
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bc" = (
/obj/structure/stone_tile/block,
@@ -251,7 +251,7 @@
/obj/structure/stone_tile{
dir = 4
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bd" = (
/obj/structure/stone_tile/block,
@@ -262,7 +262,7 @@
dir = 1
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"be" = (
/obj/structure/stone_tile/block,
@@ -272,7 +272,7 @@
/obj/structure/stone_tile{
dir = 1
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bf" = (
/obj/structure/stone_tile,
@@ -286,7 +286,7 @@
dir = 4
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bg" = (
/obj/structure/alien/weeds,
@@ -303,7 +303,7 @@
/obj/structure/stone_tile{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bi" = (
/obj/structure/alien/weeds,
@@ -336,11 +336,11 @@
dir = 1
},
/obj/structure/stone_tile,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bm" = (
/obj/structure/stone_tile/slab/cracked,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bn" = (
/obj/structure/stone_tile/block{
@@ -352,7 +352,7 @@
/obj/structure/stone_tile{
dir = 4
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bo" = (
/obj/structure/stone_tile/surrounding_tile{
@@ -383,7 +383,7 @@
dir = 1
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bs" = (
/obj/structure/stone_tile/block{
@@ -416,7 +416,7 @@
dir = 1
},
/obj/structure/stone_tile/cracked,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bw" = (
/obj/structure/stone_tile/cracked{
@@ -430,7 +430,7 @@
dir = 8
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bx" = (
/obj/structure/stone_tile/block{
@@ -441,7 +441,7 @@
dir = 8
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"by" = (
/obj/structure/stone_tile/block{
@@ -451,7 +451,7 @@
/obj/structure/stone_tile/cracked{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bz" = (
/obj/structure/stone_tile/block/cracked{
@@ -461,7 +461,7 @@
/obj/structure/stone_tile{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bA" = (
/obj/structure/stone_tile/cracked{
@@ -475,7 +475,7 @@
},
/obj/structure/stone_tile,
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bB" = (
/obj/structure/alien/weeds,
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index c235dfcd10..800eee9717 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -5103,7 +5103,7 @@
/area/security/main)
"ajv" = (
/obj/machinery/computer/med_data{
- dir = 3
+ dir = 4
},
/obj/structure/sign/poster/official/medical_green_cross{
pixel_x = -32
@@ -30889,7 +30889,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"bvH" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
@@ -53711,9 +53711,6 @@
},
/turf/open/floor/mineral/titanium/blue,
/area/crew_quarters/toilet)
-"dVU" = (
-/turf/open/floor/plating,
-/area/space/nearstation)
"dXq" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
@@ -53770,7 +53767,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 6
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"egt" = (
/obj/effect/turf_decal/tile/bar,
@@ -54417,7 +54414,7 @@
"fIs" = (
/obj/structure/grille,
/obj/structure/lattice,
-/turf/open/floor/plating,
+/turf/open/space/basic,
/area/space/nearstation)
"fJY" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -54575,19 +54572,6 @@
},
/turf/open/floor/carpet,
/area/crew_quarters/cryopod)
-"ghq" = (
-/obj/structure/lattice/catwalk,
-/obj/item/stack/marker_beacon{
- anchored = 1;
- icon_state = "markerburgundy-on";
- light_color = "#FA644B";
- light_power = 3;
- light_range = 3;
- name = "Docking Beacon";
- picked_color = "Burgundy"
- },
-/turf/open/floor/plating,
-/area/space/nearstation)
"ghD" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
@@ -54744,7 +54728,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 9
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"gJi" = (
/obj/structure/lattice/catwalk,
@@ -54980,7 +54964,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 10
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"hxn" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -57361,7 +57345,7 @@
/area/crew_quarters/theatre)
"oyN" = (
/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"oyX" = (
/obj/machinery/atmospherics/components/binary/pump/on{
@@ -58206,7 +58190,7 @@
dir = 5
},
/obj/machinery/camera{
- c_tag = "Bar Backroom"
+ c_tag = "Gravity Generator - Fore"
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
@@ -58501,7 +58485,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"slk" = (
/obj/machinery/door/airlock/maintenance{
@@ -58758,9 +58742,6 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall/r_wall,
/area/engine/engine_smes)
-"sQX" = (
-/turf/open/floor/plating,
-/area/space)
"sRH" = (
/obj/machinery/autolathe/secure{
name = "public autolathe"
@@ -58877,7 +58858,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 5
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"trb" = (
/obj/machinery/light{
@@ -59100,7 +59081,7 @@
/area/hallway/primary/central)
"uaw" = (
/obj/machinery/power/apc{
- areastring = "/area/storage/art";
+ areastring = "/area/maintenance/bar";
dir = 1;
name = "Maint bar";
pixel_y = 24
@@ -59513,7 +59494,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"vbi" = (
/obj/structure/table,
@@ -60613,7 +60594,7 @@
name = "Docking Beacon";
picked_color = "Burgundy"
},
-/turf/open/space/basic,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"xOx" = (
/obj/structure/chair/comfy/brown{
@@ -66846,11 +66827,11 @@ aaa
aaa
aaa
aaa
-ghq
+xLX
aaa
aaa
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -67097,9 +67078,9 @@ aaa
aaa
aaa
aaa
-ghq
+xLX
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -67111,9 +67092,9 @@ gXs
aaa
aaa
aaa
-ghq
+xLX
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -76662,7 +76643,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -76919,7 +76900,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77176,7 +77157,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77433,7 +77414,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77690,7 +77671,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77947,7 +77928,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -78204,7 +78185,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aoV
bZm
@@ -78461,13 +78442,13 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aoV
bVz
aaf
aaf
-sQX
+aoV
aaa
aaS
aaf
@@ -78718,7 +78699,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aag
bVz
@@ -78975,7 +78956,7 @@ aaa
aaa
aaa
aaa
-aag
+gJi
aaa
aaf
bVz
@@ -79232,7 +79213,7 @@ aaa
aaa
aaa
aaa
-aag
+gJi
aaa
aaf
bVz
@@ -84282,7 +84263,7 @@ aaa
aaa
gXs
gXs
-dVU
+aaH
abc
abu
abu
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 1bf9b01403..6a60768875 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -154,9 +154,10 @@
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
-//for the shove slowdown, see __DEFINES/movespeed_modification.dm
-#define SHOVE_SLOWDOWN_LENGTH 30
-#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
+/// how long they're staggered for
+#define SHOVE_STAGGER_DURATION 35
+/// how long they're off balance for
+#define SHOVE_OFFBALANCE_DURATION 30
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 699f39e79f..5e7d0a2cca 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -63,7 +63,6 @@
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
-#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_FAT "FAT"
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 14cc7c9e5e..9a3b5d55f4 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -111,6 +111,9 @@
#define STATUS_EFFECT_LIMP /datum/status_effect/limp //For when you have a busted leg (or two!) and want additional slowdown when walking on that leg
+/// shoves inflict this to indicate the next shove while this is in effect should disarm guns
+#define STATUS_EFFECT_OFF_BALANCE /datum/status_effect/off_balance
+
/////////////
// NEUTRAL //
/////////////
diff --git a/code/datums/components/killerqueen.dm b/code/datums/components/killerqueen.dm
new file mode 100644
index 0000000000..1c660d0a87
--- /dev/null
+++ b/code/datums/components/killerqueen.dm
@@ -0,0 +1,91 @@
+/**
+ * KILLER QUEEN
+ *
+ * Simple contact bomb component
+ * Blows up the first person to touch it.
+ */
+/datum/component/killerqueen
+ can_transfer = TRUE
+ /// strength of explosion on the touch-er. 0 to disable. usually only used if the normal explosion is disabled (this is the default).
+ var/ex_strength = EXPLODE_HEAVY
+ /// callback to invoke with (parent, victim) before standard detonation - useful for losing a reference to this component or implementing custom behavior. return FALSE to prevent explosion.
+ var/datum/callback/pre_explode
+ /// callback to invoke with (parent) when deleting without an explosion
+ var/datum/callback/failure
+ /// did we explode
+ var/exploded = FALSE
+ /// examine message
+ var/examine_message
+ /// light explosion radius
+ var/light = 0
+ /// heavy explosion radius
+ var/heavy = 0
+ /// dev explosion radius
+ var/dev = 0
+ /// flame explosion radius
+ var/flame = 0
+ /// only triggered by living mobs
+ var/living_only = TRUE
+
+
+/datum/component/killerqueen/Initialize(ex_strength = EXPLODE_HEAVY, datum/callback/pre_explode, datum/callback/failure, examine_message, light = 0, heavy = 0, dev = 0, flame = 0, living_only = TRUE)
+ . = ..()
+ if(. & COMPONENT_INCOMPATIBLE)
+ return
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ src.ex_strength = ex_strength
+ src.pre_explode = pre_explode
+ src.failure = failure
+ src.examine_message = examine_message
+ src.light = light
+ src.heavy = heavy
+ src.dev = dev
+ src.flame = flame
+ src.living_only = living_only
+
+/datum/component/killerqueen/Destroy()
+ if(!exploded)
+ failure?.Invoke(parent)
+ return ..()
+
+/datum/component/killerqueen/RegisterWithParent()
+ . = ..()
+ RegisterSignal(parent, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_ATOM_ATTACK_ANIMAL), .proc/touch_detonate)
+ RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/bump_detonate)
+ RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby_detonate)
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+
+/datum/component/killerqueen/UnregisterFromParent()
+ . = ..()
+ UnregisterSignal(parent, list(COMSIG_ATOM_ATTACK_ANIMAL, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW,
+ COMSIG_MOVABLE_BUMP, COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE))
+
+/datum/component/killerqueen/proc/attackby_detonate(datum/source, obj/item/I, mob/user)
+ detonate(user)
+
+/datum/component/killerqueen/proc/bump_detonate(datum/source, atom/A)
+ detonate(A)
+
+/datum/component/killerqueen/proc/touch_detonate(datum/source, mob/user)
+ detonate(user)
+
+/datum/component/killerqueen/proc/on_examine(datum/source, mob/examiner, list/examine_return)
+ if(examine_message)
+ examine_return += examine_message
+
+/datum/component/killerqueen/proc/detonate(atom/victim)
+ if(!isliving(victim) && living_only)
+ return
+ if(pre_explode && !pre_explode.Invoke(parent, victim))
+ return
+ if(ex_strength)
+ victim.ex_act(ex_strength)
+ if(light || heavy || dev || flame)
+ explosion(parent, dev, heavy, light, flame_range = flame)
+ else
+ var/turf/T = get_turf(parent)
+ playsound(T, 'sound/effects/explosion2.ogg', 200, 1)
+ new /obj/effect/temp_visual/explosion(T)
+ exploded = TRUE
+ qdel(src)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index c813f982c8..93a9369a4d 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -97,6 +97,21 @@
duration = set_duration
return ..()
+/datum/status_effect/off_balance
+ id = "offbalance"
+ alert_type = null
+
+/datum/status_effect/off_balance/on_creation(mob/living/new_owner, set_duration)
+ if(isnum(set_duration))
+ duration = set_duration
+ return ..()
+
+/datum/status_effect/off_balance/on_remove()
+ var/active_item = owner.get_active_held_item()
+ if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
+ owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
+ return ..()
+
/obj/screen/alert/status_effect/asleep
name = "Asleep"
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 746bd3458a..49256b490d 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -257,10 +257,8 @@
if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed)
to_chat(our_guy, "You stumble a bit on your untied shoelaces!")
- if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove)
- addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
-
+ our_guy.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
+ our_guy.Stagger(SHOVE_OFFBALANCE_DURATION) //yes, same.
if(26 to 1000)
wiser = FALSE
if(wiser)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f788ff383a..49dda71fc7 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1041,12 +1041,6 @@
return TRUE
return FALSE
-/mob/living/carbon/human/proc/clear_shove_slowdown()
- remove_movespeed_modifier(/datum/movespeed_modifier/shove)
- var/active_item = get_active_held_item()
- if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
- visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
-
/mob/living/carbon/human/updatehealth()
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index ff60c96a73..bac060ec0e 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1944,11 +1944,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.visible_message("[user.name] shoves [target.name]!",
"[user.name] shoves you!", null, COMBAT_MESSAGE_RANGE, null,
user, "You shove [target.name]!")
+ target.Stagger(SHOVE_STAGGER_DURATION)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
- if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
+ if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!",
@@ -1956,12 +1956,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
- addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("[target.name] drops \the [target_held_item]!!",
"You drop \the [target_held_item]!!", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
+ target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index 4e6923615d..26e5d791f3 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -36,60 +36,21 @@
return
if(isobj(A) && Adjacent(A))
if(bomb_cooldown <= world.time && !stat)
- var/obj/guardian_bomb/B = new /obj/guardian_bomb(get_turf(A))
+ var/datum/component/killerqueen/K = A.AddComponent(/datum/component/killerqueen, EXPLODE_HEAVY, CALLBACK(src, .proc/on_explode), CALLBACK(src, .proc/on_failure), \
+ examine_message = "It glows with a strange light!")
+ QDEL_IN(K, 1 MINUTES)
to_chat(src, "Success! Bomb armed!")
bomb_cooldown = world.time + 200
- B.spawner = src
- B.disguise(A)
else
to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.")
-/obj/guardian_bomb
- name = "bomb"
- desc = "You shouldn't be seeing this!"
- var/obj/stored_obj
- var/mob/living/simple_animal/hostile/guardian/spawner
+/mob/living/simple_animal/hostile/guardian/bomb/proc/on_explode(atom/bomb, atom/victim)
+ if((victim == src) || (victim == summoner) || (hasmatchingsummoner(victim)))
+ to_chat(victim, "[src] glows with a strange light, and you don't touch it.")
+ return FALSE
+ to_chat(src, "One of your explosive traps caught [victim]!")
+ to_chat(victim, "[bomb] was boobytrapped!")
+ return TRUE
-
-/obj/guardian_bomb/proc/disguise(obj/A)
- A.forceMove(src)
- stored_obj = A
- opacity = A.opacity
- anchored = A.anchored
- density = A.density
- appearance = A.appearance
- addtimer(CALLBACK(src, .proc/disable), 600)
-
-/obj/guardian_bomb/proc/disable()
- stored_obj.forceMove(get_turf(src))
- to_chat(spawner, "Failure! Your trap didn't catch anyone this time.")
- qdel(src)
-
-/obj/guardian_bomb/proc/detonate(mob/living/user)
- if(isliving(user))
- if(user != spawner && user != spawner.summoner && !spawner.hasmatchingsummoner(user))
- to_chat(user, "[src] was boobytrapped!")
- to_chat(spawner, "Success! Your trap caught [user]")
- var/turf/T = get_turf(src)
- stored_obj.forceMove(T)
- playsound(T,'sound/effects/explosion2.ogg', 200, 1)
- new /obj/effect/temp_visual/explosion(T)
- user.ex_act(EXPLODE_HEAVY)
- qdel(src)
- else
- to_chat(user, "[src] glows with a strange light, and you don't touch it.")
-
-/obj/guardian_bomb/Bump(atom/A)
- detonate(A)
- ..()
-
-/obj/guardian_bomb/attackby(mob/living/user)
- detonate(user)
-
-/obj/guardian_bomb/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
- detonate(user)
-
-/obj/guardian_bomb/examine(mob/user)
- . = stored_obj.examine(user)
- if(get_dist(user,src)<=2)
- . += "It glows with a strange light!"
+/mob/living/simple_animal/hostile/guardian/bomb/proc/on_failure(atom/bomb)
+ to_chat(src, "Failure! Your trap didn't catch anyone this time.")
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 0029300936..87fd0cf609 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -500,6 +500,15 @@
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
return S
+///////////////////////////////// OFF BALANCE/SHOVIES ////////////////////////
+/mob/living/proc/ShoveOffBalance(amount)
+ var/datum/status_effect/off_balance/B = has_status_effect(STATUS_EFFECT_OFF_BALANCE)
+ if(B)
+ B.duration = max(world.time + amount, B.duration)
+ else if(amount > 0)
+ B = apply_status_effect(STATUS_EFFECT_OFF_BALANCE, amount)
+ return B
+
///////////////////////////////// FROZEN /////////////////////////////////////
/mob/living/proc/IsFrozen()
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
index a2176ca95e..d17767bb1f 100644
--- a/code/modules/movespeed/modifiers/mobs.dm
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -78,9 +78,6 @@
blacklisted_movetypes = FLOATING
variable = TRUE
-/datum/movespeed_modifier/shove
- multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
-
/datum/movespeed_modifier/human_carry
variable = TRUE
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 64fe786219..ba4870903e 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -375,7 +375,6 @@
log_combat(user, target, "shoved", "into [src] (disposal bin)")
return TRUE
-
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE
diff --git a/html/changelogs/AutoChangeLog-pr-12925.yml b/html/changelogs/AutoChangeLog-pr-12925.yml
new file mode 100644
index 0000000000..5e38656352
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12925.yml
@@ -0,0 +1,5 @@
+author: "silicons"
+delete-after: True
+changes:
+ - rscadd: "shoves have been buffed to apply a status effect rather than a 0.85 movespeed modifier, meaning repeatedly shoving someone now renews the debuff"
+ - balance: "shoves now stagger for 3.5 seconds."
diff --git a/html/changelogs/AutoChangeLog-pr-12954.yml b/html/changelogs/AutoChangeLog-pr-12954.yml
new file mode 100644
index 0000000000..0b28e94936
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12954.yml
@@ -0,0 +1,5 @@
+author: "silicons"
+delete-after: True
+changes:
+ - balance: "explosive stand bombs can now be examined from any distance"
+ - code_imp: "explosive stand bombs are now a component."
diff --git a/html/changelogs/AutoChangeLog-pr-12989.yml b/html/changelogs/AutoChangeLog-pr-12989.yml
new file mode 100644
index 0000000000..6b0c2229af
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12989.yml
@@ -0,0 +1,4 @@
+author: "dapnee"
+delete-after: True
+changes:
+ - bugfix: "active turfs on box and xenohive, maintenance bar APC not being stringed correctly, turned a monitor to face a direction that makes sense, changed tag of camera in gravgen being misnamed"
diff --git a/tgstation.dme b/tgstation.dme
index 1eb5534e45..77530bbbfc 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -433,6 +433,7 @@
#include "code\datums\components\igniter.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
+#include "code\datums\components\killerqueen.dm"
#include "code\datums\components\knockback.dm"
#include "code\datums\components\knockoff.dm"
#include "code\datums\components\lifesteal.dm"