diff --git a/baystation12.dme b/baystation12.dme
index a8eeac7aede..86d2a2d5028 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -601,7 +601,10 @@
#include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm"
#include "code\game\objects\items\devices\transfer_valve.dm"
-#include "code\game\objects\items\devices\uplinks.dm"
+#include "code\game\objects\items\devices\uplink.dm"
+#include "code\game\objects\items\devices\uplink_categories.dm"
+#include "code\game\objects\items\devices\uplink_items.dm"
+#include "code\game\objects\items\devices\uplink_random_lists.dm"
#include "code\game\objects\items\devices\violin.dm"
#include "code\game\objects\items\devices\whistle.dm"
#include "code\game\objects\items\devices\PDA\cart.dm"
diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm
index aad02b1c6c6..02b048a6ee4 100644
--- a/code/game/antagonist/antagonist.dm
+++ b/code/game/antagonist/antagonist.dm
@@ -192,14 +192,12 @@
var/uplink_true = 0
var/purchases = ""
for(var/obj/item/device/uplink/H in world_uplinks)
- if(H && H.uplink_owner && H.uplink_owner == ply)
+ if(H && H.owner && H.owner == ply)
TC_uses += H.used_TC
uplink_true = 1
var/list/refined_log = new()
for(var/datum/uplink_item/UI in H.purchase_log)
- var/obj/I = new UI.path
- refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]")
- qdel(I)
+ refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
purchases = english_list(refined_log, nothing_text = "")
if(uplink_true)
text += " (used [TC_uses] TC)"
diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm
index c8b8b95b2a6..c5f4eb72897 100644
--- a/code/game/antagonist/station/traitor.dm
+++ b/code/game/antagonist/station/traitor.dm
@@ -148,8 +148,7 @@ var/datum/antagonist/traitor/traitors
if ((freq % 2) == 0)
freq += 1
freq = freqlist[rand(1, freqlist.len)]
- var/obj/item/device/uplink/hidden/T = new(R)
- T.uplink_owner = traitor_mob.mind
+ var/obj/item/device/uplink/hidden/T = new(R, traitor_mob.mind)
target_radio.hidden_uplink = T
target_radio.traitor_frequency = freq
traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
@@ -158,8 +157,7 @@ var/datum/antagonist/traitor/traitors
else if (istype(R, /obj/item/device/pda))
// generate a passcode if the uplink is hidden in a PDA
var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
- var/obj/item/device/uplink/hidden/T = new(R)
- T.uplink_owner = traitor_mob.mind
+ var/obj/item/device/uplink/hidden/T = new(R, traitor_mob.mind)
R.hidden_uplink = T
var/obj/item/device/pda/P = R
P.lock_code = pda_pass
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index c6b86d16708..74d87dc800b 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -64,82 +64,6 @@ var/global/list/additional_antag_types = list()
var/uplink_welcome = "Illegal Uplink Console:"
var/uplink_uses = 12
- var/list/datum/uplink_item/uplink_items = list(
- "Ammunition" = list(
- new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, ".357", "RA"),
- new/datum/uplink_item(/obj/item/ammo_magazine/mc9mm, 2, "9mm", "R9"),
- new/datum/uplink_item(/obj/item/ammo_magazine/chemdart, 2, "Darts", "AD"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/sniperammo, 2, "14.5mm", "SA")
- ),
- "Highly Visible and Dangerous Weapons" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/emps, 3, "5 EMP Grenades", "EM"),
- new/datum/uplink_item(/obj/item/weapon/melee/energy/sword, 4, "Energy Sword", "ES"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/dartgun, 5, "Dart Gun", "DG"),
- new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/g9mm, 5, "Silenced 9mm", "S9"),
- new/datum/uplink_item(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, 6, "Exosuit Rigged Laser", "RL"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/revolver, 6, "Revolver", "RE"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/heavysniper, 12, "Anti-materiel Rifle", "AMR")
- ),
- "Stealthy and Inconspicuous Weapons" = list(
- new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"),
- new/datum/uplink_item(/obj/item/weapon/cane/concealed, 2, "Concealed Cane Sword", "CC"),
- new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"),
- new/datum/uplink_item(/obj/item/weapon/pen/reagent/paralysis, 3, "Paralysis Pen", "PP"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/toxin, 4, "Random Toxin - Beaker", "RT")
- ),
- "Stealth and Camouflage Items" = list(
- new/datum/uplink_item(/obj/item/weapon/card/id/syndicate, 2, "Agent ID card", "AC"),
- new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Bug Kit", "BK"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"),
- new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP"),
- new/datum/uplink_item(/obj/item/clothing/mask/gas/voice, 4, "Voice Changer", "VC"),
- new/datum/uplink_item(/obj/item/weapon/disk/file/cameras/syndicate, 6, "Camera Network Access - Floppy", "SF")
- ),
- "Devices and Tools" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/toolbox/syndicate, 1, "Fully Loaded Toolbox", "ST"),
- new/datum/uplink_item(/obj/item/weapon/plastique, 2, "C-4 (Destroys walls)", "C4"),
- new/datum/uplink_item(/obj/item/device/encryptionkey/syndicate, 2, "Encrypted Radio Channel Key", "ER"),
- new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"),
- new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/clerical, 3, "Morphic Clerical Kit", "CK"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/space, 3, "Space Suit", "SS"),
- new/datum/uplink_item(/obj/item/clothing/glasses/thermal/syndi, 3, "Thermal Imaging Glasses", "TM"),
- new/datum/uplink_item(/obj/item/clothing/suit/storage/vest/heavy/merc, 4, "Heavy Armor Vest", "HAV"),
- new/datum/uplink_item(/obj/item/weapon/aiModule/syndicate, 7, "Hacked AI Upload Module", "AI"),
- new/datum/uplink_item(/obj/item/device/powersink, 5, "Powersink (DANGER!)", "PS",),
- new/datum/uplink_item(/obj/item/device/radio/beacon/syndicate, 7, "Singularity Beacon (DANGER!)", "SB"),
- new/datum/uplink_item(/obj/item/weapon/circuitboard/teleporter, 20, "Teleporter Circuit Board", "TP")
- ),
- "Implants" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_freedom, 3, "Freedom Implant", "FI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_compress, 4, "Compressed Matter Implant", "CI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_explosive, 6, "Explosive Implant (DANGER!)", "EI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_uplink, 10, "Uplink Implant (Contains 5 Telecrystals)", "UI")
- ),
- "Medical" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/sinpockets, 1, "Box of Sin-Pockets", "DP"),
- new/datum/uplink_item(/obj/item/weapon/storage/firstaid/surgery, 5, "Surgery kit", "SK"),
- new/datum/uplink_item(/obj/item/weapon/storage/firstaid/combat, 5, "Combat medical kit", "CM")
- ),
- "Hardsuit Modules" = list(
- new/datum/uplink_item(/obj/item/rig_module/vision/thermal, 2, "Thermal Scanner", "RTS"),
- new/datum/uplink_item(/obj/item/rig_module/fabricator/energy_net, 3, "Net Projector", "REN"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/ewar_voice, 4, "Electrowarfare Suite and Voice Synthesiser", "REV"),
- new/datum/uplink_item(/obj/item/rig_module/maneuvering_jets, 4, "Maneuvering Jets", "RMJ"),
- new/datum/uplink_item(/obj/item/rig_module/mounted/egun, 6, "Mounted Energy Gun", "REG"),
- new/datum/uplink_item(/obj/item/rig_module/power_sink, 6, "Power Sink", "RPS"),
- new/datum/uplink_item(/obj/item/rig_module/mounted, 8, "Mounted Laser Cannon", "RLC")
- ),
- "(Pointless) Badassery" = list(
- new/datum/uplink_item(/obj/item/toy/syndicateballoon, 10, "For showing that You Are The BOSS (Useless Balloon)", "BS"),
- new/datum/uplink_item(/obj/item/toy/nanotrasenballoon, 10, "For showing that you love NT SOO much (Useless Balloon)", "NT")
- )
- )
-
/datum/game_mode/Topic(href, href_list[])
if(..())
return
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index 72a99f494ed..8ccc4616c50 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -1,6 +1,6 @@
/obj/item/device/encryptionkey/
- name = "standard encrpytion key"
+ name = "standard encryption key"
desc = "An encryption key for a radio headset. Contains cypherkeys."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplink.dm
similarity index 55%
rename from code/game/objects/items/devices/uplinks.dm
rename to code/game/objects/items/devices/uplink.dm
index 96874bd946b..eca572ab621 100644
--- a/code/game/objects/items/devices/uplinks.dm
+++ b/code/game/objects/items/devices/uplink.dm
@@ -6,159 +6,28 @@ A list of items and costs is stored under the datum of every game mode, alongsid
*/
-/datum/uplink_item/
- var/name = ""
- var/cost = 0
- var/path = null
- var/reference = ""
- var/description = ""
-
-datum/uplink_item/New(var/itemPath, var/itemCost, var/itemName, var/itemReference, var/itemDescription)
- cost = itemCost
- path = itemPath
- name = itemName
- reference = itemReference
- description = itemDescription
-
-datum/uplink_item/proc/description()
- if(!description)
- // Fallback description
- var/obj/temp = src.path
- description = replacetext(initial(temp.desc), "\n", "
")
- return description
-
-/datum/uplink_item/proc/generate_item(var/newloc)
- var/list/L = list()
- if(ispath(path))
- L += new path(newloc)
- else if(islist(path))
- for(var/item_path in path)
- L += new item_path(newloc)
- return L
-
-datum/nano_item_lists
- var/list/items_nano
- var/list/items_reference
-
/obj/item/device/uplink
var/welcome // Welcoming menu message
var/uses // Numbers of crystals
- var/list/ItemsCategory // List of categories with lists of items
- var/list/ItemsReference // List of references with an associated item
- var/list/nanoui_items // List of items for NanoUI use
- var/nanoui_menu = 0 // The current menu we are in
- var/list/nanoui_data = new // Additional data for NanoUI use
-
- var/list/purchase_log = new
- var/uplink_owner = null//text-only
+ var/list/purchase_log
+ var/datum/mind/owner = null
var/used_TC = 0
/obj/item/device/uplink/nano_host()
return loc
-/obj/item/device/uplink/New()
+/obj/item/device/uplink/New(var/location, var/datum/mind/owner)
..()
welcome = ticker.mode.uplink_welcome
uses = ticker.mode.uplink_uses
- ItemsCategory = ticker.mode.uplink_items
-
+ src.owner = owner
+ purchase_log = list()
world_uplinks += src
/obj/item/device/uplink/Destroy()
world_uplinks -= src
..()
-/obj/item/device/uplink/proc/generate_items()
- var/datum/nano_item_lists/IL = generate_item_lists()
- nanoui_items = IL.items_nano
- ItemsReference = IL.items_reference
-
-// BS12 no longer use this menu but there are forks that do, hency why we keep it
-/obj/item/device/uplink/proc/generate_menu()
- var/dat = "[src.welcome]
"
- dat += "Tele-Crystals left: [src.uses]
"
- dat += "
"
- dat += "Request item:
"
- dat += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
-
- var/category_items = 1
- for(var/category in ItemsCategory)
- if(category_items < 1)
- dat += "We apologize, as you could not afford anything from this category.
"
- dat += "
"
- dat += "[category]
"
- category_items = 0
-
- for(var/datum/uplink_item/I in ItemsCategory[category])
- if(I.cost > uses)
- continue
- dat += "[I.name] ([I.cost])
"
- category_items++
-
- dat += "Random Item (??)
"
- dat += "
"
- return dat
-
-/*
- Built the item lists for use with NanoUI
-*/
-/obj/item/device/uplink/proc/generate_item_lists()
- var/list/nano = new
- var/list/reference = new
-
- for(var/category in ItemsCategory)
- nano[++nano.len] = list("Category" = category, "items" = list())
- for(var/datum/uplink_item/I in ItemsCategory[category])
- nano[nano.len]["items"] += list(list("Name" = I.name, "Description" = I.description(),"Cost" = I.cost, "obj_path" = I.reference))
- reference[I.reference] = I
-
- var/datum/nano_item_lists/result = new
- result.items_nano = nano
- result.items_reference = reference
- return result
-
-//If 'random' was selected
-/obj/item/device/uplink/proc/chooseRandomItem()
- if(uses <= 0)
- return
-
- var/list/random_items = new
- for(var/IR in ItemsReference)
- var/datum/uplink_item/UI = ItemsReference[IR]
- if(UI.cost <= uses)
- random_items += UI
- return pick(random_items)
-
-/obj/item/device/uplink/Topic(href, href_list)
- if(..())
- return 1
-
- if(href_list["buy_item"] == "random")
- var/datum/uplink_item/UI = chooseRandomItem()
- href_list["buy_item"] = UI.reference
- return buy(UI, "RN")
- else
- var/datum/uplink_item/UI = ItemsReference[href_list["buy_item"]]
- return buy(UI, UI ? UI.reference : "")
- return 0
-
-/obj/item/device/uplink/proc/buy(var/datum/uplink_item/UI, var/reference)
- if(UI && UI.cost <= uses)
- uses -= UI.cost
- used_TC += UI.cost
- feedback_add_details("traitor_uplink_items_bought", reference)
-
- var/list/L = UI.generate_item(get_turf(usr))
- if(ishuman(usr))
- var/mob/living/carbon/human/A = usr
- for(var/obj/I in L)
- A.put_in_any_hand_if_possible(I)
-
- purchase_log[UI] = purchase_log[UI] + 1
-
- return 1
- return 0
-
// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
/* How to create an uplink in 3 easy steps!
@@ -175,6 +44,11 @@ datum/nano_item_lists
name = "hidden uplink"
desc = "There is something wrong if you're examining this."
var/active = 0
+ var/nanoui_menu = 0 // The current menu we are in
+ var/datum/uplink_category/category = 0 // The current category we are in
+ var/exploit_id // Id of the current exploit record we are viewing
+ var/list/nanoui_data // Data for NanoUI use
+
// The hidden uplink MUST be inside an obj/item's contents.
/obj/item/device/uplink/hidden/New()
@@ -182,6 +56,8 @@ datum/nano_item_lists
if(!istype(src.loc, /obj/item))
qdel(src)
..()
+ nanoui_data = list()
+ update_nano_data()
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
/obj/item/device/uplink/hidden/proc/toggle()
@@ -212,20 +88,13 @@ datum/nano_item_lists
data["welcome"] = welcome
data["crystals"] = uses
data["menu"] = nanoui_menu
- if(!nanoui_items)
- generate_items()
- data["nano_items"] = nanoui_items
data += nanoui_data
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
- if (!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ if (!ui) // No auto-refresh
ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600, state = inventory_state)
- // when the ui is first opened this is the data it will use
ui.set_initial_data(data)
- // open the new ui window
ui.open()
@@ -235,43 +104,54 @@ datum/nano_item_lists
// The purchasing code.
/obj/item/device/uplink/hidden/Topic(href, href_list)
- if (usr.stat || usr.restrained())
+ if(..())
return 1
- if (!( istype(usr, /mob/living/carbon/human)))
- return 1
var/mob/user = usr
- var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
- if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
- usr.set_machine(src)
- if(..(href, href_list))
- return 1
- else if(href_list["lock"])
- toggle()
- ui.close()
- return 1
- if(href_list["return"])
- nanoui_menu = round(nanoui_menu/10)
- update_nano_data()
- if(href_list["menu"])
- nanoui_menu = text2num(href_list["menu"])
- update_nano_data(href_list["id"])
+ if(href_list["buy_item"])
+ var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items)
+ UI.buy(src, usr)
+ else if(href_list["lock"])
+ toggle()
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
+ ui.close()
+ else if(href_list["return"])
+ nanoui_menu = round(nanoui_menu/10)
+ else if(href_list["menu"])
+ nanoui_menu = text2num(href_list["menu"])
+ if(href_list["id"])
+ exploit_id = href_list["id"]
+ if(href_list["category"])
+ category = locate(href_list["category"]) in uplink.categories
- interact(usr)
+ update_nano_data()
return 1
-/obj/item/device/uplink/hidden/proc/update_nano_data(var/id)
- if(nanoui_menu == 1)
+/obj/item/device/uplink/hidden/proc/update_nano_data()
+ if(nanoui_menu == 0)
+ var/categories[0]
+ for(var/datum/uplink_category/category in uplink.categories)
+ if(category.can_view(src))
+ categories[++categories.len] = list("name" = category.name, "ref" = "\ref[category]")
+ nanoui_data["categories"] = categories
+ else if(nanoui_menu == 1)
+ var/items[0]
+ for(var/datum/uplink_item/item in category.items)
+ if(item.can_view(src))
+ var/cost = item.cost()
+ if(!cost) cost = "???"
+ items[++items.len] = list("name" = item.name, "description" = replacetext(item.description(), "\n", "
"), "can_buy" = item.can_buy(src), "cost" = cost, "ref" = "\ref[item]")
+ nanoui_data["items"] = items
+ else if(nanoui_menu == 2)
var/permanentData[0]
for(var/datum/data/record/L in sortRecord(data_core.locked))
permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"])
nanoui_data["exploit_records"] = permanentData
-
- if(nanoui_menu == 11)
+ else if(nanoui_menu == 21)
nanoui_data["exploit_exists"] = 0
for(var/datum/data/record/L in data_core.locked)
- if(L.fields["id"] == id)
+ if(L.fields["id"] == exploit_id)
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
diff --git a/code/game/objects/items/devices/uplink_categories.dm b/code/game/objects/items/devices/uplink_categories.dm
new file mode 100644
index 00000000000..f90c4797bc5
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_categories.dm
@@ -0,0 +1,40 @@
+/datum/uplink_category
+ var/name = ""
+ var/list/datum/uplink_item/items
+
+/datum/uplink_category/New()
+ ..()
+ items = list()
+
+/datum/uplink_category/proc/can_view(obj/item/device/uplink/U)
+ for(var/datum/uplink_item/item in items)
+ if(item.can_view(U))
+ return 1
+ return 0
+
+/datum/uplink_category/ammunition
+ name = "Ammunition"
+
+/datum/uplink_category/visible_weapons
+ name = "Highly Visible and Dangerous Weapons"
+
+/datum/uplink_category/stealthy_weapons
+ name = "Stealthy and Inconspicuous Weapons"
+
+/datum/uplink_category/stealth_items
+ name = "Stealth and Camouflage Items"
+
+/datum/uplink_category/tools
+ name = "Devices and Tools"
+
+/datum/uplink_category/implants
+ name = "Implants"
+
+/datum/uplink_category/medical
+ name = "Medical"
+
+/datum/uplink_category/hardsuit_modules
+ name = "Hardsuit Modules"
+
+/datum/uplink_category/badassery
+ name = "Badassery"
diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm
new file mode 100644
index 00000000000..e6edc632a21
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_items.dm
@@ -0,0 +1,504 @@
+var/datum/uplink/uplink = new()
+
+/datum/uplink
+ var/list/items_assoc
+ var/list/datum/uplink_item/items
+ var/list/datum/uplink_category/categories
+
+/datum/uplink/New()
+ items_assoc = list()
+ items = init_subtypes(/datum/uplink_item)
+ categories = init_subtypes(/datum/uplink_category)
+
+ for(var/datum/uplink_item/item in items)
+ if(!item.name)
+ items -= item
+ continue
+
+ items_assoc[item.type] = item
+
+ for(var/datum/uplink_category/category in categories)
+ if(item.category == category.type)
+ category.items += item
+
+ for(var/datum/uplink_category/category in categories)
+ category.items = dd_sortedObjectList(category.items)
+
+/datum/uplink_item
+ var/name
+ var/desc
+ var/item_cost = 0
+ var/datum/uplink_category/category // Item category
+ var/list/datum/antagonist/antag_roles // Antag roles this item is displayed to. If empty, display to all.
+
+/datum/uplink_item/item
+ var/path = null
+
+/datum/uplink_item/New()
+ ..()
+ antag_roles = list()
+
+/datum/uplink_item/proc/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/cost = max(0, cost(U.uses))
+ var/obj/item/I = get_goods(get_turf(user))
+ if(istype(I) && ishuman(user))
+ var/mob/living/carbon/human/A = user
+ A.put_in_any_hand_if_possible(I)
+ U.uses -= cost
+ U.used_TC += cost
+ purchase_log(U)
+
+ return cost
+
+/datum/uplink_item/proc/get_goods(var/loc)
+ return 0
+
+/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
+ if(cost(U.uses) > U.uses)
+ return 0
+
+ return can_view(U)
+
+/datum/uplink_item/proc/can_view(obj/item/device/uplink/U)
+ // Making the assumption that if no uplink was supplied, then we don't care about antag roles
+ if(!U || !antag_roles.len)
+ return 1
+
+ // With no owner, there's no need to check antag status.
+ if(!U.owner)
+ return 0
+
+ for(var/antag_role in antag_roles)
+ var/datum/antagonist/antag = all_antag_types[antag_role]
+ if(antag.is_antagonist(U.owner))
+ return 1
+ return 0
+
+/datum/uplink_item/proc/cost()
+ return item_cost
+
+/datum/uplink_item/proc/description()
+ return desc
+
+/datum/uplink_item/proc/log_icon()
+ return
+
+/datum/uplink_item/proc/purchase_log(obj/item/device/uplink/U)
+ feedback_add_details("traitor_uplink_items_bought", "[src]")
+ U.purchase_log[src] = U.purchase_log[src] + 1
+
+datum/uplink_item/dd_SortValue()
+ return cost(INFINITY)
+
+/********************************
+* *
+* Physical Uplink Entires *
+* *
+********************************/
+/datum/uplink_item/item/get_goods(var/loc)
+ var/obj/item/I = new path(loc)
+ return I
+
+/datum/uplink_item/item/description()
+ if(!desc)
+ // Fallback description
+ var/obj/temp = src.path
+ desc = initial(temp.desc)
+ return ..()
+
+/datum/uplink_item/item/log_icon()
+ var/obj/I = path
+ return "\icon[I]"
+
+/*************
+* Ammunition *
+*************/
+/datum/uplink_item/item/ammo
+ item_cost = 2
+ category = /datum/uplink_category/ammunition
+
+/datum/uplink_item/item/ammo/a357
+ name = ".357"
+ path = /obj/item/ammo_magazine/a357
+
+/datum/uplink_item/item/ammo/mc9mm
+ name = ".9mm"
+ path = /obj/item/ammo_magazine/mc9mm
+
+/datum/uplink_item/item/ammo/darts
+ name = "Darts"
+ path = /obj/item/ammo_magazine/chemdart
+
+/datum/uplink_item/item/ammo/sniperammo
+ name = "14.5mm"
+ path = /obj/item/weapon/storage/box/sniperammo
+
+/***************************************
+* Highly Visible and Dangerous Weapons *
+***************************************/
+/datum/uplink_item/item/visible_weapons
+ category = /datum/uplink_category/visible_weapons
+
+/datum/uplink_item/item/visible_weapons/emp
+ name = "5xEMP Grenades"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/emps
+
+/datum/uplink_item/item/visible_weapons/energy_sword
+ name = "Energy Sword"
+ item_cost = 4
+ path = /obj/item/weapon/melee/energy/sword
+
+/datum/uplink_item/item/visible_weapons/dartgun
+ name = "Dart Gun"
+ item_cost = 5
+ path = /obj/item/weapon/gun/projectile/dartgun
+
+/datum/uplink_item/item/visible_weapons/crossbow
+ name = "Energy Crossbow"
+ item_cost = 5
+ path = /obj/item/weapon/gun/energy/crossbow
+
+/datum/uplink_item/item/visible_weapons/g9mm
+ name = "Silenced 9mm"
+ item_cost = 5
+ path = /obj/item/weapon/storage/box/syndie_kit/g9mm
+
+/datum/uplink_item/item/visible_weapons/riggedlaser
+ name = "Exosuit Rigged Laser"
+ item_cost = 6
+ path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser
+
+/datum/uplink_item/item/visible_weapons/revolver
+ name = "Revolver"
+ item_cost = 6
+ path = /obj/item/weapon/gun/projectile/revolver
+
+/datum/uplink_item/item/visible_weapons/heavysniper
+ name = "Anti-materiel Rifle"
+ path = /obj/item/weapon/gun/projectile/heavysniper
+
+/datum/uplink_item/item/visible_weapons/heavysniper/cost()
+ return (ticker && ticker.mode && ticker.mode.uplink_uses) ? ticker.mode.uplink_uses : INFINITY
+
+/*************************************
+* Stealthy and Inconspicuous Weapons *
+*************************************/
+/datum/uplink_item/item/stealthy_weapons
+ category = /datum/uplink_category/stealthy_weapons
+
+/datum/uplink_item/item/stealthy_weapons/soap
+ name = "Subversive Soap"
+ item_cost = 1
+ path = /obj/item/weapon/soap/syndie
+
+/datum/uplink_item/item/stealthy_weapons/concealed_cane
+ name = "Concealed Cane Sword"
+ item_cost = 1
+ path = /obj/item/weapon/cane/concealed
+
+/datum/uplink_item/item/stealthy_weapons/detomatix
+ name = "Detomatix PDA Cartridge"
+ item_cost = 3
+ path = /obj/item/weapon/cartridge/syndicate
+
+/datum/uplink_item/item/stealthy_weapons/parapen
+ name = "Paralysis Pen"
+ item_cost = 3
+ path = /obj/item/weapon/pen/reagent/paralysis
+
+/datum/uplink_item/item/stealthy_weapons/cigarette_kit
+ name = "Cigarette Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/cigarette
+
+/datum/uplink_item/item/stealthy_weapons/random_toxin
+ name = "Random Toxin - Beaker"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/toxin
+
+/*******************************
+* Stealth and Camouflage Items *
+*******************************/
+/datum/uplink_item/item/stealth_items
+ category = /datum/uplink_category/stealth_items
+
+/datum/uplink_item/item/stealth_items/id
+ name = "Agent ID card"
+ item_cost = 2
+ path = /obj/item/weapon/card/id/syndicate
+
+/datum/uplink_item/item/stealth_items/syndigaloshes
+ name = "No-Slip Shoes"
+ item_cost = 2
+ path = /obj/item/clothing/shoes/syndigaloshes
+
+/datum/uplink_item/item/stealth_items/spy
+ name = "Bug Kit"
+ item_cost = 2
+ path = /obj/item/weapon/storage/box/syndie_kit/spy
+
+/datum/uplink_item/item/stealth_items/chameleon_kit
+ name = "Chameleon Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/chameleon
+
+/datum/uplink_item/item/stealth_items/chameleon_projector
+ name = "Chameleon-Projector"
+ item_cost = 4
+ path = /obj/item/device/chameleon
+
+/datum/uplink_item/item/stealth_items/chameleon_projector
+ name = "Chameleon-Projector"
+ item_cost = 4
+ path = /obj/item/device/chameleon
+
+/datum/uplink_item/item/stealth_items/voice
+ name = "Voice Changer"
+ item_cost = 4
+ path = /obj/item/clothing/mask/gas/voice
+
+/datum/uplink_item/item/stealth_items/camera_floppy
+ name = "Camera Network Access - Floppy"
+ item_cost = 6
+ path = /obj/item/weapon/disk/file/cameras/syndicate
+
+/********************
+* Devices and Tools *
+********************/
+/datum/uplink_item/item/tools
+ category = /datum/uplink_category/tools
+
+/datum/uplink_item/item/tools/toolbox
+ name = "Fully Loaded Toolbox"
+ item_cost = 1
+ path = /obj/item/weapon/storage/toolbox/syndicate
+
+/datum/uplink_item/item/tools/plastique
+ name = "C-4 (Destroys walls)"
+ item_cost = 2
+ path = /obj/item/weapon/plastique
+
+/datum/uplink_item/item/tools/encryptionkey_radio
+ name = "Encrypted Radio Channel Key"
+ item_cost = 2
+ path = /obj/item/device/encryptionkey/syndicate
+
+/datum/uplink_item/item/tools/encryptionkey_binary
+ name = "Binary Translator Key"
+ item_cost = 3
+ path = /obj/item/device/encryptionkey/binary
+
+/datum/uplink_item/item/tools/emag
+ name = "Cryptographic Sequencer"
+ item_cost = 3
+ path = /obj/item/weapon/card/emag
+
+/datum/uplink_item/item/tools/clerical
+ name = "Morphic Clerical Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/clerical
+
+/datum/uplink_item/item/tools/space_suit
+ name = "Space Suit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/space
+
+/datum/uplink_item/item/tools/thermal
+ name = "Thermal Imaging Glasses"
+ item_cost = 3
+ path = /obj/item/clothing/glasses/thermal/syndi
+
+/datum/uplink_item/item/tools/heavy_vest
+ name = "Heavy Armor Vest"
+ item_cost = 4
+ path = /obj/item/clothing/suit/storage/vest/heavy/merc
+
+/datum/uplink_item/item/tools/powersink
+ name = "Powersink (DANGER!)"
+ item_cost = 5
+ path = /obj/item/device/powersink
+
+/datum/uplink_item/item/tools/ai_module
+ name = "Hacked AI Upload Module"
+ item_cost = 7
+ path = /obj/item/weapon/aiModule/syndicate
+
+/datum/uplink_item/item/tools/singularity_beacon
+ name = "Singularity Beacon (DANGER!)"
+ item_cost = 7
+ path = /obj/item/device/radio/beacon/syndicate
+
+/datum/uplink_item/item/tools/teleporter
+ name = "Teleporter Circuit Board"
+ item_cost = 20
+ path = /obj/item/weapon/circuitboard/teleporter
+
+/datum/uplink_item/item/tools/teleporter/New()
+ ..()
+ antag_roles = list(MODE_MERCENARY)
+
+/***********
+* Implants *
+***********/
+/datum/uplink_item/item/implants
+ category = /datum/uplink_category/implants
+
+/datum/uplink_item/item/implants/imp_freedom
+ name = "Freedom Implant"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_freedom
+
+/datum/uplink_item/item/implants/imp_compress
+ name = "Compressed Matter Implant"
+ item_cost = 4
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_compress
+
+/datum/uplink_item/item/implants/imp_explosive
+ name = "Explosive Implant (DANGER!)"
+ item_cost = 6
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_explosive
+
+/datum/uplink_item/item/implants/imp_uplink
+ name = "Uplink Implant (Contains 5 Telecrystals)"
+ item_cost = 10
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_uplink
+
+/**********
+* Medical *
+**********/
+/datum/uplink_item/item/medical
+ category = /datum/uplink_category/medical
+
+/datum/uplink_item/item/medical/sinpockets
+ name = "Box of Sin-Pockets"
+ item_cost = 1
+ path = /obj/item/weapon/storage/box/sinpockets
+
+/datum/uplink_item/item/medical/surgery
+ name = "Surgery kit"
+ item_cost = 6
+ path = /obj/item/weapon/storage/firstaid/surgery
+
+/datum/uplink_item/item/medical/combat
+ name = "Combat medical kit"
+ item_cost = 6
+ path = /obj/item/weapon/storage/firstaid/combat
+
+/*******************
+* Hardsuit Modules *
+*******************/
+/datum/uplink_item/item/hardsuit_modules
+ category = /datum/uplink_category/hardsuit_modules
+
+/datum/uplink_item/item/hardsuit_modules/thermal
+ name = "Thermal Scanner"
+ item_cost = 2
+ path = /obj/item/rig_module/vision/thermal
+
+/datum/uplink_item/item/hardsuit_modules/energy_net
+ name = "Net Projector"
+ item_cost = 3
+ path = /obj/item/rig_module/fabricator/energy_net
+
+/datum/uplink_item/item/ewar_voice
+ name = "Electrowarfare Suite and Voice Synthesiser"
+ item_cost = 4
+ path = /obj/item/weapon/storage/box/syndie_kit/ewar_voice
+
+/datum/uplink_item/item/hardsuit_modules/maneuvering_jets
+ name = "Maneuvering Jets"
+ item_cost = 4
+ path = /obj/item/rig_module/maneuvering_jets
+
+/datum/uplink_item/item/hardsuit_modules/egun
+ name = "Mounted Energy Gun"
+ item_cost = 6
+ path = /obj/item/rig_module/mounted/egun
+
+/datum/uplink_item/item/hardsuit_modules/power_sink
+ name = "Power Sink"
+ item_cost = 6
+ path = /obj/item/rig_module/power_sink
+
+/datum/uplink_item/item/hardsuit_modules/laser_canon
+ name = "Mounted Laser Cannon"
+ item_cost = 8
+ path = /obj/item/rig_module/mounted
+
+/************
+* Badassery *
+************/
+/datum/uplink_item/item/badassery
+ category = /datum/uplink_category/badassery
+
+/datum/uplink_item/item/badassery/balloon
+ name = "For showing that You Are The BOSS (Useless Balloon)"
+ path = /obj/item/toy/syndicateballoon
+
+/datum/uplink_item/item/badassery/balloon/NT
+ name = "For showing that you love NT SOO much (Useless Balloon)"
+ path = /obj/item/toy/nanotrasenballoon
+
+/datum/uplink_item/item/badassery/balloon/cost()
+ return (ticker && ticker.mode && ticker.mode.uplink_uses) ? ticker.mode.uplink_uses : 10
+
+/**************
+* Random Item *
+**************/
+/datum/uplink_item/item/badassery/random
+ name = "Random Item"
+ desc = "Buys you one random item."
+
+/datum/uplink_item/item/badassery/random/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/datum/uplink_item/item = default_uplink_selection.get_random_item(U)
+ item.buy(U, user)
+ return 1
+
+/datum/uplink_item/item/badassery/random/can_buy(obj/item/device/uplink/U)
+ return default_uplink_selection.get_random_item(U) != null
+
+/****************
+* Surplus Crate *
+****************/
+/datum/uplink_item/item/badassery/surplus
+ name = "Surplus Crate"
+ item_cost = 40
+ var/item_worth = 60
+ var/icon
+
+/datum/uplink_item/item/badassery/surplus/New()
+ ..()
+ antag_roles = list(MODE_MERCENARY)
+ desc = "A crate containing [item_worth] telecrystal\s worth of surplus leftovers."
+
+/datum/uplink_item/item/badassery/surplus/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/obj/structure/largecrate/C = new(get_turf(user))
+ var/list/bought_items = list()
+ var/remaining_TC = item_worth
+ U.uses += (item_worth - item_cost)
+ U.used_TC -= (item_worth - item_cost)
+
+ while(remaining_TC)
+ var/datum/uplink_item/I = default_uplink_selection.get_random_item(telecrystals = remaining_TC, bought_items = bought_items)
+ if(!I)
+ break
+ bought_items += I
+ remaining_TC -= I.cost()
+
+ purchase_log(U)
+ for(var/datum/uplink_item/item in bought_items)
+ item.purchase_log(U)
+ item.get_goods(C)
+
+ U.uses -= item_worth
+ U.used_TC += item_worth
+
+ return 1
+
+/datum/uplink_item/item/badassery/surplus/log_icon()
+ if(!icon)
+ var/obj/structure/largecrate/C = /obj/structure/largecrate
+ icon = image(initial(C.icon), initial(C.icon_state))
+
+ return "\icon[icon]"
diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm
new file mode 100644
index 00000000000..18d9d7841de
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_random_lists.dm
@@ -0,0 +1,103 @@
+var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_random_selection/default()
+
+/datum/uplink_random_item
+ var/uplink_item // The uplink item
+ var/keep_probability // The probability we'll decide to keep this item if selected
+ var/reselect_probability // Probability that we'll decide to keep this item if previously selected.
+ // Is done together with the keep_probability check. Being selected more than once does not affect this probability.
+
+/datum/uplink_random_item/New(var/uplink_item, var/keep_probability = 100, var/reselect_propbability = 33)
+ ..()
+ src.uplink_item = uplink_item
+ src.keep_probability = keep_probability
+ src.reselect_probability = reselect_probability
+
+/datum/uplink_random_selection
+ var/list/datum/uplink_random_item/items
+
+/datum/uplink_random_selection/New()
+ ..()
+ items = list()
+
+/datum/uplink_random_selection/proc/get_random_item(obj/item/device/uplink/U, var/telecrystals, var/list/bought_items)
+ var/const/attempts = 50
+ var/remainingTC = telecrystals ? telecrystals : U.uses
+
+ for(var/i = 0; i < attempts; i++)
+ var/datum/uplink_random_item/RI = pick(items)
+ if(!prob(RI.keep_probability))
+ continue
+ var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
+ if(I.cost() > remainingTC)
+ continue
+ if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
+ continue
+ if(U && !I.can_buy(U))
+ continue
+ return I
+
+/datum/uplink_random_selection/default/New()
+ ..()
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/g9mm)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/mc9mm)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/revolver)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysniper, 15, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/emp, 50)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/soap, 5, 100)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/concealed_cane, 50, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/detomatix, 20, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/parapen)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/cigarette_kit)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/id)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/spy)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/camera_floppy, 10, 0)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_binary)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/emag, 100, 50)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/heavy_vest)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/surgery, reselect_propbability = 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/combat, reselect_propbability = 10)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/thermal, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/energy_net, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ewar_voice, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/maneuvering_jets, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/egun, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/power_sink, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/laser_canon, reselect_propbability = 5)
+
+#ifdef DEBUG
+/proc/debug_uplink_purchage_log()
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/A = all_antag_types[antag_type]
+ A.print_player_summary()
+
+/proc/debug_uplink_item_assoc_list()
+ for(var/key in uplink.items_assoc)
+ world << "[key] - [uplink.items_assoc[key]]"
+#endif
diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl
index e981155622d..a92fe95c6ee 100644
--- a/nano/templates/uplink.tmpl
+++ b/nano/templates/uplink.tmpl
@@ -12,48 +12,45 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}}
- {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}}
+ {{:helper.link('Exploitable Information', 'gear', {'menu' : 2}, null, 'fixedLeftWider')}}
{{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}}
{{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
-
+
+
+
+ Tele-Crystals:
+
+
+ {{:data.crystals}}
+
+
+
{{if data.menu == 0}}
+ Categories:
+ {{for data.categories}}
+
+ {{:helper.link(value.name, 'gear', {'menu' : 1, 'category' : value.ref})}}
+
+ {{/for}}
+{{else data.menu == 1}}
Request items:
Each item costs a number of tele-crystals as indicated by the number following their name.
-
-
- Tele-Crystals:
-
-
- {{:data.crystals}}
-
-
-
- {{for data.nano_items}}
-
-
{{:value.Category}}
-
- {{for value.items :itemValue:itemIndex}}
-
- {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}}
-
-
- {{if itemValue.Cost <= data.crystals}}
-
- {{:itemValue.Description}}
-
- {{/if}}
- {{/for}}
-
- {{/for}}
-
-
- {{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}}
-
-{{else data.menu == 1}}
+ {{for data.items}}
+
+ {{:helper.link(value.name, 'gear', {'buy_item' : value.ref}, value.can_buy ? null : 'disabled')}} - {{:value.cost}}
+
+
+ {{if value.can_buy}}
+
+ {{:value.description}}
+
+ {{/if}}
+ {{/for}}
+{{else data.menu == 2}}
Information Record List:
@@ -62,11 +59,10 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{for data.exploit_records}}
- {{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}}
+ {{:helper.link(value.Name, 'gear', {'menu' : 21, 'id' : value.id}, null, null)}}
{{/for}}
-
-{{else data.menu == 11}}
+{{else data.menu == 21}}
Information Record: