mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 04:27:35 +01:00
Merge remote-tracking branch 'upstream/master' into diagnostic-hud-fixes-and-upgrade
This commit is contained in:
@@ -26,9 +26,12 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/ghostvision = TRUE //is the ghost able to see things humans can't?
|
||||
var/seedarkness = TRUE
|
||||
var/data_hud_seen = FALSE //this should one of the defines in __DEFINES/hud.dm
|
||||
var/seerads = FALSE // can the ghost see radiation?
|
||||
/// Defines from __DEFINES/hud.dm go here based on which huds the ghost has activated.
|
||||
var/list/data_hud_seen = list()
|
||||
var/ghost_orbit = GHOST_ORBIT_CIRCLE
|
||||
var/health_scan = FALSE //does the ghost have health scanner mode on? by default it should be off
|
||||
var/datum/orbit_menu/orbit_menu
|
||||
|
||||
/mob/dead/observer/New(mob/body=null, flags=1)
|
||||
set_invisibility(GLOB.observer_default_invisibility)
|
||||
@@ -41,7 +44,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
/mob/dead/observer/proc/open_spawners_menu)
|
||||
|
||||
// Our new boo spell.
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/boo(null))
|
||||
AddSpell(new /obj/effect/proc_holder/spell/targeted/click/boo(null))
|
||||
|
||||
can_reenter_corpse = flags & GHOST_CAN_REENTER
|
||||
started_as_observer = flags & GHOST_IS_OBSERVER
|
||||
@@ -53,7 +56,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
if(ismob(body))
|
||||
T = get_turf(body) //Where is the body located?
|
||||
attack_log_old = body.attack_log_old //preserve our attack logs by copying them to our ghost
|
||||
logs = body.logs.Copy()
|
||||
|
||||
var/mutable_appearance/MA = copy_appearance(body)
|
||||
if(body.mind && body.mind.name)
|
||||
@@ -86,7 +88,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
real_name = name
|
||||
|
||||
//starts ghosts off with all HUDs.
|
||||
toggle_medHUD()
|
||||
toggle_all_huds_on(body)
|
||||
..()
|
||||
|
||||
/mob/dead/observer/Destroy()
|
||||
@@ -94,6 +96,11 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
GLOB.ghost_images -= ghostimage
|
||||
QDEL_NULL(ghostimage)
|
||||
updateallghostimages()
|
||||
if(orbit_menu)
|
||||
SStgui.close_uis(orbit_menu)
|
||||
QDEL_NULL(orbit_menu)
|
||||
if (seerads)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/mob/dead/observer/examine(mob/user)
|
||||
@@ -101,6 +108,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
if(!invisibility)
|
||||
. += "It seems extremely obvious."
|
||||
|
||||
/mob/dead/observer/process()
|
||||
if(seerads)
|
||||
show_rads(5)
|
||||
|
||||
// This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening
|
||||
// Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density
|
||||
// You might recognize these things as "fucking ridiculous to put in an appearance"
|
||||
@@ -159,8 +170,6 @@ Works together with spawning an observer, noted above.
|
||||
else
|
||||
GLOB.non_respawnable_keys[ckey] = 1
|
||||
ghost.key = key
|
||||
if(!(ghost.client && ghost.client.holder) && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
|
||||
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
|
||||
return ghost
|
||||
|
||||
/*
|
||||
@@ -284,7 +293,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return 1
|
||||
|
||||
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source)
|
||||
/mob/dead/observer/proc/notify_cloning(message, sound, atom/source)
|
||||
if(message)
|
||||
to_chat(src, "<span class='ghostalert'>[message]</span>")
|
||||
if(source)
|
||||
@@ -307,82 +316,70 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/proc/show_me_the_hud(hud_index)
|
||||
var/datum/atom_hud/H = GLOB.huds[hud_index]
|
||||
H.add_hud_to(src)
|
||||
data_hud_seen |= hud_index
|
||||
|
||||
/mob/dead/observer/proc/remove_the_hud(hud_index) //remove old huds
|
||||
var/datum/atom_hud/H = GLOB.huds[hud_index]
|
||||
H.remove_hud_from(src)
|
||||
data_hud_seen -= hud_index
|
||||
|
||||
/mob/dead/observer/verb/toggle_medHUD()
|
||||
/mob/dead/observer/verb/open_hud_panel()
|
||||
set category = "Ghost"
|
||||
set name = "Toggle All/Sec/Med/Diag HUDs"
|
||||
set desc = "Toggles the HUDs."
|
||||
set name = "Ghost HUD Panel"
|
||||
if(!client)
|
||||
return
|
||||
GLOB.ghost_hud_panel.ui_interact(src)
|
||||
|
||||
switch(data_hud_seen) //give new huds
|
||||
if(FALSE)
|
||||
data_hud_seen = DATA_HUD_DIAGNOSTIC_ADVANCED + DATA_HUD_SECURITY_ADVANCED + DATA_HUD_MEDICAL_ADVANCED
|
||||
show_me_the_hud(DATA_HUD_DIAGNOSTIC_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_SECURITY_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
to_chat(src, "<span class='notice'>All HUDs enabled.</span>")
|
||||
if(DATA_HUD_DIAGNOSTIC_ADVANCED + DATA_HUD_SECURITY_ADVANCED + DATA_HUD_MEDICAL_ADVANCED)
|
||||
data_hud_seen = DATA_HUD_SECURITY_ADVANCED
|
||||
remove_the_hud(DATA_HUD_DIAGNOSTIC_ADVANCED)
|
||||
remove_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
to_chat(src, "<span class='notice'>Security HUD set.</span>")
|
||||
if(DATA_HUD_SECURITY_ADVANCED)
|
||||
data_hud_seen = DATA_HUD_MEDICAL_ADVANCED
|
||||
remove_the_hud(DATA_HUD_SECURITY_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
to_chat(src, "<span class='notice'>Medical HUD set.</span>")
|
||||
if(DATA_HUD_MEDICAL_ADVANCED)
|
||||
data_hud_seen = DATA_HUD_DIAGNOSTIC_ADVANCED
|
||||
remove_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_DIAGNOSTIC_ADVANCED)
|
||||
to_chat(src, "<span class='notice'>Diagnostic HUD set.</span>")
|
||||
else
|
||||
data_hud_seen = FALSE
|
||||
remove_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
to_chat(src, "<span class='notice'>HUDs disabled.</span>")
|
||||
|
||||
|
||||
/mob/dead/observer/verb/toggle_antagHUD()
|
||||
set category = "Ghost"
|
||||
set name = "Toggle AntagHUD"
|
||||
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
|
||||
if(!config.antag_hud_allowed && !client.holder)
|
||||
to_chat(src, "<span class='warning'>Admins have disabled this for this round.</span>")
|
||||
/**
|
||||
* Toggles on all HUDs for the ghost player.
|
||||
*
|
||||
* Enables antag HUD only if the ghost belongs to an admin.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - A reference to the ghost's old mob. This argument is required since `src` does not have a `client` at this point.
|
||||
*/
|
||||
/mob/dead/observer/proc/toggle_all_huds_on(mob/user)
|
||||
show_me_the_hud(DATA_HUD_DIAGNOSTIC_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_SECURITY_ADVANCED)
|
||||
show_me_the_hud(DATA_HUD_MEDICAL_ADVANCED)
|
||||
if(!check_rights((R_ADMIN | R_MOD), FALSE, user))
|
||||
return
|
||||
if(!client)
|
||||
return
|
||||
var/mob/dead/observer/M = src
|
||||
if(jobban_isbanned(M, "AntagHUD"))
|
||||
to_chat(src, "<span class='danger'>You have been banned from using this feature</span>")
|
||||
return
|
||||
if(config.antag_hud_restricted && !M.has_enabled_antagHUD && !check_rights(R_ADMIN|R_MOD,0))
|
||||
var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No")
|
||||
if(response == "No") return
|
||||
M.can_reenter_corpse = 0
|
||||
if(M in GLOB.respawnable_list)
|
||||
GLOB.respawnable_list -= M
|
||||
if(!M.has_enabled_antagHUD && !check_rights(R_ADMIN|R_MOD,0))
|
||||
M.has_enabled_antagHUD = 1
|
||||
antagHUD = TRUE
|
||||
for(var/datum/atom_hud/antag/H in GLOB.huds)
|
||||
H.add_hud_to(src)
|
||||
|
||||
//var/datum/atom_hud/A = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
//var/adding_hud = (usr in A.hudusers) ? 0 : 1
|
||||
|
||||
for(var/datum/atom_hud/antag/H in (GLOB.huds))
|
||||
if(!M.antagHUD)
|
||||
H.add_hud_to(usr)
|
||||
else
|
||||
H.remove_hud_from(usr)
|
||||
if(!M.antagHUD)
|
||||
to_chat(usr, "AntagHud Toggled ON")
|
||||
M.antagHUD = 1
|
||||
/mob/dead/observer/proc/set_radiation_view(enabled)
|
||||
if (enabled)
|
||||
seerads = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
to_chat(usr, "AntagHud Toggled OFF")
|
||||
M.antagHUD = 0
|
||||
seerads = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/mob/dead/observer/verb/set_dnr()
|
||||
set name = "Set DNR"
|
||||
set category = "Ghost"
|
||||
set desc = "Prevent your character from being revived."
|
||||
|
||||
if(!isobserver(src)) // Somehow
|
||||
return
|
||||
if(!can_reenter_corpse)
|
||||
to_chat(src, "<span class='warning'>You are already set to DNR!</span>")
|
||||
return
|
||||
if(!mind || QDELETED(mind.current))
|
||||
to_chat(src, "<span class='warning'>You have no body.</span>")
|
||||
return
|
||||
if(mind.current.stat != DEAD)
|
||||
to_chat(src, "<span class='warning'>Your body is still alive!</span>")
|
||||
return
|
||||
|
||||
var/choice = alert(src, "If you enable this, your body will be unrevivable for the remainder of the round.", "Are you sure?", "Yes", "No")
|
||||
if(choice == "Yes")
|
||||
to_chat(src, "<span class='boldnotice'>Do Not Revive state enabled.</span>")
|
||||
create_log(MISC_LOG, "DNR Enabled")
|
||||
can_reenter_corpse = FALSE
|
||||
if(!QDELETED(mind.current)) // Could change while they're choosing
|
||||
mind.current.med_hud_set_status()
|
||||
|
||||
/mob/dead/observer/proc/dead_tele()
|
||||
set category = "Ghost"
|
||||
@@ -393,7 +390,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "Not when you're not dead!")
|
||||
return
|
||||
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", GLOB.ghostteleportlocs)
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", SSmapping.ghostteleportlocs)
|
||||
A.on_close(CALLBACK(src, .proc/teleport))
|
||||
|
||||
/mob/dead/observer/proc/teleport(area/thearea)
|
||||
@@ -416,9 +413,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Orbit" // "Haunt"
|
||||
set desc = "Follow and orbit a mob."
|
||||
|
||||
var/list/mobs = getpois(FALSE, TRUE, TRUE, TRUE)
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
|
||||
A.on_close(CALLBACK(src, .proc/ManualFollow))
|
||||
if(!orbit_menu)
|
||||
orbit_menu = new(src)
|
||||
|
||||
orbit_menu.ui_interact(src)
|
||||
|
||||
// This is the ghost's follow verb with an argument
|
||||
/mob/dead/observer/proc/ManualFollow(atom/movable/target)
|
||||
@@ -574,12 +572,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/verb/view_manifest()
|
||||
set name = "View Crew Manifest"
|
||||
set category = "Ghost"
|
||||
|
||||
var/dat
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
|
||||
src << browse(dat, "window=manifest;size=370x420;can_close=1")
|
||||
GLOB.generic_crew_manifest.ui_interact(usr, state = GLOB.observer_state)
|
||||
|
||||
//this is called when a ghost is drag clicked to something.
|
||||
/mob/dead/observer/MouseDrop(atom/over)
|
||||
@@ -590,7 +583,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
return ..()
|
||||
|
||||
/proc/ghost_follow_link(var/atom/target, var/atom/ghost)
|
||||
/proc/ghost_follow_link(atom/target, atom/ghost)
|
||||
if((!target) || (!ghost)) return
|
||||
if(isAI(target)) // AI core/eye follow links
|
||||
var/mob/living/silicon/ai/A = target
|
||||
@@ -624,7 +617,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
if(href_list["jump"])
|
||||
var/mob/target = locate(href_list["jump"])
|
||||
var/mob/A = usr;
|
||||
var/mob/A = usr
|
||||
to_chat(A, "Teleporting to [target]...")
|
||||
//var/mob/living/silicon/ai/A = locate(href_list["track2"]) in GLOB.mob_list
|
||||
if(target && target != usr)
|
||||
@@ -648,8 +641,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Toggle Anonymous Dead-chat"
|
||||
set category = "Ghost"
|
||||
set desc = "Toggles showing your key in dead chat."
|
||||
client.prefs.ghost_anonsay = !client.prefs.ghost_anonsay
|
||||
to_chat(src, "As a ghost, your key will [(client.prefs.ghost_anonsay) ? "no longer" : "now"] be shown when you speak in dead chat.</span>")
|
||||
client.prefs.toggles2 ^= PREFTOGGLE_2_ANONDCHAT
|
||||
to_chat(src, "As a ghost, your key will [(client.prefs.toggles2 & PREFTOGGLE_2_ANONDCHAT) ? "no longer" : "now"] be shown when you speak in dead chat.</span>")
|
||||
client.prefs.save_preferences(src)
|
||||
|
||||
/mob/dead/observer/verb/toggle_ghostsee()
|
||||
@@ -694,6 +687,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
updateghostimages()
|
||||
|
||||
/mob/dead/observer/can_see_reagents()
|
||||
return TRUE
|
||||
|
||||
/proc/updateallghostimages()
|
||||
for(var/mob/dead/observer/O in GLOB.player_list)
|
||||
O.updateghostimages()
|
||||
@@ -735,19 +731,26 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
//overriden here and in /mob/living for different point span classes and sanity checks
|
||||
/mob/dead/observer/pointed(atom/A as mob|obj|turf in view())
|
||||
if(!..())
|
||||
return 0
|
||||
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A].</span>")
|
||||
return 1
|
||||
return FALSE
|
||||
var/follow_link
|
||||
if(invisibility) // Only show the button if the ghost is not visible to the living
|
||||
follow_link = " ([ghost_follow_link(A, src)])"
|
||||
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A][follow_link].</span>")
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/proc/incarnate_ghost()
|
||||
if(!client)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/new_char = new(get_turf(src))
|
||||
client.prefs.copy_to(new_char)
|
||||
client.prefs.active_character.copy_to(new_char)
|
||||
if(mind)
|
||||
mind.active = TRUE
|
||||
mind.transfer_to(new_char)
|
||||
if(mind.vampire)
|
||||
mind.vampire.owner = new_char
|
||||
mind.vampire.powers.Cut()
|
||||
mind.vampire.check_vampire_upgrade(FALSE)
|
||||
else
|
||||
new_char.key = key
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/datum/orbit_menu
|
||||
var/mob/dead/observer/owner
|
||||
|
||||
/datum/orbit_menu/New(mob/dead/observer/new_owner)
|
||||
if(!istype(new_owner))
|
||||
qdel(src)
|
||||
owner = new_owner
|
||||
|
||||
/datum/orbit_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Orbit", "Orbit", 700, 500, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/orbit_menu/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("orbit")
|
||||
var/ref = params["ref"]
|
||||
|
||||
var/atom/movable/poi = (locate(ref) in GLOB.mob_list) || (locate(ref) in GLOB.poi_list)
|
||||
if(poi == null)
|
||||
. = TRUE
|
||||
return
|
||||
owner.ManualFollow(poi)
|
||||
. = TRUE
|
||||
if("refresh")
|
||||
update_static_data(owner, ui)
|
||||
. = TRUE
|
||||
|
||||
/datum/orbit_menu/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/alive = list()
|
||||
var/list/antagonists = list()
|
||||
var/list/dead = list()
|
||||
var/list/ghosts = list()
|
||||
var/list/misc = list()
|
||||
var/list/npcs = list()
|
||||
|
||||
var/list/pois = getpois(mobs_only = FALSE, skip_mindless = FALSE)
|
||||
for(var/name in pois)
|
||||
var/mob/M = pois[name]
|
||||
if(name == null)
|
||||
if(pois[name] && M.type)
|
||||
stack_trace("getpois returned something under a null name. Type: [M.type]")
|
||||
else
|
||||
stack_trace("getpois returned a null value")
|
||||
continue
|
||||
|
||||
var/list/serialized = list()
|
||||
serialized["name"] = "[name]" // stringify it; If it's null or something - we'd like to know it and fix getpois()
|
||||
if(serialized["name"] != name)
|
||||
stack_trace("getpois returned something under a non-string name [name] - [pois[name]] - [M.type]")
|
||||
continue
|
||||
|
||||
serialized["ref"] = "\ref[M]"
|
||||
|
||||
if(istype(M))
|
||||
if(isnewplayer(M)) // People in the lobby screen; only have their ckey as a name.
|
||||
continue
|
||||
if(isobserver(M) && M.client)
|
||||
ghosts += list(serialized)
|
||||
else if(M.mind == null)
|
||||
npcs += list(serialized)
|
||||
else if(M.stat == DEAD)
|
||||
dead += list(serialized)
|
||||
else
|
||||
alive += list(serialized)
|
||||
|
||||
var/datum/mind/mind = M.mind
|
||||
if(user.antagHUD)
|
||||
// If a mind is many antags at once, we'll display all of them, each
|
||||
// under their own antag sub-section.
|
||||
// This is arguably better, than picking one of the antag datums at random.
|
||||
|
||||
// Traitors - the only antags in `.antag_datums` at the time of writing.
|
||||
for(var/_A in mind.antag_datums)
|
||||
var/datum/antagonist/A = _A
|
||||
var/antag_serialized = serialized.Copy()
|
||||
antag_serialized["antag"] = A.name
|
||||
antagonists += list(antag_serialized)
|
||||
|
||||
// Not-very-datumized antags follow
|
||||
// Associative list of antag name => whether this mind is this antag
|
||||
var/other_antags = list(
|
||||
"Changeling" = (mind.changeling != null),
|
||||
"Vampire" = (mind.vampire != null),
|
||||
)
|
||||
if(SSticker && SSticker.mode)
|
||||
other_antags += list(
|
||||
"Blob" = (mind.special_role == SPECIAL_ROLE_BLOB),
|
||||
"Cultist" = (mind in SSticker.mode.cult),
|
||||
"Wizard" = (mind in SSticker.mode.wizards),
|
||||
"Wizard's Apprentice" = (mind in SSticker.mode.apprentices),
|
||||
"Nuclear Operative" = (mind in SSticker.mode.syndicates),
|
||||
"Shadowling" = (mind in SSticker.mode.shadows),
|
||||
"Shadowling Thrall" = (mind in SSticker.mode.shadowling_thralls),
|
||||
"Abductor" = (mind in SSticker.mode.abductors),
|
||||
"Revolutionary" = (mind in SSticker.mode.revolutionaries),
|
||||
"Head Revolutionary" = (mind in SSticker.mode.head_revolutionaries)
|
||||
)
|
||||
|
||||
for(var/antag_name in other_antags)
|
||||
var/is_antag = other_antags[antag_name]
|
||||
if(!is_antag)
|
||||
continue
|
||||
var/antag_serialized = serialized.Copy()
|
||||
antag_serialized["antag"] = antag_name
|
||||
antagonists += list(antag_serialized)
|
||||
|
||||
// Player terror spiders have their own category to help see how much there are.
|
||||
// Not in the above block because terrors can be known whether AHUD is on or not.
|
||||
if(isterrorspider(M))
|
||||
var/list/antag_serialized = serialized.Copy()
|
||||
antag_serialized["antag"] = "Terror Spider"
|
||||
antagonists += list(antag_serialized)
|
||||
else if(istype(M, /mob/living/simple_animal/revenant))
|
||||
var/list/antag_serialized = serialized.Copy()
|
||||
antag_serialized["antag"] = "Revenant"
|
||||
antagonists += list(antag_serialized)
|
||||
else
|
||||
misc += list(serialized)
|
||||
|
||||
data["alive"] = alive
|
||||
data["antagonists"] = antagonists
|
||||
data["dead"] = dead
|
||||
data["ghosts"] = ghosts
|
||||
data["misc"] = misc
|
||||
data["npcs"] = npcs
|
||||
return data
|
||||
@@ -1,20 +1,10 @@
|
||||
/mob/dead/observer/say(var/message)
|
||||
/mob/dead/observer/say(message)
|
||||
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
log_ghostsay(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<span class='warning'>You cannot talk in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
if(src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
. = src.say_dead(message)
|
||||
return say_dead(message)
|
||||
|
||||
|
||||
/mob/dead/observer/emote(act, type, message, force)
|
||||
@@ -29,7 +19,7 @@
|
||||
log_ghostemote(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot emote in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
@@ -38,11 +28,11 @@
|
||||
|
||||
. = src.emote_dead(message)
|
||||
|
||||
/mob/dead/observer/handle_track(var/message, var/verb = "says", var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
|
||||
/mob/dead/observer/handle_track(message, verb = "says", mob/speaker = null, speaker_name, atom/follow_target, hard_to_hear)
|
||||
return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
|
||||
|
||||
/mob/dead/observer/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
|
||||
/mob/dead/observer/handle_speaker_name(mob/speaker = null, vname, hard_to_hear)
|
||||
var/speaker_name = ..()
|
||||
if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker) && !istype(speaker, /mob/living/automatedannouncer)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
return speaker_name
|
||||
|
||||
@@ -9,22 +9,38 @@ GLOBAL_LIST_INIT(boo_phrases, list(
|
||||
"It feels like someone's standing behind you.",
|
||||
))
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/boo
|
||||
/obj/effect/proc_holder/spell/targeted/click/boo
|
||||
name = "Boo!"
|
||||
desc = "Fuck with the living."
|
||||
selection_deactivated_message = "<span class='shadowling'>Your presence will not be known. For now.</span>"
|
||||
selection_activated_message = "<span class='shadowling'>You prepare to reach across the veil. <b>Left-click to influence a target!</b></span>"
|
||||
auto_target_single = FALSE
|
||||
allowed_type = /atom // No subtypes are safe from spookage.
|
||||
|
||||
ghost = TRUE
|
||||
|
||||
action_icon_state = "boo"
|
||||
school = "transmutation"
|
||||
charge_max = 600
|
||||
charge_max = 2 MINUTES
|
||||
starts_charged = FALSE
|
||||
clothes_req = 0
|
||||
stat_allowed = 1
|
||||
invocation = ""
|
||||
invocation_type = "none"
|
||||
range = 1 // Or maybe 3?
|
||||
range = 20
|
||||
// no need to spam admins regarding boo casts
|
||||
create_logs = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/boo/cast(list/targets, mob/user = usr)
|
||||
for(var/turf/T in targets)
|
||||
T.get_spooked()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/click/boo/cast(list/targets, mob/user = usr)
|
||||
var/atom/target = targets[1]
|
||||
ASSERT(istype(target))
|
||||
|
||||
if(target.get_spooked())
|
||||
var/area/spook_zone = get_area(target)
|
||||
if (spook_zone.is_haunted == TRUE)
|
||||
to_chat(usr, "<span class='shadowling'>The veil is weak in [spook_zone], it took less effort to influence [target].</span>")
|
||||
charge_counter = charge_max / 2
|
||||
return
|
||||
|
||||
charge_counter = charge_max * 0.9 // We've targetted a non-spookable object! Try again fast!
|
||||
|
||||
Reference in New Issue
Block a user