mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-27 22:18:27 +01:00
replace xeno regen
This commit is contained in:
@@ -593,6 +593,8 @@
|
||||
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
|
||||
///Whenever EquipRanked is called, called after job is set
|
||||
#define COMSIG_JOB_RECEIVED "job_received"
|
||||
///When the initial spawn's records are saved. Regardless of pref for it.
|
||||
#define COMSIG_INITIAL_RECORDS "initial_record_save"
|
||||
|
||||
// /datum/species signals
|
||||
|
||||
|
||||
@@ -11,20 +11,29 @@
|
||||
'sound/effects/mob_effects/xenochimera/regen_3.ogg',
|
||||
'sound/effects/mob_effects/xenochimera/regen_5.ogg'
|
||||
)
|
||||
var/datum/transhuman/body_record/revival_record
|
||||
|
||||
/datum/component/xenochimera/Initialize()
|
||||
if(!ishuman(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
owner = parent
|
||||
RegisterSignal(owner, COMSIG_XENOCHIMERA_COMPONENT, PROC_REF(handle_comp))
|
||||
RegisterSignal(owner, COMSIG_INITIAL_RECORDS, PROC_REF(handle_record))
|
||||
add_verb(owner, /mob/living/carbon/human/proc/reconstitute_form)
|
||||
|
||||
/datum/component/xenochimera/Destroy(force)
|
||||
UnregisterSignal(owner, COMSIG_XENOCHIMERA_COMPONENT)
|
||||
UnregisterSignal(owner, COMSIG_INITIAL_RECORDS)
|
||||
remove_verb(owner, /mob/living/carbon/human/proc/reconstitute_form)
|
||||
qdel_null(revival_record)
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/datum/component/xenochimera/proc/handle_record()
|
||||
if(QDELETED(owner))
|
||||
return
|
||||
revival_record = new(owner)
|
||||
|
||||
/datum/component/xenochimera/proc/handle_comp()
|
||||
if(QDELETED(owner))
|
||||
return
|
||||
@@ -397,8 +406,8 @@
|
||||
var/old_nutrition = nutrition
|
||||
var/braindamage = min(5, max(0, (brainloss-1) * 0.5)) //brainloss is tricky to heal and might take a couple of goes to get rid of completely.
|
||||
var/uninjured=quickcheckuninjured()
|
||||
//I did have special snowflake code, but this is easier. //It's also EXTREMELY BAD AND LETS THEM SAVEFILE HACK.
|
||||
revive()
|
||||
xc.revival_record.rebuild_human_mob(src,FALSE)
|
||||
|
||||
mutations.Remove(HUSK)
|
||||
setBrainLoss(braindamage)
|
||||
species.update_vore_belly_def_variant()
|
||||
|
||||
@@ -68,27 +68,27 @@
|
||||
return
|
||||
|
||||
//Start growing a human clone in the pod!
|
||||
/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
|
||||
/obj/machinery/clonepod/proc/growclone(var/datum/transhuman/body_record/BR)
|
||||
if(mess || attempting)
|
||||
return 0
|
||||
var/datum/mind/clonemind = locate(R.mind)
|
||||
var/datum/mind/clonemind = locate(BR.mydna.mind)
|
||||
|
||||
if(!istype(clonemind, /datum/mind)) //not a mind
|
||||
return 0
|
||||
if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body
|
||||
return 0
|
||||
if(clonemind.active) //somebody is using that mind
|
||||
if(ckey(clonemind.key) != R.ckey)
|
||||
if(ckey(clonemind.key) != BR.ckey)
|
||||
return 0
|
||||
else
|
||||
for(var/mob/observer/dead/G in player_list)
|
||||
if(G.ckey == R.ckey)
|
||||
if(G.ckey == BR.ckey)
|
||||
if(G.can_reenter_corpse)
|
||||
break
|
||||
else
|
||||
return 0
|
||||
|
||||
for(var/modifier_type in R.genetic_modifiers) //Can't be cloned, even if they had a previous scan
|
||||
for(var/modifier_type in BR.genetic_modifiers) //Can't be cloned, even if they had a previous scan
|
||||
if(istype(modifier_type, /datum/modifier/no_clone))
|
||||
return 0
|
||||
|
||||
@@ -102,24 +102,16 @@
|
||||
spawn(30)
|
||||
eject_wait = 0
|
||||
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species)
|
||||
occupant = H
|
||||
|
||||
if(!R.dna.real_name) //to prevent null names
|
||||
R.dna.real_name = "clone ([rand(0,999)])"
|
||||
H.real_name = R.dna.real_name
|
||||
H.gender = R.gender
|
||||
H.descriptors = R.body_descriptors
|
||||
|
||||
//Get the clone body ready
|
||||
//Get the clone body ready, let's calculate their health so the pod doesn't immediately eject them!!!
|
||||
var/mob/living/carbon/human/H = BR.produce_human_mob(src,FALSE, FALSE, "clone ([rand(0,999)])")
|
||||
H.adjustCloneLoss(150) // New damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite
|
||||
H.Paralyse(4)
|
||||
|
||||
//Here let's calculate their health so the pod doesn't immediately eject them!!!
|
||||
H.updatehealth()
|
||||
H.set_cloned_appearance()
|
||||
|
||||
// Move mind to body along with key
|
||||
clonemind.transfer_to(H)
|
||||
H.ckey = R.ckey
|
||||
H.ckey = BR.ckey
|
||||
to_chat(H, span_warning(span_bold("Consciousness slowly creeps over you as your body regenerates.") + "<br>" + span_bold(span_large("Your recent memories are fuzzy, and it's hard to remember anything from today...")) + \
|
||||
"<br>" + span_notice(span_italics("So this is what cloning feels like?"))))
|
||||
|
||||
@@ -128,44 +120,24 @@
|
||||
update_antag_icons(H.mind)
|
||||
// -- End mode specific stuff
|
||||
|
||||
if(!R.dna)
|
||||
H.dna = new /datum/dna()
|
||||
qdel_swap(H.dna, new /datum/dna())
|
||||
else
|
||||
qdel_swap(H.dna, R.dna)
|
||||
H.UpdateAppearance()
|
||||
H.sync_dna_traits(FALSE) // Traitgenes Sync traits to genetics if needed
|
||||
H.sync_organ_dna()
|
||||
H.initialize_vessel()
|
||||
|
||||
H.set_cloned_appearance()
|
||||
update_icon()
|
||||
|
||||
// A modifier is added which makes the new clone be unrobust.
|
||||
// Upgraded cloners can reduce the time of the modifier, up to 80%
|
||||
var/modifier_lower_bound = 25 MINUTES
|
||||
var/modifier_upper_bound = 40 MINUTES
|
||||
|
||||
// Upgraded cloners can reduce the time of the modifier, up to 80%
|
||||
var/clone_sickness_length = abs(((heal_level - 20) / 100 ) - 1)
|
||||
clone_sickness_length = between(0.2, clone_sickness_length, 1.0) // Caps it off just incase.
|
||||
modifier_lower_bound = round(modifier_lower_bound * clone_sickness_length, 1)
|
||||
modifier_upper_bound = round(modifier_upper_bound * clone_sickness_length, 1)
|
||||
|
||||
H.add_modifier(H.species.cloning_modifier, rand(modifier_lower_bound, modifier_upper_bound))
|
||||
|
||||
// Modifier that doesn't do anything.
|
||||
H.add_modifier(/datum/modifier/cloned)
|
||||
|
||||
// This is really stupid.
|
||||
for(var/modifier_type in R.genetic_modifiers)
|
||||
H.add_modifier(modifier_type)
|
||||
|
||||
for(var/datum/language/L in R.languages)
|
||||
H.add_language(L.name)
|
||||
|
||||
H.flavor_texts = R.flavor.Copy()
|
||||
H.suiciding = 0
|
||||
// Finished!
|
||||
update_icon()
|
||||
occupant = H
|
||||
attempting = 0
|
||||
|
||||
return 1
|
||||
|
||||
//Grow clones to maturity then kick them out. FREELOADERS
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/list/scantemp = null
|
||||
var/menu = MENU_MAIN //Which menu screen to display
|
||||
var/list/records = null
|
||||
var/datum/dna2/record/active_record = null
|
||||
var/datum/transhuman/body_record/active_BR = null
|
||||
var/obj/item/disk/body_record/diskette = null // Traitgenes - Storing the entire body record
|
||||
var/loading = 0 // Nice loading text
|
||||
var/autoprocess = 0
|
||||
@@ -206,15 +206,14 @@
|
||||
. = TRUE
|
||||
switch(tgui_modal_act(src, action, params))
|
||||
if(TGUI_MODAL_ANSWER)
|
||||
if(params["id"] == "del_rec" && active_record)
|
||||
if(params["id"] == "del_rec" && active_BR)
|
||||
var/obj/item/card/id/C = ui.user.get_active_hand()
|
||||
if(!istype(C) && !istype(C, /obj/item/pda))
|
||||
set_temp("ID not in hand.", "danger")
|
||||
return
|
||||
if(check_access(C))
|
||||
records.Remove(active_record)
|
||||
qdel(active_record.dna)
|
||||
qdel(active_record)
|
||||
records.Remove(active_BR)
|
||||
qdel(active_BR) // Already deletes dna in destroy()
|
||||
set_temp("Record deleted.", "success")
|
||||
menu = MENU_RECORDS
|
||||
else
|
||||
@@ -245,28 +244,28 @@
|
||||
var/ref = params["ref"]
|
||||
if(!length(ref))
|
||||
return
|
||||
active_record = locate(ref)
|
||||
if(istype(active_record))
|
||||
if(isnull(active_record.ckey))
|
||||
qdel(active_record)
|
||||
active_BR = locate(ref)
|
||||
if(istype(active_BR))
|
||||
if(isnull(active_BR.ckey))
|
||||
qdel(active_BR)
|
||||
set_temp("Error: Record corrupt.", "danger")
|
||||
else
|
||||
var/obj/item/implant/health/H = null
|
||||
if(active_record.implant)
|
||||
H = locate(active_record.implant)
|
||||
if(active_BR.mydna.implant)
|
||||
H = locate(active_BR.mydna.implant)
|
||||
var/list/payload = list(
|
||||
activerecord = "\ref[active_record]",
|
||||
activerecord = "\ref[active_BR]",
|
||||
health = (H && istype(H)) ? H.sensehealth() : "",
|
||||
realname = sanitize(active_record.dna.real_name),
|
||||
unidentity = active_record.dna.uni_identity,
|
||||
strucenzymes = active_record.dna.struc_enzymes,
|
||||
realname = sanitize(active_BR.mydna.dna.real_name),
|
||||
unidentity = active_BR.mydna.dna.uni_identity,
|
||||
strucenzymes = active_BR.mydna.dna.struc_enzymes,
|
||||
)
|
||||
tgui_modal_message(src, action, "", null, payload)
|
||||
else
|
||||
active_record = null
|
||||
active_BR = null
|
||||
set_temp("Error: Record missing.", "danger")
|
||||
if("del_rec")
|
||||
if(!active_record)
|
||||
if(!active_BR)
|
||||
return
|
||||
tgui_modal_boolean(src, action, "Please confirm that you want to delete the record by holding your ID and pressing Delete:", yes_text = "Delete", no_text = "Cancel")
|
||||
if("disk") // Disk management.
|
||||
@@ -277,20 +276,20 @@
|
||||
if(isnull(diskette) || isnull(diskette.stored)) // Traitgenes Storing the entire body record
|
||||
set_temp("Error: The disk's data could not be read.", "danger")
|
||||
return
|
||||
else if(isnull(active_record))
|
||||
else if(isnull(active_BR))
|
||||
set_temp("Error: No active record was found.", "danger")
|
||||
menu = MENU_MAIN
|
||||
return
|
||||
|
||||
active_record = diskette.stored.mydna // Traitgenes Storing the entire body record
|
||||
active_BR = new(diskette.stored) // Traitgenes Storing the entire body record
|
||||
set_temp("Successfully loaded from disk.", "success")
|
||||
if("save")
|
||||
if(isnull(diskette) || isnull(active_record)) // Traitgenes Removed readonly
|
||||
if(isnull(diskette) || isnull(active_BR)) // Traitgenes Removed readonly
|
||||
set_temp("Error: The data could not be saved.", "danger")
|
||||
return
|
||||
|
||||
diskette.stored.mydna = active_record // Traitgenes Storing the entire body record
|
||||
diskette.name = "data disk - '[active_record.dna.real_name]'"
|
||||
diskette.stored = new(active_BR) // Traitgenes Storing the entire body record
|
||||
diskette.name = "data disk - '[active_BR.mydna.dna.real_name]'"
|
||||
set_temp("Successfully saved to disk.", "success")
|
||||
if("eject")
|
||||
if(!isnull(diskette))
|
||||
|
||||
@@ -26,20 +26,23 @@
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(character && !istype(character,/mob/living/carbon/human/dummy))
|
||||
spawn(50)
|
||||
if(QDELETED(character) || QDELETED(pref))
|
||||
return // They might have been deleted during the wait
|
||||
if(!character.virtual_reality_mob && !(/mob/living/carbon/human/proc/perform_exit_vr in character.verbs)) //Janky fix to prevent resleeving VR avatars but beats refactoring transcore
|
||||
if(pref.resleeve_scan)
|
||||
var/datum/transhuman/body_record/BR = new()
|
||||
BR.init_from_mob(character, pref.resleeve_scan, pref.resleeve_lock)
|
||||
if(pref.mind_scan)
|
||||
var/datum/transcore_db/our_db = SStranscore.db_by_key(null)
|
||||
if(our_db)
|
||||
our_db.m_backup(character.mind,character.nif,one_time = TRUE)
|
||||
if(pref.resleeve_lock)
|
||||
character.resleeve_lock = character.ckey
|
||||
character.original_player = character.ckey
|
||||
addtimer(CALLBACK(character, TYPE_PROC_REF(/mob/living/carbon/human,initial_record_sync), pref), 5 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/mob/living/carbon/human/proc/initial_record_sync(var/datum/preferences/pref)
|
||||
if(QDELETED(src) || QDELETED(pref))
|
||||
return // They might have been deleted during the wait
|
||||
if(!virtual_reality_mob && !(/mob/living/carbon/human/proc/perform_exit_vr in verbs)) //Janky fix to prevent resleeving VR avatars but beats refactoring transcore
|
||||
if(pref.resleeve_scan)
|
||||
var/datum/transhuman/body_record/BR = new()
|
||||
BR.init_from_mob(src, pref.resleeve_scan, pref.resleeve_lock)
|
||||
if(pref.mind_scan)
|
||||
var/datum/transcore_db/our_db = SStranscore.db_by_key(null)
|
||||
if(our_db)
|
||||
our_db.m_backup(mind,nif,one_time = TRUE)
|
||||
if(pref.resleeve_lock)
|
||||
resleeve_lock = ckey
|
||||
original_player = ckey
|
||||
SEND_SIGNAL(src, COMSIG_INITIAL_RECORDS)
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/content(var/mob/user)
|
||||
. += "<br>"
|
||||
|
||||
@@ -679,7 +679,12 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/// Revives a body using the client's preferences if human
|
||||
/mob/living/proc/revive()
|
||||
revival_healing_action()
|
||||
|
||||
/// Performs the actual healing of Aheal, seperate from revive() because it does not use client prefs. Will not heal everything, and expects to be called through revive() or with a bodyrecord doing a respawn/revive.
|
||||
/mob/living/proc/revival_healing_action()
|
||||
rejuvenate()
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob()
|
||||
|
||||
@@ -246,24 +246,35 @@
|
||||
*/
|
||||
|
||||
/// The core of resleeving, creates a mob based on the current record
|
||||
/datum/transhuman/body_record/proc/produce_human_mob(var/is_synthfab, var/force_unlock, var/backup_name)
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, mydna.dna.species)
|
||||
|
||||
if(!mydna.dna.real_name)
|
||||
mydna.dna.real_name = backup_name
|
||||
H.real_name = mydna.dna.real_name
|
||||
|
||||
// Setup body
|
||||
/datum/transhuman/body_record/proc/produce_human_mob(var/location, var/is_synthfab, var/force_unlock, var/backup_name)
|
||||
// These are broken up into steps, otherwise the proc gets massive and hard to read.
|
||||
var/mob/living/carbon/human/H = internal_producebody(location,backup_name)
|
||||
internal_producebody_handlesleevelock(H,force_unlock)
|
||||
internal_producebody_updatelimbandorgans(H)
|
||||
internal_producebody_updatednastate(H,is_synthfab)
|
||||
internal_producebody_virgocharacterdata(H)
|
||||
|
||||
// Finish off
|
||||
H.suiciding = 0
|
||||
H.mind = null
|
||||
return H
|
||||
|
||||
/// Creates a human mob with the correct species, name, and a stable state.
|
||||
/datum/transhuman/body_record/proc/internal_producebody(var/location,var/backup_name)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(location, mydna.dna.species)
|
||||
if(!mydna.dna.real_name)
|
||||
mydna.dna.real_name = backup_name
|
||||
H.real_name = mydna.dna.real_name
|
||||
H.gender = mydna.gender
|
||||
H.descriptors = mydna.body_descriptors
|
||||
for(var/datum/language/L in mydna.languages)
|
||||
H.add_language(L.name)
|
||||
H.suiciding = 0
|
||||
H.losebreath = 0
|
||||
H.mind = null
|
||||
|
||||
return H
|
||||
|
||||
/// Sets the new body's sleevelock status, to prevent impersonation by transfering an incorrect mind.
|
||||
/datum/transhuman/body_record/proc/internal_producebody_handlesleevelock(var/mob/living/carbon/human/H,var/force_unlock)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
@@ -274,6 +285,7 @@
|
||||
// Ensure even body scans without an attached ckey respect locking
|
||||
H.resleeve_lock = "@badckey"
|
||||
|
||||
/// Either converts limbs to robotics or prosthetic states, or removes them entirely based off record.
|
||||
/datum/transhuman/body_record/proc/internal_producebody_updatelimbandorgans(var/mob/living/carbon/human/H,var/is_synthfab)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
@@ -313,11 +325,14 @@
|
||||
else if(status == 3) //Digital organ
|
||||
I.digitize()
|
||||
|
||||
/// Transfers dna data to mob, and reinits traits and appearance from it
|
||||
/datum/transhuman/body_record/proc/internal_producebody_updatednastate(var/mob/living/carbon/human/H,var/is_synthfab)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
//Apply DNA from record
|
||||
if(!mydna.dna) // This case should never happen, but copied from clone pod... Who knows with this codebase.
|
||||
mydna.dna = new /datum/dna()
|
||||
qdel_swap(H.dna, mydna.dna.Clone())
|
||||
H.original_player = ckey
|
||||
|
||||
@@ -338,10 +353,10 @@
|
||||
H.regenerate_icons()
|
||||
H.initialize_vessel()
|
||||
|
||||
/// Transfers VORE related information cached in the mob
|
||||
/datum/transhuman/body_record/proc/internal_producebody_virgocharacterdata(var/mob/living/carbon/human/H)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
//Basically all the VORE stuff
|
||||
H.ooc_notes = body_oocnotes
|
||||
H.ooc_notes_likes = body_ooclikes
|
||||
H.ooc_notes_dislikes = body_oocdislikes
|
||||
@@ -354,3 +369,34 @@
|
||||
H.weight = weight
|
||||
if(speciesname)
|
||||
H.custom_species = speciesname
|
||||
|
||||
/// Rebuild a body from a record, like aheal, but without save files. Primarily used for anything that heals like xenochimera.
|
||||
/datum/transhuman/body_record/proc/rebuild_human_mob(var/mob/living/carbon/human/H,var/heal_robot_limbs)
|
||||
// Boy this one is complex, but what do we expect when trying to heal damage and organ loss in this game!
|
||||
if(!H || QDELETED(H)) // Someone, somewhere, will call this without any safety. I feel it in my bones cappin'
|
||||
return
|
||||
|
||||
// Reset our organs/limbs.
|
||||
H.species.create_organs(H)
|
||||
internal_producebody_updatelimbandorgans(H)
|
||||
|
||||
//Don't boot out anyone already in the mob.
|
||||
if(!H.client || !H.key)
|
||||
for (var/obj/item/organ/internal/brain/CH in GLOB.all_brain_organs)
|
||||
if(CH.brainmob)
|
||||
if(CH.brainmob.real_name == H.real_name)
|
||||
if(CH.brainmob.mind)
|
||||
CH.brainmob.mind.transfer_to(H)
|
||||
qdel(CH)
|
||||
|
||||
// Traitgenes Disable all traits currently active, before prefs.copy_to() is applied, as it refreshes the traits list!
|
||||
for(var/datum/gene/trait/gene in GLOB.dna_genes)
|
||||
if(gene.name in H.active_genes)
|
||||
gene.deactivate(H)
|
||||
H.active_genes -= gene.name
|
||||
internal_producebody_updatednastate(H,heal_robot_limbs)
|
||||
|
||||
// Begin actual REVIVIAL. Do NOT use revive(). That uses client prefs and allows save hacking.
|
||||
H.revival_healing_action()
|
||||
|
||||
return H
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
remove_biomass(CLONE_BIOMASS)
|
||||
|
||||
//Get the DNA and generate a new mob
|
||||
var/mob/living/carbon/human/H = current_project.produce_human_mob(FALSE,FALSE,"clone ([rand(0,999)])")
|
||||
var/mob/living/carbon/human/H = current_project.produce_human_mob(src,FALSE,FALSE,"clone ([rand(0,999)])")
|
||||
|
||||
//Give breathing equipment if needed
|
||||
if(current_project.breath_type != null && current_project.breath_type != GAS_O2)
|
||||
@@ -206,7 +206,7 @@
|
||||
return
|
||||
|
||||
//Get the DNA and generate a new mob
|
||||
var/mob/living/carbon/human/H = current_project.produce_human_mob(TRUE,FALSE,"synth ([rand(0,999)])")
|
||||
var/mob/living/carbon/human/H = current_project.produce_human_mob(src,TRUE,FALSE,"synth ([rand(0,999)])")
|
||||
|
||||
//Apply damage
|
||||
H.adjustBruteLoss(brute_value)
|
||||
|
||||
Reference in New Issue
Block a user