From 34f1f2466732a8eb35a3e7aa8997cc29358696aa Mon Sep 17 00:00:00 2001 From: forest2001 <41653574+realforest2001@users.noreply.github.com> Date: Fri, 4 Aug 2023 06:13:26 +0100 Subject: [PATCH] Admin Flag for Disposal mobs (#3814) # About the pull request Allows admins to toggle a flag as to whether mobs will fit inside disposals tubes. # Explain why it's good for the game Regarding disposal tubes, there are some situations where I can see it being fitting to the situation, and this will also allow a measured level of return for a feature we had to remove due to abuse. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: add: Added an admin toggle flag for fitting mobs into disposals. (Within reason - no queens...) add: The Crawler trait that allows mobs to enter vents will also allow them to climb into disposals regardless of above flag. add: Added a subtype of disposal that can't fit mobs, used for the delivery units. /:cl: --- code/__DEFINES/mode.dm | 1 + code/_globalvars/bitfields.dm | 1 + code/modules/admin/admin_verbs.dm | 1 + code/modules/admin/tabs/admin_tab.dm | 14 +++ code/modules/recycling/disposal.dm | 112 +++++++++++++-------- maps/map_files/USS_Almayer/USS_Almayer.dmm | 6 +- 6 files changed, 89 insertions(+), 46 deletions(-) diff --git a/code/__DEFINES/mode.dm b/code/__DEFINES/mode.dm index 2895b3211fd3..32a292d0d8cc 100644 --- a/code/__DEFINES/mode.dm +++ b/code/__DEFINES/mode.dm @@ -70,6 +70,7 @@ #define MODE_LZ_PROTECTION (1<<7) /// Prevents the LZ from being mortared #define MODE_SHIPSIDE_SD (1<<8) /// Toggles whether Predators can big SD when not on the groundmap #define MODE_HARDCORE_PERMA (1<<9) /// Toggles Hardcore for all marines, meaning they instantly perma upon death +#define MODE_DISPOSABLE_MOBS (1<<10) // Toggles if mobs fit in disposals or not. Off by default. #define ROUNDSTATUS_FOG_DOWN 1 #define ROUNDSTATUS_PODDOORS_OPEN 2 diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index ef539b8459c7..4936609d892e 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -415,6 +415,7 @@ DEFINE_BITFIELD(toggleable_flags, list( "MODE_NO_COMBAT_CAS" = MODE_NO_COMBAT_CAS, "MODE_LZ_PROTECTION" = MODE_LZ_PROTECTION, "MODE_SHIPSIDE_SD" = MODE_SHIPSIDE_SD, + "MODE_DISPOSABLE_MOBS" = MODE_DISPOSABLE_MOBS, )) DEFINE_BITFIELD(state, list( diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 20ff65ed144e..de884cfebe61 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -121,6 +121,7 @@ var/list/admin_verbs_minor_event = list( /client/proc/toggle_sniper_upgrade, /client/proc/toggle_attack_dead, /client/proc/toggle_strip_drag, + /client/proc/toggle_disposal_mobs, /client/proc/toggle_uniform_strip, /client/proc/toggle_strong_defibs, /client/proc/toggle_blood_optimization, diff --git a/code/modules/admin/tabs/admin_tab.dm b/code/modules/admin/tabs/admin_tab.dm index a2f3bd42df5f..6dc08c63e5de 100644 --- a/code/modules/admin/tabs/admin_tab.dm +++ b/code/modules/admin/tabs/admin_tab.dm @@ -708,6 +708,20 @@ SSticker.mode.toggleable_flags ^= MODE_NO_ATTACK_DEAD message_admins("[src] has [MODE_HAS_TOGGLEABLE_FLAG(MODE_NO_ATTACK_DEAD) ? "prevented dead mobs from being" : "allowed dead mobs to be"] attacked.") +/client/proc/toggle_disposal_mobs() + set name = "Toggle Disposable Mobs" + set category = "Admin.Flags" + + if(!admin_holder || !check_rights(R_EVENT, FALSE)) + return + + if(!SSticker.mode) + to_chat(usr, SPAN_WARNING("A mode hasn't been selected yet!")) + return + + SSticker.mode.toggleable_flags ^= MODE_DISPOSABLE_MOBS + message_admins("[src] has [MODE_HAS_TOGGLEABLE_FLAG(MODE_DISPOSABLE_MOBS) ? "allowed mobs to fit" : "prevented mobs fitting"] inside disposals.") + /client/proc/toggle_strip_drag() set name = "Toggle Strip/Drag Dead" set category = "Admin.Flags" diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 8a5a6ec960ec..2c7401ac278c 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -37,6 +37,13 @@ active_power_usage = 3500 idle_power_usage = 100 var/disposal_pressure = 0 + ///Whether the disposals tube is too narrow for a mob to fit into. + var/narrow_tube = FALSE + +/obj/structure/machinery/disposal/delivery + name = "delivery chute" + desc = "A pneumatic delivery unit connecting two locations. It's rather narrow." + narrow_tube = TRUE /obj/structure/machinery/disposal/broken name = "broken disposal unit" @@ -128,24 +135,42 @@ update() return - var/obj/item/grab/G = I - if(istype(G)) //Handle grabbed mob - if(ismob(G.grabbed_thing)) - to_chat(user, SPAN_WARNING("You can't fit that in there!")) - return - /*&& user.grab_level >= GRAB_AGGRESSIVE) - var/mob/GM = G.grabbed_thing - user.visible_message(SPAN_WARNING("[user] starts putting [GM] into [src]."), - SPAN_WARNING("You start putting [GM] into [src].")) - if(do_after(user, 20, INTERRUPT_ALL, BUSY_ICON_HOSTILE)) - GM.forceMove(src) - user.visible_message(SPAN_WARNING("[user] puts [GM] into [src]."), - SPAN_WARNING("[user] puts [GM] into [src].")) - user.attack_log += text("\[[time_stamp()]\] Has placed [GM] ([GM.ckey]) in disposals.") - GM.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [user] ([user.ckey])") - msg_admin_attack("[user] ([user.ckey]) placed [GM] ([GM.ckey]) in a disposals unit in [get_area(user)] ([user.loc.x],[user.loc.y],[user.loc.z]).", user.loc.x, user.loc.y, user.loc.z) - flush()*/ - return + var/obj/item/grab/grab_effect = I + if(istype(grab_effect)) //Handle grabbed mob + if(ismob(grab_effect.grabbed_thing)) + var/mob/grabbed_mob = grab_effect.grabbed_thing + if((!MODE_HAS_TOGGLEABLE_FLAG(MODE_DISPOSABLE_MOBS) && !HAS_TRAIT(grabbed_mob, TRAIT_CRAWLER)) || narrow_tube || grabbed_mob.mob_size >= MOB_SIZE_BIG) + to_chat(user, SPAN_WARNING("You can't fit that in there!")) + return FALSE + var/max_grab_size = user.mob_size + /// Amazing what you can do with a bit of dexterity. + if(HAS_TRAIT(user, TRAIT_DEXTROUS)) + max_grab_size++ + /// Strong mobs can lift above their own weight. + if(HAS_TRAIT(user, TRAIT_SUPER_STRONG))//NB; this will mean Yautja can bodily lift MOB_SIZE_XENO(3) and Synths can lift MOB_SIZE_XENO_SMALL(2) + max_grab_size++ + if(grabbed_mob.mob_size > max_grab_size || !(grabbed_mob.status_flags & CANPUSH)) + to_chat(user, SPAN_WARNING("You don't have the strength to move [grabbed_mob]!")) + return FALSE//can't tighten your grip on mobs bigger than you and mobs you can't push. + if(!user.grab_level >= GRAB_AGGRESSIVE) + to_chat(user, SPAN_WARNING("You need a better grip to force [grabbed_mob] in there!")) + return FALSE + user.visible_message(SPAN_WARNING("[user] starts putting [grabbed_mob] into [src]."), + SPAN_WARNING("You start putting [grabbed_mob] into [src].")) + if(!do_after(user, 2 SECONDS, INTERRUPT_ALL, BUSY_ICON_HOSTILE)) + user.visible_message(SPAN_WARNING("[user] stops putting [grabbed_mob] into [src]."), + SPAN_WARNING("You stop putting [grabbed_mob] into [src].")) + return FALSE + + grabbed_mob.forceMove(src) + user.visible_message(SPAN_WARNING("[user] puts [grabbed_mob] into [src]."), + SPAN_WARNING("[user] puts [grabbed_mob] into [src].")) + user.attack_log += text("\[[time_stamp()]\] Has placed [key_name(grabbed_mob)] in disposals.") + grabbed_mob.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [user] ([user.ckey])") + msg_admin_attack("[user] ([user.ckey]) placed [key_name(grabbed_mob)] in a disposals unit in [get_area(user)] ([user.loc.x],[user.loc.y],[user.loc.z]).", user.loc.x, user.loc.y, user.loc.z) + flush(TRUE)//Forcibly flushing someone if forced in by another player. + return TRUE + return FALSE if(isrobot(user)) return @@ -161,51 +186,50 @@ ///Mouse drop another mob or self /obj/structure/machinery/disposal/MouseDrop_T(mob/target, mob/user) - return -/* - if(!istype(target) || target.anchored || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.is_mob_incapacitated(TRUE) || isRemoteControlling(user) || target.mob_size >= MOB_SIZE_BIG) - return - if(!(ishuman(target)) || !(ishuman(user))) return - if(isanimal(user) && target != user) return //Animals cannot put mobs other than themselves into disposal + if((!MODE_HAS_TOGGLEABLE_FLAG(MODE_DISPOSABLE_MOBS) && !HAS_TRAIT(user, TRAIT_CRAWLER)) || narrow_tube) + to_chat(user, SPAN_WARNING("Looks a little bit too tight in there!")) + return FALSE + + if(target != user) + to_chat(user, SPAN_WARNING("You need a better grip on [target] to force them into [src]!")) + return FALSE //Need a firm grip to put someone else in there. + + if(!istype(target) || target.anchored || target.buckled || get_dist(user, src) > 1 || user.is_mob_incapacitated(TRUE) || isRemoteControlling(user) || target.mob_size >= MOB_SIZE_BIG) + to_chat(user, SPAN_WARNING("You cannot get into the [src]!")) + return FALSE add_fingerprint(user) var/target_loc = target.loc if(target == user) visible_message(SPAN_NOTICE("[user] starts climbing into the disposal.")) - else - if(user.is_mob_restrained()) return //can't stuff someone other than you if restrained. - visible_message(SPAN_WARNING("[user] starts stuffing [target] into the disposal.")) + if(!do_after(user, 40, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) - return + return FALSE if(target_loc != target.loc) - return + return FALSE + if(user.is_mob_incapacitated(TRUE)) + to_chat(user, SPAN_WARNING("You cannot do this while incapacitated!")) + return FALSE + if(target == user) - if(user.is_mob_incapacitated(TRUE)) return user.visible_message(SPAN_NOTICE("[user] climbs into [src]."), SPAN_NOTICE("You climb into [src].")) - else - if(user.is_mob_incapacitated()) return - user.visible_message(SPAN_DANGER("[user] stuffs [target] into [src]!"), - SPAN_WARNING("You stuff [target] into [src]!")) - - user.attack_log += text("\[[time_stamp()]\] Has placed [target.name] ([target.ckey]) in disposals.") - target.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [user.name] ([user.ckey])") - msg_admin_attack("[user] ([user.ckey]) placed [target] ([target.ckey]) in a disposals unit in [get_area(user)] ([user.loc.x],[user.loc.y],[user.loc.z]).", user.loc.x, user.loc.y, user.loc.z) + user.attack_log += text("\[[time_stamp()]\] [key_name(user)] climbed into a disposals bin!") target.forceMove(src) - flush() - update()*/ + flush()//Not forcing flush if climbing in by self. + update() ///Attempt to move while inside /obj/structure/machinery/disposal/relaymove(mob/user) if(user.stat || user.stunned || user.knocked_down || flushing) - return + return FALSE if(user.loc == src) go_out(user) + return TRUE ///Leave the disposal /obj/structure/machinery/disposal/proc/go_out(mob/user) - if(user.client) user.client.eye = user.client.mob user.client.perspective = MOB_PERSPECTIVE @@ -364,7 +388,9 @@ return ///Perform a flush -/obj/structure/machinery/disposal/proc/flush() +/obj/structure/machinery/disposal/proc/flush(forced = FALSE) + if((disposal_pressure < SEND_PRESSURE) && !forced) + return FALSE flushing = TRUE flick("[icon_state]-flush", src) diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index 741b511792b1..ce4a853acc62 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -5011,7 +5011,7 @@ /obj/structure/disposalpipe/trunk{ dir = 1 }, -/obj/structure/machinery/disposal{ +/obj/structure/machinery/disposal/delivery{ density = 0; desc = "A pneumatic delivery unit. Sends items to the requisitions."; icon_state = "delivery_engi"; @@ -76155,12 +76155,12 @@ /obj/structure/disposalpipe/trunk{ dir = 1 }, -/obj/structure/machinery/disposal{ +/obj/structure/machinery/disposal/delivery{ density = 0; desc = "A pneumatic delivery unit. Sends items to the requisitions."; icon_state = "delivery_med"; name = "Requisitions Delivery Unit"; - pixel_y = 29 + pixel_y = 28 }, /turf/open/floor/almayer{ icon_state = "mono"