mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-07-20 12:44:04 +01:00
Merge branch 'master' of https://github.com/Yawn-Wider/YWPolarisVore into August2020UpstreamPull
August2020UpstreamPull
This commit is contained in:
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
Asset cache quick users guide:
|
||||
|
||||
Make a datum at the bottom of this file with your assets for your thing.
|
||||
The simple subsystem will most like be of use for most cases.
|
||||
Then call get_asset_datum() with the type of the datum you created and store the return
|
||||
Then call .send(client) on that stored return value.
|
||||
|
||||
You can set verify to TRUE if you want send() to sleep until the client has the assets.
|
||||
*/
|
||||
|
||||
|
||||
// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
|
||||
// This is doubled for the first asset, then added per asset after
|
||||
#define ASSET_CACHE_SEND_TIMEOUT 7
|
||||
|
||||
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
||||
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
||||
|
||||
//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
|
||||
#define ASSET_CACHE_PRELOAD_CONCURRENT 3
|
||||
|
||||
/client
|
||||
var/list/cache = list() // List of all assets sent to this client by the asset cache.
|
||||
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
|
||||
var/list/sending = list()
|
||||
var/last_asset_job = 0 // Last job done.
|
||||
|
||||
//This proc sends the asset to the client, but only if it needs it.
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
|
||||
client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null
|
||||
if(!istype(client))
|
||||
return 0
|
||||
|
||||
if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
|
||||
return 0
|
||||
|
||||
client << browse_rsc(SSassets.cache[asset_name], asset_name)
|
||||
if(!verify) // Can't access the asset cache browser, rip.
|
||||
client.cache += asset_name
|
||||
return 1
|
||||
|
||||
client.sending |= asset_name
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= asset_name
|
||||
client.cache |= asset_name
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
|
||||
client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null
|
||||
if(!istype(client))
|
||||
return 0
|
||||
|
||||
var/list/unreceived = asset_list - (client.cache + client.sending)
|
||||
if(!unreceived || !unreceived.len)
|
||||
return 0
|
||||
if(unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
|
||||
to_chat(client, "Sending Resources...")
|
||||
for(var/asset in unreceived)
|
||||
if(asset in SSassets.cache)
|
||||
client << browse_rsc(SSassets.cache[asset], asset)
|
||||
|
||||
if(!verify) // Can't access the asset cache browser, rip.
|
||||
client.cache += unreceived
|
||||
return 1
|
||||
|
||||
client.sending |= unreceived
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= unreceived
|
||||
client.cache |= unreceived
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
|
||||
//The proc calls procs that sleep for long times.
|
||||
/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
||||
var/concurrent_tracker = 1
|
||||
for(var/file in files)
|
||||
if(!client)
|
||||
break
|
||||
if(register_asset)
|
||||
register_asset(file, files[file])
|
||||
if(concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT)
|
||||
concurrent_tracker = 1
|
||||
send_asset(client, file)
|
||||
else
|
||||
concurrent_tracker++
|
||||
send_asset(client, file, verify = FALSE)
|
||||
sleep(0) //queuing calls like this too quickly can cause issues in some client versions
|
||||
|
||||
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
|
||||
//if it's an icon or something be careful, you'll have to copy it before further use.
|
||||
/proc/register_asset(var/asset_name, var/asset)
|
||||
SSassets.cache[asset_name] = asset
|
||||
|
||||
//These datums are used to populate the asset cache, the proc "register()" does this.
|
||||
|
||||
//all of our asset datums, used for referring to these later
|
||||
/var/global/list/asset_datums = list()
|
||||
|
||||
//get a assetdatum or make a new one
|
||||
/proc/get_asset_datum(var/type)
|
||||
if(!(type in asset_datums))
|
||||
return new type()
|
||||
return asset_datums[type]
|
||||
|
||||
/datum/asset
|
||||
var/_abstract = /datum/asset // Marker so we don't instanatiate abstract types
|
||||
|
||||
/datum/asset/New()
|
||||
asset_datums[type] = src
|
||||
register()
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
/datum/asset/proc/send(client)
|
||||
return
|
||||
|
||||
//If you don't need anything complicated.
|
||||
/datum/asset/simple
|
||||
_abstract = /datum/asset/simple
|
||||
var/assets = list()
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/simple/register()
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
/datum/asset/simple/send(client)
|
||||
send_asset_list(client,assets,verify)
|
||||
|
||||
//
|
||||
// iconsheet Assets - For making lots of icon states available at once without sending a thousand tiny files.
|
||||
//
|
||||
/datum/asset/iconsheet
|
||||
_abstract = /datum/asset/iconsheet
|
||||
var/name // Name of the iconsheet. Asset will be named after this.
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/iconsheet/register(var/list/sprites)
|
||||
if (!name)
|
||||
CRASH("iconsheet [type] cannot register without a name")
|
||||
if (!islist(sprites))
|
||||
CRASH("iconsheet [type] cannot register without a sprites list")
|
||||
|
||||
var/res_name = "iconsheet_[name].css"
|
||||
var/fname = "data/iconsheets/[res_name]"
|
||||
fdel(fname)
|
||||
text2file(generate_css(sprites), fname)
|
||||
register_asset(res_name, fcopy_rsc(fname))
|
||||
fdel(fname)
|
||||
|
||||
/datum/asset/iconsheet/send(client/C)
|
||||
if (!name)
|
||||
return
|
||||
send_asset_list(C, list("iconsheet_[name].css"), verify)
|
||||
|
||||
/datum/asset/iconsheet/proc/generate_css(var/list/sprites)
|
||||
var/list/out = list(".[name]{display:inline-block;}")
|
||||
for(var/sprite_id in sprites)
|
||||
var/icon/I = sprites[sprite_id]
|
||||
var/data_url = "'data:image/png;base64,[icon2base64(I)]'"
|
||||
out += ".[name].[sprite_id]{width:[I.Width()]px;height:[I.Height()]px;background-image:url([data_url]);}"
|
||||
return out.Join("\n")
|
||||
|
||||
/datum/asset/iconsheet/proc/build_sprite_list(icon/I, list/directions, prefix = null)
|
||||
if (length(prefix))
|
||||
prefix = "[prefix]-"
|
||||
|
||||
if (!directions)
|
||||
directions = list(SOUTH)
|
||||
|
||||
var/sprites = list()
|
||||
for (var/icon_state_name in cached_icon_states(I))
|
||||
for (var/direction in directions)
|
||||
var/suffix = (directions.len > 1) ? "-[dir2text(direction)]" : ""
|
||||
var/sprite_name = "[prefix][icon_state_name][suffix]"
|
||||
var/icon/sprite = icon(I, icon_state=icon_state_name, dir=direction, frame=1, moving=FALSE)
|
||||
if (!sprite || !length(cached_icon_states(sprite))) // that direction or state doesn't exist
|
||||
continue
|
||||
sprites[sprite_name] = sprite
|
||||
return sprites
|
||||
|
||||
// Get HTML link tag for including the iconsheet css file.
|
||||
/datum/asset/iconsheet/proc/css_tag()
|
||||
return "<link rel='stylesheet' href='iconsheet_[name].css' />"
|
||||
|
||||
// get HTML tag for showing an icon
|
||||
/datum/asset/iconsheet/proc/icon_tag(icon_state, dir = SOUTH)
|
||||
return "<span class='[name] [icon_state]-[dir2text(dir)]'></span>"
|
||||
|
||||
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
||||
/datum/asset/simple/generic
|
||||
assets = list(
|
||||
"search.js" = 'html/search.js',
|
||||
"panels.css" = 'html/panels.css',
|
||||
"loading.gif" = 'html/images/loading.gif',
|
||||
"ntlogo.png" = 'html/images/ntlogo.png',
|
||||
"sglogo.png" = 'html/images/sglogo.png',
|
||||
"talisman.png" = 'html/images/talisman.png',
|
||||
"paper_bg.png" = 'html/images/paper_bg.png',
|
||||
"no_image32.png" = 'html/images/no_image32.png',
|
||||
)
|
||||
|
||||
/datum/asset/simple/changelog
|
||||
assets = list(
|
||||
"88x31.png" = 'html/88x31.png',
|
||||
"bug-minus.png" = 'html/bug-minus.png',
|
||||
"cross-circle.png" = 'html/cross-circle.png',
|
||||
"hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png',
|
||||
"image-minus.png" = 'html/image-minus.png',
|
||||
"image-plus.png" = 'html/image-plus.png',
|
||||
"map-pencil.png" = 'html/map-pencil.png',
|
||||
"music-minus.png" = 'html/music-minus.png',
|
||||
"music-plus.png" = 'html/music-plus.png',
|
||||
"tick-circle.png" = 'html/tick-circle.png',
|
||||
"wrench-screwdriver.png" = 'html/wrench-screwdriver.png',
|
||||
"spell-check.png" = 'html/spell-check.png',
|
||||
"burn-exclamation.png" = 'html/burn-exclamation.png',
|
||||
"chevron.png" = 'html/chevron.png',
|
||||
"chevron-expand.png" = 'html/chevron-expand.png',
|
||||
"changelog.css" = 'html/changelog.css',
|
||||
"changelog.js" = 'html/changelog.js',
|
||||
"changelog.html" = 'html/changelog.html'
|
||||
)
|
||||
|
||||
/datum/asset/nanoui
|
||||
var/list/common = list()
|
||||
|
||||
var/list/common_dirs = list(
|
||||
"nano/css/",
|
||||
"nano/images/",
|
||||
"nano/images/modular_computers/",
|
||||
"nano/js/"
|
||||
)
|
||||
var/list/template_dirs = list(
|
||||
"nano/templates/"
|
||||
)
|
||||
|
||||
/datum/asset/nanoui/register()
|
||||
// Crawl the directories to find files.
|
||||
for(var/path in common_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
||||
if(fexists(path + filename))
|
||||
common[filename] = fcopy_rsc(path + filename)
|
||||
register_asset(filename, common[filename])
|
||||
// Combine all templates into a single bundle.
|
||||
var/list/template_data = list()
|
||||
for(var/path in template_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
|
||||
template_data[filename] = file2text(path + filename)
|
||||
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
|
||||
var/fname = "data/nano_templates_bundle.js"
|
||||
fdel(fname)
|
||||
text2file(template_bundle, fname)
|
||||
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
|
||||
fdel(fname)
|
||||
|
||||
/datum/asset/nanoui/send(client)
|
||||
send_asset_list(client, common)
|
||||
|
||||
|
||||
// VOREStation Add Start - pipes iconsheet asset
|
||||
/datum/asset/iconsheet/pipes
|
||||
name = "pipes"
|
||||
|
||||
/datum/asset/iconsheet/pipes/register()
|
||||
var/list/sprites = list()
|
||||
for (var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi'))
|
||||
sprites += build_sprite_list(each, global.alldirs)
|
||||
..(sprites)
|
||||
// VOREStation Add End
|
||||
@@ -61,3 +61,17 @@
|
||||
var/global/obj/screen/click_catcher/void
|
||||
|
||||
control_freak = 0 //CHOMPedit KSC 1/30/20 - This enables all clientside options for Players.
|
||||
// List of all asset filenames sent to this client by the asset cache, along with their assoicated md5s
|
||||
var/list/sent_assets = list()
|
||||
/// List of all completed blocking send jobs awaiting acknowledgement by send_asset
|
||||
var/list/completed_asset_jobs = list()
|
||||
/// Last asset send job id.
|
||||
var/last_asset_job = 0
|
||||
var/last_completed_asset_job = 0
|
||||
|
||||
///world.time they connected
|
||||
var/connection_time
|
||||
///world.realtime they connected
|
||||
var/connection_realtime
|
||||
///world.timeofday they connected
|
||||
var/connection_timeofday
|
||||
|
||||
@@ -34,10 +34,12 @@
|
||||
|
||||
#endif
|
||||
|
||||
// asset_cache
|
||||
var/asset_cache_job
|
||||
if(href_list["asset_cache_confirm_arrival"])
|
||||
var/job = text2num(href_list["asset_cache_confirm_arrival"])
|
||||
completed_asset_jobs += job
|
||||
return
|
||||
asset_cache_job = asset_cache_confirm_arrival(href_list["asset_cache_confirm_arrival"])
|
||||
if (!asset_cache_job)
|
||||
return
|
||||
|
||||
//search the href for script injection
|
||||
if( findtext(href,"<script",1,0) )
|
||||
@@ -46,6 +48,10 @@
|
||||
//del(usr)
|
||||
return
|
||||
|
||||
// Tgui Topic middleware
|
||||
if(!tgui_Topic(href_list))
|
||||
return
|
||||
|
||||
//Admin PM
|
||||
if(href_list["priv_msg"])
|
||||
var/client/C = locate(href_list["priv_msg"])
|
||||
@@ -106,6 +112,15 @@
|
||||
if(config && config.log_hrefs && href_logfile)
|
||||
WRITE_LOG(href_logfile, "[src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]")
|
||||
|
||||
//byond bug ID:2256651
|
||||
if (asset_cache_job && (asset_cache_job in completed_asset_jobs))
|
||||
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
|
||||
src << browse("...", "window=asset_cache_browser")
|
||||
return
|
||||
if (href_list["asset_cache_preload_data"])
|
||||
asset_cache_preload_data(href_list["asset_cache_preload_data"])
|
||||
return
|
||||
|
||||
switch(href_list["_src_"])
|
||||
if("holder") hsrc = holder
|
||||
if("usr") hsrc = mob
|
||||
@@ -181,6 +196,10 @@
|
||||
. = ..() //calls mob.Login()
|
||||
prefs.sanitize_preferences()
|
||||
|
||||
connection_time = world.time
|
||||
connection_realtime = world.realtime
|
||||
connection_timeofday = world.timeofday
|
||||
|
||||
if(custom_event_msg && custom_event_msg != "")
|
||||
to_chat(src, "<h1 class='alert'>Custom Event</h1>")
|
||||
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
|
||||
@@ -407,8 +426,12 @@
|
||||
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
|
||||
/client/proc/send_resources()
|
||||
spawn (10) //removing this spawn causes all clients to not get verbs.
|
||||
|
||||
//load info on what assets the client has
|
||||
src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser")
|
||||
|
||||
//Precache the client with all other assets slowly, so as to not block other browse() calls
|
||||
getFilesSlow(src, SSassets.preload, register_asset = FALSE)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/getFilesSlow, src, SSassets.preload, FALSE), 5 SECONDS)
|
||||
|
||||
mob/proc/MayRespawn()
|
||||
return 0
|
||||
@@ -453,7 +476,7 @@ client/verb/character_setup()
|
||||
alert(src, "You can only try to reload VChat every 10 seconds at most.")
|
||||
return
|
||||
|
||||
verbs -= /client/proc/vchat_export_log
|
||||
// YW EDIT: disabled until we can fix the lag: verbs -= /client/proc/vchat_export_log
|
||||
|
||||
//Log, disable
|
||||
log_debug("[key_name(src)] reloaded VChat.")
|
||||
|
||||
@@ -19,6 +19,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
S["grad_green"] >> pref.g_grad
|
||||
S["grad_blue"] >> pref.b_grad
|
||||
S["facial_red"] >> pref.r_facial
|
||||
S["grad_red"] >> pref.r_grad
|
||||
S["grad_green"] >> pref.g_grad
|
||||
S["grad_blue"] >> pref.b_grad
|
||||
S["facial_green"] >> pref.g_facial
|
||||
S["facial_blue"] >> pref.b_facial
|
||||
S["skin_tone"] >> pref.s_tone
|
||||
@@ -28,6 +31,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
S["hair_style_name"] >> pref.h_style
|
||||
S["grad_style_name"] >> pref.grad_style
|
||||
S["facial_style_name"] >> pref.f_style
|
||||
S["grad_style_name"] >> pref.grad_style
|
||||
S["eyes_red"] >> pref.r_eyes
|
||||
S["eyes_green"] >> pref.g_eyes
|
||||
S["eyes_blue"] >> pref.b_eyes
|
||||
@@ -67,6 +71,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
S["hair_style_name"] << pref.h_style
|
||||
S["grad_style_name"] << pref.grad_style
|
||||
S["facial_style_name"] << pref.f_style
|
||||
S["grad_style_name"] << pref.grad_style
|
||||
S["eyes_red"] << pref.r_eyes
|
||||
S["eyes_green"] << pref.g_eyes
|
||||
S["eyes_blue"] << pref.b_eyes
|
||||
@@ -107,6 +112,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
pref.h_style = sanitize_inlist(pref.h_style, hair_styles_list, initial(pref.h_style))
|
||||
pref.grad_style = sanitize_inlist(pref.grad_style, GLOB.hair_gradients, initial(pref.grad_style))
|
||||
pref.f_style = sanitize_inlist(pref.f_style, facial_hair_styles_list, initial(pref.f_style))
|
||||
pref.grad_style = sanitize_inlist(pref.grad_style, GLOB.hair_gradients, initial(pref.grad_style))
|
||||
pref.r_eyes = sanitize_integer(pref.r_eyes, 0, 255, initial(pref.r_eyes))
|
||||
pref.g_eyes = sanitize_integer(pref.g_eyes, 0, 255, initial(pref.g_eyes))
|
||||
pref.b_eyes = sanitize_integer(pref.b_eyes, 0, 255, initial(pref.b_eyes))
|
||||
@@ -144,6 +150,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
character.h_style = pref.h_style
|
||||
character.grad_style= pref.grad_style
|
||||
character.f_style = pref.f_style
|
||||
character.grad_style= pref.grad_style
|
||||
character.b_type = pref.b_type
|
||||
character.synth_color = pref.synth_color
|
||||
character.r_synth = pref.r_synth
|
||||
@@ -359,11 +366,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
if(has_flag(mob_species, HAS_HAIR_COLOR))
|
||||
. += "<a href='?src=\ref[src];hair_color=1'>Change Color</a> [color_square(pref.r_hair, pref.g_hair, pref.b_hair)] "
|
||||
. += " Style: <a href='?src=\ref[src];hair_style_left=[pref.h_style]'><</a> <a href='?src=\ref[src];hair_style_right=[pref.h_style]''>></a> <a href='?src=\ref[src];hair_style=1'>[pref.h_style]</a><br>" //The <</a> & ></a> in this line is correct-- those extra characters are the arrows you click to switch between styles.
|
||||
|
||||
|
||||
. += "<b>Gradient</b><br>"
|
||||
. += "<a href='?src=\ref[src];grad_color=1'>Change Color</a> [color_square(pref.r_grad, pref.g_grad, pref.b_grad)] "
|
||||
. += "<a href='?src=\ref[src];grad_color=1'>Change Color</a> [color_square(pref.r_grad, pref.g_grad, pref.b_grad)] "
|
||||
. += " Style: <a href='?src=\ref[src];grad_style_left=[pref.grad_style]'><</a> <a href='?src=\ref[src];grad_style_right=[pref.grad_style]''>></a> <a href='?src=\ref[src];grad_style=1'>[pref.grad_style]</a><br>"
|
||||
|
||||
|
||||
. += "<br><b>Facial</b><br>"
|
||||
if(has_flag(mob_species, HAS_HAIR_COLOR))
|
||||
. += "<a href='?src=\ref[src];facial_color=1'>Change Color</a> [color_square(pref.r_facial, pref.g_facial, pref.b_facial)] "
|
||||
@@ -503,6 +510,16 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
pref.b_grad = hex2num(copytext(new_grad, 6, 8))
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["grad_color"])
|
||||
if(!has_flag(mob_species, HAS_HAIR_COLOR))
|
||||
return TOPIC_NOACTION
|
||||
var/new_grad = input(user, "Choose your character's secondary hair color:", "Character Preference", rgb(pref.r_grad, pref.g_grad, pref.b_grad)) as color|null
|
||||
if(new_grad && has_flag(mob_species, HAS_HAIR_COLOR) && CanUseTopic(user))
|
||||
pref.r_grad = hex2num(copytext(new_grad, 2, 4))
|
||||
pref.g_grad = hex2num(copytext(new_grad, 4, 6))
|
||||
pref.b_grad = hex2num(copytext(new_grad, 6, 8))
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["hair_style"])
|
||||
var/list/valid_hairstyles = pref.get_valid_hairstyles()
|
||||
|
||||
@@ -519,6 +536,14 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
pref.grad_style = new_grad_style
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["grad_style"])
|
||||
var/list/valid_gradients = GLOB.hair_gradients
|
||||
|
||||
var/new_grad_style = input(user, "Choose a color pattern for your hair:", "Character Preference", pref.grad_style) as null|anything in valid_gradients
|
||||
if(new_grad_style && CanUseTopic(user))
|
||||
pref.grad_style = new_grad_style
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["hair_style_left"])
|
||||
var/H = href_list["hair_style_left"]
|
||||
var/list/valid_hairstyles = pref.get_valid_hairstyles()
|
||||
@@ -977,6 +1002,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
dat += "</br><b>Does not have a respiratory system.</b>"
|
||||
if(current_species.flags & NO_SCAN)
|
||||
dat += "</br><b>Does not have DNA.</b>"
|
||||
if(current_species.flags & NO_DEFIB)
|
||||
dat += "</br><b>Cannot be defibrillated.</b>"
|
||||
if(current_species.flags & NO_PAIN)
|
||||
dat += "</br><b>Does not feel pain.</b>"
|
||||
if(current_species.flags & NO_SLIP)
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
S["ooccolor"] >> pref.ooccolor
|
||||
S["tooltipstyle"] >> pref.tooltipstyle
|
||||
S["client_fps"] >> pref.client_fps
|
||||
S["tgui_fancy"] >> pref.tgui_fancy
|
||||
S["tgui_lock"] >> pref.tgui_lock
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
|
||||
S["UI_style"] << pref.UI_style
|
||||
@@ -17,6 +19,8 @@
|
||||
S["ooccolor"] << pref.ooccolor
|
||||
S["tooltipstyle"] << pref.tooltipstyle
|
||||
S["client_fps"] << pref.client_fps
|
||||
S["tgui_fancy"] << pref.tgui_fancy
|
||||
S["tgui_lock"] << pref.tgui_lock
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
|
||||
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
|
||||
@@ -25,20 +29,24 @@
|
||||
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
|
||||
pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle))
|
||||
pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps))
|
||||
pref.tgui_fancy = sanitize_integer(pref.tgui_fancy, 0, 1, initial(pref.tgui_fancy))
|
||||
pref.tgui_lock = sanitize_integer(pref.tgui_lock, 0, 1, initial(pref.tgui_lock))
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
|
||||
. = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
|
||||
. += "<b>Custom UI</b> (recommended for White UI):<br>"
|
||||
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a> [color_square(hex = pref.UI_style_color)] <a href='?src=\ref[src];reset=ui'>reset</a><br>"
|
||||
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a> <a href='?src=\ref[src];reset=alpha'>reset</a><br>"
|
||||
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a>�[color_square(hex = pref.UI_style_color)]�<a href='?src=\ref[src];reset=ui'>reset</a><br>"
|
||||
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a>�<a href='?src=\ref[src];reset=alpha'>reset</a><br>"
|
||||
. += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>"
|
||||
. += "<b>Client FPS:</b> <a href='?src=\ref[src];select_client_fps=1'><b>[pref.client_fps]</b></a><br>"
|
||||
. += "<b>tgui Window Mode:</b> <a href='?src=\ref[src];tgui_fancy=1'><b>[(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]</b></a><br>"
|
||||
. += "<b>tgui Window Placement:</b> <a href='?src=\ref[src];tgui_lock=1'><b>[(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]</b></a><br>"
|
||||
if(can_select_ooc_color(user))
|
||||
. += "<b>OOC Color:</b> "
|
||||
. += "<b>OOC Color:</b>�"
|
||||
if(pref.ooccolor == initial(pref.ooccolor))
|
||||
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>"
|
||||
else
|
||||
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)] <a href='?src=\ref[src];reset=ooc'>reset</a><br>"
|
||||
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)]�<a href='?src=\ref[src];reset=ooc'>reset</a><br>"
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["select_style"])
|
||||
@@ -80,6 +88,14 @@
|
||||
pref.client.fps = fps_new
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["tgui_fancy"])
|
||||
pref.tgui_fancy = !pref.tgui_fancy
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["tgui_lock"])
|
||||
pref.tgui_lock = !pref.tgui_lock
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset"])
|
||||
switch(href_list["reset"])
|
||||
if("ui")
|
||||
|
||||
@@ -266,6 +266,18 @@ var/list/_client_preferences_by_type
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/status_indicators
|
||||
description = "Status Indicators"
|
||||
key = "SHOW_STATUS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/status_indicators/toggled(mob/preference_mob, enabled)
|
||||
. = ..()
|
||||
if(preference_mob && preference_mob.plane_holder)
|
||||
var/datum/plane_holder/PH = preference_mob.plane_holder
|
||||
PH.set_vis(VIS_STATUS, enabled)
|
||||
|
||||
/********************
|
||||
* Staff Preferences *
|
||||
********************/
|
||||
|
||||
@@ -279,3 +279,7 @@
|
||||
/datum/gear/accessory/cowledvest
|
||||
display_name = "cowled vest"
|
||||
path = /obj/item/clothing/accessory/cowledvest
|
||||
|
||||
/datum/gear/accessory/asymovercoat
|
||||
display_name = "orange asymmetrical overcoat"
|
||||
path = /obj/item/clothing/accessory/asymovercoat
|
||||
|
||||
@@ -627,6 +627,14 @@
|
||||
// J CKEYS
|
||||
|
||||
// K CKEYS
|
||||
//kbraid
|
||||
//Eili
|
||||
/datum/gear/fluff/kbraidgoggles
|
||||
path = /obj/item/clothing/glasses/fluff/avigoggles_yw
|
||||
display_name = "K'braid Aviation Goggles"
|
||||
description = "You're such a goggle head!"
|
||||
ckeywhitelist = list("kbraid")
|
||||
character_name = list("Eili") //Character name. this variable is required, or the item doesn't show in loadout. Change to "character_name = null" if not character restricted.
|
||||
|
||||
// L CKEYS
|
||||
|
||||
@@ -977,4 +985,4 @@
|
||||
|
||||
// Y CKEYS
|
||||
|
||||
// Z CKEYS
|
||||
// Z CKEYS
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/datum/gear/ball
|
||||
display_name = "tennis ball selection"
|
||||
description = "Choose from a num- BALL!"
|
||||
path = /obj/item/toy/tennis
|
||||
|
||||
/datum/gear/ball/New()
|
||||
..()
|
||||
var/list/balls = list()
|
||||
for(var/ball in typesof(/obj/item/toy/tennis/))
|
||||
var/obj/item/toy/tennis/ball_type = ball
|
||||
balls[initial(ball_type.name)] = ball_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls))
|
||||
@@ -366,4 +366,20 @@
|
||||
|
||||
/datum/gear/head/jingasa
|
||||
display_name = "jingasa"
|
||||
path = /obj/item/clothing/head/jingasa
|
||||
path = /obj/item/clothing/head/jingasa
|
||||
|
||||
/datum/gear/head/sunflower_crown
|
||||
display_name = "sunflower crown"
|
||||
path = /obj/item/clothing/head/sunflower_crown
|
||||
|
||||
/datum/gear/head/lavender_crown
|
||||
display_name = "lavender crown"
|
||||
path = /obj/item/clothing/head/lavender_crown
|
||||
|
||||
/datum/gear/head/poppy_crown
|
||||
display_name = "poppy crown"
|
||||
path = /obj/item/clothing/head/poppy_crown
|
||||
|
||||
/datum/gear/head/rose_crown
|
||||
display_name = "rose crown"
|
||||
path = /obj/item/clothing/head/rose_crown
|
||||
|
||||
@@ -20,4 +20,8 @@
|
||||
/datum/gear/mask/sterile
|
||||
display_name = "sterile mask"
|
||||
path = /obj/item/clothing/mask/surgical
|
||||
cost = 2
|
||||
cost = 2
|
||||
|
||||
/datum/gear/mask/veil
|
||||
display_name = "black veil"
|
||||
path = /obj/item/clothing/mask/veil
|
||||
@@ -556,4 +556,36 @@
|
||||
|
||||
/datum/gear/uniform/haltertop
|
||||
display_name = "halter top"
|
||||
path = /obj/item/clothing/under/haltertop
|
||||
path = /obj/item/clothing/under/haltertop
|
||||
|
||||
/datum/gear/uniform/revealingdress
|
||||
display_name = "revealing dress"
|
||||
path = /obj/item/clothing/under/dress/revealingdress
|
||||
|
||||
/datum/gear/uniform/rippedpunk
|
||||
display_name = "ripped punk jeans"
|
||||
path = /obj/item/clothing/under/rippedpunk
|
||||
|
||||
/datum/gear/uniform/gothic
|
||||
display_name = "gothic dress"
|
||||
path = /obj/item/clothing/under/dress/gothic
|
||||
|
||||
/datum/gear/uniform/formalred
|
||||
display_name = "formal red dress"
|
||||
path = /obj/item/clothing/under/dress/formalred
|
||||
|
||||
/datum/gear/uniform/pentagram
|
||||
display_name = "pentagram dress"
|
||||
path = /obj/item/clothing/under/dress/pentagram
|
||||
|
||||
/datum/gear/uniform/yellowswoop
|
||||
display_name = "yellow swooped dress"
|
||||
path = /obj/item/clothing/under/dress/yellowswoop
|
||||
|
||||
/datum/gear/uniform/greenasym
|
||||
display_name = "green asymmetrical jumpsuit"
|
||||
path = /obj/item/clothing/under/greenasym
|
||||
|
||||
/datum/gear/uniform/cyberpunkharness
|
||||
display_name = "cyberpunk strapped harness"
|
||||
path = /obj/item/clothing/under/cyberpunkharness
|
||||
@@ -32,4 +32,188 @@
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/hooded/teshari/standard))
|
||||
var/obj/item/clothing/suit/storage/seromi/cloak/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/beltcloak
|
||||
display_name = "belted cloak selection (Teshari)"
|
||||
path = /obj/item/clothing/suit/storage/seromi/beltcloak/standard
|
||||
whitelisted = SPECIES_TESHARI
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/suit/beltcloak/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/beltcloak/standard))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/standard/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/uniform/beltcloakcolor/New()
|
||||
..()
|
||||
gear_tweaks = list(gear_tweak_free_color_choice)
|
||||
|
||||
/datum/gear/suit/cloakcolor
|
||||
display_name = "belted cloak, recolorable (Teshari)"
|
||||
path = /obj/item/clothing/suit/storage/seromi/beltcloak/standard/white_grey
|
||||
whitelisted = SPECIES_TESHARI
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/suit/dept/beltcloak/
|
||||
whitelisted = SPECIES_TESHARI
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/suit/dept/beltcloak/wrdn
|
||||
display_name = "warden belted cloak (Teshari)"
|
||||
path = /obj/item/clothing/suit/storage/seromi/beltcloak/jobs/wrdn
|
||||
allowed_roles = list("Head of Security","Warden")
|
||||
|
||||
/datum/gear/suit/dept/beltcloak/hos
|
||||
display_name = "Chief of Security belted cloak (Teshari)"
|
||||
path = /obj/item/clothing/suit/storage/seromi/beltcloak/jobs/hos
|
||||
allowed_roles = list("Head of Security")
|
||||
|
||||
/datum/gear/suit/dept/beltcloak/jani
|
||||
display_name = "janitor belted cloak (Teshari)"
|
||||
path = /obj/item/clothing/suit/storage/seromi/beltcloak/jobs/jani
|
||||
allowed_roles = list("Janitor")
|
||||
|
||||
/datum/gear/suit/dept/cloak/command/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/command,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/command))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/cargo/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/cargo,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cargo))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/mining/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/mining,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/mining))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/qm/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/qm,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/qm))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/security/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/sec,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/sec))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/service/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/service,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/service))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/ce/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/ce,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/ce))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/engineer/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/eningeer,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/eningeer))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/atmos/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/atmos,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/atmos))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/research/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/sci,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/sci))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/robo/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/robo,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/robo))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/cmo/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/cmo,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cmo))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/medical/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/medical,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/medical))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/chemistry/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/chemistry,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/chemistry))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/virology/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/viro,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/viro))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/paramedic/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/para,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/para))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/suit/dept/cloak/iaa/New()
|
||||
..()
|
||||
var/list/cloaks = list()
|
||||
for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/jobs/iaa,/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/iaa))
|
||||
var/obj/item/clothing/suit/storage/seromi/beltcloak/jobs/cloak_type = cloak
|
||||
cloaks[initial(cloak_type.name)] = cloak_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks))
|
||||
|
||||
/datum/gear/uniform/harness_white
|
||||
display_name = "white gear harness (Full Body Prosthetic, Diona)"
|
||||
path = /obj/item/clothing/under/harness_white
|
||||
sort_category = "Xenowear"
|
||||
@@ -24,6 +24,9 @@ datum/preferences
|
||||
var/tooltipstyle = "Midnight" //Style for popup tooltips
|
||||
var/client_fps = 0
|
||||
|
||||
var/tgui_fancy = TRUE
|
||||
var/tgui_lock = FALSE
|
||||
|
||||
//character preferences
|
||||
var/real_name //our character's name
|
||||
var/be_random_name = 0 //whether we are a random name every round
|
||||
|
||||
@@ -334,6 +334,19 @@
|
||||
You will have to reload VChat and/or reconnect to the server for these changes to take place. \
|
||||
VChat message persistence is not guaranteed if you change this again before the start of the next round.")
|
||||
|
||||
/client/verb/toggle_status_indicators()
|
||||
set name = "Toggle Status Indicators"
|
||||
set category = "Preferences"
|
||||
set desc = "Enable/Disable seeing status indicators over peoples' heads."
|
||||
|
||||
var/pref_path = /datum/client_preference/status_indicators
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/status_indicators)) ? "see" : "not see"] status indicators.")
|
||||
|
||||
feedback_add_details("admin_verb","TStatusIndicators")
|
||||
|
||||
|
||||
// Not attached to a pref datum because those are strict binary toggles
|
||||
/client/verb/toggle_examine_mode()
|
||||
|
||||
Reference in New Issue
Block a user