Merge remote-tracking branch 'bay12-upstream/master' into development

This commit is contained in:
skull132
2016-10-07 00:58:39 +03:00
1594 changed files with 53994 additions and 48590 deletions
-1
View File
@@ -17,7 +17,6 @@
var/moving = null
var/adminobs = null
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
var/adminhelped = 0
+7 -4
View File
@@ -165,7 +165,7 @@
if ("webint")
src.open_webint()
..() //redirect to hsrc.()
..() //redirect to hsrc.Topic()
/client/proc/handle_spam_prevention(var/message, var/mute_type)
if(config.automute_on && !holder && src.last_message == message)
@@ -256,9 +256,6 @@
del(src)
return 0
if( (world.address == address || !address) && !host )
host = key
world.update_status()
if(holder)
add_admin_verbs()
@@ -451,6 +448,12 @@
// Something went wrong, client is usually kicked or transfered to a new mob at this point
return 0
/client/verb/character_setup()
set name = "Character Setup"
set category = "Preferences"
if(prefs)
prefs.ShowChoices(usr)
//I honestly can't find a good place for this atm.
//If the webint interaction gets more features, I'll move it. - Skull132
/client/verb/view_linking_requests()
+15
View File
@@ -0,0 +1,15 @@
/client/New()
..()
dir = NORTH
/client/verb/spinleft()
set name = "Spin View CCW"
set category = "OOC"
dir = turn(dir, 90)
/client/verb/spinright()
set name = "Spin View CW"
set category = "OOC"
dir = turn(dir, -90)
@@ -0,0 +1,81 @@
/datum/category_item/player_setup_item/antagonism/candidacy
name = "Candidacy"
sort_order = 1
/datum/category_item/player_setup_item/antagonism/candidacy/load_character(var/savefile/S)
S["be_special"] >> pref.be_special_role
/datum/category_item/player_setup_item/antagonism/candidacy/save_character(var/savefile/S)
S["be_special"] << pref.be_special_role
/datum/category_item/player_setup_item/antagonism/candidacy/sanitize_character()
if(!istype(pref.be_special_role))
pref.be_special_role = list()
for(var/role in pref.be_special_role)
if(!(role in valid_special_roles()))
pref.be_special_role -= role
/datum/category_item/player_setup_item/antagonism/candidacy/content(var/mob/user)
. += "<b>Special Role Availability:</b><br>"
. += "<table>"
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
. += "<tr><td>[antag.role_text]: </td><td>"
if(jobban_isbanned(preference_mob(), antag.bantype))
. += "<span class='danger'>\[BANNED\]</span><br>"
else if(antag.role_type in pref.be_special_role)
. += "<b>Yes</b> / <a href='?src=\ref[src];del_special=[antag.role_type]'>No</a></br>"
else
. += "<a href='?src=\ref[src];add_special=[antag.role_type]'>Yes</a> / <b>No</b></br>"
. += "</td></tr>"
var/list/ghost_traps = get_ghost_traps()
for(var/ghost_trap_key in ghost_traps)
var/datum/ghosttrap/ghost_trap = ghost_traps[ghost_trap_key]
if(!ghost_trap.list_as_special_role)
continue
. += "<tr><td>[(ghost_trap.ghost_trap_role)]: </td><td>"
if(banned_from_ghost_role(preference_mob(), ghost_trap))
. += "<span class='danger'>\[BANNED\]</span><br>"
else if(ghost_trap.pref_check in pref.be_special_role)
. += "<b>Yes</b> / <a href='?src=\ref[src];del_special=[ghost_trap.pref_check]'>No</a></br>"
else
. += "<a href='?src=\ref[src];add_special=[ghost_trap.pref_check]'>Yes</a> / <b>No</b></br>"
. += "</td></tr>"
. += "</table>"
/datum/category_item/player_setup_item/proc/banned_from_ghost_role(var/mob, var/datum/ghosttrap/ghost_trap)
for(var/ban_type in ghost_trap.ban_checks)
if(jobban_isbanned(mob, ban_type))
return 1
return 0
/datum/category_item/player_setup_item/antagonism/candidacy/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["add_special"])
if(!(href_list["add_special"] in valid_special_roles()))
return TOPIC_HANDLED
pref.be_special_role |= href_list["add_special"]
return TOPIC_REFRESH
if(href_list["del_special"])
pref.be_special_role -= href_list["del_special"]
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/antagonism/candidacy/proc/valid_special_roles()
var/list/private_valid_special_roles = list()
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
private_valid_special_roles += antag.role_type
var/list/ghost_traps = get_ghost_traps()
for(var/ghost_trap_key in ghost_traps)
var/datum/ghosttrap/ghost_trap = ghost_traps[ghost_trap_key]
if(!ghost_trap.list_as_special_role)
continue
private_valid_special_roles += ghost_trap.pref_check
return private_valid_special_roles
@@ -0,0 +1,38 @@
var/global/list/uplink_locations = list("PDA", "Headset", "None")
/datum/category_item/player_setup_item/antagonism/basic
name = "Setup"
sort_order = 2
/datum/category_item/player_setup_item/antagonism/basic/load_character(var/savefile/S)
S["uplinklocation"] >> pref.uplinklocation
S["exploit_record"] >> pref.exploit_record
/datum/category_item/player_setup_item/antagonism/basic/save_character(var/savefile/S)
S["uplinklocation"] << pref.uplinklocation
S["exploit_record"] << pref.exploit_record
/datum/category_item/player_setup_item/antagonism/basic/sanitize_character()
pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation))
/datum/category_item/player_setup_item/antagonism/basic/content(var/mob/user)
. +="<b>Antag Setup:</b><br>"
. +="Uplink Type: <a href='?src=\ref[src];antagtask=1'>[pref.uplinklocation]</a><br>"
. +="Exploitable information:<br>"
if(jobban_isbanned(user, "Records"))
. += "<b>You are banned from using character records.</b><br>"
else
. +="<a href='?src=\ref[src];exploitable_record=1'>[TextPreview(pref.exploit_record,40)]</a><br>"
/datum/category_item/player_setup_item/antagonism/basic/OnTopic(var/href,var/list/href_list, var/mob/user)
if (href_list["antagtask"])
pref.uplinklocation = next_in_list(pref.uplinklocation, uplink_locations)
return TOPIC_REFRESH
if(href_list["exploitable_record"])
var/exploitmsg = sanitize(input(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!isnull(exploitmsg) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.exploit_record = exploitmsg
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,88 @@
/datum/category_item/player_setup_item/general/basic
name = "Basic"
sort_order = 1
var/list/valid_player_genders = list(MALE, FEMALE)
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
S["real_name"] >> pref.real_name
S["name_is_always_random"] >> pref.be_random_name
S["gender"] >> pref.gender
S["age"] >> pref.age
S["spawnpoint"] >> pref.spawnpoint
S["OOC_Notes"] >> pref.metadata
/datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S)
S["real_name"] << pref.real_name
S["name_is_always_random"] << pref.be_random_name
S["gender"] << pref.gender
S["age"] << pref.age
S["spawnpoint"] << pref.spawnpoint
S["OOC_Notes"] << pref.metadata
/datum/category_item/player_setup_item/general/basic/sanitize_character()
pref.age = sanitize_integer(pref.age, AGE_MIN, AGE_MAX, initial(pref.age))
pref.gender = sanitize_inlist(pref.gender, valid_player_genders, pick(valid_player_genders))
pref.real_name = sanitize_name(pref.real_name, pref.species)
if(!pref.real_name)
pref.real_name = random_name(pref.gender, pref.species)
pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint))
pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name))
/datum/category_item/player_setup_item/general/basic/content()
. = "<b>Name:</b> "
. += "<a href='?src=\ref[src];rename=1'><b>[pref.real_name]</b></a><br>"
. += "(<a href='?src=\ref[src];random_name=1'>Random Name</A>) "
. += "(<a href='?src=\ref[src];always_random_name=1'>Always Random Name: [pref.be_random_name ? "Yes" : "No"]</a>)"
. += "<br>"
. += "<b>Gender:</b> <a href='?src=\ref[src];gender=1'><b>[capitalize(lowertext(pref.gender))]</b></a><br>"
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
if(config.allow_Metadata)
. += "<b>OOC Notes:</b> <a href='?src=\ref[src];metadata=1'> Edit </a><br>"
/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 = input(user, "Choose your character's name:", "Character Name") as text|null
if (!isnull(raw_name) && CanUseTopic(user))
var/new_name = sanitize_name(raw_name, pref.species)
if(new_name)
pref.real_name = new_name
return TOPIC_REFRESH
else
user << "<span class='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 .</span>"
return TOPIC_NOACTION
else if(href_list["random_name"])
pref.real_name = random_name(pref.gender, pref.species)
return TOPIC_REFRESH
else if(href_list["always_random_name"])
pref.be_random_name = !pref.be_random_name
return TOPIC_REFRESH
else if(href_list["gender"])
pref.gender = next_in_list(pref.gender, valid_player_genders)
return TOPIC_REFRESH
else if(href_list["age"])
var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference", pref.age) as num|null
if(new_age && CanUseTopic(user))
pref.age = max(min(round(text2num(new_age)), AGE_MAX), AGE_MIN)
return TOPIC_REFRESH
else if(href_list["spawnpoint"])
var/list/spawnkeys = list()
for(var/S in spawntypes)
spawnkeys += S
var/choice = input(user, "Where would you like to spawn when late-joining?") as null|anything in spawnkeys
if(!choice || !spawntypes[choice] || !CanUseTopic(user)) return TOPIC_NOACTION
pref.spawnpoint = choice
return TOPIC_REFRESH
else if(href_list["metadata"])
var/new_metadata = sanitize(input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , pref.metadata)) as message|null
if(new_metadata && CanUseTopic(user))
pref.metadata = sanitize(new_metadata)
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,60 @@
/datum/category_item/player_setup_item/general/language
name = "Language"
sort_order = 2
/datum/category_item/player_setup_item/general/language/load_character(var/savefile/S)
S["language"] >> pref.alternate_languages
/datum/category_item/player_setup_item/general/language/save_character(var/savefile/S)
S["language"] << pref.alternate_languages
/datum/category_item/player_setup_item/general/language/sanitize_character()
if(!islist(pref.alternate_languages)) pref.alternate_languages = list()
/datum/category_item/player_setup_item/general/language/content()
. += "<b>Languages</b><br>"
var/datum/species/S = all_species[pref.species]
if(S.language)
. += "- [S.language]<br>"
if(S.default_language && S.default_language != S.language)
. += "- [S.default_language]<br>"
if(S.num_alternate_languages)
if(pref.alternate_languages.len)
for(var/i = 1 to pref.alternate_languages.len)
var/lang = pref.alternate_languages[i]
. += "- [lang] - <a href='?src=\ref[src];remove_language=[i]'>remove</a><br>"
if(pref.alternate_languages.len < S.num_alternate_languages)
. += "- <a href='?src=\ref[src];add_language=1'>add</a> ([S.num_alternate_languages - pref.alternate_languages.len] remaining)<br>"
else
. += "- [pref.species] cannot choose secondary languages.<br>"
/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 = all_species[pref.species]
if(pref.alternate_languages.len >= S.num_alternate_languages)
alert(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 all_languages)
var/datum/language/lang = all_languages[L]
if(!(lang.flags & RESTRICTED) && (!config.usealienwhitelist || is_alien_whitelisted(user, L) || !(lang.flags & WHITELISTED)))
available_languages |= L
// make sure we don't let them waste slots on the default languages
available_languages -= S.language
available_languages -= S.default_language
available_languages -= pref.alternate_languages
if(!available_languages.len)
alert(user, "There are no additional languages available to select.")
else
var/new_lang = input(user, "Select an additional language", "Character Generation", null) as null|anything in available_languages
if(new_lang)
pref.alternate_languages |= new_lang
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,500 @@
var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-")
/datum/category_item/player_setup_item/general/body
name = "Body"
sort_order = 3
/datum/category_item/player_setup_item/general/body/load_character(var/savefile/S)
S["species"] >> pref.species
S["hair_red"] >> pref.r_hair
S["hair_green"] >> pref.g_hair
S["hair_blue"] >> pref.b_hair
S["facial_red"] >> pref.r_facial
S["facial_green"] >> pref.g_facial
S["facial_blue"] >> pref.b_facial
S["skin_tone"] >> pref.s_tone
S["skin_red"] >> pref.r_skin
S["skin_green"] >> pref.g_skin
S["skin_blue"] >> pref.b_skin
S["hair_style_name"] >> pref.h_style
S["facial_style_name"] >> pref.f_style
S["eyes_red"] >> pref.r_eyes
S["eyes_green"] >> pref.g_eyes
S["eyes_blue"] >> pref.b_eyes
S["b_type"] >> pref.b_type
S["disabilities"] >> pref.disabilities
S["organ_data"] >> pref.organ_data
S["rlimb_data"] >> pref.rlimb_data
/datum/category_item/player_setup_item/general/body/save_character(var/savefile/S)
S["species"] << pref.species
S["hair_red"] << pref.r_hair
S["hair_green"] << pref.g_hair
S["hair_blue"] << pref.b_hair
S["facial_red"] << pref.r_facial
S["facial_green"] << pref.g_facial
S["facial_blue"] << pref.b_facial
S["skin_tone"] << pref.s_tone
S["skin_red"] << pref.r_skin
S["skin_green"] << pref.g_skin
S["skin_blue"] << pref.b_skin
S["hair_style_name"] << pref.h_style
S["facial_style_name"] << pref.f_style
S["eyes_red"] << pref.r_eyes
S["eyes_green"] << pref.g_eyes
S["eyes_blue"] << pref.b_eyes
S["b_type"] << pref.b_type
S["disabilities"] << pref.disabilities
S["organ_data"] << pref.organ_data
S["rlimb_data"] << pref.rlimb_data
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
if(!pref.species || !(pref.species in playable_species))
pref.species = "Human"
pref.r_hair = sanitize_integer(pref.r_hair, 0, 255, initial(pref.r_hair))
pref.g_hair = sanitize_integer(pref.g_hair, 0, 255, initial(pref.g_hair))
pref.b_hair = sanitize_integer(pref.b_hair, 0, 255, initial(pref.b_hair))
pref.r_facial = sanitize_integer(pref.r_facial, 0, 255, initial(pref.r_facial))
pref.g_facial = sanitize_integer(pref.g_facial, 0, 255, initial(pref.g_facial))
pref.b_facial = sanitize_integer(pref.b_facial, 0, 255, initial(pref.b_facial))
pref.s_tone = sanitize_integer(pref.s_tone, -185, 34, initial(pref.s_tone))
pref.r_skin = sanitize_integer(pref.r_skin, 0, 255, initial(pref.r_skin))
pref.g_skin = sanitize_integer(pref.g_skin, 0, 255, initial(pref.g_skin))
pref.b_skin = sanitize_integer(pref.b_skin, 0, 255, initial(pref.b_skin))
pref.h_style = sanitize_inlist(pref.h_style, hair_styles_list, initial(pref.h_style))
pref.f_style = sanitize_inlist(pref.f_style, facial_hair_styles_list, initial(pref.f_style))
pref.r_eyes = sanitize_integer(pref.r_eyes, 0, 255, initial(pref.r_eyes))
pref.g_eyes = sanitize_integer(pref.g_eyes, 0, 255, initial(pref.g_eyes))
pref.b_eyes = sanitize_integer(pref.b_eyes, 0, 255, initial(pref.b_eyes))
pref.b_type = sanitize_text(pref.b_type, initial(pref.b_type))
pref.disabilities = sanitize_integer(pref.disabilities, 0, 65535, initial(pref.disabilities))
if(!pref.organ_data) pref.organ_data = list()
if(!pref.rlimb_data) pref.rlimb_data = list()
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
pref.update_preview_icon()
if(pref.preview_icon_front && pref.preview_icon_side)
user << browse_rsc(pref.preview_icon_front, "previewicon.png")
user << browse_rsc(pref.preview_icon_side, "previewicon2.png")
var/mob_species = all_species[pref.species]
. += "<table><tr style='vertical-align:top'><td><b>Body</b> "
. += "(<a href='?src=\ref[src];random=1'>&reg;</A>)"
. += "<br>"
. += "Species: <a href='?src=\ref[src];show_species=1'>[pref.species]</a><br>"
. += "Blood Type: <a href='?src=\ref[src];blood_type=1'>[pref.b_type]</a><br>"
if(has_flag(mob_species, HAS_SKIN_TONE))
. += "Skin Tone: <a href='?src=\ref[src];skin_tone=1'>[-pref.s_tone + 35]/220</a><br>"
. += "Needs Glasses: <a href='?src=\ref[src];disabilities=[NEARSIGHTED]'><b>[pref.disabilities & NEARSIGHTED ? "Yes" : "No"]</b></a><br>"
. += "Limbs: <a href='?src=\ref[src];limbs=1'>Adjust</a><br>"
. += "Internal Organs: <a href='?src=\ref[src];organs=1'>Adjust</a><br>"
//display limbs below
var/ind = 0
for(var/name in pref.organ_data)
var/status = pref.organ_data[name]
var/organ_name = null
switch(name)
if("l_arm")
organ_name = "left arm"
if("r_arm")
organ_name = "right arm"
if("l_leg")
organ_name = "left leg"
if("r_leg")
organ_name = "right leg"
if("l_foot")
organ_name = "left foot"
if("r_foot")
organ_name = "right foot"
if("l_hand")
organ_name = "left hand"
if("r_hand")
organ_name = "right hand"
if("heart")
organ_name = "heart"
if("eyes")
organ_name = "eyes"
if(status == "cyborg")
++ind
if(ind > 1)
. += ", "
var/datum/robolimb/R
if(pref.rlimb_data[name] && all_robolimbs[pref.rlimb_data[name]])
R = all_robolimbs[pref.rlimb_data[name]]
else
R = basic_robolimb
. += "\t[R.company] [organ_name] prothesis"
else if(status == "amputated")
++ind
if(ind > 1)
. += ", "
. += "\tAmputated [organ_name]"
else if(status == "mechanical")
++ind
if(ind > 1)
. += ", "
. += "\tMechanical [organ_name]"
else if(status == "assisted")
++ind
if(ind > 1)
. += ", "
switch(organ_name)
if("heart")
. += "\tPacemaker-assisted [organ_name]"
if("voicebox") //on adding voiceboxes for speaking skrell/similar replacements
. += "\tSurgically altered [organ_name]"
if("eyes")
. += "\tRetinal overlayed [organ_name]"
else
. += "\tMechanically assisted [organ_name]"
if(!ind)
. += "\[...\]<br><br>"
else
. += "<br><br>"
. += "</td><td><b>Preview</b><br><img src=previewicon.png height=64 width=64><img src=previewicon2.png height=64 width=64>"
. += "</td></tr></table>"
. += "<b>Hair</b><br>"
if(has_flag(mob_species, HAS_HAIR_COLOR))
. += "<a href='?src=\ref[src];hair_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_hair, 2)][num2hex(pref.g_hair, 2)][num2hex(pref.b_hair, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_hair, 2)][num2hex(pref.g_hair, 2)][num2hex(pref.b_hair)]'><tr><td>__</td></tr></table></font> "
. += " Style: <a href='?src=\ref[src];hair_style=1'>[pref.h_style]</a><br>"
. += "<br><b>Facial</b><br>"
if(has_flag(mob_species, HAS_HAIR_COLOR))
. += "<a href='?src=\ref[src];facial_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_facial, 2)][num2hex(pref.g_facial, 2)][num2hex(pref.b_facial, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_facial, 2)][num2hex(pref.g_facial, 2)][num2hex(pref.b_facial)]'><tr><td>__</td></tr></table></font> "
. += " Style: <a href='?src=\ref[src];facial_style=1'>[pref.f_style]</a><br>"
if(has_flag(mob_species, HAS_EYE_COLOR))
. += "<br><b>Eyes</b><br>"
. += "<a href='?src=\ref[src];eye_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_eyes, 2)][num2hex(pref.g_eyes, 2)][num2hex(pref.b_eyes, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_eyes, 2)][num2hex(pref.g_eyes, 2)][num2hex(pref.b_eyes)]'><tr><td>__</td></tr></table></font><br>"
if(has_flag(mob_species, HAS_SKIN_COLOR))
. += "<br><b>Body Color</b><br>"
. += "<a href='?src=\ref[src];skin_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_skin, 2)][num2hex(pref.g_skin, 2)][num2hex(pref.b_skin, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_skin, 2)][num2hex(pref.g_skin, 2)][num2hex(pref.b_skin)]'><tr><td>__</td></tr></table></font><br>"
/datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag)
return mob_species && (mob_species.appearance_flags & flag)
/datum/category_item/player_setup_item/general/body/OnTopic(var/href,var/list/href_list, var/mob/user)
var/datum/species/mob_species = all_species[pref.species]
if(href_list["random"])
pref.randomize_appearance_for()
return TOPIC_REFRESH
else if(href_list["blood_type"])
var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in valid_bloodtypes
if(new_b_type && CanUseTopic(user))
pref.b_type = new_b_type
return TOPIC_REFRESH
else if(href_list["show_species"])
// Actual whitelist checks are handled elsewhere, this is just for accessing the preview window.
var/choice = input("Which species would you like to look at?") as null|anything in playable_species
if(!choice) return
pref.species_preview = choice
SetSpecies(preference_mob())
pref.alternate_languages.Cut() // Reset their alternate languages. Todo: attempt to just fix it instead?
return TOPIC_HANDLED
else if(href_list["set_species"])
user << browse(null, "window=species")
if(!pref.species_preview || !(pref.species_preview in all_species))
return TOPIC_NOACTION
var/prev_species = pref.species
pref.species = href_list["set_species"]
if(prev_species != pref.species)
mob_species = all_species[pref.species]
//grab one of the valid hair styles for the newly chosen species
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
if(valid_hairstyles.len)
pref.h_style = pick(valid_hairstyles)
else
//this shouldn't happen
pref.h_style = hair_styles_list["Bald"]
//grab one of the valid facial hair styles for the newly chosen species
var/list/valid_facialhairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
if(valid_facialhairstyles.len)
pref.f_style = pick(valid_facialhairstyles)
else
//this shouldn't happen
pref.f_style = facial_hair_styles_list["Shaved"]
//reset hair colour and skin colour
pref.r_hair = 0//hex2num(copytext(new_hair, 2, 4))
pref.g_hair = 0//hex2num(copytext(new_hair, 4, 6))
pref.b_hair = 0//hex2num(copytext(new_hair, 6, 8))
pref.s_tone = 0
return TOPIC_REFRESH
else if(href_list["hair_color"])
if(!has_flag(mob_species, HAS_HAIR_COLOR))
return TOPIC_NOACTION
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference", rgb(pref.r_hair, pref.g_hair, pref.b_hair)) as color|null
if(new_hair && has_flag(mob_species, HAS_HAIR_COLOR) && CanUseTopic(user))
pref.r_hair = hex2num(copytext(new_hair, 2, 4))
pref.g_hair = hex2num(copytext(new_hair, 4, 6))
pref.b_hair = hex2num(copytext(new_hair, 6, 8))
return TOPIC_REFRESH
else if(href_list["hair_style"])
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference", pref.h_style) as null|anything in valid_hairstyles
if(new_h_style && CanUseTopic(user))
pref.h_style = new_h_style
return TOPIC_REFRESH
else if(href_list["facial_color"])
if(!has_flag(mob_species, HAS_HAIR_COLOR))
return TOPIC_NOACTION
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(pref.r_facial, pref.g_facial, pref.b_facial)) as color|null
if(new_facial && has_flag(mob_species, HAS_HAIR_COLOR) && CanUseTopic(user))
pref.r_facial = hex2num(copytext(new_facial, 2, 4))
pref.g_facial = hex2num(copytext(new_facial, 4, 6))
pref.b_facial = hex2num(copytext(new_facial, 6, 8))
return TOPIC_REFRESH
else if(href_list["eye_color"])
if(!has_flag(mob_species, HAS_EYE_COLOR))
return TOPIC_NOACTION
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", rgb(pref.r_eyes, pref.g_eyes, pref.b_eyes)) as color|null
if(new_eyes && has_flag(mob_species, HAS_EYE_COLOR) && CanUseTopic(user))
pref.r_eyes = hex2num(copytext(new_eyes, 2, 4))
pref.g_eyes = hex2num(copytext(new_eyes, 4, 6))
pref.b_eyes = hex2num(copytext(new_eyes, 6, 8))
return TOPIC_REFRESH
else if(href_list["skin_tone"])
if(!has_flag(mob_species, HAS_SKIN_TONE))
return TOPIC_NOACTION
var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference", (-pref.s_tone) + 35) as num|null
if(new_s_tone && has_flag(mob_species, HAS_SKIN_TONE) && CanUseTopic(user))
pref.s_tone = 35 - max(min( round(new_s_tone), 220),1)
return TOPIC_REFRESH
else if(href_list["skin_color"])
if(!has_flag(mob_species, HAS_SKIN_COLOR))
return TOPIC_NOACTION
var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(pref.r_skin, pref.g_skin, pref.b_skin)) as color|null
if(new_skin && has_flag(mob_species, HAS_SKIN_COLOR) && CanUseTopic(user))
pref.r_skin = hex2num(copytext(new_skin, 2, 4))
pref.g_skin = hex2num(copytext(new_skin, 4, 6))
pref.b_skin = hex2num(copytext(new_skin, 6, 8))
return TOPIC_REFRESH
else if(href_list["facial_style"])
var/list/valid_facialhairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
if(pref.gender == MALE && S.gender == FEMALE)
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference", pref.f_style) as null|anything in valid_facialhairstyles
if(new_f_style && has_flag(mob_species, HAS_HAIR_COLOR) && CanUseTopic(user))
pref.f_style = new_f_style
return TOPIC_REFRESH
else if(href_list["limbs"])
var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand")
if(!limb_name && !CanUseTopic(user)) return TOPIC_NOACTION
var/limb = null
var/second_limb = null // if you try to change the arm, the hand should also change
var/third_limb = null // if you try to unchange the hand, the arm should also change
switch(limb_name)
if("Left Leg")
limb = "l_leg"
second_limb = "l_foot"
if("Right Leg")
limb = "r_leg"
second_limb = "r_foot"
if("Left Arm")
limb = "l_arm"
second_limb = "l_hand"
if("Right Arm")
limb = "r_arm"
second_limb = "r_hand"
if("Left Foot")
limb = "l_foot"
third_limb = "l_leg"
if("Right Foot")
limb = "r_foot"
third_limb = "r_leg"
if("Left Hand")
limb = "l_hand"
third_limb = "l_arm"
if("Right Hand")
limb = "r_hand"
third_limb = "r_arm"
var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis")
if(!new_state && !CanUseTopic(user)) return TOPIC_NOACTION
switch(new_state)
if("Normal")
pref.organ_data[limb] = null
pref.rlimb_data[limb] = null
if(third_limb)
pref.organ_data[third_limb] = null
pref.rlimb_data[third_limb] = null
if("Amputated")
pref.organ_data[limb] = "amputated"
pref.rlimb_data[limb] = null
if(second_limb)
pref.organ_data[second_limb] = "amputated"
pref.rlimb_data[second_limb] = null
if("Prothesis")
var/tmp_species = pref.species ? pref.species : "Human"
var/list/usable_manufacturers = list()
for(var/company in chargen_robolimbs)
var/datum/robolimb/M = chargen_robolimbs[company]
if(tmp_species in M.species_cannot_use)
continue
usable_manufacturers[company] = M
if(!usable_manufacturers.len)
return
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in usable_manufacturers
if(!choice)
return
pref.rlimb_data[limb] = choice
pref.organ_data[limb] = "cyborg"
if(second_limb)
pref.rlimb_data[second_limb] = choice
pref.organ_data[second_limb] = "cyborg"
if(third_limb && pref.organ_data[third_limb] == "amputated")
pref.organ_data[third_limb] = null
return TOPIC_REFRESH
else if(href_list["organs"])
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
if(!organ_name) return
var/organ = null
switch(organ_name)
if("Heart")
organ = "heart"
if("Eyes")
organ = "eyes"
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical")
if(!new_state) return
switch(new_state)
if("Normal")
pref.organ_data[organ] = null
if("Assisted")
pref.organ_data[organ] = "assisted"
if("Mechanical")
pref.organ_data[organ] = "mechanical"
return TOPIC_REFRESH
else if(href_list["disabilities"])
var/disability_flag = text2num(href_list["disabilities"])
pref.disabilities ^= disability_flag
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/general/body/proc/SetSpecies(mob/user)
if(!pref.species_preview || !(pref.species_preview in all_species))
pref.species_preview = "Human"
var/datum/species/current_species = all_species[pref.species_preview]
var/dat = "<body>"
dat += "<center><h2>[current_species.name] \[<a href='?src=\ref[src];show_species=1'>change</a>\]</h2></center><hr/>"
dat += "<table padding='8px'>"
dat += "<tr>"
dat += "<td width = 400>[current_species.blurb]</td>"
dat += "<td width = 200 align='center'>"
if("preview" in icon_states(current_species.icobase))
usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png")
dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>"
dat += "<b>Language:</b> [current_species.language]<br/>"
dat += "<small>"
if(current_species.spawn_flags & CAN_JOIN)
dat += "</br><b>Often present on human stations.</b>"
if(current_species.spawn_flags & IS_WHITELISTED)
dat += "</br><b>Whitelist restricted.</b>"
if(current_species.flags & NO_BLOOD)
dat += "</br><b>Does not have blood.</b>"
if(current_species.flags & NO_BREATHE)
dat += "</br><b>Does not breathe.</b>"
if(current_species.flags & NO_SCAN)
dat += "</br><b>Does not have DNA.</b>"
if(current_species.flags & NO_PAIN)
dat += "</br><b>Does not feel pain.</b>"
if(current_species.flags & NO_SLIP)
dat += "</br><b>Has excellent traction.</b>"
if(current_species.flags & NO_POISON)
dat += "</br><b>Immune to most poisons.</b>"
if(current_species.appearance_flags & HAS_SKIN_TONE)
dat += "</br><b>Has a variety of skin tones.</b>"
if(current_species.appearance_flags & HAS_SKIN_COLOR)
dat += "</br><b>Has a variety of skin colours.</b>"
if(current_species.appearance_flags & HAS_EYE_COLOR)
dat += "</br><b>Has a variety of eye colours.</b>"
if(current_species.flags & IS_PLANT)
dat += "</br><b>Has a plantlike physiology.</b>"
dat += "</small></td>"
dat += "</tr>"
dat += "</table><center><hr/>"
var/restricted = 0
if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
if(!(current_species.spawn_flags & CAN_JOIN))
restricted = 2
else if((current_species.spawn_flags & IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),current_species))
restricted = 1
if(restricted)
if(restricted == 1)
dat += "<font color='red'><b>You cannot play as this species.</br><small>If you wish to be whitelisted, you can make an application post on <a href='?src=\ref[user];preference=open_whitelist_forum'>the forums</a>.</small></b></font></br>"
else if(restricted == 2)
dat += "<font color='red'><b>You cannot play as this species.</br><small>This species is not available for play as a station race..</small></b></font></br>"
if(!restricted || check_rights(R_ADMIN, 0))
dat += "\[<a href='?src=\ref[src];set_species=[pref.species_preview]'>select</a>\]"
dat += "</center></body>"
user << browse(dat, "window=species;size=700x400")
@@ -0,0 +1,129 @@
/datum/category_item/player_setup_item/general/equipment
name = "Equipment"
sort_order = 4
/datum/category_item/player_setup_item/general/equipment/load_character(var/savefile/S)
S["underwear"] >> pref.underwear
S["undershirt"] >> pref.undershirt
S["backbag"] >> pref.backbag
S["gear"] >> pref.gear
/datum/category_item/player_setup_item/general/equipment/save_character(var/savefile/S)
S["underwear"] << pref.underwear
S["undershirt"] << pref.undershirt
S["backbag"] << pref.backbag
S["gear"] << pref.gear
/datum/category_item/player_setup_item/general/equipment/sanitize_character()
pref.backbag = sanitize_integer(pref.backbag, 1, backbaglist.len, initial(pref.backbag))
if(!islist(pref.gear)) pref.gear = list()
var/undies = get_undies()
if(!get_key_by_value(undies, pref.underwear))
pref.underwear = undies[1]
if(!get_key_by_value(undershirt_t, pref.undershirt))
pref.undershirt = undershirt_t[1]
var/total_cost = 0
for(var/gear_name in pref.gear)
if(!gear_datums[gear_name])
pref.gear -= gear_name
else if(!(gear_name in valid_gear_choices()))
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
else
total_cost += G.cost
/datum/category_item/player_setup_item/general/equipment/content()
. += "<b>Equipment Loadout:</b><br>"
. += "Underwear: <a href='?src=\ref[src];change_underwear=1'><b>[get_key_by_value(get_undies(),pref.underwear)]</b></a><br>"
. += "Undershirt: <a href='?src=\ref[src];change_undershirt=1'><b>[get_key_by_value(undershirt_t,pref.undershirt)]</b></a><br>"
. += "Backpack Type: <a href='?src=\ref[src];change_backpack=1'><b>[backbaglist[pref.backbag]]</b></a><br>"
. += "<br><b>Custom Loadout:</b><br>"
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
. += "[pref.gear[i]] ([G.cost] points) <a href='?src=\ref[src];remove_loadout=[i]'>Remove</a><br>"
. += "<b>Used:</b> [total_cost] points."
else
. += "None."
if(total_cost < MAX_GEAR_COST)
. += " <a href='?src=\ref[src];add_loadout=1'>Add</a>"
if(pref.gear && pref.gear.len)
. += " <a href='?src=\ref[src];clear_loadout=1'>Clear</a>"
. += "<br>"
/datum/category_item/player_setup_item/general/equipment/proc/get_undies()
return pref.gender == MALE ? underwear_m : underwear_f
/datum/category_item/player_setup_item/general/equipment/proc/valid_gear_choices(var/max_cost)
var/list/valid_gear_choices = list()
for(var/gear_name in gear_datums)
var/datum/gear/G = gear_datums[gear_name]
if(G.whitelisted && !is_alien_whitelisted(preference_mob(), G.whitelisted))
continue
if(max_cost && G.cost > max_cost)
continue
valid_gear_choices += gear_name
return valid_gear_choices
/datum/category_item/player_setup_item/general/equipment/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["change_underwear"])
var/underwear_options = get_undies()
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference", get_key_by_value(get_undies(),pref.underwear)) as null|anything in underwear_options
if(!isnull(new_underwear) && CanUseTopic(user))
pref.underwear = underwear_options[new_underwear]
return TOPIC_REFRESH
else if(href_list["change_undershirt"])
var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference", get_key_by_value(undershirt_t,pref.undershirt)) as null|anything in undershirt_t
if(!isnull(new_undershirt) && CanUseTopic(user))
pref.undershirt = undershirt_t[new_undershirt]
return TOPIC_REFRESH
else if(href_list["change_backpack"])
var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference", backbaglist[pref.backbag]) as null|anything in backbaglist
if(!isnull(new_backbag) && CanUseTopic(user))
pref.backbag = backbaglist.Find(new_backbag)
return TOPIC_REFRESH
else if(href_list["add_loadout"])
var/total_cost = 0
for(var/gear_name in pref.gear)
if(gear_datums[gear_name])
var/datum/gear/G = gear_datums[gear_name]
total_cost += G.cost
var/choice = input(user, "Select gear to add:", "Character Preference") as null|anything in valid_gear_choices(MAX_GEAR_COST - total_cost)
if(choice && gear_datums[choice] && CanUseTopic(user))
var/datum/gear/C = gear_datums[choice]
total_cost += C.cost
if(C && total_cost <= MAX_GEAR_COST)
pref.gear += choice
user << "<span class='notice'>Added \the '[choice]' for [C.cost] points ([MAX_GEAR_COST - total_cost] points remaining).</span>"
else
user << "<span class='warning'>Adding \the '[choice]' will exceed the maximum loadout cost of [MAX_GEAR_COST] points.</span>"
return TOPIC_REFRESH
else if(href_list["remove_loadout"])
var/i_remove = text2num(href_list["remove_loadout"])
if(i_remove < 1 || i_remove > pref.gear.len) return TOPIC_NOACTION
pref.gear.Cut(i_remove, i_remove + 1)
return TOPIC_REFRESH
else if(href_list["clear_loadout"])
pref.gear.Cut()
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,125 @@
/datum/category_item/player_setup_item/general/background
name = "Background"
sort_order = 5
/datum/category_item/player_setup_item/general/background/load_character(var/savefile/S)
S["med_record"] >> pref.med_record
S["sec_record"] >> pref.sec_record
S["gen_record"] >> pref.gen_record
S["home_system"] >> pref.home_system
S["citizenship"] >> pref.citizenship
S["faction"] >> pref.faction
S["religion"] >> pref.religion
S["nanotrasen_relation"] >> pref.nanotrasen_relation
/datum/category_item/player_setup_item/general/background/save_character(var/savefile/S)
S["med_record"] << pref.med_record
S["sec_record"] << pref.sec_record
S["gen_record"] << pref.gen_record
S["home_system"] << pref.home_system
S["citizenship"] << pref.citizenship
S["faction"] << pref.faction
S["religion"] << pref.religion
S["nanotrasen_relation"] << pref.nanotrasen_relation
/datum/category_item/player_setup_item/general/background/sanitize_character()
if(!pref.home_system) pref.home_system = "Unset"
if(!pref.citizenship) pref.citizenship = "None"
if(!pref.faction) pref.faction = "None"
if(!pref.religion) pref.religion = "None"
pref.nanotrasen_relation = sanitize_inlist(pref.nanotrasen_relation, COMPANY_ALIGNMENTS, initial(pref.nanotrasen_relation))
/datum/category_item/player_setup_item/general/background/content(var/mob/user)
. += "<b>Background Information</b><br>"
. += "[company_name] Relation: <a href='?src=\ref[src];nt_relation=1'>[pref.nanotrasen_relation]</a><br/>"
. += "Home System: <a href='?src=\ref[src];home_system=1'>[pref.home_system]</a><br/>"
. += "Citizenship: <a href='?src=\ref[src];citizenship=1'>[pref.citizenship]</a><br/>"
. += "Faction: <a href='?src=\ref[src];faction=1'>[pref.faction]</a><br/>"
. += "Religion: <a href='?src=\ref[src];religion=1'>[pref.religion]</a><br/>"
. += "<br/><b>Records</b>:<br/>"
if(jobban_isbanned(user, "Records"))
. += "<span class='danger'>You are banned from using character records.</span><br>"
else
. += "Medical Records:<br>"
. += "<a href='?src=\ref[src];set_medical_records=1'>[TextPreview(pref.med_record,40)]</a><br><br>"
. += "Employment Records:<br>"
. += "<a href='?src=\ref[src];set_general_records=1'>[TextPreview(pref.gen_record,40)]</a><br><br>"
. += "Security Records:<br>"
. += "<a href='?src=\ref[src];set_security_records=1'>[TextPreview(pref.sec_record,40)]</a><br>"
/datum/category_item/player_setup_item/general/background/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["nt_relation"])
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference", pref.nanotrasen_relation) as null|anything in COMPANY_ALIGNMENTS
if(new_relation && CanUseTopic(user))
pref.nanotrasen_relation = new_relation
return TOPIC_REFRESH
else if(href_list["home_system"])
var/choice = input(user, "Please choose a home system.", "Character Preference", pref.home_system) as null|anything in home_system_choices + list("Unset","Other")
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
if(choice == "Other")
var/raw_choice = sanitize(input(user, "Please enter a home system.", "Character Preference") as text|null, MAX_NAME_LEN)
if(raw_choice && CanUseTopic(user))
pref.home_system = raw_choice
else
pref.home_system = choice
return TOPIC_REFRESH
else if(href_list["citizenship"])
var/choice = input(user, "Please choose your current citizenship.", "Character Preference", pref.citizenship) as null|anything in citizenship_choices + list("None","Other")
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
if(choice == "Other")
var/raw_choice = sanitize(input(user, "Please enter your current citizenship.", "Character Preference") as text|null, MAX_NAME_LEN)
if(raw_choice && CanUseTopic(user))
pref.citizenship = raw_choice
else
pref.citizenship = choice
return TOPIC_REFRESH
else if(href_list["faction"])
var/choice = input(user, "Please choose a faction to work for.", "Character Preference", pref.faction) as null|anything in faction_choices + list("None","Other")
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
if(choice == "Other")
var/raw_choice = sanitize(input(user, "Please enter a faction.", "Character Preference") as text|null, MAX_NAME_LEN)
if(raw_choice)
pref.faction = raw_choice
else
pref.faction = choice
return TOPIC_REFRESH
else if(href_list["religion"])
var/choice = input(user, "Please choose a religion.", "Character Preference", pref.religion) as null|anything in religion_choices + list("None","Other")
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
if(choice == "Other")
var/raw_choice = sanitize(input(user, "Please enter a religon.", "Character Preference") as text|null, MAX_NAME_LEN)
if(raw_choice)
pref.religion = sanitize(raw_choice)
else
pref.religion = choice
return TOPIC_REFRESH
else if(href_list["set_medical_records"])
var/new_medical = sanitize(input(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.med_record = new_medical
return TOPIC_REFRESH
else if(href_list["set_general_records"])
var/new_general = sanitize(input(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.gen_record = new_general
return TOPIC_REFRESH
else if(href_list["set_security_records"])
var/sec_medical = sanitize(input(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.sec_record = sec_medical
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,127 @@
/datum/category_item/player_setup_item/general/flavor
name = "Flavor"
sort_order = 6
/datum/category_item/player_setup_item/general/flavor/load_character(var/savefile/S)
S["flavor_texts_general"] >> pref.flavor_texts["general"]
S["flavor_texts_head"] >> pref.flavor_texts["head"]
S["flavor_texts_face"] >> pref.flavor_texts["face"]
S["flavor_texts_eyes"] >> pref.flavor_texts["eyes"]
S["flavor_texts_torso"] >> pref.flavor_texts["torso"]
S["flavor_texts_arms"] >> pref.flavor_texts["arms"]
S["flavor_texts_hands"] >> pref.flavor_texts["hands"]
S["flavor_texts_legs"] >> pref.flavor_texts["legs"]
S["flavor_texts_feet"] >> pref.flavor_texts["feet"]
//Flavour text for robots.
S["flavour_texts_robot_Default"] >> pref.flavour_texts_robot["Default"]
for(var/module in robot_module_types)
S["flavour_texts_robot_[module]"] >> pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/save_character(var/savefile/S)
S["flavor_texts_general"] << pref.flavor_texts["general"]
S["flavor_texts_head"] << pref.flavor_texts["head"]
S["flavor_texts_face"] << pref.flavor_texts["face"]
S["flavor_texts_eyes"] << pref.flavor_texts["eyes"]
S["flavor_texts_torso"] << pref.flavor_texts["torso"]
S["flavor_texts_arms"] << pref.flavor_texts["arms"]
S["flavor_texts_hands"] << pref.flavor_texts["hands"]
S["flavor_texts_legs"] << pref.flavor_texts["legs"]
S["flavor_texts_feet"] << pref.flavor_texts["feet"]
S["flavour_texts_robot_Default"] << pref.flavour_texts_robot["Default"]
for(var/module in robot_module_types)
S["flavour_texts_robot_[module]"] << pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/sanitize_character()
return
/datum/category_item/player_setup_item/general/flavor/content(var/mob/user)
. += "<b>Flavor:</b><br>"
. += "<a href='?src=\ref[src];flavor_text=open'>Set Flavor Text</a><br/>"
. += "<a href='?src=\ref[src];flavour_text_robot=open'>Set Robot Flavor Text</a><br/>"
/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"])
if("open")
if("general")
var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(pref.flavor_texts[href_list["flavor_text"]])) as message, extra = 0)
if(CanUseTopic(user))
pref.flavor_texts[href_list["flavor_text"]] = msg
else
var/msg = sanitize(input(usr,"Set the flavor text for your [href_list["flavor_text"]].","Flavor Text",html_decode(pref.flavor_texts[href_list["flavor_text"]])) as message, extra = 0)
if(CanUseTopic(user))
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")
if("Default")
var/msg = sanitize(input(usr,"Set the default flavour text for your robot. It will be used for any module without individual setting.","Flavour Text",html_decode(pref.flavour_texts_robot["Default"])) as message, extra = 0)
if(CanUseTopic(user))
pref.flavour_texts_robot[href_list["flavour_text_robot"]] = msg
else
var/msg = sanitize(input(usr,"Set the flavour text for your robot with [href_list["flavour_text_robot"]] module. If you leave this empty, default flavour text will be used for this module.","Flavour Text",html_decode(pref.flavour_texts_robot[href_list["flavour_text_robot"]])) as message, extra = 0)
if(CanUseTopic(user))
pref.flavour_texts_robot[href_list["flavour_text_robot"]] = msg
SetFlavourTextRobot(user)
return TOPIC_HANDLED
return ..()
/datum/category_item/player_setup_item/general/flavor/proc/SetFlavorText(mob/user)
var/HTML = "<body>"
HTML += "<tt><center>"
HTML += "<b>Set Flavour Text</b> <hr />"
HTML += "<br></center>"
HTML += "<a href='?src=\ref[src];flavor_text=general'>General:</a> "
HTML += TextPreview(pref.flavor_texts["general"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=head'>Head:</a> "
HTML += TextPreview(pref.flavor_texts["head"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=face'>Face:</a> "
HTML += TextPreview(pref.flavor_texts["face"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=eyes'>Eyes:</a> "
HTML += TextPreview(pref.flavor_texts["eyes"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=torso'>Body:</a> "
HTML += TextPreview(pref.flavor_texts["torso"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=arms'>Arms:</a> "
HTML += TextPreview(pref.flavor_texts["arms"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=hands'>Hands:</a> "
HTML += TextPreview(pref.flavor_texts["hands"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=legs'>Legs:</a> "
HTML += TextPreview(pref.flavor_texts["legs"])
HTML += "<br>"
HTML += "<a href='?src=\ref[src];flavor_text=feet'>Feet:</a> "
HTML += TextPreview(pref.flavor_texts["feet"])
HTML += "<br>"
HTML += "<hr />"
HTML += "<tt>"
user << browse(HTML, "window=flavor_text;size=430x300")
return
/datum/category_item/player_setup_item/general/flavor/proc/SetFlavourTextRobot(mob/user)
var/HTML = "<body>"
HTML += "<tt><center>"
HTML += "<b>Set Robot Flavour Text</b> <hr />"
HTML += "<br></center>"
HTML += "<a href='?src=\ref[src];flavour_text_robot=Default'>Default:</a> "
HTML += TextPreview(pref.flavour_texts_robot["Default"])
HTML += "<hr />"
for(var/module in robot_module_types)
HTML += "<a href='?src=\ref[src];flavour_text_robot=[module]'>[module]:</a> "
HTML += TextPreview(pref.flavour_texts_robot[module])
HTML += "<br>"
HTML += "<hr />"
HTML += "<tt>"
user << browse(HTML, "window=flavour_text_robot;size=430x300")
return
@@ -0,0 +1,74 @@
/datum/category_item/player_setup_item/player_global/ui
name = "UI"
sort_order = 1
/datum/category_item/player_setup_item/player_global/ui/load_preferences(var/savefile/S)
S["UI_style"] >> pref.UI_style
S["UI_style_color"] >> pref.UI_style_color
S["UI_style_alpha"] >> pref.UI_style_alpha
S["ooccolor"] >> pref.ooccolor
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
S["UI_style"] << pref.UI_style
S["UI_style_color"] << pref.UI_style_color
S["UI_style_alpha"] << pref.UI_style_alpha
S["ooccolor"] << pref.ooccolor
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color))
pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha))
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
. += "<b>UI Settings</b><br>"
. += "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
. += "<b>Custom UI</b> (recommended for White UI):<br>"
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a> <table style='display:inline;' bgcolor='[pref.UI_style_color]'><tr><td>__</td></tr></table> <a href='?src=\ref[src];reset=ui'>reset</a><br>"
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a> <a href='?src=\ref[src];reset=alpha'>reset</a><br>"
if(can_select_ooc_color(user))
. += "<b>OOC Color:</b> "
if(pref.ooccolor == initial(pref.ooccolor))
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>"
else
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> <table style='display:inline;' bgcolor='[pref.ooccolor]'><tr><td>__</td></tr></table> <a href='?src=\ref[src];reset=ooc'>reset</a><br>"
/datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["select_style"])
var/UI_style_new = input(user, "Choose UI style.", "Character Preference", pref.UI_style) as null|anything in all_ui_styles
if(!UI_style_new || !CanUseTopic(user)) return TOPIC_NOACTION
pref.UI_style = UI_style_new
return TOPIC_REFRESH
else if(href_list["select_color"])
var/UI_style_color_new = input(user, "Choose UI color, dark colors are not recommended!", "Global Preference", pref.UI_style_color) as color|null
if(isnull(UI_style_color_new) || !CanUseTopic(user)) return TOPIC_NOACTION
pref.UI_style_color = UI_style_color_new
return TOPIC_REFRESH
else if(href_list["select_alpha"])
var/UI_style_alpha_new = input(user, "Select UI alpha (transparency) level, between 50 and 255.", "Global Preference", pref.UI_style_alpha) as num|null
if(isnull(UI_style_alpha_new) || (UI_style_alpha_new < 50 || UI_style_alpha_new > 255) || !CanUseTopic(user)) return TOPIC_NOACTION
pref.UI_style_alpha = UI_style_alpha_new
return TOPIC_REFRESH
else if(href_list["select_ooc_color"])
var/new_ooccolor = input(user, "Choose OOC color:", "Global Preference") as color|null
if(new_ooccolor && can_select_ooc_color(user) && CanUseTopic(user))
pref.ooccolor = new_ooccolor
return TOPIC_REFRESH
else if(href_list["reset"])
switch(href_list["reset"])
if("ui")
pref.UI_style_color = initial(pref.UI_style_color)
if("alpha")
pref.UI_style_alpha = initial(pref.UI_style_alpha)
if("ooc")
pref.ooccolor = initial(pref.ooccolor)
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/player_global/ui/proc/can_select_ooc_color(var/mob/user)
return config.allow_admin_ooccolor && check_rights(R_ADMIN, 0, user)
@@ -0,0 +1,38 @@
/datum/category_item/player_setup_item/player_global/settings
name = "Settings"
sort_order = 2
/datum/category_item/player_setup_item/player_global/settings/load_preferences(var/savefile/S)
S["lastchangelog"] >> pref.lastchangelog
S["default_slot"] >> pref.default_slot
S["toggles"] >> pref.toggles
/datum/category_item/player_setup_item/player_global/settings/save_preferences(var/savefile/S)
S["lastchangelog"] << pref.lastchangelog
S["default_slot"] << pref.default_slot
S["toggles"] << pref.toggles
/datum/category_item/player_setup_item/player_global/settings/sanitize_preferences()
pref.lastchangelog = sanitize_text(pref.lastchangelog, initial(pref.lastchangelog))
pref.default_slot = sanitize_integer(pref.default_slot, 1, config.character_slots, initial(pref.default_slot))
pref.toggles = sanitize_integer(pref.toggles, 0, 65535, initial(pref.toggles))
/datum/category_item/player_setup_item/player_global/settings/content(var/mob/user)
. += "<b>Play admin midis:</b> <a href='?src=\ref[src];toggle=[SOUND_MIDI]'><b>[(pref.toggles & SOUND_MIDI) ? "Yes" : "No"]</b></a><br>"
. += "<b>Play lobby music:</b> <a href='?src=\ref[src];toggle=[SOUND_LOBBY]'><b>[(pref.toggles & SOUND_LOBBY) ? "Yes" : "No"]</b></a><br>"
. += "<b>Ghost ears:</b> <a href='?src=\ref[src];toggle=[CHAT_GHOSTEARS]'><b>[(pref.toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
. += "<b>Ghost sight:</b> <a href='?src=\ref[src];toggle=[CHAT_GHOSTSIGHT]'><b>[(pref.toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
. += "<b>Ghost radio:</b> <a href='?src=\ref[src];toggle=[CHAT_GHOSTRADIO]'><b>[(pref.toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
/datum/category_item/player_setup_item/player_global/settings/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["toggle"])
var/toggle_flag = text2num(href_list["toggle"])
pref.toggles ^= toggle_flag
if(toggle_flag == SOUND_LOBBY && isnewplayer(user))
if(pref.toggles & SOUND_LOBBY)
user << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1)
else
user << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1)
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,55 @@
/datum/category_item/player_setup_item/player_global/language
name = "Language"
sort_order = 3
/datum/category_item/player_setup_item/player_global/language/load_preferences(var/savefile/S)
S["language_prefixes"] >> pref.language_prefixes
/datum/category_item/player_setup_item/player_global/language/save_preferences(var/savefile/S)
S["language_prefixes"] << pref.language_prefixes
/datum/category_item/player_setup_item/player_global/language/sanitize_preferences()
if(isnull(pref.language_prefixes) || !pref.language_prefixes.len)
pref.language_prefixes = config.language_prefixes.Copy()
/datum/category_item/player_setup_item/player_global/language/content(var/mob/user)
. += "<b>Language Keys</b><br>"
. += " [english_list(pref.language_prefixes, and_text = " ", comma_text = " ")] <a href='?src=\ref[src];change_prefix=1'>Change</a> <a href='?src=\ref[src];reset_prefix=1'>Reset</a><br>"
/datum/category_item/player_setup_item/player_global/language/OnTopic(var/href, var/list/href_list, var/mob/user)
if(href_list["change_prefix"])
var/char
var/keys[0]
do
char = input("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") as null|text
if(char)
if(length(char) > 1)
alert(user, "Only single characters allowed.", "Error", "Ok")
else if(char in list(";", ":", "."))
alert(user, "Radio character. Rejected.", "Error", "Ok")
else if(char in list("!","*", "^"))
alert(user, "Say character. Rejected.", "Error", "Ok")
else if(contains_az09(char))
alert(user, "Non-special character. Rejected.", "Error", "Ok")
else
keys.Add(char)
while(char && keys.len < 3)
if(keys.len == 3)
pref.language_prefixes = keys
return TOPIC_REFRESH
else if(href_list["reset_prefix"])
pref.language_prefixes = config.language_prefixes.Copy()
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/player_global/language/update_setup(var/savefile/preferences, var/savefile/character)
if(preferences["version"] == 11)
var/list/prefixes = character["language_prefixes"]
if(istype(prefixes) && prefixes.len)
preferences["language_prefixes"] = prefixes.Copy()
return 1
@@ -0,0 +1,57 @@
/datum/category_item/player_setup_item/player_global/pai
name = "pAI"
sort_order = 4
var/datum/paiCandidate/candidate
/datum/category_item/player_setup_item/player_global/pai/load_preferences(var/savefile/S)
if(!candidate)
candidate = new()
if(!preference_mob())
return
candidate.savefile_load(preference_mob())
/datum/category_item/player_setup_item/player_global/pai/save_preferences(var/savefile/S)
if(!candidate)
return
if(!preference_mob())
return
candidate.savefile_save(preference_mob())
/datum/category_item/player_setup_item/player_global/pai/content(var/mob/user)
if(!candidate)
candidate = new()
. += "<b>pAI:</b><br>"
. += "Name: <a href='?src=\ref[src];option=name'>[candidate.name ? candidate.name : "None Set"]</a><br>"
. += "Description: <a href='?src=\ref[src];option=desc'>[candidate.description ? TextPreview(candidate.description, 40) : "None Set"]</a><br>"
. += "Role: <a href='?src=\ref[src];option=role'>[candidate.role ? TextPreview(candidate.role, 40) : "None Set"]</a><br>"
. += "OOC Comments: <a href='?src=\ref[src];option=ooc'>[candidate.comments ? TextPreview(candidate.comments, 40) : "None Set"]</a><br>"
/datum/category_item/player_setup_item/player_global/pai/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["option"])
var/t
switch(href_list["option"])
if("name")
t = sanitizeName(input(user, "Enter a name for your pAI", "Global Preference", candidate.name) as text|null, MAX_NAME_LEN, 1)
if(t && CanUseTopic(user))
candidate.name = t
if("desc")
t = input(user, "Enter a description for your pAI", "Global Preference", html_decode(candidate.description)) as message|null
if(!isnull(t) && CanUseTopic(user))
candidate.description = sanitize(t)
if("role")
t = input(user, "Enter a role for your pAI", "Global Preference", html_decode(candidate.role)) as text|null
if(!isnull(t) && CanUseTopic(user))
candidate.role = sanitize(t)
if("ooc")
t = input(user, "Enter any OOC comments", "Global Preference", html_decode(candidate.comments)) as message
if(!isnull(t) && CanUseTopic(user))
candidate.comments = sanitize(t)
return TOPIC_REFRESH
return ..()
@@ -0,0 +1,294 @@
//used for pref.alternate_option
#define GET_RANDOM_JOB 0
#define BE_ASSISTANT 1
#define RETURN_TO_LOBBY 2
/datum/category_item/player_setup_item/occupation
name = "Occupation"
sort_order = 1
/datum/category_item/player_setup_item/occupation/load_character(var/savefile/S)
S["alternate_option"] >> pref.alternate_option
S["job_civilian_high"] >> pref.job_civilian_high
S["job_civilian_med"] >> pref.job_civilian_med
S["job_civilian_low"] >> pref.job_civilian_low
S["job_medsci_high"] >> pref.job_medsci_high
S["job_medsci_med"] >> pref.job_medsci_med
S["job_medsci_low"] >> pref.job_medsci_low
S["job_engsec_high"] >> pref.job_engsec_high
S["job_engsec_med"] >> pref.job_engsec_med
S["job_engsec_low"] >> pref.job_engsec_low
S["player_alt_titles"] >> pref.player_alt_titles
/datum/category_item/player_setup_item/occupation/save_character(var/savefile/S)
S["alternate_option"] << pref.alternate_option
S["job_civilian_high"] << pref.job_civilian_high
S["job_civilian_med"] << pref.job_civilian_med
S["job_civilian_low"] << pref.job_civilian_low
S["job_medsci_high"] << pref.job_medsci_high
S["job_medsci_med"] << pref.job_medsci_med
S["job_medsci_low"] << pref.job_medsci_low
S["job_engsec_high"] << pref.job_engsec_high
S["job_engsec_med"] << pref.job_engsec_med
S["job_engsec_low"] << pref.job_engsec_low
S["player_alt_titles"] << pref.player_alt_titles
/datum/category_item/player_setup_item/occupation/sanitize_character()
pref.alternate_option = sanitize_integer(pref.alternate_option, 0, 2, initial(pref.alternate_option))
pref.job_civilian_high = sanitize_integer(pref.job_civilian_high, 0, 65535, initial(pref.job_civilian_high))
pref.job_civilian_med = sanitize_integer(pref.job_civilian_med, 0, 65535, initial(pref.job_civilian_med))
pref.job_civilian_low = sanitize_integer(pref.job_civilian_low, 0, 65535, initial(pref.job_civilian_low))
pref.job_medsci_high = sanitize_integer(pref.job_medsci_high, 0, 65535, initial(pref.job_medsci_high))
pref.job_medsci_med = sanitize_integer(pref.job_medsci_med, 0, 65535, initial(pref.job_medsci_med))
pref.job_medsci_low = sanitize_integer(pref.job_medsci_low, 0, 65535, initial(pref.job_medsci_low))
pref.job_engsec_high = sanitize_integer(pref.job_engsec_high, 0, 65535, initial(pref.job_engsec_high))
pref.job_engsec_med = sanitize_integer(pref.job_engsec_med, 0, 65535, initial(pref.job_engsec_med))
pref.job_engsec_low = sanitize_integer(pref.job_engsec_low, 0, 65535, initial(pref.job_engsec_low))
if(!pref.player_alt_titles) pref.player_alt_titles = new()
if(!job_master)
return
for(var/datum/job/job in job_master.occupations)
var/alt_title = pref.player_alt_titles[job.title]
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 = 16, list/splitJobs = list("Chief Medical Officer"))
if(!job_master)
return
. += "<tt><center>"
. += "<b>Choose occupation chances</b><br>Unavailable occupations are crossed out.<br>"
. += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
. += "<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
if (!job_master) return
for(var/datum/job/job in job_master.occupations)
index += 1
if((index >= limit) || (job.title in splitJobs))
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. Creating a rather nice effect.
for(var/i = 0, i < (limit - index), i += 1)
. += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'><a>&nbsp</a></td><td><a>&nbsp</a></td></tr>"
. += "</table></td><td width='20%'><table width='100%' cellpadding='1' cellspacing='0'>"
index = 0
. += "<tr bgcolor='[job.selection_color]'><td width='60%' align='right'>"
var/rank = job.title
lastJob = job
if(jobban_isbanned(user, rank))
. += "<del>[rank]</del></td><td><b> \[BANNED]</b></td></tr>"
continue
if(!job.player_old_enough(user.client))
var/available_in_days = job.available_in_days(user.client)
. += "<del>[rank]</del></td><td> \[IN [(available_in_days)] DAYS]</td></tr>"
continue
if(job.minimum_character_age && user.client && (user.client.prefs.age < job.minimum_character_age))
. += "<del>[rank]</del></td><td> \[MINIMUM CHARACTER AGE: [job.minimum_character_age]]</td></tr>"
continue
if((pref.job_civilian_low & ASSISTANT) && (rank != "Assistant"))
. += "<font color=orange>[rank]</font></td><td></td></tr>"
continue
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
. += "<b>[rank]</b>"
else
. += "[rank]"
. += "</td><td width='40%'>"
. += "<a href='?src=\ref[src];set_job=[rank]'>"
if(rank == "Assistant")//Assistant is special
if(pref.job_civilian_low & ASSISTANT)
. += " <font color=green>\[Yes]</font>"
else
. += " <font color=red>\[No]</font>"
if(job.alt_titles) //Blatantly cloned from a few lines down.
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'>&nbsp</td><td><a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
. += "</a></td></tr>"
continue
if(pref.GetJobDepartment(job, 1) & job.flag)
. += " <font color=blue>\[High]</font>"
else if(pref.GetJobDepartment(job, 2) & job.flag)
. += " <font color=green>\[Medium]</font>"
else if(pref.GetJobDepartment(job, 3) & job.flag)
. += " <font color=orange>\[Low]</font>"
else
. += " <font color=red>\[NEVER]</font>"
if(job.alt_titles)
. += "</a></td></tr><tr bgcolor='[lastJob.selection_color]'><td width='60%' align='center'>&nbsp</td><td><a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></td></tr>"
. += "</a></td></tr>"
. += "</td'></tr></table>"
. += "</center></table>"
switch(pref.alternate_option)
if(GET_RANDOM_JOB)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=green>Get random job if preferences unavailable</font></a></u></center><br>"
if(BE_ASSISTANT)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=red>Be assistant if preference unavailable</font></a></u></center><br>"
if(RETURN_TO_LOBBY)
. += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=purple>Return to lobby if preference unavailable</font></a></u></center><br>"
. += "<center><a href='?src=\ref[src];reset_jobs=1'>\[Reset\]</a></center>"
. += "</tt>"
/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 = input("Choose an title for [job.title].", "Choose Title", pref.GetPlayerAltTitle(job)) as anything in choices|null
if(choice && CanUseTopic(user))
SetPlayerAltTitle(job, choice)
return TOPIC_REFRESH
else if(href_list["set_job"])
if(SetJob(user, href_list["set_job"])) return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/occupation/proc/SetPlayerAltTitle(datum/job/job, new_title)
// remove existing entry
pref.player_alt_titles -= job.title
// add one if it's not default
if(job.title != new_title)
pref.player_alt_titles[job.title] = new_title
/datum/category_item/player_setup_item/occupation/proc/SetJob(mob/user, role)
var/datum/job/job = job_master.GetJob(role)
if(!job)
return 0
if(role == "Assistant")
if(pref.job_civilian_low & job.flag)
pref.job_civilian_low &= ~job.flag
else
pref.job_civilian_low |= job.flag
return 1
if(pref.GetJobDepartment(job, 1) & job.flag)
SetJobDepartment(job, 1)
else if(pref.GetJobDepartment(job, 2) & job.flag)
SetJobDepartment(job, 2)
else if(pref.GetJobDepartment(job, 3) & job.flag)
SetJobDepartment(job, 3)
else//job = Never
SetJobDepartment(job, 4)
return 1
/datum/category_item/player_setup_item/occupation/proc/SetJobDepartment(var/datum/job/job, var/level)
if(!job || !level) return 0
switch(level)
if(1)//Only one of these should ever be active at once so clear them all here
pref.job_civilian_high = 0
pref.job_medsci_high = 0
pref.job_engsec_high = 0
return 1
if(2)//Set current highs to med, then reset them
pref.job_civilian_med |= pref.job_civilian_high
pref.job_medsci_med |= pref.job_medsci_high
pref.job_engsec_med |= pref.job_engsec_high
pref.job_civilian_high = 0
pref.job_medsci_high = 0
pref.job_engsec_high = 0
switch(job.department_flag)
if(CIVILIAN)
switch(level)
if(2)
pref.job_civilian_high = job.flag
pref.job_civilian_med &= ~job.flag
if(3)
pref.job_civilian_med |= job.flag
pref.job_civilian_low &= ~job.flag
else
pref.job_civilian_low |= job.flag
if(MEDSCI)
switch(level)
if(2)
pref.job_medsci_high = job.flag
pref.job_medsci_med &= ~job.flag
if(3)
pref.job_medsci_med |= job.flag
pref.job_medsci_low &= ~job.flag
else
pref.job_medsci_low |= job.flag
if(ENGSEC)
switch(level)
if(2)
pref.job_engsec_high = job.flag
pref.job_engsec_med &= ~job.flag
if(3)
pref.job_engsec_med |= job.flag
pref.job_engsec_low &= ~job.flag
else
pref.job_engsec_low |= job.flag
return 1
/datum/category_item/player_setup_item/occupation/proc/ResetJobs()
pref.job_civilian_high = 0
pref.job_civilian_med = 0
pref.job_civilian_low = 0
pref.job_medsci_high = 0
pref.job_medsci_med = 0
pref.job_medsci_low = 0
pref.job_engsec_high = 0
pref.job_engsec_med = 0
pref.job_engsec_low = 0
pref.player_alt_titles.Cut()
/datum/preferences/proc/GetPlayerAltTitle(datum/job/job)
return (job.title in player_alt_titles) ? player_alt_titles[job.title] : job.title
/datum/preferences/proc/GetJobDepartment(var/datum/job/job, var/level)
if(!job || !level) return 0
switch(job.department_flag)
if(CIVILIAN)
switch(level)
if(1)
return job_civilian_high
if(2)
return job_civilian_med
if(3)
return job_civilian_low
if(MEDSCI)
switch(level)
if(1)
return job_medsci_high
if(2)
return job_medsci_med
if(3)
return job_medsci_low
if(ENGSEC)
switch(level)
if(1)
return job_engsec_high
if(2)
return job_engsec_med
if(3)
return job_engsec_low
return 0
@@ -0,0 +1,240 @@
// These are not flags, binary operations not intended
#define TOPIC_NOACTION 0
#define TOPIC_HANDLED 1
#define TOPIC_REFRESH 2
/datum/category_group/player_setup_category/general_preferences
name = "General"
sort_order = 1
category_item_type = /datum/category_item/player_setup_item/general
/datum/category_group/player_setup_category/skill_preferences
name = "Skills"
sort_order = 2
category_item_type = /datum/category_item/player_setup_item/skills
/datum/category_group/player_setup_category/occupation_preferences
name = "Occupation"
sort_order = 3
category_item_type = /datum/category_item/player_setup_item/occupation
/datum/category_group/player_setup_category/appearance_preferences
name = "Roles"
sort_order = 4
category_item_type = /datum/category_item/player_setup_item/antagonism
/datum/category_group/player_setup_category/global_preferences
name = "Global"
sort_order = 5
category_item_type = /datum/category_item/player_setup_item/player_global
/****************************
* Category Collection Setup *
****************************/
/datum/category_collection/player_setup_collection
category_group_type = /datum/category_group/player_setup_category
var/datum/preferences/preferences
var/datum/category_group/player_setup_category/selected_category = null
/datum/category_collection/player_setup_collection/New(var/datum/preferences/preferences)
src.preferences = preferences
..()
selected_category = categories[1]
/datum/category_collection/player_setup_collection/Destroy()
preferences = null
selected_category = null
return ..()
/datum/category_collection/player_setup_collection/proc/sanitize_setup()
for(var/datum/category_group/player_setup_category/PS in categories)
PS.sanitize_setup()
/datum/category_collection/player_setup_collection/proc/load_character(var/savefile/S)
for(var/datum/category_group/player_setup_category/PS in categories)
PS.load_character(S)
/datum/category_collection/player_setup_collection/proc/save_character(var/savefile/S)
for(var/datum/category_group/player_setup_category/PS in categories)
PS.save_character(S)
/datum/category_collection/player_setup_collection/proc/load_preferences(var/savefile/S)
for(var/datum/category_group/player_setup_category/PS in categories)
PS.load_preferences(S)
/datum/category_collection/player_setup_collection/proc/save_preferences(var/savefile/S)
for(var/datum/category_group/player_setup_category/PS in categories)
PS.save_preferences(S)
/datum/category_collection/player_setup_collection/proc/update_setup(var/savefile/preferences, var/savefile/character)
for(var/datum/category_group/player_setup_category/PS in categories)
. = . || PS.update_setup(preferences, character)
/datum/category_collection/player_setup_collection/proc/header()
var/dat = ""
for(var/datum/category_group/player_setup_category/PS in categories)
if(PS == selected_category)
dat += "[PS.name] " // TODO: Check how to properly mark a href/button selected in a classic browser window
else
dat += "<a href='?src=\ref[src];category=\ref[PS]'>[PS.name]</a> "
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
var/mob/user = usr
if(!user.client)
return 1
if(href_list["category"])
var/category = locate(href_list["category"])
if(category && category in categories)
selected_category = category
. = 1
if(.)
user.client.prefs.ShowChoices(user)
/**************************
* Category Category Setup *
**************************/
/datum/category_group/player_setup_category
var/sort_order = 0
/datum/category_group/player_setup_category/dd_SortValue()
return sort_order
/datum/category_group/player_setup_category/proc/sanitize_setup()
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_preferences()
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_character()
/datum/category_group/player_setup_category/proc/load_character(var/savefile/S)
// Load all data, then sanitize it.
// Need due to, for example, the 01_basic module relying on species having been loaded to sanitize correctly but that isn't loaded until module 03_body.
for(var/datum/category_item/player_setup_item/PI in items)
PI.load_character(S)
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_character()
/datum/category_group/player_setup_category/proc/save_character(var/savefile/S)
// Sanitize all data, then save it
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_character()
for(var/datum/category_item/player_setup_item/PI in items)
PI.save_character(S)
/datum/category_group/player_setup_category/proc/load_preferences(var/savefile/S)
for(var/datum/category_item/player_setup_item/PI in items)
PI.load_preferences(S)
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_preferences()
/datum/category_group/player_setup_category/proc/save_preferences(var/savefile/S)
for(var/datum/category_item/player_setup_item/PI in items)
PI.sanitize_preferences()
for(var/datum/category_item/player_setup_item/PI in items)
PI.save_preferences(S)
/datum/category_group/player_setup_category/proc/update_setup(var/savefile/preferences, var/savefile/character)
for(var/datum/category_item/player_setup_item/PI in items)
. = . || PI.update_setup(preferences, character)
/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 *
**********************/
/datum/category_item/player_setup_item
var/sort_order = 0
var/datum/preferences/pref
/datum/category_item/player_setup_item/New()
..()
var/datum/category_collection/player_setup_collection/psc = category.collection
pref = psc.preferences
/datum/category_item/player_setup_item/Destroy()
pref = null
return ..()
/datum/category_item/player_setup_item/dd_SortValue()
return sort_order
/*
* Called when the item is asked to load per character settings
*/
/datum/category_item/player_setup_item/proc/load_character(var/savefile/S)
return
/*
* Called when the item is asked to save per character settings
*/
/datum/category_item/player_setup_item/proc/save_character(var/savefile/S)
return
/*
* Called when the item is asked to load user/global settings
*/
/datum/category_item/player_setup_item/proc/load_preferences(var/savefile/S)
return
/*
* Called when the item is asked to save user/global settings
*/
/datum/category_item/player_setup_item/proc/save_preferences(var/savefile/S)
return
/*
* Called when the item is asked to update user/global settings
*/
/datum/category_item/player_setup_item/proc/update_setup(var/savefile/preferences, var/savefile/character)
return 0
/datum/category_item/player_setup_item/proc/content()
return
/datum/category_item/player_setup_item/proc/sanitize_character()
return
/datum/category_item/player_setup_item/proc/sanitize_preferences()
return
/datum/category_item/player_setup_item/Topic(var/href,var/list/href_list)
if(..())
return 1
var/mob/user = usr
if(!user.client)
return 1
. = OnTopic(href, href_list, user)
if(. == TOPIC_REFRESH)
user.client.prefs.ShowChoices(user)
/datum/category_item/player_setup_item/CanUseTopic(var/mob/user)
return 1
/datum/category_item/player_setup_item/proc/OnTopic(var/href,var/list/href_list, var/mob/user)
return TOPIC_NOACTION
/datum/category_item/player_setup_item/proc/preference_mob()
if(pref && pref.client && pref.client.mob)
return pref.client.mob
@@ -0,0 +1,77 @@
/datum/category_item/player_setup_item/skills
name = "Skills"
sort_order = 1
/datum/category_item/player_setup_item/skills/load_character(var/savefile/S)
S["skills"] >> pref.skills
S["used_skillpoints"] >> pref.used_skillpoints
S["skill_specialization"] >> pref.skill_specialization
/datum/category_item/player_setup_item/skills/save_character(var/savefile/S)
S["skills"] << pref.skills
S["used_skillpoints"] << pref.used_skillpoints
S["skill_specialization"] << pref.skill_specialization
/datum/category_item/player_setup_item/skills/sanitize_character()
if(SKILLS == null) setup_skills()
if(!pref.skills) pref.skills = list()
if(!pref.skills.len) pref.ZeroSkills()
if(pref.used_skillpoints < 0) pref.used_skillpoints = 0
/datum/category_item/player_setup_item/skills/content()
. += "<b>Select your Skills</b><br>"
. += "Current skill level: <b>[pref.GetSkillClass(pref.used_skillpoints)]</b> ([pref.used_skillpoints])<br>"
. += "<a href='?src=\ref[src];preconfigured=1'>Use preconfigured skillset</a><br>"
. += "<table>"
for(var/V in SKILLS)
. += "<tr><th colspan = 5><b>[V]</b>"
. += "</th></tr>"
for(var/datum/skill/S in SKILLS[V])
var/level = pref.skills[S.ID]
. += "<tr style='text-align:left;'>"
. += "<th><a href='?src=\ref[src];skillinfo=\ref[S]'>[S.name]</a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_NONE]'><font color=[(level == SKILL_NONE) ? "red" : "black"]>\[Untrained\]</font></a></th>"
// secondary skills don't have an amateur level
if(S.secondary)
. += "<th></th>"
else
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_BASIC]'><font color=[(level == SKILL_BASIC) ? "red" : "black"]>\[Amateur\]</font></a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_ADEPT]'><font color=[(level == SKILL_ADEPT) ? "red" : "black"]>\[Trained\]</font></a></th>"
. += "<th><a href='?src=\ref[src];setskill=\ref[S];newvalue=[SKILL_EXPERT]'><font color=[(level == SKILL_EXPERT) ? "red" : "black"]>\[Professional\]</font></a></th>"
. += "</tr>"
. += "</table>"
/datum/category_item/player_setup_item/skills/OnTopic(href, href_list, user)
if(href_list["skillinfo"])
var/datum/skill/S = locate(href_list["skillinfo"])
var/HTML = "<b>[S.name]</b><br>[S.desc]"
user << browse(HTML, "window=\ref[user]skillinfo")
return TOPIC_HANDLED
else if(href_list["setskill"])
var/datum/skill/S = locate(href_list["setskill"])
var/value = text2num(href_list["newvalue"])
pref.skills[S.ID] = value
pref.CalculateSkillPoints()
return TOPIC_REFRESH
else if(href_list["preconfigured"])
var/selected = input(user, "Select a skillset", "Skillset") as null|anything in SKILL_PRE
if(!selected && !CanUseTopic(user)) return
pref.ZeroSkills(1)
for(var/V in SKILL_PRE[selected])
if(V == "field")
pref.skill_specialization = SKILL_PRE[selected]["field"]
continue
pref.skills[V] = SKILL_PRE[selected][V]
pref.CalculateSkillPoints()
return TOPIC_REFRESH
else if(href_list["setspecialization"])
pref.skill_specialization = href_list["setspecialization"]
pref.CalculateSkillPoints()
return TOPIC_REFRESH
return ..()
File diff suppressed because it is too large Load Diff
+118 -8
View File
@@ -74,22 +74,36 @@ var/global/list/gear_datums = list()
slot = slot_head
/datum/gear/bsec_beret
display_name = "beret, blue (security)"
path = /obj/item/clothing/head/beret/sec/alt
display_name = "beret, navy (officer)"
path = /obj/item/clothing/head/beret/sec/navy/officer
cost = 1
slot = slot_head
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/bsec_beret_warden
display_name = "beret, navy (warden)"
path = /obj/item/clothing/head/beret/sec/navy/warden
cost = 1
slot = slot_head
allowed_roles = list("Head of Security","Warden")
/datum/gear/bsec_beret_hos
display_name = "beret, navy (hos)"
path = /obj/item/clothing/head/beret/sec/navy/hos
cost = 1
slot = slot_head
allowed_roles = list("Head of Security")
/datum/gear/eng_beret
display_name = "beret, engie-orange"
path = /obj/item/clothing/head/beret/eng
path = /obj/item/clothing/head/beret/engineering
cost = 1
slot = slot_head
// allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer")
/datum/gear/purp_beret
display_name = "beret, purple"
path = /obj/item/clothing/head/beret/jan
path = /obj/item/clothing/head/beret/purple
cost = 1
slot = slot_head
@@ -401,6 +415,13 @@ var/global/list/gear_datums = list()
slot = slot_w_uniform
cost = 1
/datum/gear/roboticist_skirt
display_name = "skirt, roboticist"
path = /obj/item/clothing/under/rank/roboticist/skirt
slot = slot_w_uniform
cost = 1
allowed_roles = list("Roboticist")
/datum/gear/amishsuit
display_name = "suit, amish"
path = /obj/item/clothing/under/sl_suit
@@ -582,8 +603,47 @@ var/global/list/gear_datums = list()
slot = slot_w_uniform
cost = 1
// Attachments
// Resomi junk
/datum/gear/resomi_grey
display_name = "Resomi uniform, grey"
path = /obj/item/clothing/under/resomi
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_rainbow
display_name = "Resomi uniform, rainbow"
path = /obj/item/clothing/under/resomi/rainbow
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_white
display_name = "Resomi uniform, white"
path = /obj/item/clothing/under/resomi/white
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_eng
display_name = "Resomi uniform, Engineering"
path = /obj/item/clothing/under/resomi/yellow
cost = 1
slot = slot_w_uniform
allowed_roles = list("Chief Engineer","Station Engineer","Atmospherics Technician")
/datum/gear/resomi_sec
display_name = "Resomi uniform, Security"
path = /obj/item/clothing/under/resomi/red
cost = 1
slot = slot_w_uniform
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/resomi_med
display_name = "Resomi uniform, Medical"
path = /obj/item/clothing/under/resomi/medical
cost = 1
slot = slot_w_uniform
// Attachments
/datum/gear/armband_cargo
display_name = "armband, cargo"
path = /obj/item/clothing/accessory/armband/cargo
@@ -712,7 +772,7 @@ var/global/list/gear_datums = list()
slot = slot_wear_suit
/datum/gear/leather_jacket_nt
display_name = "leather jacket, NanoTrasen, black"
display_name = "leather jacket, corporate, black"
path = /obj/item/clothing/suit/storage/leather_jacket/nanotrasen
cost = 2
slot = slot_wear_suit
@@ -724,7 +784,7 @@ var/global/list/gear_datums = list()
slot = slot_wear_suit
/datum/gear/brown_jacket_nt
display_name = "leather jacket, NanoTrasen, brown"
display_name = "leather jacket, corporate, brown"
path = /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen
cost = 2
slot = slot_wear_suit
@@ -1188,12 +1248,25 @@ var/global/list/gear_datums = list()
sort_category = "utility"
cost = 2
/datum/gear/wallet
display_name = "wallet"
path = /obj/item/weapon/storage/wallet
sort_category = "utility"
cost = 1
/datum/gear/cheaptablet
display_name = "cheap tablet computer"
path = /obj/item/modular_computer/tablet/preset/custom_loadout/cheap
sort_category = "utility"
cost = 3
/datum/gear/normaltablet
display_name = "tablet computer"
path = /obj/item/modular_computer/tablet/preset/custom_loadout/advanced
sort_category = "utility"
cost = 4
// The rest of the trash.
/datum/gear/ashtray
@@ -1202,6 +1275,12 @@ var/global/list/gear_datums = list()
sort_category = "misc"
cost = 1
/datum/gear/boot_knife
display_name = "boot knife"
path = /obj/item/weapon/material/kitchen/utensil/knife/boot
sort_category = "misc"
cost = 3
/datum/gear/cane
display_name = "cane"
path = /obj/item/weapon/cane
@@ -1216,7 +1295,31 @@ var/global/list/gear_datums = list()
/datum/gear/cards
display_name = "deck of cards"
path = /obj/item/weapon/deck
path = /obj/item/weapon/deck/cards
sort_category = "misc"
cost = 1
/datum/gear/tarot
display_name = "deck of tarot cards"
path = /obj/item/weapon/deck/tarot
sort_category = "misc"
cost = 1
/datum/gear/holder
display_name = "card holder"
path = /obj/item/weapon/deck/holder
sort_category = "misc"
cost = 1
/datum/gear/cardemon_pack
display_name = "\improper Cardemon booster pack"
path = /obj/item/weapon/pack/cardemon
sort_category = "misc"
cost = 1
/datum/gear/spaceball_pack
display_name = "\improper Spaceball booster pack"
path = /obj/item/weapon/pack/spaceball
sort_category = "misc"
cost = 1
@@ -1279,12 +1382,19 @@ var/global/list/gear_datums = list()
sort_category = "misc"
cost = 1
/datum/gear/cape
display_name = " tunnel cloak"
path = /obj/item/weapon/storage/backpack/cloak
sort_category = "misc"
cost = 1
/datum/gear/mirror
display_name = "handheld mirror"
path = /obj/item/weapon/mirror
sort_category = "misc"
cost = 1
/datum/gear/zippo
display_name = "zippo"
path = /obj/item/weapon/flame/lighter/zippo
+18 -306
View File
@@ -1,30 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
#define SAVEFILE_VERSION_MAX 11
//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
//If the sanity checks are capable of handling any issues. Only increase SAVEFILE_VERSION_MAX,
//this will mean that savefile_version will still be over SAVEFILE_VERSION_MIN, meaning
//this savefile update doesn't run everytime we load from the savefile.
//This is mainly for format changes, such as the bitflags in toggles changing order or something.
//if a file can't be updated, return 0 to delete it and start again
//if a file was updated, return 1
/datum/preferences/proc/savefile_update()
if(savefile_version < 8) //lazily delete everything + additional files so they can be saved in the new format
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
var/delpath = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/"
if(delpath && fexists(delpath))
fdel(delpath)
break
return 0
if(savefile_version == SAVEFILE_VERSION_MAX) //update successful.
save_preferences()
save_character()
return 1
return 0
#define SAVEFILE_VERSION_MAX 12
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey) return
@@ -39,40 +14,8 @@
S.cd = "/"
S["version"] >> savefile_version
//Conversion
if(!savefile_version || !isnum(savefile_version) || savefile_version < SAVEFILE_VERSION_MIN || savefile_version > SAVEFILE_VERSION_MAX)
if(!savefile_update()) //handles updates
savefile_version = SAVEFILE_VERSION_MAX
save_preferences()
save_character()
return 0
//general preferences
S["ooccolor"] >> ooccolor
S["lastchangelog"] >> lastchangelog
S["UI_style"] >> UI_style
S["be_special"] >> be_special
S["default_slot"] >> default_slot
S["toggles"] >> toggles
S["UI_style_color"] >> UI_style_color
S["UI_style_alpha"] >> UI_style_alpha
S["asfx_togs"] >> asfx_togs
S["motd_hash"] >> motd_hash
S["memo_hash"] >> memo_hash
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
motd_hash = sanitize_text(motd_hash, initial(motd_hash))
memo_hash = sanitize_text(memo_hash, initial(memo_hash))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight","Orange","old"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, config.character_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
asfx_togs = sanitize_integer(asfx_togs, 0, 65535, initial(asfx_togs))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
player_setup.load_preferences(S)
loaded_preferences = S
return 1
/datum/preferences/proc/save_preferences()
@@ -81,19 +24,9 @@
if(!S) return 0
S.cd = "/"
S["version"] << savefile_version
//general preferences
S["ooccolor"] << ooccolor
S["lastchangelog"] << lastchangelog
S["UI_style"] << UI_style
S["be_special"] << be_special
S["default_slot"] << default_slot
S["toggles"] << toggles
S["asfx_togs"] << asfx_togs
S["motd_hash"] << motd_hash
S["memo_hash"] << memo_hash
S["version"] << SAVEFILE_VERSION_MAX
player_setup.save_preferences(S)
loaded_preferences = S
return 1
/datum/preferences/proc/load_character(slot)
@@ -109,156 +42,8 @@
S["default_slot"] << slot
S.cd = "/character[slot]"
//Character
S["OOC_Notes"] >> metadata
S["real_name"] >> real_name
S["name_is_always_random"] >> be_random_name
S["gender"] >> gender
S["age"] >> age
S["species"] >> species
S["language"] >> language
S["spawnpoint"] >> spawnpoint
//colors to be consolidated into hex strings (requires some work with dna code)
S["hair_red"] >> r_hair
S["hair_green"] >> g_hair
S["hair_blue"] >> b_hair
S["facial_red"] >> r_facial
S["facial_green"] >> g_facial
S["facial_blue"] >> b_facial
S["skin_tone"] >> s_tone
S["skin_red"] >> r_skin
S["skin_green"] >> g_skin
S["skin_blue"] >> b_skin
S["hair_style_name"] >> h_style
S["facial_style_name"] >> f_style
S["eyes_red"] >> r_eyes
S["eyes_green"] >> g_eyes
S["eyes_blue"] >> b_eyes
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["backbag"] >> backbag
S["b_type"] >> b_type
//Jobs
S["alternate_option"] >> alternate_option
S["job_civilian_high"] >> job_civilian_high
S["job_civilian_med"] >> job_civilian_med
S["job_civilian_low"] >> job_civilian_low
S["job_medsci_high"] >> job_medsci_high
S["job_medsci_med"] >> job_medsci_med
S["job_medsci_low"] >> job_medsci_low
S["job_engsec_high"] >> job_engsec_high
S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low
//Flavour Text
S["flavor_texts_general"] >> flavor_texts["general"]
S["flavor_texts_head"] >> flavor_texts["head"]
S["flavor_texts_face"] >> flavor_texts["face"]
S["flavor_texts_eyes"] >> flavor_texts["eyes"]
S["flavor_texts_torso"] >> flavor_texts["torso"]
S["flavor_texts_arms"] >> flavor_texts["arms"]
S["flavor_texts_hands"] >> flavor_texts["hands"]
S["flavor_texts_legs"] >> flavor_texts["legs"]
S["flavor_texts_feet"] >> flavor_texts["feet"]
//Flavour text for robots.
S["flavour_texts_robot_Default"] >> flavour_texts_robot["Default"]
for(var/module in robot_module_types)
S["flavour_texts_robot_[module]"] >> flavour_texts_robot[module]
//Miscellaneous
S["med_record"] >> med_record
S["sec_record"] >> sec_record
S["gen_record"] >> gen_record
S["be_special"] >> be_special
S["disabilities"] >> disabilities
S["player_alt_titles"] >> player_alt_titles
S["used_skillpoints"] >> used_skillpoints
S["skills"] >> skills
S["skill_specialization"] >> skill_specialization
S["organ_data"] >> organ_data
S["rlimb_data"] >> rlimb_data
S["gear"] >> gear
S["home_system"] >> home_system
S["citizenship"] >> citizenship
S["faction"] >> faction
S["religion"] >> religion
S["nanotrasen_relation"] >> nanotrasen_relation
//S["skin_style"] >> skin_style
S["uplinklocation"] >> uplinklocation
S["exploit_record"] >> exploit_record
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = sanitizeName(real_name)
if(isnull(species) || !(species in playable_species))
species = "Human"
if(isnum(underwear))
var/list/undies = gender == MALE ? underwear_m : underwear_f
underwear = undies[undies[underwear]]
if(isnum(undershirt))
undershirt = undershirt_t[undershirt_t[undershirt]]
if(isnull(language)) language = "None"
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, getMinAge(), getMaxAge(), initial(age))
r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
if(!skills) skills = list()
if(!used_skillpoints) used_skillpoints= 0
if(isnull(disabilities)) disabilities = 0
if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
if(!rlimb_data) src.rlimb_data = list()
if(!gear) src.gear = list()
//if(!skin_style) skin_style = "Default"
if(!home_system) home_system = "Unset"
if(!citizenship) citizenship = "None"
if(!faction) faction = "None"
if(!religion) religion = "None"
player_setup.load_character(S)
loaded_character = S
return 1
/datum/preferences/proc/save_character()
@@ -267,92 +52,19 @@
if(!S) return 0
S.cd = "/character[default_slot]"
//Character
S["OOC_Notes"] << metadata
S["real_name"] << real_name
S["name_is_always_random"] << be_random_name
S["gender"] << gender
S["age"] << age
S["species"] << species
S["language"] << language
S["hair_red"] << r_hair
S["hair_green"] << g_hair
S["hair_blue"] << b_hair
S["facial_red"] << r_facial
S["facial_green"] << g_facial
S["facial_blue"] << b_facial
S["skin_tone"] << s_tone
S["skin_red"] << r_skin
S["skin_green"] << g_skin
S["skin_blue"] << b_skin
S["hair_style_name"] << h_style
S["facial_style_name"] << f_style
S["eyes_red"] << r_eyes
S["eyes_green"] << g_eyes
S["eyes_blue"] << b_eyes
S["underwear"] << underwear
S["undershirt"] << undershirt
S["backbag"] << backbag
S["b_type"] << b_type
S["spawnpoint"] << spawnpoint
//Jobs
S["alternate_option"] << alternate_option
S["job_civilian_high"] << job_civilian_high
S["job_civilian_med"] << job_civilian_med
S["job_civilian_low"] << job_civilian_low
S["job_medsci_high"] << job_medsci_high
S["job_medsci_med"] << job_medsci_med
S["job_medsci_low"] << job_medsci_low
S["job_engsec_high"] << job_engsec_high
S["job_engsec_med"] << job_engsec_med
S["job_engsec_low"] << job_engsec_low
//Flavour Text
S["flavor_texts_general"] << flavor_texts["general"]
S["flavor_texts_head"] << flavor_texts["head"]
S["flavor_texts_face"] << flavor_texts["face"]
S["flavor_texts_eyes"] << flavor_texts["eyes"]
S["flavor_texts_torso"] << flavor_texts["torso"]
S["flavor_texts_arms"] << flavor_texts["arms"]
S["flavor_texts_hands"] << flavor_texts["hands"]
S["flavor_texts_legs"] << flavor_texts["legs"]
S["flavor_texts_feet"] << flavor_texts["feet"]
//Flavour text for robots.
S["flavour_texts_robot_Default"] << flavour_texts_robot["Default"]
for(var/module in robot_module_types)
S["flavour_texts_robot_[module]"] << flavour_texts_robot[module]
//Miscellaneous
S["med_record"] << med_record
S["sec_record"] << sec_record
S["gen_record"] << gen_record
S["player_alt_titles"] << player_alt_titles
S["be_special"] << be_special
S["disabilities"] << disabilities
S["used_skillpoints"] << used_skillpoints
S["skills"] << skills
S["skill_specialization"] << skill_specialization
S["organ_data"] << organ_data
S["rlimb_data"] << rlimb_data
S["gear"] << gear
S["home_system"] << home_system
S["citizenship"] << citizenship
S["faction"] << faction
S["religion"] << religion
S["nanotrasen_relation"] << nanotrasen_relation
//S["skin_style"] << skin_style
S["uplinklocation"] << uplinklocation
S["exploit_record"] << exploit_record
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
S["version"] << SAVEFILE_VERSION_MAX
player_setup.save_character(S)
loaded_character = S
return S
/datum/preferences/proc/sanitize_preferences()
player_setup.sanitize_setup()
return 1
/datum/preferences/proc/update_setup(var/savefile/preferences, var/savefile/character)
if(!preferences || !character)
return 0
return player_setup.update_setup(preferences, character)
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
@@ -145,53 +145,3 @@
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//be special
/client/verb/toggle_be_special(role in be_special_flags)
set name = "Toggle SpecialRole Candidacy"
set category = "Preferences"
set desc = "Toggles which special roles you would like to be a candidate for, during events."
var/role_flag = be_special_flags[role]
if(!role_flag) return
prefs.be_special ^= role_flag
prefs.handle_preferences_save(src)
src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/change_ui()
set name = "Change UI"
set category = "Preferences"
set desc = "Configure your user interface"
if(!ishuman(usr))
usr << "This only for human"
return
var/UI_style_new = input(usr, "Select a style, we recommend White for customization") in list("White", "Midnight", "Orange", "old")
if(!UI_style_new) return
var/UI_style_alpha_new = input(usr, "Select a new alpha(transparence) parametr for UI, between 50 and 255") as num
if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
var/UI_style_color_new = input(usr, "Choose your UI color, dark colors are not recommended!") as color|null
if(!UI_style_color_new) return
//update UI
var/list/icons = usr.hud_used.adding + usr.hud_used.other +usr.hud_used.hotkeybuttons
icons.Add(usr.zone_sel)
for(var/obj/screen/I in icons)
if(I.name in list(I_HELP, I_HURT, I_DISARM, I_GRAB)) continue
I.icon = ui_style2icon(UI_style_new)
I.color = UI_style_color_new
I.alpha = UI_style_alpha_new
if(alert("Like it? Save changes?",,"Yes", "No") == "Yes")
prefs.UI_style = UI_style_new
prefs.UI_style_alpha = UI_style_alpha_new
prefs.UI_style_color = UI_style_color_new
prefs.handle_preferences_save(src)
usr << "UI was saved"
+57
View File
@@ -0,0 +1,57 @@
/var/all_ui_styles = list(
"Midnight" = 'icons/mob/screen/midnight.dmi',
"Orange" = 'icons/mob/screen/orange.dmi',
"old" = 'icons/mob/screen/old.dmi',
"White" = 'icons/mob/screen/white.dmi',
"old-noborder" = 'icons/mob/screen/old-noborder.dmi'
)
/proc/ui_style2icon(ui_style)
if(ui_style in all_ui_styles)
return all_ui_styles[ui_style]
return all_ui_styles["White"]
/client/verb/change_ui()
set name = "Change UI"
set category = "Preferences"
set desc = "Configure your user interface"
if(!ishuman(usr))
usr << "<span class='warning'>You must be human to use this verb.</span>"
return
var/UI_style_new = input(usr, "Select a style. White is recommended for customization") as null|anything in all_ui_styles
if(!UI_style_new) return
var/UI_style_alpha_new = input(usr, "Select a new alpha (transparency) parameter for your UI, between 50 and 255") as null|num
if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
var/UI_style_color_new = input(usr, "Choose your UI color. Dark colors are not recommended!") as color|null
if(!UI_style_color_new) return
//update UI
var/list/icons = usr.hud_used.adding + usr.hud_used.other + usr.hud_used.hotkeybuttons
icons.Add(usr.zone_sel)
icons.Add(usr.gun_setting_icon)
icons.Add(usr.item_use_icon)
icons.Add(usr.gun_move_icon)
icons.Add(usr.radio_use_icon)
var/icon/ic = all_ui_styles[UI_style_new]
for(var/obj/screen/I in icons)
if(I.name in list(I_HELP, I_HURT, I_DISARM, I_GRAB)) continue
I.icon = ic
I.color = UI_style_color_new
I.alpha = UI_style_alpha_new
if(alert("Like it? Save changes?",,"Yes", "No") == "Yes")
prefs.UI_style = UI_style_new
prefs.UI_style_alpha = UI_style_alpha_new
prefs.UI_style_color = UI_style_color_new
prefs.save_preferences()
usr << "UI was saved"