diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm
index 7393c20758e..2a90270ef73 100644
--- a/code/game/objects/structures/icemoon/cave_entrance.dm
+++ b/code/game/objects/structures/icemoon/cave_entrance.dm
@@ -20,6 +20,9 @@ GLOBAL_LIST_INIT(ore_probability, list(
mob_types = list(/mob/living/simple_animal/hostile/asteroid/wolf)
move_resist = INFINITY
anchored = TRUE
+ scanner_taggable = TRUE
+ mob_gps_id = "WF" // wolf
+ spawner_gps_id = "Animal Den"
/obj/structure/spawner/ice_moon/Initialize(mapload)
. = ..()
@@ -65,6 +68,7 @@ GLOBAL_LIST_INIT(ore_probability, list(
max_mobs = 1
spawn_time = 60 SECONDS
mob_types = list(/mob/living/simple_animal/hostile/asteroid/polarbear)
+ mob_gps_id = "BR" // bear
/obj/structure/spawner/ice_moon/polarbear/clear_rock()
for(var/turf/potential in RANGE_TURFS(1, src))
@@ -79,6 +83,8 @@ GLOBAL_LIST_INIT(ore_probability, list(
mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_demon)
light_range = 1
light_color = COLOR_SOFT_RED
+ mob_gps_id = "WT|B" // watcher | bluespace
+ spawner_gps_id = "Netheric Distortion"
/obj/structure/spawner/ice_moon/demonic_portal/Initialize(mapload)
. = ..()
@@ -100,9 +106,11 @@ GLOBAL_LIST_INIT(ore_probability, list(
/obj/structure/spawner/ice_moon/demonic_portal/ice_whelp
mob_types = list(/mob/living/basic/mining/ice_whelp)
+ mob_gps_id = "ID|W" // ice drake | whelp
/obj/structure/spawner/ice_moon/demonic_portal/snowlegion
mob_types = list(/mob/living/basic/mining/legion/snow/spawner_made)
+ mob_gps_id = "LG|S" // legion | snow
/obj/effect/collapsing_demonic_portal
name = "collapsing demonic portal"
diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm
index 22f7f0422cd..6d6b2e6af37 100644
--- a/code/game/objects/structures/lavaland/necropolis_tendril.dm
+++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm
@@ -14,19 +14,22 @@
move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it
anchored = TRUE
resistance_flags = FIRE_PROOF | LAVA_PROOF
-
- var/gps = null
var/obj/effect/light_emitter/tendril/emitted_light
-
+ scanner_taggable = TRUE
+ mob_gps_id = "WT"
+ spawner_gps_id = "Necropolis Tendril"
/obj/structure/spawner/lavaland/goliath
mob_types = list(/mob/living/basic/mining/goliath)
+ mob_gps_id = "GL"
/obj/structure/spawner/lavaland/legion
mob_types = list(/mob/living/basic/mining/legion/spawner_made)
+ mob_gps_id = "LG"
/obj/structure/spawner/lavaland/icewatcher
mob_types = list(/mob/living/basic/mining/watcher/icewing)
+ mob_gps_id = "WT|I" // icewing
GLOBAL_LIST_INIT(tendrils, list())
/obj/structure/spawner/lavaland/Initialize(mapload)
@@ -63,7 +66,6 @@ GLOBAL_LIST_INIT(tendrils, list())
L.client.give_award(/datum/award/score/tendril_score, L) //Progresses score by one
GLOB.tendrils -= src
QDEL_NULL(emitted_light)
- QDEL_NULL(gps)
return ..()
/obj/effect/light_emitter/tendril
diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm
index 340bcf212de..c481bb697c6 100644
--- a/code/game/objects/structures/spawner.dm
+++ b/code/game/objects/structures/spawner.dm
@@ -14,6 +14,48 @@
var/spawn_text = "emerges from"
var/faction = list(FACTION_HOSTILE)
var/spawner_type = /datum/component/spawner
+ /// Is this spawner taggable with something?
+ var/scanner_taggable = FALSE
+ /// If this spawner's taggable, what can we tag it with?
+ var/static/list/scanner_types = list(/obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner)
+ /// If this spawner's taggable, what's the text we use to describe what we can tag it with?
+ var/scanner_descriptor = "mining analyzer"
+ /// Has this spawner been tagged/analyzed by a mining scanner?
+ var/gps_tagged = FALSE
+ /// A short identifier for the mob it spawns. Keep around 3 characters or less?
+ var/mob_gps_id = "???"
+ /// A short identifier for what kind of spawner it is, for use in putting together its GPS tag.
+ var/spawner_gps_id = "Creature Nest"
+ /// A complete identifier. Generated on tag (if tagged), used for its examine.
+ var/assigned_tag
+
+/obj/structure/spawner/examine(mob/user)
+ . = ..()
+ if(!scanner_taggable)
+ return
+ if(gps_tagged)
+ . += span_notice("A holotag's been attached, projecting \"[assigned_tag]\".")
+ else
+ . += span_notice("It looks like you could probably scan and tag it with a [scanner_descriptor].")
+
+/obj/structure/spawner/attackby(obj/item/item, mob/user, params)
+ if(scanner_taggable && is_type_in_list(item, scanner_types))
+ gps_tag(user)
+
+/// Tag the spawner, prefixing its GPS entry with an identifier - or giving it one, if nonexistent.
+/obj/structure/spawner/proc/gps_tag(mob/user)
+ if(gps_tagged)
+ to_chat(user, span_warning("[src] already has a holotag attached!"))
+ return
+ to_chat(user, span_notice("You affix a holotag to [src]."))
+ playsound(src, 'sound/machines/twobeep.ogg', 100)
+ gps_tagged = TRUE
+ assigned_tag = "\[[mob_gps_id]-[rand(100,999)]\] " + spawner_gps_id
+ var/datum/component/gps/our_gps = GetComponent(/datum/component/gps)
+ if(our_gps)
+ our_gps.gpstag = assigned_tag
+ return
+ AddComponent(/datum/component/gps, assigned_tag)
/obj/structure/spawner/Initialize(mapload)
. = ..()
@@ -32,6 +74,8 @@
spawn_text = "warps in from"
mob_types = list(/mob/living/basic/syndicate/ranged)
faction = list(ROLE_SYNDICATE)
+ mob_gps_id = "SYN" // syndicate
+ spawner_gps_id = "Hostile Warp Beacon"
/obj/structure/spawner/skeleton
name = "bone pit"
@@ -44,6 +88,8 @@
mob_types = list(/mob/living/simple_animal/hostile/skeleton)
spawn_text = "climbs out of"
faction = list(FACTION_SKELETON)
+ mob_gps_id = "SKL" // skeletons
+ spawner_gps_id = "Bone Pit"
/obj/structure/spawner/clown
name = "Laughing Larry"
@@ -67,6 +113,8 @@
)
spawn_text = "climbs out of"
faction = list(FACTION_CLOWN)
+ mob_gps_id = "???" // clowns
+ spawner_gps_id = "Clown Planet Distortion"
/obj/structure/spawner/mining
name = "monster den"
@@ -80,7 +128,7 @@
/mob/living/basic/mining/basilisk,
/mob/living/basic/mining/goldgrub,
/mob/living/basic/mining/goliath/ancient,
- /mob/living/basic/mining/legion,
+ /mob/living/basic/mining/hivelord,
/mob/living/basic/wumborian_fugu,
)
faction = list(FACTION_MINING)
@@ -89,26 +137,31 @@
name = "goldgrub den"
desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest."
mob_types = list(/mob/living/basic/mining/goldgrub)
+ mob_gps_id = "GG"
/obj/structure/spawner/mining/goliath
name = "goliath den"
desc = "A den housing a nest of goliaths, oh god why?"
mob_types = list(/mob/living/basic/mining/goliath/ancient)
+ mob_gps_id = "GL|A"
/obj/structure/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
mob_types = list(/mob/living/basic/mining/hivelord)
+ mob_gps_id = "HL"
/obj/structure/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
mob_types = list(/mob/living/basic/mining/basilisk)
+ mob_gps_id = "BK"
/obj/structure/spawner/mining/wumborian
name = "wumborian fugu den"
desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?"
mob_types = list(/mob/living/basic/wumborian_fugu)
+ mob_gps_id = "WF"
/obj/structure/spawner/nether
name = "netherworld link"
@@ -125,6 +178,9 @@
/mob/living/basic/migo,
)
faction = list(FACTION_NETHER)
+ scanner_taggable = TRUE
+ mob_gps_id = "?!?"
+ spawner_gps_id = "Netheric Distortion"
/obj/structure/spawner/nether/Initialize(mapload)
. = ..()