From e08086ba8d1bf25d76cdf8ffbea76684628a5bdd Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Jun 2025 00:12:51 +0200 Subject: [PATCH] Brings back ghost verbs (chatbar only) (#91619) ## About The Pull Request Partially rolls back #91370 by reintroducing ghost verbs, but for the chatbar only. Doesn't clutter up the statpanel, but powerusers can quickly type them in without navigating the menu. ## Why It's Good For The Game The change massively fucked over our powerusers (aka admins, which are already suffering from poor UX) who were used to typing out the verbs in the chat. No reason to remove functionality, the menu is neat but if you remember commands by heart its faster to type them out. ## Changelog :cl: add: Ghost verbs are back in the chatbar, you can now type out things like "Orbit" or "T-ray-scan" once again as a ghost. /:cl: --- code/modules/mob/dead/observer/observer.dm | 187 ++++++++++++++++++++- 1 file changed, 184 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 54ad599d3e7..fe60f1f8953 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -75,7 +75,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) /mob/dead/observer/Initialize(mapload) set_invisibility(GLOB.observer_default_invisibility) - if(icon_state in GLOB.ghost_forms_with_directions_list) ghostimage_default = image(src.icon,src,src.icon_state + "_nodir") else @@ -366,7 +365,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(new_area != ambience_tracked_area) update_ambience_area(new_area) -/mob/dead/observer/proc/reenter_corpse() +/mob/dead/observer/verb/reenter_corpse() + set name = "Re-enter Corpse" + if(!client) return if(!mind || QDELETED(mind.current)) @@ -386,6 +387,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp mind.current.client.init_verbs() return TRUE +/mob/dead/observer/verb/do_not_resuscitate() + set name = "Do Not Resuscitate" + + if(!can_reenter_corpse) + to_chat(usr, span_warning("You're already stuck out of your body!")) + return FALSE + + var/response = tgui_alert(usr, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone.", "Are you sure you want to stay dead?", list("DNR","Save Me")) + if(response == "DNR") + stay_dead() + /mob/dead/observer/proc/stay_dead() if(!can_reenter_corpse) to_chat(usr, span_warning("You're already stuck out of your body!")) @@ -441,7 +453,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(sound) SEND_SOUND(src, sound(sound)) -/mob/dead/observer/proc/dead_tele() +/mob/dead/observer/verb/dead_tele() + set name = "Teleport" + if(!isobserver(usr)) to_chat(usr, span_warning("Not when you're not dead!")) return @@ -467,6 +481,173 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp usr.abstract_move(pick(L)) +/mob/dead/observer/verb/follow() + set name = "Orbit" + + GLOB.orbit_menu.show(src) + +/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak + set name = "Jump to Mob" + + if(!isobserver(usr)) //Make sure they're an observer! + return + + var/list/possible_destinations = SSpoints_of_interest.get_mob_pois() + var/target = null + + target = tgui_input_list(usr, "Please, select a player!", "Jump to Mob", possible_destinations) + if(isnull(target)) + return + if (!isobserver(usr)) + return + + var/mob/destination_mob = possible_destinations[target] //Destination mob + + // During the break between opening the input menu and selecting our target, has this become an invalid option? + if(!SSpoints_of_interest.is_valid_poi(destination_mob)) + return + + var/mob/source_mob = src //Source mob + var/turf/destination_turf = get_turf(destination_mob) //Turf of the destination mob + + if(isturf(destination_turf)) + source_mob.abstract_move(destination_turf) + else + to_chat(source_mob, span_danger("This mob is not located in the game world.")) + +/mob/dead/observer/verb/change_view_range() + set name = "View Range" + + if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder) + to_chat(usr, span_notice("That verb is currently globally disabled.")) + return + + var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT + if(client.view_size.getView() == client.view_size.default) + var/list/views = list() + for(var/i in 7 to max_view) + views |= i + var/new_view = tgui_input_list(usr, "New view", "Modify view range", views) + if(new_view) + client.view_size.setTo(clamp(new_view, 7, max_view) - 7) + else + client.view_size.resetToDefault() + +/mob/dead/observer/verb/toggle_ghostsee() + set name = "Toggle Ghost Vision" + + ghost_hud_flags ^= GHOST_VISION + update_sight() + to_chat(usr, span_boldnotice("You [(ghost_hud_flags & GHOST_VISION) ? "now" : "no longer"] have ghost vision.")) + +/mob/dead/observer/verb/toggle_darkness() + set name = "Toggle Darkness" + + switch(lighting_cutoff) + if (LIGHTING_CUTOFF_VISIBLE) + lighting_cutoff = LIGHTING_CUTOFF_MEDIUM + if (LIGHTING_CUTOFF_MEDIUM) + lighting_cutoff = LIGHTING_CUTOFF_HIGH + if (LIGHTING_CUTOFF_HIGH) + lighting_cutoff = LIGHTING_CUTOFF_FULLBRIGHT + else + lighting_cutoff = LIGHTING_CUTOFF_VISIBLE + + update_sight() + +/mob/dead/observer/verb/view_manifest() + set name = "View Crew Manifest" + + GLOB.manifest.ui_interact(src) + +/mob/dead/observer/verb/observe() + set name = "Observe" + + if(!isobserver(usr) || HAS_TRAIT(src, TRAIT_NO_OBSERVE)) //Make sure they're an observer! + return + + reset_perspective(null) + + var/list/possible_destinations = SSpoints_of_interest.get_mob_pois() + var/target = null + + target = tgui_input_list(usr, "Please, select a player!", "Jump to Mob", possible_destinations) + if(isnull(target)) + return + if (!isobserver(usr)) + return + + reset_perspective(null) // Reset again for sanity + + var/mob/chosen_target = possible_destinations[target] + + // During the break between opening the input menu and selecting our target, has this become an invalid option? + if(!SSpoints_of_interest.is_valid_poi(chosen_target)) + return + + if (chosen_target == usr) + return + + do_observe(chosen_target) + +/mob/dead/observer/verb/tray_view() + set name = "T-ray scan" + + if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder) + to_chat(usr, span_notice("That verb is currently globally disabled.")) + return + + t_ray_scan(src) + +/mob/dead/observer/verb/toggle_data_huds() + set name = "Toggle Sec/Med/Diag HUD" + + ghost_hud_flags ^= GHOST_DATA_HUDS + if(ghost_hud_flags & GHOST_DATA_HUDS) + show_data_huds() + to_chat(src, span_notice("Data HUDs enabled.")) + else + remove_data_huds() + to_chat(src, span_notice("Data HUDs disabled.")) + +/mob/dead/observer/verb/toggle_health_scan() + set name = "Toggle Health Scan" + + ghost_hud_flags ^= GHOST_HEALTH + if(ghost_hud_flags & GHOST_HEALTH) + to_chat(src, span_notice("Health scan enabled.")) + else + to_chat(src, span_notice("Health scan disabled.")) + +/mob/dead/observer/verb/toggle_chem_scan() + set name = "Toggle Chem Scan" + + ghost_hud_flags ^= GHOST_CHEM + if(ghost_hud_flags & GHOST_CHEM) + to_chat(src, span_notice("Chem scan enabled.")) + else + to_chat(src, span_notice("Chem scan disabled.")) + +/mob/dead/observer/verb/toggle_gas_scan() + set name = "Toggle Gas Scan" + + ghost_hud_flags ^= GHOST_GAS + if(ghost_hud_flags & GHOST_GAS) + to_chat(src, span_notice("Gas scan enabled.")) + else + to_chat(src, span_notice("Gas scan disabled.")) + +/mob/dead/observer/verb/restore_ghost_appearance() + set name = "Restore Ghost Character" + + set_ghost_appearance() + if(client?.prefs) + var/real_name = client.prefs.read_preference(/datum/preference/name/real_name) + deadchat_name = real_name + if(mind) + mind.ghostname = real_name + name = real_name + // This is the ghost's follow verb with an argument /mob/dead/observer/proc/ManualFollow(atom/movable/target) if (!istype(target) || (is_secret_level(target.z) && !client?.holder))