var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
//SleeveMate!
/obj/item/device/sleevemate
name = "\improper SleeveMate 3700"
desc = "A hand-held sleeve management tool for performing one-time backups and managing mindstates."
icon = 'icons/obj/device_alt.dmi'
icon_state = "sleevemate"
item_state = "healthanalyzer"
slot_flags = SLOT_BELT
throwforce = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
matter = list(DEFAULT_WALL_MATERIAL = 200)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
var/datum/mind/stored_mind
var/ooc_notes = null //For holding prefs
//These don't perform any checks and need to be wrapped by checks
/obj/item/device/sleevemate/proc/clear_mind()
stored_mind = null
ooc_notes = null
update_icon()
/obj/item/device/sleevemate/proc/get_mind(mob/living/M)
ASSERT(M.mind)
ooc_notes = M.ooc_notes
stored_mind = M.mind
M.ghostize()
stored_mind.current = null
update_icon()
/obj/item/device/sleevemate/proc/put_mind(mob/living/M)
stored_mind.active = TRUE
stored_mind.transfer_to(M)
M.ooc_notes = ooc_notes
clear_mind()
/obj/item/device/sleevemate/attack(mob/living/M, mob/living/user)
// Gather potential subtargets
var/list/choices = list(M)
if(istype(M))
for(var/belly in M.vore_organs)
var/obj/belly/B = belly
for(var/mob/living/carbon/human/H in B) // I do want an istype
choices += H
// Subtargets
if(choices.len > 1)
var/mob/living/new_M = input(user, "Ambiguous target. Please validate target:", "Target Validation", M) as null|anything in choices
if(!new_M || !M.Adjacent(user))
return
M = new_M
if(ishuman(M))
scan_mob(M, user)
else
to_chat(user,"Not a compatible subject to work with!")
/obj/item/device/sleevemate/attack_self(mob/living/user)
if(!stored_mind)
to_chat(user,"No stored mind in \the [src].")
return
var/choice = alert(user,"What would you like to do?","Stored: [stored_mind.name]","Delete","Backup","Cancel")
if(!stored_mind || user.get_active_hand() != src)
return
switch(choice)
if("Delete")
to_chat(user,"Internal copy of [stored_mind.name] deleted.")
clear_mind()
if("Backup")
to_chat(user,"Internal copy of [stored_mind.name] backed up to database.")
SStranscore.m_backup(stored_mind,null,one_time = TRUE)
if("Cancel")
return
/obj/item/device/sleevemate/proc/scan_mob(mob/living/carbon/human/H, mob/living/user)
var/output = ""
output += "
[src.name] Scan Results
"
//Mind name
output += "Sleeved Mind: "
if(H.mind)
output += "[H.mind.name]
"
else
output += "Unknown/None
"
//Mind status
output += "Mind Status: "
if(H.client)
output += "Healthy
"
else
output += "Space Sleep Disorder
"
//Body status
output += "Sleeve Status: "
switch(H.stat)
if(CONSCIOUS)
output += "Alive
"
if(UNCONSCIOUS)
output += "Unconscious
"
if(DEAD)
output += "Deceased
"
else
output += "Unknown
"
//Mind/body comparison
output += "Sleeve Pair: "
if(!H.ckey)
output += "No mind in that body [stored_mind != null ? "\[Upload\]" : null]
"
else if(H.mind && ckey(H.mind.key) != H.ckey)
output += "May not be correct body
"
else if(H.mind && ckey(H.mind.key) == H.ckey)
output += "Appears to be correct mind in body
"
else
output += "Unable to perform comparison
"
//Actions
output += "
-- Possible Actions --
"
output += "Mind-Scan (One Time): \[Perform\]
"
output += "Body-Scan (One Time): \[Perform\]
"
//Saving a mind
output += "Store Full Mind: "
if(stored_mind)
output += "Already Stored ([stored_mind.name])
"
else if(H.mind)
output += "\[Perform\]
"
else
output += "Unable
"
//Soulcatcher transfer
if(H.nif)
var/datum/nifsoft/soulcatcher/SC = H.nif.imp_check(NIF_SOULCATCHER)
if(SC)
output += "
"
output += "Soulcatcher detected ([SC.brainmobs.len] minds)
"
for(var/mob/living/carbon/brain/caught_soul/mind in SC.brainmobs)
output += "[mind.name]: [mind.transient == FALSE ? "\[Load\]" : "Incompatible"]
"
if(stored_mind)
output += "Store in Soulcatcher: \[Perform\]
"
to_chat(user,output)
/obj/item/device/sleevemate/Topic(href, href_list)
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
//Sanity checking/href-hacking checking
if(usr.get_active_hand() != src)
to_chat(usr,"You're not holding \the [src].")
return
var/target_ref = href_list["target"]
var/mob/living/target = locate(target_ref) in mob_list
if(!target)
to_chat(usr,"Unable to operate on that target.")
return
if(!usr.Adjacent(target))
to_chat(usr,"You are too far from that target.")
return
//The actual options
if(href_list["mindscan"])
if(!target.mind || target.mind.name in prevent_respawns)
to_chat(usr,"Target seems totally braindead.")
return
var/nif
if(ishuman(target))
var/mob/living/carbon/human/H = target
nif = H.nif
persist_nif_data(H)
usr.visible_message("[usr] begins scanning [target]'s mind.","You begin scanning [target]'s mind.")
if(do_after(usr,8 SECONDS,target))
SStranscore.m_backup(target.mind,nif,one_time = TRUE)
to_chat(usr,"Mind backed up!")
else
to_chat(usr,"You must remain close to your target!")
return
if(href_list["bodyscan"])
if(!ishuman(target))
to_chat(usr,"Target is not of an acceeptable body type.")
return
var/mob/living/carbon/human/H = target
usr.visible_message("[usr] begins scanning [target]'s body.","You begin scanning [target]'s body.")
if(do_after(usr,8 SECONDS,target))
var/datum/transhuman/body_record/BR = new()
BR.init_from_mob(H, TRUE, TRUE)
to_chat(usr,"Body scanned!")
else
to_chat(usr,"You must remain close to your target!")
return
if(href_list["mindsteal"])
if(!target.mind || target.mind.name in prevent_respawns)
to_chat(usr,"Target seems totally braindead.")
return
if(stored_mind)
to_chat(usr,"There is already someone's mind stored inside")
return
var/choice = alert(usr,"This will remove the target's mind from their body (and from the game as long as they're in the sleevemate). You can put them into a (mindless) body, a NIF, or back them up for normal resleeving, but you should probably have a plan in advance so you don't leave them unable to interact for too long. Continue?","Confirmation","Continue","Cancel")
if(choice == "Continue" && usr.get_active_hand() == src && usr.Adjacent(target))
usr.visible_message("[usr] begins downloading [target]'s mind!","You begin downloading [target]'s mind!")
if(do_after(usr,35 SECONDS,target)) //This is powerful, yo.
if(!stored_mind && target.mind)
get_mind(target)
to_chat(usr,"Mind downloaded!")
return
if(href_list["mindput"])
if(!stored_mind)
to_chat(usr,"\The [src] no longer has a stored mind.")
return
var/mob/living/carbon/human/H = target
if(!istype(target))
return //href hacking only
if(!H.nif)
return //Lost it? or href hacking
var/datum/nifsoft/soulcatcher/SC = H.nif.imp_check(NIF_SOULCATCHER)
if(!SC)
return //Uninstalled it?
//Lazzzyyy.
if(!sleevemate_mob)
sleevemate_mob = new()
put_mind(sleevemate_mob)
SC.catch_mob(sleevemate_mob)
to_chat(usr,"Mind transferred into Soulcatcher!")
if(href_list["mindupload"])
if(!stored_mind)
to_chat(usr,"\The [src] no longer has a stored mind.")
return
if(!istype(target))
return
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(H.resleeve_lock && stored_mind.loaded_from_ckey != H.resleeve_lock)
to_chat(usr,"\[H] is protected from impersonation!")
return
usr.visible_message("[usr] begins uploading someone's mind into [target]!","You begin uploading a mind into [target]!")
if(do_after(usr,35 SECONDS,target))
if(!stored_mind)
to_chat(usr,"\The [src] no longer has a stored mind.")
return
put_mind(target)
to_chat(usr,"Mind transferred into [target]!")
if(href_list["mindrelease"])
if(stored_mind)
to_chat(usr,"There is already someone's mind stored inside")
return
var/mob/living/carbon/human/H = target
var/datum/nifsoft/soulcatcher/SC = H.nif.imp_check(NIF_SOULCATCHER)
if(!SC)
return
for(var/mob/living/carbon/brain/caught_soul/soul in SC.brainmobs)
if(soul.name == href_list["mindrelease"])
get_mind(soul)
qdel(soul)
to_chat(usr,"Mind downloaded!")
return
to_chat(usr,"Unable to find that mind in Soulcatcher!")
/obj/item/device/sleevemate/update_icon()
if(stored_mind)
icon_state = "[initial(icon_state)]_on"
else
icon_state = initial(icon_state)