diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index 750e15488b5..0fe48a8ffdf 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -82,6 +82,7 @@ CREATE TABLE `characters` (
`speciesprefs` int(1) NOT NULL,
`socks` mediumtext NOT NULL,
`body_accessory` mediumtext NOT NULL,
+ `gear` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18747 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql
index 8af09a45737..cc73257ebe2 100644
--- a/SQL/paradise_schema_prefixed.sql
+++ b/SQL/paradise_schema_prefixed.sql
@@ -82,6 +82,7 @@ CREATE TABLE `SS13_characters` (
`speciesprefs` int(1) NOT NULL,
`socks` mediumtext NOT NULL,
`body_accessory` mediumtext NOT NULL,
+ `gear` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18747 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 9f9658a9dff..5147f6d061a 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -379,9 +379,60 @@ var/global/datum/controller/occupations/job_master
proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
if(!H) return null
var/datum/job/job = GetJob(rank)
+ var/list/spawn_in_storage = list()
+
if(job)
+
+ //Equip custom gear loadout.
+ var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage.
+ var/list/custom_equip_leftovers = list()
+ if(H.client.prefs.gear && H.client.prefs.gear.len && job.title != "Cyborg" && job.title != "AI")
+ for(var/thing in H.client.prefs.gear)
+ var/datum/gear/G = gear_datums[thing]
+ if(G)
+ var/permitted
+ if(G.allowed_roles)
+ for(var/job_name in G.allowed_roles)
+ if(job.title == job_name)
+ permitted = 1
+ else
+ permitted = 1
+
+ if(G.whitelisted && !is_alien_whitelisted(H, G.whitelisted))
+ permitted = 0
+
+ if(!permitted)
+ to_chat(H, "Your current job or whitelist status does not permit you to spawn with [thing]!")
+ continue
+
+ if(G.slot && !(G.slot in custom_equip_slots))
+ // This is a miserable way to fix the loadout overwrite bug, but the alternative requires
+ // adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z
+ if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
+ custom_equip_leftovers += thing
+ else if(H.equip_to_slot_or_del(G.spawn_item(H), G.slot))
+ to_chat(H, "Equipping you with \the [thing]!")
+ custom_equip_slots.Add(G.slot)
+ else
+ custom_equip_leftovers.Add(thing)
+ else
+ spawn_in_storage += thing
+
job.equip(H)
job.apply_fingerprints(H)
+
+ //If some custom items could not be equipped before, try again now.
+ for(var/thing in custom_equip_leftovers)
+ var/datum/gear/G = gear_datums[thing]
+ if(G.slot in custom_equip_slots)
+ spawn_in_storage += thing
+ else
+ var/metadata = H.client.prefs.gear[G.display_name]
+ if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
+ to_chat(H, "Equipping you with \the [thing]!")
+ custom_equip_slots.Add(G.slot)
+ else
+ spawn_in_storage += thing
else
to_chat(H, "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator.")
@@ -464,6 +515,22 @@ var/global/datum/controller/occupations/job_master
H.equip_to_slot_or_del(BPK, slot_back,1)
H.species.equip(H)
+ //Deferred item spawning.
+ if(spawn_in_storage && spawn_in_storage.len)
+ var/obj/item/weapon/storage/B
+ for(var/obj/item/weapon/storage/S in H.contents)
+ B = S
+ break
+
+ if(!isnull(B))
+ for(var/thing in spawn_in_storage)
+ H << "Placing \the [thing] in your [B.name]!"
+ var/datum/gear/G = gear_datums[thing]
+ G.spawn_item(B)
+ else
+ H << "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug."
+
+
to_chat(H, "You are the [alt_title ? alt_title : rank].")
to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")
if(job.req_admin_notify)
diff --git a/code/modules/client/preference/loadout/loadout.dm b/code/modules/client/preference/loadout/loadout.dm
new file mode 100644
index 00000000000..9a369331534
--- /dev/null
+++ b/code/modules/client/preference/loadout/loadout.dm
@@ -0,0 +1,74 @@
+var/list/loadout_categories = list()
+var/list/gear_datums = list()
+
+/datum/loadout_category
+ var/category = ""
+ var/list/gear = list()
+
+/datum/loadout_category/New(cat)
+ category = cat
+ ..()
+
+/hook/startup/proc/populate_gear_list()
+ //create a list of gear datums to sort
+ for(var/geartype in subtypesof(/datum/gear))
+ var/datum/gear/G = geartype
+
+ var/use_name = initial(G.display_name)
+ var/use_category = initial(G.sort_category)
+
+ if(G == initial(G.subtype_path))
+ continue
+
+ if(!use_name)
+ error("Loadout - Missing display name: [G]")
+ continue
+ if(!initial(G.cost))
+ error("Loadout - Missing cost: [G]")
+ continue
+ if(!initial(G.path))
+ error("Loadout - Missing path definition: [G]")
+ continue
+
+ if(!loadout_categories[use_category])
+ loadout_categories[use_category] = new /datum/loadout_category(use_category)
+ var/datum/loadout_category/LC = loadout_categories[use_category]
+ gear_datums[use_name] = new geartype
+ LC.gear[use_name] = gear_datums[use_name]
+
+ loadout_categories = sortAssoc(loadout_categories)
+ for(var/loadout_category in loadout_categories)
+ var/datum/loadout_category/LC = loadout_categories[loadout_category]
+ LC.gear = sortAssoc(LC.gear)
+ return 1
+
+/datum/gear
+ var/display_name //Name/index. Must be unique.
+ var/description //Description of this gear. If left blank will default to the description of the pathed item.
+ var/path //Path to item.
+ var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
+ var/slot //Slot to equip to.
+ var/list/allowed_roles //Roles that can spawn with this item.
+ var/whitelisted //Term to check the whitelist for..
+ var/sort_category = "General"
+ var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
+ var/subtype_path = /datum/gear //for skipping organizational subtypes (optional)
+
+/datum/gear/New()
+ ..()
+ if(!description)
+ var/obj/O = path
+ description = initial(O.desc)
+
+/datum/gear_data
+ var/path
+ var/location
+
+/datum/gear_data/New(npath, nlocation)
+ path = npath
+ location = nlocation
+
+/datum/gear/proc/spawn_item(var/location)
+ var/datum/gear_data/gd = new(path, location)
+ var/item = new gd.path(gd.location)
+ return item
\ No newline at end of file
diff --git a/code/modules/client/preference/loadout/loadout_accessories.dm b/code/modules/client/preference/loadout/loadout_accessories.dm
new file mode 100644
index 00000000000..e392f8a4087
--- /dev/null
+++ b/code/modules/client/preference/loadout/loadout_accessories.dm
@@ -0,0 +1,64 @@
+/datum/gear/accessory
+ subtype_path = /datum/gear/accessory
+ slot = slot_tie
+ sort_category = "Accessories"
+
+/datum/gear/accessory/scarf
+ display_name = "scarf"
+ path = /obj/item/clothing/accessory/scarf
+
+/datum/gear/accessory/scarf/red
+ display_name = "scarf, red"
+ path = /obj/item/clothing/accessory/scarf/red
+
+/datum/gear/accessory/scarf/green
+ display_name = "scarf, green"
+ path = /obj/item/clothing/accessory/scarf/green
+
+/datum/gear/accessory/scarf/darkblue
+ display_name = "scarf, dark blue"
+ path = /obj/item/clothing/accessory/scarf/darkblue
+
+/datum/gear/accessory/scarf/purple
+ display_name = "scarf, purple"
+ path = /obj/item/clothing/accessory/scarf/purple
+
+/datum/gear/accessory/scarf/yellow
+ display_name = "scarf, yellow"
+ path = /obj/item/clothing/accessory/scarf/yellow
+
+/datum/gear/accessory/scarf/orange
+ display_name = "scarf, orange"
+ path = /obj/item/clothing/accessory/scarf/orange
+
+/datum/gear/accessory/scarf/lightblue
+ display_name = "scarf, light blue"
+ path = /obj/item/clothing/accessory/scarf/lightblue
+
+/datum/gear/accessory/scarf/white
+ display_name = "scarf, white"
+ path = /obj/item/clothing/accessory/scarf/white
+
+/datum/gear/accessory/scarf/black
+ display_name = "scarf, black"
+ path = /obj/item/clothing/accessory/scarf/black
+
+/datum/gear/accessory/scarf/zebra
+ display_name = "scarf, zebra"
+ path = /obj/item/clothing/accessory/scarf/zebra
+
+/datum/gear/accessory/scarf/christmas
+ display_name = "scarf, christmas"
+ path = /obj/item/clothing/accessory/scarf/christmas
+
+/datum/gear/accessory/scarf/stripedred
+ display_name = "scarf, striped red"
+ path = /obj/item/clothing/accessory/stripedredscarf
+
+/datum/gear/accessory/scarf/stripedgreen
+ display_name = "scarf, striped green"
+ path = /obj/item/clothing/accessory/stripedgreenscarf
+
+/datum/gear/accessory/scarf/stripedblue
+ display_name = "scarf, striped blue"
+ path = /obj/item/clothing/accessory/stripedbluescarf
\ No newline at end of file
diff --git a/code/modules/client/preference/loadout/loadout_cosmetics.dm b/code/modules/client/preference/loadout/loadout_cosmetics.dm
new file mode 100644
index 00000000000..6fc2c7f321b
--- /dev/null
+++ b/code/modules/client/preference/loadout/loadout_cosmetics.dm
@@ -0,0 +1,16 @@
+/datum/gear/lipstick
+ display_name = "lipstick, black"
+ path = /obj/item/weapon/lipstick/black
+ sort_category = "Cosmetics"
+
+/datum/gear/lipstick/jade
+ display_name = "lipstick, jade"
+ path = /obj/item/weapon/lipstick/jade
+
+/datum/gear/lipstick/purple
+ display_name = "lipstick, purple"
+ path = /obj/item/weapon/lipstick/purple
+
+/datum/gear/lipstick/red
+ display_name = "lipstick, red"
+ path = /obj/item/weapon/lipstick
\ No newline at end of file
diff --git a/code/modules/client/preference/loadout/loadout_general.dm b/code/modules/client/preference/loadout/loadout_general.dm
new file mode 100644
index 00000000000..9266dc6ebf0
--- /dev/null
+++ b/code/modules/client/preference/loadout/loadout_general.dm
@@ -0,0 +1,3 @@
+/datum/gear/dice
+ display_name = "d20"
+ path = /obj/item/weapon/dice/d20
\ No newline at end of file
diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm
new file mode 100644
index 00000000000..ed1d689b6cf
--- /dev/null
+++ b/code/modules/client/preference/loadout/loadout_uniform.dm
@@ -0,0 +1,91 @@
+// Uniform slot
+/datum/gear/uniform
+ subtype_path = /datum/gear/uniform
+ slot = slot_w_uniform
+ sort_category = "Uniforms and Casual Dress"
+
+/datum/gear/uniform/skirt
+ display_name = "plaid skirt, blue"
+ path = /obj/item/clothing/under/dress/plaid_blue
+
+/datum/gear/uniform/skirt/purple
+ display_name = "plaid skirt, purple"
+ path = /obj/item/clothing/under/dress/plaid_purple
+
+/datum/gear/uniform/skirt/red
+ display_name = "plaid skirt, red"
+ path = /obj/item/clothing/under/dress/plaid_red
+
+/datum/gear/uniform/skirt/black
+ display_name = "skirt, black"
+ path = /obj/item/clothing/under/blackskirt
+
+/datum/gear/uniform/skirt/ce
+ display_name = "skirt, ce"
+ path = /obj/item/clothing/under/rank/chief_engineer/skirt
+ allowed_roles = list("Chief Engineer")
+
+/datum/gear/uniform/skirt/atmos
+ display_name = "skirt, atmos"
+ path = /obj/item/clothing/under/rank/atmospheric_technician/skirt
+ allowed_roles = list("Chief Engineer","Atmospheric Technician")
+
+/datum/gear/uniform/skirt/eng
+ display_name = "skirt, engineer"
+ path = /obj/item/clothing/under/rank/engineer/skirt
+ allowed_roles = list("Chief Engineer","Station Engineer")
+
+/datum/gear/uniform/skirt/roboticist
+ display_name = "skirt, roboticist"
+ path = /obj/item/clothing/under/rank/roboticist/skirt
+ allowed_roles = list("Research Director","Roboticist")
+
+/datum/gear/uniform/skirt/cmo
+ display_name = "skirt, cmo"
+ path = /obj/item/clothing/under/rank/chief_medical_officer
+ allowed_roles = list("Chief Medical Officer")
+
+/datum/gear/uniform/skirt/chem
+ display_name = "skirt, chemist"
+ path = /obj/item/clothing/under/rank/chemist/skirt
+ allowed_roles = list("Chief Medical Officer","Chemist")
+
+/datum/gear/uniform/skirt/viro
+ display_name = "skirt, virologist"
+ path = /obj/item/clothing/under/rank/virologist/skirt
+ allowed_roles = list("Chief Medical Officer","Medical Doctor")
+
+/datum/gear/uniform/skirt/med
+ display_name = "skirt, medical"
+ path = /obj/item/clothing/under/rank/medical/skirt
+ allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic")
+
+/datum/gear/uniform/skirt/sci
+ display_name = "skirt, scientist"
+ path = /obj/item/clothing/under/rank/scientist/skirt
+ allowed_roles = list("Research Director","Scientist")
+
+/datum/gear/uniform/skirt/cargo
+ display_name = "skirt, cargo"
+ path = /obj/item/clothing/under/rank/cargotech/skirt
+ allowed_roles = list("Quartermaster","Cargo Technician")
+
+/datum/gear/uniform/skirt/qm
+ display_name = "skirt, QM"
+ path = /obj/item/clothing/under/rank/cargo/skirt
+ allowed_roles = list("Quartermaster")
+
+/datum/gear/uniform/skirt/warden
+ display_name = "skirt, warden"
+ path = /obj/item/clothing/under/rank/warden/skirt
+ allowed_roles = list("Head of Security", "Warden")
+
+/datum/gear/uniform/skirt/security
+ display_name = "skirt, security"
+ path = /obj/item/clothing/under/rank/security/skirt
+ allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer")
+
+/datum/gear/uniform/skirt/head_of_security
+ display_name = "skirt, hos"
+ path = /obj/item/clothing/under/rank/head_of_security/skirt
+ allowed_roles = list("Head of Security")
\ No newline at end of file
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preference/preferences.dm
similarity index 96%
rename from code/modules/client/preferences.dm
rename to code/modules/client/preference/preferences.dm
index 043caf0ca0e..82f587a7f2b 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -1,1887 +1,1954 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
-
-var/list/preferences_datums = list()
-
-var/global/list/special_role_times = list( //minimum age (in days) for accounts to play these roles
- ROLE_PAI = 0,
- ROLE_POSIBRAIN = 0,
- ROLE_GUARDIAN = 0,
- ROLE_TRAITOR = 7,
- ROLE_CHANGELING = 14,
- ROLE_SHADOWLING = 14,
- ROLE_WIZARD = 14,
- ROLE_REV = 14,
- ROLE_VAMPIRE = 14,
- ROLE_BLOB = 14,
- ROLE_REVENANT = 14,
- ROLE_OPERATIVE = 21,
- ROLE_CULTIST = 21,
- ROLE_RAIDER = 21,
- ROLE_ALIEN = 21,
- ROLE_DEMON = 21,
- ROLE_SENTIENT = 21,
-// ROLE_GANG = 21,
- ROLE_BORER = 21,
- ROLE_NINJA = 21,
- ROLE_MUTINEER = 21,
- ROLE_MALF = 30,
- ROLE_ABDUCTOR = 30,
-)
-
-/proc/player_old_enough_antag(client/C, role)
- if(available_in_days_antag(C, role) == 0)
- return 1 //Available in 0 days = available right now = player is old enough to play.
- return 0
-
-/proc/available_in_days_antag(client/C, role)
- if(!C)
- return 0
- if(!role)
- return 0
- if(!config.use_age_restriction_for_antags)
- return 0
- if(!isnum(C.player_age))
- return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
- var/minimal_player_age_antag = special_role_times[num2text(role)]
- if(!isnum(minimal_player_age_antag))
- return 0
-
- return max(0, minimal_player_age_antag - C.player_age)
-
-/proc/check_client_age(client/C, var/days) // If days isn't provided, returns the age of the client. If it is provided, it returns the days until the player_age is equal to or greater than the days variable
- if(!days)
- return C.player_age
- else
- return max(0, days - C.player_age)
- return 0
-
-//used for alternate_option
-#define GET_RANDOM_JOB 0
-#define BE_CIVILIAN 1
-#define RETURN_TO_LOBBY 2
-
-#define MAX_SAVE_SLOTS 20 // Save slots for regular players
-#define MAX_SAVE_SLOTS_MEMBER 20 // Save slots for BYOND members
-
-#define TAB_CHAR 0
-#define TAB_GAME 1
-
-/datum/preferences
- //doohickeys for savefiles
-// var/path
- var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
-// var/savefile_version = 0
- var/max_save_slots = MAX_SAVE_SLOTS
-
- //non-preference stuff
- var/warns = 0
- var/muted = 0
- var/last_ip
- var/last_id
-
- //game-preferences
-// var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
- var/ooccolor = "#b82e00"
- var/be_special = list() //Special role selection
- var/UI_style = "Midnight"
- var/nanoui_fancy = TRUE
- var/toggles = TOGGLES_DEFAULT
- var/sound = SOUND_DEFAULT
- var/show_ghostitem_attack = TRUE
- var/UI_style_color = "#ffffff"
- var/UI_style_alpha = 255
-
-
- //character preferences
- var/real_name //our character's name
- var/be_random_name = 0 //whether we are a random name every round
- var/gender = MALE //gender of character (well duh)
- var/age = 30 //age of character
- var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
- var/b_type = "A+" //blood type (not-chooseable)
- var/underwear = "Nude" //underwear type
- var/undershirt = "Nude" //undershirt type
- var/socks = "Nude" //socks type
- var/backbag = 2 //backpack type
- var/ha_style = "None" //Head accessory style
- var/r_headacc = 0 //Head accessory colour
- var/g_headacc = 0 //Head accessory colour
- var/b_headacc = 0 //Head accessory colour
- var/m_style = "None" //Marking style
- var/r_markings = 0 //Marking colour
- var/g_markings = 0 //Marking colour
- var/b_markings = 0 //Marking colour
- var/h_style = "Bald" //Hair type
- var/r_hair = 0 //Hair color
- var/g_hair = 0 //Hair color
- var/b_hair = 0 //Hair color
- var/f_style = "Shaved" //Face hair type
- var/r_facial = 0 //Face hair color
- var/g_facial = 0 //Face hair color
- var/b_facial = 0 //Face hair color
- var/s_tone = 0 //Skin tone
- var/r_skin = 0 //Skin color
- var/g_skin = 0 //Skin color
- var/b_skin = 0 //Skin color
- var/r_eyes = 0 //Eye color
- var/g_eyes = 0 //Eye color
- var/b_eyes = 0 //Eye color
- var/species = "Human"
- var/language = "None" //Secondary language
-
- var/body_accessory = null
-
- var/speciesprefs = 0//I hate having to do this, I really do (Using this for oldvox code, making names universal I guess
-
- //Mob preview
- var/icon/preview_icon = null
- var/icon/preview_icon_front = null
- var/icon/preview_icon_side = null
-
- //Jobs, uses bitflags
- var/job_support_high = 0
- var/job_support_med = 0
- var/job_support_low = 0
-
- var/job_medsci_high = 0
- var/job_medsci_med = 0
- var/job_medsci_low = 0
-
- var/job_engsec_high = 0
- var/job_engsec_med = 0
- var/job_engsec_low = 0
-
- var/job_karma_high = 0
- var/job_karma_med = 0
- var/job_karma_low = 0
-
- //Keeps track of preferrence for not getting any wanted jobs
- var/alternate_option = 0
-
- // maps each organ to either null(intact), "cyborg" or "amputated"
- // will probably not be able to do this for head and torso ;)
- var/list/organ_data = list()
- var/list/rlimb_data = list()
-
- var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor"
-// var/accent = "en-us"
-// var/voice = "m1"
-// var/pitch = 50
-// var/talkspeed = 175
- var/flavor_text = ""
- var/med_record = ""
- var/sec_record = ""
- var/gen_record = ""
- var/disabilities = 0
-
- var/nanotrasen_relation = "Neutral"
-
- // 0 = character settings, 1 = game preferences
- var/current_tab = TAB_CHAR
-
- // OOC Metadata:
- var/metadata = ""
- var/slot_name = ""
-
- // Whether or not to use randomized character slots
- var/randomslot = 0
-
- // jukebox volume
- var/volume = 100
-
- // BYOND membership
- var/unlock_content = 0
-
-/datum/preferences/New(client/C)
- b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
- if(istype(C))
- if(!IsGuestKey(C.key))
- unlock_content = C.IsByondMember()
- if(unlock_content)
- max_save_slots = MAX_SAVE_SLOTS_MEMBER
- var/loaded_preferences_successfully = load_preferences(C)
- if(loaded_preferences_successfully)
- if(load_character(C))
- return
- //we couldn't load character data so just randomize the character appearance + name
- random_character() //let's create a random character then - rather than a fat, bald and naked man.
- real_name = random_name(gender)
- if(!loaded_preferences_successfully)
- save_preferences(C)
- save_character(C) //let's save this new random character so it doesn't keep generating new ones.
-
-/datum/preferences/proc/color_square(r, g, b)
- return "___"
-
-// Hello I am a proc full of snowflake species checks how are you
-/datum/preferences/proc/ShowChoices(mob/user)
- if(!user || !user.client)
- return
- update_preview_icon()
- user << browse_rsc(preview_icon_front, "previewicon.png")
- user << browse_rsc(preview_icon_side, "previewicon2.png")
-
- var/dat = ""
- dat += "
"
- dat += "Character Settings"
- dat += "Game Preferences"
- dat += ""
- dat += "
"
-
- switch(current_tab)
- if(TAB_CHAR) // Character Settings
- dat += "

"
- dat += ""
- dat += ""
- dat += "Identity"
- if(appearance_isbanned(user))
- dat += "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.\
- "
- dat += "Gender: [gender == MALE ? "Male" : "Female"] "
- dat += "Age: [age] "
- dat += "Body: (®) "
- dat += "Species: [species] "
- if(species == "Vox")
- dat += "N2 Tank: [speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"] "
- dat += "Secondary Language: [language] "
- dat += "Blood Type: [b_type] "
- if(species in list("Human", "Drask"))
- dat += "Skin Tone: [-s_tone + 35]/220 "
- dat += "Disabilities: \[Set\] "
- dat += "Nanotrasen Relation: [nanotrasen_relation] "
- dat += "Set Flavor Text "
- if(lentext(flavor_text) <= 40)
- if(!lentext(flavor_text)) dat += "\[...\] "
- else dat += "[flavor_text] "
- else dat += "[TextPreview(flavor_text)]... "
-
- dat += "Hair & Accessories"
-
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have head accessories.
- var/headaccessoryname = "Head Accessory: "
- if(species == "Unathi")
- headaccessoryname = "Horns: "
- dat += "[headaccessoryname]"
- dat += "[ha_style] "
- dat += "Color [color_square(r_headacc, g_headacc, b_headacc)] "
-
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have body markings.
- dat += "Body Markings: "
- dat += "[m_style]"
- dat += "Color [color_square(r_markings, g_markings, b_markings)] "
-
- dat += "Hair: "
- dat += "[h_style]"
- dat += "Color [color_square(r_hair, g_hair, b_hair)] "
-
- dat += "Facial Hair: "
- dat += "[f_style ? "[f_style]" : "Shaved"]"
- dat += "Color [color_square(r_facial, g_facial, b_facial)] "
-
- if(species != "Machine")
- dat += "Eyes: "
- dat += "Color [color_square(r_eyes, g_eyes, b_eyes)] "
-
- if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) //admins can always fuck with this, because they are admins
- dat += "Body Color: "
- dat += "Color [color_square(r_skin, g_skin, b_skin)] "
-
- if(body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
- dat += "Body Accessory: "
- dat += "[body_accessory ? "[body_accessory]" : "None"] "
-
- dat += " | "
- dat += "Occupation Choices"
- dat += "Set Occupation Preferences "
- if(jobban_isbanned(user, "Records"))
- dat += "You are banned from using character records. "
- else
- dat += "Character Records "
-
- dat += "Limbs"
- dat += "Limbs and Parts: Adjust "
- if(species != "Slime People" && species != "Machine")
- dat += "Internal Organs: Adjust "
-
- //display limbs below
- var/ind = 0
- for(var/name in organ_data)
- var/status = organ_data[name]
- var/organ_name = null
- switch(name)
- if("chest") organ_name = "torso"
- if("groin") organ_name = "lower body"
- if("head") organ_name = "head"
- 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 in list("cyborg", "amputated", "mechanical", "assisted"))
- ++ind
- if(ind > 1) dat += ", "
-
- switch(status)
- if("cyborg")
- var/datum/robolimb/R
- if(rlimb_data[name] && all_robolimbs[rlimb_data[name]])
- R = all_robolimbs[rlimb_data[name]]
- else
- R = basic_robolimb
- dat += "\t[R.company] [organ_name] prosthesis"
- if("amputated") dat += "\tAmputated [organ_name]"
- if("mechanical") dat += "\tMechanical [organ_name]"
- if("assisted")
- switch(organ_name)
- if("heart") dat += "\tPacemaker-assisted [organ_name]"
- if("voicebox") dat += "\tSurgically altered [organ_name]"
- if("eyes") dat += "\tRetinal overlayed [organ_name]"
- else dat += "\tMechanically assisted [organ_name]"
- if(!ind) dat += "\[...\] "
- else dat += " "
-
- dat += "Clothing"
- dat += "Underwear: [underwear] "
- dat += "Undershirt: [undershirt] "
- dat += "Socks: [socks] "
- dat += "Backpack Type: [backbaglist[backbag]] "
-
- dat += " |
"
-
- if(TAB_GAME) // General Preferences
- dat += ""
+//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
+
+var/list/preferences_datums = list()
+
+var/global/list/special_role_times = list( //minimum age (in days) for accounts to play these roles
+ ROLE_PAI = 0,
+ ROLE_POSIBRAIN = 0,
+ ROLE_GUARDIAN = 0,
+ ROLE_TRAITOR = 7,
+ ROLE_CHANGELING = 14,
+ ROLE_SHADOWLING = 14,
+ ROLE_WIZARD = 14,
+ ROLE_REV = 14,
+ ROLE_VAMPIRE = 14,
+ ROLE_BLOB = 14,
+ ROLE_REVENANT = 14,
+ ROLE_OPERATIVE = 21,
+ ROLE_CULTIST = 21,
+ ROLE_RAIDER = 21,
+ ROLE_ALIEN = 21,
+ ROLE_DEMON = 21,
+ ROLE_SENTIENT = 21,
+// ROLE_GANG = 21,
+ ROLE_BORER = 21,
+ ROLE_NINJA = 21,
+ ROLE_MUTINEER = 21,
+ ROLE_MALF = 30,
+ ROLE_ABDUCTOR = 30,
+)
+
+/proc/player_old_enough_antag(client/C, role)
+ if(available_in_days_antag(C, role) == 0)
+ return 1 //Available in 0 days = available right now = player is old enough to play.
+ return 0
+
+/proc/available_in_days_antag(client/C, role)
+ if(!C)
+ return 0
+ if(!role)
+ return 0
+ if(!config.use_age_restriction_for_antags)
+ return 0
+ if(!isnum(C.player_age))
+ return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
+ var/minimal_player_age_antag = special_role_times[num2text(role)]
+ if(!isnum(minimal_player_age_antag))
+ return 0
+
+ return max(0, minimal_player_age_antag - C.player_age)
+
+/proc/check_client_age(client/C, var/days) // If days isn't provided, returns the age of the client. If it is provided, it returns the days until the player_age is equal to or greater than the days variable
+ if(!days)
+ return C.player_age
+ else
+ return max(0, days - C.player_age)
+ return 0
+
+//used for alternate_option
+#define GET_RANDOM_JOB 0
+#define BE_CIVILIAN 1
+#define RETURN_TO_LOBBY 2
+
+#define MAX_SAVE_SLOTS 20 // Save slots for regular players
+#define MAX_SAVE_SLOTS_MEMBER 20 // Save slots for BYOND members
+
+#define MAX_GEAR_COST 10
+
+#define TAB_CHAR 0
+#define TAB_GAME 1
+#define TAB_GEAR 2
+
+/datum/preferences
+ //doohickeys for savefiles
+// var/path
+ var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
+// var/savefile_version = 0
+ var/max_save_slots = MAX_SAVE_SLOTS
+
+ //non-preference stuff
+ var/warns = 0
+ var/muted = 0
+ var/last_ip
+ var/last_id
+
+ //game-preferences
+// var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
+ var/ooccolor = "#b82e00"
+ var/be_special = list() //Special role selection
+ var/UI_style = "Midnight"
+ var/nanoui_fancy = TRUE
+ var/toggles = TOGGLES_DEFAULT
+ var/sound = SOUND_DEFAULT
+ var/show_ghostitem_attack = TRUE
+ var/UI_style_color = "#ffffff"
+ var/UI_style_alpha = 255
+
+
+ //character preferences
+ var/real_name //our character's name
+ var/be_random_name = 0 //whether we are a random name every round
+ var/gender = MALE //gender of character (well duh)
+ var/age = 30 //age of character
+ var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
+ var/b_type = "A+" //blood type (not-chooseable)
+ var/underwear = "Nude" //underwear type
+ var/undershirt = "Nude" //undershirt type
+ var/socks = "Nude" //socks type
+ var/backbag = 2 //backpack type
+ var/ha_style = "None" //Head accessory style
+ var/r_headacc = 0 //Head accessory colour
+ var/g_headacc = 0 //Head accessory colour
+ var/b_headacc = 0 //Head accessory colour
+ var/m_style = "None" //Marking style
+ var/r_markings = 0 //Marking colour
+ var/g_markings = 0 //Marking colour
+ var/b_markings = 0 //Marking colour
+ var/h_style = "Bald" //Hair type
+ var/r_hair = 0 //Hair color
+ var/g_hair = 0 //Hair color
+ var/b_hair = 0 //Hair color
+ var/f_style = "Shaved" //Face hair type
+ var/r_facial = 0 //Face hair color
+ var/g_facial = 0 //Face hair color
+ var/b_facial = 0 //Face hair color
+ var/s_tone = 0 //Skin tone
+ var/r_skin = 0 //Skin color
+ var/g_skin = 0 //Skin color
+ var/b_skin = 0 //Skin color
+ var/r_eyes = 0 //Eye color
+ var/g_eyes = 0 //Eye color
+ var/b_eyes = 0 //Eye color
+ var/species = "Human"
+ var/language = "None" //Secondary language
+
+ var/body_accessory = null
+
+ var/speciesprefs = 0//I hate having to do this, I really do (Using this for oldvox code, making names universal I guess
+
+ //Mob preview
+ var/icon/preview_icon = null
+ var/icon/preview_icon_front = null
+ var/icon/preview_icon_side = null
+
+ //Jobs, uses bitflags
+ var/job_support_high = 0
+ var/job_support_med = 0
+ var/job_support_low = 0
+
+ var/job_medsci_high = 0
+ var/job_medsci_med = 0
+ var/job_medsci_low = 0
+
+ var/job_engsec_high = 0
+ var/job_engsec_med = 0
+ var/job_engsec_low = 0
+
+ var/job_karma_high = 0
+ var/job_karma_med = 0
+ var/job_karma_low = 0
+
+ //Keeps track of preferrence for not getting any wanted jobs
+ var/alternate_option = 0
+
+ // maps each organ to either null(intact), "cyborg" or "amputated"
+ // will probably not be able to do this for head and torso ;)
+ var/list/organ_data = list()
+ var/list/rlimb_data = list()
+
+ var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor"
+// var/accent = "en-us"
+// var/voice = "m1"
+// var/pitch = 50
+// var/talkspeed = 175
+ var/flavor_text = ""
+ var/med_record = ""
+ var/sec_record = ""
+ var/gen_record = ""
+ var/disabilities = 0
+
+ var/nanotrasen_relation = "Neutral"
+
+ // 0 = character settings, 1 = game preferences
+ var/current_tab = TAB_CHAR
+
+ // OOC Metadata:
+ var/metadata = ""
+ var/slot_name = ""
+
+ // Whether or not to use randomized character slots
+ var/randomslot = 0
+
+ // jukebox volume
+ var/volume = 100
+
+ // BYOND membership
+ var/unlock_content = 0
+
+ //Gear stuff
+ var/list/gear = list()
+ var/gear_tab = "General"
+
+/datum/preferences/New(client/C)
+ b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
+ if(istype(C))
+ if(!IsGuestKey(C.key))
+ unlock_content = C.IsByondMember()
+ if(unlock_content)
+ max_save_slots = MAX_SAVE_SLOTS_MEMBER
+ var/loaded_preferences_successfully = load_preferences(C)
+ if(loaded_preferences_successfully)
+ if(load_character(C))
+ return
+ //we couldn't load character data so just randomize the character appearance + name
+ random_character() //let's create a random character then - rather than a fat, bald and naked man.
+ real_name = random_name(gender)
+ if(!loaded_preferences_successfully)
+ save_preferences(C)
+ save_character(C) //let's save this new random character so it doesn't keep generating new ones.
+
+/datum/preferences/proc/color_square(r, g, b)
+ return "___"
+
+// Hello I am a proc full of snowflake species checks how are you
+/datum/preferences/proc/ShowChoices(mob/user)
+ if(!user || !user.client)
+ return
+ update_preview_icon()
+ user << browse_rsc(preview_icon_front, "previewicon.png")
+ user << browse_rsc(preview_icon_side, "previewicon2.png")
+
+ var/dat = ""
+ dat += ""
+ dat += "Character Settings"
+ dat += "Game Preferences"
+ dat += "Loadout"
+ dat += ""
+ dat += "
"
+
+ switch(current_tab)
+ if(TAB_CHAR) // Character Settings
+ dat += "

"
+ dat += ""
+ dat += ""
+ dat += "Identity"
+ if(appearance_isbanned(user))
+ dat += "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.\
+ "
+ dat += "Gender: [gender == MALE ? "Male" : "Female"] "
+ dat += "Age: [age] "
+ dat += "Body: (®) "
+ dat += "Species: [species] "
+ if(species == "Vox")
+ dat += "N2 Tank: [speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"] "
+ dat += "Secondary Language: [language] "
+ dat += "Blood Type: [b_type] "
+ if(species in list("Human", "Drask"))
+ dat += "Skin Tone: [-s_tone + 35]/220 "
+ dat += "Disabilities: \[Set\] "
+ dat += "Nanotrasen Relation: [nanotrasen_relation] "
+ dat += "Set Flavor Text "
+ if(lentext(flavor_text) <= 40)
+ if(!lentext(flavor_text)) dat += "\[...\] "
+ else dat += "[flavor_text] "
+ else dat += "[TextPreview(flavor_text)]... "
+
+ dat += "Hair & Accessories"
+
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have head accessories.
+ var/headaccessoryname = "Head Accessory: "
+ if(species == "Unathi")
+ headaccessoryname = "Horns: "
+ dat += "[headaccessoryname]"
+ dat += "[ha_style] "
+ dat += "Color [color_square(r_headacc, g_headacc, b_headacc)] "
+
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have body markings.
+ dat += "Body Markings: "
+ dat += "[m_style]"
+ dat += "Color [color_square(r_markings, g_markings, b_markings)] "
+
+ dat += "Hair: "
+ dat += "[h_style]"
+ dat += "Color [color_square(r_hair, g_hair, b_hair)] "
+
+ dat += "Facial Hair: "
+ dat += "[f_style ? "[f_style]" : "Shaved"]"
+ dat += "Color [color_square(r_facial, g_facial, b_facial)] "
+
+ if(species != "Machine")
+ dat += "Eyes: "
+ dat += "Color [color_square(r_eyes, g_eyes, b_eyes)] "
+
+ if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) //admins can always fuck with this, because they are admins
+ dat += "Body Color: "
+ dat += "Color [color_square(r_skin, g_skin, b_skin)] "
+
+ if(body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
+ dat += "Body Accessory: "
+ dat += "[body_accessory ? "[body_accessory]" : "None"] "
+
+ dat += " | "
+ dat += "Occupation Choices"
+ dat += "Set Occupation Preferences "
+ if(jobban_isbanned(user, "Records"))
+ dat += "You are banned from using character records. "
+ else
+ dat += "Character Records "
+
+ dat += "Limbs"
+ dat += "Limbs and Parts: Adjust "
+ if(species != "Slime People" && species != "Machine")
+ dat += "Internal Organs: Adjust "
+
+ //display limbs below
+ var/ind = 0
+ for(var/name in organ_data)
+ var/status = organ_data[name]
+ var/organ_name = null
+ switch(name)
+ if("chest") organ_name = "torso"
+ if("groin") organ_name = "lower body"
+ if("head") organ_name = "head"
+ 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 in list("cyborg", "amputated", "mechanical", "assisted"))
+ ++ind
+ if(ind > 1) dat += ", "
+
+ switch(status)
+ if("cyborg")
+ var/datum/robolimb/R
+ if(rlimb_data[name] && all_robolimbs[rlimb_data[name]])
+ R = all_robolimbs[rlimb_data[name]]
+ else
+ R = basic_robolimb
+ dat += "\t[R.company] [organ_name] prosthesis"
+ if("amputated") dat += "\tAmputated [organ_name]"
+ if("mechanical") dat += "\tMechanical [organ_name]"
+ if("assisted")
+ switch(organ_name)
+ if("heart") dat += "\tPacemaker-assisted [organ_name]"
+ if("voicebox") dat += "\tSurgically altered [organ_name]"
+ if("eyes") dat += "\tRetinal overlayed [organ_name]"
+ else dat += "\tMechanically assisted [organ_name]"
+ if(!ind) dat += "\[...\] "
+ else dat += " "
+
+ dat += "Clothing"
+ dat += "Underwear: [underwear] "
+ dat += "Undershirt: [undershirt] "
+ dat += "Socks: [socks] "
+ dat += "Backpack Type: [backbaglist[backbag]] "
+
+ dat += " |
"
+
+ if(TAB_GAME) // General Preferences
+ dat += ""
+
+ if(TAB_GEAR)
+ var/total_cost = 0
+ if(gear && gear.len)
+ for(var/i = 1, i <= gear.len, i++)
+ var/datum/gear/G = gear_datums[gear[i]]
+ if(G)
+ total_cost += G.cost
+
+ var/fcolor = "#3366CC"
+ if(total_cost < MAX_GEAR_COST)
+ fcolor = "#E67300"
+ dat += ""
+ dat += "| [total_cost]/[MAX_GEAR_COST] loadout points spent. \[Clear Loadout\] |
"
+ dat += "| "
+
+ var/firstcat = 1
+ for(var/category in loadout_categories)
+ if(firstcat)
+ firstcat = 0
+ else
+ dat += " |"
+ if(category == gear_tab)
+ dat += " [category] "
+ else
+ dat += " [category] "
+ dat += " |
"
+
+ var/datum/loadout_category/LC = loadout_categories[gear_tab]
+ dat += "
|
"
+ dat += "| [LC.category] |
"
+ dat += "
|
"
+ for(var/gear_name in LC.gear)
+ var/datum/gear/G = LC.gear[gear_name]
+ var/ticked = (G.display_name in gear)
+ dat += "| [G.display_name] | "
+ dat += "[G.cost] | "
+ dat += "[G.description] |
"
+ dat += "
"
+
+ dat += "
"
+ if(!IsGuestKey(user.key))
+ dat += "Undo - "
+ dat += "Save Setup - "
+
+ dat += "Reset Setup"
+ dat += ""
+
+ var/datum/browser/popup = new(user, "preferences", "Character Setup
", 820, 640)
+ popup.set_content(dat)
+ popup.open(0)
+
+/datum/preferences/proc/SetChoices(mob/user, limit = 12, list/splitJobs = list("Civilian","Research Director","AI","Bartender"), width = 760, height = 790)
+ if(!job_master)
+ return
+
+ //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
+ //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice.
+ //width - Screen' width. Defaults to 550 to make it look nice.
+ //height - Screen's height. Defaults to 500 to make it look nice.
+
+
+ var/HTML = ""
+ HTML += ""
+ HTML += "Choose occupation chances
Unavailable occupations are crossed out.
"
+ HTML += "\[Done\]
" // Easier to press up here.
+ HTML += "Left-click to raise an occupation preference, right-click to lower it.
"
+ HTML += ""
+ HTML += "" // Table within a table for alignment, also allows you to easily add more colomns.
+ HTML += ""
+ 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)
+ HTML += "|   |   | "
+ HTML += " | "
+ index = 0
+
+ HTML += "| "
+ var/rank = job.title
+ lastJob = job
+ if(!is_job_whitelisted(user, rank))
+ HTML += "[rank] | \[KARMA] | "
+ continue
+ if(jobban_isbanned(user, rank))
+ HTML += "[rank] \[BANNED] | "
+ continue
+ if(!job.player_old_enough(user.client))
+ var/available_in_days = job.available_in_days(user.client)
+ HTML += "[rank] \[IN [(available_in_days)] DAYS] | "
+ continue
+ if((job_support_low & CIVILIAN) && (rank != "Civilian"))
+ HTML += "[rank] | "
+ continue
+ if((rank in command_positions) || (rank == "AI"))//Bold head jobs
+ HTML += "[rank]"
+ else
+ HTML += "[rank]"
+
+ HTML += ""
+
+ var/prefLevelLabel = "ERROR"
+ var/prefLevelColor = "pink"
+ var/prefUpperLevel = -1 // level to assign on left click
+ var/prefLowerLevel = -1 // level to assign on right click
+
+ if(GetJobDepartment(job, 1) & job.flag)
+ prefLevelLabel = "High"
+ prefLevelColor = "slateblue"
+ prefUpperLevel = 4
+ prefLowerLevel = 2
+ else if(GetJobDepartment(job, 2) & job.flag)
+ prefLevelLabel = "Medium"
+ prefLevelColor = "green"
+ prefUpperLevel = 1
+ prefLowerLevel = 3
+ else if(GetJobDepartment(job, 3) & job.flag)
+ prefLevelLabel = "Low"
+ prefLevelColor = "orange"
+ prefUpperLevel = 2
+ prefLowerLevel = 4
+ else
+ prefLevelLabel = "NEVER"
+ prefLevelColor = "red"
+ prefUpperLevel = 3
+ prefLowerLevel = 1
+
+
+ HTML += ""
+
+// HTML += ""
+
+ if(rank == "Civilian")//Civilian is special
+ if(job_support_low & CIVILIAN)
+ HTML += " \[Yes]"
+ else
+ HTML += " \[No]"
+ if(job.alt_titles)
+ HTML += " \[[GetPlayerAltTitle(job)]\] | "
+ HTML += ""
+ continue
+/*
+ if(GetJobDepartment(job, 1) & job.flag)
+ HTML += " \[High]"
+ else if(GetJobDepartment(job, 2) & job.flag)
+ HTML += " \[Medium]"
+ else if(GetJobDepartment(job, 3) & job.flag)
+ HTML += " \[Low]"
+ else
+ HTML += " \[NEVER]"
+ */
+ HTML += "[prefLevelLabel]"
+
+ if(job.alt_titles)
+ HTML += " \[[GetPlayerAltTitle(job)]\]"
+
+
+ HTML += ""
+
+ for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
+ HTML += "|   |   | "
+
+ HTML += " "
+
+ HTML += " |
"
+
+ switch(alternate_option)
+ if(GET_RANDOM_JOB)
+ HTML += "
Get random job if preferences unavailable
"
+ if(BE_CIVILIAN)
+ HTML += "
Be a civilian if preferences unavailable
"
+ if(RETURN_TO_LOBBY)
+ HTML += "
Return to lobby if preferences unavailable
"
+
+ HTML += "\[Reset\]"
+ HTML += ""
+
+ user << browse(null, "window=preferences")
+// user << browse(HTML, "window=mob_occupation;size=[width]x[height]")
+ var/datum/browser/popup = new(user, "mob_occupation", "Occupation Preferences
", width, height)
+ popup.set_window_options("can_close=0")
+ popup.set_content(HTML)
+ popup.open(0)
+ return
+
+/datum/preferences/proc/SetJobPreferenceLevel(var/datum/job/job, var/level)
+ if (!job)
+ return 0
+
+ if (level == 1) // to high
+ // remove any other job(s) set to high
+ job_support_med |= job_support_high
+ job_engsec_med |= job_engsec_high
+ job_medsci_med |= job_medsci_high
+ job_karma_med |= job_karma_high
+ job_support_high = 0
+ job_engsec_high = 0
+ job_medsci_high = 0
+ job_karma_high = 0
+
+ if (job.department_flag == SUPPORT)
+ job_support_low &= ~job.flag
+ job_support_med &= ~job.flag
+ job_support_high &= ~job.flag
+
+ switch(level)
+ if (1)
+ job_support_high |= job.flag
+ if (2)
+ job_support_med |= job.flag
+ if (3)
+ job_support_low |= job.flag
+
+ return 1
+ else if (job.department_flag == ENGSEC)
+ job_engsec_low &= ~job.flag
+ job_engsec_med &= ~job.flag
+ job_engsec_high &= ~job.flag
+
+ switch(level)
+ if (1)
+ job_engsec_high |= job.flag
+ if (2)
+ job_engsec_med |= job.flag
+ if (3)
+ job_engsec_low |= job.flag
+
+ return 1
+ else if (job.department_flag == MEDSCI)
+ job_medsci_low &= ~job.flag
+ job_medsci_med &= ~job.flag
+ job_medsci_high &= ~job.flag
+
+ switch(level)
+ if (1)
+ job_medsci_high |= job.flag
+ if (2)
+ job_medsci_med |= job.flag
+ if (3)
+ job_medsci_low |= job.flag
+
+ return 1
+ else if (job.department_flag == KARMA)
+ job_karma_low &= ~job.flag
+ job_karma_med &= ~job.flag
+ job_karma_high &= ~job.flag
+
+ switch(level)
+ if (1)
+ job_karma_high |= job.flag
+ if (2)
+ job_karma_med |= job.flag
+ if (3)
+ job_karma_low |= job.flag
+
+ return 1
+
+ return 0
+
+/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl)
+ var/datum/job/job = job_master.GetJob(role)
+
+ if(!job)
+ user << browse(null, "window=mob_occupation")
+ ShowChoices(user)
+ return
+
+ if (!isnum(desiredLvl))
+ to_chat(user, "\red UpdateJobPreference - desired level was not a number. Please notify coders!")
+ ShowChoices(user)
+ return
+
+ if(role == "Civilian")
+ if(job_support_low & job.flag)
+ job_support_low &= ~job.flag
+ else
+ job_support_low |= job.flag
+ SetChoices(user)
+ return 1
+
+ SetJobPreferenceLevel(job, desiredLvl)
+ SetChoices(user)
+
+ return 1
+
+/datum/preferences/proc/ShowDisabilityState(mob/user,flag,label)
+ if(flag==DISABILITY_FLAG_FAT && species!=("Human" || "Tajaran" || "Grey"))
+ return "[species] cannot be fat."
+ return "[label]: [disabilities & flag ? "Yes" : "No"]"
+
+/datum/preferences/proc/SetDisabilities(mob/user)
+ var/HTML = ""
+
+ // AUTOFIXED BY fix_string_idiocy.py
+ // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:474: HTML += ""
+ HTML += {"
+ Choose disabilities"}
+ // END AUTOFIX
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_NEARSIGHTED,"Needs Glasses")
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_FAT,"Obese")
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures")
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_DEAF,"Deaf")
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_BLIND,"Blind")
+ HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute")
+
+
+ // AUTOFIXED BY fix_string_idiocy.py
+ // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:481: HTML += "
"
+ HTML += {"
+ \[Done\]
+ \[Reset\]
+ "}
+ // END AUTOFIX
+ user << browse(null, "window=preferences")
+ user << browse(HTML, "window=disabil;size=350x300")
+ return
+
+/datum/preferences/proc/SetRecords(mob/user)
+ var/HTML = ""
+ HTML += ""
+ HTML += "Set Character Records
"
+
+ HTML += "Medical Records
"
+
+ if(lentext(med_record) <= 40)
+ HTML += "[med_record]"
+ else
+ HTML += "[copytext(med_record, 1, 37)]..."
+
+ HTML += "
Employment Records
"
+
+ if(lentext(gen_record) <= 40)
+ HTML += "[gen_record]"
+ else
+ HTML += "[copytext(gen_record, 1, 37)]..."
+
+ HTML += "
Security Records
"
+
+ if(lentext(sec_record) <= 40)
+ HTML += "[sec_record]
"
+ else
+ HTML += "[copytext(sec_record, 1, 37)]...
"
+
+ HTML += "
"
+ HTML += "\[Done\]"
+ HTML += ""
+
+ user << browse(null, "window=preferences")
+ user << browse(HTML, "window=records;size=350x300")
+ return
+
+/datum/preferences/proc/GetPlayerAltTitle(datum/job/job)
+ return player_alt_titles.Find(job.title) > 0 \
+ ? player_alt_titles[job.title] \
+ : job.title
+
+/datum/preferences/proc/SetPlayerAltTitle(datum/job/job, new_title)
+ // remove existing entry
+ if(player_alt_titles.Find(job.title))
+ player_alt_titles -= job.title
+ // add one if it's not default
+ if(job.title != new_title)
+ player_alt_titles[job.title] = new_title
+
+/datum/preferences/proc/SetJob(mob/user, role)
+ var/datum/job/job = job_master.GetJob(role)
+ if(!job)
+ user << browse(null, "window=mob_occupation")
+ ShowChoices(user)
+ return
+
+ if(role == "Civilian")
+ if(job_support_low & job.flag)
+ job_support_low &= ~job.flag
+ else
+ job_support_low |= job.flag
+ SetChoices(user)
+ return 1
+
+ if(GetJobDepartment(job, 1) & job.flag)
+ SetJobDepartment(job, 1)
+ else if(GetJobDepartment(job, 2) & job.flag)
+ SetJobDepartment(job, 2)
+ else if(GetJobDepartment(job, 3) & job.flag)
+ SetJobDepartment(job, 3)
+ else//job = Never
+ SetJobDepartment(job, 4)
+
+ SetChoices(user)
+ return 1
+
+/datum/preferences/proc/ResetJobs()
+ job_support_high = 0
+ job_support_med = 0
+ job_support_low = 0
+
+ job_medsci_high = 0
+ job_medsci_med = 0
+ job_medsci_low = 0
+
+ job_engsec_high = 0
+ job_engsec_med = 0
+ job_engsec_low = 0
+
+ job_karma_high = 0
+ job_karma_med = 0
+ job_karma_low = 0
+
+
+/datum/preferences/proc/GetJobDepartment(var/datum/job/job, var/level)
+ if(!job || !level) return 0
+ switch(job.department_flag)
+ if(SUPPORT)
+ switch(level)
+ if(1)
+ return job_support_high
+ if(2)
+ return job_support_med
+ if(3)
+ return job_support_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
+ if(KARMA)
+ switch(level)
+ if(1)
+ return job_karma_high
+ if(2)
+ return job_karma_med
+ if(3)
+ return job_karma_low
+ return 0
+
+/datum/preferences/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
+ job_support_high = 0
+ job_medsci_high = 0
+ job_engsec_high = 0
+ job_karma_high = 0
+ return 1
+ if(2)//Set current highs to med, then reset them
+ job_support_med |= job_support_high
+ job_medsci_med |= job_medsci_high
+ job_engsec_med |= job_engsec_high
+ job_karma_med |= job_karma_high
+ job_support_high = 0
+ job_medsci_high = 0
+ job_engsec_high = 0
+ job_karma_high = 0
+
+ switch(job.department_flag)
+ if(SUPPORT)
+ switch(level)
+ if(2)
+ job_support_high = job.flag
+ job_support_med &= ~job.flag
+ if(3)
+ job_support_med |= job.flag
+ job_support_low &= ~job.flag
+ else
+ job_support_low |= job.flag
+ if(MEDSCI)
+ switch(level)
+ if(2)
+ job_medsci_high = job.flag
+ job_medsci_med &= ~job.flag
+ if(3)
+ job_medsci_med |= job.flag
+ job_medsci_low &= ~job.flag
+ else
+ job_medsci_low |= job.flag
+ if(ENGSEC)
+ switch(level)
+ if(2)
+ job_engsec_high = job.flag
+ job_engsec_med &= ~job.flag
+ if(3)
+ job_engsec_med |= job.flag
+ job_engsec_low &= ~job.flag
+ else
+ job_engsec_low |= job.flag
+ if(KARMA)
+ switch(level)
+ if(2)
+ job_karma_high = job.flag
+ job_karma_med &= ~job.flag
+ if(3)
+ job_karma_med |= job.flag
+ job_karma_low &= ~job.flag
+ else
+ job_karma_low |= job.flag
+ return 1
+
+/datum/preferences/proc/process_link(mob/user, list/href_list)
+ if(!user) return
+
+ if(href_list["preference"] == "job")
+ switch(href_list["task"])
+ if("close")
+ user << browse(null, "window=mob_occupation")
+ ShowChoices(user)
+ if("reset")
+ ResetJobs()
+ SetChoices(user)
+ if("random")
+ if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_CIVILIAN)
+ alternate_option += 1
+ else if(alternate_option == RETURN_TO_LOBBY)
+ alternate_option = 0
+ else
+ return 0
+ SetChoices(user)
+ if ("alt_title")
+ var/datum/job/job = locate(href_list["job"])
+ if (job)
+ var/choices = list(job.title) + job.alt_titles
+ var/choice = input("Pick a title for [job.title].", "Character Generation", GetPlayerAltTitle(job)) as anything in choices | null
+ if(choice)
+ SetPlayerAltTitle(job, choice)
+ SetChoices(user)
+ if("input")
+ SetJob(user, href_list["text"])
+ if("setJobLevel")
+ UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
+ else
+ SetChoices(user)
+ return 1
+ else if(href_list["preference"] == "disabilities")
+
+ switch(href_list["task"])
+ if("close")
+ user << browse(null, "window=disabil")
+ ShowChoices(user)
+ if("reset")
+ disabilities=0
+ SetDisabilities(user)
+ if("input")
+ var/dflag=text2num(href_list["disability"])
+ if(dflag >= 0)
+ if(!(dflag==DISABILITY_FLAG_FAT && species!=("Human" || "Tajaran" || "Grey")))
+ disabilities ^= text2num(href_list["disability"]) //MAGIC
+ SetDisabilities(user)
+ else
+ SetDisabilities(user)
+ return 1
+
+ else if(href_list["preference"] == "records")
+ if(text2num(href_list["record"]) >= 1)
+ SetRecords(user)
+ return
+ else
+ user << browse(null, "window=records")
+ if(href_list["task"] == "med_record")
+ var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(med_record)) as message
+
+ if(medmsg != null)
+ medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN)
+ medmsg = html_encode(medmsg)
+
+ med_record = medmsg
+ SetRecords(user)
+
+ if(href_list["task"] == "sec_record")
+ var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(sec_record)) as message
+
+ if(secmsg != null)
+ secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN)
+ secmsg = html_encode(secmsg)
+
+ sec_record = secmsg
+ SetRecords(user)
+ if(href_list["task"] == "gen_record")
+ var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(gen_record)) as message
+
+ if(genmsg != null)
+ genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN)
+ genmsg = html_encode(genmsg)
+
+ gen_record = genmsg
+ SetRecords(user)
+
+ if(href_list["preference"] == "gear")
+ if(href_list["toggle_gear"])
+ var/datum/gear/TG = gear_datums[href_list["toggle_gear"]]
+ if(TG.display_name in gear)
+ gear -= TG.display_name
+ else
+ var/total_cost = 0
+ for(var/gear_name in gear)
+ var/datum/gear/G = gear_datums[gear_name]
+ if(istype(G)) total_cost += G.cost
+ if((total_cost+TG.cost) <= MAX_GEAR_COST)
+ gear += TG.display_name
+ else if(href_list["select_category"])
+ gear_tab = href_list["select_category"]
+ else if(href_list["clear_loadout"])
+ gear.Cut()
+
+ ShowChoices(user)
+ return
+
+ switch(href_list["task"])
+ if("random")
+ switch(href_list["preference"])
+ if("name")
+ real_name = random_name(gender,species)
+ if("age")
+ age = rand(AGE_MIN, AGE_MAX)
+ if("hair")
+ if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Wryn" || species == "Vulpkanin")
+ r_hair = rand(0,255)
+ g_hair = rand(0,255)
+ b_hair = rand(0,255)
+ if("h_style")
+ h_style = random_hair_style(gender, species)
+ if("facial")
+ r_facial = rand(0,255)
+ g_facial = rand(0,255)
+ b_facial = rand(0,255)
+ if("f_style")
+ f_style = random_facial_hair_style(gender, species)
+ if("underwear")
+ underwear = random_underwear(gender)
+ ShowChoices(user)
+ if("undershirt")
+ undershirt = random_undershirt(gender)
+ ShowChoices(user)
+ if("socks")
+ socks = random_socks(gender)
+ ShowChoices(user)
+ if("eyes")
+ r_eyes = rand(0,255)
+ g_eyes = rand(0,255)
+ b_eyes = rand(0,255)
+ if("s_tone")
+ if(species in list("Human", "Drask"))
+ s_tone = random_skin_tone()
+ if("s_color")
+ if(species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Wyrn", "Vulpkanin", "Machine"))
+ r_skin = rand(0,255)
+ g_skin = rand(0,255)
+ b_skin = rand(0,255)
+ if("bag")
+ backbag = rand(1,4)
+ /*if("skin_style")
+ h_style = random_skin_style(gender)*/
+ if("all")
+ random_character()
+ if("input")
+ switch(href_list["preference"])
+ if("name")
+ var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
+ if (!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.)
+ var/new_name = reject_bad_name(raw_name)
+ if(new_name)
+ real_name = new_name
+ else
+ to_chat(user, "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 .")
+
+ if("age")
+ var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
+ if(new_age)
+ age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
+ if("species")
+
+ var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
+ var/prev_species = species
+// var/whitelisted = 0
+
+ if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
+ for(var/S in whitelisted_species)
+ if(is_alien_whitelisted(user,S))
+ new_species += S
+// whitelisted = 1
+// if(!whitelisted)
+// alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.")
+ else //Not using the whitelist? Aliens for everyone!
+ new_species += whitelisted_species
+
+ species = input("Please select a species", "Character Generation", null) in new_species
+
+ if(prev_species != 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(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(!(species in S.species_allowed))
+ continue
+
+ valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
+
+ if(valid_hairstyles.len)
+ h_style = pick(valid_hairstyles)
+ else
+ //this shouldn't happen
+ 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(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(!(species in S.species_allowed))
+ continue
+
+ valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
+
+ if(valid_facialhairstyles.len)
+ f_style = pick(valid_facialhairstyles)
+ else
+ //this shouldn't happen
+ f_style = facial_hair_styles_list["Shaved"]
+
+ // Don't wear another species' underwear!
+ var/datum/sprite_accessory/S = underwear_list[underwear]
+ if(!(species in S.species_allowed))
+ underwear = random_underwear(gender, species)
+
+ S = undershirt_list[undershirt]
+ if(!(species in S.species_allowed))
+ undershirt = random_undershirt(gender, species)
+
+ S = socks_list[socks]
+ if(!(species in S.species_allowed))
+ socks = random_socks(gender, species)
+
+ //reset hair colour and skin colour
+ r_hair = 0//hex2num(copytext(new_hair, 2, 4))
+ g_hair = 0//hex2num(copytext(new_hair, 4, 6))
+ b_hair = 0//hex2num(copytext(new_hair, 6, 8))
+
+ s_tone = 0
+
+ ha_style = "None" // No Vulp ears on Unathi
+ m_style = "None" // No Unathi markings on Tajara
+
+ body_accessory = null //no vulptail on humans damnit
+
+ //Reset prosthetics.
+ organ_data = list()
+ rlimb_data = list()
+ if("speciesprefs")//oldvox code
+ speciesprefs = !speciesprefs
+
+ if("language")
+// var/languages_available
+ var/list/new_languages = list("None")
+/*
+ if(config.usealienwhitelist)
+ for(var/L in all_languages)
+ var/datum/language/lang = all_languages[L]
+ if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))))
+ new_languages += lang
+ languages_available = 1
+
+ if(!(languages_available))
+ alert(user, "There are not currently any available secondary languages.")
+ else
+*/
+ for(var/L in all_languages)
+ var/datum/language/lang = all_languages[L]
+ if(!(lang.flags & RESTRICTED))
+ new_languages += lang.name
+
+ language = input("Please select a secondary language", "Character Generation", null) in new_languages
+
+ if("metadata")
+ var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
+ if(new_metadata)
+ metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))
+
+ if("b_type")
+ var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" )
+ if(new_b_type)
+ b_type = new_b_type
+
+ if("hair")
+ if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Vulpkanin")
+ var/input = "Choose your character's hair colour:"
+ var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
+ if(new_hair)
+ r_hair = hex2num(copytext(new_hair, 2, 4))
+ g_hair = hex2num(copytext(new_hair, 4, 6))
+ b_hair = hex2num(copytext(new_hair, 6, 8))
+
+ if("h_style")
+ var/list/valid_hairstyles = list()
+ for(var/hairstyle in hair_styles_list)
+ var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
+ if(species == "Machine") //Species that can use prosthetic heads.
+ var/obj/item/organ/external/head/H = new()
+ if(S.name == "Bald")
+ valid_hairstyles[hairstyle] = S
+ if(!rlimb_data["head"]) //Handle situations where the head is default.
+ H.model = "Morpheus Cyberkinetics"
+ else
+ H.model = rlimb_data["head"]
+ var/datum/robolimb/robohead = all_robolimbs[H.model]
+ if(species in S.species_allowed)
+ if(robohead.is_monitor && (robohead.company in S.models_allowed)) //If the Machine character has the default Morpheus screen head or another screen head
+ //and said head is in the hair style's allowed models list...
+ valid_hairstyles[hairstyle] = S //Allow them to select the hairstyle.
+ continue
+ else
+ if(robohead.is_monitor) //Monitors (incl. the default morpheus head) cannot have wigs (human hairstyles).
+ continue
+ else if(!robohead.is_monitor && ("Human" in S.species_allowed))
+ valid_hairstyles[hairstyle] = S
+ continue
+ else
+ if(!(species in S.species_allowed))
+ continue
+
+ valid_hairstyles[hairstyle] = S
+
+ var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles
+ if(new_h_style)
+ h_style = new_h_style
+
+ if("headaccessory")
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
+ var/input = "Choose the colour of your your character's head accessory:"
+ var/new_head_accessory = input(user, input, "Character Preference", rgb(r_headacc, g_headacc, b_headacc)) as color|null
+ if(new_head_accessory)
+ r_headacc = hex2num(copytext(new_head_accessory, 2, 4))
+ g_headacc = hex2num(copytext(new_head_accessory, 4, 6))
+ b_headacc = hex2num(copytext(new_head_accessory, 6, 8))
+
+ if("ha_style")
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
+ var/list/valid_head_accessory_styles = list()
+ for(var/head_accessory_style in head_accessory_styles_list)
+ var/datum/sprite_accessory/H = head_accessory_styles_list[head_accessory_style]
+ if(!(species in H.species_allowed))
+ continue
+
+ valid_head_accessory_styles[head_accessory_style] = head_accessory_styles_list[head_accessory_style]
+
+ var/new_head_accessory_style = input(user, "Choose the style of your character's head accessory:", "Character Preference") as null|anything in valid_head_accessory_styles
+ if(new_head_accessory_style)
+ ha_style = new_head_accessory_style
+
+ if("markings")
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with markings.
+ var/input = "Choose the colour of your your character's markings:"
+ var/new_markings = input(user, input, "Character Preference", rgb(r_markings, g_markings, b_markings)) as color|null
+ if(new_markings)
+ r_markings = hex2num(copytext(new_markings, 2, 4))
+ g_markings = hex2num(copytext(new_markings, 4, 6))
+ b_markings = hex2num(copytext(new_markings, 6, 8))
+
+ if("m_style")
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with markings.
+ var/list/valid_markings = list()
+ for(var/markingstyle in marking_styles_list)
+ var/datum/sprite_accessory/M = marking_styles_list[markingstyle]
+ if(!(species in M.species_allowed))
+ continue
+
+ if(species == "Machine") //Species that can use prosthetic heads.
+ var/obj/item/organ/external/head/H = new()
+ if(!rlimb_data["head"]) //Handle situations where the head is default.
+ H.model = "Morpheus Cyberkinetics"
+ else
+ H.model = rlimb_data["head"]
+ var/datum/robolimb/robohead = all_robolimbs[H.model]
+ if(robohead.is_monitor && M.name != "None") //If the character can have prosthetic heads and they have the default Morpheus head (or another monitor-head), no optic markings.
+ continue
+ else if(!robohead.is_monitor && M.name != "None") //Otherwise, if they DON'T have the default head and the head's not a monitor but the head's not in the style's list of allowed models, skip.
+ if(!(robohead.company in M.models_allowed))
+ continue
+
+ valid_markings[markingstyle] = marking_styles_list[markingstyle]
+
+ var/new_marking_style = input(user, "Choose the style of your character's markings:", "Character Preference", m_style) as null|anything in valid_markings
+ if(new_marking_style)
+ m_style = new_marking_style
+
+ if("body_accessory")
+ var/list/possible_body_accessories = list()
+ if(check_rights(R_ADMIN, 1, user))
+ possible_body_accessories = body_accessory_by_name.Copy()
+ else
+ for(var/B in body_accessory_by_name)
+ var/datum/body_accessory/accessory = body_accessory_by_name[B]
+ if(!istype(accessory))
+ possible_body_accessories += "None" //the only null entry should be the "None" option
+ continue
+ if(species in accessory.allowed_species)
+ possible_body_accessories += B
+
+ var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories
+ if(new_body_accessory)
+ body_accessory = (new_body_accessory == "None") ? null : new_body_accessory
+
+ if("facial")
+ var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null
+ if(new_facial)
+ r_facial = hex2num(copytext(new_facial, 2, 4))
+ g_facial = hex2num(copytext(new_facial, 4, 6))
+ b_facial = hex2num(copytext(new_facial, 6, 8))
+
+ if("f_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(S.name == "Shaved")
+ valid_facialhairstyles[facialhairstyle] = S
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(species == "Machine") //Species that can use prosthetic heads.
+ var/obj/item/organ/external/head/H = new()
+ if(!rlimb_data["head"]) //Handle situations where the head is default.
+ H.model = "Morpheus Cyberkinetics"
+ else
+ H.model = rlimb_data["head"]
+ var/datum/robolimb/robohead = all_robolimbs[H.model]
+ if(species in S.species_allowed)
+ if(robohead.is_monitor) //If the Machine character has the default Morpheus screen head or another screen head and they're allowed to have the style, let them have it.
+ valid_facialhairstyles[facialhairstyle] = S
+ continue
+ else
+ if(robohead.is_monitor) //Monitors (incl. the default morpheus head) cannot have wigs (human facial hairstyles).
+ continue
+ else if(!robohead.is_monitor && ("Human" in S.species_allowed))
+ valid_facialhairstyles[facialhairstyle] = S
+ continue
+ else
+ if(!(species 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") as null|anything in valid_facialhairstyles
+ if(new_f_style)
+ f_style = new_f_style
+
+ if("underwear")
+ var/list/underwear_options
+ if(gender == MALE)
+ underwear_options = underwear_m
+ else
+ underwear_options = underwear_f
+
+ var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in underwear_options
+ if(new_underwear)
+ underwear = new_underwear
+ ShowChoices(user)
+
+ if("undershirt")
+ var/new_undershirt
+ if(gender == MALE)
+ new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_m
+ else
+ new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_f
+ if(new_undershirt)
+ undershirt = new_undershirt
+ ShowChoices(user)
+
+ if("socks")
+ var/list/valid_sockstyles = list()
+ for(var/sockstyle in socks_list)
+ var/datum/sprite_accessory/S = socks_list[sockstyle]
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(!(species in S.species_allowed))
+ continue
+ valid_sockstyles[sockstyle] = socks_list[sockstyle]
+ var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles
+ ShowChoices(user)
+ if(new_socks)
+ socks = new_socks
+
+ if("eyes")
+ var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", rgb(r_eyes, g_eyes, b_eyes)) as color|null
+ if(new_eyes)
+ r_eyes = hex2num(copytext(new_eyes, 2, 4))
+ g_eyes = hex2num(copytext(new_eyes, 4, 6))
+ b_eyes = hex2num(copytext(new_eyes, 6, 8))
+
+ if("s_tone")
+ if(species != "Human" && species != "Drask")
+ return
+ var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null
+ if(new_s_tone)
+ s_tone = 35 - max(min( round(new_s_tone), 220),1)
+
+ if("skin")
+ if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
+ var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(r_skin, g_skin, b_skin)) as color|null
+ if(new_skin)
+ r_skin = hex2num(copytext(new_skin, 2, 4))
+ g_skin = hex2num(copytext(new_skin, 4, 6))
+ b_skin = hex2num(copytext(new_skin, 6, 8))
+
+
+ if("ooccolor")
+ var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null
+ if(new_ooccolor)
+ ooccolor = new_ooccolor
+
+ if("bag")
+ var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in backbaglist
+ if(new_backbag)
+ backbag = backbaglist.Find(new_backbag)
+
+ if("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") as null|anything in list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed")
+ if(new_relation)
+ nanotrasen_relation = new_relation
+
+ if("flavor_text")
+ var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(flavor_text)) as message
+
+ if(msg != null)
+ msg = copytext(msg, 1, MAX_MESSAGE_LEN)
+ msg = html_encode(msg)
+
+ flavor_text = msg
+
+ if("limbs")
+ var/valid_limbs = list("Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
+ if(species == "Machine")
+ valid_limbs = list("Torso", "Lower Body", "Head", "Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
+ var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_limbs
+ if(!limb_name) return
+
+ 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
+ var/valid_limb_states = list("Normal", "Amputated", "Prosthesis")
+ var/no_amputate = 0
+
+ switch(limb_name)
+ if("Torso")
+ limb = "chest"
+ second_limb = "groin"
+ no_amputate = 1
+ if("Lower Body")
+ limb = "groin"
+ no_amputate = 1
+ if("Head")
+ limb = "head"
+ no_amputate = 1
+ 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"
+ if(species != "Machine")
+ third_limb = "l_leg"
+ if("Right Foot")
+ limb = "r_foot"
+ if(species != "Machine")
+ third_limb = "r_leg"
+ if("Left Hand")
+ limb = "l_hand"
+ if(species != "Machine")
+ third_limb = "l_arm"
+ if("Right Hand")
+ limb = "r_hand"
+ if(species != "Machine")
+ third_limb = "r_arm"
+
+ var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in valid_limb_states
+ if(!new_state) return
+
+ switch(new_state)
+ if("Normal")
+ if(limb == "head")
+ m_style = "None"
+ h_style = random_hair_style(gender, species)
+ f_style = facial_hair_styles_list["Shaved"]
+ organ_data[limb] = null
+ rlimb_data[limb] = null
+ if(third_limb)
+ organ_data[third_limb] = null
+ rlimb_data[third_limb] = null
+ if("Amputated")
+ if(!no_amputate)
+ organ_data[limb] = "amputated"
+ rlimb_data[limb] = null
+ if(second_limb)
+ organ_data[second_limb] = "amputated"
+ rlimb_data[second_limb] = null
+ if("Prosthesis")
+ var/choice
+ var/subchoice
+ var/datum/robolimb/R = new()
+ var/in_model
+ var/robolimb_companies = list()
+ for(var/limb_type in typesof(/datum/robolimb)) //This loop populates a list of companies that offer the limb the user selected previously as one of their cybernetic products.
+ R = new limb_type()
+ if(!R.unavailable_at_chargen && (limb in R.parts) && R.has_subtypes) //Ensures users can only choose companies that offer the parts they want, that singular models get added to the list as well companies that offer more than one model, and...
+ robolimb_companies[R.company] = R //List only main brands that have the parts we're looking for.
+ R = new() //Re-initialize R.
+
+ choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in robolimb_companies //Choose from a list of companies that offer the part the user wants.
+ if(!choice)
+ return
+ R.company = choice
+ R = all_robolimbs[R.company]
+ if(R.has_subtypes == 1) //If the company the user selected provides more than just one base model, lets handle it.
+ var/list/robolimb_models = list()
+ for(var/limb_type in typesof(R)) //Handling the different models of parts that manufacturers can provide.
+ var/datum/robolimb/L = new limb_type()
+ if(limb in L.parts) //Make sure that only models that provide the parts the user needs populate the list.
+ robolimb_models[L.company] = L
+ if(robolimb_models.len == 1) //If there's only one model available in the list, autoselect it to avoid having to bother the user with a dialog that provides only one option.
+ subchoice = L.company //If there ends up being more than one model populating the list, subchoice will be overwritten later anyway, so this isn't a problem.
+ if(second_limb in L.parts) //If the child limb of the limb the user selected is also present in the model's parts list, state it's been found so the second limb can be set later.
+ in_model = 1
+ if(robolimb_models.len > 1) //If there's more than one model in the list that can provide the part the user wants, let them choose.
+ subchoice = input(user, "Which model of [choice] [limb_name] do you wish to use?") as null|anything in robolimb_models
+ if(subchoice)
+ choice = subchoice
+ if(limb == "head")
+ ha_style = "None"
+ h_style = hair_styles_list["Bald"]
+ f_style = facial_hair_styles_list["Shaved"]
+ m_style = "None"
+ rlimb_data[limb] = choice
+ organ_data[limb] = "cyborg"
+ if(second_limb)
+ if(subchoice)
+ if(in_model)
+ rlimb_data[second_limb] = choice
+ organ_data[second_limb] = "cyborg"
+ else
+ rlimb_data[second_limb] = choice
+ organ_data[second_limb] = "cyborg"
+
+ if("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")
+ organ_data[organ] = null
+ if("Assisted")
+ organ_data[organ] = "assisted"
+ if("Mechanical")
+ organ_data[organ] = "mechanical"
+
+/*
+ if("skin_style")
+ var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
+ if(!skin_style_name) return
+*/
+
+/* if("spawnpoint")
+ var/list/spawnkeys = list()
+ for(var/S in spawntypes)
+ spawnkeys += S
+ var/choice = input(user, "Where would you like to spawn when latejoining?") as null|anything in spawnkeys
+ if(!choice || !spawntypes[choice])
+ spawnpoint = "Arrivals Shuttle"
+ return
+ spawnpoint = choice */
+
+ else
+ switch(href_list["preference"])
+ if("publicity")
+ if(unlock_content)
+ toggles ^= MEMBER_PUBLIC
+
+ if("gender")
+ if(gender == MALE)
+ gender = FEMALE
+ else
+ gender = MALE
+ underwear = random_underwear(gender)
+
+ if("hear_adminhelps")
+ sound ^= SOUND_ADMINHELP
+
+ if("ui")
+ switch(UI_style)
+ if("Midnight")
+ UI_style = "Plasmafire"
+ if("Plasmafire")
+ UI_style = "Retro"
+ if("Retro")
+ UI_style = "Slimecore"
+ if("Slimecore")
+ UI_style = "Operative"
+ if("Operative")
+ UI_style = "White"
+ else
+ UI_style = "Midnight"
+
+ if(ishuman(usr)) //mid-round preference changes, for aesthetics
+ var/mob/living/carbon/human/H = usr
+ H.remake_hud()
+
+ if("nanoui")
+ nanoui_fancy = !nanoui_fancy
- dat += "
"
- if(!IsGuestKey(user.key))
- dat += "Undo - "
- dat += "Save Setup - "
-
- dat += "Reset Setup"
- dat += ""
-
- var/datum/browser/popup = new(user, "preferences", "Character Setup
", 820, 640)
- popup.set_content(dat)
- popup.open(0)
-
-/datum/preferences/proc/SetChoices(mob/user, limit = 12, list/splitJobs = list("Civilian","Research Director","AI","Bartender"), width = 760, height = 790)
- if(!job_master)
- return
-
- //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
- //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice.
- //width - Screen' width. Defaults to 550 to make it look nice.
- //height - Screen's height. Defaults to 500 to make it look nice.
-
-
- var/HTML = ""
- HTML += ""
- HTML += "Choose occupation chances
Unavailable occupations are crossed out.
"
- HTML += "\[Done\]
" // Easier to press up here.
- HTML += "Left-click to raise an occupation preference, right-click to lower it.
"
- HTML += ""
- HTML += "" // Table within a table for alignment, also allows you to easily add more colomns.
- HTML += ""
- 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)
- HTML += "|   |   | "
- HTML += " | "
- index = 0
-
- HTML += "| "
- var/rank = job.title
- lastJob = job
- if(!is_job_whitelisted(user, rank))
- HTML += "[rank] | \[KARMA] | "
- continue
- if(jobban_isbanned(user, rank))
- HTML += "[rank] \[BANNED] | "
- continue
- if(!job.player_old_enough(user.client))
- var/available_in_days = job.available_in_days(user.client)
- HTML += "[rank] \[IN [(available_in_days)] DAYS] | "
- continue
- if((job_support_low & CIVILIAN) && (rank != "Civilian"))
- HTML += "[rank] | "
- continue
- if((rank in command_positions) || (rank == "AI"))//Bold head jobs
- HTML += "[rank]"
- else
- HTML += "[rank]"
-
- HTML += ""
-
- var/prefLevelLabel = "ERROR"
- var/prefLevelColor = "pink"
- var/prefUpperLevel = -1 // level to assign on left click
- var/prefLowerLevel = -1 // level to assign on right click
-
- if(GetJobDepartment(job, 1) & job.flag)
- prefLevelLabel = "High"
- prefLevelColor = "slateblue"
- prefUpperLevel = 4
- prefLowerLevel = 2
- else if(GetJobDepartment(job, 2) & job.flag)
- prefLevelLabel = "Medium"
- prefLevelColor = "green"
- prefUpperLevel = 1
- prefLowerLevel = 3
- else if(GetJobDepartment(job, 3) & job.flag)
- prefLevelLabel = "Low"
- prefLevelColor = "orange"
- prefUpperLevel = 2
- prefLowerLevel = 4
- else
- prefLevelLabel = "NEVER"
- prefLevelColor = "red"
- prefUpperLevel = 3
- prefLowerLevel = 1
-
-
- HTML += ""
-
-// HTML += ""
-
- if(rank == "Civilian")//Civilian is special
- if(job_support_low & CIVILIAN)
- HTML += " \[Yes]"
- else
- HTML += " \[No]"
- if(job.alt_titles)
- HTML += " \[[GetPlayerAltTitle(job)]\] | "
- HTML += ""
- continue
-/*
- if(GetJobDepartment(job, 1) & job.flag)
- HTML += " \[High]"
- else if(GetJobDepartment(job, 2) & job.flag)
- HTML += " \[Medium]"
- else if(GetJobDepartment(job, 3) & job.flag)
- HTML += " \[Low]"
- else
- HTML += " \[NEVER]"
- */
- HTML += "[prefLevelLabel]"
-
- if(job.alt_titles)
- HTML += " \[[GetPlayerAltTitle(job)]\]"
-
-
- HTML += ""
-
- for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
- HTML += "|   |   | "
-
- HTML += " "
-
- HTML += " |
"
-
- switch(alternate_option)
- if(GET_RANDOM_JOB)
- HTML += "
Get random job if preferences unavailable
"
- if(BE_CIVILIAN)
- HTML += "
Be a civilian if preferences unavailable
"
- if(RETURN_TO_LOBBY)
- HTML += "
Return to lobby if preferences unavailable
"
-
- HTML += "\[Reset\]"
- HTML += ""
-
- user << browse(null, "window=preferences")
-// user << browse(HTML, "window=mob_occupation;size=[width]x[height]")
- var/datum/browser/popup = new(user, "mob_occupation", "Occupation Preferences
", width, height)
- popup.set_window_options("can_close=0")
- popup.set_content(HTML)
- popup.open(0)
- return
-
-/datum/preferences/proc/SetJobPreferenceLevel(var/datum/job/job, var/level)
- if (!job)
- return 0
-
- if (level == 1) // to high
- // remove any other job(s) set to high
- job_support_med |= job_support_high
- job_engsec_med |= job_engsec_high
- job_medsci_med |= job_medsci_high
- job_karma_med |= job_karma_high
- job_support_high = 0
- job_engsec_high = 0
- job_medsci_high = 0
- job_karma_high = 0
-
- if (job.department_flag == SUPPORT)
- job_support_low &= ~job.flag
- job_support_med &= ~job.flag
- job_support_high &= ~job.flag
-
- switch(level)
- if (1)
- job_support_high |= job.flag
- if (2)
- job_support_med |= job.flag
- if (3)
- job_support_low |= job.flag
-
- return 1
- else if (job.department_flag == ENGSEC)
- job_engsec_low &= ~job.flag
- job_engsec_med &= ~job.flag
- job_engsec_high &= ~job.flag
-
- switch(level)
- if (1)
- job_engsec_high |= job.flag
- if (2)
- job_engsec_med |= job.flag
- if (3)
- job_engsec_low |= job.flag
-
- return 1
- else if (job.department_flag == MEDSCI)
- job_medsci_low &= ~job.flag
- job_medsci_med &= ~job.flag
- job_medsci_high &= ~job.flag
-
- switch(level)
- if (1)
- job_medsci_high |= job.flag
- if (2)
- job_medsci_med |= job.flag
- if (3)
- job_medsci_low |= job.flag
-
- return 1
- else if (job.department_flag == KARMA)
- job_karma_low &= ~job.flag
- job_karma_med &= ~job.flag
- job_karma_high &= ~job.flag
-
- switch(level)
- if (1)
- job_karma_high |= job.flag
- if (2)
- job_karma_med |= job.flag
- if (3)
- job_karma_low |= job.flag
-
- return 1
-
- return 0
-
-/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl)
- var/datum/job/job = job_master.GetJob(role)
-
- if(!job)
- user << browse(null, "window=mob_occupation")
- ShowChoices(user)
- return
-
- if (!isnum(desiredLvl))
- to_chat(user, "\red UpdateJobPreference - desired level was not a number. Please notify coders!")
- ShowChoices(user)
- return
-
- if(role == "Civilian")
- if(job_support_low & job.flag)
- job_support_low &= ~job.flag
- else
- job_support_low |= job.flag
- SetChoices(user)
- return 1
-
- SetJobPreferenceLevel(job, desiredLvl)
- SetChoices(user)
-
- return 1
-
-/datum/preferences/proc/ShowDisabilityState(mob/user,flag,label)
- if(flag==DISABILITY_FLAG_FAT && species!=("Human" || "Tajaran" || "Grey"))
- return "[species] cannot be fat."
- return "[label]: [disabilities & flag ? "Yes" : "No"]"
-
-/datum/preferences/proc/SetDisabilities(mob/user)
- var/HTML = ""
-
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:474: HTML += ""
- HTML += {"
- Choose disabilities"}
- // END AUTOFIX
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_NEARSIGHTED,"Needs Glasses")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_FAT,"Obese")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_DEAF,"Deaf")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_BLIND,"Blind")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute")
-
-
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:481: HTML += "
"
- HTML += {"
- \[Done\]
- \[Reset\]
- "}
- // END AUTOFIX
- user << browse(null, "window=preferences")
- user << browse(HTML, "window=disabil;size=350x300")
- return
-
-/datum/preferences/proc/SetRecords(mob/user)
- var/HTML = ""
- HTML += ""
- HTML += "Set Character Records
"
-
- HTML += "Medical Records
"
-
- if(lentext(med_record) <= 40)
- HTML += "[med_record]"
- else
- HTML += "[copytext(med_record, 1, 37)]..."
-
- HTML += "
Employment Records
"
-
- if(lentext(gen_record) <= 40)
- HTML += "[gen_record]"
- else
- HTML += "[copytext(gen_record, 1, 37)]..."
-
- HTML += "
Security Records
"
-
- if(lentext(sec_record) <= 40)
- HTML += "[sec_record]
"
- else
- HTML += "[copytext(sec_record, 1, 37)]...
"
-
- HTML += "
"
- HTML += "\[Done\]"
- HTML += ""
-
- user << browse(null, "window=preferences")
- user << browse(HTML, "window=records;size=350x300")
- return
-
-/datum/preferences/proc/GetPlayerAltTitle(datum/job/job)
- return player_alt_titles.Find(job.title) > 0 \
- ? player_alt_titles[job.title] \
- : job.title
-
-/datum/preferences/proc/SetPlayerAltTitle(datum/job/job, new_title)
- // remove existing entry
- if(player_alt_titles.Find(job.title))
- player_alt_titles -= job.title
- // add one if it's not default
- if(job.title != new_title)
- player_alt_titles[job.title] = new_title
-
-/datum/preferences/proc/SetJob(mob/user, role)
- var/datum/job/job = job_master.GetJob(role)
- if(!job)
- user << browse(null, "window=mob_occupation")
- ShowChoices(user)
- return
-
- if(role == "Civilian")
- if(job_support_low & job.flag)
- job_support_low &= ~job.flag
- else
- job_support_low |= job.flag
- SetChoices(user)
- return 1
-
- if(GetJobDepartment(job, 1) & job.flag)
- SetJobDepartment(job, 1)
- else if(GetJobDepartment(job, 2) & job.flag)
- SetJobDepartment(job, 2)
- else if(GetJobDepartment(job, 3) & job.flag)
- SetJobDepartment(job, 3)
- else//job = Never
- SetJobDepartment(job, 4)
-
- SetChoices(user)
- return 1
-
-/datum/preferences/proc/ResetJobs()
- job_support_high = 0
- job_support_med = 0
- job_support_low = 0
-
- job_medsci_high = 0
- job_medsci_med = 0
- job_medsci_low = 0
-
- job_engsec_high = 0
- job_engsec_med = 0
- job_engsec_low = 0
-
- job_karma_high = 0
- job_karma_med = 0
- job_karma_low = 0
-
-
-/datum/preferences/proc/GetJobDepartment(var/datum/job/job, var/level)
- if(!job || !level) return 0
- switch(job.department_flag)
- if(SUPPORT)
- switch(level)
- if(1)
- return job_support_high
- if(2)
- return job_support_med
- if(3)
- return job_support_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
- if(KARMA)
- switch(level)
- if(1)
- return job_karma_high
- if(2)
- return job_karma_med
- if(3)
- return job_karma_low
- return 0
-
-/datum/preferences/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
- job_support_high = 0
- job_medsci_high = 0
- job_engsec_high = 0
- job_karma_high = 0
- return 1
- if(2)//Set current highs to med, then reset them
- job_support_med |= job_support_high
- job_medsci_med |= job_medsci_high
- job_engsec_med |= job_engsec_high
- job_karma_med |= job_karma_high
- job_support_high = 0
- job_medsci_high = 0
- job_engsec_high = 0
- job_karma_high = 0
-
- switch(job.department_flag)
- if(SUPPORT)
- switch(level)
- if(2)
- job_support_high = job.flag
- job_support_med &= ~job.flag
- if(3)
- job_support_med |= job.flag
- job_support_low &= ~job.flag
- else
- job_support_low |= job.flag
- if(MEDSCI)
- switch(level)
- if(2)
- job_medsci_high = job.flag
- job_medsci_med &= ~job.flag
- if(3)
- job_medsci_med |= job.flag
- job_medsci_low &= ~job.flag
- else
- job_medsci_low |= job.flag
- if(ENGSEC)
- switch(level)
- if(2)
- job_engsec_high = job.flag
- job_engsec_med &= ~job.flag
- if(3)
- job_engsec_med |= job.flag
- job_engsec_low &= ~job.flag
- else
- job_engsec_low |= job.flag
- if(KARMA)
- switch(level)
- if(2)
- job_karma_high = job.flag
- job_karma_med &= ~job.flag
- if(3)
- job_karma_med |= job.flag
- job_karma_low &= ~job.flag
- else
- job_karma_low |= job.flag
- return 1
-
-/datum/preferences/proc/process_link(mob/user, list/href_list)
- if(!user) return
-
- if(href_list["preference"] == "job")
- switch(href_list["task"])
- if("close")
- user << browse(null, "window=mob_occupation")
- ShowChoices(user)
- if("reset")
- ResetJobs()
- SetChoices(user)
- if("random")
- if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_CIVILIAN)
- alternate_option += 1
- else if(alternate_option == RETURN_TO_LOBBY)
- alternate_option = 0
- else
- return 0
- SetChoices(user)
- if ("alt_title")
- var/datum/job/job = locate(href_list["job"])
- if (job)
- var/choices = list(job.title) + job.alt_titles
- var/choice = input("Pick a title for [job.title].", "Character Generation", GetPlayerAltTitle(job)) as anything in choices | null
- if(choice)
- SetPlayerAltTitle(job, choice)
- SetChoices(user)
- if("input")
- SetJob(user, href_list["text"])
- if("setJobLevel")
- UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
- else
- SetChoices(user)
- return 1
- else if(href_list["preference"] == "disabilities")
-
- switch(href_list["task"])
- if("close")
- user << browse(null, "window=disabil")
- ShowChoices(user)
- if("reset")
- disabilities=0
- SetDisabilities(user)
- if("input")
- var/dflag=text2num(href_list["disability"])
- if(dflag >= 0)
- if(!(dflag==DISABILITY_FLAG_FAT && species!=("Human" || "Tajaran" || "Grey")))
- disabilities ^= text2num(href_list["disability"]) //MAGIC
- SetDisabilities(user)
- else
- SetDisabilities(user)
- return 1
-
- else if(href_list["preference"] == "records")
- if(text2num(href_list["record"]) >= 1)
- SetRecords(user)
- return
- else
- user << browse(null, "window=records")
- if(href_list["task"] == "med_record")
- var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(med_record)) as message
-
- if(medmsg != null)
- medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN)
- medmsg = html_encode(medmsg)
-
- med_record = medmsg
- SetRecords(user)
-
- if(href_list["task"] == "sec_record")
- var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(sec_record)) as message
-
- if(secmsg != null)
- secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN)
- secmsg = html_encode(secmsg)
-
- sec_record = secmsg
- SetRecords(user)
- if(href_list["task"] == "gen_record")
- var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(gen_record)) as message
-
- if(genmsg != null)
- genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN)
- genmsg = html_encode(genmsg)
-
- gen_record = genmsg
- SetRecords(user)
-
- switch(href_list["task"])
- if("random")
- switch(href_list["preference"])
- if("name")
- real_name = random_name(gender,species)
- if("age")
- age = rand(AGE_MIN, AGE_MAX)
- if("hair")
- if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Wryn" || species == "Vulpkanin")
- r_hair = rand(0,255)
- g_hair = rand(0,255)
- b_hair = rand(0,255)
- if("h_style")
- h_style = random_hair_style(gender, species)
- if("facial")
- r_facial = rand(0,255)
- g_facial = rand(0,255)
- b_facial = rand(0,255)
- if("f_style")
- f_style = random_facial_hair_style(gender, species)
- if("underwear")
- underwear = random_underwear(gender)
- ShowChoices(user)
- if("undershirt")
- undershirt = random_undershirt(gender)
- ShowChoices(user)
- if("socks")
- socks = random_socks(gender)
- ShowChoices(user)
- if("eyes")
- r_eyes = rand(0,255)
- g_eyes = rand(0,255)
- b_eyes = rand(0,255)
- if("s_tone")
- if(species in list("Human", "Drask"))
- s_tone = random_skin_tone()
- if("s_color")
- if(species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Wyrn", "Vulpkanin", "Machine"))
- r_skin = rand(0,255)
- g_skin = rand(0,255)
- b_skin = rand(0,255)
- if("bag")
- backbag = rand(1,4)
- /*if("skin_style")
- h_style = random_skin_style(gender)*/
- if("all")
- random_character()
- if("input")
- switch(href_list["preference"])
- if("name")
- var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
- if (!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.)
- var/new_name = reject_bad_name(raw_name)
- if(new_name)
- real_name = new_name
- else
- to_chat(user, "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 .")
-
- if("age")
- var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
- if(new_age)
- age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
- if("species")
-
- var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
- var/prev_species = species
-// var/whitelisted = 0
-
- if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
- for(var/S in whitelisted_species)
- if(is_alien_whitelisted(user,S))
- new_species += S
-// whitelisted = 1
-// if(!whitelisted)
-// alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.")
- else //Not using the whitelist? Aliens for everyone!
- new_species += whitelisted_species
-
- species = input("Please select a species", "Character Generation", null) in new_species
-
- if(prev_species != 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(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if(!(species in S.species_allowed))
- continue
-
- valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
-
- if(valid_hairstyles.len)
- h_style = pick(valid_hairstyles)
- else
- //this shouldn't happen
- 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(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if(!(species in S.species_allowed))
- continue
-
- valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
-
- if(valid_facialhairstyles.len)
- f_style = pick(valid_facialhairstyles)
- else
- //this shouldn't happen
- f_style = facial_hair_styles_list["Shaved"]
-
- // Don't wear another species' underwear!
- var/datum/sprite_accessory/S = underwear_list[underwear]
- if(!(species in S.species_allowed))
- underwear = random_underwear(gender, species)
-
- S = undershirt_list[undershirt]
- if(!(species in S.species_allowed))
- undershirt = random_undershirt(gender, species)
-
- S = socks_list[socks]
- if(!(species in S.species_allowed))
- socks = random_socks(gender, species)
-
- //reset hair colour and skin colour
- r_hair = 0//hex2num(copytext(new_hair, 2, 4))
- g_hair = 0//hex2num(copytext(new_hair, 4, 6))
- b_hair = 0//hex2num(copytext(new_hair, 6, 8))
-
- s_tone = 0
-
- ha_style = "None" // No Vulp ears on Unathi
- m_style = "None" // No Unathi markings on Tajara
-
- body_accessory = null //no vulptail on humans damnit
-
- //Reset prosthetics.
- organ_data = list()
- rlimb_data = list()
- if("speciesprefs")//oldvox code
- speciesprefs = !speciesprefs
-
- if("language")
-// var/languages_available
- var/list/new_languages = list("None")
-/*
- if(config.usealienwhitelist)
- for(var/L in all_languages)
- var/datum/language/lang = all_languages[L]
- if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))))
- new_languages += lang
- languages_available = 1
-
- if(!(languages_available))
- alert(user, "There are not currently any available secondary languages.")
- else
-*/
- for(var/L in all_languages)
- var/datum/language/lang = all_languages[L]
- if(!(lang.flags & RESTRICTED))
- new_languages += lang.name
-
- language = input("Please select a secondary language", "Character Generation", null) in new_languages
-
- if("metadata")
- var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
- if(new_metadata)
- metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))
-
- if("b_type")
- var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" )
- if(new_b_type)
- b_type = new_b_type
-
- if("hair")
- if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Vulpkanin")
- var/input = "Choose your character's hair colour:"
- var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
- if(new_hair)
- r_hair = hex2num(copytext(new_hair, 2, 4))
- g_hair = hex2num(copytext(new_hair, 4, 6))
- b_hair = hex2num(copytext(new_hair, 6, 8))
-
- if("h_style")
- var/list/valid_hairstyles = list()
- for(var/hairstyle in hair_styles_list)
- var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if(species == "Machine") //Species that can use prosthetic heads.
- var/obj/item/organ/external/head/H = new()
- if(S.name == "Bald")
- valid_hairstyles[hairstyle] = S
- if(!rlimb_data["head"]) //Handle situations where the head is default.
- H.model = "Morpheus Cyberkinetics"
- else
- H.model = rlimb_data["head"]
- var/datum/robolimb/robohead = all_robolimbs[H.model]
- if(species in S.species_allowed)
- if(robohead.is_monitor && (robohead.company in S.models_allowed)) //If the Machine character has the default Morpheus screen head or another screen head
- //and said head is in the hair style's allowed models list...
- valid_hairstyles[hairstyle] = S //Allow them to select the hairstyle.
- continue
- else
- if(robohead.is_monitor) //Monitors (incl. the default morpheus head) cannot have wigs (human hairstyles).
- continue
- else if(!robohead.is_monitor && ("Human" in S.species_allowed))
- valid_hairstyles[hairstyle] = S
- continue
- else
- if(!(species in S.species_allowed))
- continue
-
- valid_hairstyles[hairstyle] = S
-
- var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles
- if(new_h_style)
- h_style = new_h_style
-
- if("headaccessory")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
- var/input = "Choose the colour of your your character's head accessory:"
- var/new_head_accessory = input(user, input, "Character Preference", rgb(r_headacc, g_headacc, b_headacc)) as color|null
- if(new_head_accessory)
- r_headacc = hex2num(copytext(new_head_accessory, 2, 4))
- g_headacc = hex2num(copytext(new_head_accessory, 4, 6))
- b_headacc = hex2num(copytext(new_head_accessory, 6, 8))
-
- if("ha_style")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
- var/list/valid_head_accessory_styles = list()
- for(var/head_accessory_style in head_accessory_styles_list)
- var/datum/sprite_accessory/H = head_accessory_styles_list[head_accessory_style]
- if(!(species in H.species_allowed))
- continue
-
- valid_head_accessory_styles[head_accessory_style] = head_accessory_styles_list[head_accessory_style]
-
- var/new_head_accessory_style = input(user, "Choose the style of your character's head accessory:", "Character Preference") as null|anything in valid_head_accessory_styles
- if(new_head_accessory_style)
- ha_style = new_head_accessory_style
-
- if("markings")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with markings.
- var/input = "Choose the colour of your your character's markings:"
- var/new_markings = input(user, input, "Character Preference", rgb(r_markings, g_markings, b_markings)) as color|null
- if(new_markings)
- r_markings = hex2num(copytext(new_markings, 2, 4))
- g_markings = hex2num(copytext(new_markings, 4, 6))
- b_markings = hex2num(copytext(new_markings, 6, 8))
-
- if("m_style")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with markings.
- var/list/valid_markings = list()
- for(var/markingstyle in marking_styles_list)
- var/datum/sprite_accessory/M = marking_styles_list[markingstyle]
- if(!(species in M.species_allowed))
- continue
-
- if(species == "Machine") //Species that can use prosthetic heads.
- var/obj/item/organ/external/head/H = new()
- if(!rlimb_data["head"]) //Handle situations where the head is default.
- H.model = "Morpheus Cyberkinetics"
- else
- H.model = rlimb_data["head"]
- var/datum/robolimb/robohead = all_robolimbs[H.model]
- if(robohead.is_monitor && M.name != "None") //If the character can have prosthetic heads and they have the default Morpheus head (or another monitor-head), no optic markings.
- continue
- else if(!robohead.is_monitor && M.name != "None") //Otherwise, if they DON'T have the default head and the head's not a monitor but the head's not in the style's list of allowed models, skip.
- if(!(robohead.company in M.models_allowed))
- continue
-
- valid_markings[markingstyle] = marking_styles_list[markingstyle]
-
- var/new_marking_style = input(user, "Choose the style of your character's markings:", "Character Preference", m_style) as null|anything in valid_markings
- if(new_marking_style)
- m_style = new_marking_style
-
- if("body_accessory")
- var/list/possible_body_accessories = list()
- if(check_rights(R_ADMIN, 1, user))
- possible_body_accessories = body_accessory_by_name.Copy()
- else
- for(var/B in body_accessory_by_name)
- var/datum/body_accessory/accessory = body_accessory_by_name[B]
- if(!istype(accessory))
- possible_body_accessories += "None" //the only null entry should be the "None" option
- continue
- if(species in accessory.allowed_species)
- possible_body_accessories += B
-
- var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories
- if(new_body_accessory)
- body_accessory = (new_body_accessory == "None") ? null : new_body_accessory
-
- if("facial")
- var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null
- if(new_facial)
- r_facial = hex2num(copytext(new_facial, 2, 4))
- g_facial = hex2num(copytext(new_facial, 4, 6))
- b_facial = hex2num(copytext(new_facial, 6, 8))
-
- if("f_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(S.name == "Shaved")
- valid_facialhairstyles[facialhairstyle] = S
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if(species == "Machine") //Species that can use prosthetic heads.
- var/obj/item/organ/external/head/H = new()
- if(!rlimb_data["head"]) //Handle situations where the head is default.
- H.model = "Morpheus Cyberkinetics"
- else
- H.model = rlimb_data["head"]
- var/datum/robolimb/robohead = all_robolimbs[H.model]
- if(species in S.species_allowed)
- if(robohead.is_monitor) //If the Machine character has the default Morpheus screen head or another screen head and they're allowed to have the style, let them have it.
- valid_facialhairstyles[facialhairstyle] = S
- continue
- else
- if(robohead.is_monitor) //Monitors (incl. the default morpheus head) cannot have wigs (human facial hairstyles).
- continue
- else if(!robohead.is_monitor && ("Human" in S.species_allowed))
- valid_facialhairstyles[facialhairstyle] = S
- continue
- else
- if(!(species 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") as null|anything in valid_facialhairstyles
- if(new_f_style)
- f_style = new_f_style
-
- if("underwear")
- var/list/underwear_options
- if(gender == MALE)
- underwear_options = underwear_m
- else
- underwear_options = underwear_f
-
- var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in underwear_options
- if(new_underwear)
- underwear = new_underwear
- ShowChoices(user)
-
- if("undershirt")
- var/new_undershirt
- if(gender == MALE)
- new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_m
- else
- new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_f
- if(new_undershirt)
- undershirt = new_undershirt
- ShowChoices(user)
-
- if("socks")
- var/list/valid_sockstyles = list()
- for(var/sockstyle in socks_list)
- var/datum/sprite_accessory/S = socks_list[sockstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if(!(species in S.species_allowed))
- continue
- valid_sockstyles[sockstyle] = socks_list[sockstyle]
- var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles
- ShowChoices(user)
- if(new_socks)
- socks = new_socks
-
- if("eyes")
- var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", rgb(r_eyes, g_eyes, b_eyes)) as color|null
- if(new_eyes)
- r_eyes = hex2num(copytext(new_eyes, 2, 4))
- g_eyes = hex2num(copytext(new_eyes, 4, 6))
- b_eyes = hex2num(copytext(new_eyes, 6, 8))
-
- if("s_tone")
- if(species != "Human" && species != "Drask")
- return
- var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null
- if(new_s_tone)
- s_tone = 35 - max(min( round(new_s_tone), 220),1)
-
- if("skin")
- if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
- var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(r_skin, g_skin, b_skin)) as color|null
- if(new_skin)
- r_skin = hex2num(copytext(new_skin, 2, 4))
- g_skin = hex2num(copytext(new_skin, 4, 6))
- b_skin = hex2num(copytext(new_skin, 6, 8))
-
-
- if("ooccolor")
- var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null
- if(new_ooccolor)
- ooccolor = new_ooccolor
-
- if("bag")
- var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in backbaglist
- if(new_backbag)
- backbag = backbaglist.Find(new_backbag)
-
- if("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") as null|anything in list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed")
- if(new_relation)
- nanotrasen_relation = new_relation
-
- if("flavor_text")
- var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(flavor_text)) as message
-
- if(msg != null)
- msg = copytext(msg, 1, MAX_MESSAGE_LEN)
- msg = html_encode(msg)
-
- flavor_text = msg
-
- if("limbs")
- var/valid_limbs = list("Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
- if(species == "Machine")
- valid_limbs = list("Torso", "Lower Body", "Head", "Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
- var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_limbs
- if(!limb_name) return
-
- 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
- var/valid_limb_states = list("Normal", "Amputated", "Prosthesis")
- var/no_amputate = 0
-
- switch(limb_name)
- if("Torso")
- limb = "chest"
- second_limb = "groin"
- no_amputate = 1
- if("Lower Body")
- limb = "groin"
- no_amputate = 1
- if("Head")
- limb = "head"
- no_amputate = 1
- 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"
- if(species != "Machine")
- third_limb = "l_leg"
- if("Right Foot")
- limb = "r_foot"
- if(species != "Machine")
- third_limb = "r_leg"
- if("Left Hand")
- limb = "l_hand"
- if(species != "Machine")
- third_limb = "l_arm"
- if("Right Hand")
- limb = "r_hand"
- if(species != "Machine")
- third_limb = "r_arm"
-
- var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in valid_limb_states
- if(!new_state) return
-
- switch(new_state)
- if("Normal")
- if(limb == "head")
- m_style = "None"
- h_style = random_hair_style(gender, species)
- f_style = facial_hair_styles_list["Shaved"]
- organ_data[limb] = null
- rlimb_data[limb] = null
- if(third_limb)
- organ_data[third_limb] = null
- rlimb_data[third_limb] = null
- if("Amputated")
- if(!no_amputate)
- organ_data[limb] = "amputated"
- rlimb_data[limb] = null
- if(second_limb)
- organ_data[second_limb] = "amputated"
- rlimb_data[second_limb] = null
- if("Prosthesis")
- var/choice
- var/subchoice
- var/datum/robolimb/R = new()
- var/in_model
- var/robolimb_companies = list()
- for(var/limb_type in typesof(/datum/robolimb)) //This loop populates a list of companies that offer the limb the user selected previously as one of their cybernetic products.
- R = new limb_type()
- if(!R.unavailable_at_chargen && (limb in R.parts) && R.has_subtypes) //Ensures users can only choose companies that offer the parts they want, that singular models get added to the list as well companies that offer more than one model, and...
- robolimb_companies[R.company] = R //List only main brands that have the parts we're looking for.
- R = new() //Re-initialize R.
-
- choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in robolimb_companies //Choose from a list of companies that offer the part the user wants.
- if(!choice)
- return
- R.company = choice
- R = all_robolimbs[R.company]
- if(R.has_subtypes == 1) //If the company the user selected provides more than just one base model, lets handle it.
- var/list/robolimb_models = list()
- for(var/limb_type in typesof(R)) //Handling the different models of parts that manufacturers can provide.
- var/datum/robolimb/L = new limb_type()
- if(limb in L.parts) //Make sure that only models that provide the parts the user needs populate the list.
- robolimb_models[L.company] = L
- if(robolimb_models.len == 1) //If there's only one model available in the list, autoselect it to avoid having to bother the user with a dialog that provides only one option.
- subchoice = L.company //If there ends up being more than one model populating the list, subchoice will be overwritten later anyway, so this isn't a problem.
- if(second_limb in L.parts) //If the child limb of the limb the user selected is also present in the model's parts list, state it's been found so the second limb can be set later.
- in_model = 1
- if(robolimb_models.len > 1) //If there's more than one model in the list that can provide the part the user wants, let them choose.
- subchoice = input(user, "Which model of [choice] [limb_name] do you wish to use?") as null|anything in robolimb_models
- if(subchoice)
- choice = subchoice
- if(limb == "head")
- ha_style = "None"
- h_style = hair_styles_list["Bald"]
- f_style = facial_hair_styles_list["Shaved"]
- m_style = "None"
- rlimb_data[limb] = choice
- organ_data[limb] = "cyborg"
- if(second_limb)
- if(subchoice)
- if(in_model)
- rlimb_data[second_limb] = choice
- organ_data[second_limb] = "cyborg"
- else
- rlimb_data[second_limb] = choice
- organ_data[second_limb] = "cyborg"
-
- if("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")
- organ_data[organ] = null
- if("Assisted")
- organ_data[organ] = "assisted"
- if("Mechanical")
- organ_data[organ] = "mechanical"
-
-/*
- if("skin_style")
- var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
- if(!skin_style_name) return
-*/
-
-/* if("spawnpoint")
- var/list/spawnkeys = list()
- for(var/S in spawntypes)
- spawnkeys += S
- var/choice = input(user, "Where would you like to spawn when latejoining?") as null|anything in spawnkeys
- if(!choice || !spawntypes[choice])
- spawnpoint = "Arrivals Shuttle"
- return
- spawnpoint = choice */
-
- else
- switch(href_list["preference"])
- if("publicity")
- if(unlock_content)
- toggles ^= MEMBER_PUBLIC
-
- if("gender")
- if(gender == MALE)
- gender = FEMALE
- else
- gender = MALE
- underwear = random_underwear(gender)
-
- if("hear_adminhelps")
- sound ^= SOUND_ADMINHELP
-
- if("ui")
- switch(UI_style)
- if("Midnight")
- UI_style = "Plasmafire"
- if("Plasmafire")
- UI_style = "Retro"
- if("Retro")
- UI_style = "Slimecore"
- if("Slimecore")
- UI_style = "Operative"
- if("Operative")
- UI_style = "White"
- else
- UI_style = "Midnight"
-
- if(ishuman(usr)) //mid-round preference changes, for aesthetics
- var/mob/living/carbon/human/H = usr
- H.remake_hud()
-
- if("nanoui")
- nanoui_fancy = !nanoui_fancy
-
if("ghost_att_anim")
- show_ghostitem_attack = !show_ghostitem_attack
-
- if("UIcolor")
- var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
- if(!UI_style_color_new) return
- UI_style_color = UI_style_color_new
-
- if(ishuman(usr)) //mid-round preference changes, for aesthetics
- var/mob/living/carbon/human/H = usr
- H.remake_hud()
-
- if("UIalpha")
- var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num
- if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
- UI_style_alpha = UI_style_alpha_new
-
- if(ishuman(usr)) //mid-round preference changes, for aesthetics
- var/mob/living/carbon/human/H = usr
- H.remake_hud()
-
- if("be_special")
- var/r = href_list["role"]
- if(!(r in special_roles))
- var/cleaned_r = sql_sanitize_text(r)
- if(r != cleaned_r) // up to no good
- message_admins("[user] attempted an href exploit! (This could have possibly lead to a \"Bobby Tables\" exploit, so they're probably up to no good). String: [r] ID: [last_id] IP: [last_ip]")
- to_chat(user, "Stop right there, criminal scum")
- else
- be_special ^= r
-
- if("name")
- be_random_name = !be_random_name
-
- if("randomslot")
- randomslot = !randomslot
-
- if("hear_midis")
- sound ^= SOUND_MIDI
-
- if("lobby_music")
- sound ^= SOUND_LOBBY
- if(sound & SOUND_LOBBY)
- to_chat(user, sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1))
- else
- to_chat(user, sound(null, repeat = 0, wait = 0, volume = 85, channel = 1))
-
- if("ghost_ears")
- toggles ^= CHAT_GHOSTEARS
-
- if("ghost_sight")
- toggles ^= CHAT_GHOSTSIGHT
-
- if("ghost_radio")
- toggles ^= CHAT_GHOSTRADIO
-
- if("ghost_radio")
- toggles ^= CHAT_GHOSTRADIO
-
- if("save")
- save_preferences(user)
- save_character(user)
-
- if("reload")
- load_preferences(user)
- load_character(user)
-
- if("open_load_dialog")
- if(!IsGuestKey(user.key))
- open_load_dialog(user)
- return 1
-
- if("close_load_dialog")
- close_load_dialog(user)
-
- if("changeslot")
- if(!load_character(user,text2num(href_list["num"])))
- random_character()
- real_name = random_name(gender)
- save_character(user)
- close_load_dialog(user)
-
- if("tab")
- if (href_list["tab"])
- current_tab = text2num(href_list["tab"])
-
- ShowChoices(user)
- return 1
-
-/datum/preferences/proc/copy_to(mob/living/carbon/human/character)
- var/datum/species/S = all_species[species]
- character.change_species(species) // Yell at me if this causes everything to melt
- if(be_random_name)
- real_name = random_name(gender,species)
-
- if(config.humans_need_surnames)
- var/firstspace = findtext(real_name, " ")
- var/name_length = length(real_name)
- if(!firstspace) //we need a surname
- real_name += " [pick(last_names)]"
- else if(firstspace == name_length)
- real_name += "[pick(last_names)]"
-
- character.add_language(language)
-
- character.real_name = real_name
- character.dna.real_name = real_name
- character.name = character.real_name
-
- character.flavor_text = flavor_text
- if(character.ckey && !jobban_isbanned(character, "Records"))
- character.med_record = med_record
- character.sec_record = sec_record
- character.gen_record = gen_record
-
- character.change_gender(gender)
- character.age = age
- character.b_type = b_type
-
- character.r_eyes = r_eyes
- character.g_eyes = g_eyes
- character.b_eyes = b_eyes
-
- character.r_hair = r_hair
- character.g_hair = g_hair
- character.b_hair = b_hair
-
- character.r_facial = r_facial
- character.g_facial = g_facial
- character.b_facial = b_facial
-
- character.r_skin = r_skin
- character.g_skin = g_skin
- character.b_skin = b_skin
-
- character.s_tone = s_tone
-
- character.h_style = h_style
- character.f_style = f_style
-
- // Destroy/cyborgize organs
- for(var/name in organ_data)
-
- var/status = organ_data[name]
- var/obj/item/organ/external/O = character.organs_by_name[name]
- if(O)
- if(status == "amputated")
- character.organs_by_name[O.limb_name] = null
- character.organs -= O
- if(O.children) // This might need to become recursive.
- for(var/obj/item/organ/external/child in O.children)
- character.organs_by_name[child.limb_name] = null
- character.organs -= child
-
- else if(status == "cyborg")
- if(rlimb_data[name])
- O.robotize(rlimb_data[name])
- else
- O.robotize()
- else
- var/obj/item/organ/internal/I = character.get_int_organ_tag(name)
- if(I)
- if(status == "assisted")
- I.mechassist()
- else if(status == "mechanical")
- I.robotize()
-
- character.dna.b_type = b_type
- if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)
- character.dna.SetSEState(FATBLOCK,1,1)
- character.mutations += FAT
- character.mutations += OBESITY
- character.overeatduration = 600
-
- if(disabilities & DISABILITY_FLAG_NEARSIGHTED)
- character.dna.SetSEState(GLASSESBLOCK,1,1)
- character.disabilities|=NEARSIGHTED
-
- if(disabilities & DISABILITY_FLAG_EPILEPTIC)
- character.dna.SetSEState(EPILEPSYBLOCK,1,1)
- character.disabilities|=EPILEPSY
-
- if(disabilities & DISABILITY_FLAG_DEAF)
- character.dna.SetSEState(DEAFBLOCK,1,1)
- character.sdisabilities|=DEAF
-
- if(disabilities & DISABILITY_FLAG_BLIND)
- character.dna.SetSEState(BLINDBLOCK,1,1)
- character.sdisabilities|=BLIND
-
- if(disabilities & DISABILITY_FLAG_MUTE)
- character.dna.SetSEState(MUTEBLOCK,1,1)
- character.sdisabilities |= MUTE
-
- S.handle_dna(character)
-
- if(character.dna.dirtySE)
- character.dna.UpdateSE()
- domutcheck(character)
-
- // Wheelchair necessary?
- var/obj/item/organ/external/l_foot = character.get_organ("l_foot")
- var/obj/item/organ/external/r_foot = character.get_organ("r_foot")
- if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED))
- var/obj/structure/stool/bed/chair/wheelchair/W = new /obj/structure/stool/bed/chair/wheelchair (character.loc)
- character.buckled = W
- character.update_canmove()
- W.dir = character.dir
- W.buckled_mob = character
- W.add_fingerprint(character)
-
- character.underwear = underwear
- character.undershirt = undershirt
- character.socks = socks
-
- if(character.species.bodyflags & HAS_HEAD_ACCESSORY)
- character.r_headacc = r_headacc
- character.g_headacc = g_headacc
- character.b_headacc = b_headacc
- character.ha_style = ha_style
- if(character.species.bodyflags & HAS_MARKINGS)
- character.r_markings = r_markings
- character.g_markings = g_markings
- character.b_markings = b_markings
- character.m_style = m_style
-
- if(body_accessory)
- character.body_accessory = body_accessory_by_name["[body_accessory]"]
-
- if(backbag > 4 || backbag < 1)
- backbag = 1 //Same as above
- character.backbag = backbag
-
- //Debugging report to track down a bug, which randomly assigned the plural gender to people.
- if(character.gender in list(PLURAL, NEUTER))
- if(isliving(src)) //Ghosts get neuter by default
- message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.")
- character.change_gender(MALE)
-
- character.dna.ready_dna(character, flatten_SE = 0)
- character.sync_organ_dna(assimilate=1)
- character.UpdateAppearance()
-
- // Do the initial caching of the player's body icons.
- character.force_update_limbs()
- character.update_eyes()
- character.regenerate_icons()
-
-/datum/preferences/proc/open_load_dialog(mob/user)
-
- var/DBQuery/query = dbcon.NewQuery("SELECT slot,real_name FROM [format_table_name("characters")] WHERE ckey='[user.ckey]' ORDER BY slot")
-
- var/dat = ""
- dat += ""
- dat += "Select a character slot to load
"
- var/name
-
- for(var/i=1, i<=max_save_slots, i++)
- if(!query.Execute())
- var/err = query.ErrorMsg()
- log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n")
- message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n")
- return
- while(query.NextRow())
- if(i==text2num(query.item[1]))
- name = query.item[2]
- if(!name) name = "Character[i]"
- if(i==default_slot)
- name = "[name]"
- dat += "[name]
"
- name = null
-
- dat += "
"
- dat += "Close
"
- dat += ""
-// user << browse(dat, "window=saves;size=300x390")
- var/datum/browser/popup = new(user, "saves", "Character Saves
", 300, 390)
- popup.set_content(dat)
- popup.open(0)
-
-/datum/preferences/proc/close_load_dialog(mob/user)
- user << browse(null, "window=saves")
+ show_ghostitem_attack = !show_ghostitem_attack
+
+ if("UIcolor")
+ var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
+ if(!UI_style_color_new) return
+ UI_style_color = UI_style_color_new
+
+ if(ishuman(usr)) //mid-round preference changes, for aesthetics
+ var/mob/living/carbon/human/H = usr
+ H.remake_hud()
+
+ if("UIalpha")
+ var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num
+ if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
+ UI_style_alpha = UI_style_alpha_new
+
+ if(ishuman(usr)) //mid-round preference changes, for aesthetics
+ var/mob/living/carbon/human/H = usr
+ H.remake_hud()
+
+ if("be_special")
+ var/r = href_list["role"]
+ if(!(r in special_roles))
+ var/cleaned_r = sql_sanitize_text(r)
+ if(r != cleaned_r) // up to no good
+ message_admins("[user] attempted an href exploit! (This could have possibly lead to a \"Bobby Tables\" exploit, so they're probably up to no good). String: [r] ID: [last_id] IP: [last_ip]")
+ to_chat(user, "Stop right there, criminal scum")
+ else
+ be_special ^= r
+
+ if("name")
+ be_random_name = !be_random_name
+
+ if("randomslot")
+ randomslot = !randomslot
+
+ if("hear_midis")
+ sound ^= SOUND_MIDI
+
+ if("lobby_music")
+ sound ^= SOUND_LOBBY
+ if(sound & SOUND_LOBBY)
+ to_chat(user, sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1))
+ else
+ to_chat(user, sound(null, repeat = 0, wait = 0, volume = 85, channel = 1))
+
+ if("ghost_ears")
+ toggles ^= CHAT_GHOSTEARS
+
+ if("ghost_sight")
+ toggles ^= CHAT_GHOSTSIGHT
+
+ if("ghost_radio")
+ toggles ^= CHAT_GHOSTRADIO
+
+ if("ghost_radio")
+ toggles ^= CHAT_GHOSTRADIO
+
+ if("save")
+ save_preferences(user)
+ save_character(user)
+
+ if("reload")
+ load_preferences(user)
+ load_character(user)
+
+ if("open_load_dialog")
+ if(!IsGuestKey(user.key))
+ open_load_dialog(user)
+ return 1
+
+ if("close_load_dialog")
+ close_load_dialog(user)
+
+ if("changeslot")
+ if(!load_character(user,text2num(href_list["num"])))
+ random_character()
+ real_name = random_name(gender)
+ save_character(user)
+ close_load_dialog(user)
+
+ if("tab")
+ if (href_list["tab"])
+ current_tab = text2num(href_list["tab"])
+
+ ShowChoices(user)
+ return 1
+
+/datum/preferences/proc/copy_to(mob/living/carbon/human/character)
+ var/datum/species/S = all_species[species]
+ character.change_species(species) // Yell at me if this causes everything to melt
+ if(be_random_name)
+ real_name = random_name(gender,species)
+
+ if(config.humans_need_surnames)
+ var/firstspace = findtext(real_name, " ")
+ var/name_length = length(real_name)
+ if(!firstspace) //we need a surname
+ real_name += " [pick(last_names)]"
+ else if(firstspace == name_length)
+ real_name += "[pick(last_names)]"
+
+ character.add_language(language)
+
+ character.real_name = real_name
+ character.dna.real_name = real_name
+ character.name = character.real_name
+
+ character.flavor_text = flavor_text
+ if(character.ckey && !jobban_isbanned(character, "Records"))
+ character.med_record = med_record
+ character.sec_record = sec_record
+ character.gen_record = gen_record
+
+ character.change_gender(gender)
+ character.age = age
+ character.b_type = b_type
+
+ character.r_eyes = r_eyes
+ character.g_eyes = g_eyes
+ character.b_eyes = b_eyes
+
+ character.r_hair = r_hair
+ character.g_hair = g_hair
+ character.b_hair = b_hair
+
+ character.r_facial = r_facial
+ character.g_facial = g_facial
+ character.b_facial = b_facial
+
+ character.r_skin = r_skin
+ character.g_skin = g_skin
+ character.b_skin = b_skin
+
+ character.s_tone = s_tone
+
+ character.h_style = h_style
+ character.f_style = f_style
+
+ // Destroy/cyborgize organs
+ for(var/name in organ_data)
+
+ var/status = organ_data[name]
+ var/obj/item/organ/external/O = character.organs_by_name[name]
+ if(O)
+ if(status == "amputated")
+ character.organs_by_name[O.limb_name] = null
+ character.organs -= O
+ if(O.children) // This might need to become recursive.
+ for(var/obj/item/organ/external/child in O.children)
+ character.organs_by_name[child.limb_name] = null
+ character.organs -= child
+
+ else if(status == "cyborg")
+ if(rlimb_data[name])
+ O.robotize(rlimb_data[name])
+ else
+ O.robotize()
+ else
+ var/obj/item/organ/internal/I = character.get_int_organ_tag(name)
+ if(I)
+ if(status == "assisted")
+ I.mechassist()
+ else if(status == "mechanical")
+ I.robotize()
+
+ character.dna.b_type = b_type
+ if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)
+ character.dna.SetSEState(FATBLOCK,1,1)
+ character.mutations += FAT
+ character.mutations += OBESITY
+ character.overeatduration = 600
+
+ if(disabilities & DISABILITY_FLAG_NEARSIGHTED)
+ character.dna.SetSEState(GLASSESBLOCK,1,1)
+ character.disabilities|=NEARSIGHTED
+
+ if(disabilities & DISABILITY_FLAG_EPILEPTIC)
+ character.dna.SetSEState(EPILEPSYBLOCK,1,1)
+ character.disabilities|=EPILEPSY
+
+ if(disabilities & DISABILITY_FLAG_DEAF)
+ character.dna.SetSEState(DEAFBLOCK,1,1)
+ character.sdisabilities|=DEAF
+
+ if(disabilities & DISABILITY_FLAG_BLIND)
+ character.dna.SetSEState(BLINDBLOCK,1,1)
+ character.sdisabilities|=BLIND
+
+ if(disabilities & DISABILITY_FLAG_MUTE)
+ character.dna.SetSEState(MUTEBLOCK,1,1)
+ character.sdisabilities |= MUTE
+
+ S.handle_dna(character)
+
+ if(character.dna.dirtySE)
+ character.dna.UpdateSE()
+ domutcheck(character)
+
+ // Wheelchair necessary?
+ var/obj/item/organ/external/l_foot = character.get_organ("l_foot")
+ var/obj/item/organ/external/r_foot = character.get_organ("r_foot")
+ if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED))
+ var/obj/structure/stool/bed/chair/wheelchair/W = new /obj/structure/stool/bed/chair/wheelchair (character.loc)
+ character.buckled = W
+ character.update_canmove()
+ W.dir = character.dir
+ W.buckled_mob = character
+ W.add_fingerprint(character)
+
+ character.underwear = underwear
+ character.undershirt = undershirt
+ character.socks = socks
+
+ if(character.species.bodyflags & HAS_HEAD_ACCESSORY)
+ character.r_headacc = r_headacc
+ character.g_headacc = g_headacc
+ character.b_headacc = b_headacc
+ character.ha_style = ha_style
+ if(character.species.bodyflags & HAS_MARKINGS)
+ character.r_markings = r_markings
+ character.g_markings = g_markings
+ character.b_markings = b_markings
+ character.m_style = m_style
+
+ if(body_accessory)
+ character.body_accessory = body_accessory_by_name["[body_accessory]"]
+
+ if(backbag > 4 || backbag < 1)
+ backbag = 1 //Same as above
+ character.backbag = backbag
+
+ //Debugging report to track down a bug, which randomly assigned the plural gender to people.
+ if(character.gender in list(PLURAL, NEUTER))
+ if(isliving(src)) //Ghosts get neuter by default
+ message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.")
+ character.change_gender(MALE)
+
+ character.dna.ready_dna(character, flatten_SE = 0)
+ character.sync_organ_dna(assimilate=1)
+ character.UpdateAppearance()
+
+ // Do the initial caching of the player's body icons.
+ character.force_update_limbs()
+ character.update_eyes()
+ character.regenerate_icons()
+
+/datum/preferences/proc/open_load_dialog(mob/user)
+
+ var/DBQuery/query = dbcon.NewQuery("SELECT slot,real_name FROM [format_table_name("characters")] WHERE ckey='[user.ckey]' ORDER BY slot")
+
+ var/dat = ""
+ dat += ""
+ dat += "Select a character slot to load
"
+ var/name
+
+ for(var/i=1, i<=max_save_slots, i++)
+ if(!query.Execute())
+ var/err = query.ErrorMsg()
+ log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n")
+ message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n")
+ return
+ while(query.NextRow())
+ if(i==text2num(query.item[1]))
+ name = query.item[2]
+ if(!name) name = "Character[i]"
+ if(i==default_slot)
+ name = "[name]"
+ dat += "[name]
"
+ name = null
+
+ dat += "
"
+ dat += "Close
"
+ dat += ""
+// user << browse(dat, "window=saves;size=300x390")
+ var/datum/browser/popup = new(user, "saves", "Character Saves
", 300, 390)
+ popup.set_content(dat)
+ popup.open(0)
+
+/datum/preferences/proc/close_load_dialog(mob/user)
+ user << browse(null, "window=saves")
diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm
similarity index 98%
rename from code/modules/client/preferences_mysql.dm
rename to code/modules/client/preference/preferences_mysql.dm
index cb2e3116526..43dc470c784 100644
--- a/code/modules/client/preferences_mysql.dm
+++ b/code/modules/client/preference/preferences_mysql.dm
@@ -155,7 +155,8 @@
nanotrasen_relation,
speciesprefs,
socks,
- body_accessory
+ body_accessory,
+ gear
FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[slot]'"})
if(!query.Execute())
var/err = query.ErrorMsg()
@@ -233,6 +234,7 @@
//socks
socks = query.item[58]
body_accessory = query.item[59]
+ gear = params2list(query.item[60])
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
@@ -295,6 +297,7 @@
if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
if(!rlimb_data) src.rlimb_data = list()
+ if(!gear) gear = list()
return 1
@@ -302,12 +305,15 @@
var/organlist
var/rlimblist
var/playertitlelist
+ var/gearlist
if(!isemptylist(organ_data))
organlist = list2params(organ_data)
if(!isemptylist(rlimb_data))
rlimblist = list2params(rlimb_data)
if(!isemptylist(player_alt_titles))
playertitlelist = list2params(player_alt_titles)
+ if(!isemptylist(gear))
+ gearlist = list2params(gear)
var/DBQuery/firstquery = dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' ORDER BY slot")
firstquery.Execute()
@@ -371,7 +377,8 @@
nanotrasen_relation='[nanotrasen_relation]',
speciesprefs='[speciesprefs]',
socks='[socks]',
- body_accessory='[body_accessory]'
+ body_accessory='[body_accessory]',
+ gear='[gearlist]'
WHERE ckey='[C.ckey]'
AND slot='[default_slot]'"}
)
@@ -402,7 +409,7 @@
flavor_text, med_record, sec_record, gen_record,
player_alt_titles,
disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs,
- socks, body_accessory)
+ socks, body_accessory, gear)
VALUES
('[C.ckey]', '[default_slot]', '[sql_sanitize_text(metadata)]', '[sql_sanitize_text(real_name)]', '[be_random_name]','[gender]',
@@ -423,7 +430,7 @@
'[sql_sanitize_text(html_encode(flavor_text))]', '[sql_sanitize_text(html_encode(med_record))]', '[sql_sanitize_text(html_encode(sec_record))]', '[sql_sanitize_text(html_encode(gen_record))]',
'[playertitlelist]',
'[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]',
- '[socks]', '[body_accessory]')
+ '[socks]', '[body_accessory]', '[gearlist]')
"}
)
diff --git a/code/modules/client/preferences_spawnpoints.dm b/code/modules/client/preference/preferences_spawnpoints.dm
similarity index 100%
rename from code/modules/client/preferences_spawnpoints.dm
rename to code/modules/client/preference/preferences_spawnpoints.dm
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
similarity index 97%
rename from code/modules/client/preferences_toggles.dm
rename to code/modules/client/preference/preferences_toggles.dm
index afb70577dd0..cab1914b71f 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -1,216 +1,216 @@
-//toggles
-/client/verb/toggle_ghost_ears()
- set name = "Show/Hide GhostEars"
- set category = "Preferences"
- set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
- prefs.toggles ^= CHAT_GHOSTEARS
- to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
- prefs.save_preferences(src)
- feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/toggle_ghost_sight()
- set name = "Show/Hide GhostSight"
- set category = "Preferences"
- set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
- prefs.toggles ^= CHAT_GHOSTSIGHT
- to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
- prefs.save_preferences(src)
- feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/toggle_ghost_radio()
- set name = "Enable/Disable GhostRadio"
- set category = "Preferences"
- set desc = ".Toggle between hearing all radio chatter, or only from nearby speakers"
- prefs.toggles ^= CHAT_GHOSTRADIO
- to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"].")
- prefs.save_preferences(src)
- feedback_add_details("admin_verb","TGR")
-
-/client/proc/toggle_hear_radio()
- set name = "Show/Hide RadioChatter"
- set category = "Preferences"
- set desc = "Toggle seeing radiochatter from radios and speakers"
- if(!holder) return
- prefs.toggles ^= CHAT_RADIO
- prefs.save_preferences(src)
- to_chat(usr, "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers")
- feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/toggleadminhelpsound()
- set name = "Hear/Silence Adminhelps"
- set category = "Preferences"
- set desc = "Toggle hearing a notification when admin PMs are recieved"
- if(!holder) return
- prefs.sound ^= SOUND_ADMINHELP
- prefs.save_preferences(src)
- to_chat(usr, "You will [(prefs.sound & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive.")
- feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/deadchat() // Deadchat toggle is usable by anyone.
- set name = "Show/Hide Deadchat"
- set category = "Preferences"
- set desc ="Toggles seeing deadchat"
- prefs.toggles ^= CHAT_DEAD
- prefs.save_preferences(src)
-
- if(src.holder)
- to_chat(src, "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
- else
- to_chat(src, "As a ghost, you will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
-
- feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/toggleprayers()
- set name = "Show/Hide Prayers"
- set category = "Preferences"
- set desc = "Toggles seeing prayers"
- prefs.toggles ^= CHAT_PRAYER
- prefs.save_preferences(src)
- to_chat(src, "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
- feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/togglescoreboard()
- set name = "Hide/Display End Round Scoreboard"
- set category = "Preferences"
- set desc = "Toggles displaying end of round scoreboard"
- prefs.toggles ^= DISABLE_SCOREBOARD
- prefs.save_preferences(src)
- to_chat(src, "You will [(prefs.toggles & DISABLE_SCOREBOARD) ? "no longer" : "now"] see the end of round scoreboard.")
- feedback_add_details("admin_verb","TScoreboard") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/togglekarmareminder()
- set name = "Hide/Display End Round Karma Reminder"
- set category = "Preferences"
- set desc = "Toggles displaying end of round karma reminder"
- prefs.toggles ^= DISABLE_KARMA_REMINDER
- prefs.save_preferences(src)
- to_chat(src, "You will [(prefs.toggles & DISABLE_KARMA_REMINDER) ? "no longer" : "now"] see the end of round karma reminder.")
- feedback_add_details("admin_verb","TKarmabugger") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/toggletitlemusic()
- set name = "Hear/Silence LobbyMusic"
- set category = "Preferences"
- set desc = "Toggles hearing the GameLobby music"
- prefs.sound ^= SOUND_LOBBY
- prefs.save_preferences(src)
- if(prefs.sound & SOUND_LOBBY)
- to_chat(src, "You will now hear music in the game lobby.")
- if(istype(mob, /mob/new_player))
- playtitlemusic()
- else
- to_chat(src, "You will no longer hear music in the game lobby.")
- if(istype(mob, /mob/new_player))
- to_chat(src, sound(null, repeat = 0, wait = 0, volume = 85, channel = 1))// stop the jamsz
-
- feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/togglemidis()
- set name = "Hear/Silence Midis"
- set category = "Preferences"
- set desc = "Toggles hearing sounds uploaded by admins"
- prefs.sound ^= SOUND_MIDI
- prefs.save_preferences(src)
- if(prefs.sound & SOUND_MIDI)
- to_chat(src, "You will now hear any sounds uploaded by admins.")
- else
- var/sound/break_sound = sound(null, repeat = 0, wait = 0, channel = 777)
- break_sound.priority = 250
- to_chat(src, break_sound)//breaks the client's sound output on channel 777
-
- to_chat(src, "You will no longer hear sounds uploaded by admins; any currently playing midis have been disabled.")
- feedback_add_details("admin_verb","TMidi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/listen_ooc()
- set name = "Show/Hide OOC"
- set category = "Preferences"
- set desc = "Toggles seeing OutOfCharacter chat"
- prefs.toggles ^= CHAT_OOC
- prefs.save_preferences(src)
- to_chat(src, "You will [(prefs.toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
- feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/verb/listen_looc()
- set name = "Show/Hide LOOC"
- set category = "Preferences"
- set desc = "Toggles seeing Local OutOfCharacter chat"
- prefs.toggles ^= CHAT_LOOC
- prefs.save_preferences(src)
- to_chat(src, "You will [(prefs.toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.")
- feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful
- set name = "Hear/Silence Ambience"
- set category = "Preferences"
- set desc = "Toggles hearing ambient sound effects"
- prefs.sound ^= SOUND_AMBIENCE
- prefs.save_preferences(src)
- if(prefs.sound & SOUND_AMBIENCE)
- to_chat(src, "You will now hear ambient sounds.")
- else
- to_chat(src, "You will no longer hear ambient sounds.")
- to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 1))
- feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/Toggle_Buzz() //No more headaches because headphones bump up shipambience.ogg to insanity levels.
- set name = "Hear/Silence White Noise"
- set category = "Preferences"
- set desc = "Toggles hearing ambient white noise"
- prefs.sound ^= SOUND_BUZZ
- prefs.save_preferences(src)
- if(prefs.sound & SOUND_BUZZ)
- to_chat(src, "You will now hear ambient white noise.")
- else
- to_chat(src, "You will no longer hear ambient white noise.")
- to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 2))
- feedback_add_details("admin_verb","TBuzz") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/verb/Toggle_Heartbeat() //to toggle off heartbeat sounds, in case they get too annoying
- set name = "Hear/Silence Heartbeat"
- set category = "Preferences"
- set desc = "Toggles hearing heart beating sound effects"
- prefs.sound ^= SOUND_HEARTBEAT
- prefs.save_preferences(src)
- if(prefs.sound & SOUND_HEARTBEAT)
- to_chat(src, "You will now hear heartbeat sounds.")
- else
- to_chat(src, "You will no longer hear heartbeat sounds.")
- to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 1))
- to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 2))
- feedback_add_details("admin_verb","Thb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-// This needs a toggle because you people are awful and spammed terrible music
-/client/verb/toggle_instruments()
- set name = "Hear/Silence Instruments"
- set category = "Preferences"
- set desc = "Toggles hearing musical instruments like the violin and piano"
- prefs.toggles ^= SOUND_INSTRUMENTS
- prefs.save_preferences(src)
- if(prefs.toggles & SOUND_INSTRUMENTS)
- to_chat(src, "You will now hear people playing musical instruments.")
- else
- to_chat(src, "You will no longer hear musical instruments.")
- feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/verb/toggle_media()
- set name = "Hear/Silence Streaming"
- set category = "Preferences"
- set desc = "Toggle hearing streaming media (radios, jukeboxes, etc)"
-
- prefs.sound ^= SOUND_STREAMING
- prefs.save_preferences(src)
- to_chat(usr, "You will [(prefs.sound & SOUND_STREAMING) ? "now" : "no longer"] hear streamed media.")
- if(!media) return
- if(prefs.sound & SOUND_STREAMING)
- media.update_music()
- else
- media.stop_music()
-
-/client/verb/setup_character()
- set name = "Game Preferences"
- set category = "Preferences"
- set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will."
- prefs.current_tab = 1
+//toggles
+/client/verb/toggle_ghost_ears()
+ set name = "Show/Hide GhostEars"
+ set category = "Preferences"
+ set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
+ prefs.toggles ^= CHAT_GHOSTEARS
+ to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
+ prefs.save_preferences(src)
+ feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/toggle_ghost_sight()
+ set name = "Show/Hide GhostSight"
+ set category = "Preferences"
+ set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
+ prefs.toggles ^= CHAT_GHOSTSIGHT
+ to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
+ prefs.save_preferences(src)
+ feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/toggle_ghost_radio()
+ set name = "Enable/Disable GhostRadio"
+ set category = "Preferences"
+ set desc = ".Toggle between hearing all radio chatter, or only from nearby speakers"
+ prefs.toggles ^= CHAT_GHOSTRADIO
+ to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"].")
+ prefs.save_preferences(src)
+ feedback_add_details("admin_verb","TGR")
+
+/client/proc/toggle_hear_radio()
+ set name = "Show/Hide RadioChatter"
+ set category = "Preferences"
+ set desc = "Toggle seeing radiochatter from radios and speakers"
+ if(!holder) return
+ prefs.toggles ^= CHAT_RADIO
+ prefs.save_preferences(src)
+ to_chat(usr, "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers")
+ feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/toggleadminhelpsound()
+ set name = "Hear/Silence Adminhelps"
+ set category = "Preferences"
+ set desc = "Toggle hearing a notification when admin PMs are recieved"
+ if(!holder) return
+ prefs.sound ^= SOUND_ADMINHELP
+ prefs.save_preferences(src)
+ to_chat(usr, "You will [(prefs.sound & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive.")
+ feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/deadchat() // Deadchat toggle is usable by anyone.
+ set name = "Show/Hide Deadchat"
+ set category = "Preferences"
+ set desc ="Toggles seeing deadchat"
+ prefs.toggles ^= CHAT_DEAD
+ prefs.save_preferences(src)
+
+ if(src.holder)
+ to_chat(src, "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
+ else
+ to_chat(src, "As a ghost, you will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
+
+ feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggleprayers()
+ set name = "Show/Hide Prayers"
+ set category = "Preferences"
+ set desc = "Toggles seeing prayers"
+ prefs.toggles ^= CHAT_PRAYER
+ prefs.save_preferences(src)
+ to_chat(src, "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
+ feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/togglescoreboard()
+ set name = "Hide/Display End Round Scoreboard"
+ set category = "Preferences"
+ set desc = "Toggles displaying end of round scoreboard"
+ prefs.toggles ^= DISABLE_SCOREBOARD
+ prefs.save_preferences(src)
+ to_chat(src, "You will [(prefs.toggles & DISABLE_SCOREBOARD) ? "no longer" : "now"] see the end of round scoreboard.")
+ feedback_add_details("admin_verb","TScoreboard") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/togglekarmareminder()
+ set name = "Hide/Display End Round Karma Reminder"
+ set category = "Preferences"
+ set desc = "Toggles displaying end of round karma reminder"
+ prefs.toggles ^= DISABLE_KARMA_REMINDER
+ prefs.save_preferences(src)
+ to_chat(src, "You will [(prefs.toggles & DISABLE_KARMA_REMINDER) ? "no longer" : "now"] see the end of round karma reminder.")
+ feedback_add_details("admin_verb","TKarmabugger") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/toggletitlemusic()
+ set name = "Hear/Silence LobbyMusic"
+ set category = "Preferences"
+ set desc = "Toggles hearing the GameLobby music"
+ prefs.sound ^= SOUND_LOBBY
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_LOBBY)
+ to_chat(src, "You will now hear music in the game lobby.")
+ if(istype(mob, /mob/new_player))
+ playtitlemusic()
+ else
+ to_chat(src, "You will no longer hear music in the game lobby.")
+ if(istype(mob, /mob/new_player))
+ to_chat(src, sound(null, repeat = 0, wait = 0, volume = 85, channel = 1))// stop the jamsz
+
+ feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/togglemidis()
+ set name = "Hear/Silence Midis"
+ set category = "Preferences"
+ set desc = "Toggles hearing sounds uploaded by admins"
+ prefs.sound ^= SOUND_MIDI
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_MIDI)
+ to_chat(src, "You will now hear any sounds uploaded by admins.")
+ else
+ var/sound/break_sound = sound(null, repeat = 0, wait = 0, channel = 777)
+ break_sound.priority = 250
+ to_chat(src, break_sound)//breaks the client's sound output on channel 777
+
+ to_chat(src, "You will no longer hear sounds uploaded by admins; any currently playing midis have been disabled.")
+ feedback_add_details("admin_verb","TMidi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/listen_ooc()
+ set name = "Show/Hide OOC"
+ set category = "Preferences"
+ set desc = "Toggles seeing OutOfCharacter chat"
+ prefs.toggles ^= CHAT_OOC
+ prefs.save_preferences(src)
+ to_chat(src, "You will [(prefs.toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
+ feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/verb/listen_looc()
+ set name = "Show/Hide LOOC"
+ set category = "Preferences"
+ set desc = "Toggles seeing Local OutOfCharacter chat"
+ prefs.toggles ^= CHAT_LOOC
+ prefs.save_preferences(src)
+ to_chat(src, "You will [(prefs.toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.")
+ feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful
+ set name = "Hear/Silence Ambience"
+ set category = "Preferences"
+ set desc = "Toggles hearing ambient sound effects"
+ prefs.sound ^= SOUND_AMBIENCE
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_AMBIENCE)
+ to_chat(src, "You will now hear ambient sounds.")
+ else
+ to_chat(src, "You will no longer hear ambient sounds.")
+ to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 1))
+ feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/Toggle_Buzz() //No more headaches because headphones bump up shipambience.ogg to insanity levels.
+ set name = "Hear/Silence White Noise"
+ set category = "Preferences"
+ set desc = "Toggles hearing ambient white noise"
+ prefs.sound ^= SOUND_BUZZ
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_BUZZ)
+ to_chat(src, "You will now hear ambient white noise.")
+ else
+ to_chat(src, "You will no longer hear ambient white noise.")
+ to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 2))
+ feedback_add_details("admin_verb","TBuzz") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/verb/Toggle_Heartbeat() //to toggle off heartbeat sounds, in case they get too annoying
+ set name = "Hear/Silence Heartbeat"
+ set category = "Preferences"
+ set desc = "Toggles hearing heart beating sound effects"
+ prefs.sound ^= SOUND_HEARTBEAT
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_HEARTBEAT)
+ to_chat(src, "You will now hear heartbeat sounds.")
+ else
+ to_chat(src, "You will no longer hear heartbeat sounds.")
+ to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 1))
+ to_chat(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = 2))
+ feedback_add_details("admin_verb","Thb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+// This needs a toggle because you people are awful and spammed terrible music
+/client/verb/toggle_instruments()
+ set name = "Hear/Silence Instruments"
+ set category = "Preferences"
+ set desc = "Toggles hearing musical instruments like the violin and piano"
+ prefs.toggles ^= SOUND_INSTRUMENTS
+ prefs.save_preferences(src)
+ if(prefs.toggles & SOUND_INSTRUMENTS)
+ to_chat(src, "You will now hear people playing musical instruments.")
+ else
+ to_chat(src, "You will no longer hear musical instruments.")
+ feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/toggle_media()
+ set name = "Hear/Silence Streaming"
+ set category = "Preferences"
+ set desc = "Toggle hearing streaming media (radios, jukeboxes, etc)"
+
+ prefs.sound ^= SOUND_STREAMING
+ prefs.save_preferences(src)
+ to_chat(usr, "You will [(prefs.sound & SOUND_STREAMING) ? "now" : "no longer"] hear streamed media.")
+ if(!media) return
+ if(prefs.sound & SOUND_STREAMING)
+ media.update_music()
+ else
+ media.stop_music()
+
+/client/verb/setup_character()
+ set name = "Game Preferences"
+ set category = "Preferences"
+ set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will."
+ prefs.current_tab = 1
prefs.ShowChoices(usr)
\ No newline at end of file
diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm
index 78d9428d4b2..6a27ec3ba8b 100644
--- a/code/modules/clothing/under/jobs/civilian.dm
+++ b/code/modules/clothing/under/jobs/civilian.dm
@@ -24,6 +24,13 @@
item_color = "qm"
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/cargo/skirt
+ name = "quartermaster's jumpskirt"
+ desc = "It's a jumpskirt worn by the quartermaster. It's specially designed to prevent back injuries caused by pushing paper."
+ icon_state = "qmf"
+ item_color = "qmf"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
/obj/item/clothing/under/rank/cargotech
name = "cargo technician's jumpsuit"
@@ -33,6 +40,12 @@
item_color = "cargo"
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/cargotech/skirt
+ name = "cargo technician's jumpskirt"
+ desc = "Skirrrrrts! They're comfy and easy to wear!"
+ icon_state = "cargof"
+ item_color = "cargof"
+ flags = null
/obj/item/clothing/under/rank/chaplain
desc = "It's a black jumpsuit, often worn by religious folk."
diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm
index 4b91e82b2fc..d22c5160c27 100644
--- a/code/modules/clothing/under/jobs/engineering.dm
+++ b/code/modules/clothing/under/jobs/engineering.dm
@@ -8,6 +8,14 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 10)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/chief_engineer/skirt
+ desc = "It's a high visibility jumpskirt given to those engineers insane enough to achieve the rank of \"Chief engineer\". It has minor radiation shielding."
+ name = "chief engineer's jumpskirt"
+ icon_state = "chieff"
+ item_color = "chieff"
+ flags = null
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
/obj/item/clothing/under/rank/atmospheric_technician
desc = "It's a jumpsuit worn by atmospheric technicians."
name = "atmospheric technician's jumpsuit"
@@ -16,6 +24,14 @@
item_color = "atmos"
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/atmospheric_technician/skirt
+ desc = "It's a jumpskirt worn by atmospheric technicians."
+ name = "atmospheric technician's jumpskirt"
+ icon_state = "atmosf"
+ item_color = "atmosf"
+ flags = null
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
/obj/item/clothing/under/rank/engineer
desc = "It's an orange high visibility jumpsuit worn by engineers. It has minor radiation shielding."
name = "engineer's jumpsuit"
@@ -25,6 +41,15 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 10)
flags = ONESIZEFITSALL
+
+/obj/item/clothing/under/rank/engineer/skirt
+ desc = "It's an orange high visibility jumpskirt worn by engineers. It has minor radiation shielding."
+ name = "engineer's jumpskirt"
+ icon_state = "enginef"
+ item_color = "enginef"
+ flags = null
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
/obj/item/clothing/under/rank/roboticist
desc = "It's a slimming black with reinforced seams; great for industrial work."
name = "roboticist's jumpsuit"
@@ -33,6 +58,13 @@
item_color = "robotics"
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/roboticist/skirt
+ desc = "It's a slimming black jumpskirt with reinforced seams; great for industrial work."
+ name = "roboticist's jumpskirt"
+ icon_state = "roboticsf"
+ item_color = "roboticsf"
+ flags = null
+
/obj/item/clothing/under/rank/mechanic
desc = "It's a pair of overalls worn by mechanics."
name = "mechanic's overalls"
diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm
index b6f83e78beb..92e875da72b 100644
--- a/code/modules/clothing/under/jobs/medsci.dm
+++ b/code/modules/clothing/under/jobs/medsci.dm
@@ -20,6 +20,13 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/scientist/skirt
+ name = "scientist's jumpskirt"
+ icon_state = "sciencewhitef"
+ item_color = "sciencewhitef"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/obj/item/clothing/under/rank/chemist
desc = "It's made of a special fiber that gives special protection against biohazards. It has a chemist rank stripe on it."
name = "chemist's jumpsuit"
@@ -30,6 +37,13 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/chemist/skirt
+ name = "chemist's jumpskirt"
+ icon_state = "chemistrywhitef"
+ item_color = "chemistrywhitef"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/*
* Medical
*/
@@ -43,6 +57,14 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/chief_medical_officer/skirt
+ desc = "It's a jumpskirt worn by those with the experience to be \"Chief Medical Officer\". It provides minor biological protection."
+ name = "chief medical officer's jumpskirt"
+ icon_state = "cmof"
+ item_color = "cmof"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/obj/item/clothing/under/rank/geneticist
desc = "It's made of a special fiber that gives special protection against biohazards. It has a genetics rank stripe on it."
name = "geneticist's jumpsuit"
@@ -53,6 +75,13 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/geneticist/skirt
+ name = "geneticist's jumpskirt"
+ icon_state = "geneticswhitef"
+ item_color = "geneticswhitef"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/obj/item/clothing/under/rank/virologist
desc = "It's made of a special fiber that gives special protection against biohazards. It has a virologist rank stripe on it."
name = "virologist's jumpsuit"
@@ -63,6 +92,13 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/virologist/skirt
+ name = "virologist's jumpskirt"
+ icon_state = "virologywhitef"
+ item_color = "virologywhitef"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/obj/item/clothing/under/rank/nursesuit
desc = "It's a jumpsuit commonly worn by nursing staff in the medical department."
name = "nurse's suit"
@@ -103,6 +139,13 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = ONESIZEFITSALL
+/obj/item/clothing/under/rank/medical/skirt
+ name = "medical doctor's jumpskirt"
+ icon_state = "medicalf"
+ item_color = "medicalf"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+ flags = null
+
/obj/item/clothing/under/rank/medical/blue
name = "medical scrubs"
desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue."
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index d40952e2030..8d7871039d2 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -19,6 +19,14 @@
flags = ONESIZEFITSALL
strip_delay = 50
+/obj/item/clothing/under/rank/warden/skirt
+ desc = "Standard feminine fashion for a Warden. It is made of sturdier material than standard jumpskirts. It has the word \"Warden\" written on the shoulders."
+ name = "warden's jumpskirt"
+ icon_state = "wardenf"
+ item_state = "r_suit"
+ item_color = "wardenf"
+ flags = null
+
/obj/item/clothing/under/rank/security
name = "security officer's jumpsuit"
desc = "It's made of a slightly sturdier material than standard jumpsuits, to allow for robust protection."
@@ -29,6 +37,14 @@
flags = ONESIZEFITSALL
strip_delay = 50
+/obj/item/clothing/under/rank/security/skirt
+ name = "security officer's jumpskirt"
+ desc = "Standard feminine fashion for Security Officers. It's made of sturdier material than the standard jumpskirts."
+ icon_state = "secredf"
+ item_state = "r_suit"
+ item_color = "secredf"
+ flags = null
+
/obj/item/clothing/under/rank/dispatch
name = "dispatcher's uniform"
desc = "A dress shirt and khakis with a security patch sewn on."
@@ -86,6 +102,14 @@
flags = ONESIZEFITSALL
strip_delay = 60
+/obj/item/clothing/under/rank/head_of_security/skirt
+ desc = "It's a fashionable jumpskirt worn by those few with the dedication to achieve the position of \"Head of Security\". It has additional armor to protect the wearer."
+ name = "head of security's jumpskirt"
+ icon_state = "hosredf"
+ item_state = "r_suit"
+ item_color = "hosredf"
+ flags = null
+
/obj/item/clothing/under/rank/head_of_security/corp
icon_state = "hos_corporate"
item_state = "hos_corporate"
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 07455bdf920..09203887784 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 05ccd754f9d..8aacc4a4178 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 0adb0c5b5b4..4c94b33990b 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1112,10 +1112,15 @@
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\message.dm"
-#include "code\modules\client\preferences.dm"
-#include "code\modules\client\preferences_mysql.dm"
-#include "code\modules\client\preferences_spawnpoints.dm"
-#include "code\modules\client\preferences_toggles.dm"
+#include "code\modules\client\preference\preferences.dm"
+#include "code\modules\client\preference\preferences_mysql.dm"
+#include "code\modules\client\preference\preferences_spawnpoints.dm"
+#include "code\modules\client\preference\preferences_toggles.dm"
+#include "code\modules\client\preference\loadout\loadout.dm"
+#include "code\modules\client\preference\loadout\loadout_accessories.dm"
+#include "code\modules\client\preference\loadout\loadout_cosmetics.dm"
+#include "code\modules\client\preference\loadout\loadout_general.dm"
+#include "code\modules\client\preference\loadout\loadout_uniform.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\glasses\glasses.dm"
#include "code\modules\clothing\glasses\hud.dm"