diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 623b6be8ef0..c233fdd87a8 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -258,6 +258,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_NEGATES_GRAVITY "negates_gravity"
/// Lets us scan reagents
#define TRAIT_REAGENT_SCANNER "reagent_scanner"
+/// Lets us scan machine parts and tech unlocks
+#define TRAIT_RESEARCH_SCANNER "research_scanner"
/// Can weave webs into cloth
#define TRAIT_WEB_WEAVER "web_weaver"
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index fcc9cfe1522..91c6c2c6029 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -463,28 +463,6 @@
check_flags = NONE
name = "Activate Explosive Implant"
-/datum/action/item_action/toggle_research_scanner
- name = "Toggle Research Scanner"
- icon_icon = 'icons/mob/actions/actions_items.dmi'
- button_icon_state = "scan_mode"
- var/active = FALSE
-
-/datum/action/item_action/toggle_research_scanner/Trigger(trigger_flags)
- if(IsAvailable())
- active = !active
- if(active)
- owner.research_scanner++
- else
- owner.research_scanner--
- to_chat(owner, span_notice("[target] research scanner has been [active ? "activated" : "deactivated"]."))
- return 1
-
-/datum/action/item_action/toggle_research_scanner/Remove(mob/M)
- if(owner && active)
- owner.research_scanner--
- active = FALSE
- ..()
-
/datum/action/item_action/instrument
name = "Use Instrument"
desc = "Use the instrument specified"
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 5a8a6326947..9959271ce60 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -936,7 +936,10 @@
. += "It appears heavily damaged."
if(0 to 25)
. += span_warning("It's falling apart!")
- if(user.research_scanner && component_parts)
+
+/obj/machinery/examine_more(mob/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER) && component_parts)
. += display_parts(user, TRUE)
//called on machinery construction (i.e from frame to machinery) but not on initialization
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index bb74c715c61..5a62109038b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -360,10 +360,14 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
. += "[src] is made of cold-resistant materials."
if(resistance_flags & FIRE_PROOF)
. += "[src] is made of fire-retardant materials."
-
- if(!user.research_scanner)
return
+/obj/item/examine_more(mob/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER))
+ . += research_scan(user)
+
+/obj/item/proc/research_scan(mob/user)
/// Research prospects, including boostable nodes and point values. Deliver to a console to know whether the boosts have already been used.
var/list/research_msg = list("Research prospects: ")
///Separator between the items on the list
@@ -397,7 +401,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
else
research_msg += "None"
research_msg += "."
- . += research_msg.Join()
+ return research_msg.Join()
/obj/item/interact(mob/user)
add_fingerprint(user)
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index 818d0261a40..e04f47e3eaa 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -317,7 +317,7 @@
/obj/structure/blob/examine(mob/user)
. = ..()
var/datum/atom_hud/hud_to_check = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
- if(user.research_scanner || hud_to_check.hudusers[user])
+ if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER) || hud_to_check.hudusers[user])
. += "Your HUD displays an extensive report...
"
if(overmind)
. += overmind.blobstrain.examine(user)
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 0424791abd7..f8e2982644b 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -145,11 +145,10 @@
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
icon_state = "purple"
inhand_icon_state = "glasses"
- actions_types = list(/datum/action/item_action/toggle_research_scanner)
glass_colour_type = /datum/client_colour/glass_colour/purple
resistance_flags = ACID_PROOF
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 80, ACID = 100)
- clothing_traits = list(TRAIT_REAGENT_SCANNER)
+ clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_RESEARCH_SCANNER)
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
if(slot == ITEM_SLOT_EYES)
@@ -315,8 +314,7 @@
name = "science glasses"
icon_state = "sunhudsci"
desc = "A pair of tacky purple sunglasses that allow the wearer to recognize various chemical compounds with only a glance."
- clothing_traits = list(TRAIT_REAGENT_SCANNER)
- actions_types = list(/datum/action/item_action/toggle_research_scanner)
+ clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_RESEARCH_SCANNER)
/obj/item/clothing/glasses/sunglasses/gar
name = "black gar glasses"
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 4f171e7cdd9..2e827fd7e5d 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -149,8 +149,6 @@
var/datum/component/storage/active_storage
/// Active hud
var/datum/hud/hud_used = null
- /// I have no idea tbh
- var/research_scanner = FALSE
/// Is the mob throw intent on
var/throw_mode = THROW_MODE_DISABLED
diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm
index 1db740b9791..ac1b9e2e543 100644
--- a/code/modules/mod/modules/modules_science.dm
+++ b/code/modules/mod/modules/modules_science.dm
@@ -35,15 +35,15 @@
. = ..()
if(!.)
return
- mod.wearer.research_scanner++
+ ADD_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, MOD_TRAIT)
RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, .proc/sense_explosion)
/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
- mod.wearer.research_scanner--
- RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION)
+ REMOVE_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, MOD_TRAIT)
+ UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION)
/obj/item/mod/module/reagent_scanner/advanced/proc/sense_explosion(datum/source, turf/epicenter,
devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
diff --git a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm
index be6ddd5d560..a4b5d7acf56 100644
--- a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm
+++ b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm
@@ -65,14 +65,14 @@
RegisterSignal(biological_sample, COMSIG_SAMPLE_GROWTH_COMPLETED, .proc/on_sample_growth_completed)
///Adds text for when there is a sample in the vat
-/obj/machinery/plumbing/growing_vat/examine(mob/user)
+/obj/machinery/plumbing/growing_vat/examine_more(mob/user)
. = ..()
if(!biological_sample)
return
. += span_notice("It seems to have a sample in it!")
for(var/i in biological_sample.micro_organisms)
var/datum/micro_organism/MO = i
- . += MO.get_details(user.research_scanner)
+ . += MO.get_details(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER))
/obj/machinery/plumbing/growing_vat/plunger_act(obj/item/plunger/P, mob/living/user, reinforced)
. = ..()