mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-14 00:26:02 +01:00
Character Setup Rework (#17576)
* Character Setup Rework Little tweaks Species selection done~ Merk randomize body button Body color and eye color Merk more replaced code Convert robolimbs to tgui Add a warning if flavor text/ooc notes are too short Custom preview icons for species selector! A sidequest that only took 8 hours. Also add digitigrade and blood type. Remove unused body_descriptor system completely Finish the general tab~ Reorganization to prepare for loadout page creation * Start of work on the loadout screen * Only send the data that's actually selected * Get rid of these ugly ../../../.. * Retype this to avoid conflicts * Holy shit why did this work this way * Finish loadout screen * Add copy loadout function * Finish occupation page * Move Special Roles into general tab * Fix path conflict * Move size prefs to general tab * Convert jukebox and volume settings to datum/preference * Fix a little mergery fuckery in loadout * Migrate jukebox to new range * Fix TabbedMenu tabs * Fix wordwrap for loadout screen * Kill the vore tab, just traits left to convert * Convert custom messages * Convert custom species name * Convert blood color and reagents * Move icobase to tgui * Finished * This can fuck off too * Fix a few bugs * Update index.tsx * initial for emote sound mode switch * Make show_roles actually work, hide fluff items * Fix not being able to select species * Add emote_sound_mode to body tab * Fix runtime when no active gear list is present * Add a save notification to character setup * Switch to floating * Add more search bars * Whoops forgot to add this --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -1,124 +0,0 @@
|
||||
/datum/category_item/player_setup_item/antagonism/basic
|
||||
name = "Basic"
|
||||
sort_order = 1
|
||||
|
||||
var/datum/paiCandidate/candidate
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/load_character(list/save_data)
|
||||
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(list/save_data)
|
||||
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/load_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
candidate = new()
|
||||
var/preference_mob = preference_mob()
|
||||
if(!preference_mob)// No preference mob - this happens when we're called from client/New() before it calls ..() (via datum/preferences/New())
|
||||
spawn()
|
||||
preference_mob = preference_mob()
|
||||
if(!preference_mob)
|
||||
return
|
||||
candidate.savefile_load(preference_mob)
|
||||
return
|
||||
|
||||
candidate.savefile_load(preference_mob)
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/save_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
return
|
||||
|
||||
if(!preference_mob())
|
||||
return
|
||||
|
||||
candidate.savefile_save(preference_mob())
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/sanitize_character()
|
||||
if(!pref.antag_faction) pref.antag_faction = "None"
|
||||
if(!pref.antag_vis) pref.antag_vis = "Hidden"
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/antagonism/basic/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.exploit_record = pref.exploit_record
|
||||
character.antag_faction = pref.antag_faction
|
||||
character.antag_vis = pref.antag_vis
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/content(var/mob/user)
|
||||
. += "Faction: <a href='byond://?src=\ref[src];antagfaction=1'>[pref.antag_faction]</a><br/>"
|
||||
. += "Visibility: <a href='byond://?src=\ref[src];antagvis=1'>[pref.antag_vis]</a><br/>"
|
||||
. += span_bold("Uplink Type:") + " <a href='byond://?src=\ref[src];antagtask=1'>[pref.read_preference(/datum/preference/choiced/uplinklocation)]</a>"
|
||||
. +="<br>"
|
||||
. +=span_bold("Exploitable information:") + "<br>"
|
||||
if(jobban_isbanned(user, "Records"))
|
||||
. += span_bold("You are banned from using character records.") + "<br>"
|
||||
else
|
||||
. +="<a href='byond://?src=\ref[src];exploitable_record=1'>[TextPreview(pref.exploit_record,40)]</a><br>"
|
||||
. += "<br>"
|
||||
. += span_bold("pAI:") + "<br>"
|
||||
if(!candidate)
|
||||
log_debug("[user] pAI prefs have a null candidate var.")
|
||||
return .
|
||||
. += "Name: <a href='byond://?src=\ref[src];option=name'>[candidate.name ? candidate.name : "None Set"]</a><br>"
|
||||
. += "Description: <a href='byond://?src=\ref[src];option=desc'>[candidate.description ? TextPreview(candidate.description, 40) : "None Set"]</a><br>"
|
||||
. += "Role: <a href='byond://?src=\ref[src];option=role'>[candidate.role ? TextPreview(candidate.role, 40) : "None Set"]</a><br>"
|
||||
. += "OOC Comments: <a href='byond://?src=\ref[src];option=ooc'>[candidate.comments ? TextPreview(candidate.comments, 40) : "None Set"]</a><br>"
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/basic/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["uplinklocation"])
|
||||
var/new_uplinklocation = tgui_input_list(user, "Choose your uplink location:", "Character Preference", GLOB.uplink_locations, pref.read_preference(/datum/preference/choiced/uplinklocation))
|
||||
if(new_uplinklocation && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/choiced/uplinklocation, new_uplinklocation)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["exploitable_record"])
|
||||
var/exploitmsg = sanitize(tgui_input_text(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH, extra = 0)
|
||||
if(!isnull(exploitmsg) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
|
||||
pref.exploit_record = exploitmsg
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["antagfaction"])
|
||||
var/choice = tgui_input_list(user, "Please choose an antagonistic faction to work for.", "Character Preference", antag_faction_choices + list("None","Other"), pref.antag_faction)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Please enter a faction.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.antag_faction = raw_choice
|
||||
else
|
||||
pref.antag_faction = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["antagvis"])
|
||||
var/choice = tgui_input_list(user, "Please choose an antagonistic visibility level.", "Character Preference", antag_visiblity_choices, pref.antag_vis)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
else
|
||||
pref.antag_vis = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["option"])
|
||||
var/t
|
||||
switch(href_list["option"])
|
||||
if("name")
|
||||
t = sanitizeName(tgui_input_text(user, "Enter a name for your pAI", "Global Preference", candidate.name, MAX_NAME_LEN), MAX_NAME_LEN, 1)
|
||||
if(t && CanUseTopic(user))
|
||||
candidate.name = t
|
||||
if("desc")
|
||||
t = tgui_input_text(user, "Enter a description for your pAI", "Global Preference", html_decode(candidate.description), multiline = TRUE, prevent_enter = TRUE)
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.description = sanitize(t)
|
||||
if("role")
|
||||
t = tgui_input_text(user, "Enter a role for your pAI", "Global Preference", html_decode(candidate.role))
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.role = sanitize(t)
|
||||
if("ooc")
|
||||
t = tgui_input_text(user, "Enter any OOC comments", "Global Preference", html_decode(candidate.comments), multiline = TRUE, prevent_enter = TRUE)
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.comments = sanitize(t)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
@@ -1,64 +0,0 @@
|
||||
var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm --rastaf
|
||||
//some autodetection here.
|
||||
// Change these to 0 if the equivalent mode is disabled for whatever reason!
|
||||
"traitor" = 0, // 0
|
||||
"operative" = 0, // 1
|
||||
"changeling" = 0, // 2
|
||||
"wizard" = 0, // 3
|
||||
"malf AI" = 0, // 4
|
||||
"revolutionary" = 0, // 5
|
||||
"alien candidate" = 0, // 6
|
||||
"positronic brain" = 1, // 7
|
||||
"cultist" = 0, // 8
|
||||
"renegade" = 0, // 9
|
||||
"ninja" = 0, // 10
|
||||
"raider" = 0, // 11
|
||||
"diona" = 0, // 12
|
||||
"mutineer" = 0, // 13
|
||||
"loyalist" = 0, // 14
|
||||
"pAI candidate" = 1, // 15
|
||||
//VOREStation Add
|
||||
"lost drone" = 1, // 16
|
||||
"maint pred" = 1, // 17
|
||||
"maint lurker" = 1, // 18
|
||||
"morph" = 1, // 19
|
||||
"corgi" = 1, // 20
|
||||
"cursed sword" = 1, // 21
|
||||
"Ship Survivor" = 1, // 22
|
||||
//VOREStation Add End
|
||||
)
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy
|
||||
name = "Candidacy"
|
||||
sort_order = 2
|
||||
|
||||
/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(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
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/content(var/mob/user)
|
||||
if(jobban_isbanned(user, JOB_SYNDICATE))
|
||||
. += span_bold("You are banned from antagonist roles.")
|
||||
pref.be_special = 0
|
||||
else
|
||||
var/n = 0
|
||||
for (var/i in special_roles)
|
||||
if(special_roles[i]) //if mode is available on the server
|
||||
if(jobban_isbanned(user, i) || (i == "positronic brain" && jobban_isbanned(user, JOB_AI) && jobban_isbanned(user, JOB_CYBORG)) || (i == "pAI candidate" && jobban_isbanned(user, JOB_PAI)))
|
||||
. += span_bold("Be [i]:") + " " + span_red(span_bold(" \[BANNED]")) + "<br>"
|
||||
else
|
||||
. += span_bold("Be [i]:") + " <a href='byond://?src=\ref[src];be_special=[n]'>" + span_bold("[pref.be_special&(1<<n) ? "Yes" : "No"]") + "</a><br>"
|
||||
n++
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["be_special"])
|
||||
var/num = text2num(href_list["be_special"])
|
||||
pref.be_special ^= (1<<num)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
@@ -1,7 +1,14 @@
|
||||
#define AUTOHISS_OFF 0
|
||||
#define AUTOHISS_BASIC 1
|
||||
#define AUTOHISS_FULL 2
|
||||
|
||||
/datum/preferences
|
||||
var/biological_gender = MALE
|
||||
var/identifying_gender = MALE
|
||||
|
||||
var/vore_egg_type = "Egg" //The egg type they have.
|
||||
var/autohiss = "Full" // VOREStation Add: Whether we have Autohiss on. I'm hijacking the egg panel bc this one has a shitton of unused space.
|
||||
|
||||
/datum/preferences/proc/set_biological_gender(var/gender)
|
||||
biological_gender = gender
|
||||
identifying_gender = gender
|
||||
@@ -11,16 +18,20 @@
|
||||
sort_order = 1
|
||||
|
||||
/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.biological_gender = save_data["gender"]
|
||||
pref.identifying_gender = save_data["id_gender"]
|
||||
pref.real_name = save_data["real_name"]
|
||||
pref.nickname = save_data["nickname"]
|
||||
pref.biological_gender = save_data["gender"]
|
||||
pref.identifying_gender = save_data["id_gender"]
|
||||
pref.vore_egg_type = save_data["vore_egg_type"]
|
||||
pref.autohiss = save_data["autohiss"]
|
||||
|
||||
/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["gender"] = pref.biological_gender
|
||||
save_data["id_gender"] = pref.identifying_gender
|
||||
save_data["vore_egg_type"] = pref.vore_egg_type
|
||||
save_data["autohiss"] = pref.autohiss
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/sanitize_character()
|
||||
pref.biological_gender = sanitize_inlist(pref.biological_gender, get_genders(), pick(get_genders()))
|
||||
@@ -29,6 +40,8 @@
|
||||
if(!pref.real_name)
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
pref.nickname = sanitize_name(pref.nickname)
|
||||
pref.vore_egg_type = sanitize_inlist(pref.vore_egg_type, GLOB.global_vore_egg_types, initial(pref.vore_egg_type))
|
||||
pref.autohiss = sanitize_inlist(pref.autohiss, list("None", "Basic", "Full"), initial(pref.autohiss))
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/general/basic/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
@@ -50,174 +63,232 @@
|
||||
character.gender = pref.biological_gender
|
||||
character.identifying_gender = pref.identifying_gender
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/content()
|
||||
. = list()
|
||||
. += span_bold("Name:") + " "
|
||||
. += "<a href='byond://?src=\ref[src];rename=1'><b>[pref.real_name]</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];random_name=1'>Randomize Name</A><br>"
|
||||
. += "<a href='byond://?src=\ref[src];always_random_name=1'>Always Random Name: [pref.read_preference(/datum/preference/toggle/human/name_is_always_random) ? "Yes" : "No"]</a><br>"
|
||||
. += span_bold("Nickname:") + " "
|
||||
. += "<a href='byond://?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_nickname=1'>Clear</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Biological Sex:") + " <a href='byond://?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
|
||||
. += span_bold("Pronouns:") + " <a href='byond://?src=\ref[src];id_gender=1'><b>[genders_to_pronoun_set[pref.identifying_gender]]</b></a><br>"
|
||||
. += span_bold("Age:") + " <a href='byond://?src=\ref[src];age=1'>[pref.read_preference(/datum/preference/numeric/human/age)]</a> <b>Birthday:</b> <a href='byond://?src=\ref[src];bday_month=1'>[pref.read_preference(/datum/preference/numeric/human/bday_month)]</a><b>/</b><a href='byond://?src=\ref[src];bday_day=1'>[pref.read_preference(/datum/preference/numeric/human/bday_day)]</a> - <b>Announce?:</b> <a href='byond://?src=\ref[src];bday_announce=1'>[pref.read_preference(/datum/preference/toggle/human/bday_announce) ? "Yes" : "Disabled"]</a><br>"
|
||||
. += span_bold("Spawn Point:") + " <a href='byond://?src=\ref[src];spawnpoint=1'>[pref.read_preference(/datum/preference/choiced/living/spawnpoint)]</a><br>"
|
||||
if(CONFIG_GET(flag/allow_metadata))
|
||||
. += span_bold("OOC Notes: <a href='byond://?src=\ref[src];edit_ooc_notes=1'>Edit</a><a href='byond://?src=\ref[src];edit_ooc_note_favs=1'>Favs</a><a href='byond://?src=\ref[src];edit_ooc_note_likes=1'>Likes</a><a href='byond://?src=\ref[src];edit_ooc_note_maybes=1'>Maybes</a><a href='byond://?src=\ref[src];edit_ooc_note_dislikes=1'>Dislikes</a>") + "<br>"
|
||||
. += "Detailed field or short list system? <a href='byond://?src=\ref[src];edit_ooc_note_style=1'>[pref.read_preference(/datum/preference/toggle/living/ooc_notes_style) ? "Lists" : "Fields"]</a><br><br>"
|
||||
. = jointext(.,null)
|
||||
character.vore_egg_type = pref.vore_egg_type
|
||||
// VOREStation Add
|
||||
if(pref.client) // Safety, just in case so we don't runtime.
|
||||
if(!pref.autohiss)
|
||||
pref.client.autohiss_mode = AUTOHISS_FULL
|
||||
else
|
||||
switch(pref.autohiss)
|
||||
if("Full")
|
||||
pref.client.autohiss_mode = AUTOHISS_FULL
|
||||
if("Basic")
|
||||
pref.client.autohiss_mode = AUTOHISS_BASIC
|
||||
if("Off")
|
||||
pref.client.autohiss_mode = AUTOHISS_OFF
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["rename"])
|
||||
var/raw_name = tgui_input_text(user, "Choose your character's name:", "Character Name")
|
||||
if (!isnull(raw_name) && CanUseTopic(user))
|
||||
var/new_name = sanitize_name(raw_name, pref.species, is_FBP())
|
||||
if(new_name)
|
||||
pref.real_name = new_name
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
return TOPIC_NOACTION
|
||||
/datum/category_item/player_setup_item/general/basic/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
else if(href_list["random_name"])
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
return TOPIC_REFRESH
|
||||
data["real_name"] = pref.real_name
|
||||
data["be_random_name"] = pref.read_preference(/datum/preference/toggle/human/name_is_always_random)
|
||||
data["nickname"] = pref.nickname
|
||||
data["biological_sex"] = gender2text(pref.biological_gender)
|
||||
data["identifying_gender"] = gender2text(pref.identifying_gender)
|
||||
data["age"] = pref.read_preference(/datum/preference/numeric/human/age)
|
||||
data["bday_month"] = pref.read_preference(/datum/preference/numeric/human/bday_month)
|
||||
data["bday_day"] = pref.read_preference(/datum/preference/numeric/human/bday_day)
|
||||
data["bday_announce"] = pref.read_preference(/datum/preference/toggle/human/bday_announce)
|
||||
data["spawnpoint"] = pref.read_preference(/datum/preference/choiced/living/spawnpoint)
|
||||
data["ooc_notes_length"] = LAZYLEN(pref.read_preference(/datum/preference/text/living/ooc_notes))
|
||||
data["vore_egg_type"] = pref.vore_egg_type
|
||||
data["autohiss"] = pref.autohiss
|
||||
data["emote_sound_mode"] = pref.read_preference(/datum/preference/choiced/living/emote_sound_mode)
|
||||
|
||||
else if(href_list["always_random_name"])
|
||||
pref.update_preference_by_type(/datum/preference/toggle/human/name_is_always_random, !pref.read_preference(/datum/preference/toggle/human/name_is_always_random))
|
||||
return TOPIC_REFRESH
|
||||
return data
|
||||
|
||||
else if(href_list["nickname"])
|
||||
var/raw_nickname = tgui_input_text(user, "Choose your character's nickname:", "Character Nickname", pref.nickname)
|
||||
if (!isnull(raw_nickname) && CanUseTopic(user))
|
||||
var/new_nickname = sanitize_name(raw_nickname, pref.species, is_FBP())
|
||||
if(new_nickname)
|
||||
pref.nickname = new_nickname
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
return TOPIC_NOACTION
|
||||
/datum/category_item/player_setup_item/general/basic/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
else if(href_list["reset_nickname"])
|
||||
var/nick_choice = tgui_alert(user, "Wipe your Nickname? This will completely remove any chosen nickname(s).","Wipe Nickname",list("Yes","No"))
|
||||
if(nick_choice == "Yes")
|
||||
pref.nickname = null
|
||||
return TOPIC_REFRESH
|
||||
data["allow_metadata"] = CONFIG_GET(flag/allow_metadata)
|
||||
|
||||
else if(href_list["bio_gender"])
|
||||
var/new_gender = tgui_input_list(user, "Choose your character's biological sex:", "Character Preference", get_genders(), pref.biological_gender)
|
||||
if(new_gender && CanUseTopic(user))
|
||||
pref.set_biological_gender(new_gender)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
return data
|
||||
|
||||
else if(href_list["id_gender"])
|
||||
var/new_gender = tgui_input_list(user, "Choose your character's pronouns:", "Character Preference", pronoun_set_to_genders, genders_to_pronoun_set[pref.identifying_gender])
|
||||
if(new_gender && CanUseTopic(user))
|
||||
pref.identifying_gender = pronoun_set_to_genders[new_gender]
|
||||
return TOPIC_REFRESH
|
||||
/datum/category_item/player_setup_item/general/basic/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
else if(href_list["age"])
|
||||
var/min_age = get_min_age()
|
||||
var/max_age = get_max_age()
|
||||
var/new_age = tgui_input_number(user, "Choose your character's age:\n([min_age]-[max_age])", "Character Preference", pref.read_preference(/datum/preference/numeric/human/age), max_age, min_age)
|
||||
if(new_age && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/age, max(min(round(text2num(new_age)), max_age), min_age))
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/raw_name = tgui_input_text(user, "Choose your character's name:", "Character Name", pref.real_name)
|
||||
if(!isnull(raw_name))
|
||||
var/new_name = sanitize_name(raw_name, pref.species, is_FBP())
|
||||
if(new_name)
|
||||
pref.real_name = new_name
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if("random_name")
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["bday_month"])
|
||||
var/new_month = tgui_input_number(user, "Choose your character's birth month (number)", "Birthday Month", pref.read_preference(/datum/preference/numeric/human/bday_month), 12, 0)
|
||||
if(new_month && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, new_month)
|
||||
else if((tgui_alert(user, "Would you like to clear the birthday entry?","Clear?",list("No","Yes")) == "Yes") && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, 0)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, 0)
|
||||
return TOPIC_REFRESH
|
||||
if("always_random_name")
|
||||
pref.update_preference_by_type(/datum/preference/toggle/human/name_is_always_random, !pref.read_preference(/datum/preference/toggle/human/name_is_always_random))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["bday_day"])
|
||||
if(!pref.read_preference(/datum/preference/numeric/human/bday_month))
|
||||
tgui_alert(user,"You must set a birth month before you can set a day.", "Error", list("Okay"))
|
||||
return
|
||||
var/max_days
|
||||
switch(pref.read_preference(/datum/preference/numeric/human/bday_month))
|
||||
if(1)
|
||||
max_days = 31
|
||||
if(2)
|
||||
max_days = 29
|
||||
if(3)
|
||||
max_days = 31
|
||||
if(4)
|
||||
max_days = 30
|
||||
if(5)
|
||||
max_days = 31
|
||||
if(6)
|
||||
max_days = 30
|
||||
if(7)
|
||||
max_days = 31
|
||||
if(8)
|
||||
max_days = 31
|
||||
if(9)
|
||||
max_days = 30
|
||||
if(10)
|
||||
max_days = 31
|
||||
if(11)
|
||||
max_days = 30
|
||||
if(12)
|
||||
max_days = 31
|
||||
if("nickname")
|
||||
var/raw_nickname = tgui_input_text(user, "Choose your character's nickname:", "Character Nickname", pref.nickname)
|
||||
if(!isnull(raw_nickname))
|
||||
var/new_nickname = sanitize_name(raw_nickname, pref.species, is_FBP())
|
||||
if(new_nickname)
|
||||
pref.nickname = new_nickname
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
var/new_day = tgui_input_number(user, "Choose your character's birth day (number, 1-[max_days])", "Birthday Day", pref.read_preference(/datum/preference/numeric/human/bday_day), max_days, 0)
|
||||
if(new_day && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, new_day)
|
||||
else if((tgui_alert(user, "Would you like to clear the birthday entry?","Clear?",list("No","Yes")) == "Yes") && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, 0)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, 0)
|
||||
return TOPIC_REFRESH
|
||||
if("reset_nickname")
|
||||
var/nick_choice = tgui_alert(user, "Wipe your Nickname? This will completely remove any chosen nickname(s).","Wipe Nickname",list("Yes","No"))
|
||||
if(nick_choice == "Yes")
|
||||
pref.nickname = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["bday_announce"])
|
||||
pref.update_preference_by_type(/datum/preference/toggle/human/bday_announce, !pref.read_preference(/datum/preference/toggle/human/bday_announce))
|
||||
return TOPIC_REFRESH
|
||||
if("bio_gender")
|
||||
var/new_gender = lowertext(params["gender"])
|
||||
if(new_gender in get_genders())
|
||||
pref.set_biological_gender(new_gender)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["spawnpoint"])
|
||||
var/list/spawnkeys = list()
|
||||
for(var/spawntype in spawntypes)
|
||||
spawnkeys += spawntype
|
||||
var/choice = tgui_input_list(user, "Where would you like to spawn when late-joining?", "Late-Join Choice", spawnkeys)
|
||||
if(!choice || !spawntypes[choice] || !CanUseTopic(user)) return TOPIC_NOACTION
|
||||
pref.update_preference_by_type(/datum/preference/choiced/living/spawnpoint, choice)
|
||||
return TOPIC_REFRESH
|
||||
if("id_gender")
|
||||
var/new_gender = lowertext(params["gender"])
|
||||
if(new_gender in all_genders_define_list)
|
||||
pref.identifying_gender = new_gender
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("age")
|
||||
var/min_age = get_min_age()
|
||||
var/max_age = get_max_age()
|
||||
var/new_age = tgui_input_number(user, "Choose your character's age:\n([min_age]-[max_age])", "Character Preference", pref.read_preference(/datum/preference/numeric/human/age), max_age, min_age)
|
||||
if(new_age)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/age, max(min(round(text2num(new_age)), max_age), min_age))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("bday_month")
|
||||
var/new_month = tgui_input_number(user, "Choose your character's birth month (number)", "Birthday Month", pref.read_preference(/datum/preference/numeric/human/bday_month), 12, 0)
|
||||
if(new_month)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, new_month)
|
||||
else if((tgui_alert(user, "Would you like to clear the birthday entry?","Clear?",list("No","Yes")) == "Yes"))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, 0)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, 0)
|
||||
|
||||
if("bday_day")
|
||||
if(!pref.read_preference(/datum/preference/numeric/human/bday_month))
|
||||
tgui_alert(user,"You must set a birth month before you can set a day.", "Error", list("Okay"))
|
||||
return
|
||||
var/max_days
|
||||
switch(pref.read_preference(/datum/preference/numeric/human/bday_month))
|
||||
if(1)
|
||||
max_days = 31
|
||||
if(2)
|
||||
max_days = 29
|
||||
if(3)
|
||||
max_days = 31
|
||||
if(4)
|
||||
max_days = 30
|
||||
if(5)
|
||||
max_days = 31
|
||||
if(6)
|
||||
max_days = 30
|
||||
if(7)
|
||||
max_days = 31
|
||||
if(8)
|
||||
max_days = 31
|
||||
if(9)
|
||||
max_days = 30
|
||||
if(10)
|
||||
max_days = 31
|
||||
if(11)
|
||||
max_days = 30
|
||||
if(12)
|
||||
max_days = 31
|
||||
|
||||
var/new_day = tgui_input_number(user, "Choose your character's birth day (number, 1-[max_days])", "Birthday Day", pref.read_preference(/datum/preference/numeric/human/bday_day), max_days, 0)
|
||||
if(new_day)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, new_day)
|
||||
else if((tgui_alert(user, "Would you like to clear the birthday entry?","Clear?",list("No","Yes")) == "Yes"))
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_month, 0)
|
||||
pref.update_preference_by_type(/datum/preference/numeric/human/bday_day, 0)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("bday_announce")
|
||||
pref.update_preference_by_type(/datum/preference/toggle/human/bday_announce, !pref.read_preference(/datum/preference/toggle/human/bday_announce))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("spawnpoint")
|
||||
var/list/spawnkeys = list()
|
||||
for(var/spawntype in spawntypes)
|
||||
spawnkeys += spawntype
|
||||
var/choice = tgui_input_list(user, "Where would you like to spawn when late-joining?", "Late-Join Choice", spawnkeys)
|
||||
if(!choice || !spawntypes[choice])
|
||||
return TOPIC_NOACTION
|
||||
pref.update_preference_by_type(/datum/preference/choiced/living/spawnpoint, choice)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("edit_ooc_notes")
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see, such as Roleplay-preferences. This will not be saved permanently unless you click save in the Character Setup panel!", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata)
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes, new_metadata)
|
||||
|
||||
if("edit_ooc_note_favs")
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your FAVOURITE roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_favs)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata)
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_favs, new_metadata)
|
||||
|
||||
if("edit_ooc_note_likes")
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your LIKED roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_likes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata)
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_likes, new_metadata)
|
||||
|
||||
if("edit_ooc_note_maybes")
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your MAYBE roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_maybes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_maybes, new_metadata)
|
||||
|
||||
if("edit_ooc_note_dislikes")
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your DISLIKED roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_dislikes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata)
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_dislikes, new_metadata)
|
||||
|
||||
if("edit_ooc_note_style")
|
||||
pref.update_preference_by_type(/datum/preference/toggle/living/ooc_notes_style, !pref.read_preference(/datum/preference/toggle/living/ooc_notes_style))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("vore_egg_type")
|
||||
var/list/vore_egg_types = GLOB.global_vore_egg_types
|
||||
var/selection = tgui_input_list(user, "Choose your character's egg type:", "Character Preference", vore_egg_types, pref.vore_egg_type)
|
||||
if(selection)
|
||||
pref.vore_egg_type = selection
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("autohiss")
|
||||
var/list/autohiss_selection = list("Full", "Basic", "Off")
|
||||
var/selection = tgui_input_list(user, "Choose your default autohiss setting:", "Character Preference", autohiss_selection, pref.autohiss)
|
||||
if(selection)
|
||||
pref.autohiss = selection
|
||||
else if(!selection)
|
||||
pref.autohiss = "Full"
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("emote_sound_mode")
|
||||
var/datum/preference/choiced/living/emote_sound_mode = GLOB.preference_entries_by_key["emote_sound_mode"]
|
||||
var/selection = tgui_input_list(user, "Choose your emote sound mode", "Emote Sound Mode", emote_sound_mode.get_choices())
|
||||
if(selection)
|
||||
pref.update_preference(emote_sound_mode, selection)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["edit_ooc_notes"])
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see, such as Roleplay-preferences. This will not be saved permanently unless you click save in the Character Setup panel!", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes, new_metadata)
|
||||
else if(href_list["edit_ooc_note_likes"])
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your LIKED roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_likes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_likes, new_metadata)
|
||||
else if(href_list["edit_ooc_note_dislikes"])
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your DISLIKED roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_dislikes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_dislikes, new_metadata)
|
||||
else if(href_list["edit_ooc_note_favs"])
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your FAVOURITE roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_favs)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_favs, new_metadata)
|
||||
else if(href_list["edit_ooc_note_maybes"])
|
||||
var/new_metadata = strip_html_simple(tgui_input_text(user, "Enter any information you'd like others to see relating to your MAYBE roleplay preferences. This will not be saved permanently unless you click save in the Character Setup panel! Type \"!clear\" to empty.", "Game Preference" , html_decode(pref.read_preference(/datum/preference/text/living/ooc_notes_maybes)), multiline = TRUE, prevent_enter = TRUE))
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
if(new_metadata == "!clear")
|
||||
new_metadata = ""
|
||||
pref.update_preference_by_type(/datum/preference/text/living/ooc_notes_maybes, new_metadata)
|
||||
else if(href_list["edit_ooc_note_style"])
|
||||
pref.update_preference_by_type(/datum/preference/toggle/living/ooc_notes_style, !pref.read_preference(/datum/preference/toggle/living/ooc_notes_style))
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/proc/get_genders()
|
||||
@@ -232,3 +303,7 @@
|
||||
possible_genders = possible_genders.Copy()
|
||||
possible_genders |= NEUTER
|
||||
return possible_genders
|
||||
|
||||
#undef AUTOHISS_OFF
|
||||
#undef AUTOHISS_BASIC
|
||||
#undef AUTOHISS_FULL
|
||||
|
||||
@@ -68,42 +68,59 @@
|
||||
|
||||
pref.runechat_color = sanitize_hexcolor(pref.runechat_color, COLOR_BLACK)
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/content()
|
||||
. += span_bold("Languages") + "<br>"
|
||||
/datum/category_item/player_setup_item/general/language/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/languages_list = list()
|
||||
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
if(pref.alternate_languages.len > (S.num_alternate_languages + pref.extra_languages))
|
||||
testing("LANGSANI: Truncated [pref.client]'s character [pref.real_name || "-name not yet loaded-"] language list because it was too long (len: [pref.alternate_languages.len], allowed: [S.num_alternate_languages])")
|
||||
pref.alternate_languages.len = (S.num_alternate_languages + pref.extra_languages) // Truncate to allowed length
|
||||
if(S.language)
|
||||
. += "- [S.language] - <a href='byond://?src=\ref[src];set_custom_key=[S.language]'>Set Custom Key</a><br>"
|
||||
UNTYPED_LIST_ADD(languages_list, list(
|
||||
"name" = S.language,
|
||||
"removable" = FALSE
|
||||
))
|
||||
if(S.default_language && S.default_language != S.language)
|
||||
. += "- [S.default_language] - <a href='byond://?src=\ref[src];set_custom_key=[S.default_language]'>Set Custom Key</a><br>"
|
||||
if(S.num_alternate_languages + pref.extra_languages)
|
||||
if(pref.alternate_languages.len)
|
||||
for(var/i = 1 to pref.alternate_languages.len)
|
||||
var/lang = pref.alternate_languages[i]
|
||||
. += "- [lang] - <a href='byond://?src=\ref[src];remove_language=[i]'>remove</a> - <a href='byond://?src=\ref[src];set_custom_key=[lang]'>Set Custom Key</a><br>"
|
||||
UNTYPED_LIST_ADD(languages_list, list(
|
||||
"name" = S.default_language,
|
||||
"removable" = FALSE
|
||||
))
|
||||
for(var/lang in pref.alternate_languages)
|
||||
UNTYPED_LIST_ADD(languages_list, list(
|
||||
"name" = lang,
|
||||
"removable" = TRUE
|
||||
))
|
||||
|
||||
if(pref.alternate_languages.len < (S.num_alternate_languages + pref.extra_languages))
|
||||
. += "- <a href='byond://?src=\ref[src];add_language=1'>add</a> ([(S.num_alternate_languages + pref.extra_languages) - pref.alternate_languages.len] remaining)<br>"
|
||||
else
|
||||
. += "- [pref.species] cannot choose secondary languages.<br>"
|
||||
data["languages"] = languages_list
|
||||
|
||||
. += span_bold("Language Keys") + "<br>"
|
||||
. += " [jointext(pref.language_prefixes, " ")] <a href='byond://?src=\ref[src];change_prefix=1'>Change</a> <a href='byond://?src=\ref[src];reset_prefix=1'>Reset</a><br>"
|
||||
. += span_bold("Preferred Language") + " <a href='byond://?src=\ref[src];pref_lang=1'>[pref.preferred_language]</a><br>" // VOREStation Add
|
||||
. += span_bold("Runechat Color") + " <a href='byond://?src=\ref[src];pref_runechat_color=1'>Change Runechat Color</a> [color_square(hex = pref.runechat_color)]"
|
||||
data["languages_can_add"] = LAZYLEN(pref.alternate_languages) < (S.num_alternate_languages + pref.extra_languages)
|
||||
data["language_keys"] = pref.language_prefixes
|
||||
data["preferred_language"] = pref.preferred_language
|
||||
data["runechat_color"] = pref.runechat_color
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
|
||||
switch(action)
|
||||
if("remove_language")
|
||||
var/lang_to_remove = params["lang"]
|
||||
var/index = pref.alternate_languages.Find(lang_to_remove)
|
||||
if(!index)
|
||||
return TOPIC_REFRESH
|
||||
pref.alternate_languages.Cut(index, index+1)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("add_language")
|
||||
if(pref.alternate_languages.len >= (S.num_alternate_languages + pref.extra_languages))
|
||||
tgui_alert_async(user, "You have already selected the maximum number of alternate languages for this species!")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["remove_language"])
|
||||
var/index = text2num(href_list["remove_language"])
|
||||
pref.alternate_languages.Cut(index, index+1)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["add_language"])
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
if(pref.alternate_languages.len >= (S.num_alternate_languages + pref.extra_languages))
|
||||
tgui_alert_async(user, "You have already selected the maximum number of alternate languages for this species!")
|
||||
else
|
||||
var/list/available_languages = S.secondary_langs.Copy()
|
||||
for(var/L in GLOB.all_languages)
|
||||
var/datum/language/lang = GLOB.all_languages[L]
|
||||
@@ -117,74 +134,73 @@
|
||||
|
||||
if(!available_languages.len)
|
||||
tgui_alert_async(user, "There are no additional languages available to select.")
|
||||
else
|
||||
var/new_lang = tgui_input_list(user, "Select an additional language", "Character Generation", available_languages)
|
||||
if(new_lang && pref.alternate_languages.len < (S.num_alternate_languages + pref.extra_languages))
|
||||
var/datum/language/chosen_lang = GLOB.all_languages[new_lang]
|
||||
if(istype(chosen_lang))
|
||||
var/choice = tgui_alert(user, "[chosen_lang.desc]",chosen_lang.name, list("Take","Cancel"))
|
||||
if(choice != "Cancel" && pref.alternate_languages.len < (S.num_alternate_languages + pref.extra_languages))
|
||||
pref.alternate_languages |= new_lang
|
||||
return TOPIC_REFRESH
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["change_prefix"])
|
||||
var/char
|
||||
var/keys[0]
|
||||
do
|
||||
char = tgui_input_text(user, "Enter a single special character.\nYou may re-select the same characters.\nThe following characters are already in use by radio: ; : .\nThe following characters are already in use by special say commands: ! * ^", "Enter Character - [3 - keys.len] remaining")
|
||||
if(char)
|
||||
if(length(char) > 1)
|
||||
tgui_alert_async(user, "Only single characters allowed.", "Error")
|
||||
else if(char in list(";", ":", "."))
|
||||
tgui_alert_async(user, "Radio character. Rejected.", "Error")
|
||||
else if(char in list("!","*","^","-"))
|
||||
tgui_alert_async(user, "Say character. Rejected.", "Error")
|
||||
else if(contains_az09(char))
|
||||
tgui_alert_async(user, "Non-special character. Rejected.", "Error")
|
||||
else
|
||||
keys.Add(char)
|
||||
while(char && keys.len < 3)
|
||||
var/new_lang = tgui_input_list(user, "Select an additional language", "Character Generation", available_languages)
|
||||
if(new_lang && pref.alternate_languages.len < (S.num_alternate_languages + pref.extra_languages))
|
||||
var/datum/language/chosen_lang = GLOB.all_languages[new_lang]
|
||||
if(istype(chosen_lang))
|
||||
var/choice = tgui_alert(user, "[chosen_lang.desc]",chosen_lang.name, list("Take","Cancel"))
|
||||
if(choice != "Cancel" && pref.alternate_languages.len < (S.num_alternate_languages + pref.extra_languages))
|
||||
pref.alternate_languages |= new_lang
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(keys.len == 3)
|
||||
pref.language_prefixes = keys
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["reset_prefix"])
|
||||
var/list/prefixes = CONFIG_GET(str_list/language_prefixes)
|
||||
pref.language_prefixes = prefixes.Copy()
|
||||
return TOPIC_REFRESH
|
||||
if("change_prefix")
|
||||
var/char
|
||||
var/keys[0]
|
||||
do
|
||||
char = tgui_input_text(user, "Enter a single special character.\nYou may re-select the same characters.\nThe following characters are already in use by radio: ; : .\nThe following characters are already in use by special say commands: ! * ^", "Enter Character - [3 - keys.len] remaining")
|
||||
if(char)
|
||||
if(length(char) > 1)
|
||||
tgui_alert_async(user, "Only single characters allowed.", "Error")
|
||||
else if(char in list(";", ":", "."))
|
||||
tgui_alert_async(user, "Radio character. Rejected.", "Error")
|
||||
else if(char in list("!","*","^","-"))
|
||||
tgui_alert_async(user, "Say character. Rejected.", "Error")
|
||||
else if(contains_az09(char))
|
||||
tgui_alert_async(user, "Non-special character. Rejected.", "Error")
|
||||
else
|
||||
keys.Add(char)
|
||||
while(char && keys.len < 3)
|
||||
|
||||
else if(href_list["set_custom_key"])
|
||||
var/lang = href_list["set_custom_key"]
|
||||
if(!(lang in GLOB.all_languages))
|
||||
if(keys.len == 3)
|
||||
pref.language_prefixes = keys
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("reset_prefix")
|
||||
var/list/prefixes = CONFIG_GET(str_list/language_prefixes)
|
||||
pref.language_prefixes = prefixes.Copy()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
var/oldkey = ""
|
||||
for(var/key in pref.language_custom_keys)
|
||||
if(pref.language_custom_keys[key] == lang)
|
||||
oldkey = key
|
||||
break
|
||||
if("set_custom_key")
|
||||
var/lang = params["lang"]
|
||||
if(!(lang in GLOB.all_languages))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
var/char = tgui_input_text(user, "Input a language key for [lang]. Input a single space to reset.", "Language Custom Key", oldkey)
|
||||
if(length(char) != 1)
|
||||
return TOPIC_REFRESH
|
||||
else if(char == " ")
|
||||
var/oldkey = ""
|
||||
for(var/key in pref.language_custom_keys)
|
||||
if(pref.language_custom_keys[key] == lang)
|
||||
pref.language_custom_keys -= key
|
||||
oldkey = key
|
||||
break
|
||||
else if(contains_az09(char))
|
||||
if(!(char in pref.language_custom_keys))
|
||||
pref.language_custom_keys += char
|
||||
pref.language_custom_keys[char] = lang
|
||||
else
|
||||
tgui_alert_async(user, "Improper language key. Rejected.", "Error")
|
||||
|
||||
return TOPIC_REFRESH
|
||||
var/char = tgui_input_text(user, "Input a language key for [lang]. Input a single space to reset.", "Language Custom Key", oldkey)
|
||||
if(length(char) != 1)
|
||||
return TOPIC_REFRESH
|
||||
else if(char == " ")
|
||||
for(var/key in pref.language_custom_keys)
|
||||
if(pref.language_custom_keys[key] == lang)
|
||||
pref.language_custom_keys -= key
|
||||
break
|
||||
else if(contains_az09(char))
|
||||
if(!(char in pref.language_custom_keys))
|
||||
pref.language_custom_keys += char
|
||||
pref.language_custom_keys[char] = lang
|
||||
else
|
||||
tgui_alert_async(user, "Improper language key. Rejected.", "Error")
|
||||
|
||||
// VOREStation Add: Preferred Language
|
||||
else if(href_list["pref_lang"])
|
||||
if(pref.species) // Safety to prevent a null runtime here
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("pref_lang")
|
||||
var/list/lang_opts = list(S.language) + pref.alternate_languages + LANGUAGE_GALCOM
|
||||
var/selection = tgui_input_list(user, "Choose your preferred spoken language:", "Preferred Spoken Language", lang_opts, pref.preferred_language)
|
||||
if(!selection) // Set our preferred to default, just in case.
|
||||
@@ -196,19 +212,15 @@
|
||||
else // Did they set anything else?
|
||||
tgui_alert_async(user, "You will now speak [pref.preferred_language] if you do not specify a language when speaking.", "Preferred Language Set")
|
||||
return TOPIC_REFRESH
|
||||
// VOREStation Add End
|
||||
|
||||
else if(href_list["pref_runechat_color"])
|
||||
var/new_runechat_color = tgui_color_picker(user, "Choose your character's runechat colour (#000000 for random):", "Character Preference", pref.runechat_color)
|
||||
if(new_runechat_color && CanUseTopic(user))
|
||||
pref.runechat_color = new_runechat_color
|
||||
// whenever we change this, we update our mob
|
||||
var/mob/pref_mob = preference_mob()
|
||||
if(pref_mob)
|
||||
pref_mob.chat_color = new_runechat_color
|
||||
pref_mob.chat_color_darkened = new_runechat_color
|
||||
pref_mob.chat_color_name = pref_mob.name
|
||||
return TOPIC_REFRESH
|
||||
|
||||
|
||||
return ..()
|
||||
if("pref_runechat_color")
|
||||
var/new_runechat_color = tgui_color_picker(user, "Choose your character's runechat colour (#000000 for random):", "Character Preference", pref.runechat_color)
|
||||
if(new_runechat_color)
|
||||
pref.runechat_color = new_runechat_color
|
||||
// whenever we change this, we update our mob
|
||||
var/mob/pref_mob = preference_mob()
|
||||
if(pref_mob)
|
||||
pref_mob.chat_color = new_runechat_color
|
||||
pref_mob.chat_color_darkened = new_runechat_color
|
||||
pref_mob.chat_color_name = pref_mob.name
|
||||
return TOPIC_REFRESH
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,130 +43,133 @@
|
||||
character.personal_faction = pref.faction
|
||||
character.religion = pref.religion
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/content(var/mob/user)
|
||||
. += span_bold("Background Information") + "<br>"
|
||||
. += "Economic Status: <a href='byond://?src=\ref[src];econ_status=1'>[pref.economic_status]</a><br/>"
|
||||
. += "Home: <a href='byond://?src=\ref[src];home_system=1'>[pref.home_system]</a><br/>"
|
||||
. += "Birthplace: <a href='byond://?src=\ref[src];birthplace=1'>[pref.birthplace]</a><br/>"
|
||||
. += "Citizenship: <a href='byond://?src=\ref[src];citizenship=1'>[pref.citizenship]</a><br/>"
|
||||
. += "Faction: <a href='byond://?src=\ref[src];faction=1'>[pref.faction]</a><br/>"
|
||||
. += "Religion: <a href='byond://?src=\ref[src];religion=1'>[pref.religion]</a><br/>"
|
||||
/datum/category_item/player_setup_item/general/background/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["economic_status"] = pref.economic_status
|
||||
data["home_system"] = pref.home_system
|
||||
data["birthplace"] = pref.birthplace
|
||||
data["citizenship"] = pref.citizenship
|
||||
data["faction"] = pref.faction
|
||||
data["religion"] = pref.religion
|
||||
data["ooc_note_style"] = pref.read_preference(/datum/preference/toggle/living/ooc_notes_style)
|
||||
|
||||
. += "<br/><b>Records</b>:<br/>"
|
||||
if(jobban_isbanned(user, "Records"))
|
||||
. += span_danger("You are banned from using character records.") + "<br>"
|
||||
data["records_banned"] = TRUE
|
||||
else
|
||||
. += "Medical Records:<br>"
|
||||
. += "<a href='byond://?src=\ref[src];set_medical_records=1'>[TextPreview(pref.med_record,40)]</a><br>"
|
||||
. += " (<a href='byond://?src=\ref[src];reset_medrecord=1'>Reset</A>)<br><br>"
|
||||
. += "Employment Records:<br>"
|
||||
. += "<a href='byond://?src=\ref[src];set_general_records=1'>[TextPreview(pref.gen_record,40)]</a><br>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_emprecord=1'>Reset</A>)<br><br>"
|
||||
. += "Security Records:<br>"
|
||||
. += "<a href='byond://?src=\ref[src];set_security_records=1'>[TextPreview(pref.sec_record,40)]</a><br>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_secrecord=1'>Reset</A>)"
|
||||
data["records_banned"] = FALSE
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["econ_status"])
|
||||
var/new_class = tgui_input_list(user, "Choose your economic status. This will affect the amount of money you will start with.", "Character Preference", ECONOMIC_CLASS, pref.economic_status)
|
||||
if(new_class && CanUseTopic(user))
|
||||
pref.economic_status = new_class
|
||||
data["med_record"] = TextPreview(pref.med_record,40)
|
||||
data["gen_record"] = TextPreview(pref.gen_record,40)
|
||||
data["sec_record"] = TextPreview(pref.sec_record,40)
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/background/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
switch(action)
|
||||
if("econ_status")
|
||||
var/new_class = tgui_input_list(user, "Choose your economic status. This will affect the amount of money you will start with.", "Character Preference", ECONOMIC_CLASS, pref.economic_status)
|
||||
if(new_class)
|
||||
pref.economic_status = new_class
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("home_system")
|
||||
var/choice = tgui_input_list(user, "Please choose your home planet and/or system. This should be your current primary residence. Select \"Other\" to specify manually.", "Character Preference", home_system_choices + list("Unset","Other"), pref.home_system)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a home system.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.home_system = raw_choice
|
||||
else
|
||||
pref.home_system = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["home_system"])
|
||||
var/choice = tgui_input_list(user, "Please choose your home planet and/or system. This should be your current primary residence. Select \"Other\" to specify manually.", "Character Preference", home_system_choices + list("Unset","Other"), pref.home_system)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a home system.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice && CanUseTopic(user))
|
||||
pref.home_system = raw_choice
|
||||
else
|
||||
pref.home_system = choice
|
||||
return TOPIC_REFRESH
|
||||
if("birthplace")
|
||||
var/choice = tgui_input_list(user, "Please choose the planet and/or system or other appropriate location that you were born/created. Select \"Other\" to specify manually.", "Character Preference", home_system_choices + list("Unset","Other"), pref.birthplace)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a birthplace.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.birthplace = raw_choice
|
||||
else
|
||||
pref.birthplace = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["birthplace"])
|
||||
var/choice = tgui_input_list(user, "Please choose the planet and/or system or other appropriate location that you were born/created. Select \"Other\" to specify manually.", "Character Preference", home_system_choices + list("Unset","Other"), pref.birthplace)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a birthplace.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice && CanUseTopic(user))
|
||||
pref.birthplace = raw_choice
|
||||
else
|
||||
pref.birthplace = choice
|
||||
return TOPIC_REFRESH
|
||||
if("citizenship")
|
||||
var/choice = tgui_input_list(user, "Please select the faction or political entity with which you currently hold citizenship. Select \"Other\" to specify manually.", "Character Preference", citizenship_choices + list("None","Other"), pref.citizenship)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter your current citizenship.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.citizenship = raw_choice
|
||||
else
|
||||
pref.citizenship = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["citizenship"])
|
||||
var/choice = tgui_input_list(user, "Please select the faction or political entity with which you currently hold citizenship. Select \"Other\" to specify manually.", "Character Preference", citizenship_choices + list("None","Other"), pref.citizenship)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter your current citizenship.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice && CanUseTopic(user))
|
||||
pref.citizenship = raw_choice
|
||||
else
|
||||
pref.citizenship = choice
|
||||
return TOPIC_REFRESH
|
||||
if("faction")
|
||||
var/choice = tgui_input_list(user, "Please choose the faction you primarily work for, if you are not under the direct employ of NanoTrasen. Select \"Other\" to specify manually.", "Character Preference", faction_choices + list("None","Other"), pref.faction)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a faction.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.faction = raw_choice
|
||||
else
|
||||
pref.faction = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["faction"])
|
||||
var/choice = tgui_input_list(user, "Please choose the faction you primarily work for, if you are not under the direct employ of NanoTrasen. Select \"Other\" to specify manually.", "Character Preference", faction_choices + list("None","Other"), pref.faction)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a faction.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.faction = raw_choice
|
||||
else
|
||||
pref.faction = choice
|
||||
return TOPIC_REFRESH
|
||||
if("religion")
|
||||
var/choice = tgui_input_list(user, "Please choose a religion. Select \"Other\" to specify manually.", "Character Preference", religion_choices + list("None","Other"), pref.religion)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a religon.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.religion = sanitize(raw_choice)
|
||||
else
|
||||
pref.religion = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["religion"])
|
||||
var/choice = tgui_input_list(user, "Please choose a religion. Select \"Other\" to specify manually.", "Character Preference", religion_choices + list("None","Other"), pref.religion)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = strip_html_simple(tgui_input_text(user, "Please enter a religon.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.religion = sanitize(raw_choice)
|
||||
else
|
||||
pref.religion = choice
|
||||
return TOPIC_REFRESH
|
||||
if("set_medical_records")
|
||||
var/new_medical = strip_html_simple(tgui_input_text(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(new_medical && !jobban_isbanned(user, JOB_RECORDS))
|
||||
pref.med_record = new_medical
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["set_medical_records"])
|
||||
var/new_medical = strip_html_simple(tgui_input_text(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(new_medical && !jobban_isbanned(user, JOB_RECORDS) && CanUseTopic(user))
|
||||
pref.med_record = new_medical
|
||||
return TOPIC_REFRESH
|
||||
if("set_general_records")
|
||||
var/new_general = strip_html_simple(tgui_input_text(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(new_general && !jobban_isbanned(user, JOB_RECORDS))
|
||||
pref.gen_record = new_general
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["set_general_records"])
|
||||
var/new_general = strip_html_simple(tgui_input_text(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(new_general && !jobban_isbanned(user, JOB_RECORDS) && CanUseTopic(user))
|
||||
pref.gen_record = new_general
|
||||
return TOPIC_REFRESH
|
||||
if("set_security_records")
|
||||
var/sec_medical = strip_html_simple(tgui_input_text(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(sec_medical && !jobban_isbanned(user, JOB_RECORDS))
|
||||
pref.sec_record = sec_medical
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["set_security_records"])
|
||||
var/sec_medical = strip_html_simple(tgui_input_text(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH)
|
||||
if(sec_medical && !jobban_isbanned(user, JOB_RECORDS) && CanUseTopic(user))
|
||||
pref.sec_record = sec_medical
|
||||
return TOPIC_REFRESH
|
||||
if("reset_medrecord")
|
||||
var/resetmed_choice = tgui_alert(user, "Wipe your Medical Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetmed_choice == "Yes")
|
||||
pref.med_record = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_medrecord"])
|
||||
var/resetmed_choice = tgui_alert(user, "Wipe your Medical Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetmed_choice == "Yes")
|
||||
pref.med_record = null
|
||||
return TOPIC_REFRESH
|
||||
if("reset_emprecord")
|
||||
var/resetemp_choice = tgui_alert(user, "Wipe your Employment Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetemp_choice == "Yes")
|
||||
pref.gen_record = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_emprecord"])
|
||||
var/resetemp_choice = tgui_alert(user, "Wipe your Employment Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetemp_choice == "Yes")
|
||||
pref.gen_record = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_secrecord"])
|
||||
var/resetsec_choice = tgui_alert(user, "Wipe your Security Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetsec_choice == "Yes")
|
||||
pref.sec_record = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
if("reset_secrecord")
|
||||
var/resetsec_choice = tgui_alert(user, "Wipe your Security Records? This cannot be reverted if you have not saved your character recently! You may wish to make a backup first.","Reset Records",list("Yes","No"))
|
||||
if(resetsec_choice == "Yes")
|
||||
pref.sec_record = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
@@ -50,12 +50,37 @@
|
||||
character.flavor_texts["feet"] = pref.flavor_texts["feet"]
|
||||
character.custom_link = pref.custom_link
|
||||
|
||||
/datum/category_item/player_setup_item/general/flavor/content(var/mob/user)
|
||||
. += span_bold("Flavor:") + "<br>"
|
||||
. += "<a href='byond://?src=\ref[src];flavor_text=open'>Set Flavor Text</a><br/>"
|
||||
. += "<a href='byond://?src=\ref[src];flavour_text_robot=open'>Set Robot Flavor Text</a><br/>"
|
||||
. += "<a href='byond://?src=\ref[src];custom_link=1'>Set Custom Link</a><br/>"
|
||||
/datum/category_item/player_setup_item/general/flavor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["flavor_text_length"] = LAZYLEN(pref.flavor_texts["general"])
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/flavor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("flavor_text")
|
||||
SetFlavorText(user)
|
||||
return TOPIC_HANDLED
|
||||
if("flavour_text_robot")
|
||||
SetFlavourTextRobot(user)
|
||||
return TOPIC_HANDLED
|
||||
if("custom_link")
|
||||
var/new_link = strip_html_simple(tgui_input_text(user, "Enter a link to add on to your examine text! This should be a related image link/gallery, or things like your F-list. This is not the place for memes.", "Custom Link" , html_decode(pref.custom_link), max_length = 100, encode = TRUE, prevent_enter = TRUE))
|
||||
if(new_link)
|
||||
if(length(new_link) > 100)
|
||||
to_chat(user, span_warning("Your entry is too long, it must be 100 characters or less."))
|
||||
return
|
||||
pref.custom_link = new_link
|
||||
log_admin("[user]/[user.ckey] set their custom link to [pref.custom_link]")
|
||||
|
||||
// README: This must stay for SetFlavorText to work!
|
||||
/datum/category_item/player_setup_item/general/flavor/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["flavor_text"])
|
||||
switch(href_list["flavor_text"])
|
||||
@@ -75,7 +100,6 @@
|
||||
pref.flavor_texts[href_list["flavor_text"]] = msg
|
||||
SetFlavorText(user)
|
||||
return TOPIC_HANDLED
|
||||
|
||||
else if(href_list["flavour_text_robot"])
|
||||
switch(href_list["flavour_text_robot"])
|
||||
if("open")
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism
|
||||
name = "Basic"
|
||||
sort_order = 7
|
||||
|
||||
var/datum/paiCandidate/candidate
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/load_character(list/save_data)
|
||||
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/general/basic_antagonism/save_character(list/save_data)
|
||||
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/general/basic_antagonism/load_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
candidate = new()
|
||||
var/preference_mob = preference_mob()
|
||||
if(!preference_mob)// No preference mob - this happens when we're called from client/New() before it calls ..() (via datum/preferences/New())
|
||||
spawn()
|
||||
preference_mob = preference_mob()
|
||||
if(!preference_mob)
|
||||
return
|
||||
candidate.savefile_load(preference_mob)
|
||||
return
|
||||
|
||||
candidate.savefile_load(preference_mob)
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/save_preferences(datum/json_savefile/savefile)
|
||||
if(!candidate)
|
||||
return
|
||||
|
||||
if(!preference_mob())
|
||||
return
|
||||
|
||||
candidate.savefile_save(preference_mob())
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/sanitize_character()
|
||||
if(!pref.antag_faction) pref.antag_faction = "None"
|
||||
if(!pref.antag_vis) pref.antag_vis = "Hidden"
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.exploit_record = pref.exploit_record
|
||||
character.antag_faction = pref.antag_faction
|
||||
character.antag_vis = pref.antag_vis
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["antag_faction"] = pref.antag_faction
|
||||
data["antag_vis"] = pref.antag_vis
|
||||
data["uplink_type"] = pref.read_preference(/datum/preference/choiced/uplinklocation)
|
||||
data["record_banned"] = jobban_isbanned(user, "Records")
|
||||
if(!jobban_isbanned(user, "Records"))
|
||||
data["exploitable_record"] = TextPreview(pref.exploit_record, 40)
|
||||
|
||||
if(!candidate)
|
||||
CRASH("[user] pAI prefs have a null candidate var.")
|
||||
|
||||
data["pai_name"] = candidate.name ? candidate.name : "None Set"
|
||||
data["pai_desc"] = candidate.description ? TextPreview(candidate.description, 40) : "None Set"
|
||||
data["pai_role"] = candidate.role ? TextPreview(candidate.role, 40) : "None Set"
|
||||
data["pai_comments"] = candidate.comments ? TextPreview(candidate.comments, 40) : "None Set"
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic_antagonism/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
switch(action)
|
||||
if("uplinklocation")
|
||||
var/new_uplinklocation = tgui_input_list(user, "Choose your uplink location:", "Character Preference", GLOB.uplink_locations, pref.read_preference(/datum/preference/choiced/uplinklocation))
|
||||
if(new_uplinklocation && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/choiced/uplinklocation, new_uplinklocation)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("exploitable_record")
|
||||
var/exploitmsg = sanitize(tgui_input_text(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH, extra = 0)
|
||||
if(!isnull(exploitmsg) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
|
||||
pref.exploit_record = exploitmsg
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("antagfaction")
|
||||
var/choice = tgui_input_list(user, "Please choose an antagonistic faction to work for.", "Character Preference", antag_faction_choices + list("None","Other"), pref.antag_faction)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Please enter a faction.", "Character Preference", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(raw_choice)
|
||||
pref.antag_faction = raw_choice
|
||||
else
|
||||
pref.antag_faction = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("antagvis")
|
||||
var/choice = tgui_input_list(user, "Please choose an antagonistic visibility level.", "Character Preference", antag_visiblity_choices, pref.antag_vis)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
else
|
||||
pref.antag_vis = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("option")
|
||||
var/t
|
||||
switch(params["option"])
|
||||
if("name")
|
||||
t = sanitizeName(tgui_input_text(user, "Enter a name for your pAI", "Global Preference", candidate.name, MAX_NAME_LEN), MAX_NAME_LEN, 1)
|
||||
if(t && CanUseTopic(user))
|
||||
candidate.name = t
|
||||
if("desc")
|
||||
t = tgui_input_text(user, "Enter a description for your pAI", "Global Preference", html_decode(candidate.description), multiline = TRUE, prevent_enter = TRUE)
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.description = sanitize(t)
|
||||
if("role")
|
||||
t = tgui_input_text(user, "Enter a role for your pAI", "Global Preference", html_decode(candidate.role))
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.role = sanitize(t)
|
||||
if("ooc")
|
||||
t = tgui_input_text(user, "Enter any OOC comments", "Global Preference", html_decode(candidate.comments), multiline = TRUE, prevent_enter = TRUE)
|
||||
if(!isnull(t) && CanUseTopic(user))
|
||||
candidate.comments = sanitize(t)
|
||||
return TOPIC_REFRESH
|
||||
@@ -0,0 +1,81 @@
|
||||
var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm --rastaf
|
||||
//some autodetection here.
|
||||
// Change these to 0 if the equivalent mode is disabled for whatever reason!
|
||||
"traitor" = 0, // 0
|
||||
"operative" = 0, // 1
|
||||
"changeling" = 0, // 2
|
||||
"wizard" = 0, // 3
|
||||
"malf AI" = 0, // 4
|
||||
"revolutionary" = 0, // 5
|
||||
"alien candidate" = 0, // 6
|
||||
"positronic brain" = 1, // 7
|
||||
"cultist" = 0, // 8
|
||||
"renegade" = 0, // 9
|
||||
"ninja" = 0, // 10
|
||||
"raider" = 0, // 11
|
||||
"diona" = 0, // 12
|
||||
"mutineer" = 0, // 13
|
||||
"loyalist" = 0, // 14
|
||||
"pAI candidate" = 1, // 15
|
||||
//VOREStation Add
|
||||
"lost drone" = 1, // 16
|
||||
"maint pred" = 1, // 17
|
||||
"maint lurker" = 1, // 18
|
||||
"morph" = 1, // 19
|
||||
"corgi" = 1, // 20
|
||||
"cursed sword" = 1, // 21
|
||||
"Ship Survivor" = 1, // 22
|
||||
//VOREStation Add End
|
||||
)
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy
|
||||
name = "Candidacy"
|
||||
sort_order = 8
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy/load_character(list/save_data)
|
||||
pref.be_special = save_data["be_special"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy/save_character(list/save_data)
|
||||
save_data["be_special"] = pref.be_special
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy/sanitize_character()
|
||||
pref.be_special = sanitize_integer(pref.be_special, 0, 16777215, initial(pref.be_special)) //VOREStation Edit - 24 bits of support
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("be_special")
|
||||
var/num = text2num(params["be_special"])
|
||||
pref.be_special ^= (1<<num)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
/datum/category_item/player_setup_item/general/candidacy/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["syndicate_ban"] = FALSE
|
||||
|
||||
if(jobban_isbanned(user, JOB_SYNDICATE))
|
||||
data["syndicate_ban"] = TRUE
|
||||
return
|
||||
|
||||
var/list/special_data = list()
|
||||
var/n = 0
|
||||
for(var/i in special_roles)
|
||||
if(special_roles[i])
|
||||
var/banned = FALSE
|
||||
if(jobban_isbanned(user, i) || (i == "positronic brain" && jobban_isbanned(user, JOB_AI) && jobban_isbanned(user, JOB_CYBORG)) || (i == "pAI candidate" && jobban_isbanned(user, JOB_PAI)))
|
||||
banned = TRUE
|
||||
|
||||
UNTYPED_LIST_ADD(special_data, list(
|
||||
"idx" = n,
|
||||
"name" = "Be [i]",
|
||||
"selected" = pref.be_special & (1<<n),
|
||||
"banned" = banned
|
||||
))
|
||||
n++
|
||||
data["special_roles"] = special_data
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,305 @@
|
||||
// Body weight limits on a character.
|
||||
#define WEIGHT_CHANGE_MIN 0
|
||||
#define WEIGHT_CHANGE_MAX 100
|
||||
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/size_multiplier = RESIZE_NORMAL
|
||||
// Body weight stuff.
|
||||
var/weight_vr = 137 // bodyweight of character (pounds, because I'm not doing the math again -Spades)
|
||||
var/weight_gain = 100 // Weight gain rate.
|
||||
var/weight_loss = 50 // Weight loss rate.
|
||||
var/fuzzy = 0 // Preference toggle for sharp/fuzzy icon. Default sharp.
|
||||
var/offset_override = FALSE
|
||||
var/voice_freq = 42500
|
||||
var/voice_sound = "beep-boop"
|
||||
var/custom_speech_bubble = "default"
|
||||
var/custom_footstep = "Default"
|
||||
var/species_sound = "Unset"
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/general/size
|
||||
name = "Size"
|
||||
sort_order = 9
|
||||
|
||||
/datum/category_item/player_setup_item/general/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"]
|
||||
pref.custom_footstep = save_data["custom_footstep"]
|
||||
pref.species_sound = save_data["species_sound"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/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
|
||||
save_data["custom_footstep"] = pref.custom_footstep
|
||||
save_data["species_sound"] = pref.species_sound
|
||||
|
||||
/datum/category_item/player_setup_item/general/size/sanitize_character()
|
||||
pref.weight_vr = sanitize_integer(pref.weight_vr, WEIGHT_MIN, WEIGHT_MAX, initial(pref.weight_vr))
|
||||
pref.weight_gain = sanitize_integer(pref.weight_gain, WEIGHT_CHANGE_MIN, WEIGHT_CHANGE_MAX, initial(pref.weight_gain))
|
||||
pref.weight_loss = sanitize_integer(pref.weight_loss, WEIGHT_CHANGE_MIN, WEIGHT_CHANGE_MAX, initial(pref.weight_loss))
|
||||
pref.fuzzy = sanitize_integer(pref.fuzzy, 0, 1, initial(pref.fuzzy))
|
||||
pref.offset_override = sanitize_integer(pref.offset_override, 0, 1, initial(pref.offset_override))
|
||||
if(pref.voice_freq != 0)
|
||||
pref.voice_freq = sanitize_integer(pref.voice_freq, MIN_VOICE_FREQ, MAX_VOICE_FREQ, initial(pref.fuzzy))
|
||||
if(pref.size_multiplier == null || pref.size_multiplier < RESIZE_TINY || pref.size_multiplier > RESIZE_HUGE)
|
||||
pref.size_multiplier = initial(pref.size_multiplier)
|
||||
if(!(pref.custom_speech_bubble in GLOB.selectable_speech_bubbles))
|
||||
pref.custom_speech_bubble = "default"
|
||||
if(!(pref.custom_footstep))
|
||||
pref.custom_footstep = "Default"
|
||||
if(!(pref.species_sound))
|
||||
pref.species_sound = "Unset"
|
||||
|
||||
/datum/category_item/player_setup_item/general/size/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.weight = pref.weight_vr
|
||||
character.weight_gain = pref.weight_gain
|
||||
character.weight_loss = pref.weight_loss
|
||||
character.fuzzy = pref.fuzzy
|
||||
character.offset_override = pref.offset_override
|
||||
character.voice_freq = pref.voice_freq
|
||||
character.resize(pref.size_multiplier, animate = FALSE, ignore_prefs = TRUE)
|
||||
if(!pref.voice_sound)
|
||||
character.voice_sounds_list = DEFAULT_TALK_SOUNDS
|
||||
else
|
||||
character.voice_sounds_list = get_talk_sound(pref.voice_sound)
|
||||
character.custom_speech_bubble = pref.custom_speech_bubble
|
||||
character.custom_footstep = pref.custom_footstep
|
||||
|
||||
/datum/category_item/player_setup_item/general/size/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["size_multiplier"] = round(pref.size_multiplier * 100)
|
||||
data["fuzzy"] = pref.fuzzy
|
||||
data["offset_override"] = pref.offset_override
|
||||
data["voice_freq"] = pref.voice_freq
|
||||
data["voice_sound"] = pref.voice_sound
|
||||
data["custom_speech_bubble"] = pref.custom_speech_bubble
|
||||
data["custom_footstep"] = pref.custom_footstep
|
||||
data["custom_species_sound"] = pref.species_sound
|
||||
data["weight_vr"] = pref.weight_vr
|
||||
data["weight_gain"] = pref.weight_gain
|
||||
data["weight_loss"] = pref.weight_loss
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/size/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
switch(action)
|
||||
if("size_multiplier")
|
||||
var/new_size = tgui_input_number(user, "Choose your character's size, ranging from [RESIZE_MINIMUM * 100]% to [RESIZE_MAXIMUM * 100]%", "Set Size", pref.size_multiplier * 100, RESIZE_MAXIMUM * 100, RESIZE_MINIMUM * 100)
|
||||
if (!ISINRANGE(new_size, RESIZE_MINIMUM * 100, RESIZE_MAXIMUM * 100))
|
||||
pref.size_multiplier = 1
|
||||
to_chat(user, span_notice("Invalid size."))
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(new_size)
|
||||
pref.size_multiplier = (new_size / 100)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("toggle_fuzzy")
|
||||
pref.fuzzy = pref.fuzzy ? 0 : 1;
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("toggle_offset_override")
|
||||
pref.offset_override = pref.offset_override ? 0 : 1;
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("weight")
|
||||
var/new_weight = tgui_input_number(user, "Choose your character's relative body weight.\n\
|
||||
Note: Scifi characters come in all shapes and sizes in this game, and not all follow the traditional shape of a human. Like a naga or a taur or a giant will weigh a\n\
|
||||
lot more than what this allows, or a micro will weigh a lot less. Just ignore all of that for a second and PRETEND the weight you're setting is visually for an \n\
|
||||
average human. This is the best solution we have at the moment.!\n\
|
||||
([WEIGHT_MIN]-[WEIGHT_MAX])", "Character Preference", null, WEIGHT_MAX, WEIGHT_MIN, round_value=FALSE)
|
||||
if(new_weight)
|
||||
var/unit_of_measurement = tgui_alert(user, "Is that number in pounds (lb) or kilograms (kg)?", "Confirmation", list("Pounds", "Kilograms"))
|
||||
if(!unit_of_measurement)
|
||||
return TOPIC_NOACTION
|
||||
if(unit_of_measurement == "Pounds")
|
||||
new_weight = round(text2num(new_weight),4)
|
||||
if(unit_of_measurement == "Kilograms")
|
||||
new_weight = round(2.20462*text2num(new_weight),4)
|
||||
pref.weight_vr = sanitize_integer(new_weight, WEIGHT_MIN, WEIGHT_MAX, pref.weight_vr)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("weight_gain")
|
||||
var/weight_gain_rate = tgui_input_number(user, "Choose your character's rate of weight gain between 100% \
|
||||
(full realism body fat gain) and 0% (no body fat gain).\n\
|
||||
(If you want to disable weight gain, set this to 0.01 to round it to 0%.)\
|
||||
([WEIGHT_CHANGE_MIN]-[WEIGHT_CHANGE_MAX])", "Character Preference", pref.weight_gain, WEIGHT_CHANGE_MAX, WEIGHT_CHANGE_MIN, round_value=FALSE)
|
||||
if(weight_gain_rate)
|
||||
pref.weight_gain = round(text2num(weight_gain_rate),1)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("weight_loss")
|
||||
var/weight_loss_rate = tgui_input_number(user, "Choose your character's rate of weight loss between 100% \
|
||||
(full realism body fat loss) and 0% (no body fat loss).\n\
|
||||
(If you want to disable weight loss, set this to 0.01 round it to 0%.)\
|
||||
([WEIGHT_CHANGE_MIN]-[WEIGHT_CHANGE_MAX])", "Character Preference", pref.weight_loss, WEIGHT_CHANGE_MAX, WEIGHT_CHANGE_MIN, round_value=FALSE)
|
||||
if(weight_loss_rate)
|
||||
pref.weight_loss = round(text2num(weight_loss_rate),1)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("voice_freq")
|
||||
var/list/preset_voice_freqs = list("high" = MAX_VOICE_FREQ, "middle-high" = 56250, "middle" = 42500, "middle-low"= 28750, "low" = MIN_VOICE_FREQ, "custom" = 1, "random" = 0)
|
||||
var/choice = tgui_input_list(user, "What would you like to set your voice frequency to? ([MIN_VOICE_FREQ] - [MAX_VOICE_FREQ])", "Voice Frequency", preset_voice_freqs)
|
||||
if(!choice)
|
||||
return
|
||||
choice = preset_voice_freqs[choice]
|
||||
if(choice == 0)
|
||||
pref.voice_freq = choice
|
||||
return TOPIC_REFRESH
|
||||
else if(choice == 1)
|
||||
choice = tgui_input_number(user, "Choose your character's voice frequency, ranging from [MIN_VOICE_FREQ] to [MAX_VOICE_FREQ]", "Custom Voice Frequency", null, MAX_VOICE_FREQ, MIN_VOICE_FREQ)
|
||||
if(choice > MAX_VOICE_FREQ)
|
||||
choice = MAX_VOICE_FREQ
|
||||
else if(choice < MIN_VOICE_FREQ)
|
||||
choice = MIN_VOICE_FREQ
|
||||
|
||||
pref.voice_freq = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("voice_sounds_list")
|
||||
var/choice = tgui_input_list(user, "Which set of sounds would you like to use for your character's speech sounds?", "Voice Sounds", SSsounds.talk_sound_map)
|
||||
if(!choice)
|
||||
pref.voice_sound = "beep-boop"
|
||||
else
|
||||
pref.voice_sound = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("customize_speech_bubble")
|
||||
var/choice = tgui_input_list(user, "What speech bubble style do you want to use?", "Custom Speech Bubble", GLOB.selectable_speech_bubbles)
|
||||
if(choice)
|
||||
pref.custom_speech_bubble = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("customize_footsteps")
|
||||
var/list/footstep_choice = selectable_footstep
|
||||
var/choice = tgui_input_list(user, "What footstep sounds would your character make?", "Custom Foostep Sounds", footstep_choice)
|
||||
if(choice)
|
||||
pref.custom_footstep = footstep_choice[choice]
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("voice_test")
|
||||
var/sound/S = sound(pick(SSsounds.talk_sound_map[pref.voice_sound])) // talk_sound_map returns a list of sounds
|
||||
if(S)
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 50
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("customize_species_sounds") // You shouldn't be able to see this option if you don't have the option to select a custom icon base, so we don't need to re-check for safety here.
|
||||
var/list/possible_species_sound_types = species_sound_map
|
||||
var/choice = tgui_input_list(user, "Which set of sounds would you like to use for your character's species sounds? (Cough, Sneeze, Scream, Pain, Gasp, Death)", "Species Sounds", possible_species_sound_types)
|
||||
if(choice)
|
||||
pref.species_sound = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("cough_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["cough"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["cough"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have cough sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("sneeze_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["sneeze"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["sneeze"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have sneeze sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("scream_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["scream"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["scream"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have scream sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("pain_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["pain"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["pain"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have pain sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("gasp_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["gasp"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["gasp"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have gasp sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
if("death_test")
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["death"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["death"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have death sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
|
||||
#undef WEIGHT_CHANGE_MIN
|
||||
#undef WEIGHT_CHANGE_MAX
|
||||
@@ -0,0 +1,39 @@
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/persistence_settings = PERSIST_DEFAULT // Control what if anything is persisted for this character between rounds.
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/general/persistence
|
||||
name = "Persistence"
|
||||
sort_order = 10
|
||||
|
||||
/datum/category_item/player_setup_item/general/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/general/persistence/save_character(list/save_data)
|
||||
save_data["persistence_settings"] = pref.persistence_settings
|
||||
|
||||
/datum/category_item/player_setup_item/general/persistence/sanitize_character()
|
||||
pref.persistence_settings = sanitize_integer(pref.persistence_settings, 0, (1<<(PERSIST_COUNT+1)-1), initial(pref.persistence_settings))
|
||||
|
||||
/datum/category_item/player_setup_item/general/persistence/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["persistence_settings"] = pref.persistence_settings
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/persistence/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("toggle_persist")
|
||||
var/bit = text2num(params["bit"])
|
||||
if(pref.persistence_settings & bit)
|
||||
pref.persistence_settings &= ~bit
|
||||
else
|
||||
pref.persistence_settings |= bit
|
||||
return TOPIC_REFRESH
|
||||
@@ -0,0 +1,333 @@
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/vantag_volunteer = 0 // What state I want to be in, in terms of being affected by antags.
|
||||
var/vantag_preference = VANTAG_NONE // Whether I'd like to volunteer to be an antag at some point.
|
||||
var/resleeve_lock = 0 // Whether movs should have OOC reslieving protection. Default false.
|
||||
var/resleeve_scan = 1 // Whether mob should start with a pre-spawn body scan. Default true.
|
||||
var/mind_scan = 1 // Whether mob should start with a pre-spawn mind scan. Default true.
|
||||
|
||||
var/custom_species // Custom species name, can't be changed due to it having been used in savefiles already.
|
||||
|
||||
var/custom_say = null
|
||||
var/custom_whisper = null
|
||||
var/custom_ask = null
|
||||
var/custom_exclaim = null
|
||||
|
||||
var/list/custom_heat = list()
|
||||
var/list/custom_cold = list()
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc
|
||||
name = "Misc Settings"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/load_character(list/save_data)
|
||||
pref.show_in_directory = save_data["show_in_directory"]
|
||||
pref.directory_tag = save_data["directory_tag"]
|
||||
pref.directory_gendertag = save_data["directory_gendertag"]
|
||||
pref.directory_sexualitytag = save_data["directory_sexualitytag"]
|
||||
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.resleeve_lock = save_data["resleeve_lock"]
|
||||
pref.resleeve_scan = save_data["resleeve_scan"]
|
||||
pref.mind_scan = save_data["mind_scan"]
|
||||
pref.vantag_volunteer = save_data["vantag_volunteer"]
|
||||
pref.vantag_preference = save_data["vantag_preference"]
|
||||
|
||||
pref.custom_species = save_data["custom_species"]
|
||||
|
||||
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"]
|
||||
pref.custom_heat = check_list_copy(save_data["custom_heat"])
|
||||
pref.custom_cold = check_list_copy(save_data["custom_cold"])
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/save_character(list/save_data)
|
||||
save_data["show_in_directory"] = pref.show_in_directory
|
||||
save_data["directory_tag"] = pref.directory_tag
|
||||
save_data["directory_gendertag"] = pref.directory_gendertag
|
||||
save_data["directory_sexualitytag"] = pref.directory_sexualitytag
|
||||
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["resleeve_lock"] = pref.resleeve_lock
|
||||
save_data["resleeve_scan"] = pref.resleeve_scan
|
||||
save_data["mind_scan"] = pref.mind_scan
|
||||
save_data["vantag_volunteer"] = pref.vantag_volunteer
|
||||
save_data["vantag_preference"] = pref.vantag_preference
|
||||
|
||||
save_data["custom_species"] = pref.custom_species
|
||||
|
||||
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
|
||||
save_data["custom_heat"] = check_list_copy(pref.custom_heat)
|
||||
save_data["custom_cold"] = check_list_copy(pref.custom_cold)
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.custom_species = pref.custom_species
|
||||
|
||||
character.custom_say = lowertext(trim(pref.custom_say))
|
||||
character.custom_ask = lowertext(trim(pref.custom_ask))
|
||||
character.custom_whisper = lowertext(trim(pref.custom_whisper))
|
||||
character.custom_exclaim = lowertext(trim(pref.custom_exclaim))
|
||||
character.custom_heat = pref.custom_heat
|
||||
character.custom_cold = pref.custom_cold
|
||||
|
||||
if(pref.sensorpref > 5 || pref.sensorpref < 1)
|
||||
pref.sensorpref = 5
|
||||
character.sensorpref = pref.sensorpref
|
||||
character.capture_crystal = pref.capture_crystal
|
||||
//Vore Stomach Sprite Preference
|
||||
character.recalculate_vis()
|
||||
|
||||
if(character && !istype(character,/mob/living/carbon/human/dummy))
|
||||
character.vantag_pref = pref.vantag_preference
|
||||
BITSET(character.hud_updateflag, VANTAG_HUD)
|
||||
|
||||
spawn(50)
|
||||
if(QDELETED(character) || QDELETED(pref))
|
||||
return // They might have been deleted during the wait
|
||||
if(!character.virtual_reality_mob && !(/mob/living/carbon/human/proc/perform_exit_vr in character.verbs)) //Janky fix to prevent resleeving VR avatars but beats refactoring transcore
|
||||
if(pref.resleeve_scan)
|
||||
var/datum/transhuman/body_record/BR = new()
|
||||
BR.init_from_mob(character, pref.resleeve_scan, pref.resleeve_lock)
|
||||
if(pref.mind_scan)
|
||||
var/datum/transcore_db/our_db = SStranscore.db_by_key(null)
|
||||
if(our_db)
|
||||
our_db.m_backup(character.mind,character.nif,one_time = TRUE)
|
||||
if(pref.resleeve_lock)
|
||||
character.resleeve_lock = character.ckey
|
||||
character.original_player = character.ckey
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/sanitize_character()
|
||||
pref.show_in_directory = sanitize_integer(pref.show_in_directory, 0, 1, initial(pref.show_in_directory))
|
||||
pref.directory_tag = sanitize_inlist(pref.directory_tag, GLOB.char_directory_tags, initial(pref.directory_tag))
|
||||
pref.directory_gendertag = sanitize_inlist(pref.directory_gendertag, GLOB.char_directory_gendertags, initial(pref.directory_gendertag))
|
||||
pref.directory_sexualitytag = sanitize_inlist(pref.directory_sexualitytag, GLOB.char_directory_sexualitytags, initial(pref.directory_sexualitytag))
|
||||
pref.directory_erptag = sanitize_inlist(pref.directory_erptag, GLOB.char_directory_erptags, initial(pref.directory_erptag))
|
||||
pref.sensorpref = sanitize_integer(pref.sensorpref, 1, GLOB.sensorpreflist.len, initial(pref.sensorpref))
|
||||
pref.capture_crystal = sanitize_integer(pref.capture_crystal, 0, 1, initial(pref.capture_crystal))
|
||||
pref.auto_backup_implant = sanitize_integer(pref.auto_backup_implant, 0, 1, initial(pref.auto_backup_implant))
|
||||
pref.borg_petting = sanitize_integer(pref.borg_petting, 0, 1, initial(pref.borg_petting))
|
||||
pref.resleeve_lock = sanitize_integer(pref.resleeve_lock, 0, 1, initial(pref.resleeve_lock))
|
||||
pref.resleeve_scan = sanitize_integer(pref.resleeve_scan, 0, 1, initial(pref.resleeve_scan))
|
||||
pref.mind_scan = sanitize_integer(pref.mind_scan, 0, 1, initial(pref.mind_scan))
|
||||
pref.vantag_volunteer = sanitize_integer(pref.vantag_volunteer, 0, 1, initial(pref.vantag_volunteer))
|
||||
pref.vantag_preference = sanitize_inlist(pref.vantag_preference, GLOB.vantag_choices_list, initial(pref.vantag_preference))
|
||||
|
||||
pref.custom_say = lowertext(trim(pref.custom_say))
|
||||
pref.custom_whisper = lowertext(trim(pref.custom_whisper))
|
||||
pref.custom_ask = lowertext(trim(pref.custom_ask))
|
||||
pref.custom_exclaim = lowertext(trim(pref.custom_exclaim))
|
||||
if (islist(pref.custom_heat)) //don't bother checking these for actual singular message length, they should already have been checked and it'd take too long every time it's sanitized
|
||||
if (length(pref.custom_heat) > 10)
|
||||
pref.custom_heat.Cut(11)
|
||||
else
|
||||
pref.custom_heat = list()
|
||||
if (islist(pref.custom_cold))
|
||||
if (length(pref.custom_cold) > 10)
|
||||
pref.custom_cold.Cut(11)
|
||||
else
|
||||
pref.custom_cold = list()
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["show_in_directory"] = pref.show_in_directory
|
||||
data["directory_tag"] = pref.directory_tag
|
||||
data["directory_gendertag"] = pref.directory_gendertag
|
||||
data["directory_sexualitytag"] = pref.directory_sexualitytag
|
||||
data["directory_erptag"] = pref.directory_erptag
|
||||
data["sensorpref"] = GLOB.sensorpreflist[pref.sensorpref]
|
||||
data["capture_crystal"] = pref.capture_crystal
|
||||
data["auto_backup_implant"] = pref.auto_backup_implant
|
||||
data["borg_petting"] = pref.borg_petting
|
||||
|
||||
data["resleeve_lock"] = pref.resleeve_lock
|
||||
data["resleeve_scan"] = pref.resleeve_scan
|
||||
data["mind_scan"] = pref.mind_scan
|
||||
|
||||
data["vantag_volunteer"] = pref.vantag_volunteer
|
||||
data["vantag_preference"] = GLOB.vantag_choices_list[pref.vantag_preference]
|
||||
|
||||
data["custom_species"] = pref.custom_species
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/vore_misc/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("toggle_show_in_directory")
|
||||
pref.show_in_directory = pref.show_in_directory ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("directory_tag")
|
||||
var/new_tag = tgui_input_list(user, "Pick a new Vore tag for the character directory", "Character Vore Tag", GLOB.char_directory_tags, pref.directory_tag)
|
||||
if(!new_tag)
|
||||
return
|
||||
pref.directory_tag = new_tag
|
||||
return TOPIC_REFRESH
|
||||
if("directory_gendertag")
|
||||
var/new_gendertag = tgui_input_list(user, "Pick a new Gender tag for the character directory. This is YOUR gender, not what you prefer.", "Character Gender Tag", GLOB.char_directory_gendertags, pref.directory_gendertag)
|
||||
if(!new_gendertag)
|
||||
return
|
||||
pref.directory_gendertag = new_gendertag
|
||||
return TOPIC_REFRESH
|
||||
if("directory_sexualitytag")
|
||||
var/new_sexualitytag = tgui_input_list(user, "Pick a new Sexuality/Orientation tag for the character directory", "Character Sexuality/Orientation Tag", GLOB.char_directory_sexualitytags, pref.directory_sexualitytag)
|
||||
if(!new_sexualitytag)
|
||||
return
|
||||
pref.directory_sexualitytag = new_sexualitytag
|
||||
return TOPIC_REFRESH
|
||||
if("directory_erptag")
|
||||
var/new_erptag = tgui_input_list(user, "Pick a new ERP tag for the character directory", "Character ERP Tag", GLOB.char_directory_erptags, pref.directory_erptag)
|
||||
if(!new_erptag)
|
||||
return
|
||||
pref.directory_erptag = new_erptag
|
||||
return TOPIC_REFRESH
|
||||
if("directory_ad")
|
||||
var/msg = sanitize(tgui_input_text(user,"Write your advertisement here!", "Flavor Text", html_decode(pref.directory_ad), multiline = TRUE, prevent_enter = TRUE), extra = 0) //VOREStation Edit: separating out OOC notes
|
||||
if(!msg)
|
||||
return
|
||||
pref.directory_ad = msg
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_sensor_setting")
|
||||
var/new_sensorpref = tgui_input_list(user, "Choose your character's sensor preferences:", "Character Preferences", GLOB.sensorpreflist, GLOB.sensorpreflist[pref.sensorpref])
|
||||
if (!isnull(new_sensorpref))
|
||||
pref.sensorpref = GLOB.sensorpreflist.Find(new_sensorpref)
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_capture_crystal")
|
||||
pref.capture_crystal = pref.capture_crystal ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_implant")
|
||||
pref.auto_backup_implant = pref.auto_backup_implant ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_borg_petting")
|
||||
pref.borg_petting = pref.borg_petting ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("edit_private_notes")
|
||||
var/new_metadata = sanitize(tgui_input_text(user,"Write some notes for yourself. These can be anything that is useful, whether it's character events that you want to remember or a bit of lore. Things that you would normally stick in a txt file for yourself!", "Private Notes", html_decode(pref.read_preference(/datum/preference/text/living/private_notes)), multiline = TRUE, prevent_enter = TRUE), extra = 0)
|
||||
if(new_metadata)
|
||||
pref.update_preference_by_type(/datum/preference/text/living/private_notes, new_metadata)
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_resleeve_lock")
|
||||
pref.resleeve_lock = pref.resleeve_lock ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_resleeve_scan")
|
||||
pref.resleeve_scan = pref.resleeve_scan ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_mind_scan")
|
||||
pref.mind_scan = pref.mind_scan ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_vantag_volunteer")
|
||||
pref.vantag_volunteer = pref.vantag_volunteer ? 0 : 1
|
||||
return TOPIC_REFRESH
|
||||
if("change_vantag")
|
||||
var/list/names_list = list()
|
||||
for(var/C in GLOB.vantag_choices_list)
|
||||
names_list[GLOB.vantag_choices_list[C]] = C
|
||||
|
||||
var/selection = tgui_input_list(user, "How do you want to be involved with VS Event Characters, ERP-wise? They will see this choice on you in a HUD. Event characters are admin-selected and spawned players, possibly with assigned objectives, who are obligated to respect ERP prefs and RP their actions like any other player, though it may be a slightly shorter RP if they are pressed for time or being caught.", "Event Preference", names_list)
|
||||
if(selection && selection != "Normal")
|
||||
pref.vantag_preference = names_list[selection]
|
||||
return TOPIC_REFRESH
|
||||
if("custom_say")
|
||||
var/say_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'says': [pref.real_name] says, \"Hi.\"", "Custom Say", pref.custom_say, 12), 12)
|
||||
if(say_choice)
|
||||
pref.custom_say = say_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_whisper")
|
||||
var/whisper_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'whispers': [pref.real_name] whispers, \"Hi...\"", "Custom Whisper", pref.custom_whisper, 12), 12)
|
||||
if(whisper_choice)
|
||||
pref.custom_whisper = whisper_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_ask")
|
||||
var/ask_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'asks': [pref.real_name] asks, \"Hi?\"", "Custom Ask", pref.custom_ask, 12), 12)
|
||||
if(ask_choice)
|
||||
pref.custom_ask = ask_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_exclaim")
|
||||
var/exclaim_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'exclaims', 'shouts' or 'yells': [pref.real_name] exclaims, \"Hi!\"", "Custom Exclaim", pref.custom_exclaim, 12), 12)
|
||||
if(exclaim_choice)
|
||||
pref.custom_exclaim = exclaim_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_heat")
|
||||
tgui_alert(user, "You are setting custom heat messages. These will overwrite your species' defaults. To return to defaults, click reset.")
|
||||
var/old_message = pref.custom_heat.Join("\n\n")
|
||||
var/new_message = sanitize(tgui_input_text(user,"Use double enter between messages to enter a new one. Must be at least 3 characters long, 160 characters max and up to 10 messages are allowed.","Heat Discomfort messages",old_message, multiline= TRUE, prevent_enter = TRUE), MAX_MESSAGE_LEN,0,0,0)
|
||||
if(length(new_message) > 0)
|
||||
var/list/raw_list = splittext(new_message,"\n\n")
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) < 3 || length(raw_list[i]) > 160)
|
||||
raw_list.Cut(i,i)
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
ASSERT(raw_list.len <= 10)
|
||||
pref.custom_heat = raw_list
|
||||
return TOPIC_REFRESH
|
||||
if("custom_cold")
|
||||
tgui_alert(user, "You are setting custom cold messages. These will overwrite your species' defaults. To return to defaults, click reset.")
|
||||
var/old_message = pref.custom_heat.Join("\n\n")
|
||||
var/new_message = sanitize(tgui_input_text(user,"Use double enter between messages to enter a new one. Must be at least 3 characters long, 160 characters max and up to 10 messages are allowed.","Cold Discomfort messages",old_message, multiline= TRUE, prevent_enter = TRUE), MAX_MESSAGE_LEN,0,0,0)
|
||||
if(length(new_message) > 0)
|
||||
var/list/raw_list = splittext(new_message,"\n\n")
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) < 3 || length(raw_list[i]) > 160)
|
||||
raw_list.Cut(i,i)
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
ASSERT(raw_list.len <= 10)
|
||||
pref.custom_cold = raw_list
|
||||
return TOPIC_REFRESH
|
||||
if("reset_say")
|
||||
var/say_choice = tgui_alert(user, "Reset your Custom Say Verb?","Reset Verb",list("Yes","No"))
|
||||
if(say_choice == "Yes")
|
||||
pref.custom_say = null
|
||||
return TOPIC_REFRESH
|
||||
if("reset_whisper")
|
||||
var/whisper_choice = tgui_alert(user, "Reset your Custom Whisper Verb?","Reset Verb",list("Yes","No"))
|
||||
if(whisper_choice == "Yes")
|
||||
pref.custom_whisper = null
|
||||
return TOPIC_REFRESH
|
||||
if("reset_ask")
|
||||
var/ask_choice = tgui_alert(user, "Reset your Custom Ask Verb?","Reset Verb",list("Yes","No"))
|
||||
if(ask_choice == "Yes")
|
||||
pref.custom_ask = null
|
||||
return TOPIC_REFRESH
|
||||
if("reset_exclaim")
|
||||
var/exclaim_choice = tgui_alert(user, "Reset your Custom Exclaim Verb?","Reset Verb",list("Yes","No"))
|
||||
if(exclaim_choice == "Yes")
|
||||
pref.custom_exclaim = null
|
||||
return TOPIC_REFRESH
|
||||
if("reset_cold")
|
||||
var/cold_choice = tgui_alert(user, "Reset your Custom Cold Discomfort messages?", "Reset Discomfort",list("Yes","No"))
|
||||
if(cold_choice == "Yes")
|
||||
pref.custom_cold = list()
|
||||
return TOPIC_REFRESH
|
||||
if("reset_heat")
|
||||
var/heat_choice = tgui_alert(user, "Reset your Custom Heat Discomfort messages?", "Reset Discomfort",list("Yes","No"))
|
||||
if(heat_choice == "Yes")
|
||||
pref.custom_heat = list()
|
||||
return TOPIC_REFRESH
|
||||
if("custom_species")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Input your custom species name:",
|
||||
"Character Preference", pref.custom_species, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
pref.custom_species = raw_choice
|
||||
return TOPIC_REFRESH
|
||||
@@ -0,0 +1,412 @@
|
||||
#define POSITIVE_MODE 1
|
||||
#define NEUTRAL_MODE 2
|
||||
#define NEGATIVE_MODE 3
|
||||
|
||||
var/global/list/valid_bloodreagents = list("default",REAGENT_ID_IRON,REAGENT_ID_COPPER,REAGENT_ID_PHORON,REAGENT_ID_SILVER,REAGENT_ID_GOLD,REAGENT_ID_SLIMEJELLY) //allowlist-based so people don't make their blood restored by alcohol or something really silly. use reagent IDs!
|
||||
|
||||
/datum/preferences
|
||||
var/custom_base // What to base the custom species on
|
||||
var/blood_color = "#A10808"
|
||||
|
||||
var/list/pos_traits = list() // What traits they've selected for their custom species
|
||||
var/list/neu_traits = list()
|
||||
var/list/neg_traits = list()
|
||||
|
||||
var/traits_cheating = 0 //Varedit by admins allows saving new maximums on people who apply/etc
|
||||
var/starting_trait_points = 0
|
||||
var/max_traits = MAX_SPECIES_TRAITS
|
||||
var/dirty_synth = 0 //Are you a synth
|
||||
var/gross_meatbag = 0 //Where'd I leave my Voight-Kampff test kit?
|
||||
|
||||
/datum/preferences/proc/get_custom_bases_for_species(var/new_species)
|
||||
if (!new_species)
|
||||
new_species = species
|
||||
var/list/choices
|
||||
var/datum/species/spec = GLOB.all_species[new_species]
|
||||
if (spec.selects_bodytype == SELECTS_BODYTYPE_SHAPESHIFTER)
|
||||
choices = spec.get_valid_shapeshifter_forms()
|
||||
choices = choices.Copy()
|
||||
else if (spec.selects_bodytype == SELECTS_BODYTYPE_CUSTOM)
|
||||
choices = GLOB.custom_species_bases.Copy()
|
||||
if(new_species != SPECIES_CUSTOM)
|
||||
choices = (choices | new_species)
|
||||
return choices
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/proc/get_pref_choice_from_trait(var/mob/user, var/datum/trait/trait, var/preference)
|
||||
if (!trait || !preference)
|
||||
return
|
||||
var/list/trait_prefs
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
var/list/traitlist
|
||||
switch(instance.category)
|
||||
if (1)
|
||||
traitlist = pref.pos_traits
|
||||
if (0)
|
||||
traitlist = pref.neu_traits
|
||||
if (-1)
|
||||
traitlist = pref.neg_traits
|
||||
if (!LAZYLEN(instance.has_preferences) || !(preference in instance.has_preferences) || !traitlist)
|
||||
return
|
||||
if (!LAZYLEN(traitlist[trait]))
|
||||
traitlist[trait] = instance.get_default_prefs()
|
||||
trait_prefs = traitlist[trait]
|
||||
if (!(preference in trait_prefs))
|
||||
trait_prefs[preference] = instance.default_value_for_pref(preference) //won't be called at all often
|
||||
switch(instance.has_preferences[preference][1])
|
||||
if (1) //TRAIT_PREF_TYPE_BOOLEAN
|
||||
trait_prefs[preference] = !trait_prefs[preference]
|
||||
if (2) //TRAIT_PREF_TYPE_COLOR
|
||||
var/new_color = tgui_color_picker(user, "Choose the color for this trait preference:", "Trait Preference", trait_prefs[preference])
|
||||
if (new_color)
|
||||
trait_prefs[preference] = new_color
|
||||
if (3) //TRAIT_PREF_TYPE_STRING
|
||||
var/new_string = instance.apply_sanitization_to_string(preference, tgui_input_text(user, "What should the new value be?", instance.has_preferences[preference][2], trait_prefs[preference], MAX_NAME_LEN))
|
||||
trait_prefs[preference] = new_string
|
||||
|
||||
// Definition of the stuff for Ears
|
||||
/datum/category_item/player_setup_item/general/traits
|
||||
name = "Traits"
|
||||
sort_order = 7
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/load_character(list/save_data)
|
||||
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"]
|
||||
|
||||
pref.traits_cheating = save_data["traits_cheating"]
|
||||
pref.max_traits = save_data["max_traits"]
|
||||
pref.starting_trait_points = save_data["trait_points"]
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/save_character(list/save_data)
|
||||
save_data["custom_base"] = pref.custom_base
|
||||
save_data["pos_traits"] = check_list_copy(pref.pos_traits)
|
||||
save_data["neu_traits"] = check_list_copy(pref.neu_traits)
|
||||
save_data["neg_traits"] = check_list_copy(pref.neg_traits)
|
||||
save_data["blood_color"] = pref.blood_color
|
||||
save_data["blood_reagents"] = pref.blood_reagents
|
||||
|
||||
save_data["traits_cheating"] = pref.traits_cheating
|
||||
save_data["max_traits"] = pref.max_traits
|
||||
save_data["trait_points"] = pref.starting_trait_points
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/sanitize_character()
|
||||
if(!pref.pos_traits) pref.pos_traits = list()
|
||||
if(!pref.neu_traits) pref.neu_traits = list()
|
||||
if(!pref.neg_traits) pref.neg_traits = list()
|
||||
|
||||
pref.blood_color = sanitize_hexcolor(pref.blood_color, default="#A10808")
|
||||
pref.blood_reagents = sanitize_text(pref.blood_reagents, initial(pref.blood_reagents))
|
||||
|
||||
if(!pref.traits_cheating)
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
if(S)
|
||||
pref.starting_trait_points = S.trait_points
|
||||
else
|
||||
pref.starting_trait_points = 0
|
||||
pref.max_traits = MAX_SPECIES_TRAITS
|
||||
|
||||
if(pref.organ_data[O_BRAIN]) //Checking if we have a synth on our hands, boys.
|
||||
pref.dirty_synth = 1
|
||||
pref.gross_meatbag = 0
|
||||
else
|
||||
pref.gross_meatbag = 1
|
||||
pref.dirty_synth = 0
|
||||
|
||||
// Clean up positive traits
|
||||
for(var/datum/trait/path as anything in pref.pos_traits)
|
||||
if(!(path in GLOB.positive_traits))
|
||||
pref.pos_traits -= path
|
||||
continue
|
||||
if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_positive))
|
||||
pref.pos_traits -= path
|
||||
continue
|
||||
var/take_flags = initial(path.can_take)
|
||||
if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS)))
|
||||
pref.pos_traits -= path
|
||||
//Neutral traits
|
||||
for(var/datum/trait/path as anything in pref.neu_traits)
|
||||
if(!(path in GLOB.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 GLOB.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)
|
||||
if(!(path in GLOB.negative_traits))
|
||||
pref.neg_traits -= path
|
||||
continue
|
||||
if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_negative))
|
||||
pref.neg_traits -= path
|
||||
continue
|
||||
var/take_flags = initial(path.can_take)
|
||||
if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS)))
|
||||
pref.neg_traits -= path
|
||||
|
||||
var/datum/species/selected_species = GLOB.all_species[pref.species]
|
||||
if(selected_species.selects_bodytype)
|
||||
if (!(pref.custom_base in pref.get_custom_bases_for_species()))
|
||||
pref.custom_base = SPECIES_HUMAN
|
||||
//otherwise, allowed!
|
||||
else if(!pref.custom_base || !(pref.custom_base in GLOB.custom_species_bases))
|
||||
pref.custom_base = SPECIES_HUMAN
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(character.isSynthetic()) //Checking if we have a synth on our hands, boys.
|
||||
pref.dirty_synth = 1
|
||||
pref.gross_meatbag = 0
|
||||
else
|
||||
pref.gross_meatbag = 1
|
||||
pref.dirty_synth = 0
|
||||
|
||||
var/datum/species/S = character.species
|
||||
var/datum/species/new_S = S.produceCopy(pref.pos_traits + pref.neu_traits + pref.neg_traits, character, pref.custom_base, TRUE)
|
||||
|
||||
for(var/datum/trait/T in new_S.traits)
|
||||
T.apply_pref(src)
|
||||
|
||||
//Any additional non-trait settings can be applied here
|
||||
new_S.blood_color = pref.blood_color
|
||||
if(!(pref.blood_reagents == "default"))
|
||||
new_S.blood_reagents = pref.blood_reagents
|
||||
|
||||
var/species_sounds_to_copy = pref.species_sound // What sounds are we using?
|
||||
if(species_sounds_to_copy == "Unset") // Are we unset?
|
||||
species_sounds_to_copy = select_default_species_sound(pref) // This will also grab gendered versions of the sounds, if they exist.
|
||||
|
||||
new_S.species_sounds = species_sounds_to_copy // Now we send our sounds over to the mob
|
||||
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
//Statistics for this would be nice
|
||||
var/english_traits = english_list(new_S.traits, and_text = ";", comma_text = ";")
|
||||
log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/datum/species/selected_species = GLOB.all_species[pref.species]
|
||||
data["selects_bodytype"] = selected_species.selects_bodytype
|
||||
data["custom_base"] = pref.custom_base
|
||||
data["blood_color"] = pref.blood_color
|
||||
data["blood_reagents"] = pref.blood_reagents
|
||||
|
||||
data["pos_traits"] = pref.pos_traits
|
||||
data["neu_traits"] = pref.neu_traits
|
||||
data["neg_traits"] = pref.neg_traits
|
||||
data["traits_cheating"] = pref.traits_cheating
|
||||
data["max_traits"] = pref.max_traits
|
||||
data["trait_points"] = pref.starting_trait_points
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/tgui_constant_data()
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/all_traits = list()
|
||||
for(var/path in GLOB.all_traits)
|
||||
var/datum/trait/T = GLOB.all_traits[path]
|
||||
all_traits[path] = list(
|
||||
"cost" = T.cost,
|
||||
"name" = T.name,
|
||||
"category" = T.category,
|
||||
"has_preferences" = T.has_preferences,
|
||||
)
|
||||
|
||||
data["all_traits"] = all_traits
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/general/traits/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
switch(action)
|
||||
if("custom_base")
|
||||
var/list/choices = pref.get_custom_bases_for_species()
|
||||
var/text_choice = tgui_input_list(user, "Pick an icon set for your species:","Icon Base", choices)
|
||||
if(text_choice in choices)
|
||||
pref.custom_base = text_choice
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if("blood_color")
|
||||
var/color_choice = tgui_color_picker(user, "Pick a blood color (does not apply to synths)","Blood Color",pref.blood_color)
|
||||
if(color_choice)
|
||||
pref.blood_color = sanitize_hexcolor(color_choice, default="#A10808")
|
||||
return TOPIC_REFRESH
|
||||
if("blood_reset")
|
||||
var/datum/species/spec = GLOB.all_species[pref.species]
|
||||
var/new_blood = spec.blood_color ? spec.blood_color : "#A10808"
|
||||
var/choice = tgui_alert(user, "Reset blood color to species default ([new_blood])?","Reset Blood Color",list("Reset","Cancel"))
|
||||
if(choice == "Reset")
|
||||
pref.blood_color = new_blood
|
||||
return TOPIC_REFRESH
|
||||
if("blood_reagents")
|
||||
var/new_blood_reagents = tgui_input_list(user, "Choose your character's blood restoration reagent:", "Character Preference", valid_bloodreagents)
|
||||
if(new_blood_reagents && CanUseTopic(user))
|
||||
pref.blood_reagents = new_blood_reagents
|
||||
return TOPIC_REFRESH
|
||||
if("clicked_pos_trait")
|
||||
var/datum/trait/trait = text2path(params["trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)] and regain [initial(trait.cost)] points?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.pos_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
if("clicked_neu_trait")
|
||||
var/datum/trait/trait = text2path(params["trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)]?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.neu_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
if("clicked_neg_trait")
|
||||
var/datum/trait/trait = text2path(params["trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)] and lose [initial(trait.cost)] points?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.neg_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
if("clicked_trait_pref")
|
||||
var/datum/trait/trait = text2path(params["clicked_trait_pref"])
|
||||
get_pref_choice_from_trait(user, trait, params["pref"])
|
||||
return TOPIC_REFRESH
|
||||
if("add_trait")
|
||||
var/mode = text2num(params["add_trait"])
|
||||
var/list/picklist
|
||||
var/list/mylist
|
||||
switch(mode)
|
||||
if(POSITIVE_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.positive_traits.Copy() - pref.pos_traits
|
||||
mylist = pref.pos_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_positive.Copy() - pref.pos_traits
|
||||
mylist = pref.pos_traits
|
||||
if(NEUTRAL_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.neutral_traits.Copy() - pref.neu_traits
|
||||
mylist = pref.neu_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_neutral.Copy() - pref.neu_traits
|
||||
mylist = pref.neu_traits
|
||||
if(NEGATIVE_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.negative_traits.Copy() - pref.neg_traits
|
||||
mylist = pref.neg_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_negative.Copy() - pref.neg_traits
|
||||
mylist = pref.neg_traits
|
||||
|
||||
if(isnull(picklist))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(isnull(mylist))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
var/list/nicelist = list()
|
||||
for(var/P in picklist)
|
||||
var/datum/trait/T = picklist[P]
|
||||
nicelist[T.name] = P
|
||||
|
||||
var/points_left = pref.starting_trait_points
|
||||
for(var/T in pref.pos_traits + pref.neu_traits + pref.neg_traits)
|
||||
points_left -= GLOB.traits_costs[T]
|
||||
|
||||
var/traits_left = pref.max_traits - (pref.pos_traits.len + pref.neg_traits.len)
|
||||
|
||||
var/message = "Select a trait to learn more."
|
||||
if(mode != NEUTRAL_MODE)
|
||||
message = "\[Remaining: [points_left] points, [traits_left] traits\]\n" + message
|
||||
var/title = "Traits"
|
||||
switch(mode)
|
||||
if(POSITIVE_MODE)
|
||||
title = "Positive Traits"
|
||||
if(NEUTRAL_MODE)
|
||||
title = "Neutral Traits"
|
||||
if(NEGATIVE_MODE)
|
||||
title = "Negative Traits"
|
||||
|
||||
var/trait_choice
|
||||
var/done = FALSE
|
||||
while(!done)
|
||||
trait_choice = tgui_input_list(user, message, title, nicelist)
|
||||
if(!trait_choice)
|
||||
done = TRUE
|
||||
if(trait_choice in nicelist)
|
||||
var/datum/trait/path = nicelist[trait_choice]
|
||||
var/choice = tgui_alert(user, "\[Cost:[initial(path.cost)]\] [initial(path.desc)]",initial(path.name), list("Take Trait","Go Back"))
|
||||
if(choice == "Take Trait")
|
||||
done = TRUE
|
||||
|
||||
if(!trait_choice)
|
||||
return TOPIC_REFRESH
|
||||
else if(trait_choice in nicelist)
|
||||
var/datum/trait/path = nicelist[trait_choice]
|
||||
var/datum/trait/instance = GLOB.all_traits[path]
|
||||
|
||||
var/conflict = FALSE
|
||||
|
||||
if(pref.dirty_synth && !(instance.can_take & SYNTHETICS))
|
||||
tgui_alert_async(user, "The trait you've selected can only be taken by organic characters!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(pref.gross_meatbag && !(instance.can_take & ORGANICS))
|
||||
tgui_alert_async(user, "The trait you've selected can only be taken by synthetic characters!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(pref.species in instance.banned_species)
|
||||
tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if( LAZYLEN(instance.allowed_species) && !(pref.species in instance.allowed_species))
|
||||
tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(trait_choice in (pref.pos_traits + pref.neu_traits + pref.neg_traits))
|
||||
conflict = instance.name
|
||||
|
||||
varconflict:
|
||||
for(var/P in (pref.pos_traits + pref.neu_traits + pref.neg_traits))
|
||||
var/datum/trait/instance_test = GLOB.all_traits[P]
|
||||
if(path in instance_test.excludes)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
for(var/V in instance.var_changes)
|
||||
if(V == "flags")
|
||||
continue
|
||||
if(V in instance_test.var_changes)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
for(var/V in instance.var_changes_pref)
|
||||
if(V in instance_test.var_changes_pref)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
if(conflict)
|
||||
tgui_alert_async(user, "You cannot take this trait and [conflict] at the same time. Please remove that trait, or pick another trait to add.", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
instance.apply_pref(pref)
|
||||
mylist[path] = instance.get_default_prefs()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
#undef POSITIVE_MODE
|
||||
#undef NEUTRAL_MODE
|
||||
#undef NEGATIVE_MODE
|
||||
+11
-7
@@ -6,7 +6,7 @@
|
||||
|
||||
// Definition of the stuff for NIFs
|
||||
// Magic bullshit, they're stored separately from everything else
|
||||
/datum/category_item/player_setup_item/vore/nif
|
||||
/datum/category_item/player_setup_item/general/nif
|
||||
name = "NIF Data"
|
||||
sort_order = 8
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
return
|
||||
return "data/player_saves/[copytext(ckey,1,2)]/[ckey]/nif.json"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/load_character()
|
||||
/datum/category_item/player_setup_item/general/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())
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
pref.nif_durability = save_data_file["nif_durability"]
|
||||
pref.nif_savedata = check_list_copy(save_data_file["nif_savedata"])
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/save_character()
|
||||
/datum/category_item/player_setup_item/general/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())
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
savefile.set_entry("character[pref.default_slot]", save_data_file)
|
||||
savefile.save()
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/sanitize_character()
|
||||
/datum/category_item/player_setup_item/general/nif/sanitize_character()
|
||||
if(pref.nif_path && !ispath(pref.nif_path)) //We have at least a text string that should be a path.
|
||||
pref.nif_path = text2path(pref.nif_path) //Try to convert it to a hard path.
|
||||
if(!pref.nif_path) //If we couldn't, kill it.
|
||||
@@ -51,10 +51,14 @@
|
||||
if(!islist(pref.nif_savedata))
|
||||
pref.nif_savedata = list()
|
||||
|
||||
/datum/category_item/player_setup_item/vore/nif/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
/datum/category_item/player_setup_item/general/nif/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
//If you had a NIF...
|
||||
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)
|
||||
. += span_bold("NIF:") + " [ispath(pref.nif_path) ? "Present" : "None"]"
|
||||
/datum/category_item/player_setup_item/general/nif/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["nif"] = ispath(pref.nif_path)
|
||||
|
||||
return data
|
||||
+113
-83
@@ -2,11 +2,11 @@
|
||||
var/list/all_underwear
|
||||
var/list/all_underwear_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment
|
||||
name = "Clothing"
|
||||
sort_order = 4
|
||||
/datum/category_item/player_setup_item/loadout/equipment
|
||||
name = "Equipment"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/load_character(list/save_data)
|
||||
/datum/category_item/player_setup_item/loadout/equipment/load_character(list/save_data)
|
||||
pref.all_underwear = check_list_copy(save_data["all_underwear"])
|
||||
pref.all_underwear_metadata = check_list_copy(save_data["all_underwear_metadata"])
|
||||
for(var/i in pref.all_underwear_metadata)
|
||||
@@ -19,7 +19,7 @@
|
||||
pref.shoe_hater = save_data["shoe_hater"]
|
||||
pref.no_jacket = save_data["no_jacket"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/save_character(list/save_data)
|
||||
/datum/category_item/player_setup_item/loadout/equipment/save_character(list/save_data)
|
||||
save_data["all_underwear"] = pref.all_underwear
|
||||
var/list/underwear = list()
|
||||
for(var/i in pref.all_underwear_metadata)
|
||||
@@ -61,7 +61,7 @@ var/global/list/valid_ringtones = list(
|
||||
)
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/general/equipment/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
/datum/category_item/player_setup_item/loadout/equipment/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.all_underwear.Cut()
|
||||
character.all_underwear_metadata.Cut()
|
||||
|
||||
@@ -88,9 +88,7 @@ var/global/list/valid_ringtones = list(
|
||||
pref.pdachoice = 1
|
||||
character.pdachoice = pref.pdachoice
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/sanitize_character()
|
||||
if(!islist(pref.gear)) pref.gear = list()
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/sanitize_character()
|
||||
if(!istype(pref.all_underwear))
|
||||
pref.all_underwear = list()
|
||||
|
||||
@@ -120,29 +118,53 @@ var/global/list/valid_ringtones = list(
|
||||
pref.pdachoice = sanitize_integer(pref.pdachoice, 1, pdachoicelist.len, initial(pref.pdachoice))
|
||||
pref.ringtone = sanitize(pref.ringtone, 20)
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/content()
|
||||
. = list()
|
||||
. += span_bold("Equipment:") + "<br>"
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/underwear_data = list()
|
||||
for(var/datum/category_group/underwear/UWC in global_underwear.categories)
|
||||
var/item_name = pref.all_underwear[UWC.name] ? pref.all_underwear[UWC.name] : "None"
|
||||
. += "[UWC.name]: <a href='byond://?src=\ref[src];change_underwear=[UWC.name]'><b>[item_name]</b></a>"
|
||||
var/item_name = LAZYACCESS(pref.all_underwear, UWC.name) || "None"
|
||||
|
||||
var/list/tweaks = list()
|
||||
var/datum/category_item/underwear/UWI = UWC.items_by_name[item_name]
|
||||
if(UWI)
|
||||
for(var/datum/gear_tweak/gt in UWI.tweaks)
|
||||
. += " <a href='byond://?src=\ref[src];underwear=[UWC.name];tweak=\ref[gt]'>[gt.get_contents(get_metadata(UWC.name, gt))]</a>"
|
||||
UNTYPED_LIST_ADD(tweaks, list(
|
||||
"ref" = REF(gt),
|
||||
"contents" = gt.get_contents(get_metadata(UWC.name, gt))
|
||||
))
|
||||
|
||||
. += "<br>"
|
||||
. += "Headset Type: <a href='byond://?src=\ref[src];change_headset=1'><b>[GLOB.headsetlist[pref.headset]]</b></a><br>"
|
||||
. += "Backpack Type: <a href='byond://?src=\ref[src];change_backpack=1'><b>[backbaglist[pref.backbag]]</b></a><br>"
|
||||
. += "PDA Type: <a href='byond://?src=\ref[src];change_pda=1'><b>[pdachoicelist[pref.pdachoice]]</b></a><br>"
|
||||
. += "Communicator Visibility: <a href='byond://?src=\ref[src];toggle_comm_visibility=1'><b>[(pref.communicator_visibility) ? "Yes" : "No"]</b></a><br>"
|
||||
. += "Ringtone (leave blank for job default): <a href='byond://?src=\ref[src];set_ringtone=1'><b>[pref.ringtone]</b></a><br>"
|
||||
. += "Spawn With Shoes:<a href='byond://?src=\ref[src];toggle_shoes=1'><b>[(pref.shoe_hater) ? "No" : "Yes"]</b></a><br>"
|
||||
. += "Spawn With Jacket:<a href='byond://?src=\ref[src];toggle_jacket=1'><b>[(pref.no_jacket) ? "No" : "Yes"]</b></a><br>"
|
||||
UNTYPED_LIST_ADD(underwear_data, list(
|
||||
"category" = UWC.name,
|
||||
"name" = item_name,
|
||||
"tweaks" = tweaks
|
||||
))
|
||||
data["underwear"] = underwear_data
|
||||
|
||||
return jointext(.,null)
|
||||
data["headset_type"] = GLOB.headsetlist[pref.headset]
|
||||
data["backpack_type"] = backbaglist[pref.backbag]
|
||||
data["pda_type"] = pdachoicelist[pref.pdachoice]
|
||||
data["communicator_visibility"] = pref.communicator_visibility // boolean
|
||||
data["ringtone"] = pref.ringtone
|
||||
data["shoes"] = pref.shoe_hater
|
||||
data["jacket"] = pref.no_jacket
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/proc/get_metadata(var/underwear_category, var/datum/gear_tweak/gt)
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_constant_data()
|
||||
var/list/data = ..()
|
||||
|
||||
data["headsetlist"] = GLOB.headsetlist
|
||||
data["backbaglist"] = backbaglist
|
||||
data["pdachoicelist"] = pdachoicelist
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/proc/get_metadata(var/underwear_category, var/datum/gear_tweak/gt)
|
||||
var/metadata = pref.all_underwear_metadata[underwear_category]
|
||||
if(!metadata)
|
||||
metadata = list()
|
||||
@@ -154,72 +176,80 @@ var/global/list/valid_ringtones = list(
|
||||
metadata["[gt]"] = tweak_data
|
||||
return tweak_data
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/proc/set_metadata(var/underwear_category, var/datum/gear_tweak/gt, var/new_metadata)
|
||||
/datum/category_item/player_setup_item/loadout/equipment/proc/set_metadata(var/underwear_category, var/datum/gear_tweak/gt, var/new_metadata)
|
||||
var/list/metadata = pref.all_underwear_metadata[underwear_category]
|
||||
metadata["[gt]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
/datum/category_item/player_setup_item/general/equipment/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(href_list["change_headset"])
|
||||
var/new_headset = tgui_input_list(user, "Choose your character's style of headset:", "Character Preference", GLOB.headsetlist, GLOB.headsetlist[pref.headset])
|
||||
if(!isnull(new_headset) && CanUseTopic(user))
|
||||
pref.headset = GLOB.headsetlist.Find(new_headset)
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("change_headset")
|
||||
// Takes the JS index
|
||||
var/new_headset = text2num(params["headset"]) + 1
|
||||
if(LAZYACCESS(GLOB.headsetlist, new_headset))
|
||||
pref.headset = new_headset
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_backpack")
|
||||
// Takes the JS index
|
||||
var/new_backbag = text2num(params["backbag"]) + 1
|
||||
if(LAZYACCESS(backbaglist, new_backbag))
|
||||
pref.backbag = new_backbag
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_pda")
|
||||
// Takes the JS index
|
||||
var/new_pdachoice = text2num(params["pda"]) + 1
|
||||
if(LAZYACCESS(backbaglist, new_pdachoice))
|
||||
pref.pdachoice = new_pdachoice
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_underwear")
|
||||
var/datum/category_group/underwear/UWC = LAZYACCESS(global_underwear.categories_by_name, params["underwear"])
|
||||
if(!UWC)
|
||||
return
|
||||
var/datum/category_item/underwear/selected_underwear = tgui_input_list(user, "Choose underwear:", "Character Preference", UWC.items, pref.all_underwear[UWC.name])
|
||||
if(selected_underwear)
|
||||
pref.all_underwear[UWC.name] = selected_underwear.name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if(href_list["change_backpack"])
|
||||
var/new_backbag = tgui_input_list(user, "Choose your character's style of bag:", "Character Preference", backbaglist, backbaglist[pref.backbag])
|
||||
if(!isnull(new_backbag) && CanUseTopic(user))
|
||||
pref.backbag = backbaglist.Find(new_backbag)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if("underwear_tweak")
|
||||
var/underwear = params["underwear"]
|
||||
if(!(underwear in pref.all_underwear))
|
||||
return TOPIC_NOACTION
|
||||
var/datum/gear_tweak/gt = locate(params["tweak"])
|
||||
if(!gt)
|
||||
return TOPIC_NOACTION
|
||||
var/new_metadata = gt.get_metadata(user, get_metadata(underwear, gt))
|
||||
if(new_metadata)
|
||||
set_metadata(underwear, gt, new_metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["change_pda"])
|
||||
var/new_pdachoice = tgui_input_list(user, "Choose your character's style of PDA:", "Character Preference", pdachoicelist, pdachoicelist[pref.pdachoice])
|
||||
if(!isnull(new_pdachoice) && CanUseTopic(user))
|
||||
pref.pdachoice = pdachoicelist.Find(new_pdachoice)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["change_underwear"])
|
||||
var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[href_list["change_underwear"]]
|
||||
if(!UWC)
|
||||
return
|
||||
var/datum/category_item/underwear/selected_underwear = tgui_input_list(user, "Choose underwear:", "Character Preference", UWC.items, pref.all_underwear[UWC.name])
|
||||
if(selected_underwear && CanUseTopic(user))
|
||||
pref.all_underwear[UWC.name] = selected_underwear.name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["underwear"] && href_list["tweak"])
|
||||
var/underwear = href_list["underwear"]
|
||||
if(!(underwear in pref.all_underwear))
|
||||
return TOPIC_NOACTION
|
||||
var/datum/gear_tweak/gt = locate(href_list["tweak"])
|
||||
if(!gt)
|
||||
return TOPIC_NOACTION
|
||||
var/new_metadata = gt.get_metadata(user, get_metadata(underwear, gt))
|
||||
if(new_metadata)
|
||||
set_metadata(underwear, gt, new_metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(href_list["toggle_comm_visibility"])
|
||||
if(CanUseTopic(user))
|
||||
if("toggle_comm_visibility")
|
||||
pref.communicator_visibility = !pref.communicator_visibility
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["set_ringtone"])
|
||||
var/choice = tgui_input_list(user, "Please select a ringtone. All of these choices come with an associated preset sound. Alternately, select \"Other\" to specify manually.", "Character Preference", valid_ringtones + "Other", pref.ringtone)
|
||||
if(!choice || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Please enter a custom ringtone. If this doesn't match any of the other listed choices, your PDA will use the default (\"beep\") sound.", "Character Preference", null, 20), 20)
|
||||
if(raw_choice && CanUseTopic(user))
|
||||
pref.ringtone = raw_choice
|
||||
else
|
||||
pref.ringtone = choice
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_shoes"])
|
||||
if(CanUseTopic(user))
|
||||
pref.shoe_hater = !pref.shoe_hater
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_jacket"])
|
||||
if(CanUseTopic(user))
|
||||
pref.no_jacket = !pref.no_jacket
|
||||
|
||||
if("set_ringtone")
|
||||
var/choice = tgui_input_list(user, "Please select a ringtone. All of these choices come with an associated preset sound. Alternately, select \"Other\" to specify manually.", "Character Preference", valid_ringtones + "Other", pref.ringtone)
|
||||
if(!choice)
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Please enter a custom ringtone. If this doesn't match any of the other listed choices, your PDA will use the default (\"beep\") sound.", "Character Preference", null, 20), 20)
|
||||
if(raw_choice)
|
||||
pref.ringtone = raw_choice
|
||||
else
|
||||
pref.ringtone = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
if("toggle_shoes")
|
||||
pref.shoe_hater = !pref.shoe_hater
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("toggle_jacket")
|
||||
pref.no_jacket = !pref.no_jacket
|
||||
return TOPIC_REFRESH
|
||||
@@ -0,0 +1,295 @@
|
||||
var/list/loadout_categories = list()
|
||||
var/list/gear_datums = list()
|
||||
|
||||
/datum/loadout_category
|
||||
var/category = ""
|
||||
var/list/gear = list()
|
||||
|
||||
/datum/loadout_category/New(var/cat)
|
||||
category = cat
|
||||
..()
|
||||
|
||||
/hook/startup/proc/populate_gear_list()
|
||||
|
||||
//create a list of gear datums to sort
|
||||
for(var/datum/gear/G as anything in subtypesof(/datum/gear))
|
||||
if(initial(G.type_category) == G)
|
||||
continue
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(isnull(initial(G.cost)))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!loadout_categories[use_category])
|
||||
loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = loadout_categories[use_category]
|
||||
gear_datums[use_name] = new G
|
||||
LC.gear[use_name] = gear_datums[use_name]
|
||||
|
||||
loadout_categories = sortAssoc(loadout_categories)
|
||||
for(var/loadout_category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[loadout_category]
|
||||
LC.gear = sortAssoc(LC.gear)
|
||||
return 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout
|
||||
name = "Loadout"
|
||||
sort_order = 2
|
||||
var/current_tab = "General"
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/load_character(list/save_data)
|
||||
pref.gear_list = list()
|
||||
var/all_gear = check_list_copy(save_data["gear_list"])
|
||||
for(var/i in all_gear)
|
||||
var/list/entries = check_list_copy(all_gear["[i]"])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = path2text_list(entries["[j]"])
|
||||
pref.gear_list["[i]"] = entries
|
||||
pref.gear_slot = save_data["gear_slot"]
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/save_character(list/save_data)
|
||||
var/list/all_gear = list()
|
||||
var/worn_gear = check_list_copy(pref.gear_list)
|
||||
for(var/i in worn_gear)
|
||||
var/list/entries = check_list_copy(worn_gear["[i]"])
|
||||
if(!length(entries))
|
||||
entries = check_list_copy(worn_gear[i])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = check_list_copy(entries["[j]"])
|
||||
all_gear["[i]"] = entries
|
||||
save_data["gear_list"] = all_gear
|
||||
save_data["gear_slot"] = pref.gear_slot
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/is_valid_gear(datum/gear/G, max_cost)
|
||||
if(G.whitelisted && CONFIG_GET(flag/loadout_whitelist) != LOADOUT_WHITELIST_OFF && pref.client) //VOREStation Edit.
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
|
||||
return FALSE
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(pref.client, GLOB.all_species[G.whitelisted]))
|
||||
return FALSE
|
||||
|
||||
if(max_cost && G.cost > max_cost)
|
||||
return FALSE
|
||||
if(pref.client)
|
||||
if(G.ckeywhitelist && !(pref.client_ckey in G.ckeywhitelist))
|
||||
return FALSE
|
||||
if(G.character_name && !(pref.real_name in G.character_name))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/sanitize_character()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
if(LAZYLEN(pref.gear_list) < 0)
|
||||
return
|
||||
|
||||
if(pref.gear_slot > LAZYLEN(pref.gear_list))
|
||||
pref.gear_slot = 1
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in active_gear_list)
|
||||
if(!gear_datums[gear_name])
|
||||
to_chat(preference_mob, span_warning("You cannot have the \the [gear_name]."))
|
||||
active_gear_list -= gear_name
|
||||
continue
|
||||
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(!is_valid_gear(G))
|
||||
to_chat(preference_mob, span_warning("You cannot take \the [gear_name] as you are not whitelisted for the species or item."))
|
||||
active_gear_list -= gear_name
|
||||
continue
|
||||
|
||||
if(total_cost + G.cost > MAX_GEAR_COST)
|
||||
active_gear_list -= gear_name
|
||||
to_chat(preference_mob, span_warning("You cannot afford to take \the [gear_name]"))
|
||||
continue
|
||||
total_cost += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["total_cost"] = get_total()
|
||||
data["gear_slot"] = pref.gear_slot
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
data["active_gear_list"] = active_gear_list
|
||||
|
||||
var/list/gear_tweaks = list()
|
||||
for(var/item in active_gear_list)
|
||||
var/datum/gear/G = gear_datums[item]
|
||||
var/list/tweaks = list()
|
||||
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
|
||||
UNTYPED_LIST_ADD(tweaks, list(
|
||||
"ref" = REF(tweak),
|
||||
"contents" = tweak.get_contents(get_tweak_metadata(G, tweak))
|
||||
))
|
||||
gear_tweaks[G.display_name] = tweaks
|
||||
data["gear_tweaks"] = gear_tweaks
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/categories = list()
|
||||
for(var/category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[category]
|
||||
var/list/items = list()
|
||||
for(var/gear in LC.gear)
|
||||
var/datum/gear/G = LC.gear[gear]
|
||||
if(!is_valid_gear(G))
|
||||
continue
|
||||
|
||||
UNTYPED_LIST_ADD(items, list(
|
||||
"name" = G.display_name,
|
||||
"desc" = G.description,
|
||||
"cost" = G.cost,
|
||||
"show_roles" = G.show_roles,
|
||||
"allowed_roles" = G.allowed_roles
|
||||
))
|
||||
categories[category] = items
|
||||
data["categories"] = categories
|
||||
|
||||
data["max_gear_cost"] = MAX_GEAR_COST
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_gear_metadata(var/datum/gear/G)
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
|
||||
// {"/datum/gear_tweak/custom_name": "" }
|
||||
. = LAZYACCESS(active_gear_list, G.display_name)
|
||||
if(!.)
|
||||
. = list()
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
. = metadata["[tweak]"]
|
||||
if(!.)
|
||||
. = tweak.get_default()
|
||||
metadata["[tweak]"] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/set_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak, var/new_metadata)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
metadata["[tweak]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_total()
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
. = 0
|
||||
for(var/gear_name in active_gear_list)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(G)
|
||||
. += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("next_slot")
|
||||
pref.gear_slot = pref.gear_slot + 1
|
||||
if(pref.gear_slot > CONFIG_GET(number/loadout_slots))
|
||||
pref.gear_slot = 1
|
||||
if(!("[pref.gear_slot]" in pref.gear_list))
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("prev_slot")
|
||||
pref.gear_slot = pref.gear_slot - 1
|
||||
if(pref.gear_slot <= 0)
|
||||
pref.gear_slot = CONFIG_GET(number/loadout_slots)
|
||||
if(!("[pref.gear_slot]" in pref.gear_list))
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("clear_loadout")
|
||||
active_gear_list.Cut()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("copy_loadout")
|
||||
var/copy_to = tgui_input_number(user, "What slot would you like to copy slot [pref.gear_slot] to?", "Copy Slot", 1, CONFIG_GET(number/loadout_slots), 1)
|
||||
if(!copy_to)
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if("[copy_to]" in pref.gear_list)
|
||||
var/confirm = tgui_alert(user, "This will overwrite slot [copy_to], are you sure?", "Are you sure?", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
return TOPIC_HANDLED
|
||||
|
||||
pref.gear_list["[copy_to]"] = check_list_copy(active_gear_list)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("toggle_gear")
|
||||
var/datum/gear/TG = gear_datums[params["gear"]]
|
||||
if(TG)
|
||||
if(TG.display_name in active_gear_list)
|
||||
active_gear_list -= TG.display_name
|
||||
else if(get_total() + TG.cost <= MAX_GEAR_COST)
|
||||
active_gear_list[TG.display_name] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("gear_tweak")
|
||||
var/datum/gear/gear = gear_datums[params["gear"]]
|
||||
var/datum/gear_tweak/tweak = locate(params["tweak"])
|
||||
if(!tweak || !gear || !(tweak in gear.gear_tweaks))
|
||||
return TOPIC_HANDLED
|
||||
var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak))
|
||||
if(!metadata)
|
||||
return TOPIC_HANDLED
|
||||
set_tweak_metadata(gear, tweak, metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
/datum/gear
|
||||
var/display_name //Name/index. Must be unique.
|
||||
var/description //Description of this gear. If left blank will default to the description of the pathed item.
|
||||
var/path //Path to item.
|
||||
var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
|
||||
var/slot //Slot to equip to.
|
||||
var/list/allowed_roles //Roles that can spawn with this item.
|
||||
var/show_roles = TRUE //Show the role restrictions on this item?
|
||||
var/whitelisted //Term to check the whitelist for..
|
||||
var/sort_category = "General"
|
||||
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
|
||||
var/exploitable = 0 //Does it go on the exploitable information list?
|
||||
var/type_category = null
|
||||
var/list/ckeywhitelist //restricted based on these ckeys?
|
||||
var/list/character_name //restricted to these character names?
|
||||
|
||||
/datum/gear/New()
|
||||
..()
|
||||
if(!description)
|
||||
var/obj/O = path
|
||||
description = initial(O.desc)
|
||||
gear_tweaks = list(gear_tweak_free_name, gear_tweak_free_desc, GLOB.gear_tweak_item_tf_spawn, GLOB.gear_tweak_free_matrix_recolor)
|
||||
|
||||
/datum/gear_data
|
||||
var/path
|
||||
var/location
|
||||
|
||||
/datum/gear_data/New(var/path, var/location)
|
||||
src.path = path
|
||||
src.location = location
|
||||
|
||||
/datum/gear/proc/spawn_item(var/location, var/metadata)
|
||||
var/datum/gear_data/gd = new(path, location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_gear_data(metadata["[gt]"], gd)
|
||||
var/item = new gd.path(gd.location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_item(item, metadata["[gt]"])
|
||||
var/mob/M = location
|
||||
if(istype(M) && exploitable) //Update exploitable info records for the mob without creating a duplicate object at their feet.
|
||||
M.amend_exploitable(item)
|
||||
return item
|
||||
@@ -1,304 +0,0 @@
|
||||
var/list/loadout_categories = list()
|
||||
var/list/gear_datums = list()
|
||||
|
||||
/datum/loadout_category
|
||||
var/category = ""
|
||||
var/list/gear = list()
|
||||
|
||||
/datum/loadout_category/New(var/cat)
|
||||
category = cat
|
||||
..()
|
||||
|
||||
/hook/startup/proc/populate_gear_list()
|
||||
|
||||
//create a list of gear datums to sort
|
||||
for(var/datum/gear/G as anything in subtypesof(/datum/gear))
|
||||
if(initial(G.type_category) == G)
|
||||
continue
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(isnull(initial(G.cost)))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!loadout_categories[use_category])
|
||||
loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = loadout_categories[use_category]
|
||||
gear_datums[use_name] = new G
|
||||
LC.gear[use_name] = gear_datums[use_name]
|
||||
|
||||
loadout_categories = sortAssoc(loadout_categories)
|
||||
for(var/loadout_category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[loadout_category]
|
||||
LC.gear = sortAssoc(LC.gear)
|
||||
return 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout
|
||||
name = "Loadout"
|
||||
sort_order = 1
|
||||
var/current_tab = "General"
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/load_character(list/save_data)
|
||||
pref.gear_list = list()
|
||||
var/all_gear = check_list_copy(save_data["gear_list"])
|
||||
for(var/i in all_gear)
|
||||
var/list/entries = check_list_copy(all_gear["[i]"])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = path2text_list(entries["[j]"])
|
||||
pref.gear_list["[i]"] = entries
|
||||
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
|
||||
pref.gear = check_list_copy(save_data["gear"])
|
||||
pref.gear_slot = 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/save_character(list/save_data)
|
||||
pref.gear_list["[pref.gear_slot]"] = pref.gear
|
||||
var/list/all_gear = list()
|
||||
var/worn_gear = check_list_copy(pref.gear_list)
|
||||
for(var/i in worn_gear)
|
||||
var/list/entries = check_list_copy(worn_gear["[i]"])
|
||||
if(!length(entries))
|
||||
entries = check_list_copy(worn_gear[i])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = check_list_copy(entries["[j]"])
|
||||
all_gear["[i]"] = entries
|
||||
save_data["gear_list"] = all_gear
|
||||
save_data["gear_slot"] = pref.gear_slot
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/valid_gear_choices(var/max_cost)
|
||||
. = list()
|
||||
for(var/gear_name in gear_datums)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
|
||||
if(G.whitelisted && CONFIG_GET(flag/loadout_whitelist) != LOADOUT_WHITELIST_OFF && pref.client) //VOREStation Edit.
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
|
||||
continue
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(pref.client, GLOB.all_species[G.whitelisted]))
|
||||
continue
|
||||
|
||||
if(max_cost && G.cost > max_cost)
|
||||
continue
|
||||
if(pref.client)
|
||||
if(G.ckeywhitelist && !(pref.client_ckey in G.ckeywhitelist))
|
||||
continue
|
||||
if(G.character_name && pref.client.prefs && !(pref.client.prefs.real_name in G.character_name))
|
||||
continue
|
||||
. += gear_name
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/sanitize_character()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
if(!islist(pref.gear))
|
||||
pref.gear = list()
|
||||
if(!islist(pref.gear_list))
|
||||
pref.gear_list = list()
|
||||
|
||||
for(var/gear_name in pref.gear)
|
||||
if(!(gear_name in gear_datums))
|
||||
pref.gear -= gear_name
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in pref.gear)
|
||||
if(!gear_datums[gear_name])
|
||||
to_chat(preference_mob, span_warning("You cannot have more than one of the \the [gear_name]"))
|
||||
pref.gear -= gear_name
|
||||
else if(!(gear_name in valid_gear_choices()))
|
||||
to_chat(preference_mob, span_warning("You cannot take \the [gear_name] as you are not whitelisted for the species or item.")) //Vorestation Edit
|
||||
pref.gear -= gear_name
|
||||
else
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(total_cost + G.cost > MAX_GEAR_COST)
|
||||
pref.gear -= gear_name
|
||||
to_chat(preference_mob, span_warning("You cannot afford to take \the [gear_name]"))
|
||||
else
|
||||
total_cost += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/content()
|
||||
. = list()
|
||||
var/mob/preference_mob = preference_mob() //Vorestation Edit
|
||||
var/total_cost = 0
|
||||
if(pref.gear && pref.gear.len)
|
||||
for(var/i = 1; i <= pref.gear.len; i++)
|
||||
var/datum/gear/G = gear_datums[pref.gear[i]]
|
||||
if(G)
|
||||
total_cost += G.cost
|
||||
|
||||
var/fcolor = "#3366CC"
|
||||
if(total_cost < MAX_GEAR_COST)
|
||||
fcolor = "#E67300"
|
||||
|
||||
. += "<table align = 'center' width = 100%>"
|
||||
. += "<tr><td colspan=3><center><a href='byond://?src=\ref[src];prev_slot=1'>\<\<</a>" + span_bold("<font color = '[fcolor]'>\[[pref.gear_slot]\]</font> ") + "<a href='byond://?src=\ref[src];next_slot=1'>\>\></a>" + span_bold("<font color = '[fcolor]'>[total_cost]/[MAX_GEAR_COST]</font> loadout points spent.") + " \[<a href='byond://?src=\ref[src];clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
|
||||
|
||||
. += "<tr><td colspan=3><center><b>"
|
||||
var/firstcat = 1
|
||||
for(var/category in loadout_categories)
|
||||
|
||||
if(firstcat)
|
||||
firstcat = 0
|
||||
else
|
||||
. += " |"
|
||||
|
||||
var/datum/loadout_category/LC = loadout_categories[category]
|
||||
var/category_cost = 0
|
||||
for(var/gear in LC.gear)
|
||||
if(gear in pref.gear)
|
||||
var/datum/gear/G = LC.gear[gear]
|
||||
category_cost += G.cost
|
||||
|
||||
if(category == current_tab)
|
||||
. += " " + span_linkOn("[category] - [category_cost]") + " "
|
||||
else
|
||||
if(category_cost)
|
||||
. += " <a href='byond://?src=\ref[src];select_category=[category]'><font color = '#E67300'>[category] - [category_cost]</font></a> "
|
||||
else
|
||||
. += " <a href='byond://?src=\ref[src];select_category=[category]'>[category] - 0</a> "
|
||||
. += "</b></center></td></tr>"
|
||||
|
||||
var/datum/loadout_category/LC = loadout_categories[current_tab]
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
. += "<tr><td colspan=3>" + span_bold("<center>[LC.category]</center>") + "</td></tr>"
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
for(var/gear_name in LC.gear)
|
||||
var/datum/gear/G = LC.gear[gear_name]
|
||||
if(preference_mob && preference_mob.client)
|
||||
if(G.ckeywhitelist && !(preference_mob.ckey in G.ckeywhitelist))
|
||||
continue
|
||||
if(G.character_name && preference_mob.client.prefs && !(preference_mob.client.prefs.real_name in G.character_name))
|
||||
continue
|
||||
var/ticked = (G.display_name in pref.gear)
|
||||
. += "<tr style='vertical-align:top;'><td width=25%><a style='white-space:normal;' [ticked ? "class='linkOn' " : ""]href='byond://?src=\ref[src];toggle_gear=[html_encode(G.display_name)]'>[G.display_name]</a></td>"
|
||||
. += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
|
||||
. += "<td>" + span_normal(span_italics("[G.description]")) + "</td></tr>"
|
||||
if(G.show_roles && G.allowed_roles)
|
||||
. += "<td colspan=3> Restricted to: [list2text(G.allowed_roles,", ")]</td>"
|
||||
if(ticked)
|
||||
. += "<tr><td colspan=3>"
|
||||
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
|
||||
. += " <a href='byond://?src=\ref[src];gear=[url_encode(G.display_name)];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
|
||||
. += "</td></tr>"
|
||||
. += "</table>"
|
||||
. = jointext(., null)
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/datum/gear/G)
|
||||
. = pref.gear[G.display_name]
|
||||
if(!.)
|
||||
. = list()
|
||||
pref.gear[G.display_name] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/get_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
. = metadata["[tweak]"]
|
||||
if(!.)
|
||||
. = tweak.get_default()
|
||||
metadata["[tweak]"] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/set_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak, var/new_metadata)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
metadata["[tweak]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/OnTopic(href, href_list, user)
|
||||
if(href_list["toggle_gear"])
|
||||
var/datum/gear/TG = gear_datums[href_list["toggle_gear"]]
|
||||
if(TG.display_name in pref.gear)
|
||||
pref.gear -= TG.display_name
|
||||
else
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in pref.gear)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(istype(G)) total_cost += G.cost
|
||||
if((total_cost+TG.cost) <= MAX_GEAR_COST)
|
||||
pref.gear += TG.display_name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if(href_list["gear"] && href_list["tweak"])
|
||||
var/datum/gear/gear = gear_datums[url_decode(href_list["gear"])]
|
||||
var/datum/gear_tweak/tweak = locate(href_list["tweak"])
|
||||
if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks))
|
||||
return TOPIC_NOACTION
|
||||
var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak))
|
||||
if(!metadata || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
set_tweak_metadata(gear, tweak, metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if(href_list["next_slot"] || href_list["prev_slot"])
|
||||
//Set the current slot in the gear list to the currently selected gear
|
||||
pref.gear_list["[pref.gear_slot]"] = pref.gear
|
||||
//If we're moving up a slot..
|
||||
if(href_list["next_slot"])
|
||||
//change the current slot number
|
||||
pref.gear_slot = pref.gear_slot+1
|
||||
if(pref.gear_slot > CONFIG_GET(number/loadout_slots))
|
||||
pref.gear_slot = 1
|
||||
//If we're moving down a slot..
|
||||
else if(href_list["prev_slot"])
|
||||
//change current slot one down
|
||||
pref.gear_slot = pref.gear_slot-1
|
||||
if(pref.gear_slot<1)
|
||||
pref.gear_slot = CONFIG_GET(number/loadout_slots)
|
||||
// Set the currently selected gear to whatever's in the new slot
|
||||
if(pref.gear_list["[pref.gear_slot]"])
|
||||
pref.gear = pref.gear_list["[pref.gear_slot]"]
|
||||
else
|
||||
pref.gear = list()
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
// Refresh?
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(href_list["select_category"])
|
||||
current_tab = href_list["select_category"]
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["clear_loadout"])
|
||||
pref.gear.Cut()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
return ..()
|
||||
|
||||
/datum/gear
|
||||
var/display_name //Name/index. Must be unique.
|
||||
var/description //Description of this gear. If left blank will default to the description of the pathed item.
|
||||
var/path //Path to item.
|
||||
var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
|
||||
var/slot //Slot to equip to.
|
||||
var/list/allowed_roles //Roles that can spawn with this item.
|
||||
var/show_roles = TRUE //Show the role restrictions on this item?
|
||||
var/whitelisted //Term to check the whitelist for..
|
||||
var/sort_category = "General"
|
||||
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
|
||||
var/exploitable = 0 //Does it go on the exploitable information list?
|
||||
var/type_category = null
|
||||
var/list/ckeywhitelist //restricted based on these ckeys?
|
||||
var/list/character_name //restricted to these character names?
|
||||
|
||||
/datum/gear/New()
|
||||
..()
|
||||
if(!description)
|
||||
var/obj/O = path
|
||||
description = initial(O.desc)
|
||||
gear_tweaks = list(gear_tweak_free_name, gear_tweak_free_desc, GLOB.gear_tweak_item_tf_spawn, GLOB.gear_tweak_free_matrix_recolor)
|
||||
|
||||
/datum/gear_data
|
||||
var/path
|
||||
var/location
|
||||
|
||||
/datum/gear_data/New(var/path, var/location)
|
||||
src.path = path
|
||||
src.location = location
|
||||
|
||||
/datum/gear/proc/spawn_item(var/location, var/metadata)
|
||||
var/datum/gear_data/gd = new(path, location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_gear_data(metadata["[gt]"], gd)
|
||||
var/item = new gd.path(gd.location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_item(item, metadata["[gt]"])
|
||||
var/mob/M = location
|
||||
if(istype(M) && exploitable) //Update exploitable info records for the mob without creating a duplicate object at their feet.
|
||||
M.amend_exploitable(item)
|
||||
return item
|
||||
@@ -64,26 +64,11 @@
|
||||
if(alt_title && !(alt_title in job.alt_titles))
|
||||
pref.player_alt_titles -= job.title
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/content(mob/user, limit = 25, list/splitJobs = list())
|
||||
if(!job_master)
|
||||
return
|
||||
|
||||
. = list()
|
||||
. += "<tt><center>"
|
||||
. += span_bold("Choose occupation chances") + "<br>Unavailable occupations are crossed out.<br>"
|
||||
. += "<script type='text/javascript'>function setJobPrefRedirect(level, rank) { window.location.href='byond://?src=\ref[src];level=' + level + ';set_job=' + encodeURIComponent(rank); return false; }</script>"
|
||||
. += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%' valign='top'>" // Table within a table for alignment, also allows you to easily add more columns.
|
||||
. += "<table width='100%' cellpadding='1' cellspacing='0'>"
|
||||
var/index = -1
|
||||
|
||||
//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
|
||||
var/datum/job/lastJob
|
||||
var/datum/department/last_department = null // Used to avoid repeating the look-ahead check for if a whole department can fit.
|
||||
/datum/category_item/player_setup_item/occupation/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/jobs_data = list()
|
||||
var/list/all_valid_jobs = list()
|
||||
// If the occupation window gets opened before SSJob initializes, then it'll just be blank, with no runtimes.
|
||||
// It will work once init is finished.
|
||||
|
||||
for(var/D in SSjob.department_datums)
|
||||
var/datum/department/department = SSjob.department_datums[D]
|
||||
if(department.centcom_only) // No joining as a centcom role, if any are ever added.
|
||||
@@ -92,194 +77,141 @@
|
||||
for(var/J in department.primary_jobs)
|
||||
all_valid_jobs += department.jobs[J]
|
||||
|
||||
jobs_data[department.name] = list()
|
||||
|
||||
for(var/datum/job/job in all_valid_jobs)
|
||||
if(job.latejoin_only) continue //VOREStation Code
|
||||
if(job.latejoin_only)
|
||||
continue
|
||||
var/datum/department/current_department = SSjob.get_primary_department_of_job(job)
|
||||
// for the is_job_whitelisted check..
|
||||
usr = user
|
||||
var/list/job_data = list(
|
||||
"title" = job.title,
|
||||
"ref" = REF(job),
|
||||
"selection_color" = job.selection_color,
|
||||
// reasons you can't select it
|
||||
"banned" = !!jobban_isbanned(user, job.title),
|
||||
"denylist_days" = !job.player_old_enough(user.client),
|
||||
"available_in_days" = !job.available_in_days(user.client),
|
||||
"denylist_playtime" = !job.player_has_enough_playtime(user.client),
|
||||
"available_in_hours" = job.available_in_playhours(user.client),
|
||||
"denylist_whitelist" = !is_job_whitelisted(user, job.title),
|
||||
// tigercat2000 - these shouldn't exist >:(
|
||||
"denylist_character_age" = FALSE,
|
||||
"min_age" = job.get_min_age(pref.species, pref.organ_data[O_BRAIN]),
|
||||
"special_color" = "",
|
||||
"selected" = 0,
|
||||
"selected_title" = "",
|
||||
"alt_titles" = list(),
|
||||
)
|
||||
|
||||
// Should we add a new column?
|
||||
var/make_new_column = FALSE
|
||||
if(++index > limit)
|
||||
// Ran out of rows, make a new column.
|
||||
make_new_column = TRUE
|
||||
|
||||
else if(job.title in splitJobs)
|
||||
// Is hardcoded to split at this job title.
|
||||
make_new_column = TRUE
|
||||
|
||||
else if(current_department != last_department)
|
||||
// If the department is bigger than the limit then we have to split.
|
||||
if(limit >= current_department.primary_jobs.len)
|
||||
// Look ahead to see if we would need to split, and if so, avoid it.
|
||||
if(index + current_department.primary_jobs.len > limit)
|
||||
// Looked ahead, and determined that a new column is needed to avoid splitting the department into two.
|
||||
make_new_column = TRUE
|
||||
|
||||
|
||||
if(make_new_column)
|
||||
/*******
|
||||
if((index < limit) && (lastJob != null))
|
||||
//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
|
||||
//the last job's selection color and blank buttons that do nothing. Creating a rather nice effect.
|
||||
for(var/i = 0, i < (limit - index), i++)
|
||||
. += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'>//> </a></td><td><a> </a></td></tr>"
|
||||
*******/
|
||||
. += "</table></td><td width='20%' valign='top'><table width='100%' cellpadding='1' cellspacing='0'>"
|
||||
index = 0
|
||||
last_department = current_department
|
||||
|
||||
. += "<tr bgcolor='[job.selection_color]'><td width='60%' align='right'>"
|
||||
|
||||
var/rank = job.title
|
||||
lastJob = job
|
||||
. += "<a href='byond://?src=\ref[src];job_info=[rank]'>"
|
||||
if(jobban_isbanned(user, rank))
|
||||
. += "<del>[rank]</del></td></a><td>" + span_bold(" \[BANNED]") + "</td></tr>"
|
||||
continue
|
||||
if(!job.player_old_enough(user.client))
|
||||
var/available_in_days = job.available_in_days(user.client)
|
||||
. += "<del>[rank]</del></td></a><td> \[IN [(available_in_days)] DAYS]</td></tr>"
|
||||
continue
|
||||
//VOREStation Add
|
||||
if(!job.player_has_enough_playtime(user.client))
|
||||
var/available_in_hours = job.available_in_playhours(user.client)
|
||||
. += "<del>[rank]</del></td></a><td> \[IN [round(available_in_hours, 0.1)] DEPTHOURS]</td></tr>"
|
||||
continue
|
||||
if(!is_job_whitelisted(user,rank))
|
||||
. += "<del>[rank]</del></td></a><td>" + span_bold(" \[WHITELIST ONLY]") + "</td></tr>"
|
||||
continue
|
||||
//VOREStation Add End
|
||||
if(job.is_species_banned(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN]) == TRUE)
|
||||
. += "<del>[rank]</del></td></a><td> \[THIS RACE/BRAIN TYPE CANNOT TAKE THIS ROLE.\]</td></tr>"
|
||||
continue
|
||||
if((job.minimum_character_age || job.min_age_by_species) && user.client && (user.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN])))
|
||||
. += "<del>[rank]</del></td></a><td> \[MINIMUM CHARACTER AGE FOR SELECTED RACE/BRAIN TYPE: [job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN])]\]</td></tr>"
|
||||
continue
|
||||
job_data["denylist_character_age"] = TRUE
|
||||
|
||||
if((pref.job_civilian_low & ASSISTANT) && job.type != /datum/job/assistant)
|
||||
. += span_gray("[rank]") + "</a></td><td></td></tr>"
|
||||
continue
|
||||
if((rank in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND) ) || (rank == JOB_AI))//Bold head jobs
|
||||
. += span_bold("[rank]") + "</a>"
|
||||
else
|
||||
. += "[rank]</a>"
|
||||
|
||||
. += "</td><td width='40%'>"
|
||||
|
||||
var/prefLevelLabel = "ERROR"
|
||||
var/prefLevelColor = "pink"
|
||||
var/prefUpperLevel = -1 // level to assign on left click
|
||||
var/prefLowerLevel = -1 // level to assign on right click
|
||||
if(pref.GetJobDepartment(job, 1) & job.flag)
|
||||
prefLevelLabel = "High"
|
||||
prefLevelColor = "55cc55"
|
||||
prefUpperLevel = 4
|
||||
prefLowerLevel = 2
|
||||
else if(pref.GetJobDepartment(job, 2) & job.flag)
|
||||
prefLevelLabel = "Medium"
|
||||
prefLevelColor = "eecc22"
|
||||
prefUpperLevel = 1
|
||||
prefLowerLevel = 3
|
||||
else if(pref.GetJobDepartment(job, 3) & job.flag)
|
||||
prefLevelLabel = "Low"
|
||||
prefLevelColor = "cc5555"
|
||||
prefUpperLevel = 2
|
||||
prefLowerLevel = 4
|
||||
else
|
||||
prefLevelLabel = "NEVER"
|
||||
prefLevelColor = "black"
|
||||
prefUpperLevel = 3
|
||||
prefLowerLevel = 1
|
||||
|
||||
. += "<a href='byond://?src=\ref[src];set_job=[rank];level=[prefUpperLevel]' oncontextmenu='javascript:return setJobPrefRedirect([prefLowerLevel], \"[rank]\");'>"
|
||||
job_data["special_color"] = "gray"
|
||||
if((job.title in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND) ) || (job.title == JOB_AI))//Bold head jobs
|
||||
job_data["special_color"] = "bold"
|
||||
|
||||
if(job.type == /datum/job/assistant)//Assistant is special
|
||||
if(pref.job_civilian_low & ASSISTANT)
|
||||
. += " <font color=55cc55>\[Yes]</font>"
|
||||
job_data["selected"] = 4
|
||||
else
|
||||
. += " " + span_black("\[No]")
|
||||
if(LAZYLEN(job.alt_titles)) //Blatantly cloned from a few lines down.
|
||||
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'> </td><td><a href='byond://?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
|
||||
. += "</a></td></tr>"
|
||||
continue
|
||||
job_data["selected"] = 0
|
||||
else if(pref.GetJobDepartment(job, 1) & job.flag)
|
||||
job_data["selected"] = 3
|
||||
else if(pref.GetJobDepartment(job, 2) & job.flag)
|
||||
job_data["selected"] = 2
|
||||
else if(pref.GetJobDepartment(job, 3) & job.flag)
|
||||
job_data["selected"] = 1
|
||||
else
|
||||
job_data["selected"] = 0
|
||||
|
||||
. += " <font color=[prefLevelColor]>\[[prefLevelLabel]]</font>"
|
||||
if(LAZYLEN(job.alt_titles))
|
||||
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'> </td><td><a href='byond://?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
|
||||
. += "</a></td></tr>"
|
||||
. += "</td'></tr></table>"
|
||||
. += "</center></table><center>"
|
||||
job_data["selected_title"] = pref.GetPlayerAltTitle(job)
|
||||
for(var/title in job.alt_titles)
|
||||
job_data["alt_titles"] += title
|
||||
|
||||
switch(pref.alternate_option)
|
||||
if(GET_RANDOM_JOB)
|
||||
. += span_underline("<a href='byond://?src=\ref[src];job_alternative=1'>Get random job if preferences unavailable</a>")
|
||||
if(BE_ASSISTANT)
|
||||
. += span_underline("<a href='byond://?src=\ref[src];job_alternative=1'>Be assistant if preference unavailable</a>")
|
||||
if(RETURN_TO_LOBBY)
|
||||
. += span_underline("<a href='byond://?src=\ref[src];job_alternative=1'>Return to lobby if preference unavailable</a>")
|
||||
UNTYPED_LIST_ADD(jobs_data[current_department.name], job_data)
|
||||
|
||||
. += "<a href='byond://?src=\ref[src];reset_jobs=1'>\[Reset\]</a></center>"
|
||||
. += "</tt>"
|
||||
. = jointext(.,null)
|
||||
data["jobs"] = jobs_data
|
||||
data["alternate_option"] = pref.alternate_option
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("reset_jobs")
|
||||
ResetJobs()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("job_alternative")
|
||||
if(pref.alternate_option == GET_RANDOM_JOB || pref.alternate_option == BE_ASSISTANT)
|
||||
pref.alternate_option += 1
|
||||
else if(pref.alternate_option == RETURN_TO_LOBBY)
|
||||
pref.alternate_option = 0
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("select_alt_title")
|
||||
var/datum/job/J = locate(params["job"])
|
||||
if(istype(J))
|
||||
var/choices = list(J.title) + J.alt_titles
|
||||
var/choice = tgui_input_list(user, "Choose a title for [J.title].", "Choose Title", choices, pref.GetPlayerAltTitle(J))
|
||||
if(choice)
|
||||
SetPlayerAltTitle(J, choice)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("set_job")
|
||||
if(SetJob(user, params["set_job"], text2num(params["level"])))
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if("job_info")
|
||||
var/rank = params["rank"]
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
if(!istype(job))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
var/dat = list()
|
||||
|
||||
dat += "<p style='background-color: [job.selection_color]'><br><br><p>"
|
||||
if(job.alt_titles)
|
||||
dat += span_italics(span_bold("Alternate titles:") + " [english_list(job.alt_titles)].")
|
||||
send_rsc(user, job.get_job_icon(), "job[ckey(rank)].png")
|
||||
dat += "<img src=job[ckey(rank)].png width=96 height=96 style='float:left;'>"
|
||||
if(job.departments)
|
||||
dat += span_bold("Departments:") + " [english_list(job.departments)]."
|
||||
if(LAZYLEN(job.departments_managed))
|
||||
dat += "You manage these departments: [english_list(job.departments_managed)]"
|
||||
|
||||
dat += "You answer to " + span_bold("[job.supervisors]") + " normally."
|
||||
|
||||
dat += "<hr style='clear:left;'>"
|
||||
if(CONFIG_GET(string/wikiurl))
|
||||
dat += "<a href='byond://?src=\ref[src];job_wiki=[rank]'>Open wiki page in browser</a>"
|
||||
|
||||
var/alt_title = pref.GetPlayerAltTitle(job)
|
||||
var/list/description = job.get_description_blurb(alt_title)
|
||||
if(LAZYLEN(description))
|
||||
dat += html_encode(description[1])
|
||||
if(description.len > 1)
|
||||
if(!isnull(description[2]))
|
||||
dat += "<br>"
|
||||
dat += html_encode(description[2])
|
||||
|
||||
var/datum/browser/popup = new(user, "Job Info", "[capitalize(rank)]", 430, 520, src)
|
||||
popup.set_content(jointext(dat,"<br>"))
|
||||
popup.open()
|
||||
return TOPIC_HANDLED
|
||||
|
||||
// must stay for job popup to work
|
||||
/datum/category_item/player_setup_item/occupation/OnTopic(href, href_list, user)
|
||||
if(href_list["reset_jobs"])
|
||||
ResetJobs()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["job_alternative"])
|
||||
if(pref.alternate_option == GET_RANDOM_JOB || pref.alternate_option == BE_ASSISTANT)
|
||||
pref.alternate_option += 1
|
||||
else if(pref.alternate_option == RETURN_TO_LOBBY)
|
||||
pref.alternate_option = 0
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["select_alt_title"])
|
||||
var/datum/job/job = locate(href_list["select_alt_title"])
|
||||
if (job)
|
||||
var/choices = list(job.title) + job.alt_titles
|
||||
var/choice = tgui_input_list(user, "Choose a title for [job.title].", "Choose Title", choices, pref.GetPlayerAltTitle(job))
|
||||
if(choice && CanUseTopic(user))
|
||||
SetPlayerAltTitle(job, choice)
|
||||
return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH)
|
||||
|
||||
else if(href_list["set_job"])
|
||||
if(SetJob(user, href_list["set_job"], text2num(href_list["level"])))
|
||||
return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH)
|
||||
|
||||
else if(href_list["job_info"])
|
||||
var/rank = href_list["job_info"]
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
var/dat = list()
|
||||
|
||||
dat += "<p style='background-color: [job.selection_color]'><br><br><p>"
|
||||
if(job.alt_titles)
|
||||
dat += span_italics(span_bold("Alternate titles:") + " [english_list(job.alt_titles)].")
|
||||
send_rsc(user, job.get_job_icon(), "job[ckey(rank)].png")
|
||||
dat += "<img src=job[ckey(rank)].png width=96 height=96 style='float:left;'>"
|
||||
if(job.departments)
|
||||
dat += span_bold("Departments:") + " [english_list(job.departments)]."
|
||||
if(LAZYLEN(job.departments_managed))
|
||||
dat += "You manage these departments: [english_list(job.departments_managed)]"
|
||||
|
||||
dat += "You answer to " + span_bold("[job.supervisors]") + " normally."
|
||||
|
||||
dat += "<hr style='clear:left;'>"
|
||||
if(CONFIG_GET(string/wikiurl))
|
||||
dat += "<a href='byond://?src=\ref[src];job_wiki=[rank]'>Open wiki page in browser</a>"
|
||||
|
||||
var/alt_title = pref.GetPlayerAltTitle(job)
|
||||
var/list/description = job.get_description_blurb(alt_title)
|
||||
if(LAZYLEN(description))
|
||||
dat += html_encode(description[1])
|
||||
if(description.len > 1)
|
||||
if(!isnull(description[2]))
|
||||
dat += "<br>"
|
||||
dat += html_encode(description[2])
|
||||
|
||||
var/datum/browser/popup = new(user, "Job Info", "[capitalize(rank)]", 430, 520, src)
|
||||
popup.set_content(jointext(dat,"<br>"))
|
||||
popup.open()
|
||||
|
||||
else if(href_list["job_wiki"])
|
||||
if(href_list["job_wiki"])
|
||||
var/rank = href_list["job_wiki"]
|
||||
open_link(user,"[CONFIG_GET(string/wikiurl)][rank]")
|
||||
|
||||
|
||||
@@ -12,11 +12,6 @@
|
||||
sort_order = 3
|
||||
category_item_type = /datum/category_item/player_setup_item/occupation
|
||||
|
||||
/datum/category_group/player_setup_category/appearance_preferences
|
||||
name = "Special Roles"
|
||||
sort_order = 4
|
||||
category_item_type = /datum/category_item/player_setup_item/antagonism
|
||||
|
||||
/datum/category_group/player_setup_category/loadout_preferences
|
||||
name = "Loadout"
|
||||
sort_order = 5
|
||||
@@ -86,10 +81,6 @@
|
||||
dat += "<a href='byond://?src=\ref[src];game_prefs=1'>Game Options</a>"
|
||||
return dat
|
||||
|
||||
/datum/category_collection/player_setup_collection/proc/content(var/mob/user)
|
||||
if(selected_category)
|
||||
return selected_category.content(user)
|
||||
|
||||
/datum/category_collection/player_setup_collection/Topic(var/href,var/list/href_list)
|
||||
if(..())
|
||||
return 1
|
||||
@@ -104,7 +95,7 @@
|
||||
. = 1
|
||||
|
||||
else if(href_list["game_prefs"])
|
||||
user.client.prefs.tgui_interact(user)
|
||||
user.client.game_options()
|
||||
|
||||
if(.)
|
||||
user.client.prefs.ShowChoices(user)
|
||||
@@ -152,21 +143,6 @@
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.copy_to_mob(C)
|
||||
|
||||
/datum/category_group/player_setup_category/proc/content(var/mob/user)
|
||||
. = "<table style='width:100%'><tr style='vertical-align:top'><td style='width:50%'>"
|
||||
var/current = 0
|
||||
var/halfway = items.len / 2
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
if(halfway && current++ >= halfway)
|
||||
halfway = 0
|
||||
. += "</td><td></td><td style='width:50%'>"
|
||||
. += "[PI.content(user)]<br>"
|
||||
. += "</td></tr></table>"
|
||||
|
||||
/datum/category_group/player_setup_category/occupation_preferences/content(var/mob/user)
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
. += "[PI.content(user)]<br>"
|
||||
|
||||
/**********************
|
||||
* Category Item Setup *
|
||||
**********************/
|
||||
@@ -216,9 +192,6 @@
|
||||
/datum/category_item/player_setup_item/proc/copy_to_mob(var/mob/living/carbon/human/C)
|
||||
return
|
||||
|
||||
/datum/category_item/player_setup_item/proc/content()
|
||||
return
|
||||
|
||||
/datum/category_item/player_setup_item/proc/sanitize_character()
|
||||
return
|
||||
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
// This contains character setup datums for traits.
|
||||
// The actual modifiers (if used) for these are stored inside code/modules/mob/_modifiers/traits.dm
|
||||
|
||||
/datum/trait/modifier
|
||||
abstract_type = /datum/trait/modifier
|
||||
var/modifier_type = null // Type to add to the mob post spawn.
|
||||
|
||||
/datum/trait/modifier/apply_trait_post_spawn(mob/living/L)
|
||||
L.add_modifier(modifier_type)
|
||||
|
||||
/datum/trait/modifier/is_available()
|
||||
return !!modifier_type
|
||||
|
||||
/datum/trait/modifier/generate_desc()
|
||||
var/new_desc = desc
|
||||
if(!is_available())
|
||||
new_desc = "[new_desc] This trait is not implemented yet."
|
||||
return new_desc
|
||||
var/datum/modifier/M = new modifier_type()
|
||||
if(!desc)
|
||||
new_desc = M.desc // Use the modifier's description, if the trait doesn't have one defined.
|
||||
var/modifier_effects = M.describe_modifier_effects()
|
||||
new_desc = "[new_desc][modifier_effects ? "<br>[modifier_effects]":""]" // Now describe what the trait actually does.
|
||||
qdel(M)
|
||||
return new_desc
|
||||
|
||||
|
||||
// Physical traits are what they sound like, and involve the character's physical body, as opposed to their mental state.
|
||||
/datum/trait/modifier/physical
|
||||
abstract_type = /datum/trait/modifier/physical
|
||||
name = "Physical"
|
||||
category = "Physical"
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/flimsy
|
||||
name = "Flimsy"
|
||||
desc = "You're more fragile than most, and have less of an ability to endure harm."
|
||||
modifier_type = /datum/modifier/trait/flimsy
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/frail)
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/frail
|
||||
name = "Frail"
|
||||
desc = "Your body is very fragile, and has even less of an ability to endure harm."
|
||||
modifier_type = /datum/modifier/trait/frail
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/flimsy)
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/haemophilia
|
||||
name = "Haemophilia"
|
||||
desc = "Some say that when it rains, it pours. Unfortunately, this is also true for yourself if you get cut."
|
||||
modifier_type = /datum/modifier/trait/haemophilia
|
||||
|
||||
/datum/trait/modifier/physical/haemophilia/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics cannot bleed."
|
||||
// If a species lacking blood is added, it is suggested to add a check for them here.
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/weak
|
||||
name = "Weak"
|
||||
desc = "A lack of physical strength causes a diminshed capability in close quarters combat."
|
||||
modifier_type = /datum/modifier/trait/weak
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/wimpy)
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/wimpy
|
||||
name = "Wimpy"
|
||||
desc = "An extreme lack of physical strength causes a greatly diminished capability in close quarters combat."
|
||||
modifier_type = /datum/modifier/trait/wimpy
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/weak)
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/inaccurate
|
||||
name = "Inaccurate"
|
||||
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
|
||||
Regardless, you find it quite difficult to land shots where you wanted them to go."
|
||||
modifier_type = /datum/modifier/trait/inaccurate
|
||||
|
||||
/datum/trait/modifier/physical/shorter
|
||||
name = "Shorter"
|
||||
modifier_type = /datum/modifier/trait/shorter
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/short, /datum/trait/modifier/physical/tall, /datum/trait/modifier/physical/taller)
|
||||
|
||||
/datum/trait/modifier/physical/short
|
||||
name = "Short"
|
||||
modifier_type = /datum/modifier/trait/short
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/shorter, /datum/trait/modifier/physical/tall, /datum/trait/modifier/physical/taller)
|
||||
|
||||
/datum/trait/modifier/physical/tall
|
||||
name = "Tall"
|
||||
modifier_type = /datum/modifier/trait/tall
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/shorter, /datum/trait/modifier/physical/short, /datum/trait/modifier/physical/taller)
|
||||
|
||||
/datum/trait/modifier/physical/taller
|
||||
name = "Taller"
|
||||
modifier_type = /datum/modifier/trait/taller
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/shorter, /datum/trait/modifier/physical/short, /datum/trait/modifier/physical/tall)
|
||||
|
||||
/datum/trait/modifier/physical/thin
|
||||
name = "Thin"
|
||||
modifier_type = /datum/modifier/trait/thin
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/fat, /datum/trait/modifier/physical/obese, /datum/trait/modifier/physical/thinner)
|
||||
|
||||
/datum/trait/modifier/physical/thinner
|
||||
name = "Rail Thin"
|
||||
modifier_type = /datum/modifier/trait/thinner
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/fat, /datum/trait/modifier/physical/obese, /datum/trait/modifier/physical/thin)
|
||||
|
||||
/datum/trait/modifier/physical/fat
|
||||
name = "Broad-Shouldered"
|
||||
modifier_type = /datum/modifier/trait/fat
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/thin, /datum/trait/modifier/physical/obese, /datum/trait/modifier/physical/thinner)
|
||||
|
||||
/datum/trait/modifier/physical/obese
|
||||
name = "Heavily Built"
|
||||
modifier_type = /datum/modifier/trait/obese
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/fat, /datum/trait/modifier/physical/thinner, /datum/trait/modifier/physical/thin)
|
||||
|
||||
/datum/trait/modifier/physical/colorblind_protanopia
|
||||
name = "Protanopia"
|
||||
desc = "You have a form of red-green colorblindness. You cannot see reds, and have trouble distinguishing them from yellows and greens."
|
||||
modifier_type = /datum/modifier/trait/colorblind_protanopia
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_tritanopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||
|
||||
/datum/trait/modifier/physical/colorblind_deuteranopia
|
||||
name = "Deuteranopia"
|
||||
desc = "You have a form of red-green colorblindness. You cannot see greens, and have trouble distinguishing them from yellows and reds."
|
||||
modifier_type = /datum/modifier/trait/colorblind_deuteranopia
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_tritanopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||
|
||||
/datum/trait/modifier/physical/colorblind_tritanopia
|
||||
name = "Tritanopia"
|
||||
desc = "You have a form of blue-yellow colorblindness. You have trouble distinguishing between blues, greens, and yellows, and see blues and violets as dim."
|
||||
modifier_type = /datum/modifier/trait/colorblind_tritanopia
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||
|
||||
/datum/trait/modifier/physical/colorblind_monochrome
|
||||
name = "Monochromacy"
|
||||
desc = "You are fully colorblind. Your condition is rare, but you can see no colors at all."
|
||||
modifier_type = /datum/modifier/trait/colorblind_monochrome
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_tritanopia)
|
||||
|
||||
// These two traits might be borderline, feel free to remove if they get abused.
|
||||
/datum/trait/modifier/physical/high_metabolism
|
||||
name = "High Metabolism"
|
||||
modifier_type = /datum/modifier/trait/high_metabolism
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/low_metabolism)
|
||||
|
||||
/datum/trait/modifier/physical/high_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics do not have a metabolism."
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/low_metabolism
|
||||
name = "Low Metabolism"
|
||||
modifier_type = /datum/modifier/trait/low_metabolism
|
||||
mutually_exclusive = list(/datum/trait/modifier/physical/high_metabolism)
|
||||
|
||||
/datum/trait/modifier/physical/low_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics do not have a metabolism."
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/cloned
|
||||
name = "Cloned"
|
||||
desc = "At some point in your life, you died and were cloned."
|
||||
modifier_type = /datum/modifier/cloned
|
||||
|
||||
/datum/trait/modifier/physical/cloned/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics cannot be cloned."
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/no_clone
|
||||
name = "Cloning Incompatibility"
|
||||
modifier_type = /datum/modifier/no_clone
|
||||
|
||||
/datum/trait/modifier/physical/no_clone/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics cannot be cloned anyways."
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/physical/no_borg
|
||||
name = "Cybernetic Incompatibility"
|
||||
modifier_type = /datum/modifier/no_borg
|
||||
|
||||
/datum/trait/modifier/physical/no_borg/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
return "Full Body Prosthetics are already partly or fully mechanical."
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
// 'Mental' traits are just those that only sapients can have, for now, and generally involves fears.
|
||||
// So far, all of them are just for fluff/don't have mechanical effects.
|
||||
/datum/trait/modifier/mental
|
||||
abstract_type = /datum/trait/modifier/mental
|
||||
name = "Mental"
|
||||
category = "Mental"
|
||||
|
||||
/datum/trait/modifier/mental/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(setup.is_FBP())
|
||||
if(setup.get_FBP_type() == PREF_FBP_SOFTWARE)
|
||||
return "Drone Intelligences cannot feel emotions."
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait/modifier/mental/arachnophobe
|
||||
name = "Arachnophobic"
|
||||
desc = "Spiders are quite creepy to most people, however for you, those chitters of pure evil inspire pure dread and fear."
|
||||
modifier_type = /datum/modifier/trait/phobia/arachnophobe
|
||||
|
||||
|
||||
/datum/trait/modifier/mental/nyctophobe
|
||||
name = "Nyctophobic"
|
||||
desc = "More commonly known as the fear of darkness. The shadows can hide many dangers, which makes the prospect of going into the depths of Maintenance rather worrisome."
|
||||
modifier_type = /datum/modifier/trait/phobia/nyctophobe
|
||||
|
||||
|
||||
/datum/trait/modifier/mental/haemophobe
|
||||
name = "Haemophobia"
|
||||
desc = "Not to be confused with Haemophilia (which makes you bleed faster), Haemophobia is the fear of blood. Seeing a bunch of blood isn't really \
|
||||
pleasant for most people, but for you, it is very distressing."
|
||||
modifier_type = /datum/modifier/trait/phobia/haemophobia
|
||||
|
||||
|
||||
/datum/trait/modifier/mental/claustrophobe
|
||||
name = "Claustrophobic"
|
||||
desc = "Small spaces and tight quarters makes you feel distressed. Unfortunately both are rather common when living in space."
|
||||
modifier_type = /datum/modifier/trait/phobia/claustrophobe
|
||||
|
||||
|
||||
/datum/trait/modifier/mental/blennophobe
|
||||
name = "Blennophobia"
|
||||
desc = "Slimes are quite dangerous, but just the aspect of something being slimey is uncomfortable."
|
||||
modifier_type = /datum/modifier/trait/phobia/blennophobe
|
||||
|
||||
/datum/trait/modifier/mental/trypanophobe
|
||||
name = "Trypanophobia"
|
||||
desc = "Syringes and needles make you very distressed. You really don't want to get sick..."
|
||||
modifier_type = /datum/modifier/trait/phobia/trypanophobe
|
||||
|
||||
/*
|
||||
// Uncomment this when/if these get finished.
|
||||
/datum/trait/modifier/mental/synthphobe
|
||||
name = "Synthphobic"
|
||||
desc = "You know, deep down, that synthetics cannot be trusted, and so you are always on guard whenever you see one wandering around. No one knows how a Positronic's mind works, \
|
||||
Drones are just waiting for the right time for Emergence, and the poor brains trapped in the cage of Man Machine Interfaces are now soulless, despite being unaware of it. None \
|
||||
can be trusted."
|
||||
|
||||
/datum/trait/modifier/mental/xenophobe
|
||||
name = "Xenophobic"
|
||||
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
|
||||
closely, waiting to strike."
|
||||
mutually_exclusive = list(
|
||||
/datum/trait/modifier/mental/humanphobe,
|
||||
/datum/trait/modifier/mental/skrellphobe,
|
||||
/datum/trait/modifier/mental/tajaraphobe,
|
||||
/datum/trait/modifier/mental/unathiphobe,
|
||||
/datum/trait/modifier/mental/teshariphobe,
|
||||
/datum/trait/modifier/mental/prometheanphobe
|
||||
)
|
||||
|
||||
/datum/trait/modifier/mental/humanphobe
|
||||
name = "Human-phobic"
|
||||
desc = "Boilerplate racism for monkeys goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
/datum/trait/modifier/mental/skrellphobe
|
||||
name = "Skrell-phobic"
|
||||
desc = "Boilerplate racism for squid goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
/datum/trait/modifier/mental/tajaraphobe
|
||||
name = "Tajaran-phobic"
|
||||
desc = "Boilerplate racism for cats goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
/datum/trait/modifier/mental/unathiphobe
|
||||
name = "Unathi-phobic"
|
||||
desc = "Boilerplate racism for lizards goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
// Not sure why anyone would hate/fear these guys but for the sake of completeness here we are.
|
||||
/datum/trait/modifier/mental/dionaphobe
|
||||
name = "Diona-phobic"
|
||||
desc = "Boilerplate racism for trees goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
/datum/trait/modifier/mental/teshariphobe
|
||||
name = "Teshari-phobic"
|
||||
desc = "Boilerplate racism for birds goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
|
||||
/datum/trait/modifier/mental/prometheanphobe
|
||||
name = "Promethean-phobic"
|
||||
desc = "Boilerplate racism for jellos goes here."
|
||||
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
|
||||
*/
|
||||
@@ -1,205 +0,0 @@
|
||||
var/list/trait_datums = list() // Assoc list using name = instance. Traits are saved as a list of strings.
|
||||
var/list/trait_type_to_ref = list() // Similar to above but uses paths, which is more reliable but more risky to save.
|
||||
var/list/trait_categories = list() // The categories available for the trait menu.
|
||||
|
||||
/hook/startup/proc/populate_trait_list()
|
||||
|
||||
//create a list of trait datums
|
||||
for(var/trait_type as anything in subtypesof(/datum/trait))
|
||||
if (is_abstract(trait_type))
|
||||
continue
|
||||
var/datum/trait/T = new trait_type
|
||||
if(!T.is_available())
|
||||
qdel(T)
|
||||
continue
|
||||
|
||||
if(!T.name)
|
||||
error("Trait Menu - Missing name: [T.type]")
|
||||
continue
|
||||
|
||||
if(!T.category)
|
||||
error("Trait Menu - Missing category: [T.type]")
|
||||
continue
|
||||
|
||||
T.desc = T.generate_desc()
|
||||
|
||||
trait_datums[T.name] = T
|
||||
trait_type_to_ref[T.type] = T
|
||||
if(!(T.category in trait_categories))
|
||||
trait_categories += T.category
|
||||
|
||||
return 1
|
||||
|
||||
/datum/category_item/player_setup_item/traits
|
||||
name = "Quirks" //VOREStation Edit
|
||||
sort_order = 1
|
||||
var/current_tab = "Physical"
|
||||
|
||||
/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(list/save_data)
|
||||
save_data["traits"] = pref.traits
|
||||
|
||||
|
||||
/datum/category_item/player_setup_item/traits/content()
|
||||
. = list()
|
||||
. += "<table align = 'center' width = 100%>"
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
. += "<tr><td colspan=3>" + span_bold("<center>Traits</center>") + "</td></tr>"
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
|
||||
. += "<tr><td colspan=3><center>"
|
||||
var/firstcat = 1
|
||||
for(var/category in trait_categories)
|
||||
if(firstcat)
|
||||
firstcat = 0
|
||||
else
|
||||
. += " |"
|
||||
|
||||
if(category == current_tab)
|
||||
. += " " + span_linkOn("[category]") + " "
|
||||
else
|
||||
. += " <a href='byond://?src=\ref[src];select_category=[category]'>[category]</a> "
|
||||
. += "</center></td></tr>"
|
||||
|
||||
|
||||
for(var/trait_name in trait_datums)
|
||||
var/datum/trait/T = trait_datums[trait_name]
|
||||
if(T.category != current_tab)
|
||||
continue
|
||||
|
||||
var/ticked = (T.name in pref.traits)
|
||||
var/style_class
|
||||
if(!T.validate(pref.traits, src))
|
||||
style_class = "linkOff"
|
||||
else if(ticked)
|
||||
style_class = "linkOn"
|
||||
. += "<tr style='vertical-align:top;'><td width=25%><div align='center'><a style='white-space:normal;' [style_class ? "class='[style_class]' " : ""]href='byond://?src=\ref[src];toggle_trait=[html_encode(T.name)]'>[T.name]</a></div></td>"
|
||||
// . += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
|
||||
|
||||
var/invalidity = T.test_for_invalidity(src)
|
||||
var/conflicts = T.test_for_trait_conflict(pref.traits)
|
||||
var/invalid = ""
|
||||
if(invalidity)
|
||||
invalid += "[invalidity] "
|
||||
if(conflicts)
|
||||
invalid += "This trait is mutually exclusive with [conflicts]."
|
||||
|
||||
. += "<td width = 75%><font size=2>" + span_italics("[T.desc]") + "\
|
||||
[invalid ? span_red("<br>Cannot take trait. Reason: [invalid]"):""]</font></td></tr>"
|
||||
// if(ticked)
|
||||
// . += "<tr><td colspan=3>"
|
||||
// for(var/datum/gear_tweak/tweak in G.gear_tweaks)
|
||||
// . += " <a href='byond://?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
|
||||
// . += "</td></tr>"
|
||||
. += "</table>"
|
||||
. = jointext(., null)
|
||||
|
||||
/datum/category_item/player_setup_item/traits/sanitize_character()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
if(!islist(pref.traits))
|
||||
pref.traits = list()
|
||||
|
||||
for(var/trait_name in pref.traits)
|
||||
if(!(trait_name in trait_datums))
|
||||
pref.traits -= trait_name
|
||||
|
||||
for(var/trait_name in pref.traits)
|
||||
if(!trait_datums[trait_name])
|
||||
to_chat(preference_mob, span_warning("You cannot have more than one of trait: [trait_name]"))
|
||||
pref.traits -= trait_name
|
||||
else
|
||||
var/datum/trait/T = trait_datums[trait_name]
|
||||
var/invalidity = T.test_for_invalidity(src)
|
||||
if(invalidity)
|
||||
pref.traits -= trait_name
|
||||
to_chat(preference_mob, span_warning("You cannot take the [trait_name] trait. Reason: [invalidity]"))
|
||||
|
||||
var/conflicts = T.test_for_trait_conflict(pref.traits)
|
||||
if(conflicts)
|
||||
pref.traits -= trait_name
|
||||
to_chat(preference_mob, span_warning("The [trait_name] trait is mutually exclusive with [conflicts]."))
|
||||
|
||||
/datum/category_item/player_setup_item/traits/OnTopic(href, href_list, user)
|
||||
if(href_list["toggle_trait"])
|
||||
var/datum/trait/T = trait_datums[href_list["toggle_trait"]]
|
||||
if(T.name in pref.traits)
|
||||
pref.traits -= T.name
|
||||
else
|
||||
var/invalidity = T.test_for_invalidity(src)
|
||||
if(invalidity)
|
||||
to_chat(user, span_warning("You cannot take the [T.name] trait. Reason: [invalidity]"))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
var/conflicts = T.test_for_trait_conflict(pref.traits)
|
||||
if(conflicts)
|
||||
to_chat(user, span_warning("The [T.name] trait is mutually exclusive with [conflicts]."))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
pref.traits += T.name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(href_list["select_category"])
|
||||
current_tab = href_list["select_category"]
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/trait
|
||||
abstract_type = /datum/trait
|
||||
var/name = null // Name to show on UI
|
||||
var/desc = null // Description of what it does, also shown on UI.
|
||||
var/list/mutually_exclusive = list() // List of trait types which cannot be taken alongside this trait.
|
||||
var/category = null // What section to place this trait inside.
|
||||
|
||||
// Applies effects to the newly spawned mob.
|
||||
/datum/trait/proc/apply_trait_post_spawn(var/mob/living/L)
|
||||
return
|
||||
|
||||
// Used to forbid a trait based on certain criteria (e.g. if they are an FBP).
|
||||
// It receives the player_setup_item datum since some reasons for being invalid depend on the currently loaded preferences.
|
||||
// Returns a string explaining why the trait is invalid. Returns null if valid.
|
||||
/datum/trait/proc/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
|
||||
return null
|
||||
|
||||
// Checks mutually_exclusive. current_traits needs to be a list of strings.
|
||||
// Returns null if everything is well, similar to the above proc. Otherwise returns an english_list() of conflicting traits.
|
||||
/datum/trait/proc/test_for_trait_conflict(var/list/current_traits)
|
||||
var/list/conflicts = list()
|
||||
var/result
|
||||
|
||||
if(mutually_exclusive.len)
|
||||
for(var/trait_name in current_traits)
|
||||
var/datum/trait/T = trait_datums[trait_name]
|
||||
if(T.type in mutually_exclusive)
|
||||
conflicts.Add(T.name)
|
||||
|
||||
if(conflicts.len)
|
||||
result = english_list(conflicts)
|
||||
|
||||
return result
|
||||
|
||||
/datum/trait/proc/is_available()
|
||||
return TRUE
|
||||
|
||||
// Similar to above, but uses the above two procs, in one place.
|
||||
// Returns TRUE is everything is well.
|
||||
/datum/trait/proc/validate(var/list/current_traits, var/datum/category_item/player_setup_item/traits/setup)
|
||||
if(test_for_invalidity(setup))
|
||||
return FALSE
|
||||
if(test_for_trait_conflict(current_traits))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// Creates a description, if one doesn't exist.
|
||||
// This one is for inheritence, and so doesn't do anything.
|
||||
/datum/trait/proc/generate_desc()
|
||||
return desc
|
||||
|
||||
/mob/living/proc/apply_traits()
|
||||
if(!mind || !mind.traits || !mind.traits.len)
|
||||
return
|
||||
for(var/trait in mind.traits)
|
||||
var/datum/trait/T = trait_datums[trait]
|
||||
if(istype(T))
|
||||
T.apply_trait_post_spawn(src)
|
||||
@@ -1,106 +0,0 @@
|
||||
/datum/category_group/player_setup_category/volume_sliders
|
||||
name = "Sound"
|
||||
sort_order = 7
|
||||
category_item_type = /datum/category_item/player_setup_item/volume_sliders
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume
|
||||
name = "General Volume"
|
||||
sort_order = 1
|
||||
|
||||
/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(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))
|
||||
pref.volume_channels = list()
|
||||
|
||||
for(var/channel in pref.volume_channels)
|
||||
if(!(channel in GLOB.all_volume_channels))
|
||||
// Channel no longer exists, yeet
|
||||
pref.volume_channels.Remove(channel)
|
||||
|
||||
for(var/channel in GLOB.all_volume_channels)
|
||||
if(!(channel in pref.volume_channels))
|
||||
pref.volume_channels["[channel]"] = 1
|
||||
else
|
||||
pref.volume_channels["[channel]"] = clamp(pref.volume_channels["[channel]"], 0, 2)
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/content(var/mob/user)
|
||||
. += span_bold("Volume Settings") + "<br>"
|
||||
for(var/channel in pref.volume_channels)
|
||||
. += "[channel]: <a href='byond://?src=\ref[src];change_volume=[channel];'><b>[pref.volume_channels[channel] * 100]%</b></a><br>"
|
||||
. += "<br>"
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/volume/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["change_volume"])
|
||||
if(CanUseTopic(user))
|
||||
var/channel = href_list["change_volume"]
|
||||
if(!(channel in pref.volume_channels))
|
||||
pref.volume_channels["[channel]"] = 1
|
||||
var/value = tgui_input_number(user, "Choose your volume for [channel] (0-200%)", "[channel] volume", (pref.volume_channels[channel] * 100), 200, 0)
|
||||
if(isnum(value))
|
||||
value = CLAMP(value, 0, 200)
|
||||
pref.volume_channels["[channel]"] = (value / 100)
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
|
||||
/mob/proc/get_preference_volume_channel(volume_channel)
|
||||
if(!client)
|
||||
return 0
|
||||
return client.get_preference_volume_channel(volume_channel)
|
||||
|
||||
/client/proc/get_preference_volume_channel(volume_channel)
|
||||
if(!volume_channel || !prefs)
|
||||
return 1
|
||||
if(!(volume_channel in prefs.volume_channels))
|
||||
prefs.volume_channels["[volume_channel]"] = 1
|
||||
return prefs.volume_channels["[volume_channel]"]
|
||||
|
||||
|
||||
// Neat little volume adjuster thing in case you don't wanna touch preferences by hand you lazy fuck
|
||||
/datum/volume_panel
|
||||
/datum/volume_panel/tgui_state(mob/user)
|
||||
return GLOB.tgui_always_state
|
||||
|
||||
/datum/volume_panel/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "VolumePanel", "Volume Panel")
|
||||
ui.open()
|
||||
|
||||
/datum/volume_panel/tgui_data(mob/user)
|
||||
if(!user.client || !user.client.prefs)
|
||||
return list("error" = TRUE)
|
||||
|
||||
var/list/data = ..()
|
||||
data["volume_channels"] = user.client.prefs.volume_channels
|
||||
return data
|
||||
|
||||
/datum/volume_panel/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(!ui.user?.client?.prefs)
|
||||
return TRUE
|
||||
|
||||
var/datum/preferences/P = ui.user.client.prefs
|
||||
switch(action)
|
||||
if("adjust_volume")
|
||||
var/channel = params["channel"]
|
||||
if(channel in P.volume_channels)
|
||||
P.volume_channels["[channel]"] = clamp(params["vol"], 0, 2)
|
||||
SScharacter_setup.queue_preferences_save(P)
|
||||
return TRUE
|
||||
|
||||
/client/verb/volume_panel()
|
||||
set name = "Volume Panel"
|
||||
set category = "Preferences.Sounds"
|
||||
set desc = "Allows you to adjust volume levels on the fly."
|
||||
|
||||
if(!volume_panel)
|
||||
volume_panel = new(src)
|
||||
|
||||
volume_panel.tgui_interact(mob)
|
||||
@@ -1,53 +0,0 @@
|
||||
/datum/preferences
|
||||
var/media_volume = 1
|
||||
var/media_player = 2 // 0 = VLC, 1 = WMP, 2 = HTML5, 3+ = unassigned
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media
|
||||
name = "Media"
|
||||
sort_order = 2
|
||||
|
||||
/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(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)
|
||||
pref.media_player = sanitize_inlist(pref.media_player, list(0, 1, 2), initial(pref.media_player))
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/content(var/mob/user)
|
||||
. += span_bold("Jukebox Volume:")
|
||||
. += "<a href='byond://?src=\ref[src];change_media_volume=1'><b>[round(pref.media_volume * 100)]%</b></a><br>"
|
||||
. += span_bold("Media Player Type:") + " Depending on you operating system, one of these might work better. "
|
||||
. += "Use HTML5 if it works for you. If neither HTML5 nor WMP work, you'll have to fall back to using VLC, "
|
||||
. += "but this requires you have the VLC client installed on your comptuer."
|
||||
. += "Try the others if you want but you'll probably just get no music.<br>"
|
||||
. += (pref.media_player == 2) ? (span_linkOn(span_bold("HTML5")) + " ") : "<a href='byond://?src=\ref[src];set_media_player=2'>HTML5</a> "
|
||||
. += (pref.media_player == 1) ? (span_linkOn(span_bold("WMP")) + " ") : "<a href='byond://?src=\ref[src];set_media_player=1'>WMP</a> "
|
||||
. += (pref.media_player == 0) ? (span_linkOn(span_bold("VLC")) + " ") : "<a href='byond://?src=\ref[src];set_media_player=0'>VLC</a> "
|
||||
. += "<br>"
|
||||
|
||||
/datum/category_item/player_setup_item/volume_sliders/media/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["change_media_volume"])
|
||||
if(CanUseTopic(user))
|
||||
var/value = tgui_input_number(user, "Choose your Jukebox volume (0-100%)", "Jukebox volume", round(pref.media_volume * 100), 100, 0)
|
||||
if(isnum(value))
|
||||
value = CLAMP(value, 0, 100)
|
||||
pref.media_volume = value/100.0
|
||||
if(user.client && user.client.media)
|
||||
user.client.media.update_volume(pref.media_volume)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["set_media_player"])
|
||||
if(CanUseTopic(user))
|
||||
var/newval = sanitize_inlist(text2num(href_list["set_media_player"]), list(0, 1, 2), pref.media_player)
|
||||
if(newval != pref.media_player)
|
||||
pref.media_player = newval
|
||||
if(user.client && user.client.media)
|
||||
user.client.media.open()
|
||||
spawn(10)
|
||||
user.update_music()
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
@@ -1,5 +0,0 @@
|
||||
// Global stuff that will put us on the map
|
||||
/datum/category_group/player_setup_category/vore
|
||||
name = "VORE"
|
||||
sort_order = 8
|
||||
category_item_type = /datum/category_item/player_setup_item/vore
|
||||
@@ -1,314 +0,0 @@
|
||||
// Body weight limits on a character.
|
||||
#define WEIGHT_CHANGE_MIN 0
|
||||
#define WEIGHT_CHANGE_MAX 100
|
||||
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/size_multiplier = RESIZE_NORMAL
|
||||
// Body weight stuff.
|
||||
var/weight_vr = 137 // bodyweight of character (pounds, because I'm not doing the math again -Spades)
|
||||
var/weight_gain = 100 // Weight gain rate.
|
||||
var/weight_loss = 50 // Weight loss rate.
|
||||
var/fuzzy = 0 // Preference toggle for sharp/fuzzy icon. Default sharp.
|
||||
var/offset_override = FALSE
|
||||
var/voice_freq = 42500
|
||||
var/voice_sound = "goon speak 1"
|
||||
var/custom_speech_bubble = "default"
|
||||
var/custom_footstep = "Default"
|
||||
var/species_sound = "Unset"
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/vore/size
|
||||
name = "Size"
|
||||
sort_order = 2
|
||||
|
||||
/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"]
|
||||
pref.custom_footstep = save_data["custom_footstep"]
|
||||
pref.species_sound = save_data["species_sound"]
|
||||
|
||||
/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
|
||||
save_data["custom_footstep"] = pref.custom_footstep
|
||||
save_data["species_sound"] = pref.species_sound
|
||||
|
||||
/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))
|
||||
pref.weight_gain = sanitize_integer(pref.weight_gain, WEIGHT_CHANGE_MIN, WEIGHT_CHANGE_MAX, initial(pref.weight_gain))
|
||||
pref.weight_loss = sanitize_integer(pref.weight_loss, WEIGHT_CHANGE_MIN, WEIGHT_CHANGE_MAX, initial(pref.weight_loss))
|
||||
pref.fuzzy = sanitize_integer(pref.fuzzy, 0, 1, initial(pref.fuzzy))
|
||||
pref.offset_override = sanitize_integer(pref.offset_override, 0, 1, initial(pref.offset_override))
|
||||
if(pref.voice_freq != 0)
|
||||
pref.voice_freq = sanitize_integer(pref.voice_freq, MIN_VOICE_FREQ, MAX_VOICE_FREQ, initial(pref.voice_freq))
|
||||
if(pref.size_multiplier == null || pref.size_multiplier < RESIZE_TINY || pref.size_multiplier > RESIZE_HUGE)
|
||||
pref.size_multiplier = initial(pref.size_multiplier)
|
||||
if(!(pref.custom_speech_bubble in GLOB.selectable_speech_bubbles))
|
||||
pref.custom_speech_bubble = "default"
|
||||
if(!(pref.custom_footstep))
|
||||
pref.custom_footstep = "Default"
|
||||
// var/datum/species/selected_species = GLOB.all_species[pref.species]
|
||||
if(!(pref.species_sound))
|
||||
pref.species_sound = "Unset"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.weight = pref.weight_vr
|
||||
character.weight_gain = pref.weight_gain
|
||||
character.weight_loss = pref.weight_loss
|
||||
character.fuzzy = pref.fuzzy
|
||||
character.offset_override = pref.offset_override
|
||||
character.voice_freq = pref.voice_freq
|
||||
character.resize(pref.size_multiplier, animate = FALSE, ignore_prefs = TRUE)
|
||||
|
||||
if(!pref.voice_sound)
|
||||
character.voice_sounds_list = DEFAULT_TALK_SOUNDS
|
||||
else
|
||||
character.voice_sounds_list = get_talk_sound(pref.voice_sound)
|
||||
character.custom_speech_bubble = pref.custom_speech_bubble
|
||||
character.custom_footstep = pref.custom_footstep
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/content(var/mob/user)
|
||||
. += "<br>"
|
||||
. += span_bold("Scale:") + " <a href='byond://?src=\ref[src];size_multiplier=1'>[round(pref.size_multiplier*100)]%</a><br>"
|
||||
. += span_bold("Scaled Appearance:") + " <a [pref.fuzzy ? "" : ""] href='byond://?src=\ref[src];toggle_fuzzy=1'><b>[pref.fuzzy ? "Fuzzy" : "Sharp"]</b></a><br>"
|
||||
. += span_bold("Scaling Center:") + " <a [pref.offset_override ? "" : ""] href='byond://?src=\ref[src];toggle_offset_override=1'><b>[pref.offset_override ? "Odd" : "Even"]</b></a><br>"
|
||||
. += "<br>"
|
||||
. += span_bold("Mob Speech/Noise Customization") + ""
|
||||
. += "<br>"
|
||||
. += span_bold("Voice Frequency:") + " <a href='byond://?src=\ref[src];voice_freq=1'>[pref.voice_freq]</a><br>"
|
||||
. += span_bold("Voice Sounds:") + " <a href='byond://?src=\ref[src];voice_sounds_list=1'>[pref.voice_sound]</a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];voice_test=1'><b>Test Selected Voice</b></a><br>"
|
||||
. += span_bold("Custom Speech Bubble:") + " <a href='byond://?src=\ref[src];customize_speech_bubble=1'>[pref.custom_speech_bubble]</a><br>"
|
||||
. += span_bold("Custom Footstep Sounds:") + "<a href='byond://?src=\ref[src];customize_footsteps=1'>[pref.custom_footstep]</a><br>"
|
||||
. += "<br>"
|
||||
. += span_bold("Species Sounds:") + " <a href='byond://?src=\ref[src];species_sound_options=1'>[pref.species_sound]</a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];cough_test=1'><b>Test Cough Sounds</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];sneeze_test=1'><b>Test Sneeze Sounds</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];scream_test=1'><b>Test Scream Sounds</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];pain_test=1'><b>Test Pain Sounds</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];gasp_test=1'><b>Test Gasp Sounds</b></a><br>"
|
||||
. += "<a href='byond://?src=\ref[src];death_test=1'><b>Test Death Sounds</b></a><br>"
|
||||
. += "<br>"
|
||||
. += span_bold("Relative Weight:") + " <a href='byond://?src=\ref[src];weight=1'>[pref.weight_vr]</a><br>"
|
||||
. += span_bold("Weight Gain Rate:") + " <a href='byond://?src=\ref[src];weight_gain=1'>[pref.weight_gain]</a><br>"
|
||||
. += span_bold("Weight Loss Rate:") + " <a href='byond://?src=\ref[src];weight_loss=1'>[pref.weight_loss]</a><br>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/size/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["size_multiplier"])
|
||||
var/new_size = tgui_input_number(user, "Choose your character's size, ranging from [RESIZE_MINIMUM * 100]% to [RESIZE_MAXIMUM * 100]%", "Set Size", pref.size_multiplier * 100, RESIZE_MAXIMUM * 100, RESIZE_MINIMUM * 100)
|
||||
if (!ISINRANGE(new_size, RESIZE_MINIMUM * 100, RESIZE_MAXIMUM * 100))
|
||||
pref.size_multiplier = 1
|
||||
to_chat(user, span_notice("Invalid size."))
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(new_size)
|
||||
pref.size_multiplier = (new_size / 100)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["toggle_fuzzy"])
|
||||
pref.fuzzy = pref.fuzzy ? 0 : 1;
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["toggle_offset_override"])
|
||||
pref.offset_override = pref.offset_override ? 0 : 1;
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["weight"])
|
||||
var/new_weight = tgui_input_number(user, "Choose your character's relative body weight.\n\
|
||||
Note: Scifi characters come in all shapes and sizes in this game, and not all follow the traditional shape of a human. Like a naga or a taur or a giant will weigh a\n\
|
||||
lot more than what this allows, or a micro will weigh a lot less. Just ignore all of that for a second and PRETEND the weight you're setting is visually for an \n\
|
||||
average human. This is the best solution we have at the moment.!\n\
|
||||
([WEIGHT_MIN]-[WEIGHT_MAX])", "Character Preference", null, WEIGHT_MAX, WEIGHT_MIN, round_value=FALSE)
|
||||
if(new_weight)
|
||||
var/unit_of_measurement = tgui_alert(user, "Is that number in pounds (lb) or kilograms (kg)?", "Confirmation", list("Pounds", "Kilograms"))
|
||||
if(!unit_of_measurement)
|
||||
return TOPIC_NOACTION
|
||||
if(unit_of_measurement == "Pounds")
|
||||
new_weight = round(text2num(new_weight),4)
|
||||
if(unit_of_measurement == "Kilograms")
|
||||
new_weight = round(2.20462*text2num(new_weight),4)
|
||||
pref.weight_vr = sanitize_integer(new_weight, WEIGHT_MIN, WEIGHT_MAX, pref.weight_vr)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["weight_gain"])
|
||||
var/weight_gain_rate = tgui_input_number(user, "Choose your character's rate of weight gain between 100% \
|
||||
(full realism body fat gain) and 0% (no body fat gain).\n\
|
||||
(If you want to disable weight gain, set this to 0.01 to round it to 0%.)\
|
||||
([WEIGHT_CHANGE_MIN]-[WEIGHT_CHANGE_MAX])", "Character Preference", pref.weight_gain, WEIGHT_CHANGE_MAX, WEIGHT_CHANGE_MIN, round_value=FALSE)
|
||||
if(weight_gain_rate)
|
||||
pref.weight_gain = round(text2num(weight_gain_rate),1)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["weight_loss"])
|
||||
var/weight_loss_rate = tgui_input_number(user, "Choose your character's rate of weight loss between 100% \
|
||||
(full realism body fat loss) and 0% (no body fat loss).\n\
|
||||
(If you want to disable weight loss, set this to 0.01 round it to 0%.)\
|
||||
([WEIGHT_CHANGE_MIN]-[WEIGHT_CHANGE_MAX])", "Character Preference", pref.weight_loss, WEIGHT_CHANGE_MAX, WEIGHT_CHANGE_MIN, round_value=FALSE)
|
||||
if(weight_loss_rate)
|
||||
pref.weight_loss = round(text2num(weight_loss_rate),1)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["voice_freq"])
|
||||
var/list/preset_voice_freqs = list("high" = MAX_VOICE_FREQ, "middle-high" = 56250, "middle" = 42500, "middle-low"= 28750, "low" = MIN_VOICE_FREQ, "custom" = 1, "random" = 0)
|
||||
var/choice = tgui_input_list(user, "What would you like to set your voice frequency to? ([MIN_VOICE_FREQ] - [MAX_VOICE_FREQ])", "Voice Frequency", preset_voice_freqs)
|
||||
if(!choice)
|
||||
return
|
||||
choice = preset_voice_freqs[choice]
|
||||
if(choice == 0)
|
||||
pref.voice_freq = 42500
|
||||
return TOPIC_REFRESH
|
||||
else if(choice == 1)
|
||||
choice = tgui_input_number(user, "Choose your character's voice frequency, ranging from [MIN_VOICE_FREQ] to [MAX_VOICE_FREQ]", "Custom Voice Frequency", null, MAX_VOICE_FREQ, MIN_VOICE_FREQ)
|
||||
if(choice > MAX_VOICE_FREQ)
|
||||
choice = MAX_VOICE_FREQ
|
||||
else if(choice < MIN_VOICE_FREQ)
|
||||
choice = MIN_VOICE_FREQ
|
||||
|
||||
pref.voice_freq = choice
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["voice_sounds_list"])
|
||||
var/choice = tgui_input_list(user, "Which set of sounds would you like to use for your character's speech sounds?", "Voice Sounds", SSsounds.talk_sound_map)
|
||||
if(!pref.voice_sound)
|
||||
pref.voice_sound = "goon speak 1"
|
||||
else if(!choice)
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
pref.voice_sound = choice
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["customize_speech_bubble"])
|
||||
var/choice = tgui_input_list(user, "What speech bubble style do you want to use? (default for automatic selection)", "Custom Speech Bubble", GLOB.selectable_speech_bubbles)
|
||||
if(!choice)
|
||||
pref.custom_speech_bubble = "default"
|
||||
else
|
||||
pref.custom_speech_bubble = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["customize_footsteps"])
|
||||
var/list/footstep_choice = selectable_footstep
|
||||
var/choice = tgui_input_list(user, "What footstep sounds would your character make?", "Custom Foostep Sounds", footstep_choice)
|
||||
if(choice)
|
||||
pref.custom_footstep = footstep_choice[choice]
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["voice_test"])
|
||||
var/sound/S = sound(pick(SSsounds.talk_sound_map[pref.voice_sound])) // talk_sound_map returns a list of sounds
|
||||
if(S)
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 50
|
||||
SEND_SOUND(user, S)
|
||||
else if(href_list["species_sound_options"]) // You shouldn't be able to see this option if you don't have the option to select a custom icon base, so we don't need to re-check for safety here.
|
||||
var/list/possible_species_sound_types = species_sound_map
|
||||
var/choice = tgui_input_list(user, "Which set of sounds would you like to use for your character's species sounds? (Cough, Sneeze, Scream, Pain, Gasp, Death)", "Species Sounds", possible_species_sound_types)
|
||||
if(!choice)
|
||||
return TOPIC_REFRESH // No choice? Don't reset our selection
|
||||
else
|
||||
pref.species_sound = choice
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["cough_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["cough"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["cough"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have cough sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["sneeze_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["sneeze"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["sneeze"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have sneeze sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["scream_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["scream"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["scream"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have scream sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["pain_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["pain"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["pain"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have pain sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["gasp_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["gasp"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["gasp"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have gasp sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["death_test"])
|
||||
var/sound/S
|
||||
var/ourpref = pref.species_sound
|
||||
var/oursound = get_species_sound(ourpref)["death"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "Unset")
|
||||
oursound = get_species_sound(select_default_species_sound(pref))["death"]
|
||||
S = sound(pick(oursound))
|
||||
if(pref.species_sound == "None" || oursound == null)
|
||||
to_chat(user, span_warning("This set does not have death sounds!"))
|
||||
return TOPIC_REFRESH
|
||||
S.frequency = pick(pref.voice_freq)
|
||||
S.volume = 20
|
||||
SEND_SOUND(user, S)
|
||||
return TOPIC_REFRESH
|
||||
return ..();
|
||||
|
||||
#undef WEIGHT_CHANGE_MIN
|
||||
#undef WEIGHT_CHANGE_MAX
|
||||
@@ -1,76 +0,0 @@
|
||||
// Define a place to save appearance in character setup
|
||||
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
|
||||
#define AUTOHISS_OFF 0
|
||||
#define AUTOHISS_BASIC 1
|
||||
#define AUTOHISS_FULL 2
|
||||
// VOREStation Add End
|
||||
|
||||
/datum/preferences
|
||||
var/vore_egg_type = "Egg" //The egg type they have.
|
||||
var/autohiss = "Full" // VOREStation Add: Whether we have Autohiss on. I'm hijacking the egg panel bc this one has a shitton of unused space.
|
||||
|
||||
// Definition of the stuff for the egg type.
|
||||
/datum/category_item/player_setup_item/vore/egg
|
||||
name = "Egg appearance."
|
||||
sort_order = 3
|
||||
|
||||
/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(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, GLOB.global_vore_egg_types, initial(pref.vore_egg_type))
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.vore_egg_type = pref.vore_egg_type
|
||||
// VOREStation Add
|
||||
if(pref.client) // Safety, just in case so we don't runtime.
|
||||
if(!pref.autohiss)
|
||||
pref.client.autohiss_mode = AUTOHISS_FULL
|
||||
else
|
||||
switch(pref.autohiss)
|
||||
if("Full")
|
||||
pref.client.autohiss_mode = AUTOHISS_FULL
|
||||
if("Basic")
|
||||
pref.client.autohiss_mode = AUTOHISS_BASIC
|
||||
if("Off")
|
||||
pref.client.autohiss_mode = AUTOHISS_OFF
|
||||
// VOREStation Add
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/content(var/mob/user)
|
||||
. += "<br>"
|
||||
. += " Egg Type: <a href='byond://?src=\ref[src];vore_egg_type=1'>[pref.vore_egg_type]</a><br>"
|
||||
. += span_bold("Autohiss Default Setting:") + " <a href='byond://?src=\ref[src];autohiss=1'>[pref.autohiss]</a><br>" // VOREStation Add
|
||||
|
||||
/datum/category_item/player_setup_item/vore/egg/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(!CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
else if(href_list["vore_egg_type"])
|
||||
var/list/vore_egg_types = GLOB.global_vore_egg_types
|
||||
var/selection = tgui_input_list(user, "Choose your character's egg type:", "Character Preference", vore_egg_types, pref.vore_egg_type)
|
||||
if(selection)
|
||||
pref.vore_egg_type = selection
|
||||
return TOPIC_REFRESH
|
||||
// VOREStation Add Start
|
||||
else if(href_list["autohiss"])
|
||||
var/list/autohiss_selection = list("Full", "Basic", "Off")
|
||||
var/selection = tgui_input_list(user, "Choose your default autohiss setting:", "Character Preference", autohiss_selection, pref.autohiss)
|
||||
if(selection)
|
||||
pref.autohiss = selection
|
||||
else if(!selection)
|
||||
pref.autohiss = "Full"
|
||||
return TOPIC_REFRESH
|
||||
// VOREStation Add End
|
||||
else
|
||||
return
|
||||
|
||||
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
|
||||
#undef AUTOHISS_OFF
|
||||
#undef AUTOHISS_BASIC
|
||||
#undef AUTOHISS_FULL
|
||||
// VOREStation Add End
|
||||
@@ -1,60 +0,0 @@
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/resleeve_lock = 0 // Whether movs should have OOC reslieving protection. Default false.
|
||||
var/resleeve_scan = 1 // Whether mob should start with a pre-spawn body scan. Default true.
|
||||
var/mind_scan = 1 // Whether mob should start with a pre-spawn mind scan. Default true.
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/vore/resleeve
|
||||
name = "Resleeving"
|
||||
sort_order = 4
|
||||
|
||||
/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(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))
|
||||
pref.resleeve_scan = sanitize_integer(pref.resleeve_scan, 0, 1, initial(pref.resleeve_scan))
|
||||
pref.mind_scan = sanitize_integer(pref.mind_scan, 0, 1, initial(pref.mind_scan))
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(character && !istype(character,/mob/living/carbon/human/dummy))
|
||||
spawn(50)
|
||||
if(QDELETED(character) || QDELETED(pref))
|
||||
return // They might have been deleted during the wait
|
||||
if(!character.virtual_reality_mob && !(/mob/living/carbon/human/proc/perform_exit_vr in character.verbs)) //Janky fix to prevent resleeving VR avatars but beats refactoring transcore
|
||||
if(pref.resleeve_scan)
|
||||
var/datum/transhuman/body_record/BR = new()
|
||||
BR.init_from_mob(character, pref.resleeve_scan, pref.resleeve_lock)
|
||||
if(pref.mind_scan)
|
||||
var/datum/transcore_db/our_db = SStranscore.db_by_key(null)
|
||||
if(our_db)
|
||||
our_db.m_backup(character.mind,character.nif,one_time = TRUE)
|
||||
if(pref.resleeve_lock)
|
||||
character.resleeve_lock = character.ckey
|
||||
character.original_player = character.ckey
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/content(var/mob/user)
|
||||
. += "<br>"
|
||||
. += span_bold("Start With Body Scan:") + " <a [pref.resleeve_scan ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_resleeve_scan=1'><b>[pref.resleeve_scan ? "Yes" : "No"]</b></a><br>"
|
||||
. += span_bold("Start With Mind Scan:") + " <a [pref.mind_scan ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_mind_scan=1'><b>[pref.mind_scan ? "Yes" : "No"]</b></a><br>"
|
||||
. += span_bold("Prevent Body Impersonation:") + " <a [pref.resleeve_lock ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_resleeve_lock=1'><b>[pref.resleeve_lock ? "Yes" : "No"]</b></a><br>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/resleeve/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["toggle_resleeve_lock"])
|
||||
pref.resleeve_lock = pref.resleeve_lock ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_resleeve_scan"])
|
||||
pref.resleeve_scan = pref.resleeve_scan ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_mind_scan"])
|
||||
pref.mind_scan = pref.mind_scan ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
return ..();
|
||||
@@ -1,63 +0,0 @@
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/persistence_settings = PERSIST_DEFAULT // Control what if anything is persisted for this character between rounds.
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/vore/persistence
|
||||
name = "Persistence"
|
||||
sort_order = 5
|
||||
|
||||
/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(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))
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/content(var/mob/user)
|
||||
. = list()
|
||||
. += span_bold("Round-to-Round Persistence") + "<br>"
|
||||
. += "<table>"
|
||||
|
||||
. += "<tr><td title=\"Set spawn location based on where you cryo'd out.\">Save Spawn Location: </td>"
|
||||
. += make_yesno(PERSIST_SPAWN)
|
||||
. += "</tr>"
|
||||
|
||||
. += "<tr><td title=\"Save your character's weight until next round.\">Save Weight: </td>"
|
||||
. += make_yesno(PERSIST_WEIGHT)
|
||||
. += "</tr>"
|
||||
|
||||
. += "<tr><td title=\"Update organ preferences (normal/amputated/robotic/etc) and model (for robotic) based on what you have at round end.\">Save Organs: </td>"
|
||||
. += make_yesno(PERSIST_ORGANS)
|
||||
. += "</tr>"
|
||||
|
||||
. += "<tr><td title=\"Update marking preferences (type and color) based on what you have at round end.\">Save Markings: </td>"
|
||||
. += make_yesno(PERSIST_MARKINGS)
|
||||
. += "</tr>"
|
||||
|
||||
. += "<tr><td title=\"Update character scale based on what you were at round end.\">Save Scale: </td>"
|
||||
. += make_yesno(PERSIST_SIZE)
|
||||
. += "</tr>"
|
||||
|
||||
. += "</table>"
|
||||
return jointext(., "")
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/proc/make_yesno(var/bit)
|
||||
if(pref.persistence_settings & bit)
|
||||
return "<td>" + span_linkOn(span_bold("Yes")) + "</td> <td><a href='byond://?src=\ref[src];toggle_off=[bit]'>No</a></td>"
|
||||
else
|
||||
return "<td><a href='byond://?src=\ref[src];toggle_on=[bit]'>Yes</a></td> <td>" + span_linkOn(span_bold("No")) + "</td>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/persistence/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["toggle_on"])
|
||||
var/bit = text2num(href_list["toggle_on"])
|
||||
pref.persistence_settings |= bit
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_off"])
|
||||
var/bit = text2num(href_list["toggle_off"])
|
||||
pref.persistence_settings &= ~bit
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
@@ -1,48 +0,0 @@
|
||||
// Define a place to save in character setup
|
||||
/datum/preferences
|
||||
var/vantag_volunteer = 0 // What state I want to be in, in terms of being affected by antags.
|
||||
var/vantag_preference = VANTAG_NONE // Whether I'd like to volunteer to be an antag at some point.
|
||||
|
||||
// Definition of the stuff for Sizing
|
||||
/datum/category_item/player_setup_item/vore/vantag
|
||||
name = "VS Events"
|
||||
sort_order = 6
|
||||
|
||||
/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(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))
|
||||
pref.vantag_preference = sanitize_inlist(pref.vantag_preference, GLOB.vantag_choices_list, initial(pref.vantag_preference))
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(character && !istype(character,/mob/living/carbon/human/dummy))
|
||||
character.vantag_pref = pref.vantag_preference
|
||||
BITSET(character.hud_updateflag, VANTAG_HUD)
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/content(var/mob/user)
|
||||
. += "<br>"
|
||||
. += span_bold("Event Volunteer:") + " <a [pref.vantag_volunteer ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_vantag_volunteer=1'>" + span_bold("[pref.vantag_volunteer ? "Yes" : "No"]") + "</a><br>"
|
||||
. += span_bold("Event Pref:") + " <a href='byond://?src=\ref[src];change_vantag=1'>" + span_bold("[GLOB.vantag_choices_list[pref.vantag_preference]]") + "</a><br>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/vantag/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["toggle_vantag_volunteer"])
|
||||
pref.vantag_volunteer = pref.vantag_volunteer ? 0 : 1
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["change_vantag"])
|
||||
var/list/names_list = list()
|
||||
for(var/C in GLOB.vantag_choices_list)
|
||||
names_list[GLOB.vantag_choices_list[C]] = C
|
||||
|
||||
var/selection = tgui_input_list(user, "How do you want to be involved with VS Event Characters, ERP-wise? They will see this choice on you in a HUD. Event characters are admin-selected and spawned players, possibly with assigned objectives, who are obligated to respect ERP prefs and RP their actions like any other player, though it may be a slightly shorter RP if they are pressed for time or being caught.", "Event Preference", names_list)
|
||||
if(selection && selection != "Normal")
|
||||
pref.vantag_preference = names_list[selection]
|
||||
|
||||
return TOPIC_REFRESH
|
||||
return ..()
|
||||
@@ -1,651 +0,0 @@
|
||||
#define POSITIVE_MODE 1
|
||||
#define NEUTRAL_MODE 2
|
||||
#define NEGATIVE_MODE 3
|
||||
|
||||
var/global/list/valid_bloodreagents = list("default",REAGENT_ID_IRON,REAGENT_ID_COPPER,REAGENT_ID_PHORON,REAGENT_ID_SILVER,REAGENT_ID_GOLD,REAGENT_ID_SLIMEJELLY) //allowlist-based so people don't make their blood restored by alcohol or something really silly. use reagent IDs!
|
||||
|
||||
/datum/preferences
|
||||
var/custom_species // Custom species name, can't be changed due to it having been used in savefiles already.
|
||||
var/custom_base // What to base the custom species on
|
||||
var/blood_color = "#A10808"
|
||||
|
||||
var/custom_say = null
|
||||
var/custom_whisper = null
|
||||
var/custom_ask = null
|
||||
var/custom_exclaim = null
|
||||
|
||||
var/list/custom_heat = list()
|
||||
var/list/custom_cold = list()
|
||||
|
||||
var/list/pos_traits = list() // What traits they've selected for their custom species
|
||||
var/list/neu_traits = list()
|
||||
var/list/neg_traits = list()
|
||||
|
||||
var/traits_cheating = 0 //Varedit by admins allows saving new maximums on people who apply/etc
|
||||
var/starting_trait_points = 0
|
||||
var/max_traits = MAX_SPECIES_TRAITS
|
||||
var/dirty_synth = 0 //Are you a synth
|
||||
var/gross_meatbag = 0 //Where'd I leave my Voight-Kampff test kit?
|
||||
|
||||
/datum/preferences/proc/get_custom_bases_for_species(var/new_species)
|
||||
if (!new_species)
|
||||
new_species = species
|
||||
var/list/choices
|
||||
var/datum/species/spec = GLOB.all_species[new_species]
|
||||
if (spec.selects_bodytype == SELECTS_BODYTYPE_SHAPESHIFTER)
|
||||
choices = spec.get_valid_shapeshifter_forms()
|
||||
choices = choices.Copy()
|
||||
else if (spec.selects_bodytype == SELECTS_BODYTYPE_CUSTOM)
|
||||
choices = GLOB.custom_species_bases.Copy()
|
||||
if(new_species != SPECIES_CUSTOM)
|
||||
choices = (choices | new_species)
|
||||
return choices
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/proc/get_html_for_trait(var/datum/trait/trait, var/list/trait_prefs = null)
|
||||
. = ""
|
||||
if (!LAZYLEN(trait.has_preferences))
|
||||
return
|
||||
. = "<br><ul>"
|
||||
var/altered = FALSE
|
||||
if (!LAZYLEN(trait_prefs))
|
||||
trait_prefs = trait.get_default_prefs()
|
||||
altered = TRUE
|
||||
for (var/identifier in trait.has_preferences)
|
||||
var/pref_list = trait.has_preferences[identifier] //faster
|
||||
if (LAZYLEN(pref_list) >= 2)
|
||||
if (!(identifier in trait_prefs))
|
||||
trait_prefs[identifier] = trait.default_value_for_pref(identifier) //won't be called at all often
|
||||
altered = TRUE
|
||||
. += "<li>- [pref_list[2]]:"
|
||||
var/link = " <a href='byond://?src=\ref[src];clicked_trait_pref=[trait.type];pref=[identifier]'>"
|
||||
switch (pref_list[1])
|
||||
if (1) //TRAIT_PREF_TYPE_BOOLEAN
|
||||
. += link + (trait_prefs[identifier] ? "Enabled" : "Disabled")
|
||||
if (2) //TRAIT_PREF_TYPE_COLOR
|
||||
. += " " + color_square(hex = trait_prefs[identifier]) + link + "Change"
|
||||
if (3) //TRAIT_PREF_TYPE_STRING
|
||||
var/string = trait_prefs[identifier]
|
||||
. += link + (length(string) > 0 ? string : "\[Empty\]")
|
||||
. += "</a></li>"
|
||||
. += "</ul>"
|
||||
if (altered)
|
||||
switch(trait.category)
|
||||
if (1) //TRAIT_TYPE_POSITIVE
|
||||
pref.pos_traits[trait.type] = trait_prefs
|
||||
if (0) //TRAIT_TYPE_NEUTRAL
|
||||
pref.neu_traits[trait.type] = trait_prefs
|
||||
if (-1)//TRAIT_TYPE_NEGATIVE
|
||||
pref.neg_traits[trait.type] = trait_prefs
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/proc/get_pref_choice_from_trait(var/mob/user, var/datum/trait/trait, var/preference)
|
||||
if (!trait || !preference)
|
||||
return
|
||||
var/list/trait_prefs
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
var/list/traitlist
|
||||
switch(instance.category)
|
||||
if (1)
|
||||
traitlist = pref.pos_traits
|
||||
if (0)
|
||||
traitlist = pref.neu_traits
|
||||
if (-1)
|
||||
traitlist = pref.neg_traits
|
||||
if (!LAZYLEN(instance.has_preferences) || !(preference in instance.has_preferences) || !traitlist)
|
||||
return
|
||||
if (!LAZYLEN(traitlist[trait]))
|
||||
traitlist[trait] = instance.get_default_prefs()
|
||||
trait_prefs = traitlist[trait]
|
||||
if (!(preference in trait_prefs))
|
||||
trait_prefs[preference] = instance.default_value_for_pref(preference) //won't be called at all often
|
||||
switch(instance.has_preferences[preference][1])
|
||||
if (1) //TRAIT_PREF_TYPE_BOOLEAN
|
||||
trait_prefs[preference] = !trait_prefs[preference]
|
||||
if (2) //TRAIT_PREF_TYPE_COLOR
|
||||
var/new_color = tgui_color_picker(user, "Choose the color for this trait preference:", "Trait Preference", trait_prefs[preference])
|
||||
if (new_color)
|
||||
trait_prefs[preference] = new_color
|
||||
if (3) //TRAIT_PREF_TYPE_STRING
|
||||
var/new_string = instance.apply_sanitization_to_string(preference, tgui_input_text(user, "What should the new value be?", instance.has_preferences[preference][2], trait_prefs[preference], MAX_NAME_LEN))
|
||||
trait_prefs[preference] = new_string
|
||||
|
||||
// Definition of the stuff for Ears
|
||||
/datum/category_item/player_setup_item/vore/traits
|
||||
name = "Traits"
|
||||
sort_order = 7
|
||||
|
||||
/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"]
|
||||
|
||||
pref.traits_cheating = save_data["traits_cheating"]
|
||||
pref.max_traits = save_data["max_traits"]
|
||||
pref.starting_trait_points = save_data["trait_points"]
|
||||
|
||||
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"]
|
||||
|
||||
pref.custom_heat = check_list_copy(save_data["custom_heat"])
|
||||
pref.custom_cold = check_list_copy(save_data["custom_cold"])
|
||||
|
||||
/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"] = check_list_copy(pref.pos_traits)
|
||||
save_data["neu_traits"] = check_list_copy(pref.neu_traits)
|
||||
save_data["neg_traits"] = check_list_copy(pref.neg_traits)
|
||||
save_data["blood_color"] = pref.blood_color
|
||||
save_data["blood_reagents"] = pref.blood_reagents
|
||||
|
||||
save_data["traits_cheating"] = pref.traits_cheating
|
||||
save_data["max_traits"] = pref.max_traits
|
||||
save_data["trait_points"] = pref.starting_trait_points
|
||||
|
||||
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
|
||||
|
||||
save_data["custom_heat"] = check_list_copy(pref.custom_heat)
|
||||
save_data["custom_cold"] = check_list_copy(pref.custom_cold)
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/sanitize_character()
|
||||
if(!pref.pos_traits) pref.pos_traits = list()
|
||||
if(!pref.neu_traits) pref.neu_traits = list()
|
||||
if(!pref.neg_traits) pref.neg_traits = list()
|
||||
|
||||
pref.blood_color = sanitize_hexcolor(pref.blood_color, default="#A10808")
|
||||
pref.blood_reagents = sanitize_text(pref.blood_reagents, initial(pref.blood_reagents))
|
||||
|
||||
if(!pref.traits_cheating)
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
if(S)
|
||||
pref.starting_trait_points = S.trait_points
|
||||
else
|
||||
pref.starting_trait_points = 0
|
||||
pref.max_traits = MAX_SPECIES_TRAITS
|
||||
|
||||
if(pref.organ_data[O_BRAIN]) //Checking if we have a synth on our hands, boys.
|
||||
pref.dirty_synth = 1
|
||||
pref.gross_meatbag = 0
|
||||
else
|
||||
pref.gross_meatbag = 1
|
||||
pref.dirty_synth = 0
|
||||
|
||||
// Clean up positive traits
|
||||
for(var/datum/trait/path as anything in pref.pos_traits)
|
||||
if(!(path in GLOB.positive_traits))
|
||||
pref.pos_traits -= path
|
||||
continue
|
||||
if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_positive))
|
||||
pref.pos_traits -= path
|
||||
continue
|
||||
var/take_flags = initial(path.can_take)
|
||||
if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS)))
|
||||
pref.pos_traits -= path
|
||||
//Neutral traits
|
||||
for(var/datum/trait/path as anything in pref.neu_traits)
|
||||
if(!(path in GLOB.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 GLOB.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)
|
||||
if(!(path in GLOB.negative_traits))
|
||||
pref.neg_traits -= path
|
||||
continue
|
||||
if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_negative))
|
||||
pref.neg_traits -= path
|
||||
continue
|
||||
var/take_flags = initial(path.can_take)
|
||||
if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS)))
|
||||
pref.neg_traits -= path
|
||||
|
||||
var/datum/species/selected_species = GLOB.all_species[pref.species]
|
||||
if(selected_species.selects_bodytype)
|
||||
if (!(pref.custom_base in pref.get_custom_bases_for_species()))
|
||||
pref.custom_base = SPECIES_HUMAN
|
||||
//otherwise, allowed!
|
||||
else if(!pref.custom_base || !(pref.custom_base in GLOB.custom_species_bases))
|
||||
pref.custom_base = SPECIES_HUMAN
|
||||
|
||||
pref.custom_say = lowertext(trim(pref.custom_say))
|
||||
pref.custom_whisper = lowertext(trim(pref.custom_whisper))
|
||||
pref.custom_ask = lowertext(trim(pref.custom_ask))
|
||||
pref.custom_exclaim = lowertext(trim(pref.custom_exclaim))
|
||||
|
||||
if (islist(pref.custom_heat)) //don't bother checking these for actual singular message length, they should already have been checked and it'd take too long every time it's sanitized
|
||||
if (length(pref.custom_heat) > 10)
|
||||
pref.custom_heat.Cut(11)
|
||||
else
|
||||
pref.custom_heat = list()
|
||||
if (islist(pref.custom_cold))
|
||||
if (length(pref.custom_cold) > 10)
|
||||
pref.custom_cold.Cut(11)
|
||||
else
|
||||
pref.custom_cold = list()
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.custom_species = pref.custom_species
|
||||
character.custom_say = lowertext(trim(pref.custom_say))
|
||||
character.custom_ask = lowertext(trim(pref.custom_ask))
|
||||
character.custom_whisper = lowertext(trim(pref.custom_whisper))
|
||||
character.custom_exclaim = lowertext(trim(pref.custom_exclaim))
|
||||
character.custom_heat = pref.custom_heat
|
||||
character.custom_cold = pref.custom_cold
|
||||
|
||||
|
||||
if(character.isSynthetic()) //Checking if we have a synth on our hands, boys.
|
||||
pref.dirty_synth = 1
|
||||
pref.gross_meatbag = 0
|
||||
else
|
||||
pref.gross_meatbag = 1
|
||||
pref.dirty_synth = 0
|
||||
|
||||
var/datum/species/S = character.species
|
||||
var/datum/species/new_S = S.produceCopy(pref.pos_traits + pref.neu_traits + pref.neg_traits, character, pref.custom_base, TRUE)
|
||||
|
||||
for(var/datum/trait/T in new_S.traits)
|
||||
T.apply_pref(src)
|
||||
|
||||
//Any additional non-trait settings can be applied here
|
||||
new_S.blood_color = pref.blood_color
|
||||
if(!(pref.blood_reagents == "default"))
|
||||
new_S.blood_reagents = pref.blood_reagents
|
||||
|
||||
//Any additional non-trait settings can be applied here
|
||||
new_S.blood_color = pref.blood_color
|
||||
|
||||
var/species_sounds_to_copy = pref.species_sound // What sounds are we using?
|
||||
if(species_sounds_to_copy == "Unset") // Are we unset?
|
||||
species_sounds_to_copy = select_default_species_sound(pref) // This will also grab gendered versions of the sounds, if they exist.
|
||||
|
||||
new_S.species_sounds = species_sounds_to_copy // Now we send our sounds over to the mob
|
||||
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
//Statistics for this would be nice
|
||||
var/english_traits = english_list(new_S.traits, and_text = ";", comma_text = ";")
|
||||
log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/content(var/mob/user)
|
||||
. += span_bold("Custom Species Name:") + " "
|
||||
. += "<a href='byond://?src=\ref[src];custom_species=1'>[pref.custom_species ? pref.custom_species : "-Input Name-"]</a><br>"
|
||||
|
||||
var/datum/species/selected_species = GLOB.all_species[pref.species]
|
||||
if(selected_species.selects_bodytype)
|
||||
. += span_bold("Icon Base:") + " "
|
||||
. += "<a href='byond://?src=\ref[src];custom_base=1'>[pref.custom_base ? pref.custom_base : "Human"]</a><br>"
|
||||
|
||||
var/traits_left = pref.max_traits
|
||||
|
||||
|
||||
var/points_left = pref.starting_trait_points
|
||||
|
||||
|
||||
for(var/T in pref.pos_traits + pref.neg_traits)
|
||||
points_left -= GLOB.traits_costs[T]
|
||||
if(T in pref.pos_traits)
|
||||
traits_left--
|
||||
. += span_bold("Traits Left:") + " [traits_left]<br>"
|
||||
. += span_bold("Points Left:") + " [points_left]<br>"
|
||||
if(points_left < 0 || traits_left < 0 || (!pref.custom_species && pref.species == SPECIES_CUSTOM))
|
||||
. += span_red(span_bold("^ Fix things! ^")) + "<br>"
|
||||
|
||||
. += "<a href='byond://?src=\ref[src];add_trait=[POSITIVE_MODE]'>Positive Trait(s) (Limited) +</a><br>"
|
||||
. += "<ul>"
|
||||
for(var/T in pref.pos_traits)
|
||||
var/datum/trait/trait = GLOB.positive_traits[T]
|
||||
. += "<li>- <a href='byond://?src=\ref[src];clicked_pos_trait=[T]'>[trait.name] ([trait.cost])</a> [get_html_for_trait(trait, pref.pos_traits[T])]</li>"
|
||||
. += "</ul>"
|
||||
|
||||
. += "<a href='byond://?src=\ref[src];add_trait=[NEUTRAL_MODE]'>Neutral Trait(s) (No Limit) +</a><br>"
|
||||
. += "<ul>"
|
||||
for(var/T in pref.neu_traits)
|
||||
var/datum/trait/trait = GLOB.neutral_traits[T]
|
||||
. += "<li>- <a href='byond://?src=\ref[src];clicked_neu_trait=[T]'>[trait.name] ([trait.cost])</a> [get_html_for_trait(trait, pref.neu_traits[T])]</li>"
|
||||
. += "</ul>"
|
||||
|
||||
. += "<a href='byond://?src=\ref[src];add_trait=[NEGATIVE_MODE]'>Negative Trait(s) (No Limit) +</a><br>"
|
||||
. += "<ul>"
|
||||
for(var/T in pref.neg_traits)
|
||||
var/datum/trait/trait = GLOB.negative_traits[T]
|
||||
. += "<li>- <a href='byond://?src=\ref[src];clicked_neg_trait=[T]'>[trait.name] ([trait.cost])</a> [get_html_for_trait(trait, pref.neg_traits[T])]</li>"
|
||||
. += "</ul>"
|
||||
|
||||
. += span_bold("Blood Color: ") //People that want to use a certain species to have that species traits (xenochimera/promethean/spider) should be able to set their own blood color.
|
||||
. += "<a href='byond://?src=\ref[src];blood_color=1'>Set Color <font color='[pref.blood_color]'>⚫</font></a>"
|
||||
. += "<a href='byond://?src=\ref[src];blood_reset=1'>R</a><br>"
|
||||
. += span_bold("Blood Reagent: ") //Wanna be copper-based? Go ahead.
|
||||
. += "<a href='byond://?src=\ref[src];blood_reagents=1'>[pref.blood_reagents]</a><br>"
|
||||
. += "<br>"
|
||||
|
||||
. += span_bold("Custom Say: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_say=1'>Set Say Verb</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_say=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Custom Whisper: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_whisper=1'>Set Whisper Verb</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_whisper=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Custom Ask: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_ask=1'>Set Ask Verb</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_ask=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Custom Exclaim: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_exclaim=1'>Set Exclaim Verb</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_exclaim=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Custom Heat Discomfort: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_heat=1'>Set Heat Messages</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_heat=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
. += span_bold("Custom Cold Discomfort: ")
|
||||
. += "<a href='byond://?src=\ref[src];custom_cold=1'>Set Cold Messages</a>"
|
||||
. += "(<a href='byond://?src=\ref[src];reset_cold=1'>Reset</A>)"
|
||||
. += "<br>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/traits/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(!CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
else if(href_list["custom_species"])
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Input your custom species name:",
|
||||
"Character Preference", pref.custom_species, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if (CanUseTopic(user))
|
||||
pref.custom_species = raw_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_base"])
|
||||
var/list/choices = pref.get_custom_bases_for_species()
|
||||
var/text_choice = tgui_input_list(user, "Pick an icon set for your species:","Icon Base", choices)
|
||||
if(text_choice in choices)
|
||||
pref.custom_base = text_choice
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["blood_color"])
|
||||
var/color_choice = tgui_color_picker(user, "Pick a blood color (does not apply to synths)","Blood Color",pref.blood_color)
|
||||
if(color_choice)
|
||||
pref.blood_color = sanitize_hexcolor(color_choice, default="#A10808")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["blood_reset"])
|
||||
var/datum/species/spec = GLOB.all_species[pref.species]
|
||||
var/new_blood = spec.blood_color ? spec.blood_color : "#A10808"
|
||||
var/choice = tgui_alert(user, "Reset blood color to species default ([new_blood])?","Reset Blood Color",list("Reset","Cancel"))
|
||||
if(choice == "Reset")
|
||||
pref.blood_color = new_blood
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["blood_reagents"])
|
||||
var/new_blood_reagents = tgui_input_list(user, "Choose your character's blood restoration reagent:", "Character Preference", valid_bloodreagents)
|
||||
if(new_blood_reagents && CanUseTopic(user))
|
||||
pref.blood_reagents = new_blood_reagents
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["clicked_pos_trait"])
|
||||
var/datum/trait/trait = text2path(href_list["clicked_pos_trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)] and regain [initial(trait.cost)] points?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.pos_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["clicked_neu_trait"])
|
||||
var/datum/trait/trait = text2path(href_list["clicked_neu_trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)]?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.neu_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["clicked_neg_trait"])
|
||||
var/datum/trait/trait = text2path(href_list["clicked_neg_trait"])
|
||||
var/choice = tgui_alert(user, "Remove [initial(trait.name)] and lose [initial(trait.cost)] points?","Remove Trait",list("Remove","Cancel"))
|
||||
if(choice == "Remove")
|
||||
pref.neg_traits -= trait
|
||||
var/datum/trait/instance = GLOB.all_traits[trait]
|
||||
instance.remove_pref(pref)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["clicked_trait_pref"])
|
||||
var/datum/trait/trait = text2path(href_list["clicked_trait_pref"])
|
||||
get_pref_choice_from_trait(user, trait, href_list["pref"])
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_say"])
|
||||
var/say_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'says': [pref.real_name] says, \"Hi.\"", "Custom Say", pref.custom_say, 12), 12)
|
||||
if(say_choice)
|
||||
pref.custom_say = say_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_whisper"])
|
||||
var/whisper_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'whispers': [pref.real_name] whispers, \"Hi...\"", "Custom Whisper", pref.custom_whisper, 12), 12)
|
||||
if(whisper_choice)
|
||||
pref.custom_whisper = whisper_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_ask"])
|
||||
var/ask_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'asks': [pref.real_name] asks, \"Hi?\"", "Custom Ask", pref.custom_ask, 12), 12)
|
||||
if(ask_choice)
|
||||
pref.custom_ask = ask_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_exclaim"])
|
||||
var/exclaim_choice = sanitize(tgui_input_text(user, "This word or phrase will appear instead of 'exclaims', 'shouts' or 'yells': [pref.real_name] exclaims, \"Hi!\"", "Custom Exclaim", pref.custom_exclaim, 12), 12)
|
||||
if(exclaim_choice)
|
||||
pref.custom_exclaim = exclaim_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_heat"])
|
||||
tgui_alert(user, "You are setting custom heat messages. These will overwrite your species' defaults. To return to defaults, click reset.")
|
||||
var/old_message = pref.custom_heat.Join("\n\n")
|
||||
var/new_message = sanitize(tgui_input_text(user,"Use double enter between messages to enter a new one. Must be at least 3 characters long, 160 characters max and up to 10 messages are allowed.","Heat Discomfort messages",old_message, multiline= TRUE, prevent_enter = TRUE), MAX_MESSAGE_LEN,0,0,0)
|
||||
if(length(new_message) > 0)
|
||||
var/list/raw_list = splittext(new_message,"\n\n")
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) < 3 || length(raw_list[i]) > 160)
|
||||
raw_list.Cut(i,i)
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
ASSERT(raw_list.len <= 10)
|
||||
pref.custom_heat = raw_list
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["custom_cold"])
|
||||
tgui_alert(user, "You are setting custom cold messages. These will overwrite your species' defaults. To return to defaults, click reset.")
|
||||
var/old_message = pref.custom_heat.Join("\n\n")
|
||||
var/new_message = sanitize(tgui_input_text(user,"Use double enter between messages to enter a new one. Must be at least 3 characters long, 160 characters max and up to 10 messages are allowed.","Cold Discomfort messages",old_message, multiline= TRUE, prevent_enter = TRUE), MAX_MESSAGE_LEN,0,0,0)
|
||||
if(length(new_message) > 0)
|
||||
var/list/raw_list = splittext(new_message,"\n\n")
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) < 3 || length(raw_list[i]) > 160)
|
||||
raw_list.Cut(i,i)
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
ASSERT(raw_list.len <= 10)
|
||||
pref.custom_cold = raw_list
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_say"])
|
||||
var/say_choice = tgui_alert(user, "Reset your Custom Say Verb?","Reset Verb",list("Yes","No"))
|
||||
if(say_choice == "Yes")
|
||||
pref.custom_say = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_whisper"])
|
||||
var/whisper_choice = tgui_alert(user, "Reset your Custom Whisper Verb?","Reset Verb",list("Yes","No"))
|
||||
if(whisper_choice == "Yes")
|
||||
pref.custom_whisper = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_ask"])
|
||||
var/ask_choice = tgui_alert(user, "Reset your Custom Ask Verb?","Reset Verb",list("Yes","No"))
|
||||
if(ask_choice == "Yes")
|
||||
pref.custom_ask = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_exclaim"])
|
||||
var/exclaim_choice = tgui_alert(user, "Reset your Custom Exclaim Verb?","Reset Verb",list("Yes","No"))
|
||||
if(exclaim_choice == "Yes")
|
||||
pref.custom_exclaim = null
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_cold"])
|
||||
var/cold_choice = tgui_alert(user, "Reset your Custom Cold Discomfort messages?", "Reset Discomfort",list("Yes","No"))
|
||||
if(cold_choice == "Yes")
|
||||
pref.custom_cold = list()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["reset_heat"])
|
||||
var/heat_choice = tgui_alert(user, "Reset your Custom Heat Discomfort messages?", "Reset Discomfort",list("Yes","No"))
|
||||
if(heat_choice == "Yes")
|
||||
pref.custom_heat = list()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
else if(href_list["add_trait"])
|
||||
var/mode = text2num(href_list["add_trait"])
|
||||
var/list/picklist
|
||||
var/list/mylist
|
||||
switch(mode)
|
||||
if(POSITIVE_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.positive_traits.Copy() - pref.pos_traits
|
||||
mylist = pref.pos_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_positive.Copy() - pref.pos_traits
|
||||
mylist = pref.pos_traits
|
||||
if(NEUTRAL_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.neutral_traits.Copy() - pref.neu_traits
|
||||
mylist = pref.neu_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_neutral.Copy() - pref.neu_traits
|
||||
mylist = pref.neu_traits
|
||||
if(NEGATIVE_MODE)
|
||||
if(pref.species == SPECIES_CUSTOM)
|
||||
picklist = GLOB.negative_traits.Copy() - pref.neg_traits
|
||||
mylist = pref.neg_traits
|
||||
else
|
||||
picklist = GLOB.everyone_traits_negative.Copy() - pref.neg_traits
|
||||
mylist = pref.neg_traits
|
||||
|
||||
if(isnull(picklist))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(isnull(mylist))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
var/list/nicelist = list()
|
||||
for(var/P in picklist)
|
||||
var/datum/trait/T = picklist[P]
|
||||
nicelist[T.name] = P
|
||||
|
||||
var/points_left = pref.starting_trait_points
|
||||
for(var/T in pref.pos_traits + pref.neu_traits + pref.neg_traits)
|
||||
points_left -= GLOB.traits_costs[T]
|
||||
|
||||
var/traits_left = pref.max_traits - pref.pos_traits.len
|
||||
|
||||
var/message = "Select a trait to learn more."
|
||||
if(mode != NEUTRAL_MODE)
|
||||
message = "\[Remaining: [points_left] points, [traits_left] traits\]\n" + message
|
||||
var/title = "Traits"
|
||||
switch(mode)
|
||||
if(POSITIVE_MODE)
|
||||
title = "Positive Traits"
|
||||
if(NEUTRAL_MODE)
|
||||
title = "Neutral Traits"
|
||||
if(NEGATIVE_MODE)
|
||||
title = "Negative Traits"
|
||||
|
||||
var/trait_choice
|
||||
var/done = FALSE
|
||||
while(!done)
|
||||
trait_choice = tgui_input_list(user, message, title, nicelist)
|
||||
if(!trait_choice)
|
||||
done = TRUE
|
||||
if(trait_choice in nicelist)
|
||||
var/datum/trait/path = nicelist[trait_choice]
|
||||
var/choice = tgui_alert(user, "\[Cost:[initial(path.cost)]\] [initial(path.desc)]",initial(path.name), list("Take Trait","Go Back"))
|
||||
if(choice == "Take Trait")
|
||||
done = TRUE
|
||||
|
||||
if(!trait_choice)
|
||||
return TOPIC_REFRESH
|
||||
else if(trait_choice in nicelist)
|
||||
var/datum/trait/path = nicelist[trait_choice]
|
||||
var/datum/trait/instance = GLOB.all_traits[path]
|
||||
|
||||
var/conflict = FALSE
|
||||
|
||||
if(pref.dirty_synth && !(instance.can_take & SYNTHETICS))
|
||||
tgui_alert_async(user, "The trait you've selected can only be taken by organic characters!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(pref.gross_meatbag && !(instance.can_take & ORGANICS))
|
||||
tgui_alert_async(user, "The trait you've selected can only be taken by synthetic characters!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(pref.species in instance.banned_species)
|
||||
tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if( LAZYLEN(instance.allowed_species) && !(pref.species in instance.allowed_species))
|
||||
tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(trait_choice in (pref.pos_traits + pref.neu_traits + pref.neg_traits))
|
||||
conflict = instance.name
|
||||
|
||||
varconflict:
|
||||
for(var/P in (pref.pos_traits + pref.neu_traits + pref.neg_traits))
|
||||
var/datum/trait/instance_test = GLOB.all_traits[P]
|
||||
if(path in instance_test.excludes)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
for(var/V in instance.var_changes)
|
||||
if(V == "flags")
|
||||
continue
|
||||
if(V in instance_test.var_changes)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
for(var/V in instance.var_changes_pref)
|
||||
if(V in instance_test.var_changes_pref)
|
||||
conflict = instance_test.name
|
||||
break varconflict
|
||||
|
||||
if(conflict)
|
||||
tgui_alert_async(user, "You cannot take this trait and [conflict] at the same time. Please remove that trait, or pick another trait to add.", "Error")
|
||||
return TOPIC_REFRESH
|
||||
|
||||
instance.apply_pref(pref)
|
||||
mylist[path] = instance.get_default_prefs()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
return ..()
|
||||
|
||||
#undef POSITIVE_MODE
|
||||
#undef NEUTRAL_MODE
|
||||
#undef NEGATIVE_MODE
|
||||
@@ -1,115 +0,0 @@
|
||||
/datum/category_item/player_setup_item/vore/misc
|
||||
name = "Misc Settings"
|
||||
sort_order = 9
|
||||
|
||||
/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"]
|
||||
pref.directory_gendertag = save_data["directory_gendertag"]
|
||||
pref.directory_sexualitytag = save_data["directory_sexualitytag"]
|
||||
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"]
|
||||
|
||||
/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
|
||||
save_data["directory_gendertag"] = pref.directory_gendertag
|
||||
save_data["directory_sexualitytag"] = pref.directory_sexualitytag
|
||||
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
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
if(pref.sensorpref > 5 || pref.sensorpref < 1)
|
||||
pref.sensorpref = 5
|
||||
character.sensorpref = pref.sensorpref
|
||||
character.capture_crystal = pref.capture_crystal
|
||||
//Vore Stomach Sprite Preference
|
||||
character.recalculate_vis()
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/sanitize_character()
|
||||
pref.show_in_directory = sanitize_integer(pref.show_in_directory, 0, 1, initial(pref.show_in_directory))
|
||||
pref.directory_tag = sanitize_inlist(pref.directory_tag, GLOB.char_directory_tags, initial(pref.directory_tag))
|
||||
pref.directory_gendertag = sanitize_inlist(pref.directory_gendertag, GLOB.char_directory_gendertags, initial(pref.directory_gendertag))
|
||||
pref.directory_sexualitytag = sanitize_inlist(pref.directory_sexualitytag, GLOB.char_directory_sexualitytags, initial(pref.directory_sexualitytag))
|
||||
pref.directory_erptag = sanitize_inlist(pref.directory_erptag, GLOB.char_directory_erptags, initial(pref.directory_erptag))
|
||||
pref.sensorpref = sanitize_integer(pref.sensorpref, 1, GLOB.sensorpreflist.len, initial(pref.sensorpref))
|
||||
pref.capture_crystal = sanitize_integer(pref.capture_crystal, 0, 1, initial(pref.capture_crystal))
|
||||
pref.auto_backup_implant = sanitize_integer(pref.auto_backup_implant, 0, 1, initial(pref.auto_backup_implant))
|
||||
pref.borg_petting = sanitize_integer(pref.borg_petting, 0, 1, initial(pref.borg_petting))
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/content(var/mob/user)
|
||||
. += "<br>"
|
||||
. += span_bold("Appear in Character Directory:") + " <a [pref.show_in_directory ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_show_in_directory=1'><b>[pref.show_in_directory ? "Yes" : "No"]</b></a><br>"
|
||||
. += span_bold("Character Directory Vore Tag:") + " <a href='byond://?src=\ref[src];directory_tag=1'><b>[pref.directory_tag]</b></a><br>"
|
||||
. += span_bold("Character Directory Gender:") + " <a href='byond://?src=\ref[src];directory_gendertag=1'><b>[pref.directory_gendertag]</b></a><br>"
|
||||
. += span_bold("Character Directory Sexuality:") + " <a href='byond://?src=\ref[src];directory_sexualitytag=1'><b>[pref.directory_sexualitytag]</b></a><br>"
|
||||
. += span_bold("Character Directory ERP Tag:") + " <a href='byond://?src=\ref[src];directory_erptag=1'><b>[pref.directory_erptag]</b></a><br>"
|
||||
. += span_bold("Character Directory Advertisement:") + " <a href='byond://?src=\ref[src];directory_ad=1'><b>Set Directory Ad</b></a><br>"
|
||||
. += span_bold("Suit Sensors Preference:") + " <a [pref.sensorpref ? "" : ""] href='byond://?src=\ref[src];toggle_sensor_setting=1'><b>[GLOB.sensorpreflist[pref.sensorpref]]</b></a><br>"
|
||||
. += span_bold("Capture Crystal Preference:") + " <a [pref.capture_crystal ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_capture_crystal=1'><b>[pref.capture_crystal ? "Yes" : "No"]</b></a><br>"
|
||||
. += span_bold("Spawn With Backup Implant:") + " <a [pref.auto_backup_implant ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_implant=1'><b>[pref.auto_backup_implant ? "Yes" : "No"]</b></a><br>"
|
||||
. += span_bold("Allow petting as robot:") + " <a [pref.borg_petting ? "class='linkOn'" : ""] href='byond://?src=\ref[src];toggle_borg_petting=1'><b>[pref.borg_petting ? "Yes" : "No"]</b></a><br>"
|
||||
if(CONFIG_GET(flag/allow_metadata))
|
||||
. += span_bold("Private Notes: <a href='byond://?src=\ref[src];edit_private_notes=1'>Edit</a>") + "<br>"
|
||||
|
||||
/datum/category_item/player_setup_item/vore/misc/OnTopic(var/href, var/list/href_list, var/mob/user)
|
||||
if(href_list["toggle_show_in_directory"])
|
||||
pref.show_in_directory = pref.show_in_directory ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["directory_tag"])
|
||||
var/new_tag = tgui_input_list(user, "Pick a new Vore tag for the character directory", "Character Vore Tag", GLOB.char_directory_tags, pref.directory_tag)
|
||||
if(!new_tag)
|
||||
return
|
||||
pref.directory_tag = new_tag
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["directory_gendertag"])
|
||||
var/new_gendertag = tgui_input_list(user, "Pick a new Gender tag for the character directory. This is YOUR gender, not what you prefer.", "Character Gender Tag", GLOB.char_directory_gendertags, pref.directory_gendertag)
|
||||
if(!new_gendertag)
|
||||
return
|
||||
pref.directory_gendertag = new_gendertag
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["directory_sexualitytag"])
|
||||
var/new_sexualitytag = tgui_input_list(user, "Pick a new Sexuality/Orientation tag for the character directory", "Character Sexuality/Orientation Tag", GLOB.char_directory_sexualitytags, pref.directory_sexualitytag)
|
||||
if(!new_sexualitytag)
|
||||
return
|
||||
pref.directory_sexualitytag = new_sexualitytag
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["directory_erptag"])
|
||||
var/new_erptag = tgui_input_list(user, "Pick a new ERP tag for the character directory", "Character ERP Tag", GLOB.char_directory_erptags, pref.directory_erptag)
|
||||
if(!new_erptag)
|
||||
return
|
||||
pref.directory_erptag = new_erptag
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["directory_ad"])
|
||||
var/msg = sanitize(tgui_input_text(user,"Write your advertisement here!", "Flavor Text", html_decode(pref.directory_ad), multiline = TRUE, prevent_enter = TRUE), extra = 0) //VOREStation Edit: separating out OOC notes
|
||||
if(!msg)
|
||||
return
|
||||
pref.directory_ad = msg
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_sensor_setting"])
|
||||
var/new_sensorpref = tgui_input_list(user, "Choose your character's sensor preferences:", "Character Preferences", GLOB.sensorpreflist, GLOB.sensorpreflist[pref.sensorpref])
|
||||
if (!isnull(new_sensorpref) && CanUseTopic(user))
|
||||
pref.sensorpref = GLOB.sensorpreflist.Find(new_sensorpref)
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_capture_crystal"])
|
||||
pref.capture_crystal = pref.capture_crystal ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_implant"])
|
||||
pref.auto_backup_implant = pref.auto_backup_implant ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["toggle_borg_petting"])
|
||||
pref.borg_petting = pref.borg_petting ? 0 : 1;
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["edit_private_notes"])
|
||||
var/new_metadata = sanitize(tgui_input_text(user,"Write some notes for yourself. These can be anything that is useful, whether it's character events that you want to remember or a bit of lore. Things that you would normally stick in a txt file for yourself!", "Private Notes", html_decode(pref.read_preference(/datum/preference/text/living/private_notes)), multiline = TRUE, prevent_enter = TRUE), extra = 0)
|
||||
if(new_metadata && CanUseTopic(user))
|
||||
pref.update_preference_by_type(/datum/preference/text/living/private_notes, new_metadata)
|
||||
return ..();
|
||||
Reference in New Issue
Block a user