Character Creation Overhaul (#7987)

* Rebase fail. good thing I made back ups. c:

* Tails more or less done

* wouldn't update cleanly otherwise

* It's completly working now. holy fuck I did it

Just need the refurbished body markings done, then to chop 'em up for full PR status

* MARKINGS DONE AAAAAAAAAAAAA

* fixes digi legs that didn't convert correctly

* ports the refractored preferences

Kinda ugly now tbh. but fuckit

* quality sweep, things should should properly now in general

* Taurs converted and improved! BODYMARKING -> MATRIXED

* oops. s'what I get for not compile checking

* remember to throw shade at furries

* vigorously update markings upon switching species and colors

* re-adds old wolf ears, Big Wolf fixes snout bugs

* few more snout tweaks

* cut the lists, cut everything. reeee

* This code I s2g

* Adds context clues to preferences

Hopefully people will read them before making an OOC fuss

* Fixes hands and feet markings with this one weird trick

remember kids, proper layering and order of operations is important

* Sprite tweaking and polishing

Sergal stuff being worked on

* a few QoL things for species swapping

* how the fuck did I miss these markings

* fleshes out sprites in preperation for marking experimentation later

* fixes catboy problems

* Mam_snout is a thing now,

* pixel adjusted tails, cleaned up wah tail a bit better

also gets digitgate legs missing pixels fixed

* cleans up more shit. ree

* force "plain" instead of none to avoid missing pixel reports

* tweaks to reinspire mapdiff

* Clean up Preference UI

Looks a little better now

* k

* doubly ensure None markings aren't valid

* reee spessman barbie

* brightens pixels around tiger head markings

* YEENS

* Cat ears tweaked because it triggers Kev otherwise

* another session of quality control

* Crows and crow accessories

* husk fixes

* works good enough, mission accomplished

* fixes the proc properly

* cleans up brute force code that isn't needed

* c a t
This commit is contained in:
Poojawa
2019-02-22 07:59:05 -06:00
committed by kevinz000
parent d043323c69
commit b393789f19
45 changed files with 1094 additions and 457 deletions
+3 -1
View File
@@ -72,4 +72,6 @@
var/list/credits //lazy list of all credit object bound to this client
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
+21
View File
@@ -454,6 +454,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
GLOB.ahelp_tickets.ClientLogout(src)
GLOB.directory -= ckey
GLOB.clients -= src
QDEL_LIST_ASSOC_VAL(char_render_holders)
if(movingmob != null)
movingmob.client_mobs_in_contents -= mob
UNSETEMPTY(movingmob.client_mobs_in_contents)
@@ -877,3 +878,23 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
/client/proc/AnnouncePR(announcement)
if(prefs && prefs.chat_toggles & CHAT_PULLR)
to_chat(src, announcement)
/client/proc/show_character_previews(mutable_appearance/MA)
var/pos = 0
for(var/D in GLOB.cardinals)
pos++
var/obj/screen/O = LAZYACCESS(char_render_holders, "[D]")
if(!O)
O = new
LAZYSET(char_render_holders, "[D]", O)
screen |= O
O.appearance = MA
O.dir = D
O.screen_loc = "character_preview_map:0,[pos]"
/client/proc/clear_character_previews()
for(var/index in char_render_holders)
var/obj/screen/S = char_render_holders[index]
screen -= S
qdel(S)
char_render_holders = null
+191 -104
View File
@@ -74,17 +74,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/eye_color = "000" //Eye color
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFF",
"tail_lizard" = "Smooth", "tail_human" = "None",
"snout" = "Round", "horns" = "None", "ears" = "None",
"tail_lizard" = "Smooth", "tail_human" = "Cat",
"snout" = "Round", "horns" = "None", "ears" = "Cat",
"wings" = "None", "frills" = "None", "spines" = "None",
"body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain")
var/list/custom_names = list()
var/prefered_security_department = SEC_DEPT_RANDOM
//Mob preview
var/icon/preview_icon = null
//Quirk list
var/list/positive_quirks = list()
var/list/negative_quirks = list()
@@ -155,17 +152,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
menuoptions = list()
return
#define APPEARANCE_CATEGORY_COLUMN "<td valign='top' width='14%'>"
#define APPEARANCE_CATEGORY_COLUMN "<td valign='top' width='17%'>"
#define MAX_MUTANT_ROWS 4
/datum/preferences/proc/ShowChoices(mob/user)
if(!user || !user.client)
return
if(current_tab == 2) //CITADEL EDIT, for muh nudies
update_preview_icon(nude=TRUE)
else
update_preview_icon(nude=FALSE) //EDIT END
user << browse_rsc(preview_icon, "previewicon.png")
update_preview_icon()
var/list/dat = list("<center>")
dat += "<a href='?_src_=prefs;preference=tab;tab=0' [current_tab == 0 ? "class='linkOn'" : ""]>Character Settings</a>"
@@ -210,14 +203,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(jobban_isbanned(user, "appearance"))
dat += "<b>You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.</b><br>"
dat += "<a href='?_src_=prefs;preference=name;task=random'>Random Name</A> "
dat += "<a href='?_src_=prefs;preference=name'>Always Random Name: [be_random_name ? "Yes" : "No"]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=name;task=random'>Random Name</A> "
dat += "<b>Always Random Name:</b><a style='display:block;width:30px' href='?_src_=prefs;preference=name'>[be_random_name ? "Yes" : "No"]</a><BR>"
dat += "<b>Name:</b> "
dat += "<b>Name:</b>"
dat += "<a href='?_src_=prefs;preference=name;task=input'>[real_name]</a><BR>"
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
dat += "<b>Age:</b> <a href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
dat += "<b>Age:</b> <a style='display:block;width:30px' href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
dat += "<b>Special Names:</b><BR>"
var/old_group
@@ -233,19 +226,32 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Custom job preferences:</b><BR>"
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Prefered security department:</b> [prefered_security_department]</a><BR></td>"
dat += "<td valign='center'>"
dat += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
dat += "</td></tr></table>"
dat += "</tr></table>"
//Character Appearance
if(2)
update_preview_icon(nude=TRUE)
user << browse_rsc(preview_icon, "previewicon.png")
if(path)
var/savefile/S = new /savefile(path)
if(S)
dat += "<center>"
var/name
var/unspaced_slots = 0
for(var/i=1, i<=max_save_slots, i++)
unspaced_slots++
if(unspaced_slots > 4)
dat += "<br>"
unspaced_slots = 0
S.cd = "/character[i]"
S["real_name"] >> name
if(!name)
name = "Character[i]"
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
dat += "</center>"
update_preview_icon()
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Flavor Text</b></a><br>"
dat += "<h2>Flavor Text</h2>"
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Examine Text</b></a><br>"
if(lentext(features["flavor_text"]) <= 40)
if(!lentext(features["flavor_text"]))
dat += "\[...\]"
@@ -254,10 +260,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "[TextPreview(features["flavor_text"])]...<BR>"
dat += "<h2>Body</h2>"
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
dat += "<b>Species:</b><a href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
dat += "<a href='?_src_=prefs;preference=all;task=random'>Random Body</A><BR>"
dat += "<a href='?_src_=prefs;preference=all'>Always Random Body: [be_random_body ? "Yes" : "No"]</A><BR>"
dat += "<b>Gender:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
dat += "<b>Species:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=all;task=random'>Random Body</A><BR>"
dat += "<b>Always Random Body:</b><a href='?_src_=prefs;preference=all'>[be_random_body ? "Yes" : "No"]</A><BR>"
var/use_skintones = pref_species.use_skintones
if(use_skintones)
@@ -265,17 +271,23 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Skin Tone</h3>"
dat += "<a href='?_src_=prefs;preference=s_tone;task=input'>[skin_tone]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=s_tone;task=input'>[skin_tone]</a><BR>"
var/mutant_colors
if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
if(!use_skintones)
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Body Colors</h3><BR>"
dat += "<b>Primary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color;task=input'>Change</a><BR>"
dat += "<b>Secondary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor2"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color2;task=input'>Change</a><BR>"
dat += "<b>Tertiary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
dat += "<h2>Body Colors</h2>"
dat += "<b>Primary Color:</b><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color;task=input'>Change</a><BR>"
dat += "<b>Secondary Color:</b><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor2"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color2;task=input'>Change</a><BR>"
dat += "<b>Tertiary Color:</b><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
mutant_colors = TRUE
if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits))
@@ -297,13 +309,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Hair Style</h3>"
dat += "<a href='?_src_=prefs;preference=hair_style;task=input'>[hair_style]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=hair_style;task=input'>[hair_style]</a>"
dat += "<a href='?_src_=prefs;preference=previous_hair_style;task=input'>&lt;</a> <a href='?_src_=prefs;preference=next_hair_style;task=input'>&gt;</a><BR>"
dat += "<span style='border:1px solid #161616; background-color: #[hair_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=hair;task=input'>Change</a><BR>"
dat += "<h3>Facial Hair Style</h3>"
dat += "<a href='?_src_=prefs;preference=facial_hair_style;task=input'>[facial_hair_style]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=facial_hair_style;task=input'>[facial_hair_style]</a>"
dat += "<a href='?_src_=prefs;preference=previous_facehair_style;task=input'>&lt;</a> <a href='?_src_=prefs;preference=next_facehair_style;task=input'>&gt;</a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[facial_hair_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=facial;task=input'>Change</a><BR>"
@@ -317,7 +329,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Tail</h3>"
dat += "<a href='?_src_=prefs;preference=tail_lizard;task=input'>[features["tail_lizard"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=tail_lizard;task=input'>[features["tail_lizard"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -330,7 +342,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Tail</h3>"
dat += "<a href='?_src_=prefs;preference=mam_tail;task=input'>[features["mam_tail"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=mam_tail;task=input'>[features["mam_tail"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -342,7 +354,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Tail</h3>"
dat += "<a href='?_src_=prefs;preference=tail_human;task=input'>[features["tail_human"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=tail_human;task=input'>[features["tail_human"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -354,7 +366,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Snout</h3>"
dat += "<a href='?_src_=prefs;preference=snout;task=input'>[features["snout"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=snout;task=input'>[features["snout"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -366,7 +378,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Horns</h3>"
dat += "<a href='?_src_=prefs;preference=horns;task=input'>[features["horns"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=horns;task=input'>[features["horns"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -377,7 +389,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Frills</h3>"
dat += "<a href='?_src_=prefs;preference=frills;task=input'>[features["frills"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=frills;task=input'>[features["frills"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -390,7 +402,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Spines</h3>"
dat += "<a href='?_src_=prefs;preference=spines;task=input'>[features["spines"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=spines;task=input'>[features["spines"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -403,7 +415,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Body Markings</h3>"
dat += "<a href='?_src_=prefs;preference=body_markings;task=input'>[features["body_markings"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=body_markings;task=input'>[features["body_markings"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -415,7 +427,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Species Markings</h3>"
dat += "<a href='?_src_=prefs;preference=mam_body_markings;task=input'>[features["mam_body_markings"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=mam_body_markings;task=input'>[features["mam_body_markings"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -427,7 +439,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Ears</h3>"
dat += "<a href='?_src_=prefs;preference=mam_ears;task=input'>[features["mam_ears"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=mam_ears;task=input'>[features["mam_ears"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -439,7 +451,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Ears</h3>"
dat += "<a href='?_src_=prefs;preference=ears;task=input'>[features["ears"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=ears;task=input'>[features["ears"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("mam_snouts" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Snout</h3>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=mam_snouts;task=input'>[features["mam_snouts"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -451,7 +475,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Legs</h3>"
dat += "<a href='?_src_=prefs;preference=legs;task=input'>[features["legs"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=legs;task=input'>[features["legs"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -463,7 +487,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Moth wings</h3>"
dat += "<a href='?_src_=prefs;preference=moth_wings;task=input'>[features["moth_wings"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=moth_wings;task=input'>[features["moth_wings"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -475,7 +499,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Tauric Body</h3>"
dat += "<a href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -487,7 +511,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Wings</h3>"
dat += "<a href='?_src_=prefs;preference=wings;task=input'>[features["wings"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=wings;task=input'>[features["wings"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -499,7 +523,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Caste Head</h3>"
dat += "<a href='?_src_=prefs;preference=xenohead;task=input'>[features["xenohead"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=xenohead;task=input'>[features["xenohead"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -511,7 +535,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Tail</h3>"
dat += "<a href='?_src_=prefs;preference=xenotail;task=input'>[features["xenotail"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=xenotail;task=input'>[features["xenotail"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -523,7 +547,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Dorsal Spines</h3>"
dat += "<a href='?_src_=prefs;preference=xenodorsal;task=input'>[features["xenodorsal"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=xenodorsal;task=input'>[features["xenodorsal"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -535,7 +559,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Screen</h3>"
dat += "<a href='?_src_=prefs;preference=ipc_screen;task=input'>[features["ipc_screen"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=ipc_screen;task=input'>[features["ipc_screen"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -547,7 +571,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<h3>Antenna</h3>"
dat += "<a href='?_src_=prefs;preference=ipc_antenna;task=input'>[features["ipc_antenna"]]</a><BR>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=ipc_antenna;task=input'>[features["ipc_antenna"]]</a>"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
@@ -560,53 +584,69 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</tr></table>"
dat += "</td><td width='300px' height='300px' valign='top'>"
dat += "</td>"
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h2>Clothing & Equipment</h2>"
dat += "<b>Underwear:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a>"
dat += "<b>Undershirt:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a>"
dat += "<b>Socks:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=socks;task=input'>[socks]</a>"
dat += "<b>Backpack:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a>"
dat += "<b>Uplink Location:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a>"
dat += "</td>"
dat += "<b>Underwear:</b><a href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a><br>"
dat += "<b>Undershirt:</b><a href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a><br>"
dat += "<b>Socks:</b><a href ='?_src_=prefs;preference=socks;task=input'>[socks]</a><br>"
dat += "<b>Backpack:</b><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><br>"
dat += "<b>Uplink Location:</b><a href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a><br>"
dat += "<h2>Genitals</h2>"
dat +="<td width='220px' height='300px' valign='top'>"
if(NOGENITALS in pref_species.species_traits)
dat += "<b>Your species ([pref_species.name]) does not support genitals!</b><br>"
else
if(pref_species.use_skintones)
dat += "<b>Genitals use skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Has Penis:</b><a href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Genitals use skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]</a>"
dat += "<b>Has Penis:</b>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_cock"] == TRUE)
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<BR>"
dat += "<b>Penis Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><BR>"
dat += "<b>Penis Shape:</b> <a href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a><BR>"
dat += "<b>Penis Length:</b> <a href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a><BR>"
dat += "<b>Has Testicles:</b><a href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Penis Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a>"
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_balls"] == TRUE)
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<BR>"
dat += "<b>Testicles Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><BR>"
dat += "<b>Has Vagina:</b><a href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Testicles Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<b>Has Vagina:</b>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_vag"])
dat += "<b>Vagina Type:</b> <a href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a><BR>"
dat += "<b>Vagina Type:</b> <a style='display:block;width:100px' href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a>"
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<BR>"
dat += "<b>Vagina Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><BR>"
dat += "<b>Has Womb:</b><a href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Has Breasts:</b><a href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Vagina Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><br>"
dat += "<b>Has Womb:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a>"
dat += "</td>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<b>Has Breasts:</b>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_breasts"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<BR>"
dat += "<b>Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><BR>"
dat += "<b>Cup Size:</b><a href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a><br>"
dat += "<b>Breast Shape:</b><a href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a><br>"
dat += "</td></tr></table>"
dat += "<b>Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><br>"
dat += "<b>Cup Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a>"
dat += "<b>Breast Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
dat += "</td>"
dat += "</td>"
dat += "</tr></table>"
if (1) // Game Preferences
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
@@ -646,6 +686,21 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<br>"
dat += "<b>Combo HUD Lighting:</b> <a href = '?_src_=prefs;preference=combohud_lighting'>[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]</a><br>"
dat += "</td>"
dat +="<td width='300px' height='300px' valign='top'>"
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Exhibitionist:</b><a href='?_src_=prefs;preference=exhibitionist'>[features["exhibitionist"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
if (user && user.client && !user.client.prefs.screenshake==0)
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
dat += "<br>"
dat += "</td>"
dat += "</tr></table>"
if(unlock_content)
dat += "<b>Ghost Form:</b> <a href='?_src_=prefs;task=input;preference=ghostform'>[ghost_form]</a><br>"
@@ -731,18 +786,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
dat += "<br>"
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Exhibitionist:</b><a href='?_src_=prefs;preference=exhibitionist'>[features["exhibitionist"] == TRUE ? "Yes" : "No"]</a><BR>"
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
if (user && user.client && !user.client.prefs.screenshake==0)
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
dat += "<br>"
if(3)
if(!gear_tab)
@@ -804,9 +847,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
dat += "</center>"
var/datum/browser/popup = new(user, "preferences", "<div align='center'>Character Setup</div>", 640, 770)
winshow(user, "preferences_window", TRUE)
var/datum/browser/popup = new(user, "preferences_browser", "<div align='center'>Character Setup</div>", 640, 770)
popup.set_content(dat.Join())
popup.open(0)
popup.open(FALSE)
onclose(user, "preferences_window", src)
#undef APPEARANCE_CATEGORY_COLUMN
#undef MAX_MUTANT_ROWS
@@ -932,12 +977,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
HTML += "<center><br><a href='?_src_=prefs;preference=job;task=random'>[message]</a></center>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=reset'>Reset Preferences</a></center>"
user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Occupation Preferences</div>", width, height)
popup.set_window_options("can_close=0")
popup.set_content(HTML)
popup.open(0)
return
popup.open(FALSE)
/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level)
if (!job)
@@ -1126,12 +1169,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>"
user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Quirk Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
popup.set_window_options("can_close=0")
popup.set_content(dat.Join())
popup.open(0)
return
popup.open(FALSE)
/datum/preferences/proc/GetQuirkBalance()
var/bal = 0
@@ -1140,6 +1181,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
bal -= initial(T.value)
return bal
/datum/preferences/Topic(href, href_list, hsrc) //yeah, gotta do this I guess..
. = ..()
if(href_list["close"])
var/client/C = usr.client
if(C)
C.clear_character_previews()
/datum/preferences/proc/process_link(mob/user, list/href_list)
if(href_list["jobbancheck"])
var/job = sanitizeSQL(href_list["jobbancheck"])
@@ -1412,6 +1460,23 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(result)
var/newtype = GLOB.species_list[result]
pref_species = new newtype()
//let's ensure that no weird shit happens on species swapping.
if(!("body_markings" in pref_species.default_features))
features["body_markings"] = "None"
if(!("mam_body_markings" in pref_species.default_features))
features["mam_body_markings"] = "None"
if("mam_body_markings" in pref_species.default_features && features["mam_body_markings"] == "None")
features["mam_body_markings"] = "Plain"
if("tail_lizard" in pref_species.default_features)
features["tail_lizard"] = "Smooth"
if("mam_tail" in pref_species.default_features)
features["mam_tail"] = "None"
if("mam_ears" in pref_species.default_features)
features["mam_ears"] = "None"
if(pref_species.id == "felinid")
features["mam_tail"] = "Cat"
features["mam_ears"] = "Cat"
//Now that we changed our species, we must verify that the mutant colour is still allowed.
var/temp_hsv = RGBtoHSV(features["mcolor"])
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
@@ -1427,8 +1492,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor"] = pref_species.default_color
update_preview_icon()
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
update_preview_icon()
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1438,8 +1505,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor2"] = pref_species.default_color
update_preview_icon()
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
update_preview_icon()
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1449,8 +1518,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor3"] = pref_species.default_color
update_preview_icon()
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
update_preview_icon()
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1516,6 +1587,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_snout)
features["snout"] = new_snout
if("mam_snouts")
var/new_mam_snouts
new_mam_snouts = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.mam_snouts_list
if(new_mam_snouts)
features["mam_snouts"] = new_mam_snouts
if("horns")
var/new_horns
new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list
@@ -1551,12 +1628,16 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list
if(new_body_markings)
features["body_markings"] = new_body_markings
if(new_body_markings != "None")
features["mam_body_markings"] = "None"
update_preview_icon()
if("legs")
var/new_legs
new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list
if(new_legs)
features["legs"] = new_legs
update_preview_icon()
if("moth_wings")
var/new_moth_wings
@@ -1625,6 +1706,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in snowflake_markings_list
if(new_mam_body_markings)
features["mam_body_markings"] = new_mam_body_markings
if(new_mam_body_markings != "None")
features["body_markings"] = "None"
else if(new_mam_body_markings == "None")
features["mam_body_markings"] = "Plain"
features["body_markings"] = "None"
update_preview_icon()
//Xeno Bodyparts
if("xenohead")//Head or caste type
@@ -301,6 +301,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_mam_ears"] >> features["mam_ears"]
S["feature_mam_tail_animated"] >> features["mam_tail_animated"]
S["feature_taur"] >> features["taur"]
S["feature_mam_snouts"] >> features["mam_snouts"]
//Xeno features
S["feature_xeno_tail"] >> features["xenotail"]
S["feature_xeno_dors"] >> features["xenodorsal"]