Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makes observers able to see the UI of Xeno players (and also action buttons) #5751

Merged
merged 6 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions code/_onclick/hud/screen_objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@
/atom/movable/screen/action_button/attack_ghost(mob/dead/observer/user)
return

/atom/movable/screen/action_button/clicked(mob/user)
/atom/movable/screen/action_button/clicked(mob/user, list/mods)
if(!user || !source_action)
return TRUE
if(source_action.owner != user)
return TRUE

if(source_action.can_use_action())
source_action.action_activate()
Expand Down Expand Up @@ -97,7 +99,7 @@
icon_state = "hide"
var/hidden = 0

/atom/movable/screen/action_button/hide_toggle/clicked(mob/user, mods)
/atom/movable/screen/action_button/hide_toggle/clicked(mob/user, list/mods)
user.hud_used.action_buttons_hidden = !user.hud_used.action_buttons_hidden
hidden = user.hud_used.action_buttons_hidden
if(hidden)
Expand All @@ -107,7 +109,7 @@
name = "Hide Buttons"
icon_state = "hide"
user.update_action_buttons()
return 1
return TRUE

/atom/movable/screen/action_button/ghost/minimap/get_button_screen_loc(button_number)
return "SOUTH:6,CENTER+1:24"
Expand Down Expand Up @@ -211,7 +213,7 @@
update_icon(user)
return 1

/atom/movable/screen/clicked(mob/user)
/atom/movable/screen/clicked(mob/user, list/mods)
if(!user)
return TRUE

Expand Down
78 changes: 28 additions & 50 deletions code/modules/mob/dead/observer/observer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -188,37 +188,38 @@
clean_observe_target()

/// When the observer target gets a screen, our observer gets a screen minus some game screens we don't want the observer to touch
/mob/dead/observer/proc/observe_target_screen_add(observe_target_mob_client, add_to_screen)
/mob/dead/observer/proc/observe_target_screen_add(observe_target_mob_client, screen_add)
SIGNAL_HANDLER

if(!client)
return

if(istype(add_to_screen, /atom/movable/screen/action_button))
return

if(istype(add_to_screen, /atom/movable/screen/fullscreen))
return
var/static/list/excluded_types = typecacheof(list(
/atom/movable/screen/fullscreen,
/atom/movable/screen/click_catcher,
/atom/movable/screen/escape_menu,
/atom/movable/screen/buildmode,
/obj/effect/detector_blip,
))

if(istype(add_to_screen, /atom/movable/screen/click_catcher))
if(!client)
return

if(istype(add_to_screen, /atom/movable/screen/escape_menu))
return
// `screen_add` can sometimes be a list, so it's safest to just handle everything as one.
var/list/stuff_to_add = (islist(screen_add) ? screen_add : list(screen_add))

if(istype(add_to_screen, /obj/effect/detector_blip))
return
for(var/item in stuff_to_add)
// Ignore anything that's in `excluded_types`.
if(is_type_in_typecache(item, excluded_types))
continue

client.add_to_screen(add_to_screen)
client.add_to_screen(screen_add)

/// When the observer target loses a screen, our observer loses it as well
/mob/dead/observer/proc/observe_target_screen_remove(observe_target_mob_client, remove_from_screen)
/mob/dead/observer/proc/observe_target_screen_remove(observe_target_mob_client, screen_remove)
SIGNAL_HANDLER

if(!client)
return

client.remove_from_screen(remove_from_screen)
client.remove_from_screen(screen_remove)

/// When the observe target ghosts our observer disconnect from their screen updates
/mob/dead/observer/proc/observe_target_ghosting(mob/observer_target_mob)
Expand Down Expand Up @@ -256,48 +257,25 @@
ManualFollow(target)
reset_perspective()

if(!ishuman(target) || !client.prefs?.auto_observe)
if(!iscarbon(target) || !client.prefs?.auto_observe)
return
var/mob/living/carbon/human/human_target = target

client.eye = human_target
observe_target_mob = human_target
RegisterSignal(observe_target_mob, COMSIG_PARENT_QDELETING, PROC_REF(clean_observe_target))
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(observer_move_react))

if(!human_target.hud_used)
var/mob/living/carbon/carbon_target = target
if(!carbon_target.hud_used)
return

client.clear_screen()
LAZYINITLIST(human_target.observers)
human_target.observers |= src
human_target.hud_used.show_hud(human_target.hud_used.hud_version, src)

var/list/target_contents = human_target.get_contents()

//Handles any currently open storage containers the target is looking in when we observe
for(var/obj/item/storage/checked_storage in target_contents)
if(!(human_target in checked_storage.content_watchers))
continue

client.add_to_screen(checked_storage.closer)
client.add_to_screen(checked_storage.contents)

if(checked_storage.storage_slots)
client.add_to_screen(checked_storage.boxes)
else
client.add_to_screen(checked_storage.storage_start)
client.add_to_screen(checked_storage.storage_continue)
client.add_to_screen(checked_storage.storage_end)

break
client.eye = carbon_target
observe_target_mob = carbon_target
carbon_target.auto_observed(src)

RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(observer_move_react))
RegisterSignal(observe_target_mob, COMSIG_PARENT_QDELETING, PROC_REF(clean_observe_target))
RegisterSignal(observe_target_mob, COMSIG_MOB_GHOSTIZE, PROC_REF(observe_target_ghosting))
RegisterSignal(observe_target_mob, COMSIG_MOB_NEW_MIND, PROC_REF(observe_target_new_mind))
RegisterSignal(observe_target_mob, COMSIG_MOB_LOGIN, PROC_REF(observe_target_login))

if(human_target.client)
observe_target_client = human_target.client
if(observe_target_mob.client)
observe_target_client = observe_target_mob.client
RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add))
RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove))

Expand Down
19 changes: 19 additions & 0 deletions code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,25 @@
<BR>"}
show_browser(user, dat, name, "mob[name]")

/**
* Called by [/mob/dead/observer/proc/do_observe] when a carbon mob is observed by a ghost with [/datum/preferences/var/auto_observe] enabled.
*
* Any HUD changes past this point are handled by [/mob/dead/observer/proc/observe_target_screen_add]
* and [/mob/dead/observer/proc/observe_target_screen_remove].
*
* Override on subtype mobs if they have any extra HUD elements/behaviour.
*/
/mob/living/carbon/proc/auto_observed(mob/dead/observer/observer)
SHOULD_CALL_PARENT(TRUE)

LAZYINITLIST(observers)
observers |= observer
hud_used.show_hud(hud_used.hud_version, observer)

for(var/datum/action/action as anything in actions)
// Add the action's button (not the action itself) to the observer's screen.
observer.client.add_to_screen(action.button)

//generates realistic-ish pulse output based on preset levels
/mob/living/carbon/proc/get_pulse(method) //method 0 is for hands, 1 is for machines, more accurate
var/temp = 0 //see setup.dm:694
Expand Down
23 changes: 23 additions & 0 deletions code/modules/mob/living/carbon/human/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,29 @@
<BR>"}
show_browser(user, dat, name, "mob[name]")

/**
* Handles any storage containers that the human is looking inside when auto-observed.
*/
/mob/living/carbon/human/auto_observed(mob/dead/observer/observer)
SabreML marked this conversation as resolved.
Show resolved Hide resolved
. = ..()

// If `src` doesn't have an inventory open.
if(!s_active)
return

// Add the storage interface to `observer`'s screen.
observer.client.add_to_screen(s_active.closer)
observer.client.add_to_screen(s_active.contents)

// If the storage has a set number of item slots.
if(s_active.storage_slots)
observer.client.add_to_screen(s_active.boxes)
// If the storage instead has a maximum combined item 'weight'.
else
observer.client.add_to_screen(s_active.storage_start)
observer.client.add_to_screen(s_active.storage_continue)
observer.client.add_to_screen(s_active.storage_end)

// called when something steps onto a human
// this handles mulebots and vehicles
/mob/living/carbon/human/Crossed(atom/movable/AM)
Expand Down
1 change: 1 addition & 0 deletions strings/metatips.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ As a mentor, you can become the imaginary friend of a new player to teach them!
You shouldn't ignore what your allies are up to. Sometimes they can be organizing a flank in hivemind/radio, sometimes they can be walking up behind you with a slug-loaded shotgun. Either way, it pays to be alert to what they're doing, as much to as what the enemies are.
The Wiki (https://cm-ss13.com/wiki) is a very useful repository of information about the game, such as weapons, equipment, xenomorph castes and their strains. It may not be fully up to date much of the time, but the basics are usually accurate.
As an observer, you may see how much remaining hijack time is left in the status panel.
As an observer, you can quickly follow someone by ctrl-clicking on their sprite.
You can always AdminHelp with the F1 key to question a member of staff regarding rules or game bugs.
As ghost you are given extra tools for spectating the round: you can jump and follow specific players, get notifications about CAS and OB strikes, can see all health bars, and such.
You can press ESC key to bring up the game pause menu. It allows you change settings, AdminHelp and MentorHelp, and even access the Web Maps of game by clicking at top right.
Expand Down
Loading