diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 5056899d9b1e..0f7e8143361b 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -87,3 +87,12 @@ /// cooldown for being shown the images for any particular data hud #define ADD_HUD_TO_COOLDOWN 20 + + +#define GHOST_DATA_HUDS (1<<0) +#define GHOST_VISION (1<<1) +#define GHOST_HEALTH (1<<2) +#define GHOST_CHEM (1<<3) +#define GHOST_GAS (1<<4) +#define GHOST_TRAY (1<<5) +#define GHOST_DARKNESS_LEVEL (1<<6) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index c996c0f8b294..9aff2d57ddb1 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -160,11 +160,10 @@ #define ui_pai_view_images "SOUTH:6,WEST+13" //Ghosts -#define ui_ghost_respawn "SOUTH:6,CENTER-3:24" -#define ui_ghost_orbit "SOUTH:6,CENTER-2:24" -#define ui_ghost_reenter_corpse "SOUTH:6,CENTER-1:24" -#define ui_ghost_teleport "SOUTH:6,CENTER:24" -#define ui_ghost_pai "SOUTH: 6,CENTER+1:24" -#define ui_ghost_spawner_menu "SOUTH:6,CENTER+2:24" +#define ui_ghost_orbit "SOUTH:6,CENTER-3:24" +#define ui_ghost_reenter_corpse "SOUTH:6,CENTER-2:24" +#define ui_ghost_teleport "SOUTH:6,CENTER-1:24" +#define ui_dnr "SOUTH:6,CENTER:24" +#define ui_ghost_respawn "SOUTH:6,CENTER+1:24" #define ui_wanted_lvl "NORTH,11" diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index d1c7cb81ca7d..eddad47a1fe3 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -39,6 +39,14 @@ var/mob/dead/observer/G = usr G.reenter_corpse() +/atom/movable/screen/ghost/dnr + name = "Do Not Resuscitate" + icon_state = "dnr" + +/atom/movable/screen/ghost/dnr/Click() + var/mob/dead/observer/dnring = usr + dnring.stay_dead() + /atom/movable/screen/ghost/teleport name = "Teleport" icon_state = "teleport" @@ -47,23 +55,106 @@ var/mob/dead/observer/G = usr G.dead_tele() -/atom/movable/screen/ghost/pai +/atom/movable/screen/ghost/hudbox + icon_state = "smallbox" + bad_type = /atom/movable/screen/ghost/hudbox + /// Icon state used for the overlay representing this hudbox + var/hud_icon_state + /// The flag this hudbox toggles + var/relevant_flag + +/atom/movable/screen/ghost/hudbox/update_overlays() + . = ..() + . += hud_icon_state + +/atom/movable/screen/ghost/hudbox/update_icon_state() + . = ..() + var/mob/dead/observer/observer = usr + if(!istype(observer)) + return + + icon_state = "smallbox[is_active(observer) ? "_active" : ""]" + +/atom/movable/screen/ghost/hudbox/proc/is_active(mob/dead/observer/observer) + return (observer.ghost_hud_flags & relevant_flag) + +/atom/movable/screen/ghost/hudbox/Click(location, control, params) + var/mob/dead/observer/observer = usr + switch(relevant_flag) + if(GHOST_DARKNESS_LEVEL) + observer.toggle_darkness() + if(GHOST_TRAY) + observer.tray_view() + else + observer.toggle_ghost_hud_flag(relevant_flag) + + update_appearance(UPDATE_ICON_STATE) + +/atom/movable/screen/ghost/hudbox/health_scanner + name = "Health Scanner" + desc = "Toggles your ability to health scan mobs on click." + hud_icon_state = "health_vision" + relevant_flag = GHOST_HEALTH + +/atom/movable/screen/ghost/hudbox/chem_scanner + name = "Chem Scanner" + desc = "Toggles your ability to chemical scan mobs on click." + hud_icon_state = "chem_vision" + relevant_flag = GHOST_CHEM + +/atom/movable/screen/ghost/hudbox/gas_scanner + name = "Gas Scanner" + desc = "Toggles your ability to gas scan objects on click." + hud_icon_state = "atmos_vision" + relevant_flag = GHOST_GAS + +/atom/movable/screen/ghost/hudbox/ghost + name = "Ghost Vision" + desc = "Toggles whether you can see other ghosts." + hud_icon_state = "ghost_vision" + relevant_flag = GHOST_VISION + +/atom/movable/screen/ghost/hudbox/data_huds + name = "Data HUDs" + desc = "Toggles the display of data HUDs (health, security, diagnostics, etc)." + hud_icon_state = "data_vision" + relevant_flag = GHOST_DATA_HUDS + +/atom/movable/screen/ghost/hudbox/pai name = "pAI Candidate" - icon_state = "pai" + hud_icon_state = "pai" -/atom/movable/screen/ghost/pai/Click() +/atom/movable/screen/ghost/hudbox/pai/Click() var/mob/dead/observer/G = usr G.register_pai() -/atom/movable/screen/ghost/spawner_menu +/atom/movable/screen/ghost/hudbox/spawner_menu name = "Spawner Menu" - icon = 'icons/hud/screen_ghost.dmi' - icon_state = "spawner_menu" + hud_icon_state = "spawner_menu" -/atom/movable/screen/ghost/spawner_menu/Click() +/atom/movable/screen/ghost/hudbox/spawner_menu/Click() var/mob/dead/observer/G = usr G.open_spawners_menu() +/atom/movable/screen/ghost/hudbox/tray_icon + name = "Tray View" + desc = "Shows the t-ray view of the area around your ghost." + hud_icon_state = "tray_vision" + relevant_flag = GHOST_TRAY + +/atom/movable/screen/ghost/hudbox/darkness_level + name = "Darkness Level" + desc = "Cycles through different darkness levels for ghost vision." + hud_icon_state = "darkness_vision" + relevant_flag = GHOST_DARKNESS_LEVEL + +/atom/movable/screen/ghost/hudbox/language_menu + name = "language menu" + hud_icon_state = "talk_wheel" + +/atom/movable/screen/ghost/hudbox/language_menu/Click() + usr.get_language_holder().open_language_menu(usr) + /datum/hud/ghost/New(mob/owner) ..() var/atom/movable/screen/using @@ -83,25 +174,28 @@ using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/teleport() - using.screen_loc = ui_ghost_teleport + using = new /atom/movable/screen/ghost/dnr(null, src) + using.screen_loc = ui_dnr using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/pai() - using.screen_loc = ui_ghost_pai + using = new /atom/movable/screen/ghost/teleport() + using.screen_loc = ui_ghost_teleport using.hud = src static_inventory += using - using = new /atom/movable/screen/language_menu - using.icon = ui_style - using.hud = src - static_inventory += using + var/list/hudboxes = subtypesof(/atom/movable/screen/ghost/hudbox) + for(var/i in 1 to length(hudboxes)) + var/hudbox_type = hudboxes[i] + var/atom/movable/screen/ghost/hudbox/hudbox = new hudbox_type(null, src) + hudbox.screen_loc = position_hudbox(i - 1) + static_inventory += hudbox + hudbox.update_appearance() - using = new /atom/movable/screen/ghost/spawner_menu() - using.screen_loc = ui_ghost_spawner_menu - using.hud = src - static_inventory += using +/datum/hud/ghost/proc/position_hudbox(i) + var/row = floor(i / 5) + var/column = i % 5 + return "SOUTH:[6 + row * 16], CENTER+2:[7 + column * 15]" /datum/hud/ghost/show_hud(version = 0, mob/viewmob) // don't show this HUD if observing; show the HUD of the observee @@ -115,7 +209,9 @@ return var/mob/screenmob = viewmob || mymob if(!screenmob.client.prefs.ghost_hud) - screenmob.client.screen -= static_inventory + screenmob.client.screen |= static_inventory + for(var/atom/movable/screen/ghost/hudbox/hud in static_inventory) + hud.update_appearance() else screenmob.client.screen += static_inventory diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index be934a395b30..8573c616f151 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -51,7 +51,7 @@ if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND) return TRUE if(user.client) - if(user.gas_scan && atmosanalyzer_scan(user, src)) + if((user.ghost_hud_flags & GHOST_GAS) && atmosanalyzer_scan(user, src)) return TRUE else if(isAdminGhostAI(user)) attack_ai(user) @@ -60,9 +60,13 @@ return FALSE /mob/living/attack_ghost(mob/dead/observer/user) - if(user.client && user.health_scan) - healthscan(user, src, 2, TRUE, TRUE) - if(user.client && user.chem_scan) + . = ..() + if(isnull(user.client)) + return + + if (user.ghost_hud_flags & GHOST_HEALTH) + healthscan(user, src, 1, TRUE) + if (user.ghost_hud_flags & GHOST_CHEM) chemscan(user, src) return ..() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index e94a7781dda1..f02576717419 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -33,12 +33,9 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) var/image/ghostimage_simple = null //this mob with the simple white ghost sprite var/ghostvision = 1 //is the ghost able to see things humans can't? var/mob/observetarget = null //The target mob that the ghost is observing. Used as a reference in logout() - var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD? - var/data_huds_on = 0 //Are data HUDs currently enabled? - var/health_scan = FALSE //Are health scans currently enabled? - var/chem_scan = FALSE //Are chem scans currently enabled? - var/gas_scan = FALSE //Are gas scans currently enabled? var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED) //list of data HUDs shown to ghosts. + ///Selection: GHOST_DATA_HUDS | GHOST_VISION | GHOST_HEALTH | GHOST_CHEM | GHOST_GAS + var/ghost_hud_flags = NONE var/ghost_orbit = GHOST_ORBIT_CIRCLE //These variables store hair data if the ghost originates from a species with head and/or facial hair. @@ -149,9 +146,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) SSpoints_of_interest.make_point_of_interest(src) grant_all_languages() - show_data_huds() - data_huds_on = 1 - + toggle_ghost_hud_flag(GHOST_VISION | GHOST_DATA_HUDS) /mob/dead/observer/get_photo_description(obj/item/camera/camera) if(!invisibility || camera.see_ghosts) @@ -164,6 +159,9 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_atom_colour)), 10) /mob/dead/observer/Destroy() + if(ghost_hud_flags & GHOST_DATA_HUDS) + remove_data_huds() + // Update our old body's medhud since we're abandoning it if(mind && mind.current) mind.current.med_hud_set_status() @@ -362,18 +360,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!client) return if(!mind || QDELETED(mind.current) || mind.current.loc == null) - to_chat(src, span_warning("You have no body.")) + to_chat(src, span_warning("А тела то и нет.")) return if(!can_reenter_corpse) - to_chat(src, span_warning("You cannot re-enter your body.")) + to_chat(src, span_warning("Не могу вернуться в тело.")) return if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients - to_chat(usr, span_warning("Another consciousness is in your body...It is resisting you.")) + to_chat(usr, span_warning("Кто-то уже копается в моём теле... Оно отвергает меня.")) return client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))//Let's reset so people can't become allseeing gods SStgui.on_transfer(src, mind.current) // Transfer NanoUIs. if(mind.current.stat == DEAD && SSlag_switch.measures[DISABLE_DEAD_KEYLOOP]) - to_chat(src, span_warning("To leave your body again use the Ghost verb.")) + to_chat(src, span_warning("Чтобы покинуть тело используй кнопку Призрак.")) mind.current.key = key mind.current.client.init_verbs() mind.current.ignore_SSD = FALSE @@ -385,10 +383,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!client) return if(!can_reenter_corpse) - to_chat(usr, span_warning("You're already stuck out of your body!")) + to_chat(usr, span_warning("Да я как бы уже!")) return FALSE - var/response = alert(src, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone. ","Are you sure you want to stay dead?","DNR","Save Me") + var/response = tgui_alert(src, "Отменяем возможность возродиться?\nОБРАТНОГО ПУТИ НЕ БУДЕТ!", "Умираем?", list("DNR", "Я передумал")) if(response != "DNR") return @@ -399,7 +397,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp // Disassociates observer mind from the body mind mind = null - to_chat(src, span_boldnotice("You can no longer be brought back into your body.")) + to_chat(src, span_boldnotice("Связь с телом потеряна. Приятного времяпрепровождения.")) return TRUE /mob/dead/observer/proc/notify_cloning(message, sound, atom/source, flashwindow = TRUE) @@ -459,6 +457,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp orbit_menu.ui_interact(src) +/// Toggles a flag from ghost hud and updates the mob accordingly +/mob/dead/observer/proc/toggle_ghost_hud_flag(toggled) + ghost_hud_flags ^= toggled + if(ghost_hud_flags & GHOST_DATA_HUDS) + show_data_huds() + else + remove_data_huds() + update_sight() + for(var/atom/movable/screen/ghost/hudbox/hud in hud_used?.static_inventory) + if(hud.relevant_flag & toggled) + hud.update_appearance(UPDATE_ICON_STATE) + // This is the ghost's follow verb with an argument /mob/dead/observer/proc/ManualFollow(atom/movable/target) if (!istype(target)) @@ -530,10 +540,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(A, span_danger("This mob is not located in the game world.")) /mob/dead/observer/verb/respawn() - if(can_reenter_corpse && client?.holder) - var/poll_client = tgui_alert(usr, "Returning to the title screen will forfeit any possible revival. Are you sure?", "Confirmation", list("Yes", "No")) - if(poll_client == "No") - return + if(!client) + return + var/poll_client = tgui_alert(usr, "Возврат в лобби-меню, это отменит возможность возрождение этим персонажем.\nВы ТОЧНО уверены?", "Респавн", list("Верни меня в лобби", "Я передумал")) + if(poll_client != "Верни меня в лобби") + return + abandon_mob() /mob/dead/observer/verb/change_view_range() @@ -594,11 +606,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/toggle_ghostsee() set name = "Toggle Ghost Vision" - set desc = "Toggles your ability to see things only ghosts can see, like other ghosts" - set category = "Ghost" - ghostvision = !(ghostvision) + + toggle_ghost_hud_flag(GHOST_VISION) update_sight() - to_chat(usr, span_boldnotice("You [(ghostvision?"now":"no longer")] have ghost vision.")) + 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" @@ -619,7 +630,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(client) ghost_others = client.prefs.ghost_others //A quick update just in case this setting was changed right before calling the proc - if (!ghostvision) + if(!(ghost_hud_flags & GHOST_VISION)) see_invisible = SEE_INVISIBLE_LIVING else see_invisible = SEE_INVISIBLE_OBSERVER @@ -646,7 +657,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(GHOST_OTHERS_SIMPLE) client.images -= GLOB.ghost_images_simple lastsetting = client.prefs.ghost_others - if(!ghostvision) + if(!(ghost_hud_flags & GHOST_VISION)) return if(client.prefs.ghost_others != GHOST_OTHERS_THEIR_SETTING) switch(client.prefs.ghost_others) @@ -744,64 +755,47 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return /mob/dead/observer/proc/show_data_huds() + ghost_hud_flags |= GHOST_DATA_HUDS // only for safety, it should be set already. for(var/hudtype in datahuds) var/datum/atom_hud/H = GLOB.huds[hudtype] H.add_hud_to(src) /mob/dead/observer/proc/remove_data_huds() + ghost_hud_flags &= ~GHOST_DATA_HUDS // only for safety, it should be unset already. for(var/hudtype in datahuds) var/datum/atom_hud/H = GLOB.huds[hudtype] H.remove_hud_from(src) /mob/dead/observer/verb/toggle_data_huds() set name = "Toggle Sec/Med/Diag HUD" - set desc = "Toggles whether you see medical/security/diagnostic HUDs" - set category = "Ghost" - if(data_huds_on) //remove old huds + toggle_ghost_hud_flag(GHOST_DATA_HUDS) + if(ghost_hud_flags & GHOST_DATA_HUDS) remove_data_huds() - to_chat(src, span_notice("Data HUDs disabled.")) - data_huds_on = 0 else show_data_huds() - to_chat(src, span_notice("Data HUDs enabled.")) - data_huds_on = 1 + to_chat(src, span_notice("Data HUDs [(ghost_hud_flags & GHOST_DATA_HUDS) ? "enabled": "disabled" ].")) /mob/dead/observer/verb/toggle_health_scan() set name = "Toggle Health Scan" - set desc = "Toggles whether you health-scan living beings on click" - set category = "Ghost" - if(health_scan) //remove old huds - to_chat(src, span_notice("Health scan disabled.")) - health_scan = FALSE - else - to_chat(src, span_notice("Health scan enabled.")) - health_scan = TRUE + toggle_ghost_hud_flag(GHOST_HEALTH) + to_chat(src, span_notice("Health scan [(ghost_hud_flags & GHOST_HEALTH) ? "enabled": "disabled" ].")) /mob/dead/observer/verb/toggle_chem_scan() set name = "Toggle Chem Scan" - set desc = "Toggles whether you scan living beings for chemicals and addictions on click" - set category = "Ghost" - if(chem_scan) //remove old huds - to_chat(src, span_notice("Chem scan disabled.")) - chem_scan = FALSE - else - to_chat(src, span_notice("Chem scan enabled.")) - chem_scan = TRUE + toggle_ghost_hud_flag(GHOST_CHEM) + to_chat(src, span_notice("Chem scan [(ghost_hud_flags & GHOST_CHEM) ? "enabled": "disabled" ].")) /mob/dead/observer/verb/toggle_gas_scan() set name = "Toggle Gas Scan" - set desc = "Toggles whether you analyze gas contents on click" - set category = "Ghost" - if(gas_scan) - to_chat(src, span_notice("Gas scan disabled.")) - gas_scan = FALSE - else - to_chat(src, span_notice("Gas scan enabled.")) - gas_scan = TRUE + toggle_ghost_hud_flag(GHOST_GAS) + to_chat(src, span_notice("Gas scan [(ghost_hud_flags & GHOST_GAS) ? "enabled": "disabled" ].")) + +/mob/dead/observer/proc/toggle_hud_type(mob/dead/observer/user, hud_type) + user.toggle_ghost_hud_flag(hud_type) /mob/dead/observer/verb/restore_ghost_appearance() set name = "Restore Ghost Character" diff --git a/icons/hud/screen_ghost.dmi b/icons/hud/screen_ghost.dmi index ff14e4e1dd3b..2ba38b33f15e 100644 Binary files a/icons/hud/screen_ghost.dmi and b/icons/hud/screen_ghost.dmi differ