diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 6225bacad8b..96def0b7f10 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -455,7 +455,7 @@
//Return the active mutation of a type if there is one
/datum/dna/proc/get_mutation(A)
- for(var/datum/mutation/HM as() in mutations)
+ for(var/datum/mutation/HM in mutations)
if(HM.type == A)
return HM
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 62f98b6f96e..197659c8e4e 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -630,6 +630,25 @@
if(!HM)
return
+ // nullifier part
+ // this exists earlier before activator part because "activator" items doesn't work as nullifier because of inject() proc does
+ var/is_nullifier = text2num(params["is_nullifier"])
+ if(is_nullifier)
+ var/obj/item/dnainjector/I = new /obj/item/dnainjector(loc)
+ I.remove_mutations += HM.type // this should accept a typepath, not an actual type reference
+ I.name = "DNA nullifier"
+ I.desc = "Removes a specific mutation on injection."
+ I.icon_state = "dnanullifier"
+ I.base_icon_state = "dnanullifier"
+ // printing nullifiers a lot wouldn't be good, so it has some cooldown
+ if(scanner_operational())
+ I.damage_coeff = connected_scanner.damage_coeff
+ injectorready = world.time + INJECTOR_TIMEOUT * 3 * (1 - 0.1 * connected_scanner.precision_coeff)
+ else
+ injectorready = world.time + INJECTOR_TIMEOUT * 3
+ return
+
+
// Create a new DNA Injector and add the appropriate mutations to it
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
I.add_mutations += new HM.type(copymut = HM)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 1c57db25ca2..9b05b323b9f 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -842,9 +842,22 @@ GENE SCANNER
return
buffer = C.dna.mutation_index
to_chat(user, "Subject [C.name]'s DNA sequence has been saved to buffer.")
- if(LAZYLEN(buffer))
- for(var/A in buffer)
- to_chat(user, "[get_display_name(A)]")
+ var/list/full_list_mutations = list()
+ for(var/each in buffer) // get inherent mutations first
+ full_list_mutations[each] = FALSE
+ for(var/datum/mutation/each_mutation in C.dna.mutations)
+ if(each_mutation.type in buffer) // active inherent mutation
+ full_list_mutations[each_mutation.type] = "Activated"
+ else // active artificial mutation
+ full_list_mutations[each_mutation.type] = "Injected"
+ for(var/datum/mutation/each_mutation in C.dna.temporary_mutations)
+ full_list_mutations[each_mutation.type] = "Temporary"
+
+ for(var/A in full_list_mutations)
+ to_chat(user, "\t[get_display_name(A)]") // if you want to make the scanner tell which mutation is active, put "full_list_mutations[A]" to the second parameter of get_display_name() proc.
+ to_chat(user, "\tGenetic Stability: [C.dna.stability]%.")
+ if(C.has_status_effect(STATUS_EFFECT_LING_TRANSFORMATION))
+ to_chat(user, "\tSubject's DNA appears to be in an unstable state.")
/obj/item/sequence_scanner/proc/display_sequence(mob/living/user)
@@ -879,14 +892,14 @@ GENE SCANNER
icon_state = initial(icon_state)
ready = TRUE
-/obj/item/sequence_scanner/proc/get_display_name(mutation)
+/obj/item/sequence_scanner/proc/get_display_name(mutation, active_detail=FALSE)
var/datum/mutation/HM = GET_INITIALIZED_MUTATION(mutation)
if(!HM)
return "ERROR"
if(discovered[mutation])
- return "[HM.name] ([HM.alias])"
+ return !active_detail ? "[HM.name] ([HM.alias])" : "[HM.name] ([HM.alias]) - [active_detail]"
else
- return HM.alias
+ return !active_detail ? HM.alias : "[HM.alias] - [active_detail]"
/obj/item/extrapolator
name = "virus extrapolator"
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index e7cc258602a..50a9f0395a8 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -3,6 +3,7 @@
desc = "A cheap single use autoinjector that injects the user with DNA."
icon = 'icons/obj/syringe.dmi'
icon_state = "dnainjector"
+ base_icon_state = "dnainjector"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 3
@@ -25,6 +26,7 @@
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/HM in remove_mutations)
M.dna.remove_mutation(HM)
+ log_msg += "(mutation removal: [english_list(remove_mutations)])"
for(var/HM in add_mutations)
if(HM == RACEMUT)
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] (MONKEY)")
@@ -74,7 +76,7 @@
to_chat(user, "It appears that [target] does not have compatible DNA.")
used = TRUE
- icon_state = "dnainjector0"
+ icon_state = "[base_icon_state]0"
desc += " This one is spent, you better recycle it!"
@@ -480,6 +482,7 @@
name = "\improper DNA injector (Anti-Medieval)"
remove_mutations = list(MEDIEVAL)
+// note: this is not functional. mutation is not added to temporary_mutation list - it becomes permanent.
/obj/item/dnainjector/timed
var/duration = 600
diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi
index 1248fa674a3..fa3390e1aaf 100644
Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ
diff --git a/tgui/packages/tgui/interfaces/DnaConsole.js b/tgui/packages/tgui/interfaces/DnaConsole.js
index 287c29496d0..bd34f20505b 100644
--- a/tgui/packages/tgui/interfaces/DnaConsole.js
+++ b/tgui/packages/tgui/interfaces/DnaConsole.js
@@ -679,6 +679,18 @@ const MutationInfo = (props, context) => {
is_activator: 0,
source: mutation.Source,
})} />
+