diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 65b9c3a7c10..c5bae131c37 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -684,6 +684,9 @@ #define COMSIG_CARBON_HUGGED "carbon_hugged" ///When a carbon mob is headpatted, this is called on the carbon that is headpatted. (mob/living/headpatter) #define COMSIG_CARBON_HEADPAT "carbon_headpatted" +///When a carbon mob is disarmed, this is called on objects that have unique behavior when the target is shoved into it (obj/structure/table, obj/machinery/disposal/bin) +#define COMSIG_CARBON_DISARM_COLLIDE "carbon_disarm_collision" + #define COMSIG_CARBON_SHOVE_HANDLED (1<<0) ///When a carbon slips. Called on /turf/open/handle_slip() #define COMSIG_ON_CARBON_SLIP "carbon_slip" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 58faca0bfe1..216a180863f 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -74,6 +74,7 @@ . = ..() update_appearance() PopulateContents() + RegisterSignal(src, COMSIG_CARBON_DISARM_COLLIDE, .proc/locker_carbon) //USE THIS TO FILL IT, NOT INITIALIZE OR NEW /obj/structure/closet/proc/PopulateContents() @@ -326,7 +327,9 @@ /obj/structure/closet/proc/after_close(mob/living/user) return - +/** + * Toggles a closet open or closed, to the opposite state. Does not respect locked or welded states, however. + */ /obj/structure/closet/proc/toggle(mob/living/user) if(opened) return close(user) @@ -676,4 +679,19 @@ /obj/structure/closet/return_temperature() return +/obj/structure/closet/proc/locker_carbon(obj/structure/closet/closet, mob/living/carbon/shover, mob/living/carbon/target) + SIGNAL_HANDLER + if(opened) + target.forceMove(src) + if(!(locked || welded)) + toggle() + update_icon() + target.visible_message(span_danger("[shover.name] shoves [target.name] into \the [src]!"), + span_userdanger("You're shoved into \the [src] by [target.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) + to_chat(src, span_danger("You shove [target.name] into \the [src]!")) + log_combat(src, target, "shoved", "into [src] (locker/crate)") + if(locked || welded) + return + return COMSIG_CARBON_SHOVE_HANDLED + #undef LOCKER_FULL diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 7e9c563f0bc..4a67b9e3d54 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -41,6 +41,7 @@ if(_buildstack) buildstack = _buildstack AddElement(/datum/element/climbable) + RegisterSignal(src, COMSIG_CARBON_DISARM_COLLIDE, .proc/table_carbon) /obj/structure/table/examine(mob/user) . = ..() @@ -258,6 +259,15 @@ return TRUE return FALSE +/obj/structure/table/proc/table_carbon(obj/structure/table/the_table, mob/living/carbon/shover, mob/living/carbon/target) + SIGNAL_HANDLER + target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [the_table]!"), + span_userdanger("You're shoved onto \the [the_table] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) + to_chat(shover, span_danger("You shove [target.name] onto \the [the_table]!")) + target.throw_at(src, 1, 1, null, FALSE) //1 speed throws with no spin are basically just forcemoves with a hard collision check + log_combat(src, target, "shoved", "onto [the_table] (table)") + return COMSIG_CARBON_SHOVE_HANDLED /obj/structure/table/greyscale icon = 'icons/obj/smooth_structures/table_greyscale.dmi' diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 7aa747b87f9..70daf543522 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -8,6 +8,8 @@ ADD_TRAIT(src, TRAIT_AGEUSIA, NO_TONGUE_TRAIT) GLOB.carbon_list += src + RegisterSignal(src, COMSIG_LIVING_DEATH, .proc/attach_rot) + RegisterSignal(src, COMSIG_CARBON_DISARM_COLLIDE, .proc/disarm_collision) /mob/living/carbon/Destroy() //This must be done first, so the mob ghosts correctly before DNA etc is nulled @@ -1291,3 +1293,14 @@ /mob/living/carbon/proc/attach_rot() if(mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)) AddComponent(/datum/component/rot, 6 MINUTES, 10 MINUTES, 1) + +/mob/living/carbon/proc/disarm_collision(mob/living/carbon/collateral, mob/living/carbon/shover, mob/living/carbon/target) + SIGNAL_HANDLER + target.Knockdown(SHOVE_KNOCKDOWN_HUMAN) + if(!collateral.is_shove_knockdown_blocked()) + collateral.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL) + target.visible_message(span_danger("[shover] shoves [target.name] into [collateral.name]!"), + span_userdanger("You're shoved into [collateral.name] by [shover]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) + to_chat(src, span_danger("You shove [target.name] into [collateral.name]!")) + log_combat(src, target, "shoved", "into [collateral.name]") + return COMSIG_CARBON_SHOVE_HANDLED diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 533069bb80d..85f14725092 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -258,10 +258,16 @@ var/shove_dir = get_dir(loc, target_oldturf) var/turf/target_shove_turf = get_step(target.loc, shove_dir) var/mob/living/carbon/target_collateral_carbon - var/obj/structure/table/target_table - var/obj/machinery/disposal/bin/target_disposal_bin var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied - + var/handled = FALSE + for(var/atom/movable/every_single_thing_but_target as anything in target_shove_turf.contents - target) + if(SEND_SIGNAL(every_single_thing_but_target, COMSIG_CARBON_DISARM_COLLIDE, src, target) & COMSIG_CARBON_SHOVE_HANDLED) + handled = TRUE + break + if(!handled) + SEND_SIGNAL(target, COMSIG_CARBON_DISARM_COLLIDE, src, target) + if(handled) + return //We are using an object's disarm collision reaction instead of base disarm reactions. //Thank you based whoneedsspace target_collateral_carbon = locate(/mob/living/carbon) in target_shove_turf.contents @@ -274,8 +280,6 @@ else target.Move(target_shove_turf, shove_dir) if(get_turf(target) == target_oldturf) - target_table = locate(/obj/structure/table) in target_shove_turf.contents - target_disposal_bin = locate(/obj/machinery/disposal/bin) in target_shove_turf.contents shove_blocked = TRUE if(target.IsKnockdown() && !target.IsParalyzed()) @@ -299,34 +303,12 @@ if(obj_content.flags_1 & ON_BORDER_1 && obj_content.dir == turn(shove_dir, 180) && obj_content.density) directional_blocked = TRUE break - if((!target_table && !target_collateral_carbon && !target_disposal_bin) || directional_blocked) + if((!target_collateral_carbon) || directional_blocked) target.Knockdown(SHOVE_KNOCKDOWN_SOLID) target.visible_message(span_danger("[name] shoves [target.name], knocking [target.p_them()] down!"), span_userdanger("You're knocked down from a shove by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) to_chat(src, span_danger("You shove [target.name], knocking [target.p_them()] down!")) log_combat(src, target, "shoved", "knocking them down") - else if(target_table) - target.Knockdown(SHOVE_KNOCKDOWN_TABLE) - target.visible_message(span_danger("[name] shoves [target.name] onto \the [target_table]!"), - span_userdanger("You're shoved onto \the [target_table] by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) - to_chat(src, span_danger("You shove [target.name] onto \the [target_table]!")) - target.throw_at(target_table, 1, 1, null, FALSE) //1 speed throws with no spin are basically just forcemoves with a hard collision check - log_combat(src, target, "shoved", "onto [target_table] (table)") - else if(target_collateral_carbon) - target.Knockdown(SHOVE_KNOCKDOWN_HUMAN) - if(!target_collateral_carbon.is_shove_knockdown_blocked()) - target_collateral_carbon.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL) - target.visible_message(span_danger("[name] shoves [target.name] into [target_collateral_carbon.name]!"), - span_userdanger("You're shoved into [target_collateral_carbon.name] by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) - to_chat(src, span_danger("You shove [target.name] into [target_collateral_carbon.name]!")) - log_combat(src, target, "shoved", "into [target_collateral_carbon.name]") - else if(target_disposal_bin) - target.Knockdown(SHOVE_KNOCKDOWN_SOLID) - target.forceMove(target_disposal_bin) - target.visible_message(span_danger("[name] shoves [target.name] into \the [target_disposal_bin]!"), - span_userdanger("You're shoved into \the [target_disposal_bin] by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) - to_chat(src, span_danger("You shove [target.name] into \the [target_disposal_bin]!")) - log_combat(src, target, "shoved", "into [target_disposal_bin] (disposal bin)") else target.visible_message(span_danger("[name] shoves [target.name]!"), span_userdanger("You're shoved by [name]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, src) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index b2dac725c63..b4aab279237 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -41,6 +41,7 @@ //gas.volume = 1.05 * CELLSTANDARD update_appearance() RegisterSignal(src, COMSIG_RAT_INTERACT, .proc/on_rat_rummage) + RegisterSignal(src, COMSIG_CARBON_DISARM_COLLIDE, .proc/trash_carbon) return INITIALIZE_HINT_LATELOAD //we need turfs to have air @@ -526,3 +527,12 @@ INVOKE_ASYNC(src, /obj/machinery/disposal/.proc/rat_rummage, king) +/obj/machinery/disposal/proc/trash_carbon(obj/machinery/disposal/binny, mob/living/carbon/shover, mob/living/carbon/target) + SIGNAL_HANDLER + target.Knockdown(SHOVE_KNOCKDOWN_SOLID) + target.forceMove(binny) + target.visible_message(span_danger("[shover.name] shoves [target.name] into \the [binny]!"), + span_userdanger("You're shoved into \the [binny] by [target.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, binny) + to_chat(binny, span_danger("You shove [target.name] into \the [binny]!")) + log_combat(binny, target, "shoved", "into [binny] (disposal bin)") + return COMSIG_CARBON_SHOVE_HANDLED