Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions code/datums/dna.dm
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
var/datum/blood_type/blood_type
///The type of mutant race the player is if applicable (i.e. potato-man)
var/datum/species/species = new /datum/species/human
///first value is mutant color
var/list/features = list("FFF")
/// Assoc list of feature keys to their value
/// Note if you set these manually, and do not update [unique_features] afterwards, it will likely be reset.
var/list/features = list("mcolor" = COLOR_WHITE)
///Stores the hashed values of the person's non-human features
var/unique_features
///Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
Expand Down Expand Up @@ -548,27 +549,28 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
return dna


/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, list/default_mutation_genes, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/mutations, force_transfer_mutations)
/// Sets the DNA of the mob to the given DNA.
/mob/living/carbon/human/proc/hardset_dna(unique_identity, list/mutation_index, list/default_mutation_genes, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/mutations, force_transfer_mutations)
//Do not use force_transfer_mutations for stuff like cloners without some precautions, otherwise some conditional mutations could break (timers, drill hat etc)
if(newfeatures)
dna.features = newfeatures
dna.generate_unique_features()

if(mrace)
var/datum/species/newrace = new mrace.type
newrace.copy_properties_from(mrace)
set_species(newrace, icon_update=0)
set_species(newrace, icon_update = 0)

if(newreal_name)
real_name = newreal_name
dna.real_name = newreal_name
dna.generate_unique_enzymes()

if(newblood_type)
dna.blood_type = newblood_type

if(ui)
dna.unique_identity = ui
updateappearance(icon_update=0)
if(unique_identity)
dna.unique_identity = unique_identity
updateappearance(icon_update = 0)

if(newfeatures)
dna.features = newfeatures
dna.generate_unique_features()

if(LAZYLEN(mutation_index))
dna.mutation_index = mutation_index.Copy()
Expand All @@ -578,17 +580,14 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
dna.default_mutation_genes = mutation_index.Copy()
domutcheck()

if(mrace || newfeatures || ui)
if(mrace || newfeatures || unique_identity)
update_body()
update_hair()
update_body_parts()
update_mutations_overlay()

if(LAZYLEN(mutations))
for(var/M in mutations)
var/datum/mutation/human/HM = M
if(HM.allow_transfer || force_transfer_mutations)
dna.force_give(new HM.type(HM.class, copymut=HM)) //using force_give since it may include exotic mutations that otherwise wont be handled properly
if(LAZYLEN(mutations) && force_transfer_mutations)
for(var/datum/mutation/human/mutation as anything in mutations)
dna.force_give(new mutation.type(mutation.class, copymut = mutation)) //using force_give since it may include exotic mutations that otherwise won't be handled properly

/mob/living/carbon/proc/create_dna()
dna = new /datum/dna(src)
Expand Down
34 changes: 28 additions & 6 deletions code/game/machinery/computer/cloning.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
//select which parts of the diskette to load
var/include_se = FALSE //mutations
var/include_ui = FALSE //appearance
var/include_uf = FALSE //features
var/include_ue = FALSE //blood type, UE, and name

var/loading = FALSE // Nice loading text
Expand Down Expand Up @@ -63,7 +64,22 @@
. = pod

/proc/grow_clone_from_record(obj/machinery/clonepod/pod, datum/data/record/R, empty)
return pod.growclone(R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["makeup"], R.fields["mindref"], R.fields["last_death"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"], empty, R.fields["mood"])
return pod.growclone(
clonename = R.fields["name"],
ui = R.fields["UI"],
mutation_index = R.fields["SE"],
makeup = R.fields["makeup"],
mindref = R.fields["mindref"],
last_death = R.fields["last_death"],
mrace = R.fields["mrace"],
features = R.fields["features"],
factions = R.fields["factions"],
quirks = R.fields["quirks"],
insurance = R.fields["bank_account"],
traumas = R.fields["traumas"],
empty = empty,
mood = R.fields["mood"],
)

/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
Expand Down Expand Up @@ -259,6 +275,7 @@
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"

dat += "<b>Unique Identifier:</b><br />[span_highlight("[active_record.fields["UI"]]")]<br>"
dat += "<b>Unique Features:</b><br />[span_highlight("[active_record.fields["UF"]]")]<br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>"
for(var/key in active_record.fields["SE"])
if(key != RACEMUT)
Expand All @@ -273,10 +290,13 @@
dat += "<h4>Inserted Disk</h4>"
dat += "<b>Contents:</b> "
var/list/L = list()
if(diskette.fields["UI"])
L += "Unique Identifier"

if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
L += "Unique Enzymes"
if(diskette.fields["UI"])
L += "Unique Identifier"
if(diskette.fields["UF"])
L += "Unique Features"
if(diskette.fields["SE"])
L += "Structural Enzymes"
dat += english_list(L, "Empty", " + ", " + ")
Expand Down Expand Up @@ -441,6 +461,7 @@
overwrite_field_if_available(active_record, diskette, "blood_type")
if(include_ui)
overwrite_field_if_available(active_record, diskette, "UI")
overwrite_field_if_available(active_record, diskette, "UF")
if(include_se)
overwrite_field_if_available(active_record, diskette, "SE")

Expand Down Expand Up @@ -552,11 +573,12 @@

R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.unique_identity
R.fields["UE"] = "[dna.unique_enzymes]"
R.fields["UI"] = "[dna.unique_identity]"
R.fields["UF"] = "[dna.unique_features]"
R.fields["SE"] = dna.mutation_index
R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features
R.fields["features"] = dna.features.Copy()
R.fields["makeup"] = dna.default_mutation_genes
R.fields["factions"] = mob_occupant.faction
R.fields["quirks"] = list()
Expand Down
16 changes: 11 additions & 5 deletions code/game/machinery/computer/dna_console.dm
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
stored_research = SSresearch.science_tech

/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, datum/tgui/ui)

. = ..()
// Most of ui_interact is spent setting variables for passing to the tgui
// interface.
// We can also do some general state processing here too as it's a good
Expand Down Expand Up @@ -302,7 +302,7 @@
data["subjectUNI"] = scanner_occupant.dna.unique_identity
data["subjectUF"] = scanner_occupant.dna.unique_features
data["storage"]["occupant"] = tgui_occupant_mutations
//data["subjectMutations"] = tgui_occupant_mutations

else
data["subjectName"] = null
data["subjectStatus"] = null
Expand Down Expand Up @@ -1143,7 +1143,13 @@
return

I = new /obj/item/dnainjector/timed(loc)
I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "UF"=buffer_slot["UF"], "blood_type"=buffer_slot["blood_type"])
I.fields = list(
"UI" = buffer_slot["UI"],
"name" = buffer_slot["name"],
"UE" = buffer_slot["UE"],
"UF" = buffer_slot["UF"],
"blood_type" = buffer_slot["blood_type"]
)

// If there is a connected scanner, we can use its upgrades to reduce
// the radiation generated by this injector
Expand Down Expand Up @@ -1506,7 +1512,7 @@
scanner_occupant.real_name = buffer_slot["name"]
scanner_occupant.name = buffer_slot["name"]
scanner_occupant.dna.unique_enzymes = buffer_slot["UE"]
scanner_occupant.dna.blood_type = buffer_slot["blood_type"]
scanner_occupant.dna.blood_type = get_blood_type(buffer_slot["blood_type"])
scanner_occupant.radiation += rad_increase
scanner_occupant.domutcheck()
return TRUE
Expand All @@ -1524,7 +1530,7 @@
scanner_occupant.real_name = buffer_slot["name"]
scanner_occupant.name = buffer_slot["name"]
scanner_occupant.dna.unique_enzymes = buffer_slot["UE"]
scanner_occupant.dna.blood_type = buffer_slot["blood_type"]
scanner_occupant.dna.blood_type = get_blood_type(buffer_slot["blood_type"])
scanner_occupant.radiation += rad_increase
scanner_occupant.domutcheck()
return TRUE
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/exp_cloner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
internal_radio = FALSE

//Start growing a human clone in the pod!
/obj/machinery/clonepod/experimental/growclone(clonename, ui, mutation_index, makeup, mindref, last_death, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance)
/obj/machinery/clonepod/experimental/growclone(clonename, ui, mutation_index, makeup, mindref, last_death, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance, list/traumas, empty, mood)
if(panel_open)
return NONE
if(mess || attempting)
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/dna_injector.dm
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
if(fields["UF"])
M.dna.unique_features = merge_text(M.dna.unique_features, fields["UF"])
if(fields["UI"] || fields["UF"])
M.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
M.updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE)
log_attack("[log_msg] [loc_name(user)]")
return TRUE
return FALSE
Expand Down
7 changes: 3 additions & 4 deletions code/modules/hydroponics/grown/replicapod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,11 @@
podman.ckey = ckey_holder
podman.gender = blood_gender
podman.faction |= factions
if(!features["mcolor"])
features["mcolor"] = "#59CE00"

for(var/V in quirks)
new V(podman)
podman.hardset_dna(null,null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance()
podman.hardset_dna(null, null, null, podman.real_name, blood_type, /datum/species/pod, features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman

podman.dna.species.exotic_blood = max(reagents_add) || /datum/reagent/water
log_cloning("[key_name(mind)] cloned as a podman via [src] in [parent] at [AREACOORD(parent)].")
to_chat(podman, span_userdanger("You do not remember your death, how you died, or who killed you. <a href='https://forums.yogstation.net/help/rules/#rule-1_6'>See rule 1.6</a>.")) //yogs
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/human/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@
underwear = "Nude"
update_body()
update_hair()
dna.update_dna_identity()

/mob/living/carbon/human/singularity_pull(S, current_size)
..()
Expand Down
7 changes: 2 additions & 5 deletions code/modules/mob/living/carbon/human/update_icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,10 @@ There are several things that need to be remembered:

//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
/mob/living/carbon/human/proc/update_mutant_bodyparts()
dna.species.handle_mutant_bodyparts(src)

dna?.species.handle_mutant_bodyparts(src)

/mob/living/carbon/human/update_body()
remove_overlay(BODY_LAYER)
dna.species.handle_body(src)
dna?.species.handle_body(src)
..()

/mob/living/carbon/human/update_fire()
Expand Down Expand Up @@ -887,4 +885,3 @@ generate/load female uniform sprites matching all previously decided variables
update_inv_wear_mask()

#undef RESOLVE_ICON_STATE

17 changes: 16 additions & 1 deletion code/modules/reagents/chemistry/reagents/other_reagents.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/datum/reagent/blood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null)
name = "Blood"
color = COLOR_BLOOD
metabolization_rate = 5 //fast rate so it disappears fast.
Expand All @@ -10,6 +9,22 @@
glass_desc = "Are you sure this is tomato juice?"
shot_glass_icon_state = "shotglassred"

data = list(
"donor" = null,
"viruses" = null,
"blood_DNA" = null,
"blood_type" = null,
"resistances" = null,
"trace_chem" = null,
"mind" = null,
"ckey" = null,
"gender" = null,
"real_name" = null,
"cloneable" = null,
"factions" = null,
"quirks" = null
)

/datum/reagent/blood/reaction_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = TRUE, permeability = 1)
var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(L) //bloodsucker start
if(bloodsuckerdatum)
Expand Down