diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm
new file mode 100644
index 00000000000..9865159529d
--- /dev/null
+++ b/code/datums/components/gps.dm
@@ -0,0 +1,154 @@
+///Global GPS_list. All GPS components get saved in here for easy reference.
+GLOBAL_LIST_EMPTY(GPS_list)
+///GPS component. Atoms that have this show up on gps. Pretty simple stuff.
+/datum/component/gps
+ var/gpstag = "COM0"
+ var/tracking = TRUE
+ var/emped = FALSE
+
+/datum/component/gps/Initialize(_gpstag = "COM0")
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ gpstag = _gpstag
+ GLOB.GPS_list += src
+
+/datum/component/gps/Destroy()
+ GLOB.GPS_list -= src
+ return ..()
+
+///GPS component subtype. Only gps/item's can be used to open the UI.
+/datum/component/gps/item
+ var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
+ var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
+
+/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE)
+ . = ..()
+ if(. == COMPONENT_INCOMPATIBLE || !isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+ var/atom/A = parent
+ A.add_overlay("working")
+ A.name = "[initial(A.name)] ([gpstag])"
+ RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
+ if(!emp_proof)
+ RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp_act)
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+ RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_AltClick)
+
+///Called on COMSIG_ITEM_ATTACK_SELF
+/datum/component/gps/item/proc/interact(datum/source, mob/user)
+ if(user)
+ ui_interact(user)
+
+///Called on COMSIG_PARENT_EXAMINE
+/datum/component/gps/item/proc/on_examine(datum/source, mob/user, list/examine_list)
+ examine_list += "Alt-click to switch it [tracking ? "off":"on"]."
+
+///Called on COMSIG_ATOM_EMP_ACT
+/datum/component/gps/item/proc/on_emp_act(datum/source, severity)
+ emped = TRUE
+ var/atom/A = parent
+ A.cut_overlay("working")
+ A.add_overlay("emp")
+ addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
+ SStgui.close_uis(src) //Close the UI control if it is open.
+
+///Restarts the GPS after getting turned off by an EMP.
+/datum/component/gps/item/proc/reboot()
+ emped = FALSE
+ var/atom/A = parent
+ A.cut_overlay("emp")
+ A.add_overlay("working")
+
+///Calls toggletracking
+/datum/component/gps/item/proc/on_AltClick(datum/source, mob/user)
+ toggletracking(user)
+
+///Toggles the tracking for the gps
+/datum/component/gps/item/proc/toggletracking(mob/user)
+ if(!user.canUseTopic(parent, BE_CLOSE))
+ return //user not valid to use gps
+ if(emped)
+ to_chat(user, "It's busted!")
+ return
+ var/atom/A = parent
+ if(tracking)
+ A.cut_overlay("working")
+ to_chat(user, "[parent] is no longer tracking, or visible to other GPS devices.")
+ tracking = FALSE
+ else
+ A.add_overlay("working")
+ to_chat(user, "[parent] is now tracking, and visible to other GPS devices.")
+ tracking = TRUE
+
+/datum/component/gps/item/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
+ if(emped)
+ to_chat(user, "[parent] fizzles weakly.")
+ return
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
+ ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
+ ui.open()
+
+ ui.set_autoupdate(state = updating)
+
+/datum/component/gps/item/ui_data(mob/user)
+ var/list/data = list()
+ data["power"] = tracking
+ data["tag"] = gpstag
+ data["updating"] = updating
+ data["globalmode"] = global_mode
+ if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
+ return data
+
+ var/turf/curr = get_turf(parent)
+ data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
+
+ var/list/signals = list()
+ data["signals"] = list()
+
+ for(var/gps in GLOB.GPS_list)
+ var/datum/component/gps/G = gps
+ if(G.emped || !G.tracking || G == src)
+ continue
+ var/turf/pos = get_turf(G.parent)
+ if(!pos || !global_mode && pos.z != curr.z)
+ continue
+ var/list/signal = list()
+ signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
+ signal["area"] = get_area_name(G, TRUE)
+ signal["coord"] = "[pos.x], [pos.y], [pos.z]"
+ if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
+ signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
+ signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
+ var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
+ if(!direction)
+ direction = "CENTER"
+ signal["degrees"] = "N/A"
+ signal["direction"] = direction
+
+ signals += list(signal) //Add this signal to the list of signals
+ data["signals"] = signals
+ return data
+
+/datum/component/gps/item/ui_act(action, params)
+ if(..())
+ return
+ switch(action)
+ if("rename")
+ var/atom/parentasatom = parent
+ var/a = input("Please enter desired tag.", parentasatom.name, gpstag) as text
+ a = copytext(sanitize(a), 1, 20)
+ gpstag = a
+ . = TRUE
+ parentasatom.name = "global positioning system ([gpstag])"
+
+ if("power")
+ toggletracking(usr)
+ . = TRUE
+ if("updating")
+ updating = !updating
+ . = TRUE
+ if("globalmode")
+ global_mode = !global_mode
+ . = TRUE
diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm
index 3b1740fb639..b5aeb0ee8d7 100644
--- a/code/game/machinery/computer/law.dm
+++ b/code/game/machinery/computer/law.dm
@@ -3,23 +3,11 @@
/obj/machinery/computer/upload
var/mob/living/silicon/current = null //The target of future law uploads
icon_screen = "command"
- var/obj/item/gps/internal/ai_upload/embedded_gps
- var/obj/item/gps/internal/ai_upload/embedded_gps_type = /obj/item/gps/internal/ai_upload
time_to_screwdrive = 60
-/obj/item/gps/internal/ai_upload
- icon_state = null
- gpstag = "Encrypted Upload Signal"
- desc = "Signal used to connect remotely with silicons."
- invisibility = 100
-
/obj/machinery/computer/upload/Initialize()
- embedded_gps = new embedded_gps_type(src)
- return ..()
-
-/obj/machinery/computer/upload/Destroy()
- QDEL_NULL(embedded_gps)
- return ..()
+ . = ..()
+ AddComponent(/datum/component/gps, "Encrypted Upload Signal")
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/aiModule))
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index 4654bb4aac7..6195fc1fcda 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -1,4 +1,4 @@
-GLOBAL_LIST_EMPTY(GPS_list)
+
/obj/item/gps
name = "global positioning system"
desc = "Helping lost spacemen find their way through the planets since 2016."
@@ -7,137 +7,11 @@ GLOBAL_LIST_EMPTY(GPS_list)
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
obj_flags = UNIQUE_RENAME
- var/gpstag = "COM0"
- var/emped = FALSE
- var/tracking = TRUE
- var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
- var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
-
-/obj/item/gps/examine(mob/user)
- . = ..()
- . += "Alt-click to switch it [tracking ? "off":"on"]."
+ var/gpstag
/obj/item/gps/Initialize()
. = ..()
- GLOB.GPS_list += src
- name = "global positioning system ([gpstag])"
- add_overlay("working")
-
-/obj/item/gps/Destroy()
- GLOB.GPS_list -= src
- return ..()
-
-/obj/item/gps/emp_act(severity)
- . = ..()
- if (. & EMP_PROTECT_SELF)
- return
- emped = TRUE
- cut_overlay("working")
- add_overlay("emp")
- addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
- SStgui.close_uis(src) //Close the UI control if it is open.
-
-/obj/item/gps/proc/reboot()
- emped = FALSE
- cut_overlay("emp")
- add_overlay("working")
-
-/obj/item/gps/AltClick(mob/user)
- if(!user.canUseTopic(src, BE_CLOSE))
- return
- toggletracking(user)
-
-/obj/item/gps/proc/toggletracking(mob/user)
- if(!user.canUseTopic(src, BE_CLOSE))
- return //user not valid to use gps
- if(emped)
- to_chat(user, "It's busted!")
- return
- if(tracking)
- cut_overlay("working")
- to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
- tracking = FALSE
- else
- add_overlay("working")
- to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
- tracking = TRUE
-
-
-/obj/item/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
- if(emped)
- to_chat(user, "[src] fizzles weakly.")
- return
- ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
- ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
- ui.open()
-
- ui.set_autoupdate(state = updating)
-
-
-/obj/item/gps/ui_data(mob/user)
- var/list/data = list()
- data["power"] = tracking
- data["tag"] = gpstag
- data["updating"] = updating
- data["globalmode"] = global_mode
- if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
- return data
-
- var/turf/curr = get_turf(src)
- data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
-
- var/list/signals = list()
- data["signals"] = list()
-
- for(var/gps in GLOB.GPS_list)
- var/obj/item/gps/G = gps
- if(G.emped || !G.tracking || G == src)
- continue
- var/turf/pos = get_turf(G)
- if(!pos || !global_mode && pos.z != curr.z)
- continue
- var/list/signal = list()
- signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
- signal["area"] = get_area_name(G, TRUE)
- signal["coord"] = "[pos.x], [pos.y], [pos.z]"
- if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
- signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
- signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
- var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
- if(!direction)
- direction = "CENTER"
- signal["degrees"] = "N/A"
- signal["direction"] = direction
-
- signals += list(signal) //Add this signal to the list of signals
- data["signals"] = signals
- return data
-
-
-
-/obj/item/gps/ui_act(action, params)
- if(..())
- return
- switch(action)
- if("rename")
- var/a = input("Please enter desired tag.", name, gpstag) as text
- a = copytext(sanitize(a), 1, 20)
- gpstag = a
- . = TRUE
- name = "global positioning system ([gpstag])"
-
- if("power")
- toggletracking(usr)
- . = TRUE
- if("updating")
- updating = !updating
- . = TRUE
- if("globalmode")
- global_mode = !global_mode
- . = TRUE
-
+ AddComponent(/datum/component/gps/item, gpstag)
/obj/item/gps/science
icon_state = "gps-s"
@@ -161,22 +35,11 @@ GLOBAL_LIST_EMPTY(GPS_list)
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
-/obj/item/gps/internal
- icon_state = null
- item_flags = ABSTRACT
- gpstag = "Eerie Signal"
- desc = "Report to a coder immediately."
- invisibility = INVISIBILITY_MAXIMUM
-
/obj/item/gps/mining/internal
icon_state = "gps-m"
gpstag = "MINER"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
-/obj/item/gps/internal/base
- gpstag = "NT_AUX"
- desc = "A homing signal from Nanotrasen's mining base."
-
/obj/item/gps/visible_debug
name = "visible GPS"
gpstag = "ADMIN"
diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm
index 6543bc1909b..12dbafdedf1 100644
--- a/code/game/objects/structures/lavaland/necropolis_tendril.dm
+++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm
@@ -33,20 +33,20 @@ GLOBAL_LIST_INIT(tendrils, list())
if(ismineralturf(F))
var/turf/closed/mineral/M = F
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
- gps = new /obj/item/gps/internal(src)
+ AddComponent(/datum/component/gps, "Eerie Signal")
GLOB.tendrils += src
/obj/structure/spawner/lavaland/deconstruct(disassembled)
new /obj/effect/collapse(loc)
new /obj/structure/closet/crate/necropolis/tendril(loc)
return ..()
-
-
+
+
/obj/structure/spawner/lavaland/Destroy()
var/last_tendril = TRUE
if(GLOB.tendrils.len>1)
last_tendril = FALSE
-
+
if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1))
if(SSmedals.hub_enabled)
for(var/mob/living/L in view(7,src))
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index 8bb1fbc7e8b..0e41f4b9c19 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -96,14 +96,11 @@
icon_state = "dominator"
density = TRUE
var/active = FALSE
- var/obj/item/gps/gps
var/credits_stored = 0
var/siphon_per_tick = 5
/obj/machinery/shuttle_scrambler/Initialize(mapload)
. = ..()
- gps = new/obj/item/gps/internal/pirate(src)
- gps.tracking = FALSE
update_icon()
/obj/machinery/shuttle_scrambler/process()
@@ -122,7 +119,7 @@
/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
SSshuttle.registerTradeBlockade(src)
- gps.tracking = TRUE
+ AddComponent(/datum/component/gps, "Nautical Signal")
active = TRUE
to_chat(user,"You toggle [src] [active ? "on":"off"].")
to_chat(user,"The scrambling signal can be now tracked by GPS.")
@@ -158,7 +155,6 @@
/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
SSshuttle.clearTradeBlockade(src)
- gps.tracking = FALSE
active = FALSE
STOP_PROCESSING(SSobj,src)
@@ -170,13 +166,8 @@
/obj/machinery/shuttle_scrambler/Destroy()
toggle_off()
- QDEL_NULL(gps)
return ..()
-/obj/item/gps/internal/pirate
- gpstag = "Nautical Signal"
- desc = "You can hear shanties over the static."
-
/obj/machinery/computer/shuttle/pirate
name = "pirate shuttle console"
shuttleId = "pirateship"
diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm
index 91eab536c96..6eabdf5d75e 100644
--- a/code/modules/mining/aux_base.dm
+++ b/code/modules/mining/aux_base.dm
@@ -24,12 +24,11 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
req_one_access = list(ACCESS_CARGO, ACCESS_CONSTRUCTION, ACCESS_HEADS, ACCESS_RESEARCH)
var/possible_destinations
clockwork = TRUE
- var/obj/item/gps/internal/base/locator
circuit = /obj/item/circuitboard/computer/auxillary_base
/obj/machinery/computer/auxillary_base/Initialize()
. = ..()
- locator = new(src)
+ AddComponent(/datum/component/gps, "NT_AUX")
/obj/machinery/computer/auxillary_base/ui_interact(mob/user)
. = ..()
@@ -151,7 +150,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(!is_mining_level(T.z))
return BAD_ZLEVEL
-
+
var/list/colony_turfs = base_dock.return_ordered_turfs(T.x,T.y,T.z,base_dock.dir)
for(var/i in 1 to colony_turfs.len)
CHECK_TICK
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 15fec5c922f..24f7ab3f599 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -44,7 +44,7 @@ Difficulty: Medium
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
- internal_type = /obj/item/gps/internal/miner
+ gps_name = "Resonant Signal"
medal_type = BOSS_MEDAL_MINER
var/obj/item/melee/transforming/cleaving_saw/miner/miner_saw
var/time_until_next_transform = 0
@@ -275,12 +275,6 @@ Difficulty: Medium
sleep(4)
animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
-/obj/item/gps/internal/miner
- icon_state = null
- gpstag = "Resonant Signal"
- desc = "The sweet blood, oh, it sings to me."
- invisibility = 100
-
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance
guidance = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 34d617ff397..3871c3bfaea 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -59,7 +59,7 @@ Difficulty: Hard
var/enrage_till = 0
var/enrage_time = 70
var/revving_charge = FALSE
- internal_type = /obj/item/gps/internal/bubblegum
+ gps_name = "Bloody Signal"
medal_type = BOSS_MEDAL_BUBBLEGUM
score_type = BUBBLEGUM_SCORE
deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... "
@@ -384,12 +384,6 @@ Difficulty: Hard
if(useoriginal)
charge(chargeat, delay, chargepast)
-/obj/item/gps/internal/bubblegum
- icon_state = null
- gpstag = "Bloody Signal"
- desc = "You're not quite sure how a signal can be bloody."
- invisibility = 100
-
/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(. > 0 && prob(25))
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 3ab9d133ae0..da7d274d93f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -42,7 +42,7 @@ Difficulty: Very Hard
ranged = TRUE
pixel_x = -32
del_on_death = TRUE
- internal_type = /obj/item/gps/internal/colossus
+ gps_name = "Angelic Signal"
medal_type = BOSS_MEDAL_COLOSSUS
score_type = COLOSSUS_SCORE
crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
@@ -259,13 +259,6 @@ Difficulty: Very Hard
target.ex_act(EXPLODE_HEAVY)
-/obj/item/gps/internal/colossus
- icon_state = null
- gpstag = "Angelic Signal"
- desc = "Get in the fucking robot."
- invisibility = 100
-
-
//Black Box
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index 24cc474304a..99446e0d7d6 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -56,7 +56,7 @@ Difficulty: Medium
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/ashdrake = 10)
var/swooping = NONE
var/player_cooldown = 0
- internal_type = /obj/item/gps/internal/dragon
+ gps_name = "Fiery Signal"
medal_type = BOSS_MEDAL_DRAKE
score_type = DRAKE_SCORE
deathmessage = "collapses into a pile of bones, its flesh sloughing away."
@@ -380,10 +380,6 @@ Difficulty: Medium
if(!lava_success)
arena_escape_enrage()
-/mob/living/simple_animal/hostile/megafauna/dragon/death()
- QDEL_NULL(internal) // so drake corpses don't have a gps signal
- . = ..()
-
/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target)
if(severity == EXPLODE_LIGHT)
return
@@ -415,12 +411,6 @@ Difficulty: Medium
if(!swooping)
..()
-/obj/item/gps/internal/dragon
- icon_state = null
- gpstag = "Fiery Signal"
- desc = "Here there be dragons."
- invisibility = 100
-
/obj/effect/temp_visual/lava_warning
icon_state = "lavastaff_warn"
layer = BELOW_MOB_LAYER
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 4ac16ea3dd7..0bfd26a87a1 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -58,7 +58,7 @@ Difficulty: Hard
loot = list(/obj/item/hierophant_club)
crusher_loot = list(/obj/item/hierophant_club, /obj/item/crusher_trophy/vortex_talisman)
wander = FALSE
- internal_type = /obj/item/gps/internal/hierophant
+ gps_name = "Zealous Signal"
medal_type = BOSS_MEDAL_HIEROPHANT
score_type = HIEROPHANT_SCORE
del_on_death = TRUE
@@ -731,9 +731,3 @@ Difficulty: Hard
to_chat(user, "You touch the beacon with the club, but nothing happens.")
else
return ..()
-
-/obj/item/gps/internal/hierophant
- icon_state = null
- gpstag = "Zealous Signal"
- desc = "Heed its words."
- invisibility = 100
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 7e76008650b..db63199bd5b 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -36,7 +36,7 @@
retreat_distance = 5
minimum_distance = 5
ranged_cooldown_time = 20
- internal_type = /obj/item/gps/internal/legion
+ gps_name = "Echoing Signal"
medal_type = BOSS_MEDAL_LEGION
score_type = LEGION_SCORE
pixel_y = -16
@@ -241,12 +241,6 @@
faction = L.faction.Copy()
GiveTarget(L.target)
-/obj/item/gps/internal/legion
- icon_state = null
- gpstag = "Echoing Signal"
- desc = "The message repeats."
- invisibility = 100
-
//Loot
/obj/item/staff/storm
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index f4390a53d68..d7403f598da 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -33,8 +33,7 @@
var/score_type = BOSS_SCORE
var/elimination = 0
var/anger_modifier = 0
- var/obj/item/gps/internal
- var/internal_type
+ var/gps_name = null
var/recovery_time = 0
var/true_spawn = TRUE // if this is a megafauna that should grant achievements, or have a gps signal
var/nest_range = 10
@@ -44,8 +43,8 @@
/mob/living/simple_animal/hostile/megafauna/Initialize(mapload)
. = ..()
- if(internal_type && true_spawn)
- internal = new internal_type(src)
+ if(gps_name && true_spawn)
+ AddComponent(/datum/component/gps, gps_name)
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
for(var/action_type in attack_action_types)
@@ -55,10 +54,6 @@
var/datum/action/small_sprite/small_action = new small_sprite_type()
small_action.Grant(src)
-/mob/living/simple_animal/hostile/megafauna/Destroy()
- QDEL_NULL(internal)
- . = ..()
-
/mob/living/simple_animal/hostile/megafauna/Moved()
if(nest && nest.parent && get_dist(nest.parent, src) > nest_range)
var/turf/closest = get_turf(nest.parent)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index 8698b8953b6..0c434a12cd8 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -48,7 +48,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
health = 750
maxHealth = 750 //""""low-ish"""" HP because it's a passive boss, and the swarm itself is the real foe
mob_biotypes = list(MOB_ROBOTIC)
- internal_type = /obj/item/gps/internal/swarmer_beacon
+ gps_name = "Hungry Signal"
medal_type = BOSS_MEDAL_SWARMERS
score_type = SWARMER_BEACON_SCORE
faction = list("mining", "boss", "swarmer")
@@ -89,12 +89,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
summon_backup(25) //long range, only called max once per 15 seconds, so it's not deathlag
-/obj/item/gps/internal/swarmer_beacon
- icon_state = null
- gpstag = "Hungry Signal"
- desc = "Transmitted over the signal is a strange message repeated in every language you know of, and some you don't too..." //the message is "nom nom nom"
- invisibility = 100
-
//SWARMER AI
//AI versions of the swarmer mini-antag
//This is an Abstract Base, it re-enables AI, but does not give the swarmer any goals/targets
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
index 777739f3422..fd725b3a212 100644
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ b/code/modules/ruins/lavaland_ruin_code.dm
@@ -152,7 +152,4 @@
/obj/item/clothing/mask/chameleon/gps/Initialize()
. = ..()
- new /obj/item/gps/internal/lavaland_syndicate_base(src)
-
-/obj/item/gps/internal/lavaland_syndicate_base
- gpstag = "Encrypted Signal"
+ AddComponent(/datum/component/gps, "Encrypted Signal")
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index 2c365e9d5ef..7cf0a152624 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -253,7 +253,7 @@
/obj/machinery/computer/bsa_control/proc/calibrate(mob/user)
var/list/gps_locators = list()
- for(var/obj/item/gps/G in GLOB.GPS_list) //nulls on the list somehow
+ for(var/datum/component/gps/G in GLOB.GPS_list) //nulls on the list somehow
if(G.tracking)
gps_locators[G.gpstag] = G
diff --git a/tgstation.dme b/tgstation.dme
index 916e687701a..532743b73ba 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -365,6 +365,7 @@
#include "code\datums\components\footstep.dm"
#include "code\datums\components\forced_gravity.dm"
#include "code\datums\components\forensics.dm"
+#include "code\datums\components\gps.dm"
#include "code\datums\components\heirloom.dm"
#include "code\datums\components\igniter.dm"
#include "code\datums\components\infective.dm"