//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak /* A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message. */ /obj/item/uplink /// Welcoming menu message. var/welcome = "Welcome, Operative" /// Number of telecrystals. var/telecrystals /// Number of bluecrystals. var/bluecrystals /// Counter of used telecrystals. var/used_telecrystals = 0 /// Counter of used bluecrystals. var/used_bluecrystals = 0 /// List of categories with lists of items. var/list/ItemsCategory /// List of references with an associated item. var/list/ItemsReference /// List of items for TGUI use. var/list/tgui_items /// The current menu we are in. var/tgui_menu = 0 // Assoc list of item to times bought; shared/referenced by child uplinks var/list/purchase_log = list() /// Mind of the uplink's owner. var/datum/mind/uplink_owner = null /obj/item/uplink/ui_host() return loc /obj/item/uplink/Initialize(var/mapload, var/datum/mind/owner, var/new_telecrystals = DEFAULT_TELECRYSTAL_AMOUNT, var/new_bluecrystals = DEFAULT_BLUECRYSTAL_AMOUNT) . = ..() src.uplink_owner = owner purchase_log = list() GLOB.world_uplinks += src telecrystals = new_telecrystals bluecrystals = new_bluecrystals /obj/item/uplink/Destroy() GLOB.world_uplinks -= src src.uplink_owner = null return ..() // 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! 1. All obj/item 's have a hidden_uplink var. By default it's null. Give the item one with "new(src)", it must be in it's contents. Feel free to add "uses". 2. Code in the triggers. Use check_trigger for this, I recommend closing the item's menu with "user << browse(null, "window=windowname") if it returns true.) The var/value is the value that will be compared with the var/target. If they are equal it will activate the menu. 3. If you want the menu to stay until the users locks his uplink, add an active_uplink_check(mob/user as mob) in your interact/attack_hand proc. Then check if it's true, if true return. This will stop the normal menu appearing and will instead show the uplink menu. */ /obj/item/uplink/hidden name = "hidden uplink" desc = "There is something wrong if you're examining this." var/active = 0 /// The current category we are in, the open category var/datum/uplink_category/category /// ID of the current exploit record we are viewing var/exploit_id var/pda_code = "" /obj/item/uplink/hidden/Initialize(mapload, datum/mind/owner, new_telecrystals, new_bluecrystals) . = ..() return INITIALIZE_HINT_LATELOAD /obj/item/uplink/hidden/LateInitialize() // The hidden uplink MUST be inside an obj/item's contents. if(!istype(loc, /obj/item)) qdel(src) // 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/uplink/hidden/proc/toggle() active = !active // Directly trigger the uplink. Turn on if it isn't already. /obj/item/uplink/hidden/proc/trigger(mob/user as mob) if(!active) toggle() interact(user) // Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset. // If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the // current item's menu. /obj/item/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target) if(value == target) trigger(user) return 1 return 0 /* TGUI FOR UPLINK WOOP WOOP */ /obj/item/uplink/hidden/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "Uplink", capitalize_first_letters(name)) ui.open() /obj/item/uplink/hidden/ui_data(mob/user) var/list/data = list() data["welcome"] = welcome data["menu"] = tgui_menu data["telecrystals"] = telecrystals data["bluecrystals"] = bluecrystals return data /obj/item/uplink/hidden/ui_static_data(mob/user) . = ..() . += update_tgui_data() // Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button. /obj/item/uplink/hidden/interact(mob/user) ui_interact(user, null) /obj/item/uplink/hidden/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) if(..()) return 1 if(action == "buy_item") var/datum/uplink_item/UI = (locate(params["buy_item"]) in GLOB.uplink.items) UI.buy(src, usr) update_static_data(usr, ui) else if(action == "lock") toggle() SStgui.close_uis(src) else if(action == "return") tgui_menu = round(tgui_menu/10) update_static_data(usr, ui) else if(action == "menu") tgui_menu = text2num(params["menu"]) if(params["id"]) exploit_id = params["id"] if(params["category"]) category = locate(params["category"]) in GLOB.uplink.categories update_static_data(usr, ui) if(action == "contract_interact") var/list/params_webint = list("location" = "contract_details", "contract" = params["contract_interact"]) usr.client.process_webint_link("interface/login/sso_server", list2params(params_webint)) update_static_data(usr, ui) if(action == "contract_page") .["contracts_current_page"] = text2num(params["contract_page"]) update_static_data(usr, ui) if(action == "contract_view") .["contracts_view"] = text2num(params["contract_view"]) .["contracts_current_page"] = 1 update_static_data(usr, ui) return 1 /obj/item/uplink/hidden/proc/new_tgui_item_data(var/datum/uplink_item/item) var/tc_cost = item.telecrystal_cost(telecrystals) var/bc_cost = item.bluecrystal_cost(bluecrystals) var/can_buy = item.can_buy_telecrystals(src) || item.can_buy_bluecrystals(src) var/newItem = list( "name" = item.name, "description" = replacetext(item.description(), "\n", "
"), "can_buy" = can_buy, "tc_cost" = tc_cost, "bc_cost" = bc_cost, "left" = item.items_left(src), "ref" = "[REF(item)]" ) return newItem /obj/item/uplink/hidden/proc/update_tgui_data() . = list() if(tgui_menu == 0) var/list/categories = list() var/list/items = list() for(var/datum/uplink_category/category in GLOB.uplink.categories) if(category.can_view(src)) categories[++categories.len] = list("name" = category.name, "ref" = "[REF(category)]") for(var/datum/uplink_item/item in category.items) if(item.can_view(src)) items[++items.len] = new_tgui_item_data(item) .["categories"] = categories .["items"] = items else if(tgui_menu == 1) var/items[0] for(var/datum/uplink_item/item in category?.items) if(item.can_view(src)) items[++items.len] = new_tgui_item_data(item) .["items"] = items else if(tgui_menu == 2) var/permanentData[0] for(var/datum/record/general/locked/record in SSrecords.records_locked) permanentData[++permanentData.len] = list("name" = record.name,"id" = record.id, "has_exploitables" = !!record.exploit_record) .["exploit_records"] = permanentData else if(tgui_menu == 21) .["exploit_exists"] = 0 for(var/datum/record/general/locked/L in SSrecords.records_locked) if(L.id == exploit_id) .["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. .["exploit"]["tgui_exploit_record"] = html_decode(L.exploit_record) // this user input is already sanitized and encoded when saved to the DB, we can just decode it and slap it into a span .["exploit"]["name"] = html_encode(L.name) .["exploit"]["sex"] = html_encode(L.sex) .["exploit"]["age"] = html_encode(L.age) .["exploit"]["species"] = html_encode(L.species) .["exploit"]["rank"] = html_encode(L.rank) .["exploit"]["citizenship"] = html_encode(L.citizenship) .["exploit"]["employer"] = html_encode(L.employer) .["exploit"]["religion"] = html_encode(L.religion) .["exploit"]["fingerprint"] = html_encode(L.fingerprint) .["exploit_exists"] = 1 break else if(tgui_menu == 3) .["contracts_found"] = 0 if(establish_db_connection(GLOB.dbcon)) .["contracts"] = list() if (!.["contracts_current_page"]) .["contracts_current_page"] = 1 if (!.["contracts_view"]) .["contracts_view"] = 1 var/query_details[0] switch (.["contracts_view"]) if (1) query_details["status"] = "open" if (2) query_details["status"] = "closed" else .["contracts_view"] = 1 query_details["status"] = "open" var/DBQuery/index_query = GLOB.dbcon.NewQuery("SELECT count(*) as Total_Contracts FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status:") index_query.Execute(query_details) var/pages = 0 if (index_query.NextRow()) var/total_contracts = text2num(index_query.item[1]) pages = total_contracts / 10 if (total_contracts % 10) pages++ pages = round(pages) var/list/contracts_pages = list() for (var/i = 1, i <= pages, i++) contracts_pages.Add(i) .["contracts_pages"] = contracts_pages if (.["contracts_current_page"] > pages) return query_details["offset"] = (.["contracts_current_page"] - 1) * 10 var/DBQuery/list_query = GLOB.dbcon.NewQuery("SELECT contract_id, contractee_name, title FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status: LIMIT 10 OFFSET :offset:") list_query.Execute(query_details) var/list/contracts = list() while (list_query.NextRow()) contracts.Add(list(list("id" = list_query.item[1], "contractee" = list_query.item[2], "title" = list_query.item[3]))) .["contracts"] = contracts .["contracts_found"] = 1 if(tgui_menu == 31) .["contracts_found"] = 0 if (GLOB.config.sql_enabled && establish_db_connection(GLOB.dbcon)) .["contracts"] = list() if (!.["contracts_current_page"]) .["contracts_current_page"] = 1 if (!.["contracts_view"]) .["contracts_view"] = 1 var/query_details[0] query_details["contract_id"] = exploit_id var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT contract_id, contractee_name, status, title, description, reward_other FROM ss13_syndie_contracts WHERE contract_id = :contract_id:") select_query.Execute(query_details) if (select_query.NextRow()) .["contracts_found"] = 1 var/contract[0] contract["id"] = select_query.item[1] contract["contractee"] = select_query.item[2] switch (select_query.item[3]) if ("open") contract["status"] = "1" else contract["status"] = "0" contract["title"] = html_encode(select_query.item[4]) contract["description"] = select_query.item[5] contract["description"] = html_encode(contract["description"]) contract["description"] = replacetext(contract["description"], "\n", "
") contract["description"] = replacetext(contract["description"], ascii2text(13), "") contract["reward_other"] = select_query.item[6] .["contract"] = contract // I placed this here because of how relevant it is. // You place this in your uplinkable item to check if an uplink is active or not. // If it is, it will display the uplink menu and return 1, else it'll return false. // If it returns true, I recommend closing the item's normal menu with "user << browse(null, "window=name")") /obj/item/proc/active_uplink_check(mob/user as mob) // Activates the uplink if it's active if(src.hidden_uplink) if(src.hidden_uplink.active) src.hidden_uplink.trigger(user) return 1 return 0 // PRESET UPLINKS // A collection of preset uplinks. // // Includes normal radio uplink, multitool uplink, // implant uplink (not the implant tool) and a preset headset uplink. /obj/item/radio/uplink/New(var/loc, var/mind) hidden_uplink = new(src, mind) icon_state = "radio" /obj/item/radio/uplink/attack_self(mob/user as mob) if(hidden_uplink) hidden_uplink.trigger(user) /obj/item/multitool/uplink/New(var/loc, var/mind) hidden_uplink = new(src, mind) /obj/item/multitool/uplink/attack_self(mob/user as mob) if(hidden_uplink) hidden_uplink.trigger(user) /obj/item/radio/headset/uplink traitor_frequency = 1445 /obj/item/radio/headset/uplink/New(var/loc, var/mind) ..() hidden_uplink = new(src, mind) hidden_uplink.telecrystals = DEFAULT_TELECRYSTAL_AMOUNT hidden_uplink.bluecrystals = DEFAULT_BLUECRYSTAL_AMOUNT /* * A simple device for accessing the SQL based contract database */ /obj/item/contract_uplink name = "contract uplink" desc = "A small device used for access restricted sites in the remote corners of the Extranet." icon = 'icons/obj/radio.dmi' icon_state = "radio" obj_flags = OBJ_FLAG_CONDUCTABLE w_class = WEIGHT_CLASS_SMALL /obj/item/contract_uplink/Initialize(var/mapload, var/mind) . = ..() hidden_uplink = new(src, mind) hidden_uplink.telecrystals = 0 hidden_uplink.bluecrystals = 0 hidden_uplink.tgui_menu = 3 /obj/item/contract_uplink/attack_self(mob/user as mob) if (hidden_uplink) hidden_uplink.trigger(user) //for revs to create their own central command reports /obj/item/announcer name = "relay positioning device" icon = 'icons/obj/item/gps.dmi' icon_state = "gps" item_state = "radio" w_class = WEIGHT_CLASS_SMALL /obj/item/announcer/antagonist_hints(mob/user, distance, is_adjacent) . += ..() . += "This device allows you to create a single Central Command report. It has only one use." /obj/item/announcer/attack_self(mob/user as mob) if(!player_is_antag(user.mind)) return var/title = sanitize(input("Enter your announcement title.", "Announcement Title") as null|text) if(!title) return var/message = sanitize(input("Enter your announcement message.", "Announcement Title") as message|null) if(!message) return command_announcement.Announce("[message]", title, new_sound = 'sound/AI/commandreport.ogg', msg_sanitized = 1); SSdiscord.send_to_cciaa("Announcer - Fake announcement:`[title]` - `[message]`, sent by [user]!") qdel(src) /obj/item/special_uplink name = "special uplink" desc = "A small device with knobs and switches." icon = 'icons/obj/radio.dmi' icon_state = "radio" obj_flags = OBJ_FLAG_CONDUCTABLE w_class = WEIGHT_CLASS_SMALL ///Amount of starting telecrystals. Defaults to default amount if not set. var/starting_telecrystals ///Amount of starting bluecrystals, used to buy support/medical/gimmick items. Defaults to default amount if not set. var/starting_bluecrystals /obj/item/special_uplink/antagonist_hints(mob/user, distance, is_adjacent) . += ..() . += "This is hidden uplink! Use it in-hand to access the uplink interface and spend telecrystals to beam in items." . += "Take care to only use it in private; it could look suspicious." /obj/item/special_uplink/New(var/loc, var/mind) ..() hidden_uplink = new(src, mind) if(!starting_telecrystals) hidden_uplink.telecrystals = DEFAULT_TELECRYSTAL_AMOUNT else hidden_uplink.telecrystals = starting_telecrystals if(!starting_bluecrystals) hidden_uplink.bluecrystals = DEFAULT_BLUECRYSTAL_AMOUNT else hidden_uplink.bluecrystals = DEFAULT_BLUECRYSTAL_AMOUNT hidden_uplink.tgui_menu = 1 /obj/item/special_uplink/attack_self(mob/user as mob) if(hidden_uplink) hidden_uplink.trigger(user) /obj/item/special_uplink/ninja name = "infiltrator uplink" starting_telecrystals = 15 /obj/item/special_uplink/mercenary name = "milspec uplink" starting_telecrystals = 15 /obj/item/special_uplink/burglar name = "sponsored uplink" starting_telecrystals = 20 /obj/item/special_uplink/jockey name = "jockey uplink" starting_telecrystals = 10 /obj/item/special_uplink/raider name = "underground uplink" starting_telecrystals = 3 /obj/item/special_uplink/rev name = "shortwave radio" desc = null // SBRs have no desc icon_state = "walkietalkie" // more incognito starting_telecrystals = DEFAULT_TELECRYSTAL_AMOUNT * 2