diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index f619e9aa9bd..3e3e1696e61 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -57,6 +57,9 @@ W.plane = initial(W.plane) W.loc = affected_mob.loc W.dropped(affected_mob) + if(isobj(affected_mob.loc)) + var/obj/O = affected_mob.loc + O.force_eject_occupant() var/mob/living/new_mob = new new_form(affected_mob.loc) if(istype(new_mob)) new_mob.a_intent = "harm" diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index fb0ccff32cb..d887153c6d5 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -282,6 +282,9 @@ occupant = null icon_state = "scanner_open" +/obj/machinery/dna_scannernew/force_eject_occupant() + go_out(null, TRUE) + /obj/machinery/dna_scannernew/ex_act(severity) if(occupant) occupant.ex_act(severity) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index e4d0befa61e..7c5a03e29e6 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -411,6 +411,9 @@ for(var/atom/movable/A in contents - component_parts - list(beaker)) A.forceMove(loc) +/obj/machinery/sleeper/force_eject_occupant() + go_out() + /obj/machinery/sleeper/proc/inject_chemical(mob/living/user as mob, chemical, amount) if(!(chemical in possible_chems)) to_chat(user, "The sleeper does not offer that chemical!") diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 1ee30b6e9d0..3fa78dd02e6 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -172,6 +172,9 @@ for(var/atom/movable/A in contents - component_parts) A.forceMove(loc) +/obj/machinery/bodyscanner/force_eject_occupant() + go_out() + /obj/machinery/bodyscanner/ex_act(severity) if(occupant) occupant.ex_act(severity) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 4213ff517bf..8be09ef30b7 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -443,6 +443,9 @@ for(var/atom/movable/A in contents - component_parts - list(beaker)) A.forceMove(get_step(loc, SOUTH)) +/obj/machinery/atmospherics/unary/cryo_cell/force_eject_occupant() + go_out() + /// Called when either the occupant is dead and the AUTO_EJECT_DEAD flag is present, OR the occupant is alive, has no external damage, and the AUTO_EJECT_HEALTHY flag is present. /obj/machinery/atmospherics/unary/cryo_cell/proc/auto_eject(eject_flag) on = FALSE diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 2e0c4c54375..fecd006886e 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -769,9 +769,13 @@ return ..() + /proc/cryo_ssd(var/mob/living/carbon/person_to_cryo) if(istype(person_to_cryo.loc, /obj/machinery/cryopod)) return 0 + if(isobj(person_to_cryo.loc)) + var/obj/O = person_to_cryo.loc + O.force_eject_occupant() var/list/free_cryopods = list() for(var/obj/machinery/cryopod/P in GLOB.machines) if(!P.occupant && istype(get_area(P), /area/crew_quarters/sleep)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index da4df4f8382..cd6b33d0a95 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -740,10 +740,11 @@ if(!occupant) return - if(user != occupant) - to_chat(occupant, "The machine kicks you out!") - if(user.loc != loc) - to_chat(occupant, "You leave the not-so-cozy confines of the SSU.") + if(user) + if(user != occupant) + to_chat(occupant, "The machine kicks you out!") + if(user.loc != loc) + to_chat(occupant, "You leave the not-so-cozy confines of [src].") occupant.forceMove(loc) occupant = null if(!state_open) @@ -751,6 +752,8 @@ update_icon() return +/obj/machinery/suit_storage_unit/force_eject_occupant() + eject_occupant() /obj/machinery/suit_storage_unit/verb/get_out() set name = "Eject Suit Storage Unit" diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 540e1074844..69f70207452 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1273,6 +1273,9 @@ L.client.RemoveViewMod("mecha") zoom_mode = FALSE +/obj/mecha/force_eject_occupant() + go_out() + ///////////////////////// ////// Access stuff ///// ///////////////////////// diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index d40c628ed90..7a56c53f73a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -351,3 +351,9 @@ a { /obj/proc/check_uplink_validity() return TRUE + +/obj/proc/force_eject_occupant() + // This proc handles safely removing occupant mobs from the object if they must be teleported out (due to being SSD/AFK, by admin teleport, etc) or transformed. + // In the event that the object doesn't have an overriden version of this proc to do it, log a runtime so one can be added. + CRASH("Proc force_eject_occupant() is not overriden on a machine containing a mob.") + diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 04373502832..6db1846e872 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -354,6 +354,11 @@ /obj/structure/closet/AllowDrop() return TRUE +/obj/structure/closet/force_eject_occupant() + // Its okay to silently teleport mobs out of lockers, since the only thing affected is their contents list. + return + + /obj/structure/closet/bluespace name = "bluespace closet" desc = "A storage unit that moves and stores through the fourth dimension." diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 0c1a8c5f14f..ca83b5bad08 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -22,6 +22,10 @@ to_chat(src, "Nowhere to jump to!") return + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() + admin_forcemove(usr, T) log_admin("[key_name(usr)] jumped to [A]") if(!isobserver(usr)) @@ -35,6 +39,9 @@ if(!check_rights(R_ADMIN)) return + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() log_admin("[key_name(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]") if(!isobserver(usr)) message_admins("[key_name_admin(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]", 1) @@ -52,6 +59,9 @@ log_admin("[key_name(usr)] jumped to [key_name(M)]") if(!isobserver(usr)) message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1) + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() if(src.mob) var/mob/A = src.mob var/turf/T = get_turf(M) @@ -70,6 +80,9 @@ var/turf/T = locate(tx, ty, tz) if(T) + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() admin_forcemove(usr, T) if(isobserver(usr)) var/mob/dead/observer/O = usr @@ -96,7 +109,9 @@ log_admin("[key_name(usr)] jumped to [key_name(M)]") if(!isobserver(usr)) message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1) - + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() admin_forcemove(usr, M.loc) feedback_add_details("admin_verb","JK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -111,6 +126,10 @@ log_admin("[key_name(usr)] teleported [key_name(M)]") message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1) + + if(isobj(M.loc)) + var/obj/O = M.loc + O.force_eject_occupant() admin_forcemove(M, get_turf(usr)) feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -135,6 +154,9 @@ log_admin("[key_name(usr)] teleported [key_name(M)]") message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1) if(M) + if(isobj(M.loc)) + var/obj/O = M.loc + O.force_eject_occupant() admin_forcemove(M, get_turf(usr)) admin_forcemove(usr, M.loc) feedback_add_details("admin_verb","GK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -148,6 +170,9 @@ var/area/A = input(usr, "Pick an area.", "Pick an area") in return_sorted_areas() if(A) + if(isobj(M.loc)) + var/obj/O = M.loc + O.force_eject_occupant() admin_forcemove(M, pick(get_area_turfs(A))) feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_admin("[key_name(usr)] teleported [key_name(M)] to [A]") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 43db66cabc5..03b9dfb60e7 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -917,6 +917,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(istype(landmark)) var/datum/map_template/ruin/template = landmark.ruin_template + if(isobj(usr.loc)) + var/obj/O = usr.loc + O.force_eject_occupant() admin_forcemove(usr, get_turf(landmark)) to_chat(usr, "[template.name]")