mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-28 02:21:53 +00:00
309 lines
12 KiB
Plaintext
309 lines
12 KiB
Plaintext
GLOBAL_DATUM(character_directory, /datum/character_directory)
|
|
#define READ_PREFS(target, pref) (target.client.prefs.read_preference(/datum/preference/pref) || "Unset")
|
|
|
|
//We want players to be able to decide whether they show up in the directory or not
|
|
/datum/preference/toggle/show_in_directory
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
default_value = TRUE
|
|
savefile_key = "show_in_directory"
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
//The advertisement that you show to people looking through the directory
|
|
/datum/preference/text/character_ad
|
|
savefile_key = "character_ad"
|
|
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
|
savefile_identifier = PREFERENCE_CHARACTER
|
|
maximum_value_length = MAX_FLAVOR_LEN
|
|
|
|
//TGUI gets angry if you don't define a default on text preferences
|
|
/datum/preference/text/character_ad/create_default_value()
|
|
return ""
|
|
|
|
//Any text preference needs this for some reason
|
|
/datum/preference/text/character_ad/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
|
|
/datum/preference/choiced/attraction
|
|
savefile_key = "attraction"
|
|
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
|
savefile_identifier = PREFERENCE_CHARACTER
|
|
|
|
/datum/preference/choiced/attraction/init_possible_values()
|
|
return list("Gay", "Lesbian", "Straight", "Skolio", "Bi", "Pan", "Poly", "Omni", "Ace", "Aro", "Aro/Ace", "Unset", "Check OOC")
|
|
|
|
/datum/preference/choiced/attraction/create_default_value()
|
|
return "Unset"
|
|
|
|
/datum/preference/choiced/attraction/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
|
|
/datum/preference/choiced/display_gender
|
|
savefile_key = "display_gender"
|
|
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
|
savefile_identifier = PREFERENCE_CHARACTER
|
|
|
|
/datum/preference/choiced/display_gender/init_possible_values()
|
|
return list("Male", "Female", "Null", "Plural", "Nonbinary", "Omni", "Trans", "Transmasc", "Transfem", "Andro", "Gyno", "Fluid", "Unset", "Check OOC")
|
|
|
|
/datum/preference/choiced/display_gender/create_default_value()
|
|
return "Unset"
|
|
|
|
/datum/preference/choiced/display_gender/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
//Can't believe Bubberstation invented attraction and gender in the year December 2023
|
|
|
|
/datum/preference/choiced/emote_length
|
|
savefile_key = "emote_length"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/emote_length/init_possible_values()
|
|
return list("A few sentences", "1-2 Paragraphs", "Multi-Paragraph", "I'll Match You", "No Preference", "Check OOC")
|
|
|
|
/datum/preference/choiced/emote_length/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
|
|
/datum/preference/choiced/emote_length/create_default_value()
|
|
return "No Preference"
|
|
|
|
/datum/preference/choiced/approach_pref
|
|
savefile_key = "approach_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/approach_pref/init_possible_values()
|
|
return list("Approach IC", "Approach OOC", "Any", "Both", "Check OOC", "See Below", "Unset")
|
|
|
|
/datum/preference/choiced/approach_pref/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
|
|
/datum/preference/choiced/approach_pref/create_default_value()
|
|
return "Unset"
|
|
|
|
/// Pref for all the things with the same "Yes", "No", "No ERP", "Check OOC", "Unset", "Maybe" setting
|
|
/// Saves us on copypaste code
|
|
/datum/preference/choiced/directory_character_prefs
|
|
savefile_key = "char_directory_char_prefs" // This is so unit checks don't scream
|
|
|
|
/datum/preference/choiced/directory_character_prefs/init_possible_values()
|
|
return list("Yes", "No", "No ERP", "Check OOC", "Unset", "Maybe")
|
|
|
|
/datum/preference/choiced/directory_character_prefs/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
|
return FALSE
|
|
|
|
/datum/preference/choiced/directory_character_prefs/create_default_value()
|
|
return "Unset"
|
|
|
|
/datum/preference/choiced/directory_character_prefs/furry_pref
|
|
savefile_key = "furry_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/directory_character_prefs/scalie_pref
|
|
savefile_key = "scalie_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/directory_character_prefs/other_pref
|
|
savefile_key = "other_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/directory_character_prefs/demihuman_pref
|
|
savefile_key = "demihuman_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
/datum/preference/choiced/directory_character_prefs/human_pref
|
|
savefile_key = "human_pref"
|
|
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
|
savefile_identifier = PREFERENCE_PLAYER
|
|
|
|
//CHARACTER DIRECTORY CODE START
|
|
//Add a cooldown for the character directory to the client, primarily to stop server lag from refresh spam
|
|
/client
|
|
COOLDOWN_DECLARE(char_directory_cooldown)
|
|
|
|
//Make a verb to open the character directory
|
|
/client/verb/show_character_directory()
|
|
set name = "Character Directory"
|
|
set category = "OOC"
|
|
set desc = "Shows a listing of all active characters, along with their associated OOC notes, flavor text, and more."
|
|
|
|
// This is primarily to stop malicious users from trying to lag the server by spamming this verb
|
|
if(!COOLDOWN_FINISHED(src, char_directory_cooldown))
|
|
to_chat(src, span_alert("Hold your horses! It's still refreshing!"))
|
|
return
|
|
COOLDOWN_START(src, char_directory_cooldown, 10)
|
|
|
|
//Check if there's not already a character directory open; open a new one if one is not present
|
|
if(!GLOB.character_directory)
|
|
GLOB.character_directory = new
|
|
GLOB.character_directory.ui_interact(mob)
|
|
|
|
// This is a global singleton. Keep in mind that all operations should occur on user, not src.
|
|
/datum/character_directory
|
|
|
|
/datum/character_directory/ui_state(mob/user)
|
|
return GLOB.always_state
|
|
|
|
/datum/character_directory/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "ZubbersCharacterDirectory", "Character Directory")
|
|
ui.open()
|
|
|
|
//We want this information to update any time the player updates their preferences, not just when the panel is refreshed
|
|
/datum/character_directory/ui_data(mob/user)
|
|
. = ..()
|
|
var/list/data = .
|
|
|
|
//Collect the user's own preferences for the top of the UI
|
|
if (user?.client?.prefs)
|
|
data["personalVisibility"] = READ_PREFS(user, toggle/show_in_directory)
|
|
data["personalAttraction"] = READ_PREFS(user, choiced/attraction)
|
|
data["personalGender"] = READ_PREFS(user, choiced/display_gender)
|
|
data["personalErpTag"] = READ_PREFS(user, choiced/erp_status)
|
|
data["personalVoreTag"] = READ_PREFS(user, choiced/erp_status_v)
|
|
data["personalHypnoTag"] = READ_PREFS(user, choiced/erp_status_hypno)
|
|
data["personalNonconTag"] = READ_PREFS(user, choiced/erp_status_nc)
|
|
data["prefsOnly"] = TRUE
|
|
|
|
data["canOrbit"] = isobserver(user)
|
|
|
|
return data
|
|
|
|
/datum/character_directory/ui_static_data(mob/user)
|
|
. = ..()
|
|
var/list/data = .
|
|
|
|
var/list/directory_mobs = list()
|
|
//We want the directory to display only alive players, not observers or people in the lobby
|
|
for(var/mob/mob in GLOB.alive_player_list)
|
|
// These are the variables we're trying to display in the directory
|
|
var/name = ""
|
|
var/species = "Ask"
|
|
var/ooc_notes = ""
|
|
var/flavor_text = ""
|
|
var/nsfw_flavor_text = ""
|
|
var/attraction = "Unset"
|
|
var/gender = "Nonbinary"
|
|
var/erp = "Ask"
|
|
var/vore = "Ask"
|
|
var/hypno = "Ask"
|
|
var/noncon = "Ask"
|
|
var/character_ad = ""
|
|
var/exploitable = ""
|
|
var/ref = REF(mob)
|
|
//Just in case something we get is not a mob
|
|
if(!mob)
|
|
continue
|
|
|
|
//Different approach for humans and silicons
|
|
if(ishuman(mob))
|
|
var/mob/living/carbon/human/human = mob
|
|
//If someone is obscured without flavor text visible, we don't want them on the Directory.
|
|
if((human.wear_mask && (human.wear_mask.flags_inv & HIDEFACE) && READ_PREFS(human, toggle/obscurity_examine)) || (human.head && (human.head.flags_inv & HIDEFACE) && READ_PREFS(human, toggle/obscurity_examine)) || (HAS_TRAIT(human, TRAIT_UNKNOWN)))
|
|
continue
|
|
//Display custom species, otherwise show base species instead
|
|
species = (READ_PREFS(human, text/custom_species))
|
|
if(species == "Unset")
|
|
species = "[human.dna.species.name]"
|
|
//Load standard flavor text preference
|
|
flavor_text = READ_PREFS(human, text/flavor_text)
|
|
if((READ_PREFS(human, choiced/show_nsfw_flavor_text) == "Always On") || ((READ_PREFS(human, choiced/show_nsfw_flavor_text) == "Nude Only") && !(human.w_uniform)))
|
|
nsfw_flavor_text = READ_PREFS(human, text/flavor_text_nsfw)
|
|
else nsfw_flavor_text = "Unavailable"
|
|
|
|
else if(issilicon(mob))
|
|
var/mob/living/silicon/silicon = mob
|
|
//If the target is a silicon, we want it to show its brain as its species
|
|
species = READ_PREFS(silicon, choiced/brain_type)
|
|
//Load silicon flavor text in place of normal flavor text
|
|
flavor_text = READ_PREFS(silicon, text/silicon_flavor_text)
|
|
if(READ_PREFS(silicon, choiced/show_nsfw_flavor_text) != "Never")
|
|
nsfw_flavor_text = READ_PREFS(silicon, text/flavor_text_nsfw/silicon)
|
|
else nsfw_flavor_text = "Unavailable"
|
|
//Don't show if they are not a human or a silicon
|
|
else continue
|
|
//List of all the shown ERP preferences in the Directory. If there is none, return "Unset"
|
|
attraction = READ_PREFS(mob, choiced/attraction)
|
|
gender = READ_PREFS(mob, choiced/display_gender)
|
|
erp = READ_PREFS(mob, choiced/erp_status)
|
|
vore = READ_PREFS(mob, choiced/erp_status_v)
|
|
hypno = READ_PREFS(mob, choiced/erp_status_hypno)
|
|
noncon = READ_PREFS(mob, choiced/erp_status_nc)
|
|
character_ad = READ_PREFS(mob, text/character_ad)
|
|
ooc_notes = READ_PREFS(mob, text/ooc_notes)
|
|
//If the user is an antagonist or Observer, we want them to be able to see exploitables in the Directory.
|
|
if(user.mind?.has_antag_datum(/datum/antagonist) || isobserver(user))
|
|
if(exploitable == EXPLOITABLE_DEFAULT_TEXT)
|
|
exploitable = "Unset"
|
|
else exploitable = READ_PREFS(mob, text/exploitable)
|
|
else exploitable = "Obscured"
|
|
//And finally, we want to get the mob's name, taking into account disguised names.
|
|
name = mob.real_name ? mob.name : mob.real_name
|
|
|
|
directory_mobs.Add(list(list(
|
|
"name" = name,
|
|
"species" = species,
|
|
"ooc_notes" = ooc_notes,
|
|
"attraction" = attraction,
|
|
"gender" = gender,
|
|
"erp" = erp,
|
|
"vore" = vore,
|
|
"hypno" = hypno,
|
|
"noncon" = noncon,
|
|
"exploitable" = exploitable,
|
|
"character_ad" = character_ad,
|
|
"flavor_text" = flavor_text,
|
|
"nsfw_flavor_text" = nsfw_flavor_text,
|
|
"ref" = ref
|
|
)))
|
|
|
|
data["directory"] = directory_mobs
|
|
|
|
return data
|
|
|
|
/datum/character_directory/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
|
|
if(.)
|
|
return
|
|
|
|
var/mob/user = usr
|
|
if(!user)
|
|
return
|
|
|
|
switch(action)
|
|
if("refresh")
|
|
// This is primarily to stop malicious users from trying to lag the server by spamming this verb
|
|
if(!COOLDOWN_FINISHED(user.client, char_directory_cooldown))
|
|
to_chat(user, "<span class='warning'>Don't spam character directory refresh.</span>")
|
|
return
|
|
COOLDOWN_START(user.client, char_directory_cooldown, 10)
|
|
update_static_data(user, ui)
|
|
return TRUE
|
|
if("orbit")
|
|
var/ref = params["ref"]
|
|
var/mob/dead/observer/ghost = user
|
|
var/atom/movable/poi = (locate(ref) in GLOB.mob_list)
|
|
if (poi == null)
|
|
return TRUE
|
|
ghost.ManualFollow(poi)
|
|
ghost.reset_perspective(null)
|
|
return TRUE
|
|
if("view")
|
|
var/ref = params["ref"]
|
|
var/datum/examine_panel/panel
|
|
var/mob/living/carbon/target = (locate(ref) in GLOB.mob_list)
|
|
if(issilicon(target))
|
|
var/mob/living/silicon/robot/typed_target = target
|
|
panel = typed_target.examine_panel
|
|
panel.holder = typed_target
|
|
else
|
|
var/mob/living/carbon/human/typed_target = target
|
|
panel = typed_target.tgui
|
|
panel.holder = typed_target
|
|
panel.ui_interact(user)
|