mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
[MIRROR] Revert "Revert "/tg/ preference datums part 1: take two"" (#8929)
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com> Co-authored-by: Kashargul <KashL@t-online.de> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -225,12 +225,15 @@
|
||||
|
||||
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
|
||||
prefs = preferences_datums[ckey]
|
||||
if(!prefs)
|
||||
if(prefs)
|
||||
prefs.client = src
|
||||
prefs.load_savefile() // just to make sure we have the latest data
|
||||
prefs.apply_all_client_preferences()
|
||||
else
|
||||
prefs = new /datum/preferences(src)
|
||||
preferences_datums[ckey] = prefs
|
||||
prefs.last_ip = address //these are gonna be used for banning
|
||||
prefs.last_id = computer_id //these are gonna be used for banning
|
||||
prefs.client = src // Only relevant if we reloaded it from the global list, otherwise prefs/New sets it
|
||||
|
||||
hook_vr("client_new",list(src)) //VOREStation Code. For now this only loads vore prefs, so better put before mob.Login() call but after normal prefs are loaded.
|
||||
|
||||
@@ -302,7 +305,7 @@
|
||||
alert = TRUE
|
||||
if(alert)
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(X.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||
if(X.prefs?.read_preference(/datum/preference/toggle/holder/play_adminhelp_ping))
|
||||
X << 'sound/voice/bcriminal.ogg' //ChompEDIT - back to beepsky
|
||||
window_flash(X)
|
||||
//VOREStation Edit end.
|
||||
@@ -522,6 +525,12 @@
|
||||
if(prefs)
|
||||
prefs.ShowChoices(usr)
|
||||
|
||||
/client/verb/game_options()
|
||||
set name = "Game Options"
|
||||
set category = "Preferences"
|
||||
if(prefs)
|
||||
prefs.tgui_interact(usr)
|
||||
|
||||
/client/proc/findJoinDate()
|
||||
var/list/http = world.Export("http://byond.com/members/[ckey]?format=text")
|
||||
if(!http)
|
||||
|
||||
@@ -4,17 +4,17 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None")
|
||||
name = "Basic"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/load_character(var/savefile/S)
|
||||
S["uplinklocation"] >> pref.uplinklocation
|
||||
S["exploit_record"] >> pref.exploit_record
|
||||
S["antag_faction"] >> pref.antag_faction
|
||||
S["antag_vis"] >> pref.antag_vis
|
||||
/datum/category_item/player_setup_item/antagonism/basic/load_character(list/save_data)
|
||||
pref.uplinklocation = save_data["uplinklocation"]
|
||||
pref.exploit_record = save_data["exploit_record"]
|
||||
pref.antag_faction = save_data["antag_faction"]
|
||||
pref.antag_vis = save_data["antag_vis"]
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/save_character(var/savefile/S)
|
||||
S["uplinklocation"] << pref.uplinklocation
|
||||
S["exploit_record"] << pref.exploit_record
|
||||
S["antag_faction"] << pref.antag_faction
|
||||
S["antag_vis"] << pref.antag_vis
|
||||
/datum/category_item/player_setup_item/antagonism/basic/save_character(list/save_data)
|
||||
save_data["uplinklocation"] = pref.uplinklocation
|
||||
save_data["exploit_record"] = pref.exploit_record
|
||||
save_data["antag_faction"] = pref.antag_faction
|
||||
save_data["antag_vis"] = pref.antag_vis
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/sanitize_character()
|
||||
pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation))
|
||||
|
||||
@@ -32,11 +32,11 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
|
||||
name = "Candidacy"
|
||||
sort_order = 2
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/load_character(var/savefile/S)
|
||||
S["be_special"] >> pref.be_special
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/load_character(list/save_data)
|
||||
pref.be_special = save_data["be_special"]
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/save_character(var/savefile/S)
|
||||
S["be_special"] << pref.be_special
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/save_character(list/save_data)
|
||||
save_data["be_special"] = pref.be_special
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/sanitize_character()
|
||||
pref.be_special = sanitize_integer(pref.be_special, 0, 16777215, initial(pref.be_special)) //VOREStation Edit - 24 bits of support
|
||||
|
||||
@@ -10,47 +10,47 @@
|
||||
name = "Basic"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
|
||||
S["real_name"] >> pref.real_name
|
||||
S["nickname"] >> pref.nickname
|
||||
S["name_is_always_random"] >> pref.be_random_name
|
||||
S["gender"] >> pref.biological_gender
|
||||
S["id_gender"] >> pref.identifying_gender
|
||||
S["age"] >> pref.age
|
||||
S["bday_month"] >> pref.bday_month
|
||||
S["bday_day"] >> pref.bday_day
|
||||
S["last_bday_note"] >> pref.last_birthday_notification
|
||||
S["bday_announce"] >> pref.bday_announce
|
||||
S["spawnpoint"] >> pref.spawnpoint
|
||||
S["OOC_Notes"] >> pref.metadata
|
||||
S["OOC_Notes_Likes"] >> pref.metadata_likes
|
||||
S["OOC_Notes_Disikes"] >> pref.metadata_dislikes
|
||||
//CHOMPEdit Start
|
||||
S["OOC_Notes_Maybes"] >> pref.metadata_maybes
|
||||
S["OOC_Notes_Favs"] >> pref.metadata_favs
|
||||
S["OOC_Notes_System"] >> pref.matadata_ooc_style
|
||||
//CHOMPEdit End
|
||||
/datum/category_item/player_setup_item/general/basic/load_character(list/save_data)
|
||||
pref.real_name = save_data["real_name"]
|
||||
pref.nickname = save_data["nickname"]
|
||||
pref.be_random_name = save_data["name_is_always_random"]
|
||||
pref.biological_gender = save_data["gender"]
|
||||
pref.identifying_gender = save_data["id_gender"]
|
||||
pref.age = save_data["age"]
|
||||
pref.bday_month = save_data["bday_month"]
|
||||
pref.bday_day = save_data["bday_day"]
|
||||
pref.last_birthday_notification = save_data["last_bday_note"]
|
||||
pref.bday_announce = save_data["bday_announce"]
|
||||
pref.spawnpoint = save_data["spawnpoint"]
|
||||
pref.metadata = save_data["OOC_Notes"]
|
||||
pref.metadata_likes = save_data["OOC_Notes_Likes"]
|
||||
pref.metadata_dislikes = save_data["OOC_Notes_Disikes"]
|
||||
//CHOMPAdd Start
|
||||
pref.metadata_maybes = save_data["OOC_Notes_Maybes"]
|
||||
pref.metadata_favs = save_data["OOC_Notes_Favs"]
|
||||
pref.matadata_ooc_style = save_data["OOC_Notes_System"]
|
||||
//CHOMPAdd End
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S)
|
||||
S["real_name"] << pref.real_name
|
||||
S["nickname"] << pref.nickname
|
||||
S["name_is_always_random"] << pref.be_random_name
|
||||
S["gender"] << pref.biological_gender
|
||||
S["id_gender"] << pref.identifying_gender
|
||||
S["age"] << pref.age
|
||||
S["bday_month"] << pref.bday_month
|
||||
S["bday_day"] << pref.bday_day
|
||||
S["last_bday_note"] << pref.last_birthday_notification
|
||||
S["bday_announce"] << pref.bday_announce
|
||||
S["spawnpoint"] << pref.spawnpoint
|
||||
S["OOC_Notes"] << pref.metadata
|
||||
S["OOC_Notes_Likes"] << pref.metadata_likes
|
||||
S["OOC_Notes_Disikes"] << pref.metadata_dislikes
|
||||
//CHOMPEdit Start
|
||||
S["OOC_Notes_Favs"] << pref.metadata_favs
|
||||
S["OOC_Notes_Maybes"] << pref.metadata_maybes
|
||||
S["OOC_Notes_System"] << pref.matadata_ooc_style
|
||||
//CHOMPEdit End
|
||||
/datum/category_item/player_setup_item/general/basic/save_character(list/save_data)
|
||||
save_data["real_name"] = pref.real_name
|
||||
save_data["nickname"] = pref.nickname
|
||||
save_data["name_is_always_random"] = pref.be_random_name
|
||||
save_data["gender"] = pref.biological_gender
|
||||
save_data["id_gender"] = pref.identifying_gender
|
||||
save_data["age"] = pref.age
|
||||
save_data["bday_month"] = pref.bday_month
|
||||
save_data["bday_day"] = pref.bday_day
|
||||
save_data["last_bday_note"] = pref.last_birthday_notification
|
||||
save_data["bday_announce"] = pref.bday_announce
|
||||
save_data["spawnpoint"] = pref.spawnpoint
|
||||
save_data["OOC_Notes"] = pref.metadata
|
||||
save_data["OOC_Notes_Likes"] = pref.metadata_likes
|
||||
save_data["OOC_Notes_Disikes"] = pref.metadata_dislikes
|
||||
//CHOMPAdd Start
|
||||
save_data["OOC_Notes_Maybes"] = pref.metadata_maybes
|
||||
save_data["OOC_Notes_Favs"] = pref.metadata_favs
|
||||
save_data["OOC_Notes_System"] = pref.matadata_ooc_style
|
||||
//CHOMPAdd End
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/sanitize_character()
|
||||
pref.age = sanitize_integer(pref.age, get_min_age(), get_max_age(), initial(pref.age))
|
||||
|
||||
@@ -7,28 +7,20 @@
|
||||
sort_order = 2
|
||||
var/static/list/forbidden_prefixes = list(";", ":", ".", "!", "*", "^", "-")
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/load_character(var/savefile/S)
|
||||
S["language"] >> pref.alternate_languages
|
||||
S["extra_languages"] >> pref.extra_languages
|
||||
if(islist(pref.alternate_languages)) // Because aparently it may not be?
|
||||
testing("LANGSANI: Loaded from [pref.client]'s character [pref.real_name || "-name not yet loaded-"] savefile: [english_list(pref.alternate_languages || list())]")
|
||||
S["language_prefixes"] >> pref.language_prefixes
|
||||
//CHOMPEdit Begin
|
||||
S["species"] >> pref.species
|
||||
//CHOMPEdit End
|
||||
//VORE Edit Begin
|
||||
S["preflang"] >> pref.preferred_language
|
||||
//VORE Edit End
|
||||
S["language_custom_keys"] >> pref.language_custom_keys
|
||||
/datum/category_item/player_setup_item/general/language/load_character(list/save_data)
|
||||
pref.alternate_languages = save_data["language"]
|
||||
pref.extra_languages = save_data["extra_languages"]
|
||||
pref.language_prefixes = save_data["language_prefixes"]
|
||||
pref.species = save_data["species"] //CHOMPAdd
|
||||
pref.preferred_language = save_data["preflang"]
|
||||
pref.language_custom_keys = save_data["language_custom_keys"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/save_character(var/savefile/S)
|
||||
S["language"] << pref.alternate_languages
|
||||
S["extra_languages"] << pref.extra_languages
|
||||
if(islist(pref.alternate_languages)) // Because aparently it may not be?
|
||||
testing("LANGSANI: Loaded from [pref.client]'s character [pref.real_name || "-name not yet loaded-"] savefile: [english_list(pref.alternate_languages || list())]")
|
||||
S["language_prefixes"] << pref.language_prefixes
|
||||
S["language_custom_keys"] << pref.language_custom_keys
|
||||
S["preflang"] << pref.preferred_language // VOREStation Edit
|
||||
/datum/category_item/player_setup_item/general/language/save_character(list/save_data)
|
||||
save_data["language"] = pref.alternate_languages
|
||||
save_data["extra_languages"] = pref.extra_languages
|
||||
save_data["language_prefixes"] = pref.language_prefixes
|
||||
save_data["language_custom_keys"] = pref.language_custom_keys
|
||||
save_data["preflang"] = pref.preferred_language
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/sanitize_character()
|
||||
if(!islist(pref.alternate_languages)) pref.alternate_languages = list()
|
||||
|
||||
@@ -90,152 +90,151 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
name = "Body"
|
||||
sort_order = 3
|
||||
|
||||
/datum/category_item/player_setup_item/general/body/load_character(var/savefile/S)
|
||||
S["species"] >> pref.species
|
||||
S["hair_red"] >> pref.r_hair
|
||||
S["hair_green"] >> pref.g_hair
|
||||
S["hair_blue"] >> pref.b_hair
|
||||
S["grad_red"] >> pref.r_grad
|
||||
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
|
||||
S["skin_red"] >> pref.r_skin
|
||||
S["skin_green"] >> pref.g_skin
|
||||
S["skin_blue"] >> pref.b_skin
|
||||
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
|
||||
S["b_type"] >> pref.b_type
|
||||
S["disabilities"] >> pref.disabilities
|
||||
S["organ_data"] >> pref.organ_data
|
||||
S["rlimb_data"] >> pref.rlimb_data
|
||||
S["body_markings"] >> pref.body_markings
|
||||
S["synth_color"] >> pref.synth_color
|
||||
S["synth_red"] >> pref.r_synth
|
||||
S["synth_green"] >> pref.g_synth
|
||||
S["synth_blue"] >> pref.b_synth
|
||||
S["synth_markings"] >> pref.synth_markings
|
||||
S["bgstate"] >> pref.bgstate
|
||||
S["body_descriptors"] >> pref.body_descriptors
|
||||
S["Wingdings"] >> pref.wingdings //YWadd start
|
||||
S["colorblind_mono"] >> pref.colorblind_mono
|
||||
S["colorblind_vulp"] >> pref.colorblind_vulp
|
||||
S["colorblind_taj"] >> pref.colorblind_taj
|
||||
S["haemophilia"] >> pref.haemophilia //YWadd end
|
||||
S["ear_style"] >> pref.ear_style
|
||||
S["r_ears"] >> pref.r_ears
|
||||
S["g_ears"] >> pref.g_ears
|
||||
S["b_ears"] >> pref.b_ears
|
||||
S["r_ears2"] >> pref.r_ears2
|
||||
S["g_ears2"] >> pref.g_ears2
|
||||
S["b_ears2"] >> pref.b_ears2
|
||||
S["r_ears3"] >> pref.r_ears3
|
||||
S["g_ears3"] >> pref.g_ears3
|
||||
S["b_ears3"] >> pref.b_ears3
|
||||
S["tail_style"] >> pref.tail_style
|
||||
S["r_tail"] >> pref.r_tail
|
||||
S["g_tail"] >> pref.g_tail
|
||||
S["b_tail"] >> pref.b_tail
|
||||
S["r_tail2"] >> pref.r_tail2
|
||||
S["g_tail2"] >> pref.g_tail2
|
||||
S["b_tail2"] >> pref.b_tail2
|
||||
S["r_tail3"] >> pref.r_tail3
|
||||
S["g_tail3"] >> pref.g_tail3
|
||||
S["b_tail3"] >> pref.b_tail3
|
||||
S["wing_style"] >> pref.wing_style
|
||||
S["r_wing"] >> pref.r_wing
|
||||
S["g_wing"] >> pref.g_wing
|
||||
S["b_wing"] >> pref.b_wing
|
||||
S["r_wing2"] >> pref.r_wing2
|
||||
S["g_wing2"] >> pref.g_wing2
|
||||
S["b_wing2"] >> pref.b_wing2
|
||||
S["r_wing3"] >> pref.r_wing3
|
||||
S["g_wing3"] >> pref.g_wing3
|
||||
S["b_wing3"] >> pref.b_wing3
|
||||
S["digitigrade"] >> pref.digitigrade
|
||||
/datum/category_item/player_setup_item/general/body/load_character(list/save_data)
|
||||
pref.species = save_data["species"]
|
||||
pref.r_hair = save_data["hair_red"]
|
||||
pref.g_hair = save_data["hair_green"]
|
||||
pref.b_hair = save_data["hair_blue"]
|
||||
pref.r_facial = save_data["facial_red"]
|
||||
pref.r_grad = save_data["grad_red"]
|
||||
pref.g_grad = save_data["grad_green"]
|
||||
pref.b_grad = save_data["grad_blue"]
|
||||
pref.g_facial = save_data["facial_green"]
|
||||
pref.b_facial = save_data["facial_blue"]
|
||||
pref.s_tone = save_data["skin_tone"]
|
||||
pref.r_skin = save_data["skin_red"]
|
||||
pref.g_skin = save_data["skin_green"]
|
||||
pref.b_skin = save_data["skin_blue"]
|
||||
pref.h_style = save_data["hair_style_name"]
|
||||
pref.f_style = save_data["facial_style_name"]
|
||||
pref.grad_style = save_data["grad_style_name"]
|
||||
pref.r_eyes = save_data["eyes_red"]
|
||||
pref.g_eyes = save_data["eyes_green"]
|
||||
pref.b_eyes = save_data["eyes_blue"]
|
||||
pref.b_type = save_data["b_type"]
|
||||
pref.disabilities = save_data["disabilities"]
|
||||
pref.organ_data = save_data["organ_data"]
|
||||
pref.rlimb_data = save_data["rlimb_data"]
|
||||
pref.body_markings = save_data["body_markings"]
|
||||
pref.synth_color = save_data["synth_color"]
|
||||
pref.r_synth = save_data["synth_red"]
|
||||
pref.g_synth = save_data["synth_green"]
|
||||
pref.b_synth = save_data["synth_blue"]
|
||||
pref.synth_markings = save_data["synth_markings"]
|
||||
pref.bgstate = save_data["bgstate"]
|
||||
pref.body_descriptors = save_data["body_descriptors"]
|
||||
//YWadd start
|
||||
pref.wingdings = save_data["Wingdings"]
|
||||
pref.colorblind_mono = save_data["colorblind_mono"]
|
||||
pref.colorblind_vulp = save_data["colorblind_vulp"]
|
||||
pref.colorblind_taj = save_data["colorblind_taj"]
|
||||
pref.haemophilia = save_data["haemophilia"]
|
||||
//YWadd end
|
||||
pref.ear_style = save_data["ear_style"]
|
||||
pref.r_ears = save_data["r_ears"]
|
||||
pref.g_ears = save_data["g_ears"]
|
||||
pref.b_ears = save_data["b_ears"]
|
||||
pref.r_ears2 = save_data["r_ears2"]
|
||||
pref.g_ears2 = save_data["g_ears2"]
|
||||
pref.b_ears2 = save_data["b_ears2"]
|
||||
pref.r_ears3 = save_data["r_ears3"]
|
||||
pref.g_ears3 = save_data["g_ears3"]
|
||||
pref.b_ears3 = save_data["b_ears3"]
|
||||
pref.tail_style = save_data["tail_style"]
|
||||
pref.r_tail = save_data["r_tail"]
|
||||
pref.g_tail = save_data["g_tail"]
|
||||
pref.b_tail = save_data["b_tail"]
|
||||
pref.r_tail2 = save_data["r_tail2"]
|
||||
pref.g_tail2 = save_data["g_tail2"]
|
||||
pref.b_tail2 = save_data["b_tail2"]
|
||||
pref.r_tail3 = save_data["r_tail3"]
|
||||
pref.g_tail3 = save_data["g_tail3"]
|
||||
pref.b_tail3 = save_data["b_tail3"]
|
||||
pref.wing_style = save_data["wing_style"]
|
||||
pref.r_wing = save_data["r_wing"]
|
||||
pref.g_wing = save_data["g_wing"]
|
||||
pref.b_wing = save_data["b_wing"]
|
||||
pref.r_wing2 = save_data["r_wing2"]
|
||||
pref.g_wing2 = save_data["g_wing2"]
|
||||
pref.b_wing2 = save_data["b_wing2"]
|
||||
pref.r_wing3 = save_data["r_wing3"]
|
||||
pref.g_wing3 = save_data["g_wing3"]
|
||||
pref.b_wing3 = save_data["b_wing3"]
|
||||
pref.digitigrade = save_data["digitigrade"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/body/save_character(var/savefile/S)
|
||||
S["species"] << pref.species
|
||||
S["hair_red"] << pref.r_hair
|
||||
S["hair_green"] << pref.g_hair
|
||||
S["hair_blue"] << pref.b_hair
|
||||
S["grad_red"] << pref.r_grad
|
||||
S["grad_green"] << pref.g_grad
|
||||
S["grad_blue"] << pref.b_grad
|
||||
S["facial_red"] << pref.r_facial
|
||||
S["facial_green"] << pref.g_facial
|
||||
S["facial_blue"] << pref.b_facial
|
||||
S["skin_tone"] << pref.s_tone
|
||||
S["skin_red"] << pref.r_skin
|
||||
S["skin_green"] << pref.g_skin
|
||||
S["skin_blue"] << pref.b_skin
|
||||
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
|
||||
S["b_type"] << pref.b_type
|
||||
S["disabilities"] << pref.disabilities
|
||||
S["organ_data"] << pref.organ_data
|
||||
S["rlimb_data"] << pref.rlimb_data
|
||||
S["body_markings"] << pref.body_markings
|
||||
S["synth_color"] << pref.synth_color
|
||||
S["synth_red"] << pref.r_synth
|
||||
S["synth_green"] << pref.g_synth
|
||||
S["synth_blue"] << pref.b_synth
|
||||
S["synth_markings"] << pref.synth_markings
|
||||
S["bgstate"] << pref.bgstate
|
||||
S["body_descriptors"] << pref.body_descriptors
|
||||
S["Wingdings"] << pref.wingdings //YWadd start
|
||||
S["colorblind_mono"] << pref.colorblind_mono
|
||||
S["colorblind_vulp"] << pref.colorblind_vulp
|
||||
S["colorblind_taj"] << pref.colorblind_taj
|
||||
S["haemophilia"] << pref.haemophilia //YWadd end
|
||||
S["ear_style"] << pref.ear_style
|
||||
S["r_ears"] << pref.r_ears
|
||||
S["g_ears"] << pref.g_ears
|
||||
S["b_ears"] << pref.b_ears
|
||||
S["r_ears2"] << pref.r_ears2
|
||||
S["g_ears2"] << pref.g_ears2
|
||||
S["b_ears2"] << pref.b_ears2
|
||||
S["r_ears3"] << pref.r_ears3
|
||||
S["g_ears3"] << pref.g_ears3
|
||||
S["b_ears3"] << pref.b_ears3
|
||||
S["tail_style"] << pref.tail_style
|
||||
S["r_tail"] << pref.r_tail
|
||||
S["g_tail"] << pref.g_tail
|
||||
S["b_tail"] << pref.b_tail
|
||||
S["r_tail2"] << pref.r_tail2
|
||||
S["g_tail2"] << pref.g_tail2
|
||||
S["b_tail2"] << pref.b_tail2
|
||||
S["r_tail3"] << pref.r_tail3
|
||||
S["g_tail3"] << pref.g_tail3
|
||||
S["b_tail3"] << pref.b_tail3
|
||||
S["wing_style"] << pref.wing_style
|
||||
S["r_wing"] << pref.r_wing
|
||||
S["g_wing"] << pref.g_wing
|
||||
S["b_wing"] << pref.b_wing
|
||||
S["r_wing2"] << pref.r_wing2
|
||||
S["g_wing2"] << pref.g_wing2
|
||||
S["b_wing2"] << pref.b_wing2
|
||||
S["r_wing3"] << pref.r_wing3
|
||||
S["g_wing3"] << pref.g_wing3
|
||||
S["b_wing3"] << pref.b_wing3
|
||||
S["digitigrade"] << pref.digitigrade
|
||||
/datum/category_item/player_setup_item/general/body/save_character(list/save_data)
|
||||
save_data["species"] = pref.species
|
||||
save_data["hair_red"] = pref.r_hair
|
||||
save_data["hair_green"] = pref.g_hair
|
||||
save_data["hair_blue"] = pref.b_hair
|
||||
save_data["grad_red"] = pref.r_grad
|
||||
save_data["grad_green"] = pref.g_grad
|
||||
save_data["grad_blue"] = pref.b_grad
|
||||
save_data["facial_red"] = pref.r_facial
|
||||
save_data["facial_green"] = pref.g_facial
|
||||
save_data["facial_blue"] = pref.b_facial
|
||||
save_data["skin_tone"] = pref.s_tone
|
||||
save_data["skin_red"] = pref.r_skin
|
||||
save_data["skin_green"] = pref.g_skin
|
||||
save_data["skin_blue"] = pref.b_skin
|
||||
save_data["hair_style_name"] = pref.h_style
|
||||
save_data["facial_style_name"] = pref.f_style
|
||||
save_data["grad_style_name"] = pref.grad_style
|
||||
save_data["eyes_red"] = pref.r_eyes
|
||||
save_data["eyes_green"] = pref.g_eyes
|
||||
save_data["eyes_blue"] = pref.b_eyes
|
||||
save_data["b_type"] = pref.b_type
|
||||
save_data["disabilities"] = pref.disabilities
|
||||
save_data["organ_data"] = pref.organ_data
|
||||
save_data["rlimb_data"] = pref.rlimb_data
|
||||
save_data["body_markings"] = pref.body_markings
|
||||
save_data["synth_color"] = pref.synth_color
|
||||
save_data["synth_red"] = pref.r_synth
|
||||
save_data["synth_green"] = pref.g_synth
|
||||
save_data["synth_blue"] = pref.b_synth
|
||||
save_data["synth_markings"] = pref.synth_markings
|
||||
save_data["bgstate"] = pref.bgstate
|
||||
save_data["body_descriptors"] = pref.body_descriptors
|
||||
//YWadd start
|
||||
save_data["Wingdings"] = pref.wingdings
|
||||
save_data["colorblind_mono"] = pref.colorblind_mono
|
||||
save_data["colorblind_vulp"] = pref.colorblind_vulp
|
||||
save_data["colorblind_taj"] = pref.colorblind_taj
|
||||
save_data["haemophilia"] = pref.haemophilia
|
||||
//YWadd end
|
||||
save_data["ear_style"] = pref.ear_style
|
||||
save_data["r_ears"] = pref.r_ears
|
||||
save_data["g_ears"] = pref.g_ears
|
||||
save_data["b_ears"] = pref.b_ears
|
||||
save_data["r_ears2"] = pref.r_ears2
|
||||
save_data["g_ears2"] = pref.g_ears2
|
||||
save_data["b_ears2"] = pref.b_ears2
|
||||
save_data["r_ears3"] = pref.r_ears3
|
||||
save_data["g_ears3"] = pref.g_ears3
|
||||
save_data["b_ears3"] = pref.b_ears3
|
||||
save_data["tail_style"] = pref.tail_style
|
||||
save_data["r_tail"] = pref.r_tail
|
||||
save_data["g_tail"] = pref.g_tail
|
||||
save_data["b_tail"] = pref.b_tail
|
||||
save_data["r_tail2"] = pref.r_tail2
|
||||
save_data["g_tail2"] = pref.g_tail2
|
||||
save_data["b_tail2"] = pref.b_tail2
|
||||
save_data["r_tail3"] = pref.r_tail3
|
||||
save_data["g_tail3"] = pref.g_tail3
|
||||
save_data["b_tail3"] = pref.b_tail3
|
||||
save_data["wing_style"] = pref.wing_style
|
||||
save_data["r_wing"] = pref.r_wing
|
||||
save_data["g_wing"] = pref.g_wing
|
||||
save_data["b_wing"] = pref.b_wing
|
||||
save_data["r_wing2"] = pref.r_wing2
|
||||
save_data["g_wing2"] = pref.g_wing2
|
||||
save_data["b_wing2"] = pref.b_wing2
|
||||
save_data["r_wing3"] = pref.r_wing3
|
||||
save_data["g_wing3"] = pref.g_wing3
|
||||
save_data["b_wing3"] = pref.b_wing3
|
||||
save_data["digitigrade"] = pref.digitigrade
|
||||
|
||||
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/general/body/sanitize_character()
|
||||
if(!pref.species || !(pref.species in GLOB.playable_species))
|
||||
pref.species = SPECIES_HUMAN
|
||||
pref.r_hair = sanitize_integer(pref.r_hair, 0, 255, initial(pref.r_hair))
|
||||
@@ -539,11 +538,17 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
++ind
|
||||
if(ind > 1)
|
||||
. += ", "
|
||||
var/datum/robolimb/R
|
||||
if(pref.rlimb_data[name] && all_robolimbs[pref.rlimb_data[name]])
|
||||
R = all_robolimbs[pref.rlimb_data[name]]
|
||||
|
||||
var/datum/robolimb/R = basic_robolimb
|
||||
var/key = pref.rlimb_data[name]
|
||||
if(!istext(key))
|
||||
log_debug("Bad rlimb_data for [key_name(pref.client)], [name] was set to [key]")
|
||||
to_chat(usr, span_warning("Error loading robot limb data for `[name]`, clearing pref."))
|
||||
pref.rlimb_data -= name
|
||||
else
|
||||
R = basic_robolimb
|
||||
R = LAZYACCESS(all_robolimbs, key)
|
||||
if(!istype(R))
|
||||
R = basic_robolimb
|
||||
. += "\t[R.company] [organ_name] prosthesis"
|
||||
else if(status == "amputated")
|
||||
++ind
|
||||
|
||||
@@ -6,23 +6,23 @@
|
||||
name = "Clothing"
|
||||
sort_order = 4
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/load_character(var/savefile/S)
|
||||
S["all_underwear"] >> pref.all_underwear
|
||||
S["all_underwear_metadata"] >> pref.all_underwear_metadata
|
||||
S["backbag"] >> pref.backbag
|
||||
S["pdachoice"] >> pref.pdachoice
|
||||
S["communicator_visibility"] >> pref.communicator_visibility
|
||||
S["ttone"] >> pref.ringtone // CHOMPEdit - We use ttone in the pref so that it doesnt get reset
|
||||
//S["shoe_hater"] >> pref.shoe_hater //RS ADD //CHOMPRemove, remove RS No shoes
|
||||
/datum/category_item/player_setup_item/general/equipment/load_character(list/save_data)
|
||||
pref.all_underwear = save_data["all_underwear"]
|
||||
pref.all_underwear_metadata = save_data["all_underwear_metadata"]
|
||||
pref.backbag = save_data["backbag"]
|
||||
pref.pdachoice = save_data["pdachoice"]
|
||||
pref.communicator_visibility = save_data["communicator_visibility"]
|
||||
pref.ringtone = save_data["ttone"] // CHOMPEdit - We use ttone in the pref so that it doesnt get reset
|
||||
//pref.shoe_hater = save_data["shoe_hater"] //CHOMPRemove, remove RS No shoes
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/save_character(var/savefile/S)
|
||||
S["all_underwear"] << pref.all_underwear
|
||||
S["all_underwear_metadata"] << pref.all_underwear_metadata
|
||||
S["backbag"] << pref.backbag
|
||||
S["pdachoice"] << pref.pdachoice
|
||||
S["communicator_visibility"] << pref.communicator_visibility
|
||||
S["ttone"] << pref.ringtone // CHOMPEdit - We use ttone in the pref so that it doesnt get reset
|
||||
//S["shoe_hater"] << pref.shoe_hater //RS ADD //CHOMPRemove, remove RS No shoes
|
||||
/datum/category_item/player_setup_item/general/equipment/save_character(list/save_data)
|
||||
save_data["all_underwear"] = pref.all_underwear
|
||||
save_data["all_underwear_metadata"] = pref.all_underwear_metadata
|
||||
save_data["backbag"] = pref.backbag
|
||||
save_data["pdachoice"] = pref.pdachoice
|
||||
save_data["communicator_visibility"] = pref.communicator_visibility
|
||||
save_data["ttone"] = pref.ringtone // CHOMPEdit - We use ttone in the pref so that it doesnt get reset
|
||||
//save_data["shoe_hater"] = pref.shoe_hater //CHOMPRemove, remove RS No shoes
|
||||
|
||||
var/global/list/valid_ringtones = list(
|
||||
"beep",
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
/datum/category_item/player_setup_item/general/background
|
||||
name = "Background"
|
||||
sort_order = 5
|
||||
/datum/category_item/player_setup_item/general/background/load_character(list/save_data)
|
||||
pref.med_record = save_data["med_record"]
|
||||
pref.sec_record = save_data["sec_record"]
|
||||
pref.gen_record = save_data["gen_record"]
|
||||
pref.home_system = save_data["home_system"]
|
||||
pref.birthplace = save_data["birthplace"]
|
||||
pref.citizenship = save_data["citizenship"]
|
||||
pref.faction = save_data["faction"]
|
||||
pref.religion = save_data["religion"]
|
||||
pref.economic_status = save_data["economic_status"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/load_character(var/savefile/S)
|
||||
S["med_record"] >> pref.med_record
|
||||
S["sec_record"] >> pref.sec_record
|
||||
S["gen_record"] >> pref.gen_record
|
||||
S["home_system"] >> pref.home_system
|
||||
S["birthplace"] >> pref.birthplace
|
||||
S["citizenship"] >> pref.citizenship
|
||||
S["faction"] >> pref.faction
|
||||
S["religion"] >> pref.religion
|
||||
S["economic_status"] >> pref.economic_status
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/save_character(var/savefile/S)
|
||||
S["med_record"] << pref.med_record
|
||||
S["sec_record"] << pref.sec_record
|
||||
S["gen_record"] << pref.gen_record
|
||||
S["home_system"] << pref.home_system
|
||||
S["birthplace"] << pref.birthplace
|
||||
S["citizenship"] << pref.citizenship
|
||||
S["faction"] << pref.faction
|
||||
S["religion"] << pref.religion
|
||||
S["economic_status"] << pref.economic_status
|
||||
/datum/category_item/player_setup_item/general/background/save_character(list/save_data)
|
||||
save_data["med_record"] = pref.med_record
|
||||
save_data["sec_record"] = pref.sec_record
|
||||
save_data["gen_record"] = pref.gen_record
|
||||
save_data["home_system"] = pref.home_system
|
||||
save_data["birthplace"] = pref.birthplace
|
||||
save_data["citizenship"] = pref.citizenship
|
||||
save_data["faction"] = pref.faction
|
||||
save_data["religion"] = pref.religion
|
||||
save_data["economic_status"] = pref.economic_status
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/sanitize_character()
|
||||
if(!pref.home_system) pref.home_system = "Unset"
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
name = "Flavor"
|
||||
sort_order = 6
|
||||
|
||||
/datum/category_item/player_setup_item/general/flavor/load_character(var/savefile/S)
|
||||
S["flavor_texts_general"] >> pref.flavor_texts["general"]
|
||||
S["flavor_texts_head"] >> pref.flavor_texts["head"]
|
||||
S["flavor_texts_face"] >> pref.flavor_texts["face"]
|
||||
S["flavor_texts_eyes"] >> pref.flavor_texts["eyes"]
|
||||
S["flavor_texts_torso"] >> pref.flavor_texts["torso"]
|
||||
S["flavor_texts_arms"] >> pref.flavor_texts["arms"]
|
||||
S["flavor_texts_hands"] >> pref.flavor_texts["hands"]
|
||||
S["flavor_texts_legs"] >> pref.flavor_texts["legs"]
|
||||
S["flavor_texts_feet"] >> pref.flavor_texts["feet"]
|
||||
S["custom_link"] >> pref.custom_link
|
||||
/datum/category_item/player_setup_item/general/flavor/load_character(list/save_data)
|
||||
pref.flavor_texts["general"] = save_data["flavor_texts_general"]
|
||||
pref.flavor_texts["head"] = save_data["flavor_texts_head"]
|
||||
pref.flavor_texts["face"] = save_data["flavor_texts_face"]
|
||||
pref.flavor_texts["eyes"] = save_data["flavor_texts_eyes"]
|
||||
pref.flavor_texts["torso"] = save_data["flavor_texts_torso"]
|
||||
pref.flavor_texts["arms"] = save_data["flavor_texts_arms"]
|
||||
pref.flavor_texts["hands"] = save_data["flavor_texts_hands"]
|
||||
pref.flavor_texts["legs"] = save_data["flavor_texts_legs"]
|
||||
pref.flavor_texts["feet"] = save_data["flavor_texts_feet"]
|
||||
pref.custom_link = save_data["custom_link"]
|
||||
//Flavour text for robots.
|
||||
S["flavour_texts_robot_Default"] >> pref.flavour_texts_robot["Default"]
|
||||
pref.flavour_texts_robot["Default"] = save_data["flavour_texts_robot_Default"]
|
||||
for(var/module in robot_module_types)
|
||||
S["flavour_texts_robot_[module]"] >> pref.flavour_texts_robot[module]
|
||||
pref.flavour_texts_robot[module] = save_data["flavour_texts_robot_[module]"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/flavor/save_character(var/savefile/S)
|
||||
S["flavor_texts_general"] << pref.flavor_texts["general"]
|
||||
S["flavor_texts_head"] << pref.flavor_texts["head"]
|
||||
S["flavor_texts_face"] << pref.flavor_texts["face"]
|
||||
S["flavor_texts_eyes"] << pref.flavor_texts["eyes"]
|
||||
S["flavor_texts_torso"] << pref.flavor_texts["torso"]
|
||||
S["flavor_texts_arms"] << pref.flavor_texts["arms"]
|
||||
S["flavor_texts_hands"] << pref.flavor_texts["hands"]
|
||||
S["flavor_texts_legs"] << pref.flavor_texts["legs"]
|
||||
S["flavor_texts_feet"] << pref.flavor_texts["feet"]
|
||||
S["custom_link"] << pref.custom_link
|
||||
/datum/category_item/player_setup_item/general/flavor/save_character(list/save_data)
|
||||
save_data["flavor_texts_general"] = pref.flavor_texts["general"]
|
||||
save_data["flavor_texts_head"] = pref.flavor_texts["head"]
|
||||
save_data["flavor_texts_face"] = pref.flavor_texts["face"]
|
||||
save_data["flavor_texts_eyes"] = pref.flavor_texts["eyes"]
|
||||
save_data["flavor_texts_torso"] = pref.flavor_texts["torso"]
|
||||
save_data["flavor_texts_arms"] = pref.flavor_texts["arms"]
|
||||
save_data["flavor_texts_hands"] = pref.flavor_texts["hands"]
|
||||
save_data["flavor_texts_legs"] = pref.flavor_texts["legs"]
|
||||
save_data["flavor_texts_feet"] = pref.flavor_texts["feet"]
|
||||
save_data["custom_link"] = pref.custom_link
|
||||
|
||||
S["flavour_texts_robot_Default"] << pref.flavour_texts_robot["Default"]
|
||||
save_data["flavour_texts_robot_Default"] = pref.flavour_texts_robot["Default"]
|
||||
for(var/module in robot_module_types)
|
||||
S["flavour_texts_robot_[module]"] << pref.flavour_texts_robot[module]
|
||||
save_data["flavour_texts_robot_[module]"] = pref.flavour_texts_robot[module]
|
||||
|
||||
/datum/category_item/player_setup_item/general/flavor/sanitize_character()
|
||||
return
|
||||
|
||||
@@ -2,41 +2,41 @@
|
||||
name = "UI"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/load_preferences(var/savefile/S)
|
||||
S["UI_style"] >> pref.UI_style
|
||||
S["UI_style_color"] >> pref.UI_style_color
|
||||
S["UI_style_alpha"] >> pref.UI_style_alpha
|
||||
S["ooccolor"] >> pref.ooccolor
|
||||
S["tooltipstyle"] >> pref.tooltipstyle
|
||||
S["client_fps"] >> pref.client_fps
|
||||
S["ambience_freq"] >> pref.ambience_freq
|
||||
S["ambience_chance"] >> pref.ambience_chance
|
||||
S["tgui_fancy"] >> pref.tgui_fancy
|
||||
S["tgui_lock"] >> pref.tgui_lock
|
||||
S["tgui_input_mode"] >> pref.tgui_input_mode
|
||||
S["tgui_large_buttons"] >> pref.tgui_large_buttons
|
||||
S["tgui_swapped_buttons"] >> pref.tgui_swapped_buttons
|
||||
S["obfuscate_key"] >> pref.obfuscate_key
|
||||
S["obfuscate_job"] >> pref.obfuscate_job
|
||||
S["chat_timestamp"] >> pref.chat_timestamp
|
||||
/datum/category_item/player_setup_item/player_global/ui/load_preferences(datum/json_savefile/savefile)
|
||||
pref.UI_style = savefile.get_entry("UI_style")
|
||||
pref.UI_style_color = savefile.get_entry("UI_style_color")
|
||||
pref.UI_style_alpha = savefile.get_entry("UI_style_alpha")
|
||||
pref.ooccolor = savefile.get_entry("ooccolor")
|
||||
pref.tooltipstyle = savefile.get_entry("tooltipstyle")
|
||||
pref.client_fps = savefile.get_entry("client_fps")
|
||||
pref.ambience_freq = savefile.get_entry("ambience_freq")
|
||||
pref.ambience_chance = savefile.get_entry("ambience_chance")
|
||||
pref.tgui_fancy = savefile.get_entry("tgui_fancy")
|
||||
pref.tgui_lock = savefile.get_entry("tgui_lock")
|
||||
pref.tgui_input_mode = savefile.get_entry("tgui_input_mode")
|
||||
pref.tgui_large_buttons = savefile.get_entry("tgui_large_buttons")
|
||||
pref.tgui_swapped_buttons = savefile.get_entry("tgui_swapped_buttons")
|
||||
pref.obfuscate_key = savefile.get_entry("obfuscate_key")
|
||||
pref.obfuscate_job = savefile.get_entry("obfuscate_job")
|
||||
pref.chat_timestamp = savefile.get_entry("chat_timestamp")
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
|
||||
S["UI_style"] << pref.UI_style
|
||||
S["UI_style_color"] << pref.UI_style_color
|
||||
S["UI_style_alpha"] << pref.UI_style_alpha
|
||||
S["ooccolor"] << pref.ooccolor
|
||||
S["tooltipstyle"] << pref.tooltipstyle
|
||||
S["client_fps"] << pref.client_fps
|
||||
S["ambience_freq"] << pref.ambience_freq
|
||||
S["ambience_chance"] << pref.ambience_chance
|
||||
S["tgui_fancy"] << pref.tgui_fancy
|
||||
S["tgui_lock"] << pref.tgui_lock
|
||||
S["tgui_input_mode"] << pref.tgui_input_mode
|
||||
S["tgui_large_buttons"] << pref.tgui_large_buttons
|
||||
S["tgui_swapped_buttons"] << pref.tgui_swapped_buttons
|
||||
S["obfuscate_key"] << pref.obfuscate_key
|
||||
S["obfuscate_job"] << pref.obfuscate_job
|
||||
S["chat_timestamp"] << pref.chat_timestamp
|
||||
/datum/category_item/player_setup_item/player_global/ui/save_preferences(datum/json_savefile/savefile)
|
||||
savefile.set_entry("UI_style", pref.UI_style)
|
||||
savefile.set_entry("UI_style_color", pref.UI_style_color)
|
||||
savefile.set_entry("UI_style_alpha", pref.UI_style_alpha)
|
||||
savefile.set_entry("ooccolor", pref.ooccolor)
|
||||
savefile.set_entry("tooltipstyle", pref.tooltipstyle)
|
||||
savefile.set_entry("client_fps", pref.client_fps)
|
||||
savefile.set_entry("ambience_freq", pref.ambience_freq)
|
||||
savefile.set_entry("ambience_chance", pref.ambience_chance)
|
||||
savefile.set_entry("tgui_fancy", pref.tgui_fancy)
|
||||
savefile.set_entry("tgui_lock", pref.tgui_lock)
|
||||
savefile.set_entry("tgui_input_mode", pref.tgui_input_mode)
|
||||
savefile.set_entry("tgui_large_buttons", pref.tgui_large_buttons)
|
||||
savefile.set_entry("tgui_swapped_buttons", pref.tgui_swapped_buttons)
|
||||
savefile.set_entry("obfuscate_key", pref.obfuscate_key)
|
||||
savefile.set_entry("obfuscate_job", pref.obfuscate_job)
|
||||
savefile.set_entry("chat_timestamp", pref.chat_timestamp)
|
||||
|
||||
/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))
|
||||
|
||||
@@ -1,141 +1,20 @@
|
||||
/datum/preferences
|
||||
var/preferences_enabled = null
|
||||
var/preferences_disabled = null
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings
|
||||
name = "Settings"
|
||||
sort_order = 2
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings/load_preferences(var/savefile/S)
|
||||
S["lastchangelog"] >> pref.lastchangelog
|
||||
S["lastnews"] >> pref.lastnews
|
||||
S["lastlorenews"] >> pref.lastlorenews
|
||||
S["default_slot"] >> pref.default_slot
|
||||
S["preferences"] >> pref.preferences_enabled
|
||||
S["preferences_disabled"] >> pref.preferences_disabled
|
||||
/datum/category_item/player_setup_item/player_global/settings/load_preferences(datum/json_savefile/savefile)
|
||||
pref.lastchangelog = savefile.get_entry("lastchangelog")
|
||||
pref.lastnews = savefile.get_entry("lastnews")
|
||||
pref.lastlorenews = savefile.get_entry("lastlorenews")
|
||||
pref.default_slot = savefile.get_entry("default_slot")
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings/save_preferences(var/savefile/S)
|
||||
S["lastchangelog"] << pref.lastchangelog
|
||||
S["lastnews"] << pref.lastnews
|
||||
S["lastlorenews"] << pref.lastlorenews
|
||||
S["default_slot"] << pref.default_slot
|
||||
S["preferences"] << pref.preferences_enabled
|
||||
S["preferences_disabled"] << pref.preferences_disabled
|
||||
/datum/category_item/player_setup_item/player_global/settings/save_preferences(datum/json_savefile/savefile)
|
||||
savefile.set_entry("lastchangelog", pref.lastchangelog)
|
||||
savefile.set_entry("lastnews", pref.lastnews)
|
||||
savefile.set_entry("lastlorenews", pref.lastlorenews)
|
||||
savefile.set_entry("default_slot", pref.default_slot)
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings/sanitize_preferences()
|
||||
// Ensure our preferences are lists.
|
||||
if(!istype(pref.preferences_enabled, /list))
|
||||
pref.preferences_enabled = list()
|
||||
if(!istype(pref.preferences_disabled, /list))
|
||||
pref.preferences_disabled = list()
|
||||
|
||||
// Arrange preferences that have never been enabled/disabled.
|
||||
var/list/client_preference_keys = list()
|
||||
for(var/datum/client_preference/client_pref as anything in get_client_preferences())
|
||||
client_preference_keys += client_pref.key
|
||||
if((client_pref.key in pref.preferences_enabled) || (client_pref.key in pref.preferences_disabled))
|
||||
continue
|
||||
|
||||
if(client_pref.enabled_by_default)
|
||||
pref.preferences_enabled += client_pref.key
|
||||
else
|
||||
pref.preferences_disabled += client_pref.key
|
||||
|
||||
// Clean out preferences that no longer exist.
|
||||
for(var/key in pref.preferences_enabled)
|
||||
if(!(key in client_preference_keys))
|
||||
pref.preferences_enabled -= key
|
||||
for(var/key in pref.preferences_disabled)
|
||||
if(!(key in client_preference_keys))
|
||||
pref.preferences_disabled -= key
|
||||
|
||||
pref.lastchangelog = sanitize_text(pref.lastchangelog, initial(pref.lastchangelog))
|
||||
pref.lastnews = sanitize_text(pref.lastnews, initial(pref.lastnews))
|
||||
pref.default_slot = sanitize_integer(pref.default_slot, 1, CONFIG_GET(number/character_slots), initial(pref.default_slot)) // CHOMPEdit
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings/content(var/mob/user)
|
||||
. = list()
|
||||
. += "<b>Preferences</b><br>"
|
||||
. += "<table>"
|
||||
var/mob/pref_mob = preference_mob()
|
||||
for(var/datum/client_preference/client_pref as anything in get_client_preferences())
|
||||
if(!client_pref.may_toggle(pref_mob))
|
||||
continue
|
||||
|
||||
. += "<tr><td>[client_pref.description]: </td>"
|
||||
if(pref_mob.is_preference_enabled(client_pref.key))
|
||||
. += "<td><span class='linkOn'><b>[client_pref.enabled_description]</b></span></td> <td><a href='?src=\ref[src];toggle_off=[client_pref.key]'>[client_pref.disabled_description]</a></td>"
|
||||
else
|
||||
. += "<td><a href='?src=\ref[src];toggle_on=[client_pref.key]'>[client_pref.enabled_description]</a></td> <td><span class='linkOn'><b>[client_pref.disabled_description]</b></span></td>"
|
||||
. += "</tr>"
|
||||
|
||||
. += "</table>"
|
||||
return jointext(., "")
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/settings/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
var/mob/pref_mob = preference_mob()
|
||||
if(href_list["toggle_on"])
|
||||
. = pref_mob.set_preference(href_list["toggle_on"], TRUE)
|
||||
else if(href_list["toggle_off"])
|
||||
. = pref_mob.set_preference(href_list["toggle_off"], FALSE)
|
||||
if(.)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* This can take either a single preference datum or a list of preferences, and will return true if *all* preferences in the arguments are enabled.
|
||||
*/
|
||||
/client/proc/is_preference_enabled(var/preference)
|
||||
if(!islist(preference))
|
||||
preference = list(preference)
|
||||
for(var/p in preference)
|
||||
var/datum/client_preference/cp = get_client_preference(p)
|
||||
if(!prefs || !cp || !istype(cp, /datum/client_preference) || !(cp.key in prefs.preferences_enabled))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/client/proc/set_preference(var/preference, var/set_preference)
|
||||
var/datum/client_preference/cp = get_client_preference(preference)
|
||||
if(!cp)
|
||||
return FALSE
|
||||
preference = cp.key
|
||||
|
||||
if(set_preference && !(preference in prefs.preferences_enabled))
|
||||
return toggle_preference(cp)
|
||||
else if(!set_preference && (preference in prefs.preferences_enabled))
|
||||
return toggle_preference(cp)
|
||||
|
||||
/client/proc/toggle_preference(var/preference, var/set_preference)
|
||||
var/datum/client_preference/cp = get_client_preference(preference)
|
||||
if(!cp)
|
||||
return FALSE
|
||||
preference = cp.key
|
||||
|
||||
var/enabled
|
||||
if(preference in prefs.preferences_disabled)
|
||||
prefs.preferences_enabled |= preference
|
||||
prefs.preferences_disabled -= preference
|
||||
enabled = TRUE
|
||||
. = TRUE
|
||||
else if(preference in prefs.preferences_enabled)
|
||||
prefs.preferences_enabled -= preference
|
||||
prefs.preferences_disabled |= preference
|
||||
enabled = FALSE
|
||||
. = TRUE
|
||||
if(.)
|
||||
cp.toggled(mob, enabled)
|
||||
|
||||
/mob/proc/is_preference_enabled(var/preference)
|
||||
if(!client)
|
||||
return FALSE
|
||||
return client.is_preference_enabled(preference)
|
||||
|
||||
/mob/proc/set_preference(var/preference, var/set_preference)
|
||||
if(!client)
|
||||
return FALSE
|
||||
if(!client.prefs)
|
||||
log_debug("Client prefs found to be null for mob [src] and client [ckey], this should be investigated.")
|
||||
return FALSE
|
||||
|
||||
return client.set_preference(preference, set_preference)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
var/datum/paiCandidate/candidate
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/pai/load_preferences(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/player_global/pai/load_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
candidate = new()
|
||||
var/preference_mob = preference_mob()
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
candidate.savefile_load(preference_mob)
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/pai/save_preferences(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/player_global/pai/save_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
return
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
name = "OOC"
|
||||
sort_order = 4
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ooc/load_preferences(var/savefile/S)
|
||||
S["ignored_players"] >> pref.ignored_players
|
||||
/datum/category_item/player_setup_item/player_global/ooc/load_preferences(datum/json_savefile/savefile)
|
||||
pref.ignored_players = savefile.get_entry("ignored_players")
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/player_global/ooc/save_preferences(var/savefile/S)
|
||||
S["ignored_players"] << pref.ignored_players
|
||||
/datum/category_item/player_setup_item/player_global/ooc/save_preferences(datum/json_savefile/savefile)
|
||||
savefile.set_entry("ignored_players", pref.ignored_players)
|
||||
|
||||
/*
|
||||
/datum/category_item/player_setup_item/player_global/ooc/sanitize_preferences()
|
||||
@@ -39,4 +39,4 @@
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,503 +0,0 @@
|
||||
var/list/_client_preferences
|
||||
var/list/_client_preferences_by_key
|
||||
var/list/_client_preferences_by_type
|
||||
|
||||
/proc/get_client_preferences()
|
||||
if(!_client_preferences)
|
||||
_client_preferences = list()
|
||||
for(var/datum/client_preference/client_type as anything in subtypesof(/datum/client_preference))
|
||||
if(initial(client_type.description))
|
||||
_client_preferences += new client_type()
|
||||
return _client_preferences
|
||||
|
||||
/proc/get_client_preference(var/datum/client_preference/preference)
|
||||
if(istype(preference))
|
||||
return preference
|
||||
if(ispath(preference))
|
||||
return get_client_preference_by_type(preference)
|
||||
return get_client_preference_by_key(preference)
|
||||
|
||||
/proc/get_client_preference_by_key(var/preference)
|
||||
if(!_client_preferences_by_key)
|
||||
_client_preferences_by_key = list()
|
||||
for(var/datum/client_preference/client_pref as anything in get_client_preferences())
|
||||
_client_preferences_by_key[client_pref.key] = client_pref
|
||||
return _client_preferences_by_key[preference]
|
||||
|
||||
/proc/get_client_preference_by_type(var/preference)
|
||||
if(!_client_preferences_by_type)
|
||||
_client_preferences_by_type = list()
|
||||
for(var/datum/client_preference/client_pref as anything in get_client_preferences())
|
||||
_client_preferences_by_type[client_pref.type] = client_pref
|
||||
return _client_preferences_by_type[preference]
|
||||
|
||||
/datum/client_preference
|
||||
var/description
|
||||
var/key
|
||||
var/enabled_by_default = TRUE
|
||||
var/enabled_description = "Yes"
|
||||
var/disabled_description = "No"
|
||||
|
||||
/datum/client_preference/proc/may_toggle(var/mob/preference_mob)
|
||||
return TRUE
|
||||
|
||||
/datum/client_preference/proc/toggled(var/mob/preference_mob, var/enabled)
|
||||
return
|
||||
|
||||
/*********************
|
||||
* Player Preferences *
|
||||
*********************/
|
||||
|
||||
/datum/client_preference/play_admin_midis
|
||||
description ="Play admin midis"
|
||||
key = "SOUND_MIDI"
|
||||
|
||||
/datum/client_preference/play_lobby_music
|
||||
description ="Play lobby music"
|
||||
key = "SOUND_LOBBY"
|
||||
|
||||
/datum/client_preference/play_lobby_music/toggled(var/mob/preference_mob, var/enabled)
|
||||
if(!preference_mob.client || !preference_mob.client.media)
|
||||
return
|
||||
|
||||
if(enabled)
|
||||
preference_mob.client.playtitlemusic()
|
||||
else
|
||||
preference_mob.client.media.stop_music()
|
||||
|
||||
/datum/client_preference/play_ambiance
|
||||
description ="Play ambience"
|
||||
key = "SOUND_AMBIENCE"
|
||||
|
||||
/datum/client_preference/play_ambiance/toggled(var/mob/preference_mob, var/enabled)
|
||||
if(!enabled)
|
||||
preference_mob << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
|
||||
preference_mob << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
|
||||
//VOREStation Add - Need to put it here because it should be ordered riiiight here.
|
||||
/datum/client_preference/play_jukebox
|
||||
description ="Play jukebox music"
|
||||
key = "SOUND_JUKEBOX"
|
||||
|
||||
/datum/client_preference/play_jukebox/toggled(var/mob/preference_mob, var/enabled)
|
||||
if(!enabled)
|
||||
preference_mob.stop_all_music()
|
||||
else
|
||||
preference_mob.update_music()
|
||||
|
||||
/datum/client_preference/eating_noises
|
||||
description = "Eating Noises"
|
||||
key = "EATING_NOISES"
|
||||
enabled_description = "Noisy"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/digestion_noises
|
||||
description = "Digestion Noises"
|
||||
key = "DIGEST_NOISES"
|
||||
enabled_description = "Noisy"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/belch_noises // Belching noises - pref toggle for 'em
|
||||
description = "Burping"
|
||||
key = "BELCH_NOISES"
|
||||
enabled_description = "Noisy"
|
||||
disabled_description = "Silent"
|
||||
enabled_by_default = FALSE //CHOMPedit
|
||||
|
||||
/datum/client_preference/emote_noises
|
||||
description = "Emote Noises" //MERP
|
||||
key = "EMOTE_NOISES"
|
||||
enabled_description = "Noisy"
|
||||
disabled_description = "Silent"
|
||||
/datum/client_preference/whisubtle_vis
|
||||
description = "Whi/Subtles Ghost Visible"
|
||||
key = "WHISUBTLE_VIS"
|
||||
enabled_description = "Visible"
|
||||
disabled_description = "Hidden"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/ghost_see_whisubtle
|
||||
description = "See subtles/whispers as ghost"
|
||||
key = "GHOST_SEE_WHISUBTLE"
|
||||
enabled_description = "Visible"
|
||||
disabled_description = "Hidden"
|
||||
enabled_by_default = TRUE
|
||||
//VOREStation Add End
|
||||
/datum/client_preference/weather_sounds
|
||||
description ="Weather sounds"
|
||||
key = "SOUND_WEATHER"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/supermatter_hum
|
||||
description ="Supermatter hum"
|
||||
key = "SOUND_SUPERMATTER"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/ghost_ears
|
||||
description ="Ghost ears"
|
||||
key = "CHAT_GHOSTEARS"
|
||||
enabled_description = "All Speech"
|
||||
disabled_description = "Nearby"
|
||||
|
||||
/datum/client_preference/ghost_sight
|
||||
description ="Ghost sight"
|
||||
key = "CHAT_GHOSTSIGHT"
|
||||
enabled_description = "All Emotes"
|
||||
disabled_description = "Nearby"
|
||||
|
||||
/datum/client_preference/ghost_radio
|
||||
description ="Ghost radio"
|
||||
key = "CHAT_GHOSTRADIO"
|
||||
enabled_description = "All Chatter"
|
||||
disabled_description = "Nearby"
|
||||
|
||||
/datum/client_preference/chat_tags
|
||||
description ="Chat tags"
|
||||
key = "CHAT_SHOWICONS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/air_pump_noise
|
||||
description ="Air Pump Ambient Noise"
|
||||
key = "SOUND_AIRPUMP"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/looping_alarms // CHOMPStation Add: Looping Alarms
|
||||
description ="Looping Alarm Sounds"
|
||||
key = "SOUND_ALARMLOOP"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/fridge_hum // CHOMPStation Add: Misc Sounds
|
||||
description ="Fridge Humming"
|
||||
key = "SOUND_FRIDGEHUM"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/old_door_sounds
|
||||
description ="Old Door Sounds"
|
||||
key = "SOUND_OLDDOORS"
|
||||
enabled_description = "Old"
|
||||
disabled_description = "New"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/department_door_sounds
|
||||
description ="Department-Specific Door Sounds"
|
||||
key = "SOUND_DEPARTMENTDOORS"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/pickup_sounds
|
||||
description = "Picked Up Item Sounds"
|
||||
key = "SOUND_PICKED"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/drop_sounds
|
||||
description = "Dropped Item Sounds"
|
||||
key = "SOUND_DROPPED"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/mob_tooltips
|
||||
description ="Mob tooltips"
|
||||
key = "MOB_TOOLTIPS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/inv_tooltips
|
||||
description ="Inventory tooltips"
|
||||
key = "INV_TOOLTIPS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/attack_icons
|
||||
description ="Attack icons"
|
||||
key = "ATTACK_ICONS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/precision_placement
|
||||
description ="Precision Placement"
|
||||
key = "PRECISE_PLACEMENT"
|
||||
enabled_description = "Active"
|
||||
disabled_description = "Inactive"
|
||||
|
||||
/datum/client_preference/hotkeys_default
|
||||
description ="Hotkeys Default"
|
||||
key = "HUD_HOTKEYS"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
enabled_by_default = TRUE // Backwards compatibility //CHOMP Edit: It's 2020, use your WASD keys by default. Flipped to True.
|
||||
|
||||
/datum/client_preference/show_typing_indicator
|
||||
description ="Typing indicator"
|
||||
key = "SHOW_TYPING"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/show_typing_indicator/toggled(var/mob/preference_mob, var/enabled)
|
||||
if(!enabled)
|
||||
preference_mob.client?.stop_thinking()
|
||||
|
||||
/datum/client_preference/show_typing_indicator_subtle
|
||||
description ="Typing indicator (subtle)"
|
||||
key = "SHOW_TYPING_SUBTLE"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/show_ooc
|
||||
description ="OOC chat"
|
||||
key = "CHAT_OOC"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/show_looc
|
||||
description ="LOOC chat"
|
||||
key = "CHAT_LOOC"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/show_dsay
|
||||
description ="Dead chat"
|
||||
key = "CHAT_DEAD"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/check_mention
|
||||
description ="Emphasize Name Mention"
|
||||
key = "CHAT_MENTION"
|
||||
enabled_description = "Emphasize"
|
||||
disabled_description = "Normal"
|
||||
|
||||
/datum/client_preference/show_progress_bar
|
||||
description ="Progress Bar"
|
||||
key = "SHOW_PROGRESS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/safefiring
|
||||
description = "Gun Firing Intent Requirement"
|
||||
key = "SAFE_FIRING"
|
||||
enabled_description = "Safe"
|
||||
disabled_description = "Dangerous"
|
||||
|
||||
/datum/client_preference/browser_style
|
||||
description = "Fake NanoUI Browser Style"
|
||||
key = "BROWSER_STYLED"
|
||||
enabled_description = "Fancy"
|
||||
disabled_description = "Plain"
|
||||
|
||||
/datum/client_preference/ambient_occlusion
|
||||
description = "Fake Ambient Occlusion"
|
||||
key = "AMBIENT_OCCLUSION_PREF"
|
||||
enabled_by_default = FALSE
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/ambient_occlusion/toggled(var/mob/preference_mob, var/enabled)
|
||||
. = ..()
|
||||
if(preference_mob && preference_mob.plane_holder)
|
||||
var/datum/plane_holder/PH = preference_mob.plane_holder
|
||||
PH.set_ao(VIS_OBJS, enabled)
|
||||
PH.set_ao(VIS_MOBS, enabled)
|
||||
|
||||
/datum/client_preference/instrument_toggle
|
||||
description ="Hear In-game Instruments"
|
||||
key = "SOUND_INSTRUMENT"
|
||||
|
||||
/datum/client_preference/vchat_enable
|
||||
description = "Enable/Disable TGChat"
|
||||
key = "VCHAT_ENABLE"
|
||||
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/radio_sounds
|
||||
description = "Radio Sounds"
|
||||
key = "RADIO_SOUNDS"
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/say_sounds
|
||||
description = "Say Sounds"
|
||||
key = "SAY_SOUNDS"
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/emote_sounds
|
||||
description = "Me Sounds"
|
||||
key = "EMOTE_SOUNDS"
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/whisper_sounds
|
||||
description = "Whisper Sounds"
|
||||
key = "WHISPER_SOUNDS"
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/subtle_sounds
|
||||
description = "Subtle Sounds"
|
||||
key = "SUBTLE_SOUNDS"
|
||||
enabled_description = "On"
|
||||
disabled_description = "Off"
|
||||
|
||||
/datum/client_preference/vore_health_bars
|
||||
description = "Vore Health Bars"
|
||||
key = "VORE_HEALTH_BARS"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/runechat_mob
|
||||
description = "Runechat (Mobs)"
|
||||
key = "RUNECHAT_MOB"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/runechat_obj
|
||||
description = "Runechat (Objs)"
|
||||
key = "RUNECHAT_OBJ"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/runechat_border
|
||||
description = "Runechat Message Border"
|
||||
key = "RUNECHAT_BORDER"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
enabled_by_default = TRUE
|
||||
|
||||
/datum/client_preference/runechat_long_messages
|
||||
description = "Runechat Message Length"
|
||||
key = "RUNECHAT_LONG"
|
||||
enabled_description = "Long"
|
||||
disabled_description = "Short"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/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)
|
||||
|
||||
/datum/client_preference/show_lore_news
|
||||
description = "Lore News Popup"
|
||||
key = "NEWS_POPUP"
|
||||
enabled_by_default = TRUE
|
||||
enabled_description = "Popup New On Login"
|
||||
disabled_description = "Do Nothing"
|
||||
|
||||
/datum/client_preference/play_mentorhelp_ping
|
||||
description = "Mentorhelps"
|
||||
key = "SOUND_MENTORHELP"
|
||||
enabled_description = "Hear"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/player_tips
|
||||
description = "Receive Tips Periodically"
|
||||
key = "RECEIVE_TIPS"
|
||||
enabled_description = "Enabled"
|
||||
disabled_description = "Disabled"
|
||||
|
||||
/datum/client_preference/pain_frequency
|
||||
description = "Pain Messages Cooldown"
|
||||
key = "PAIN_FREQUENCY"
|
||||
enabled_by_default = FALSE
|
||||
enabled_description = "Extended"
|
||||
disabled_description = "Default"
|
||||
|
||||
// CHOMPAdd
|
||||
/datum/client_preference/sleep_music
|
||||
description = "Sleeping Music"
|
||||
key = "SLEEP_MUSIC"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
// CHOMPAdd End
|
||||
|
||||
/datum/client_preference/auto_afk
|
||||
description = "Automatic AFK Status"
|
||||
key = "AUTO_AFK"
|
||||
enabled_by_default = TRUE
|
||||
enabled_description = "Automatic"
|
||||
disabled_description = "Manual Only"
|
||||
|
||||
/datum/client_preference/tgui_say
|
||||
description = "TGUI Say: Use TGUI For Say Input"
|
||||
key = "TGUI_SAY"
|
||||
enabled_by_default = TRUE
|
||||
enabled_description = "Yes"
|
||||
disabled_description = "No"
|
||||
|
||||
/datum/client_preference/tgui_say_light
|
||||
description = "TGUI Say: Use Light Mode"
|
||||
key = "TGUI_SAY_LIGHT_MODE"
|
||||
enabled_by_default = FALSE
|
||||
enabled_description = "Yes"
|
||||
disabled_description = "No"
|
||||
|
||||
/********************
|
||||
* Staff Preferences *
|
||||
********************/
|
||||
/datum/client_preference/admin/may_toggle(var/mob/preference_mob)
|
||||
return check_rights(R_ADMIN|R_EVENT, 0, preference_mob)
|
||||
|
||||
/datum/client_preference/mod/may_toggle(var/mob/preference_mob)
|
||||
return check_rights(R_MOD|R_ADMIN, 0, preference_mob)
|
||||
|
||||
/datum/client_preference/debug/may_toggle(var/mob/preference_mob)
|
||||
return check_rights(R_DEBUG|R_ADMIN, 0, preference_mob)
|
||||
|
||||
/datum/client_preference/mod/show_attack_logs
|
||||
description = "Attack Log Messages"
|
||||
key = "CHAT_ATTACKLOGS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/debug/show_debug_logs
|
||||
description = "Debug Log Messages"
|
||||
key = "CHAT_DEBUGLOGS"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/admin/show_chat_prayers
|
||||
description = "Chat Prayers"
|
||||
key = "CHAT_PRAYER"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/holder/may_toggle(var/mob/preference_mob)
|
||||
return preference_mob && preference_mob.client && preference_mob.client.holder
|
||||
|
||||
/datum/client_preference/holder/play_adminhelp_ping
|
||||
description = "Adminhelps"
|
||||
key = "SOUND_ADMINHELP"
|
||||
enabled_description = "Hear"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/holder/hear_radio
|
||||
description = "Radio chatter"
|
||||
key = "CHAT_RADIO"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/holder/show_rlooc
|
||||
description ="Remote LOOC chat"
|
||||
key = "CHAT_RLOOC"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/holder/show_staff_dsay
|
||||
description ="Staff Deadchat"
|
||||
key = "CHAT_ADSAY"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
@@ -45,19 +45,19 @@ var/list/gear_datums = list()
|
||||
sort_order = 1
|
||||
var/current_tab = "General"
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/load_character(var/savefile/S)
|
||||
from_file(S["gear_list"], pref.gear_list)
|
||||
from_file(S["gear_slot"], pref.gear_slot)
|
||||
/datum/category_item/player_setup_item/loadout/load_character(list/save_data)
|
||||
pref.gear_list = save_data["gear_list"]
|
||||
pref.gear_slot = save_data["gear_slot"]
|
||||
if(pref.gear_list!=null && pref.gear_slot!=null)
|
||||
pref.gear = pref.gear_list["[pref.gear_slot]"]
|
||||
else
|
||||
from_file(S["gear"], pref.gear)
|
||||
pref.gear = save_data["gear"]
|
||||
pref.gear_slot = 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/save_character(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/loadout/save_character(list/save_data)
|
||||
pref.gear_list["[pref.gear_slot]"] = pref.gear
|
||||
to_file(S["gear_list"], pref.gear_list)
|
||||
to_file(S["gear_slot"], pref.gear_slot)
|
||||
save_data["gear_list"] = pref.gear_list
|
||||
save_data["gear_slot"] = pref.gear_slot
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/valid_gear_choices(var/max_cost)
|
||||
. = list()
|
||||
|
||||
@@ -2,51 +2,51 @@
|
||||
name = "Occupation"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/load_character(var/savefile/S)
|
||||
S["alternate_option"] >> pref.alternate_option
|
||||
S["job_civilian_high"] >> pref.job_civilian_high
|
||||
S["job_civilian_med"] >> pref.job_civilian_med
|
||||
S["job_civilian_low"] >> pref.job_civilian_low
|
||||
S["job_medsci_high"] >> pref.job_medsci_high
|
||||
S["job_medsci_med"] >> pref.job_medsci_med
|
||||
S["job_medsci_low"] >> pref.job_medsci_low
|
||||
S["job_engsec_high"] >> pref.job_engsec_high
|
||||
S["job_engsec_med"] >> pref.job_engsec_med
|
||||
S["job_engsec_low"] >> pref.job_engsec_low
|
||||
/datum/category_item/player_setup_item/occupation/load_character(list/save_data)
|
||||
pref.alternate_option = save_data["alternate_option"]
|
||||
pref.job_civilian_high = save_data["job_civilian_high"]
|
||||
pref.job_civilian_med = save_data["job_civilian_med"]
|
||||
pref.job_civilian_low = save_data["job_civilian_low"]
|
||||
pref.job_medsci_high = save_data["job_medsci_high"]
|
||||
pref.job_medsci_med = save_data["job_medsci_med"]
|
||||
pref.job_medsci_low = save_data["job_medsci_low"]
|
||||
pref.job_engsec_high = save_data["job_engsec_high"]
|
||||
pref.job_engsec_med = save_data["job_engsec_med"]
|
||||
pref.job_engsec_low = save_data["job_engsec_low"]
|
||||
//VOREStation Add
|
||||
S["job_talon_low"] >> pref.job_talon_low
|
||||
S["job_talon_med"] >> pref.job_talon_med
|
||||
S["job_talon_high"] >> pref.job_talon_high
|
||||
pref.job_talon_low = save_data["job_talon_low"]
|
||||
pref.job_talon_med = save_data["job_talon_med"]
|
||||
pref.job_talon_high = save_data["job_talon_high"]
|
||||
//VOREStation Add End
|
||||
S["player_alt_titles"] >> pref.player_alt_titles
|
||||
pref.player_alt_titles = save_data["player_alt_titles"]
|
||||
//CHOMPStation Add
|
||||
S["job_other_low"] >> pref.job_other_low
|
||||
S["job_other_med"] >> pref.job_other_med
|
||||
S["job_other_high"] >> pref.job_other_high
|
||||
pref.job_other_low = save_data["job_other_low"]
|
||||
pref.job_other_med = save_data["job_other_med"]
|
||||
pref.job_other_high = save_data["job_other_high"]
|
||||
//CHOMPStation Add End
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/save_character(var/savefile/S)
|
||||
S["alternate_option"] << pref.alternate_option
|
||||
S["job_civilian_high"] << pref.job_civilian_high
|
||||
S["job_civilian_med"] << pref.job_civilian_med
|
||||
S["job_civilian_low"] << pref.job_civilian_low
|
||||
S["job_medsci_high"] << pref.job_medsci_high
|
||||
S["job_medsci_med"] << pref.job_medsci_med
|
||||
S["job_medsci_low"] << pref.job_medsci_low
|
||||
S["job_engsec_high"] << pref.job_engsec_high
|
||||
S["job_engsec_med"] << pref.job_engsec_med
|
||||
S["job_engsec_low"] << pref.job_engsec_low
|
||||
/datum/category_item/player_setup_item/occupation/save_character(list/save_data)
|
||||
save_data["alternate_option"] = pref.alternate_option
|
||||
save_data["job_civilian_high"] = pref.job_civilian_high
|
||||
save_data["job_civilian_med"] = pref.job_civilian_med
|
||||
save_data["job_civilian_low"] = pref.job_civilian_low
|
||||
save_data["job_medsci_high"] = pref.job_medsci_high
|
||||
save_data["job_medsci_med"] = pref.job_medsci_med
|
||||
save_data["job_medsci_low"] = pref.job_medsci_low
|
||||
save_data["job_engsec_high"] = pref.job_engsec_high
|
||||
save_data["job_engsec_med"] = pref.job_engsec_med
|
||||
save_data["job_engsec_low"] = pref.job_engsec_low
|
||||
//VOREStation Add
|
||||
S["job_talon_low"] << pref.job_talon_low
|
||||
S["job_talon_med"] << pref.job_talon_med
|
||||
S["job_talon_high"] << pref.job_talon_high
|
||||
save_data["job_talon_low"] = pref.job_talon_low
|
||||
save_data["job_talon_med"] = pref.job_talon_med
|
||||
save_data["job_talon_high"] = pref.job_talon_high
|
||||
//VOREStation Add End
|
||||
S["player_alt_titles"] << pref.player_alt_titles
|
||||
save_data["player_alt_titles"] = pref.player_alt_titles
|
||||
//CHOMPStation Add
|
||||
S["job_other_low"] << pref.job_other_low
|
||||
S["job_other_med"] << pref.job_other_med
|
||||
S["job_other_high"] << pref.job_other_high
|
||||
//CHOMPStation Add End
|
||||
save_data["job_other_low"] = pref.job_other_low
|
||||
save_data["job_other_med"] = pref.job_other_med
|
||||
save_data["job_other_high"] = pref.job_other_high
|
||||
//CHOMPStation Add Endarkens/revert-16279-revert-16253-reprefs
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/sanitize_character()
|
||||
pref.alternate_option = sanitize_integer(pref.alternate_option, 0, 2, initial(pref.alternate_option))
|
||||
|
||||
@@ -59,21 +59,21 @@
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
PS.sanitize_setup()
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/load_character(var/savefile/S)
|
||||
/datum/category_collection/player_setup_collection/proc/load_character(list/save_data)
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
PS.load_character(S)
|
||||
PS.load_character(save_data)
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/save_character(var/savefile/S)
|
||||
/datum/category_collection/player_setup_collection/proc/save_character(list/save_data)
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
PS.save_character(S)
|
||||
PS.save_character(save_data)
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/load_preferences(var/savefile/S)
|
||||
/datum/category_collection/player_setup_collection/proc/load_preferences(datum/json_savefile/savefile)
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
PS.load_preferences(S)
|
||||
PS.load_preferences(savefile)
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/save_preferences(var/savefile/S)
|
||||
/datum/category_collection/player_setup_collection/proc/save_preferences(datum/json_savefile/savefile)
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
PS.save_preferences(S)
|
||||
PS.save_preferences(savefile)
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/copy_to_mob(var/mob/living/carbon/human/C)
|
||||
for(var/datum/category_group/player_setup_category/PS in categories)
|
||||
@@ -86,6 +86,7 @@
|
||||
dat += "[PS.name] " // TODO: Check how to properly mark a href/button selected in a classic browser window
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];category=\ref[PS]'>[PS.name]</a> "
|
||||
dat += "<a href='?src=\ref[src];game_prefs=1'>Game Options</a>"
|
||||
return dat
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/content(var/mob/user)
|
||||
@@ -105,6 +106,9 @@
|
||||
selected_category = category
|
||||
. = 1
|
||||
|
||||
else if(href_list["game_prefs"])
|
||||
user.client.prefs.tgui_interact(user)
|
||||
|
||||
if(.)
|
||||
user.client.prefs.ShowChoices(user)
|
||||
|
||||
@@ -123,29 +127,29 @@
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.sanitize_character()
|
||||
|
||||
/datum/category_group/player_setup_category/proc/load_character(var/savefile/S)
|
||||
/datum/category_group/player_setup_category/proc/load_character(list/save_data)
|
||||
// Load all data, then sanitize it.
|
||||
// Need due to, for example, the 01_basic module relying on species having been loaded to sanitize correctly but that isn't loaded until module 03_body.
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.load_character(S)
|
||||
PI.load_character(save_data)
|
||||
|
||||
|
||||
/datum/category_group/player_setup_category/proc/save_character(var/savefile/S)
|
||||
/datum/category_group/player_setup_category/proc/save_character(list/save_data)
|
||||
// Sanitize all data, then save it
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.sanitize_character()
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.save_character(S)
|
||||
PI.save_character(save_data)
|
||||
|
||||
/datum/category_group/player_setup_category/proc/load_preferences(var/savefile/S)
|
||||
/datum/category_group/player_setup_category/proc/load_preferences(datum/json_savefile/savefile)
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.load_preferences(S)
|
||||
PI.load_preferences(savefile)
|
||||
|
||||
/datum/category_group/player_setup_category/proc/save_preferences(var/savefile/S)
|
||||
/datum/category_group/player_setup_category/proc/save_preferences(datum/json_savefile/savefile)
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.sanitize_preferences()
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.save_preferences(S)
|
||||
PI.save_preferences(savefile)
|
||||
|
||||
/datum/category_group/player_setup_category/proc/copy_to_mob(var/mob/living/carbon/human/C)
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
@@ -188,25 +192,25 @@
|
||||
/*
|
||||
* Called when the item is asked to load per character settings
|
||||
*/
|
||||
/datum/category_item/player_setup_item/proc/load_character(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/proc/load_character(list/save_data)
|
||||
return
|
||||
|
||||
/*
|
||||
* Called when the item is asked to save per character settings
|
||||
*/
|
||||
/datum/category_item/player_setup_item/proc/save_character(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/proc/save_character(list/save_data)
|
||||
return
|
||||
|
||||
/*
|
||||
* Called when the item is asked to load user/global settings
|
||||
*/
|
||||
/datum/category_item/player_setup_item/proc/load_preferences(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/proc/load_preferences(datum/json_savefile/savefile)
|
||||
return
|
||||
|
||||
/*
|
||||
* Called when the item is asked to save user/global settings
|
||||
*/
|
||||
/datum/category_item/player_setup_item/proc/save_preferences(var/savefile/S)
|
||||
/datum/category_item/player_setup_item/proc/save_preferences(datum/json_savefile/savefile)
|
||||
return
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
name = "Skills"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/skills/load_character(var/savefile/S)
|
||||
S["skills"] >> pref.skills
|
||||
S["used_skillpoints"] >> pref.used_skillpoints
|
||||
S["skill_specialization"] >> pref.skill_specialization
|
||||
/datum/category_item/player_setup_item/skills/load_character(list/save_data)
|
||||
pref.skills = save_data["skills"]
|
||||
pref.used_skillpoints = save_data["used_skillpoints"]
|
||||
pref.skill_specialization = save_data["skill_specialization"]
|
||||
|
||||
/datum/category_item/player_setup_item/skills/save_character(var/savefile/S)
|
||||
S["skills"] << pref.skills
|
||||
S["used_skillpoints"] << pref.used_skillpoints
|
||||
S["skill_specialization"] << pref.skill_specialization
|
||||
/datum/category_item/player_setup_item/skills/save_character(list/save_data)
|
||||
save_data["skills"] = pref.skills
|
||||
save_data["used_skillpoints"] = pref.used_skillpoints
|
||||
save_data["skill_specialization"] = pref.skill_specialization
|
||||
|
||||
/datum/category_item/player_setup_item/skills/sanitize_character()
|
||||
if(SKILLS == null) setup_skills()
|
||||
|
||||
@@ -35,11 +35,11 @@ var/list/trait_categories = list() // The categories available for the trait men
|
||||
sort_order = 1
|
||||
var/current_tab = "Physical"
|
||||
|
||||
/datum/category_item/player_setup_item/traits/load_character(var/savefile/S)
|
||||
S["traits"] >> pref.traits
|
||||
/datum/category_item/player_setup_item/traits/load_character(list/save_data)
|
||||
pref.traits = save_data["traits"]
|
||||
|
||||
/datum/category_item/player_setup_item/traits/save_character(var/savefile/S)
|
||||
S["traits"] << pref.traits
|
||||
/datum/category_item/player_setup_item/traits/save_character(list/save_data)
|
||||
save_data["traits"] = pref.traits
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/traits/content()
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
name = "General Volume"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/load_preferences(var/savefile/S)
|
||||
S["volume_channels"] >> pref.volume_channels
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/load_preferences(datum/json_savefile/savefile)
|
||||
pref.volume_channels = savefile.get_entry("volume_channels")
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/save_preferences(var/savefile/S)
|
||||
S["volume_channels"] << pref.volume_channels
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/save_preferences(datum/json_savefile/savefile)
|
||||
savefile.set_entry("volume_channels", pref.volume_channels)
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/sanitize_preferences()
|
||||
if(isnull(pref.volume_channels))
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
name = "Media"
|
||||
sort_order = 2
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/load_preferences(var/savefile/S)
|
||||
S["media_volume"] >> pref.media_volume
|
||||
S["media_player"] >> pref.media_player
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/load_preferences(datum/json_savefile/savefile)
|
||||
pref.media_volume = savefile.get_entry("media_volume")
|
||||
pref.media_player = savefile.get_entry("media_player")
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/save_preferences(var/savefile/S)
|
||||
S["media_volume"] << pref.media_volume
|
||||
S["media_player"] << pref.media_player
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/save_preferences(datum/json_savefile/savefile)
|
||||
savefile.set_entry("media_volume", pref.media_volume)
|
||||
savefile.set_entry("media_player", pref.media_player)
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/sanitize_preferences()
|
||||
pref.media_volume = isnum(pref.media_volume) ? CLAMP(pref.media_volume, 0, 1) : initial(pref.media_volume)
|
||||
|
||||
@@ -24,32 +24,35 @@
|
||||
name = "Size"
|
||||
sort_order = 2
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/load_character(var/savefile/S)
|
||||
S["size_multiplier"] >> pref.size_multiplier
|
||||
S["weight_vr"] >> pref.weight_vr
|
||||
S["weight_gain"] >> pref.weight_gain
|
||||
S["weight_loss"] >> pref.weight_loss
|
||||
S["fuzzy"] >> pref.fuzzy
|
||||
S["offset_override"] >> pref.offset_override
|
||||
S["voice_freq"] >> pref.voice_freq
|
||||
S["voice_sound"] >> pref.voice_sound
|
||||
S["custom_speech_bubble"] >> pref.custom_speech_bubble
|
||||
S["custom_footstep"] >> pref.custom_footstep // CHOMPEdit
|
||||
S["species_sound"] >> pref.species_sound // CHOMPEdit
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/save_character(var/savefile/S)
|
||||
S["size_multiplier"] << pref.size_multiplier
|
||||
S["weight_vr"] << pref.weight_vr
|
||||
S["weight_gain"] << pref.weight_gain
|
||||
S["weight_loss"] << pref.weight_loss
|
||||
S["fuzzy"] << pref.fuzzy
|
||||
S["offset_override"] << pref.offset_override
|
||||
S["voice_freq"] << pref.voice_freq
|
||||
S["voice_sound"] << pref.voice_sound
|
||||
S["custom_speech_bubble"] << pref.custom_speech_bubble
|
||||
S["custom_footstep"] << pref.custom_footstep // CHOMPEdit
|
||||
S["species_sound"] << pref.species_sound // CHOMPEdit
|
||||
/datum/category_item/player_setup_item/vore/size/load_character(list/save_data)
|
||||
pref.size_multiplier = save_data["size_multiplier"]
|
||||
pref.weight_vr = save_data["weight_vr"]
|
||||
pref.weight_gain = save_data["weight_gain"]
|
||||
pref.weight_loss = save_data["weight_loss"]
|
||||
pref.fuzzy = save_data["fuzzy"]
|
||||
pref.offset_override = save_data["offset_override"]
|
||||
pref.voice_freq = save_data["voice_freq"]
|
||||
pref.voice_sound = save_data["voice_sound"]
|
||||
pref.custom_speech_bubble = save_data["custom_speech_bubble"]
|
||||
//CHOMPAdd Start
|
||||
pref.custom_footstep = save_data["custom_footstep"]
|
||||
pref.species_sound = save_data["species_sound"]
|
||||
//CHOMPAdd End
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/save_character(list/save_data)
|
||||
save_data["size_multiplier"] = pref.size_multiplier
|
||||
save_data["weight_vr"] = pref.weight_vr
|
||||
save_data["weight_gain"] = pref.weight_gain
|
||||
save_data["weight_loss"] = pref.weight_loss
|
||||
save_data["fuzzy"] = pref.fuzzy
|
||||
save_data["offset_override"] = pref.offset_override
|
||||
save_data["voice_freq"] = pref.voice_freq
|
||||
save_data["voice_sound"] = pref.voice_sound
|
||||
save_data["custom_speech_bubble"] = pref.custom_speech_bubble
|
||||
//CHOMPAdd Start
|
||||
save_data["custom_footstep"] = pref.custom_footstep
|
||||
save_data["species_sound"] = pref.species_sound
|
||||
//CHOMPAdd End
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/sanitize_character()
|
||||
pref.weight_vr = sanitize_integer(pref.weight_vr, WEIGHT_MIN, WEIGHT_MAX, initial(pref.weight_vr))
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
name = "Egg appearance."
|
||||
sort_order = 3
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/load_character(var/savefile/S)
|
||||
S["vore_egg_type"] >> pref.vore_egg_type
|
||||
S["autohiss"] >> pref.autohiss // VOREStation Add
|
||||
/datum/category_item/player_setup_item/vore/egg/load_character(list/save_data)
|
||||
pref.vore_egg_type = save_data["vore_egg_type"]
|
||||
pref.autohiss = save_data["autohiss"]
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/save_character(var/savefile/S)
|
||||
S["vore_egg_type"] << pref.vore_egg_type
|
||||
S["autohiss"] << pref.autohiss // VOREStation Add
|
||||
/datum/category_item/player_setup_item/vore/egg/save_character(list/save_data)
|
||||
save_data["vore_egg_type"] = pref.vore_egg_type
|
||||
save_data["autohiss"] = pref.autohiss
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/sanitize_character()
|
||||
pref.vore_egg_type = sanitize_inlist(pref.vore_egg_type, global_vore_egg_types, initial(pref.vore_egg_type))
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
name = "Resleeving"
|
||||
sort_order = 4
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/load_character(var/savefile/S)
|
||||
S["resleeve_lock"] >> pref.resleeve_lock
|
||||
S["resleeve_scan"] >> pref.resleeve_scan
|
||||
S["mind_scan"] >> pref.mind_scan
|
||||
/datum/category_item/player_setup_item/vore/resleeve/load_character(list/save_data)
|
||||
pref.resleeve_lock = save_data["resleeve_lock"]
|
||||
pref.resleeve_scan = save_data["resleeve_scan"]
|
||||
pref.mind_scan = save_data["mind_scan"]
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/save_character(var/savefile/S)
|
||||
S["resleeve_lock"] << pref.resleeve_lock
|
||||
S["resleeve_scan"] << pref.resleeve_scan
|
||||
S["mind_scan"] << pref.mind_scan
|
||||
/datum/category_item/player_setup_item/vore/resleeve/save_character(list/save_data)
|
||||
save_data["resleeve_lock"] = pref.resleeve_lock
|
||||
save_data["resleeve_scan"] = pref.resleeve_scan
|
||||
save_data["mind_scan"] = pref.mind_scan
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/sanitize_character()
|
||||
pref.resleeve_lock = sanitize_integer(pref.resleeve_lock, 0, 1, initial(pref.resleeve_lock))
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
name = "Persistence"
|
||||
sort_order = 5
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/load_character(var/savefile/S)
|
||||
S["persistence_settings"] >> pref.persistence_settings
|
||||
/datum/category_item/player_setup_item/vore/persistence/load_character(list/save_data)
|
||||
pref.persistence_settings = save_data["persistence_settings"]
|
||||
sanitize_character() // Don't let new characters start off with nulls
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/save_character(var/savefile/S)
|
||||
S["persistence_settings"] << pref.persistence_settings
|
||||
/datum/category_item/player_setup_item/vore/persistence/save_character(list/save_data)
|
||||
save_data["persistence_settings"] = pref.persistence_settings
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/sanitize_character()
|
||||
pref.persistence_settings = sanitize_integer(pref.persistence_settings, 0, (1<<(PERSIST_COUNT+1)-1), initial(pref.persistence_settings))
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
name = "VS Events"
|
||||
sort_order = 6
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/load_character(var/savefile/S)
|
||||
S["vantag_volunteer"] >> pref.vantag_volunteer
|
||||
S["vantag_preference"] >> pref.vantag_preference
|
||||
/datum/category_item/player_setup_item/vore/vantag/load_character(list/save_data)
|
||||
pref.vantag_volunteer = save_data["vantag_volunteer"]
|
||||
pref.vantag_preference = save_data["vantag_preference"]
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/save_character(var/savefile/S)
|
||||
S["vantag_volunteer"] << pref.vantag_volunteer
|
||||
S["vantag_preference"] << pref.vantag_preference
|
||||
/datum/category_item/player_setup_item/vore/vantag/save_character(list/save_data)
|
||||
save_data["vantag_volunteer"] = pref.vantag_volunteer
|
||||
save_data["vantag_preference"] = pref.vantag_preference
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/sanitize_character()
|
||||
pref.vantag_volunteer = sanitize_integer(pref.vantag_volunteer, 0, 1, initial(pref.vantag_volunteer))
|
||||
|
||||
@@ -113,47 +113,47 @@ var/global/list/valid_bloodreagents = list("default","iron","copper","phoron","s
|
||||
name = "Traits"
|
||||
sort_order = 7
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/load_character(var/savefile/S)
|
||||
S["custom_species"] >> pref.custom_species
|
||||
S["custom_base"] >> pref.custom_base
|
||||
S["pos_traits"] >> pref.pos_traits
|
||||
S["neu_traits"] >> pref.neu_traits
|
||||
S["neg_traits"] >> pref.neg_traits
|
||||
S["blood_color"] >> pref.blood_color
|
||||
S["blood_reagents"] >> pref.blood_reagents
|
||||
/datum/category_item/player_setup_item/vore/traits/load_character(list/save_data)
|
||||
pref.custom_species = save_data["custom_species"]
|
||||
pref.custom_base = save_data["custom_base"]
|
||||
pref.pos_traits = text2path_list(save_data["pos_traits"])
|
||||
pref.neu_traits = text2path_list(save_data["neu_traits"])
|
||||
pref.neg_traits = text2path_list(save_data["neg_traits"])
|
||||
pref.blood_color = save_data["blood_color"]
|
||||
pref.blood_reagents = save_data["blood_reagents"]
|
||||
|
||||
S["traits_cheating"] >> pref.traits_cheating
|
||||
S["max_traits"] >> pref.max_traits
|
||||
S["trait_points"] >> pref.starting_trait_points
|
||||
pref.traits_cheating = save_data["traits_cheating"]
|
||||
pref.max_traits = save_data["max_traits"]
|
||||
pref.starting_trait_points = save_data["trait_points"]
|
||||
|
||||
S["custom_say"] >> pref.custom_say
|
||||
S["custom_whisper"] >> pref.custom_whisper
|
||||
S["custom_ask"] >> pref.custom_ask
|
||||
S["custom_exclaim"] >> pref.custom_exclaim
|
||||
pref.custom_say = save_data["custom_say"]
|
||||
pref.custom_whisper = save_data["custom_whisper"]
|
||||
pref.custom_ask = save_data["custom_ask"]
|
||||
pref.custom_exclaim = save_data["custom_exclaim"]
|
||||
|
||||
S["custom_heat"] >> pref.custom_heat
|
||||
S["custom_cold"] >> pref.custom_cold
|
||||
pref.custom_heat = save_data["custom_heat"]
|
||||
pref.custom_cold = save_data["custom_cold"]
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/save_character(var/savefile/S)
|
||||
S["custom_species"] << pref.custom_species
|
||||
S["custom_base"] << pref.custom_base
|
||||
S["pos_traits"] << pref.pos_traits
|
||||
S["neu_traits"] << pref.neu_traits
|
||||
S["neg_traits"] << pref.neg_traits
|
||||
S["blood_color"] << pref.blood_color
|
||||
S["blood_reagents"] << pref.blood_reagents
|
||||
/datum/category_item/player_setup_item/vore/traits/save_character(list/save_data)
|
||||
save_data["custom_species"] = pref.custom_species
|
||||
save_data["custom_base"] = pref.custom_base
|
||||
save_data["pos_traits"] = pref.pos_traits
|
||||
save_data["neu_traits"] = pref.neu_traits
|
||||
save_data["neg_traits"] = pref.neg_traits
|
||||
save_data["blood_color"] = pref.blood_color
|
||||
save_data["blood_reagents"] = pref.blood_reagents
|
||||
|
||||
S["traits_cheating"] << pref.traits_cheating
|
||||
S["max_traits"] << pref.max_traits
|
||||
S["trait_points"] << pref.starting_trait_points
|
||||
save_data["traits_cheating"] = pref.traits_cheating
|
||||
save_data["max_traits"] = pref.max_traits
|
||||
save_data["trait_points"] = pref.starting_trait_points
|
||||
|
||||
S["custom_say"] << pref.custom_say
|
||||
S["custom_whisper"] << pref.custom_whisper
|
||||
S["custom_ask"] << pref.custom_ask
|
||||
S["custom_exclaim"] << pref.custom_exclaim
|
||||
save_data["custom_say"] = pref.custom_say
|
||||
save_data["custom_whisper"] = pref.custom_whisper
|
||||
save_data["custom_ask"] = pref.custom_ask
|
||||
save_data["custom_exclaim"] = pref.custom_exclaim
|
||||
|
||||
S["custom_heat"] << pref.custom_heat
|
||||
S["custom_cold"] << pref.custom_cold
|
||||
save_data["custom_heat"] = pref.custom_heat
|
||||
save_data["custom_cold"] = pref.custom_cold
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/sanitize_character()
|
||||
if(!pref.pos_traits) pref.pos_traits = list()
|
||||
@@ -192,13 +192,16 @@ var/global/list/valid_bloodreagents = list("default","iron","copper","phoron","s
|
||||
//Neutral traits
|
||||
for(var/datum/trait/path as anything in pref.neu_traits)
|
||||
if(!(path in neutral_traits))
|
||||
to_world_log("removing [path] for not being in neutral_traits")
|
||||
pref.neu_traits -= path
|
||||
continue
|
||||
if(!(pref.species == SPECIES_CUSTOM) && !(path in everyone_traits_neutral))
|
||||
to_world_log("removing [path] for not being a custom species")
|
||||
pref.neu_traits -= path
|
||||
continue
|
||||
var/take_flags = initial(path.can_take)
|
||||
if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS)))
|
||||
to_world_log("removing [path] for being a dirty synth")
|
||||
pref.neu_traits -= path
|
||||
//Negative traits
|
||||
for(var/datum/trait/path as anything in pref.neg_traits)
|
||||
|
||||
@@ -5,19 +5,34 @@
|
||||
var/list/nif_savedata
|
||||
|
||||
// Definition of the stuff for NIFs
|
||||
// Magic bullshit, they're stored separately from everything else
|
||||
/datum/category_item/player_setup_item/vore/nif
|
||||
name = "NIF Data"
|
||||
sort_order = 8
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/load_character(var/savefile/S)
|
||||
S["nif_path"] >> pref.nif_path
|
||||
S["nif_durability"] >> pref.nif_durability
|
||||
S["nif_savedata"] >> pref.nif_savedata
|
||||
/proc/nif_savefile_path(ckey)
|
||||
if(!ckey)
|
||||
return
|
||||
return "data/player_saves/[copytext(ckey,1,2)]/[ckey]/nif.json"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/save_character(var/savefile/S)
|
||||
S["nif_path"] << pref.nif_path
|
||||
S["nif_durability"] << pref.nif_durability
|
||||
S["nif_savedata"] << pref.nif_savedata
|
||||
/datum/category_item/player_setup_item/vore/nif/load_character()
|
||||
var/datum/json_savefile/savefile = new /datum/json_savefile(nif_savefile_path(pref.client_ckey))
|
||||
var/list/save_data_file = savefile.get_entry("character[pref.default_slot]", list())
|
||||
|
||||
pref.nif_path = save_data_file["nif_path"]
|
||||
pref.nif_durability = save_data_file["nif_durability"]
|
||||
pref.nif_savedata = save_data_file["nif_savedata"]
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/save_character()
|
||||
var/datum/json_savefile/savefile = new /datum/json_savefile(nif_savefile_path(pref.client_ckey))
|
||||
var/list/save_data_file = savefile.get_entry("character[pref.default_slot]", list())
|
||||
|
||||
save_data_file["nif_path"] = pref.nif_path
|
||||
save_data_file["nif_durability"] = pref.nif_durability
|
||||
save_data_file["nif_savedata"] = pref.nif_savedata
|
||||
|
||||
savefile.set_entry("character[pref.default_slot]", save_data_file)
|
||||
savefile.save()
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/sanitize_character()
|
||||
if(pref.nif_path && !ispath(pref.nif_path)) //We have at least a text string that should be a path.
|
||||
@@ -38,23 +53,8 @@
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
//If you had a NIF...
|
||||
if((character.type == /mob/living/carbon/human) && ispath(pref.nif_path) && pref.nif_durability)
|
||||
new pref.nif_path(character,pref.nif_durability,pref.nif_savedata)
|
||||
|
||||
/*
|
||||
//And now here's the trick. We wipe these so that if they die, they lose the NIF.
|
||||
//Backup implants will start saving this again periodically, and so will cryo'ing out.
|
||||
pref.nif_path = null
|
||||
pref.nif_durability = null
|
||||
pref.nif_savedata = null
|
||||
*/
|
||||
//No we do not, that's lame and admins have to re-NIF them later.
|
||||
//If they leave round after they get their NIF extracted, it will save as 'gone' anyway
|
||||
//The NIF will save automatically every time durability changes too now.
|
||||
var/savefile/S = new /savefile(pref.path)
|
||||
if(!S) WARNING ("Couldn't load NIF save savefile? [pref.real_name]")
|
||||
S.cd = "/character[pref.default_slot]"
|
||||
save_character(S)
|
||||
if(istype(character) && ispath(pref.nif_path) && pref.nif_durability)
|
||||
new pref.nif_path(character, pref.nif_durability, pref.nif_savedata)
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/content(var/mob/user)
|
||||
. += "<b>NIF:</b> [ispath(pref.nif_path) ? "Present" : "None"]"
|
||||
|
||||
@@ -2,31 +2,35 @@
|
||||
name = "Misc Settings"
|
||||
sort_order = 9
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/load_character(var/savefile/S)
|
||||
S["show_in_directory"] >> pref.show_in_directory
|
||||
S["directory_tag"] >> pref.directory_tag
|
||||
S["directory_gendertag"] >> pref.directory_gendertag // CHOMPStation Edit: Character Directory Update
|
||||
S["directory_sexualitytag"] >> pref.directory_sexualitytag // CHOMPStation Edit: Character Directory Update
|
||||
S["directory_erptag"] >> pref.directory_erptag
|
||||
S["directory_ad"] >> pref.directory_ad
|
||||
S["sensorpref"] >> pref.sensorpref
|
||||
S["capture_crystal"] >> pref.capture_crystal
|
||||
S["auto_backup_implant"] >> pref.auto_backup_implant
|
||||
S["borg_petting"] >> pref.borg_petting
|
||||
S["stomach_vision"] >> pref.stomach_vision
|
||||
/datum/category_item/player_setup_item/vore/misc/load_character(list/save_data)
|
||||
pref.show_in_directory = save_data["show_in_directory"]
|
||||
pref.directory_tag = save_data["directory_tag"]
|
||||
//CHOMPAdd Start
|
||||
pref.directory_gendertag = save_data["directory_gendertag"]
|
||||
pref.directory_sexualitytag = save_data["directory_sexualitytag"]
|
||||
//CHOMPAdd End
|
||||
pref.directory_erptag = save_data["directory_erptag"]
|
||||
pref.directory_ad = save_data["directory_ad"]
|
||||
pref.sensorpref = save_data["sensorpref"]
|
||||
pref.capture_crystal = save_data["capture_crystal"]
|
||||
pref.auto_backup_implant = save_data["auto_backup_implant"]
|
||||
pref.borg_petting = save_data["borg_petting"]
|
||||
pref.stomach_vision = save_data["stomach_vision"]
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/save_character(var/savefile/S)
|
||||
S["show_in_directory"] << pref.show_in_directory
|
||||
S["directory_tag"] << pref.directory_tag
|
||||
S["directory_gendertag"] << pref.directory_gendertag // CHOMPStation Edit: Character Directory Update
|
||||
S["directory_sexualitytag"] << pref.directory_sexualitytag // CHOMPStation Edit: Character Directory Update
|
||||
S["directory_erptag"] << pref.directory_erptag
|
||||
S["directory_ad"] << pref.directory_ad
|
||||
S["sensorpref"] << pref.sensorpref
|
||||
S["capture_crystal"] << pref.capture_crystal
|
||||
S["auto_backup_implant"] << pref.auto_backup_implant
|
||||
S["borg_petting"] << pref.borg_petting
|
||||
S["stomach_vision"] << pref.stomach_vision
|
||||
/datum/category_item/player_setup_item/vore/misc/save_character(list/save_data)
|
||||
save_data["show_in_directory"] = pref.show_in_directory
|
||||
save_data["directory_tag"] = pref.directory_tag
|
||||
//CHOMPAdd Start
|
||||
save_data["directory_gendertag"] = pref.directory_gendertag
|
||||
save_data["directory_sexualitytag"] = pref.directory_sexualitytag
|
||||
//CHOMPAdd End
|
||||
save_data["directory_erptag"] = pref.directory_erptag
|
||||
save_data["directory_ad"] = pref.directory_ad
|
||||
save_data["sensorpref"] = pref.sensorpref
|
||||
save_data["capture_crystal"] = pref.capture_crystal
|
||||
save_data["auto_backup_implant"] = pref.auto_backup_implant
|
||||
save_data["borg_petting"] = pref.borg_petting
|
||||
save_data["stomach_vision"] = pref.stomach_vision
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(pref.sensorpref > 5 || pref.sensorpref < 1)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
var/list/preferences_datums = list()
|
||||
|
||||
/datum/preferences
|
||||
//doohickeys for savefiles
|
||||
/// The path to the general savefile for this datum
|
||||
var/path
|
||||
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
|
||||
var/savefile_version = 0
|
||||
/// Whether or not we allow saving/loading. Used for guests, if they're enabled
|
||||
var/load_and_save = TRUE
|
||||
/// Ensures that we always load the last used save, QOL
|
||||
var/default_slot = 1
|
||||
|
||||
//non-preference stuff
|
||||
var/warns = 0
|
||||
@@ -176,29 +178,55 @@ var/list/preferences_datums = list()
|
||||
///If they are currently in the process of swapping slots, don't let them open 999 windows for it and get confused
|
||||
var/selecting_slots = FALSE
|
||||
|
||||
/// The json savefile for this datum
|
||||
var/datum/json_savefile/savefile
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
client = C
|
||||
|
||||
for(var/middleware_type in subtypesof(/datum/preference_middleware))
|
||||
middleware += new middleware_type(src)
|
||||
|
||||
if(istype(C)) // IS_CLIENT_OR_MOCK
|
||||
client_ckey = C.ckey
|
||||
load_and_save = !IsGuestKey(C.key)
|
||||
load_path(C.ckey)
|
||||
if(load_and_save && !fexists(path))
|
||||
try_savefile_type_migration()
|
||||
else
|
||||
CRASH("attempted to create a preferences datum without a client or mock!")
|
||||
load_savefile()
|
||||
|
||||
// Legacy code
|
||||
gear = list()
|
||||
gear_list = list()
|
||||
gear_slot = 1
|
||||
// End legacy code
|
||||
|
||||
player_setup = new(src)
|
||||
|
||||
var/loaded_preferences_successfully = load_preferences()
|
||||
if(loaded_preferences_successfully)
|
||||
if(load_character())
|
||||
return
|
||||
|
||||
// Didn't load a character, so let's randomize
|
||||
set_biological_gender(pick(MALE, FEMALE))
|
||||
real_name = random_name(identifying_gender,species)
|
||||
b_type = RANDOM_BLOOD_TYPE
|
||||
|
||||
gear = list()
|
||||
gear_list = list()
|
||||
gear_slot = 1
|
||||
|
||||
if(istype(C))
|
||||
client = C
|
||||
client_ckey = C.ckey
|
||||
if(!IsGuestKey(C.key))
|
||||
load_path(C.ckey)
|
||||
if(load_preferences())
|
||||
load_character()
|
||||
if(client)
|
||||
apply_all_client_preferences()
|
||||
|
||||
if(!loaded_preferences_successfully)
|
||||
save_preferences()
|
||||
save_character() // Save random character
|
||||
|
||||
/datum/preferences/Destroy()
|
||||
. = ..()
|
||||
QDEL_LIST_ASSOC_VAL(char_render_holders)
|
||||
QDEL_NULL(middleware)
|
||||
value_cache = null
|
||||
return ..()
|
||||
|
||||
/datum/preferences/proc/ZeroSkills(var/forced = 0)
|
||||
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
|
||||
@@ -357,8 +385,8 @@ var/list/preferences_datums = list()
|
||||
return 1
|
||||
|
||||
if(href_list["save"])
|
||||
save_preferences()
|
||||
save_character()
|
||||
save_preferences()
|
||||
else if(href_list["reload"])
|
||||
load_preferences()
|
||||
load_character()
|
||||
@@ -373,7 +401,7 @@ var/list/preferences_datums = list()
|
||||
return 0
|
||||
if("Yes" != tgui_alert(usr, "Are you completely sure that you want to reset this character slot?", "Reset current slot?", list("No", "Yes")))
|
||||
return 0
|
||||
load_character(SAVE_RESET)
|
||||
reset_slot()
|
||||
sanitize_preferences()
|
||||
else if(href_list["copy"])
|
||||
if(!IsGuestKey(usr.key))
|
||||
@@ -402,6 +430,12 @@ var/list/preferences_datums = list()
|
||||
// Ask the preferences datums to apply their own settings to the new mob
|
||||
player_setup.copy_to_mob(character)
|
||||
|
||||
for(var/datum/preference/preference as anything in get_preferences_in_priority_order())
|
||||
if(preference.savefile_identifier != PREFERENCE_CHARACTER)
|
||||
continue
|
||||
|
||||
preference.apply_to_human(character, read_preference(preference.type))
|
||||
|
||||
// VOREStation Edit - Sync up all their organs and species one final time
|
||||
character.force_update_organs()
|
||||
|
||||
@@ -420,26 +454,23 @@ var/list/preferences_datums = list()
|
||||
if(selecting_slots)
|
||||
to_chat(user, "<span class='warning'>You already have a slot selection dialog open!</span>")
|
||||
return
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S)
|
||||
error("Somehow missing savefile path?! [path]")
|
||||
if(!savefile)
|
||||
return
|
||||
|
||||
var/name
|
||||
var/nickname //vorestation edit - This set appends nicknames to the save slot
|
||||
var/default
|
||||
var/list/charlist = list()
|
||||
var/default //VOREStation edit
|
||||
for(var/i = 1, i <= CONFIG_GET(number/character_slots), i++) // CHOMPEdit
|
||||
S.cd = "/character[i]"
|
||||
S["real_name"] >> name
|
||||
S["nickname"] >> nickname //vorestation edit
|
||||
|
||||
for(var/i in 1 to CONFIG_GET(number/character_slots)) //CHOMPEdit
|
||||
var/list/save_data = savefile.get_entry("character[i]", list())
|
||||
var/name = save_data["real_name"]
|
||||
var/nickname = save_data["nickname"]
|
||||
if(!name)
|
||||
name = "[i] - \[Unused Slot\]"
|
||||
else if(i == default_slot)
|
||||
name = "►[i] - [name]"
|
||||
else
|
||||
name = "[i] - [name]"
|
||||
if (i == default_slot) //VOREStation edit
|
||||
if(i == default_slot)
|
||||
default = "[name][nickname ? " ([nickname])" : ""]"
|
||||
charlist["[name][nickname ? " ([nickname])" : ""]"] = i
|
||||
|
||||
@@ -454,33 +485,34 @@ var/list/preferences_datums = list()
|
||||
error("Player picked [choice] slot to load, but that wasn't one we sent.")
|
||||
return
|
||||
|
||||
load_preferences()
|
||||
load_character(slotnum)
|
||||
attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit
|
||||
sanitize_preferences()
|
||||
save_preferences()
|
||||
ShowChoices(user)
|
||||
|
||||
/datum/preferences/proc/open_copy_dialog(mob/user)
|
||||
if(selecting_slots)
|
||||
to_chat(user, "<span class='warning'>You already have a slot selection dialog open!</span>")
|
||||
return
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S)
|
||||
error("Somehow missing savefile path?! [path]")
|
||||
if(!savefile)
|
||||
return
|
||||
|
||||
var/name
|
||||
var/nickname //vorestation edit - This set appends nicknames to the save slot
|
||||
var/list/charlist = list()
|
||||
for(var/i = 1, i <= CONFIG_GET(number/character_slots), i++) // CHOMPEdit
|
||||
S.cd = "/character[i]"
|
||||
S["real_name"] >> name
|
||||
S["nickname"] >> nickname //vorestation edit
|
||||
|
||||
for(var/i in 1 to CONFIG_GET(number/character_slots)) //CHOMPEdit
|
||||
var/list/save_data = savefile.get_entry("character[i]", list())
|
||||
var/name = save_data["real_name"]
|
||||
var/nickname = save_data["nickname"]
|
||||
|
||||
if(!name)
|
||||
name = "[i] - \[Unused Slot\]"
|
||||
if(i == default_slot)
|
||||
else if(i == default_slot)
|
||||
name = "►[i] - [name]"
|
||||
else
|
||||
name = "[i] - [name]"
|
||||
|
||||
charlist["[name][nickname ? " ([nickname])" : ""]"] = i
|
||||
|
||||
selecting_slots = TRUE
|
||||
@@ -494,10 +526,10 @@ var/list/preferences_datums = list()
|
||||
error("Player picked [choice] slot to copy to, but that wasn't one we sent.")
|
||||
return
|
||||
|
||||
if(tgui_alert(user, "Are you sure you want to override slot [slotnum], [name][nickname ? " ([nickname])" : ""]'s savedata?", "Confirm Override", list("No", "Yes")) == "Yes")
|
||||
if(tgui_alert(user, "Are you sure you want to override slot [slotnum], [choice]'s savedata?", "Confirm Override", list("No", "Yes")) == "Yes")
|
||||
overwrite_character(slotnum)
|
||||
sanitize_preferences()
|
||||
save_preferences()
|
||||
save_character()
|
||||
save_preferences()
|
||||
attempt_vr(user.client?.prefs_vr,"load_vore","")
|
||||
ShowChoices(user)
|
||||
|
||||
456
code/modules/client/preferences/README.md
Normal file
456
code/modules/client/preferences/README.md
Normal file
@@ -0,0 +1,456 @@
|
||||
# Preferences (by Mothblocks)
|
||||
|
||||
This does not contain all the information on specific values--you can find those as doc-comments in relevant paths, such as `/datum/preference`. Rather, this gives you an overview for creating *most* preferences, and getting your foot in the door to create more advanced ones.
|
||||
|
||||
## Anatomy of a preference (A.K.A. how do I make one?)
|
||||
|
||||
Most preferences consist of two parts:
|
||||
|
||||
1. A `/datum/preference` type.
|
||||
2. A tgui representation in a TypeScript file.
|
||||
|
||||
Every `/datum/preference` requires these three values be set:
|
||||
1. `category` - See [Categories](#Categories).
|
||||
2. `savefile_key` - The value which will be saved in the savefile. This will also be the identifier for tgui.
|
||||
3. `savefile_identifier` - Whether or not this is a character specific preference (`PREFERENCE_CHARACTER`) or one that affects the player (`PREFERENCE_PLAYER`). As an example: hair color is `PREFERENCE_CHARACTER` while your UI settings are `PREFERENCE_PLAYER`, since they do not change between characters.
|
||||
|
||||
For the tgui representation, most preferences will create a `.tsx` file in `tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/`. If your preference is a character preference, make a new file in `character_preferences`. Otherwise, put it in `game_preferences`. The filename does not matter, and this file can hold multiple relevant preferences if you would like.
|
||||
|
||||
From here, you will want to write code resembling:
|
||||
|
||||
```ts
|
||||
import { Feature } from "../base";
|
||||
|
||||
export const savefile_key_here: Feature<T> = {
|
||||
name: "Preference Name Here",
|
||||
component: Component,
|
||||
|
||||
// Necessary for game preferences, unused for others
|
||||
category: "CATEGORY",
|
||||
|
||||
// Optional, shown as a tooltip
|
||||
description: "This preference will blow your mind!",
|
||||
}
|
||||
```
|
||||
|
||||
`T` and `Component` depend on the type of preference you're making. Here are all common examples...
|
||||
|
||||
## Numeric preferences
|
||||
|
||||
Examples include age and FPS.
|
||||
|
||||
A numeric preference derives from `/datum/preference/numeric`.
|
||||
|
||||
```dm
|
||||
/datum/preference/numeric/legs
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "legs"
|
||||
|
||||
minimum = 1
|
||||
maximum = 8
|
||||
```
|
||||
|
||||
You can optionally provide a `step` field. This value is 1 by default, meaning only integers are accepted.
|
||||
|
||||
Your `.tsx` file would look like:
|
||||
|
||||
```ts
|
||||
import { Feature, FeatureNumberInput } from "../base";
|
||||
|
||||
export const legs: Feature<number> = {
|
||||
name: "Legs",
|
||||
component: FeatureNumberInput,
|
||||
}
|
||||
```
|
||||
|
||||
## Toggle preferences
|
||||
|
||||
Examples include enabling tooltips.
|
||||
|
||||
```dm
|
||||
/datum/preference/toggle/enable_breathing
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "enable_breathing"
|
||||
|
||||
// Optional, TRUE by default
|
||||
default_value = FALSE
|
||||
```
|
||||
|
||||
Your `.tsx` file would look like:
|
||||
|
||||
```ts
|
||||
import { CheckboxInput, FeatureToggle } from "../base";
|
||||
|
||||
export const enable_breathing: FeatureToggle = {
|
||||
name: "Enable breathing",
|
||||
component: CheckboxInput,
|
||||
}
|
||||
```
|
||||
|
||||
## Choiced preferences
|
||||
A choiced preference is one where the only options are in a distinct few amount of choices. Examples include skin tone, shirt, and UI style.
|
||||
|
||||
To create one, derive from `/datum/preference/choiced`.
|
||||
|
||||
```dm
|
||||
/datum/preference/choiced/favorite_drink
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "favorite_drink"
|
||||
```
|
||||
|
||||
Now we need to tell the game what the choices are. We do this by overriding `init_possible_values()`. This will return a list of possible options.
|
||||
|
||||
```dm
|
||||
/datum/preference/choiced/favorite_drink/init_possible_values()
|
||||
return list(
|
||||
"Milk",
|
||||
"Cola",
|
||||
"Water",
|
||||
)
|
||||
```
|
||||
|
||||
Your `.tsx` file would then look like:
|
||||
|
||||
```tsx
|
||||
import { FeatureChoiced, FeatureDropdownInput } from "../base";
|
||||
|
||||
export const favorite_drink: FeatureChoiced = {
|
||||
name: "Favorite drink",
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
```
|
||||
|
||||
This will create a dropdown input for your preference.
|
||||
|
||||
### Choiced preferences - Icons
|
||||
Choiced preferences can generate icons. This is how the clothing/species preferences work, for instance. However, if we just want a basic dropdown input with icons, it would look like this:
|
||||
|
||||
```dm
|
||||
/datum/preference/choiced/favorite_drink
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "favorite_drink"
|
||||
should_generate_icons = TRUE // NEW! This is necessary.
|
||||
|
||||
/datum/preference/choiced/favorite_drink/init_possible_values()
|
||||
return list("Milk", "Cola", "Water")
|
||||
|
||||
// New! This proc will get called for every value.
|
||||
/datum/preference/choiced/favorite_drink/icon_for(value)
|
||||
switch (value)
|
||||
if ("Milk")
|
||||
return icon('drinks.dmi', "milk")
|
||||
if ("Cola")
|
||||
return icon('drinks.dmi', "cola")
|
||||
if ("Water")
|
||||
return icon('drinks.dmi', "water")
|
||||
```
|
||||
|
||||
Then, change your `.tsx` file to look like:
|
||||
|
||||
```tsx
|
||||
import { FeatureChoiced, FeatureIconnedDropdownInput } from "../base";
|
||||
|
||||
export const favorite_drink: FeatureChoiced = {
|
||||
name: "Favorite drink",
|
||||
component: FeatureIconnedDropdownInput,
|
||||
};
|
||||
```
|
||||
|
||||
### Choiced preferences - Display names
|
||||
Sometimes the values you want to save in code aren't the same as the ones you want to display. You can specify display names to change this.
|
||||
|
||||
The only thing you will add is "compiled data".
|
||||
|
||||
```dm
|
||||
/datum/preference/choiced/favorite_drink/compile_constant_data()
|
||||
var/list/data = ..()
|
||||
|
||||
// An assoc list of values to display names
|
||||
data[CHOICED_PREFERENCE_DISPLAY_NAMES] = list(
|
||||
"Milk" = "Delicious Milk",
|
||||
"Cola" = "Crisp Cola",
|
||||
"Water" = "Plain Ol' Water",
|
||||
)
|
||||
|
||||
return data
|
||||
```
|
||||
|
||||
Your `.tsx` file does not change. The UI will figure it out for you!
|
||||
|
||||
## Color preferences
|
||||
These refer to colors, such as your OOC color. When read, these values will be given as 6 hex digits, *without* the pound sign.
|
||||
|
||||
```dm
|
||||
/datum/preference/color/eyeliner_color
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "eyeliner_color"
|
||||
```
|
||||
|
||||
Your `.tsx` file would look like:
|
||||
|
||||
```ts
|
||||
import { FeatureColorInput, Feature } from "../base";
|
||||
|
||||
export const eyeliner_color: Feature<string> = {
|
||||
name: "Eyeliner color",
|
||||
component: FeatureColorInput,
|
||||
};
|
||||
```
|
||||
|
||||
## Name preferences
|
||||
These refer to an alternative name. Examples include AI names and backup human names.
|
||||
|
||||
These exist in `code/modules/client/preferences/names.dm`.
|
||||
|
||||
These do not need a `.ts` file, and will be created in the UI automatically.
|
||||
|
||||
```dm
|
||||
/datum/preference/name/doctor
|
||||
savefile_key = "doctor_name"
|
||||
|
||||
// The name on the UI
|
||||
explanation = "Doctor name"
|
||||
|
||||
// This groups together with anything else with the same group
|
||||
group = "medicine"
|
||||
|
||||
// Optional, if specified the UI will show this name actively
|
||||
// when the player is a medical doctor.
|
||||
relevant_job = /datum/job/medical_doctor
|
||||
```
|
||||
|
||||
## Making your preference do stuff
|
||||
|
||||
There are a handful of procs preferences can use to act on their own:
|
||||
|
||||
```dm
|
||||
/// Apply this preference onto the given client.
|
||||
/// Called when the savefile_identifier == PREFERENCE_PLAYER.
|
||||
/datum/preference/proc/apply_to_client(client/client, value)
|
||||
|
||||
/// Fired when the preference is updated.
|
||||
/// Calls apply_to_client by default, but can be overridden.
|
||||
/datum/preference/proc/apply_to_client_updated(client/client, value)
|
||||
|
||||
/// Apply this preference onto the given human.
|
||||
/// Must be overriden by subtypes.
|
||||
/// Called when the savefile_identifier == PREFERENCE_CHARACTER.
|
||||
/datum/preference/proc/apply_to_human(mob/living/carbon/human/target, value)
|
||||
```
|
||||
|
||||
For example, `/datum/preference/numeric/age` contains:
|
||||
|
||||
```dm
|
||||
/datum/preference/numeric/age/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.age = value
|
||||
```
|
||||
|
||||
If your preference is `PREFERENCE_CHARACTER`, it MUST override `apply_to_human`, even if just to immediately `return`.
|
||||
|
||||
You can also read preferences directly with `prefs.read_preference(/datum/preference/type/here)`, which will return the stored value.
|
||||
|
||||
## Categories
|
||||
Every preference needs to be in a `category`. These can be found in `code/__DEFINES/preferences.dm`.
|
||||
|
||||
```dm
|
||||
/// These will be shown in the character sidebar, but at the bottom.
|
||||
#define PREFERENCE_CATEGORY_FEATURES "features"
|
||||
|
||||
/// Any preferences that will show to the sides of the character in the setup menu.
|
||||
#define PREFERENCE_CATEGORY_CLOTHING "clothing"
|
||||
|
||||
/// Preferences that will be put into the 3rd list, and are not contextual.
|
||||
#define PREFERENCE_CATEGORY_NON_CONTEXTUAL "non_contextual"
|
||||
|
||||
/// Will be put under the game preferences window.
|
||||
#define PREFERENCE_CATEGORY_GAME_PREFERENCES "game_preferences"
|
||||
|
||||
/// These will show in the list to the right of the character preview.
|
||||
#define PREFERENCE_CATEGORY_SECONDARY_FEATURES "secondary_features"
|
||||
|
||||
/// These are preferences that are supplementary for main features,
|
||||
/// such as hair color being affixed to hair.
|
||||
#define PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES "supplemental_features"
|
||||
```
|
||||
|
||||

|
||||
|
||||
> SECONDARY_FEATURES or NON_CONTEXTUAL?
|
||||
|
||||
Secondary features tend to be species specific. Non contextual features shouldn't change much from character to character.
|
||||
|
||||
## Default values and randomization
|
||||
|
||||
There are three procs to be aware of in regards to this topic:
|
||||
|
||||
- `create_default_value()`. This is used when a value deserializes improperly or when a new character is created.
|
||||
- `create_informed_default_value(datum/preferences/preferences)` - Used for more complicated default values, like how names require the gender. Will call `create_default_value()` by default.
|
||||
- `create_random_value(datum/preferences/preferences)` - Explicitly used for random values, such as when a character is being randomized.
|
||||
|
||||
`create_default_value()` in most preferences will create a random value. If this is a problem (like how default characters should always be human), you can override `create_default_value()`. By default (without overriding `create_random_value`), random values are just default values.
|
||||
|
||||
## Advanced - Server data
|
||||
|
||||
As previewed in [the display names implementation](#Choiced-preferences---Display-names), there exists a `compile_constant_data()` proc you can override.
|
||||
|
||||
Compiled data is used wherever the server needs to give the client some value it can't figure out on its own. Skin tones use this to tell the client what colors they represent, for example.
|
||||
|
||||
Compiled data is sent to the `serverData` field in the `FeatureValueProps`.
|
||||
|
||||
## Advanced - Creating your own tgui component
|
||||
|
||||
If you have good knowledge with tgui (especially TypeScript), you'll be able to create your own component to represent preferences.
|
||||
|
||||
The `component` field in a feature accepts __any__ component that accepts `FeatureValueProps<TReceiving, TSending = TReceiving, TServerData = undefined>`.
|
||||
|
||||
This will give you the fields:
|
||||
|
||||
```ts
|
||||
act: typeof sendAct,
|
||||
featureId: string,
|
||||
handleSetValue: (newValue: TSending) => void,
|
||||
serverData: TServerData | undefined,
|
||||
shrink?: boolean,
|
||||
value: TReceiving,
|
||||
```
|
||||
|
||||
`act` is the same as the one you get from `useBackend`.
|
||||
|
||||
`featureId` is the savefile_key of the feature.
|
||||
|
||||
`handleSetValue` is a function that, when called, will tell the server the new value, as well as changing the value immediately locally.
|
||||
|
||||
`serverData` is the [server data](#Advanced---Server-data), if it has been fetched yet (and exists).
|
||||
|
||||
`shrink` is whether or not the UI should appear smaller. This is only used for supplementary features.
|
||||
|
||||
`value` is the current value, could be predicted (meaning that the value was changed locally, but has not yet reached the server).
|
||||
|
||||
For a basic example of how this can look, observe `CheckboxInput`:
|
||||
|
||||
```tsx
|
||||
export const CheckboxInput = (
|
||||
props: FeatureValueProps<BooleanLike, boolean>
|
||||
) => {
|
||||
return (<Button.Checkbox
|
||||
checked={!!props.value}
|
||||
onClick={() => {
|
||||
props.handleSetValue(!props.value);
|
||||
}}
|
||||
/>);
|
||||
};
|
||||
```
|
||||
|
||||
## Advanced - Middleware
|
||||
A `/datum/preference_middleware` is a way to inject your own data at specific points, as well as hijack actions.
|
||||
|
||||
Middleware can hijack actions by specifying `action_delegations`:
|
||||
|
||||
```dm
|
||||
/datum/preference_middleware/congratulations
|
||||
action_delegations = list(
|
||||
"congratulate_me" = PROC_REF(congratulate_me),
|
||||
)
|
||||
|
||||
/datum/preference_middleware/congratulations/proc/congratulate_me(list/params, mob/user)
|
||||
to_chat(user, span_notice("Wow, you did a great job learning about middleware!"))
|
||||
|
||||
return TRUE
|
||||
```
|
||||
|
||||
Middleware can inject its own data at several points, such as providing new UI assets, compiled data (used by middleware such as quirks to tell the client what quirks exist), etc. Look at `code/modules/client/preferences/middleware/_middleware.dm` for full information.
|
||||
|
||||
---
|
||||
|
||||
## Antagonists
|
||||
|
||||
In order to make an antagonist selectable, you must do a few things:
|
||||
|
||||
1. Your antagonist needs an icon.
|
||||
2. Your antagonist must be in a Dynamic ruleset. The ruleset must specify the antagonist as its `antag_flag`.
|
||||
3. Your antagonist needs a file in `tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/filename.ts`. This file name MUST be the `antag_flag` of your ruleset, with nothing but letters remaining (e.g. "Nuclear Operative" -> `nuclearoperative`).
|
||||
4. Add it to `special_roles`.
|
||||
|
||||
## Creating icons
|
||||
|
||||
If you are satisfied with your icon just being a dude with some clothes, then you can specify `preview_outfit` in your `/datum/antagonist`.
|
||||
|
||||
Space Ninja, for example, looks like:
|
||||
|
||||
```dm
|
||||
/datum/antagonist/ninja
|
||||
preview_outift = /datum/outfit/ninja
|
||||
```
|
||||
|
||||
However, if you want to get creative, you can override `/get_preview_icon()`. This proc should return an icon of size `ANTAGONIST_PREVIEW_ICON_SIZE`x`ANTAGONIST_PREVIEW_ICON_SIZE`.
|
||||
|
||||
There are some helper procs you can use as well. `render_preview_outfit(outfit_type)` will take an outfit and give you an icon of someone wearing those clothes. `finish_preview_outfit` will, given an icon, resize it appropriately and zoom in on the head. Note that this will look bad on anything that isn't a human, so if you have a non-human antagonist (such as sentient disease), just run `icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE)`.
|
||||
|
||||
For inspiration, here is changeling's:
|
||||
|
||||
```dm
|
||||
/datum/antagonist/changeling/get_preview_icon()
|
||||
var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling)
|
||||
var/icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer)
|
||||
|
||||
final_icon.Shift(WEST, world.icon_size / 2)
|
||||
final_icon.Shift(EAST, world.icon_size / 2)
|
||||
|
||||
split_icon.Shift(EAST, world.icon_size / 2)
|
||||
split_icon.Shift(WEST, world.icon_size / 2)
|
||||
|
||||
final_icon.Blend(split_icon, ICON_OVERLAY)
|
||||
|
||||
return finish_preview_icon(final_icon)
|
||||
```
|
||||
|
||||
...which creates:
|
||||
|
||||

|
||||
|
||||
## Creating the tgui representation
|
||||
|
||||
In the `.ts` file you created earlier, you must now give the information of your antagonist. For reference, this is the changeling's:
|
||||
|
||||
```ts
|
||||
import { Antagonist, Category } from "../base";
|
||||
import { multiline } from "common/string";
|
||||
|
||||
const Changeling: Antagonist = {
|
||||
key: "changeling", // This must be the same as your filename
|
||||
name: "Changeling",
|
||||
description: [
|
||||
multiline`
|
||||
A highly intelligent alien predator that is capable of altering their
|
||||
shape to flawlessly resemble a human.
|
||||
`,
|
||||
|
||||
multiline`
|
||||
Transform yourself or others into different identities, and buy from an
|
||||
arsenal of biological weaponry with the DNA you collect.
|
||||
`,
|
||||
],
|
||||
category: Category.Roundstart, // Category.Roundstart, Category.Midround, or Category.Latejoin
|
||||
};
|
||||
|
||||
export default Changeling;
|
||||
```
|
||||
|
||||
## Readying the Dynamic ruleset
|
||||
|
||||
You already need to create a Dynamic ruleset, so in order to get your antagonist recognized, you just need to specify `antag_flag`. This must be unique per ruleset.
|
||||
|
||||
Two other values to note are `antag_flag_override` and `antag_preference`.
|
||||
|
||||
`antag_flag_override` exists for cases where you want the banned antagonist to be separate from `antag_flag`. As an example: roundstart, midround, and latejoin traitors have separate `antag_flag`, but all have `antag_flag_override = ROLE_TRAITOR`. This is because admins want to ban a player from Traitor altogether, not specific rulesets.
|
||||
|
||||
If `antag_preference` is set, it will refer to that preference instead of `antag_flag`. This is used for clown operatives, which we want to be on the same preference as standard nuke ops, but must specify a unique `antag_flag` for.
|
||||
|
||||
## Updating special_roles
|
||||
|
||||
In `code/__DEFINES/role_preferences.dm` (the same place you'll need to make your ROLE_\* defined), simply add your antagonist to the `special_roles` assoc list. The key is your ROLE, the value is the number of days since your first game in order to play as that antagonist.
|
||||
546
code/modules/client/preferences/_preference.dm
Normal file
546
code/modules/client/preferences/_preference.dm
Normal file
@@ -0,0 +1,546 @@
|
||||
// Priorities must be in order!
|
||||
/// The default priority level
|
||||
#define PREFERENCE_PRIORITY_DEFAULT 1
|
||||
|
||||
/// The priority at which species runs, needed for external organs to apply properly.
|
||||
#define PREFERENCE_PRIORITY_SPECIES 2
|
||||
|
||||
/**
|
||||
* Some preferences get applied directly to bodyparts (anything head_flags related right now).
|
||||
* These must apply after species, as species gaining might replace the bodyparts of the human.
|
||||
*/
|
||||
#define PREFERENCE_PRIORITY_BODYPARTS 3
|
||||
|
||||
/// The priority at which gender is determined, needed for proper randomization.
|
||||
#define PREFERENCE_PRIORITY_GENDER 4
|
||||
|
||||
/// The priority at which body type is decided, applied after gender so we can
|
||||
/// support the "use gender" option.
|
||||
#define PREFERENCE_PRIORITY_BODY_TYPE 5
|
||||
|
||||
/// Used for preferences that rely on body setup being finalized.
|
||||
#define PREFERENCE_PRORITY_LATE_BODY_TYPE 6
|
||||
|
||||
/// Equpping items based on preferences.
|
||||
/// Should happen after species and body type to make sure it looks right.
|
||||
/// Mostly redundant, but a safety net for saving/loading.
|
||||
#define PREFERENCE_PRIORITY_LOADOUT 7
|
||||
|
||||
/// The priority at which names are decided, needed for proper randomization.
|
||||
#define PREFERENCE_PRIORITY_NAMES 8
|
||||
|
||||
/// Preferences that aren't names, but change the name changes set by PREFERENCE_PRIORITY_NAMES.
|
||||
#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 9
|
||||
|
||||
/// The maximum preference priority, keep this updated, but don't use it for `priority`.
|
||||
#define MAX_PREFERENCE_PRIORITY PREFERENCE_PRIORITY_NAME_MODIFICATIONS
|
||||
|
||||
/// For choiced preferences, this key will be used to set display names in constant data.
|
||||
#define CHOICED_PREFERENCE_DISPLAY_NAMES "display_names"
|
||||
|
||||
/// For main feature preferences, this key refers to a feature considered supplemental.
|
||||
/// For instance, hair color being supplemental to hair.
|
||||
#define SUPPLEMENTAL_FEATURE_KEY "supplemental_feature"
|
||||
|
||||
/// An assoc list list of types to instantiated `/datum/preference` instances
|
||||
GLOBAL_LIST_INIT(preference_entries, init_preference_entries())
|
||||
|
||||
/// An assoc list of preference entries by their `savefile_key`
|
||||
GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
||||
|
||||
/proc/init_preference_entries()
|
||||
var/list/output = list()
|
||||
for(var/datum/preference/preference_type as anything in subtypesof(/datum/preference))
|
||||
if(is_abstract(preference_type))
|
||||
continue
|
||||
output[preference_type] = new preference_type
|
||||
return output
|
||||
|
||||
/proc/init_preference_entries_by_key()
|
||||
var/list/output = list()
|
||||
for(var/datum/preference/preference_type as anything in subtypesof(/datum/preference))
|
||||
if(is_abstract(preference_type))
|
||||
continue
|
||||
output[initial(preference_type.savefile_key)] = GLOB.preference_entries[preference_type]
|
||||
return output
|
||||
|
||||
/// Returns a flat list of preferences in order of their priority
|
||||
/proc/get_preferences_in_priority_order()
|
||||
var/list/preferences[MAX_PREFERENCE_PRIORITY]
|
||||
|
||||
for(var/preference_type in GLOB.preference_entries)
|
||||
var/datum/preference/preference = GLOB.preference_entries[preference_type]
|
||||
LAZYADD(preferences[preference.priority], preference)
|
||||
|
||||
var/list/flattened = list()
|
||||
for(var/index in 1 to MAX_PREFERENCE_PRIORITY)
|
||||
// Don't add nulls to the list if there's no preferences in a given priority level
|
||||
if(LAZYLEN(preferences[index]))
|
||||
flattened += preferences[index]
|
||||
return flattened
|
||||
|
||||
/// Represents an individual preference.
|
||||
/datum/preference
|
||||
/// The key inside the savefile to use.
|
||||
/// This is also sent to the UI.
|
||||
/// Once you pick this, don't change it.
|
||||
var/savefile_key
|
||||
|
||||
/// The category of preference, for use by the PreferencesMenu.
|
||||
/// This isn't used for anything other than as a key for UI data.
|
||||
/// It is up to the PreferencesMenu UI itself to interpret it.
|
||||
var/category = "misc"
|
||||
|
||||
/// Do not instantiate if type matches this.
|
||||
abstract_type = /datum/preference
|
||||
|
||||
/// What savefile should this preference be read from?
|
||||
/// Valid values are PREFERENCE_CHARACTER and PREFERENCE_PLAYER.
|
||||
/// See the documentation in [code/__DEFINES/preferences.dm].
|
||||
var/savefile_identifier
|
||||
|
||||
/// The priority of when to apply this preference.
|
||||
/// Used for when you need to rely on another preference.
|
||||
var/priority = PREFERENCE_PRIORITY_DEFAULT
|
||||
|
||||
/// If set, will be available to randomize, but only if the preference
|
||||
/// is for PREFERENCE_CHARACTER.
|
||||
var/can_randomize = TRUE
|
||||
|
||||
/// If randomizable (PREFERENCE_CHARACTER and can_randomize), whether
|
||||
/// or not to enable randomization by default.
|
||||
/// This doesn't mean it'll always be random, but rather if a player
|
||||
/// DOES have random body on, will this already be randomized?
|
||||
var/randomize_by_default = TRUE
|
||||
|
||||
/// If the selected species has this in its /datum/species/mutant_bodyparts,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_mutant_bodypart = null
|
||||
|
||||
/// If the selected species has this in its /datum/species/body_markings,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_body_markings = null
|
||||
|
||||
/// If the selected species has this in its /datum/species/inherent_traits,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_inherent_trait = null
|
||||
|
||||
/// If the selected species has this in its /datum/species/var/external_organs,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_external_organ = null
|
||||
|
||||
/// If the selected species has this head_flag by default,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_head_flag = null
|
||||
|
||||
/// Called on the saved input when retrieving.
|
||||
/// Also called by the value sent from the user through UI. Do not trust it.
|
||||
/// Input is the value inside the savefile, output is to tell other code
|
||||
/// what the value is.
|
||||
/// This is useful either for more optimal data saving or for migrating
|
||||
/// older data.
|
||||
/// Must be overridden by subtypes.
|
||||
/// Can return null if no value was found.
|
||||
/datum/preference/proc/pref_deserialize(input, datum/preferences/preferences)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("`pref_deserialize()` was not implemented on [type]!")
|
||||
|
||||
/// Called on the input while saving.
|
||||
/// Input is the current value, output is what to save in the savefile.
|
||||
/datum/preference/proc/pref_serialize(input)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
return input
|
||||
|
||||
/// Produce a default, potentially random value for when no value for this
|
||||
/// preference is found in the savefile.
|
||||
/// Either this or create_informed_default_value must be overriden by subtypes.
|
||||
/datum/preference/proc/create_default_value()
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("`create_default_value()` was not implemented on [type]!")
|
||||
|
||||
/// Produce a default, potentially random value for when no value for this
|
||||
/// preference is found in the savefile.
|
||||
/// Unlike create_default_value(), will provide the preferences object if you
|
||||
/// need to use it.
|
||||
/// If not overriden, will call create_default_value() instead.
|
||||
/datum/preference/proc/create_informed_default_value(datum/preferences/preferences)
|
||||
return create_default_value()
|
||||
|
||||
/// Produce a random value for the purposes of character randomization.
|
||||
/// Will just create a default value by default.
|
||||
/datum/preference/proc/create_random_value(datum/preferences/preferences)
|
||||
return create_informed_default_value(preferences)
|
||||
|
||||
/// Returns whether or not a preference can be randomized.
|
||||
/datum/preference/proc/is_randomizable()
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
return savefile_identifier == PREFERENCE_CHARACTER && can_randomize
|
||||
|
||||
/// Given a savefile, return either the saved data or an acceptable default.
|
||||
/// This will write to the savefile if a value was not found with the new value.
|
||||
/datum/preference/proc/read(list/save_data, datum/preferences/preferences)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
|
||||
var/value
|
||||
|
||||
if(!isnull(save_data))
|
||||
value = save_data[savefile_key]
|
||||
|
||||
if(isnull(value))
|
||||
return null
|
||||
else
|
||||
return pref_deserialize(value, preferences)
|
||||
|
||||
/// Given a savefile, writes the inputted value.
|
||||
/// Returns TRUE for a successful application.
|
||||
/// Return FALSE if it is invalid.
|
||||
/datum/preference/proc/write(list/save_data, value)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
|
||||
if(!is_valid(value))
|
||||
return FALSE
|
||||
|
||||
if(!isnull(save_data))
|
||||
save_data[savefile_key] = pref_serialize(value)
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Apply this preference onto the given client.
|
||||
/// Called when the savefile_identifier == PREFERENCE_PLAYER.
|
||||
/datum/preference/proc/apply_to_client(client/client, value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return
|
||||
|
||||
/// Fired when the preference is updated.
|
||||
/// Calls apply_to_client by default, but can be overridden.
|
||||
/datum/preference/proc/apply_to_client_updated(client/client, value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
apply_to_client(client, value)
|
||||
|
||||
/// Apply this preference onto the given human.
|
||||
/// Must be overriden by subtypes.
|
||||
/// Called when the savefile_identifier == PREFERENCE_CHARACTER.
|
||||
/datum/preference/proc/apply_to_human(mob/living/carbon/human/target, value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("`apply_to_human()` was not implemented for [type]!")
|
||||
|
||||
/// Returns which savefile to use for a given savefile identifier
|
||||
/datum/preferences/proc/get_save_data_for_savefile_identifier(savefile_identifier)
|
||||
RETURN_TYPE(/list)
|
||||
|
||||
if(!client)
|
||||
return null
|
||||
if(!savefile)
|
||||
CRASH("Attempted to get the savedata for [savefile_identifier] of [client] without a savefile. This should have been handled by load_preferences()")
|
||||
|
||||
// Both of these will cache savefiles, but only for a tick.
|
||||
// This is because storing a savefile will lock it, causing later issues down the line.
|
||||
// Do not change them to addtimer, since the timer SS might not be running at this time.
|
||||
switch (savefile_identifier)
|
||||
if(PREFERENCE_CHARACTER)
|
||||
return savefile.get_entry("character[default_slot]")
|
||||
if(PREFERENCE_PLAYER)
|
||||
return savefile.get_entry()
|
||||
else
|
||||
CRASH("Unknown savefile identifier [savefile_identifier]")
|
||||
|
||||
/// Read a /datum/preference type and return its value.
|
||||
/// This will write to the savefile if a value was not found with the new value.
|
||||
/datum/preferences/proc/read_preference(preference_type)
|
||||
var/datum/preference/preference_entry = GLOB.preference_entries[preference_type]
|
||||
if(isnull(preference_entry))
|
||||
var/extra_info = ""
|
||||
|
||||
// Current initializing subsystem is important to know because it might be a problem with
|
||||
// things running pre-assets-initialization.
|
||||
// if(!isnull(Master.current_initializing_subsystem))
|
||||
// extra_info = "Info was attempted to be retrieved while [Master.current_initializing_subsystem] was initializing."
|
||||
// else if(!MC_RUNNING())
|
||||
// extra_info = "Info was attempted to be retrieved before the MC started, but not while it was actively initializing a subsystem"
|
||||
|
||||
CRASH("Preference type `[preference_type]` is invalid! [extra_info]")
|
||||
|
||||
if(preference_type in value_cache)
|
||||
return value_cache[preference_type]
|
||||
|
||||
var/value = preference_entry.read(get_save_data_for_savefile_identifier(preference_entry.savefile_identifier), src)
|
||||
if(isnull(value))
|
||||
value = preference_entry.create_informed_default_value(src)
|
||||
if(write_preference(preference_entry, value))
|
||||
return value
|
||||
else
|
||||
CRASH("Couldn't write the default value for [preference_type] (received [value])")
|
||||
value_cache[preference_type] = value
|
||||
return value
|
||||
|
||||
/// Read a /datum/preference type and return its value.
|
||||
/mob/proc/read_preference(preference_type)
|
||||
return client?.prefs?.read_preference(preference_type)
|
||||
|
||||
/// Set a /datum/preference entry.
|
||||
/// Returns TRUE for a successful preference application.
|
||||
/// Returns FALSE if it is invalid.
|
||||
/datum/preferences/proc/write_preference(datum/preference/preference, preference_value)
|
||||
var/save_data = get_save_data_for_savefile_identifier(preference.savefile_identifier)
|
||||
var/new_value = preference.pref_deserialize(preference_value, src)
|
||||
var/success = preference.write(save_data, new_value)
|
||||
if(success)
|
||||
value_cache[preference.type] = new_value
|
||||
return success
|
||||
|
||||
/// Will perform an update on the preference, but not write to the savefile.
|
||||
/// This will, for instance, update the character preference view.
|
||||
/// Performs sanity checks.
|
||||
/datum/preferences/proc/update_preference(datum/preference/preference, preference_value)
|
||||
if(!preference.is_accessible(src))
|
||||
return FALSE
|
||||
|
||||
var/new_value = preference.pref_deserialize(preference_value, src)
|
||||
var/success = preference.write(null, new_value)
|
||||
|
||||
if(!success)
|
||||
return FALSE
|
||||
|
||||
recently_updated_keys |= preference.type
|
||||
value_cache[preference.type] = new_value
|
||||
|
||||
if(preference.savefile_identifier == PREFERENCE_PLAYER)
|
||||
preference.apply_to_client_updated(client, read_preference(preference.type))
|
||||
else
|
||||
update_preview_icon()
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Checks that a given value is valid.
|
||||
/// Must be overriden by subtypes.
|
||||
/// Any type can be passed through.
|
||||
/datum/preference/proc/is_valid(value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("`is_valid()` was not implemented for [type]!")
|
||||
|
||||
/// Returns data to be sent to users in the menu
|
||||
/datum/preference/proc/compile_ui_data(mob/user, value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
return pref_serialize(value)
|
||||
|
||||
/// Returns data compiled into the preferences JSON asset
|
||||
/datum/preference/proc/compile_constant_data()
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
return null
|
||||
|
||||
/// Returns whether or not this preference is accessible.
|
||||
/// If FALSE, will not show in the UI and will not be editable (by update_preference).
|
||||
/datum/preference/proc/is_accessible(datum/preferences/preferences)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
// if(
|
||||
// !isnull(relevant_mutant_bodypart)
|
||||
// || !isnull(relevant_inherent_trait)
|
||||
// || !isnull(relevant_external_organ)
|
||||
// || !isnull(relevant_head_flag)
|
||||
// || !isnull(relevant_body_markings)
|
||||
// )
|
||||
// var/species_type = preferences.read_preference(/datum/preference/choiced/species)
|
||||
|
||||
// var/datum/species/species = GLOB.species_prototypes[species_type]
|
||||
// if(!(savefile_key in species.get_features()))
|
||||
// return FALSE
|
||||
|
||||
if(!should_show_on_page(preferences.current_window))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Returns whether or not, given the PREFERENCE_TAB_*, this preference should
|
||||
/// appear.
|
||||
/datum/preference/proc/should_show_on_page(preference_tab)
|
||||
var/is_on_character_page = preference_tab == PREFERENCE_TAB_CHARACTER_PREFERENCES
|
||||
var/is_character_preference = savefile_identifier == PREFERENCE_CHARACTER
|
||||
return is_on_character_page == is_character_preference
|
||||
|
||||
/// A preference that is a choice of one option among a fixed set.
|
||||
/// Used for preferences such as clothing.
|
||||
/datum/preference/choiced
|
||||
/// If this is TRUE, an icon will be generated for every value.
|
||||
/// If you implement this, you must implement `icon_for(value)` for every possible value.
|
||||
var/should_generate_icons = FALSE
|
||||
|
||||
var/list/cached_values
|
||||
|
||||
/// If the preference is a main feature (PREFERENCE_CATEGORY_FEATURES or PREFERENCE_CATEGORY_CLOTHING)
|
||||
/// this is the name of the feature that will be presented.
|
||||
var/main_feature_name
|
||||
|
||||
abstract_type = /datum/preference/choiced
|
||||
|
||||
/// Returns a list of every possible value.
|
||||
/// The first time this is called, will run `init_values()`.
|
||||
/// Return value can be in the form of:
|
||||
/// - A flat list of raw values, such as list(MALE, FEMALE, PLURAL).
|
||||
/// - An assoc list of raw values to atoms/icons.
|
||||
/datum/preference/choiced/proc/get_choices()
|
||||
// Override `init_values()` instead.
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
|
||||
if(isnull(cached_values))
|
||||
cached_values = init_possible_values()
|
||||
ASSERT(cached_values.len)
|
||||
|
||||
return cached_values
|
||||
|
||||
/// Returns a list of every possible value, serialized.
|
||||
/datum/preference/choiced/proc/get_choices_serialized()
|
||||
// Override `init_values()` instead.
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
|
||||
var/list/serialized_choices = list()
|
||||
|
||||
for(var/choice in get_choices())
|
||||
serialized_choices += pref_serialize(choice)
|
||||
|
||||
return serialized_choices
|
||||
|
||||
/// Returns a list of every possible value.
|
||||
/// This must be overriden by `/datum/preference/choiced` subtypes.
|
||||
/// If `should_generate_icons` is TRUE, then you will also need to implement `icon_for(value)`
|
||||
/// for every possible value.
|
||||
/datum/preference/choiced/proc/init_possible_values()
|
||||
CRASH("`init_possible_values()` was not implemented for [type]!")
|
||||
|
||||
/// When `should_generate_icons` is TRUE, this proc is called for every value.
|
||||
/// It can return either an icon or a typepath to an atom to create.
|
||||
/datum/preference/choiced/proc/icon_for(value)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
CRASH("`icon_for()` was not implemented for [type], even though should_generate_icons = TRUE!")
|
||||
|
||||
/datum/preference/choiced/is_valid(value)
|
||||
return value in get_choices()
|
||||
|
||||
/datum/preference/choiced/pref_deserialize(input, datum/preferences/preferences)
|
||||
return sanitize_inlist(input, get_choices(), create_default_value())
|
||||
|
||||
/datum/preference/choiced/create_default_value()
|
||||
return pick(get_choices())
|
||||
|
||||
/datum/preference/choiced/compile_constant_data()
|
||||
var/list/data = list()
|
||||
|
||||
var/list/choices = list()
|
||||
|
||||
for(var/choice in get_choices())
|
||||
choices += choice
|
||||
|
||||
data["choices"] = choices
|
||||
|
||||
if(should_generate_icons)
|
||||
var/list/icons = list()
|
||||
|
||||
// for(var/choice in choices) // TODO: Pref spritesheet asset
|
||||
// icons[choice] = get_spritesheet_key(choice)
|
||||
|
||||
data["icons"] = icons
|
||||
|
||||
if(!isnull(main_feature_name))
|
||||
data["name"] = main_feature_name
|
||||
|
||||
return data
|
||||
|
||||
/// A preference that represents an RGB color of something.
|
||||
/// Will give the value as 6 hex digits, without a hash.
|
||||
/datum/preference/color
|
||||
abstract_type = /datum/preference/color
|
||||
|
||||
/datum/preference/color/pref_deserialize(input, datum/preferences/preferences)
|
||||
return sanitize_hexcolor(input)
|
||||
|
||||
/datum/preference/color/create_default_value()
|
||||
return random_color()
|
||||
|
||||
/datum/preference/color/pref_serialize(input)
|
||||
return sanitize_hexcolor(input)
|
||||
|
||||
/datum/preference/color/is_valid(value)
|
||||
return findtext(value, GLOB.is_color)
|
||||
|
||||
/// A numeric preference with a minimum and maximum value
|
||||
/datum/preference/numeric
|
||||
/// The minimum value
|
||||
var/minimum
|
||||
|
||||
/// The maximum value
|
||||
var/maximum
|
||||
|
||||
/// The step of the number, such as 1 for integers or 0.5 for half-steps.
|
||||
var/step = 1
|
||||
|
||||
abstract_type = /datum/preference/numeric
|
||||
|
||||
/datum/preference/numeric/pref_deserialize(input, datum/preferences/preferences)
|
||||
if(istext(input)) // Sometimes TGUI will return a string instead of a number, so we take that into account.
|
||||
input = text2num(input) // Worst case, it's null, it'll just use create_default_value()
|
||||
return sanitize_float(input, minimum, maximum, step, create_default_value())
|
||||
|
||||
/datum/preference/numeric/pref_serialize(input)
|
||||
return sanitize_float(input, minimum, maximum, step, create_default_value())
|
||||
|
||||
/datum/preference/numeric/create_default_value()
|
||||
return rand(minimum, maximum)
|
||||
|
||||
/datum/preference/numeric/is_valid(value)
|
||||
return isnum(value) && value >= round(minimum, step) && value <= round(maximum, step)
|
||||
|
||||
/datum/preference/numeric/compile_constant_data()
|
||||
return list(
|
||||
"minimum" = minimum,
|
||||
"maximum" = maximum,
|
||||
"step" = step,
|
||||
)
|
||||
|
||||
/// A preference whose value is always TRUE or FALSE
|
||||
/datum/preference/toggle
|
||||
abstract_type = /datum/preference/toggle
|
||||
|
||||
/// The default value of the toggle, if create_default_value is not specified
|
||||
var/default_value = TRUE
|
||||
|
||||
/datum/preference/toggle/create_default_value()
|
||||
return default_value
|
||||
|
||||
/datum/preference/toggle/pref_deserialize(input, datum/preferences/preferences)
|
||||
return !!input
|
||||
|
||||
/datum/preference/toggle/is_valid(value)
|
||||
return value == TRUE || value == FALSE
|
||||
|
||||
|
||||
/// A string-based preference accepting arbitrary string values entered by the user, with a maximum length.
|
||||
/datum/preference/text
|
||||
abstract_type = /datum/preference/text
|
||||
|
||||
/// What is the maximum length of the value allowed in this field?
|
||||
var/maximum_value_length = 256
|
||||
|
||||
/// Should we strip HTML the input or simply restrict it to the maximum_value_length?
|
||||
var/should_strip_html = TRUE
|
||||
|
||||
|
||||
/datum/preference/text/pref_deserialize(input, datum/preferences/preferences)
|
||||
return should_strip_html ? STRIP_HTML_SIMPLE(input, maximum_value_length) : copytext(input, 1, maximum_value_length)
|
||||
|
||||
/datum/preference/text/create_default_value()
|
||||
return ""
|
||||
|
||||
/datum/preference/text/is_valid(value)
|
||||
return istext(value) && length(value) < maximum_value_length
|
||||
|
||||
/datum/preference/text/compile_constant_data()
|
||||
return list("maximum_length" = maximum_value_length)
|
||||
52
code/modules/client/preferences/middleware/_middleware.dm
Normal file
52
code/modules/client/preferences/middleware/_middleware.dm
Normal file
@@ -0,0 +1,52 @@
|
||||
/// Preference middleware is code that helps to decentralize complicated preference features.
|
||||
/datum/preference_middleware
|
||||
/// The preferences datum
|
||||
var/datum/preferences/preferences
|
||||
|
||||
/// The key that will be used for get_constant_data().
|
||||
/// If null, will use the typepath minus /datum/preference_middleware.
|
||||
var/key = null
|
||||
|
||||
/// Map of ui_act actions -> proc paths to call.
|
||||
/// Signature is `(list/params, mob/user) -> TRUE/FALSE.
|
||||
/// Return output is the same as ui_act--TRUE if it should update, FALSE if it should not
|
||||
var/list/action_delegations = list()
|
||||
|
||||
/datum/preference_middleware/New(datum/preferences)
|
||||
src.preferences = preferences
|
||||
|
||||
if (isnull(key))
|
||||
// + 2 coming from the off-by-one of copytext, and then another from the slash
|
||||
key = copytext("[type]", length("[parent_type]") + 2)
|
||||
|
||||
/datum/preference_middleware/Destroy()
|
||||
preferences = null
|
||||
return ..()
|
||||
|
||||
/// Append all of these into ui_data
|
||||
/datum/preference_middleware/proc/get_ui_data(mob/user)
|
||||
return list()
|
||||
|
||||
/// Append all of these into ui_static_data
|
||||
/datum/preference_middleware/proc/get_ui_static_data(mob/user)
|
||||
return list()
|
||||
|
||||
/// Append all of these into ui_assets
|
||||
/datum/preference_middleware/proc/get_ui_assets()
|
||||
return list()
|
||||
|
||||
/// Append all of these into /datum/asset/json/preferences.
|
||||
/datum/preference_middleware/proc/get_constant_data()
|
||||
return null
|
||||
|
||||
/// Merge this into the result of compile_character_preferences.
|
||||
/datum/preference_middleware/proc/get_character_preferences(mob/user)
|
||||
return null
|
||||
|
||||
/// Called every set_preference, returns TRUE if this handled it.
|
||||
/datum/preference_middleware/proc/pre_set_preference(mob/user, preference, value)
|
||||
return FALSE
|
||||
|
||||
/// Called when a character is changed.
|
||||
/datum/preference_middleware/proc/on_new_character(mob/user)
|
||||
return
|
||||
12
code/modules/client/preferences/migrations/13_preferences.dm
Normal file
12
code/modules/client/preferences/migrations/13_preferences.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/// Transforms the bay style `"preferences": ["SOUND_MIDI", ...]` to `"SOUND_MIDI": 1` and `"preferences_disabled": [...]` to `0`.
|
||||
/datum/preferences/proc/migration_13_preferences(datum/json_savefile/S)
|
||||
var/list/preferences_enabled = S.get_entry("preferences")
|
||||
for(var/key in preferences_enabled)
|
||||
S.set_entry("[key]", TRUE)
|
||||
|
||||
var/list/preferences_disabled = S.get_entry("preferences_disabled")
|
||||
for(var/key in preferences_disabled)
|
||||
S.set_entry("[key]", FALSE)
|
||||
|
||||
// Force a reload of the value cache
|
||||
apply_all_client_preferences()
|
||||
17
code/modules/client/preferences/migrations/14_nifs.dm
Normal file
17
code/modules/client/preferences/migrations/14_nifs.dm
Normal file
@@ -0,0 +1,17 @@
|
||||
/// Moves nif stuff to it's own file
|
||||
/datum/preferences/proc/migration_14_nifs(datum/json_savefile/S)
|
||||
var/datum/json_savefile/new_savefile = new /datum/json_savefile(nif_savefile_path(client_ckey))
|
||||
|
||||
for(var/slot in 1 to CONFIG_GET(number/character_slots)) //CHOMPEdit
|
||||
var/list/prefs = S.get_entry("character[slot]", null)
|
||||
if(!islist(prefs))
|
||||
continue
|
||||
|
||||
var/list/new_data = list()
|
||||
new_data["nif_path"] = prefs["nif_path"]
|
||||
new_data["nif_durability"] = prefs["nif_durability"]
|
||||
new_data["nif_savedata"] = prefs["nif_savedata"]
|
||||
|
||||
new_savefile.set_entry("character[slot]", new_data)
|
||||
|
||||
new_savefile.save()
|
||||
28
code/modules/client/preferences/preferences_tg.dm
Normal file
28
code/modules/client/preferences/preferences_tg.dm
Normal file
@@ -0,0 +1,28 @@
|
||||
// Contains all of the variables and such to make tg prefs work
|
||||
/datum/preferences
|
||||
/// The savefile relating to character preferences, PREFERENCE_CHARACTER
|
||||
var/list/character_data
|
||||
|
||||
/// A list of keys that have been updated since the last save.
|
||||
var/list/recently_updated_keys = list()
|
||||
|
||||
/// A cache of preference entries to values.
|
||||
/// Used to avoid expensive READ_FILE every time a preference is retrieved.
|
||||
var/value_cache = list()
|
||||
|
||||
/// If set to TRUE, will update character_profiles on the next ui_data tick.
|
||||
var/tainted_character_profiles = FALSE
|
||||
|
||||
var/current_window = PREFERENCE_TAB_GAME_PREFERENCES
|
||||
|
||||
/// A list of instantiated middleware
|
||||
var/list/datum/preference_middleware/middleware = list()
|
||||
|
||||
/// Applies all PREFERENCE_PLAYER preferences
|
||||
/datum/preferences/proc/apply_all_client_preferences()
|
||||
for(var/datum/preference/preference as anything in get_preferences_in_priority_order())
|
||||
if(preference.savefile_identifier != PREFERENCE_PLAYER)
|
||||
continue
|
||||
|
||||
value_cache -= preference.type
|
||||
preference.apply_to_client(client, read_preference(preference.type))
|
||||
73
code/modules/client/preferences/types/admin.dm
Normal file
73
code/modules/client/preferences/types/admin.dm
Normal file
@@ -0,0 +1,73 @@
|
||||
/datum/preference/toggle/show_attack_logs
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_ATTACKLOGS"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_attack_logs/is_accessible(datum/preferences/preferences)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
return check_rights(R_MOD|R_ADMIN, FALSE, preferences.client)
|
||||
|
||||
/datum/preference/toggle/show_debug_logs
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_DEBUGLOGS"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_debug_logs/is_accessible(datum/preferences/preferences)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
return check_rights(R_DEBUG|R_ADMIN, FALSE, preferences.client)
|
||||
|
||||
/datum/preference/toggle/show_chat_prayers
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_PRAYER"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_chat_prayers/is_accessible(datum/preferences/preferences)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
return check_rights(R_EVENT|R_ADMIN, FALSE, preferences.client)
|
||||
|
||||
// General holder prefs
|
||||
/datum/preference/toggle/holder
|
||||
abstract_type = /datum/preference/toggle/holder
|
||||
|
||||
/datum/preference/toggle/holder/is_accessible(datum/preferences/preferences)
|
||||
. = ..(preferences)
|
||||
if(!.)
|
||||
return
|
||||
|
||||
return preferences.client.holder
|
||||
|
||||
/datum/preference/toggle/holder/play_adminhelp_ping
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_ADMINHELP"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/holder/hear_radio
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_RADIO"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/holder/show_rlooc
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_RLOOC"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/holder/show_staff_dsay
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_ADSAY"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
69
code/modules/client/preferences/types/chat.dm
Normal file
69
code/modules/client/preferences/types/chat.dm
Normal file
@@ -0,0 +1,69 @@
|
||||
/datum/preference/toggle/chat_tags
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_SHOWICONS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_typing_indicator
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SHOW_TYPING"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_typing_indicator/apply_to_client(client/client, value)
|
||||
if(!value)
|
||||
client.stop_thinking()
|
||||
|
||||
/datum/preference/toggle/show_typing_indicator_subtle
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SHOW_TYPING_SUBTLE"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_ooc
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_OOC"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_looc
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_LOOC"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_dsay
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_DEAD"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/check_mention
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_MENTION"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/vore_health_bars
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "VORE_HEALTH_BARS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_lore_news
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "NEWS_POPUP"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/player_tips
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RECEIVE_TIPS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/pain_frequency
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "PAIN_FREQUENCY"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
29
code/modules/client/preferences/types/ghost.dm
Normal file
29
code/modules/client/preferences/types/ghost.dm
Normal file
@@ -0,0 +1,29 @@
|
||||
/datum/preference/toggle/whisubtle_vis
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "WHISUBTLE_VIS"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/ghost_see_whisubtle
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "GHOST_SEE_WHISUBTLE"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/ghost_ears
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_GHOSTEARS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/ghost_sight
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_GHOSTSIGHT"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/ghost_radio
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "CHAT_GHOSTRADIO"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
71
code/modules/client/preferences/types/misc.dm
Normal file
71
code/modules/client/preferences/types/misc.dm
Normal file
@@ -0,0 +1,71 @@
|
||||
/// Whether or not to toggle ambient occlusion, the shadows around people
|
||||
/datum/preference/toggle/ambient_occlusion
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "AMBIENT_OCCLUSION_PREF"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/ambient_occlusion/apply_to_client(client/client, value)
|
||||
var/datum/plane_holder/PH = client?.mob?.plane_holder
|
||||
if(PH)
|
||||
PH.set_ao(VIS_OBJS, value)
|
||||
PH.set_ao(VIS_MOBS, value)
|
||||
|
||||
/datum/preference/toggle/mob_tooltips
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "MOB_TOOLTIPS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/inv_tooltips
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "INV_TOOLTIPS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/attack_icons
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "ATTACK_ICONS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/precision_placement
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "PRECISE_PLACEMENT"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/hotkeys_default
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "HUD_HOTKEYS"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/show_progress_bar
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SHOW_PROGRESS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/safefiring
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SAFE_FIRING"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/status_indicators
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SHOW_STATUS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/status_indicators/apply_to_client(client/client, value)
|
||||
var/datum/plane_holder/PH = client?.mob?.plane_holder
|
||||
if(PH)
|
||||
PH.set_vis(VIS_STATUS, value)
|
||||
|
||||
/datum/preference/toggle/auto_afk
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "AUTO_AFK"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
23
code/modules/client/preferences/types/runechat.dm
Normal file
23
code/modules/client/preferences/types/runechat.dm
Normal file
@@ -0,0 +1,23 @@
|
||||
/datum/preference/toggle/runechat_mob
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RUNECHAT_MOB"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/runechat_obj
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RUNECHAT_OBJ"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/runechat_border
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RUNECHAT_BORDER"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/runechat_long_messages
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RUNECHAT_LONG"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
149
code/modules/client/preferences/types/sound.dm
Normal file
149
code/modules/client/preferences/types/sound.dm
Normal file
@@ -0,0 +1,149 @@
|
||||
/datum/preference/toggle/play_admin_midis
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_MIDI"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/play_lobby_music
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_LOBBY"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/play_lobby_music/apply_to_client(client/client, value)
|
||||
if(value)
|
||||
client?.playtitlemusic()
|
||||
else
|
||||
client?.media?.stop_music()
|
||||
|
||||
/datum/preference/toggle/play_ambience
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_AMBIENCE"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/play_ambience/apply_to_client(client/client, value)
|
||||
if(!value)
|
||||
client << sound(null, repeat = 0, wait = 0, volume = 0, channel = CHANNEL_AMBIENCE_FORCED)
|
||||
client << sound(null, repeat = 0, wait = 0, volume = 0, channel = CHANNEL_AMBIENCE)
|
||||
|
||||
/datum/preference/toggle/play_jukebox
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_JUKEBOX"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/play_jukebox/apply_to_client(client/client, value)
|
||||
if(value)
|
||||
client?.mob?.update_music()
|
||||
else
|
||||
client?.mob?.stop_all_music()
|
||||
|
||||
/datum/preference/toggle/instrument_toggle
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_INSTRUMENT"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/emote_noises
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "EMOTE_NOISES"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/radio_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "RADIO_SOUNDS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/say_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SAY_SOUNDS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/emote_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "EMOTE_SOUNDS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/whisper_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "WHISPER_SOUNDS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/subtle_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SUBTLE_SOUNDS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/air_pump_noise
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_AIRPUMP"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/old_door_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_OLDDOORS"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/department_door_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_DEPARTMENTDOORS"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/pickup_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_PICKED"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/drop_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_DROPPED"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/weather_sounds
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_WEATHER"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/supermatter_hum
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_SUPERMATTER"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/play_mentorhelp_ping
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "SOUND_MENTORHELP"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
// Vorey sounds
|
||||
/datum/preference/toggle/belch_noises // Belching noises - pref toggle for 'em
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "BELCH_NOISES"
|
||||
default_value = FALSE //CHOMPEdit
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/eating_noises
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "EATING_NOISES"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/digestion_noises
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "DIGEST_NOISES"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
37
code/modules/client/preferences/types/ui.dm
Normal file
37
code/modules/client/preferences/types/ui.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
/datum/preference/toggle/browser_style
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "BROWSER_STYLED"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/vchat_enable
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "VCHAT_ENABLE"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/vchat_enable/apply_to_client(client/client, value)
|
||||
var/before = client.tgui_panel.oldchat
|
||||
if(value)
|
||||
client.tgui_panel.oldchat = FALSE
|
||||
else
|
||||
client.tgui_panel.oldchat = TRUE
|
||||
|
||||
// If something actually changed, reload chat
|
||||
if(before != client.tgui_panel.oldchat)
|
||||
client.nuke_chat()
|
||||
|
||||
/datum/preference/toggle/tgui_say
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "TGUI_SAY"
|
||||
default_value = TRUE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/tgui_say_light
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "TGUI_SAY_LIGHT_MODE"
|
||||
default_value = FALSE
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/toggle/tgui_say_light/apply_to_client(client/client, value)
|
||||
client.tgui_say?.load()
|
||||
@@ -1,67 +0,0 @@
|
||||
/client/verb/toggle_looping_alarms()
|
||||
set name = "Looping Alarms"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles alarm sound loops."
|
||||
|
||||
var/pref_path = /datum/client_preference/looping_alarms
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear alarm sounds looping.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAlarmLoops") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_sleep_music()
|
||||
set name = "Toggle Sleeping Music"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "When enabled, you will hear cozy music played during surgery, cryo, and sleeper pod usage."
|
||||
|
||||
var/pref_path = /datum/client_preference/sleep_music
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You are [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hearing sleeping music while in cryo/surgery/sleeper.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb", "TSleepMusic")
|
||||
|
||||
/* // Up-ported to Virgo, disabling here
|
||||
/datum/preferences/proc/update_character_previews(var/mob/living/carbon/human/mannequin)
|
||||
if(!client)
|
||||
return
|
||||
|
||||
var/obj/screen/setup_preview/pm_helper/PMH = LAZYACCESS(char_render_holders, "PMH")
|
||||
if(!PMH)
|
||||
PMH = new
|
||||
LAZYSET(char_render_holders, "PMH", PMH)
|
||||
client.screen |= PMH
|
||||
PMH.screen_loc = preview_screen_locs["PMH"]
|
||||
|
||||
var/obj/screen/setup_preview/bg/BG = LAZYACCESS(char_render_holders, "BG")
|
||||
if(!BG)
|
||||
BG = new
|
||||
BG.plane = TURF_PLANE
|
||||
BG.icon = 'icons/effects/setup_backgrounds_vr.dmi'
|
||||
BG.pref = src
|
||||
LAZYSET(char_render_holders, "BG", BG)
|
||||
client.screen |= BG
|
||||
BG.icon_state = bgstate
|
||||
BG.screen_loc = preview_screen_locs["BG"]
|
||||
|
||||
for(var/D in global.cardinal)
|
||||
var/obj/screen/setup_preview/O = LAZYACCESS(char_render_holders, "[D]")
|
||||
if(!O)
|
||||
O = new
|
||||
O.pref = src
|
||||
LAZYSET(char_render_holders, "[D]", O)
|
||||
client.screen |= O
|
||||
mannequin.set_dir(D)
|
||||
mannequin.update_tail_showing()
|
||||
mannequin.ImmediateOverlayUpdate()
|
||||
var/mutable_appearance/MA = new(mannequin)
|
||||
O.appearance = MA
|
||||
O.screen_loc = preview_screen_locs["[D]"]
|
||||
*/
|
||||
@@ -1,121 +1,267 @@
|
||||
#define SAVEFILE_VERSION_MIN 8
|
||||
#define SAVEFILE_VERSION_MAX 11
|
||||
#define SAVEFILE_VERSION_MAX 14
|
||||
|
||||
//handles converting savefiles to new formats
|
||||
//MAKE SURE YOU KEEP THIS UP TO DATE!
|
||||
//If the sanity checks are capable of handling any issues. Only increase SAVEFILE_VERSION_MAX,
|
||||
//this will mean that savefile_version will still be over SAVEFILE_VERSION_MIN, meaning
|
||||
//this savefile update doesn't run everytime we load from the savefile.
|
||||
//This is mainly for format changes, such as the bitflags in toggles changing order or something.
|
||||
//if a file can't be updated, return 0 to delete it and start again
|
||||
//if a file was updated, return 1
|
||||
/datum/preferences/proc/savefile_update()
|
||||
if(savefile_version < 8) //lazily delete everything + additional files so they can be saved in the new format
|
||||
for(var/ckey in preferences_datums)
|
||||
var/datum/preferences/D = preferences_datums[ckey]
|
||||
if(D == src)
|
||||
var/delpath = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/"
|
||||
if(delpath && fexists(delpath))
|
||||
fdel(delpath)
|
||||
break
|
||||
return 0
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
This proc checks if the current directory of the savefile S needs updating
|
||||
It is to be used by the load_character and load_preferences procs.
|
||||
(S.cd == "/" is preferences, S.cd == "/character[integer]" is a character slot, etc)
|
||||
|
||||
if(savefile_version == SAVEFILE_VERSION_MAX) //update successful.
|
||||
save_preferences()
|
||||
save_character()
|
||||
return 1
|
||||
return 0
|
||||
if the current directory's version is below SAVEFILE_VERSION_MIN it will simply wipe everything in that directory
|
||||
(if we're at root "/" then it'll just wipe the entire savefile, for instance.)
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey) return
|
||||
if its version is below SAVEFILE_VERSION_MAX but above the minimum, it will load data but later call the
|
||||
respective update_preferences() or update_character() proc.
|
||||
Those procs allow coders to specify format changes so users do not lose their setups and have to redo them again.
|
||||
|
||||
Failing all that, the standard sanity checks are performed. They simply check the data is suitable, reverting to
|
||||
initial() values if necessary.
|
||||
*/
|
||||
/datum/preferences/proc/save_data_needs_update(list/save_data)
|
||||
if(!save_data) // empty list, either savefile isnt loaded or its a new char
|
||||
return -1
|
||||
if(!save_data["version"]) // special case: if there is no version key, such as in character slots before v12
|
||||
return -3
|
||||
if(save_data["version"] < SAVEFILE_VERSION_MIN)
|
||||
return -2
|
||||
if(save_data["version"] < SAVEFILE_VERSION_MAX)
|
||||
return save_data["version"]
|
||||
return -1
|
||||
|
||||
//should these procs get fairly long
|
||||
//just increase SAVEFILE_VERSION_MIN so it's not as far behind
|
||||
//SAVEFILE_VERSION_MAX and then delete any obsolete if clauses
|
||||
//from these procs.
|
||||
//This only really meant to avoid annoying frequent players
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, datum/json_savefile/S)
|
||||
// Migration from BYOND savefiles to JSON: Important milemark.
|
||||
// if(current_version < 11)
|
||||
|
||||
// Migration for client preferences
|
||||
if(current_version < 13)
|
||||
log_debug("[client_ckey] preferences migrating from [current_version] to v13....")
|
||||
to_chat(client, span_danger("Migrating savefile from version [current_version] to v13..."))
|
||||
|
||||
migration_13_preferences(S)
|
||||
|
||||
log_debug("[client_ckey] preferences successfully migrated from [current_version] to v13.")
|
||||
to_chat(client, span_danger("v13 savefile migration complete."))
|
||||
|
||||
// Migration for nifs
|
||||
if(current_version < 14)
|
||||
log_debug("[client_ckey] preferences migrating from [current_version] to v14....")
|
||||
to_chat(client, span_danger("Migrating savefile from version [current_version] to v14..."))
|
||||
|
||||
migration_14_nifs(S)
|
||||
|
||||
log_debug("[client_ckey] preferences successfully migrated from [current_version] to v14.")
|
||||
to_chat(client, span_danger("v14 savefile migration complete."))
|
||||
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, list/save_data)
|
||||
// Migration from BYOND savefiles to JSON: Important milemark.
|
||||
if(current_version == -3)
|
||||
// Add a version field inside each character
|
||||
save_data["version"] = SAVEFILE_VERSION_MAX
|
||||
|
||||
/// Migrates from byond savefile to json savefile
|
||||
/datum/preferences/proc/try_savefile_type_migration()
|
||||
log_debug("[client_ckey] preferences migrating from savefile to JSON...")
|
||||
to_chat(client, span_danger("Savefile migration to JSON in progress..."))
|
||||
|
||||
load_path(client.ckey, "preferences.sav") // old save file
|
||||
var/old_path = path
|
||||
load_path(client.ckey)
|
||||
if(!fexists(old_path))
|
||||
return
|
||||
var/datum/json_savefile/json_savefile = new(path)
|
||||
json_savefile.import_byond_savefile(new /savefile(old_path))
|
||||
json_savefile.save()
|
||||
|
||||
log_debug("[client_ckey] preferences successfully migrated from savefile to JSON.")
|
||||
to_chat(client, span_danger("Savefile migration to JSON is complete."))
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/load_path(ckey, filename = "preferences.json")
|
||||
if(!ckey || !load_and_save)
|
||||
return
|
||||
path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[filename]"
|
||||
savefile_version = SAVEFILE_VERSION_MAX
|
||||
|
||||
/datum/preferences/proc/load_savefile()
|
||||
if(load_and_save && !path)
|
||||
CRASH("Attempted to load savefile without first loading a path!")
|
||||
savefile = new /datum/json_savefile(load_and_save ? path : null)
|
||||
|
||||
/datum/preferences/proc/load_preferences()
|
||||
if(!path) return 0
|
||||
if(!fexists(path)) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
S.cd = "/"
|
||||
if(!savefile)
|
||||
stack_trace("Attempted to load the preferences of [client] without a savefile; did you forget to call load_savefile?")
|
||||
load_savefile()
|
||||
if(!savefile)
|
||||
stack_trace("Failed to load the savefile for [client] after manually calling load_savefile; something is very wrong.")
|
||||
return FALSE
|
||||
|
||||
S["version"] >> savefile_version
|
||||
//Conversion
|
||||
if(!savefile_version || !isnum(savefile_version) || savefile_version < SAVEFILE_VERSION_MIN || savefile_version > SAVEFILE_VERSION_MAX)
|
||||
if(!savefile_update()) //handles updates
|
||||
savefile_version = SAVEFILE_VERSION_MAX
|
||||
save_preferences()
|
||||
save_character()
|
||||
return 0
|
||||
var/needs_update = save_data_needs_update(savefile.get_entry())
|
||||
if(load_and_save && (needs_update <= -2)) //fatal, can't load any data
|
||||
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
|
||||
if(fexists(bacpath))
|
||||
fdel(bacpath) //only keep 1 version of backup
|
||||
fcopy(savefile.path, bacpath) //byond helpfully lets you use a savefile for the first arg.
|
||||
return FALSE
|
||||
|
||||
player_setup.load_preferences(S)
|
||||
return 1
|
||||
apply_all_client_preferences()
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
if(needs_update >= 0)
|
||||
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
|
||||
if(fexists(bacpath))
|
||||
fdel(bacpath) //only keep 1 version of backup
|
||||
fcopy(savefile.path, bacpath) //byond helpfully lets you use a savefile for the first arg.
|
||||
update_preferences(needs_update, savefile) //needs_update = savefile_version if we need an update (positive integer)
|
||||
|
||||
// Load general prefs after applying migrations
|
||||
player_setup.load_preferences(savefile)
|
||||
|
||||
//save the updated version
|
||||
var/old_default_slot = default_slot
|
||||
// var/old_max_save_slots = max_save_slots
|
||||
|
||||
for(var/slot in savefile.get_entry()) //but first, update all current character slots.
|
||||
if (copytext(slot, 1, 10) != "character")
|
||||
continue
|
||||
var/slotnum = text2num(copytext(slot, 10))
|
||||
if (!slotnum)
|
||||
continue
|
||||
// max_save_slots = max(max_save_slots, slotnum) //so we can still update byond member slots after they lose memeber status
|
||||
default_slot = slotnum
|
||||
if(load_character())
|
||||
save_character()
|
||||
default_slot = old_default_slot
|
||||
// max_save_slots = old_max_save_slots
|
||||
save_preferences()
|
||||
else
|
||||
// Load general prefs
|
||||
player_setup.load_preferences(savefile)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/save_preferences()
|
||||
if(!path) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
S.cd = "/"
|
||||
if(!savefile)
|
||||
CRASH("Attempted to save the preferences of [client] without a savefile. This should have been handled by load_preferences()")
|
||||
savefile.set_entry("version", SAVEFILE_VERSION_MAX) //updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date
|
||||
|
||||
S["version"] << savefile_version
|
||||
player_setup.save_preferences(S)
|
||||
return 1
|
||||
player_setup.save_preferences(savefile)
|
||||
|
||||
for(var/preference_type in GLOB.preference_entries)
|
||||
var/datum/preference/preference = GLOB.preference_entries[preference_type]
|
||||
if(preference.savefile_identifier != PREFERENCE_PLAYER)
|
||||
continue
|
||||
|
||||
if(!(preference.type in recently_updated_keys))
|
||||
continue
|
||||
|
||||
recently_updated_keys -= preference.type
|
||||
|
||||
if(preference_type in value_cache)
|
||||
write_preference(preference, preference.pref_serialize(value_cache[preference_type]))
|
||||
|
||||
savefile.save()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/reset_slot()
|
||||
var/bacpath = "[path].resetbac"
|
||||
if(fexists(bacpath))
|
||||
fdel(bacpath) //only keep 1 version of backup
|
||||
fcopy(savefile.path, bacpath) //byond helpfully lets you use a savefile for the first arg.
|
||||
|
||||
savefile.remove_entry("character[default_slot]")
|
||||
default_slot = 1
|
||||
|
||||
clear_character_previews()
|
||||
|
||||
// Load slot 1 character
|
||||
load_character()
|
||||
// And save them immediately, in case we load an empty slot
|
||||
save_character()
|
||||
save_preferences()
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/load_character(slot)
|
||||
if(!path) return 0
|
||||
if(!fexists(path)) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
S.cd = "/"
|
||||
if(!slot) slot = default_slot
|
||||
if(slot != SAVE_RESET) // SAVE_RESET will reset the slot as though it does not exist, but keep the current slot for saving purposes.
|
||||
slot = sanitize_integer(slot, 1, CONFIG_GET(number/character_slots), initial(default_slot)) // CHOMPEdit
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
S["default_slot"] << slot
|
||||
else
|
||||
S["default_slot"] << default_slot
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(!slot)
|
||||
slot = default_slot
|
||||
|
||||
if(slot != SAVE_RESET)
|
||||
S.cd = "/character[slot]"
|
||||
player_setup.load_character(S)
|
||||
else
|
||||
player_setup.load_character(S)
|
||||
S.cd = "/character[default_slot]"
|
||||
player_setup.save_character(S)
|
||||
slot = sanitize_integer(slot, 1, CONFIG_GET(number/character_slots), initial(default_slot)) // CHOMPEdit
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
savefile.set_entry("default_slot", slot)
|
||||
|
||||
clear_character_previews() // VOREStation Edit
|
||||
return 1
|
||||
var/list/save_data = savefile.get_entry("character[slot]") // This is allowed to be null and will give a -1 in needs_update
|
||||
|
||||
var/needs_update = save_data_needs_update(save_data)
|
||||
if(needs_update == -2) //fatal, can't load any data
|
||||
return FALSE
|
||||
|
||||
// Read everything into cache (pre-migrations, as migrations should have access to deserialized data)
|
||||
// Uses priority order as some values may rely on others for creating default values
|
||||
for(var/datum/preference/preference as anything in get_preferences_in_priority_order())
|
||||
if(preference.savefile_identifier != PREFERENCE_CHARACTER)
|
||||
continue
|
||||
|
||||
value_cache -= preference.type
|
||||
read_preference(preference.type)
|
||||
|
||||
// It has to be a list or load_character freaks out
|
||||
if(!save_data)
|
||||
player_setup.load_character(list())
|
||||
else
|
||||
player_setup.load_character(save_data)
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
//preference updating will handle saving the updated data for us.
|
||||
if(needs_update >= 0 || needs_update == -3)
|
||||
update_character(needs_update, save_data) //needs_update == savefile_version if we need an update (positive integer
|
||||
|
||||
clear_character_previews()
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/save_character()
|
||||
if(!path) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
S.cd = "/character[default_slot]"
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(!savefile)
|
||||
return FALSE
|
||||
|
||||
player_setup.save_character(S)
|
||||
return 1
|
||||
var/tree_key = "character[default_slot]"
|
||||
if(!(tree_key in savefile.get_entry()))
|
||||
savefile.set_entry(tree_key, list())
|
||||
var/save_data = savefile.get_entry(tree_key)
|
||||
|
||||
save_data["version"] = SAVEFILE_VERSION_MAX //load_character will sanitize any bad data, so assume up-to-date.
|
||||
player_setup.save_character(save_data)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/overwrite_character(slot)
|
||||
if(!path) return 0
|
||||
if(!fexists(path)) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
if(!slot) slot = default_slot
|
||||
if(slot != SAVE_RESET)
|
||||
slot = sanitize_integer(slot, 1, CONFIG_GET(number/character_slots), initial(default_slot)) // CHOMPEdit
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
nif_path = nif_durability = nif_savedata = null //VOREStation Add - Don't copy NIF
|
||||
S["default_slot"] << slot
|
||||
if(!savefile)
|
||||
return FALSE
|
||||
if(!slot)
|
||||
slot = default_slot
|
||||
|
||||
else
|
||||
S["default_slot"] << default_slot
|
||||
// This basically just changes default_slot without loading the correct data, so the next save call will overwrite
|
||||
// the slot
|
||||
slot = sanitize_integer(slot, 1, CONFIG_GET(number/character_slots), initial(default_slot)) // CHOMPEdit
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
nif_path = nif_durability = nif_savedata = null //VOREStation Add - Don't copy NIF
|
||||
savefile.set_entry("default_slot", slot)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/preferences/proc/sanitize_preferences()
|
||||
player_setup.sanitize_setup()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
#undef SAVEFILE_VERSION_MAX
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
|
||||
138
code/modules/client/preferences_tgui.dm
Normal file
138
code/modules/client/preferences_tgui.dm
Normal file
@@ -0,0 +1,138 @@
|
||||
/datum/preferences/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, custom_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PreferencesMenu", "Preferences")
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/datum/preferences/tgui_state(mob/user)
|
||||
return GLOB.tgui_always_state
|
||||
|
||||
/datum/preferences/tgui_status(mob/user, datum/tgui_state/state)
|
||||
return user.client == client ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
|
||||
/datum/preferences/ui_assets(mob/user)
|
||||
var/list/assets = list(
|
||||
// get_asset_datum(/datum/asset/spritesheet/preferences),
|
||||
get_asset_datum(/datum/asset/json/preferences),
|
||||
)
|
||||
|
||||
for (var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
assets += preference_middleware.get_ui_assets()
|
||||
|
||||
return assets
|
||||
|
||||
/datum/preferences/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(tainted_character_profiles)
|
||||
data["character_profiles"] = create_character_profiles()
|
||||
tainted_character_profiles = FALSE
|
||||
|
||||
data["character_preferences"] = compile_character_preferences(user)
|
||||
|
||||
data["active_slot"] = default_slot
|
||||
|
||||
for(var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
data += preference_middleware.get_ui_data(user)
|
||||
|
||||
return data
|
||||
|
||||
/datum/preferences/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["character_profiles"] = create_character_profiles()
|
||||
|
||||
// data["character_preview_view"] = character_preview_view.assigned_map
|
||||
// data["overflow_role"] = SSjob.GetJobType(SSjob.overflow_role).title
|
||||
data["window"] = current_window
|
||||
|
||||
for(var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
data += preference_middleware.get_ui_static_data(user)
|
||||
|
||||
return data
|
||||
|
||||
/datum/preferences/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("set_preference")
|
||||
var/requested_preference_key = params["preference"]
|
||||
var/value = params["value"]
|
||||
|
||||
for(var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
if(preference_middleware.pre_set_preference(usr, requested_preference_key, value))
|
||||
return TRUE
|
||||
|
||||
var/datum/preference/requested_preference = GLOB.preference_entries_by_key[requested_preference_key]
|
||||
if(isnull(requested_preference))
|
||||
return FALSE
|
||||
|
||||
// SAFETY: `update_preference` performs validation checks
|
||||
if(!update_preference(requested_preference, value))
|
||||
return FALSE
|
||||
|
||||
// if(istype(requested_preference, /datum/preference/name)) // TODO: do this
|
||||
// tainted_character_profiles = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
for(var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
var/delegation = preference_middleware.action_delegations[action]
|
||||
if(!isnull(delegation))
|
||||
return call(preference_middleware, delegation)(params, usr)
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/preferences/tgui_close(mob/user)
|
||||
save_character()
|
||||
save_preferences()
|
||||
|
||||
/datum/preferences/proc/create_character_profiles()
|
||||
var/list/profiles = list()
|
||||
|
||||
for(var/index in 1 to CONFIG_GET(number/character_slots)) //CHOMPEdit
|
||||
// TODO: It won't be updated in the savefile yet, so just read the name directly
|
||||
// if(index == default_slot)
|
||||
// profiles += read_preference(/datum/preference/name/real_name)
|
||||
// continue
|
||||
|
||||
var/tree_key = "character[index]"
|
||||
var/save_data = savefile.get_entry(tree_key)
|
||||
var/name = save_data?["real_name"]
|
||||
|
||||
if(isnull(name))
|
||||
profiles += null
|
||||
continue
|
||||
|
||||
profiles += name
|
||||
|
||||
return profiles
|
||||
|
||||
/datum/preferences/proc/compile_character_preferences(mob/user)
|
||||
var/list/preferences = list()
|
||||
|
||||
for(var/datum/preference/preference as anything in get_preferences_in_priority_order())
|
||||
if(!preference.is_accessible(src))
|
||||
continue
|
||||
|
||||
var/value = read_preference(preference.type)
|
||||
var/data = preference.compile_ui_data(user, value)
|
||||
|
||||
LAZYINITLIST(preferences[preference.category])
|
||||
preferences[preference.category][preference.savefile_key] = data
|
||||
|
||||
for(var/datum/preference_middleware/preference_middleware as anything in middleware)
|
||||
var/list/append_character_preferences = preference_middleware.get_character_preferences(user)
|
||||
if(isnull(append_character_preferences))
|
||||
continue
|
||||
|
||||
for(var/category in append_character_preferences)
|
||||
if(category in preferences)
|
||||
preferences[category] += append_character_preferences[category]
|
||||
else
|
||||
preferences[category] = append_character_preferences[category]
|
||||
|
||||
return preferences
|
||||
@@ -1,229 +1,3 @@
|
||||
//Toggles for preferences, normal clients
|
||||
/client/verb/toggle_ghost_ears()
|
||||
set name = "Toggle Ghost Ears"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles between seeing all mob speech and only nearby mob speech as an observer."
|
||||
|
||||
var/pref_path = /datum/client_preference/ghost_ears
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear all mob speech as a ghost.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TGEars") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ghost_vision()
|
||||
set name = "Toggle Ghost Sight"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles between seeing all mob emotes and only nearby mob emotes as an observer."
|
||||
|
||||
var/pref_path = /datum/client_preference/ghost_sight
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] see all emotes as a ghost.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TGVision") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ghost_radio()
|
||||
set name = "Toggle Ghost Radio"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles between seeing all radio chat and only nearby radio chatter as an observer."
|
||||
|
||||
var/pref_path = /datum/client_preference/ghost_radio
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear all radios as a ghost.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TGRadio") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_deadchat()
|
||||
set name = "Toggle Deadchat"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles visibility of dead chat."
|
||||
|
||||
var/pref_path = /datum/client_preference/show_dsay
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear dead chat as a ghost.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TDeadChat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ooc()
|
||||
set name = "Toggle OOC"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles visibility of global out of character chat."
|
||||
|
||||
var/pref_path = /datum/client_preference/show_ooc
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(/datum/client_preference/show_ooc)) ? "now" : "no longer"] hear global out of character chat.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_looc()
|
||||
set name = "Toggle LOOC"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles visibility of local out of character chat."
|
||||
|
||||
var/pref_path = /datum/client_preference/show_looc
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear local out of character chat.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_precision_placement()
|
||||
set name = "Toggle Precision Placement"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles whether objects placed on table will be on cursor position or centered."
|
||||
|
||||
var/pref_path = /datum/client_preference/precision_placement
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] place items where your cursor is on the table.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TPIP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_typing()
|
||||
set name = "Toggle Typing Indicator"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles you having the speech bubble typing indicator."
|
||||
|
||||
var/pref_path = /datum/client_preference/show_typing_indicator
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] have the speech indicator.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TTIND") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ahelp_sound()
|
||||
set name = "Toggle Admin Help Sound"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear a noise broadcasted when you get an admin message."
|
||||
|
||||
var/pref_path = /datum/client_preference/holder/play_adminhelp_ping
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive noise from admin messages.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAHelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_lobby_music()
|
||||
set name = "Toggle Lobby Music"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear the music in the lobby."
|
||||
|
||||
var/pref_path = /datum/client_preference/play_lobby_music
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear music in the lobby.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TLobMusic") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_admin_midis()
|
||||
set name = "Toggle Admin Music"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear music played by admins."
|
||||
|
||||
var/pref_path = /datum/client_preference/play_admin_midis
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear music from admins.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAMidis") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ambience()
|
||||
set name = "Toggle Ambience"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear local ambience."
|
||||
|
||||
var/pref_path = /datum/client_preference/play_ambiance
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear ambient noise.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAmbience") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_weather_sounds()
|
||||
set name = "Toggle Weather Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear weather sounds while on a planet."
|
||||
|
||||
var/pref_path = /datum/client_preference/weather_sounds
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear weather sounds.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TWeatherSounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_supermatter_hum()
|
||||
set name = "Toggle SM Hum" // Avoiding using the full 'Supermatter' name to not conflict with the Setup-Supermatter adminverb.
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear supermatter hums."
|
||||
|
||||
var/pref_path = /datum/client_preference/supermatter_hum
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear a hum from the supermatter.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TSupermatterHum") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_jukebox()
|
||||
set name = "Toggle Jukebox"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear jukebox music."
|
||||
|
||||
var/pref_path = /datum/client_preference/play_jukebox
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear jukebox music.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TJukebox") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_be_special(role in be_special_flags)
|
||||
set name = "Toggle Special Role Candidacy"
|
||||
set category = "Preferences.Character" //CHOMPEdit
|
||||
@@ -239,146 +13,6 @@
|
||||
|
||||
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_air_pump_hum()
|
||||
set name = "Toggle Air Vent Noise"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear air vent humming."
|
||||
|
||||
var/pref_path = /datum/client_preference/air_pump_noise
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear air vents hum, start, and stop.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAirPumpNoise")
|
||||
|
||||
/client/verb/toggle_old_door_sounds()
|
||||
set name = "Toggle Door: Old Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles door sounds between old and new."
|
||||
|
||||
var/pref_path = /datum/client_preference/old_door_sounds
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear the legacy door sounds.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TOldDoorSounds")
|
||||
|
||||
/client/verb/toggle_department_door_sounds()
|
||||
set name = "Toggle Door: Department Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles hearing of department-specific door sounds."
|
||||
|
||||
var/pref_path = /datum/client_preference/department_door_sounds
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear per-department door sounds.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TDepartmentDoorSounds")
|
||||
|
||||
/client/verb/toggle_pickup_sounds()
|
||||
set name = "Toggle Item: Picked up Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear sounds when items are picked up."
|
||||
|
||||
var/pref_path = /datum/client_preference/pickup_sounds
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear sounds when items are picked up.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb", "TPickupSounds")
|
||||
|
||||
/client/verb/toggle_drop_sounds()
|
||||
set name = "Toggle Item: Dropped Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear sounds when items are dropped or thrown."
|
||||
|
||||
var/pref_path = /datum/client_preference/drop_sounds
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear sounds when items are dropped or thrown.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb", "TDropSounds")
|
||||
|
||||
/client/verb/toggle_safe_firing()
|
||||
set name = "Toggle Gun Firing Intent Requirement"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles between safe and dangerous firing. Safe requires a non-help intent to fire, dangerous can be fired on help intent."
|
||||
|
||||
var/pref_path = /datum/client_preference/safefiring
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src,"You will now use [(is_preference_enabled(/datum/client_preference/safefiring)) ? "safe" : "dangerous"] firearms firing.")
|
||||
|
||||
feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_mob_tooltips()
|
||||
set name = "Toggle Mob Tooltips"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles displaying name/species over mobs when they are moused over."
|
||||
|
||||
var/pref_path = /datum/client_preference/mob_tooltips
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src,"You will now [(is_preference_enabled(/datum/client_preference/mob_tooltips)) ? "see" : "not see"] mob tooltips.")
|
||||
|
||||
feedback_add_details("admin_verb","TMobTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_inv_tooltips()
|
||||
set name = "Toggle Item Tooltips"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles displaying name/desc over items when they are moused over (only applies in inventory)."
|
||||
|
||||
var/pref_path = /datum/client_preference/inv_tooltips
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src,"You will now [(is_preference_enabled(/datum/client_preference/inv_tooltips)) ? "see" : "not see"] inventory tooltips.")
|
||||
|
||||
feedback_add_details("admin_verb","TInvTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_hear_instruments()
|
||||
set name = "Toggle Hear/Ignore Instruments"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles the ability to hear instruments playing."
|
||||
|
||||
var/pref_path = /datum/client_preference/instrument_toggle
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/instrument_toggle)) ? "hear" : "not hear"] instruments being played.")
|
||||
|
||||
feedback_add_details("admin_verb","THInstm") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_vchat()
|
||||
set name = "Toggle TGChat"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles TGChat. Reloading TGChat and/or reconnecting required to affect changes."
|
||||
|
||||
var/pref_path = /datum/client_preference/vchat_enable
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You have toggled TGChat [is_preference_enabled(pref_path) ? "on" : "off"]. \
|
||||
You will have to reload TGChat and/or reconnect to the server for these changes to take place. \
|
||||
TGChat message persistence is not guaranteed if you change this again before the start of the next round.")
|
||||
|
||||
/client/verb/toggle_chat_timestamps()
|
||||
set name = "Toggle Chat Timestamps"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
@@ -389,101 +23,6 @@
|
||||
|
||||
to_chat(src, span_notice("You have toggled chat timestamps: [prefs.chat_timestamp ? "ON" : "OFF"]."))
|
||||
|
||||
/client/verb/toggle_status_indicators()
|
||||
set name = "Toggle Status Indicators"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "Toggles 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")
|
||||
|
||||
|
||||
/client/verb/toggle_radio_sounds()
|
||||
set name = "Toggle Radio Sounds"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggle hearing a sound when somebody speaks over your headset."
|
||||
|
||||
var/pref_path = /datum/client_preference/radio_sounds
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/radio_sounds)) ? "hear" : "not hear"] radio sounds.")
|
||||
|
||||
feedback_add_details("admin_verb","TRadioSounds")
|
||||
|
||||
/client/verb/toggle_say_sounds()
|
||||
set name = "Toggle Voice Sounds" //CHOMPEdit - changed name to one that doesn't interfere with say autofill
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggle hearing a sound when somebody speaks or emotes."
|
||||
|
||||
var/pref_path = /datum/client_preference/say_sounds
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/say_sounds)) ? "hear" : "not hear"] say sounds.")
|
||||
|
||||
feedback_add_details("admin_verb","TSaySounds")
|
||||
/*
|
||||
CHOMPRemove. Bundled voice sounds into emote/whisper/subtle. Going this extra length to babyproof prefs wasn't necessary and got in the way of quick whisper/say autofill.
|
||||
|
||||
/client/verb/toggle_emote_sounds()
|
||||
set name = "Sound-Toggle-Me"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggle hearing a sound when somebody speaks using me ."
|
||||
|
||||
var/pref_path = /datum/client_preference/emote_sounds
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/emote_sounds)) ? "hear" : "not hear"] me sounds.")
|
||||
|
||||
feedback_add_details("admin_verb","TMeSounds")
|
||||
|
||||
/client/verb/toggle_whisper_sounds()
|
||||
set name = "Sound-Toggle-Whisper"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggle hearing a sound when somebody speaks using whisper."
|
||||
|
||||
var/pref_path = /datum/client_preference/whisper_sounds
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/whisper_sounds)) ? "hear" : "not hear"] whisper sounds.")
|
||||
|
||||
feedback_add_details("admin_verb","TWhisperSounds")
|
||||
|
||||
/client/verb/toggle_subtle_sounds()
|
||||
set name = "Sound-Toggle-Subtle"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggle hearing a sound when somebody uses subtle."
|
||||
|
||||
var/pref_path = /datum/client_preference/subtle_sounds
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/subtle_sounds)) ? "hear" : "not hear"] subtle sounds.")
|
||||
|
||||
feedback_add_details("admin_verb","TSubtleSounds")
|
||||
*/
|
||||
|
||||
/client/verb/toggle_vore_health_bars()
|
||||
set name = "Toggle Vore Health Bars"
|
||||
set category = "Preferences.Vore" //CHOMPEdit
|
||||
set desc = "Toggle the display of vore related health bars"
|
||||
|
||||
var/pref_path = /datum/client_preference/vore_health_bars
|
||||
toggle_preference(pref_path)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
to_chat(src, "Vore related health bars - [(is_preference_enabled(/datum/client_preference/vore_health_bars)) ? "Enabled" : "Disabled"]")
|
||||
|
||||
feedback_add_details("admin_verb","TVoreHealthBars")
|
||||
|
||||
// Not attached to a pref datum because those are strict binary toggles
|
||||
/client/verb/toggle_examine_mode()
|
||||
set name = "Toggle Examine Mode"
|
||||
@@ -518,65 +57,3 @@ CHOMPRemove. Bundled voice sounds into emote/whisper/subtle. Going this extra le
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing will enforce the a language delimiter after the delimiter-key combination (,0,galcom -2 still galcom). The extra delimiter will be consumed by the pattern-matching.</span>")
|
||||
if(MULTILINGUAL_OFF)
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing is now disabled. Entire messages will be in the language specified at the start of the message.</span>")
|
||||
|
||||
|
||||
//Toggles for Staff
|
||||
//Developers
|
||||
|
||||
/client/proc/toggle_debug_logs()
|
||||
set name = "Toggle Debug Logs"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles seeing debug logs."
|
||||
|
||||
var/pref_path = /datum/client_preference/debug/show_debug_logs
|
||||
|
||||
if(check_rights(R_ADMIN|R_DEBUG))
|
||||
toggle_preference(pref_path)
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive debug logs.")
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TADebugLogs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
//Mods
|
||||
/client/proc/toggle_attack_logs()
|
||||
set name = "Toggle Attack Logs"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles seeing attack logs."
|
||||
|
||||
var/pref_path = /datum/client_preference/mod/show_attack_logs
|
||||
|
||||
if(check_rights(R_ADMIN|R_MOD))
|
||||
toggle_preference(pref_path)
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive attack logs.")
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAAttackLogs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
//General
|
||||
/client/proc/toggle_admin_global_looc()
|
||||
set name = "Toggle Admin Global LOOC Visibility"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles seeing LOOC messages outside your actual LOOC range."
|
||||
|
||||
var/pref_path = /datum/client_preference/holder/show_rlooc
|
||||
|
||||
if(holder)
|
||||
toggle_preference(pref_path)
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear global LOOC.")
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAGlobalLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/toggle_admin_deadchat()
|
||||
set name = "Toggle Admin Living Deadchat"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles seeing deadchat while not observing."
|
||||
|
||||
var/pref_path = /datum/client_preference/holder/show_staff_dsay
|
||||
|
||||
if(holder)
|
||||
toggle_preference(pref_path)
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear deadchat while not observing.")
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TADeadchat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -18,97 +18,6 @@
|
||||
var/job_talon_low = 0
|
||||
|
||||
//Why weren't these in game toggles already?
|
||||
/client/verb/toggle_eating_noises()
|
||||
set name = "Toggle Eating Noises"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles hearing Vore Eating noises."
|
||||
|
||||
var/pref_path = /datum/client_preference/eating_noises
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear eating related vore noises.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TEatNoise") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/client/verb/toggle_digestion_noises()
|
||||
set name = "Toggle Digestion Noises"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles hearing Vore Digestion noises."
|
||||
|
||||
var/pref_path = /datum/client_preference/digestion_noises
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear digestion related vore noises.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TDigestNoise") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_belch_noises()
|
||||
set name = "Toggle Audible Belching"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles hearing audible belches."
|
||||
|
||||
var/pref_path = /datum/client_preference/belch_noises
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear belching.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TBelchNoise")
|
||||
|
||||
/client/verb/toggle_emote_noises()
|
||||
set name = "Toggle Emote Noises"
|
||||
set category = "Preferences.Sounds" //CHOMPEdit
|
||||
set desc = "Toggles hearing emote noises."
|
||||
|
||||
var/pref_path = /datum/client_preference/emote_noises
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear emote-related noises.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TEmoteNoise") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ghost_quiets()
|
||||
set name = "Toggle Ghost Privacy"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "Toggles ghosts being able to see your subtles/whispers."
|
||||
|
||||
var/pref_path = /datum/client_preference/whisubtle_vis
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "Ghosts will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear subtles/whispers made by you.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TWhisubtleVis") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ghost_privacyvision()
|
||||
set name = "Toggle Ghost Private Eyes/ears"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles your ability to see subtles/whispers. Overrides admin status. Respects Ghost Privacy"
|
||||
|
||||
var/pref_path = /datum/client_preference/ghost_see_whisubtle
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "As a ghost, you will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear subtles/whispers made by players.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TGhostSeeWhisSubtle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_capture_crystal()
|
||||
set name = "Toggle Catchable"
|
||||
set category = "Preferences.Character" //CHOMPEdit
|
||||
@@ -127,55 +36,3 @@
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TCaptureCrystal") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_mentorhelp_ping()
|
||||
set name = "Toggle Mentorhelp Ping"
|
||||
set category = "Preferences.Admin" //CHOMPEdit
|
||||
set desc = "Toggles the mentorhelp ping"
|
||||
|
||||
var/pref_path = /datum/client_preference/play_mentorhelp_ping
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "Mentorhelp pings are now [ is_preference_enabled(pref_path) ? "enabled" : "disabled"]")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb", "TSoundMentorhelps")
|
||||
|
||||
/client/verb/toggle_player_tips()
|
||||
set name = "Toggle Receiving Player Tips"
|
||||
set category = "Preferences.Chat" //CHOMPEdit
|
||||
set desc = "When toggled on, you receive tips periodically on roleplay and gameplay."
|
||||
|
||||
var/pref_path = /datum/client_preference/player_tips
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You are [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] periodically receiving advice on gameplay and roleplay.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb", "TReceivePlayerTips")
|
||||
|
||||
/client/verb/toggle_pain_frequency()
|
||||
set name = "Toggle Pain Frequency"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "When toggled on, increases the cooldown of pain messages sent to chat for minor injuries"
|
||||
|
||||
var/pref_path = /datum/client_preference/pain_frequency
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "The cooldown between pain messages for minor (under 20/5 injury. Multi-limb injuries are still faster) is now [ (is_preference_enabled(pref_path)) ? "extended" : "default"].")
|
||||
|
||||
/client/verb/toggle_automatic_afk()
|
||||
set name = "Toggle Automatic AFK"
|
||||
set category = "Preferences.Game" //CHOMPEdit
|
||||
set desc = "When enabled, causes you to be automatically marked as AFK if you are idle for too long."
|
||||
|
||||
var/pref_path = /datum/client_preference/auto_afk
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "not"] be automatically marked as AFK if you are idle for ten minutes or more.")
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
msg = sanitize(msg)
|
||||
if(!msg) return
|
||||
|
||||
if(!is_preference_enabled(/datum/client_preference/show_ooc))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_ooc))
|
||||
to_chat(src, "<span class='warning'>You have OOC muted.</span>")
|
||||
return
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
msg = GLOB.is_valid_url.Replace(msg,"<span class='linkify'>$1</span>")
|
||||
|
||||
for(var/client/target in GLOB.clients)
|
||||
if(target.is_preference_enabled(/datum/client_preference/show_ooc))
|
||||
if(target.prefs?.read_preference(/datum/preference/toggle/show_ooc))
|
||||
if(target.is_key_ignored(key)) // If we're ignored by this person, then do nothing.
|
||||
continue
|
||||
var/display_name = src.key
|
||||
@@ -101,7 +101,7 @@
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
if(!is_preference_enabled(/datum/client_preference/show_looc))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_looc))
|
||||
to_chat(src, "<span class='danger'>You have LOOC muted.</span>")
|
||||
return
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
|
||||
// Everyone in normal viewing range of the LOOC
|
||||
for(var/mob/viewer in m_viewers)
|
||||
if(viewer.client && viewer.client.is_preference_enabled(/datum/client_preference/show_looc))
|
||||
if(viewer.client && viewer.client.prefs?.read_preference(/datum/preference/toggle/show_looc))
|
||||
receivers |= viewer.client
|
||||
else if(istype(viewer,/mob/observer/eye)) // For AI eyes and the like
|
||||
var/mob/observer/eye/E = viewer
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
// Admins with RLOOC displayed who weren't already in
|
||||
for(var/client/admin in GLOB.admins)
|
||||
if(!(admin in receivers) && admin.is_preference_enabled(/datum/client_preference/holder/show_rlooc))
|
||||
if(!(admin in receivers) && admin.prefs?.read_preference(/datum/preference/toggle/holder/show_rlooc))
|
||||
if(check_rights(R_ADMIN|R_SERVER, FALSE, admin)) //Stop rLOOC showing for retired staff //CHOMPEdit, admins should see LOOC
|
||||
r_receivers |= admin
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
src << output('html/typing_indicator.html', "commandbar_spy")
|
||||
|
||||
/client/proc/handle_commandbar_typing(href_list)
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator))
|
||||
return
|
||||
|
||||
if(length(href_list["verb"]) < 1 || !(lowertext(href_list["verb"]) in IC_VERBS) || text2num(href_list["argument_length"]) < 1)
|
||||
@@ -31,10 +31,10 @@
|
||||
|
||||
/** Sets the mob as "thinking" - with indicator and the TRAIT_THINKING_IN_CHARACTER trait */
|
||||
/client/proc/start_thinking(channel)
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator))
|
||||
return FALSE
|
||||
if(channel == "Whis" || channel == "Subtle" || channel == "whisper" || channel == "subtle")
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator_subtle))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator_subtle))
|
||||
return FALSE
|
||||
ADD_TRAIT(mob, TRAIT_THINKING_IN_CHARACTER, CURRENTLY_TYPING_TRAIT)
|
||||
mob.create_thinking_indicator()
|
||||
@@ -50,10 +50,10 @@
|
||||
/client/proc/start_typing(channel)
|
||||
var/mob/client_mob = mob
|
||||
client_mob.remove_thinking_indicator()
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator) || !HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator) || !HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
|
||||
return FALSE
|
||||
if(channel == "Whis" || channel == "Subtle" || channel == "whisper" || channel == "subtle")
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator_subtle))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator_subtle))
|
||||
return FALSE
|
||||
client_mob.create_typing_indicator()
|
||||
addtimer(CALLBACK(src, PROC_REF(stop_typing), channel), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE)
|
||||
@@ -67,10 +67,10 @@
|
||||
return FALSE
|
||||
var/mob/client_mob = mob
|
||||
client_mob.remove_typing_indicator()
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator) || !HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator) || !HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
|
||||
return FALSE
|
||||
if(channel == "Whis" || channel == "Subtle" || channel == "whisper" || channel == "subtle")
|
||||
if(!is_preference_enabled(/datum/client_preference/show_typing_indicator_subtle))
|
||||
if(!prefs?.read_preference(/datum/preference/toggle/show_typing_indicator_subtle))
|
||||
return FALSE
|
||||
client_mob.create_thinking_indicator()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user