/obj/machinery/r_n_d/server name = "R&D Server" icon = 'icons/obj/machines/research.dmi' icon_state = "server" var/datum/research/files var/heat_health = 100 var/list/id_with_upload = list() //List of R&D consoles with upload to server access. var/list/id_with_download = list() //List of R&D consoles with download from server access. var/id_with_upload_string = "" //String versions for easy editing in map editor. var/id_with_download_string = "" var/server_id = 0 var/heat_gen = 100 var/heating_power = 40000 var/delay = 10 req_access = list(ACCESS_RD) //ONLY THE R&D CAN CHANGE SERVER SETTINGS. /obj/machinery/r_n_d/server/Initialize() . = ..() var/obj/item/circuitboard/machine/B = new /obj/item/circuitboard/machine/rdserver(null) B.apply_default_parts(src) /obj/machinery/r_n_d/server/Destroy() griefProtection() return ..() /obj/machinery/r_n_d/server/RefreshParts() var/tot_rating = 0 for(var/obj/item/stock_parts/SP in src) tot_rating += SP.rating heat_gen /= max(1, tot_rating) /obj/machinery/r_n_d/server/Initialize(mapload) . = ..() if(!files) files = new /datum/research(src) var/list/temp_list if(!id_with_upload.len) temp_list = list() temp_list = splittext(id_with_upload_string, ";") for(var/N in temp_list) id_with_upload += text2num(N) if(!id_with_download.len) temp_list = list() temp_list = splittext(id_with_download_string, ";") for(var/N in temp_list) id_with_download += text2num(N) /obj/machinery/r_n_d/server/process() var/datum/gas_mixture/environment = loc.return_air() switch(environment.temperature) if(0 to T0C) heat_health = min(100, heat_health + 1) if(T0C to (T20C + 20)) heat_health = Clamp(heat_health, 0, 100) if((T20C + 20) to (T0C + 70)) heat_health = max(0, heat_health - 1) if(heat_health <= 0) /*griefProtection() This seems to get called twice before running any code that deletes/damages the server or it's files anwyay. refreshParts and the hasReq procs that get called by this are laggy and do not need to be called by every server on the map every tick */ var/updateRD = 0 files.known_designs = list() for(var/v in files.known_tech) var/datum/tech/T = files.known_tech[v] if(prob(1)) updateRD++ T.level-- if(updateRD) files.RefreshResearch() if(delay) delay-- else produce_heat(heat_gen) delay = initial(delay) /obj/machinery/r_n_d/server/emp_act(severity) griefProtection() ..() /obj/machinery/r_n_d/server/ex_act(severity, target) griefProtection() ..() //Backup files to centcom to help admins recover data after greifer attacks /obj/machinery/r_n_d/server/proc/griefProtection() for(var/obj/machinery/r_n_d/server/centcom/C in GLOB.machines) for(var/v in files.known_tech) var/datum/tech/T = files.known_tech[v] C.files.AddTech2Known(T) for(var/v in files.known_designs) var/datum/design/D = files.known_designs[v] C.files.AddDesign2Known(D) C.files.RefreshResearch() /obj/machinery/r_n_d/server/proc/produce_heat(heat_amt) if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater. var/turf/L = loc if(istype(L)) var/datum/gas_mixture/env = L.return_air() if(env.temperature < (heat_amt+T0C)) var/transfer_moles = 0.25 * env.total_moles() var/datum/gas_mixture/removed = env.remove(transfer_moles) if(removed) var/heat_capacity = removed.heat_capacity() if(heat_capacity == 0 || heat_capacity == null) heat_capacity = 1 removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000) env.merge(removed) air_update_turf() //called when the server is deconstructed. /obj/machinery/r_n_d/server/on_deconstruction() griefProtection() ..() /obj/machinery/r_n_d/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves. if (disabled) return if (shocked) shock(user,50) return /obj/machinery/r_n_d/server/centcom name = "CentCom Central R&D Database" server_id = -1 /obj/machinery/r_n_d/server/centcom/Initialize() . = ..() fix_noid_research_servers() /proc/fix_noid_research_servers() var/list/no_id_servers = list() var/list/server_ids = list() for(var/obj/machinery/r_n_d/server/S in GLOB.machines) switch(S.server_id) if(-1) continue if(0) no_id_servers += S else server_ids += S.server_id for(var/obj/machinery/r_n_d/server/S in no_id_servers) var/num = 1 while(!S.server_id) if(num in server_ids) num++ else S.server_id = num server_ids += num no_id_servers -= S /obj/machinery/r_n_d/server/centcom/process() return PROCESS_KILL //don't need process() /obj/machinery/computer/rdservercontrol name = "R&D Server Controller" desc = "Used to manage access to research and manufacturing databases." icon_screen = "rdcomp" icon_keyboard = "rd_key" var/screen = 0 var/obj/machinery/r_n_d/server/temp_server var/list/servers = list() var/list/consoles = list() var/badmin = 0 circuit = /obj/item/circuitboard/computer/rdservercontrol /obj/machinery/computer/rdservercontrol/Topic(href, href_list) if(..()) return add_fingerprint(usr) usr.set_machine(src) if(!src.allowed(usr) && !emagged) to_chat(usr, "You do not have the required access level.") return if(href_list["main"]) screen = 0 else if(href_list["access"] || href_list["data"] || href_list["transfer"]) temp_server = null consoles = list() servers = list() for(var/obj/machinery/r_n_d/server/S in GLOB.machines) if(S.server_id == text2num(href_list["access"]) || S.server_id == text2num(href_list["data"]) || S.server_id == text2num(href_list["transfer"])) temp_server = S break if(href_list["access"]) screen = 1 for(var/obj/machinery/computer/rdconsole/C in GLOB.machines) if(C.sync) consoles += C else if(href_list["data"]) screen = 2 else if(href_list["transfer"]) screen = 3 for(var/obj/machinery/r_n_d/server/S in GLOB.machines) if(S == src) continue servers += S else if(href_list["upload_toggle"]) var/num = text2num(href_list["upload_toggle"]) if(num in temp_server.id_with_upload) temp_server.id_with_upload -= num else temp_server.id_with_upload += num else if(href_list["download_toggle"]) var/num = text2num(href_list["download_toggle"]) if(num in temp_server.id_with_download) temp_server.id_with_download -= num else temp_server.id_with_download += num else if(href_list["reset_tech"]) var/choice = alert("Technology Data Reset", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel") if(choice == "Continue" && usr.canUseTopic(src)) var/datum/tech/T = temp_server.files.known_tech[href_list["reset_tech"]] if(T) T.level = 1 temp_server.files.RefreshResearch() else if(href_list["reset_design"]) var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? Data lost cannot be recovered.", "Continue", "Cancel") if(choice == "Continue" && usr.canUseTopic(src)) var/datum/design/D = temp_server.files.known_designs[href_list["reset_design"]] if(D) temp_server.files.known_designs -= D.id temp_server.files.RefreshResearch() updateUsrDialog() return /obj/machinery/computer/rdservercontrol/attack_hand(mob/user) if(..()) return user.set_machine(src) var/dat = "" switch(screen) if(0) //Main Menu dat += "Connected Servers:

" for(var/obj/machinery/r_n_d/server/S in GLOB.machines) if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin) continue dat += "[S.name] || " dat += "Access Rights | " dat += "Data Management" if(badmin) dat += " | Server-to-Server Transfer" dat += "
" if(1) //Access rights menu dat += "[temp_server.name] Access Rights

" dat += "Consoles with Upload Access
" for(var/obj/machinery/computer/rdconsole/C in consoles) var/turf/console_turf = get_turf(C) dat += "* [console_turf.loc]" //FYI, these are all numeric ids, eventually. if(C.id in temp_server.id_with_upload) dat += " (Remove)
" else dat += " (Add)
" dat += "Consoles with Download Access
" for(var/obj/machinery/computer/rdconsole/C in consoles) var/turf/console_turf = get_turf(C) dat += "* [console_turf.loc]" if(C.id in temp_server.id_with_download) dat += " (Remove)
" else dat += " (Add)
" dat += "
Main Menu" if(2) //Data Management menu dat += "[temp_server.name] Data ManagementP

" dat += "Known Technologies
" for(var/v in temp_server.files.known_tech) var/datum/tech/T = temp_server.files.known_tech[v] if(T.level <= 0) continue dat += "* [T.name] " dat += "(Reset)
" //FYI, these are all strings. dat += "Known Designs
" for(var/v in temp_server.files.known_designs) var/datum/design/D = temp_server.files.known_designs[v] dat += "* [D.name] " dat += "(Delete)
" dat += "
Main Menu" if(3) //Server Data Transfer dat += "[temp_server.name] Server to Server Transfer

" dat += "Send Data to what server?
" for(var/obj/machinery/r_n_d/server/S in servers) dat += "[S.name] (Transfer)
" dat += "
Main Menu" user << browse("R&D Server Control
[dat]", "window=server_control;size=575x400") onclose(user, "server_control") return /obj/machinery/computer/rdservercontrol/attackby(obj/item/D, mob/user, params) . = ..() src.updateUsrDialog() /obj/machinery/computer/rdservercontrol/emag_act(mob/user) if(emagged) return playsound(src, "sparks", 75, 1) emagged = TRUE to_chat(user, "You you disable the security protocols.") /obj/machinery/r_n_d/server/robotics name = "Robotics R&D Server" id_with_upload_string = "1;2" id_with_download_string = "1;2" server_id = 2 /obj/machinery/r_n_d/server/core name = "Core R&D Server" id_with_upload_string = "1" id_with_download_string = "1" server_id = 1