mirror of
https://github.com/Yawn-Wider/YWPolarisVore.git
synced 2026-08-24 21:47:21 +01:00
Soulcatchers were trying to periodically backup the caught mind but stumbling into runtimes because the mind backups were relying on humanmob exclusive gender var that the brainmobs did not have.
583 lines
18 KiB
Plaintext
583 lines
18 KiB
Plaintext
//These two also have NIF FLAG representations. These are the local setting representations.
|
|
#define NIF_SC_CATCHING_ME 0x1
|
|
#define NIF_SC_CATCHING_OTHERS 0x2
|
|
//These are purely local setings flags, without global representation.
|
|
#define NIF_SC_ALLOW_EARS 0x4
|
|
#define NIF_SC_ALLOW_EYES 0x8
|
|
#define NIF_SC_BACKUPS 0x10
|
|
#define NIF_SC_PROJECTING 0x20
|
|
|
|
///////////
|
|
// Soulcatcher - Like a posibrain, sorta!
|
|
/datum/nifsoft/soulcatcher
|
|
name = "Soulcatcher"
|
|
desc = "A mind storage and processing system capable of capturing and supporting human-level minds in a small VR space."
|
|
list_pos = NIF_SOULCATCHER
|
|
cost = 100 //If I wanna trap people's minds and lood them, then by god I'll do so.
|
|
wear = 1
|
|
p_drain = 0.01
|
|
|
|
var/setting_flags = (NIF_SC_CATCHING_OTHERS|NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES|NIF_SC_BACKUPS|NIF_SC_PROJECTING)
|
|
var/list/brainmobs = list()
|
|
var/inside_flavor = "A small completely white room with a couch, and a window to what seems to be the outside world. A small sign in the corner says 'Configure Me'."
|
|
|
|
New()
|
|
..()
|
|
load_settings()
|
|
|
|
Destroy()
|
|
QDEL_LIST_NULL(brainmobs)
|
|
return ..()
|
|
|
|
activate()
|
|
if((. = ..()))
|
|
show_settings(nif.human)
|
|
spawn(0)
|
|
deactivate()
|
|
|
|
deactivate()
|
|
if((. = ..()))
|
|
return TRUE
|
|
|
|
stat_text()
|
|
return "Change Settings ([brainmobs.len] minds)"
|
|
|
|
install()
|
|
if((. = ..()))
|
|
nif.set_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER) //Required on install, because other_flags aren't sufficient for our complicated settings.
|
|
nif.human.verbs |= /mob/living/carbon/human/proc/nsay
|
|
nif.human.verbs |= /mob/living/carbon/human/proc/nme
|
|
|
|
uninstall()
|
|
QDEL_LIST_NULL(brainmobs)
|
|
if((. = ..()) && nif && nif.human) //Sometimes NIFs are deleted outside of a human
|
|
nif.human.verbs -= /mob/living/carbon/human/proc/nsay
|
|
nif.human.verbs -= /mob/living/carbon/human/proc/nme
|
|
|
|
proc/save_settings()
|
|
nif.save_data["[list_pos]"] = inside_flavor
|
|
return TRUE
|
|
|
|
proc/load_settings()
|
|
var/load = nif.save_data["[list_pos]"]
|
|
if(load)
|
|
inside_flavor = load
|
|
return TRUE
|
|
|
|
proc/notify_into(var/message)
|
|
var/sound = nif.good_sound
|
|
|
|
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice'>[message]</span>\"")
|
|
nif.human << sound
|
|
|
|
for(var/brainmob in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
|
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice'>[message]</span>\"")
|
|
brainmob << sound
|
|
|
|
proc/say_into(var/message, var/mob/living/sender, var/mob/eyeobj)
|
|
var/sender_name = eyeobj ? eyeobj.name : sender.name
|
|
|
|
//AR Projecting
|
|
if(eyeobj)
|
|
sender.eyeobj.visible_message("<b>[sender_name]</b> says, \"[message]\"")
|
|
|
|
//Not AR Projecting
|
|
else
|
|
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"")
|
|
for(var/brainmob in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
|
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"")
|
|
|
|
log_nsay(message,nif.human.real_name,sender)
|
|
|
|
proc/emote_into(var/message, var/mob/living/sender, var/mob/eyeobj)
|
|
var/sender_name = eyeobj ? eyeobj.name : sender.name
|
|
|
|
//AR Projecting
|
|
if(eyeobj)
|
|
sender.eyeobj.visible_message("[sender_name] [message]")
|
|
|
|
//Not AR Projecting
|
|
else
|
|
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> [message]")
|
|
for(var/brainmob in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
|
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> [message]")
|
|
|
|
log_nme(message,nif.human.real_name,sender)
|
|
|
|
proc/show_settings(var/mob/living/carbon/human/H)
|
|
set waitfor = FALSE
|
|
var/settings_list = list(
|
|
"Catching You \[[setting_flags & NIF_SC_CATCHING_ME ? "Enabled" : "Disabled"]\]" = NIF_SC_CATCHING_ME,
|
|
"Catching Prey \[[setting_flags & NIF_SC_CATCHING_OTHERS ? "Enabled" : "Disabled"]\]" = NIF_SC_CATCHING_OTHERS,
|
|
"Ext. Hearing \[[setting_flags & NIF_SC_ALLOW_EARS ? "Enabled" : "Disabled"]\]" = NIF_SC_ALLOW_EARS,
|
|
"Ext. Vision \[[setting_flags & NIF_SC_ALLOW_EYES ? "Enabled" : "Disabled"]\]" = NIF_SC_ALLOW_EYES,
|
|
"Mind Backups \[[setting_flags & NIF_SC_BACKUPS ? "Enabled" : "Disabled"]\]" = NIF_SC_BACKUPS,
|
|
"AR Projecting \[[setting_flags & NIF_SC_PROJECTING ? "Enabled" : "Disabled"]\]" = NIF_SC_PROJECTING,
|
|
"Design Inside",
|
|
"Erase Contents")
|
|
var/choice = input(nif.human,"Select a setting to modify:","Soulcatcher NIFSoft") as null|anything in settings_list
|
|
if(choice in settings_list)
|
|
switch(choice)
|
|
|
|
if("Design Inside")
|
|
var/new_flavor = input(nif.human, "Type what the prey sees after being 'caught'. This will be \
|
|
printed after an intro ending with: \"Around you, you see...\" to the prey. If you already \
|
|
have prey, this will be printed to them after \"Your surroundings change to...\". Limit 2048 char.", \
|
|
"VR Environment", html_decode(inside_flavor)) as message
|
|
new_flavor = sanitize(new_flavor, MAX_MESSAGE_LEN*2)
|
|
inside_flavor = new_flavor
|
|
nif.notify("Updating VR environment...")
|
|
for(var/brain in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/CS = brain
|
|
to_chat(CS,"<span class='notice'>Your surroundings change to...</span>\n[inside_flavor]")
|
|
save_settings()
|
|
return TRUE
|
|
|
|
if("Erase Contents")
|
|
var/mob/living/carbon/brain/caught_soul/brainpick = input(nif.human,"Select a mind to delete:","Erase Mind") as null|anything in brainmobs
|
|
|
|
var/warning = alert(nif.human,"Are you SURE you want to erase \"[brainpick]\"?","Erase Mind","CANCEL","DELETE","CANCEL")
|
|
if(warning == "DELETE")
|
|
brainmobs -= brainpick
|
|
qdel(brainpick)
|
|
return TRUE
|
|
|
|
//Must just be a flag without special handling then.
|
|
else
|
|
var/flag = settings_list[choice]
|
|
return toggle_setting(flag)
|
|
|
|
proc/toggle_setting(var/flag)
|
|
setting_flags ^= flag
|
|
|
|
var/notify_message
|
|
//Special treatment
|
|
switch(flag)
|
|
if(NIF_SC_BACKUPS)
|
|
if(setting_flags & NIF_SC_BACKUPS)
|
|
notify_message = "Mind backup system enabled."
|
|
else
|
|
notify_message = "Mind backup system disabled."
|
|
|
|
if(NIF_SC_CATCHING_ME)
|
|
if(setting_flags & NIF_SC_CATCHING_ME)
|
|
nif.set_flag(NIF_O_SCMYSELF,NIF_FLAGS_OTHER)
|
|
else
|
|
nif.clear_flag(NIF_O_SCMYSELF,NIF_FLAGS_OTHER)
|
|
if(NIF_SC_CATCHING_OTHERS)
|
|
if(setting_flags & NIF_SC_CATCHING_OTHERS)
|
|
nif.set_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER)
|
|
else
|
|
nif.clear_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER)
|
|
if(NIF_SC_ALLOW_EARS)
|
|
if(setting_flags & NIF_SC_ALLOW_EARS)
|
|
for(var/brain in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/brainmob = brain
|
|
brainmob.ext_deaf = FALSE
|
|
notify_message = "External audio input enabled."
|
|
else
|
|
for(var/brain in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/brainmob = brain
|
|
brainmob.ext_deaf = TRUE
|
|
notify_message = "External audio input disabled."
|
|
if(NIF_SC_ALLOW_EYES)
|
|
if(setting_flags & NIF_SC_ALLOW_EYES)
|
|
for(var/brain in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/brainmob = brain
|
|
brainmob.ext_blind = FALSE
|
|
notify_message = "External video input enabled."
|
|
else
|
|
for(var/brain in brainmobs)
|
|
var/mob/living/carbon/brain/caught_soul/brainmob = brain
|
|
brainmob.ext_blind = TRUE
|
|
notify_message = "External video input disabled."
|
|
|
|
if(notify_message)
|
|
notify_into(notify_message)
|
|
|
|
return TRUE
|
|
|
|
//Complex version for catching in-round characters
|
|
proc/catch_mob(var/mob/M)
|
|
if(!M.mind) return
|
|
|
|
//Create a new brain mob
|
|
var/mob/living/carbon/brain/caught_soul/brainmob = new(nif)
|
|
brainmob.nif = nif
|
|
brainmob.soulcatcher = src
|
|
brainmob.container = src
|
|
brainmob.stat = 0
|
|
brainmob.silent = FALSE
|
|
dead_mob_list -= brainmob
|
|
brainmob.add_language(LANGUAGE_GALCOM)
|
|
brainmobs |= brainmob
|
|
|
|
//Put the mind and player into the mob
|
|
M.mind.transfer_to(brainmob)
|
|
brainmob.name = brainmob.mind.name
|
|
brainmob.real_name = brainmob.mind.name
|
|
|
|
//If we caught our owner, special settings.
|
|
if(M == nif.human)
|
|
brainmob.ext_deaf = FALSE
|
|
brainmob.ext_blind = FALSE
|
|
brainmob.parent_mob = TRUE
|
|
|
|
//If they have these values, apply them
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
brainmob.dna = H.dna
|
|
brainmob.ooc_notes = H.ooc_notes
|
|
brainmob.timeofhostdeath = H.timeofdeath
|
|
SStranscore.m_backup(brainmob.mind,0) //It does ONE, so medical will hear about it.
|
|
|
|
//Else maybe they're a joining ghost
|
|
else if(isobserver(M))
|
|
brainmob.transient = TRUE
|
|
qdel(M) //Bye ghost
|
|
|
|
//Give them a flavortext message
|
|
var/message = "<span class='notice'>Your vision fades in a haze of static, before returning.</span>\n\
|
|
Around you, you see...\n\
|
|
[inside_flavor]"
|
|
|
|
to_chat(brainmob,message)
|
|
|
|
//Reminder on how this works to host
|
|
if(brainmobs.len == 1) //Only spam this on the first one
|
|
to_chat(nif.human,"<span class='notice'>Your occupant's messages/actions can only be seen by you, and you can \
|
|
send messages that only they can hear/see by using the NSay and NMe verbs (or the *nsay and *nme emotes).</span>")
|
|
|
|
//Announce to host and other minds
|
|
notify_into("New mind loaded: [brainmob.name]")
|
|
return TRUE
|
|
|
|
////////////////
|
|
//The caught mob
|
|
/mob/living/carbon/brain/caught_soul
|
|
name = "recorded mind"
|
|
desc = "A mind recorded and being played on digital hardware."
|
|
use_me = 1
|
|
var/ext_deaf = FALSE //Forbidden from 'ear' access on host
|
|
var/ext_blind = FALSE //Forbidden from 'eye' access on host
|
|
var/parent_mob = FALSE //If we've captured our owner
|
|
var/transient = FALSE //Someone who ghosted into the NIF
|
|
var/client_missing = 0 //How long the client has been missing
|
|
universal_understand = TRUE
|
|
|
|
var/obj/item/device/nif/nif
|
|
var/datum/nifsoft/soulcatcher/soulcatcher
|
|
var/identifying_gender
|
|
|
|
/mob/living/carbon/brain/caught_soul/Login()
|
|
..()
|
|
plane_holder.set_vis(VIS_AUGMENTED, TRUE)
|
|
identifying_gender = client.prefs.identifying_gender
|
|
|
|
/mob/living/carbon/brain/caught_soul/Destroy()
|
|
if(soulcatcher)
|
|
soulcatcher.notify_into("Mind unloaded: [name]")
|
|
soulcatcher.brainmobs -= src
|
|
soulcatcher = null
|
|
if(eyeobj)
|
|
reenter_soulcatcher()
|
|
eyeobj = null //This SHOULD be null already, reenter_soulcatcher destroys and nulls it, but safety first.
|
|
container = null
|
|
nif = null
|
|
return ..()
|
|
|
|
/mob/living/carbon/brain/caught_soul/Life()
|
|
if(!mind || !key)
|
|
qdel(src)
|
|
return
|
|
|
|
. = ..()
|
|
|
|
if(!parent_mob && !transient &&(life_tick % 150 == 0) && soulcatcher.setting_flags & NIF_SC_BACKUPS)
|
|
SStranscore.m_backup(mind,0) //Passed 0 means "Don't touch the nif fields on the mind record"
|
|
|
|
life_tick++
|
|
|
|
if(!client)
|
|
if(++client_missing == 300)
|
|
qdel(src)
|
|
return
|
|
else
|
|
client_missing = 0
|
|
|
|
if(parent_mob) return
|
|
|
|
//If they're blinded
|
|
if(ext_blind)
|
|
eye_blind = 5
|
|
client.screen.Remove(global_hud.whitense)
|
|
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
|
else
|
|
eye_blind = 0
|
|
clear_fullscreens()
|
|
client.screen.Add(global_hud.whitense)
|
|
|
|
//If they're deaf
|
|
if(ext_deaf)
|
|
ear_deaf = 5
|
|
else
|
|
ear_deaf = 0
|
|
|
|
/mob/living/carbon/brain/caught_soul/hear_say()
|
|
if(ext_deaf || !client)
|
|
return FALSE
|
|
..()
|
|
|
|
/mob/living/carbon/brain/caught_soul/show_message()
|
|
if(ext_blind || !client)
|
|
return FALSE
|
|
..()
|
|
|
|
/mob/living/carbon/brain/caught_soul/me_verb_subtle()
|
|
set hidden = TRUE
|
|
|
|
return FALSE
|
|
|
|
/mob/living/carbon/brain/caught_soul/whisper()
|
|
set hidden = TRUE
|
|
|
|
return FALSE
|
|
|
|
/mob/living/carbon/brain/caught_soul/face_atom(var/atom/A)
|
|
if(eyeobj)
|
|
return eyeobj.face_atom(A)
|
|
else
|
|
return ..(A)
|
|
|
|
/mob/living/carbon/brain/caught_soul/set_dir(var/direction)
|
|
if(eyeobj)
|
|
return eyeobj.set_dir(direction)
|
|
else
|
|
return ..(direction)
|
|
|
|
/mob/living/carbon/brain/caught_soul/say(var/message)
|
|
if(silent) return FALSE
|
|
soulcatcher.say_into(message,src,eyeobj)
|
|
|
|
/mob/living/carbon/brain/caught_soul/emote(var/act,var/m_type=1,var/message = null)
|
|
if(silent) return FALSE
|
|
if (act == "me")
|
|
if(silent)
|
|
return
|
|
if (src.client)
|
|
if (client.prefs.muted & MUTE_IC)
|
|
src << "<span class='warning'>You cannot send IC messages (muted).</span>"
|
|
return
|
|
if (stat)
|
|
return
|
|
if(!(message))
|
|
return
|
|
return custom_emote(m_type, message)
|
|
else
|
|
return FALSE
|
|
|
|
/mob/living/carbon/brain/caught_soul/custom_emote(var/m_type, var/message)
|
|
if(silent) return FALSE
|
|
soulcatcher.emote_into(message,src,eyeobj)
|
|
|
|
/mob/living/carbon/brain/caught_soul/resist()
|
|
set name = "Resist"
|
|
set category = "IC"
|
|
|
|
to_chat(src,"<span class='warning'>There's no way out! You're stuck in VR.</span>")
|
|
|
|
///////////////////
|
|
//A projected AR soul thing
|
|
/mob/observer/eye/ar_soul
|
|
plane = PLANE_AUGMENTED
|
|
icon = 'icons/obj/machines/ar_elements.dmi'
|
|
icon_state = "beacon"
|
|
var/mob/living/carbon/human/parent_human
|
|
|
|
/mob/observer/eye/ar_soul/New(var/mob/brainmob, var/human)
|
|
ASSERT(brainmob && brainmob.client)
|
|
..()
|
|
|
|
owner = brainmob //Set eyeobj's owner
|
|
parent_human = human //E-z reference to human
|
|
sight |= SEE_SELF //Always see yourself
|
|
|
|
name = "[brainmob.name] (AR)" //Set the name
|
|
real_name = brainmob.real_name //And the OTHER name
|
|
|
|
forceMove(get_turf(parent_human))
|
|
GLOB.moved_event.register(parent_human, src, /mob/observer/eye/ar_soul/proc/human_moved)
|
|
|
|
//Time to play dressup
|
|
if(brainmob.client.prefs)
|
|
var/mob/living/carbon/human/dummy/dummy = new ()
|
|
brainmob.client.prefs.dress_preview_mob(dummy)
|
|
sleep(1 SECOND) //Strange bug in preview code? Without this, certain things won't show up. Yay race conditions?
|
|
dummy.regenerate_icons()
|
|
|
|
var/icon/new_icon = getHologramIcon(getCompoundIcon(dummy))
|
|
qdel(dummy)
|
|
icon = new_icon
|
|
|
|
/mob/observer/eye/ar_soul/Destroy()
|
|
if(parent_human) //It's POSSIBLE they've been deleted before the NIF somehow
|
|
GLOB.moved_event.unregister(parent_human, src)
|
|
parent_human = null
|
|
return ..()
|
|
|
|
/mob/observer/eye/ar_soul/EyeMove(n, direct)
|
|
var/initial = initial(sprint)
|
|
var/max_sprint = 50
|
|
|
|
if(cooldown && cooldown < world.timeofday)
|
|
sprint = initial
|
|
|
|
for(var/i = 0; i < max(sprint, initial); i += 20)
|
|
var/turf/stepn = get_turf(get_step(src, direct))
|
|
if(stepn)
|
|
set_dir(direct)
|
|
if(can_see(parent_human, stepn))
|
|
forceMove(stepn)
|
|
|
|
cooldown = world.timeofday + 5
|
|
if(acceleration)
|
|
sprint = min(sprint + 0.5, max_sprint)
|
|
else
|
|
sprint = initial
|
|
return 1
|
|
|
|
/mob/observer/eye/ar_soul/proc/human_moved()
|
|
if(!can_see(parent_human,src))
|
|
forceMove(get_turf(parent_human))
|
|
|
|
///////////////////
|
|
//The catching hook
|
|
/hook/death/proc/nif_soulcatcher(var/mob/living/carbon/human/H)
|
|
if(!istype(H) || !H.mind) return TRUE //Hooks must return TRUE
|
|
|
|
if(isbelly(H.loc)) //Died in someone
|
|
var/obj/belly/B = H.loc
|
|
var/mob/living/carbon/human/HP = B.owner
|
|
if(istype(HP) && HP.nif && HP.nif.flag_check(NIF_O_SCOTHERS,NIF_FLAGS_OTHER))
|
|
var/datum/nifsoft/soulcatcher/SC = HP.nif.imp_check(NIF_SOULCATCHER)
|
|
SC.catch_mob(H)
|
|
else if(H.nif && H.nif.flag_check(NIF_O_SCMYSELF,NIF_FLAGS_OTHER)) //They are caught in their own NIF
|
|
var/datum/nifsoft/soulcatcher/SC = H.nif.imp_check(NIF_SOULCATCHER)
|
|
SC.catch_mob(H)
|
|
|
|
return TRUE
|
|
|
|
///////////////////
|
|
//Verbs for humans
|
|
/mob/living/carbon/human/proc/nsay(message as text|null)
|
|
set name = "NSay"
|
|
set desc = "Speak into your NIF's Soulcatcher."
|
|
set category = "IC"
|
|
|
|
if(!nif)
|
|
to_chat(src,"<span class='warning'>You can't use NSay without a NIF.</span>")
|
|
return
|
|
var/datum/nifsoft/soulcatcher/SC = nif.imp_check(NIF_SOULCATCHER)
|
|
if(!SC)
|
|
to_chat(src,"<span class='warning'>You need the Soulcatcher software to use NSay.</span>")
|
|
return
|
|
if(!SC.brainmobs.len)
|
|
to_chat(src,"<span class='warning'>You need a loaded mind to use NSay.</span>")
|
|
return
|
|
if(!message)
|
|
message = input("Type a message to say.","Speak into Soulcatcher") as text|null
|
|
if(message)
|
|
var/sane_message = sanitize(message)
|
|
SC.say_into(sane_message,src)
|
|
|
|
/mob/living/carbon/human/proc/nme(message as text|null)
|
|
set name = "NMe"
|
|
set desc = "Emote into your NIF's Soulcatcher."
|
|
set category = "IC"
|
|
|
|
if(!nif)
|
|
to_chat(src,"<span class='warning'>You can't use NMe without a NIF.</span>")
|
|
return
|
|
var/datum/nifsoft/soulcatcher/SC = nif.imp_check(NIF_SOULCATCHER)
|
|
if(!SC)
|
|
to_chat(src,"<span class='warning'>You need the Soulcatcher software to use NMe.</span>")
|
|
return
|
|
if(!SC.brainmobs.len)
|
|
to_chat(src,"<span class='warning'>You need a loaded mind to use NMe.</span>")
|
|
return
|
|
|
|
if(!message)
|
|
message = input("Type an action to perform.","Emote into Soulcatcher") as text|null
|
|
if(message)
|
|
var/sane_message = sanitize(message)
|
|
SC.emote_into(sane_message,src)
|
|
|
|
///////////////////
|
|
//Verbs for soulbrains
|
|
/mob/living/carbon/brain/caught_soul/verb/ar_project()
|
|
set name = "AR Project"
|
|
set desc = "Project your form into Augmented Reality for those around your predator with the appearance of your loaded character."
|
|
set category = "Soulcatcher"
|
|
|
|
if(eyeobj)
|
|
to_chat(src,"<span class='warning'>You're already projecting in AR!</span>")
|
|
return
|
|
|
|
if(!(soulcatcher.setting_flags & NIF_SC_PROJECTING))
|
|
to_chat(src,"<span class='warning'>Projecting from this NIF has been disabled!</span>")
|
|
return
|
|
|
|
if(!client || !client.prefs)
|
|
return //Um...
|
|
|
|
eyeobj = new/mob/observer/eye/ar_soul(src,nif.human)
|
|
soulcatcher.notify_into("[src] now AR projecting.")
|
|
|
|
/mob/living/carbon/brain/caught_soul/verb/jump_to_owner()
|
|
set name = "Jump to Owner"
|
|
set desc = "Jump your projection back to the owner of the soulcatcher you're inside."
|
|
set category = "Soulcatcher"
|
|
|
|
if(!eyeobj)
|
|
to_chat(src,"<span class='warning'>You're not projecting into AR!</span>")
|
|
return
|
|
|
|
eyeobj.forceMove(get_turf(nif))
|
|
|
|
/mob/living/carbon/brain/caught_soul/verb/reenter_soulcatcher()
|
|
set name = "Re-enter Soulcatcher"
|
|
set desc = "Leave AR projection and drop back into the soulcatcher."
|
|
set category = "Soulcatcher"
|
|
|
|
if(!eyeobj)
|
|
to_chat(src,"<span class='warning'>You're not projecting into AR!</span>")
|
|
return
|
|
|
|
QDEL_NULL(eyeobj)
|
|
soulcatcher.notify_into("[src] ended AR projection.")
|
|
|
|
/mob/living/carbon/brain/caught_soul/verb/nsay(message as text|null)
|
|
set name = "NSay"
|
|
set desc = "Speak into the NIF's Soulcatcher (circumventing AR speaking)."
|
|
set category = "Soulcatcher"
|
|
|
|
if(!message)
|
|
message = input("Type a message to say.","Speak into Soulcatcher") as text|null
|
|
if(message)
|
|
var/sane_message = sanitize(message)
|
|
soulcatcher.say_into(sane_message,src,null)
|
|
|
|
/mob/living/carbon/brain/caught_soul/verb/nme(message as text|null)
|
|
set name = "NMe"
|
|
set desc = "Emote into the NIF's Soulcatcher (circumventing AR speaking)."
|
|
set category = "Soulcatcher"
|
|
|
|
if(!message)
|
|
message = input("Type an action to perform.","Emote into Soulcatcher") as text|null
|
|
if(message)
|
|
var/sane_message = sanitize(message)
|
|
soulcatcher.emote_into(sane_message,src,null)
|