diff --git a/SQL/beestation_schema.sql b/SQL/beestation_schema.sql index a89a7000b8be3..773a6212a0079 100644 --- a/SQL/beestation_schema.sql +++ b/SQL/beestation_schema.sql @@ -147,6 +147,12 @@ CREATE TABLE IF NOT EXISTS `SS13_characters` ( `joblessrole` TINYINT(4) UNSIGNED, `job_preferences` MEDIUMTEXT COLLATE 'utf8mb4_general_ci', `all_quirks` MEDIUMTEXT COLLATE 'utf8mb4_general_ci', + `quirk_prosthetic_limb_location` VARCHAR(64) COLLATE 'utf8mb4_general_ci', + `quirk_phobia` VARCHAR(64) COLLATE 'utf8mb4_general_ci', + `quirk_multilingual_language` VARCHAR(64) COLLATE 'utf8mb4_general_ci', + `quirk_smoker_cigarettes` VARCHAR(64) COLLATE 'utf8mb4_general_ci', + `quirk_junkie_drug` VARCHAR(64) COLLATE 'utf8mb4_general_ci', + `quirk_alcohol_type` VARCHAR(64) COLLATE 'utf8mb4_general_ci', `equipped_gear` MEDIUMTEXT COLLATE 'utf8mb4_general_ci', `role_preferences` MEDIUMTEXT COLLATE 'utf8mb4_general_ci', `randomize` MEDIUMTEXT COLLATE 'utf8mb4_general_ci', @@ -491,7 +497,7 @@ CREATE TABLE IF NOT EXISTS `SS13_schema_revision` ( `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`major`,`minor`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (7, 0); +INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (7, 2); diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index 54fd94bf1d2c9..0b634e2470bd5 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,13 +1,29 @@ Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. -The latest database version is 7.1; The query to update the schema revision table is: +The latest database version is 7.2; The query to update the schema revision table is: -INSERT INTO `schema_revision` (`major`, `minor`) VALUES (7, 1); +INSERT INTO `schema_revision` (`major`, `minor`) VALUES (7, 2); or -INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (7, 1); +INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (7, 2); In any query remember to add a prefix to the table names if you use one. + +----------------------------------------------------- + +----------------------------------------------------- + +Version 7.2, 20 December 2023, by that0neperson and Absolucy +Added customization for quirks. + +ALTER TABLE `SS13_characters` + ADD COLUMN IF NOT EXISTS `quirk_prosthetic_limb_location` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `all_quirks`, + ADD COLUMN IF NOT EXISTS `quirk_phobia` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `quirk_prosthetic_limb_location`, + ADD COLUMN IF NOT EXISTS `quirk_multilingual_language` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `quirk_phobia`, + ADD COLUMN IF NOT EXISTS `quirk_smoker_cigarettes` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `quirk_multilingual_language` , + ADD COLUMN IF NOT EXISTS `quirk_junkie_drug` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `quirk_smoker_cigarettes`, + ADD COLUMN IF NOT EXISTS `quirk_alcohol_type` VARCHAR(64) COLLATE 'utf8mb4_general_ci' AFTER `quirk_junkie_drug`; + ----------------------------------------------------- ----------------------------------------------------- diff --git a/beestation.dme b/beestation.dme index 4645da2cd5c4c..5708d1de225f5 100644 --- a/beestation.dme +++ b/beestation.dme @@ -2299,12 +2299,19 @@ #include "code\modules\client\preferences\entries\character\jobless_role.dm" #include "code\modules\client\preferences\entries\character\names.dm" #include "code\modules\client\preferences\entries\character\pda.dm" +#include "code\modules\client\preferences\entries\character\quirks.dm" #include "code\modules\client\preferences\entries\character\random.dm" #include "code\modules\client\preferences\entries\character\security_department.dm" #include "code\modules\client\preferences\entries\character\skin_tone.dm" #include "code\modules\client\preferences\entries\character\species.dm" #include "code\modules\client\preferences\entries\character\underwear_color.dm" #include "code\modules\client\preferences\entries\character\uplink_location.dm" +#include "code\modules\client\preferences\entries\character\quirks\alcoholic.dm" +#include "code\modules\client\preferences\entries\character\quirks\junkie.dm" +#include "code\modules\client\preferences\entries\character\quirks\multilingual.dm" +#include "code\modules\client\preferences\entries\character\quirks\phobia.dm" +#include "code\modules\client\preferences\entries\character\quirks\prosthetic.dm" +#include "code\modules\client\preferences\entries\character\quirks\smoker.dm" #include "code\modules\client\preferences\entries\character\species_features\apid.dm" #include "code\modules\client\preferences\entries\character\species_features\basic.dm" #include "code\modules\client\preferences\entries\character\species_features\ethereal.dm" diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm index 851d6c74a37c8..ceb84e9dca1d9 100644 --- a/code/__DEFINES/language.dm +++ b/code/__DEFINES/language.dm @@ -46,3 +46,20 @@ #define LANGUAGE_MULTILINGUAL "multilingual" #define LANGUAGE_EMP "emp" #define LANGUAGE_HOLOPARA "holoparasite" + +// Languages available from Multilingual +GLOBAL_LIST_INIT(multilingual_language_list, typecacheof(list( + /datum/language/apidite, + /datum/language/beachbum, + /datum/language/buzzwords, + /datum/language/calcic, + /datum/language/draconic, + /datum/language/moffic, + /datum/language/monkey, + /datum/language/piratespeak, + /datum/language/shadowtongue, + /datum/language/slime, + /datum/language/sylvan, + /datum/language/terrum, + /datum/language/uncommon +))) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 125752601c5f9..0ecfcf6461f78 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -148,6 +148,26 @@ #define TRAUMA_RESILIENCE_MAGIC 4 //! Curable only with magic #define TRAUMA_RESILIENCE_ABSOLUTE 5 //! This is here to stay +GLOBAL_LIST_INIT(available_random_trauma_list, list( + "spiders" = 5, + "space" = 2, + "security" = 5, + "clowns" = 5, + "greytide" = 5, + "lizards" = 5, + "skeletons" = 5, + "snakes" = 5, + "robots" = 4, + "doctors" = 4, + "authority" = 5, + "the supernatural" = 5, + "aliens" = 5, + "strangers" = 5, + "birds" = 5, + "falling" = 5, + "anime" = 5 +)) + /// This trauma cannot be cured through "special" means, such as nanites or viruses. #define TRAUMA_SPECIAL_CURE_PROOF (1<<0) /// This trauma transfers on cloning. diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index a4a3b0bac9163..2780fe928dfdd 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -20,7 +20,7 @@ * * make sure you add an update to the schema_version stable in the db changelog */ -#define DB_MINOR_VERSION 1 +#define DB_MINOR_VERSION 2 //! ## Timing subsystem diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index a0d4e30d8c62a..0cc40beca53d7 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -374,3 +374,31 @@ GLOBAL_LIST_INIT(pAI_faces_icons, list( "Sunglasses" = image(icon = 'icons/obj/aicards.dmi', icon_state = "pai-sunglasses"), "What" = image(icon = 'icons/obj/aicards.dmi', icon_state = "pai-what"), )) + +GLOBAL_LIST_INIT(smoker_cigarettes, list( + /obj/item/storage/fancy/cigarettes, + /obj/item/storage/fancy/cigarettes/cigpack_midori, + /obj/item/storage/fancy/cigarettes/cigpack_uplift, + /obj/item/storage/fancy/cigarettes/cigpack_robust, + /obj/item/storage/fancy/cigarettes/cigpack_robustgold, + /obj/item/storage/fancy/cigarettes/cigpack_carp +)) + +GLOBAL_LIST_INIT(alcoholic_bottles, list( + /obj/item/reagent_containers/food/drinks/bottle/ale, + /obj/item/reagent_containers/food/drinks/bottle/beer, + /obj/item/reagent_containers/food/drinks/bottle/gin, + /obj/item/reagent_containers/food/drinks/bottle/whiskey, + /obj/item/reagent_containers/food/drinks/bottle/vodka, + /obj/item/reagent_containers/food/drinks/bottle/rum, + /obj/item/reagent_containers/food/drinks/bottle/applejack +)) + +GLOBAL_LIST_INIT(junkie_drugs, list( + /datum/reagent/drug/crank, + /datum/reagent/drug/krokodil, + /datum/reagent/medicine/morphine, + /datum/reagent/drug/happiness, + /datum/reagent/drug/methamphetamine, + /datum/reagent/drug/ketamine +)) diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 955ebd9de1644..1875d6872b77b 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -10,10 +10,9 @@ SUBSYSTEM_DEF(traumas) /datum/controller/subsystem/traumas/Initialize() //phobia types is to pull from randomly for brain traumas, e.g. conspiracies is for special assignment only + //defined in __DEFINES/mobs.dm //5 is the default weight, lower it for more punishing phobias - phobia_types = sort_list(list("spiders" = 5, "space" = 2, "security" = 5, "clowns" = 5, "greytide" = 5, "lizards" = 5, - "skeletons" = 5, "snakes" = 5, "robots" = 4, "doctors" = 4, "authority" = 5, "the supernatural" = 5, - "aliens" = 5, "strangers" = 5, "birds" = 5, "falling" = 5, "anime" = 5)) + phobia_types = sort_list(GLOB.available_random_trauma_list) phobia_words = list( "spiders" = strings(PHOBIA_FILE, "spiders"), diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index 8b2082406f550..cc6e15cfa8574 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -8,7 +8,7 @@ var/icon var/value = 0 var/list/restricted_mobtypes = list(/mob/living/carbon/human) //specifies valid mobtypes, have a good reason to change this - var/list/restricted_species //specifies valid species, use /datum/species/ + var/list/restricted_species //specifies valid species, use /datum/species/ var/species_whitelist = TRUE //whether restricted_species is a whitelist or a blacklist var/gain_text var/lose_text @@ -134,6 +134,12 @@ return "None" return dat.Join("
") +/datum/quirk/proc/read_choice_preference(path) + var/client/qclient = GLOB.directory[ckey(quirk_holder.key)] + var/pref = qclient?.prefs.read_character_preference(path) + if(pref != "Random") + return pref + /* Commented version of Nearsighted to help you add your own quirks diff --git a/code/datums/traits/negative_quirk.dm b/code/datums/traits/negative_quirk.dm index 29f816597c20d..b6c1883cbb30b 100644 --- a/code/datums/traits/negative_quirk.dm +++ b/code/datums/traits/negative_quirk.dm @@ -144,7 +144,6 @@ if(is_species(H, /datum/species/moth) && prob(50)) heirloom_type = /obj/item/flashlight/lantern/heirloom_moth else - //surely there is a better way to do this switch(quirk_holder.assigned_role) //Service jobs if(JOB_NAME_CLOWN) @@ -427,7 +426,7 @@ var/slot_string = "limb" /datum/quirk/prosthetic_limb/on_spawn() - var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + var/limb_slot = read_choice_preference(/datum/preference/choiced/quirk/prosthetic_limb_location) || pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) // default to random var/mob/living/carbon/human/H = quirk_target var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot) var/obj/item/bodypart/prosthetic @@ -542,6 +541,7 @@ /datum/quirk/junkie/on_spawn() var/mob/living/carbon/human/H = quirk_target + reagent_type = reagent_type || read_choice_preference(/datum/preference/choiced/quirk/junkie_drug) if (!reagent_type) reagent_type = pick(drug_list) reagent_instance = new reagent_type() @@ -603,7 +603,9 @@ process = TRUE /datum/quirk/junkie/smoker/on_spawn() - drug_container_type = pick(/obj/item/storage/fancy/cigarettes, + drug_container_type = read_choice_preference(/datum/preference/choiced/quirk/smoker_cigarettes) + if(!drug_container_type) + drug_container_type = pick(/obj/item/storage/fancy/cigarettes, /obj/item/storage/fancy/cigarettes/cigpack_midori, /obj/item/storage/fancy/cigarettes/cigpack_uplift, /obj/item/storage/fancy/cigarettes/cigpack_robust, @@ -648,7 +650,9 @@ var/obj/item/reagent_containers/food/drinks/bottle/drink_instance /datum/quirk/alcoholic/on_spawn() - drink_instance = pick(drink_types) + drink_instance = read_choice_preference(/datum/preference/choiced/quirk/alcohol_type) + if(!drink_instance) + drink_instance = pick(drink_types) drink_instance = new drink_instance() var/list/slots = list("in your backpack" = ITEM_SLOT_BACKPACK) var/mob/living/carbon/human/H = quirk_target @@ -709,7 +713,7 @@ var/trauma /datum/quirk/trauma/add() - trauma = new trauma_type + trauma = new trauma_type(read_choice_preference(/datum/preference/choiced/quirk/phobia)) var/mob/living/carbon/human/H = quirk_target H.gain_trauma(trauma, TRAUMA_RESILIENCE_ABSOLUTE) diff --git a/code/datums/traits/positive_quirk.dm b/code/datums/traits/positive_quirk.dm index b78664cc0e038..c9b71106f1148 100644 --- a/code/datums/traits/positive_quirk.dm +++ b/code/datums/traits/positive_quirk.dm @@ -139,7 +139,8 @@ //Credit To Yowii/Yoworii/Yorii for a much more streamlined method of language library building /datum/quirk/multilingual/add() - if(!known_language) + known_language = read_choice_preference(/datum/preference/choiced/quirk/multilingual_language) + if(!known_language) // default to random set_up_language() var/datum/language_holder/LH = quirk_holder.get_language_holder() LH.grant_language(known_language, TRUE, TRUE, LANGUAGE_MULTILINGUAL) diff --git a/code/modules/client/preferences/entries/character/quirks.dm b/code/modules/client/preferences/entries/character/quirks.dm new file mode 100644 index 0000000000000..bd2452590592c --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks.dm @@ -0,0 +1,32 @@ +/datum/preference/choiced/quirk + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + preference_type = PREFERENCE_CHARACTER + can_randomize = TRUE + abstract_type = /datum/preference/choiced/quirk + /// typepath of the quirk to be checked for (exact) + var/required_quirk + +/datum/preference/choiced/quirk/deserialize(input, datum/preferences/preferences) + // stupid, but if you have a better solution, then go ahead and write it + var/input_path = text2path(input) + if(ispath(input_path)) + return ..(input_path, preferences) + else + return ..(input, preferences) + +/datum/preference/choiced/quirk/create_default_value() + return "Random" + +/datum/preference/choiced/quirk/apply_to_human(mob/living/carbon/human/target, value) + return + +/datum/preference/choiced/quirk/is_accessible(datum/preferences/preferences, ignore_page = FALSE) + if (!..()) + return FALSE + var/datum/quirk/quirk = required_quirk + if(initial(quirk.name) in preferences.all_quirks) + return TRUE + return FALSE + +/datum/preference/choiced/quirk/init_possible_values() + return list("Random") diff --git a/code/modules/client/preferences/entries/character/quirks/alcoholic.dm b/code/modules/client/preferences/entries/character/quirks/alcoholic.dm new file mode 100644 index 0000000000000..849a1e15e4096 --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/alcoholic.dm @@ -0,0 +1,14 @@ +/datum/preference/choiced/quirk/alcohol_type + db_key = "quirk_alcohol_type" + required_quirk = /datum/quirk/alcoholic + +/datum/preference/choiced/quirk/alcohol_type/init_possible_values() + return ..() + GLOB.alcoholic_bottles + +/datum/preference/choiced/quirk/alcohol_type/compile_constant_data() + var/list/data = ..() + var/list/clean_names = list("Random" = "Random") + for(var/obj/item/reagent_containers/food/drinks/bottle/S as() in GLOB.alcoholic_bottles) + clean_names[S] = initial(S.name) + data[CHOICED_PREFERENCE_DISPLAY_NAMES] = clean_names + return data diff --git a/code/modules/client/preferences/entries/character/quirks/junkie.dm b/code/modules/client/preferences/entries/character/quirks/junkie.dm new file mode 100644 index 0000000000000..cfdcb83bab5b7 --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/junkie.dm @@ -0,0 +1,14 @@ +/datum/preference/choiced/quirk/junkie_drug + db_key = "quirk_junkie_drug" + required_quirk = /datum/quirk/junkie + +/datum/preference/choiced/quirk/junkie_drug/init_possible_values() + return ..() + GLOB.junkie_drugs + +/datum/preference/choiced/quirk/junkie_drug/compile_constant_data() + var/list/data = ..() + var/list/clean_names = list("Random" = "Random") + for(var/datum/reagent/drug/D as() in GLOB.junkie_drugs) + clean_names[D] = initial(D.name) + data[CHOICED_PREFERENCE_DISPLAY_NAMES] = clean_names + return data diff --git a/code/modules/client/preferences/entries/character/quirks/multilingual.dm b/code/modules/client/preferences/entries/character/quirks/multilingual.dm new file mode 100644 index 0000000000000..8815150c4257a --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/multilingual.dm @@ -0,0 +1,16 @@ +/datum/preference/choiced/quirk/multilingual_language + db_key = "quirk_multilingual_language" + required_quirk = /datum/quirk/multilingual + +/datum/preference/choiced/quirk/multilingual_language/init_possible_values() + return ..() + assoc_to_keys(GLOB.multilingual_language_list) + +/datum/preference/choiced/quirk/multilingual_language/compile_constant_data() + var/list/data = ..() + var/list/clean_names = list("Random" = "Random") + for(var/datum/language/L as() in GLOB.multilingual_language_list) + clean_names[L] = initial(L.name) + + data[CHOICED_PREFERENCE_DISPLAY_NAMES] = clean_names + + return data diff --git a/code/modules/client/preferences/entries/character/quirks/phobia.dm b/code/modules/client/preferences/entries/character/quirks/phobia.dm new file mode 100644 index 0000000000000..6ce6dfbb721c5 --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/phobia.dm @@ -0,0 +1,6 @@ +/datum/preference/choiced/quirk/phobia + db_key = "quirk_phobia" + required_quirk = /datum/quirk/trauma + +/datum/preference/choiced/quirk/phobia/init_possible_values() + return ..() + assoc_to_keys(GLOB.available_random_trauma_list) diff --git a/code/modules/client/preferences/entries/character/quirks/prosthetic.dm b/code/modules/client/preferences/entries/character/quirks/prosthetic.dm new file mode 100644 index 0000000000000..6306239e3490e --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/prosthetic.dm @@ -0,0 +1,19 @@ +/datum/preference/choiced/quirk/prosthetic_limb_location + db_key = "quirk_prosthetic_limb_location" + required_quirk = /datum/quirk/prosthetic_limb + +/datum/preference/choiced/quirk/prosthetic_limb_location/init_possible_values() + return ..() + list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + +/datum/preference/choiced/quirk/prosthetic_limb_location/compile_constant_data() + var/list/data = ..() + + data[CHOICED_PREFERENCE_DISPLAY_NAMES] = list( + "Random" = "Random", + BODY_ZONE_L_ARM = "Left Arm", + BODY_ZONE_R_ARM = "Right Arm", + BODY_ZONE_L_LEG = "Left Leg", + BODY_ZONE_R_LEG = "Right Leg", + ) + + return data diff --git a/code/modules/client/preferences/entries/character/quirks/smoker.dm b/code/modules/client/preferences/entries/character/quirks/smoker.dm new file mode 100644 index 0000000000000..02e54661ebbfa --- /dev/null +++ b/code/modules/client/preferences/entries/character/quirks/smoker.dm @@ -0,0 +1,16 @@ +/datum/preference/choiced/quirk/smoker_cigarettes + db_key = "quirk_smoker_cigarettes" + required_quirk = /datum/quirk/junkie/smoker + +/datum/preference/choiced/quirk/smoker_cigarettes/init_possible_values() + return ..() + GLOB.smoker_cigarettes + +/datum/preference/choiced/quirk/smoker_cigarettes/compile_constant_data() + var/list/data = ..() + var/list/clean_names = list("Random" = "Random") + for(var/obj/item/storage/fancy/cigarettes/S as() in GLOB.smoker_cigarettes) + clean_names[S] = initial(S.name) + + data[CHOICED_PREFERENCE_DISPLAY_NAMES] = clean_names + + return data diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/custom_quirk.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/custom_quirk.tsx new file mode 100644 index 0000000000000..9a09ee5281725 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/custom_quirk.tsx @@ -0,0 +1,31 @@ +import { FeatureChoiced, FeatureButtonedDropdownInput } from '../base'; + +export const quirk_prosthetic_limb_location: FeatureChoiced = { + name: 'Prosthetic Limb Location', + component: FeatureButtonedDropdownInput, +}; + +export const quirk_phobia: FeatureChoiced = { + name: 'Phobia Type', + component: FeatureButtonedDropdownInput, +}; + +export const quirk_multilingual_language: FeatureChoiced = { + name: 'Second Language', + component: FeatureButtonedDropdownInput, +}; + +export const quirk_smoker_cigarettes: FeatureChoiced = { + name: 'Type Of Cigarettes', + component: FeatureButtonedDropdownInput, +}; + +export const quirk_junkie_drug: FeatureChoiced = { + name: 'Drug Addiction', + component: FeatureButtonedDropdownInput, +}; + +export const quirk_alcohol_type: FeatureChoiced = { + name: 'Type Of Alcohol', + component: FeatureButtonedDropdownInput, +};