mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-14 01:18:40 +01:00
201592f6bd
Refactoring the entire destroy proc path from Mob Human all the way down to Atom while trying to find the causes for the damn mob human hard deletes. This PR comprehensively reorganizes every single stray snowflake var used by /atom/ all the way to /mob/living/carbon/human, and makes sure that every var that COULD store a reference, is now cleared during the entirety of the Mob Destroy() parent hierarchy. This may very well be the end of the lag war. In total, I've hunted down and cleared 39 hanging references between /atom and /mob/living/carbon/human --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com>
214 lines
6.7 KiB
Plaintext
214 lines
6.7 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 = FALSE
|
|
/// 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)
|
|
orbiting_ref = null
|
|
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 = XGM_PRESSURE(environment)
|
|
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)
|