diff --git a/code/datums/browser.dm b/code/datums/browser.dm index c935a7a9f93..a143be58501 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -1,44 +1,48 @@ /datum/browser var/mob/user - var/title - var/window_id // window_id is used as the window name for browse and onclose + var/title = "" + /// window_id is used as the window name for browse and onclose + var/window_id var/width = 0 var/height = 0 - var/datum/weakref/ref = null - var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id - var/stylesheets[0] - var/scripts[0] + var/datum/weakref/source_ref = null + /// window option is set using window_id + var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" + var/list/stylesheets = list() + var/list/scripts = list() var/head_elements var/body_elements var/head_content = "" var/content = "" -/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null) - if(IS_CLIENT_OR_MOCK(nuser)) - var/client/client_user = nuser +/datum/browser/New(mob/user, window_id, title = "", width = 0, height = 0, atom/source = null) + if(IS_CLIENT_OR_MOCK(user)) + var/client/client_user = user user = client_user.mob - else - user = nuser + src.user = user RegisterSignal(user, COMSIG_QDELETING, PROC_REF(user_deleted)) - window_id = nwindow_id - if (ntitle) - title = format_text(ntitle) - if (nwidth) - width = nwidth - if (nheight) - height = nheight - if (nref) - ref = WEAKREF(nref) + src.window_id = window_id + if (title) + src.title = format_text(title) + if (width) + src.width = width + if (height) + src.height = height + if (source) + src.source_ref = WEAKREF(source) /datum/browser/proc/user_deleted(datum/source) SIGNAL_HANDLER user = null -/datum/browser/proc/add_head_content(nhead_content) - head_content = nhead_content +/datum/browser/proc/add_head_content(head_content) + src.head_content += head_content -/datum/browser/proc/set_window_options(nwindow_options) - window_options = nwindow_options +/datum/browser/proc/set_head_content(head_content) + src.head_content = head_content + +/datum/browser/proc/set_window_options(window_options) + src.window_options = window_options /datum/browser/proc/add_stylesheet(name, file) if (istype(name, /datum/asset/spritesheet)) @@ -59,21 +63,21 @@ scripts["[ckey(name)].js"] = file SSassets.transport.register_asset("[ckey(name)].js", file) -/datum/browser/proc/set_content(ncontent) - content = ncontent +/datum/browser/proc/set_content(content) + src.content = content -/datum/browser/proc/add_content(ncontent) - content += ncontent +/datum/browser/proc/add_content(content) + src.content += content /datum/browser/proc/get_header() var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common) - var/file - head_content += "" - for (file in stylesheets) - head_content += "" + var/list/new_head_content = list() + new_head_content += "" + for (var/file in stylesheets) + new_head_content += "" if(user.client?.window_scaling && user.client?.window_scaling != 1 && !user.client?.prefs.read_preference(/datum/preference/toggle/ui_scale) && width && height) - head_content += {" + new_head_content += {" "} - for (file in scripts) - head_content += "" + for (var/file in scripts) + new_head_content += "" + head_content += new_head_content.Join() return {" @@ -96,6 +101,7 @@ [title ? "
[title]
" : ""]
"} + //" This is here because else the rest of the file looks like a string in notepad++. /datum/browser/proc/get_footer() return {" @@ -106,16 +112,17 @@ /datum/browser/proc/get_content() return {" - [get_header()] - [content] - [get_footer()] + [get_header()] + [content] + [get_footer()] "} -/datum/browser/proc/open(use_onclose = TRUE) +/datum/browser/proc/open(use_on_close = TRUE) if(isnull(window_id)) //null check because this can potentially nuke goonchat WARNING("Browser [title] tried to open with a null ID") to_chat(user, span_userdanger("The [title] browser you tried to open failed a sanity check! Please report this on GitHub!")) return + var/window_size = "" if(width && height) if(user.client?.prefs?.read_preference(/datum/preference/toggle/ui_scale)) @@ -123,27 +130,28 @@ window_size = "size=[width * scaling]x[height * scaling];" else window_size = "size=[width]x[height];" + var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common) common_asset.send(user) - if (stylesheets.len) + if (length(stylesheets)) SSassets.transport.send_assets(user, stylesheets) - if (scripts.len) + if (length(scripts)) SSassets.transport.send_assets(user, scripts) DIRECT_OUTPUT(user, browse(get_content(), "window=[window_id];[window_size][window_options]")) - if (use_onclose) + if (use_on_close) setup_onclose() /datum/browser/proc/setup_onclose() set waitfor = 0 //winexists sleeps, so we don't need to. for (var/i in 1 to 10) - if (user?.client && winexists(user, window_id)) - var/atom/send_ref - if(ref) - send_ref = ref.resolve() - if(!send_ref) - ref = null - onclose(user, window_id, send_ref) - break + if (!user?.client || !winexists(user, window_id)) + continue + var/atom/send_ref + if(source_ref) + send_ref = source_ref.resolve() + if(!send_ref) + source_ref = null + onclose(user, window_id, send_ref) /datum/browser/proc/close() if(!isnull(window_id))//null check because this can potentially nuke goonchat @@ -151,106 +159,106 @@ else WARNING("Browser [title] tried to close with a null ID") -/datum/browser/modal/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000) - if (!User) +/datum/browser/modal/alert/New(user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = 600 SECONDS) + if (!user) return - var/output = {"
[Message]

+ var/list/display_list = list() + display_list += {"
[message]

- [Button1]"} + [button_1]"} - if (Button2) - output += {"[Button2]"} + if (button_2) + display_list += {"[button_2]"} - if (Button3) - output += {"[Button3]"} + if (button_3) + display_list += {"[button_3]"} - output += {"
"} + display_list += {"
"} - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout) - set_content(output) + ..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, 350, 150, src, steal_focus, timeout) + set_content(display_list.Join()) /datum/browser/modal/alert/Topic(href,href_list) if (href_list["close"] || !user || !user.client) - opentime = 0 + open_time = 0 return if (href_list["button"]) var/button = text2num(href_list["button"]) if (button <= 3 && button >= 1) - selectedbutton = button - opentime = 0 + selected_button = button + open_time = 0 close() /** * **DEPRECATED: USE tgui_alert(...) INSTEAD** * - * Designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) + * Designed as a drop in replacement for alert(); functions the same. (outside of needing user specified) * Arguments: - * * User - The user to show the alert to. - * * Message - The textual body of the alert. - * * Title - The title of the alert's window. - * * Button1 - The first button option. - * * Button2 - The second button option. - * * Button3 - The third button option. - * * StealFocus - Boolean operator controlling if the alert will steal the user's window focus. - * * Timeout - The timeout of the window, after which no responses will be valid. + * * user - The user to show the alert to. + * * message - The textual body of the alert. + * * title - The title of the alert's window. + * * button_1 - The first button option. + * * button_2 - The second button option. + * * button_3 - The third button option. + * * steal_focus - Boolean operator controlling if the alert will steal the user's window focus. + * * timeout - The timeout of the window, after which no responses will be valid. */ -/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = TRUE, Timeout = 6000) - if (!User) - User = usr - if (!istype(User)) - if (istype(User, /client)) - var/client/client = User - User = client.mob - else +/proc/tg_alert(mob/user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = 600 SECONDS) + if (!user) + user = usr + if (!ismob(user)) + if (!istype(user, /client)) return + var/client/user_client = user + user = user_client.mob // Get user's response using a modal - var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) - A.open() - A.wait() - switch(A.selectedbutton) + var/datum/browser/modal/alert/window = new(user, message, title, button_1, button_2, button_3, steal_focus, timeout) + window.open() + window.wait() + switch(window.selected_button) if (1) - return Button1 + return button_1 if (2) - return Button2 + return button_2 if (3) - return Button3 + return button_3 /datum/browser/modal - var/opentime = 0 + var/open_time = 0 var/timeout - var/selectedbutton = 0 - var/stealfocus + var/selected_button = 0 + var/steal_focus -/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null, StealFocus = 1, Timeout = 6000) +/datum/browser/modal/New(user, window_id, title = 0, width = 0, height = 0, atom/source = null, steal_focus = TRUE, timeout = 600 SECONDS) ..() - stealfocus = StealFocus - if (!StealFocus) + src.steal_focus = steal_focus + if (!src.steal_focus) window_options += "focus=false;" - timeout = Timeout - + src.timeout = timeout /datum/browser/modal/close() - .=..() - opentime = 0 + . = ..() + open_time = 0 -/datum/browser/modal/open(use_onclose) +/datum/browser/modal/open(use_on_close) set waitfor = FALSE - opentime = world.time + open_time = world.time + use_on_close = TRUE - if (stealfocus) - . = ..(use_onclose = 1) + if (steal_focus) + . = ..() else - var/focusedwindow = winget(user, null, "focus") - . = ..(use_onclose = 1) + var/focused_window = winget(user, null, "focus") + . = ..() //waits for the window to show up client side before attempting to un-focus it //winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping for (var/i in 1 to 10) if (user && winexists(user, window_id)) - if (focusedwindow) - winset(user, focusedwindow, "focus=true") + if (focused_window) + winset(user, focused_window, "focus=true") else winset(user, "mapwindow", "focus=true") break @@ -258,239 +266,235 @@ addtimer(CALLBACK(src, PROC_REF(close)), timeout) /datum/browser/modal/proc/wait() - while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) + while (open_time && selected_button <= 0 && (!timeout || open_time + timeout > world.time)) stoplag(1) -/datum/browser/modal/listpicker - var/valueslist = list() +/datum/browser/modal/list_picker + var/values_list = list() -/datum/browser/modal/listpicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/values,inputtype="checkbox", width, height, slidecolor) - if (!User) +/datum/browser/modal/list_picker/New(user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = FALSE, list/values, input_type = "checkbox", width, height, slide_color) + if (!user) return - var/output = {"
+ "} - if (Button2) - output += {""} + if (button_2) + display_list += {""} - if (Button3) - output += {""} + if (button_3) + display_list += {""} - output += {"
"} - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) - set_content(output) + display_list += {""} + ..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, width, height, src, steal_focus, timeout) + set_content(display_list.Join()) -/datum/browser/modal/listpicker/Topic(href,href_list) +/datum/browser/modal/list_picker/Topic(href, list/href_list) if (href_list["close"] || !user || !user.client) - opentime = 0 + open_time = 0 return if (href_list["button"]) var/button = text2num(href_list["button"]) if (button <= 3 && button >= 1) - selectedbutton = button - for (var/item in href_list) - switch(item) - if ("close", "button", "src") - continue - else - valueslist[item] = href_list[item] - opentime = 0 + selected_button = button + values_list = href_list.Copy() + values_list -= list("close", "button", "src") + open_time = 0 close() -/proc/presentpicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else +/proc/present_picker(mob/user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = 600 SECONDS, list/values, input_type = "checkbox", width, height, slide_color) + if (!ismob(user)) + if (!istype(user, /client)) return - var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor) - A.open() - A.wait() - if (A.selectedbutton) - return list("button" = A.selectedbutton, "values" = A.valueslist) + var/client/user_client = user + user = user_client.mob + var/datum/browser/modal/list_picker/window = new(user, message, title, button_1, button_2, button_3, steal_focus, timeout, values, input_type, width, height, slide_color) + window.open() + window.wait() + if (window.selected_button) + return list("button" = window.selected_button, "values" = window.values_list) -/proc/input_bitfield(mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_flags = ALL) +/proc/input_bitfield(mob/user, title, bitfield, current_value, width = 350, height = 350, slide_color, allowed_edit_field = ALL) var/list/bitflags = get_valid_bitflags(bitfield) - if (!User || !length(bitflags)) + if (!user || !length(bitflags)) return var/list/picker_list = list() for (var/bit_name in bitflags) var/bit_value = bitflags[bit_name] - // TRUE/FALSE cast, sorry :) - var/can_edit = !!(allowed_edit_flags & bit_value) - var/flag_set = !!(current_value & bit_value) - picker_list += list(list("checked" = flag_set, "value" = bit_value, "name" = bit_name, "allowed_edit" = can_edit)) + // Gotta make it TRUE/FALSE sorry brother + var/can_edit = !!(allowed_edit_field & bit_value) + var/enabled = !!(current_value & bit_value) + picker_list += list(list("checked" = enabled, "value" = bit_value, "name" = bit_name, "allowed_edit" = can_edit)) - var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = picker_list, width = nwidth, height = nheight, slidecolor = nslidecolor) - if (islist(result)) - if (result["button"] == 2) // If the user pressed the cancel button - return - . = NONE - for (var/flag_name in result["values"]) - . |= bitflags[flag_name] - else + var/list/result = present_picker(user, "", title, button_1 = "Save", button_2 = "Cancel", timeout = FALSE, values = picker_list, width = width, height = height, slide_color = slide_color) + if (!islist(result)) + return + if (result["button"] == 2) // If the user pressed the cancel button return -/datum/browser/modal/preflikepicker + var/result_bitfield = NONE + for (var/flag_name in result["values"]) + result_bitfield |= bitflags[flag_name] + return result_bitfield + +/datum/browser/modal/pref_like_picker var/settings = list() var/icon/preview_icon = null var/datum/callback/preview_update -/datum/browser/modal/preflikepicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/settings,inputtype="checkbox", width = 600, height, slidecolor) - if (!User) +/datum/browser/modal/pref_like_picker/New(mob/user, message, title, steal_focus = TRUE, timeout = 600 SECONDS, list/settings, width, height) + if (!user) return src.settings = settings - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) - set_content(ShowChoices(User)) + ..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, width, height, src, steal_focus, timeout) + set_content(show_choices(user)) -/datum/browser/modal/preflikepicker/proc/ShowChoices(mob/user) +/datum/browser/modal/pref_like_picker/proc/show_choices(mob/user) if (settings["preview_callback"]) var/datum/callback/callback = settings["preview_callback"] preview_icon = callback.Invoke(settings) if (preview_icon) user << browse_rsc(preview_icon, "previewicon.png") - var/dat = "" + var/list/display_list = list() for (var/name in settings["mainsettings"]) var/setting = settings["mainsettings"][name] if (setting["type"] == "datum") if (setting["subtypesonly"]) - dat += "[setting["desc"]]: [setting["value"]]
" + display_list += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + display_list += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + display_list += "[setting["desc"]]: [setting["value"]]
" if (preview_icon) - dat += "" + display_list += "" + display_list += "
" + display_list += "" - dat += "
" + display_list += "" + display_list += "
Ok " + display_list += "
" - dat += "" + return display_list.Join() - dat += "" - - dat += "
Ok " - - dat += "
" - - return dat - -/datum/browser/modal/preflikepicker/Topic(href,href_list) +/datum/browser/modal/pref_like_picker/Topic(href,href_list) if (href_list["close"] || !user || !user.client) - opentime = 0 + open_time = 0 return + if (href_list["task"] == "input") - var/setting = href_list["setting"] + var/setting_key = href_list["setting"] + var/list/setting = settings["mainsettings"][setting_key] switch (href_list["type"]) if ("datum") - var/oldval = settings["mainsettings"][setting]["value"] + var/parent_path = text2path(href_list["path"]) + var/list/paths if (href_list["subtypesonly"]) - settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(subtypesof(text2path(href_list["path"])))) + paths = subtypesof(parent_path) else - settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(typesof(text2path(href_list["path"])))) - if (isnull(settings["mainsettings"][setting]["value"])) - settings["mainsettings"][setting]["value"] = oldval + paths = typesof(parent_path) + + var/new_value = pick_closest_path(null, make_types_fancy(paths)) + if (!isnull(new_value)) + setting["value"] = new_value + if ("string") - settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) + setting["value"] = stripped_input(user, "Enter new value for [setting["desc"]]", "Enter new value for [setting["desc"]]", setting["value"]) if ("number") - settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num + setting["value"] = input(user, "Enter new value for [setting["desc"]]", "Enter new value for [setting["desc"]]") as num if ("color") - settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) as color + setting["value"] = input(user, "Enter new value for [setting["desc"]]", "Enter new value for [setting["desc"]]", setting["value"]) as color if ("boolean") - settings["mainsettings"][setting]["value"] = (settings["mainsettings"][setting]["value"] == "Yes") ? "No" : "Yes" + setting["value"] = (setting["value"] == "Yes") ? "No" : "Yes" if ("ckey") - settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory - if (settings["mainsettings"][setting]["callback"]) - var/datum/callback/callback = settings["mainsettings"][setting]["callback"] + setting["value"] = input(user, "[setting["desc"]]?") in (list("none") + GLOB.directory) + if (setting["callback"]) + var/datum/callback/callback = setting["callback"] settings = callback.Invoke(settings) + if (href_list["button"]) var/button = text2num(href_list["button"]) if (button <= 3 && button >= 1) - selectedbutton = button - if (selectedbutton != 1) - set_content(ShowChoices(user)) + selected_button = button + + if (selected_button != 1) + set_content(show_choices(user)) open() return - for (var/item in href_list) - switch(item) - if ("close", "button", "src") - continue - opentime = 0 + + open_time = 0 close() -/proc/presentpreflikepicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else +/proc/present_pref_like_picker(mob/user, message, title, steal_focus = TRUE, timeout = 600 SECONDS, list/settings, width, height) + if (!ismob(user)) + if (!istype(user, /client)) return - var/datum/browser/modal/preflikepicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, settings, width, height, slidecolor) - A.open() - A.wait() - if (A.selectedbutton) - return list("button" = A.selectedbutton, "settings" = A.settings) + var/client/user_client = user + user = user_client.mob + var/datum/browser/modal/pref_like_picker/window = new(user, message, title, steal_focus, timeout, settings, width, height) + window.open() + window.wait() + if (window.selected_button) + return list("button" = window.selected_button, "settings" = window.settings) -// Registers the on-close verb for a browse window (client/verb/.windowclose) -// this will be called when the close-button of a window is pressed. -// -// This is usually only needed for devices that regularly update the browse window, -// e.g. canisters, timers, etc. -// -// windowid should be the specified window name -// e.g. code is : user << browse(text, "window=fred") -// then use : onclose(user, "fred") -// -// Optionally, specify the "ref" parameter as the controlled atom (usually src) +/// Registers the on-close verb for a browse window (client/verb/windowclose) +/// this will be called when the close-button of a window is pressed. +/// +/// This is usually only needed for devices that regularly update the browse window, +/// e.g. canisters, timers, etc. +/// +/// windowid should be the specified window name +/// e.g. code is : user << browse(text, "window=fred") +/// then use : onclose(user, "fred") +/// +/// Optionally, specify the "source" parameter as the controlled atom (usually src) // to pass a "close=1" parameter to the atom's Topic() proc for special handling. -// Otherwise, the user mob's machine var will be reset directly. -// -/proc/onclose(mob/user, windowid, atom/ref=null) +/// Otherwise, the user mob's machine var will be reset directly. +/// +/proc/onclose(mob/user, windowid, atom/source = null) if(!user.client) return var/param = "null" - if(ref) - param = "[REF(ref)]" + if(source) + param = "[REF(source)]" winset(user, windowid, "on-close=\".windowclose [param]\"") - - -// the on-close client verb -// called when a browser popup window is closed after registering with proc/onclose() -// if a valid atom reference is supplied, call the atom's Topic() with "close=1" -// otherwise, just reset the client mob's machine var. -// +/// the on-close client verb +/// called when a browser popup window is closed after registering with proc/onclose() +/// if a valid atom reference is supplied, call the atom's Topic() with "close=1" +/// otherwise, just reset the client mob's machine var. /client/verb/windowclose(atomref as text) set hidden = TRUE // hide this verb from the user's panel set name = ".windowclose" // no autocomplete on cmd line - if(atomref != "null") // if passed a real atomref - var/hsrc = locate(atomref) // find the reffed atom - var/href = "close=1" - if(hsrc) - usr = src.mob - src.Topic(href, params2list(href), hsrc) // this will direct to the atom's - return // Topic() proc via client.Topic() + if(atomref == "null") + return + // if passed a real atomref + var/atom/hsrc = locate(atomref) // find the reffed atom + var/href = "close=1" + if(!hsrc) + return + usr = src.mob + src.Topic(href, params2list(href), hsrc) // this will direct to the atom's diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 796397736b7..92f8be528c6 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -80,25 +80,30 @@ if(href_list[VV_HK_ARMOR_MOD]) if(!check_rights(NONE)) return - var/list/pickerlist = list() - var/list/armorlist = get_armor().get_rating_list() - for (var/i in armorlist) - pickerlist += list(list("value" = armorlist[i], "name" = i)) - var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [src]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist) + var/list/picker_list = list() + var/list/armor_list = get_armor().get_rating_list() + for (var/rating in armor_list) + picker_list += list(list("value" = armor_list[rating], "name" = rating)) + + var/list/result = present_picker(usr, "Modify armor", "Modify armor: [src]", button_1 = "Save", button_2 = "Cancel", timeout = FALSE, input_type = "text", values = picker_list) + if(!islist(result)) + return + if(result["button"] == 2) // If the user pressed the cancel button + return + var/list/armor_all = ARMOR_LIST_ALL() - if(islist(result)) - if(result["button"] != 2) // If the user pressed the cancel button - // text2num conveniently returns a null on invalid values - var/list/converted = list() - for(var/armor_key in armor_all) - converted[armor_key] = text2num(result["values"][armor_key]) - set_armor(get_armor().generate_new_with_specific(converted)) - var/message = "[key_name(usr)] modified the armor on [src] ([type]) to: " - for(var/armor_key in armor_all) - message += "[armor_key]=[get_armor_rating(armor_key)]," - message = copytext(message, 1, -1) - log_admin(span_notice(message)) - message_admins(span_notice(message)) + // text2num conveniently returns a null on invalid values + var/list/converted = list() + for(var/armor_key in armor_all) + converted[armor_key] = text2num(result["values"][armor_key]) + set_armor(get_armor().generate_new_with_specific(converted)) + + var/message = "[key_name(usr)] modified the armor on [src] ([type]) to: " + for(var/armor_key in armor_all) + message += "[armor_key]=[get_armor_rating(armor_key)]," + message = copytext(message, 1, -1) + log_admin(span_notice(message)) + message_admins(span_notice(message)) if(href_list[VV_HK_ADD_AI]) if(!check_rights(R_VAREDIT)) diff --git a/code/game/objects/structures/detectiveboard.dm b/code/game/objects/structures/detectiveboard.dm index b2c0565bc9c..2f9aae546a2 100644 --- a/code/game/objects/structures/detectiveboard.dm +++ b/code/game/objects/structures/detectiveboard.dm @@ -189,9 +189,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/detectiveboard, 32) for(var/datum/paper_input/text_input as anything in paper.raw_text_inputs) paper_text += text_input.raw_text user << browse("[paper.name]" \ - + "" \ - + "[paper_text]" \ - + "", "window=photo_showing;size=480x608") + + "" \ + + "[paper_text]" \ + + "", "window=photo_showing;size=480x608") onclose(user, "[name]") if("remove_evidence") var/datum/case/case = cases[current_case] diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index f0ffe85aa2d..b2605fea270 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -471,8 +471,10 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm admin_holder.rank_flags(), 350, 590, - allowed_edit_flags = usr.client.holder.can_edit_rights_flags(), + allowed_edit_field = usr.client.holder.can_edit_rights_flags(), ) + if(isnull(new_flags)) + return admin_holder.disassociate() diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index 7ee51a895ab..c7b13469333 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -71,7 +71,7 @@ unset_busy_human_dummy(DUMMY_HUMAN_SLOT_ADMIN) return preview_icon -/datum/admins/proc/makeEmergencyresponseteam(datum/ert/ertemplate = null) +/datum/admins/proc/make_emergency_response_team(datum/ert/ertemplate = null) if (ertemplate) ertemplate = new ertemplate else @@ -96,182 +96,181 @@ ) ) - var/list/prefreturn = presentpreflikepicker(usr, "Customize ERT", "Customize ERT", Button1="Ok", width = 600, StealFocus = 1,Timeout = 0, settings=settings) + var/list/pref_return = present_pref_like_picker(usr, "Customize ERT", "Customize ERT", width = 600, timeout = 0, settings = settings) - if (isnull(prefreturn)) + if (isnull(pref_return)) return FALSE - if (prefreturn["button"] == 1) - var/list/prefs = settings["mainsettings"] + if (pref_return["button"] != 1) + return FALSE - var/templtype = prefs["template"]["value"] - if (!ispath(prefs["template"]["value"])) - templtype = text2path(prefs["template"]["value"]) // new text2path ... doesn't compile in 511 + var/list/prefs = settings["mainsettings"] - if (ertemplate.type != templtype) - ertemplate = new templtype + var/templtype = prefs["template"]["value"] + if (!ispath(prefs["template"]["value"])) + templtype = text2path(prefs["template"]["value"]) // new text2path ... doesn't compile in 511 - ertemplate.teamsize = prefs["teamsize"]["value"] - ertemplate.mission = prefs["mission"]["value"] - ertemplate.polldesc = prefs["polldesc"]["value"] - ertemplate.enforce_human = prefs["enforce_human"]["value"] == "Yes" // these next 6 are effectively toggles - ertemplate.opendoors = prefs["open_armory"]["value"] == "Yes" - ertemplate.leader_experience = prefs["leader_experience"]["value"] == "Yes" - ertemplate.random_names = prefs["random_names"]["value"] == "Yes" - ertemplate.spawn_admin = prefs["spawn_admin"]["value"] == "Yes" - ertemplate.use_custom_shuttle = prefs["use_custom_shuttle"]["value"] == "Yes" - ertemplate.mob_type = prefs["mob_type"]["value"] + if (ertemplate.type != templtype) + ertemplate = new templtype - var/list/spawnpoints = GLOB.emergencyresponseteamspawn - var/index = 0 + ertemplate.teamsize = prefs["teamsize"]["value"] + ertemplate.mission = prefs["mission"]["value"] + ertemplate.polldesc = prefs["polldesc"]["value"] + ertemplate.enforce_human = prefs["enforce_human"]["value"] == "Yes" // these next 6 are effectively toggles + ertemplate.opendoors = prefs["open_armory"]["value"] == "Yes" + ertemplate.leader_experience = prefs["leader_experience"]["value"] == "Yes" + ertemplate.random_names = prefs["random_names"]["value"] == "Yes" + ertemplate.spawn_admin = prefs["spawn_admin"]["value"] == "Yes" + ertemplate.use_custom_shuttle = prefs["use_custom_shuttle"]["value"] == "Yes" + ertemplate.mob_type = prefs["mob_type"]["value"] - var/list/mob/dead/observer/candidates = SSpolling.poll_ghost_candidates("Do you wish to be considered for [span_notice(ertemplate.polldesc)]?", check_jobban = "deathsquad", alert_pic = /obj/item/card/id/advanced/centcom/ert, role_name_text = "emergency response team") - var/teamSpawned = FALSE + var/list/spawn_points = GLOB.emergencyresponseteamspawn - // This list will take priority over spawnpoints if not empty - var/list/spawn_turfs = list() + var/list/mob/dead/observer/candidates = SSpolling.poll_ghost_candidates("Do you wish to be considered for [span_notice(ertemplate.polldesc)]?", check_jobban = "deathsquad", alert_pic = /obj/item/card/id/advanced/centcom/ert, role_name_text = "emergency response team") + var/team_spawned = 0 - // Takes precedence over spawnpoints[1] if not null - var/turf/brief_spawn + // This list will take priority over spawn_points if not empty + var/list/spawn_turfs = list() - if(!length(candidates)) - return FALSE + // Takes precedence over spawn_points[1] if not null + var/turf/brief_spawn - if(ertemplate.use_custom_shuttle && ertemplate.ert_template) - to_chat(usr, span_boldnotice("Attempting to spawn ERT custom shuttle, this may take a few seconds...")) - var/datum/map_template/shuttle/ship = new ertemplate.ert_template - var/x = rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE - ship.width) - var/y = rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE - ship.height) - var/z = SSmapping.empty_space.z_value - var/turf/located_turf = locate(x, y, z) - if(!located_turf) - CRASH("ERT shuttle found no place to load in") + if(!length(candidates)) + return FALSE - if(!ship.load(located_turf)) - CRASH("Loading ERT shuttle failed!") + if(ertemplate.use_custom_shuttle && ertemplate.ert_template) + to_chat(usr, span_boldnotice("Attempting to spawn ERT custom shuttle, this may take a few seconds...")) + var/datum/map_template/shuttle/ship = new ertemplate.ert_template + var/x = rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE - ship.width) + var/y = rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE - ship.height) + var/z = SSmapping.empty_space.z_value + var/turf/located_turf = locate(x, y, z) + if(!located_turf) + CRASH("ERT shuttle found no place to load in") - var/list/shuttle_turfs = ship.get_affected_turfs(located_turf) + if(!ship.load(located_turf)) + CRASH("Loading ERT shuttle failed!") - for(var/turf/affected_turf as anything in shuttle_turfs) - for(var/obj/effect/landmark/ert_shuttle_spawn/spawner in affected_turf) - spawn_turfs += get_turf(spawner) + var/list/shuttle_turfs = ship.get_affected_turfs(located_turf) - if(!brief_spawn) - brief_spawn = get_turf(locate(/obj/effect/landmark/ert_shuttle_brief_spawn) in affected_turf) + for(var/turf/affected_turf as anything in shuttle_turfs) + for(var/obj/effect/landmark/ert_shuttle_spawn/spawner in affected_turf) + spawn_turfs += get_turf(spawner) - if(!length(spawn_turfs)) - stack_trace("ERT shuttle loaded but found no spawnpoints, placing the ERT at wherever inside the shuttle instead.") + if(!brief_spawn) + brief_spawn = get_turf(locate(/obj/effect/landmark/ert_shuttle_brief_spawn) in affected_turf) - for(var/turf/open/floor/open_turf in shuttle_turfs) - if(!is_safe_turf(open_turf)) - continue - spawn_turfs += open_turf + if(!length(spawn_turfs)) + stack_trace("ERT shuttle loaded but found no spawn points, placing the ERT at wherever inside the shuttle instead.") + + for(var/turf/open/floor/open_turf in shuttle_turfs) + if(!is_safe_turf(open_turf)) + continue + spawn_turfs += open_turf - if(ertemplate.spawn_admin) - if(isobserver(usr)) - var/mob/living/carbon/human/admin_officer = new (brief_spawn || spawnpoints[1]) - var/chosen_outfit = usr.client?.prefs?.read_preference(/datum/preference/choiced/brief_outfit) - usr.client.prefs.safe_transfer_prefs_to(admin_officer, is_antag = TRUE) - admin_officer.equipOutfit(chosen_outfit) - admin_officer.PossessByPlayer(usr.key) + if(ertemplate.spawn_admin) + if(isobserver(usr)) + var/mob/living/carbon/human/admin_officer = new (brief_spawn || spawn_points[1]) + var/chosen_outfit = usr.client?.prefs?.read_preference(/datum/preference/choiced/brief_outfit) + usr.client.prefs.safe_transfer_prefs_to(admin_officer, is_antag = TRUE) + admin_officer.equipOutfit(chosen_outfit) + admin_officer.PossessByPlayer(usr.key) - else - to_chat(usr, span_warning("Could not spawn you in as briefing officer as you are not a ghost!")) - - //Pick the (un)lucky players - var/numagents = min(ertemplate.teamsize, length(candidates)) - - //Create team - var/datum/team/ert/ert_team = new ertemplate.team() - if(ertemplate.rename_team) - ert_team.name = ertemplate.rename_team - - //Assign team objective - var/datum/objective/missionobj = new () - missionobj.team = ert_team - missionobj.explanation_text = ertemplate.mission - missionobj.completed = TRUE - ert_team.objectives += missionobj - ert_team.mission = missionobj - - var/mob/dead/observer/earmarked_leader - var/leader_spawned = FALSE // just in case the earmarked leader disconnects or becomes unavailable, we can try giving leader to the last guy to get chosen - - if(ertemplate.leader_experience) - var/list/candidate_living_exps = list() - for(var/i in candidates) - var/mob/dead/observer/potential_leader = i - candidate_living_exps[potential_leader] = potential_leader.client?.get_exp_living(TRUE) - - candidate_living_exps = sort_list(candidate_living_exps, cmp=/proc/cmp_numeric_dsc) - if(candidate_living_exps.len > ERT_EXPERIENCED_LEADER_CHOOSE_TOP) - candidate_living_exps.Cut(ERT_EXPERIENCED_LEADER_CHOOSE_TOP+1) // pick from the top ERT_EXPERIENCED_LEADER_CHOOSE_TOP contenders in playtime - earmarked_leader = pick(candidate_living_exps) else - earmarked_leader = pick(candidates) + to_chat(usr, span_warning("Could not spawn you in as briefing officer as you are not a ghost!")) - while(numagents && candidates.len) - var/turf/spawnloc - if(length(spawn_turfs)) - spawnloc = pick(spawn_turfs) - else - spawnloc = spawnpoints[index+1] - //loop through spawnpoints one at a time - index = (index + 1) % spawnpoints.len + //Pick the (un)lucky players + var/numagents = min(ertemplate.teamsize, length(candidates)) - var/mob/dead/observer/chosen_candidate = earmarked_leader || pick(candidates) // this way we make sure that our leader gets chosen - candidates -= chosen_candidate - if(!chosen_candidate?.key) - continue + //Create team + var/datum/team/ert/ert_team = new ertemplate.team() + if(ertemplate.rename_team) + ert_team.name = ertemplate.rename_team - //Spawn the body - var/mob/living/carbon/human/ert_operative - if(ertemplate.mob_type) - ert_operative = new ertemplate.mob_type(spawnloc) - else - ert_operative = new /mob/living/carbon/human(spawnloc) - chosen_candidate.client.prefs.safe_transfer_prefs_to(ert_operative, is_antag = TRUE) - ert_operative.PossessByPlayer(chosen_candidate.key) + //Assign team objective + var/datum/objective/missionobj = new () + missionobj.team = ert_team + missionobj.explanation_text = ertemplate.mission + missionobj.completed = TRUE + ert_team.objectives += missionobj + ert_team.mission = missionobj - if(ertemplate.enforce_human || !(ert_operative.dna.species.changesource_flags & ERT_SPAWN)) - ert_operative.set_species(/datum/species/human) + var/mob/dead/observer/earmarked_leader + var/leader_spawned = FALSE // just in case the earmarked leader disconnects or becomes unavailable, we can try giving leader to the last guy to get chosen - //Give antag datum - var/datum/antagonist/ert/ert_antag + if(ertemplate.leader_experience) + var/list/candidate_living_exps = list() + for(var/i in candidates) + var/mob/dead/observer/potential_leader = i + candidate_living_exps[potential_leader] = potential_leader.client?.get_exp_living(TRUE) - if((chosen_candidate == earmarked_leader) || (numagents == 1 && !leader_spawned)) - ert_antag = new ertemplate.leader_role () - earmarked_leader = null - leader_spawned = TRUE - else - ert_antag = ertemplate.roles[WRAP(numagents,1,length(ertemplate.roles) + 1)] - ert_antag = new ert_antag () - ert_antag.random_names = ertemplate.random_names + candidate_living_exps = sort_list(candidate_living_exps, cmp=/proc/cmp_numeric_dsc) + if(candidate_living_exps.len > ERT_EXPERIENCED_LEADER_CHOOSE_TOP) + candidate_living_exps.Cut(ERT_EXPERIENCED_LEADER_CHOOSE_TOP+1) // pick from the top ERT_EXPERIENCED_LEADER_CHOOSE_TOP contenders in playtime + earmarked_leader = pick(candidate_living_exps) + else + earmarked_leader = pick(candidates) - ert_operative.mind.add_antag_datum(ert_antag,ert_team) - ert_operative.mind.set_assigned_role(SSjob.get_job_type(ert_antag.ert_job_path)) + var/spawn_index = 0 + while(numagents && candidates.len) + var/turf/spawnloc + if(length(spawn_turfs)) + spawnloc = pick(spawn_turfs) + else + spawnloc = spawn_points[spawn_index+1] + spawn_index = WRAP_UP(spawn_index, spawn_points.len) - //Logging and cleanup - ert_operative.log_message("has been selected as \a [ert_antag.name].", LOG_GAME) - numagents-- - teamSpawned++ + var/mob/dead/observer/chosen_candidate = earmarked_leader || pick(candidates) // this way we make sure that our leader gets chosen + candidates -= chosen_candidate + if(!chosen_candidate?.key) + continue - if (teamSpawned) - message_admins("[ertemplate.polldesc] has spawned with the mission: [ertemplate.mission]") + //Spawn the body + var/mob/living/carbon/human/ert_operative + if(ertemplate.mob_type) + ert_operative = new ertemplate.mob_type(spawnloc) + else + ert_operative = new /mob/living/carbon/human(spawnloc) + chosen_candidate.client.prefs.safe_transfer_prefs_to(ert_operative, is_antag = TRUE) + ert_operative.PossessByPlayer(chosen_candidate.key) - //Open the Armory doors - if(ertemplate.opendoors) - for(var/obj/machinery/door/poddoor/ert/door as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door/poddoor/ert)) - door.open() - CHECK_TICK - return TRUE + if(ertemplate.enforce_human || !(ert_operative.dna.species.changesource_flags & ERT_SPAWN)) + ert_operative.set_species(/datum/species/human) - return + //Give antag datum + var/datum/antagonist/ert/ert_antag + + if((chosen_candidate == earmarked_leader) || (numagents == 1 && !leader_spawned)) + ert_antag = new ertemplate.leader_role () + earmarked_leader = null + leader_spawned = TRUE + else + ert_antag = ertemplate.roles[WRAP(numagents,1,length(ertemplate.roles) + 1)] + ert_antag = new ert_antag () + ert_antag.random_names = ertemplate.random_names + + ert_operative.mind.add_antag_datum(ert_antag,ert_team) + ert_operative.mind.set_assigned_role(SSjob.get_job_type(ert_antag.ert_job_path)) + + //Logging and cleanup + ert_operative.log_message("has been selected as \a [ert_antag.name].", LOG_GAME) + numagents-- + team_spawned++ + + if (team_spawned != 0) + message_admins("[ertemplate.polldesc] has spawned with the mission: [ertemplate.mission]") + + //Open the Armory doors + if(ertemplate.opendoors) + for(var/obj/machinery/door/poddoor/ert/door as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door/poddoor/ert)) + door.open() + CHECK_TICK + return TRUE ADMIN_VERB(summon_ert, R_FUN, "Summon ERT", "Summons an emergency response team.", ADMIN_CATEGORY_FUN) message_admins("[key_name_admin(user)] is creating a CentCom response team...") - if(user.holder?.makeEmergencyresponseteam()) + if(user.holder?.make_emergency_response_team()) message_admins("[key_name_admin(user)] created a CentCom response team.") log_admin("[key_name(user)] created a CentCom response team.") else diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index 446b5d72219..9ec5ebdbcda 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -47,7 +47,6 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w return if((action != "admin_log" || action != "show_admins") && !check_rights(R_ADMIN)) return - var/datum/round_event/E switch(action) //Generic Buttons anyone can use. if("admin_log") @@ -419,57 +418,59 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w ) message_admins("[key_name(holder)] is creating a custom portal storm...") - var/list/prefreturn = presentpreflikepicker(holder,"Customize Portal Storm", "Customize Portal Storm", Button1="Ok", width = 600, StealFocus = 1,Timeout = 0, settings=settings) + var/list/pref_return = present_pref_like_picker(holder, "Customize Portal Storm", "Customize Portal Storm", width = 600, timeout = 0, settings = settings) - if (prefreturn["button"] == 1) - var/list/prefs = settings["mainsettings"] + if (pref_return["button"] != 1) + return - if (prefs["amount"]["value"] < 1 || prefs["portalnum"]["value"] < 1) - to_chat(holder, span_warning("Number of portals and mobs to spawn must be at least 1."), confidential = TRUE) - return + var/list/prefs = settings["mainsettings"] - var/mob/pathToSpawn = prefs["typepath"]["value"] - if (!ispath(pathToSpawn)) - pathToSpawn = text2path(pathToSpawn) + if (prefs["amount"]["value"] < 1 || prefs["portalnum"]["value"] < 1) + to_chat(holder, span_warning("Number of portals and mobs to spawn must be at least 1."), confidential = TRUE) + return - if (!ispath(pathToSpawn)) - to_chat(holder, span_notice("Invalid path [pathToSpawn]."), confidential = TRUE) - return + var/mob/path_to_spawn = prefs["typepath"]["value"] + if (!ispath(path_to_spawn)) + path_to_spawn = text2path(path_to_spawn) - var/list/candidates = list() + if (!ispath(path_to_spawn)) + to_chat(holder, span_notice("Invalid path [path_to_spawn]."), confidential = TRUE) + return - if (prefs["offerghosts"]["value"] == "Yes") - candidates = SSpolling.poll_ghost_candidates(replacetext(prefs["ghostpoll"]["value"], "%TYPE%", initial(pathToSpawn.name)), check_jobban = ROLE_TRAITOR, alert_pic = pathToSpawn, role_name_text = "portal storm") + var/list/candidates = list() - if (prefs["playersonly"]["value"] == "Yes" && length(candidates) < prefs["minplayers"]["value"]) + if (prefs["offerghosts"]["value"] == "Yes") + candidates = SSpolling.poll_ghost_candidates(replacetext(prefs["ghostpoll"]["value"], "%TYPE%", initial(path_to_spawn.name)), check_jobban = ROLE_TRAITOR, alert_pic = path_to_spawn, role_name_text = "portal storm") + if (length(candidates) < prefs["minplayers"]["value"]) message_admins("Not enough players signed up to create a portal storm, the minimum was [prefs["minplayers"]["value"]] and the number of signups [length(candidates)]") return - if (prefs["announce_players"]["value"] == "Yes") - portalAnnounce(prefs["announcement"]["value"], (prefs["playlightning"]["value"] == "Yes" ? TRUE : FALSE)) + if (prefs["announce_players"]["value"] == "Yes") + portal_announce(prefs["announcement"]["value"], (prefs["playlightning"]["value"] == "Yes" ? TRUE : FALSE)) - var/list/storm_appearances = list() - for(var/offset in 0 to SSmapping.max_plane_offset) - var/mutable_appearance/storm = mutable_appearance('icons/obj/machines/engine/energy_ball.dmi', "energy_ball_fast", FLY_LAYER) - SET_PLANE_W_SCALAR(storm, ABOVE_GAME_PLANE, offset) - storm.color = prefs["color"]["value"] - storm_appearances += storm + var/list/storm_appearances = list() + for(var/offset in 0 to SSmapping.max_plane_offset) + var/mutable_appearance/storm = mutable_appearance('icons/obj/machines/engine/energy_ball.dmi', "energy_ball_fast", FLY_LAYER) + SET_PLANE_W_SCALAR(storm, ABOVE_GAME_PLANE, offset) + storm.color = prefs["color"]["value"] + storm_appearances += storm - message_admins("[key_name_admin(holder)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [pathToSpawn]") - log_admin("[key_name(holder)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [pathToSpawn]") + message_admins("[key_name_admin(holder)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [path_to_spawn]") + log_admin("[key_name(holder)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [path_to_spawn]") - var/outfit = prefs["humanoutfit"]["value"] - if (!ispath(outfit)) - outfit = text2path(outfit) + var/outfit = prefs["humanoutfit"]["value"] + if (!ispath(outfit)) + outfit = text2path(outfit) + + for (var/i in 1 to prefs["portalnum"]["value"]) + if (length(candidates)) // if we're spawning players, gotta be a little tricky and also not spawn players on top of NPCs + var/ghostcandidates = list() + for (var/j in 1 to min(prefs["amount"]["value"], length(candidates))) + ghostcandidates += pick_n_take(candidates) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_portal_spawn), get_random_station_turf(), path_to_spawn, length(ghostcandidates), storm_appearances, ghostcandidates, outfit), i * prefs["delay"]["value"]) + else if (prefs["playersonly"]["value"] != "Yes") + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_portal_spawn), get_random_station_turf(), path_to_spawn, prefs["amount"]["value"], storm_appearances, null, outfit), i * prefs["delay"]["value"]) - for (var/i in 1 to prefs["portalnum"]["value"]) - if (length(candidates)) // if we're spawning players, gotta be a little tricky and also not spawn players on top of NPCs - var/ghostcandidates = list() - for (var/j in 1 to min(prefs["amount"]["value"], length(candidates))) - ghostcandidates += pick_n_take(candidates) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(doPortalSpawn), get_random_station_turf(), pathToSpawn, length(ghostcandidates), storm_appearances, ghostcandidates, outfit), i*prefs["delay"]["value"]) - else if (prefs["playersonly"]["value"] != "Yes") - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(doPortalSpawn), get_random_station_turf(), pathToSpawn, prefs["amount"]["value"], storm_appearances, null, outfit), i*prefs["delay"]["value"]) if("changebombcap") if(!is_funmin) return @@ -680,24 +681,12 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w message_admins("[key_name_admin(holder)] healed everyone.") log_admin("[key_name(holder)] healed everyone.") - if(E) - E.processing = FALSE - if(E.announce_when>0) - switch(tgui_alert(holder, "Would you like to alert the crew?", "Alert", list("Yes", "No", "Cancel"))) - if("Yes") - E.announce_chance = 100 - if("Cancel") - E.kill() - return - if("No") - E.announce_chance = 0 - E.processing = TRUE if(holder) log_admin("[key_name(holder)] used secret: [action].") #undef THUNDERDOME_TEMPLATE_FILE #undef HIGHLANDER_DELAY_TEXT -/proc/portalAnnounce(announcement, playlightning) +/proc/portal_announce(announcement, playlightning) set waitfor = FALSE if (playlightning) sound_to_playing_players('sound/effects/magic/lightning_chargeup.ogg') @@ -709,7 +698,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w /// Spawns a portal storm that spawns in sentient/non sentient mobs /// portal_appearance is a list in the form (turf's plane offset + 1) -> appearance to use -/proc/doPortalSpawn(turf/loc, mobtype, numtospawn, list/portal_appearance, players, humanoutfit) +/proc/do_portal_spawn(turf/loc, mobtype, numtospawn, list/portal_appearance, players, humanoutfit) for (var/i in 1 to numtospawn) var/mob/spawnedMob = new mobtype(loc) if (length(players)) diff --git a/code/modules/admin/verbs/spawnobjasmob.dm b/code/modules/admin/verbs/spawnobjasmob.dm index c8d9ba3719d..56fe8fbf84f 100644 --- a/code/modules/admin/verbs/spawnobjasmob.dm +++ b/code/modules/admin/verbs/spawnobjasmob.dm @@ -64,44 +64,46 @@ ADMIN_VERB(spawn_obj_as_mob, R_SPAWN, "Spawn Object-Mob", "Spawn an object as if ), )) - var/list/prefreturn = presentpreflikepicker(user.mob,"Customize mob", "Customize mob", Button1="Ok", width = 450, StealFocus = 1,Timeout = 0, settings=settings) - if (prefreturn["button"] == 1) - settings = prefreturn["settings"] - var/mainsettings = settings["mainsettings"] - chosen_obj = text2path(mainsettings["objtype"]["value"]) + var/list/pref_return = present_pref_like_picker(user.mob, "Customize mob", "Customize mob", width = 450, timeout = 0, settings = settings) + if (pref_return["button"] != 1) + return - basemob = text2path(mainsettings["mobtype"]["value"]) - if (!ispath(basemob, /mob/living/basic/mimic/copy) || !ispath(chosen_obj, /obj)) - to_chat(user.mob, "Mob or object path invalid", confidential = TRUE) + settings = pref_return["settings"] + var/mainsettings = settings["mainsettings"] + chosen_obj = text2path(mainsettings["objtype"]["value"]) - basemob = new basemob(get_turf(user.mob), new chosen_obj(get_turf(user.mob)), user.mob, mainsettings["dropitem"]["value"] == "Yes" ? FALSE : TRUE, (mainsettings["googlyeyes"]["value"] == "Yes" ? FALSE : TRUE)) + basemob = text2path(mainsettings["mobtype"]["value"]) + if (!ispath(basemob, /mob/living/basic/mimic/copy) || !ispath(chosen_obj, /obj)) + to_chat(user.mob, "Mob or object path invalid", confidential = TRUE) - if (mainsettings["disableai"]["value"] == "Yes") - qdel(basemob.ai_controller) - basemob.ai_controller = null + basemob = new basemob(get_turf(user.mob), new chosen_obj(get_turf(user.mob)), user.mob, mainsettings["dropitem"]["value"] == "Yes" ? FALSE : TRUE, (mainsettings["googlyeyes"]["value"] == "Yes" ? FALSE : TRUE)) - if (mainsettings["idledamage"]["value"] == "No") - basemob.idledamage = FALSE + if (mainsettings["disableai"]["value"] == "Yes") + qdel(basemob.ai_controller) + basemob.ai_controller = null - if (mainsettings["access"]) - var/newaccess = text2path(mainsettings["access"]["value"]) - if (ispath(newaccess)) - var/obj/item/card/id/id = new newaccess //cant do initial on lists - basemob.AddComponent(/datum/component/simple_access, id.access) - qdel(id) + if (mainsettings["idledamage"]["value"] == "No") + basemob.idledamage = FALSE - if (mainsettings["maxhealth"]["value"]) - if (!isnum(mainsettings["maxhealth"]["value"])) - mainsettings["maxhealth"]["value"] = text2num(mainsettings["maxhealth"]["value"]) - if (mainsettings["maxhealth"]["value"] > 0) - basemob.maxHealth = basemob.maxHealth = mainsettings["maxhealth"]["value"] + if (mainsettings["access"]) + var/newaccess = text2path(mainsettings["access"]["value"]) + if (ispath(newaccess)) + var/obj/item/card/id/id = new newaccess //cant do initial on lists + basemob.AddComponent(/datum/component/simple_access, id.access) + qdel(id) - if (mainsettings["name"]["value"]) - basemob.name = basemob.real_name = html_decode(mainsettings["name"]["value"]) + if (mainsettings["maxhealth"]["value"]) + if (!isnum(mainsettings["maxhealth"]["value"])) + mainsettings["maxhealth"]["value"] = text2num(mainsettings["maxhealth"]["value"]) + if (mainsettings["maxhealth"]["value"] > 0) + basemob.maxHealth = basemob.maxHealth = mainsettings["maxhealth"]["value"] - if (mainsettings["ckey"]["value"] != "none") - basemob.ckey = mainsettings["ckey"]["value"] + if (mainsettings["name"]["value"]) + basemob.name = basemob.real_name = html_decode(mainsettings["name"]["value"]) + + if (mainsettings["ckey"]["value"] != "none") + basemob.ckey = mainsettings["ckey"]["value"] - log_admin("[key_name(user.mob)] spawned a sentient object-mob [basemob] from [chosen_obj] at [AREACOORD(user.mob)]") - BLACKBOX_LOG_ADMIN_VERB("Spawn object-mob") + log_admin("[key_name(user.mob)] spawned a sentient object-mob [basemob] from [chosen_obj] at [AREACOORD(user.mob)]") + BLACKBOX_LOG_ADMIN_VERB("Spawn object-mob") diff --git a/code/modules/discord/accountlink.dm b/code/modules/discord/accountlink.dm index e3227ae9004..3ef8ff527e4 100644 --- a/code/modules/discord/accountlink.dm +++ b/code/modules/discord/accountlink.dm @@ -32,7 +32,7 @@ message = "Your one time token is: [one_time_token]. Assuming you have the required living minutes in game, you can now verify yourself on Discord by using the command: [prefix]verify [one_time_token]" //Now give them a browse window so they can't miss whatever we told them - var/datum/browser/window = new/datum/browser(usr, "discordverification", "Discord Verification") + var/datum/browser/window = new /datum/browser(usr, "discordverification", "Discord Verification") window.set_content("
[message]
") window.open() diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index 8080f3005dd..fa0d1dcc981 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -27,7 +27,7 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) /datum/error_viewer/proc/browse_to(client/user, html) var/datum/browser/browser = new(user.mob, "error_viewer", null, 600, 400) browser.set_content(html) - browser.add_head_content({" + browser.set_head_content({"