"
+ dat += "
"
if(!IsGuestKey(user.key))
- dat += "Undo - "
- dat += "Save Setup - "
+ dat += "Undo - "
+ dat += "Save Setup - "
- dat += "Reset Setup"
+ dat += "Reset Setup"
dat += ""
- user << browse(dat, "window=preferences;size=550x545")
+ user << browse(dat, "window=preferences;size=560x560")
proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), width = 550, height = 500)
//limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
@@ -256,7 +240,7 @@ datum/preferences
var/HTML = ""
HTML += ""
HTML += "Choose occupation chances Unavailable occupations are in red.
"
- HTML += "\[Done\]
" // Easier to press up here.
+ HTML += "\[Done\]
" // Easier to press up here.
HTML += "" // Table within a table for alignment, also allows you to easily add more colomns.
HTML += ""
- HTML += " Get random job if preferences unavailable" : "red>Be assistant if preference unavailable"]"
+ HTML += " Get random job if preferences unavailable" : "red>Be assistant if preference unavailable"]"
HTML += ""
@@ -435,6 +419,7 @@ datum/preferences
proc/process_link(mob/user, list/href_list)
if(!user) return
+ if(!istype(user, /mob/new_player)) return
if(href_list["preference"] == "job")
switch(href_list["task"])
@@ -459,8 +444,8 @@ datum/preferences
if("age")
age = rand(17, 85)
- if("b_type")
- b_type = pick( 31;"A+", 7;"A-", 8;"B+", 2;"B-", 2;"AB+", 1;"AB-", 40;"O+", 9;"O-" )
+// if("b_type")
+// b_type = pick( 31;"A+", 7;"A-", 8;"B+", 2;"B-", 2;"AB+", 1;"AB-", 40;"O+", 9;"O-" )
if("hair")
randomize_hair_color("hair")
@@ -498,8 +483,6 @@ datum/preferences
randomize_facial(gender)
randomize_eyes_color()
randomize_skin_tone()
- b_type = pick( 31;"A+", 7;"A-", 8;"B+", 2;"B-", 2;"AB+", 1;"AB-", 40;"O+", 9;"O-" )
-
job_civilian_high = 0
job_civilian_med = 0
job_civilian_low = 0
@@ -535,10 +518,10 @@ datum/preferences
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("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")
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
@@ -597,12 +580,6 @@ datum/preferences
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("slotname")
- var/new_slotname = input(user, "Please name this savefile:", "Save Slot Name") as text|null
- if(ckey(new_slotname))//Checks to make sure there is one letter
- slot_name = strip_html_simple(new_slotname,16)
-
else
switch(href_list["preference"])
if("gender")
@@ -647,21 +624,15 @@ datum/preferences
ghost_sight = !ghost_sight
if("save")
- if(!IsGuestKey(user.key))
- savefile_save(user)
+ save_preferences()
+ save_character()
if("load")
- if(!IsGuestKey(user.key))
- savefile_load(user)
+ load_preferences()
+ load_character()
if("changeslot")
- savefile_save(user)
- user.client.activeslot = min(max(text2num(href_list["num"]), 1), MAX_SAVE_SLOTS)
- savefile_load(user)
-
- if("defaultslot")
- default_slot = min(max(text2num(href_list["num"]), 1), MAX_SAVE_SLOTS)
- savefile_saveslot(user,default_slot)//Mirrors choice across all saves
+ load_character(text2num(href_list["num"]))
ShowChoices(user)
return 1
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 32499c47b9..c6e3c68761 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -14,7 +14,6 @@ datum/preferences
randomize_eyes_color()
underwear = 1
backbag = 2
- b_type = pick("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-")
age = rand(19,35)
copy_to(H,1)
diff --git a/code/modules/mob/new_player/savefile.dm b/code/modules/mob/new_player/savefile.dm
index 63defe03ba..7aae01a20a 100644
--- a/code/modules/mob/new_player/savefile.dm
+++ b/code/modules/mob/new_player/savefile.dm
@@ -1,237 +1,201 @@
#define SAVEFILE_VERSION_MIN 7
#define SAVEFILE_VERSION_MAX 7
-datum/preferences/proc/savefile_path(mob/user)
- if(!user.client)
- return null
- else
- return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/preferences[user.client.activeslot].sav"
+/datum/preferences/proc/load_path(ckey)
+ if(!ckey) return
+ path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/preferences.sav"
-datum/preferences/proc/savefile_saveslot(mob/user,var/slot)//Mirrors default slot across each save
- if(!user.client)
- return null
- else
- for(var/i = 1; i <= MAX_SAVE_SLOTS; i += 1)
- var/savefile/F = new /savefile("data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/preferences[i].sav")
- F["default_slot"] << slot
- return 1
+/datum/preferences/proc/load_preferences()
+ if(!path) return 0
+ if(!fexists(path)) return 0
-datum/preferences/proc/savefile_save(mob/user)
- if (IsGuestKey(user.key))
- return 0
+ var/savefile/S = new /savefile(path)
+ if(!S) return 0
- var/savefile/F = new /savefile(src.savefile_path(user))
-// var/version
-// F["version"] >> version
+ S["version"] >> savefile_version
- F["version"] << SAVEFILE_VERSION_MAX
+ //general preferences
+ S["ooccolor"] >> ooccolor
+ S["lastchangelog"] >> lastchangelog
+ S["UI_style"] >> UI_style
+ S["be_special"] >> be_special
+ S["default_slot"] >> default_slot
- F["real_name"] << src.real_name
- F["name_is_always_random"] << src.be_random_name
+ //to be consolidated into a bitfield
+ S["sound_adminhelp"] >> sound_adminhelp
+ S["lobby_music"] >> lobby_music
+ S["midis"] >> midis
+ S["ghost_ears"] >> ghost_ears
+ S["ghost_sight"] >> ghost_sight
- F["gender"] << src.gender
- F["age"] << src.age
+ //Conversion
+/* if(!savefile_version || savefile_version < SAVEFILE_VERSION_MIN || savefile_version > SAVEFILE_VERSION_MAX)
+ if(!savefile_update())
+ fdel(path)
+ C << "Error: savefile_load(): Your savefile was not compatible and had to be deleted."
+ return 0 */
- //Job data
- F["job_civilian_high"] << src.job_civilian_high
- F["job_civilian_med"] << src.job_civilian_med
- F["job_civilian_low"] << src.job_civilian_low
+ //Sanitize
+ ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
+ lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
+ UI_style = sanitize_inlist(UI_style, list("Midnight","Orange","old"), initial(UI_style))
+ be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
+ default_slot = sanitize_integer(default_slot, 1, MAX_SAVE_SLOTS, initial(default_slot))
- F["job_medsci_high"] << src.job_medsci_high
- F["job_medsci_med"] << src.job_medsci_med
- F["job_medsci_low"] << src.job_medsci_low
-
- F["job_engsec_high"] << src.job_engsec_high
- F["job_engsec_med"] << src.job_engsec_med
- F["job_engsec_low"] << src.job_engsec_low
-
- F["userandomjob"] << src.userandomjob
-
- //Body data
- F["hair_red"] << src.r_hair
- F["hair_green"] << src.g_hair
- F["hair_blue"] << src.b_hair
- F["facial_red"] << src.r_facial
- F["facial_green"] << src.g_facial
- F["facial_blue"] << src.b_facial
- F["skin_tone"] << src.s_tone
- F["hair_style_name"] << src.h_style
- F["facial_style_name"] << src.f_style
- F["eyes_red"] << src.r_eyes
- F["eyes_green"] << src.g_eyes
- F["eyes_blue"] << src.b_eyes
- F["blood_type"] << src.b_type
- F["underwear"] << src.underwear
- F["backbag"] << src.backbag
- F["backbag"] << src.backbag
-
-
-
- F["be_special"] << src.be_special
- //F["UI"] << src.UI
- if(isnull(UI_style))
- UI_style = "Midnight"
- F["UI_style"] << UI_style
- F["midis"] << src.midis
- F["ghost_ears"] << src.ghost_ears
- F["ghost_sight"] << src.ghost_sight
- F["ooccolor"] << src.ooccolor
- F["lastchangelog"] << src.lastchangelog
-
- F["OOC_Notes"] << src.metadata
-
- F["sound_adminhelp"] << src.sound_adminhelp
- F["default_slot"] << src.default_slot
- F["slotname"] << src.slot_name
- F["lobby_music"] << src.lobby_music
+ sound_adminhelp = sanitize_integer(sound_adminhelp, 0, 1, initial(sound_adminhelp))
+ lobby_music = sanitize_integer(lobby_music, 0, 1, initial(lobby_music))
+ midis = sanitize_integer(midis, 0, 1, initial(midis))
+ ghost_ears = sanitize_integer(ghost_ears, 0, 1, initial(ghost_ears))
+ ghost_sight = sanitize_integer(ghost_sight, 0, 1, initial(ghost_sight))
return 1
-// loads the savefile corresponding to the mob's ckey
-// if silent=true, report incompatible savefiles
-// returns 1 if loaded (or file was incompatible)
-// returns 0 if savefile did not exist
+/datum/preferences/proc/save_preferences()
+ if(!path) return 0
-datum/preferences/proc/savefile_load(mob/user)
- if(IsGuestKey(user.key)) return 0
+ var/savefile/S = new /savefile(path)
+ if(!S) return 0
- var/path = savefile_path(user)
+ //general preferences
+ S["ooccolor"] << ooccolor
+ S["lastchangelog"] << lastchangelog
+ S["UI_style"] << UI_style
+ S["be_special"] << be_special
+ S["default_slot"] << default_slot
- if(!fexists(path))
- //Is there a preference file before this was committed?
- path = "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/preferences.sav"
- if(!fexists(path))
- //No there is not
- return 0
- else
- //Yes there is. Let's rename it.
- var/savefile/oldsave = new/savefile(path)
- fcopy(oldsave, savefile_path(user))
- fdel(path) // We don't need the old file anymore
- path = savefile_path(user)
- // Did nothing break?
- if(!fexists(path))
- return 0
-
- var/savefile/F = new /savefile(path)
-
- var/version = null
- F["version"] >> version
-
- if(isnull(version) || version < SAVEFILE_VERSION_MIN || version > SAVEFILE_VERSION_MAX)
- fdel(path)
- if(version)
- alert(user, "Your savefile was incompatible with this version and was deleted.")
- return 0
-
- F["real_name"] >> src.real_name
- F["gender"] >> src.gender
- F["age"] >> src.age
-
- F["hair_red"] >> src.r_hair
- F["hair_green"] >> src.g_hair
- F["hair_blue"] >> src.b_hair
- F["facial_red"] >> src.r_facial
- F["facial_green"] >> src.g_facial
- F["facial_blue"] >> src.b_facial
- F["skin_tone"] >> src.s_tone
- F["hair_style_name"] >> src.h_style
- F["facial_style_name"] >> src.f_style
- F["eyes_red"] >> src.r_eyes
- F["eyes_green"] >> src.g_eyes
- F["eyes_blue"] >> src.b_eyes
- F["blood_type"] >> src.b_type
- F["underwear"] >> src.underwear
- if(underwear == 0) underwear = 12 //For old players who have 0 in their savefile
- F["backbag"] >> src.backbag
- if(isnull(backbag)) backbag = 2
- F["name_is_always_random"] >> src.be_random_name
- F["midis"] >> src.midis
- F["ghost_ears"] >> src.ghost_ears
- if(isnull(ghost_ears)) ghost_ears = 1 //Hotfix
- F["ghost_sight"] >> src.ghost_sight
- if(isnull(ghost_sight)) ghost_sight = 1 //Hotfix
- F["ooccolor"] >> src.ooccolor
- F["lastchangelog"] >> src.lastchangelog
- //F["UI"] >> src.UI
- F["UI_style"] >> src.UI_style
- if(isnull(UI_style))
- UI_style = "Midnight"
- F["be_special"] >> src.be_special
-
- F["job_civilian_high"] >> src.job_civilian_high
- F["job_civilian_med"] >> src.job_civilian_med
- F["job_civilian_low"] >> src.job_civilian_low
-
- F["job_medsci_high"] >> src.job_medsci_high
- F["job_medsci_med"] >> src.job_medsci_med
- F["job_medsci_low"] >> src.job_medsci_low
-
- F["job_engsec_high"] >> src.job_engsec_high
- F["job_engsec_med"] >> src.job_engsec_med
- F["job_engsec_low"] >> src.job_engsec_low
-
- F["userandomjob"] >> src.userandomjob
-
- F["OOC_Notes"] >> src.metadata
-
- F["sound_adminhelp"] >> src.sound_adminhelp
- F["default_slot"] >> src.default_slot
- if(isnull(default_slot))
- default_slot = 1
- F["slotname"] >> src.slot_name
- F["lobby_music"] >> src.lobby_music
- if(isnull(lobby_music))
- lobby_music = 1
-
- if(isnull(metadata))
- metadata = ""
-
- //NOTE: Conversion things go inside this if statement
- //When updating the save file remember to add 1 to BOTH the savefile constants
- //Also take the old conversion things that no longer apply out of this if
- if(version && version < SAVEFILE_VERSION_MAX)
- convert_hairstyles() // convert version 4 hairstyles to version 5
+ //to be consolidated into a bitfield
+ S["sound_adminhelp"] << sound_adminhelp
+ S["lobby_music"] << lobby_music
+ S["midis"] << midis
+ S["ghost_ears"] << ghost_ears
+ S["ghost_sight"] << ghost_sight
return 1
+/datum/preferences/proc/load_character(slot)
+ if(!path) return 0
+ if(!fexists(path)) return 0
+
+ var/savefile/S = new /savefile(path)
+ if(!S) return 0
+ if(!slot) slot = default_slot
+ slot = sanitize_integer(slot, 1, MAX_SAVE_SLOTS, initial(default_slot))
+ if(slot != default_slot)
+ default_slot = slot
+ S["default_slot"] << slot
+ S.cd = "/character[slot]"
+
+ //Character
+ S["OOC_Notes"] >> metadata
+ S["real_name"] >> real_name
+ S["name_is_always_random"] >> be_random_name
+ S["gender"] >> gender
+ S["age"] >> age
+ //colors to be consolidated into hex strings (requires some work with dna code)
+ S["hair_red"] >> r_hair
+ S["hair_green"] >> g_hair
+ S["hair_blue"] >> b_hair
+ S["facial_red"] >> r_facial
+ S["facial_green"] >> g_facial
+ S["facial_blue"] >> b_facial
+ S["skin_tone"] >> s_tone
+ S["hair_style_name"] >> h_style
+ S["facial_style_name"] >> f_style
+ S["eyes_red"] >> r_eyes
+ S["eyes_green"] >> g_eyes
+ S["eyes_blue"] >> b_eyes
+ S["underwear"] >> underwear
+ S["backbag"] >> backbag
+
+ //Jobs
+ S["userandomjob"] >> userandomjob
+ S["job_civilian_high"] >> job_civilian_high
+ S["job_civilian_med"] >> job_civilian_med
+ S["job_civilian_low"] >> job_civilian_low
+ S["job_medsci_high"] >> job_medsci_high
+ S["job_medsci_med"] >> job_medsci_med
+ S["job_medsci_low"] >> job_medsci_low
+ S["job_engsec_high"] >> job_engsec_high
+ S["job_engsec_med"] >> job_engsec_med
+ S["job_engsec_low"] >> job_engsec_low
+
+ //Sanitize
+ metadata = sanitize_text(metadata, initial(metadata))
+ real_name = reject_bad_name(real_name)
+ if(!real_name) randomize_name()
+ be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
+ gender = sanitize_gender(gender)
+ age = sanitize_integer(age, 17, 85, initial(age))
+ r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
+ g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
+ b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
+ r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
+ g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
+ b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
+ s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
+ h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
+ f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
+ r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
+ g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
+ b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
+ underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear))
+ backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
+
+ userandomjob = sanitize_integer(userandomjob, 0, 1, initial(userandomjob))
+ job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
+ job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
+ job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
+ job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
+ job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
+ job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
+ job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
+ job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
+ job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
+
+ return 1
+
+/datum/preferences/proc/save_character()
+ if(!path) return 0
+
+ var/savefile/S = new /savefile(path)
+ if(!S) return 0
+ S.cd = "/character[default_slot]"
+
+ //Character
+ S["OOC_Notes"] << metadata
+ S["real_name"] << real_name
+ S["name_is_always_random"] << be_random_name
+ S["gender"] << gender
+ S["age"] << age
+ S["hair_red"] << r_hair
+ S["hair_green"] << g_hair
+ S["hair_blue"] << b_hair
+ S["facial_red"] << r_facial
+ S["facial_green"] << g_facial
+ S["facial_blue"] << b_facial
+ S["skin_tone"] << s_tone
+ S["hair_style_name"] << h_style
+ S["facial_style_name"] << f_style
+ S["eyes_red"] << r_eyes
+ S["eyes_green"] << g_eyes
+ S["eyes_blue"] << b_eyes
+ S["underwear"] << underwear
+ S["backbag"] << backbag
+
+ //Jobs
+ S["userandomjob"] << userandomjob
+ S["job_civilian_high"] << job_civilian_high
+ S["job_civilian_med"] << job_civilian_med
+ S["job_civilian_low"] << job_civilian_low
+ S["job_medsci_high"] << job_medsci_high
+ S["job_medsci_med"] << job_medsci_med
+ S["job_medsci_low"] << job_medsci_low
+ S["job_engsec_high"] << job_engsec_high
+ S["job_engsec_med"] << job_engsec_med
+ S["job_engsec_low"] << job_engsec_low
+
+ return 1
+
+
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
-
-
-
-datum/preferences/proc/convert_hairstyles()
- // convert hairstyle names from old savefiles
- switch(h_style)
- if("Balding")
- h_style = "Balding Hair"
- if("Fag")
- h_style = "Flow Hair"
- if("Jensen Hair")
- h_style = "Adam Jensen Hair"
- if("Kusangi Hair")
- h_style = "Kusanagi Hair"
-
- switch(f_style)
- if("Watson")
- f_style = "Watson Mustache"
- if("Chaplin")
- f_style = "Square Mustache"
- if("Selleck")
- f_style = "Selleck Mustache"
- if("Van Dyke")
- f_style = "Van Dyke Mustache"
- if("Elvis")
- f_style = "Elvis Sideburns"
- if("Abe")
- f_style = "Abraham Lincoln Beard"
- if("Hipster")
- f_style = "Hipster Beard"
- if("Hogan")
- f_style = "Hulk Hogan Mustache"
- if("Jensen Goatee")
- f_style = "Adam Jensen Beard"
- return
-
-#undef SAVEFILE_VERSION_MIN
-#undef SAVEFILE_VERSION_MAX
diff --git a/code/setup.dm b/code/setup.dm
index 5b1c022e89..6b3c76d131 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -482,11 +482,6 @@ var/list/liftable_structures = list(\
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
-//The number of deciseconds which someone needs to be inactive to be classified as AFK:
-#define AFK_THRESHOLD 3000
-
-
-
#define SEE_INVISIBLE_MINIMUM 5
#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15
diff --git a/code/world.dm b/code/world.dm
index f3865d7aaf..e5ee3cc4ea 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -9,7 +9,7 @@
#define RECOMMENDED_VERSION 494
/world/New()
..()
-
+ changelog_hash = md5('html/changelog.html')
src.load_configuration()
if (config && config.server_name != null && config.server_suffix && world.port > 0)
@@ -172,14 +172,16 @@ Starting up. [time2text(world.timeofday, "hh:mm.ss")]
#define INACTIVITY_KICK 6000 //10 minutes in ticks (approx.)
/world/proc/KickInactiveClients()
- for(var/client/C)
- if( !C.holder && (C.inactivity >= INACTIVITY_KICK) )
- if(C.mob)
- if(!istype(C.mob, /mob/dead/))
- log_access("AFK: [key_name(C)]")
- C << "\red You have been inactive for more than 10 minutes and have been disconnected."
- del(C)
- spawn(3000) KickInactiveClients()//more or less five minutes
+ spawn(-1)
+ set background = 1
+ while(1)
+ sleep(INACTIVITY_KICK)
+ for(var/client/C in clients)
+ if(C.is_afk(INACTIVITY_KICK))
+ if(!istype(C.mob, /mob/dead))
+ log_access("AFK: [key_name(C)]")
+ C << "\red You have been inactive for more than 10 minutes and have been disconnected."
+ del(C)
#undef INACTIVITY_KICK
diff --git a/interface/skin.dmf b/interface/skin.dmf
index c151fdd185..652994957a 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1433,7 +1433,7 @@ window "rpane"
lock = none
elem "rulesb"
type = BUTTON
- pos = 289,0
+ pos = 278,0
size = 60x16
anchor1 = none
anchor2 = none
@@ -1459,9 +1459,37 @@ window "rpane"
is-checked = false
group = "rpanemode"
button-type = pushbutton
+ elem "changelog"
+ type = BUTTON
+ pos = 341,0
+ size = 67x16
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "is-checked"
+ on-size = ""
+ text = "Changelog"
+ image = ""
+ command = "Changelog"
+ is-flat = false
+ stretch = false
+ is-checked = false
+ group = "rpanemode"
+ button-type = pushbutton
elem "forumb"
type = BUTTON
- pos = 224,0
+ pos = 215,0
size = 60x16
anchor1 = none
anchor2 = none
@@ -1489,7 +1517,7 @@ window "rpane"
button-type = pushbutton
elem "wikib"
type = BUTTON
- pos = 160,0
+ pos = 152,0
size = 60x16
anchor1 = none
anchor2 = none
diff --git a/tgstation.dme b/tgstation.dme
index 5a3ebd4d8e..170912950d 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -6,228 +6,6 @@
// BEGIN_FILE_DIR
#define FILE_DIR .
-#define FILE_DIR "code"
-#define FILE_DIR "code/__HELPERS"
-#define FILE_DIR "code/ATMOSPHERICS"
-#define FILE_DIR "code/ATMOSPHERICS/components"
-#define FILE_DIR "code/ATMOSPHERICS/components/binary_devices"
-#define FILE_DIR "code/ATMOSPHERICS/components/trinary_devices"
-#define FILE_DIR "code/ATMOSPHERICS/components/unary"
-#define FILE_DIR "code/controllers"
-#define FILE_DIR "code/datums"
-#define FILE_DIR "code/datums/diseases"
-#define FILE_DIR "code/datums/diseases/advance"
-#define FILE_DIR "code/datums/diseases/advance/symptoms"
-#define FILE_DIR "code/datums/helper_datums"
-#define FILE_DIR "code/datums/organs"
-#define FILE_DIR "code/datums/spells"
-#define FILE_DIR "code/defines"
-#define FILE_DIR "code/defines/obj"
-#define FILE_DIR "code/defines/procs"
-#define FILE_DIR "code/FEA"
-#define FILE_DIR "code/game"
-#define FILE_DIR "code/game/area"
-#define FILE_DIR "code/game/gamemodes"
-#define FILE_DIR "code/game/gamemodes/blob"
-#define FILE_DIR "code/game/gamemodes/blob/blobs"
-#define FILE_DIR "code/game/gamemodes/changeling"
-#define FILE_DIR "code/game/gamemodes/cult"
-#define FILE_DIR "code/game/gamemodes/events"
-#define FILE_DIR "code/game/gamemodes/events/holidays"
-#define FILE_DIR "code/game/gamemodes/extended"
-#define FILE_DIR "code/game/gamemodes/malfunction"
-#define FILE_DIR "code/game/gamemodes/meteor"
-#define FILE_DIR "code/game/gamemodes/nuclear"
-#define FILE_DIR "code/game/gamemodes/revolution"
-#define FILE_DIR "code/game/gamemodes/sandbox"
-#define FILE_DIR "code/game/gamemodes/traitor"
-#define FILE_DIR "code/game/gamemodes/wizard"
-#define FILE_DIR "code/game/jobs"
-#define FILE_DIR "code/game/jobs/job"
-#define FILE_DIR "code/game/machinery"
-#define FILE_DIR "code/game/machinery/atmoalter"
-#define FILE_DIR "code/game/machinery/bots"
-#define FILE_DIR "code/game/machinery/camera"
-#define FILE_DIR "code/game/machinery/computer"
-#define FILE_DIR "code/game/machinery/doors"
-#define FILE_DIR "code/game/machinery/embedded_controller"
-#define FILE_DIR "code/game/machinery/kitchen"
-#define FILE_DIR "code/game/machinery/pipe"
-#define FILE_DIR "code/game/machinery/telecomms"
-#define FILE_DIR "code/game/mecha"
-#define FILE_DIR "code/game/mecha/combat"
-#define FILE_DIR "code/game/mecha/equipment"
-#define FILE_DIR "code/game/mecha/equipment/tools"
-#define FILE_DIR "code/game/mecha/equipment/weapons"
-#define FILE_DIR "code/game/mecha/medical"
-#define FILE_DIR "code/game/mecha/working"
-#define FILE_DIR "code/game/objects"
-#define FILE_DIR "code/game/objects/effects"
-#define FILE_DIR "code/game/objects/effects/decals"
-#define FILE_DIR "code/game/objects/effects/decals/Cleanable"
-#define FILE_DIR "code/game/objects/effects/spawners"
-#define FILE_DIR "code/game/objects/items"
-#define FILE_DIR "code/game/objects/items/devices"
-#define FILE_DIR "code/game/objects/items/devices/PDA"
-#define FILE_DIR "code/game/objects/items/devices/radio"
-#define FILE_DIR "code/game/objects/items/robot"
-#define FILE_DIR "code/game/objects/items/stacks"
-#define FILE_DIR "code/game/objects/items/stacks/sheets"
-#define FILE_DIR "code/game/objects/items/stacks/tiles"
-#define FILE_DIR "code/game/objects/items/weapons"
-#define FILE_DIR "code/game/objects/items/weapons/grenades"
-#define FILE_DIR "code/game/objects/items/weapons/implants"
-#define FILE_DIR "code/game/objects/items/weapons/secstorage"
-#define FILE_DIR "code/game/objects/items/weapons/storage"
-#define FILE_DIR "code/game/objects/items/weapons/tanks"
-#define FILE_DIR "code/game/objects/structures"
-#define FILE_DIR "code/game/objects/structures/crates_lockers"
-#define FILE_DIR "code/game/objects/structures/crates_lockers/closets"
-#define FILE_DIR "code/game/objects/structures/crates_lockers/closets/secure"
-#define FILE_DIR "code/game/objects/structures/stool_bed_chair_nest"
-#define FILE_DIR "code/game/turfs"
-#define FILE_DIR "code/game/turfs/simulated"
-#define FILE_DIR "code/game/turfs/space"
-#define FILE_DIR "code/game/turfs/unsimulated"
-#define FILE_DIR "code/game/vehicles"
-#define FILE_DIR "code/game/vehicles/airtight"
-#define FILE_DIR "code/game/verbs"
-#define FILE_DIR "code/js"
-#define FILE_DIR "code/modules"
-#define FILE_DIR "code/modules/admin"
-#define FILE_DIR "code/modules/admin/DB ban"
-#define FILE_DIR "code/modules/admin/permissionverbs"
-#define FILE_DIR "code/modules/admin/verbs"
-#define FILE_DIR "code/modules/assembly"
-#define FILE_DIR "code/modules/awaymissions"
-#define FILE_DIR "code/modules/awaymissions/maploader"
-#define FILE_DIR "code/modules/client"
-#define FILE_DIR "code/modules/clothing"
-#define FILE_DIR "code/modules/clothing/glasses"
-#define FILE_DIR "code/modules/clothing/gloves"
-#define FILE_DIR "code/modules/clothing/head"
-#define FILE_DIR "code/modules/clothing/masks"
-#define FILE_DIR "code/modules/clothing/shoes"
-#define FILE_DIR "code/modules/clothing/spacesuits"
-#define FILE_DIR "code/modules/clothing/suits"
-#define FILE_DIR "code/modules/clothing/under"
-#define FILE_DIR "code/modules/clothing/under/jobs"
-#define FILE_DIR "code/modules/critters"
-#define FILE_DIR "code/modules/critters/hivebots"
-#define FILE_DIR "code/modules/detectivework"
-#define FILE_DIR "code/modules/flufftext"
-#define FILE_DIR "code/modules/food"
-#define FILE_DIR "code/modules/library"
-#define FILE_DIR "code/modules/liquid"
-#define FILE_DIR "code/modules/mining"
-#define FILE_DIR "code/modules/mob"
-#define FILE_DIR "code/modules/mob/dead"
-#define FILE_DIR "code/modules/mob/dead/observer"
-#define FILE_DIR "code/modules/mob/living"
-#define FILE_DIR "code/modules/mob/living/blob"
-#define FILE_DIR "code/modules/mob/living/carbon"
-#define FILE_DIR "code/modules/mob/living/carbon/alien"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid/caste"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/larva"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/special"
-#define FILE_DIR "code/modules/mob/living/carbon/brain"
-#define FILE_DIR "code/modules/mob/living/carbon/human"
-#define FILE_DIR "code/modules/mob/living/carbon/metroid"
-#define FILE_DIR "code/modules/mob/living/carbon/monkey"
-#define FILE_DIR "code/modules/mob/living/silicon"
-#define FILE_DIR "code/modules/mob/living/silicon/ai"
-#define FILE_DIR "code/modules/mob/living/silicon/ai/freelook"
-#define FILE_DIR "code/modules/mob/living/silicon/decoy"
-#define FILE_DIR "code/modules/mob/living/silicon/pai"
-#define FILE_DIR "code/modules/mob/living/silicon/robot"
-#define FILE_DIR "code/modules/mob/living/simple_animal"
-#define FILE_DIR "code/modules/mob/living/simple_animal/friendly"
-#define FILE_DIR "code/modules/mob/living/simple_animal/hostile"
-#define FILE_DIR "code/modules/mob/new_player"
-#define FILE_DIR "code/modules/paperwork"
-#define FILE_DIR "code/modules/power"
-#define FILE_DIR "code/modules/power/antimatter"
-#define FILE_DIR "code/modules/power/singularity"
-#define FILE_DIR "code/modules/power/singularity/particle_accelerator"
-#define FILE_DIR "code/modules/projectiles"
-#define FILE_DIR "code/modules/projectiles/ammunition"
-#define FILE_DIR "code/modules/projectiles/guns"
-#define FILE_DIR "code/modules/projectiles/guns/energy"
-#define FILE_DIR "code/modules/projectiles/guns/projectile"
-#define FILE_DIR "code/modules/projectiles/projectile"
-#define FILE_DIR "code/modules/reagents"
-#define FILE_DIR "code/modules/reagents/reagent_containers"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks/bottle"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/snacks"
-#define FILE_DIR "code/modules/reagents/reagent_containers/glass"
-#define FILE_DIR "code/modules/reagents/reagent_containers/glass/bottle"
-#define FILE_DIR "code/modules/recycling"
-#define FILE_DIR "code/modules/research"
-#define FILE_DIR "code/modules/scripting"
-#define FILE_DIR "code/modules/scripting/AST"
-#define FILE_DIR "code/modules/scripting/AST/Operators"
-#define FILE_DIR "code/modules/scripting/Implementations"
-#define FILE_DIR "code/modules/scripting/Interpreter"
-#define FILE_DIR "code/modules/scripting/Parser"
-#define FILE_DIR "code/modules/scripting/Scanner"
-#define FILE_DIR "code/modules/security levels"
-#define FILE_DIR "code/unused"
-#define FILE_DIR "code/unused/beast"
-#define FILE_DIR "code/unused/computer2"
-#define FILE_DIR "code/unused/disease2"
-#define FILE_DIR "code/unused/gamemodes"
-#define FILE_DIR "code/unused/hivebot"
-#define FILE_DIR "code/unused/mining"
-#define FILE_DIR "code/unused/optics"
-#define FILE_DIR "code/unused/pda2"
-#define FILE_DIR "code/unused/powerarmor"
-#define FILE_DIR "code/unused/spacecraft"
-#define FILE_DIR "code/WorkInProgress"
-#define FILE_DIR "code/WorkInProgress/carn"
-#define FILE_DIR "code/WorkInProgress/mapload"
-#define FILE_DIR "code/WorkInProgress/organs"
-#define FILE_DIR "code/WorkInProgress/virus2"
-#define FILE_DIR "html"
-#define FILE_DIR "icons"
-#define FILE_DIR "icons/effects"
-#define FILE_DIR "icons/mecha"
-#define FILE_DIR "icons/misc"
-#define FILE_DIR "icons/mob"
-#define FILE_DIR "icons/obj"
-#define FILE_DIR "icons/obj/assemblies"
-#define FILE_DIR "icons/obj/atmospherics"
-#define FILE_DIR "icons/obj/clothing"
-#define FILE_DIR "icons/obj/doors"
-#define FILE_DIR "icons/obj/flora"
-#define FILE_DIR "icons/obj/machines"
-#define FILE_DIR "icons/obj/pipes"
-#define FILE_DIR "icons/pda_icons"
-#define FILE_DIR "icons/spideros_icons"
-#define FILE_DIR "icons/Testing"
-#define FILE_DIR "icons/turf"
-#define FILE_DIR "icons/vehicles"
-#define FILE_DIR "icons/vending_icons"
-#define FILE_DIR "interface"
-#define FILE_DIR "maps"
-#define FILE_DIR "maps/RandomZLevels"
-#define FILE_DIR "sound"
-#define FILE_DIR "sound/AI"
-#define FILE_DIR "sound/ambience"
-#define FILE_DIR "sound/effects"
-#define FILE_DIR "sound/hallucinations"
-#define FILE_DIR "sound/items"
-#define FILE_DIR "sound/machines"
-#define FILE_DIR "sound/mecha"
-#define FILE_DIR "sound/misc"
-#define FILE_DIR "sound/piano"
-#define FILE_DIR "sound/violin"
-#define FILE_DIR "sound/voice"
-#define FILE_DIR "sound/weapons"
-#define FILE_DIR "tools"
-#define FILE_DIR "tools/Redirector"
// END_FILE_DIR
// BEGIN_PREFERENCES
@@ -247,6 +25,7 @@
#include "code\__HELPERS\lists.dm"
#include "code\__HELPERS\logging.dm"
#include "code\__HELPERS\names.dm"
+#include "code\__HELPERS\sanitize_values.dm"
#include "code\__HELPERS\text.dm"
#include "code\__HELPERS\time.dm"
#include "code\__HELPERS\type2type.dm"
|
|