GPS cartridge

This commit is contained in:
atermonera
2018-07-24 18:58:06 -07:00
committed by Atermonera
parent da45a40fad
commit 96d24e7427
6 changed files with 249 additions and 112 deletions

View File

@@ -33,15 +33,13 @@
return list()
// Handles cartridge-specific functions
// The helper.link() MUST HAVE 'cartridge_topic' passed into href in order for cartridge functions to be processed.
// Doesn't matter what the value of it is in most cases, it's just a flag to say, "Hey, there's cartridge data to change!"
// The helper.link() MUST HAVE 'cartridge_topic' passed into the href in order for cartridge functions to be processed.
// Doesn't matter what the value of it is for now, it's just a flag to say, "Hey, there's cartridge data to change!"
/obj/item/weapon/commcard/Topic(href, href_list)
// Signalers
if(href_list["signaler_target"])
world << href
var/obj/item/device/assembly/signaler/S = locate(href_list["signaler_target"]) // Should locate the correct signaler
if(!istype(S)) // Ref is no longer valid
@@ -72,9 +70,47 @@
if(href_list["powernet_refresh"])
internal_data["grid_sensors"] = find_powernet_sensors()
// Load apc's on targeted powernet
if(href_list["powernet_target"])
internal_data["powernet_target"] = href_list["powernet_target"]
// GPS units
if(href_list["gps_target"])
var/obj/item/device/gps/G = locate(href_list["gps_target"])
if(!istype(G)) // Ref is no longer valid
return
if(G.loc != src) // No longer within the cartridge
return
world << "Valid gps_target"
switch(href_list["gps_action"])
if("Power")
world << "Setting tracking to [href_list["value"]]"
G.tracking = text2num(href_list["value"])
if("Long_Range")
world << "Setting local_mode to [href_list["value"]]"
G.local_mode = text2num(href_list["value"])
if("Hide_Signal")
world << "Setting hide_signal to [href_list["value"]]"
G.hide_signal = text2num(href_list["value"])
if("Tag")
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Ref no longer valid
return
var/newTag = input(user, "Please enter desired tag.", G.tag) as text|null
world << "Setting Tag to [newTag]"
if(newTag)
G.tag = newTag
// Engineering Cartridge:
// Devices
@@ -226,22 +262,6 @@
list("field" = "janidata", "value" = get_janitorial_locations())
)
// Too computationally expensive; unfeasible to perform the list parsing with the frequency nanoUI will demand
// In order to get all microwave recipe ingredient/product names, I'd have to instantiate and then delete everything at least once
// Drink recipes are more doable, but still requires iterating over a fairly large set of subtypes
/******************************************************
// Service Cartridge:
// Templates
// -- Recipe Lists
/obj/item/weapon/commcard/service
name = "\improper Serv-U Pro"
desc = "A data cartridge designed to serve YOU!"
//I'm gonna regret this but recipes menu
/obj/item/weapon/commcard/service/get_data()
// Add list of recipes to ui template
// SEE: /code/modules/food/recipe_dump.dm
******************************************************/
// Signal Cartridge:
// Devices
@@ -299,19 +319,6 @@
// Add supply bot access to ui template
// Mining Cartridge:
// Templates
// -- Ore Processing Recipes
// Much more doable than food/drink, there's vastly fewer recipe datums to iterate over.
// Code here will be similar to what would be used for food/drink, just different path for subtypesof()
/obj/item/weapon/commcard/miner
name = "\improper Drill-Jockey 4.5"
desc = "It's covered in some sort of sand."
/obj/item/weapon/commcard/miner/get_data()
// Add ore recipes to ui template
// Command Cartridge:
// Templates
// -- Status Display Access
@@ -493,11 +500,66 @@
/obj/item/weapon/commcard/explorer
name = "\improper Explorator cartridge"
icon_state = "cart-tox"
//GPS
ui_templates = list(
list("name" = "Integrated GPS", "template" = "gps_access.tmpl")
)
/obj/item/weapon/commcard/explorer/New()
..()
internal_devices |= new /obj/item/device/gps(src)
internal_devices |= new /obj/item/device/gps/explorer(src)
/obj/item/weapon/commcard/explorer/get_data()
// GPS Access
// GPS Access
var/intgps[0] // Gps devices within the commcard -- Allow tag edits, turning on/off, etc
var/extgps[0] // Gps devices not inside the commcard -- Print locations if a gps is on
var/stagps[0] // Gps status
var/obj/item/device/gps/cumulative = new(src)
cumulative.tracking = FALSE
cumulative.local_mode = TRUE // Won't detect long-range signals automatically
cumulative.long_range = FALSE
var/list/toggled_gps = list() // List of GPS units that are turned off before display_list() is called
for(var/obj/item/device/gps/G in internal_devices)
var/gpsdata[0]
if(G.tracking && !G.emped)
cumulative.tracking = TRUE // Turn it on
if(G.long_range)
cumulative.long_range = TRUE // It can detect long-range
if(!G.local_mode)
cumulative.local_mode = FALSE // It is detecting long-range
gpsdata["ref"] = "\ref[G]"
gpsdata["tag"] = G.gps_tag
gpsdata["power"] = G.tracking
gpsdata["local_mode"] = G.local_mode
gpsdata["long_range"] = G.long_range
gpsdata["hide_signal"] = G.hide_signal
gpsdata["can_hide"] = G.can_hide_signal
intgps[++intgps.len] = gpsdata // Add it to the list
if(G.tracking)
G.tracking = FALSE // Disable the internal gps units so they don't show up in the report
toggled_gps += G
var/list/remote_gps = cumulative.display_list()
for(var/obj/item/device/gps/G in toggled_gps)
G.tracking = TRUE
stagps["enabled"] = cumulative.tracking
stagps["long_range_en"] = (cumulative.long_range && !cumulative.local_mode)
stagps["my_area_name"] = remote_gps["my_area_name"]
stagps["curr_x"] = remote_gps["curr_x"]
stagps["curr_y"] = remote_gps["curr_y"]
stagps["curr_z"] = remote_gps["curr_z"]
stagps["curr_z_name"] = remote_gps["curr_z_name"]
extgps = remote_gps["gps_list"]
qdel(cumulative)
return list(
list("field" = "gps_access", "value" = intgps),
list("field" = "gps_signal", "value" = extgps),
list("field" = "gps_status", "value" = stagps)
)

View File

@@ -68,6 +68,55 @@ var/list/GPS_list = list()
/obj/item/device/gps/attack_self(mob/user)
display(user)
// Compiles all the data not available directly from the GPS
// Like the positions and directions to all other GPS units
/obj/item/device/gps/proc/display_list()
var/list/dat = list()
var/turf/curr = get_turf(src)
var/area/my_area = get_area(src)
dat["my_area_name"] = my_area.name
dat["curr_x"] = curr.x
dat["curr_y"] = curr.y
dat["curr_z"] = curr.z
dat["curr_z_name"] = using_map.get_zlevel_name(curr.z)
dat["gps_list"] = list()
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
for(var/obj/item/device/gps/G in GPS_list - src)
if(!G.tracking || G.emped || G.hide_signal)
continue
var/turf/T = get_turf(G)
if(local_mode && curr.z != T.z)
continue
if(!(T.z in dat["z_level_detection"]))
continue
var/gps_data[0]
gps_data["ref"] = G
gps_data["gps_tag"] = G.gps_tag
var/area/A = get_area(G)
gps_data["area_name"] = A.name
if(istype(A, /area/submap))
gps_data["area_name"] = "Unknown Area" // Avoid spoilers.
gps_data["z_name"] = using_map.get_zlevel_name(T.z)
gps_data["direction"] = get_adir(curr, T)
gps_data["degrees"] = round(Get_Angle(curr,T))
gps_data["distX"] = T.x - curr.x
gps_data["distY"] = T.y - curr.y
gps_data["distance"] = get_dist(curr, T)
gps_data["local"] = (curr.z == T.z)
gps_data["x"] = T.x
gps_data["y"] = T.y
dat["gps_list"][++dat["gps_list"].len] = gps_data
return dat
/obj/item/device/gps/proc/display(mob/user)
if(!tracking)
to_chat(user, "The device is off. Alt-click it to turn it on.")
@@ -77,48 +126,20 @@ var/list/GPS_list = list()
return
var/list/dat = list()
var/list/gps_data = display_list()
var/turf/curr = get_turf(src)
var/area/my_area = get_area(src)
dat += "Current location: [my_area.name] <b>([curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)])</b>"
dat += "Current location: [gps_data["my_area_name"]] <b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b>"
dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. <a href='?src=\ref[src];tag=1'>\[Change Tag\]</a> \
<a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a> \
[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]"
var/list/signals = list()
for(var/gps in GPS_list)
var/obj/item/device/gps/G = gps
if(G.emped || !G.tracking || G.hide_signal || G == src) // Their GPS isn't on or functional.
continue
var/turf/T = get_turf(G)
var/z_level_detection = using_map.get_map_levels(curr.z, long_range)
if(local_mode && T.z != curr.z) // Only care about the current z-level.
continue
else if(!(T.z in z_level_detection)) // Too far away.
continue
var/area/their_area = get_area(G)
var/area_name = their_area.name
if(istype(their_area, /area/submap))
area_name = "Unknown Area" // Avoid spoilers.
var/Z_name = using_map.get_zlevel_name(T.z)
var/direction = get_adir(curr, T)
var/distX = T.x - curr.x
var/distY = T.y - curr.y
var/distance = get_dist(curr, T)
var/local = curr.z == T.z ? TRUE : FALSE
if(istype(gps, /obj/item/device/gps/internal/poi))
signals += " [G.gps_tag]: [area_name] - [local ? "[direction] Dist: [round(distance, 10)]m" : "in \the [Z_name]"]"
else
signals += " [G.gps_tag]: [area_name], ([T.x], [T.y]) - [local ? "[direction] Dist: [distX ? "[abs(round(distX, 1))]m [(distX > 0) ? "E" : "W"], " : ""][distY ? "[abs(round(distY, 1))]m [(distY > 0) ? "N" : "S"]" : ""]" : "in \the [Z_name]"]"
if(signals.len)
if(gps_data["gps_list"].len)
dat += "Detected signals;"
for(var/line in signals)
dat += line
for(var/gps in gps_data["gps_list"])
if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
dat += " [gps["gps_tag"]]: [gps["area_name"]] - [gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"]"
else
dat += " [gps["gps_tag"]]: [gps["area_name"]], ([gps["x"]], [gps["y"]]) - [gps["local"] ? "[gps["direction"]] Dist: [gps["distX"] ? "[abs(round(gps["distX"], 1))]m [(gps["distX"] > 0) ? "E" : "W"], " : ""][gps["distY"] ? "[abs(round(gps["distY"], 1))]m [(gps["distY"] > 0) ? "N" : "S"]" : ""]" : "in \the [gps["z_name"]]"]"
else
dat += "No other signals detected."
@@ -221,45 +242,17 @@ var/list/GPS_list = list()
return
var/list/dat = list()
var/list/gps_data = display_list()
var/turf/curr = get_turf(src)
var/area/my_area = get_area(src)
dat += "Current location: [my_area.name] <b>([curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)])</b>"
dat += "Current location: [gps_data["my_area_name"]] <b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b>"
dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. <a href='?src=\ref[src];tag=1'>\[Change Tag\]</a> \
<a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a> \
[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]"
var/list/signals = list()
for(var/gps in GPS_list)
var/obj/item/device/gps/G = gps
if(G.emped || !G.tracking || G.hide_signal || G == src) // Their GPS isn't on or functional.
continue
var/turf/T = get_turf(G)
var/z_level_detection = using_map.get_map_levels(curr.z, long_range)
if(local_mode && T.z != curr.z) // Only care about the current z-level.
continue
else if(!(T.z in z_level_detection)) // Too far away.
continue
var/area/their_area = get_area(G)
var/area_name = their_area.name
if(istype(their_area, /area/submap))
area_name = "Unknown Area" // Avoid spoilers.
var/Z_name = using_map.get_zlevel_name(T.z)
var/coord = "[T.x], [T.y], [Z_name]"
var/degrees = round(Get_Angle(curr, T))
var/direction = get_adir(curr, T)
var/distance = get_dist(curr, T)
var/local = curr.z == T.z ? TRUE : FALSE
signals += " [G.gps_tag]: [area_name] ([coord]) [local ? "Dist: [distance]m Dir: [degrees]° ([direction])":""]"
if(signals.len)
if(gps_data["gps_list"].len)
dat += "Detected signals;"
for(var/line in signals)
dat += line
for(var/gps in gps_data["gps_list"])
dat += " [gps["gps_tag"]]: [gps["area_name"]] ([gps["x"]], [gps["y"]], [gps["z_name"]]) [gps["local"] ? "Dist: [gps["distance"]]m Dir: [gps["degrees"]]° ([gps["direction"]])" :""]"
else
dat += "No other signals detected."

View File

@@ -60,6 +60,9 @@ NanoBaseHelpers = function ()
ceil: function(number) {
return Math.ceil(number);
},
abs: function(number) {
return Math.abs(number);
},
// Format a string (~string("Hello {0}, how are {1}?", 'Martin', 'you') becomes "Hello Martin, how are you?")
string: function() {
if (arguments.length == 0)

View File

@@ -314,7 +314,10 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm
Owner:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:data.owner}}</div> {{:helper.link('Rename', 'pencil', {'rename' : 1})}}
<div style="float: left; width: 180px;">
{{:data.owner}}
</div>
{{:helper.link('Rename', 'pencil', {'rename' : 1})}}
</div>
</div>
@@ -323,7 +326,9 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm
Occupation:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:data.occupation}}</div>
<div style="float: left; width: 180px;">
{{:data.occupation}}
</div>
</div>
</div>
@@ -345,10 +350,15 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm
Device EPv2 Address:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:data.address}}</div>
<div style="float: left; width: 180px;">
{{:data.address}}
</div>
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:helper.link('Visible', 'signal-diag', {'toggle_visibility' : 1}, data.visible ? 'selected' : null)}}{{:helper.link('Invisible', 'close', {'toggle_visibility' : 1}, data.visible ? null : 'selected')}}</div>
<div style="float: left; width: 180px;">
{{:helper.link('Visible', 'signal-diag', {'toggle_visibility' : 1}, data.visible ? 'selected' : null)}}
{{:helper.link('Invisible', 'close', {'toggle_visibility' : 1}, data.visible ? null : 'selected')}}
</div>
</div>
</div>
@@ -357,7 +367,10 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm
Ringer:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:helper.link('On', 'volume-on', {'toggle_ringer' : 1}, data.ring ? 'selected' : null)}}{{:helper.link('Off', 'volume-off', {'toggle_ringer' : 1}, data.ring ? null : 'selected')}}</div>
<div style="float: left; width: 180px;">
{{:helper.link('On', 'volume-on', {'toggle_ringer' : 1}, data.ring ? 'selected' : null)}}
{{:helper.link('Off', 'volume-off', {'toggle_ringer' : 1}, data.ring ? null : 'selected')}}
</div>
</div>
</div>
@@ -383,7 +396,8 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm
{{:value.name}}
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:helper.link('On', 'volume-on', {'toggle_device' : value.index}, value.active ? 'selected' : null)}}{{:helper.link('Off', 'volume-off', {'toggle_device' : value.index}, value.active ? null : 'selected')}}</div>
<div style="float: left; width: 180px;">{{:helper.link('On', 'power', {'toggle_device' : value.index}, value.active ? 'selected' : null)}}
{{:helper.link('Off', 'stop', {'toggle_device' : value.index}, value.active ? null : 'selected')}}</div>
</div>
</div>
{{/for}}

View File

@@ -0,0 +1,66 @@
<H2>Integrated GPS</H2>
<!-- List current location -->
{{if data.gps_status.enabled}}
<div class="item">
Area: {{:data.gps_status.my_area_name}}, {{:data.gps_status.curr_z_name}}<br>
GPS Coordinates: ({{:data.gps_status.curr_x}}, {{:data.gps_status.curr_y}})
</div>
{{else}}
<div class="item">
<span class="bad">Error: Location data unavailable. No sensors online!</span>
</div>
{{/if}}
<!-- List internal gps units -->
<div class="statusDisplayRecords">
{{for data.gps_access}}
<div class="item">
<div class="itemLabel">
{{:index}}: {{:value.tag}}
</div>
<div class="itemContent">
{{:helper.link('On', 'power', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Power", 'value' : "1"}, value.power ? 'selected' : null)}}
{{:helper.link('Off', 'stop', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Power", 'value' : "0"}, value.power ? null : 'selected')}}
{{:helper.link('Edit Tag', 'power', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Tag", 'user' : data.user})}}
{{if value.power}}
{{if value.long_range}}
<br>
<!-- 'value' is inverted, because long range scanning is active-low on the variable local_mode -->
{{:helper.string("Long range scanning is {0}.", value.local_mode ? "disabled" : "active")}}
{{:helper.link('Enable', 'power', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Long_Range", 'value' : "0"}, value.long_range_en ? 'selected' : null)}}
{{:helper.link('Disable', 'stop', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Long_Range", 'value' : "1"}, value.long_range_en ? null : 'selected')}}
{{/if}}
{{if value.can_hide}}
<br>
{{:helper.string("{0}", value.hide_signal ? "Broadcasting location" : "Receiving only ")}} <!-- Lazy Padding -->
{{:helper.link('Broadcast', 'power', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Hide_Signal", 'value' : "1"}, value.hide_signal ? 'selected' : null)}}
{{:helper.link('Receive', 'stop', {'cartridge_topic' : "1", 'gps_target' : value.ref, 'gps_action' : "Hide_Signal", 'value' : "0"}, value.hide_signal ? null : 'selected')}}
{{/if}}
{{/if}}
</div>
</div>
{{empty}}
{{/for}}
</div>
<!-- List remote GPS units -->
{{if data.gps_status.enabled}}
<div class="statusDisplayRecords">
{{for data.gps_signal}}
<div class="item">
<div class="itemLabel">
{{:value.gps_tag}}
</div>
<div class="itemContent">
Coordinates: ({{:value.x}}, {{:value.y}})
<br>
Area: {{:value.area_name}}, {{:value.z_name}}
{{if value.local}}
{{:helper.string("Distance: {0}m {1} - {2}m {3}, {4}m {5}", value.distance < 0 ? 0 : value.distance, value.direction, helper.abs(value.distY), ((value.distY > 0) ? "N" : "S"), helper.abs(value.distX), ((value.distX > 0) ? "E" : "W"))}}
{{/if}}
</div>
</div>
{{/for}}
</div>
{{/if}}

View File

@@ -1,7 +1,6 @@
<H2>Signaler Control</H2>
<!-- List signalers -->
<!-- Specific bot status -->
{{for data.signaler_access}}
<div class="item">
<div class="itemLabel">