Files
cbd3f1ea2b Dna, Bodyrecord, Xenochi Revive Refactor (#17732)
* changeling fix

* Move body spawning into BR

* small fix, organization

* replace xeno regen

* Body descriptor system removed

* Revert "Body descriptor system removed"

This reverts commit 04a0aa3ac8.

* massive bodyrecord copy refactor

* this too

* dna copying is now sane

* make a merge easier

* better file for this

* may we ensure peace everlasting

* linter

* oops, missed the test

* fixed up

* furthering the test

* different way to check

* looking promising

* required exclusions

* more test

* another tweak

* setup better

* globin

* test name change

* really mess up that monkey

* gradient style to UI entry

* scramble ignore

* illegal species

* scramble fix

* grad fix, more test fixes

* doing that right

* need these too

* missed defferal

* missed pathing

* documentation wall

* blood color needs a safety

* promethean prep

* this early set isn't needed

* some protections

* fixed waddler nulltest

* failure test

* intensify scan

* second fail test

* noticing

* dna test case

* other dna test case

* Test is bunk

* huge dna cleanup, better signal

* don't edit these

* documentation

* Do not use loc = src.loc

* oops

* Use weakrefs in pods

* remaining weakrefs

* reduce changes in pr

* cloning computer does not rotate itself when used

* moved body design to new BR code, and fixed screen size

* badlinting

* updated

* No instakilling teshari

* jiggles you

* TGUI

* move along

* m ove it

* Update AppearanceChangerMisc.tsx

* this too

* gender is race whoops

* Allow old clonepods too

* xc

* further encapsulation and some fixes

* oops

* misc not race

* separated that

* custom footsteps exchanged

* Custom speech bubble and xenochi stuff

* Update xenochimera.dm

* remove digileg snowflake

* try this

* Update xenochimera.dm

* proper close

* Always update our DNA

* awa

* extremely laggy check removed, actually useless

* explaining

* lower delay time

* slower jigglin

* Revert "slower jigglin"

This reverts commit c801f7d7f5.

* disable appearance editor due to various issues

* Promie love

* xenochi vanity test

* lmao

* earwings

* wording and slot revival

* mobvar?

* Phasing out specific shapeshifter appearances

If you have access to changing your icon, you can change whatever you want.

* saveslot loading

* more

* synth

* Shoot out limbs

* almost ready

* nullcheck

* xenochi revive handles size and weight correctly

* weaver cocoon updated xenochi internal record after tf

* cannot remove from lost limbs

* limbs properly respawn on slot revive

---------

Co-authored-by: C.L. <killer65311@gmail.com>
2025-06-09 08:20:42 -07:00

169 lines
5.9 KiB
Plaintext

/*
* This file contains the alien mind-transfer pod, or 'Alien Reality' pod.
*/
/obj/machinery/vr_sleeper/alien
name = "strange pod"
desc = "A strange machine with what appears to be a comfortable, if quite vertical, bed. Numerous mechanical cylinders dot the ceiling, their purpose uncertain."
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "alienpod_0"
base_state = "alienpod_"
eject_dead = FALSE
var/produce_species = SPECIES_REPLICANT // The default species produced. Will be overridden if randomize_species is true.
var/randomize_species = FALSE
var/list/possible_species // Do we make the newly produced body a random species?
perfect_replica = TRUE //All alien VR sleepers make perfect replicas.
spawn_with_clothing = FALSE //alien VR sleepers do not spawn with clothing.
/obj/machinery/vr_sleeper/alien/Initialize(mapload)
. = ..()
if(possible_species && possible_species.len)
produce_species = pick(possible_species)
/obj/machinery/vr_sleeper/alien/process()
if(stat & (BROKEN))
if(occupant)
perform_exit()
visible_message(span_infoplain(span_bold("\The [src]") + " emits a low droning sound, before the pod door clicks open."))
return
else if(eject_dead && occupant && occupant.stat == DEAD)
visible_message(span_warning("\The [src] sounds an alarm, swinging its hatch open."))
perform_exit()
/obj/machinery/vr_sleeper/alien/attackby(var/obj/item/I, var/mob/user)
add_fingerprint(user)
if(occupant && (istype(I, /obj/item/healthanalyzer) || istype(I, /obj/item/robotanalyzer)))
I.attack(occupant, user)
return
/obj/machinery/vr_sleeper/alien/eject()
set src in view(1)
set category = "Object"
if(usr.incapacitated())
return
if(stat & (BROKEN) || (eject_dead && occupant && occupant.stat == DEAD))
perform_exit()
else
go_out()
add_fingerprint(usr)
/obj/machinery/vr_sleeper/alien/go_out()
if(!occupant)
return
if(avatar)
if(tgui_alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", list("Yes", "No")) != "Yes")
return
avatar.exit_vr() //We don't poof! We're a actual, living entity that isn't restrained by VR zones!
if(!occupant) //This whole thing needs cleaned up later, but this works for now.
return
if(occupant && occupant.client)
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
occupant.forceMove(get_turf(src))
occupant.vr_link = null //The machine remembers the avatar. 1 avatar per machine. So the vr_link isn't needed anymore.
occupant = null
for(var/atom/movable/A in src) // In case an object was dropped inside or something
if(A == circuit)
continue
if(A in component_parts)
continue
A.loc = src.loc
update_use_power(USE_POWER_IDLE)
update_icon()
/obj/machinery/vr_sleeper/alien/enter_vr()
// No mob to transfer a mind from
if(!occupant)
return
// No mind to transfer
if(!occupant.mind)
return
// Mob doesn't have an active consciousness to send/receive from
if(occupant.stat == DEAD && !occupant.client)
return
if(QDELETED(avatar)) //This REALLY needs to be changed to weakrefs
avatar = null
if(avatar && !occupant.stat)
to_chat(occupant,span_alien("\The [src] begins to [pick("whir","hum","pulse")] as a screen appears in front of you."))
if(tgui_alert(occupant, "This pod is already linked. Are you certain you wish to engage?", "Commmit?", list("Yes", "No")) != "Yes")
visible_message(span_alien("\The [src] pulses!"))
perform_exit()
return
to_chat(occupant,span_alien("Your mind blurs as information bombards you."))
if(!avatar)
var/turf/T = get_turf(src)
if(!perfect_replica)
avatar = new(src, produce_species)
else
avatar = new(src, occupant.species.name)
// If the user has a non-default (Human) bodyshape, make it match theirs.
if(occupant.species.name != "Promethean" && occupant.species.name != "Human" && mirror_first_occupant)
avatar.shapeshifter_change_shape(occupant.species.name)
avatar.Sleeping(6)
occupant.enter_vr(avatar)
if(spawn_with_clothing)
job_master.EquipRank(avatar,"Visitor", 1, FALSE)
add_verb(avatar,/mob/living/carbon/human/proc/perform_exit_vr)
avatar.virtual_reality_mob = FALSE //THIS IS THE BIG DIFFERENCE WITH ALIEN VR PODS. THEY ARE NOT VR, THEY ARE REAL.
//This handles all the 'We make it look like ourself' code.
//We do this BEFORE any mob tf so prefs carry over properly!
if(perfect_replica)
avatar.species.create_organs(avatar) // Reset our organs/limbs.
avatar.restore_all_organs()
avatar.client.prefs.copy_to(avatar)
avatar.dna.ResetUIFrom(avatar)
avatar.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed
avatar.sync_organ_dna()
avatar.initialize_vessel()
SEND_SIGNAL(avatar, COMSIG_HUMAN_DNA_FINALIZED)
var/newname = sanitize(tgui_input_text(avatar, "Your mind feels foggy. You're certain your name is [occupant.real_name], but it could also be [avatar.name]. Would you like to change it to something else?", "Name change", null, MAX_NAME_LEN), MAX_NAME_LEN)
if (newname)
avatar.real_name = newname
avatar.forceMove(T)
visible_message(span_alium("\The [src] [pick("gurgles", "churns", "sloshes")] before spitting out \the [avatar]!"))
else
// There's only one body per one of these pods, so let's be kind.
var/newname = sanitize(tgui_input_text(avatar, "Your mind feels foggy. You're certain your name is [occupant.real_name], but it feels like it is [avatar.name]. Would you like to change it to something else?", "Name change", null, MAX_NAME_LEN), MAX_NAME_LEN)
if(newname)
avatar.real_name = newname
avatar.name = newname
occupant.enter_vr(avatar)
/*
* Subtypes
*/
/obj/machinery/vr_sleeper/alien/random_replicant
possible_species = list(SPECIES_REPLICANT, SPECIES_REPLICANT_ALPHA, SPECIES_REPLICANT_BETA)
/obj/machinery/vr_sleeper/alien/alpha_replicant
produce_species = SPECIES_REPLICANT_ALPHA
/obj/machinery/vr_sleeper/alien/beta_replicant
produce_species = SPECIES_REPLICANT_BETA