From 34005d4f623da5d40884a3c8ccee0dae5f4817f9 Mon Sep 17 00:00:00 2001 From: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:48:15 -0500 Subject: [PATCH 1/8] Update poly.dm Makes poly speak once every 2.5m instead of once every 5s on avg Signed-off-by: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> --- code/modules/mob/living/basic/pets/parrot/poly.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index f825788decd98..54077bed80da4 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -16,7 +16,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." gold_core_spawnable = NO_SPAWN - speech_probability_rate = 13 + speech_probability_rate = 0.33 /// Callback to save our memory at the end of the round. var/datum/callback/roundend_callback = null From 22ed84c1d53e5fd41ab886381693d88302279db9 Mon Sep 17 00:00:00 2001 From: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:42:09 -0500 Subject: [PATCH 2/8] adds old default value + dopp edit comment Signed-off-by: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> --- code/modules/mob/living/basic/pets/parrot/poly.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index 54077bed80da4..b735fc370f2d8 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -16,7 +16,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." gold_core_spawnable = NO_SPAWN - speech_probability_rate = 0.33 + speech_probability_rate = 0.33 /// DEFAULT: 15. Doppler Edit. /// Callback to save our memory at the end of the round. var/datum/callback/roundend_callback = null From 8c03592b56a3e2120abca9df5ec62e04760e0fd8 Mon Sep 17 00:00:00 2001 From: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:42:41 -0500 Subject: [PATCH 3/8] Update poly.dm Signed-off-by: Omega_DarkPotato <66705879+OmegaDarkPotato@users.noreply.github.com> --- code/modules/mob/living/basic/pets/parrot/poly.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index b735fc370f2d8..01aabe51e847b 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -16,7 +16,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." gold_core_spawnable = NO_SPAWN - speech_probability_rate = 0.33 /// DEFAULT: 15. Doppler Edit. + speech_probability_rate = 0.33 /// DEFAULT: 13. Doppler Edit. /// Callback to save our memory at the end of the round. var/datum/callback/roundend_callback = null From d327ccf608dbcc879fc97c6b62aecf463045a23a Mon Sep 17 00:00:00 2001 From: Nerevar <12636964+Nerev4r@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:00:20 -0700 Subject: [PATCH 4/8] Update poly.dm Signed-off-by: Nerevar <12636964+Nerev4r@users.noreply.github.com> --- code/modules/mob/living/basic/pets/parrot/poly.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index 01aabe51e847b..b1a8ca5770a5b 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -16,7 +16,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." gold_core_spawnable = NO_SPAWN - speech_probability_rate = 0.33 /// DEFAULT: 13. Doppler Edit. + speech_probability_rate = 0.33 /// DOPPLER EDIT CHANGE - DEFAULT: 13 /// Callback to save our memory at the end of the round. var/datum/callback/roundend_callback = null From 1c84375bba23f82539c37da50422f5456f7c06c0 Mon Sep 17 00:00:00 2001 From: Nerevar <12636964+Nerev4r@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:01:11 -0700 Subject: [PATCH 5/8] Update poly.dm Signed-off-by: Nerevar <12636964+Nerev4r@users.noreply.github.com> --- code/modules/mob/living/basic/pets/parrot/poly.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index b1a8ca5770a5b..fb79c0d73b9b8 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -16,7 +16,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." gold_core_spawnable = NO_SPAWN - speech_probability_rate = 0.33 /// DOPPLER EDIT CHANGE - DEFAULT: 13 + speech_probability_rate = 0.33 // DOPPLER EDIT CHANGE - DEFAULT: 13 /// Callback to save our memory at the end of the round. var/datum/callback/roundend_callback = null From 929bfbd9a697b15e7dd9b83481534938d7a5c8fc Mon Sep 17 00:00:00 2001 From: Nerevar <12636964+Nerev4r@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:11:41 -0700 Subject: [PATCH 6/8] yeah i guess --- .../non_species_specific/avian/avian_snouts.dmi | Bin 507 -> 507 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modular_doppler/modular_customization/accessories/icons/non_species_specific/avian/avian_snouts.dmi b/modular_doppler/modular_customization/accessories/icons/non_species_specific/avian/avian_snouts.dmi index 9d5e5a612e5961952c1ca8c044f28ce6df7bc180..c7c30341b88dd63faf99584e2a086401bb4cfc32 100644 GIT binary patch delta 37 vcmV+=0NVfi1N#Gz`x-il9P^Vh)2U;+vVyCh3pm;VQbv`=0?}l2lNABxUCj}j delta 37 vcmV+=0NVfi1N#Gz`x^Oy9Mh9B)2U&$vVyCh3pmOF`FoV4$pCU;lNABxcia-j From 6ef0423b0b02c65695583e67da91d2435eb49abe Mon Sep 17 00:00:00 2001 From: Nerevar <12636964+Nerev4r@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:22:49 -0700 Subject: [PATCH 7/8] when i was sad i fell for you --- .../icons/insectoid/insect_snouts.dmi | Bin 353 -> 355 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modular_doppler/modular_customization/accessories/icons/insectoid/insect_snouts.dmi b/modular_doppler/modular_customization/accessories/icons/insectoid/insect_snouts.dmi index 44cf0131f5d7a3e7c979a977cf1b4275cecbe834..e2ec62e78e5cfd6bfe9a584cee73faa147c30478 100644 GIT binary patch delta 39 xcmV+?0NDTG0^ Date: Sun, 15 Dec 2024 20:15:48 +0100 Subject: [PATCH 8/8] Implements Bitrunner Prefs Disks (Feat. Quirks & Evil Hacks) (without the blowing up part) (#243) * redraw that horse as penance for rolling worst blunt imaginable * THERE we go --- .../bitrunning/server/obj_generation.dm | 21 ++++ .../code/disks/prefs_disk.dm | 119 ++++++++++++++++++ .../bitrunner_outfit_override.dm | 4 + .../bitrunning_prefs_disks/readme.md | 47 +++++++ tgstation.dme | 2 + 5 files changed, 193 insertions(+) create mode 100644 modular_doppler/bitrunning_prefs_disks/code/disks/prefs_disk.dm create mode 100644 modular_doppler/bitrunning_prefs_disks/code/outfit_overrides/bitrunner_outfit_override.dm create mode 100644 modular_doppler/bitrunning_prefs_disks/readme.md diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index 9f473980bbf96..9d63e153eb347 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -145,6 +145,9 @@ to_chat(neo, span_warning("This domain forbids the use of [english_list(import_ban)], your disk [english_list(disk_ban)] will not be granted!")) var/failed = FALSE + //DOPPLER EDIT ADDITION BEGIN - BITRUNNING_PREFS_DISKS - Track if we've used multiple avatar preference disks, for avoiding overrides and displaying the failure message. + var/duplicate_prefs = FALSE + //DOPPLER EDIT ADDITION END // We don't need to bother going over the disks if neither of the types can be used. if(domain_forbids_spells && domain_forbids_items) @@ -175,6 +178,24 @@ avatar.put_in_hands(new item_disk.granted_item()) + //DOPPLER EDIT ADDITION BEGIN - BITRUNNING_PREFS_DISKS - Handles our avatar preference disks, if present. + if(istype(disk, /obj/item/bitrunning_disk/preferences)) + var/obj/item/bitrunning_disk/preferences/prefs_disk = disk + var/datum/preferences/avatar_preference = prefs_disk.chosen_preference + + if(isnull(avatar_preference) || duplicate_prefs) + failed = TRUE + continue + + if(!domain_forbids_spells) + avatar_preference.safe_transfer_prefs_to(avatar) + SSquirks.AssignQuirks(avatar, prefs_disk.mock_client) + if(!domain_forbids_items && prefs_disk.include_loadout) + avatar.equip_outfit_and_loadout(/datum/outfit, avatar_preference) + + duplicate_prefs = TRUE + //DOPPLER EDIT ADDITION END + if(failed) to_chat(neo, span_warning("One of your disks failed to load. Check for duplicate or inactive disks.")) diff --git a/modular_doppler/bitrunning_prefs_disks/code/disks/prefs_disk.dm b/modular_doppler/bitrunning_prefs_disks/code/disks/prefs_disk.dm new file mode 100644 index 0000000000000..6079e81de4beb --- /dev/null +++ b/modular_doppler/bitrunning_prefs_disks/code/disks/prefs_disk.dm @@ -0,0 +1,119 @@ +/** + * Bitrunning tech disks which let you load a custom character preference for your bit avatar. + * This uses a preference selected from your character list. + * Optionally, this may include the loadout as well. + * + * For the sake of domain restrictions: + * - ability blocks block the application of character prefs. + * - item blocks block the application of character loadout. + */ +/obj/item/bitrunning_disk/preferences + name = "bitrunning program: personalized avatar" + desc = "A disk containing source code. It can be used to override your bit avatar's standard appearance. Further avatar disks will be ignored." + + // Allows it to be held in the pocket + w_class = WEIGHT_CLASS_SMALL + + /// Our chosen preference. + var/datum/preferences/chosen_preference + /// Whether we include the loadout as well. + var/include_loadout = FALSE + /// Mock client we use for forwarding to quirk assignment (beware, evil hacks). + var/datum/prefs_disk_client_interface/mock_client + +/obj/item/bitrunning_disk/preferences/Initialize(mapload) + . = ..() + register_context() + +/obj/item/bitrunning_disk/preferences/examine(mob/user) + . = ..() + if(isnull(chosen_preference)) + return + + . += span_info("Loadout application is currently [include_loadout ? "enabled" : "disabled"].") + . += span_notice("Ctrl-click to toggle loadout application.") + +/obj/item/bitrunning_disk/preferences/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + var/result = NONE + if(isnull(chosen_preference) && (held_item == src)) + context[SCREENTIP_CONTEXT_LMB] = "Select avatar" + result = CONTEXTUAL_SCREENTIP_SET + if(!isturf(src.loc)) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Toggle loadout" + result = CONTEXTUAL_SCREENTIP_SET + + return result + +/obj/item/bitrunning_disk/preferences/Destroy() + QDEL_NULL(chosen_preference) + QDEL_NULL(mock_client) + return ..() + +/obj/item/bitrunning_disk/preferences/attack_self(mob/user, modifiers) + . = ..() + + if(isnull(user.client) || chosen_preference) + return + + var/list/character_profiles = user.client.prefs?.create_character_profiles() + if(isnull(character_profiles) || !length(character_profiles)) + return + + var/choice = tgui_input_list(user, message = "Select a character", title = "Bitrunning Avatar", items = character_profiles) + if(isnull(choice) || !user.is_holding(src)) + return + + choice_made = choice + chosen_preference = new(user.client) + chosen_preference.load_character(character_profiles.Find(choice)) + + // Perform our evil hacks + if(isnull(mock_client)) + mock_client = new + mock_client.prefs = chosen_preference + // Done loading from the client, so replace reference to the real client + chosen_preference.parent = mock_client + + balloon_alert(user, "avatar set!") + playsound(user, 'sound/items/click.ogg', 50, TRUE) + +/obj/item/bitrunning_disk/preferences/item_ctrl_click(mob/user) + if(isturf(src.loc)) // If on a turf, we skip to dragging + return NONE + if(isnull(chosen_preference)) + balloon_alert(user, "set preference first!") + return CLICK_ACTION_BLOCKING + include_loadout = !include_loadout + balloon_alert(user, include_loadout ? "loadout enabled!" : "loadout disabled!") + + // High frequency range when enabled, low when disabled. More tactile. + var/toggle_frequency = include_loadout ? rand(45000, 55000) : rand(32000, 42000) + playsound(user, 'sound/items/click.ogg', 50, TRUE, frequency = toggle_frequency) + + return CLICK_ACTION_SUCCESS + +/** + * Allows for ordering of the prefs disk. + */ +/datum/orderable_item/bitrunning_tech/prefs_disk + cost_per_order = 1000 + purchase_path = /obj/item/bitrunning_disk/preferences + desc = "This disk contains a program that lets you load in custom bit avatars." + +/** + * Evil hack that allows us to assign quirks without needing to forward a real client. + * Using this instead of the normal mock client allows us to include only what we need without editing the base, + * or interfering with things like `mock_client_uid`. + * + * Much the same, this should match the interface of /client wherever necessary. + */ +/datum/prefs_disk_client_interface + /// Player preferences datum for the client + var/datum/preferences/prefs + + /// The mob the client controls + var/mob/mob + +/// We don't actually care about award status, but we don't want it to runtime due to not existing. +/datum/prefs_disk_client_interface/proc/get_award_status(achievement_type, mob/user, value = 1) + return 0 diff --git a/modular_doppler/bitrunning_prefs_disks/code/outfit_overrides/bitrunner_outfit_override.dm b/modular_doppler/bitrunning_prefs_disks/code/outfit_overrides/bitrunner_outfit_override.dm new file mode 100644 index 0000000000000..fbbf76ed1b12a --- /dev/null +++ b/modular_doppler/bitrunning_prefs_disks/code/outfit_overrides/bitrunner_outfit_override.dm @@ -0,0 +1,4 @@ + +// Spawns a single preferences disk to start with for all bitrunners. +/datum/outfit/job/bitrunner + r_pocket = /obj/item/bitrunning_disk/preferences diff --git a/modular_doppler/bitrunning_prefs_disks/readme.md b/modular_doppler/bitrunning_prefs_disks/readme.md new file mode 100644 index 0000000000000..b953df82da844 --- /dev/null +++ b/modular_doppler/bitrunning_prefs_disks/readme.md @@ -0,0 +1,47 @@ + + +SOON + +## Bitrunning Avatar Preference Disks + +Module ID: BITRUNNING_PREFS_DISKS + +### Description: + +Allows bitrunners to buy a personalized avatar disk, which lets them load in a given character preference, with all that entails. +This includes even quirks through evil hacks, and optionally loadouts. +Preference application and quirks are blocked if a domain blocks spells/abilities, loadouts are blocked if a domain blocks items. +The evil hacks this performs are using a barebones mock client to allow for quirk assignment without forwarding or affecting the real client. + + + +### TG Proc/File Changes: + +- `code/modules/bitrunning/server/obj_generation.dm`: `proc/stock_gear` + + +### Modular Overrides: + +- N/A + + +### Defines: + +- N/A + + +### Included files that are not contained in this module: + +- N/A + + +### Credits: 00-Steven + + \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index dee7b120891aa..e8e20c0a66b81 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6571,6 +6571,8 @@ #include "modular_doppler\autotransfer\autotransfer_config.dm" #include "modular_doppler\autotransfer\shuttle.dm" #include "modular_doppler\autotransfer\transfer_vote.dm" +#include "modular_doppler\bitrunning_prefs_disks\code\disks\prefs_disk.dm" +#include "modular_doppler\bitrunning_prefs_disks\code\outfit_overrides\bitrunner_outfit_override.dm" #include "modular_doppler\cell_component\code\cell_component.dm" #include "modular_doppler\colony_fabricator\code\cargo_packs.dm" #include "modular_doppler\colony_fabricator\code\colony_fabricator.dm"