mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-22 21:38:47 +01:00
3d183d7262
<img width="700" height="848" alt="image" src="https://github.com/user-attachments/assets/e0db50af-35db-43c7-b78e-6c1ea5ac569c" /> you take a tiny little two year LOA and this happens this PR hits some large lag culprits: - UpdateOverlays() getting spammed by human/update_icon. This was 0.85% of server CPU time during the event. Doesn't sound like a whole lot but it's insane. 99% of it was caused by sloppy duplicate calls of update_icon in set_dir (as well as update icon itself!). Refactored to stop that - Makes Follow menu update manually, which cuts down on the 2.8 million REF() calls it made during the event. This was ~1% of CPU time including ui_data as well. - Gets rid of a bunch of random runtimes and some lighting-related harddels. - NanoUIs now clean themselves up when their owner qdels rather than forcing the owner to do REF(src) and close all matching UIs. saves us ~0.1% server cpu time! wowza!
213 lines
6.6 KiB
Plaintext
213 lines
6.6 KiB
Plaintext
/mob/abstract/ghost
|
|
stat = DEAD
|
|
|
|
/// Is the ghost able to see things humans can't?
|
|
var/ghostvision = TRUE
|
|
/// This variable generally controls whether a ghost has restrictions on where it can go or not (ex. if the ghost can bypass holy places).
|
|
var/has_ghost_restrictions = TRUE
|
|
/// If the ghost has antagHUD.
|
|
var/antagHUD = 0
|
|
/// Necessary for seeing wires.
|
|
var/obj/item/multitool/ghost_multitool
|
|
/// The POI we're orbiting.
|
|
var/orbiting_ref
|
|
|
|
/mob/abstract/ghost/Initialize(mapload)
|
|
. = ..()
|
|
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
|
see_invisible = SEE_INVISIBLE_OBSERVER
|
|
add_verb(src, /mob/abstract/ghost/proc/dead_tele)
|
|
ghost_multitool = new(src)
|
|
update_sight()
|
|
|
|
/mob/abstract/ghost/Destroy()
|
|
QDEL_NULL(ghost_multitool)
|
|
return ..()
|
|
|
|
/mob/abstract/ghost/Topic(href, href_list)
|
|
if (href_list["track"])
|
|
if(istype(href_list["track"],/mob))
|
|
var/mob/target = locate(href_list["track"]) in GLOB.mob_list
|
|
if(target)
|
|
ManualFollow(target)
|
|
else
|
|
var/atom/target = locate(href_list["track"])
|
|
if(istype(target))
|
|
ManualFollow(target)
|
|
|
|
/mob/abstract/ghost/ClickOn(atom/A, params)
|
|
if(!canClick())
|
|
return
|
|
setClickCooldown(4)
|
|
// You are responsible for checking config.ghost_interaction when you override this function
|
|
// Not all of them require checking, see below
|
|
A.attack_ghost(src)
|
|
|
|
/mob/abstract/ghost/Post_Incorpmove()
|
|
orbiting?.end_orbit(src)
|
|
|
|
/mob/abstract/ghost/orbit()
|
|
set_dir(2)//reset dir so the right directional sprites show up
|
|
return ..()
|
|
|
|
/mob/abstract/ghost/verb/toggle_darkness()
|
|
set name = "Toggle Darkness"
|
|
set category = "Ghost"
|
|
|
|
var/level_message
|
|
switch(lighting_alpha)
|
|
if(LIGHTING_PLANE_ALPHA_VISIBLE)
|
|
lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE
|
|
level_message = "half night vision"
|
|
if(LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE)
|
|
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
|
level_message = "three quarters night vision"
|
|
if(LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
|
|
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
|
|
level_message = "full night vision"
|
|
if(LIGHTING_PLANE_ALPHA_INVISIBLE)
|
|
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
|
level_message = "no night vision"
|
|
to_chat(src, SPAN_NOTICE("Night vision mode switched and saved to [level_message]."))
|
|
sync_lighting_plane_alpha()
|
|
|
|
/mob/abstract/ghost/verb/toggle_ghostsee()
|
|
set name = "Toggle Ghost Vision"
|
|
set category = "Ghost"
|
|
set desc = "Toggles your ability to see things only ghosts can see, like ghosts."
|
|
|
|
ghostvision = !ghostvision
|
|
update_sight()
|
|
to_chat(usr, SPAN_NOTICE("You [(ghostvision ? "now" : "no longer")] have ghost vision."))
|
|
|
|
/mob/abstract/ghost/proc/dead_tele()
|
|
set name = "Teleport"
|
|
set category = "Ghost"
|
|
set desc= "Teleport to a location."
|
|
|
|
if(!istype(usr, /mob/abstract/ghost))
|
|
to_chat(usr, SPAN_WARNING("You need to be a ghost!"))
|
|
return
|
|
|
|
var/area_name = tgui_input_list(src, "Select an area to teleport to.", "Teleport", GLOB.ghostteleportlocs)
|
|
|
|
remove_verb(usr, /mob/abstract/ghost/proc/dead_tele)
|
|
ADD_VERB_IN(usr, 30, /mob/abstract/ghost/proc/dead_tele)
|
|
|
|
var/area/thearea = GLOB.ghostteleportlocs[area_name]
|
|
if(!thearea)
|
|
return
|
|
|
|
var/list/L = list()
|
|
var/holyblock = FALSE
|
|
|
|
if(usr.invisibility <= SEE_INVISIBLE_LIVING || (usr.mind in GLOB.cult.current_antagonists))
|
|
for(var/turf/T in get_area_turfs(thearea))
|
|
if(!T.holy && has_ghost_restrictions)
|
|
L+=T
|
|
else
|
|
holyblock = TRUE
|
|
else
|
|
for(var/turf/T in get_area_turfs(thearea))
|
|
L+=T
|
|
|
|
if(!L || !L.len)
|
|
if(holyblock && has_ghost_restrictions)
|
|
to_chat(usr, SPAN_WARNING("This area has been entirely made into sacred grounds, you cannot enter it while you are in this plane of existence!"))
|
|
return
|
|
else
|
|
to_chat(usr, "No area available.")
|
|
return
|
|
|
|
var/turf/P = pick(L)
|
|
if(on_restricted_level(P.z) && has_ghost_restrictions)
|
|
to_chat(usr, "You can not teleport to this area.")
|
|
return
|
|
|
|
orbiting?.end_orbit(src)
|
|
usr.forceMove(pick(L))
|
|
|
|
/mob/abstract/ghost/verb/follow()
|
|
set name = "Follow"
|
|
set category = "Ghost"
|
|
set desc = "Follow and haunt a mob."
|
|
|
|
GLOB.follow_menu.ui_interact(src)
|
|
|
|
// This is the ghost's follow verb with an argument
|
|
/mob/abstract/ghost/proc/ManualFollow(var/atom/movable/target)
|
|
if(!target)
|
|
return FALSE
|
|
|
|
//Stops orbit if there's any; TG doesn't do this, but if you don't it breaks the orbiting reference
|
|
//if you are jumping from one mob to another, hence why we're doing it here
|
|
orbiting?.end_orbit(src)
|
|
|
|
var/list/icon_dimensions = get_icon_dimensions(target.icon)
|
|
var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5
|
|
orbitsize -= (orbitsize/ICON_SIZE_ALL)*(ICON_SIZE_ALL*0.25)
|
|
|
|
var/rot_seg = 30 //Let's make it simple and it's just a circle
|
|
|
|
orbit(target,orbitsize, FALSE, 20, rot_seg)
|
|
|
|
to_chat(src, SPAN_NOTICE("Now following \the <b>[target]</b>."))
|
|
update_sight()
|
|
return TRUE
|
|
|
|
/mob/abstract/ghost/proc/update_sight()
|
|
//if they are on a restricted level, then set the ghost vision for them.
|
|
if(on_restricted_level())
|
|
//On the restricted level they have the same sight as the mob
|
|
set_sight(sight&(~SEE_TURFS)&(~SEE_MOBS)&(~SEE_OBJS))
|
|
else
|
|
//Outside of the restrcited level, they have enhanced vision
|
|
set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
|
|
|
if(ghostvision)
|
|
set_see_invisible(SEE_INVISIBLE_OBSERVER) //overmap viewing breaks if this is lower
|
|
else
|
|
set_see_invisible(SEE_INVISIBLE_LIVING)
|
|
|
|
/mob/abstract/ghost/proc/on_restricted_level(var/check)
|
|
if(!check)
|
|
check = z
|
|
//Check if they are a staff member
|
|
if(check_rights(R_MOD|R_ADMIN|R_DEV, show_msg=FALSE, user=src))
|
|
return FALSE
|
|
|
|
//Check if the z level is in the restricted list
|
|
if (!(check in SSatlas.current_map.restricted_levels))
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
/mob/abstract/ghost/verb/analyze_air()
|
|
set name = "Analyze Air"
|
|
set category = "Ghost"
|
|
|
|
// Shamelessly copied from the Gas Analyzers
|
|
if(!isturf(loc))
|
|
return
|
|
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
|
|
var/pressure = environment.return_pressure()
|
|
var/total_moles = environment.total_moles
|
|
|
|
to_chat(src, SPAN_NOTICE("<B>Results:</B>"))
|
|
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
|
to_chat(src, SPAN_NOTICE("Pressure: [round(pressure,0.1)] kPa"))
|
|
else
|
|
to_chat(src, SPAN_WARNING("Pressure: [round(pressure,0.1)] kPa"))
|
|
if(total_moles)
|
|
for(var/g in environment.gas)
|
|
to_chat(src, SPAN_NOTICE("[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)"))
|
|
to_chat(src, SPAN_NOTICE("Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)"))
|
|
to_chat(src, SPAN_NOTICE("Heat Capacity: [round(environment.heat_capacity(),0.1)]"))
|
|
|
|
/mob/abstract/ghost/verb/view_manifest()
|
|
set name = "Show Crew Manifest"
|
|
set category = "Ghost"
|
|
SSrecords.open_manifest_tgui(usr)
|