mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 13:38:41 +01:00
A continuation of #68389 which addresses an issue that still bothers me to this day: The orbit menu displays a player's name as a combo of name id transform. It can get lengthy to a point where the names clip the entire screen (as buttons do not multiline). This PR shortens excessively long player names on the orbit menu and adds a tooltip that will show extended info like full name, health and job titles. Mostly drawn from concerns brought up in the original.
159 lines
4.7 KiB
Plaintext
159 lines
4.7 KiB
Plaintext
GLOBAL_DATUM_INIT(orbit_menu, /datum/orbit_menu, new)
|
|
|
|
/datum/orbit_menu
|
|
|
|
/datum/orbit_menu/ui_state(mob/user)
|
|
return GLOB.observer_state
|
|
|
|
/datum/orbit_menu/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if (!ui)
|
|
ui = new(user, src, "Orbit")
|
|
ui.open()
|
|
|
|
/datum/orbit_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
|
|
if(.)
|
|
return
|
|
|
|
switch(action)
|
|
if("orbit")
|
|
var/ref = params["ref"]
|
|
var/auto_observe = params["auto_observe"]
|
|
var/atom/poi = SSpoints_of_interest.get_poi_atom_by_ref(ref)
|
|
|
|
if((ismob(poi) && !SSpoints_of_interest.is_valid_poi(poi, CALLBACK(src, .proc/validate_mob_poi))) \
|
|
|| !SSpoints_of_interest.is_valid_poi(poi)
|
|
)
|
|
to_chat(usr, span_notice("That point of interest is no longer valid."))
|
|
return TRUE
|
|
|
|
var/mob/dead/observer/user = usr
|
|
user.ManualFollow(poi)
|
|
user.reset_perspective(null)
|
|
if (auto_observe)
|
|
user.do_observe(poi)
|
|
return TRUE
|
|
if ("refresh")
|
|
update_static_data(usr, ui)
|
|
return TRUE
|
|
|
|
/datum/orbit_menu/ui_static_data(mob/user)
|
|
var/list/new_mob_pois = SSpoints_of_interest.get_mob_pois(CALLBACK(src, .proc/validate_mob_poi), append_dead_role = FALSE)
|
|
var/list/new_other_pois = SSpoints_of_interest.get_other_pois()
|
|
|
|
var/list/alive = list()
|
|
var/list/antagonists = list()
|
|
var/list/dead = list()
|
|
var/list/ghosts = list()
|
|
var/list/misc = list()
|
|
var/list/npcs = list()
|
|
|
|
for(var/name in new_mob_pois)
|
|
var/list/serialized = list()
|
|
|
|
var/mob/mob_poi = new_mob_pois[name]
|
|
|
|
var/poi_ref = REF(mob_poi)
|
|
serialized["ref"] = poi_ref
|
|
serialized["full_name"] = name
|
|
|
|
if(isobserver(mob_poi))
|
|
var/number_of_orbiters = length(mob_poi.get_all_orbiters())
|
|
if (number_of_orbiters)
|
|
serialized["orbiters"] = number_of_orbiters
|
|
ghosts += list(serialized)
|
|
continue
|
|
|
|
if(mob_poi.stat == DEAD)
|
|
dead += list(serialized)
|
|
continue
|
|
|
|
if(isnull(mob_poi.mind))
|
|
npcs += list(serialized)
|
|
continue
|
|
|
|
var/number_of_orbiters = length(mob_poi.get_all_orbiters())
|
|
if(number_of_orbiters)
|
|
serialized["orbiters"] = number_of_orbiters
|
|
|
|
var/datum/mind/mind = mob_poi.mind
|
|
var/was_antagonist = FALSE
|
|
|
|
serialized["job"] = mind?.assigned_role?.title
|
|
serialized["name"] = mob_poi.real_name
|
|
serialized["health"] = null
|
|
// Cast the mob so we can get health
|
|
var/mob/living/player
|
|
if(isliving(mob_poi)) // Kind of silly here since we've already checked for dead mobs
|
|
player = mob_poi
|
|
serialized["health"] = FLOOR((player.health / player.maxHealth * 100), 1)
|
|
|
|
for(var/datum/antagonist/antag_datum as anything in mind.antag_datums)
|
|
if (antag_datum.show_to_ghosts)
|
|
was_antagonist = TRUE
|
|
serialized["antag"] = antag_datum.name
|
|
antagonists += list(serialized)
|
|
break
|
|
|
|
if(!was_antagonist)
|
|
alive += list(serialized)
|
|
|
|
for(var/name in new_other_pois)
|
|
var/atom/atom_poi = new_other_pois[name]
|
|
|
|
misc += list(list(
|
|
"ref" = REF(atom_poi),
|
|
"name" = name,
|
|
"extra" = null, // Just in case you want to add anything
|
|
))
|
|
|
|
// Display the supermatter crystal integrity
|
|
if(istype(atom_poi, /obj/machinery/power/supermatter_crystal))
|
|
var/obj/machinery/power/supermatter_crystal/crystal = atom_poi
|
|
misc[length(misc)]["extra"] = "Integrity: [crystal.get_integrity_percent()]%"
|
|
continue
|
|
// Display the nuke timer
|
|
if(istype(atom_poi, /obj/machinery/nuclearbomb))
|
|
var/obj/machinery/nuclearbomb/bomb = atom_poi
|
|
if(bomb.timing)
|
|
misc[length(misc)]["extra"] = "Timer: [bomb.countdown?.displayed_text]s"
|
|
continue
|
|
// Display the holder if its a nuke disk
|
|
if(istype(atom_poi, /obj/item/disk/nuclear))
|
|
var/obj/item/disk/nuclear/disk = atom_poi
|
|
var/mob/holder = disk.pulledby || get(disk, /mob)
|
|
misc[length(misc)]["extra"] = "Location: [holder?.real_name || "Unsecured"]"
|
|
continue
|
|
|
|
return list(
|
|
"alive" = alive,
|
|
"antagonists" = antagonists,
|
|
"dead" = dead,
|
|
"ghosts" = ghosts,
|
|
"misc" = misc,
|
|
"npcs" = npcs,
|
|
)
|
|
|
|
/// Shows the UI to the specified user.
|
|
/datum/orbit_menu/proc/show(mob/user)
|
|
ui_interact(user)
|
|
|
|
/**
|
|
* Helper POI validation function passed as a callback to various SSpoints_of_interest procs.
|
|
*
|
|
* Provides extended validation above and beyond standard, limiting mob POIs without minds or ckeys
|
|
* unless they're mobs, camera mobs or megafauna.
|
|
*
|
|
* If they satisfy that requirement, falls back to default validation for the POI.
|
|
*/
|
|
/datum/orbit_menu/proc/validate_mob_poi(datum/point_of_interest/mob_poi/potential_poi)
|
|
var/mob/potential_mob_poi = potential_poi.target
|
|
// Skip mindless and ckeyless mobs except bots, cameramobs and megafauna.
|
|
if(!potential_mob_poi.mind && !potential_mob_poi.ckey)
|
|
if(!isbot(potential_mob_poi) && !iscameramob(potential_mob_poi) && !ismegafauna(potential_mob_poi))
|
|
return FALSE
|
|
|
|
return potential_poi.validate()
|