mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-21 04:26:57 +01:00
265 lines
7.0 KiB
Plaintext
265 lines
7.0 KiB
Plaintext
GLOBAL_DATUM_INIT(orbit_menu, /datum/orbit_menu, new)
|
|
|
|
/datum/orbit_menu
|
|
///mobs worth orbiting. Because spaghetti, all mobs have the point of interest, but only some are allowed to actually show up.
|
|
///this obviously should be changed in the future, so we only add mobs as POI if they actually are interesting, and we don't use
|
|
///a typecache.
|
|
var/static/list/mob_allowed_typecache
|
|
|
|
/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, datum/event_args/actor/actor)
|
|
. = ..()
|
|
|
|
if(.)
|
|
return
|
|
|
|
switch(action)
|
|
if("orbit")
|
|
var/ref = params["ref"]
|
|
// not implemented
|
|
// var/auto_observe = params["auto_observe"]
|
|
// no sspoi :(
|
|
var/atom/poi = locate(ref) in GLOB.mob_list
|
|
|
|
if (poi == null)
|
|
poi = locate(ref) in SSshuttle.ships
|
|
if (poi == null)
|
|
. = TRUE
|
|
return
|
|
|
|
var/mob/observer/dead/user = usr
|
|
user.ManualFollow(poi)
|
|
user.reset_perspective(null)
|
|
user.orbiting_ref = ref
|
|
return TRUE
|
|
if ("refresh")
|
|
ui.send_full_update()
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/datum/orbit_menu/ui_data(mob/user)
|
|
var/list/data = list()
|
|
|
|
if(isobserver(user))
|
|
data["orbiting"] = get_currently_orbiting(user)
|
|
|
|
return data
|
|
|
|
/datum/orbit_menu/ui_static_data(mob/user)
|
|
var/is_admin = user?.client?.holder
|
|
|
|
var/list/alive = list()
|
|
var/list/antagonists = list()
|
|
var/list/critical = list()
|
|
var/list/deadchat_controlled = list()
|
|
var/list/dead = list()
|
|
var/list/ghosts = list()
|
|
var/list/misc = list()
|
|
var/list/npcs = list()
|
|
|
|
// sortmobs is a generic list
|
|
for(var/mobthing in sortmobs())
|
|
var/list/serialized = list()
|
|
var/mob/mob_poi = mobthing
|
|
var/number_of_orbiters = length(mob_poi.get_all_orbiters())
|
|
|
|
var/datum/component/custom_transform/transform_component = mob_poi.GetComponent(/datum/component/custom_transform)
|
|
var/is_dead = mob_poi.stat == DEAD || transform_component?.get_current_stat() == DEAD
|
|
|
|
// ignore magical objects
|
|
if (isEye(mob_poi) || isvoice(mob_poi))
|
|
continue
|
|
|
|
var/name = mob_poi.real_name || mob_poi.name
|
|
if(is_dead)
|
|
if(isobserver(mob_poi))
|
|
name += " \[ghost\]"
|
|
else
|
|
name += " \[dead\]"
|
|
|
|
serialized["ref"] = REF(mob_poi)
|
|
serialized["full_name"] = name
|
|
if(number_of_orbiters)
|
|
serialized["orbiters"] = number_of_orbiters
|
|
|
|
if (is_admin)
|
|
serialized["ckey"] = mob_poi.ckey
|
|
|
|
if(isobserver(mob_poi))
|
|
// TODO remove this, go use TRAIT_ORBITING_FORBIDDEN
|
|
if(mob_poi.invisibility >= INVISIBILITY_MAXIMUM) // invismin
|
|
continue
|
|
ghosts += list(serialized)
|
|
continue
|
|
|
|
if(is_dead)
|
|
dead += list(serialized)
|
|
continue
|
|
|
|
if(isnull(mob_poi.mind))
|
|
if(isliving(mob_poi))
|
|
var/mob/living/npc = mob_poi
|
|
serialized["health"] = FLOOR((npc.health / npc.maxHealth * 100), 1)
|
|
|
|
npcs += list(serialized)
|
|
continue
|
|
|
|
serialized["client"] = !!mob_poi.client
|
|
serialized["name"] = mob_poi.real_name
|
|
|
|
if(isliving(mob_poi))
|
|
serialized += get_living_data(mob_poi)
|
|
|
|
alive += list(serialized)
|
|
|
|
for(var/atom/movable/atom_poi as anything in SSshuttle.ships)
|
|
var/list/other_data = get_misc_data(atom_poi)
|
|
var/misc_data = list(other_data[1])
|
|
|
|
misc += misc_data
|
|
|
|
if(other_data[2]) // Critical = TRUE
|
|
critical += misc_data
|
|
|
|
return list(
|
|
"alive" = alive,
|
|
"antagonists" = antagonists,
|
|
"critical" = critical,
|
|
"deadchat_controlled" = deadchat_controlled,
|
|
"dead" = dead,
|
|
"ghosts" = ghosts,
|
|
"misc" = misc,
|
|
"npcs" = npcs,
|
|
"can_observe" = FALSE, // autoobserve
|
|
)
|
|
|
|
/// Shows the UI to the specified user.
|
|
/datum/orbit_menu/proc/show(mob/user)
|
|
ui_interact(user)
|
|
|
|
/// Helper to get the current thing we're orbiting (if any)
|
|
/datum/orbit_menu/proc/get_currently_orbiting(mob/observer/dead/user)
|
|
if(isnull(user.orbiting_ref))
|
|
return
|
|
|
|
// double locate since we dont hold the ref directly
|
|
var/atom/poi = locate(user.orbiting_ref) in GLOB.mob_list
|
|
if (isnull(poi))
|
|
poi = locate(user.orbiting_ref) in SSshuttle.ships
|
|
|
|
if(isnull(poi))
|
|
user.orbiting_ref = null
|
|
return
|
|
|
|
if (ismob(poi) && (isEye(poi) || isvoice(poi)))
|
|
user.orbiting_ref = null
|
|
return
|
|
|
|
var/list/serialized = list()
|
|
|
|
if(!ismob(poi))
|
|
var/list/misc_info = get_misc_data(poi)
|
|
serialized += misc_info[1]
|
|
return serialized
|
|
|
|
var/mob/mob_poi = poi
|
|
serialized["full_name"] = mob_poi.name
|
|
serialized["ref"] = REF(poi)
|
|
|
|
if(mob_poi.mind)
|
|
serialized["client"] = !!mob_poi.client
|
|
serialized["name"] = mob_poi.real_name
|
|
|
|
if(isliving(mob_poi))
|
|
serialized += get_living_data(mob_poi)
|
|
|
|
return serialized
|
|
|
|
/// Helper function to get job / icon / health data for a living mob
|
|
/datum/orbit_menu/proc/get_living_data(mob/living/player) as /list
|
|
var/list/serialized = list()
|
|
|
|
serialized["health"] = FLOOR((player.health / player.maxHealth * 100), 1)
|
|
if(issilicon(player))
|
|
serialized["job"] = player.job
|
|
serialized["icon"] = "borg"
|
|
return serialized
|
|
|
|
var/obj/item/card/id/id_card = player.GetIdCard()
|
|
serialized["job"] = id_card?.assignment || id_card?.rank
|
|
serialized["icon"] = ckey(id_card?.GetJobName() || "unknown") // ckey for formatting
|
|
|
|
var/job = player.mind?.assigned_role
|
|
if (isnull(job))
|
|
return serialized
|
|
|
|
serialized["mind_job"] = job
|
|
// var/datum/outfit/outfit = job.get_outfit()
|
|
// if (isnull(outfit))
|
|
// return serialized
|
|
|
|
// var/datum/id_trim/trim = outfit.id_trim
|
|
// if (!isnull(trim))
|
|
// serialized["mind_icon"] = trim::sechud_icon_state
|
|
return serialized
|
|
|
|
/// Gets a list: Misc data and whether it's critical. Handles all snowflakey type cases
|
|
/datum/orbit_menu/proc/get_misc_data(atom/movable/atom_poi) as /list
|
|
var/list/misc = list()
|
|
var/critical = FALSE
|
|
|
|
misc["ref"] = REF(atom_poi)
|
|
misc["full_name"] = atom_poi.name
|
|
|
|
// Display the supermatter crystal integrity
|
|
if(istype(atom_poi, /obj/machinery/power/supermatter))
|
|
var/obj/machinery/power/supermatter/crystal = atom_poi
|
|
var/integrity = round(crystal.get_integrity())
|
|
misc["extra"] = "Integrity: [integrity]%"
|
|
|
|
if(integrity < 10)
|
|
critical = TRUE
|
|
|
|
return list(misc, critical)
|
|
|
|
// 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["extra"] = "Location: [holder?.real_name || "Unsecured"]"
|
|
|
|
return list(misc, critical)
|
|
|
|
// Display singuloths if they exist
|
|
if(istype(atom_poi, /obj/singularity))
|
|
var/obj/singularity/singulo = atom_poi
|
|
misc["extra"] = "Energy: [round(singulo.energy)]"
|
|
|
|
if(singulo.current_size > 2)
|
|
critical = TRUE
|
|
|
|
return list(misc, critical)
|
|
|
|
// Display the shuttle
|
|
if (istype(atom_poi, /obj/overmap/entity/visitable/ship))
|
|
var/obj/overmap/entity/visitable/ship/shuttle = atom_poi
|
|
// see shuttle.get_scan_data
|
|
if (!shuttle.is_moving())
|
|
misc["extra"] = "Ship is stationary."
|
|
else
|
|
misc["extra"] = "Heading: [shuttle.get_heading()] Velocity: [shuttle.get_speed_legacy() * 1000]"
|
|
|
|
// TODO somehow figure out the station ship & its shuttle then flag it as critical
|
|
return list(misc, critical)
|
|
|
|
return list(misc, critical)
|