diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm new file mode 100644 index 0000000000..c78dfb28ab --- /dev/null +++ b/code/__DEFINES/configuration.dm @@ -0,0 +1,10 @@ +//config files +#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X +#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) +#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) + +#define CONFIG_MAPS_FILE "maps.txt" + +//flags +#define CONFIG_ENTRY_LOCKED 1 //can't edit +#define CONFIG_ENTRY_HIDDEN 2 //can't see value diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8f3a0163b9..91508ded32 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -26,74 +26,74 @@ /proc/log_admin(text) GLOB.admin_log.Add(text) - if (config.log_admin) + if (CONFIG_GET(flag/log_admin)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text]") //Items using this proc are stripped from public logs - use with caution /proc/log_admin_private(text) GLOB.admin_log.Add(text) - if (config.log_admin) + if (CONFIG_GET(flag/log_admin)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMINPRIVATE: [text]") /proc/log_adminsay(text) - if (config.log_adminchat) + if (CONFIG_GET(flag/log_adminchat)) log_admin_private("ASAY: [text]") /proc/log_dsay(text) - if (config.log_adminchat) + if (CONFIG_GET(flag/log_adminchat)) log_admin("DSAY: [text]") /proc/log_game(text) - if (config.log_game) + if (CONFIG_GET(flag/log_game)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text]") /proc/log_vote(text) - if (config.log_vote) + if (CONFIG_GET(flag/log_vote)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text]") /proc/log_access(text) - if (config.log_access) + if (CONFIG_GET(flag/log_access)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ACCESS: [text]") /proc/log_say(text) - if (config.log_say) + if (CONFIG_GET(flag/log_say)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SAY: [text]") /proc/log_prayer(text) - if (config.log_prayer) + if (CONFIG_GET(flag/log_prayer)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PRAY: [text]") /proc/log_law(text) - if (config.log_law) + if (CONFIG_GET(flag/log_law)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LAW: [text]") /proc/log_ooc(text) - if (config.log_ooc) + if (CONFIG_GET(flag/log_ooc)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]OOC: [text]") /proc/log_whisper(text) - if (config.log_whisper) + if (CONFIG_GET(flag/log_whisper)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [text]") /proc/log_emote(text) - if (config.log_emote) + if (CONFIG_GET(flag/log_emote)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [text]") /proc/log_attack(text) - if (config.log_attack) + if (CONFIG_GET(flag/log_attack)) WRITE_FILE(GLOB.world_attack_log, "\[[time_stamp()]]ATTACK: [text]") /proc/log_pda(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) WRITE_FILE(GLOB.world_pda_log, "\[[time_stamp()]]PDA: [text]") /proc/log_comment(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) //reusing the PDA option because I really don't think news comments are worth a config option WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]COMMENT: [text]") /proc/log_chat(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]") /proc/log_qdel(text) @@ -102,6 +102,10 @@ /proc/log_sql(text) WRITE_FILE(GLOB.sql_error_log, "\[[time_stamp()]]SQL: [text]") +/proc/log_config(text) + WRITE_FILE(GLOB.config_error_log, text) + SEND_TEXT(world.log, text) + //This replaces world.log so it displays both in DD and the file /proc/log_world(text) WRITE_FILE(GLOB.world_runtime_log, text) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c040e264e6..e38a6826f9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -314,10 +314,11 @@ // Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer. -/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) +/proc/get_candidates(be_special_type, afk_bracket = CONFIG_GET(number/inactivity_period), jobbanType) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) - while(!candidates.len && afk_bracket < config.afk_period) + var/afk_period = CONFIG_GET(number/afk_period) + while(!candidates.len && afk_bracket < afk_period) for(var/mob/dead/observer/G in GLOB.player_list) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 1af231f893..0b79afb941 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -1,116 +1,115 @@ -////////////////////////// -/////Initial Building///// -////////////////////////// - -/proc/make_datum_references_lists() - //hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) - //facial hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) - //underwear - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - //undershirt - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - //socks - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) - //lizard bodyparts (blizzard intensifies) - init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) - - //citadel code - //mammal bodyparts (fucking furries) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) - //avian bodyparts (i swear this isn't starbound) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list) - //xeno parts (hiss?) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) - //genitals - init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) - - for(var/K in GLOB.cock_shapes_list) - var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] - GLOB.cock_shapes_icons[K] = value.icon_state - - init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. - - //Species - for(var/spath in subtypesof(/datum/species)) - var/datum/species/S = new spath() - if(S.roundstart) - GLOB.roundstart_species[S.id] = S.type - GLOB.species_list[S.id] = S.type - - //Surgeries - for(var/path in subtypesof(/datum/surgery)) - GLOB.surgeries_list += new path() - - //Materials - for(var/path in subtypesof(/datum/material)) - var/datum/material/D = new path() - GLOB.materials_list[D.id] = D - - //Techs - for(var/path in subtypesof(/datum/tech)) - var/datum/tech/D = new path() - GLOB.tech_list[D.id] = D - - //Emotes - for(var/path in subtypesof(/datum/emote)) - var/datum/emote/E = new path() - E.emote_list[E.key] = E - - init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) - -/* // Uncomment to debug chemical reaction list. -/client/verb/debug_chemical_list() - - for (var/reaction in chemical_reactions_list) - . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n" - if(islist(chemical_reactions_list[reaction])) - var/list/L = chemical_reactions_list[reaction] - for(var/t in L) - . += " has: [t]\n" - to_chat(world, .) -*/ - -//creates every subtype of prototype (excluding prototype) and adds it to list L. -//if no list/L is provided, one is created. -/proc/init_subtypes(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L += new path() - return L - -//returns a list of paths to every subtype of prototype (excluding prototype) -//if no list/L is provided, one is created. -/proc/init_paths(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L+= path - return L +////////////////////////// +/////Initial Building///// +////////////////////////// + +/proc/make_datum_references_lists() + //hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) + //facial hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) + //underwear + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + //undershirt + init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + //socks + init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) + //lizard bodyparts (blizzard intensifies) + init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) + + //citadel code + //mammal bodyparts (fucking furries) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) + //avian bodyparts (i swear this isn't starbound) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list) + //xeno parts (hiss?) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) + //genitals + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) + + for(var/K in GLOB.cock_shapes_list) + var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] + GLOB.cock_shapes_icons[K] = value.icon_state + + init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + + + //Species + for(var/spath in subtypesof(/datum/species)) + var/datum/species/S = new spath() + GLOB.species_list[S.id] = spath + + //Surgeries + for(var/path in subtypesof(/datum/surgery)) + GLOB.surgeries_list += new path() + + //Materials + for(var/path in subtypesof(/datum/material)) + var/datum/material/D = new path() + GLOB.materials_list[D.id] = D + + //Techs + for(var/path in subtypesof(/datum/tech)) + var/datum/tech/D = new path() + GLOB.tech_list[D.id] = D + + //Emotes + for(var/path in subtypesof(/datum/emote)) + var/datum/emote/E = new path() + E.emote_list[E.key] = E + + init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) + +/* // Uncomment to debug chemical reaction list. +/client/verb/debug_chemical_list() + + for (var/reaction in chemical_reactions_list) + . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n" + if(islist(chemical_reactions_list[reaction])) + var/list/L = chemical_reactions_list[reaction] + for(var/t in L) + . += " has: [t]\n" + to_chat(world, .) +*/ + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L += new path() + return L + +//returns a list of paths to every subtype of prototype (excluding prototype) +//if no list/L is provided, one is created. +/proc/init_paths(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L+= path + return L diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index ed855c33b9..de606b137e 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -220,7 +220,6 @@ GLOBAL_LIST_INIT(skin_tones, list( )) GLOBAL_LIST_EMPTY(species_list) -GLOBAL_LIST_EMPTY(roundstart_species) /proc/age2agedescription(age) switch(age) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 67179e8c8f..bfcfd23f50 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -1,246 +1,248 @@ -#define ION_FILE "ion_laws.json" - -/proc/lizard_name(gender) - if(gender == MALE) - return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" - else - return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" - -/proc/plasmaman_name() - return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" - -/proc/church_name() - var/static/church_name - if (church_name) - return church_name - - var/name = "" - - name += pick("Holy", "United", "First", "Second", "Last") - - if (prob(20)) - name += " Space" - - name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") - name += " of [religion_name()]" - - return name - -GLOBAL_VAR(command_name) -/proc/command_name() - if (GLOB.command_name) - return GLOB.command_name - - var/name = "Central Command" - - GLOB.command_name = name - return name - -/proc/change_command_name(name) - - GLOB.command_name = name - - return name - -/proc/religion_name() - var/static/religion_name - if (religion_name) - return religion_name - - var/name = "" - - name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") - name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") - - return capitalize(name) - -/proc/station_name() - if(!GLOB.station_name) - var/newname - if(config && config.station_name) - newname = config.station_name - else - newname = new_station_name() - - set_station_name(newname) - - return GLOB.station_name - -/proc/set_station_name(newname) - GLOB.station_name = newname - - if(config && config.server_name) - world.name = "[config.server_name][config.server_name==GLOB.station_name ? "" : ": [GLOB.station_name]"]" - else - world.name = GLOB.station_name - - -/proc/new_station_name() - var/random = rand(1,5) - var/name = "" - var/new_station_name = "" - - //Rare: Pre-Prefix - if (prob(10)) - name = pick(GLOB.station_prefixes) - new_station_name = name + " " - name = "" - - // Prefix - for(var/holiday_name in SSevents.holidays) - if(holiday_name == "Friday the 13th") - random = 13 - var/datum/holiday/holiday = SSevents.holidays[holiday_name] - name = holiday.getStationPrefix() - //get normal name - if(!name) - name = pick(GLOB.station_names) - if(name) - new_station_name += name + " " - - // Suffix - name = pick(GLOB.station_suffixes) - new_station_name += name + " " - - // ID Number - switch(random) - if(1) - new_station_name += "[rand(1, 99)]" - if(2) - new_station_name += pick(GLOB.greek_letters) - if(3) - new_station_name += "\Roman[rand(1,99)]" - if(4) - new_station_name += pick(GLOB.phonetic_alphabet) - if(5) - new_station_name += pick(GLOB.numbers_as_words) - if(13) - new_station_name += pick("13","XIII","Thirteen") - return new_station_name - -/proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name - - var/name = "" - - // Prefix - name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") - - // Suffix - if (prob(80)) - name += " " - - // Full - if (prob(60)) - name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") - // Broken - else - name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") - name += pick("", "-") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") - // Small - else - name += pick("-", "*", "") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - syndicate_name = name - return name - - -//Traitors and traitor silicons will get these. Revs will not. -GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. -GLOBAL_VAR(syndicate_code_response) //Code response for traitors. - - /* - Should be expanded. - How this works: - Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. - Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." - The phrase should then have the words: James Smith. - The response should then have the words: run, void, and derelict. - This way assures that the code is suited to the conversation and is unpredicatable. - Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. - Can probably be done through "{ }" but I don't really see the practical benefit. - One example of an earlier system is commented below. - /N - */ - -/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm - - if(!return_list) - . = "" - else - . = list() - - var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. - 50; 2, - 200; 3, - 50; 4, - 25; 5 - ) - - var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. - var/nouns = strings(ION_FILE, "ionabstract") - var/objects = strings(ION_FILE, "ionobjects") - var/adjectives = strings(ION_FILE, "ionadjectives") - var/threats = strings(ION_FILE, "ionthreats") - var/foods = strings(ION_FILE, "ionfood") - var/drinks = strings(ION_FILE, "iondrinks") - var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. - - var/list/names = list() - for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. - names += t.fields["name"] - - var/maxwords = words//Extra var to check for duplicates. - - for(words,words>0,words--)//Randomly picks from one of the choices below. - - if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. - safety = list(pick(1,2))//Select choice 1 or 2. - else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, - safety = list(3)//Default to list 3 - - switch(pick(safety))//Chance based on the safety list. - if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. - switch(rand(1,2))//Mainly to add more options later. - if(1) - if(names.len&&prob(70)) - . += pick(names) - else - if(prob(10)) - . += pick(lizard_name(MALE),lizard_name(FEMALE)) - else - var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) - new_name += " " - new_name += pick(GLOB.last_names) - . += new_name - if(2) - . += pick(get_all_jobs())//Returns a job. - safety -= 1 - if(2) - switch(rand(1,3))//Food, drinks, or things. Only selectable once. - if(1) - . += lowertext(pick(drinks)) - if(2) - . += lowertext(pick(foods)) - if(3) - . += lowertext(pick(locations)) - safety -= 2 - if(3) - switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. - if(1) - . += lowertext(pick(nouns)) - if(2) - . += lowertext(pick(objects)) - if(3) - . += lowertext(pick(adjectives)) - if(4) - . += lowertext(pick(threats)) - if(!return_list) - if(words==1) - . += "." - else - . += ", " +#define ION_FILE "ion_laws.json" + +/proc/lizard_name(gender) + if(gender == MALE) + return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" + else + return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" + +/proc/plasmaman_name() + return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" + +/proc/church_name() + var/static/church_name + if (church_name) + return church_name + + var/name = "" + + name += pick("Holy", "United", "First", "Second", "Last") + + if (prob(20)) + name += " Space" + + name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") + name += " of [religion_name()]" + + return name + +GLOBAL_VAR(command_name) +/proc/command_name() + if (GLOB.command_name) + return GLOB.command_name + + var/name = "Central Command" + + GLOB.command_name = name + return name + +/proc/change_command_name(name) + + GLOB.command_name = name + + return name + +/proc/religion_name() + var/static/religion_name + if (religion_name) + return religion_name + + var/name = "" + + name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") + name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") + + return capitalize(name) + +/proc/station_name() + if(!GLOB.station_name) + var/newname + var/config_station_name = CONFIG_GET(string/stationname) + if(config_station_name) + newname = config_station_name + else + newname = new_station_name() + + set_station_name(newname) + + return GLOB.station_name + +/proc/set_station_name(newname) + GLOB.station_name = newname + + var/config_server_name = CONFIG_GET(string/servername) + if(config_server_name) + world.name = "[config_server_name][config_server_name == GLOB.station_name ? "" : ": [GLOB.station_name]"]" + else + world.name = GLOB.station_name + + +/proc/new_station_name() + var/random = rand(1,5) + var/name = "" + var/new_station_name = "" + + //Rare: Pre-Prefix + if (prob(10)) + name = pick(GLOB.station_prefixes) + new_station_name = name + " " + name = "" + + // Prefix + for(var/holiday_name in SSevents.holidays) + if(holiday_name == "Friday the 13th") + random = 13 + var/datum/holiday/holiday = SSevents.holidays[holiday_name] + name = holiday.getStationPrefix() + //get normal name + if(!name) + name = pick(GLOB.station_names) + if(name) + new_station_name += name + " " + + // Suffix + name = pick(GLOB.station_suffixes) + new_station_name += name + " " + + // ID Number + switch(random) + if(1) + new_station_name += "[rand(1, 99)]" + if(2) + new_station_name += pick(GLOB.greek_letters) + if(3) + new_station_name += "\Roman[rand(1,99)]" + if(4) + new_station_name += pick(GLOB.phonetic_alphabet) + if(5) + new_station_name += pick(GLOB.numbers_as_words) + if(13) + new_station_name += pick("13","XIII","Thirteen") + return new_station_name + +/proc/syndicate_name() + var/static/syndicate_name + if (syndicate_name) + return syndicate_name + + var/name = "" + + // Prefix + name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") + + // Suffix + if (prob(80)) + name += " " + + // Full + if (prob(60)) + name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") + // Broken + else + name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") + name += pick("", "-") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") + // Small + else + name += pick("-", "*", "") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") + + syndicate_name = name + return name + + +//Traitors and traitor silicons will get these. Revs will not. +GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. +GLOBAL_VAR(syndicate_code_response) //Code response for traitors. + + /* + Should be expanded. + How this works: + Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. + Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." + The phrase should then have the words: James Smith. + The response should then have the words: run, void, and derelict. + This way assures that the code is suited to the conversation and is unpredicatable. + Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. + Can probably be done through "{ }" but I don't really see the practical benefit. + One example of an earlier system is commented below. + /N + */ + +/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm + + if(!return_list) + . = "" + else + . = list() + + var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. + 50; 2, + 200; 3, + 50; 4, + 25; 5 + ) + + var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. + var/nouns = strings(ION_FILE, "ionabstract") + var/objects = strings(ION_FILE, "ionobjects") + var/adjectives = strings(ION_FILE, "ionadjectives") + var/threats = strings(ION_FILE, "ionthreats") + var/foods = strings(ION_FILE, "ionfood") + var/drinks = strings(ION_FILE, "iondrinks") + var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. + + var/list/names = list() + for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. + names += t.fields["name"] + + var/maxwords = words//Extra var to check for duplicates. + + for(words,words>0,words--)//Randomly picks from one of the choices below. + + if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. + safety = list(pick(1,2))//Select choice 1 or 2. + else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, + safety = list(3)//Default to list 3 + + switch(pick(safety))//Chance based on the safety list. + if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. + switch(rand(1,2))//Mainly to add more options later. + if(1) + if(names.len&&prob(70)) + . += pick(names) + else + if(prob(10)) + . += pick(lizard_name(MALE),lizard_name(FEMALE)) + else + var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) + new_name += " " + new_name += pick(GLOB.last_names) + . += new_name + if(2) + . += pick(get_all_jobs())//Returns a job. + safety -= 1 + if(2) + switch(rand(1,3))//Food, drinks, or things. Only selectable once. + if(1) + . += lowertext(pick(drinks)) + if(2) + . += lowertext(pick(foods)) + if(3) + . += lowertext(pick(locations)) + safety -= 2 + if(3) + switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. + if(1) + . += lowertext(pick(nouns)) + if(2) + . += lowertext(pick(objects)) + if(3) + . += lowertext(pick(adjectives)) + if(4) + . += lowertext(pick(threats)) + if(!return_list) + if(words==1) + . += "." + else + . += ", " diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index ce8f9f9bd2..04fb2f32f7 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -19,7 +19,7 @@ return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that /proc/format_table_name(table as text) - return global.sqlfdbktableprefix + table + return CONFIG_GET(string/feedback_tableprefix) + table /* * Text sanitization @@ -594,7 +594,7 @@ GLOBAL_LIST_INIT(binary, list("0","1")) //in the json file and have it be reflected in the in game item/mob it came from. //(That's what things like savefiles are for) Note that this list is not shuffled. /proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000) - if(!islist(proposed) || !filename || !config.log_twitter) + if(!islist(proposed) || !filename || !CONFIG_GET(flag/log_twitter)) return //Regular expressions are, as usual, absolute magic diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 60b5d82940..46d6c2ce5c 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -554,3 +554,24 @@ else return /datum return text2path(copytext(string_type, 1, last_slash)) + +//returns a string the last bit of a type, without the preceeding '/' +/proc/type2top(the_type) + //handle the builtins manually + if(!ispath(the_type)) + return + switch(the_type) + if(/datum) + return "datum" + if(/atom) + return "atom" + if(/obj) + return "obj" + if(/mob) + return "mob" + if(/area) + return "area" + if(/turf) + return "turf" + else //regex everything else (works for /proc too) + return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", "")) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index c2398982c2..905babe848 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1266,7 +1266,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } #define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } -#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qel(L[I]); L.Cut(); } +#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } /proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. QDEL_LIST(L) diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 83bf3cfb5a..391744e34c 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -1,4 +1,4 @@ -GLOBAL_REAL(config, /datum/configuration) +GLOBAL_REAL(config, /datum/controller/configuration) GLOBAL_DATUM_INIT(revdata, /datum/getrev, new) @@ -11,9 +11,7 @@ GLOBAL_VAR_INIT(hub_visibility, FALSE) GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently GLOBAL_VAR_INIT(dooc_allowed, TRUE) -GLOBAL_VAR_INIT(abandon_allowed, TRUE) GLOBAL_VAR_INIT(enter_allowed, TRUE) -GLOBAL_VAR_INIT(guests_allowed, TRUE) GLOBAL_VAR_INIT(shuttle_frozen, FALSE) GLOBAL_VAR_INIT(shuttle_left, FALSE) GLOBAL_VAR_INIT(tinted_weldhelh, TRUE) @@ -25,10 +23,16 @@ GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch GLOBAL_VAR_INIT(Debug2, FALSE) //This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage +//Protecting these because the proper way to edit them is with the config/secrets GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) +GLOBAL_PROTECT(MAX_EX_DEVESTATION_RANGE) GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) +GLOBAL_PROTECT(MAX_EX_HEAVY_RANGE) GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_LIGHT_RANGE) GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLASH_RANGE) GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLAME_RANGE) GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) diff --git a/code/_globalvars/sensitive.dm b/code/_globalvars/sensitive.dm deleted file mode 100644 index e1a02621ac..0000000000 --- a/code/_globalvars/sensitive.dm +++ /dev/null @@ -1,16 +0,0 @@ -//Server API key -GLOBAL_REAL_VAR(comms_key) = "default_pwd" -GLOBAL_REAL_VAR(comms_allowed) = FALSE //By default, the server does not allow messages to be sent to it, unless the key is strong enough (this is to prevent misconfigured servers from becoming vulnerable) - -GLOBAL_REAL_VAR(medal_hub) -GLOBAL_REAL_VAR(medal_pass) = " " -GLOBAL_REAL_VAR(medals_enabled) = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. - -// MySQL configuration - -GLOBAL_REAL_VAR(sqladdress) = "localhost" -GLOBAL_REAL_VAR(sqlport) = "3306" -GLOBAL_REAL_VAR(sqlfdbkdb) = "test" -GLOBAL_REAL_VAR(sqlfdbklogin) = "root" -GLOBAL_REAL_VAR(sqlfdbkpass) = "" -GLOBAL_REAL_VAR(sqlfdbktableprefix) = "" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 0c0baccc56..1e4a574e13 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1,296 +1,156 @@ -//Configuraton defines //TODO: Move all yes/no switches into bitflags - -//Used by jobs_have_maint_access -#define ASSISTANTS_HAVE_MAINT_ACCESS 1 -#define SECURITY_HAS_MAINT_ACCESS 2 -#define EVERYONE_HAS_MAINT_ACCESS 4 - GLOBAL_VAR_INIT(config_dir, "config/") GLOBAL_PROTECT(config_dir) +/datum/controller/configuration + name = "Configuration" + + var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it + var/list/entries + var/list/entries_by_type + + var/list/maplist + var/datum/map_config/defaultmap + + var/list/modes // allowed modes + var/list/gamemode_cache + var/list/votable_modes // votable modes + var/list/mode_names + var/list/mode_reports + var/list/mode_false_report_weight + +/datum/controller/configuration/New() + config = src + var/list/config_files = InitEntries() + LoadModes() + for(var/I in config_files) + LoadEntries(I) + if(Get(/datum/config_entry/flag/maprotation)) + loadmaplist(CONFIG_MAPS_FILE) + +/datum/controller/configuration/Destroy() + entries_by_type.Cut() + QDEL_LIST_ASSOC_VAL(entries) + QDEL_LIST_ASSOC_VAL(maplist) + QDEL_NULL(defaultmap) + + config = null -/datum/configuration/can_vv_get(var_name) - var/static/list/banned_gets = list("autoadmin", "autoadmin_rank") - if (var_name in banned_gets) - return FALSE return ..() -/datum/configuration/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl") - if(var_name in banned_edits) - return FALSE - return ..() +/datum/controller/configuration/proc/InitEntries() + var/list/_entries = list() + entries = _entries + var/list/_entries_by_type = list() + entries_by_type = _entries_by_type -/datum/configuration - var/name = "Configuration" // datum name + . = list() - var/autoadmin = 0 - var/autoadmin_rank = "Game Admin" + for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case + var/datum/config_entry/E = I + if(initial(E.abstract_type) == I) + continue + E = new I + _entries_by_type[I] = E + var/esname = E.name + var/datum/config_entry/test = _entries[esname] + if(test) + log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") + qdel(E) + continue + _entries[esname] = E + .[E.resident_file] = TRUE - var/server_name = null // server name (the name of the game window) - var/server_sql_name = null // short form server name used for the DB - var/station_name = null // station name (the name of the station in-game) - var/lobby_countdown = 120 // In between round countdown. - var/round_end_countdown = 25 // Post round murder death kill countdown - var/hub = 0 +/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) + entries -= CE.name + entries_by_type -= CE.type - var/log_ooc = 0 // log OOC channel - var/log_access = 0 // log login/logout - var/log_say = 0 // log client say - var/log_admin = 0 // log admin actions - var/log_game = 0 // log game events - var/log_vote = 0 // log voting - var/log_whisper = 0 // log client whisper - var/log_prayer = 0 // log prayers - var/log_law = 0 // log lawchanges - var/log_emote = 0 // log emotes - var/log_attack = 0 // log attack messages - var/log_adminchat = 0 // log admin chat messages - var/log_pda = 0 // log pda messages - var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - var/log_world_topic = 0 // log all world.Topic() calls - var/sql_enabled = 0 // for sql switching - var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour - var/allow_vote_restart = 0 // allow votes to restart - var/allow_vote_mode = 0 // allow votes to change mode - var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) - var/vote_period = 600 // length of voting period (deciseconds, default 1 minute) - var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) - var/vote_no_dead = 0 // dead people can't vote (tbi) - var/del_new_on_log = 1 // del's new players if they log before they spawn in - var/allow_Metadata = 0 // Metadata is supported. - var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. - var/fps = 20 - var/allow_holidays = 0 //toggles whether holiday-specific content should be used - var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling +/datum/controller/configuration/proc/LoadEntries(filename) + log_config("Loading config file [filename]...") + var/list/lines = world.file2list("[GLOB.config_dir][filename]") + var/list/_entries = entries + for(var/L in lines) + if(!L) + continue - var/hostedby = null - var/respawn = 1 - var/guest_jobban = 1 - var/usewhitelist = 0 - var/inactivity_period = 3000 //time in ds until a player is considered inactive - var/afk_period = 6000 //time in ds until a player is considered afk and kickable - var/kick_inactive = FALSE //force disconnect for inactive players - var/load_jobs_from_txt = 0 - var/automute_on = 0 //enables automuting/spam prevention - var/minimal_access_threshold = 0 //If the number of players is larger than this threshold, minimal access will be turned on. - var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. - var/jobs_have_maint_access = 0 //Who gets maint access? See defines above. - var/sec_start_brig = 0 //makes sec start in brig or dept sec posts + if(copytext(L, 1, 2) == "#") + continue - var/server - var/banappeals - var/wikiurl = "http://www.tgstation13.org/wiki" // Default wiki link. - var/forumurl = "http://tgstation13.org/phpBB/index.php" //default forums - var/rulesurl = "http://www.tgstation13.org/wiki/Rules" // default rules - var/githuburl = "https://www.github.com/tgstation/-tg-station" //default github - var/githubrepoid + var/pos = findtext(L, " ") + var/entry = null + var/value = null - var/forbid_singulo_possession = 0 - var/useircbot = 0 + if(pos) + entry = lowertext(copytext(L, 1, pos)) + value = copytext(L, pos + 1) + else + entry = lowertext(L) - var/check_randomizer = 0 + if(!entry) + continue - var/panic_server_name - var/panic_address //Reconnect a player this linked server if this server isn't accepting new players + var/datum/config_entry/E = _entries[entry] + if(!E) + log_config("Unknown setting in configuration: '[entry]'") + continue - var/invoke_youtubedl + if(filename != E.resident_file) + log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") + continue - //IP Intel vars - var/ipintel_email - var/ipintel_rating_bad = 1 - var/ipintel_save_good = 12 - var/ipintel_save_bad = 1 - var/ipintel_domain = "check.getipintel.net" + var/validated = E.ValidateAndSet(value) + if(!validated) + log_config("Failed to validate setting \"[value]\" for [entry]") + else if(E.modified && !E.dupes_allowed) + log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") - var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt - var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt - var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database - var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. - var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt - var/note_fresh_days - var/note_stale_days + if(validated) + E.modified = TRUE - var/use_exp_tracking = FALSE - var/use_exp_restrictions_heads = FALSE - var/use_exp_restrictions_heads_hours = 0 - var/use_exp_restrictions_heads_department = FALSE - var/use_exp_restrictions_other = FALSE - var/use_exp_restrictions_admin_bypass = FALSE +/datum/controller/configuration/can_vv_get(var_name) + return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() - //Population cap vars - var/soft_popcap = 0 - var/hard_popcap = 0 - var/extreme_popcap = 0 - var/soft_popcap_message = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." - var/hard_popcap_message = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." - var/extreme_popcap_message = "The server is currently serving a high number of users, find alternative servers." +/datum/controller/configuration/vv_edit_var(var_name, var_value) + return !(var_name in list("entries_by_type", "entries")) && ..() - //game_options.txt configs - var/force_random_names = 0 - var/list/mode_names = list() - var/list/mode_reports = list() - var/list/mode_false_report_weight = list() - var/list/modes = list() // allowed modes - var/list/votable_modes = list() // votable modes - var/list/probabilities = list() // relative probability of each mode - var/list/min_pop = list() // overrides for acceptible player counts in a mode - var/list/max_pop = list() - var/list/repeated_mode_adjust = list() // weight adjustments for recent modes - var/humans_need_surnames = 0 - var/allow_ai = 0 // allow ai job - var/forbid_secborg = 0 // disallow secborg module to be chosen. - var/forbid_peaceborg = 0 - var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting - var/notify_new_player_age = 0 // how long do we notify admins of a new player - var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account - var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time? +/datum/controller/configuration/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Edit", src) + stat("[name]:", statclick) - var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors - var/brother_scaling_coeff = 25 //how many players per brother team - var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings - var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions - var/abductor_scaling_coeff = 15 //how many players per abductor team +/datum/controller/configuration/proc/Get(entry_type) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.value - var/traitor_objectives_amount = 2 - var/brother_objectives_amount = 2 - var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other - var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other - var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff - var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling - var/list/continuous = list() // which roundtypes continue if all antagonists die - var/list/midround_antag = list() // which roundtypes use the midround antagonist system - var/midround_antag_time_check = 60 // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system - var/midround_antag_life_check = 0.7 // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist - var/shuttle_refuel_delay = 12000 - var/show_game_type_odds = 0 //if set this allows players to see the odds of each roundtype on the get revision screen - var/mutant_races = 0 //players can choose their mutant race before joining the game - var/list/roundstart_races = list() //races you can play as from the get go. If left undefined the game's roundstart var for species is used - var/mutant_humans = 0 //players can pick mutant bodyparts for humans before joining the game +/datum/controller/configuration/proc/Set(entry_type, new_val) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") + return + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.ValidateAndSet(new_val) - var/no_summon_guns //No - var/no_summon_magic //Fun - var/no_summon_events //Allowed - - var/intercept = 1 //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. - var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." - var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." - var/alert_desc_blue_downto = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." - var/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." - var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." - var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." - - var/revival_pod_plants = FALSE - var/revival_cloning = FALSE - var/revival_brain_life = -1 - - var/rename_cyborg = 0 - var/ooc_during_round = 0 - var/emojis = 0 - var/no_credits_round_end = FALSE - - //Used for modifying movement speed for mobs. - //Unversal modifiers - var/run_speed = 0 - var/walk_speed = 0 - - //Mob specific modifiers. NOTE: These will affect different mob types in different ways - var/human_delay = 0 - var/robot_delay = 0 - var/monkey_delay = 0 - var/alien_delay = 0 - var/slime_delay = 0 - var/animal_delay = 0 - - var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour. - var/ghost_interaction = 0 - - var/silent_ai = 0 - var/silent_borg = 0 - - var/damage_multiplier = 1 //Modifier for damage to all mobs. Impacts healing as well. - - var/allowwebclient = 0 - var/webclientmembersonly = 0 - - var/sandbox_autoclose = FALSE // close the sandbox panel after spawning an item, potentially reducing griff - - var/default_laws = 0 //Controls what laws the AI spawns with. - var/silicon_max_law_amount = 12 - var/list/lawids = list() - - var/list/law_weights = list() - - var/assistant_cap = -1 - - var/starlight = 0 - var/generate_minimaps = 0 - var/grey_assistants = 0 - - var/id_console_jobslot_delay = 30 - - var/lavaland_budget = 60 - var/space_budget = 16 - - var/aggressive_changelog = 0 - - var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors - - var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database - - var/announce_admin_logout = 0 - var/announce_admin_login = 0 - - var/list/datum/map_config/maplist = list() - var/datum/map_config/defaultmap = null - var/maprotation = 1 - var/maprotatechancedelta = 0.75 - var/allow_map_voting = TRUE - - // Enables random events mid-round when set to 1 - var/allow_random_events = 0 - - // Multipliers for random events minimal starting time and minimal players amounts - var/events_min_time_mul = 1 - var/events_min_players_mul = 1 - - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick - - var/client_warn_version = 0 - var/client_warn_message = "Your version of byond may have issues or be blocked from accessing this server in the future." - var/client_error_version = 0 - var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server." - - var/cross_name = "Other server" - var/cross_address = "byond://" - var/cross_allowed = FALSE - var/showircname = 0 - - var/list/gamemode_cache = null - - var/minutetopiclimit - var/secondtopiclimit - - var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error - var/error_limit = 50 // How many occurrences before the next will silence them - var/error_silence_time = 6000 // How long a unique error will be silenced for - var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error - - var/arrivals_shuttle_dock_window = 55 //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station - var/arrivals_shuttle_require_undocked = FALSE //Require the arrivals shuttle to be undocked before latejoiners can join - var/arrivals_shuttle_require_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join - - var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart. - - var/irc_announce_new_game = FALSE - - var/list/policies = list() - - var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes - -/datum/configuration/New() - gamemode_cache = typecacheof(/datum/game_mode,TRUE) +/datum/controller/configuration/proc/LoadModes() + gamemode_cache = typecacheof(/datum/game_mode, TRUE) + modes = list() + mode_names = list() + mode_reports = list() + mode_false_report_weight = list() + votable_modes = list() + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) for(var/T in gamemode_cache) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). @@ -298,7 +158,6 @@ GLOBAL_PROTECT(config_dir) if(M.config_tag) if(!(M.config_tag in modes)) // ensure each mode is added only once - WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.") modes += M.config_tag mode_names[M.config_tag] = M.name probabilities[M.config_tag] = M.probability @@ -309,558 +168,7 @@ GLOBAL_PROTECT(config_dir) qdel(M) votable_modes += "secret" - Reload() - -/datum/configuration/proc/Reload() - load("config.txt") - load("comms.txt", "comms") - load("game_options.txt","game_options") - load("policies.txt", "policies") - loadsql("dbconfig.txt") - reload_custom_roundstart_items_list() - if (maprotation) - loadmaplist("maps.txt") - - // apply some settings from config.. - GLOB.abandon_allowed = respawn - -/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist - filename = "[GLOB.config_dir][filename]" - var/list/Lines = world.file2list(filename) - - for(var/t in Lines) - if(!t) - continue - - t = trim(t) - if(length(t) == 0) - continue - else if(copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if(pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if(!name) - continue - - if(type == "config") - switch(name) - if("hub") - hub = 1 - if("admin_legacy_system") - admin_legacy_system = 1 - if("ban_legacy_system") - ban_legacy_system = 1 - if("use_age_restriction_for_jobs") - use_age_restriction_for_jobs = 1 - if("use_account_age_for_jobs") - use_account_age_for_jobs = 1 - if("use_exp_tracking") - use_exp_tracking = TRUE - if("use_exp_restrictions_heads") - use_exp_restrictions_heads = TRUE - if("use_exp_restrictions_heads_hours") - use_exp_restrictions_heads_hours = text2num(value) - if("use_exp_restrictions_heads_department") - use_exp_restrictions_heads_department = TRUE - if("use_exp_restrictions_other") - use_exp_restrictions_other = TRUE - if("use_exp_restrictions_admin_bypass") - use_exp_restrictions_admin_bypass = TRUE - if("lobby_countdown") - lobby_countdown = text2num(value) - if("round_end_countdown") - round_end_countdown = text2num(value) - if("log_ooc") - log_ooc = 1 - if("log_access") - log_access = 1 - if("log_say") - log_say = 1 - if("log_admin") - log_admin = 1 - if("log_prayer") - log_prayer = 1 - if("log_law") - log_law = 1 - if("log_game") - log_game = 1 - if("log_vote") - log_vote = 1 - if("log_whisper") - log_whisper = 1 - if("log_attack") - log_attack = 1 - if("log_emote") - log_emote = 1 - if("log_adminchat") - log_adminchat = 1 - if("log_pda") - log_pda = 1 - if("log_twitter") - log_twitter = 1 - if("log_world_topic") - log_world_topic = 1 - if("allow_admin_ooccolor") - allow_admin_ooccolor = 1 - if("allow_vote_restart") - allow_vote_restart = 1 - if("allow_vote_mode") - allow_vote_mode = 1 - if("no_dead_vote") - vote_no_dead = 1 - if("default_no_vote") - vote_no_default = 1 - if("vote_delay") - vote_delay = text2num(value) - if("vote_period") - vote_period = text2num(value) - if("norespawn") - respawn = 0 - if("servername") - server_name = value - if("serversqlname") - server_sql_name = value - if("stationname") - station_name = value - if("hostedby") - hostedby = value - if("server") - server = value - if("banappeals") - banappeals = value - if("wikiurl") - wikiurl = value - if("forumurl") - forumurl = value - if("rulesurl") - rulesurl = value - if("githuburl") - githuburl = value - if("githubrepoid") - githubrepoid = value - if("guest_jobban") - guest_jobban = 1 - if("guest_ban") - GLOB.guests_allowed = 0 - if("usewhitelist") - usewhitelist = TRUE - if("allow_metadata") - allow_Metadata = 1 - if("id_console_jobslot_delay") - id_console_jobslot_delay = text2num(value) - if("inactivity_period") - inactivity_period = text2num(value) * 10 //documented as seconds in config.txt - if("afk_period") - afk_period = text2num(value) * 10 // ^^^ - if("kick_inactive") - kick_inactive = TRUE - if("load_jobs_from_txt") - load_jobs_from_txt = 1 - if("forbid_singulo_possession") - forbid_singulo_possession = 1 - if("popup_admin_pm") - popup_admin_pm = 1 - if("allow_holidays") - allow_holidays = 1 - if("useircbot") //tgs2 support - useircbot = 1 - if("ticklag") - var/ticklag = text2num(value) - if(ticklag > 0) - fps = 10 / ticklag - if("tick_limit_mc_init") - tick_limit_mc_init = text2num(value) - if("fps") - fps = text2num(value) - if("automute_on") - automute_on = 1 - if("panic_server_name") - if (value != "\[Put the name here\]") - panic_server_name = value - if("panic_server_address") - if(value != "byond://address:port") - panic_address = value - if("invoke_youtubedl") - invoke_youtubedl = value - if("show_irc_name") - showircname = 1 - if("see_own_notes") - see_own_notes = 1 - if("note_fresh_days") - note_fresh_days = text2num(value) - if("note_stale_days") - note_stale_days = text2num(value) - if("soft_popcap") - soft_popcap = text2num(value) - if("hard_popcap") - hard_popcap = text2num(value) - if("extreme_popcap") - extreme_popcap = text2num(value) - if("soft_popcap_message") - soft_popcap_message = value - if("hard_popcap_message") - hard_popcap_message = value - if("extreme_popcap_message") - extreme_popcap_message = value - if("panic_bunker") - panic_bunker = 1 - if("notify_new_player_age") - notify_new_player_age = text2num(value) - if("notify_new_player_account_age") - notify_new_player_account_age = text2num(value) - if("irc_first_connection_alert") - irc_first_connection_alert = 1 - if("check_randomizer") - check_randomizer = 1 - if("ipintel_email") - if (value != "ch@nge.me") - ipintel_email = value - if("ipintel_rating_bad") - ipintel_rating_bad = text2num(value) - if("ipintel_domain") - ipintel_domain = value - if("ipintel_save_good") - ipintel_save_good = text2num(value) - if("ipintel_save_bad") - ipintel_save_bad = text2num(value) - if("aggressive_changelog") - aggressive_changelog = 1 - if("autoconvert_notes") - autoconvert_notes = 1 - if("allow_webclient") - allowwebclient = 1 - if("webclient_only_byond_members") - webclientmembersonly = 1 - if("announce_admin_logout") - announce_admin_logout = 1 - if("announce_admin_login") - announce_admin_login = 1 - if("maprotation") - maprotation = 1 - if("allow_map_voting") - allow_map_voting = text2num(value) - if("maprotationchancedelta") - maprotatechancedelta = text2num(value) - if("autoadmin") - autoadmin = 1 - if(value) - autoadmin_rank = ckeyEx(value) - if("generate_minimaps") - generate_minimaps = 1 - if("client_warn_version") - client_warn_version = text2num(value) - if("client_warn_message") - client_warn_message = value - if("client_error_version") - client_error_version = text2num(value) - if("client_error_message") - client_error_message = value - if("minute_topic_limit") - minutetopiclimit = text2num(value) - if("second_topic_limit") - secondtopiclimit = text2num(value) - if("error_cooldown") - error_cooldown = text2num(value) - if("error_limit") - error_limit = text2num(value) - if("error_silence_time") - error_silence_time = text2num(value) - if("error_msg_delay") - error_msg_delay = text2num(value) - if("irc_announce_new_game") - irc_announce_new_game = TRUE - if("debug_admin_hrefs") - debug_admin_hrefs = TRUE - else -#if DM_VERSION > 511 -#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") -#endif - HandleCommsConfig(name, value) //TODO: Deprecate this eventually - else if(type == "comms") - HandleCommsConfig(name, value) - else if(type == "game_options") - switch(name) - if("damage_multiplier") - damage_multiplier = text2num(value) - if("revival_pod_plants") - revival_pod_plants = TRUE - if("revival_cloning") - revival_cloning = TRUE - if("revival_brain_life") - revival_brain_life = text2num(value) - if("rename_cyborg") - rename_cyborg = 1 - if("ooc_during_round") - ooc_during_round = 1 - if("emojis") - emojis = 1 - if("no_credits_round_end") - no_credits_round_end = TRUE - if("run_delay") - run_speed = text2num(value) - if("walk_delay") - walk_speed = text2num(value) - if("human_delay") - human_delay = text2num(value) - if("robot_delay") - robot_delay = text2num(value) - if("monkey_delay") - monkey_delay = text2num(value) - if("alien_delay") - alien_delay = text2num(value) - if("slime_delay") - slime_delay = text2num(value) - if("animal_delay") - animal_delay = text2num(value) - if("alert_red_upto") - alert_desc_red_upto = value - if("alert_red_downto") - alert_desc_red_downto = value - if("alert_blue_downto") - alert_desc_blue_downto = value - if("alert_blue_upto") - alert_desc_blue_upto = value - if("alert_green") - alert_desc_green = value - if("alert_delta") - alert_desc_delta = value - if("no_intercept_report") - intercept = 0 - if("assistants_have_maint_access") - jobs_have_maint_access |= ASSISTANTS_HAVE_MAINT_ACCESS - if("security_has_maint_access") - jobs_have_maint_access |= SECURITY_HAS_MAINT_ACCESS - if("everyone_has_maint_access") - jobs_have_maint_access |= EVERYONE_HAS_MAINT_ACCESS - if("sec_start_brig") - sec_start_brig = 1 - if("gateway_delay") - gateway_delay = text2num(value) - if("continuous") - var/mode_name = lowertext(value) - if(mode_name in modes) - continuous[mode_name] = 1 - else - WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].") - if("midround_antag") - var/mode_name = lowertext(value) - if(mode_name in modes) - midround_antag[mode_name] = 1 - else - WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].") - if("midround_antag_time_check") - midround_antag_time_check = text2num(value) - if("midround_antag_life_check") - midround_antag_life_check = text2num(value) - if("min_pop") - var/pop_pos = findtext(value, " ") - var/mode_name = null - var/mode_value = null - - if(pop_pos) - mode_name = lowertext(copytext(value, 1, pop_pos)) - mode_value = copytext(value, pop_pos + 1) - if(mode_name in modes) - min_pop[mode_name] = text2num(mode_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].") - if("max_pop") - var/pop_pos = findtext(value, " ") - var/mode_name = null - var/mode_value = null - - if(pop_pos) - mode_name = lowertext(copytext(value, 1, pop_pos)) - mode_value = copytext(value, pop_pos + 1) - if(mode_name in modes) - max_pop[mode_name] = text2num(mode_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].") - if("shuttle_refuel_delay") - shuttle_refuel_delay = text2num(value) - if("show_game_type_odds") - show_game_type_odds = 1 - if("ghost_interaction") - ghost_interaction = 1 - if("traitor_scaling_coeff") - traitor_scaling_coeff = text2num(value) - if("brother_scaling_coeff") - brother_scaling_coeff = text2num(value) - if("changeling_scaling_coeff") - changeling_scaling_coeff = text2num(value) - if("security_scaling_coeff") - security_scaling_coeff = text2num(value) - if("abductor_scaling_coeff") - abductor_scaling_coeff = text2num(value) - if("traitor_objectives_amount") - traitor_objectives_amount = text2num(value) - if("brother_objectives_amount") - brother_objectives_amount = text2num(value) - if("probability") - var/prob_pos = findtext(value, " ") - var/prob_name = null - var/prob_value = null - - if(prob_pos) - prob_name = lowertext(copytext(value, 1, prob_pos)) - prob_value = copytext(value, prob_pos + 1) - if(prob_name in modes) - probabilities[prob_name] = text2num(prob_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].") - if("repeated_mode_adjust") - if(value) - repeated_mode_adjust.Cut() - var/values = splittext(value," ") - for(var/v in values) - repeated_mode_adjust += text2num(v) - else - WRITE_FILE(GLOB.config_error_log, "Incorrect round weight adjustment configuration definition for [value].") - if("protect_roles_from_antagonist") - protect_roles_from_antagonist = 1 - if("protect_assistant_from_antagonist") - protect_assistant_from_antagonist = 1 - if("enforce_human_authority") - enforce_human_authority = 1 - if("allow_latejoin_antagonists") - allow_latejoin_antagonists = 1 - if("allow_random_events") - allow_random_events = 1 - - if("events_min_time_mul") - events_min_time_mul = text2num(value) - if("events_min_players_mul") - events_min_players_mul = text2num(value) - - if("minimal_access_threshold") - minimal_access_threshold = text2num(value) - if("jobs_have_minimal_access") - jobs_have_minimal_access = 1 - if("humans_need_surnames") - humans_need_surnames = 1 - if("force_random_names") - force_random_names = 1 - if("allow_ai") - allow_ai = 1 - if("disable_secborg") - forbid_secborg = 1 - if("disable_peaceborg") - forbid_peaceborg = 1 - if("silent_ai") - silent_ai = 1 - if("silent_borg") - silent_borg = 1 - if("sandbox_autoclose") - sandbox_autoclose = 1 - if("default_laws") - default_laws = text2num(value) - if("random_laws") - var/law_id = lowertext(value) - lawids += law_id - if("law_weight") - // Value is in the form "LAWID,NUMBER" - var/list/L = splittext(value, ",") - if(L.len != 2) - WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t) - continue - var/lawid = L[1] - var/weight = text2num(L[2]) - law_weights[lawid] = weight - - if("silicon_max_law_amount") - silicon_max_law_amount = text2num(value) - if("join_with_mutant_race") - mutant_races = 1 - if("roundstart_races") - var/race_id = lowertext(value) - for(var/species_id in GLOB.species_list) - if(species_id == race_id) - roundstart_races += GLOB.species_list[species_id] - GLOB.roundstart_species[species_id] = GLOB.species_list[species_id] - if("join_with_mutant_humans") - mutant_humans = 1 - if("assistant_cap") - assistant_cap = text2num(value) - if("starlight") - starlight = 1 - if("grey_assistants") - grey_assistants = 1 - if("lavaland_budget") - lavaland_budget = text2num(value) - if("space_budget") - space_budget = text2num(value) - if("no_summon_guns") - no_summon_guns = 1 - if("no_summon_magic") - no_summon_magic = 1 - if("no_summon_events") - no_summon_events = 1 - if("reactionary_explosions") - reactionary_explosions = 1 - if("bombcap") - var/BombCap = text2num(value) - if (!BombCap) - continue - if (BombCap < 4) - BombCap = 4 - - GLOB.MAX_EX_DEVESTATION_RANGE = round(BombCap/4) - GLOB.MAX_EX_HEAVY_RANGE = round(BombCap/2) - GLOB.MAX_EX_LIGHT_RANGE = BombCap - GLOB.MAX_EX_FLASH_RANGE = BombCap - GLOB.MAX_EX_FLAME_RANGE = BombCap - if("arrivals_shuttle_dock_window") - arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value)) - if("arrivals_shuttle_require_undocked") - arrivals_shuttle_require_undocked = TRUE - if("arrivals_shuttle_require_safe_latejoin") - arrivals_shuttle_require_safe_latejoin = TRUE - if("mice_roundstart") - mice_roundstart = text2num(value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - else if(type == "policies") - policies[name] = value - - fps = round(fps) - if(fps <= 0) - fps = initial(fps) - -/datum/configuration/proc/HandleCommsConfig(name, value) - switch(name) - if("comms_key") - global.comms_key = value - if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins - global.comms_allowed = TRUE - if("cross_server_address") - cross_address = value - if(value != "byond:\\address:port") - cross_allowed = TRUE - if("cross_comms_name") - cross_name = value - if("medal_hub_address") - global.medal_hub = value - if("medal_hub_password") - global.medal_pass = value - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/loadmaplist(filename) +/datum/controller/configuration/proc/loadmaplist(filename) filename = "[GLOB.config_dir][filename]" var/list/Lines = world.file2list(filename) @@ -895,7 +203,7 @@ GLOBAL_PROTECT(config_dir) if ("map") currentmap = new ("_maps/[data].json") if(currentmap.defaulted) - log_world("Failed to load map config for [data]!") + log_config("Failed to load map config for [data]!") if ("minplayers","minplayer") currentmap.config_min_users = text2num(data) if ("maxplayers","maxplayer") @@ -905,6 +213,7 @@ GLOBAL_PROTECT(config_dir) if ("default","defaultmap") defaultmap = currentmap if ("endmap") + LAZYINITLIST(maplist) maplist[currentmap.map_name] = currentmap currentmap = null if ("disabled") @@ -913,51 +222,7 @@ GLOBAL_PROTECT(config_dir) WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'") -/datum/configuration/proc/loadsql(filename) - filename = "[GLOB.config_dir][filename]" - var/list/Lines = world.file2list(filename) - for(var/t in Lines) - if(!t) - continue - - t = trim(t) - if(length(t) == 0) - continue - else if(copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if(pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if(!name) - continue - - switch(name) - if("sql_enabled") - sql_enabled = 1 - if("address") - global.sqladdress = value - if("port") - global.sqlport = value - if("feedback_database") - global.sqlfdbkdb = value - if("feedback_login") - global.sqlfdbklogin = value - if("feedback_password") - global.sqlfdbkpass = value - if("feedback_tableprefix") - global.sqlfdbktableprefix = value - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/pick_mode(mode_name) +/datum/controller/configuration/proc/pick_mode(mode_name) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). // ^ This guy didn't try hard enough @@ -968,8 +233,12 @@ GLOBAL_PROTECT(config_dir) return new T return new /datum/game_mode/extended() -/datum/configuration/proc/get_runnable_modes() +/datum/controller/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) + var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) for(var/T in gamemode_cache) var/datum/game_mode/M = new T() if(!(M.config_tag in modes)) @@ -994,8 +263,11 @@ GLOBAL_PROTECT(config_dir) runnable_modes[M] = final_weight return runnable_modes -/datum/configuration/proc/get_runnable_midround_modes(crew) +/datum/controller/configuration/proc/get_runnable_midround_modes(crew) var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) for(var/T in (gamemode_cache - SSticker.mode.type)) var/datum/game_mode/M = new T() if(!(M.config_tag in modes)) @@ -1013,9 +285,3 @@ GLOBAL_PROTECT(config_dir) continue runnable_modes[M] = probabilities[M.config_tag] return runnable_modes - -/datum/configuration/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Edit", src) - - stat("[name]:", statclick) diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index b439743a79..5358073dbe 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -51,13 +51,7 @@ return FALSE return ..() -/datum/config_entry/proc/VASProcCallGuard(str_val) - . = !(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "\ref[src]") - if(!.) - log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]") - /datum/config_entry/proc/ValidateAndSet(str_val) - VASProcCallGuard(str_val) CRASH("Invalid config entry type!") /datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter) @@ -98,8 +92,6 @@ return var_name != "auto_trim" && ..() /datum/config_entry/string/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE value = auto_trim ? trim(str_val) : str_val return TRUE @@ -111,8 +103,6 @@ var/min_val = -INFINITY /datum/config_entry/number/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE var/temp = text2num(trim(str_val)) if(!isnull(temp)) value = Clamp(integer ? round(temp) : temp, min_val, max_val) @@ -130,8 +120,6 @@ abstract_type = /datum/config_entry/flag /datum/config_entry/flag/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE value = text2num(trim(str_val)) != 0 return TRUE @@ -140,8 +128,6 @@ value = list() /datum/config_entry/number_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE str_val = trim(str_val) var/list/new_list = list() var/list/values = splittext(str_val," ") @@ -161,8 +147,6 @@ dupes_allowed = TRUE /datum/config_entry/keyed_flag_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ") /datum/config_entry/keyed_number_list @@ -175,8 +159,6 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_number_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter) /datum/config_entry/keyed_string_list @@ -189,8 +171,6 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_string_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter) #undef LIST_MODE_NUM diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm new file mode 100644 index 0000000000..bf099f6cb6 --- /dev/null +++ b/code/controllers/configuration/entries/comms.dm @@ -0,0 +1,22 @@ +#define CURRENT_RESIDENT_FILE "comms.txt" + +CONFIG_DEF(string/comms_key) + protection = CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/comms_key/ValidateAndSet(str_val) + return str_val != "default_pwd" && length(str_val) > 6 && ..() + +CONFIG_DEF(string/cross_server_address) + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) + return str_val != "byond:\\address:port" && ..() + +CONFIG_DEF(string/cross_comms_name) + +GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. + +CONFIG_DEF(string/medal_hub_address) + +CONFIG_DEF(string/medal_hub_password) + protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm new file mode 100644 index 0000000000..cabb6dca27 --- /dev/null +++ b/code/controllers/configuration/entries/config.dm @@ -0,0 +1,387 @@ +#define CURRENT_RESIDENT_FILE "config.txt" + +CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/servername) // server name (the name of the game window) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/serversqlname) // short form server name used for the DB + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/stationname) // station name (the name of the station in-game) + +CONFIG_DEF(number/lobby_countdown) // In between round countdown. + value = 120 + min_val = 0 + +CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown + value = 25 + min_val = 0 + +CONFIG_DEF(flag/hub) // if the game appears on the hub or not + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_ooc) // log OOC channel + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_access) // log login/logout + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_say) // log client say + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_admin) // log admin actions + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_prayer) // log prayers + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_law) // log lawchanges + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_game) // log game events + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_vote) // log voting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_whisper) // log client whisper + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_attack) // log attack messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_emote) // log emotes + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_adminchat) // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_pda) // log pda messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart + +CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode + +CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/no_dead_vote) // dead people can't vote + +CONFIG_DEF(flag/allow_metadata) // Metadata is supported. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set + +CONFIG_DEF(number/fps) + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(number/ticklag) + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(flag/allow_holidays) + +CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/hostedby) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/norespawn) + +CONFIG_DEF(flag/guest_jobban) + +CONFIG_DEF(flag/usewhitelist) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database + +CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +CONFIG_DEF(flag/use_exp_tracking) + +CONFIG_DEF(flag/use_exp_restrictions_heads) + +CONFIG_DEF(number/use_exp_restrictions_heads_hours) + value = 0 + min_val = 0 + +CONFIG_DEF(flag/use_exp_restrictions_heads_department) + +CONFIG_DEF(flag/use_exp_restrictions_other) + +CONFIG_DEF(flag/use_exp_restrictions_admin_bypass) + +CONFIG_DEF(string/server) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/banappeals) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/wikiurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki" + +CONFIG_DEF(string/forumurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://tgstation13.org/phpBB/index.php" + +CONFIG_DEF(string/rulesurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki/Rules" + +CONFIG_DEF(string/githuburl) + protection = CONFIG_ENTRY_LOCKED + value = "https://www.github.com/tgstation/-tg-station" + +CONFIG_DEF(number/githubrepoid) + protection = CONFIG_ENTRY_LOCKED + value = null + min_val = 0 + +CONFIG_DEF(flag/guest_ban) + +CONFIG_DEF(number/id_console_jobslot_delay) + value = 30 + min_val = 0 + +CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players + +CONFIG_DEF(flag/load_jobs_from_txt) + +CONFIG_DEF(flag/forbid_singulo_possession) + +CONFIG_DEF(flag/useircbot) //tgs2 support + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention + +CONFIG_DEF(string/panic_server_name) + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +CONFIG_DEF(string/panic_address) //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +CONFIG_DEF(string/invoke_youtubedl) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(flag/show_irc_name) + +CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)? + +CONFIG_DEF(number/note_fresh_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/note_stale_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(flag/maprotation) + +CONFIG_DEF(number/maprotatechancedelta) + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +CONFIG_DEF(number/soft_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/hard_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/extreme_popcap) + value = null + min_val = 0 + +CONFIG_DEF(string/soft_popcap_message) + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +CONFIG_DEF(string/hard_popcap_message) + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +CONFIG_DEF(string/extreme_popcap_message) + value = "The server is currently serving a high number of users, find alternative servers." + +CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player + min_val = -1 + +CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account + min_val = 0 + +CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time? + +CONFIG_DEF(flag/check_randomizer) + +CONFIG_DEF(string/ipintel_email) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +CONFIG_DEF(number/ipintel_rating_bad) + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +CONFIG_DEF(number/ipintel_save_good) + protection = CONFIG_ENTRY_LOCKED + value = 12 + min_val = 0 + +CONFIG_DEF(number/ipintel_save_bad) + protection = CONFIG_ENTRY_LOCKED + value = 1 + min_val = 0 + +CONFIG_DEF(string/ipintel_domain) + protection = CONFIG_ENTRY_LOCKED + value = "check.getipintel.net" + +CONFIG_DEF(flag/aggressive_changelog) + +CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_webclient) + +CONFIG_DEF(flag/webclient_only_byond_members) + +CONFIG_DEF(flag/announce_admin_logout) + +CONFIG_DEF(flag/announce_admin_login) + +CONFIG_DEF(flag/allow_map_voting) + +CONFIG_DEF(flag/generate_minimaps) + +CONFIG_DEF(number/client_warn_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_warn_message) + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +CONFIG_DEF(number/client_error_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_error_message) + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +CONFIG_DEF(number/minute_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/second_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error) + value = 600 + min_val = 0 + +CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them + value = 50 + +CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for + value = 6000 + +CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +CONFIG_DEF(flag/irc_announce_new_game) + +CONFIG_DEF(flag/debug_admin_hrefs) \ No newline at end of file diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm new file mode 100644 index 0000000000..c46880686a --- /dev/null +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -0,0 +1,28 @@ +#define CURRENT_RESIDENT_FILE "dbconfig.txt" + +CONFIG_DEF(flag/sql_enabled) // for sql switching + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/address) + value = "localhost" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(number/port) + value = 3306 + min_val = 0 + max_val = 65535 + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_database) + value = "test" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_login) + value = "root" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_password) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_tableprefix) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm new file mode 100644 index 0000000000..106804a576 --- /dev/null +++ b/code/controllers/configuration/entries/game_options.dm @@ -0,0 +1,266 @@ +#define CURRENT_RESIDENT_FILE "game_options.txt" + +CONFIG_DEF(number_list/repeated_mode_adjust) + +CONFIG_DEF(keyed_number_list/probability) + +/datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_number_list/max_pop) + +/datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_number_list/min_pop) + +/datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die + +/datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system + +/datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_string_list/policy) + +CONFIG_DEF(number/damage_multiplier) + value = 1 + integer = FALSE + +CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on. + min_val = 0 + +CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access. + +CONFIG_DEF(flag/assistants_have_maint_access) + +CONFIG_DEF(flag/security_has_maint_access) + +CONFIG_DEF(flag/everyone_has_maint_access) + +CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts + +CONFIG_DEF(flag/force_random_names) + +CONFIG_DEF(flag/humans_need_surnames) + +CONFIG_DEF(flag/allow_ai) // allow ai job + +CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. + +CONFIG_DEF(flag/disable_peaceborg) + +CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors + value = 6 + min_val = 1 + +CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team + value = 25 + min_val = 1 + +CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings + value = 6 + min_val = 1 + +CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions + value = 8 + min_val = 1 + +CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team + value = 15 + min_val = 1 + +CONFIG_DEF(number/traitor_objectives_amount) + value = 2 + min_val = 0 + +CONFIG_DEF(number/brother_objectives_amount) + value = 2 + min_val = 0 + +CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors + +CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other + +CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other + +CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff + +CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling + +CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system + value = 60 + min_val = 0 + +CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist + value = 0.7 + integer = FALSE + min_val = 0 + max_val = 1 + +CONFIG_DEF(number/shuttle_refuel_delay) + value = 12000 + min_val = 0 + +CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen + +CONFIG_DEF(flag/join_with_mutant_race) //players can choose their mutant race before joining the game + +CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. If left undefined the game's roundstart var for species is used + var/first_edit = TRUE + +/datum/config_entry/keyed_flag_list/roundstart_races/New() + for(var/I in subtypesof(/datum/species)) + var/datum/species/S = I + if(initial(S.roundstart)) + value[initial(S.id)] = TRUE + ..() + +/datum/config_entry/keyed_flag_list/roundstart_races/ValidateAndSet(str_val) + var/list/old_val + if(first_edit) + old_val = value + old_val = old_val.Copy() + . = ..() + if(first_edit) + if(!.) + value = old_val + else + first_edit = FALSE + +CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game + +CONFIG_DEF(flag/no_summon_guns) //No + +CONFIG_DEF(flag/no_summon_magic) //Fun + +CONFIG_DEF(flag/no_summon_events) //Allowed + +CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. + +CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station + value = 55 + min_val = 30 + +CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join + +CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join + +CONFIG_DEF(string/alert_green) + value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." + +CONFIG_DEF(string/alert_blue_upto) + value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." + +CONFIG_DEF(string/alert_blue_downto) + value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." + +CONFIG_DEF(string/alert_red_upto) + value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." + +CONFIG_DEF(string/alert_red_downto) + value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." + +CONFIG_DEF(string/alert_delta) + value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + +CONFIG_DEF(flag/revival_pod_plants) + +CONFIG_DEF(flag/revival_cloning) + +CONFIG_DEF(number/revival_brain_life) + value = -1 + min_val = -1 + +CONFIG_DEF(flag/rename_cyborg) + +CONFIG_DEF(flag/ooc_during_round) + +CONFIG_DEF(flag/emojis) + +CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. + +CONFIG_DEF(number/walk_delay) + + +CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways +CONFIG_DEF(number/robot_delay) +CONFIG_DEF(number/monkey_delay) +CONFIG_DEF(number/alien_delay) +CONFIG_DEF(number/slime_delay) +CONFIG_DEF(number/animal_delay) + +CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. + value = 18000 + min_val = 0 + +CONFIG_DEF(flag/ghost_interaction) + +CONFIG_DEF(flag/silent_ai) +CONFIG_DEF(flag/silent_borg) + +CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff + +CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with. + value = 0 + min_val = 0 + max_val = 3 + +CONFIG_DEF(number/silicon_max_law_amount) + value = 12 + min_val = 0 + +CONFIG_DEF(keyed_flag_list/random_laws) + +CONFIG_DEF(keyed_number_list/law_weight) + splitter = "," + +CONFIG_DEF(number/assistant_cap) + value = -1 + min_val = -1 + +CONFIG_DEF(flag/starlight) +CONFIG_DEF(flag/grey_assistants) + +CONFIG_DEF(number/lavaland_budget) + value = 60 + min_val = 0 + +CONFIG_DEF(number/space_budget) + value = 16 + min_val = 0 + +CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set + +CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts + value = 1 + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/events_min_players_mul) + value = 1 + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/mice_roundstart) + value = 10 + min_val = 0 + +CONFIG_DEF(number/bombcap) + value = 14 + min_val = 4 + +/datum/config_entry/number/bombcap/ValidateAndSet(str_val) + . = ..() + if(.) + GLOB.MAX_EX_DEVESTATION_RANGE = round(value / 4) + GLOB.MAX_EX_HEAVY_RANGE = round(value / 2) + GLOB.MAX_EX_LIGHT_RANGE = value + GLOB.MAX_EX_FLASH_RANGE = value + GLOB.MAX_EX_FLAME_RANGE = value diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 11c460e326..6ed3121179 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -169,7 +169,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/start_timeofday = REALTIMEOFDAY // Initialize subsystems. - current_ticklimit = config.tick_limit_mc_init + current_ticklimit = CONFIG_GET(number/tick_limit_mc_init) for (var/datum/controller/subsystem/SS in subsystems) if (SS.flags & SS_NO_INIT) continue @@ -189,7 +189,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new sortTim(subsystems, /proc/cmp_subsystem_display) // Set world options. world.sleep_offline = 1 - world.fps = config.fps + world.fps = CONFIG_GET(number/fps) var/initialized_tod = REALTIMEOFDAY sleep(1) initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 2870305c3e..56238d5b85 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -38,7 +38,7 @@ SUBSYSTEM_DEF(blackbox) var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')") query_record_playercount.Execute() - if(config.use_exp_tracking) + if(CONFIG_GET(flag/use_exp_tracking)) if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check update_exp(10,FALSE) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 864274b8fb..12a5342e33 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -54,32 +54,27 @@ SUBSYSTEM_DEF(dbcore) if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore. return FALSE - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return FALSE - var/user = global.sqlfdbklogin - var/pass = global.sqlfdbkpass - var/db = global.sqlfdbkdb - var/address = global.sqladdress - var/port = global.sqlport + var/user = CONFIG_GET(string/feedback_login) + var/pass = CONFIG_GET(string/feedback_password) + var/db = CONFIG_GET(string/feedback_database) + var/address = CONFIG_GET(string/address) + var/port = CONFIG_GET(number/port) - doConnect("dbi:mysql:[db]:[address]:[port]", user, pass) + _dm_db_connect(_db_con, "dbi:mysql:[db]:[address]:[port]", user, pass, Default_Cursor, null) . = IsConnected() if (!.) log_sql("Connect() failed | [ErrorMsg()]") ++failed_connections -/datum/controller/subsystem/dbcore/proc/doConnect(dbi_handler, user_handler, password_handler) - if(!config.sql_enabled) - return FALSE - return _dm_db_connect(_db_con, dbi_handler, user_handler, password_handler, Default_Cursor, null) - /datum/controller/subsystem/dbcore/proc/Disconnect() failed_connections = 0 return _dm_db_close(_db_con) /datum/controller/subsystem/dbcore/proc/IsConnected() - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return FALSE return _dm_db_is_connected(_db_con) @@ -87,7 +82,7 @@ SUBSYSTEM_DEF(dbcore) return _dm_db_quote(_db_con, str) /datum/controller/subsystem/dbcore/proc/ErrorMsg() - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return "Database disabled by configuration" return _dm_db_error_msg(_db_con) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 7816a6bdf8..f435d7e819 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -56,7 +56,7 @@ SUBSYSTEM_DEF(events) //selects a random event based on whether it can occur and it's 'weight'(probability) /datum/controller/subsystem/events/proc/spawnEvent() set waitfor = FALSE //for the admin prompt - if(!config.allow_random_events) + if(!CONFIG_GET(flag/allow_random_events)) // var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control // if(E) E.runEvent() return @@ -171,7 +171,7 @@ SUBSYSTEM_DEF(events) //sets up the holidays and holidays list /datum/controller/subsystem/events/proc/getHoliday() - if(!config.allow_holidays) + if(!CONFIG_GET(flag/allow_holidays)) return // Holiday stuff was not enabled in the config! var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index d64739698a..1eb6c75cc5 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -16,7 +16,7 @@ SUBSYSTEM_DEF(job) /datum/controller/subsystem/job/Initialize(timeofday) if(!occupations.len) SetupOccupations() - if(config.load_jobs_from_txt) + if(CONFIG_GET(flag/load_jobs_from_txt)) LoadJobs() ..() @@ -106,7 +106,7 @@ SUBSYSTEM_DEF(job) if(player.mind && job.title in player.mind.restricted_roles) Debug("FOC incompatible with antagonist role, Player: [player]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("FOC non-human failed, Player: [player]") continue if(player.client.prefs.GetJobDepartment(job, level) & job.flag) @@ -143,7 +143,7 @@ SUBSYSTEM_DEF(job) Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("GRJ non-human failed, Player: [player]") continue @@ -245,11 +245,12 @@ SUBSYSTEM_DEF(job) setup_officer_positions() //Jobs will have fewer access permissions if the number of players exceeds the threshold defined in game_options.txt - if(config.minimal_access_threshold) - if(config.minimal_access_threshold > unassigned.len) - config.jobs_have_minimal_access = 0 + var/mat = CONFIG_GET(number/minimal_access_threshold) + if(mat) + if(mat > unassigned.len) + CONFIG_SET(flag/jobs_have_minimal_access, FALSE) else - config.jobs_have_minimal_access = 1 + CONFIG_SET(flag/jobs_have_minimal_access, TRUE) //Shuffle players and jobs unassigned = shuffle(unassigned) @@ -317,7 +318,7 @@ SUBSYSTEM_DEF(job) Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("DO non-human failed, Player: [player], Job:[job.title]") continue @@ -415,8 +416,8 @@ SUBSYSTEM_DEF(job) to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset.") if(job.req_admin_notify) to_chat(M, "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.") - if(config.minimal_access_threshold) - to_chat(M, "As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") + if(CONFIG_GET(number/minimal_access_threshold)) + to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") if(job && H) job.after_spawn(H, M) @@ -429,9 +430,10 @@ SUBSYSTEM_DEF(job) if(!J) throw EXCEPTION("setup_officer_positions(): Security officer job is missing") - if(config.security_scaling_coeff > 0) + var/ssc = CONFIG_GET(number/security_scaling_coeff) + if(ssc > 0) if(J.spawn_positions > 0) - var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len/config.security_scaling_coeff))) //Scale between configured minimum and 12 officers + var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len / ssc))) //Scale between configured minimum and 12 officers Debug("Setting open security officer positions to [officer_positions]") J.total_positions = officer_positions J.spawn_positions = officer_positions @@ -491,8 +493,10 @@ SUBSYSTEM_DEF(job) SSblackbox.add_details("job_preferences",tmp_str) /datum/controller/subsystem/job/proc/PopcapReached() - if(config.hard_popcap || config.extreme_popcap) - var/relevent_cap = max(config.hard_popcap, config.extreme_popcap) + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc || epc) + var/relevent_cap = max(hpc, epc) if((initial_players_to_assign - unassigned.len) >= relevent_cap) return 1 return 0 diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 78e8b150c3..989c5b43c4 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -16,7 +16,7 @@ SUBSYSTEM_DEF(lighting) /datum/controller/subsystem/lighting/Initialize(timeofday) if(!initialized) - if (config.starlight) + if (CONFIG_GET(flag/starlight)) for(var/I in GLOB.sortedAreas) var/area/A = I if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 9549cf7b18..ab2ba54431 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mapping) loading_ruins = TRUE var/mining_type = config.minetype if (mining_type == "lavaland") - seedRuins(list(ZLEVEL_LAVALAND), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) + seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) spawn_rivers() // deep space ruins @@ -55,7 +55,7 @@ SUBSYSTEM_DEF(mapping) else space_zlevels += i - seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates) + seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates) loading_ruins = FALSE repopulate_sorted_areas() // Set up Z-level transistions. @@ -141,7 +141,8 @@ SUBSYSTEM_DEF(mapping) var/players = GLOB.clients.len var/list/mapvotes = list() //count votes - if(global.config.allow_map_voting) + var/amv = CONFIG_GET(flag/allow_map_voting) + if(amv) for (var/client/c in GLOB.clients) var/vote = c.prefs.preferred_map if (!vote) @@ -174,7 +175,7 @@ SUBSYSTEM_DEF(mapping) mapvotes.Remove(map) continue - if(global.config.allow_map_voting) + if(amv) mapvotes[map] = mapvotes[map]*VM.voteweight var/pickedmap = pickweight(mapvotes) diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm index 4e58212b44..463b82b13e 100644 --- a/code/controllers/subsystem/minimap.dm +++ b/code/controllers/subsystem/minimap.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(minimap) /datum/controller/subsystem/minimap/Initialize(timeofday) var/hash = md5(SSmapping.config.GetFullMapPath()) - if(config.generate_minimaps) + if(CONFIG_GET(flag/generate_minimaps)) if(hash == trim(file2text(hash_path()))) for(var/z in z_levels) //We have these files cached, let's register them register_asset("minimap_[z].png", fcopy_rsc(map_path(z))) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 87b06cd587..0b8fa750b6 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) - if (config.hub) + if (CONFIG_GET(flag/hub)) world.update_hub_visibility(TRUE) ..() @@ -21,16 +21,19 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun = src.currentrun var/round_started = SSticker.HasRoundStarted() + var/kick_inactive = CONFIG_GET(flag/kick_inactive) + var/afk_period + if(kick_inactive) + afk_period = CONFIG_GET(number/afk_period) for(var/I in currentrun) var/client/C = I //handle kicking inactive players - if(round_started && config.kick_inactive) - if(C.is_afk(config.afk_period)) - var/cmob = C.mob - if(!(isobserver(cmob) || (isdead(cmob) && C.holder))) - log_access("AFK: [key_name(C)]") - to_chat(C, "You have been inactive for more than [DisplayTimeText(config.afk_period)] and have been disconnected.") - qdel(C) + if(round_started && kick_inactive && C.is_afk(afk_period)) + var/cmob = C.mob + if(!(isobserver(cmob) || (isdead(cmob) && C.holder))) + log_access("AFK: [key_name(C)]") + to_chat(C, "You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.") + qdel(C) if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))) winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") @@ -40,7 +43,7 @@ SUBSYSTEM_DEF(server_maint) /datum/controller/subsystem/server_maint/Shutdown() kick_clients_in_lobby("The round came to an end with you in the lobby.", TRUE) //second parameter ensures only afk clients are kicked - var/server = config.server + var/server = CONFIG_GET(string/server) for(var/thing in GLOB.clients) if(!thing) continue diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 2b1080049e..3ebc414a02 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -176,9 +176,9 @@ SUBSYSTEM_DEF(shuttle) Good luck.") return emergency = backup_shuttle - - if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay) - to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.") + var/srd = CONFIG_GET(number/shuttle_refuel_delay) + if(world.time - SSticker.round_start_time < srd) + to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - srd)] before trying again.") return switch(emergency.mode) diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/squeak.dm index 964d970e2b..0148011e8b 100644 --- a/code/controllers/subsystem/squeak.dm +++ b/code/controllers/subsystem/squeak.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(squeak) var/list/exposed_wires = list() /datum/controller/subsystem/squeak/Initialize(timeofday) - trigger_migration(config.mice_roundstart) + trigger_migration(CONFIG_GET(number/mice_roundstart)) return ..() /datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 3932eada60..2a43d7a844 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -79,13 +79,13 @@ SUBSYSTEM_DEF(ticker) if(!GLOB.syndicate_code_response) GLOB.syndicate_code_response = generate_code_phrase() ..() - start_at = world.time + (config.lobby_countdown * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) /datum/controller/subsystem/ticker/fire() switch(current_state) if(GAME_STATE_STARTUP) if(Master.initializations_finished_with_no_players_logged_in) - start_at = world.time + (config.lobby_countdown * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. to_chat(world, "Welcome to [station_name()]!") @@ -207,7 +207,7 @@ SUBSYSTEM_DEF(ticker) else mode.announce() - if(!config.ooc_during_round) + if(!CONFIG_GET(flag/ooc_during_round)) toggle_ooc(FALSE) // Turn it off CHECK_TICK @@ -429,7 +429,7 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK - if(config.cross_allowed) + if(CONFIG_GET(string/cross_server_address)) send_news_report() CHECK_TICK @@ -495,7 +495,8 @@ SUBSYSTEM_DEF(ticker) to_chat(world, "Tip of the round: [html_encode(m)]") /datum/controller/subsystem/ticker/proc/check_queue() - if(!queued_players.len || !config.hard_popcap) + var/hpc = CONFIG_GET(number/hard_popcap) + if(!queued_players.len || !hpc) return queue_delay++ @@ -503,7 +504,7 @@ SUBSYSTEM_DEF(ticker) switch(queue_delay) if(5) //every 5 ticks check if there is a slot available - if(living_player_count() < config.hard_popcap) + if(living_player_count() < hpc) if(next_in_line && next_in_line.client) to_chat(next_in_line, "A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<") SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg')) @@ -517,7 +518,7 @@ SUBSYSTEM_DEF(ticker) queue_delay = 0 /datum/controller/subsystem/ticker/proc/check_maprotate() - if (!config.maprotation) + if (!CONFIG_GET(flag/maprotation)) return if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall()) return @@ -527,7 +528,7 @@ SUBSYSTEM_DEF(ticker) maprotatechecked = 1 //map rotate chance defaults to 75% of the length of the round (in minutes) - if (!prob((world.time/600)*config.maprotatechancedelta)) + if (!prob((world.time/600)*CONFIG_GET(number/maprotatechancedelta))) return INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate) @@ -687,7 +688,7 @@ SUBSYSTEM_DEF(ticker) return if(!delay) - delay = config.round_end_countdown * 10 + delay = CONFIG_GET(number/round_end_countdown) * 10 var/skip_delay = check_rights() if(delay_end && !skip_delay) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 0ea16b32d8..d377329312 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/fire() //called by master_controller if(mode) - time_remaining = round((started_time + config.vote_period - world.time)/10) + time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10) if(time_remaining < 0) result() @@ -54,7 +54,7 @@ SUBSYSTEM_DEF(vote) if(votes > greatest_votes) greatest_votes = votes //default-vote for everyone who didn't vote - if(!config.vote_no_default && choices.len) + if(!CONFIG_GET(flag/default_no_vote) && choices.len) var/list/non_voters = GLOB.directory.Copy() non_voters -= voted for (var/non_voter_ckey in non_voters) @@ -146,7 +146,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/submit_vote(vote) if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) + if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder) return 0 if(!(usr.ckey in voted)) if(vote && 1<=vote && vote<=choices.len) @@ -158,7 +158,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key) if(!mode) if(started_time) - var/next_allowed_time = (started_time + config.vote_delay) + var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) if(mode) to_chat(usr, "There is already a vote in progress! please wait for it to finish.") return 0 @@ -198,8 +198,9 @@ SUBSYSTEM_DEF(vote) if(mode == "custom") text += "\n[question]" log_vote(text) - to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(config.vote_period)] to vote.") - time_remaining = round(config.vote_period/10) + var/vp = CONFIG_GET(number/vote_period) + to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") + time_remaining = round(vp/10) for(var/c in GLOB.clients) var/client/C = c var/datum/action/vote/V = new @@ -238,20 +239,22 @@ SUBSYSTEM_DEF(vote) else . += "

Start a vote: