Merge pull request #1660 from VOREStation/aro-scimprovements

Soulcatcher improvements
This commit is contained in:
Arokha Sieyes
2017-06-09 20:05:18 -04:00
committed by GitHub
3 changed files with 143 additions and 82 deletions
@@ -21,14 +21,12 @@
if(!SC)
to_chat(src,"<span class='warning'>You need the Soulcatcher software to use *nme.</span>")
return 1
if(!SC.brainmob.mind)
if(!SC.brainmobs.len)
to_chat(src,"<span class='warning'>You need a loaded mind to use *nme.</span>")
return 1
var/nifmessage = sanitize(input("Type a message to say.","Speak into NIF") as text|null)
if(nifmessage)
nifmessage = "<b>\[\icon[nif.big_icon]NIF\]</b> <b>[src]</b> speaks, \"[nifmessage]\""
to_chat(SC.brainmob,nifmessage)
to_chat(src,nifmessage)
SC.say_into(nifmessage,src.real_name)
return 1
if ("nme")
@@ -39,14 +37,12 @@
if(!SC)
to_chat(src,"<span class='warning'>You need the Soulcatcher software to use *nme.</span>")
return 1
if(!SC.brainmob.mind)
if(!SC.brainmobs.len)
to_chat(src,"<span class='warning'>You need a loaded mind to use *nme.</span>")
return 1
var/nifmessage = sanitize(input("Type an action to perform.","Emote into NIF") as text|null)
if(nifmessage)
nifmessage = "<b>\[\icon[nif.big_icon]NIF\]</b> <b>[src]</b> [nifmessage]"
to_chat(SC.brainmob,nifmessage)
to_chat(src,nifmessage)
SC.emote_into(nifmessage,src.real_name)
return 1
if ("flip")
+127 -62
View File
@@ -4,36 +4,31 @@
//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
///////////
// Soulcatcher - Like a posibrain, sorta!
/datum/nifsoft/soulcatcher
name = "Soulcatcher"
desc = "A mind storage and processing system capable of capturing and supporting a single human-intelligence mind on body death, into a small VR space."
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 = 1265
wear = 1
p_drain = 0.01
var/setting_flags = (NIF_SC_CATCHING_ME|NIF_SC_CATCHING_OTHERS|NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES)
var/mob/living/carbon/brain/caught_soul/brainmob
var/setting_flags = (NIF_SC_CATCHING_ME|NIF_SC_CATCHING_OTHERS|NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES|NIF_SC_BACKUPS)
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()
..()
brainmob = new(nif)
brainmob.nif = nif
brainmob.container = src
brainmob.stat = 0
brainmob.silent = FALSE
dead_mob_list -= src.brainmob
brainmob.add_language(LANGUAGE_GALCOM)
load_settings()
Destroy()
if(brainmob)
brainmob.container = null
qdel(brainmob)
for(var/brain in brainmobs)
var/mob/living/carbon/brain/caught_soul/CS = brain
qdel(CS)
brainmobs.Cut()
..()
install()
@@ -57,7 +52,7 @@
return TRUE
stat_text()
return "Change Settings[brainmob.mind ? " (Mind Stored)" : ""]"
return "Change Settings ([brainmobs.len] minds)"
proc/save_settings()
nif.save_data["[list_pos]"] = inside_flavor
@@ -69,17 +64,32 @@
inside_flavor = load
return TRUE
proc/say_into(var/message, var/sender)
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender]</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]</b> speaks, \"[message]\"")
proc/emote_into(var/message, var/sender)
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender]</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]</b> [message]")
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 Others \[[setting_flags & NIF_SC_CATCHING_OTHERS ? "Enabled" : "Disabled"]\]" = NIF_SC_CATCHING_OTHERS,
"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,
"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 \
@@ -88,22 +98,20 @@
new_flavor = sanitize(new_flavor)
inside_flavor = new_flavor
nif.notify("Updating VR environment...")
to_chat(brainmob,"<span class='notice'>Your surroundings change to...</span>\n[inside_flavor]")
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")
if(brainmob && brainmob.mind)
var/warning = alert(nif.human,"Are you SURE you want to erase [brainmob.mind.name]?","Erase Mind","CANCEL","DELETE","CANCEL")
if(warning == "DELETE")
brainmob.ghostize()
qdel(brainmob)
brainmob = new(nif)
nif.notify("Mind deleted!",TRUE)
return TRUE
else
nif.notify("No mind to delete!",TRUE)
return TRUE
var/mob/living/carbon/brain/caught_soul/brainpick = input(nif.human,"Select a mind to delete:","Erase Mind") as null|anything in brainmobs
if(!brainpick) return
var/warning = alert(nif.human,"Are you SURE you want to erase [brainpick.name]?","Erase Mind","CANCEL","DELETE","CANCEL")
if(warning == "DELETE")
qdel(brainpick)
return TRUE
//Must just be a flag without special handling then.
else
@@ -115,6 +123,12 @@
//Special treatment
switch(flag)
if(NIF_SC_BACKUPS)
if(setting_flags & NIF_SC_BACKUPS)
emote_into(" - Mind backup system enabled.","SOULCATCHER")
else
emote_into(" - Mind backup system disabled.","SOULCATCHER")
if(NIF_SC_CATCHING_ME)
if(setting_flags & NIF_SC_CATCHING_ME)
nif.set_flag(NIF_O_SCMYSELF,NIF_FLAGS_OTHER)
@@ -127,42 +141,74 @@
nif.clear_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER)
if(NIF_SC_ALLOW_EARS)
if(setting_flags & NIF_SC_ALLOW_EARS)
brainmob.ext_deaf = FALSE
to_chat(brainmob,"<b>\[\icon[nif.big_icon]NIF\]</b> <span class='notice'>Your access to your host's auditory sense has been unrestricted.</span>")
for(var/brain in brainmobs)
var/mob/living/carbon/brain/caught_soul/brainmob = brain
brainmob.ext_deaf = FALSE
emote_into(" - External audio input enabled.","SOULCATCHER")
else
brainmob.ext_deaf = TRUE
to_chat(brainmob,"<b>\[\icon[nif.big_icon]NIF\]</b> <span class='warning'>Your access to your host's auditory sense has been restricted.</span>")
for(var/brain in brainmobs)
var/mob/living/carbon/brain/caught_soul/brainmob = brain
brainmob.ext_deaf = TRUE
emote_into(" - External audio input disabled.","SOULCATCHER")
if(NIF_SC_ALLOW_EYES)
if(setting_flags & NIF_SC_ALLOW_EYES)
brainmob.ext_blind = FALSE
to_chat(brainmob,"<b>\[\icon[nif.big_icon]NIF\]</b> <span class='notice'>Your access to your host's visual sense has been unrestricted.</span>")
for(var/brain in brainmobs)
var/mob/living/carbon/brain/caught_soul/brainmob = brain
brainmob.ext_blind = FALSE
emote_into(" - External video input enabled.","SOULCATCHER")
else
brainmob.ext_blind = TRUE
to_chat(brainmob,"<b>\[\icon[nif.big_icon]NIF\]</b> <span class='warning'>Your access to your host's visual sense has been restricted.</span>")
for(var/brain in brainmobs)
var/mob/living/carbon/brain/caught_soul/brainmob = brain
brainmob.ext_blind = TRUE
emote_into(" - External video input disabled.","SOULCATCHER")
return TRUE
proc/catch_mob(var/mob/living/carbon/human/H)
if(istype(H))
if(H == nif.human) //Reset our permissions to be permissive to the owner.
brainmob.ext_deaf = FALSE
brainmob.ext_blind = FALSE
brainmob.parent_mob = TRUE
//Create a new brain mob
var/mob/living/carbon/brain/caught_soul/brainmob = new(nif)
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
brainmob.dna = H.dna
brainmob.timeofhostdeath = H.timeofdeath
brainmob.stat = 0
if(H.mind)
H.mind.transfer_to(brainmob)
brainmob.name = brainmob.mind.name
var/message = "<span class='notice'>Your vision fades in a haze of static, before returning.</span>\nAround you, you see...\n[inside_flavor]"
to_chat(brainmob,message)
nif.notify("Mind loaded into VR space: [brainmob.name]")
//If we caught our owner, special settings.
if(H == nif.human)
brainmob.ext_deaf = FALSE
brainmob.ext_blind = FALSE
brainmob.parent_mob = TRUE
transcore.m_backup(H.mind,H) //ONE backup. Won't be called in life due to avoidance of parent_mob backups.
//Set some basics on the mob.
brainmob.dna = H.dna
brainmob.timeofhostdeath = H.timeofdeath
brainmob.stat = 0
//Put the mind and player into the mob
H.mind.transfer_to(brainmob)
brainmob.name = brainmob.mind.name
transcore.m_backup(brainmob.mind,0) //It does ONE, so medical will hear about it.
//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 'say'ing either '*nsay' or '*nme'.</span>")
return TRUE
return FALSE
//Announce to host and other minds
emote_into(" - New mind loaded: [brainmob.name]","SOULCATCHER")
return TRUE
////////////////
//The caught mob
@@ -174,16 +220,33 @@
var/ext_blind = FALSE //Forbidden from 'eye' access on host
var/parent_mob = FALSE //If we've captured our owner
var/obj/item/device/nif/nif
var/datum/nifsoft/soulcatcher/soulcatcher
/mob/living/carbon/brain/caught_soul/Destroy()
nif = null
if(soulcatcher)
soulcatcher.emote_into(" - Mind unloaded: [name]","SOULCATCHER")
soulcatcher.brainmobs -= src
soulcatcher = null
if(nif)
nif = null
if(mind && ckey)
src.ghostize()
container = null
..()
/mob/living/carbon/brain/caught_soul/Life()
if(!client) return
if(!mind)
qdel(src)
return
. = ..()
if(!parent_mob && (life_tick % 150 == 0) && soulcatcher.setting_flags & NIF_SC_BACKUPS)
transcore.m_backup(mind,0) //Passed 0 means "Don't touch the nif fields on the mind record"
life_tick++
if(!client) return
if(parent_mob) return
//If they're blinded
if(ext_blind)
@@ -214,8 +277,7 @@
/mob/living/carbon/brain/caught_soul/say(var/message)
if(parent_mob) return ..()
if(silent) return FALSE
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[name]</b> speaks, \"[message]\"")
to_chat(src,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[name]</b> speaks, \"[message]\"")
soulcatcher.say_into(message,src.name)
/mob/living/carbon/brain/caught_soul/emote(var/act,var/m_type=1,var/message = null)
if(parent_mob) return ..()
@@ -237,23 +299,26 @@
/mob/living/carbon/brain/caught_soul/custom_emote(var/m_type, var/message)
if(silent) return FALSE
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[name]</b> [message]")
to_chat(src,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[name]</b> [message]")
soulcatcher.emote_into(message,src.name)
/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>")
///////////////////
//The catching hook
/hook/death/proc/nif_soulcatcher(var/mob/living/carbon/human/H)
if(!istype(H)) return TRUE //Hooks must return TRUE
if(!istype(H) || !H.mind) return TRUE //Hooks must return TRUE
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)
if(!SC.brainmob.mind) //As long as they don't have one
SC.catch_mob(H,TRUE)
SC.catch_mob(H,TRUE)
else if(ishuman(H.loc)) //Died in someone
var/mob/living/carbon/human/HP = H.loc
if(HP.nif && HP.nif.flag_check(NIF_O_SCOTHERS,NIF_FLAGS_OTHER))
var/datum/nifsoft/soulcatcher/SC = HP.nif.imp_check(NIF_SOULCATCHER)
if(!SC.brainmob.mind) //As long as they don't have one
SC.catch_mob(H,FALSE)
SC.catch_mob(H,FALSE)
return TRUE
+12 -12
View File
@@ -50,6 +50,8 @@ var/datum/transhuman/infocore/transcore = new/datum/transhuman/infocore
if(mind.name in backed_up)
MR = backed_up[mind.name]
MR.last_update = world.time
//Pass a 0 to not change NIF status (because the elseif is checking for null)
if(nif)
MR.nif_path = nif.type
MR.nif_durability = nif.durability
@@ -59,7 +61,7 @@ var/datum/transhuman/infocore/transcore = new/datum/transhuman/infocore
var/datum/nifsoft/nifsoft = N
nifsofts += nifsoft.type
MR.nif_software = nifsofts
else
else if(isnull(nif)) //Didn't pass anything, so no NIF
MR.nif_path = null
MR.nif_durability = null
MR.nif_software = null
@@ -122,21 +124,18 @@ var/datum/transhuman/infocore/transcore = new/datum/transhuman/infocore
//Backend
var/ckey = ""
var/id_gender
var/id_gender = MALE
var/datum/mind/mind_ref
var/cryo_at
var/languages
var/mind_oocnotes
var/cryo_at = 0
var/languages = list()
var/mind_oocnotes = ""
var/nif_path
var/nif_durability
var/list/nif_software
/datum/transhuman/mind_record/New(var/datum/mind/mind,var/mob/living/carbon/human/M,var/obj/item/weapon/implant/backup/imp,var/add_to_db = 1)
ASSERT(mind && M && imp)
if(!istype(M))
return //Only works with humanoids.
ASSERT(mind)
//The mind!
mind_ref = mind
@@ -146,9 +145,10 @@ var/datum/transhuman/infocore/transcore = new/datum/transhuman/infocore
cryo_at = 0
//Mental stuff the game doesn't keep mentally
id_gender = M.identifying_gender
languages = M.languages.Copy()
mind_oocnotes = M.ooc_notes
if(istype(M))
id_gender = M.identifying_gender
languages = M.languages.Copy()
mind_oocnotes = M.ooc_notes
last_update = world.time