diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c21d96be8a3..0166c81efec 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -376,7 +376,8 @@
text += "YES|no"
if (objectives.len==0)
text += "
Objectives are empty! Randomize!"
- if( changeling && changeling.absorbed_dna.len && (current.real_name != changeling.absorbed_dna[1]) )
+ var/datum/changelingprofile/firstprof = changeling.stored_profiles[1]
+ if(changeling && changeling.stored_profiles.len && (current.real_name != firstprof.name) )
text += "
Transform to initial appearance."
else
text += "yes|NO"
@@ -971,12 +972,13 @@
usr << "The objectives for changeling [key] have been generated. You can edit them and anounce manually."
if("initialdna")
- if( !changeling || !changeling.absorbed_dna.len || !istype(current, /mob/living/carbon))
+ if( !changeling || !changeling.stored_profiles.len || !istype(current, /mob/living/carbon))
usr << "Resetting DNA failed!"
else
var/mob/living/carbon/C = current
- C.dna = changeling.absorbed_dna[1]
- C.real_name = C.dna.real_name
+ var/datum/changelingprofile/prof = changeling.stored_profiles[1]
+ C.dna = prof.dna
+ C.real_name = prof.name
updateappearance(C)
domutcheck(C)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 697531b40f0..42c8ca83ebf 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -232,9 +232,9 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
var/list/stored_profiles = list() //list of datum/changelingprofile
- var/list/absorbed_dna = list()
- var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
- var/dna_max = 4 //How many extra DNA strands the changeling can store for transformation.
+ //var/list/absorbed_dna = list()
+ //var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
+ var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
var/absorbedcount = 1 //We would require at least 1 sample of compatible DNA to have taken on the form of a human.
var/chem_charges = 20
var/chem_storage = 50
@@ -263,7 +263,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
changelingID = "[honorific] [changelingID]"
else
changelingID = "[honorific] [rand(1,999)]"
- absorbed_dna.len = dna_max
+ stored_profiles.len = dna_max
/datum/changeling/proc/regenerate(var/mob/living/carbon/the_ling)
@@ -278,7 +278,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
/datum/changeling/proc/get_dna(dna_owner)
for(var/datum/changelingprofile/prof in stored_profiles)
- if(dna_owner == prof.real_name)
+ if(dna_owner == prof.name)
return prof
/datum/changeling/proc/has_dna(datum/dna/tDNA)
@@ -307,7 +307,11 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
return
return 1
-/datum/changeling/proc/add_profile(var/mob/living/human/H)
+/datum/changeling/proc/add_profile(var/mob/living/carbon/human/H, var/mob/living/carbon/user, protect = 0)
+ if(stored_profiles.len > dna_max)
+ if(!push_out_profile())
+ return
+
var/datum/changelingprofile/prof = new()
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
@@ -320,6 +324,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
new_dna.blood_type = H.dna.blood_type
prof.dna = new_dna
prof.name = H.real_name
+ prof.protected = protect
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
for(var/slot in slots)
@@ -329,13 +334,132 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
prof.name_list[slot] = I.name
prof.appearance_list[slot] = I.appearance
prof.flags_cover_list[slot] = I.flags_cover
-
+
stored_profiles += prof
-/datum/changelingprofile
- name = "a bug"
+/datum/changeling/proc/remove_profile(var/mob/living/carbon/human/H, force = 0)
+ for(var/datum/changelingprofile/prof in stored_profiles)
+ if(H.real_name == prof.name)
+ if(prof.protected && !force)
+ continue
+ stored_profiles -= prof
+ qdel(prof)
- var/datum/dna/DNA = null
+/datum/changeling/proc/get_profile_to_remove()
+ for(var/datum/changelingprofile/prof in stored_profiles)
+ if(!prof.protected)
+ return prof
+
+/datum/changeling/proc/push_out_profile()
+ var/datum/changelingprofile/removeprofile = get_profile_to_remove()
+ if(removeprofile)
+ stored_profiles -= removeprofile
+ return 1
+ return 0
+
+/proc/changeling_transform(var/mob/living/carbon/human/user, var/datum/changelingprofile/chosen_prof)
+ user.dna = chosen_prof.dna
+ user.real_name = chosen_prof.name
+ hardset_dna(user, null, null, null, null, chosen_prof.dna.species.type, chosen_prof.dna.features)
+ //var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store") //just here as a reference.
+
+ //im so sorry
+ if(!user.head)
+ var/obj/item/clothing/head/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["head"]
+ C.name = chosen_prof.name_list["head"]
+ C.flags_cover = chosen_prof.flags_cover_list["head"]
+ user.equip_to_slot_or_del(C, slot_head)
+
+ if(!user.wear_mask)
+ var/obj/item/clothing/mask/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["wear_mask"]
+ C.name = chosen_prof.name_list["wear_mask"]
+ C.flags_cover = chosen_prof.flags_cover_list["wear_mask"]
+ user.equip_to_slot_or_del(C, slot_wear_mask)
+
+ if(!user.back)
+ var/obj/item/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["back"]
+ C.name = chosen_prof.name_list["back"]
+ user.equip_to_slot_or_del(C, slot_back)
+
+ if(!user.wear_suit)
+ var/obj/item/clothing/suit/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["wear_suit"]
+ C.name = chosen_prof.name_list["wear_suit"]
+ C.flags_cover = chosen_prof.flags_cover_list["wear_suit"]
+ user.equip_to_slot_or_del(C, slot_wear_suit)
+
+ if(!user.w_uniform)
+ var/obj/item/clothing/under/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["w_uniform"]
+ C.name = chosen_prof.name_list["w_uniform"]
+ C.flags_cover = chosen_prof.flags_cover_list["w_uniform"]
+ user.equip_to_slot_or_del(C, slot_w_uniform)
+
+ if(!user.shoes)
+ var/obj/item/clothing/shoes/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["shoes"]
+ C.name = chosen_prof.name_list["shoes"]
+ C.flags_cover = chosen_prof.flags_cover_list["shoes"]
+ user.equip_to_slot_or_del(C, slot_shoes)
+
+ if(!user.belt)
+ var/obj/item/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["belt"]
+ C.name = chosen_prof.name_list["belt"]
+ user.equip_to_slot_or_del(C, slot_belt)
+
+ if(!user.gloves)
+ var/obj/item/clothing/gloves/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["gloves"]
+ C.name = chosen_prof.name_list["gloves"]
+ C.flags_cover = chosen_prof.flags_cover_list["gloves"]
+ user.equip_to_slot_or_del(C, slot_gloves)
+
+ if(!user.glasses)
+ var/obj/item/clothing/glasses/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["glasses"]
+ C.name = chosen_prof.name_list["glasses"]
+ C.flags_cover = chosen_prof.flags_cover_list["glasses"]
+ user.equip_to_slot_or_del(C, slot_glasses)
+
+ if(!user.ears)
+ var/obj/item/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["ears"]
+ C.name = chosen_prof.name_list["ears"]
+ C.flags_cover = chosen_prof.flags_cover_list["ears"]
+ user.equip_to_slot_or_del(C, slot_ears)
+
+ if(!user.wear_id)
+ var/obj/item/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["wear_id"]
+ C.name = chosen_prof.name_list["wear_id"]
+ C.flags_cover = chosen_prof.flags_cover_list["wear_id"]
+ user.equip_to_slot_or_del(C, slot_wear_id)
+
+ if(!user.s_store)
+ var/obj/item/changeling/C = new(user)
+ C.appearance = chosen_prof.appearance_list["s_store"]
+ C.name = chosen_prof.name_list["s_store"]
+ C.flags_cover = chosen_prof.flags_cover_list["s_store"]
+ user.equip_to_slot_or_del(C, slot_s_store)
+
+
+ updateappearance(user)
+ domutcheck(user)
+
+
+/datum/changelingprofile
+ var/name = "a bug"
+
+ var/protected = 0
+
+ var/datum/dna/dna = null
var/list/name_list = list() //associative list of slotname = itemname
var/list/appearance_list = list()
var/list/flags_cover_list = list()
+
+/datum/changelingprofile/Destroy()
+ qdel(dna)
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index 9269dc71be1..5b045cf6efc 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -371,7 +371,7 @@ var/list/sting_paths
S.on_purchase(src)
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
- mind.changeling.absorbed_dna |= C.dna
+ mind.changeling.add_profile(C)
return 1
/datum/changeling/proc/reset()
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index 2b58025ddf3..f4b0ce929cf 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -54,7 +54,7 @@
target << "You are absorbed by the changeling!"
if(!changeling.has_dna(target.dna))
- changeling.absorb_dna(target, user)
+ changeling.add_profile(target, user)
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
@@ -88,7 +88,7 @@
changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage)
changeling.absorbedcount += (target.mind.changeling.absorbedcount)
- target.mind.changeling.absorbed_dna.len = 1
+ target.mind.changeling.stored_profiles.len = 1
target.mind.changeling.absorbedcount = 0
@@ -152,9 +152,8 @@
target << "[user] tightens their grip as a painful sensation invades your body."
if(!changeling.has_dna(target.dna))
- changeling.absorb_dna(target, user)
- changeling.protected_dna -= user.dna
- changeling.absorbed_dna -= user.dna
+ changeling.add_profile(target, user)
+ changeling.remove_profile(user)
var/mob/dead/observer/ghost = target.ghostize(0)
user.mind.transfer_to(target)
diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm
index 69a795ad9c4..74bee7886f1 100644
--- a/code/game/gamemodes/changeling/powers/hivemind.dm
+++ b/code/game/gamemodes/changeling/powers/hivemind.dm
@@ -31,9 +31,9 @@ var/list/datum/dna/hivemind_bank = list()
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
var/datum/changeling/changeling = user.mind.changeling
var/list/names = list()
- for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna))
- if(!(DNA in hivemind_bank))
- names += DNA.real_name
+ for(var/datum/changelingprofile/prof in changeling.stored_profiles)
+ if(!(prof in hivemind_bank))
+ names += prof.name
if(names.len <= 0)
user << "The airwaves already have all of our DNA."
@@ -43,7 +43,7 @@ var/list/datum/dna/hivemind_bank = list()
if(!chosen_name)
return
- var/datum/dna/chosen_dna = changeling.get_dna(chosen_name)
+ var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
if(!chosen_dna)
return
@@ -62,7 +62,8 @@ var/list/datum/dna/hivemind_bank = list()
if(!..())
return
var/datum/changeling/changeling = user.mind.changeling
- if(changeling.absorbed_dna[1] == user.dna)//If our current DNA is the stalest, we gotta ditch it.
+ var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
+ if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
user << "We have reached our capacity to store genetic information! We must transform before absorbing more."
return
return 1
@@ -70,9 +71,9 @@ var/list/datum/dna/hivemind_bank = list()
/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
var/datum/changeling/changeling = user.mind.changeling
var/list/names = list()
- for(var/datum/dna/DNA in hivemind_bank)
- if(!(DNA in changeling.absorbed_dna))
- names[DNA.real_name] = DNA
+ for(var/datum/changelingprofile/prof in hivemind_bank)
+ if(!(prof in changeling.stored_profiles))
+ names[prof.name] = prof
if(names.len <= 0)
user << "There's no new DNA to absorb from the air."
@@ -80,13 +81,11 @@ var/list/datum/dna/hivemind_bank = list()
var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
if(!S) return
- var/datum/dna/chosen_dna = names[S]
- if(!chosen_dna)
+ var/datum/changelingprofile/chosen_prof = names[S]
+ if(!chosen_prof)
return
- if(changeling.absorbed_dna.len)
- changeling.absorbed_dna.Cut(1,2)
- changeling.store_dna(chosen_dna, user)
+ changeling.add_profile(chosen_prof, user)
user << "We absorb the DNA of [S] from the air."
feedback_add_details("changeling_powers","HD")
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm
index 999aaf47bed..de246564451 100644
--- a/code/game/gamemodes/changeling/powers/humanform.dm
+++ b/code/game/gamemodes/changeling/powers/humanform.dm
@@ -11,25 +11,25 @@
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
var/datum/changeling/changeling = user.mind.changeling
var/list/names = list()
- for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna))
- names += "[DNA.real_name]"
+ for(var/datum/changelingprofile/prof in changeling.stored_profiles)
+ names += "[prof.name]"
var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
if(!chosen_name)
return
- var/datum/dna/chosen_dna = changeling.get_dna(chosen_name)
- if(!chosen_dna)
+ var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
+ if(!chosen_prof)
return
if(!user || user.notransform)
return 0
user << "We transform our appearance."
- user.dna = chosen_dna
- user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSRC),chosen_dna.real_name)
+ user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSRC), chosen_prof.name)
+
+ changeling_transform(user, chosen_prof)
changeling.purchasedpowers -= src
feedback_add_details("changeling_powers","LFT")
qdel(user)
return 1
-
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index 576a4102baa..243c5c8724f 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -171,7 +171,7 @@
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
add_logs(user, target, "stung", "extraction sting")
if(!(user.mind.changeling.has_dna(target.dna)))
- user.mind.changeling.absorb_dna(target, user)
+ user.mind.changeling.add_profile(target, user)
feedback_add_details("changeling_powers","ED")
return 1
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index ebbaa467fc0..5505feecf8c 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -16,6 +16,10 @@
name = "flesh"
flags = NODROP
+/obj/item/clothing/glasses/changeling
+ name = "flesh"
+ flags = NODROP
+
/obj/item/clothing/head/changeling
name = "flesh"
flags = NODROP
@@ -50,97 +54,7 @@
if(!chosen_prof)
return
- user.dna = chosen_prof.dna
- user.real_name = chosen_prof.name
- hardset_dna(user, null, null, null, null, chosen_dna.species.type, chosen_dna.features)
- var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
-
- //im so sorry
- if(!user.head)
- var/obj/item/clothing/head/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["head"]
- C.name = chosen_prof.name_list["head"]
- C.flags_cover = chosen_prof.flags_cover_list["head"]
- user.equip_to_slot_or_del(C, slot_head)
-
- if(!user.wear_mask)
- var/obj/item/clothing/mask/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["wear_mask"]
- C.name = chosen_prof.name_list["wear_mask"]
- C.flags_cover = chosen_prof.flags_cover_list["wear_mask"]
- user.equip_to_slot_or_del(C, slot_wear_mask)
-
- if(!user.back)
- var/obj/item/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["back"]
- C.name = chosen_prof.name_list["back"]
- user.equip_to_slot_or_del(C, slot_back)
-
- if(!user.wear_suit)
- var/obj/item/clothing/suit/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["wear_suit"]
- C.name = chosen_prof.name_list["wear_suit"]
- C.flags_cover = chosen_prof.flags_cover_list["wear_suit"]
- user.equip_to_slot_or_del(C, slot_wear_suit)
-
- if(!user.w_uniform)
- var/obj/item/clothing/under/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["w_uniform"]
- C.name = chosen_prof.name_list["w_uniform"]
- C.flags_cover = chosen_prof.flags_cover_list["w_uniform"]
- user.equip_to_slot_or_del(C, slot_w_uniform)
-
- if(!user.shoes)
- var/obj/item/clothing/shoes/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["shoes"]
- C.name = chosen_prof.name_list["shoes"]
- C.flags_cover = chosen_prof.flags_cover_list["shoes"]
- user.equip_to_slot_or_del(C, slot_shoes)
-
- if(!user.belt)
- var/obj/item/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["belt"]
- C.name = chosen_prof.name_list["belt"]
- user.equip_to_slot_or_del(C, slot_belt)
-
- if(!user.gloves)
- var/obj/item/clothing/gloves/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["gloves"]
- C.name = chosen_prof.name_list["gloves"]
- C.flags_cover = chosen_prof.flags_cover_list["gloves"]
- user.equip_to_slot_or_del(C, slot_gloves)
-
- if(!user.glasses)
- var/obj/item/clothing/glasses/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["glasses"]
- C.name = chosen_prof.name_list["glasses"]
- C.flags_cover = chosen_prof.flags_cover_list["glasses"]
- user.equip_to_slot_or_del(C, slot_glasses)
-
- if(!user.ears)
- var/obj/item/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["ears"]
- C.name = chosen_prof.name_list["ears"]
- C.flags_cover = chosen_prof.flags_cover_list["ears"]
- user.equip_to_slot_or_del(C, slot_ears)
-
- if(!user.wear_id)
- var/obj/item/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["wear_id"]
- C.name = chosen_prof.name_list["wear_id"]
- C.flags_cover = chosen_prof.flags_cover_list["wear_id"]
- user.equip_to_slot_or_del(C, slot_wear_id)
-
- if(!user.s_store)
- var/obj/item/changeling/C = new(user)
- C.appearance = chosen_prof.appearance_list["s_store"]
- C.name = chosen_prof.name_list["s_store"]
- C.flags_cover = chosen_prof.flags_cover_list["s_store"]
- user.equip_to_slot_or_del(C, slot_s_store)
-
-
- updateappearance(user)
- domutcheck(user)
+ changeling_transform(user, chosen_prof)
feedback_add_details("changeling_powers","TR")
return 1
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 452288e8ffd..81b671284ef 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -590,7 +590,7 @@ var/global/list/possible_items_special = list()
return target_amount
/datum/objective/absorb/check_completion()
- if(owner && owner.changeling && owner.changeling.absorbed_dna && (owner.changeling.absorbedcount >= target_amount))
+ if(owner && owner.changeling && owner.changeling.stored_profiles && (owner.changeling.absorbedcount >= target_amount))
return 1
else
return 0