Files
Batrachophreno 8111a8489b Restore many missing inhand sprites for items, add/port others (#21831)
Many, many, many items have inhand sprites in their .dmis but for
whatever reasons do not display them in-game. This PR:

1. Updates many item definitions to point to their already-existing
inhands correctly. This consists largely of held tools, but also gas
tanks and jetpacks mounted in the suit storage slot.

2. Adds a few codersprites made by me for objects with either missing
inhands or poorly matching mishands (IE, the tape recorder, which has a
black case, reused the white inhand sprites of the health analyzer). The
new sprites are modified or recolored variations of other inhand sprites
from our repo, except for circuitboards which are new.
<img width="444" height="400" alt="image"
src="https://github.com/user-attachments/assets/7f107b9a-fe24-4e31-8f16-4d34768ee117"
/>


3. Adds inhand sprites for Inflatables and Inflatable Boxes made by
Tomixcomics.
<img width="424" height="101" alt="image"
src="https://github.com/user-attachments/assets/434107c4-8577-49a2-a58e-d6b014c03933"
/>

4. Ports inhand sprites for the Hydraulic Rescue Tool from tg's Jaws of
Life.
<img width="224" height="94" alt="Screenshot 2026-02-07 172931"
src="https://github.com/user-attachments/assets/070c7956-f6a8-4fb5-870f-10c64afcc8b3"
/>

5. Some additional cleanup while in the area. The 'analyzer' has been
renamed the 'gas analyzer' to be consistent with the other analyzer
objects, standardized icon_state naming conventions where I saw
oddballs, updated code docs to use DMDocs when in the area, etc.

### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:

| Path | Original Author | License |
| --- | --- | --- |
| icons/obj/item/hydraulic_rescue_tool.dmi | [SomeAngryMiner (bee
station)](https://github.com/BeeStation/BeeStation-Hornet/pull/2487),
[maxymax
(/tg/station)](https://github.com/tgstation/tgstation/pull/58616) |
CC-BY-SA |
| icons/obj/item/inflatables.dmi |
[Tomixcomics](https://github.com/tomixcomics) | CC-BY-SA |
2026-02-17 17:51:22 +00:00

421 lines
11 KiB
Plaintext

GLOBAL_LIST_EMPTY(gps_list)
/obj/item/gps
name = "global positioning system"
desc = "Helping lost spacemen find their way through the planets since 2016."
icon = 'icons/obj/item/gps.dmi'
icon_state = "gps-com"
item_state = "radio"
contained_sprite = TRUE
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
var/gps_prefix = "COM"
var/gpstag = "COM0"
var/compass_color = "#193A7A"
var/emped = FALSE
var/mob/held_by = null
var/mob/implanted_into = null
var/turf/locked_location
var/list/tracking = list()
var/list/tracking_compass
var/obj/compass_holder/compass
var/list/static/gps_count = list()
var/process_interval = 6 SECONDS
var/last_process = 0
/obj/item/gps/Initialize()
. = ..()
compass = new(src)
gpstag = next_initial_tag()
name = "global positioning system ([gpstag])"
update_position()
if(ismob(loc))
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src in H.get_equipped_items())
held_by = H
else
implanted_into = loc
else if(issilicon(loc))
held_by = loc
implanted_into = loc
else if(istype(loc, /obj/item/robot_module))
held_by = loc.loc
implanted_into = loc.loc
update_icon()
if(held_by)
RegisterSignal(held_by, COMSIG_MOVABLE_MOVED, PROC_REF(update_position), TRUE)
if(implanted_into)
RegisterSignal(implanted_into, COMSIG_MOVABLE_MOVED, PROC_REF(update_position), TRUE)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(update_position))
for(var/gps in GLOB.gps_list)
tracking += GLOB.gps_list[gps]["tag"]
START_PROCESSING(SSprocessing, src)
/obj/item/gps/Destroy()
GLOB.gps_list -= GLOB.gps_list[gpstag]
UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
if(held_by)
UnregisterSignal(held_by, COMSIG_MOVABLE_MOVED)
held_by = null
if(implanted_into)
UnregisterSignal(implanted_into, COMSIG_MOVABLE_MOVED)
implanted_into = null
STOP_PROCESSING(SSprocessing, src)
return ..()
/obj/item/gps/attack_self(mob/user, modifiers)
if(!emped)
ui_interact(user)
var/turf/T = get_turf(src)
to_chat(user, SPAN_NOTICE("[icon2html(src, user)] [src] flashes <i>[T.x].[rand(0,9)]:[T.y].[rand(0,9)]:[T.z].[rand(0,9)]</i>."))
/obj/item/gps/update_icon()
ClearOverlays()
if(emped)
AddOverlays("emp")
else if(held_by || implanted_into)
AddOverlays("working")
else
AddOverlays("confused")
/obj/item/gps/pickup(var/mob/user)
..()
if(held_by)
UnregisterSignal(held_by, COMSIG_MOVABLE_MOVED)
held_by = user
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(update_position), TRUE)
update_icon()
/obj/item/gps/dropped(mob/user)
..()
if(isturf(loc))
held_by = null
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
if(user.client)
user.client.screen -= compass
update_icon()
/obj/item/gps/on_slotmove(mob/user, slot)
. = ..()
if(user.client && !(slot == slot_r_hand || slot == slot_l_hand))
user.client.screen -= compass
/obj/item/gps/equipped(mob/user, slot)
. = ..()
if(user.client && (slot == slot_r_hand || slot == slot_l_hand))
user.client.screen |= compass
/obj/item/gps/on_module_activate(mob/living/silicon/robot/R)
..()
if(R.client)
R.client.screen |= compass
/obj/item/gps/on_module_deactivate(mob/living/silicon/robot/R)
..()
if(R.client)
R.client.screen -= compass
/obj/item/gps/emp_act(severity)
. = ..()
emped = TRUE
addtimer(CALLBACK(src, PROC_REF(post_emp)), 30 SECONDS)
update_icon()
update_position()
/obj/item/gps/proc/post_emp()
emped = FALSE
update_icon()
update_position()
/obj/item/gps/ui_data(mob/user)
var/list/data = list()
data["own_tag"] = gpstag
var/list/tracking_list = list()
for(var/tracking_tag in sortList(tracking))
if(!GLOB.gps_list[tracking_tag]) // Another GPS device has changed its tag or been destroyed
tracking -= tracking_tag
continue
if(AreConnectedZLevels(loc.z, GLOB.gps_list[tracking_tag]["pos_z"]))
tracking_list += list(list("tag" = tracking_tag , "gps" = (GLOB.gps_list[tracking_tag])))
data["tracking_list"] = tracking_list
data["compass_list"] = tracking_compass
return data
/obj/item/gps/ui_interact(mob/user, var/datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GPS", capitalize_first_letters(name), 550, 650)
ui.open()
/obj/item/gps/process()
if(held_by || implanted_into || (world.time < last_process + process_interval))
return
update_position(FALSE)
/obj/item/gps/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("tag")
var/set_tag = uppertext(copytext(sanitize(params["tag"]), 1, 8))
var/was_tracked // If we were tracking this, we want to keep it on the list with its new tag
if(gpstag in tracking)
was_tracked = TRUE
tracking -= gpstag
if(loc == usr)
if(!GLOB.gps_list[set_tag])
GLOB.gps_list -= gpstag
gpstag = set_tag
name = "global positioning system ([gpstag])"
ui.title = capitalize_first_letters(name)
update_position()
if(was_tracked)
tracking |= gpstag
else
to_chat(usr, SPAN_WARNING("This GPS tag already assigned, please choose another."))
return TRUE
if("add_tag")
var/new_tag = uppertext(copytext(sanitize(params["add_tag"]), 1, 8))
if(GLOB.gps_list[new_tag])
tracking |= new_tag
update_compass(TRUE)
else
to_chat(usr, SPAN_WARNING("That GPS tag could not be located."))
return TRUE
if("remove_tag")
tracking -= params["remove_tag"]
update_compass(TRUE)
return TRUE
if("add_all")
tracking.Cut()
for(var/gps in GLOB.gps_list)
tracking += GLOB.gps_list[gps]["tag"]
update_compass(TRUE)
return TRUE
if("clear_all")
tracking.Cut()
tracking |= gpstag // always want to track ourselves
update_compass(TRUE)
return TRUE
if("compass")
var/tracking_tag = params["compass"]
if(LAZYISIN(tracking_compass, tracking_tag))
LAZYREMOVE(tracking_compass, tracking_tag)
else
LAZYADD(tracking_compass, tracking_tag)
update_compass(TRUE)
return TRUE
return FALSE
/obj/item/gps/proc/update_position(var/check_held_by = TRUE)
var/turf/T = get_turf(src)
if(check_held_by && held_by && (held_by.x != T.x || held_by.y != T.y || held_by.z != T.z) && held_by != recursive_loc_turf_check(src, 3, held_by))
UnregisterSignal(held_by, COMSIG_MOVABLE_MOVED)
held_by = null
update_icon()
return
var/area/gpsarea = get_area(src)
var/gps_areaname = get_area_display_name(gpsarea, TRUE, FALSE, FALSE, TRUE)
// Sanity checking with default locations in case something isn't right with locational data.
// The GPS will prefer the coordinate of its turf, but if the turf is null it will try the coordinate of whoever is holding it.
// And if both fail, it'll default to <0,0,0> so we don't crash.
var/x_coord = 0
var/y_coord = 0
var/z_coord = 0
if (T)
x_coord = T.x
y_coord = T.y
z_coord = T.z
else if (held_by)
x_coord = held_by.x
y_coord = held_by.y
z_coord = held_by.z
GLOB.gps_list[gpstag] = list("tag" = gpstag, "pos_x" = x_coord, "pos_y" = y_coord, "pos_z" = z_coord, "area" = "[gps_areaname]", "emped" = emped, "compass_color" = compass_color)
if(check_held_by && held_by && (held_by.get_active_hand() == src || held_by.get_inactive_hand() == src))
update_compass(TRUE)
/obj/item/gps/proc/update_compass(var/update_compass_icon)
compass.hide_waypoints(FALSE)
if(LAZYLEN(tracking_compass))
for(var/tracking_tag in tracking_compass - gpstag)
if(!GLOB.gps_list[tracking_tag])
continue
if(!(tracking_tag in tracking))
continue
if(GLOB.gps_list[tracking_tag]["pos_x"] == GLOB.gps_list[gpstag]["pos_x"] && GLOB.gps_list[tracking_tag]["pos_y"] == GLOB.gps_list[gpstag]["pos_y"])
continue
compass.set_waypoint(tracking_tag, tracking_tag, GLOB.gps_list[tracking_tag]["pos_x"], GLOB.gps_list[tracking_tag]["pos_y"], GLOB.gps_list[tracking_tag]["pos_z"], GLOB.gps_list[tracking_tag]["compass_color"])
var/turf/origin = get_turf(src)
if(!emped && !GLOB.gps_list[tracking_tag]["emped"] && origin.z == GLOB.gps_list[tracking_tag]["pos_z"])
compass.show_waypoint(tracking_tag)
compass.rebuild_overlay_lists(update_compass_icon)
/obj/item/gps/proc/next_initial_tag()
if(!LAZYACCESS(gps_count, gps_prefix))
gps_count[gps_prefix] = 0
. = "[gps_prefix][gps_count[gps_prefix]++]"
if(GLOB.gps_list[.]) // if someone has renamed a GPS manually to take this tag already
. = next_initial_tag()
/obj/item/gps/science
icon_state = "gps-sci"
gps_prefix = "SCI"
compass_color = "#993399"
gpstag = "SCI0"
/obj/item/gps/engineering
icon_state = "gps-eng"
gps_prefix = "ENG"
compass_color = "#A66300"
gpstag = "ENG0"
/obj/item/gps/mining
icon_state = "gps-min"
gps_prefix = "MIN"
compass_color = "#5F4519"
gpstag = "MIN0"
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/janitor
icon_state = "gps-jan"
gps_prefix = "JAN"
compass_color = "#6eaa2c"
gpstag = "JAN0"
/obj/item/gps/medical
icon_state = "gps-med"
gps_prefix = "MED"
compass_color = "#5EABEB"
gpstag = "MED0"
/obj/item/gps/marooning_equipment
icon_state = "gps-mar"
gps_prefix = "MAROON"
compass_color = "#EAD152"
gpstag = "MAROON0"
/********** Static GPS Start **********/
// Static GPS
/obj/item/gps/stationary
name = "static GPS"
desc = "A static global positioning system."
anchored = TRUE
unacidable = TRUE
layer = BASE_ABOVE_OBJ_LAYER
gpstag = "STAT0"
/obj/item/gps/stationary/Initialize()
SHOULD_CALL_PARENT(FALSE)
if(flags_1 & INITIALIZED_1)
stack_trace("Warning: [src]([type]) initialized multiple times!")
flags_1 |= INITIALIZED_1
compass = new(src)
update_position()
if(ismob(loc))
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src in H.get_equipped_items())
held_by = H
else
implanted_into = loc
else if(issilicon(loc))
held_by = loc
implanted_into = loc
else if(istype(loc, /obj/item/robot_module))
held_by = loc.loc
implanted_into = loc.loc
update_icon()
if(held_by)
RegisterSignal(held_by, COMSIG_MOVABLE_MOVED, PROC_REF(update_position), TRUE)
if(implanted_into)
RegisterSignal(implanted_into, COMSIG_MOVABLE_MOVED, PROC_REF(update_position), TRUE)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(update_position))
for(var/gps in GLOB.gps_list)
tracking += GLOB.gps_list[gps]["tag"]
START_PROCESSING(SSprocessing, src)
return INITIALIZE_HINT_NORMAL
/obj/item/gps/stationary/attack_hand() // Don't let users pick it up.
return
// Spark
/obj/item/gps/stationary/mining_shuttle
name = "static GPS (SCCV Spark)"
desc = "A static global positioning system helpful for finding your way back to the mining shuttle."
icon_state = "gps-min"
gps_prefix = "MIN"
compass_color = "#5F4519"
gpstag = "SPARK"
// Intrepid
/obj/item/gps/stationary/sccv_intrepid
name = "static GPS (SCCV Intrepid)"
desc = "A static global positioning system helpful for finding your way back to the SCCV Intrepid."
icon_state = "gps-com"
gps_prefix = "COM"
compass_color = "#193A7A"
gpstag = "INTREPID"
/obj/item/gps/stationary/sccv_canary
name = "static GPS (SCCV Canary)"
desc = "A static global positioning system helpful for finding your way back to the SCCV Canary."
icon_state = "gps-com"
gps_prefix = "COM"
compass_color = "#57c5e0"
gpstag = "CANARY"
/obj/item/gps/stationary/sccv_quark
name = "static GPS (SCCV Quark)"
desc = "A static global positioning system helpful for finding your way back to the SCCV Quark."
icon_state = "gps-sci"
gps_prefix = "SCI"
compass_color = "#d691ce"
gpstag = "QUARK"
/********** Static GPS End **********/