mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-23 00:22:12 +00:00
This is it. The big one. Risk: Very large. This modifies or rewrites several important systems. Some things still need balancing, but that's probably better done if/when this hits dev. changes: New smooth lighting system. Machinery split into three processes: machinery, powernet, pipenet Removed due to breakage. Refactored into multi-step process. Mob process rewritten. NanoUI process rewritten. Objects process rewritten. Tweaked color output of station lights. Slime core lights now emit colored light. Fixed light update frequency issue with fire alarms, hydroponics trays, and airlocks. Increased light emission from bolted airlocks. Miscellaneous performance improvements. New datum pool implementation. New lighting usage profiler. Lighting system now tracks UV light, which is not visible to players. Space now has a parallax effect. Disabled Spin View verbs due to incompatibility with the new lighting system. Disabled hallucination view spin due to incompatibility with the new lighting system. Lighting system now initializes in the lobby before the round starts to reduce BoR deadtime. Added UV light tracking to lighting engine; dionae now gain energy exclusively from UV light. Added colored lighting to a few consoles that used default (white) light.
574 lines
17 KiB
Plaintext
574 lines
17 KiB
Plaintext
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
|
|
|
var/list/preferences_datums = list()
|
|
|
|
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/current_character = 0 //SQL character ID.
|
|
var/savefile_version = 0
|
|
|
|
//non-preference stuff
|
|
var/warns = 0
|
|
var/muted = 0
|
|
var/last_ip
|
|
var/last_id
|
|
var/list/notifications = list() //A list of datums, for the dynamic server greeting window.
|
|
var/list/time_of_death = list()//This is a list of last times of death for various things with different respawn timers
|
|
|
|
//game-preferences
|
|
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
|
|
var/ooccolor = "#010000" //Whatever this is set to acts as 'reset' color and is thus unusable as an actual custom color
|
|
var/list/be_special_role = list() //Special role selection
|
|
var/UI_style = "Midnight"
|
|
var/toggles = TOGGLES_DEFAULT
|
|
var/asfx_togs = ASFX_DEFAULT
|
|
var/UI_style_color = "#ffffff"
|
|
var/UI_style_alpha = 255
|
|
var/motd_hash = "" //Hashes for the new server greeting window.
|
|
var/memo_hash = ""
|
|
|
|
//character preferences
|
|
var/real_name //our character's name
|
|
var/can_edit_name = 1 //Whether or not a character's name can be edited. Used with SQL saving.
|
|
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 //underwear type
|
|
var/undershirt //undershirt type
|
|
var/socks //socks type
|
|
var/backbag = 2 //backpack type
|
|
var/h_style = "Bald" //Hair type
|
|
var/hair_colour = "#000000" //Hair colour hex value, for SQL loading
|
|
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/facial_colour = "#000000" //Facial colour hex value, for SQL loading
|
|
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/skin_colour = "#000000" //Skin colour hex value, for SQL loading
|
|
var/r_skin = 0 //Skin color
|
|
var/g_skin = 0 //Skin color
|
|
var/b_skin = 0 //Skin color
|
|
var/eyes_colour = "#000000" //Eye colour hex value, for SQL loading
|
|
var/r_eyes = 0 //Eye color
|
|
var/g_eyes = 0 //Eye color
|
|
var/b_eyes = 0 //Eye color
|
|
var/species = "Human" //Species datum to use.
|
|
var/species_preview //Used for the species selection window.
|
|
var/list/alternate_languages = list() //Secondary language(s)
|
|
var/list/language_prefixes = list() //Kanguage prefix keys
|
|
var/list/gear //Custom/fluff item loadout.
|
|
|
|
//Some faction information.
|
|
var/home_system = "Unset" //System of birth.
|
|
var/citizenship = "None" //Current home system.
|
|
var/faction = "None" //Antag faction/general associated faction.
|
|
var/religion = "None" //Religious association.
|
|
|
|
//Mob preview
|
|
var/icon/preview_icon = null
|
|
var/icon/preview_icon_front = null
|
|
var/icon/preview_icon_side = null
|
|
var/is_updating_icon = 0
|
|
|
|
//Jobs, uses bitflags
|
|
var/job_civilian_high = 0
|
|
var/job_civilian_med = 0
|
|
var/job_civilian_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
|
|
|
|
// A text blob which temporarily houses data from the SQL.
|
|
var/unsanitized_jobs = ""
|
|
|
|
//Keeps track of preferrence for not getting any wanted jobs
|
|
var/alternate_option = 0
|
|
|
|
var/used_skillpoints = 0
|
|
var/skill_specialization = null
|
|
var/list/skills = list() // skills can range from 0 to 3
|
|
|
|
// 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/list/flavor_texts = list()
|
|
var/list/flavour_texts_robot = list()
|
|
|
|
var/med_record = ""
|
|
var/sec_record = ""
|
|
var/list/incidents = list()
|
|
var/gen_record = ""
|
|
var/exploit_record = ""
|
|
var/ccia_record = ""
|
|
var/list/ccia_actions = list()
|
|
var/disabilities = 0
|
|
|
|
var/nanotrasen_relation = "Neutral"
|
|
|
|
var/uplinklocation = "PDA"
|
|
|
|
// OOC Metadata:
|
|
var/metadata = ""
|
|
|
|
// SPAAAACE
|
|
var/parallax_speed = 2
|
|
var/parallax_togs = PARALLAX_SPACE
|
|
|
|
var/list/pai = list() // A list for holding pAI related data.
|
|
|
|
var/client/client = null
|
|
|
|
var/savefile/loaded_preferences
|
|
var/savefile/loaded_character
|
|
var/datum/category_collection/player_setup_collection/player_setup
|
|
|
|
/datum/preferences/New(client/C)
|
|
new_setup()
|
|
|
|
if(istype(C))
|
|
client = C
|
|
if(!IsGuestKey(C.key))
|
|
load_path(C.ckey)
|
|
load_preferences()
|
|
load_and_update_character()
|
|
|
|
/datum/preferences/proc/load_and_update_character(var/slot)
|
|
load_character(slot)
|
|
if(update_setup(loaded_preferences, loaded_character))
|
|
save_preferences()
|
|
save_character()
|
|
|
|
/datum/preferences/proc/getMinAge()
|
|
var/datum/species/mob_species = all_species[species]
|
|
return mob_species.age_min
|
|
|
|
/datum/preferences/proc/getMaxAge()
|
|
var/datum/species/mob_species = all_species[species]
|
|
return mob_species.age_max
|
|
|
|
/datum/preferences/proc/ZeroSkills(var/forced = 0)
|
|
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
|
|
if(!skills.Find(S.ID) || forced)
|
|
skills[S.ID] = SKILL_NONE
|
|
|
|
/datum/preferences/proc/CalculateSkillPoints()
|
|
used_skillpoints = 0
|
|
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
|
|
var/multiplier = 1
|
|
switch(skills[S.ID])
|
|
if(SKILL_NONE)
|
|
used_skillpoints += 0 * multiplier
|
|
if(SKILL_BASIC)
|
|
used_skillpoints += 1 * multiplier
|
|
if(SKILL_ADEPT)
|
|
// secondary skills cost less
|
|
if(S.secondary)
|
|
used_skillpoints += 1 * multiplier
|
|
else
|
|
used_skillpoints += 3 * multiplier
|
|
if(SKILL_EXPERT)
|
|
// secondary skills cost less
|
|
if(S.secondary)
|
|
used_skillpoints += 3 * multiplier
|
|
else
|
|
used_skillpoints += 6 * multiplier
|
|
|
|
/datum/preferences/proc/GetSkillClass(points)
|
|
return CalculateSkillClass(points, age)
|
|
|
|
/proc/CalculateSkillClass(points, age)
|
|
if(points <= 0) return "Unconfigured"
|
|
// skill classes describe how your character compares in total points
|
|
points -= min(round((age - 20) / 2.5), 4) // every 2.5 years after 20, one extra skillpoint
|
|
if(age > 30)
|
|
points -= round((age - 30) / 5) // every 5 years after 30, one extra skillpoint
|
|
switch(points)
|
|
if(-1000 to 3)
|
|
return "Terrifying"
|
|
if(4 to 6)
|
|
return "Below Average"
|
|
if(7 to 10)
|
|
return "Average"
|
|
if(11 to 14)
|
|
return "Above Average"
|
|
if(15 to 18)
|
|
return "Exceptional"
|
|
if(19 to 24)
|
|
return "Genius"
|
|
if(24 to 1000)
|
|
return "God"
|
|
|
|
/datum/preferences/proc/ShowChoices(mob/user)
|
|
if(!user || !user.client) return
|
|
var/dat = "<html><body><center>"
|
|
|
|
if(path)
|
|
dat += "<a href='?src=\ref[src];load=1'>Load slot</a> - "
|
|
dat += "<a href='?src=\ref[src];save=1'>Save slot</a> - "
|
|
dat += "<a href='?src=\ref[src];reload=1'>Reload slot</a>"
|
|
if (config.sql_saves)
|
|
dat += " - <a href='?src=\ref[src];delete=1'>Delete slot</a>"
|
|
|
|
else
|
|
dat += "Please create an account to save your preferences."
|
|
|
|
dat += "<br>"
|
|
dat += player_setup.header()
|
|
dat += "<br><HR></center>"
|
|
dat += player_setup.content(user)
|
|
|
|
dat += "</html></body>"
|
|
user << browse(dat, "window=preferences;size=625x736")
|
|
|
|
/datum/preferences/proc/process_link(mob/user, list/href_list)
|
|
if(!user) return
|
|
|
|
if(!istype(user, /mob/new_player)) return
|
|
|
|
if(href_list["preference"] == "open_whitelist_forum")
|
|
if(config.forumurl)
|
|
user << link(config.forumurl)
|
|
else
|
|
user << "<span class='danger'>The forum URL is not set in the server configuration.</span>"
|
|
return
|
|
ShowChoices(usr)
|
|
return 1
|
|
|
|
/datum/preferences/Topic(href, list/href_list)
|
|
if(..())
|
|
return 1
|
|
|
|
if(href_list["save"])
|
|
save_character()
|
|
save_preferences()
|
|
else if(href_list["reload"])
|
|
load_preferences()
|
|
load_character()
|
|
else if(href_list["load"])
|
|
if(!IsGuestKey(usr.key))
|
|
if (config.sql_saves)
|
|
open_load_dialog_sql(usr)
|
|
else
|
|
open_load_dialog_file(usr)
|
|
return 1
|
|
else if(href_list["changeslot"])
|
|
load_character(text2num(href_list["changeslot"]))
|
|
close_load_dialog(usr)
|
|
else if(href_list["new_character_sql"])
|
|
new_setup(1)
|
|
usr << "<span class='notice'>Your setup has been refreshed.</span>"
|
|
close_load_dialog(usr)
|
|
else if(href_list["close_load_dialog"])
|
|
close_load_dialog(usr)
|
|
else if(href_list["delete"])
|
|
if (!config.sql_saves)
|
|
return 0
|
|
if (alert(usr, "This will permanently delete the character you have loaded. Are you sure?", "Delete Character", "No", "Yes") == "Yes")
|
|
delete_character_sql(usr.client)
|
|
else
|
|
return 0
|
|
|
|
ShowChoices(usr)
|
|
return 1
|
|
|
|
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, safety = 0)
|
|
// Sanitizing rather than saving as someone might still be editing when copy_to occurs.
|
|
player_setup.sanitize_setup()
|
|
|
|
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.real_name = real_name
|
|
character.name = character.real_name
|
|
if(character.dna)
|
|
character.dna.real_name = character.real_name
|
|
|
|
character.flavor_texts["general"] = flavor_texts["general"]
|
|
character.flavor_texts["head"] = flavor_texts["head"]
|
|
character.flavor_texts["face"] = flavor_texts["face"]
|
|
character.flavor_texts["eyes"] = flavor_texts["eyes"]
|
|
character.flavor_texts["torso"] = flavor_texts["torso"]
|
|
character.flavor_texts["arms"] = flavor_texts["arms"]
|
|
character.flavor_texts["hands"] = flavor_texts["hands"]
|
|
character.flavor_texts["legs"] = flavor_texts["legs"]
|
|
character.flavor_texts["feet"] = flavor_texts["feet"]
|
|
character.character_id = current_character
|
|
|
|
character.med_record = med_record
|
|
character.sec_record = sec_record
|
|
character.incidents = incidents
|
|
character.gen_record = gen_record
|
|
character.ccia_record = ccia_record
|
|
character.ccia_actions = ccia_actions
|
|
character.exploit_record = exploit_record
|
|
|
|
character.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
|
|
|
|
character.home_system = home_system
|
|
character.citizenship = citizenship
|
|
character.personal_faction = faction
|
|
character.religion = religion
|
|
|
|
character.skills = skills
|
|
character.used_skillpoints = used_skillpoints
|
|
|
|
// 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)
|
|
O.status = 0
|
|
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/I = character.internal_organs_by_name[name]
|
|
if(I)
|
|
if(status == "assisted")
|
|
I.mechassist()
|
|
else if(status == "mechanical")
|
|
I.robotize()
|
|
|
|
character.underwear = underwear
|
|
|
|
character.undershirt = undershirt
|
|
|
|
character.socks = socks
|
|
|
|
if(backbag > 5 || 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("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.")
|
|
character.gender = MALE
|
|
|
|
/datum/preferences/proc/open_load_dialog_sql(mob/user)
|
|
var/dat = "<body>"
|
|
dat += "<tt><center>"
|
|
|
|
for(var/ckey in preferences_datums)
|
|
var/datum/preferences/D = preferences_datums[ckey]
|
|
if(D == src)
|
|
establish_db_connection(dbcon)
|
|
if(!dbcon.IsConnected())
|
|
return open_load_dialog_file(user)
|
|
|
|
var/DBQuery/query = dbcon.NewQuery("SELECT id, name FROM ss13_characters WHERE ckey = :ckey AND deleted_at IS NULL ORDER BY id ASC")
|
|
query.Execute(list(":ckey" = user.client.ckey))
|
|
|
|
dat += "<b>Select a character slot to load</b><hr>"
|
|
var/name
|
|
var/id
|
|
|
|
while (query.NextRow())
|
|
id = text2num(query.item[1])
|
|
name = query.item[2]
|
|
if (id == current_character)
|
|
dat += "<b><a href='?src=\ref[src];changeslot=[id];'>[name]</a></b><br>"
|
|
else
|
|
dat += "<a href='?src=\ref[src];changeslot=[id];'>[name]</a><br>"
|
|
|
|
dat += "<hr>"
|
|
dat += "<b>[query.RowCount()]/[config.character_slots] slots used</b><br>"
|
|
if (query.RowCount() < config.character_slots)
|
|
dat += "<a href='?src=\ref[src];new_character_sql=1'>New Character</a>"
|
|
else
|
|
dat += "<strike>New Character</strike>"
|
|
|
|
dat += "<hr>"
|
|
dat += "<a href='?src=\ref[src];close_load_dialog=1'>Close</a><br>"
|
|
dat += "</center></tt>"
|
|
user << browse(dat, "window=saves;size=300x390")
|
|
|
|
|
|
/datum/preferences/proc/open_load_dialog_file(mob/user)
|
|
var/dat = "<body>"
|
|
dat += "<tt><center>"
|
|
|
|
var/savefile/S = new /savefile(path)
|
|
if(S)
|
|
dat += "<b>Select a character slot to load</b><hr>"
|
|
var/name
|
|
for(var/i=1, i<= config.character_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
if(!name) name = "Character[i]"
|
|
if(i==default_slot)
|
|
name = "<b>[name]</b>"
|
|
dat += "<a href='?src=\ref[src];changeslot=[i]'>[name]</a><br>"
|
|
|
|
dat += "<hr>"
|
|
dat += "</center></tt>"
|
|
user << browse(dat, "window=saves;size=300x390")
|
|
|
|
/datum/preferences/proc/close_load_dialog(mob/user)
|
|
user << browse(null, "window=saves")
|
|
|
|
// Logs a character to the database. For statistics.
|
|
/datum/preferences/proc/log_character(var/mob/living/carbon/human/H)
|
|
if (!config.sql_saves || !config.sql_stats || !establish_db_connection(dbcon) || !H)
|
|
return
|
|
|
|
var/DBQuery/query = dbcon.NewQuery("INSERT INTO ss13_characters_log (char_id, game_id, datetime, job_name, special_role) VALUES (:char_id, :game_id, NOW(), :job, :special_role)")
|
|
query.Execute(list(":char_id" = current_character, ":game_id" = game_id, ":job" = H.mind.assigned_role, ":special_role" = H.mind.special_role))
|
|
|
|
// Turned into a proc so we could reuse it for SQL shenanigans.
|
|
/datum/preferences/proc/new_setup(var/re_initialize = 0)
|
|
if (player_setup)
|
|
qdel(player_setup)
|
|
player_setup = null
|
|
|
|
player_setup = new(src)
|
|
gender = pick(MALE, FEMALE)
|
|
real_name = random_name(gender,species)
|
|
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
|
|
|
|
current_character = 0
|
|
can_edit_name = 1
|
|
|
|
gear = list()
|
|
|
|
//Reset the records when making a new char
|
|
med_record = ""
|
|
sec_record = ""
|
|
incidents = list()
|
|
gen_record = ""
|
|
exploit_record = ""
|
|
ccia_record = ""
|
|
|
|
ZeroSkills(1)
|
|
|
|
// Do we need to reinitialize a whole bunch more vars?
|
|
if (re_initialize)
|
|
be_special_role = list()
|
|
uplinklocation = initial(uplinklocation)
|
|
|
|
r_hair = 0
|
|
g_hair = 0
|
|
b_hair = 0
|
|
r_facial = 0
|
|
g_facial = 0
|
|
b_facial = 0
|
|
r_skin = 0
|
|
g_skin = 0
|
|
b_skin = 0
|
|
r_eyes = 0
|
|
g_eyes = 0
|
|
b_eyes = 0
|
|
|
|
species = "Human"
|
|
home_system = "Unset"
|
|
citizenship = "None"
|
|
faction = "None"
|
|
religion = "None"
|
|
|
|
species = "Human"
|
|
|
|
job_civilian_high = 0
|
|
job_civilian_med = 0
|
|
job_civilian_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
|
|
|
|
alternate_option = 0
|
|
metadata = ""
|
|
|
|
organ_data = list()
|
|
rlimb_data = list()
|
|
player_alt_titles = new()
|
|
|
|
flavor_texts = list()
|
|
flavour_texts_robot = list()
|
|
|
|
ccia_actions = list()
|
|
disabilities = 0
|
|
|
|
nanotrasen_relation = "Neutral"
|
|
|
|
update_preview_icon()
|
|
|
|
// Deletes a character from the database
|
|
/datum/preferences/proc/delete_character_sql(var/client/C)
|
|
if (!C)
|
|
return
|
|
|
|
if (!current_character)
|
|
C << "<span class='notice'>You do not have a character loaded.</span>"
|
|
return
|
|
|
|
if (!establish_db_connection(dbcon))
|
|
C << "<span class='notice'>Unable to establish database connection.</span>"
|
|
return
|
|
|
|
var/DBQuery/query = dbcon.NewQuery("UPDATE ss13_characters SET deleted_at = NOW() WHERE id = :char_id")
|
|
query.Execute(list(":char_id" = current_character))
|
|
|
|
// Create a new character.
|
|
new_setup(1)
|
|
|
|
C << "<span class='warning'>Character successfully deleted! Please make a new one or load an existing setup.</span>"
|