/** * # Telecommunications Relay * * Extends the reach of telecomms to the z-level it is built on * * Relays themselves dont do any processing, they just tell the core that this z-level is available in the tcomms network. */ /obj/machinery/tcomms/relay name = "Telecommunications Relay" desc = "A large device with several radio antennas on it." icon_state = "relay" // This starts as off so you cant make cores as hot spares active = FALSE /// The host core for this relay var/obj/machinery/tcomms/core/linked_core /// ID of the hub to auto link to var/autolink_id /// Is this linked to anything at all var/linked = FALSE /// Is this link invisible on the hub? var/hidden_link = FALSE /// Does this relay need a password to connect to hubs? var/password_bypass = FALSE /** * Initializer for the relay. * * Calls parent to ensure its added to the GLOB of tcomms machines, before checking if there is an autolink that needs to be added. */ /obj/machinery/tcomms/relay/Initialize(mapload) . = ..() component_parts += new /obj/item/circuitboard/tcomms/relay(null) if(check_power_on()) active = TRUE else visible_message(SPAN_WARNING("Error: Another relay is already active in this sector. Power-up cancelled due to radio interference.")) update_icon() if(mapload && autolink_id) return INITIALIZE_HINT_LATELOAD /** * Descrutor for the relay. * * Ensures that the machine is taken out of the global list when destroyed, and also removes the link to the core. */ /obj/machinery/tcomms/relay/Destroy() Reset() return ..() /** * Late Initialize for the relay. * * Calls parent, then adds links to the cores. This is a LateInitialize because the core MUST be initialized first */ /obj/machinery/tcomms/relay/LateInitialize() . = ..() // It's also possible the relay's APC's Initialize was called after this one. // Take the opportunity here to re-check the equipment channel. power_change() for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) if(C.network_id == autolink_id) AddLink(C) // Only ONE of these with one ID should exist per world break /** * Z-Level transit change helper * * Handles parent call of disabling the machine if it changes Z-level, but also rebuilds the list of reachable levels on the linked core */ /obj/machinery/tcomms/relay/on_changed_z_level(turf/old_turf, turf/new_turf) . = ..() if(linked_core) linked_core.refresh_zlevels() /** * Power-on checker * * Checks the z-level to see if an existing relay is already powered on, and deny this one turning on if there is one. Returns TRUE if it can power on, or FALSE if it cannot */ /obj/machinery/tcomms/relay/proc/check_power_on() // Cancel if we are already on if(active) return TRUE for(var/obj/machinery/tcomms/relay/R in GLOB.tcomms_machines) // Make sure we dont check ourselves if(R == src) continue // We dont care about ones on other zlevels if(!atoms_share_level(R, src)) continue // If another relay is active, return FALSE if(R.active) if(R.stat & NOPOWER) // If another relay has no power but is supposed to be on, we shut it down so we can continue. R.active = FALSE // Since only one active relay is allowed per z level, give priority to the one that's actually working. R.update_icon() else return FALSE // If we got here there isnt an active relay on this Z-level. So return TRUE return TRUE /** * Proc to link the relay to the core. * * Sets the linked core to the target (argument below), before adding it to the list of linked relays, then re-freshing the zlevel list * The relay is then marked as linked * Arguments: * * target - The telecomms core that this relay should be linked to */ /obj/machinery/tcomms/relay/proc/AddLink(obj/machinery/tcomms/core/target) linked_core = target target.linked_relays |= src target.refresh_zlevels() linked = TRUE /** * Proc to rest the relay. * * Resets the relay, removing its linkage status, and refreshing the core's list of z-levels */ /obj/machinery/tcomms/relay/proc/Reset() if(linked_core) linked_core.linked_relays -= src linked_core.refresh_zlevels() linked_core = null linked = FALSE /** * Power Change Handler * * Proc which ensures the host core has its zlevels updated (icons are updated by parent call) */ /obj/machinery/tcomms/relay/power_change() if(!..()) return if(linked_core) linked_core.refresh_zlevels() ////////////// // UI STUFF // ////////////// /obj/machinery/tcomms/relay/ui_state(mob/user) return GLOB.default_state /obj/machinery/tcomms/relay/ui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "TcommsRelay", name) ui.open() /obj/machinery/tcomms/relay/ui_data(mob/user) var/list/data = list() // Are we on or not data["active"] = active // What is our network ID data["network_id"] = network_id // Are we linked data["linked"] = linked // Is the link hidden data["hidden_link"] = hidden_link // Only send linked tab stuff if we are linked. This saves on sending overhead. if(linked) data["linked_core_id"] = linked_core.network_id data["linked_core_addr"] = "\ref[linked_core]" else var/list/cores = list() for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) cores += list(list("addr" = "\ref[C]", "net_id" = C.network_id, "sector" = C.loc.z)) data["cores"] = cores return data /obj/machinery/tcomms/relay/ui_act(action, list/params) // Check against href exploits if(..()) return . = TRUE switch(action) if("toggle_active") if(check_power_on()) active = !active update_icon() if(linked_core) linked_core.refresh_zlevels() else to_chat(usr, SPAN_WARNING("Error: Another relay is already active in this sector. Power-up cancelled due to radio interference.")) // Set network ID if("network_id") var/new_id = input(usr, "Please enter a new network ID", "Network ID", network_id) log_action(usr, "renamed core with ID [network_id] to [new_id]") to_chat(usr, SPAN_NOTICE("Device ID changed from [network_id] to [new_id].")) network_id = new_id // Only do these hrefs if we are linked to prevent bugs/exploits if("toggle_hidden_link") if(!linked) return hidden_link = !hidden_link log_action(usr, "Modified hidden link for [network_id] (Now [hidden_link])") if("unlink") if(!linked) return var/choice = tgui_alert(usr, "Are you SURE you want to unlink this relay?\nYou wont be able to re-link without the core password", "Unlink", list("Yes", "No")) if(choice == "Yes") log_action(usr, "Unlinked [network_id] from [linked_core.network_id]") Reset() // You should only be able to link if its not linked, to prevent weirdness if("link") if(linked) return var/obj/machinery/tcomms/core/C = locate(params["addr"]) if(istype(C, /obj/machinery/tcomms/core)) if(password_bypass) AddLink(C) to_chat(usr, SPAN_NOTICE("Successfully linked to [C.network_id].")) return var/user_pass = input(usr, "Please enter core password","Password Entry") // Check the password if(user_pass == C.link_password) AddLink(C) to_chat(usr, SPAN_NOTICE("Successfully linked to [C.network_id].")) else to_chat(usr, SPAN_ALERT("ERROR: Password incorrect.")) else to_chat(usr, SPAN_ALERT("ERROR: Core not found. Please file an issue report.")) /obj/machinery/tcomms/relay/start_off/Initialize(mapload) // always starts off . = ..() active = FALSE