[MIRROR] tgui Preferences Menu + total rewrite of the preferences backend (#8153)

* tgui Preferences Menu + total rewrite of the preferences backend

* nah, we dont need to ping those people

* trying to remove the funny stuff

* unmodularizing this

* prefs reset

* this may need to be reverted, who knows

* okay, this part

* perhaps

* EEEEEEEEE

* unsanitary

* E

* Stage 1 + loadout system

* more fixes

* E

* I mean, it launches?

* More fixes and reorganisation

* E

* customisation code is spaget.

* disable ERP prefs

* Update erp_preferences.dm

* Update erp_preferences.dm

* E

* Slowly getting there

* It may be time for help :)

* tri...colors... help

* preferences now pass preferences

* Update dna.dm

* Fuck this man

* missing savefile return, set_species works, removed dumb stuff from updateappearance

* https://github.com/Skyrat-SS13/Skyrat-tg/pull/8199

* https://github.com/Skyrat-SS13/Skyrat-tg/pull/8224

* https://github.com/tgstation/tgstation/pull/61519

* https://github.com/Skyrat-SS13/Skyrat-tg/pull/8278

* e

* le butonAZARAK HELLO

* hhh

* Proper recognition where it's due, MrMelbert!

* EEEE

* examine block

* Better gen hit sounds from whitedream

* final loadout touches, more bug fixes im sure to come

* i said there would be bugfixes

* Update LoadoutManager.js

* Missing preferences in the html menu

* LIVE TESTING PHASE BABY

* Update LoadoutManager.js

* EEE

* LAUNCH TEST FIRE

* Update job.dm

* Update new_player.dm

* 50gb DAY ONE PATCH

* EEE

* Update preferences.dm

* buggle fixes

* Update examine.dm

* >LOOC starts on

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: jjpark-kb <55967837+jjpark-kb@users.noreply.github.com>
Co-authored-by: Gandalf <jzo123@hotmail.com>
Co-authored-by: Azarak <azarak10@gmail.com>
This commit is contained in:
SkyratBot
2021-09-23 00:40:37 +01:00
committed by GitHub
co-authored by Mothblocks jjpark-kb Gandalf Azarak
parent a5bfc42228
commit 124ddd7cca
582 changed files with 19548 additions and 8366 deletions
+29 -6
View File
@@ -1,4 +1,3 @@
/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR
/mob/dead/new_player
flags_1 = NONE
invisibility = INVISIBILITY_ABSTRACT
@@ -94,6 +93,7 @@
var/datum/poll_question/poll = locate(href_list["votepollref"]) in GLOB.polls
vote_on_poll_handler(poll, href_list)
//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
/mob/dead/new_player/proc/make_me_an_observer()
if(QDELETED(src) || !src.client)
@@ -126,7 +126,7 @@
observer.client = client
observer.set_ghost_appearance()
if(observer.client && observer.client.prefs)
observer.real_name = observer.client.prefs.real_name
observer.real_name = observer.client.prefs.read_preference(/datum/preference/name/real_name)
observer.name = observer.real_name
observer.client.init_verbs()
observer.update_appearance()
@@ -150,6 +150,10 @@
return "Your account is not old enough for [jobtitle]."
if(JOB_UNAVAILABLE_SLOTFULL)
return "[jobtitle] is already filled to capacity."
//SKYRAT EDIT ADDITION
if(JOB_NOT_VETERAN)
return "You need to be veteran to join as [jobtitle]."
//SKYRAT EDIT END
return "Error: Unknown job availability."
/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE)
@@ -175,8 +179,13 @@
return JOB_UNAVAILABLE_PLAYTIME
if(latejoin && !job.special_check_latejoin(client))
return JOB_UNAVAILABLE_GENERIC
//SKYRAT EDIT ADDITION
if(job.veteran_only && !is_veteran_player(client))
return JOB_NOT_VETERAN
//SKYRAT EDIT END
return JOB_AVAILABLE
/mob/dead/new_player/proc/AttemptLateSpawn(rank)
var/error = IsJobUnavailable(rank)
if(error != JOB_AVAILABLE)
@@ -249,8 +258,6 @@
if(GLOB.curse_of_madness_triggered)
give_madness(humanc, GLOB.curse_of_madness_triggered)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CREWMEMBER_JOINED, humanc, rank)
GLOB.joined_player_list += character.ckey
if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
@@ -267,6 +274,14 @@
log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CREWMEMBER_JOINED, character, rank)
//SKYRAT EDIT ADDITION
if(humanc)
for(var/datum/loadout_item/item as anything in loadout_list_to_datums(humanc?.client?.prefs?.loadout_list))
item.post_equip_item(humanc.client?.prefs, humanc)
//SKYRAT EDIT END
/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
//TODO: figure out a way to exclude wizards/nukeops/demons from this.
for(var/C in GLOB.employmentCabinets)
@@ -280,6 +295,7 @@
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
dat += "<div class='notice red' style='font-size: 125%'>Only Observers may join at this time.</div><br>"
dat += "<div class='notice'>Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]</div>"
dat += "<div class='notice'>Alert Level: [capitalize(num2seclevel(SSsecurity_level.current_level))]</div>"
if(SSshuttle.emergency)
switch(SSshuttle.emergency.mode)
if(SHUTTLE_ESCAPE)
@@ -301,6 +317,7 @@
for(var/datum/job/job_datum as anything in department.department_jobs)
if(IsJobUnavailable(job_datum.title, TRUE) != JOB_AVAILABLE)
continue
var/command_bold = ""
if(job_datum.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)
command_bold = " command"
@@ -308,6 +325,9 @@
dept_data += "<a class='job[command_bold]' href='byond://?src=[REF(src)];SelectedJob=[job_datum.title]'><span class='priority'>[job_datum.title] ([job_datum.current_positions])</span></a>"
else
dept_data += "<a class='job[command_bold]' href='byond://?src=[REF(src)];SelectedJob=[job_datum.title]'>[job_datum.title] ([job_datum.current_positions])</a>"
if(!length(dept_data))
dept_data += "<span class='nopositions'>No positions open.</span>"
dat += dept_data.Join()
@@ -332,6 +352,9 @@
var/mob/living/spawning_mob = mind.assigned_role.get_spawn_mob(client, destination)
if(QDELETED(src) || !client)
return // Disconnected while checking for the appearance ban.
if(!isAI(spawning_mob)) // Unfortunately there's still snowflake AI code out there.
mind.original_character_slot_index = client.prefs.default_slot
mind.transfer_to(spawning_mob) //won't transfer key since the mind is not active
@@ -364,6 +387,7 @@
if(!GLOB.crew_manifest_tgui)
GLOB.crew_manifest_tgui = new /datum/crew_manifest(src)
GLOB.crew_manifest_tgui.ui_interact(src)
/mob/dead/new_player/Move()
@@ -386,7 +410,7 @@
/mob/dead/new_player/proc/check_preferences()
if(!client)
return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe.
if(client.prefs.joblessrole != RETURNTOLOBBY)
if(client.prefs.read_preference(/datum/preference/choiced/jobless_role) != RETURNTOLOBBY)
return TRUE
// If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so.
var/has_antags = FALSE
@@ -429,4 +453,3 @@
// Add verb for re-opening the interview panel, and re-init the verbs for the stat panel
add_verb(src, /mob/dead/new_player/proc/open_interview)
*/
@@ -1,98 +1,25 @@
/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR
/// Fully randomizes everything in the character.
/datum/preferences/proc/randomise_appearance_prefs(randomise_flags = ALL)
if(randomise_flags & RANDOMIZE_GENDER)
gender = pick(MALE, FEMALE, PLURAL)
switch(gender)
if(MALE, FEMALE)
body_type = gender
else
body_type = pick(MALE, FEMALE)
if(randomise_flags & RANDOMIZE_SPECIES)
var/rando_race = GLOB.species_list[pick(GLOB.roundstart_races)]
pref_species = new rando_race()
if(randomise_flags & RANDOMIZE_NAME)
real_name = pref_species.random_name(gender, TRUE)
if(randomise_flags & RANDOMIZE_AGE)
age = rand(AGE_MIN, AGE_MAX)
if(randomise_flags & RANDOMIZE_UNDERWEAR)
underwear = random_underwear(gender)
if(randomise_flags & RANDOMIZE_UNDERWEAR_COLOR)
underwear_color = random_short_color()
if(randomise_flags & RANDOMIZE_UNDERSHIRT)
undershirt = random_undershirt(gender)
if(randomise_flags & RANDOMIZE_SOCKS)
socks = random_socks()
if(randomise_flags & RANDOMIZE_BACKPACK)
backpack = random_backpack()
if(randomise_flags & RANDOMIZE_JUMPSUIT_STYLE)
jumpsuit_style = pick(GLOB.jumpsuitlist)
if(randomise_flags & RANDOMIZE_HAIRSTYLE)
hairstyle = random_hairstyle(gender)
if(randomise_flags & RANDOMIZE_FACIAL_HAIRSTYLE)
facial_hairstyle = random_facial_hairstyle(gender)
if(randomise_flags & RANDOMIZE_HAIR_COLOR)
hair_color = random_short_color()
if(randomise_flags & RANDOMIZE_FACIAL_HAIR_COLOR)
facial_hair_color = random_short_color()
if(randomise_flags & RANDOMIZE_SKIN_TONE)
skin_tone = random_skin_tone()
if(randomise_flags & RANDOMIZE_EYE_COLOR)
eye_color = random_eye_color()
if(randomise_flags & RANDOMIZE_FEATURES)
features = random_features()
/datum/preferences/proc/randomise_appearance_prefs(randomize_flags = ALL)
for (var/datum/preference/preference as anything in get_preferences_in_priority_order())
if (!preference.included_in_randomization_flags(randomize_flags))
continue
if (preference.is_randomizable())
write_preference(preference, preference.create_random_value(src))
/// Randomizes the character according to preferences.
/datum/preferences/proc/apply_character_randomization_prefs(antag_override = FALSE)
if(!randomise[RANDOM_BODY] && !(antag_override && randomise[RANDOM_BODY_ANTAG]))
return // Prefs say "no, thank you"
if(randomise[RANDOM_GENDER] || antag_override && randomise[RANDOM_GENDER_ANTAG])
gender = pick(MALE, FEMALE, PLURAL)
switch(gender)
if(MALE, FEMALE)
body_type = gender
else
body_type = pick(MALE, FEMALE)
if(randomise[RANDOM_SPECIES])
random_species()
else if(randomise[RANDOM_NAME] || antag_override && randomise[RANDOM_NAME_ANTAG])
real_name = pref_species.random_name(gender, TRUE)
if(randomise[RANDOM_AGE] || antag_override && randomise[RANDOM_AGE_ANTAG])
age = rand(AGE_MIN, AGE_MAX)
if(randomise[RANDOM_UNDERWEAR])
underwear = random_underwear(gender)
if(randomise[RANDOM_UNDERWEAR_COLOR])
underwear_color = random_short_color()
if(randomise[RANDOM_UNDERSHIRT])
undershirt = random_undershirt(gender)
if(randomise[RANDOM_SOCKS])
socks = random_socks()
if(randomise[RANDOM_BACKPACK])
backpack = random_backpack()
if(randomise[RANDOM_JUMPSUIT_STYLE])
jumpsuit_style = pick(GLOB.jumpsuitlist)
if(randomise[RANDOM_HAIRSTYLE])
hairstyle = random_hairstyle(gender)
if(randomise[RANDOM_FACIAL_HAIRSTYLE])
facial_hairstyle = random_facial_hairstyle(gender)
if(randomise[RANDOM_HAIR_COLOR])
hair_color = random_short_color()
if(randomise[RANDOM_FACIAL_HAIR_COLOR])
facial_hair_color = random_short_color()
if(randomise[RANDOM_SKIN_TONE])
skin_tone = random_skin_tone()
if(randomise[RANDOM_EYE_COLOR])
eye_color = random_eye_color()
features = random_features()
switch (read_preference(/datum/preference/choiced/random_body))
if (RANDOM_ANTAG_ONLY)
if (!antag_override)
return
if (RANDOM_DISABLED)
return
/datum/preferences/proc/random_species()
var/random_species_type = GLOB.species_list[pick(GLOB.roundstart_races)]
pref_species = new random_species_type
if(randomise[RANDOM_NAME])
real_name = pref_species.random_name(gender,1)
for (var/datum/preference/preference as anything in get_preferences_in_priority_order())
if (should_randomize(preference, antag_override))
write_preference(preference, preference.create_random_value(src))
///Setup the random hardcore quirks and give the character the new score prize.
/datum/preferences/proc/hardcore_random_setup(mob/living/carbon/human/character)
@@ -149,34 +76,37 @@
. += available_hardcore_quirks[picked_quirk]
available_hardcore_quirks -= picked_quirk
/datum/preferences/proc/update_preview_icon()
// Determine what job is marked as 'High' priority, and dress them up as such.
var/datum/job/previewJob
/// Returns what job is marked as highest
/datum/preferences/proc/get_highest_priority_job()
var/datum/job/preview_job
var/highest_pref = 0
for(var/job in job_preferences)
if(job_preferences[job] > highest_pref)
previewJob = SSjob.GetJob(job)
preview_job = SSjob.GetJob(job)
highest_pref = job_preferences[job]
if(previewJob)
// Silicons only need a very basic preview since there is no customization for them.
if(istype(previewJob,/datum/job/ai))
parent.show_character_previews(image('icons/mob/ai.dmi', icon_state = resolve_ai_icon(preferred_ai_core_display), dir = SOUTH))
return
if(istype(previewJob,/datum/job/cyborg))
parent.show_character_previews(image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH))
return
return preview_job
/datum/preferences/proc/render_new_preview_appearance(mob/living/carbon/human/dummy/mannequin)
var/datum/job/preview_job = get_highest_priority_job()
switch(preview_pref)
if(PREVIEW_PREF_JOB)
if(preview_job) //SKYRAT EDIT CHANGE
// Silicons only need a very basic preview since there is no customization for them.
if (istype(preview_job,/datum/job/ai))
return image('icons/mob/ai.dmi', icon_state = resolve_ai_icon(read_preference(/datum/preference/choiced/ai_core_display)), dir = SOUTH)
if (istype(preview_job,/datum/job/cyborg))
return image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH)
mannequin.job = preview_job.title
mannequin.equip_outfit_and_loadout(preview_job.outfit, src, TRUE)
if(PREVIEW_PREF_LOADOUT)
var/default_outfit = new /datum/outfit()
mannequin.equip_outfit_and_loadout(default_outfit, src, TRUE)
// Set up the dummy for its photoshoot
var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)
apply_prefs_to(mannequin, TRUE)
if(previewJob)
mannequin.job = previewJob.title
mannequin.dress_up_as_job(previewJob, TRUE)
COMPILE_OVERLAYS(mannequin)
parent.show_character_previews(new /mutable_appearance(mannequin))
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)
*/
return mannequin.appearance
+4 -4
View File
@@ -3,16 +3,16 @@
if(!. || !client)
return FALSE
ghost_accs = client.prefs.ghost_accs
ghost_others = client.prefs.ghost_others
ghost_accs = client.prefs.read_preference(/datum/preference/choiced/ghost_accessories)
ghost_others = client.prefs.read_preference(/datum/preference/choiced/ghost_others)
var/preferred_form = null
if(isAdminGhostAI(src))
has_unlimited_silicon_privilege = 1
if(client.prefs.unlock_content)
preferred_form = client.prefs.ghost_form
ghost_orbit = client.prefs.ghost_orbit
preferred_form = client.prefs.read_preference(/datum/preference/choiced/ghost_form)
ghost_orbit = client.prefs.read_preference(/datum/preference/choiced/ghost_orbit)
var/turf/T = get_turf(src)
if (isturf(T))
+27 -19
View File
@@ -191,8 +191,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
. = ..()
if(client) //We update our preferences in case they changed right before update_appearance was called.
ghost_accs = client.prefs.ghost_accs
ghost_others = client.prefs.ghost_others
ghost_accs = client.prefs.read_preference(/datum/preference/choiced/ghost_accessories)
ghost_others = client.prefs.read_preference(/datum/preference/choiced/ghost_others)
if(hair_overlay)
cut_overlay(hair_overlay)
@@ -210,7 +210,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
else
ghostimage_default.icon_state = new_form
if(ghost_accs >= GHOST_ACCS_DIR && (icon_state in GLOB.ghost_forms_with_directions_list)) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
if((ghost_accs == GHOST_ACCS_DIR || ghost_accs == GHOST_ACCS_FULL) && (icon_state in GLOB.ghost_forms_with_directions_list)) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
updatedir = 1
else
updatedir = 0 //stop updating the dir in case we want to show accessories with dirs on a ghost sprite without dirs
@@ -375,7 +375,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients
to_chat(usr, span_warning("Another consciousness is in your body...It is resisting you."))
return
client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))//Let's reset so people can't become allseeing gods
client.view_size.setDefault(getScreenSize(client.prefs.read_preference(/datum/preference/toggle/widescreen)))//Let's reset so people can't become allseeing gods
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
if(mind.current.stat == DEAD && SSlag_switch.measures[DISABLE_DEAD_KEYLOOP])
to_chat(src, span_warning("To leave your body again use the Ghost verb."))
@@ -414,8 +414,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(source)
var/atom/movable/screen/alert/A = throw_alert("[REF(source)]_notify_cloning", /atom/movable/screen/alert/notify_cloning)
if(A)
if(client && client.prefs && client.prefs.UI_style)
A.icon = ui_style2icon(client.prefs.UI_style)
var/ui_style = client?.prefs?.read_preference(/datum/preference/choiced/ui_style)
if(ui_style)
A.icon = ui_style2icon(ui_style)
A.desc = message
var/old_layer = source.layer
var/old_plane = source.plane
@@ -601,7 +602,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/update_sight()
if(client)
ghost_others = client.prefs.ghost_others //A quick update just in case this setting was changed right before calling the proc
ghost_others = client.prefs.read_preference(/datum/preference/choiced/ghost_others) //A quick update just in case this setting was changed right before calling the proc
if (!ghostvision)
see_invisible = SEE_INVISIBLE_LIVING
@@ -629,11 +630,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images -= GLOB.ghost_images_default
if(GHOST_OTHERS_SIMPLE)
client.images -= GLOB.ghost_images_simple
lastsetting = client.prefs.ghost_others
lastsetting = client.prefs.read_preference(/datum/preference/choiced/ghost_others)
if(!ghostvision)
return
if(client.prefs.ghost_others != GHOST_OTHERS_THEIR_SETTING)
switch(client.prefs.ghost_others)
if(lastsetting != GHOST_OTHERS_THEIR_SETTING)
switch(lastsetting)
if(GHOST_OTHERS_DEFAULT_SPRITE)
client.images |= (GLOB.ghost_images_default-ghostimage_default)
if(GHOST_OTHERS_SIMPLE)
@@ -798,10 +799,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set_ghost_appearance()
if(client?.prefs)
deadchat_name = client.prefs.real_name
var/real_name = client.prefs.read_preference(/datum/preference/name/real_name)
deadchat_name = real_name
if(mind)
mind.ghostname = client.prefs.real_name
name = client.prefs.real_name
mind.ghostname = real_name
name = real_name
/mob/dead/observer/proc/set_ghost_appearance()
if(!client?.prefs)
@@ -809,12 +811,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.prefs.apply_character_randomization_prefs()
if(HAIR in client.prefs.pref_species.species_traits)
hairstyle = client.prefs.hairstyle
hair_color = brighten_color(client.prefs.hair_color)
if(FACEHAIR in client.prefs.pref_species.species_traits)
facial_hairstyle = client.prefs.facial_hairstyle
facial_hair_color = brighten_color(client.prefs.facial_hair_color)
var/species_type = client.prefs.read_preference(/datum/preference/choiced/species)
var/datum/species/species = new species_type
if(HAIR in species.species_traits)
hairstyle = client.prefs.read_preference(/datum/preference/choiced/hairstyle)
hair_color = brighten_color(client.prefs.read_preference(/datum/preference/color_legacy/hair_color))
if(FACEHAIR in species.species_traits)
facial_hairstyle = client.prefs.read_preference(/datum/preference/choiced/facial_hairstyle)
facial_hair_color = brighten_color(client.prefs.read_preference(/datum/preference/color_legacy/facial_hair_color))
qdel(species)
update_appearance()
@@ -46,7 +46,7 @@
to_follow = V.source
var/link = FOLLOW_LINK(src, to_follow)
// Create map text prior to modifying message for goonchat
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
if (client?.prefs.read_preference(/datum/preference/toggle/enable_runechat) && (client.prefs.read_preference(/datum/preference/toggle/enable_runechat_non_mobs) || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans)
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods)