diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 7c9d7f4a85c..e85b3f9290f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -79,17 +79,17 @@ var/mob/living/carbon/human/zealot_master = null /datum/mind/proc/transfer_to(mob/living/new_character) + var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list if(!istype(new_character)) log_to_dd("## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn") if(current) //remove ourself from our old body's mind variable current.mind = null + leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it nanomanager.user_transferred(current, new_character) if(new_character.mind) //remove any mind currently in our new body's mind variable new_character.mind.current = null - var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list - leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it current = new_character //link ourself to our new body new_character.mind = src //and link our new body to ourself transfer_antag_huds(hud_to_transfer) //inherit the antag HUD diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index d812296b916..9fb2402f889 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -224,7 +224,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" var/list/absorbed_dna = list() var/list/absorbed_languages = 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/dna_max = 5 //How many total DNA strands the changeling can store for transformation. var/absorbedcount = 1 //Would require at least 1 sample to take on the form of a human var/chem_charges = 20 var/chem_recharge_rate = 0.5 @@ -253,7 +253,6 @@ 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 /datum/changeling/proc/regenerate() chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage) @@ -265,14 +264,35 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" if(dna_owner == DNA.real_name) return DNA -/datum/changeling/proc/has_dna(var/datum/dna/tDNA) +/datum/changeling/proc/find_dna(var/datum/dna/tDNA) for(var/datum/dna/D in (absorbed_dna + protected_dna)) if(tDNA.unique_enzymes == D.unique_enzymes && tDNA.uni_identity == D.uni_identity && tDNA.species == D.species) - return 1 + return D + return null + +/datum/changeling/proc/has_dna(var/datum/dna/tDNA) + if(find_dna(tDNA)) + return 1 return 0 +// A changeling's DNA is "stale" if their current form's DNA is the oldest DNA in a full list +/datum/changeling/proc/using_stale_dna(var/mob/living/carbon/user) + var/current_dna = find_dna(user.dna) + if(absorbed_dna.len < dna_max) + return 0 // Still more room for DNA + if(!current_dna || !(current_dna in absorbed_dna)) + return 1 // Oops, our current DNA was somehow not absorbed; force a transformation + if(absorbed_dna[1] == current_dna) + return 1 // Oldest DNA is the current DNA + return 0 + +/datum/changeling/proc/trim_dna() + absorbed_dna -= null + if(absorbed_dna.len > dna_max) + absorbed_dna.Cut(1, (absorbed_dna.len - dna_max) + 1) + /datum/changeling/proc/can_absorb_dna(var/mob/living/carbon/user, var/mob/living/carbon/target) - if(absorbed_dna[1] == user.dna)//If our current DNA is the stalest, we gotta ditch it. + if(using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it. to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") return diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm index 8e8e824d85e..6d03a864692 100644 --- a/code/game/gamemodes/changeling/changeling_power.dm +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -73,12 +73,6 @@ return 0 return 1 -/obj/effect/proc_holder/changeling/proc/transfer_changeling_powers(var/mob/living/carbon/user, var/mob/living/carbon/target) - if(istype(target, /mob/living/carbon)) // so we don't runtime, I don't even know why it's necessary as it needs a grab - var/datum/changeling/c = user.mind.changeling - var/datum/changeling/t = target.mind.changeling - c.purchasedpowers = t.purchasedpowers - //used in /mob/Stat() /obj/effect/proc_holder/changeling/proc/can_be_used_by(var/mob/user) if(!ishuman(user)) diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index 7efcb3f09a1..43f08584823 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -376,6 +376,7 @@ var/list/sting_paths var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste mind.changeling.absorbed_dna |= C.dna + mind.changeling.trim_dna() return 1 //Used to dump the languages from the changeling datum into the actual mob. diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 6dbcc48dc2f..3800597709a 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -86,8 +86,6 @@ //Absorbs the target DNA. /datum/changeling/proc/absorb_dna(mob/living/carbon/T, var/mob/user) - if(absorbed_dna.len) - absorbed_dna.Cut(1,2) T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set. var/datum/dna/new_dna = T.dna.Clone() //Steal all of their languages! @@ -104,4 +102,5 @@ if(E.target_real_name == new_dna.real_name) protected_dna |= new_dna return - absorbed_dna |= new_dna \ No newline at end of file + absorbed_dna |= new_dna + trim_dna() diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm index 1032f84635f..0976f0da36d 100644 --- a/code/game/gamemodes/changeling/powers/hivemind.dm +++ b/code/game/gamemodes/changeling/powers/hivemind.dm @@ -62,7 +62,7 @@ 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. + if(changeling.using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it. to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") return return 1 @@ -84,8 +84,6 @@ var/list/datum/dna/hivemind_bank = list() if(!chosen_dna) return - if(changeling.absorbed_dna.len) - changeling.absorbed_dna.Cut(1,2) changeling.store_dna(chosen_dna, user) to_chat(user, "We absorb the DNA of [S] from the air.") feedback_add_details("changeling_powers","HD") diff --git a/code/game/gamemodes/changeling/powers/swap_form.dm b/code/game/gamemodes/changeling/powers/swap_form.dm index 188c5fb437b..ce8bda64d03 100644 --- a/code/game/gamemodes/changeling/powers/swap_form.dm +++ b/code/game/gamemodes/changeling/powers/swap_form.dm @@ -38,10 +38,12 @@ to_chat(target, "[user] tightens their grip as a painful sensation invades your body.") + changeling.absorbed_dna -= changeling.find_dna(user.dna) + changeling.protected_dna -= changeling.find_dna(user.dna) + changeling.absorbedcount -= 1 if(!changeling.has_dna(target.dna)) changeling.absorb_dna(target, user) - changeling.protected_dna -= user.dna - changeling.absorbed_dna -= user.dna + changeling.trim_dna() var/mob/dead/observer/ghost = target.ghostize(0) user.mind.transfer_to(target) @@ -52,6 +54,6 @@ user.Paralyse(2) target.add_language("Changeling") user.remove_language("Changeling") - transfer_changeling_powers(user, target) to_chat(target, "Our genes cry out as we swap our [user] form for [target].") + return 1 diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index eec1b92e63d..9c880666f4e 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -82,11 +82,12 @@ // Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget(). // Calling it in the overriden Login, such as /mob/living/Login() doesn't cause this. /mob/proc/update_interface() - if(client) - if(winget(src, "mainwindow.hotkey_toggle", "is-checked") == "true") - update_hotkey_mode() - else - update_normal_mode() + spawn() // Spawn off so winget/winset don't delay callers. + if(client) + if(winget(src, "mainwindow.hotkey_toggle", "is-checked") == "true") + update_hotkey_mode() + else + update_normal_mode() /mob/proc/update_hotkey_mode() var/hotkeyname = "hotkeymode" @@ -94,7 +95,7 @@ var/hotkeys = client.hotkeylist[client.hotkeytype] hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"] client.hotkeyon = 1 - winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0") + winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0") /mob/proc/update_normal_mode() var/hotkeyname = "macro" @@ -102,4 +103,4 @@ var/hotkeys = client.hotkeylist[client.hotkeytype]//get the list containing the hotkey names hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"]//get the name of the hotkey, to not clutter winset() to much client.hotkeyon = 0 - winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5") + winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")