From fe1d30fd2f50bf0a1ac57650d50ee56cb00d0557 Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Sat, 30 Jul 2022 12:14:02 +0100 Subject: [PATCH] Character-based rebindable custom emotes (#18506) * 1 * 2 * 3 * make it (mostly) work * character-based emotes * bump SQL version * where did you go little s * no more raw json * partial AA review * makes it not coded as stupidly * donor exclusive emotes 4-7 * ship it Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> * Update code/datums/keybindings/emote.dm Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> * spacings Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> --- SQL/paradise_schema.sql | 1 + SQL/updates/41-42.sql | 5 ++ code/__DEFINES/keybindings.dm | 1 + code/__DEFINES/misc.dm | 2 +- code/_globalvars/lists/keybindings.dm | 1 + code/datums/keybindings/emote.dm | 60 +++++++++++++++++++ .../login_processing/20-load_characters.dm | 4 +- code/modules/client/preference/character.dm | 30 ++++++++-- .../client/preference/link_processing.dm | 15 +++++ code/modules/client/preference/preferences.dm | 18 ++++++ config/example/config.toml | 2 +- 11 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 SQL/updates/41-42.sql diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index da7929e5f79..5ba166cac67 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -76,6 +76,7 @@ CREATE TABLE `characters` ( `hair_gradient_offset` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0,0', `hair_gradient_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', `hair_gradient_alpha` tinyint(3) UNSIGNED NOT NULL DEFAULT '255', + `custom_emotes` LONGTEXT COLLATE 'utf8mb4_unicode_ci' DEFAULT NULL, PRIMARY KEY (`id`), KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=125467 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/SQL/updates/41-42.sql b/SQL/updates/41-42.sql new file mode 100644 index 00000000000..b3e039eefa9 --- /dev/null +++ b/SQL/updates/41-42.sql @@ -0,0 +1,5 @@ +# Updating DB from 41-42 +# Adds characters.custom_emotes (longtext) ~S34N + +# Add column to characters +ALTER TABLE `characters` ADD COLUMN `custom_emotes` LONGTEXT COLLATE 'utf8mb4_unicode_ci' DEFAULT NULL AFTER `hair_gradient_alpha`; diff --git a/code/__DEFINES/keybindings.dm b/code/__DEFINES/keybindings.dm index 27f185bebdf..5523006b0f9 100644 --- a/code/__DEFINES/keybindings.dm +++ b/code/__DEFINES/keybindings.dm @@ -13,6 +13,7 @@ #define KB_CATEGORY_EMOTE_HUMAN 13 #define KB_CATEGORY_EMOTE_SILICON 14 #define KB_CATEGORY_EMOTE_ANIMAL 15 +#define KB_CATEGORY_EMOTE_CUSTOM 16 #define KB_CATEGORY_UNSORTED 1000 ///Max length of a keypress command before it's considered to be a forged packet/bogus command diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index c1eaadcbcee..8aeb376a042 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -371,7 +371,7 @@ #define INVESTIGATE_BOMB "bombs" // The SQL version required by this version of the code -#define SQL_VERSION 41 +#define SQL_VERSION 42 // Vending machine stuff #define CAT_NORMAL 1 diff --git a/code/_globalvars/lists/keybindings.dm b/code/_globalvars/lists/keybindings.dm index 41358428f2f..45a90536abc 100644 --- a/code/_globalvars/lists/keybindings.dm +++ b/code/_globalvars/lists/keybindings.dm @@ -17,4 +17,5 @@ GLOBAL_LIST_INIT(keybindings_groups, list( "Alien Emote" = KB_CATEGORY_EMOTE_ALIEN, "Admin" = KB_CATEGORY_ADMIN, "Other" = KB_CATEGORY_UNSORTED, + "Custom Emotes (Character-based)" = KB_CATEGORY_EMOTE_CUSTOM, )) diff --git a/code/datums/keybindings/emote.dm b/code/datums/keybindings/emote.dm index dc57e54d118..ba2a86b08f0 100644 --- a/code/datums/keybindings/emote.dm +++ b/code/datums/keybindings/emote.dm @@ -592,3 +592,63 @@ /datum/keybinding/emote/simple_animal/pet/cat/purr linked_emote = /datum/emote/living/simple_animal/pet/cat/purr name = "Purr (Cat)" + +/datum/keybinding/custom + category = KB_CATEGORY_EMOTE_CUSTOM + var/default_emote_text = "Insert custom me emote text." + var/donor_exclusive = FALSE + +/datum/keybinding/custom/down(client/C) + . = ..() + if(!C.prefs?.active_character?.custom_emotes) //Checks the current character save for any custom emotes + return + + var/desired_emote = C.prefs.active_character.custom_emotes[name] //check the custom emotes list for this keybind name + + if(!desired_emote) + return + + C.mob.me_verb(html_decode(desired_emote)) //do the thing! + +/datum/keybinding/custom/can_use(client/C, mob/M) + if(donor_exclusive && !(C.donator_level || C.holder || C.prefs.unlock_content)) //is this keybind restricted to donors/byond members/admins, and are you one or not? + return + + return isliving(M) && ..() + +/datum/keybinding/custom/one + name = "Custom Emote 1" + +/datum/keybinding/custom/two + name = "Custom Emote 2" + +/datum/keybinding/custom/three + name = "Custom Emote 3" + +/datum/keybinding/custom/four + name = "Custom Emote 4" + donor_exclusive = TRUE + +/datum/keybinding/custom/five + name = "Custom Emote 5" + donor_exclusive = TRUE + +/datum/keybinding/custom/six + name = "Custom Emote 6" + donor_exclusive = TRUE + +/datum/keybinding/custom/seven + name = "Custom Emote 7" + donor_exclusive = TRUE + +/datum/keybinding/custom/eight + name = "Custom Emote 8" + donor_exclusive = TRUE + +/datum/keybinding/custom/nine + name = "Custom Emote 9" + donor_exclusive = TRUE + +/datum/keybinding/custom/ten + name = "Custom Emote 10" + donor_exclusive = TRUE diff --git a/code/modules/client/login_processing/20-load_characters.dm b/code/modules/client/login_processing/20-load_characters.dm index cc02ffc8144..aea96b26dda 100644 --- a/code/modules/client/login_processing/20-load_characters.dm +++ b/code/modules/client/login_processing/20-load_characters.dm @@ -57,7 +57,8 @@ hair_gradient, hair_gradient_offset, hair_gradient_colour, - hair_gradient_alpha + hair_gradient_alpha, + custom_emotes FROM characters WHERE ckey=:ckey"}, list( "ckey" = C.ckey )) @@ -89,6 +90,7 @@ if(character_loaded) // They have a character, set their active as their default slot C.prefs.active_character = C.prefs.character_saves[C.prefs.default_slot] + C.prefs.active_character.init_custom_emotes(C.prefs.active_character.custom_emotes) else // If we are here, they dont have a character. Lets make them a random one var/datum/character_save/CS = C.prefs.character_saves[1] // Get slot 1 diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 90bf8722766..5f0519e2203 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -98,6 +98,8 @@ var/h_grad_offset_y = 0 var/h_grad_colour = "#000000" var/h_grad_alpha = 255 + /// Custom emote text ("name" = "emote text") + var/list/custom_emotes = list() // Fuckery to prevent null characters /datum/character_save/New() @@ -183,7 +185,8 @@ hair_gradient=:h_grad_style, hair_gradient_offset=:h_grad_offset, hair_gradient_colour=:h_grad_colour, - hair_gradient_alpha=:h_grad_alpha + hair_gradient_alpha=:h_grad_alpha, + custom_emotes=:custom_emotes WHERE ckey=:ckey AND slot=:slot"}, list( // OH GOD SO MANY PARAMETERS @@ -240,6 +243,7 @@ "h_grad_offset" = "[h_grad_offset_x],[h_grad_offset_y]", "h_grad_colour" = h_grad_colour, "h_grad_alpha" = h_grad_alpha, + "custom_emotes" = json_encode(custom_emotes), "ckey" = C.ckey, "slot" = slot_number )) @@ -280,7 +284,7 @@ player_alt_titles, disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs, socks, body_accessory, gear, autohiss, - hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha) + hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes) VALUES (:ckey, :slot, :metadata, :name, :be_random_name, :gender, :age, :species, :language, @@ -307,7 +311,7 @@ :playertitlelist, :disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs, :socks, :body_accessory, :gearlist, :autohiss_mode, - :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha) + :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes) "}, list( // This has too many params for anyone to look at this without going insae "ckey" = C.ckey, @@ -364,7 +368,8 @@ "h_grad_style" = h_grad_style, "h_grad_offset" = "[h_grad_offset_x],[h_grad_offset_y]", "h_grad_colour" = h_grad_colour, - "h_grad_alpha" = h_grad_alpha + "h_grad_alpha" = h_grad_alpha, + "custom_emotes" = json_encode(custom_emotes), )) if(!query.warn_execute()) @@ -449,6 +454,7 @@ h_grad_offset_x = query.item[52] // parsed down below h_grad_colour = query.item[53] h_grad_alpha = query.item[54] + var/custom_emotes_tmp = query.item[55] //Sanitize var/datum/species/SP = GLOB.all_species[species] @@ -520,7 +526,9 @@ h_grad_offset_y = text2num(expl[2]) || 0 h_grad_colour = sanitize_hexcolor(h_grad_colour) h_grad_alpha = sanitize_integer(h_grad_alpha, 0, 255, initial(h_grad_alpha)) - loadout_gear = sanitize_json(loadout_gear) + loadout_gear = sanitize_json(loadout_gear) + custom_emotes_tmp = sanitize_json(custom_emotes_tmp) + custom_emotes = init_custom_emotes(custom_emotes_tmp) if(!player_alt_titles) player_alt_titles = new() @@ -2086,3 +2094,15 @@ from_db = FALSE return TRUE + +/datum/character_save/proc/init_custom_emotes(overrides) + custom_emotes = overrides + + for(var/datum/keybinding/custom/custom_emote in GLOB.keybindings) + var/emote_text = overrides && overrides[custom_emote.name] + if(!emote_text) + continue //we don't set anything without an override + + custom_emotes[custom_emote.name] = emote_text + + return custom_emotes diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index 886f38e1416..f627d0c5699 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -1186,6 +1186,21 @@ var/datum/keybinding/KB = kb keybindings_overrides[KB.name] = list() + else if(href_list["custom_emote_set"]) + var/datum/keybinding/custom/custom_emote_keybind = locateUID(href_list["custom_emote_set"]) + if(custom_emote_keybind) + var/emote_text = active_character.custom_emotes[custom_emote_keybind.name] + var/desired_emote = stripped_input(user, "Enter your custom emote text, 128 character limit.", "Custom Emote Setter", emote_text, max_length = 128) + if(desired_emote && (desired_emote != custom_emote_keybind.default_emote_text)) //don't let them save the default custom emote text + active_character.custom_emotes[custom_emote_keybind.name] = desired_emote + active_character.save(user) + + else if(href_list["custom_emote_reset"]) + var/datum/keybinding/custom/custom_emote_keybind = locateUID(href_list["custom_emote_reset"]) + if(custom_emote_keybind) + active_character.custom_emotes.Remove(custom_emote_keybind.name) + active_character.save(user) + init_keybindings(keybindings_overrides) save_preferences(user) //Ideally we want to save people's keybinds when they enter them diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index dd6d70296eb..d83fae77808 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -518,6 +518,24 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "[KB.name]" dat += "[keys_buttons][(length(keys) < 5) ? "+" : ""]" dat += "Reset to Default Clear" + if(KB.category == KB_CATEGORY_EMOTE_CUSTOM) + var/datum/keybinding/custom/custom_emote_keybind = kb + if(custom_emote_keybind.donor_exclusive && !(user.client.donator_level || user.client.holder || unlock_content)) + dat += "" + dat += "" + dat += "The use of this emote is restricted to patrons and byond members." + dat += "" + continue + dat += "" + dat += "" + var/emote_text = active_character.custom_emotes[custom_emote_keybind.name] //check if this emote keybind has an associated value on the character save + if(!emote_text) + dat += "[custom_emote_keybind.default_emote_text]" + else + dat += "\"[active_character.real_name] [emote_text]\"" + dat += "Change Text" + dat += "Reset to Default" + dat += "
" dat += "" dat += "
" diff --git a/config/example/config.toml b/config/example/config.toml index 7abae19b9e8..7a768e387b6 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -145,7 +145,7 @@ ipc_screens = [ # Enable/disable the database on a whole sql_enabled = false # SQL version. If this is a mismatch, round start will be delayed -sql_version = 41 +sql_version = 42 # SQL server address. Can be an IP or DNS name sql_address = "127.0.0.1" # SQL server port