Files
Bubberstation/code/game/objects/items/pinpointer.dm
JJRcop c314fbc6cb [READY] (nerf) Adds proximity crew pinpointer to Paramedics (#48418)
About The Pull Request

When #48236 was in progress, there was discussion about how a crew pinpointer was OP for paramedics. I immediately had an idea for a new one and made a PR to the paramedic PR. 81Denton asked me to make this its own PR after the paramedic PR was merged.

The proximity crew pinpointer does not point in the direction of the patient, but has a circle sprite that gets smaller larger as you get closer, so you have to search around, or combine it with the handheld crew monitor.

The circle is at maximum the smallest size after 29 tiles away, so you must be 28 or fewer tiles away for an indication that you are getting close. I welcome feedback on this. The handheld crew monitor can be used to find the area they are in.

proxpin

Demo video: https://youtu.be/_rXeJ49b-e8 (The pinpointer gets bigger rather than smaller now)

This is only attainable at the moment to paramedics as they spawn. Should it also be available elsewhere? now constructable from the Biological Technology techweb
Further changes

Moved Crew Pinpointer into premium nanomed items for 900 credits
Moved Handheld Crew monitor into premium nanomed items for 1750 credits, same price as before
Why It's Good For The Game

In #48236 it was stated that paramedics should start with the bare minimum equipment to do their job. The crew pinpointer that points them in exactly the right direction is pretty powerful, and this nerf will encourage them to either get used to the proximity one, or upgrade to the normal one at a price from the NanoMed or from techwebs.

Moving the Crew Monitor into premium was necessary to make it more of a luxury than an instant grab.
Feedback for nanomed premium prices on the normal pinpointer and the handheld monitor would help a lot
Changelog

cl JJRcop
add: New proximity crew pinpointer.
balance: Paramedic's crew pinpointer replaced with proximity crew pinpointer.
balance: The crew monitor was moved to premium items in nanomed, same with the handheld crew pinpointer
/cl
2020-01-14 11:18:55 +13:00

235 lines
7.4 KiB
Plaintext

//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
/obj/item/pinpointer
name = "pinpointer"
desc = "A handheld tracking device that locks onto certain signals."
icon = 'icons/obj/device.dmi'
icon_state = "pinpointer"
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throw_speed = 3
throw_range = 7
custom_materials = list(/datum/material/iron = 500, /datum/material/glass = 250)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/active = FALSE
var/atom/movable/target //The thing we're searching for
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
var/alert = FALSE // TRUE to display things more seriously
var/process_scan = TRUE // some pinpointers change target every time they scan, which means we can't have it change very process but instead when it turns on.
var/icon_suffix = "" // for special pinpointer icons
/obj/item/pinpointer/Initialize()
. = ..()
GLOB.pinpointer_list += src
/obj/item/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
target = null
return ..()
/obj/item/pinpointer/attack_self(mob/living/user)
if(!process_scan) //since it's not scanning on process, it scans here.
scan_for_target()
toggle_on()
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
/obj/item/pinpointer/proc/toggle_on()
active = !active
playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE)
if(active)
START_PROCESSING(SSfastprocess, src)
else
target = null
STOP_PROCESSING(SSfastprocess, src)
update_icon()
/obj/item/pinpointer/process()
if(!active)
return PROCESS_KILL
if(process_scan)
scan_for_target()
update_icon()
/obj/item/pinpointer/proc/scan_for_target()
return
/obj/item/pinpointer/update_overlays()
. = ..()
if(!active)
return
if(!target)
. += "pinon[alert ? "alert" : ""]null[icon_suffix]"
return
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
. += "pinon[alert ? "alert" : ""]null[icon_suffix]"
return
update_direction_icon(here, there)
///Called by update_icon after sanity. There is a target
/obj/item/pinpointer/proc/update_direction_icon(here, there)
if(get_dist_euclidian(here,there) <= minimum_range)
. += "pinon[alert ? "alert" : ""]direct[icon_suffix]"
else
setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
. += "pinon[alert ? "alert" : "close"][icon_suffix]"
if(9 to 16)
. += "pinon[alert ? "alert" : "medium"][icon_suffix]"
if(16 to INFINITY)
. += "pinon[alert ? "alert" : "far"][icon_suffix]"
/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
name = "crew pinpointer"
desc = "A handheld tracking device that points to crew suit sensors."
icon_state = "pinpointer_crew"
custom_price = 900
custom_premium_price = 900
var/has_owner = FALSE
var/pinpointer_owner = null
var/ignore_suit_sensor_level = FALSE /// Do we find people even if their suit sensors are turned off
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
// Suit sensors must be on maximum.
if(!U.has_sensor || (U.sensor_mode < SENSOR_COORDS && !ignore_suit_sensor_level))
return FALSE
var/turf/there = get_turf(H)
return (H.z != 0 || (there && there.z == here.z))
return FALSE
/obj/item/pinpointer/crew/attack_self(mob/living/user)
if(active)
toggle_on()
user.visible_message("<span class='notice'>[user] deactivates [user.p_their()] pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
return
if (has_owner && !pinpointer_owner)
pinpointer_owner = user
if (pinpointer_owner && pinpointer_owner != user)
to_chat(user, "<span class='notice'>The pinpointer doesn't respond. It seems to only recognise its owner.</span>")
return
var/list/name_counts = list()
var/list/names = list()
for(var/i in GLOB.human_list)
var/mob/living/carbon/human/H = i
if(!trackable(H))
continue
var/crewmember_name = "Unknown"
if(H.wear_id)
var/obj/item/card/id/I = H.wear_id.GetID()
if(I && I.registered_name)
crewmember_name = I.registered_name
while(crewmember_name in name_counts)
name_counts[crewmember_name]++
crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
names[crewmember_name] = H
name_counts[crewmember_name] = 1
if(!names.len)
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
return
var/A = input(user, "Person to track", "Pinpoint") in sortList(names)
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
return
target = names[A]
toggle_on()
user.visible_message("<span class='notice'>[user] activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
/obj/item/pinpointer/crew/scan_for_target()
if(target)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(!trackable(H))
target = null
if(!target) //target can be set to null from above code, or elsewhere
active = FALSE
/obj/item/pinpointer/crew/prox //Weaker version of crew monitor primarily for EMT
name = "proximity crew pinpointer"
desc = "A handheld tracking device that displays its proximity to crew suit sensors."
icon_state = "pinpointer_crewprox"
custom_price = 300
/obj/item/pinpointer/crew/prox/update_direction_icon(here, there)
var/size = ""
if(here == there)
size = "small"
else
switch(get_dist(here, there))
if(1 to 4)
size = "xtrlarge"
if(5 to 16)
size = "large"
//17 through 28 use the normal pinion, "pinondirect"
if(29 to INFINITY)
size = "small"
add_overlay("pinondirect[size]")
/obj/item/pinpointer/pair
name = "pair pinpointer"
desc = "A handheld tracking device that locks onto its other half of the matching pair."
var/other_pair
/obj/item/pinpointer/pair/Destroy()
other_pair = null
. = ..()
/obj/item/pinpointer/pair/scan_for_target()
target = other_pair
/obj/item/pinpointer/pair/examine(mob/user)
. = ..()
if(!active || !target)
return
var/mob/mob_holder = get(target, /mob)
if(istype(mob_holder))
. += "Its pair is being held by [mob_holder]."
return
/obj/item/storage/box/pinpointer_pairs
name = "pinpointer pair box"
/obj/item/storage/box/pinpointer_pairs/PopulateContents()
var/obj/item/pinpointer/pair/A = new(src)
var/obj/item/pinpointer/pair/B = new(src)
A.other_pair = B
B.other_pair = A
/obj/item/pinpointer/shuttle
name = "fugitive pinpointer"
desc = "A handheld tracking device that locates the bounty hunter shuttle for quick escapes."
icon_state = "pinpointer_hunter"
icon_suffix = "_hunter"
var/obj/shuttleport
/obj/item/pinpointer/shuttle/Initialize(mapload)
. = ..()
shuttleport = SSshuttle.getShuttle("huntership")
/obj/item/pinpointer/shuttle/scan_for_target()
target = shuttleport
/obj/item/pinpointer/shuttle/Destroy()
shuttleport = null
. = ..()