mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-11 10:11:09 +00:00
Unfucks /datum/browse code (#89994)
What it was doing was by and large fine, HOW it was doing it SUCKED I've cleaned it up and the nearby code some, notable hits include: - random if check in secrets ui that was totally unused - proc called add that actually set - lists not defined as such - stupid var names - proc args which did nothing - code which did nothing - oververbose code - proc/var names with no spacing at all Note: This might have changed behavior accidentally, I've done my best to test but we'll need to look out for issue reports in coming days. I was working on bitflag code and saw red, now it's 2 hours later. 🆑 code: Brought browser code up to standard with the rest of the codebase admin: Hey lads, I cleaned up how non TGUI windows work on the backend, please let me know if anything is broken! PING ME MOTHERFUCKER /🆑
This commit is contained in:
committed by
Shadow-Quill
parent
ba3742ac0a
commit
844550f7c2
@@ -1,44 +1,48 @@
|
|||||||
/datum/browser
|
/datum/browser
|
||||||
var/mob/user
|
var/mob/user
|
||||||
var/title
|
var/title = ""
|
||||||
var/window_id // window_id is used as the window name for browse and onclose
|
/// window_id is used as the window name for browse and onclose
|
||||||
|
var/window_id
|
||||||
var/width = 0
|
var/width = 0
|
||||||
var/height = 0
|
var/height = 0
|
||||||
var/datum/weakref/ref = null
|
var/datum/weakref/source_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
|
/// window option is set using window_id
|
||||||
var/stylesheets[0]
|
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;"
|
||||||
var/scripts[0]
|
var/list/stylesheets = list()
|
||||||
|
var/list/scripts = list()
|
||||||
var/head_elements
|
var/head_elements
|
||||||
var/body_elements
|
var/body_elements
|
||||||
var/head_content = ""
|
var/head_content = ""
|
||||||
var/content = ""
|
var/content = ""
|
||||||
|
|
||||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null)
|
/datum/browser/New(mob/user, window_id, title = "", width = 0, height = 0, atom/source = null)
|
||||||
if(IS_CLIENT_OR_MOCK(nuser))
|
if(IS_CLIENT_OR_MOCK(user))
|
||||||
var/client/client_user = nuser
|
var/client/client_user = user
|
||||||
user = client_user.mob
|
user = client_user.mob
|
||||||
else
|
src.user = user
|
||||||
user = nuser
|
|
||||||
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(user_deleted))
|
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(user_deleted))
|
||||||
window_id = nwindow_id
|
src.window_id = window_id
|
||||||
if (ntitle)
|
if (title)
|
||||||
title = format_text(ntitle)
|
src.title = format_text(title)
|
||||||
if (nwidth)
|
if (width)
|
||||||
width = nwidth
|
src.width = width
|
||||||
if (nheight)
|
if (height)
|
||||||
height = nheight
|
src.height = height
|
||||||
if (nref)
|
if (source)
|
||||||
ref = WEAKREF(nref)
|
src.source_ref = WEAKREF(source)
|
||||||
|
|
||||||
/datum/browser/proc/user_deleted(datum/source)
|
/datum/browser/proc/user_deleted(datum/source)
|
||||||
SIGNAL_HANDLER
|
SIGNAL_HANDLER
|
||||||
user = null
|
user = null
|
||||||
|
|
||||||
/datum/browser/proc/add_head_content(nhead_content)
|
/datum/browser/proc/add_head_content(head_content)
|
||||||
head_content = nhead_content
|
src.head_content += head_content
|
||||||
|
|
||||||
/datum/browser/proc/set_window_options(nwindow_options)
|
/datum/browser/proc/set_head_content(head_content)
|
||||||
window_options = nwindow_options
|
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)
|
/datum/browser/proc/add_stylesheet(name, file)
|
||||||
if (istype(name, /datum/asset/spritesheet))
|
if (istype(name, /datum/asset/spritesheet))
|
||||||
@@ -59,21 +63,21 @@
|
|||||||
scripts["[ckey(name)].js"] = file
|
scripts["[ckey(name)].js"] = file
|
||||||
SSassets.transport.register_asset("[ckey(name)].js", file)
|
SSassets.transport.register_asset("[ckey(name)].js", file)
|
||||||
|
|
||||||
/datum/browser/proc/set_content(ncontent)
|
/datum/browser/proc/set_content(content)
|
||||||
content = ncontent
|
src.content = content
|
||||||
|
|
||||||
/datum/browser/proc/add_content(ncontent)
|
/datum/browser/proc/add_content(content)
|
||||||
content += ncontent
|
src.content += content
|
||||||
|
|
||||||
/datum/browser/proc/get_header()
|
/datum/browser/proc/get_header()
|
||||||
var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
|
var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
|
||||||
var/file
|
var/list/new_head_content = list()
|
||||||
head_content += "<link rel='stylesheet' type='text/css' href='[common_asset.get_url_mappings()["common.css"]]'>"
|
new_head_content += "<link rel='stylesheet' type='text/css' href='[common_asset.get_url_mappings()["common.css"]]'>"
|
||||||
for (file in stylesheets)
|
for (var/file in stylesheets)
|
||||||
head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url(file)]'>"
|
new_head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url(file)]'>"
|
||||||
|
|
||||||
if(user.client?.window_scaling && user.client?.window_scaling != 1 && !user.client?.prefs.read_preference(/datum/preference/toggle/ui_scale) && width && height)
|
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 += {"
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
zoom: [100 / user.client?.window_scaling]%;
|
zoom: [100 / user.client?.window_scaling]%;
|
||||||
@@ -81,9 +85,10 @@
|
|||||||
</style>
|
</style>
|
||||||
"}
|
"}
|
||||||
|
|
||||||
for (file in scripts)
|
for (var/file in scripts)
|
||||||
head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
|
new_head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
|
||||||
|
|
||||||
|
head_content += new_head_content.Join()
|
||||||
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -96,6 +101,7 @@
|
|||||||
[title ? "<div class='uiTitleWrapper'><div class='uiTitle'><tt>[title]</tt></div></div>" : ""]
|
[title ? "<div class='uiTitleWrapper'><div class='uiTitle'><tt>[title]</tt></div></div>" : ""]
|
||||||
<div class='uiContent'>
|
<div class='uiContent'>
|
||||||
"}
|
"}
|
||||||
|
|
||||||
//" This is here because else the rest of the file looks like a string in notepad++.
|
//" This is here because else the rest of the file looks like a string in notepad++.
|
||||||
/datum/browser/proc/get_footer()
|
/datum/browser/proc/get_footer()
|
||||||
return {"
|
return {"
|
||||||
@@ -106,16 +112,17 @@
|
|||||||
|
|
||||||
/datum/browser/proc/get_content()
|
/datum/browser/proc/get_content()
|
||||||
return {"
|
return {"
|
||||||
[get_header()]
|
[get_header()]
|
||||||
[content]
|
[content]
|
||||||
[get_footer()]
|
[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
|
if(isnull(window_id)) //null check because this can potentially nuke goonchat
|
||||||
WARNING("Browser [title] tried to open with a null ID")
|
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!"))
|
to_chat(user, span_userdanger("The [title] browser you tried to open failed a sanity check! Please report this on GitHub!"))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/window_size = ""
|
var/window_size = ""
|
||||||
if(width && height)
|
if(width && height)
|
||||||
if(user.client?.prefs?.read_preference(/datum/preference/toggle/ui_scale))
|
if(user.client?.prefs?.read_preference(/datum/preference/toggle/ui_scale))
|
||||||
@@ -123,27 +130,28 @@
|
|||||||
window_size = "size=[width * scaling]x[height * scaling];"
|
window_size = "size=[width * scaling]x[height * scaling];"
|
||||||
else
|
else
|
||||||
window_size = "size=[width]x[height];"
|
window_size = "size=[width]x[height];"
|
||||||
|
|
||||||
var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
|
var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
|
||||||
common_asset.send(user)
|
common_asset.send(user)
|
||||||
if (stylesheets.len)
|
if (length(stylesheets))
|
||||||
SSassets.transport.send_assets(user, stylesheets)
|
SSassets.transport.send_assets(user, stylesheets)
|
||||||
if (scripts.len)
|
if (length(scripts))
|
||||||
SSassets.transport.send_assets(user, scripts)
|
SSassets.transport.send_assets(user, scripts)
|
||||||
DIRECT_OUTPUT(user, browse(get_content(), "window=[window_id];[window_size][window_options]"))
|
DIRECT_OUTPUT(user, browse(get_content(), "window=[window_id];[window_size][window_options]"))
|
||||||
if (use_onclose)
|
if (use_on_close)
|
||||||
setup_onclose()
|
setup_onclose()
|
||||||
|
|
||||||
/datum/browser/proc/setup_onclose()
|
/datum/browser/proc/setup_onclose()
|
||||||
set waitfor = 0 //winexists sleeps, so we don't need to.
|
set waitfor = 0 //winexists sleeps, so we don't need to.
|
||||||
for (var/i in 1 to 10)
|
for (var/i in 1 to 10)
|
||||||
if (user?.client && winexists(user, window_id))
|
if (!user?.client || !winexists(user, window_id))
|
||||||
var/atom/send_ref
|
continue
|
||||||
if(ref)
|
var/atom/send_ref
|
||||||
send_ref = ref.resolve()
|
if(source_ref)
|
||||||
if(!send_ref)
|
send_ref = source_ref.resolve()
|
||||||
ref = null
|
if(!send_ref)
|
||||||
onclose(user, window_id, send_ref)
|
source_ref = null
|
||||||
break
|
onclose(user, window_id, send_ref)
|
||||||
|
|
||||||
/datum/browser/proc/close()
|
/datum/browser/proc/close()
|
||||||
if(!isnull(window_id))//null check because this can potentially nuke goonchat
|
if(!isnull(window_id))//null check because this can potentially nuke goonchat
|
||||||
@@ -151,106 +159,106 @@
|
|||||||
else
|
else
|
||||||
WARNING("Browser [title] tried to close with a null ID")
|
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)
|
/datum/browser/modal/alert/New(user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = 600 SECONDS)
|
||||||
if (!User)
|
if (!user)
|
||||||
return
|
return
|
||||||
|
|
||||||
var/output = {"<center><b>[Message]</b></center><br />
|
var/list/display_list = list()
|
||||||
|
display_list += {"<center><b>[message]</b></center><br />
|
||||||
<div style="text-align:center">
|
<div style="text-align:center">
|
||||||
<a style="font-size:large;float:[( Button2 ? "left" : "right" )]" href='byond://?src=[REF(src)];button=1'>[Button1]</a>"}
|
<a style="font-size:large;float:[( button_2 ? "left" : "right" )]" href='byond://?src=[REF(src)];button=1'>[button_1]</a>"}
|
||||||
|
|
||||||
if (Button2)
|
if (button_2)
|
||||||
output += {"<a style="font-size:large;[( Button3 ? "" : "float:right" )]" href='byond://?src=[REF(src)];button=2'>[Button2]</a>"}
|
display_list += {"<a style="font-size:large;[( button_3 ? "" : "float:right" )]" href='byond://?src=[REF(src)];button=2'>[button_2]</a>"}
|
||||||
|
|
||||||
if (Button3)
|
if (button_3)
|
||||||
output += {"<a style="font-size:large;float:right" href='byond://?src=[REF(src)];button=3'>[Button3]</a>"}
|
display_list += {"<a style="font-size:large;float:right" href='byond://?src=[REF(src)];button=3'>[button_3]</a>"}
|
||||||
|
|
||||||
output += {"</div>"}
|
display_list += {"</div>"}
|
||||||
|
|
||||||
..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout)
|
..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, 350, 150, src, steal_focus, timeout)
|
||||||
set_content(output)
|
set_content(display_list.Join())
|
||||||
|
|
||||||
/datum/browser/modal/alert/Topic(href,href_list)
|
/datum/browser/modal/alert/Topic(href,href_list)
|
||||||
if (href_list["close"] || !user || !user.client)
|
if (href_list["close"] || !user || !user.client)
|
||||||
opentime = 0
|
open_time = 0
|
||||||
return
|
return
|
||||||
if (href_list["button"])
|
if (href_list["button"])
|
||||||
var/button = text2num(href_list["button"])
|
var/button = text2num(href_list["button"])
|
||||||
if (button <= 3 && button >= 1)
|
if (button <= 3 && button >= 1)
|
||||||
selectedbutton = button
|
selected_button = button
|
||||||
opentime = 0
|
open_time = 0
|
||||||
close()
|
close()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **DEPRECATED: USE tgui_alert(...) INSTEAD**
|
* **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:
|
* Arguments:
|
||||||
* * User - The user to show the alert to.
|
* * user - The user to show the alert to.
|
||||||
* * Message - The textual body of the alert.
|
* * message - The textual body of the alert.
|
||||||
* * Title - The title of the alert's window.
|
* * title - The title of the alert's window.
|
||||||
* * Button1 - The first button option.
|
* * button_1 - The first button option.
|
||||||
* * Button2 - The second button option.
|
* * button_2 - The second button option.
|
||||||
* * Button3 - The third button option.
|
* * button_3 - The third button option.
|
||||||
* * StealFocus - Boolean operator controlling if the alert will steal the user's window focus.
|
* * 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.
|
* * 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)
|
/proc/tg_alert(mob/user, message, title, button_1 = "Ok", button_2, button_3, steal_focus = TRUE, timeout = 600 SECONDS)
|
||||||
if (!User)
|
if (!user)
|
||||||
User = usr
|
user = usr
|
||||||
if (!istype(User))
|
if (!ismob(user))
|
||||||
if (istype(User, /client))
|
if (!istype(user, /client))
|
||||||
var/client/client = User
|
|
||||||
User = client.mob
|
|
||||||
else
|
|
||||||
return
|
return
|
||||||
|
var/client/user_client = user
|
||||||
|
user = user_client.mob
|
||||||
|
|
||||||
// Get user's response using a modal
|
// Get user's response using a modal
|
||||||
var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)
|
var/datum/browser/modal/alert/window = new(user, message, title, button_1, button_2, button_3, steal_focus, timeout)
|
||||||
A.open()
|
window.open()
|
||||||
A.wait()
|
window.wait()
|
||||||
switch(A.selectedbutton)
|
switch(window.selected_button)
|
||||||
if (1)
|
if (1)
|
||||||
return Button1
|
return button_1
|
||||||
if (2)
|
if (2)
|
||||||
return Button2
|
return button_2
|
||||||
if (3)
|
if (3)
|
||||||
return Button3
|
return button_3
|
||||||
|
|
||||||
/datum/browser/modal
|
/datum/browser/modal
|
||||||
var/opentime = 0
|
var/open_time = 0
|
||||||
var/timeout
|
var/timeout
|
||||||
var/selectedbutton = 0
|
var/selected_button = 0
|
||||||
var/stealfocus
|
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
|
src.steal_focus = steal_focus
|
||||||
if (!StealFocus)
|
if (!src.steal_focus)
|
||||||
window_options += "focus=false;"
|
window_options += "focus=false;"
|
||||||
timeout = Timeout
|
src.timeout = timeout
|
||||||
|
|
||||||
|
|
||||||
/datum/browser/modal/close()
|
/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
|
set waitfor = FALSE
|
||||||
opentime = world.time
|
open_time = world.time
|
||||||
|
use_on_close = TRUE
|
||||||
|
|
||||||
if (stealfocus)
|
if (steal_focus)
|
||||||
. = ..(use_onclose = 1)
|
. = ..()
|
||||||
else
|
else
|
||||||
var/focusedwindow = winget(user, null, "focus")
|
var/focused_window = winget(user, null, "focus")
|
||||||
. = ..(use_onclose = 1)
|
. = ..()
|
||||||
|
|
||||||
//waits for the window to show up client side before attempting to un-focus it
|
//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
|
//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)
|
for (var/i in 1 to 10)
|
||||||
if (user && winexists(user, window_id))
|
if (user && winexists(user, window_id))
|
||||||
if (focusedwindow)
|
if (focused_window)
|
||||||
winset(user, focusedwindow, "focus=true")
|
winset(user, focused_window, "focus=true")
|
||||||
else
|
else
|
||||||
winset(user, "mapwindow", "focus=true")
|
winset(user, "mapwindow", "focus=true")
|
||||||
break
|
break
|
||||||
@@ -258,239 +266,235 @@
|
|||||||
addtimer(CALLBACK(src, PROC_REF(close)), timeout)
|
addtimer(CALLBACK(src, PROC_REF(close)), timeout)
|
||||||
|
|
||||||
/datum/browser/modal/proc/wait()
|
/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)
|
stoplag(1)
|
||||||
|
|
||||||
/datum/browser/modal/listpicker
|
/datum/browser/modal/list_picker
|
||||||
var/valueslist = list()
|
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)
|
/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)
|
if (!user)
|
||||||
return
|
return
|
||||||
|
|
||||||
var/output = {"<form><input type="hidden" name="src" value="[REF(src)]"><ul class="sparse">"}
|
var/list/display_list = list()
|
||||||
if (inputtype == "checkbox" || inputtype == "radio")
|
display_list += {"<form><input type="hidden" name="src" value="[REF(src)]"><ul class="sparse">"}
|
||||||
for (var/i in values)
|
if (input_type == "checkbox" || input_type == "radio")
|
||||||
var/div_slider = slidecolor
|
for (var/option in values)
|
||||||
if(!i["allowed_edit"])
|
var/div_slider = slide_color
|
||||||
|
if(!option["allowed_edit"])
|
||||||
div_slider = "locked"
|
div_slider = "locked"
|
||||||
output += {"<li>
|
display_list += {"<li>
|
||||||
<label class="switch">
|
<label class="switch">
|
||||||
<input type="[inputtype]" value="1" name="[i["name"]]"[i["checked"] ? " checked" : ""][i["allowed_edit"] ? "" : " onclick='return false' onkeydown='return false'"]>
|
<input type="[input_type]" value="1" name="[option["name"]]"[option["checked"] ? " checked" : ""][option["allowed_edit"] ? "" : " onclick='return false' onkeydown='return false'"]>
|
||||||
<div class="slider [div_slider ? "[div_slider]" : ""]"></div>
|
<div class="slider [div_slider ? "[div_slider]" : ""]"></div>
|
||||||
<span>[i["name"]]</span>
|
<span>[option["name"]]</span>
|
||||||
</label>
|
</label>
|
||||||
</li>"}
|
</li>"}
|
||||||
else
|
else
|
||||||
for (var/i in values)
|
for (var/option in values)
|
||||||
output += {"<li><input id="name="[i["name"]]"" style="width: 50px" type="[type]" name="[i["name"]]" value="[i["value"]]">
|
display_list += {"<li><input id="name="[option["name"]]"" style="width: 50px" type="[type]" name="[option["name"]]" value="[option["value"]]">
|
||||||
<label for="[i["name"]]">[i["name"]]</label></li>"}
|
<label for="[option["name"]]">[option["name"]]</label></li>"}
|
||||||
output += {"</ul><div style="text-align:center">
|
display_list += {"</ul><div style="text-align:center">
|
||||||
<button type="submit" name="button" value="1" style="font-size:large;float:[( Button2 ? "left" : "right" )]">[Button1]</button>"}
|
<button type="submit" name="button" value="1" style="font-size:large;float:[( button_2 ? "left" : "right" )]">[button_1]</button>"}
|
||||||
|
|
||||||
if (Button2)
|
if (button_2)
|
||||||
output += {"<button type="submit" name="button" value="2" style="font-size:large;[( Button3 ? "" : "float:right" )]">[Button2]</button>"}
|
display_list += {"<button type="submit" name="button" value="2" style="font-size:large;[( button_3 ? "" : "float:right" )]">[button_2]</button>"}
|
||||||
|
|
||||||
if (Button3)
|
if (button_3)
|
||||||
output += {"<button type="submit" name="button" value="3" style="font-size:large;float:right">[Button3]</button>"}
|
display_list += {"<button type="submit" name="button" value="3" style="font-size:large;float:right">[button_3]</button>"}
|
||||||
|
|
||||||
output += {"</form></div>"}
|
display_list += {"</form></div>"}
|
||||||
..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout)
|
..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, width, height, src, steal_focus, timeout)
|
||||||
set_content(output)
|
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)
|
if (href_list["close"] || !user || !user.client)
|
||||||
opentime = 0
|
open_time = 0
|
||||||
return
|
return
|
||||||
if (href_list["button"])
|
if (href_list["button"])
|
||||||
var/button = text2num(href_list["button"])
|
var/button = text2num(href_list["button"])
|
||||||
if (button <= 3 && button >= 1)
|
if (button <= 3 && button >= 1)
|
||||||
selectedbutton = button
|
selected_button = button
|
||||||
for (var/item in href_list)
|
values_list = href_list.Copy()
|
||||||
switch(item)
|
values_list -= list("close", "button", "src")
|
||||||
if ("close", "button", "src")
|
open_time = 0
|
||||||
continue
|
|
||||||
else
|
|
||||||
valueslist[item] = href_list[item]
|
|
||||||
opentime = 0
|
|
||||||
close()
|
close()
|
||||||
|
|
||||||
/proc/presentpicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor)
|
/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 (!istype(User))
|
if (!ismob(user))
|
||||||
if (istype(User, /client/))
|
if (!istype(user, /client))
|
||||||
var/client/C = User
|
|
||||||
User = C.mob
|
|
||||||
else
|
|
||||||
return
|
return
|
||||||
var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor)
|
var/client/user_client = user
|
||||||
A.open()
|
user = user_client.mob
|
||||||
A.wait()
|
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)
|
||||||
if (A.selectedbutton)
|
window.open()
|
||||||
return list("button" = A.selectedbutton, "values" = A.valueslist)
|
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)
|
var/list/bitflags = get_valid_bitflags(bitfield)
|
||||||
if (!User || !length(bitflags))
|
if (!user || !length(bitflags))
|
||||||
return
|
return
|
||||||
var/list/picker_list = list()
|
var/list/picker_list = list()
|
||||||
for (var/bit_name in bitflags)
|
for (var/bit_name in bitflags)
|
||||||
var/bit_value = bitflags[bit_name]
|
var/bit_value = bitflags[bit_name]
|
||||||
// TRUE/FALSE cast, sorry :)
|
// Gotta make it TRUE/FALSE sorry brother
|
||||||
var/can_edit = !!(allowed_edit_flags & bit_value)
|
var/can_edit = !!(allowed_edit_field & bit_value)
|
||||||
var/flag_set = !!(current_value & bit_value)
|
var/enabled = !!(current_value & bit_value)
|
||||||
picker_list += list(list("checked" = flag_set, "value" = bit_value, "name" = bit_name, "allowed_edit" = can_edit))
|
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)
|
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))
|
if (!islist(result))
|
||||||
if (result["button"] == 2) // If the user pressed the cancel button
|
return
|
||||||
return
|
if (result["button"] == 2) // If the user pressed the cancel button
|
||||||
. = NONE
|
|
||||||
for (var/flag_name in result["values"])
|
|
||||||
. |= bitflags[flag_name]
|
|
||||||
else
|
|
||||||
return
|
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/settings = list()
|
||||||
var/icon/preview_icon = null
|
var/icon/preview_icon = null
|
||||||
var/datum/callback/preview_update
|
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)
|
/datum/browser/modal/pref_like_picker/New(mob/user, message, title, steal_focus = TRUE, timeout = 600 SECONDS, list/settings, width, height)
|
||||||
if (!User)
|
if (!user)
|
||||||
return
|
return
|
||||||
src.settings = settings
|
src.settings = settings
|
||||||
|
|
||||||
..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout)
|
..(user, ckey("[user]-[message]-[title]-[world.time]-[rand(1,10000)]"), title, width, height, src, steal_focus, timeout)
|
||||||
set_content(ShowChoices(User))
|
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"])
|
if (settings["preview_callback"])
|
||||||
var/datum/callback/callback = settings["preview_callback"]
|
var/datum/callback/callback = settings["preview_callback"]
|
||||||
preview_icon = callback.Invoke(settings)
|
preview_icon = callback.Invoke(settings)
|
||||||
if (preview_icon)
|
if (preview_icon)
|
||||||
user << browse_rsc(preview_icon, "previewicon.png")
|
user << browse_rsc(preview_icon, "previewicon.png")
|
||||||
var/dat = ""
|
|
||||||
|
|
||||||
|
var/list/display_list = list()
|
||||||
for (var/name in settings["mainsettings"])
|
for (var/name in settings["mainsettings"])
|
||||||
var/setting = settings["mainsettings"][name]
|
var/setting = settings["mainsettings"][name]
|
||||||
if (setting["type"] == "datum")
|
if (setting["type"] == "datum")
|
||||||
if (setting["subtypesonly"])
|
if (setting["subtypesonly"])
|
||||||
dat += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;subtypesonly=1;type=datum;path=[setting["path"]]'>[setting["value"]]</a><BR>"
|
display_list += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;subtypesonly=1;type=datum;path=[setting["path"]]'>[setting["value"]]</a><BR>"
|
||||||
else
|
else
|
||||||
dat += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;type=datum;path=[setting["path"]]'>[setting["value"]]</a><BR>"
|
display_list += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;type=datum;path=[setting["path"]]'>[setting["value"]]</a><BR>"
|
||||||
else
|
else
|
||||||
dat += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;type=[setting["type"]]'>[setting["value"]]</a><BR>"
|
display_list += "<b>[setting["desc"]]:</b> <a href='byond://?src=[REF(src)];setting=[name];task=input;type=[setting["type"]]'>[setting["value"]]</a><BR>"
|
||||||
|
|
||||||
if (preview_icon)
|
if (preview_icon)
|
||||||
dat += "<td valign='center'>"
|
display_list += "<td valign='center'>"
|
||||||
|
display_list += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
|
||||||
|
display_list += "</td>"
|
||||||
|
|
||||||
dat += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
|
display_list += "</tr></table>"
|
||||||
|
display_list += "<hr><center><a href='byond://?src=[REF(src)];button=1'>Ok</a> "
|
||||||
|
display_list += "</center>"
|
||||||
|
|
||||||
dat += "</td>"
|
return display_list.Join()
|
||||||
|
|
||||||
dat += "</tr></table>"
|
/datum/browser/modal/pref_like_picker/Topic(href,href_list)
|
||||||
|
|
||||||
dat += "<hr><center><a href='byond://?src=[REF(src)];button=1'>Ok</a> "
|
|
||||||
|
|
||||||
dat += "</center>"
|
|
||||||
|
|
||||||
return dat
|
|
||||||
|
|
||||||
/datum/browser/modal/preflikepicker/Topic(href,href_list)
|
|
||||||
if (href_list["close"] || !user || !user.client)
|
if (href_list["close"] || !user || !user.client)
|
||||||
opentime = 0
|
open_time = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
if (href_list["task"] == "input")
|
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"])
|
switch (href_list["type"])
|
||||||
if ("datum")
|
if ("datum")
|
||||||
var/oldval = settings["mainsettings"][setting]["value"]
|
var/parent_path = text2path(href_list["path"])
|
||||||
|
var/list/paths
|
||||||
if (href_list["subtypesonly"])
|
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
|
else
|
||||||
settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(typesof(text2path(href_list["path"]))))
|
paths = typesof(parent_path)
|
||||||
if (isnull(settings["mainsettings"][setting]["value"]))
|
|
||||||
settings["mainsettings"][setting]["value"] = oldval
|
var/new_value = pick_closest_path(null, make_types_fancy(paths))
|
||||||
|
if (!isnull(new_value))
|
||||||
|
setting["value"] = new_value
|
||||||
|
|
||||||
if ("string")
|
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")
|
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")
|
if ("color")
|
||||||
settings["mainsettings"][setting]["value"] = tgui_color_picker(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) // BUBBERSTATION EDIT: TGUI COLOR PICKER
|
settings["mainsettings"][setting]["value"] = tgui_color_picker(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) // BUBBERSTATION EDIT: TGUI COLOR PICKER
|
||||||
if ("boolean")
|
if ("boolean")
|
||||||
settings["mainsettings"][setting]["value"] = (settings["mainsettings"][setting]["value"] == "Yes") ? "No" : "Yes"
|
setting["value"] = (setting["value"] == "Yes") ? "No" : "Yes"
|
||||||
if ("ckey")
|
if ("ckey")
|
||||||
settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory
|
setting["value"] = input(user, "[setting["desc"]]?") in (list("none") + GLOB.directory)
|
||||||
if (settings["mainsettings"][setting]["callback"])
|
if (setting["callback"])
|
||||||
var/datum/callback/callback = settings["mainsettings"][setting]["callback"]
|
var/datum/callback/callback = setting["callback"]
|
||||||
settings = callback.Invoke(settings)
|
settings = callback.Invoke(settings)
|
||||||
|
|
||||||
if (href_list["button"])
|
if (href_list["button"])
|
||||||
var/button = text2num(href_list["button"])
|
var/button = text2num(href_list["button"])
|
||||||
if (button <= 3 && button >= 1)
|
if (button <= 3 && button >= 1)
|
||||||
selectedbutton = button
|
selected_button = button
|
||||||
if (selectedbutton != 1)
|
|
||||||
set_content(ShowChoices(user))
|
if (selected_button != 1)
|
||||||
|
set_content(show_choices(user))
|
||||||
open()
|
open()
|
||||||
return
|
return
|
||||||
for (var/item in href_list)
|
|
||||||
switch(item)
|
open_time = 0
|
||||||
if ("close", "button", "src")
|
|
||||||
continue
|
|
||||||
opentime = 0
|
|
||||||
close()
|
close()
|
||||||
|
|
||||||
/proc/presentpreflikepicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor)
|
/proc/present_pref_like_picker(mob/user, message, title, steal_focus = TRUE, timeout = 600 SECONDS, list/settings, width, height)
|
||||||
if (!istype(User))
|
if (!ismob(user))
|
||||||
if (istype(User, /client/))
|
if (!istype(user, /client))
|
||||||
var/client/C = User
|
|
||||||
User = C.mob
|
|
||||||
else
|
|
||||||
return
|
return
|
||||||
var/datum/browser/modal/preflikepicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, settings, width, height, slidecolor)
|
var/client/user_client = user
|
||||||
A.open()
|
user = user_client.mob
|
||||||
A.wait()
|
var/datum/browser/modal/pref_like_picker/window = new(user, message, title, steal_focus, timeout, settings, width, height)
|
||||||
if (A.selectedbutton)
|
window.open()
|
||||||
return list("button" = A.selectedbutton, "settings" = A.settings)
|
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)
|
/// 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 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,
|
/// This is usually only needed for devices that regularly update the browse window,
|
||||||
// e.g. canisters, timers, etc.
|
/// e.g. canisters, timers, etc.
|
||||||
//
|
///
|
||||||
// windowid should be the specified window name
|
/// windowid should be the specified window name
|
||||||
// e.g. code is : user << browse(text, "window=fred")
|
/// e.g. code is : user << browse(text, "window=fred")
|
||||||
// then use : onclose(user, "fred")
|
/// then use : onclose(user, "fred")
|
||||||
//
|
///
|
||||||
// Optionally, specify the "ref" parameter as the controlled atom (usually src)
|
/// 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.
|
// 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.
|
/// Otherwise, the user mob's machine var will be reset directly.
|
||||||
//
|
///
|
||||||
/proc/onclose(mob/user, windowid, atom/ref=null)
|
/proc/onclose(mob/user, windowid, atom/source = null)
|
||||||
if(!user.client)
|
if(!user.client)
|
||||||
return
|
return
|
||||||
var/param = "null"
|
var/param = "null"
|
||||||
if(ref)
|
if(source)
|
||||||
param = "[REF(ref)]"
|
param = "[REF(source)]"
|
||||||
|
|
||||||
winset(user, windowid, "on-close=\".windowclose [param]\"")
|
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()
|
||||||
// the on-close client verb
|
/// if a valid atom reference is supplied, call the atom's Topic() with "close=1"
|
||||||
// called when a browser popup window is closed after registering with proc/onclose()
|
/// otherwise, just reset the client mob's machine var.
|
||||||
// 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)
|
/client/verb/windowclose(atomref as text)
|
||||||
set hidden = TRUE // hide this verb from the user's panel
|
set hidden = TRUE // hide this verb from the user's panel
|
||||||
set name = ".windowclose" // no autocomplete on cmd line
|
set name = ".windowclose" // no autocomplete on cmd line
|
||||||
|
|
||||||
if(atomref != "null") // if passed a real atomref
|
if(atomref == "null")
|
||||||
var/hsrc = locate(atomref) // find the reffed atom
|
return
|
||||||
var/href = "close=1"
|
// if passed a real atomref
|
||||||
if(hsrc)
|
var/atom/hsrc = locate(atomref) // find the reffed atom
|
||||||
usr = src.mob
|
var/href = "close=1"
|
||||||
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
if(!hsrc)
|
||||||
return // Topic() proc via client.Topic()
|
return
|
||||||
|
usr = src.mob
|
||||||
|
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
||||||
|
|
||||||
|
|||||||
@@ -80,25 +80,30 @@
|
|||||||
if(href_list[VV_HK_ARMOR_MOD])
|
if(href_list[VV_HK_ARMOR_MOD])
|
||||||
if(!check_rights(NONE))
|
if(!check_rights(NONE))
|
||||||
return
|
return
|
||||||
var/list/pickerlist = list()
|
var/list/picker_list = list()
|
||||||
var/list/armorlist = get_armor().get_rating_list()
|
var/list/armor_list = get_armor().get_rating_list()
|
||||||
for (var/i in armorlist)
|
for (var/rating in armor_list)
|
||||||
pickerlist += list(list("value" = armorlist[i], "name" = i))
|
picker_list += list(list("value" = armor_list[rating], "name" = rating))
|
||||||
var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [src]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist)
|
|
||||||
|
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()
|
var/list/armor_all = ARMOR_LIST_ALL()
|
||||||
if(islist(result))
|
// text2num conveniently returns a null on invalid values
|
||||||
if(result["button"] != 2) // If the user pressed the cancel button
|
var/list/converted = list()
|
||||||
// text2num conveniently returns a null on invalid values
|
for(var/armor_key in armor_all)
|
||||||
var/list/converted = list()
|
converted[armor_key] = text2num(result["values"][armor_key])
|
||||||
for(var/armor_key in armor_all)
|
set_armor(get_armor().generate_new_with_specific(converted))
|
||||||
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: "
|
||||||
var/message = "[key_name(usr)] modified the armor on [src] ([type]) to: "
|
for(var/armor_key in armor_all)
|
||||||
for(var/armor_key in armor_all)
|
message += "[armor_key]=[get_armor_rating(armor_key)],"
|
||||||
message += "[armor_key]=[get_armor_rating(armor_key)],"
|
message = copytext(message, 1, -1)
|
||||||
message = copytext(message, 1, -1)
|
log_admin(span_notice(message))
|
||||||
log_admin(span_notice(message))
|
message_admins(span_notice(message))
|
||||||
message_admins(span_notice(message))
|
|
||||||
|
|
||||||
if(href_list[VV_HK_ADD_AI])
|
if(href_list[VV_HK_ADD_AI])
|
||||||
if(!check_rights(R_VAREDIT))
|
if(!check_rights(R_VAREDIT))
|
||||||
|
|||||||
@@ -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)
|
for(var/datum/paper_input/text_input as anything in paper.raw_text_inputs)
|
||||||
paper_text += text_input.raw_text
|
paper_text += text_input.raw_text
|
||||||
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[paper.name]</title></head>" \
|
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[paper.name]</title></head>" \
|
||||||
+ "<body style='overflow:hidden;padding:5px'>" \
|
+ "<body style='overflow:hidden;padding:5px'>" \
|
||||||
+ "[paper_text]" \
|
+ "[paper_text]" \
|
||||||
+ "</body></html>", "window=photo_showing;size=480x608")
|
+ "</body></html>", "window=photo_showing;size=480x608")
|
||||||
onclose(user, "[name]")
|
onclose(user, "[name]")
|
||||||
if("remove_evidence")
|
if("remove_evidence")
|
||||||
var/datum/case/case = cases[current_case]
|
var/datum/case/case = cases[current_case]
|
||||||
|
|||||||
@@ -471,8 +471,10 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
|
|||||||
admin_holder.rank_flags(),
|
admin_holder.rank_flags(),
|
||||||
350,
|
350,
|
||||||
590,
|
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()
|
admin_holder.disassociate()
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_ADMIN)
|
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_ADMIN)
|
||||||
return preview_icon
|
return preview_icon
|
||||||
|
|
||||||
/datum/admins/proc/makeEmergencyresponseteam(datum/ert/ertemplate = null)
|
/datum/admins/proc/make_emergency_response_team(datum/ert/ertemplate = null)
|
||||||
if (ertemplate)
|
if (ertemplate)
|
||||||
ertemplate = new ertemplate
|
ertemplate = new ertemplate
|
||||||
else
|
else
|
||||||
@@ -97,189 +97,189 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
return FALSE
|
||||||
|
|
||||||
if (prefreturn["button"] == 1)
|
if (pref_return["button"] != 1)
|
||||||
var/list/prefs = settings["mainsettings"]
|
return FALSE
|
||||||
|
|
||||||
var/templtype = prefs["template"]["value"]
|
var/list/prefs = settings["mainsettings"]
|
||||||
if (!ispath(prefs["template"]["value"]))
|
|
||||||
templtype = text2path(prefs["template"]["value"]) // new text2path ... doesn't compile in 511
|
|
||||||
|
|
||||||
if (ertemplate.type != templtype)
|
var/templtype = prefs["template"]["value"]
|
||||||
ertemplate = new templtype
|
if (!ispath(prefs["template"]["value"]))
|
||||||
|
templtype = text2path(prefs["template"]["value"]) // new text2path ... doesn't compile in 511
|
||||||
|
|
||||||
ertemplate.teamsize = prefs["teamsize"]["value"]
|
if (ertemplate.type != templtype)
|
||||||
ertemplate.mission = prefs["mission"]["value"]
|
ertemplate = new templtype
|
||||||
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.notify_players = prefs["notify_players"]["value"] == "Yes" //SKYRAT EDIT ADDITION
|
|
||||||
ertemplate.use_custom_shuttle = prefs["use_custom_shuttle"]["value"] == "Yes"
|
|
||||||
ertemplate.mob_type = prefs["mob_type"]["value"]
|
|
||||||
|
|
||||||
var/list/spawnpoints = GLOB.emergencyresponseteamspawn
|
ertemplate.teamsize = prefs["teamsize"]["value"]
|
||||||
var/index = 0
|
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"]
|
||||||
|
ertemplate.notify_players = prefs["notify_players"]["value"] == "Yes" //SKYRAT EDIT ADDITION
|
||||||
|
|
||||||
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/list/spawn_points = GLOB.emergencyresponseteamspawn
|
||||||
var/teamSpawned = FALSE
|
|
||||||
|
|
||||||
// This list will take priority over spawnpoints if not empty
|
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/list/spawn_turfs = list()
|
var/team_spawned = 0
|
||||||
|
|
||||||
// Takes precedence over spawnpoints[1] if not null
|
// This list will take priority over spawn_points if not empty
|
||||||
var/turf/brief_spawn
|
var/list/spawn_turfs = list()
|
||||||
|
|
||||||
if(!length(candidates))
|
// Takes precedence over spawn_points[1] if not null
|
||||||
return FALSE
|
var/turf/brief_spawn
|
||||||
|
|
||||||
if(ertemplate.use_custom_shuttle && ertemplate.ert_template)
|
if(!length(candidates))
|
||||||
to_chat(usr, span_boldnotice("Attempting to spawn ERT custom shuttle, this may take a few seconds..."))
|
return FALSE
|
||||||
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(!ship.load(located_turf))
|
if(ertemplate.use_custom_shuttle && ertemplate.ert_template)
|
||||||
CRASH("Loading ERT shuttle failed!")
|
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)
|
var/list/shuttle_turfs = ship.get_affected_turfs(located_turf)
|
||||||
for(var/obj/effect/landmark/ert_shuttle_spawn/spawner in affected_turf)
|
|
||||||
spawn_turfs += get_turf(spawner)
|
|
||||||
|
|
||||||
if(!brief_spawn)
|
for(var/turf/affected_turf as anything in shuttle_turfs)
|
||||||
brief_spawn = get_turf(locate(/obj/effect/landmark/ert_shuttle_brief_spawn) in affected_turf)
|
for(var/obj/effect/landmark/ert_shuttle_spawn/spawner in affected_turf)
|
||||||
|
spawn_turfs += get_turf(spawner)
|
||||||
|
|
||||||
if(!length(spawn_turfs))
|
if(!brief_spawn)
|
||||||
stack_trace("ERT shuttle loaded but found no spawnpoints, placing the ERT at wherever inside the shuttle instead.")
|
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(!length(spawn_turfs))
|
||||||
if(!is_safe_turf(open_turf))
|
stack_trace("ERT shuttle loaded but found no spawn points, placing the ERT at wherever inside the shuttle instead.")
|
||||||
continue
|
|
||||||
spawn_turfs += open_turf
|
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(ertemplate.spawn_admin)
|
||||||
if(isobserver(usr))
|
if(isobserver(usr))
|
||||||
var/mob/living/carbon/human/admin_officer = new (brief_spawn || spawnpoints[1])
|
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)
|
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)
|
usr.client.prefs.safe_transfer_prefs_to(admin_officer, is_antag = TRUE)
|
||||||
admin_officer.equipOutfit(chosen_outfit)
|
admin_officer.equipOutfit(chosen_outfit)
|
||||||
admin_officer.PossessByPlayer(usr.key)
|
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
|
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)
|
//Pick the (un)lucky players
|
||||||
var/turf/spawnloc
|
var/numagents = min(ertemplate.teamsize, length(candidates))
|
||||||
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
|
|
||||||
|
|
||||||
var/mob/dead/observer/chosen_candidate = earmarked_leader || pick(candidates) // this way we make sure that our leader gets chosen
|
//Create team
|
||||||
candidates -= chosen_candidate
|
var/datum/team/ert/ert_team = new ertemplate.team()
|
||||||
if(!chosen_candidate?.key)
|
if(ertemplate.rename_team)
|
||||||
continue
|
ert_team.name = ertemplate.rename_team
|
||||||
|
|
||||||
//Spawn the body
|
//Assign team objective
|
||||||
var/mob/living/carbon/human/ert_operative
|
var/datum/objective/missionobj = new ()
|
||||||
if(ertemplate.mob_type)
|
missionobj.team = ert_team
|
||||||
ert_operative = new ertemplate.mob_type(spawnloc)
|
missionobj.explanation_text = ertemplate.mission
|
||||||
else
|
missionobj.completed = TRUE
|
||||||
ert_operative = new /mob/living/carbon/human(spawnloc)
|
ert_team.objectives += missionobj
|
||||||
chosen_candidate.client.prefs.safe_transfer_prefs_to(ert_operative, is_antag = TRUE)
|
ert_team.mission = missionobj
|
||||||
ert_operative.PossessByPlayer(chosen_candidate.key)
|
|
||||||
|
|
||||||
if(ertemplate.enforce_human || !(ert_operative.dna.species.changesource_flags & ERT_SPAWN))
|
var/mob/dead/observer/earmarked_leader
|
||||||
ert_operative.set_species(/datum/species/human)
|
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
|
if(ertemplate.leader_experience)
|
||||||
var/datum/antagonist/ert/ert_antag
|
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))
|
candidate_living_exps = sort_list(candidate_living_exps, cmp=/proc/cmp_numeric_dsc)
|
||||||
ert_antag = new ertemplate.leader_role ()
|
if(candidate_living_exps.len > ERT_EXPERIENCED_LEADER_CHOOSE_TOP)
|
||||||
earmarked_leader = null
|
candidate_living_exps.Cut(ERT_EXPERIENCED_LEADER_CHOOSE_TOP+1) // pick from the top ERT_EXPERIENCED_LEADER_CHOOSE_TOP contenders in playtime
|
||||||
leader_spawned = TRUE
|
earmarked_leader = pick(candidate_living_exps)
|
||||||
else
|
else
|
||||||
ert_antag = ertemplate.roles[WRAP(numagents,1,length(ertemplate.roles) + 1)]
|
earmarked_leader = pick(candidates)
|
||||||
ert_antag = new ert_antag ()
|
|
||||||
ert_antag.random_names = ertemplate.random_names
|
|
||||||
|
|
||||||
ert_operative.mind.add_antag_datum(ert_antag,ert_team)
|
var/spawn_index = 0
|
||||||
ert_operative.mind.set_assigned_role(SSjob.get_job_type(ert_antag.ert_job_path))
|
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
|
var/mob/dead/observer/chosen_candidate = earmarked_leader || pick(candidates) // this way we make sure that our leader gets chosen
|
||||||
ert_operative.log_message("has been selected as \a [ert_antag.name].", LOG_GAME)
|
candidates -= chosen_candidate
|
||||||
numagents--
|
if(!chosen_candidate?.key)
|
||||||
teamSpawned++
|
continue
|
||||||
|
|
||||||
if (teamSpawned)
|
//Spawn the body
|
||||||
message_admins("[ertemplate.polldesc] has spawned with the mission: [ertemplate.mission]")
|
var/mob/living/carbon/human/ert_operative
|
||||||
//SKYRAT EDIT ADDITION BEGIN
|
if(ertemplate.mob_type)
|
||||||
if(ertemplate.notify_players)
|
ert_operative = new ertemplate.mob_type(spawnloc)
|
||||||
priority_announce("Central command has responded to your request for a CODE [uppertext(ertemplate.code)] Emergency Response Team and have confirmed one to be enroute.", "ERT Request", ANNOUNCER_ERTYES)
|
else
|
||||||
// shitcode begin!
|
ert_operative = new /mob/living/carbon/human(spawnloc)
|
||||||
if(istype(ertemplate, /datum/ert/deathsquad))
|
chosen_candidate.client.prefs.safe_transfer_prefs_to(ert_operative, is_antag = TRUE)
|
||||||
SSsecurity_level.set_level(SEC_LEVEL_EPSILON)
|
ert_operative.PossessByPlayer(chosen_candidate.key)
|
||||||
//SKYRAT EDIT END
|
|
||||||
//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
|
|
||||||
|
|
||||||
return
|
if(ertemplate.enforce_human || !(ert_operative.dna.species.changesource_flags & ERT_SPAWN))
|
||||||
|
ert_operative.set_species(/datum/species/human)
|
||||||
|
|
||||||
|
//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]")
|
||||||
|
//SKYRAT EDIT ADDITION BEGIN
|
||||||
|
if(ertemplate.notify_players)
|
||||||
|
priority_announce("Central command has responded to your request for a CODE [uppertext(ertemplate.code)] Emergency Response Team and have confirmed one to be enroute.", "ERT Request", ANNOUNCER_ERTYES)
|
||||||
|
// shitcode begin!
|
||||||
|
if(istype(ertemplate, /datum/ert/deathsquad))
|
||||||
|
SSsecurity_level.set_level(SEC_LEVEL_EPSILON)
|
||||||
|
//SKYRAT EDIT END
|
||||||
|
|
||||||
|
//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)
|
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...")
|
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.")
|
message_admins("[key_name_admin(user)] created a CentCom response team.")
|
||||||
log_admin("[key_name(user)] created a CentCom response team.")
|
log_admin("[key_name(user)] created a CentCom response team.")
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w
|
|||||||
return
|
return
|
||||||
if((action != "admin_log" || action != "show_admins") && !check_rights(R_ADMIN))
|
if((action != "admin_log" || action != "show_admins") && !check_rights(R_ADMIN))
|
||||||
return
|
return
|
||||||
var/datum/round_event/E
|
|
||||||
switch(action)
|
switch(action)
|
||||||
//Generic Buttons anyone can use.
|
//Generic Buttons anyone can use.
|
||||||
if("admin_log")
|
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...")
|
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)
|
if (pref_return["button"] != 1)
|
||||||
var/list/prefs = settings["mainsettings"]
|
return
|
||||||
|
|
||||||
if (prefs["amount"]["value"] < 1 || prefs["portalnum"]["value"] < 1)
|
var/list/prefs = settings["mainsettings"]
|
||||||
to_chat(holder, span_warning("Number of portals and mobs to spawn must be at least 1."), confidential = TRUE)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/mob/pathToSpawn = prefs["typepath"]["value"]
|
if (prefs["amount"]["value"] < 1 || prefs["portalnum"]["value"] < 1)
|
||||||
if (!ispath(pathToSpawn))
|
to_chat(holder, span_warning("Number of portals and mobs to spawn must be at least 1."), confidential = TRUE)
|
||||||
pathToSpawn = text2path(pathToSpawn)
|
return
|
||||||
|
|
||||||
if (!ispath(pathToSpawn))
|
var/mob/path_to_spawn = prefs["typepath"]["value"]
|
||||||
to_chat(holder, span_notice("Invalid path [pathToSpawn]."), confidential = TRUE)
|
if (!ispath(path_to_spawn))
|
||||||
return
|
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")
|
var/list/candidates = list()
|
||||||
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")
|
|
||||||
|
|
||||||
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)]")
|
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
|
return
|
||||||
|
|
||||||
if (prefs["announce_players"]["value"] == "Yes")
|
if (prefs["announce_players"]["value"] == "Yes")
|
||||||
portalAnnounce(prefs["announcement"]["value"], (prefs["playlightning"]["value"] == "Yes" ? TRUE : FALSE))
|
portal_announce(prefs["announcement"]["value"], (prefs["playlightning"]["value"] == "Yes" ? TRUE : FALSE))
|
||||||
|
|
||||||
var/list/storm_appearances = list()
|
var/list/storm_appearances = list()
|
||||||
for(var/offset in 0 to SSmapping.max_plane_offset)
|
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)
|
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)
|
SET_PLANE_W_SCALAR(storm, ABOVE_GAME_PLANE, offset)
|
||||||
storm.color = prefs["color"]["value"]
|
storm.color = prefs["color"]["value"]
|
||||||
storm_appearances += storm
|
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]")
|
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 [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 [path_to_spawn]")
|
||||||
|
|
||||||
var/outfit = prefs["humanoutfit"]["value"]
|
var/outfit = prefs["humanoutfit"]["value"]
|
||||||
if (!ispath(outfit))
|
if (!ispath(outfit))
|
||||||
outfit = text2path(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("changebombcap")
|
||||||
if(!is_funmin)
|
if(!is_funmin)
|
||||||
return
|
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.")
|
message_admins("[key_name_admin(holder)] healed everyone.")
|
||||||
log_admin("[key_name(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)
|
if(holder)
|
||||||
log_admin("[key_name(holder)] used secret: [action].")
|
log_admin("[key_name(holder)] used secret: [action].")
|
||||||
#undef THUNDERDOME_TEMPLATE_FILE
|
#undef THUNDERDOME_TEMPLATE_FILE
|
||||||
#undef HIGHLANDER_DELAY_TEXT
|
#undef HIGHLANDER_DELAY_TEXT
|
||||||
|
|
||||||
/proc/portalAnnounce(announcement, playlightning)
|
/proc/portal_announce(announcement, playlightning)
|
||||||
set waitfor = FALSE
|
set waitfor = FALSE
|
||||||
if (playlightning)
|
if (playlightning)
|
||||||
sound_to_playing_players('sound/effects/magic/lightning_chargeup.ogg')
|
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
|
/// 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
|
/// 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)
|
for (var/i in 1 to numtospawn)
|
||||||
var/mob/spawnedMob = new mobtype(loc)
|
var/mob/spawnedMob = new mobtype(loc)
|
||||||
if (length(players))
|
if (length(players))
|
||||||
|
|||||||
@@ -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)
|
var/list/pref_return = present_pref_like_picker(user.mob, "Customize mob", "Customize mob", width = 450, timeout = 0, settings = settings)
|
||||||
if (prefreturn["button"] == 1)
|
if (pref_return["button"] != 1)
|
||||||
settings = prefreturn["settings"]
|
return
|
||||||
var/mainsettings = settings["mainsettings"]
|
|
||||||
chosen_obj = text2path(mainsettings["objtype"]["value"])
|
|
||||||
|
|
||||||
basemob = text2path(mainsettings["mobtype"]["value"])
|
settings = pref_return["settings"]
|
||||||
if (!ispath(basemob, /mob/living/basic/mimic/copy) || !ispath(chosen_obj, /obj))
|
var/mainsettings = settings["mainsettings"]
|
||||||
to_chat(user.mob, "Mob or object path invalid", confidential = TRUE)
|
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")
|
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))
|
||||||
qdel(basemob.ai_controller)
|
|
||||||
basemob.ai_controller = null
|
|
||||||
|
|
||||||
if (mainsettings["idledamage"]["value"] == "No")
|
if (mainsettings["disableai"]["value"] == "Yes")
|
||||||
basemob.idledamage = FALSE
|
qdel(basemob.ai_controller)
|
||||||
|
basemob.ai_controller = null
|
||||||
|
|
||||||
if (mainsettings["access"])
|
if (mainsettings["idledamage"]["value"] == "No")
|
||||||
var/newaccess = text2path(mainsettings["access"]["value"])
|
basemob.idledamage = FALSE
|
||||||
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["maxhealth"]["value"])
|
if (mainsettings["access"])
|
||||||
if (!isnum(mainsettings["maxhealth"]["value"]))
|
var/newaccess = text2path(mainsettings["access"]["value"])
|
||||||
mainsettings["maxhealth"]["value"] = text2num(mainsettings["maxhealth"]["value"])
|
if (ispath(newaccess))
|
||||||
if (mainsettings["maxhealth"]["value"] > 0)
|
var/obj/item/card/id/id = new newaccess //cant do initial on lists
|
||||||
basemob.maxHealth = basemob.maxHealth = mainsettings["maxhealth"]["value"]
|
basemob.AddComponent(/datum/component/simple_access, id.access)
|
||||||
|
qdel(id)
|
||||||
|
|
||||||
if (mainsettings["name"]["value"])
|
if (mainsettings["maxhealth"]["value"])
|
||||||
basemob.name = basemob.real_name = html_decode(mainsettings["name"]["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")
|
if (mainsettings["name"]["value"])
|
||||||
basemob.ckey = mainsettings["ckey"]["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)]")
|
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")
|
BLACKBOX_LOG_ADMIN_VERB("Spawn object-mob")
|
||||||
|
|||||||
@@ -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: <span class='code user-select'>[prefix]verify [one_time_token]</span>"
|
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: <span class='code user-select'>[prefix]verify [one_time_token]</span>"
|
||||||
|
|
||||||
//Now give them a browse window so they can't miss whatever we told them
|
//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("<div>[message]</div>")
|
window.set_content("<div>[message]</div>")
|
||||||
window.open()
|
window.open()
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache)
|
|||||||
/datum/error_viewer/proc/browse_to(client/user, html)
|
/datum/error_viewer/proc/browse_to(client/user, html)
|
||||||
var/datum/browser/browser = new(user.mob, "error_viewer", null, 600, 400)
|
var/datum/browser/browser = new(user.mob, "error_viewer", null, 600, 400)
|
||||||
browser.set_content(html)
|
browser.set_content(html)
|
||||||
browser.add_head_content({"
|
browser.set_head_content({"
|
||||||
<style>
|
<style>
|
||||||
.runtime
|
.runtime
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
nuke_chat()
|
nuke_chat()
|
||||||
|
|
||||||
// Failed to fix, using tgalert as fallback
|
// Failed to fix, using tg_alert as fallback
|
||||||
action = tgalert(src, "Did that work?", "", "Yes", "No, switch to old ui")
|
action = tg_alert(src, "Did that work?", "", "Yes", "No, switch to old ui")
|
||||||
if (action == "No, switch to old ui")
|
if (action == "No, switch to old ui")
|
||||||
winset(src, "output_selector.legacy_output_selector", "left=output_legacy")
|
winset(src, "output_selector.legacy_output_selector", "left=output_legacy")
|
||||||
log_tgui(src, "Failed to fix.", context = "verb/fix_tgui_panel")
|
log_tgui(src, "Failed to fix.", context = "verb/fix_tgui_panel")
|
||||||
|
|||||||
@@ -70,9 +70,9 @@
|
|||||||
message += "<br>The following experimental changes are active and are probably the cause of any new or sudden issues you may experience. If possible, please try to find a specific thread for your issue instead of posting to the general issue tracker:<br>"
|
message += "<br>The following experimental changes are active and are probably the cause of any new or sudden issues you may experience. If possible, please try to find a specific thread for your issue instead of posting to the general issue tracker:<br>"
|
||||||
message += GLOB.revdata.GetTestMergeInfo(FALSE)
|
message += GLOB.revdata.GetTestMergeInfo(FALSE)
|
||||||
|
|
||||||
// We still use tgalert here because some people were concerned that if someone wanted to report that tgui wasn't working
|
// We still use tg_alert here because some people were concerned that if someone wanted to report that tgui wasn't working
|
||||||
// then the report issue button being tgui-based would be problematic.
|
// then the report issue button being tgui-based would be problematic.
|
||||||
if(tgalert(src, message, "Report Issue","Yes","No") != "Yes")
|
if(tg_alert(src, message, "Report Issue", "Yes", "No") != "Yes")
|
||||||
return
|
return
|
||||||
|
|
||||||
var/base_link = githuburl + "/issues/new?template=bug_report_form.yml"
|
var/base_link = githuburl + "/issues/new?template=bug_report_form.yml"
|
||||||
|
|||||||
Reference in New Issue
Block a user