From 6bb40816229e57a30f198ed1d5aedf2aef3ab151 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Fri, 30 Aug 2024 16:04:02 -0400 Subject: [PATCH 01/24] Tricolor proof of concept Integrated into the nice UI instead of using a dropdown, keeping the character menu much cleaner. Demo'd on snouts, albiet without any ingame effect or DNA features yet. --- code/modules/client/preferences.dm | 35 ++++++++++++++ .../modules/client/preferences/_preference.dm | 25 ++++++++++ .../customization/code/tri_color_prefs.dm | 33 +++++++++++++ tgstation.dme | 1 + .../preferences/features/base.tsx | 48 +++++++++++++++++++ .../mutant_tricolors.tsx | 6 +++ 6 files changed, 148 insertions(+) create mode 100644 modular_doppler/customization/code/tri_color_prefs.dm create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c078a23e89c24..833142ed34b03 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -267,6 +267,41 @@ GLOBAL_LIST_EMPTY(preferences_datums) return FALSE return TRUE + /// DOPPLER SHIFT ADDITION BEGIN + if ("set_tricolor_preference") + var/requested_preference_key = params["preference"] + var/index_key = params["value"] + + var/datum/preference/requested_preference = GLOB.preference_entries_by_key[requested_preference_key] + if (isnull(requested_preference)) + return FALSE + + if (!istype(requested_preference, /datum/preference/tri_color)) + return FALSE + + var/default_value_list = read_preference(requested_preference.type) + if (!islist(default_value_list)) + return FALSE + var/default_value = default_value_list[index_key] + + // Yielding + var/new_color = input( + usr, + "Select new color", + null, + default_value || COLOR_WHITE, + ) as color | null + + if (!new_color) + return FALSE + + default_value_list[index_key] = new_color + + if (!update_preference(requested_preference, default_value_list)) + return FALSE + + return TRUE + /// DOPPLER SHIFT ADDITION END for (var/datum/preference_middleware/preference_middleware as anything in middleware) var/delegation = preference_middleware.action_delegations[action] diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 2ed2405f37687..1b6067bb3c43f 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -460,6 +460,31 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) /datum/preference/color/is_valid(value) return findtext(value, GLOB.is_color) +/// DOPPLER SHIFT ADDITION BEGIN +/datum/preference/tri_color + abstract_type = /datum/preference/tri_color + +/datum/preference/tri_color/deserialize(input, datum/preferences/preferences) + var/list/input_colors = input + return list(sanitize_hexcolor(input_colors[1]), sanitize_hexcolor(input_colors[2]), sanitize_hexcolor(input_colors[3])) + +/datum/preference/tri_color/create_default_value() + return list("#[random_color()]", "#[random_color()]", "#[random_color()]") + +/datum/preference/tri_color/is_valid(list/value) + return islist(value) && value.len == 3 && (findtext(value[1], GLOB.is_color) && findtext(value[2], GLOB.is_color) && findtext(value[3], GLOB.is_color)) + +/datum/preference/tri_color/is_accessible(datum/preferences/preferences) + return ..() + +// Hey, you! +// Wondering how to get the colors from a tri-col pref? +// Look no further: list(sanitize_hexcolor(value[1]), sanitize_hexcolor(value[2]), sanitize_hexcolor(value[3])) +/datum/preference/tri_color/apply_to_human(mob/living/carbon/human/target, value) + if (type == abstract_type) + return ..() +/// DOPPLER SHIFT ADDITION END + /// A numeric preference with a minimum and maximum value /datum/preference/numeric /// The minimum value diff --git a/modular_doppler/customization/code/tri_color_prefs.dm b/modular_doppler/customization/code/tri_color_prefs.dm new file mode 100644 index 0000000000000..4a28a25d4da0e --- /dev/null +++ b/modular_doppler/customization/code/tri_color_prefs.dm @@ -0,0 +1,33 @@ +/// Snoot colors! +/datum/preference/tri_color/snout_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "snout_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/snout + +/datum/preference/tri_color/snout_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/snout_color/apply_to_human(mob/living/carbon/human/target, value) + //to_chat(world, "GWA: applying tricolor alpha ([value[1]],[value[2]],[value[3]])") + //world.log << "SCREAMING AS TRICOL ALPHA IS APPLIED MAYBE HOPEFULLY ([value[1]],[value[2]],[value[3]])" + target.dna.features["snout_color_1"] = value[1] + target.dna.features["snout_color_2"] = value[2] + target.dna.features["snout_color_3"] = value[3] + +/datum/preference/tri_color/snout_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the snoot selector too +/datum/preference/choiced/lizard_snout/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/snout_color::savefile_key + + return data diff --git a/tgstation.dme b/tgstation.dme index 68246d851194b..a67cf7298f1f0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6356,6 +6356,7 @@ #include "interface\fonts\spess_font.dm" #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" +#include "modular_doppler\customization\code\tri_color_prefs.dm" #include "modular_doppler\emotes\code\emotes.dm" #include "modular_doppler\emotes\code\added_emotes\animal_sounds.dm" #include "modular_doppler\emotes\code\added_emotes\human_things.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx index 452eb677519b1..6893f5acf203a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx @@ -95,6 +95,54 @@ export const FeatureColorInput = (props: FeatureValueProps) => { ); }; +/* DOPPLER SHIFT ADDITION BEGIN: tricolor inputs */ +export const FeatureTriColorInput = (props: FeatureValueProps) => { + const buttonFromValue = (index) => { + return ( + + + + ); + }; + return ( + + {buttonFromValue(0)} + {buttonFromValue(1)} + {buttonFromValue(2)} + + ); +}; +/* DOPPLER SHIFT ADDITION END */ + export type FeatureToggle = Feature; export const CheckboxInput = ( diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx new file mode 100644 index 0000000000000..15fccf338f7b7 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx @@ -0,0 +1,6 @@ +import { FeatureTriColorInput, FeatureColorInput, Feature } from '../base'; + +export const snout_color: Feature = { + name: 'Snout Color', + component: FeatureTriColorInput, +}; \ No newline at end of file From e0d7a9f7fbb9c79686ed0f1c2ac613f37a1afdc4 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Fri, 30 Aug 2024 17:51:42 -0400 Subject: [PATCH 02/24] Ghostrole character selection, Mk 1 Not perfect still; ashies will require additional effort to properly support, but we're getting closer --- code/modules/mob_spawn/mob_spawn.dm | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index 3337a15b441c5..4af39c20d148a 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -32,6 +32,8 @@ var/skin_tone /// Weakref to the mob this spawner created - just if you needed to do something with it. var/datum/weakref/spawned_mob_ref + /// DOPPLER SHIFT ADDITION: allowing players to have their current character loaded + var/allow_prefs = TRUE /obj/effect/mob_spawn/Initialize(mapload) . = ..() @@ -93,7 +95,20 @@ if(!ispath(outfit_override[outfit_var]) && !isnull(outfit_override[outfit_var])) CRASH("outfit_override var on [mob_name] spawner has incorrect values! it must be an assoc list with outfit \"var\" = path | null") outfit.vars[outfit_var] = outfit_override[outfit_var] - spawned_human.equipOutfit(outfit) + //spawned_human.equipOutfit(outfit) /// DOPPLER SHIFT REMOVAL + /// DOPPLER SHIFT ADDITION BEGIN + if(allow_prefs && spawned_human.client) + spawned_human.client?.prefs.safe_transfer_prefs_to(spawned_human) + SSquirks.AssignQuirks(spawned_human, spawned_human.client) + spawned_human.equip_outfit_and_loadout(outfit, spawned_human.client?.prefs) + else + spawned_human.equipOutfit(outfit) + else if(allow_prefs && spawned_mob.client) + var/mob/living/carbon/human/spawned_human = spawned_mob + spawned_human.client?.prefs.safe_transfer_prefs_to(spawned_human) + SSquirks.AssignQuirks(spawned_human, spawned_human.client) + spawned_human.equip_outfit_and_loadout(new /datum/outfit(), spawned_human.client?.prefs) + /// DOPPLER SHIFT ADDITION END ///these mob spawn subtypes do not trigger until attacked by a ghost. /obj/effect/mob_spawn/ghost_role @@ -157,9 +172,14 @@ LAZYADD(ckeys_trying_to_spawn, user_ckey) if(prompt_ghost) - var/prompt = "Become [prompt_name]?" + var/realname = user.client?.prefs?.read_preference(/datum/preference/name/real_name) || "yourself" /// DOPPLER SHIFT ADDITION + var/prompt = "Become [prompt_name] as [realname]?" /// DOPPLER SHIFT EDIT: adding your name to it if(!temp_body && user.can_reenter_corpse && user.mind) prompt += " (Warning, You can no longer be revived!)" + /// DOPPLER SHIFT ADDITION BEGIN + if(allow_prefs) + prompt += "\nYou will be loaded in with your current character, [realname] - loadout & quirks included! Make sure they fit the role!" + /// DOPPLER SHIFT ADDITION END var/ghost_role = tgui_alert(usr, prompt, buttons = list("Yes", "No"), timeout = 10 SECONDS) if(ghost_role != "Yes" || !loc || QDELETED(user)) LAZYREMOVE(ckeys_trying_to_spawn, user_ckey) From b040a6b4fda8dc8ec0f199c0c4130ee81189c94b Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Sat, 31 Aug 2024 21:27:34 -0400 Subject: [PATCH 03/24] Filling out more tricolor prefs --- .../customization/code/tri_color_prefs.dm | 346 +++++++++++++++++- .../code/tri_color_prefs_bespoke.dm | 177 +++++++++ tgstation.dme | 2 + .../mutant_newparts.tsx | 26 ++ .../mutant_tricolors.tsx | 50 +++ 5 files changed, 598 insertions(+), 3 deletions(-) create mode 100644 modular_doppler/customization/code/tri_color_prefs_bespoke.dm create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx diff --git a/modular_doppler/customization/code/tri_color_prefs.dm b/modular_doppler/customization/code/tri_color_prefs.dm index 4a28a25d4da0e..6755d2f2e4c98 100644 --- a/modular_doppler/customization/code/tri_color_prefs.dm +++ b/modular_doppler/customization/code/tri_color_prefs.dm @@ -12,8 +12,6 @@ sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) /datum/preference/tri_color/snout_color/apply_to_human(mob/living/carbon/human/target, value) - //to_chat(world, "GWA: applying tricolor alpha ([value[1]],[value[2]],[value[3]])") - //world.log << "SCREAMING AS TRICOL ALPHA IS APPLIED MAYBE HOPEFULLY ([value[1]],[value[2]],[value[3]])" target.dna.features["snout_color_1"] = value[1] target.dna.features["snout_color_2"] = value[2] target.dna.features["snout_color_3"] = value[3] @@ -24,10 +22,352 @@ return TRUE -// Gotta add to the snoot selector too +// Gotta add to the selector too /datum/preference/choiced/lizard_snout/compile_constant_data() var/list/data = ..() data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/snout_color::savefile_key return data + + + +/// Horn colors! +/datum/preference/tri_color/horns_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "horns_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/horns + +/datum/preference/tri_color/horns_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/horns_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["horns_color_1"] = value[1] + target.dna.features["horns_color_2"] = value[2] + target.dna.features["horns_color_3"] = value[3] + +/datum/preference/tri_color/horns_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/lizard_horns/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/horns_color::savefile_key + + return data + + + +/// Frill colors! +/datum/preference/tri_color/frills_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "frills_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/frills + +/datum/preference/tri_color/frills_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/frills_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["frills_color_1"] = value[1] + target.dna.features["frills_color_2"] = value[2] + target.dna.features["frills_color_3"] = value[3] + +/datum/preference/tri_color/frills_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/lizard_frills/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/frills_color::savefile_key + + return data + + + +/// Tail colors! +/datum/preference/tri_color/tail_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "tail_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/tail + +/datum/preference/tri_color/tail_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/tail_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["tail_color_1"] = value[1] + target.dna.features["tail_color_2"] = value[2] + target.dna.features["tail_color_3"] = value[3] + +/datum/preference/tri_color/tail_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/lizard_tail/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/tail_color::savefile_key + + return data + + + +/// Ears colors! +/datum/preference/tri_color/ears_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "ears_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + //TODO: we might need to change this to a different organ type, it's hard to say + relevant_external_organ = /obj/item/organ/internal/ears + +/datum/preference/tri_color/ears_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/ears_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["ears_color_1"] = value[1] + target.dna.features["ears_color_2"] = value[2] + target.dna.features["ears_color_3"] = value[3] + +/datum/preference/tri_color/ears_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the snoot selector too +/datum/preference/choiced/ears/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/ears_color::savefile_key + + return data + + + +/// Spines colors! +/datum/preference/tri_color/spines_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "spines_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/spines + +/datum/preference/tri_color/spines_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/spines_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["spines_color_1"] = value[1] + target.dna.features["spines_color_2"] = value[2] + target.dna.features["spines_color_3"] = value[3] + +/datum/preference/tri_color/spines_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/lizard_spines/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/spines_color::savefile_key + + return data + + + +/// Caps colors! +/datum/preference/tri_color/caps_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "caps_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/tail + +/datum/preference/tri_color/caps_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/caps_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["caps_color_1"] = value[1] + target.dna.features["caps_color_2"] = value[2] + target.dna.features["caps_color_3"] = value[3] + +/datum/preference/tri_color/caps_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/mushroom_cap/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/caps_color::savefile_key + + return data + + + +/// Moth marking colors! +/datum/preference/tri_color/moth_markings_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "moth_markings_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/moth + +/datum/preference/tri_color/moth_markings_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/moth_markings_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["moth_markings_color_1"] = value[1] + target.dna.features["moth_markings_color_2"] = value[2] + target.dna.features["moth_markings_color_3"] = value[3] + +/datum/preference/tri_color/moth_markings_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/moth_markings/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/moth_markings_color::savefile_key + + return data + + + +/// Standard marking colors! +/datum/preference/tri_color/body_markings_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "body_markings_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/lizard + +/datum/preference/tri_color/body_markings_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/body_markings_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["body_markings_color_1"] = value[1] + target.dna.features["body_markings_color_2"] = value[2] + target.dna.features["body_markings_color_3"] = value[3] + +/datum/preference/tri_color/body_markings_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/lizard_body_markings/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/body_markings_color::savefile_key + + return data + + + +/// Wing colors! +/datum/preference/tri_color/wings_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "wings_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/wings + +/datum/preference/tri_color/wings_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/wings_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["wings_color_1"] = value[1] + target.dna.features["wings_color_2"] = value[2] + target.dna.features["wings_color_3"] = value[3] + +/datum/preference/tri_color/wings_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: can we migrate off of moth_wings for this? +/datum/preference/choiced/moth_wings/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/wings_color::savefile_key + + return data + + + +/// Moth antennae colors! +/datum/preference/tri_color/moth_antennae_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "moth_antennae_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + relevant_external_organ = /obj/item/organ/external/wings + +/datum/preference/tri_color/moth_antennae_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/moth_antennae_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["moth_antennae_color_1"] = value[1] + target.dna.features["moth_antennae_color_2"] = value[2] + target.dna.features["moth_antennae_color_3"] = value[3] + +/datum/preference/tri_color/moth_antennae_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/moth_wings/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/moth_antennae_color::savefile_key + + return data diff --git a/modular_doppler/customization/code/tri_color_prefs_bespoke.dm b/modular_doppler/customization/code/tri_color_prefs_bespoke.dm new file mode 100644 index 0000000000000..7a8d955fd0c58 --- /dev/null +++ b/modular_doppler/customization/code/tri_color_prefs_bespoke.dm @@ -0,0 +1,177 @@ +/// Fluff colors! +/datum/preference/tri_color/fluff_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "fluff_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + // TODO: we need fluff organs & selection + //relevant_external_organ = /obj/item/organ/external/fluff + +/datum/preference/tri_color/fluff_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/fluff_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["fluff_color_1"] = value[1] + target.dna.features["fluff_color_2"] = value[2] + target.dna.features["fluff_color_3"] = value[3] + +/datum/preference/tri_color/fluff_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: we need fluff organs & selection +/*/datum/preference/choiced/moth_fluff/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/fluff_color::savefile_key + + return data*/ + + + +/// Synth antenna colors! +/datum/preference/tri_color/ipc_antenna_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "ipc_antenna_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + // TODO: we need fluff organs & selection + //relevant_external_organ = /obj/item/organ/external/fluff + +/datum/preference/tri_color/ipc_antenna_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/ipc_antenna_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["ipc_antenna_color_1"] = value[1] + target.dna.features["ipc_antenna_color_2"] = value[2] + target.dna.features["ipc_antenna_color_3"] = value[3] + +/datum/preference/tri_color/ipc_antenna_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: we need fluff organs & selection +/*/datum/preference/choiced/moth_fluff/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/ipc_antenna_color::savefile_key + + return data*/ + + + +/// Taur body colors! +/datum/preference/tri_color/taur_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "taur_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + // TODO: we need fluff organs & selection + //relevant_external_organ = /obj/item/organ/external/fluff + +/datum/preference/tri_color/taur_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/taur_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["taur_color_1"] = value[1] + target.dna.features["taur_color_2"] = value[2] + target.dna.features["taur_color_3"] = value[3] + +/datum/preference/tri_color/taur_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: we need fluff organs & selection +/*/datum/preference/choiced/moth_fluff/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/taur_color::savefile_key + + return data*/ + + + +/// Xenomorph dorsal fin colors! +/datum/preference/tri_color/xenodorsal_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "xenodorsal_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + // TODO: we need fluff organs & selection + //relevant_external_organ = /obj/item/organ/external/fluff + +/datum/preference/tri_color/xenodorsal_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/xenodorsal_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["xenodorsal_color_1"] = value[1] + target.dna.features["xenodorsal_color_2"] = value[2] + target.dna.features["xenodorsal_color_3"] = value[3] + +/datum/preference/tri_color/xenodorsal_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: we need fluff organs & selection +/*/datum/preference/choiced/moth_fluff/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/xenodorsal_color::savefile_key + + return data*/ + + + +/// Xenomorph head colors! +/datum/preference/tri_color/xenohead_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "xenohead_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + // TODO: we need fluff organs & selection + //relevant_external_organ = /obj/item/organ/external/fluff + +/datum/preference/tri_color/xenohead_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/xenohead_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["xenohead_color_1"] = value[1] + target.dna.features["xenohead_color_2"] = value[2] + target.dna.features["xenohead_color_3"] = value[3] + +/datum/preference/tri_color/xenohead_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: we need fluff organs & selection +/*/datum/preference/choiced/moth_fluff/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/xenohead_color::savefile_key + + return data*/ diff --git a/tgstation.dme b/tgstation.dme index a67cf7298f1f0..308a4b222e802 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6356,7 +6356,9 @@ #include "interface\fonts\spess_font.dm" #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" +#include "modular_doppler\customization\code\dropdowns_to_icons.dm" #include "modular_doppler\customization\code\tri_color_prefs.dm" +#include "modular_doppler\customization\code\tri_color_prefs_bespoke.dm" #include "modular_doppler\emotes\code\emotes.dm" #include "modular_doppler\emotes\code\added_emotes\animal_sounds.dm" #include "modular_doppler\emotes\code\added_emotes\human_things.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx new file mode 100644 index 0000000000000..c60452ea64391 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx @@ -0,0 +1,26 @@ +import { FeatureTriColorInput, FeatureColorInput, Feature } from '../base'; + +export const fluff_color: Feature = { + name: 'Fluff Color', + component: FeatureTriColorInput, +}; + +export const ipc_antenna_color: Feature = { + name: 'Synth Antenna Color', + component: FeatureTriColorInput, +}; + +export const taur_color: Feature = { + name: 'Taur Color', + component: FeatureTriColorInput, +}; + +export const xenodorsal_color: Feature = { + name: 'Xenodorsal Color', + component: FeatureTriColorInput, +}; + +export const xenohead_color: Feature = { + name: 'Xenohead Color', + component: FeatureTriColorInput, +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx index 15fccf338f7b7..6b835ce196897 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx @@ -3,4 +3,54 @@ import { FeatureTriColorInput, FeatureColorInput, Feature } from '../base'; export const snout_color: Feature = { name: 'Snout Color', component: FeatureTriColorInput, +}; + +export const horns_color: Feature = { + name: 'Horns Color', + component: FeatureTriColorInput, +}; + +export const frills_color: Feature = { + name: 'Frills Color', + component: FeatureTriColorInput, +}; + +export const tail_color: Feature = { + name: 'Tail Color', + component: FeatureTriColorInput, +}; + +export const ears_color: Feature = { + name: 'Ears Color', + component: FeatureTriColorInput, +}; + +export const spines_color: Feature = { + name: 'Spines Color', + component: FeatureTriColorInput, +}; + +export const caps_color: Feature = { + name: 'Caps Color', + component: FeatureTriColorInput, +}; + +export const moth_markings_color: Feature = { + name: 'Moth Markings Color', + component: FeatureTriColorInput, +}; + +export const body_markings_color: Feature = { + name: 'Body Markings Color', + component: FeatureTriColorInput, +}; + +export const wings_color: Feature = { + name: 'Wings Color', + component: FeatureTriColorInput, +}; + +export const moth_antennae_color: Feature = { + name: 'Moth Antennae Color', + component: FeatureTriColorInput, }; \ No newline at end of file From c00ab7c84cfca0ec4ba83fbfb1e182a07b30f461 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Sat, 31 Aug 2024 22:47:38 -0400 Subject: [PATCH 04/24] Tricolorable Organs, Part 1 New layers to allow for reusing the admittedly-snowflakey setup cat ears do. We could do this so much better but TG made a real fucking mess of things. --- code/__DEFINES/mobs.dm | 31 ++++++++++++++-- .../bodypart_overlays/bodypart_overlay.dm | 35 ++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index dad5afdb96979..a740a2bc887e5 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -681,12 +681,20 @@ GLOBAL_LIST_INIT(human_heights_to_offsets, list( #define MUTATIONS_LAYER 35 /// Mutantrace features (tail when looking south) that must appear behind the body parts #define BODY_BEHIND_LAYER 34 +/// DOPPLER SHIFT ADDITION BEGIN +#define BODY_BEHIND_LAYER_2 33.99 +#define BODY_BEHIND_LAYER_3 33.98 +/// DOPPLER SHIFT ADDITION END /// Layer for bodyparts that should appear behind every other bodypart - Mostly, legs when facing WEST or EAST #define BODYPARTS_LOW_LAYER 33 /// Layer for most bodyparts, appears above BODYPARTS_LOW_LAYER and below BODYPARTS_HIGH_LAYER #define BODYPARTS_LAYER 32 /// Mutantrace features (snout, body markings) that must appear above the body parts #define BODY_ADJ_LAYER 31 +/// DOPPLER SHIFT ADDITION BEGIN +#define BODY_ADJ_LAYER_2 30.99 +#define BODY_ADJ_LAYER_3 30.98 +/// DOPPLER SHIFT ADDITION END /// Underwear, undershirts, socks, eyes, lips(makeup) #define BODY_LAYER 30 /// Mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes) @@ -737,6 +745,10 @@ GLOBAL_LIST_INIT(human_heights_to_offsets, list( #define HANDS_LAYER 7 /// Body front layer. Usually used for mutant bodyparts that need to be in front of stuff (e.g. cat ears) #define BODY_FRONT_LAYER 6 +/// DOPPLER SHIFT ADDITION BEGIN +#define BODY_FRONT_LAYER_2 5.99 +#define BODY_FRONT_LAYER_3 5.98 +/// DOPPLER SHIFT ADDITION END /// Special body layer that actually require to be above the hair (e.g. lifted welding goggles) #define ABOVE_BODY_FRONT_GLASSES_LAYER 5 /// Special body layer for the rare cases where something on the head needs to be above everything else (e.g. flowers) @@ -798,10 +810,25 @@ GLOBAL_LIST_INIT(layers_to_offset, list( //Bitflags for the layers a bodypart overlay can draw on (can be drawn on multiple layers) /// Draws overlay on the BODY_FRONT_LAYER #define EXTERNAL_FRONT (1 << 0) -/// Draws overlay on the BODY_ADJ_LAYER +/// DOPPLER SHIFT REMOVAL BEGIN +/*/// Draws overlay on the BODY_ADJ_LAYER #define EXTERNAL_ADJACENT (1 << 1) /// Draws overlay on the BODY_BEHIND_LAYER -#define EXTERNAL_BEHIND (1 << 2) +#define EXTERNAL_BEHIND (1 << 2) */ +/// DOPPLER SHIFT REMOVAL END +/// DOPPLER SHIFT ADDITION BEGIN +//Front extra-color layers. +#define EXTERNAL_FRONT_2 (1 << 1) +#define EXTERNAL_FRONT_3 (1 << 2) +//Updated adjacent & extra-color layers. +#define EXTERNAL_ADJACENT (1 << 3) +#define EXTERNAL_ADJACENT_2 (1 << 4) +#define EXTERNAL_ADJACENT_3 (1 << 5) +//Updated behind & extra-color layers. +#define EXTERNAL_BEHIND (1 << 6) +#define EXTERNAL_BEHIND_2 (1 << 7) +#define EXTERNAL_BEHIND_3 (1 << 8) +/// DOPPLER SHIFT ADDITION END /// Draws organ on all EXTERNAL layers #define ALL_EXTERNAL_OVERLAYS EXTERNAL_FRONT | EXTERNAL_ADJACENT | EXTERNAL_BEHIND diff --git a/code/datums/bodypart_overlays/bodypart_overlay.dm b/code/datums/bodypart_overlays/bodypart_overlay.dm index 15b1e01114943..10260c8d01910 100644 --- a/code/datums/bodypart_overlays/bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/bodypart_overlay.dm @@ -4,7 +4,12 @@ ///Sometimes we need multiple layers, for like the back, middle and front of the person (EXTERNAL_FRONT, EXTERNAL_ADJACENT, EXTERNAL_BEHIND) var/layers ///List of all possible layers. Used for looping through in drawing - var/static/list/all_layers = list(EXTERNAL_FRONT, EXTERNAL_ADJACENT, EXTERNAL_BEHIND) + //var/static/list/all_layers = list(EXTERNAL_FRONT, EXTERNAL_ADJACENT, EXTERNAL_BEHIND) /// DOPPLER SHIFT REMOVAL + /// DOPPLER SHIFT ADDITION BEGIN + var/static/list/all_layers = list(EXTERNAL_FRONT,EXTERNAL_FRONT_2,EXTERNAL_FRONT_3, + EXTERNAL_ADJACENT,EXTERNAL_ADJACENT_2,EXTERNAL_ADJACENT_3, + EXTERNAL_BEHIND,EXTERNAL_BEHIND_2,EXTERNAL_BEHIND_3) + /// DOPPLER SHIFT ADDITION END ///Key of the icon states of all the sprite_datums for easy caching var/cache_key = "" @@ -57,6 +62,20 @@ return "ADJ" if(-BODY_FRONT_LAYER) return "FRONT" + /// DOPPLER SHIFT ADDITION BEGIN + if(-BODY_BEHIND_LAYER_2) + return "BEHIND_2" + if(-BODY_BEHIND_LAYER_3) + return "BEHIND_3" + if(-BODY_ADJ_LAYER_2) + return "ADJ_2" + if(-BODY_ADJ_LAYER_3) + return "ADJ_3" + if(-BODY_FRONT_LAYER_2) + return "FRONT_2" + if(-BODY_FRONT_LAYER_3) + return "FRONT_3" + /// DOPPLER SHIFT ADDITION END ///Converts a bitflag to the right layer. I'd love to make this a static index list, but byond made an attempt on my life when i did /datum/bodypart_overlay/proc/bitflag_to_layer(layer) @@ -67,6 +86,20 @@ return -BODY_ADJ_LAYER if(EXTERNAL_FRONT) return -BODY_FRONT_LAYER + /// DOPPLER SHIFT ADDITION BEGIN + if(EXTERNAL_BEHIND_2) + return -BODY_BEHIND_LAYER_2 + if(EXTERNAL_BEHIND_3) + return -BODY_BEHIND_LAYER_3 + if(EXTERNAL_ADJACENT_2) + return -BODY_ADJ_LAYER_2 + if(EXTERNAL_ADJACENT_3) + return -BODY_ADJ_LAYER_3 + if(EXTERNAL_FRONT_2) + return -BODY_FRONT_LAYER_2 + if(EXTERNAL_FRONT_3) + return -BODY_FRONT_LAYER_3 + /// DOPPLER SHIFT ADDITION END ///Check whether we can draw the overlays. You generally don't want lizard snouts to draw over an EVA suit /datum/bodypart_overlay/proc/can_draw_on_bodypart(mob/living/carbon/human/human) From fc996018d2ada5a23ea7cb881ff45e32cfae91c4 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Sat, 31 Aug 2024 23:18:48 -0400 Subject: [PATCH 05/24] Modularizing tricolor prefs wawa Why I didn't do this sooner is beyond me --- .../modules/client/preferences/_preference.dm | 25 ----------------- .../customization/code/tri_color_prefs.dm | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 1b6067bb3c43f..2ed2405f37687 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -460,31 +460,6 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) /datum/preference/color/is_valid(value) return findtext(value, GLOB.is_color) -/// DOPPLER SHIFT ADDITION BEGIN -/datum/preference/tri_color - abstract_type = /datum/preference/tri_color - -/datum/preference/tri_color/deserialize(input, datum/preferences/preferences) - var/list/input_colors = input - return list(sanitize_hexcolor(input_colors[1]), sanitize_hexcolor(input_colors[2]), sanitize_hexcolor(input_colors[3])) - -/datum/preference/tri_color/create_default_value() - return list("#[random_color()]", "#[random_color()]", "#[random_color()]") - -/datum/preference/tri_color/is_valid(list/value) - return islist(value) && value.len == 3 && (findtext(value[1], GLOB.is_color) && findtext(value[2], GLOB.is_color) && findtext(value[3], GLOB.is_color)) - -/datum/preference/tri_color/is_accessible(datum/preferences/preferences) - return ..() - -// Hey, you! -// Wondering how to get the colors from a tri-col pref? -// Look no further: list(sanitize_hexcolor(value[1]), sanitize_hexcolor(value[2]), sanitize_hexcolor(value[3])) -/datum/preference/tri_color/apply_to_human(mob/living/carbon/human/target, value) - if (type == abstract_type) - return ..() -/// DOPPLER SHIFT ADDITION END - /// A numeric preference with a minimum and maximum value /datum/preference/numeric /// The minimum value diff --git a/modular_doppler/customization/code/tri_color_prefs.dm b/modular_doppler/customization/code/tri_color_prefs.dm index 6755d2f2e4c98..7f3f76733cf79 100644 --- a/modular_doppler/customization/code/tri_color_prefs.dm +++ b/modular_doppler/customization/code/tri_color_prefs.dm @@ -1,3 +1,31 @@ +/// Tricolor prefs +/datum/preference/tri_color + abstract_type = /datum/preference/tri_color + +/datum/preference/tri_color/deserialize(input, datum/preferences/preferences) + var/list/input_colors = input + return list(sanitize_hexcolor(input_colors[1]), sanitize_hexcolor(input_colors[2]), sanitize_hexcolor(input_colors[3])) + +/datum/preference/tri_color/create_default_value() + return list("#[random_color()]", "#[random_color()]", "#[random_color()]") + +/datum/preference/tri_color/is_valid(list/value) + return islist(value) && value.len == 3 && (findtext(value[1], GLOB.is_color) && findtext(value[2], GLOB.is_color) && findtext(value[3], GLOB.is_color)) + +/datum/preference/tri_color/is_accessible(datum/preferences/preferences) + return ..() + +// Hey, you! +// Wondering how to get the colors from a tri-col pref? +// Look no further: list(sanitize_hexcolor(value[1]), sanitize_hexcolor(value[2]), sanitize_hexcolor(value[3])) +/datum/preference/tri_color/apply_to_human(mob/living/carbon/human/target, value) + if (type == abstract_type) + return ..() + + + + + /// Snoot colors! /datum/preference/tri_color/snout_color priority = PREFERENCE_PRIORITY_BODY_TYPE From b025533f80a375465ea0bcad70521b61d2b93498 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Mon, 2 Sep 2024 01:10:47 -0400 Subject: [PATCH 06/24] Tricolorable Organs, Pt 2: Boobgaloo Proof-of-concept for showing a user-addable external mutant organ using tricolors, only added & available to customize when actively enabled. Importantly, this also includes the requisite boilerplate that allows other ERP organs to be added & properly shown/hidden down the line. --- code/__DEFINES/DNA.dm | 5 +- .../~doppler/enterprise_resource_planning.dm | 2 + code/datums/dna.dm | 12 + .../customization/code/dropdowns_to_icons.dm | 1 + .../code/breasts.dm | 251 ++++++++++++++++++ .../code/erp_prefs.dm | 18 ++ .../icons/mob/breasts.dmi | Bin 0 -> 5429 bytes .../icons/organs.dmi | Bin 0 -> 487 bytes tgstation.dme | 3 + .../dopplershift_preferences/erp_parts.tsx | 31 +++ 10 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 code/__DEFINES/~doppler/enterprise_resource_planning.dm create mode 100644 modular_doppler/customization/code/dropdowns_to_icons.dm create mode 100644 modular_doppler/enterprise_resource_planning/code/breasts.dm create mode 100644 modular_doppler/enterprise_resource_planning/code/erp_prefs.dm create mode 100644 modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi create mode 100644 modular_doppler/enterprise_resource_planning/icons/organs.dmi create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 4756b80f02737..c1e517e8fbbbe 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -60,6 +60,9 @@ #define DNA_MOTH_MARKINGS_BLOCK 13 #define DNA_MUSHROOM_CAPS_BLOCK 14 #define DNA_POD_HAIR_BLOCK 15 +/// DOPPLER SHIFT ADDITION BEGIN +#define DNA_BREASTS_BLOCK 16 +/// DOPPLER SHIFT ADDITION END // Hey! Listen up if you're here because you're adding a species feature! // @@ -68,7 +71,7 @@ // (Which means having a DNA block for a feature tied to a mob without DNA is entirely pointless.) /// Total amount of DNA blocks, must be equal to the highest DNA block number -#define DNA_FEATURE_BLOCKS 15 +#define DNA_FEATURE_BLOCKS 16 /// DOPPLER SHIFT EDIT: 16, up from 15 #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 diff --git a/code/__DEFINES/~doppler/enterprise_resource_planning.dm b/code/__DEFINES/~doppler/enterprise_resource_planning.dm new file mode 100644 index 0000000000000..9aa689eb3c13b --- /dev/null +++ b/code/__DEFINES/~doppler/enterprise_resource_planning.dm @@ -0,0 +1,2 @@ +// Why we need bespoke organ slots for these isn't entirely within my understanding but I assume there's a good reason +#define ORGAN_SLOT_EXTERNAL_BREASTS "breasts" diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 4fff0104439c1..8d6f3d1ec79ce 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -236,6 +236,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_MUSHROOM_CAPS_BLOCK] = construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list)) if(features["pod_hair"]) L[DNA_POD_HAIR_BLOCK] = construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list)) + /// DOPPLER SHIFT ADDITION BEGIN + if(features["breasts"]) + L[DNA_BREASTS_BLOCK] = construct_block(SSaccessories.breasts_list.Find(features["breasts"]), length(SSaccessories.breasts_list)) + /// DOPPLER SHIFT ADDITION END for(var/blocknum in 1 to DNA_FEATURE_BLOCKS) . += L[blocknum] || random_string(GET_UI_BLOCK_LEN(blocknum), GLOB.hex_characters) @@ -380,6 +384,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) set_uni_feature_block(blocknumber, construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list))) if(DNA_POD_HAIR_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list))) + /// DOPPLER SHIFT ADDITION BEGIN + if(DNA_BREASTS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(SSaccessories.breasts_list.Find(features["breasts"]), length(SSaccessories.breasts_list))) + /// DOPPLER SHIFT ADDITION END //Please use add_mutation or activate_mutation instead /datum/dna/proc/force_give(datum/mutation/human/human_mutation) @@ -681,6 +689,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["caps"] = SSaccessories.caps_list[deconstruct_block(get_uni_feature_block(features, DNA_MUSHROOM_CAPS_BLOCK), length(SSaccessories.caps_list))] if(dna.features["pod_hair"]) dna.features["pod_hair"] = SSaccessories.pod_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_POD_HAIR_BLOCK), length(SSaccessories.pod_hair_list))] + /// DOPPLER SHIFT ADDITION BEGIN + if(dna.features["breasts"]) + dna.features["breasts"] = SSaccessories.breasts_list[deconstruct_block(get_uni_feature_block(features, DNA_BREASTS_BLOCK), length(SSaccessories.breasts_list))] + /// DOPPLER SHIFT ADDITION END for(var/obj/item/organ/organ in organs) organ.mutate_feature(features, src) diff --git a/modular_doppler/customization/code/dropdowns_to_icons.dm b/modular_doppler/customization/code/dropdowns_to_icons.dm new file mode 100644 index 0000000000000..a553e496c9df0 --- /dev/null +++ b/modular_doppler/customization/code/dropdowns_to_icons.dm @@ -0,0 +1 @@ +//wawa diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm new file mode 100644 index 0000000000000..d125b756dca19 --- /dev/null +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -0,0 +1,251 @@ +/datum/species/get_features() + var/list/features = ..() + features += GLOB.preference_entries[/datum/preference/choiced/breasts] + return features + + + +/// SSAccessories setup +/datum/controller/subsystem/accessories + var/list/breasts_list + +/datum/controller/subsystem/accessories/setup_lists() + . = ..() + breasts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts)["default_sprites"] // FLAKY DEFINE: this should be using DEFAULT_SPRITE_LIST + //damnit SSAccessories + + + +/// The boobage in question +/obj/item/organ/external/breasts + name = "breasts" + desc = "Super-effective at deterring ice dragons." + icon_state = "snout" + + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_EXTERNAL_BREASTS + + preference = "feature_breasts" + //external_bodyshapes = BODYSHAPE_SNOUTED + + dna_block = DNA_BREASTS_BLOCK + restyle_flags = EXTERNAL_RESTYLE_FLESH + + bodypart_overlay = /datum/bodypart_overlay/mutant/breasts + +/datum/bodypart_overlay/mutant/breasts + layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 | EXTERNAL_BEHIND | EXTERNAL_BEHIND_2 | EXTERNAL_BEHIND_3 + feature_key = "breasts" + +/datum/bodypart_overlay/mutant/breasts/can_draw_on_bodypart(mob/living/carbon/human/human) + if(human.undershirt != "Nude") + return FALSE + if((human.w_uniform && human.w_uniform.body_parts_covered & CHEST) || (human.wear_suit && human.wear_suit.body_parts_covered & CHEST)) + return FALSE + return TRUE + +/datum/bodypart_overlay/mutant/breasts/get_global_feature_list() + return SSaccessories.breasts_list + +/datum/bodypart_overlay/mutant/breasts/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) + overlay.color = limb.owner.dna.features["breasts_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND)) + overlay.color = limb.owner.dna.features["breasts_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + overlay.color = limb.owner.dna.features["breasts_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_2)) + overlay.color = limb.owner.dna.features["breasts_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + overlay.color = limb.owner.dna.features["breasts_color_3"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_3)) + overlay.color = limb.owner.dna.features["breasts_color_3"] + return overlay + return overlay + +/datum/bodypart_overlay/mutant/breasts/mutant_bodyparts_layertext(layer) + switch(layer) + if(-(UNIFORM_LAYER + 0.09)) + return "ADJ" + if(-(UNIFORM_LAYER + 0.08)) + return "ADJ_2" + if(-(UNIFORM_LAYER + 0.07)) + return "ADJ_3" + return ..() + +/datum/bodypart_overlay/mutant/breasts/bitflag_to_layer(layer) + switch(layer) + if(EXTERNAL_ADJACENT) + return -(UNIFORM_LAYER + 0.09) + if(EXTERNAL_ADJACENT_2) + return -(UNIFORM_LAYER + 0.08) + if(EXTERNAL_ADJACENT_3) + return -(UNIFORM_LAYER + 0.07) + return ..() + + +/// Main breast prefs +//core toggle +/datum/preference/toggle/breasts + savefile_key = "has_breasts" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/breasts/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + //to_chat(world, "Begone, boobs.") + target.dna.features["breasts"] = "Bare" + +/datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) + . = ..() + /*to_chat(world, "Regenerating organs for [target], a [src], trying to add boobs") + for(var/feature in target.dna.features) + to_chat(world, "[target] has feature [feature]")*/ + if(target.dna.features["breasts"]) + //to_chat(world, "Boobs are in the features list, adding [target.dna.features["breasts"]]") + if(target.dna.features["breasts"] != "Bare") + //to_chat(world, "Boob type valid, trying to insert [target.dna.features["breasts"]]") + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/breasts) + //to_chat(world, "Inserted boobage exists: [replacement]") + //replacement.build_from_dna(target.dna, "breasts") //TODO: do we need to add this + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + //to_chat(world, "Boobs inserted, new state is [target.dna.features["breasts"]]") + return . + var/obj/item/organ/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_BREASTS) + if(old_part) + old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + old_part.moveToNullspace() + + + +//sprite selection +/datum/preference/choiced/breasts + savefile_key = "feature_breasts" + savefile_identifier = PREFERENCE_CHARACTER + //category = PREFERENCE_CATEGORY_FEATURES + category = PREFERENCE_CATEGORY_CLOTHING + main_feature_name = "Breasts" + should_generate_icons = TRUE + priority = PREFERENCE_PRIORITY_DEFAULT + can_randomize = FALSE + +/datum/preference/choiced/breasts/init_possible_values() + return assoc_to_keys_features(SSaccessories.breasts_list) + +/datum/preference/choiced/breasts/icon_for(value) + return generate_genitals_shot(SSaccessories.breasts_list[value], "breasts") + +/datum/preference/choiced/breasts/apply_to_human(mob/living/carbon/human/target, value) + //to_chat(world, "Applying [value] to [target]'s boobs...") + target.dna.features["breasts"] = value + //to_chat(world, "Applied!") + +/datum/preference/choiced/breasts/is_accessible(datum/preferences/preferences) + . = ..() + var/has_breasts = preferences.read_preference(/datum/preference/toggle/breasts) + if(has_breasts == TRUE) + return TRUE + return FALSE + + + +/// Breast colors! +/datum/preference/tri_color/breasts_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "breasts_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + can_randomize = FALSE + +/datum/preference/tri_color/breasts_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/breasts_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["breasts_color_1"] = value[1] + target.dna.features["breasts_color_2"] = value[2] + target.dna.features["breasts_color_3"] = value[3] + +/datum/preference/tri_color/breasts_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +/datum/preference/choiced/breasts/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/breasts_color::savefile_key + + return data + + + +/// Breast sprite accessories +/datum/sprite_accessory/breasts + icon = 'modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi' + em_block = TRUE + +/datum/sprite_accessory/breasts/bare + name = "Bare" + icon_state = "bare" + +/datum/sprite_accessory/breasts/pair + name = "Pair 0" + icon_state = "pair_0" + +/datum/sprite_accessory/breasts/pair/size1 + name = "Pair 1" + icon_state = "pair_1" + +/datum/sprite_accessory/breasts/pair/size2 + name = "Pair 2" + icon_state = "pair_2" + +/datum/sprite_accessory/breasts/pair/size3 + name = "Pair 3" + icon_state = "pair_3" + +/datum/sprite_accessory/breasts/pair/size4 + name = "Pair 4" + icon_state = "pair_4" + +/datum/sprite_accessory/breasts/pair/size5 + name = "Pair 5" + icon_state = "pair_5" + +/datum/sprite_accessory/breasts/pair/size6 + name = "Pair 6" + icon_state = "pair_6" + +/datum/sprite_accessory/breasts/pair/size7 + name = "Pair 7" + icon_state = "pair_7" + +/datum/sprite_accessory/breasts/pair/size8 + name = "Pair 8" + icon_state = "pair_8" + +/datum/sprite_accessory/breasts/pair/size9 + name = "Pair 9" + icon_state = "pair_9" + +/datum/sprite_accessory/breasts/pair/size10 + name = "Pair 10" + icon_state = "pair_10" + +/datum/sprite_accessory/breasts/pair/size11 + name = "Pair 11" + icon_state = "pair_11" + +/datum/sprite_accessory/breasts/pair/size12 + name = "Pair 12" + icon_state = "pair_12" diff --git a/modular_doppler/enterprise_resource_planning/code/erp_prefs.dm b/modular_doppler/enterprise_resource_planning/code/erp_prefs.dm new file mode 100644 index 0000000000000..2643b2fd176bb --- /dev/null +++ b/modular_doppler/enterprise_resource_planning/code/erp_prefs.dm @@ -0,0 +1,18 @@ +/proc/generate_genitals_shot(datum/sprite_accessory/sprite_accessory, key) + var/icon/final_icon = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_chest_f", SOUTH) + + if (!isnull(sprite_accessory)) + var/icon/accessory_icon = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", SOUTH) + var/icon/accessory_icon_2 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ_2", SOUTH) + accessory_icon_2.Blend(COLOR_RED, ICON_MULTIPLY) + var/icon/accessory_icon_3 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ_3", SOUTH) + accessory_icon_3.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + final_icon.Blend(accessory_icon, ICON_OVERLAY) + final_icon.Blend(accessory_icon_2, ICON_OVERLAY) + final_icon.Blend(accessory_icon_3, ICON_OVERLAY) + + final_icon.Crop(10, 8, 22, 23) + final_icon.Scale(26, 32) + final_icon.Crop(-2, 1, 29, 32) + + return final_icon diff --git a/modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi b/modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi new file mode 100644 index 0000000000000000000000000000000000000000..1f48c6f17c576edf70f08c41a5654cbd98e6c35b GIT binary patch literal 5429 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 bj|C<3+b>RTnS8RW7sT~+^>bP0l+XkKhg0Wg literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 308a4b222e802..6d0079b983799 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -395,6 +395,7 @@ #include "code\__DEFINES\traits\declarations.dm" #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" +#include "code\__DEFINES\~doppler\enterprise_resource_planning.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_dreamluau.dm" #include "code\__HELPERS\_lists.dm" @@ -6363,6 +6364,8 @@ #include "modular_doppler\emotes\code\added_emotes\animal_sounds.dm" #include "modular_doppler\emotes\code\added_emotes\human_things.dm" #include "modular_doppler\emotes\code\added_emotes\robot_sounds.dm" +#include "modular_doppler\enterprise_resource_planning\code\breasts.dm" +#include "modular_doppler\enterprise_resource_planning\code\erp_prefs.dm" #include "modular_doppler\face_mouse_preferences\code\face_mouse_pref.dm" #include "modular_doppler\icspawn\cconsultant_items.dm" #include "modular_doppler\icspawn\observer_spawn.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx new file mode 100644 index 0000000000000..db69ce3c443f0 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx @@ -0,0 +1,31 @@ +import { FeatureTriColorInput, FeatureColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; + +export const penis_color: Feature = { + name: 'Penis Color', + component: FeatureTriColorInput, +}; + +export const testicles_color: Feature = { + name: 'Testicles Color', + component: FeatureTriColorInput, +}; + +export const vagina_color: Feature = { + name: 'Vagina Color', + component: FeatureTriColorInput, +}; + +export const has_breasts: FeatureToggle = { + name: 'Add Breasts', + category: 'GAMEPLAY', + description: ` + When toggled, adds breasts to your character. + `, + component: CheckboxInput, +}; + + +export const breasts_color: Feature = { + name: 'Breasts Color', + component: FeatureTriColorInput, +}; \ No newline at end of file From 5fdbf4afad437a234608e448c0b4f6414db89f69 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Mon, 2 Sep 2024 01:44:17 -0400 Subject: [PATCH 07/24] polishing the sprites a little --- .../icons/mob/breasts.dmi | Bin 5429 -> 5396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi b/modular_doppler/enterprise_resource_planning/icons/mob/breasts.dmi index 1f48c6f17c576edf70f08c41a5654cbd98e6c35b..b08334e0dbc98b1b83c2c5f2f5d4712707b298f3 100644 GIT binary patch literal 5396 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 Date: Mon, 2 Sep 2024 23:37:58 -0400 Subject: [PATCH 08/24] Tricolor optional snoots, horns & frills, ft. Scug My slugcat sprites have already been split up to support tricolor stuff for a while, making them perfect test dummies for these. --- code/__DEFINES/~doppler/species.dm | 1 + .../preferences/species_features/lizard.dm | 34 ++- .../surgery/organs/internal/eyes/_eyes.dm | 11 +- config/game_options.txt | 1 + .../customization/code/tri_color_prefs.dm | 20 +- .../code/breasts.dm | 6 +- modular_doppler/languages/language.dmi | Bin 4476 -> 4772 bytes modular_doppler/languages/language_datums.dm | 22 ++ .../species/accessory_overrides.dm | 209 ++++++++++++++++++ modular_doppler/species/bodypart_overrides.dm | 3 + modular_doppler/species/fallbacks.dmi | Bin 0 -> 209 bytes .../lizards/code/lizard_accessories.dm | 11 + .../species/lizards/code/lizard_species.dm | 1 + .../species/lizards/icons/bodyparts.dmi | Bin 0 -> 182 bytes .../species/lizards/icons/lizard_external.dmi | Bin 0 -> 182 bytes .../species/lizards/icons/lizard_markings.dmi | Bin 0 -> 1056 bytes .../species/lizards/icons/lizard_tail.dmi | Bin 0 -> 182 bytes .../species/scugs/code/slugcat_accessories.dm | 78 +++++++ .../species/scugs/code/slugcat_bodyparts.dm | 38 ++++ .../species/scugs/code/slugcat_species.dm | 124 +++++++++++ modular_doppler/species/scugs/icons.dmi | Bin 0 -> 279 bytes .../species/scugs/icons/bodyparts.dmi | Bin 0 -> 1440 bytes .../species/scugs/icons/slugcat_external.dmi | Bin 0 -> 1972 bytes .../species/scugs/icons/slugcat_eyes.dmi | Bin 0 -> 1163 bytes .../species/scugs/icons/slugcat_markings.dmi | Bin 0 -> 470 bytes .../species/scugs/icons/slugcat_tails.dmi | Bin 0 -> 3140 bytes .../species/scugs/sounds/scugdeath.ogg | Bin 0 -> 37377 bytes .../species/scugs/sounds/scuglaugh_1.ogg | Bin 0 -> 17324 bytes .../species/scugs/sounds/scugscream_1.ogg | Bin 0 -> 26832 bytes tgstation.dme | 8 + .../dopplershift_preferences/erp_parts.tsx | 2 +- .../mutant_tricolors.tsx | 127 ++++++++++- 32 files changed, 671 insertions(+), 25 deletions(-) create mode 100644 code/__DEFINES/~doppler/species.dm create mode 100644 modular_doppler/species/accessory_overrides.dm create mode 100644 modular_doppler/species/bodypart_overrides.dm create mode 100644 modular_doppler/species/fallbacks.dmi create mode 100644 modular_doppler/species/lizards/code/lizard_accessories.dm create mode 100644 modular_doppler/species/lizards/code/lizard_species.dm create mode 100644 modular_doppler/species/lizards/icons/bodyparts.dmi create mode 100644 modular_doppler/species/lizards/icons/lizard_external.dmi create mode 100644 modular_doppler/species/lizards/icons/lizard_markings.dmi create mode 100644 modular_doppler/species/lizards/icons/lizard_tail.dmi create mode 100644 modular_doppler/species/scugs/code/slugcat_accessories.dm create mode 100644 modular_doppler/species/scugs/code/slugcat_bodyparts.dm create mode 100644 modular_doppler/species/scugs/code/slugcat_species.dm create mode 100644 modular_doppler/species/scugs/icons.dmi create mode 100644 modular_doppler/species/scugs/icons/bodyparts.dmi create mode 100644 modular_doppler/species/scugs/icons/slugcat_external.dmi create mode 100644 modular_doppler/species/scugs/icons/slugcat_eyes.dmi create mode 100644 modular_doppler/species/scugs/icons/slugcat_markings.dmi create mode 100644 modular_doppler/species/scugs/icons/slugcat_tails.dmi create mode 100644 modular_doppler/species/scugs/sounds/scugdeath.ogg create mode 100644 modular_doppler/species/scugs/sounds/scuglaugh_1.ogg create mode 100644 modular_doppler/species/scugs/sounds/scugscream_1.ogg diff --git a/code/__DEFINES/~doppler/species.dm b/code/__DEFINES/~doppler/species.dm new file mode 100644 index 0000000000000..56a4d9de13dd8 --- /dev/null +++ b/code/__DEFINES/~doppler/species.dm @@ -0,0 +1 @@ +#define SPECIES_SLUGCAT "slugcat" \ No newline at end of file diff --git a/code/modules/client/preferences/species_features/lizard.dm b/code/modules/client/preferences/species_features/lizard.dm index 11fefc17b8b9e..a0f0c58eadca4 100644 --- a/code/modules/client/preferences/species_features/lizard.dm +++ b/code/modules/client/preferences/species_features/lizard.dm @@ -15,11 +15,22 @@ if (!isnull(sprite_accessory)) var/icon/accessory_icon = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) + /// DOPPLER SHIFT ADDITION BEGIN + accessory_icon.Blend(COLOR_RED, ICON_MULTIPLY) + var/icon/accessory_icon_2 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) + accessory_icon_2.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + var/icon/accessory_icon_3 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) + accessory_icon_3.Blend(COLOR_BLUE, ICON_MULTIPLY) + /// DOPPLER SHIFT ADDITION END final_icon.Blend(accessory_icon, ICON_OVERLAY) + /// DOPPLER SHIFT ADDITION BEGIN + final_icon.Blend(accessory_icon_2, ICON_OVERLAY) + final_icon.Blend(accessory_icon_3, ICON_OVERLAY) + /// DOPPLER SHIFT ADDITION END final_icon.Crop(11, 20, 23, 32) final_icon.Scale(32, 32) - final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + //final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) /// DOPPLER SHIFT REMOVAL return final_icon @@ -40,14 +51,27 @@ var/icon/final_icon = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m") if (sprite_accessory.icon_state != "none") - var/icon/body_markings_icon = icon( + /// DOPPLER SHIFT REMOVAL BEGIN + /*var/icon/body_markings_icon = icon( 'icons/mob/human/species/lizard/lizard_misc.dmi', "male_[sprite_accessory.icon_state]_chest", ) - final_icon.Blend(body_markings_icon, ICON_OVERLAY) - - final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + final_icon.Blend(body_markings_icon, ICON_OVERLAY)*/ + /// DOPPLER SHIFT REMOVAL END + /// DOPPLER SHIFT ADDITION BEGIN + var/icon/markings_icon_1 = icon(sprite_accessory.icon, "male_[sprite_accessory.icon_state]_chest") + markings_icon_1.Blend(COLOR_RED, ICON_MULTIPLY) + var/icon/markings_icon_2 = icon(sprite_accessory.icon, "male_[sprite_accessory.icon_state]_chest_2") + markings_icon_2.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + var/icon/markings_icon_3 = icon(sprite_accessory.icon, "male_[sprite_accessory.icon_state]_chest_3") + markings_icon_3.Blend(COLOR_BLUE, ICON_MULTIPLY) + final_icon.Blend(markings_icon_1, ICON_OVERLAY) + final_icon.Blend(markings_icon_2, ICON_OVERLAY) + final_icon.Blend(markings_icon_3, ICON_OVERLAY) + /// DOPPLER SHIFT ADDITION END + + //final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) /// DOPPLER SHIFT REMOVAL final_icon.Crop(10, 8, 22, 23) final_icon.Scale(26, 32) final_icon.Crop(-2, 1, 29, 32) diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index 4b611852b79b7..0893a3a2ad7f7 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -129,15 +129,20 @@ if(isnull(eye_icon_state)) return list() - var/mutable_appearance/eye_left = mutable_appearance('icons/mob/human/human_face.dmi', "[eye_icon_state]_l", -BODY_LAYER) - var/mutable_appearance/eye_right = mutable_appearance('icons/mob/human/human_face.dmi', "[eye_icon_state]_r", -BODY_LAYER) + /// DOPPLER SHIFT ADDITION BEGIN + var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD) + var/eye_icon = my_head?.eyes_icon || 'icons/mob/human/human_face.dmi' + /// DOPPLER SHIFT ADDITION END + + var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -BODY_LAYER) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi + var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -BODY_LAYER) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi var/list/overlays = list(eye_left, eye_right) var/obscured = parent.check_obscured_slots(TRUE) if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES)) overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -BODY_LAYER, alpha = eye_left.alpha) overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -BODY_LAYER, alpha = eye_right.alpha) - var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD) + //var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD) /// DOPPLER SHIFT REMOVAL if(my_head) if(my_head.head_flags & HEAD_EYECOLOR) eye_right.color = eye_color_right diff --git a/config/game_options.txt b/config/game_options.txt index 14646c6920758..abff35f639264 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -364,6 +364,7 @@ ROUNDSTART_RACES lizard ROUNDSTART_RACES moth ROUNDSTART_RACES plasmaman #ROUNDSTART_RACES shadow +ROUNDSTART_RACES slugcat ## Races that are better than humans in some ways, but worse in others ROUNDSTART_RACES ethereal diff --git a/modular_doppler/customization/code/tri_color_prefs.dm b/modular_doppler/customization/code/tri_color_prefs.dm index 7f3f76733cf79..48080911cd30e 100644 --- a/modular_doppler/customization/code/tri_color_prefs.dm +++ b/modular_doppler/customization/code/tri_color_prefs.dm @@ -32,7 +32,7 @@ savefile_key = "snout_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/snout + //relevant_external_organ = /obj/item/organ/external/snout /datum/preference/tri_color/snout_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -66,7 +66,7 @@ savefile_key = "horns_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/horns + //relevant_external_organ = /obj/item/organ/external/horns /datum/preference/tri_color/horns_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -100,7 +100,7 @@ savefile_key = "frills_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/frills + //relevant_external_organ = /obj/item/organ/external/frills /datum/preference/tri_color/frills_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -134,7 +134,7 @@ savefile_key = "tail_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/tail + //relevant_external_organ = /obj/item/organ/external/tail /datum/preference/tri_color/tail_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -169,7 +169,7 @@ savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES //TODO: we might need to change this to a different organ type, it's hard to say - relevant_external_organ = /obj/item/organ/internal/ears + //relevant_external_organ = /obj/item/organ/internal/ears /datum/preference/tri_color/ears_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -203,7 +203,7 @@ savefile_key = "spines_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/spines + //relevant_external_organ = /obj/item/organ/external/spines /datum/preference/tri_color/spines_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -237,7 +237,7 @@ savefile_key = "caps_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/tail + //relevant_external_organ = /obj/item/organ/external/tail /datum/preference/tri_color/caps_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -271,7 +271,6 @@ savefile_key = "moth_markings_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/moth /datum/preference/tri_color/moth_markings_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -305,7 +304,6 @@ savefile_key = "body_markings_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/lizard /datum/preference/tri_color/body_markings_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -339,7 +337,7 @@ savefile_key = "wings_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/wings + //relevant_external_organ = /obj/item/organ/external/wings /datum/preference/tri_color/wings_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), @@ -374,7 +372,7 @@ savefile_key = "moth_antennae_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES - relevant_external_organ = /obj/item/organ/external/wings + //relevant_external_organ = /obj/item/organ/external/wings /datum/preference/tri_color/moth_antennae_color/create_default_value() return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm index d125b756dca19..4281428983071 100644 --- a/modular_doppler/enterprise_resource_planning/code/breasts.dm +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -1,6 +1,10 @@ /datum/species/get_features() var/list/features = ..() - features += GLOB.preference_entries[/datum/preference/choiced/breasts] + + features += /datum/preference/choiced/breasts + + GLOB.features_by_species[type] = features + return features diff --git a/modular_doppler/languages/language.dmi b/modular_doppler/languages/language.dmi index 5ece55bc6f3a8eb04d491578829367437e741830..4c42de23601854450d4e10d297681420332af8b3 100644 GIT binary patch literal 4772 zcmV;V5?k$wP)V=-0C=2@(#?v(Knw@)bLT07o>vrPZ@nxP=|SHiOk*c@KFUm5OP}6@;B857 z3H%8EknG{_a&7O>+*&hJE}SCNa6TMO_2Nz()NuMWl_Tz*e3~LC1U2kNjK$;3c4w-N zbAcL8rg~%y^r^qnVO&{Nb6S2z?s|?YT_`V%y0aMBPjMAh7Un_lnRPg#r41~3n?gu> z#_omrq0bvKd9Sj564{V$O+KJ?s>9+W#eO1Pu9K%N7jY~ct!F#vJ6lKA>5miAOl2he zcj6u{_Xe6CD!0-L+s_UKEQW1SBDWa1uyDp8Ln)Ih@xdSnjrZ_dAoxInT>^&iU~DJ#RTMcDo(_ z)QwB~L*IasmX)n0O6ecg?qvSa_YzH-iMo(&(Moc1O^xD%OUv07tyC?ytZX$|nwNz8 z5<*y-mjvOl8rX@_o{HxqUSBDnvD@v~`QTs+PrC4 zu%lAZDKx*Vy$zj5cgxC9c#dul<`!n)d{Zv~@Wh+=ryD~Ts_5NF! zWaRFx=C8A-;(2080$hW@immU-?oBP958?5^Q&Z>B-OPf~VDDMI`qqy>P+x+ehuz0SUvE4ti+=;`_nokw>wWs6pl+BG#~!H!Bs z2u=uh!H!A>5&AwFrc02D@a#1F^-2$3baBOhcZI>@vnQeZjE@iR&(FJM*GR7Wv+Dg8 z%*aLkQ_<5ce0MPpHnOtT^FaCO^2Y>pK;Nyj~Z%`R1`og+IT^@*=Q_TyWZ-;L4_DUVP;6uBS7&6fsPm?Nbw>5xF19&fNdiuH4&wn^ zJoMUO1VY?5FqVF?%>ki*xj*B)`(Od^%}6j74gi3Ta0YVsR*TZ4?xW$2D5Epg7qb%3 zmh1#R%YX&I^n4Ql;8Lp>Usy8myN8^(K9GP6Wp=2aJXI_2|VD={i6F z5CGggEb5&>WH>V5a5xlKB}xvYO0N4eEaoJ|JnAS4QLi1wm3||iKP80~!4o==nTWM8 z1*J5dp=nBGq*_+Cnpmw?^jdqdIb8?yB<>;HJuKEmfM+NzCoN3!xbIsyk*1PDl){si zpD=(*?o)H*cpw6Z2yY^#+QB4TIiPn!{GeI~HRB|5Gj}qX`qzT)N`Tr`_{lKP{ ztD-O}oS7SQ_!Jix@1)0eyM49ve7rX~UOoQEBVncVPmdpu*)Z?@rBC$y&;Kk<@%d#T zOu-cu6(K#%z^9+8JBz<}Sy4J)7ZKzrtW|=fUD9(kh}KJw636tz5w9Pu%;S$d5_S&_ zDdw9K5=b*t9YcbhhpBocAb3y`9`nZRN z7&UhS9K6iwImn!zgSK{Vl|{e3+7IB>ejsxu50JtGfb=wj$bAPJ1N^ZX#Ny)Ool-FS zJ@OrsQK>@QG)U$NmJPYRNvt3>=*UZQ7mCsw3uomZgCdk)9Np-qEUF4y&tQJQ$+B9F*j1MtBO-_s;&t@uHr-N_qavwlR8n!nbu2> zk}Z7=D9Z1HC4ULJPb|i7y1xPd{KtvgVaZ>DK=(=P|2mhvlvadDec>m^j;UqEtaD$! z%)=ByY-_I;oofN$j%)|okP2W7B84XH50x}JRRKoBS1ojuEWafd<0Yxa@fx_?wIB?EBKb(Dj9Bd58@`X~E zx+p3VJje9IOzCt$<4Ys1)`Q4;_z*UnSPTHjdiW5!Pb@}C`V^GT*D($pj@A@DId+T> z*&A^r1?ui`qYa$vl=?*tz)g}*)tv*RG1H* zPu#|&q)$Px{SU}`_zXESaO1 zOUptTP4^weIaT^opK8Zm0Nt{pI#&my}ir255 zSASB0K0SV16U~iMskxAfhP2RqK!l|nom5l3z3&R{$aX{wUCFdWsZUg0#sL$vl#`0O zF;@4{=}EjnydzHGN|$n~+gaadGXW66q#z^0`?2YUHxnjW6y(hWZ#??vhU)i}>VDu) z3v?n2f887$R|r>CRf+0v*svky`X?p7-bv46QFeB=sQs?4uBi3PSFR(h&x`l>ZD#;r z>5^v&0DN@tj|>1TFD)m=L=(2}-ppT1*0EZxRw9K5a6qkAYt*%9%WIoRRaF&9PDz4o zawe>{Or&R;QB_q%T3*`}wf@O9HKf@qomR`O-J6+p6>ss^5rr@XWJz%X09^g) zij6rO4#mIbg*Sdf0L`#I6pTNUI|*@d8pOrL0VIsOzw5%VRtsYwgqd%=u2}!%ni^8} zR1qq7+Oc-;n|zsVPyd?KtS(0F{)UKeH&AeD%J(EJOM@%5%EMJFi11Aw)A-()Ix+EMmYky14P9K4dcPElItgCnBzRzo53&nC;l`?u?N zh|XF609cVjH+n)Y4q4_m72DSSeMCBui z!jnQ&(yP^L_^@2MmCVUCHKZ(AymLa`*J>!_(`={WU^^8DfD7Hu2SBsWYa^hvj`e@l8(z<7l=)A9g zY(_4Gcv=FxMH@zF*bjt8z=T3@<>zA1Ka3$?5blCJgolPef+0d!7HyglFpMBd8(loa zN=q70eGtuFH&Ajv_g#Gum6kN{@ETpx+vY`KQDF0rwDNg%CHdHSkMe?K`|iz*G0}wM z>FIdUU_gb-1t-J6%et|FWziK1;YEW15l7+E8#f|<#R}D%qiWr=2j`laL}{VG2)ZU` zqHk&z+y!}HSszA5M&Jtu5DJCh$i|zP~+m> zvZ`_Qq0*9u0+SgOUTxkqRd{tJ`2c_eJ!8M)(6l3iI@Mo);)W8r;SJ9a2UD0UYL43$n0>!>-AwI zOn?yrr_+P0?VWty9^V1AsLn7a1B2F8h4Q&}fjFz`fwk`UkMhV!^(Q45Sl+ z7YznjGsbq}H30C;)~%u^I=kfn(o(##a0bTQC#~MACGUCFgoH0u2_sPCUQ3r zr`2F27=~V}g?AFSC1hazqKS3qn>9>XvIjLb2F+eK3QT6yxcX3*>_LsI4+SPOn!Rq+ z*cg;0d(io2jp%;6y1JMn^KD>R?%hEltS2YwQIaHn_i;YskxgX=eO|n1;I`|wS}Zu8 zo{rlR69E7p2ZQ)8zaLJ9!SDTk4En|lrn(Y2yX61?#Oy{xAOr$}P%wnBe+a>mFmyUC z;`KTV`2!eW{g~0?!RM?OcbVneUKGk&jE%l1xgTic`opz*-()&vwIb`tpbjNTK@m`v zWdViP1idUbcw}p}NcQ{j%h7(&n3RKt0XK>OTqXp);V={jk!QAUWzID<;og^?#Jw*) zDQn>DmIFAu<$%n6RK@>R!A#S~V^)a4K)(;cKoIddE#kCV%+$r>UlNmW&doKvsJuL; zWf`5e#GU$K!-6M|ENN42QDocWyfVz$wUJBSuj-G1cu zdU4L}#^)^OWFbreeNa(Bl+vS#0{T9i2?ZuIDmyv1R(28; zm}38do&qY#&L)6Imae3vL~g3~(ZN45OP4%LdJV~#tu?`vWya>MuQ0zDbtpSHz;7(j zIzQU&EYW{9jdLgFAE_T4;OOtkH?34h;Tbb#h(hq<#f#&10jcLYT4vtnAFYGFuVerz zIB6$L*N(AlOadId^jxl=aMrIQw<<&t!0ha7!m=#Z?R+{?9kTY(w^U(J*QMv0;L2Lh z06;pbiSrh9Bi{#ZJN$}li^v>TD>`?Nl<~(>h)Uq3vUFDy=T&YxLqXnBeW1&ei0PJh zMFm`1?w9$R+dcyTtZyoWRF>{)f>Ch7eG+LO=*n8pFj=GJyQ_&B=$lCzfOFqNUDL4h z6~&iE0RWYk9|8bW7jl~pLdUwY)-x1_rMsF~x~q9N(tc2wE-ZhuOSU<7$@PNh+!FdN ze=LMZK}u!G$%G{*Gve{BB-wtTG=$Zp8p=@=OPQNVJiyPgxtAI5?5M)8mbR)^h()cz z6|(SDO1l-L0pug<*)0d~tEH{Dv!hC}()y-CSshDvHHjreEjgLDlnYhgSfcxZbQGpK zeX1nl1tU4_R&*ghjamEXTTDulhj#`ANTnI(wlg1l=MxkvEbHj}4q1^Kbah;Z^Qsq2 zlyWzVMDxJ@!BmDW*Aij*2tzIa0000V=-0C=2@(y?m8Knw=p+4mG8nOhnN-Mkcs;30VjaaJtV=R0#JJH}7nA&{-e zn*<-?7t#@aF4y)B&8>9{4=}LJOw4KK&VUC-cvWN_dzuATpdfLHK@M#>A zow0jje%SMdOd*)8pH+9H+fo?Ov+1y~rr6J9%WV#{=OQdB(FgH^y|ZWX{O{u&;c{=F zxwY;O-CxWCk5z@;000nMNkl1dvH_No&K&Y$&zKsmSh96!F6gdHd}CM2;q;- z#4MqKjwuQ4I0Yxf&;TX18P8^u+Ay>br(j4jOA8Yg@Mhf>+`?o?7-+zu!D2E~9!r;3 z5=^FBsAq)UGGtGc;7C)Z*)_6Se-$MX^|NUtK-n-h3SM$?x z*Bio9hOnXt4+1R!Txom(0MOah9d|>Iw-5K+U%_>JA5*$;6{%ZWL+0_P& z$smgFQ!`(JR79rR@YkF7u+GC(|IJMX&rKhXyQc%Zdwh1$D|?2e@z1LL&6|>i^Ao4z zu}i1%)pws33ou&pQb()s?(`{th$Ky{2J4eU^cym%Z za^Ja+Gxl^`Y`VwQ?dVW^$77dH%gEA^f9%p}S$$5%*-ya^;ESP9++=P?(vh`)izrVz z`qVuTV|Ji8GtGcDOBe8$bl3q*&NTx7uDAMe#-5JfJky2yy#}N!bI19K(^d0?W-kP9 zN24MCD3NVXg?$CXlLv-{Sm8%@AQks}S=F|)?_7<`m1QyDi=hy1N75gr--^C3^!w8G zHqbyRZTrW%J;))MrRk97Db`r2r$<8dv1pQDFyg@V$61fUspV`?*UCMw?t-~KQ$|E^DQha z+(Yl3PUjkFdTe^gL1Y276)U4IS7Vg}9Py@>Tcn_%0Q2U~;jgBaTjW4vC}#U%va9K( zl2(M{`l6W6m)7A0sI6E@?8)jRW0eCO`FV5aprD|D&)e(lL05MW^XAS$N@gnJ5kZ30 z(zKcg9g~kT_2;w5RQF;600q7hQs65g05H|PnAD%oA{~>DiY!rN0n?}DL5UY6c!flkrJ!-$#;CiP!(bG#F?0|)Q6dYa-yFwANmRN zF*8t3CM@+~^Te65`ePOZ|Ih8fUS|)V?&=N>_cTS&>l9f#KyLOle_5(^)ct75IKuQE zp8>7yap0-`tw;NGT04!?h@SnWHH{ldkJsdy@b1;EQURI2_l2t zs6U@Ygn^J3;96S;?8(3>*8l)OuND72QXGyvW`q%U7xn1a=XDOfT?4`9R!y1Ik1*g%D$ z5X69}h!zt%CLd)==IR)Y-Ud(WVNCe`5p2x)5jN)h2ot`41fJHz(CBR_nX6-jGXcL8 zrXo<%N*D|$!rwoDS9ZKF3ns!@KnNlEB{TF$vl;Pe<5|(dNKJrxpEnxmy=sf1nSpXb zgCGEe+JA>|_up_aX{T}!tgTo{UfJ{A}l9E?j3rI&-NFI>K1|`Bm zsF2@_DCDQQ7Zc0ED+qW04Wahm@#HNFuYj%(gph59gqCo#$AoXCuu(@|2)Y7Hvl&JH zPlZ@rm?9f}ifC>iumn}&eBJX|Wb?$CXvsLj&_&SY)C0^^_hRy^I~TER_ASx7MFLPu z5Q-oj`FKPC0I55?ec&d(m(dY*Pav7rl*EWCfaCfi*-9@~9o6ly(9C0zR>H$!uub06H2_TeG783*Q2dn{NE#U_$5^l91aHo04ji|Cry#0nh00le2V~@ z0ev`>csgr55)w2>NJs!k1W$bB#(-7}(_mO6!kBG`h2*1Q+~i3z_W(x70~~QrPa5vr zxg)xi>Qc1)ax)1eCX!xbqORLy>bIDapwlKmr_~@S$%wv0JwgdO_)I2zzPVby8InTi z25K&$gbU|h2LR+`uaCD0k5ijA$q3t0{II2P|1B1ZAcfDAgaNIV32L>PUR{DgqtU>i zPk=_lQS8?zBB0k{K%0OblZkI96TsNOf2gP+ zr#5ZEziry2N>D0-&~Bm!n&0M_PqkO%=HVOX2n5dwoD1_)^w^cwVh zkW`!nK0I+kwIlK3!nxOZF@z$}*r0~i+FInk@(Q2s?lJS^Z7F_q_n2|#&KfHQF_*sZ{xzb*I^xRvweXKm1ppY?Aipq@xxhya z4H~)<6pp+a`BUl4+22k)?geAgMc6$3L_HiM`$Plolc8Hy$=1sLG-dg zOu6U7XRIHytRvqU6bXIQ(4dKB4N|CC0R?pl>F86uv||Tzp{WUTUV8y^UVA~-{_ML4 zarWJVveBm~{PzkbN1upkVFtZD0fYuaNYrVOpw(ikE)oBll#B~r?t{z1va;CQVG3#u z@s2*7-V%-C6CPBYSWDqQR8$ZEn3bO|%BL|xiM$Zi)zxH{)e7Tan9uu+9T^zup5T$~ z1|N1aM1`P;MO=yp-VA-y@QptopeTU!*n2$3;HAjO$RNTio;GExs>q6xGQMu{lI5g$ z$#OouqNI$Jt*VOaSyQG=A;L?oo=kv~YimfeU;KHx+3$^81WGvftOfKcYIGr%5LFf1 z$*z4{88*nR&{mX`k#Y7+&x_Hjp?uMHwb^;}4N|q|MG<*xLY?Rm z))fgr&AYDtGHNmzKE3nBUl3YelgXg2{xXF1qk)o_ilBrITh{VsUA$yDIjSENiNFSX zaa2DD8V{-}wv!E8*2=8G<4cke_GmZ2quqelbDzYP{3hAEH2_d*@!=#r#(Kqr(q#oa zY3dfZ;=%mgmCVVtHKf!c-ucndZ#9lAUNS#TK<1|j065ck%^N~)kn6y)KAp@8{Hzx% zO3KK0Ltgwg7{nK;THMgHFq^D6svpD$p%CT|^x4)(mEdVC0# zH=Y3iUIc0doC{p>@FG;&ZNQepX!d)7qNlmPTMnbrZUayLibwTDlq@AY_gE`m)>xE_ zJx?mnyu0>oWlTwCG^C|rozaL2j|W{013&AGc2!IXv;p^{5XC#7eCncfa{+Cdj3Quj?gvs{z zRNo=Q`lkF50ZJ`C)Me+O(lzqjO1lkp^_Nj;w~gev2=~J$i3?D?R`@SGNt4Nh#-d#O z?1^j~>(hzIn*`tFC>-foNY`j^BM?BkMuSuXx1D8!z1V5D<3M^k(g?viqY;kuELr=% zWN-%`9=~0UpBJ~v%GIC&0N1t}rqtp?O(uh8zZZFCD{4I5D7E-dnWBsga;%TD0&3<` z@N_k86PdIt>O9SyPf3zWe=fYc$9w1nC+Lt_A!kTUAAb!LWSMb|xj+ z$NMl9fI>6C4c`yn`4IWnuJP^E1(;z+v&#$2umi66wgOZHjyNmw^|_1>NQUAn&}_0| z*S@Vx@si~v+us4VMuXWF3#tKBn5@`gwcx{0I diff --git a/modular_doppler/languages/language_datums.dm b/modular_doppler/languages/language_datums.dm index 5e3212ccfa52a..b4ca17cd7f092 100644 --- a/modular_doppler/languages/language_datums.dm +++ b/modular_doppler/languages/language_datums.dm @@ -1,3 +1,12 @@ +/obj/item/organ/internal/tongue/get_possible_languages() + var/list/langs = ..() + langs += /datum/language/yangyu + langs += /datum/language/movespeak + return langs + + + +/// ACTUAL LANGUAGES BEGIN HERE /datum/language/yangyu name = "Yangyu" desc = "Also popularly known as \"Konjin\", this language group formally regarded as Orbital Sino-Tibetan is a result of a genetic relationship between Chinese, Tibetan, Burmese, and other Human languages of similar characteristics that was first proposed in the early 19th century and is extremely popular even in the space age. Originating from Asia, this group of tongues is the second most spoken by Human and Human-derived populations since the birth of Sol Common - and was a primary contender to be the Sol Federation's official language. Many loanwords, idioms, and cultural relics of Japanese, Ryukyuan, Korean, and other societies have managed to persist within it, especially in the daily lives of speakers coming from Martian cities." @@ -20,3 +29,16 @@ default_priority = 94 default_name_syllable_min = 1 default_name_syllable_max = 2 + +/datum/language/movespeak + name = "Move-Speak" + desc = "A primarily nonverbal language comprised of body movements, gesticulation, and sign language, with only intermittent warbles & other vocalizations. It's almost completely incomprehensible without its somatic components." + key = "M" + flags = TONGUELESS_SPEECH + space_chance = 30 + syllables = list( + "wa", "wawa", "awa", "a" + ) + icon = 'modular_doppler/languages/language.dmi' + icon_state = "movepeak" + default_priority = 93 diff --git a/modular_doppler/species/accessory_overrides.dm b/modular_doppler/species/accessory_overrides.dm new file mode 100644 index 0000000000000..e2d47bb5f4339 --- /dev/null +++ b/modular_doppler/species/accessory_overrides.dm @@ -0,0 +1,209 @@ +/datum/species/get_features() + var/list/features = ..() + + features += /datum/preference/choiced/lizard_snout + features += /datum/preference/choiced/lizard_frills + features += /datum/preference/choiced/lizard_horns + + GLOB.features_by_species[type] = features + + return features + + + + + +/// Snout fixing +/obj/item/organ/external/snout + name = "snout" + +/datum/bodypart_overlay/mutant/snout + layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 + +/datum/bodypart_overlay/mutant/snout/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) + overlay.color = limb.owner.dna.features["snout_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + overlay.color = limb.owner.dna.features["snout_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + overlay.color = limb.owner.dna.features["snout_color_3"] + return overlay + return overlay + +//core toggle +/datum/preference/toggle/snout + savefile_key = "has_snout" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/snout/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + target.dna.features["snout"] = "None" + +/datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) + . = ..() + if(target.dna.features["snout"]) + if(target.dna.features["snout"] != "None") + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/snout) + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + return . + var/obj/item/organ/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_SNOUT) + if(old_part) + old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + old_part.moveToNullspace() + +//sprite selection +/datum/preference/choiced/lizard_snout + category = PREFERENCE_CATEGORY_CLOTHING + +/datum/preference/choiced/lizard_snout/is_accessible(datum/preferences/preferences) + . = ..() + var/has_snout = preferences.read_preference(/datum/preference/toggle/snout) + if(has_snout == TRUE) + return TRUE + return FALSE + + + + + +/// Horns fixing +/obj/item/organ/external/horns + name = "horns" + +/datum/bodypart_overlay/mutant/horns + layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 + +/datum/bodypart_overlay/mutant/horns/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) + overlay.color = limb.owner.dna.features["horns_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + overlay.color = limb.owner.dna.features["horns_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + overlay.color = limb.owner.dna.features["horns_color_3"] + return overlay + return overlay + +//core toggle +/datum/preference/toggle/horns + savefile_key = "has_horns" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/horns/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + target.dna.features["horns"] = "None" + +/datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) + . = ..() + if(target.dna.features["horns"]) + if(target.dna.features["horns"] != "None") + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/horns) + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + return . + var/obj/item/organ/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_HORNS) + if(old_part) + old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + old_part.moveToNullspace() + +//sprite selection +/datum/preference/choiced/lizard_horns + category = PREFERENCE_CATEGORY_CLOTHING + +/datum/preference/choiced/lizard_horns/is_accessible(datum/preferences/preferences) + . = ..() + var/has_horns = preferences.read_preference(/datum/preference/toggle/horns) + if(has_horns == TRUE) + return TRUE + return FALSE + + + + + +/// Frills fixing +/obj/item/organ/external/frills + name = "frills" + +/datum/bodypart_overlay/mutant/frills + layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 + +/datum/bodypart_overlay/mutant/frills/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) + overlay.color = limb.owner.dna.features["frills_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + overlay.color = limb.owner.dna.features["frills_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + overlay.color = limb.owner.dna.features["frills_color_3"] + return overlay + return overlay + +//core toggle +/datum/preference/toggle/frills + savefile_key = "has_frills" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/frills/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + target.dna.features["frills"] = "None" + +/datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) + . = ..() + if(target.dna.features["frills"]) + if(target.dna.features["frills"] != "None") + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/frills) + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + return . + var/obj/item/organ/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_FRILLS) + if(old_part) + old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + old_part.moveToNullspace() + +//sprite selection +/datum/preference/choiced/lizard_frills + category = PREFERENCE_CATEGORY_CLOTHING + +/datum/preference/choiced/lizard_frills/is_accessible(datum/preferences/preferences) + . = ..() + var/has_frills = preferences.read_preference(/datum/preference/toggle/frills) + if(has_frills == TRUE) + return TRUE + return FALSE + + + + + +/// Standard bodymark fixing +/datum/bodypart_overlay/simple/body_marking/lizard + layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 + +/datum/bodypart_overlay/simple/body_marking/lizard/get_image(layer, obj/item/bodypart/limb) + var/gender_string = (use_gender && limb.is_dimorphic) ? (limb.gender == MALE ? MALE : FEMALE + "_") : "" //we only got male and female sprites + if(layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + return image(icon, gender_string + icon_state + "_" + limb.body_zone + "_2", layer = layer) + if(layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + return image(icon, gender_string + icon_state + "_" + limb.body_zone + "_3", layer = layer) + return image(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) + +/datum/bodypart_overlay/simple/body_marking/lizard/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) + overlay.color = limb.owner.dna.features["body_markings_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) + overlay.color = limb.owner.dna.features["body_markings_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) + overlay.color = limb.owner.dna.features["body_markings_color_3"] + return overlay + return overlay diff --git a/modular_doppler/species/bodypart_overrides.dm b/modular_doppler/species/bodypart_overrides.dm new file mode 100644 index 0000000000000..db2862542e110 --- /dev/null +++ b/modular_doppler/species/bodypart_overrides.dm @@ -0,0 +1,3 @@ +/obj/item/bodypart/head + /// Override of the eyes icon file - used for slugcats as test dummies, followed by teshies, vox, possibly moths & insects, and more! + var/eyes_icon diff --git a/modular_doppler/species/fallbacks.dmi b/modular_doppler/species/fallbacks.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4f5867e07e724a15ceb2638903a71ba2913faed2 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;m;-!5Tn`*LkmkKF1;}MA3GxeO zaCmkj4aiBU3W+FjNi9w;$}A|!%+F(BsF)KRR!~&>{Y!Ac$FEPcymhtCojD)8A=Kca z@q)e_1!5cyiE*d|0 zq;uX!^CUx2Pwx&3;~?Y9#$F0CsjT7l;v3i)KHlcf^{%~V4K$R;)5S4_V`g%K#2p}S W0R!VxY5#RV7K5j&pUXO@geCygCOLEf literal 0 HcmV?d00001 diff --git a/modular_doppler/species/lizards/icons/lizard_external.dmi b/modular_doppler/species/lizards/icons/lizard_external.dmi new file mode 100644 index 0000000000000000000000000000000000000000..cf74d73796c8c6121c0818fdac74e4a7f0ab9a5f GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;m;-!5T!HlRD%)E?im@cfFPOpM z*^M-ilB$r15|`BC)e_1!5cyiE*d|0 zq;uX!^CUx2Pwx&3;~?Y9#$F0CsjT7l;v3i)KHlcf^{%~V4K$R;)5S4_V`g%K#2p}S W0R!VxY5#RV7K5j&pUXO@geCygCOLEf literal 0 HcmV?d00001 diff --git a/modular_doppler/species/lizards/icons/lizard_markings.dmi b/modular_doppler/species/lizards/icons/lizard_markings.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b94ad9d570c7978d5406f1dcfe93fa9f8241ac5f GIT binary patch literal 1056 zcmV+*1mF9KP)fFDZ*Bkp zc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LY zR3KAHiHkEOv#1!zH00t;D@x2wg|OiYauah><5Nm9(^HG$lQU9_OAtCtu>-UYpMzHo zNA5w-2g*2+P3>WcFxJ2&VM~@n3R29L6p8sD9uIigLcCn2NR<69mjDT=Zk2q{}HDDnUJE#FW)b(#x9`; zsu6Z+N_#nfhs~khr~k#fV|mGX zb*Srqx`M-XN7zRCF?MmAlDr3j4q#dGDC++JOSmgDKZ6cY8GwfRQ#8J zf#W!i<2Zk?>i^7MUDM|3^*;=Uz2nX~FPBF+F_U1R;=*M)YlLI0EE1LU*%!M)VZ05@4tezz;xlxqDC`TUXW zo@fWP`XBOn{ow{L<7@Rl<}(IZ!dm?g`48#`INnteMmimLqKU80Tu+|S)zWaw9$8j9z zNs;|S4G{Hz12q4T8Cm}~K+*pVI*|QC4LYdw4^<=U{}vs{{-Fj``iJU~^?w5t{qH!= aGw~a^(sae!sw4LR0000)e_1!5cyiE*d|0 zq;uX!^CUx2Pwx&3;~?Y9#$F0CsjT7l;v3i)KHlcf^{%~V4K$R;)5S4_V`g%K#2p}S W0R!VxY5#RV7K5j&pUXO@geCygCOLEf literal 0 HcmV?d00001 diff --git a/modular_doppler/species/scugs/code/slugcat_accessories.dm b/modular_doppler/species/scugs/code/slugcat_accessories.dm new file mode 100644 index 0000000000000..9757d0e4628ae --- /dev/null +++ b/modular_doppler/species/scugs/code/slugcat_accessories.dm @@ -0,0 +1,78 @@ +//snouts +/datum/sprite_accessory/snouts/slugcat + icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + name = "Slugcat" + icon_state = "scug_standard" + +/datum/sprite_accessory/snouts/slugcat/sharp + name = "Slugcat Sharp" + icon_state = "scug_sharp" + +/datum/sprite_accessory/snouts/slugcat/round + name = "Slugcat Round" + icon_state = "scug_round" + +//frills +/datum/sprite_accessory/frills/slugcat + icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + name = "Slugcat" + icon_state = "scug_aquatic" + +/datum/sprite_accessory/frills/slugcat/sharp + name = "Slugcat Sharp" + icon_state = "scug_sharp" + +/datum/sprite_accessory/frills/slugcat/fluffy + name = "Slugcat Fluffy" + icon_state = "scug_fluffy" + +/datum/sprite_accessory/frills/slugcat/draconic + name = "Slugcat Draconic" + icon_state = "scug_dragon" + +//horns +/datum/sprite_accessory/horns/slugcat + icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + name = "Slugcat" + icon_state = "scug_standard" + +/datum/sprite_accessory/horns/slugcat/tall + name = "Slugcat Tall" + icon_state = "scug_tall" + +/datum/sprite_accessory/horns/slugcat/sharp + name = "Slugcat Sharp" + icon_state = "scug_sharp" + +/datum/sprite_accessory/horns/slugcat/forward + name = "Slugcat Droopy" + icon_state = "scug_forward" + +/datum/sprite_accessory/horns/slugcat/flopped + name = "Slugcat Long Flop" + icon_state = "scug_flopped" + +/datum/sprite_accessory/horns/slugcat/fluffy + name = "Slugcat Fluffy" + icon_state = "scug_fluffy" + +/datum/sprite_accessory/horns/slugcat/short + name = "Slugcat Short" + icon_state = "scug_short" + +//tails +/datum/sprite_accessory/tails/lizard/slugcat + icon = 'modular_doppler/species/scugs/icons/slugcat_tails.dmi' + name = "Slugcat" + icon_state = "scug_std" + +/datum/sprite_accessory/tails/lizard/slugcat/thick + name = "Slugcat Thick" + icon_state = "scug_thick" + +//body markings +/datum/sprite_accessory/lizard_markings/slugcat + icon = 'modular_doppler/species/scugs/icons/slugcat_markings.dmi' + name = "Slugcat Underbelly" + icon_state = "scug_lbelly" + gender_specific = TRUE diff --git a/modular_doppler/species/scugs/code/slugcat_bodyparts.dm b/modular_doppler/species/scugs/code/slugcat_bodyparts.dm new file mode 100644 index 0000000000000..91b4b26a06291 --- /dev/null +++ b/modular_doppler/species/scugs/code/slugcat_bodyparts.dm @@ -0,0 +1,38 @@ +/obj/item/bodypart/head/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = SPECIES_SLUGCAT + is_dimorphic = FALSE + eyes_icon = 'modular_doppler/species/scugs/icons/slugcat_eyes.dmi' + +/obj/item/bodypart/chest/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = SPECIES_SLUGCAT + is_dimorphic = TRUE + +/obj/item/bodypart/arm/left/lizard/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = SPECIES_SLUGCAT + +/obj/item/bodypart/arm/right/lizard/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = SPECIES_SLUGCAT + +/obj/item/bodypart/leg/left/digitigrade/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = BODYPART_ID_DIGITIGRADE + bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE + +/obj/item/bodypart/leg/left/digitigrade/slugcat/update_limb(dropping_limb = FALSE, is_creating = FALSE) + . = ..() + if(limb_id == SPECIES_LIZARD) + limb_id = SPECIES_SLUGCAT + +/obj/item/bodypart/leg/right/digitigrade/slugcat + icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + limb_id = BODYPART_ID_DIGITIGRADE + bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE + +/obj/item/bodypart/leg/right/digitigrade/slugcat/update_limb(dropping_limb = FALSE, is_creating = FALSE) + . = ..() + if(limb_id == SPECIES_LIZARD) + limb_id = SPECIES_SLUGCAT diff --git a/modular_doppler/species/scugs/code/slugcat_species.dm b/modular_doppler/species/scugs/code/slugcat_species.dm new file mode 100644 index 0000000000000..616ee548370d2 --- /dev/null +++ b/modular_doppler/species/scugs/code/slugcat_species.dm @@ -0,0 +1,124 @@ +/// Slugcat language holder - they are adept in understanding machines, though unable to speak the tongue themselves. +/datum/language_holder/slugcat + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/movespeak = list(LANGUAGE_ATOM), + /datum/language/machine = list(LANGUAGE_ATOM), + /datum/language/drone = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/movespeak = list(LANGUAGE_ATOM)) + + + +/datum/species/slugcat + // The Slugcats of Talon III + name = "\improper Slugcat" + plural_form = "Slugcats" + id = SPECIES_SLUGCAT + inherent_traits = list( + TRAIT_MUTANT_COLORS, + TRAIT_TACKLING_TAILED_DEFENDER, + ) + inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID + body_markings = list(/datum/bodypart_overlay/simple/body_marking/lizard = "None") + mutant_organs = list( + /obj/item/organ/external/horns = "Slugcat", + /obj/item/organ/external/frills = "None", + /obj/item/organ/external/snout = "Slugcat", + /obj/item/organ/external/tail/lizard = "Slugcat", + ) + payday_modifier = 1.0 + changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT + inert_mutation = /datum/mutation/human/mute + death_sound = 'modular_doppler/species/scugs/sounds/scugdeath.ogg' + species_language_holder = /datum/language_holder/slugcat + digitigrade_customization = DIGITIGRADE_OPTIONAL + + bodypart_overrides = list( + BODY_ZONE_HEAD = /obj/item/bodypart/head/slugcat, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/slugcat, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/lizard/slugcat, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/lizard/slugcat, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/digitigrade/slugcat, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/digitigrade/slugcat, + ) + +/// SOUNDS BREAKER +/datum/species/slugcat/get_scream_sound(mob/living/carbon/human/scug) + return pick( + 'modular_doppler/species/scugs/sounds/scugscream_1.ogg', + ) + +/datum/species/slugcat/get_cough_sound(mob/living/carbon/human/scug) + if(scug.physique == FEMALE) + return pick( + 'sound/voice/human/female_cough1.ogg', + 'sound/voice/human/female_cough2.ogg', + 'sound/voice/human/female_cough3.ogg', + 'sound/voice/human/female_cough4.ogg', + 'sound/voice/human/female_cough5.ogg', + 'sound/voice/human/female_cough6.ogg', + ) + return pick( + 'sound/voice/human/male_cough1.ogg', + 'sound/voice/human/male_cough2.ogg', + 'sound/voice/human/male_cough3.ogg', + 'sound/voice/human/male_cough4.ogg', + 'sound/voice/human/male_cough5.ogg', + 'sound/voice/human/male_cough6.ogg', + ) + +/datum/species/slugcat/get_cry_sound(mob/living/carbon/human/scug) + if(scug.physique == FEMALE) + return pick( + 'sound/voice/human/female_cry1.ogg', + 'sound/voice/human/female_cry2.ogg', + ) + return pick( + 'sound/voice/human/male_cry1.ogg', + 'sound/voice/human/male_cry2.ogg', + 'sound/voice/human/male_cry3.ogg', + ) + +/datum/species/lizard/get_sneeze_sound(mob/living/carbon/human/scug) + if(scug.physique == FEMALE) + return 'sound/voice/human/female_sneeze1.ogg' + return 'sound/voice/human/male_sneeze1.ogg' + +/datum/species/lizard/get_laugh_sound(mob/living/carbon/human/scug) + return 'modular_doppler/species/scugs/sounds/scuglaugh_1.ogg' + +/datum/species/lizard/get_sigh_sound(mob/living/carbon/human/scug) + if(scug.physique == FEMALE) + return 'sound/voice/human/female_sigh.ogg' + return 'sound/voice/human/male_sigh.ogg' + +/datum/species/lizard/get_sniff_sound(mob/living/carbon/human/scug) + if(scug.physique == FEMALE) + return 'sound/voice/human/female_sniff.ogg' + return 'sound/voice/human/male_sniff.ogg' +/// SOUNDS BREAKER END + +/datum/species/slugcat/get_species_description() + return "Nimble omnivores frequently cursed with chronic mutism and a natural aptitude for talking to machines, the Slugcats are a rare sight in systems far from their homeworld of Talon III. \ + Genetically engineered over untold cycles by the manipulation of their homeworld's Resonance field, Slugcats are crafty and intelligent, with incredible capabilities yet incredible fragility, \ + still carrying the scars of their homeworld's brush with death long, long ago." + +/datum/species/slugcat/get_species_lore() + return list( + "Nimble omnivores, both predator and prey, they served as the eyes and ears of the great mechanical minds, the Iterators, as they worked to uncover the secrets of the progenitor species who once ruled their homeworld. \ + Over time, Iterators began to see Slugcats as more than mere servants, treating them as friends and trusted allies despite their small stature. Gazes At Satellites, the leader \ + of the Primary Group began a research project in tandem with 6 Small Stones to try and further guide the growth & evolution of Slugcats.", + + "After many cycles of study & untold many, many more of natural adaptation, Slugcats have ascended to a more recognizable humanoid form, trading some of their nimbleness for craftiness \ + and intelligence to more than rival their most notable compeititors, the Scavs. When exploration probes from 4CA's Ministry of Contact entered orbit of Tallon III, \ + they were contacted by Gazes At Satellites, and soon Slugcats entered the collective consciousness of the galaxy...and due to their history, the baleful gaze of the AIA.", + + "Slugcats remain uncommonly seen beyond the Talon system, as their numbers remain few despite improvements that have been made to the safety and stability of the so-called \"Rain World's\" eco-system. \ + As such, those who do choose to venture beyond their world must do so with their Iterator's express approval and guidance, and typically seek employ and residence within outposts near the Talon system. \ + Slugcats who venture beyond Talon III typically retain the titles given to them by their tribe & Iterator, such as \"The Hunter\" or \"The Artificer\", although some take on the names given to them by their compatriots beyond the stars.", + + "Most of those who do venture beyond remain independents primarily tied to their homeworld, or within the service of the Fourth Celestial Alignment. The Iterators hold a steadfast neutral stance- \ + Talon III remains officially neutral & unaligned, which is how both they & the Slugcats prefer it. This has drawn intense ire from the AIA, whose attempts to convince Slugcats to join them have thus far failed; \ + the entire AIA playbook is based around collective trauma & hatred of uplifting factions...yet amongst the Slugcats' closest allies and confidantes are the Iterators, themselves such a faction. \ + As such, most Slugcats hold a strong dislike & distrust of the AIA, despite their official stance of neutrality.", + ) diff --git a/modular_doppler/species/scugs/icons.dmi b/modular_doppler/species/scugs/icons.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a78d1523292b4fa9778902ac74dd37a8d214a32d GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|t_KbrxbnZ@)&KqeOwx;i zf{Z0We!&b5&u*jvIXP7!5hX6E#mPmP1tppJc?=8{bArPPib}tK2`>2f^@*0ZuGYCT z=Yuzd8eBAf@JQ#pkLF2+BA&B5ER2JUFB^L)%y~5F$fOX3;FT83P4@0kFg1+s>^4^2 zyh1|d?9rKFQ)bNOO4Qcg@oQ&8FB`)_8R>hI?A<;B?RD{VaSY*@nVi7D?8dHe(2UW; zWrdN!1~UUzgA4`njxgN@xNA4`O3l literal 0 HcmV?d00001 diff --git a/modular_doppler/species/scugs/icons/bodyparts.dmi b/modular_doppler/species/scugs/icons/bodyparts.dmi new file mode 100644 index 0000000000000000000000000000000000000000..bd748505773f48d49bc3c8be886a7bf9c6a3b692 GIT binary patch literal 1440 zcmV;R1z-A!P)tJwpQo2*AL=WGJrb00001bW%=J06^y0W&i*Hs(MsdbVOxyV{&P5 zbZKvH004NLm6FX0!Y~ko&&gAS_AdTiy-17nU|%6D%{Ey`D{NMMeOtW!Q?GyInU*k|9;3tc*vFM?m? z(6^}>#^Nmaw5s4#4Quw#wODZCuhI9b3pV3|tJg5$JrWmCtt{wLfd4v|8tj!Ztoz^V zn}_%`5*J-uwUg#2{V*KHVvnI=7=~dOza`uIJr}~BgfsjevkEojXOle2!R&6R$rpaF zN)7XS+!53KHNVFNY5r+)iL{As_IoV<4ElTM_BZ=I z%s&G^?(Zi3o*6*HFbu;mei7cQKi@_ksZS@mjMR1ihosRJN;hX2??`B<|??(ma6mj-PFbu;m4C8-E ztsJ{`J?@Vk$vc%;dy%&!g08}i=w5m6ntt%DeTyIrT_XxQ<=bXdu#99gx}T>OIPT!UfNmi;?f5npEX0D{ u%82joZY{{G=%p=RS@7Wn;=9k=2>uJ@0KBRZIO!|^0000D((b%Qe zp)NtWJCebA4J3^Sv8UYS>5)3l>+(a*irvhR&^r*qL^}rG9>;i&O`;zhq-=+AyB?L? ze|PBJaL!q~iGfn5BeGg&6B`x7OM6Tcvufz#VmDLkm8CRxNVzGyQ>g);oS?d+OOu&C zGO%Y_&kr`#Bkn1DN><-ZJ5ujOTs|OoTTg$EDlr%2xdo`Dw;Bh?n%bYccl488{)TzR z!mv=5rvdp+aD`-CeOTc+66b?AB`ixz>IS+)$JZ*qrPN7}*1*R>5El!lgYaUv#n}sxK2O?#h{XuOohwoa5d75v zF6p$>Zs6LR99vuF30}QX+yJO=wg1kpKm-&jMw!?0g;CRXsgb^C8#{4Y#BVzRDQYvL zqm1nQ?YI(&+fVPus%snvmtkO&{1vd&XXqRCU4CbFe1G%?!5AVd<0tRyYEjP6N)ZQ?hkrzZY3VKEH%z0-v;HOx z?;7b&HKtx*bB{K&w8Cp&@WmxJFlyJQ`0%B_LT51qLG2qRc$OSqn2__3z;eb(%Y< zbj?QkYE+<{`U2+1&)TOJ)98-JNP^eoKYYH}WZ)To zb3GxmG$|u%0GC@`wctCnGoMytS(lhqc=Fn%Ez^g#9q{qpq~TFt%_m>RR6p!V^hkef zirz?eDx+rq-YyuzOOo$?)brA;PQ11BCx?1X?d0;6s`*I`y`im&vOaHZHGbjn7JB{k zfrOm^0?enS3;lSLCyb1j-!p(Vo$h|w41 zWwfG0oD9LeGgMxQ?>2557{unQvTt33yS5#N_-DbYOUN7VFZi7SMmEA;Y}6DyI!|@E zaK&Ouyz1#}uTZSOkMoOoSl@!Evg~KBf@pZ9)Cqs|cR7)n^I~4VZe0Gg6EQd!C^?hs zUQIEIT*m~+Lb^gX)=od9WGeLtMx~vk%Vt#|*dZw+!ulb*BN>CME%QGIw=YS(BmqMq zv1)A~A)&>6=5UU=onM3=g2e6*TtMZ}M=<7;%?BR!Xkt+K{6Xd(|JjKp*)ReZ?6~ZP z>KBn`UnlC%bQbw*`IZ(p-Vc&_WLaPm_wFU-P7xGI(mltWmU_V%Yr}KD>E8xh<1<(f z)Da0}n89FeaimpajJ0!h*p^1V+xfc^NYU}d0l%IOvEia(Hr(|R^$fVTZG8kO8f9dH uYO1DJ>?!79kA=|WUaG#K{^yRndR8n~eRBha7MsXF8iLuvZR)K26aEdCZN-NG literal 0 HcmV?d00001 diff --git a/modular_doppler/species/scugs/icons/slugcat_eyes.dmi b/modular_doppler/species/scugs/icons/slugcat_eyes.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b99a0bbb550f16ad7972a5588fc0bb3ab0b3457c GIT binary patch literal 1163 zcmeAS@N?(olHy`uVBq!ia0vp^4}kap2OE%-ZOp$8q!w0%M3lIs7AF^F7L;V>=P@u; z%$a&&KUcGX1j`4@`@u51rUk9_Zr4!_GJ2uiF=4&o19=apqubvrY?&;u-TFu2;inbX z^zS;E&a!*c9G&J7a$UOf>P!oVM{$!RZroISr+UQBNM%z`OQD^^B889N{vN6R$9T`; zPhe@!u9K|~(q^|EcPY!es=ldsby>`{lAAZ1_j?Jo9j|LX@;E4EaktG3V`FL%$~;5)Fapvs%@j3KerLDQfcIJke?Oyh9;OCdtoe){)sc z-U4TPKK^Qc_kEF{)buyMLfmBk#LLOct1tK%zL&uwovCF4gQCg-VZ-yEi@L5`mCiRh zV0f(P4$Eg7{p6m__XL3S=}q@_Bc`eLe)w2Wv2*Y4_+^>1^4`Cje*EymrBSD=Yfmve z45|5O%u+I^K|n~Mg@r?r(aD2iX2xcQ{>O{HZFs)*hiw|$y3L*q+snV7KK%5kSpBQ* zHZgHa1ozGJKk@G~r~Rbw=hVM&aVdUgRD8k$_KgDvr+^d0V-zuC4%Qs{yzOa*72~>q z^XfIZ^PZ>nd{n$vq&F?~rj8S%(}@}f4ogNw6^blDb}?^{;ks)z{tePUH6EY(W^inW zRo;&4^Uq(Ec>L=1(e2MozbA$^^tT^AZJE0x9uyODdit+Y-#psy`>p0qLA?GxTmQ>j zvOdpkdTjgSgnhC z%QB^sbzopr02Dg44*&oF literal 0 HcmV?d00001 diff --git a/modular_doppler/species/scugs/icons/slugcat_markings.dmi b/modular_doppler/species/scugs/icons/slugcat_markings.dmi new file mode 100644 index 0000000000000000000000000000000000000000..9784d69dd4e7b599c3f0607745701b3526dd60c5 GIT binary patch literal 470 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 aTqc|PdA8nXa{20Pz0c(G)!BNVXDbem9kNgW literal 0 HcmV?d00001 diff --git a/modular_doppler/species/scugs/sounds/scuglaugh_1.ogg b/modular_doppler/species/scugs/sounds/scuglaugh_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..33e49aceca961a087e71f108b441965254539dac GIT binary patch literal 17324 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%0A(^GIzmrFD}r>uKp|(v(hJT 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 literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 6d0079b983799..c0db475ba0d0a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -396,6 +396,7 @@ #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" #include "code\__DEFINES\~doppler\enterprise_resource_planning.dm" +#include "code\__DEFINES\~doppler\species.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_dreamluau.dm" #include "code\__HELPERS\_lists.dm" @@ -6375,6 +6376,13 @@ #include "modular_doppler\modular_cosmetics\code\neck\collar.dm" #include "modular_doppler\modular_cosmetics\code\suits\jacket.dm" #include "modular_doppler\modular_cosmetics\GAGS\greyscale_configs_neck.dm" +#include "modular_doppler\species\accessory_overrides.dm" +#include "modular_doppler\species\bodypart_overrides.dm" +#include "modular_doppler\species\lizards\code\lizard_accessories.dm" +#include "modular_doppler\species\lizards\code\lizard_species.dm" +#include "modular_doppler\species\scugs\code\slugcat_accessories.dm" +#include "modular_doppler\species\scugs\code\slugcat_bodyparts.dm" +#include "modular_doppler\species\scugs\code\slugcat_species.dm" #include "modular_doppler\sprite_accessories\code\hair.dm" #include "modular_doppler\tableflip\tableflip.dm" #include "modular_doppler\wargaming\code\game_kit.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx index db69ce3c443f0..ce3ff99894606 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx @@ -16,7 +16,7 @@ export const vagina_color: Feature = { }; export const has_breasts: FeatureToggle = { - name: 'Add Breasts', + name: 'Add Genitals: Breasts', category: 'GAMEPLAY', description: ` When toggled, adds breasts to your character. diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx index 6b835ce196897..543f1439238a6 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx @@ -1,43 +1,124 @@ -import { FeatureTriColorInput, FeatureColorInput, Feature } from '../base'; +import { FeatureTriColorInput, FeatureColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; + +export const has_snout: FeatureToggle = { + name: 'Add Part: Snout', + category: 'GAMEPLAY', + description: ` + When toggled, adds a snout to your character. + `, + component: CheckboxInput, +}; export const snout_color: Feature = { name: 'Snout Color', component: FeatureTriColorInput, }; + + +export const has_horns: FeatureToggle = { + name: 'Add Part: Horns', + category: 'GAMEPLAY', + description: ` + When toggled, adds horns to your character. + `, + component: CheckboxInput, +}; + export const horns_color: Feature = { name: 'Horns Color', component: FeatureTriColorInput, }; + + +export const has_frills: FeatureToggle = { + name: 'Add Part: Frills', + category: 'GAMEPLAY', + description: ` + When toggled, adds frills to your character. + `, + component: CheckboxInput, +}; + export const frills_color: Feature = { name: 'Frills Color', component: FeatureTriColorInput, }; + + +export const has_tail: FeatureToggle = { + name: 'Add Part: Tail', + category: 'GAMEPLAY', + description: ` + When toggled, adds a tail to your character. + `, + component: CheckboxInput, +}; + export const tail_color: Feature = { name: 'Tail Color', component: FeatureTriColorInput, }; + + +export const has_ears: FeatureToggle = { + name: 'Add Part: Snout', + category: 'GAMEPLAY', + description: ` + When toggled, adds fancy ears to your character. + `, + component: CheckboxInput, +}; + export const ears_color: Feature = { name: 'Ears Color', component: FeatureTriColorInput, }; + + +export const has_spines: FeatureToggle = { + name: 'Add Part: Spines', + category: 'GAMEPLAY', + description: ` + When toggled, adds spines to your character. + `, + component: CheckboxInput, +}; + export const spines_color: Feature = { name: 'Spines Color', component: FeatureTriColorInput, }; + + +export const has_caps: FeatureToggle = { + name: 'Add Part: Snout', + category: 'GAMEPLAY', + description: ` + When toggled, adds mushperson caps to your character. + `, + component: CheckboxInput, +}; + export const caps_color: Feature = { name: 'Caps Color', component: FeatureTriColorInput, }; -export const moth_markings_color: Feature = { - name: 'Moth Markings Color', - component: FeatureTriColorInput, + + +export const has_markings: FeatureToggle = { + name: 'Add Part: Basic Markings', + category: 'GAMEPLAY', + description: ` + When toggled, adds basic bodymarkings to your character. + `, + component: CheckboxInput, }; export const body_markings_color: Feature = { @@ -45,11 +126,49 @@ export const body_markings_color: Feature = { component: FeatureTriColorInput, }; + + +export const has_moth_markings: FeatureToggle = { + name: 'Add Part: Moth Markings', + category: 'GAMEPLAY', + description: ` + When toggled, adds moth-style bodymarkings to your character. + `, + component: CheckboxInput, +}; + +export const moth_markings_color: Feature = { + name: 'Moth Markings Color', + component: FeatureTriColorInput, +}; + + + +export const has_wings: FeatureToggle = { + name: 'Add Part: Wings', + category: 'GAMEPLAY', + description: ` + When toggled, adds wings to your character. + `, + component: CheckboxInput, +}; + export const wings_color: Feature = { name: 'Wings Color', component: FeatureTriColorInput, }; + + +export const has_antennae: FeatureToggle = { + name: 'Add Part: Antennae', + category: 'GAMEPLAY', + description: ` + When toggled, adds antennae to your character. + `, + component: CheckboxInput, +}; + export const moth_antennae_color: Feature = { name: 'Moth Antennae Color', component: FeatureTriColorInput, From 3cb648472eba36c00a431a37cb73a226ee505a03 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Wed, 4 Sep 2024 04:08:49 -0400 Subject: [PATCH 09/24] Some assorted fixes --- .../preferences/species_features/lizard.dm | 4 +- .../code/breasts.dm | 16 +++--- .../species/accessory_overrides.dm | 49 +++++++++++++------ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/code/modules/client/preferences/species_features/lizard.dm b/code/modules/client/preferences/species_features/lizard.dm index a0f0c58eadca4..7749b31a8b287 100644 --- a/code/modules/client/preferences/species_features/lizard.dm +++ b/code/modules/client/preferences/species_features/lizard.dm @@ -17,9 +17,9 @@ var/icon/accessory_icon = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) /// DOPPLER SHIFT ADDITION BEGIN accessory_icon.Blend(COLOR_RED, ICON_MULTIPLY) - var/icon/accessory_icon_2 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) + var/icon/accessory_icon_2 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ_2", EAST) accessory_icon_2.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) - var/icon/accessory_icon_3 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST) + var/icon/accessory_icon_3 = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ_3", EAST) accessory_icon_3.Blend(COLOR_BLUE, ICON_MULTIPLY) /// DOPPLER SHIFT ADDITION END final_icon.Blend(accessory_icon, ICON_OVERLAY) diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm index 4281428983071..d0c3e97818e2d 100644 --- a/modular_doppler/enterprise_resource_planning/code/breasts.dm +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -52,25 +52,21 @@ return SSaccessories.breasts_list /datum/bodypart_overlay/mutant/breasts/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb.owner == null) + return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["breasts_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND)) overlay.color = limb.owner.dna.features["breasts_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["breasts_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_2)) overlay.color = limb.owner.dna.features["breasts_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["breasts_color_3"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_3)) overlay.color = limb.owner.dna.features["breasts_color_3"] - return overlay - return overlay + return ..() /datum/bodypart_overlay/mutant/breasts/mutant_bodyparts_layertext(layer) switch(layer) @@ -106,6 +102,9 @@ //to_chat(world, "Begone, boobs.") target.dna.features["breasts"] = "Bare" +/datum/preference/toggle/breasts/create_default_value() + return FALSE + /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() /*to_chat(world, "Regenerating organs for [target], a [src], trying to add boobs") @@ -150,6 +149,9 @@ target.dna.features["breasts"] = value //to_chat(world, "Applied!") +/datum/preference/choiced/breasts/create_default_value() + return pick(SSaccessories.breasts_list["None"]) + /datum/preference/choiced/breasts/is_accessible(datum/preferences/preferences) . = ..() var/has_breasts = preferences.read_preference(/datum/preference/toggle/breasts) diff --git a/modular_doppler/species/accessory_overrides.dm b/modular_doppler/species/accessory_overrides.dm index e2d47bb5f4339..2f10ecef0c08e 100644 --- a/modular_doppler/species/accessory_overrides.dm +++ b/modular_doppler/species/accessory_overrides.dm @@ -21,16 +21,15 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/snout/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb.owner == null) + return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["snout_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["snout_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["snout_color_3"] - return overlay - return overlay + return ..() //core toggle /datum/preference/toggle/snout @@ -43,6 +42,9 @@ if(value == FALSE) target.dna.features["snout"] = "None" +/datum/preference/toggle/snout/create_default_value() + return FALSE + /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["snout"]) @@ -66,6 +68,9 @@ return TRUE return FALSE +/datum/preference/choiced/lizard_snout/create_default_value() + return pick(SSaccessories.snouts_list["None"]) + @@ -78,16 +83,15 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/horns/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb.owner == null) + return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["horns_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["horns_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["horns_color_3"] - return overlay - return overlay + return ..() //core toggle /datum/preference/toggle/horns @@ -100,6 +104,9 @@ if(value == FALSE) target.dna.features["horns"] = "None" +/datum/preference/toggle/horns/create_default_value() + return FALSE + /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["horns"]) @@ -123,6 +130,9 @@ return TRUE return FALSE +/datum/preference/choiced/lizard_horns/create_default_value() + return pick(SSaccessories.horns_list["None"]) + @@ -135,16 +145,15 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/frills/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb.owner == null) + return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["frills_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["frills_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["frills_color_3"] - return overlay - return overlay + return ..() //core toggle /datum/preference/toggle/frills @@ -157,6 +166,9 @@ if(value == FALSE) target.dna.features["frills"] = "None" +/datum/preference/toggle/frills/create_default_value() + return FALSE + /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["frills"]) @@ -180,6 +192,9 @@ return TRUE return FALSE +/datum/preference/choiced/lizard_frills/create_default_value() + return pick(SSaccessories.frills_list["None"]) + @@ -197,13 +212,15 @@ return image(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) /datum/bodypart_overlay/simple/body_marking/lizard/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb.owner == null) + return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["body_markings_color_1"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["body_markings_color_2"] - return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["body_markings_color_3"] - return overlay - return overlay + return ..() + +/datum/preference/choiced/lizard_body_markings/create_default_value() + return pick(SSaccessories.lizard_markings_list["None"]) From a10f4a0590f55691f3e5da1765940d228df45e31 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Wed, 4 Sep 2024 15:18:23 -0400 Subject: [PATCH 10/24] Fixing the fix, optional bodymarkings --- .../code/breasts.dm | 6 ++ .../species/accessory_overrides.dm | 64 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm index d0c3e97818e2d..89af26192374c 100644 --- a/modular_doppler/enterprise_resource_planning/code/breasts.dm +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -56,16 +56,22 @@ return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["breasts_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND)) overlay.color = limb.owner.dna.features["breasts_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["breasts_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_2)) overlay.color = limb.owner.dna.features["breasts_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["breasts_color_3"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_3)) overlay.color = limb.owner.dna.features["breasts_color_3"] + return overlay return ..() /datum/bodypart_overlay/mutant/breasts/mutant_bodyparts_layertext(layer) diff --git a/modular_doppler/species/accessory_overrides.dm b/modular_doppler/species/accessory_overrides.dm index 2f10ecef0c08e..8371473674ed1 100644 --- a/modular_doppler/species/accessory_overrides.dm +++ b/modular_doppler/species/accessory_overrides.dm @@ -25,10 +25,13 @@ return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["snout_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["snout_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["snout_color_3"] + return overlay return ..() //core toggle @@ -87,10 +90,13 @@ return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["horns_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["horns_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["horns_color_3"] + return overlay return ..() //core toggle @@ -149,10 +155,13 @@ return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["frills_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["frills_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["frills_color_3"] + return overlay return ..() //core toggle @@ -216,11 +225,66 @@ return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) overlay.color = limb.owner.dna.features["body_markings_color_1"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) overlay.color = limb.owner.dna.features["body_markings_color_2"] + return overlay else if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT_3)) overlay.color = limb.owner.dna.features["body_markings_color_3"] + return overlay return ..() /datum/preference/choiced/lizard_body_markings/create_default_value() return pick(SSaccessories.lizard_markings_list["None"]) + +//toggle prefs +/datum/preference/toggle/markings + savefile_key = "has_markings" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/markings/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + target.dna.features["lizard_markings"] = "None" + +/datum/preference/toggle/markings/create_default_value() + return FALSE + +//toggle pref integration +/datum/preference/choiced/lizard_body_markings + category = PREFERENCE_CATEGORY_CLOTHING + +/datum/preference/choiced/lizard_body_markings/is_accessible(datum/preferences/preferences) + . = ..() + var/has_markings = preferences.read_preference(/datum/preference/toggle/markings) + if(has_markings == TRUE) + return TRUE + return FALSE + +//manually adding them now +/datum/species/add_body_markings(mob/living/carbon/human/hooman) + . = ..() + if(hooman.dna.features["lizard_markings"] && hooman.dna.features["lizard_markings"] != "None") //loop through possible species markings + var/datum/bodypart_overlay/simple/body_marking/markings = new /datum/bodypart_overlay/simple/body_marking/lizard() // made to die... mostly because we cant use initial on lists but its convenient and organized + var/accessory_name = hooman.dna.features[markings.dna_feature_key] //get the accessory name from dna + var/datum/sprite_accessory/moth_markings/accessory = markings.get_accessory(accessory_name) //get the actual datum + + if(isnull(accessory)) + CRASH("Value: [accessory_name] did not have a corresponding sprite accessory!") + + for(var/obj/item/bodypart/part as anything in markings.applies_to) //check through our limbs + var/obj/item/bodypart/people_part = hooman.get_bodypart(initial(part.body_zone)) // and see if we have a compatible marking for that limb + + if(!people_part) + continue + + var/datum/bodypart_overlay/simple/body_marking/overlay = new /datum/bodypart_overlay/simple/body_marking/lizard() + + // Tell the overlay what it should look like + overlay.icon = accessory.icon + overlay.icon_state = accessory.icon_state + overlay.use_gender = accessory.gender_specific + overlay.draw_color = accessory.color_src ? hooman.dna.features["mcolor"] : null + + people_part.add_bodypart_overlay(overlay) From a290d01cff1a1fa593d9df64c74de7b830f633a5 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Wed, 4 Sep 2024 16:58:01 -0400 Subject: [PATCH 11/24] Re-ordering some things --- .../customization/code/accessory_overrides.dm | 0 .../code/accessory_overrides_lizard.dm} | 1 + .../code/accessory_overrides_moth.dm | 0 .../customization/code/bodypart_overrides.dm | 16 ++++++++++++++++ .../customization/code/custom_accessories.dm | 1 + .../icons}/fallbacks.dmi | Bin .../species/lizards/code/lizard_accessories.dm | 4 ++-- .../species/lizards/code/lizard_species.dm | 0 .../species/lizards/icons/bodyparts.dmi | Bin .../species/lizards/icons/lizard_external.dmi | Bin .../species/lizards/icons/lizard_markings.dmi | Bin .../species/lizards/icons/lizard_tail.dmi | Bin .../species/scugs/code/slugcat_accessories.dm | 10 +++++----- .../species/scugs/code/slugcat_bodyparts.dm | 14 +++++++------- .../species/scugs/code/slugcat_species.dm | 6 +++--- .../species/scugs/icons/bodyparts.dmi | Bin .../species/scugs/icons/slugcat_external.dmi | Bin .../species/scugs/icons/slugcat_eyes.dmi | Bin .../species/scugs/icons/slugcat_markings.dmi | Bin .../species/scugs/icons/slugcat_tails.dmi | Bin .../species/scugs/sounds/scugdeath.ogg | Bin .../species/scugs/sounds/scuglaugh_1.ogg | Bin .../species/scugs/sounds/scugscream_1.ogg | Bin modular_doppler/species/bodypart_overrides.dm | 3 --- modular_doppler/species/scugs/icons.dmi | Bin 279 -> 0 bytes tgstation.dme | 17 ++++++++++------- 26 files changed, 45 insertions(+), 27 deletions(-) create mode 100644 modular_doppler/customization/code/accessory_overrides.dm rename modular_doppler/{species/accessory_overrides.dm => customization/code/accessory_overrides_lizard.dm} (99%) create mode 100644 modular_doppler/customization/code/accessory_overrides_moth.dm create mode 100644 modular_doppler/customization/code/bodypart_overrides.dm create mode 100644 modular_doppler/customization/code/custom_accessories.dm rename modular_doppler/{species => customization/icons}/fallbacks.dmi (100%) rename modular_doppler/{ => customization}/species/lizards/code/lizard_accessories.dm (56%) rename modular_doppler/{ => customization}/species/lizards/code/lizard_species.dm (100%) rename modular_doppler/{ => customization}/species/lizards/icons/bodyparts.dmi (100%) rename modular_doppler/{ => customization}/species/lizards/icons/lizard_external.dmi (100%) rename modular_doppler/{ => customization}/species/lizards/icons/lizard_markings.dmi (100%) rename modular_doppler/{ => customization}/species/lizards/icons/lizard_tail.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/code/slugcat_accessories.dm (81%) rename modular_doppler/{ => customization}/species/scugs/code/slugcat_bodyparts.dm (61%) rename modular_doppler/{ => customization}/species/scugs/code/slugcat_species.dm (96%) rename modular_doppler/{ => customization}/species/scugs/icons/bodyparts.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/icons/slugcat_external.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/icons/slugcat_eyes.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/icons/slugcat_markings.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/icons/slugcat_tails.dmi (100%) rename modular_doppler/{ => customization}/species/scugs/sounds/scugdeath.ogg (100%) rename modular_doppler/{ => customization}/species/scugs/sounds/scuglaugh_1.ogg (100%) rename modular_doppler/{ => customization}/species/scugs/sounds/scugscream_1.ogg (100%) delete mode 100644 modular_doppler/species/bodypart_overrides.dm delete mode 100644 modular_doppler/species/scugs/icons.dmi diff --git a/modular_doppler/customization/code/accessory_overrides.dm b/modular_doppler/customization/code/accessory_overrides.dm new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/modular_doppler/species/accessory_overrides.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm similarity index 99% rename from modular_doppler/species/accessory_overrides.dm rename to modular_doppler/customization/code/accessory_overrides_lizard.dm index 8371473674ed1..3aed0527df471 100644 --- a/modular_doppler/species/accessory_overrides.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -4,6 +4,7 @@ features += /datum/preference/choiced/lizard_snout features += /datum/preference/choiced/lizard_frills features += /datum/preference/choiced/lizard_horns + features += /datum/preference/choiced/lizard_body_markings GLOB.features_by_species[type] = features diff --git a/modular_doppler/customization/code/accessory_overrides_moth.dm b/modular_doppler/customization/code/accessory_overrides_moth.dm new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/modular_doppler/customization/code/bodypart_overrides.dm b/modular_doppler/customization/code/bodypart_overrides.dm new file mode 100644 index 0000000000000..1e443cc80df80 --- /dev/null +++ b/modular_doppler/customization/code/bodypart_overrides.dm @@ -0,0 +1,16 @@ +/// If you need to make edits to existing bodyparts, do so in here. +/obj/item/bodypart/head + /// Override of the eyes icon file - used for slugcats as test dummies, followed by teshies, vox, possibly moths & insects, and more! + var/eyes_icon + +/obj/item/bodypart/head/lizard + head_flags = HEAD_ALL_FEATURES + +/obj/item/bodypart/head/moth + head_flags = HEAD_ALL_FEATURES + +/obj/item/bodypart/head/robot + head_flags = HEAD_EYESPRITES | HEAD_FACIAL_HAIR | HEAD_HAIR | HEAD_EYECOLOR + +/obj/item/bodypart/head/snail + head_flags = HEAD_EYESPRITES | HEAD_DEBRAIN | HEAD_FACIAL_HAIR | HEAD_HAIR diff --git a/modular_doppler/customization/code/custom_accessories.dm b/modular_doppler/customization/code/custom_accessories.dm new file mode 100644 index 0000000000000..0fc28fc9c3b36 --- /dev/null +++ b/modular_doppler/customization/code/custom_accessories.dm @@ -0,0 +1 @@ +// This is where our bespoke fluff, IPC antennae, etc accessories should go. diff --git a/modular_doppler/species/fallbacks.dmi b/modular_doppler/customization/icons/fallbacks.dmi similarity index 100% rename from modular_doppler/species/fallbacks.dmi rename to modular_doppler/customization/icons/fallbacks.dmi diff --git a/modular_doppler/species/lizards/code/lizard_accessories.dm b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm similarity index 56% rename from modular_doppler/species/lizards/code/lizard_accessories.dm rename to modular_doppler/customization/species/lizards/code/lizard_accessories.dm index 4ac1d8cbba679..a08724401bb6d 100644 --- a/modular_doppler/species/lizards/code/lizard_accessories.dm +++ b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm @@ -1,6 +1,6 @@ //snouts /datum/sprite_accessory/snouts/none - icon = 'modular_doppler/species/fallbacks.dmi' + icon = 'modular_doppler/customization/icons/fallbacks.dmi' name = "None" icon_state = "none" @@ -8,4 +8,4 @@ feature_key = "tail" /datum/sprite_accessory/lizard_markings - icon = 'modular_doppler/species/lizards/icons/lizard_markings.dmi' + icon = 'modular_doppler/customization/species/lizards/icons/lizard_markings.dmi' diff --git a/modular_doppler/species/lizards/code/lizard_species.dm b/modular_doppler/customization/species/lizards/code/lizard_species.dm similarity index 100% rename from modular_doppler/species/lizards/code/lizard_species.dm rename to modular_doppler/customization/species/lizards/code/lizard_species.dm diff --git a/modular_doppler/species/lizards/icons/bodyparts.dmi b/modular_doppler/customization/species/lizards/icons/bodyparts.dmi similarity index 100% rename from modular_doppler/species/lizards/icons/bodyparts.dmi rename to modular_doppler/customization/species/lizards/icons/bodyparts.dmi diff --git a/modular_doppler/species/lizards/icons/lizard_external.dmi b/modular_doppler/customization/species/lizards/icons/lizard_external.dmi similarity index 100% rename from modular_doppler/species/lizards/icons/lizard_external.dmi rename to modular_doppler/customization/species/lizards/icons/lizard_external.dmi diff --git a/modular_doppler/species/lizards/icons/lizard_markings.dmi b/modular_doppler/customization/species/lizards/icons/lizard_markings.dmi similarity index 100% rename from modular_doppler/species/lizards/icons/lizard_markings.dmi rename to modular_doppler/customization/species/lizards/icons/lizard_markings.dmi diff --git a/modular_doppler/species/lizards/icons/lizard_tail.dmi b/modular_doppler/customization/species/lizards/icons/lizard_tail.dmi similarity index 100% rename from modular_doppler/species/lizards/icons/lizard_tail.dmi rename to modular_doppler/customization/species/lizards/icons/lizard_tail.dmi diff --git a/modular_doppler/species/scugs/code/slugcat_accessories.dm b/modular_doppler/customization/species/scugs/code/slugcat_accessories.dm similarity index 81% rename from modular_doppler/species/scugs/code/slugcat_accessories.dm rename to modular_doppler/customization/species/scugs/code/slugcat_accessories.dm index 9757d0e4628ae..b95c1d478d172 100644 --- a/modular_doppler/species/scugs/code/slugcat_accessories.dm +++ b/modular_doppler/customization/species/scugs/code/slugcat_accessories.dm @@ -1,6 +1,6 @@ //snouts /datum/sprite_accessory/snouts/slugcat - icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + icon = 'modular_doppler/customization/species/scugs/icons/slugcat_external.dmi' name = "Slugcat" icon_state = "scug_standard" @@ -14,7 +14,7 @@ //frills /datum/sprite_accessory/frills/slugcat - icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + icon = 'modular_doppler/customization/species/scugs/icons/slugcat_external.dmi' name = "Slugcat" icon_state = "scug_aquatic" @@ -32,7 +32,7 @@ //horns /datum/sprite_accessory/horns/slugcat - icon = 'modular_doppler/species/scugs/icons/slugcat_external.dmi' + icon = 'modular_doppler/customization/species/scugs/icons/slugcat_external.dmi' name = "Slugcat" icon_state = "scug_standard" @@ -62,7 +62,7 @@ //tails /datum/sprite_accessory/tails/lizard/slugcat - icon = 'modular_doppler/species/scugs/icons/slugcat_tails.dmi' + icon = 'modular_doppler/customization/species/scugs/icons/slugcat_tails.dmi' name = "Slugcat" icon_state = "scug_std" @@ -72,7 +72,7 @@ //body markings /datum/sprite_accessory/lizard_markings/slugcat - icon = 'modular_doppler/species/scugs/icons/slugcat_markings.dmi' + icon = 'modular_doppler/customization/species/scugs/icons/slugcat_markings.dmi' name = "Slugcat Underbelly" icon_state = "scug_lbelly" gender_specific = TRUE diff --git a/modular_doppler/species/scugs/code/slugcat_bodyparts.dm b/modular_doppler/customization/species/scugs/code/slugcat_bodyparts.dm similarity index 61% rename from modular_doppler/species/scugs/code/slugcat_bodyparts.dm rename to modular_doppler/customization/species/scugs/code/slugcat_bodyparts.dm index 91b4b26a06291..ebcfcf5c86eaf 100644 --- a/modular_doppler/species/scugs/code/slugcat_bodyparts.dm +++ b/modular_doppler/customization/species/scugs/code/slugcat_bodyparts.dm @@ -1,24 +1,24 @@ /obj/item/bodypart/head/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = SPECIES_SLUGCAT is_dimorphic = FALSE - eyes_icon = 'modular_doppler/species/scugs/icons/slugcat_eyes.dmi' + eyes_icon = 'modular_doppler/customization/species/scugs/icons/slugcat_eyes.dmi' /obj/item/bodypart/chest/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = SPECIES_SLUGCAT is_dimorphic = TRUE /obj/item/bodypart/arm/left/lizard/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = SPECIES_SLUGCAT /obj/item/bodypart/arm/right/lizard/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = SPECIES_SLUGCAT /obj/item/bodypart/leg/left/digitigrade/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = BODYPART_ID_DIGITIGRADE bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE @@ -28,7 +28,7 @@ limb_id = SPECIES_SLUGCAT /obj/item/bodypart/leg/right/digitigrade/slugcat - icon_greyscale = 'modular_doppler/species/scugs/icons/bodyparts.dmi' + icon_greyscale = 'modular_doppler/customization/species/scugs/icons/bodyparts.dmi' limb_id = BODYPART_ID_DIGITIGRADE bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE diff --git a/modular_doppler/species/scugs/code/slugcat_species.dm b/modular_doppler/customization/species/scugs/code/slugcat_species.dm similarity index 96% rename from modular_doppler/species/scugs/code/slugcat_species.dm rename to modular_doppler/customization/species/scugs/code/slugcat_species.dm index 616ee548370d2..18680d4f4babb 100644 --- a/modular_doppler/species/scugs/code/slugcat_species.dm +++ b/modular_doppler/customization/species/scugs/code/slugcat_species.dm @@ -29,7 +29,7 @@ payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT inert_mutation = /datum/mutation/human/mute - death_sound = 'modular_doppler/species/scugs/sounds/scugdeath.ogg' + death_sound = 'modular_doppler/customization/species/scugs/sounds/scugdeath.ogg' species_language_holder = /datum/language_holder/slugcat digitigrade_customization = DIGITIGRADE_OPTIONAL @@ -45,7 +45,7 @@ /// SOUNDS BREAKER /datum/species/slugcat/get_scream_sound(mob/living/carbon/human/scug) return pick( - 'modular_doppler/species/scugs/sounds/scugscream_1.ogg', + 'modular_doppler/customization/species/scugs/sounds/scugscream_1.ogg', ) /datum/species/slugcat/get_cough_sound(mob/living/carbon/human/scug) @@ -85,7 +85,7 @@ return 'sound/voice/human/male_sneeze1.ogg' /datum/species/lizard/get_laugh_sound(mob/living/carbon/human/scug) - return 'modular_doppler/species/scugs/sounds/scuglaugh_1.ogg' + return 'modular_doppler/customization/species/scugs/sounds/scuglaugh_1.ogg' /datum/species/lizard/get_sigh_sound(mob/living/carbon/human/scug) if(scug.physique == FEMALE) diff --git a/modular_doppler/species/scugs/icons/bodyparts.dmi b/modular_doppler/customization/species/scugs/icons/bodyparts.dmi similarity index 100% rename from modular_doppler/species/scugs/icons/bodyparts.dmi rename to modular_doppler/customization/species/scugs/icons/bodyparts.dmi diff --git a/modular_doppler/species/scugs/icons/slugcat_external.dmi b/modular_doppler/customization/species/scugs/icons/slugcat_external.dmi similarity index 100% rename from modular_doppler/species/scugs/icons/slugcat_external.dmi rename to modular_doppler/customization/species/scugs/icons/slugcat_external.dmi diff --git a/modular_doppler/species/scugs/icons/slugcat_eyes.dmi b/modular_doppler/customization/species/scugs/icons/slugcat_eyes.dmi similarity index 100% rename from modular_doppler/species/scugs/icons/slugcat_eyes.dmi rename to modular_doppler/customization/species/scugs/icons/slugcat_eyes.dmi diff --git a/modular_doppler/species/scugs/icons/slugcat_markings.dmi b/modular_doppler/customization/species/scugs/icons/slugcat_markings.dmi similarity index 100% rename from modular_doppler/species/scugs/icons/slugcat_markings.dmi rename to modular_doppler/customization/species/scugs/icons/slugcat_markings.dmi diff --git a/modular_doppler/species/scugs/icons/slugcat_tails.dmi b/modular_doppler/customization/species/scugs/icons/slugcat_tails.dmi similarity index 100% rename from modular_doppler/species/scugs/icons/slugcat_tails.dmi rename to modular_doppler/customization/species/scugs/icons/slugcat_tails.dmi diff --git a/modular_doppler/species/scugs/sounds/scugdeath.ogg b/modular_doppler/customization/species/scugs/sounds/scugdeath.ogg similarity index 100% rename from modular_doppler/species/scugs/sounds/scugdeath.ogg rename to modular_doppler/customization/species/scugs/sounds/scugdeath.ogg diff --git a/modular_doppler/species/scugs/sounds/scuglaugh_1.ogg b/modular_doppler/customization/species/scugs/sounds/scuglaugh_1.ogg similarity index 100% rename from modular_doppler/species/scugs/sounds/scuglaugh_1.ogg rename to modular_doppler/customization/species/scugs/sounds/scuglaugh_1.ogg diff --git a/modular_doppler/species/scugs/sounds/scugscream_1.ogg b/modular_doppler/customization/species/scugs/sounds/scugscream_1.ogg similarity index 100% rename from modular_doppler/species/scugs/sounds/scugscream_1.ogg rename to modular_doppler/customization/species/scugs/sounds/scugscream_1.ogg diff --git a/modular_doppler/species/bodypart_overrides.dm b/modular_doppler/species/bodypart_overrides.dm deleted file mode 100644 index db2862542e110..0000000000000 --- a/modular_doppler/species/bodypart_overrides.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj/item/bodypart/head - /// Override of the eyes icon file - used for slugcats as test dummies, followed by teshies, vox, possibly moths & insects, and more! - var/eyes_icon diff --git a/modular_doppler/species/scugs/icons.dmi b/modular_doppler/species/scugs/icons.dmi deleted file mode 100644 index a78d1523292b4fa9778902ac74dd37a8d214a32d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|t_KbrxbnZ@)&KqeOwx;i zf{Z0We!&b5&u*jvIXP7!5hX6E#mPmP1tppJc?=8{bArPPib}tK2`>2f^@*0ZuGYCT z=Yuzd8eBAf@JQ#pkLF2+BA&B5ER2JUFB^L)%y~5F$fOX3;FT83P4@0kFg1+s>^4^2 zyh1|d?9rKFQ)bNOO4Qcg@oQ&8FB`)_8R>hI?A<;B?RD{VaSY*@nVi7D?8dHe(2UW; zWrdN!1~UUzgA4`njxgN@xNA4`O3l diff --git a/tgstation.dme b/tgstation.dme index c0db475ba0d0a..37e80244dc15d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6358,9 +6358,19 @@ #include "interface\fonts\spess_font.dm" #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" +#include "modular_doppler\customization\code\accessory_overrides.dm" +#include "modular_doppler\customization\code\accessory_overrides_lizard.dm" +#include "modular_doppler\customization\code\accessory_overrides_moth.dm" +#include "modular_doppler\customization\code\bodypart_overrides.dm" +#include "modular_doppler\customization\code\custom_accessories.dm" #include "modular_doppler\customization\code\dropdowns_to_icons.dm" #include "modular_doppler\customization\code\tri_color_prefs.dm" #include "modular_doppler\customization\code\tri_color_prefs_bespoke.dm" +#include "modular_doppler\customization\species\lizards\code\lizard_accessories.dm" +#include "modular_doppler\customization\species\lizards\code\lizard_species.dm" +#include "modular_doppler\customization\species\scugs\code\slugcat_accessories.dm" +#include "modular_doppler\customization\species\scugs\code\slugcat_bodyparts.dm" +#include "modular_doppler\customization\species\scugs\code\slugcat_species.dm" #include "modular_doppler\emotes\code\emotes.dm" #include "modular_doppler\emotes\code\added_emotes\animal_sounds.dm" #include "modular_doppler\emotes\code\added_emotes\human_things.dm" @@ -6376,13 +6386,6 @@ #include "modular_doppler\modular_cosmetics\code\neck\collar.dm" #include "modular_doppler\modular_cosmetics\code\suits\jacket.dm" #include "modular_doppler\modular_cosmetics\GAGS\greyscale_configs_neck.dm" -#include "modular_doppler\species\accessory_overrides.dm" -#include "modular_doppler\species\bodypart_overrides.dm" -#include "modular_doppler\species\lizards\code\lizard_accessories.dm" -#include "modular_doppler\species\lizards\code\lizard_species.dm" -#include "modular_doppler\species\scugs\code\slugcat_accessories.dm" -#include "modular_doppler\species\scugs\code\slugcat_bodyparts.dm" -#include "modular_doppler\species\scugs\code\slugcat_species.dm" #include "modular_doppler\sprite_accessories\code\hair.dm" #include "modular_doppler\tableflip\tableflip.dm" #include "modular_doppler\wargaming\code\game_kit.dm" From 2b18c3a40325f01a5baf880e7ad7592375ab003d Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 00:34:18 -0400 Subject: [PATCH 12/24] Tails, matrix moths, more fixing & sprite polish --- .../mutant_bodypart_overlay.dm | 2 +- .../customization/code/accessory_overrides.dm | 3 + .../code/accessory_overrides_lizard.dm | 128 ++++++++++++++++++ .../code/accessory_overrides_moth.dm | 81 +++++++++++ .../customization/code/tri_color_prefs.dm | 6 +- .../code/tri_color_prefs_bespoke.dm | 35 +++++ .../lizards/code/lizard_accessories.dm | 22 ++- .../species/lizards/icons/lizard_external.dmi | Bin 182 -> 3382 bytes .../species/lizards/icons/lizard_tail.dmi | Bin 182 -> 0 bytes .../species/lizards/icons/lizard_tails.dmi | Bin 0 -> 7277 bytes .../species/scugs/icons/slugcat_external.dmi | Bin 1972 -> 1972 bytes .../species/scugs/icons/slugcat_tails.dmi | Bin 3140 -> 3103 bytes .../mutant_tricolors.tsx | 30 +++- 13 files changed, 297 insertions(+), 10 deletions(-) delete mode 100644 modular_doppler/customization/species/lizards/icons/lizard_tail.dmi create mode 100644 modular_doppler/customization/species/lizards/icons/lizard_tails.dmi diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index d0250cce686eb..83691ea8a8ace 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -71,7 +71,7 @@ var/gender = (limb?.limb_gender == FEMALE) ? "f" : "m" var/list/icon_state_builder = list() icon_state_builder += sprite_datum.gender_specific ? gender : "m" //Male is default because sprite accessories are so ancient they predate the concept of not hardcoding gender - icon_state_builder += feature_key + icon_state_builder += feature_key_sprite ? feature_key_sprite : feature_key /// DOPPLER SHIFT EDIT: try to use the sprite key first, normal key otherwise icon_state_builder += get_base_icon_state() icon_state_builder += mutant_bodyparts_layertext(image_layer) diff --git a/modular_doppler/customization/code/accessory_overrides.dm b/modular_doppler/customization/code/accessory_overrides.dm index e69de29bb2d1d..d29dfe667f433 100644 --- a/modular_doppler/customization/code/accessory_overrides.dm +++ b/modular_doppler/customization/code/accessory_overrides.dm @@ -0,0 +1,3 @@ +/datum/bodypart_overlay/mutant + /// Annoying annoying annoyed annoyance - this is to avoid a massive headache trying to work around tails + var/feature_key_sprite = null diff --git a/modular_doppler/customization/code/accessory_overrides_lizard.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm index 3aed0527df471..c70ffd111d590 100644 --- a/modular_doppler/customization/code/accessory_overrides_lizard.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -4,6 +4,7 @@ features += /datum/preference/choiced/lizard_snout features += /datum/preference/choiced/lizard_frills features += /datum/preference/choiced/lizard_horns + features += /datum/preference/choiced/lizard_tail features += /datum/preference/choiced/lizard_body_markings GLOB.features_by_species[type] = features @@ -22,6 +23,8 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/snout/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() if(limb.owner == null) return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) @@ -87,6 +90,8 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/horns/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() if(limb.owner == null) return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) @@ -152,6 +157,8 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/mutant/frills/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() if(limb.owner == null) return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) @@ -209,11 +216,130 @@ +/// Tails fixing +/obj/item/organ/external/tail/lizard + name = "tail" + +/datum/bodypart_overlay/mutant/tail/lizard + layers = EXTERNAL_FRONT | EXTERNAL_FRONT_2 | EXTERNAL_FRONT_3 | EXTERNAL_BEHIND | EXTERNAL_BEHIND_2 | EXTERNAL_BEHIND_3 + feature_key_sprite = "tail" + +/datum/bodypart_overlay/mutant/tail/lizard/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() + if(limb.owner == null) + return ..() + if(draw_layer == bitflag_to_layer(EXTERNAL_FRONT)) + overlay.color = limb.owner.dna.features["tail_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND)) + overlay.color = limb.owner.dna.features["tail_color_1"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_FRONT_2)) + overlay.color = limb.owner.dna.features["tail_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_2)) + overlay.color = limb.owner.dna.features["tail_color_2"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_FRONT_3)) + overlay.color = limb.owner.dna.features["tail_color_3"] + return overlay + else if(draw_layer == bitflag_to_layer(EXTERNAL_BEHIND_3)) + overlay.color = limb.owner.dna.features["tail_color_3"] + return overlay + return ..() + +//core toggle +/datum/preference/toggle/tail + savefile_key = "has_tail" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + priority = PREFERENCE_PRIORITY_DEFAULT + +/datum/preference/toggle/tail/apply_to_human(mob/living/carbon/human/target, value) + if(value == FALSE) + target.dna.features["tail_lizard"] = "None" + +/datum/preference/toggle/tail/create_default_value() + return FALSE + +/datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) + . = ..() + if(target == null) + return + if(target.dna.features["tail_lizard"]) + if(target.dna.features["tail_lizard"] != "None") + var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/tail/lizard) + replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + return . + var/obj/item/organ/external/tail/lizard/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + if(istype(old_part)) + to_chat(world, "Removing old tail on [src] for [target]") + old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) + old_part.moveToNullspace() + +//sprite selection +/datum/preference/choiced/lizard_tail + category = PREFERENCE_CATEGORY_CLOTHING + relevant_external_organ = null + should_generate_icons = TRUE + main_feature_name = "Tail" + +/datum/preference/choiced/lizard_tail/is_accessible(datum/preferences/preferences) + . = ..() + var/has_tail = preferences.read_preference(/datum/preference/toggle/tail) + if(has_tail == TRUE) + return TRUE + return FALSE + +/datum/preference/choiced/lizard_tail/create_default_value() + return /datum/sprite_accessory/tails/lizard/none::name + +/datum/preference/choiced/lizard_tail/icon_for(value) + var/datum/sprite_accessory/sprite_accessory = SSaccessories.tails_list_lizard[value] + + var/icon/final_icon = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m", NORTH) + + if (sprite_accessory.icon_state != "none") + var/icon/markings_icon_1 = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_BEHIND", NORTH) + markings_icon_1.Blend(COLOR_RED, ICON_MULTIPLY) + var/icon/markings_icon_2 = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_BEHIND_2", NORTH) + markings_icon_2.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + var/icon/markings_icon_3 = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_BEHIND_3", NORTH) + markings_icon_3.Blend(COLOR_BLUE, ICON_MULTIPLY) + final_icon.Blend(markings_icon_1, ICON_OVERLAY) + final_icon.Blend(markings_icon_2, ICON_OVERLAY) + final_icon.Blend(markings_icon_3, ICON_OVERLAY) + // front breaker + var/icon/markings_icon_1_f = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_FRONT", NORTH) + markings_icon_1_f.Blend(COLOR_RED, ICON_MULTIPLY) + var/icon/markings_icon_2_f = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_FRONT_2", NORTH) + markings_icon_2_f.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY) + var/icon/markings_icon_3_f = icon(sprite_accessory.icon, "m_tail_[sprite_accessory.icon_state]_FRONT_3", NORTH) + markings_icon_3_f.Blend(COLOR_BLUE, ICON_MULTIPLY) + final_icon.Blend(markings_icon_1_f, ICON_OVERLAY) + final_icon.Blend(markings_icon_2_f, ICON_OVERLAY) + final_icon.Blend(markings_icon_3_f, ICON_OVERLAY) + + //final_icon.Crop(4, 12, 28, 32) + //final_icon.Scale(32, 26) + //final_icon.Crop(-2, 1, 29, 32) + + return final_icon + + + + + /// Standard bodymark fixing /datum/bodypart_overlay/simple/body_marking/lizard layers = EXTERNAL_ADJACENT | EXTERNAL_ADJACENT_2 | EXTERNAL_ADJACENT_3 /datum/bodypart_overlay/simple/body_marking/lizard/get_image(layer, obj/item/bodypart/limb) + if(limb == null) + return ..() + if(limb.owner == null) + return ..() var/gender_string = (use_gender && limb.is_dimorphic) ? (limb.gender == MALE ? MALE : FEMALE + "_") : "" //we only got male and female sprites if(layer == bitflag_to_layer(EXTERNAL_ADJACENT_2)) return image(icon, gender_string + icon_state + "_" + limb.body_zone + "_2", layer = layer) @@ -222,6 +348,8 @@ return image(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) /datum/bodypart_overlay/simple/body_marking/lizard/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() if(limb.owner == null) return ..() if(draw_layer == bitflag_to_layer(EXTERNAL_ADJACENT)) diff --git a/modular_doppler/customization/code/accessory_overrides_moth.dm b/modular_doppler/customization/code/accessory_overrides_moth.dm index e69de29bb2d1d..b71ab3f2e69f4 100644 --- a/modular_doppler/customization/code/accessory_overrides_moth.dm +++ b/modular_doppler/customization/code/accessory_overrides_moth.dm @@ -0,0 +1,81 @@ +/// Moth bodymark fixing +/datum/bodypart_overlay/simple/body_marking/moth/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() + if(limb.owner == null) + return ..() + var/color_intended = COLOR_WHITE + + var/tcol_1 = limb.owner.dna.features["moth_markings_color_1"] + var/tcol_2 = limb.owner.dna.features["moth_markings_color_2"] + var/tcol_3 = limb.owner.dna.features["moth_markings_color_3"] + if(tcol_1 && tcol_2 && tcol_3) + //this is beyond ugly but it works + var/r1 = hex2num(copytext(tcol_1, 2, 4)) / 255.0 + var/g1 = hex2num(copytext(tcol_1, 4, 6)) / 255.0 + var/b1 = hex2num(copytext(tcol_1, 6, 8)) / 255.0 + var/r2 = hex2num(copytext(tcol_2, 2, 4)) / 255.0 + var/g2 = hex2num(copytext(tcol_2, 4, 6)) / 255.0 + var/b2 = hex2num(copytext(tcol_2, 6, 8)) / 255.0 + var/r3 = hex2num(copytext(tcol_3, 2, 4)) / 255.0 + var/g3 = hex2num(copytext(tcol_3, 4, 6)) / 255.0 + var/b3 = hex2num(copytext(tcol_3, 6, 8)) / 255.0 + color_intended = list(r1,g1,b1, r2,g2,b2, r3,g3,b3) + overlay.color = color_intended + return overlay + + + +/// Moth wings recolorening +/datum/bodypart_overlay/mutant/wings/moth/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() + if(limb.owner == null) + return ..() + var/color_intended = COLOR_WHITE + + var/tcol_1 = limb.owner.dna.features["moth_wings_color_1"] + var/tcol_2 = limb.owner.dna.features["moth_wings_color_2"] + var/tcol_3 = limb.owner.dna.features["moth_wings_color_3"] + if(tcol_1 && tcol_2 && tcol_3) + //this is beyond ugly but it works + var/r1 = hex2num(copytext(tcol_1, 2, 4)) / 255.0 + var/g1 = hex2num(copytext(tcol_1, 4, 6)) / 255.0 + var/b1 = hex2num(copytext(tcol_1, 6, 8)) / 255.0 + var/r2 = hex2num(copytext(tcol_2, 2, 4)) / 255.0 + var/g2 = hex2num(copytext(tcol_2, 4, 6)) / 255.0 + var/b2 = hex2num(copytext(tcol_2, 6, 8)) / 255.0 + var/r3 = hex2num(copytext(tcol_3, 2, 4)) / 255.0 + var/g3 = hex2num(copytext(tcol_3, 4, 6)) / 255.0 + var/b3 = hex2num(copytext(tcol_3, 6, 8)) / 255.0 + color_intended = list(r1,g1,b1, r2,g2,b2, r3,g3,b3) + overlay.color = color_intended + return overlay + + + +/// Moth antennae recolorening +/datum/bodypart_overlay/mutant/antennae/color_image(image/overlay, draw_layer, obj/item/bodypart/limb) + if(limb == null) + return ..() + if(limb.owner == null) + return ..() + var/color_intended = COLOR_WHITE + + var/tcol_1 = limb.owner.dna.features["moth_antennae_color_1"] + var/tcol_2 = limb.owner.dna.features["moth_antennae_color_2"] + var/tcol_3 = limb.owner.dna.features["moth_antennae_color_3"] + if(tcol_1 && tcol_2 && tcol_3) + //this is beyond ugly but it works + var/r1 = hex2num(copytext(tcol_1, 2, 4)) / 255.0 + var/g1 = hex2num(copytext(tcol_1, 4, 6)) / 255.0 + var/b1 = hex2num(copytext(tcol_1, 6, 8)) / 255.0 + var/r2 = hex2num(copytext(tcol_2, 2, 4)) / 255.0 + var/g2 = hex2num(copytext(tcol_2, 4, 6)) / 255.0 + var/b2 = hex2num(copytext(tcol_2, 6, 8)) / 255.0 + var/r3 = hex2num(copytext(tcol_3, 2, 4)) / 255.0 + var/g3 = hex2num(copytext(tcol_3, 4, 6)) / 255.0 + var/b3 = hex2num(copytext(tcol_3, 6, 8)) / 255.0 + color_intended = list(r1,g1,b1, r2,g2,b2, r3,g3,b3) + overlay.color = color_intended + return overlay diff --git a/modular_doppler/customization/code/tri_color_prefs.dm b/modular_doppler/customization/code/tri_color_prefs.dm index 48080911cd30e..8e9e5866a3674 100644 --- a/modular_doppler/customization/code/tri_color_prefs.dm +++ b/modular_doppler/customization/code/tri_color_prefs.dm @@ -357,12 +357,12 @@ // Gotta add to the selector too // TODO: can we migrate off of moth_wings for this? -/datum/preference/choiced/moth_wings/compile_constant_data() +/*/datum/preference/choiced/wings/compile_constant_data() var/list/data = ..() data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/wings_color::savefile_key - return data + return data*/ @@ -391,7 +391,7 @@ return TRUE // Gotta add to the selector too -/datum/preference/choiced/moth_wings/compile_constant_data() +/datum/preference/choiced/moth_antennae/compile_constant_data() var/list/data = ..() data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/moth_antennae_color::savefile_key diff --git a/modular_doppler/customization/code/tri_color_prefs_bespoke.dm b/modular_doppler/customization/code/tri_color_prefs_bespoke.dm index 7a8d955fd0c58..436a95a81c969 100644 --- a/modular_doppler/customization/code/tri_color_prefs_bespoke.dm +++ b/modular_doppler/customization/code/tri_color_prefs_bespoke.dm @@ -175,3 +175,38 @@ data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/xenohead_color::savefile_key return data*/ + + + +/// Moth wing colors! +/datum/preference/tri_color/moth_wings_color + priority = PREFERENCE_PRIORITY_BODY_TYPE + savefile_key = "moth_wings_color" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES + //relevant_external_organ = /obj/item/organ/external/wings + +/datum/preference/tri_color/moth_wings_color/create_default_value() + return list(sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"), + sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")) + +/datum/preference/tri_color/moth_wings_color/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["moth_wings_color_1"] = value[1] + target.dna.features["moth_wings_color_2"] = value[2] + target.dna.features["moth_wings_color_3"] = value[3] + +/datum/preference/tri_color/moth_wings_color/is_valid(value) + if (!..(value)) + return FALSE + + return TRUE + +// Gotta add to the selector too +// TODO: can we migrate off of moth_wings for this? +/datum/preference/choiced/moth_wings/compile_constant_data() + var/list/data = ..() + + data[SUPPLEMENTAL_FEATURE_KEY] = /datum/preference/tri_color/moth_wings_color::savefile_key + + return data diff --git a/modular_doppler/customization/species/lizards/code/lizard_accessories.dm b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm index a08724401bb6d..8a07757813d67 100644 --- a/modular_doppler/customization/species/lizards/code/lizard_accessories.dm +++ b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm @@ -1,11 +1,25 @@ //snouts +/datum/sprite_accessory/lizard_markings + icon = 'modular_doppler/customization/species/lizards/icons/lizard_markings.dmi' + +/datum/sprite_accessory/snouts + icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' + /datum/sprite_accessory/snouts/none icon = 'modular_doppler/customization/icons/fallbacks.dmi' name = "None" icon_state = "none" -/datum/bodypart_overlay/mutant/tail/lizard - feature_key = "tail" +/datum/sprite_accessory/frills + icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' -/datum/sprite_accessory/lizard_markings - icon = 'modular_doppler/customization/species/lizards/icons/lizard_markings.dmi' +/datum/sprite_accessory/horns + icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' + +/datum/sprite_accessory/tails/lizard + icon = 'modular_doppler/customization/species/lizards/icons/lizard_tails.dmi' + +/datum/sprite_accessory/tails/lizard/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "None" + icon_state = "none" diff --git a/modular_doppler/customization/species/lizards/icons/lizard_external.dmi b/modular_doppler/customization/species/lizards/icons/lizard_external.dmi index cf74d73796c8c6121c0818fdac74e4a7f0ab9a5f..ca7ad196b22930d371877f580d49f0caba5965db 100644 GIT binary patch literal 3382 zcmcJRX;>528pl(m7G<+8U@1%SDvGj*0uqD-L7-p*A|OlI1VKc03~NZJ7Evr>jeupX zm9hi_0)_|yB3mLLn+O3}0)!ADBoU${fsouoZNJ>->Ft+$=b1BSo|!W<@BH82`M>A( zIY&E%9jZGZ5Qu{Pw`a~nAfH)+_KoZ|aHaDS?mg&)Nv;cnsd=*(Dgt<+RG=Uw{x@$v9&bTxx=cmUpkQv-iL406hfP- zVT*dM`CjU`9xG@#c)%TAy|b

k)pm+=O7ZCA$yhI~@PQ76OqI*`GP>noz)*tcm#Ay%93q zeoHB;l5<98*XR5EAAND`{Nx!O;((m)G(|uDGg2%;efxn)u8GXb7MJHn@h(1dpOx-Q zh3M?RmwIh|n{|O6Dl7MAo!bwBO-tt2AzEKT&82WwF`s?U=$IDJ`;QH!)n8`VUlwhu zO2tt%?otdh{XUMqxVeH-?THbQY&>$#%AG*vrPq2>bn{(dDxM~{uZVHfQq^=1X+-u7 zLMsZbZY6y7FHujibPrm%Ty}0xU4ItQ)A^NRk{EGm?7-@Ja}-+g8&;!-f2E+mx}C|i zVYSd;@!PUR!>t4s3Ov+btXj3$?0ypf7FGK z1K&GKN!iTf!DA)$i7#urRAR|jDa=~I1D6*N=n^Yl(h#@Jvzagw*-)vn}mD+d5d^O~h zgE-=Jyhl6Q*mjr^d8EJ0ufw2+DNznik8_jas8hB$DW|xeh9RsX!&4WZZ)$=j&J(OG{A576N)>l)tP+l^EjVWb>(Uco0 z0$mx+TTl5KmKp)|yFL&M+bZLAmAx&27FUOlw7!tdtQ{fBc$$n=Dv@Uf!Y3g>2Li7Z z92aZNECGBrhH@KdgExaRbz!^KH`)3nvgz0TS!?2;$t~ojrV!3$XoaYkMVkqY-aXZv z;@0CWZ^uaZ1mZsVJ}Y7}kQ#hc1AiN{;~W$IgK0zJ<>QUj z8R3}5Tlm_Ek+g(tLB*6&I&Kz8OgZiR$_h*fCbN^Z-Vi)?K)G|NqQU&#%F1tbW+H$# zn8WYlvQ!(0VV?SdV65}2HWYdTN^P7iEGEAzX{#=Z?PiF@HhBKMS-P9Fkx@EE`_JMxxlkGZJVa>h|c32pHRsN7zq(07t1?C zGb>f=b_6wuzaN4wRn~e-@EM|t(1Oc4dOzvrcj)FDy_U(pA6JavS-Ere=cYjEQoo0T zv)dpWx+{poEOdh6>zlK~XnvW;r;!@q_VsdXpq!KwjT!^VW;-n>g%ht?g zyaJq*VhZpVTI3WJ zv}%QWMMryro|xSR*T6m#f{GLa3m>X+qmcD_sW79$Ykf$c1TC=ubrM?Nx8|O*6c~O& zlXNbA!v*Lwk=Uzb$9NcoeLMeql~4&SSHK!FE%rIr$+Cbv1)XP~ zfb6!mLYjN3~_boR;iSxL;ak8PD9VVkwyc4EZzq74bE=J|N2GV2>5ub}RA~!PN zqY!J^nRHFej43+VKf$v3mGi;QXq zh3TsP{qf=8_K)XyR!ebNW?+S)#ECO7FxWhEGe`~38>@;7Mx1Q9V)(C4AM=35GBWga1jZ+bylAb9YD+_TXGP}05^_@5KK(_XA5N6xwGz@7rF%r!q0@nZlhMcQ4#S?rSiGV+OyH?}JGVN6S7+K}Z(?ZY-98 znG$*NHYnu0@w>e9Z`WvJ5TegJx05$Z8T5K561jw1P#d<3k4j>Vze+E{;MS+mhZe&9 z)t9l2{d~i?BA2B8W+m)BN3@EjCHz{8PA+So)KIk4rr)246=C|8-5E>mT=jyKa~iZ3~7x_nt0@p zX#kv8vkz&Ul@i+he#!jVG&@W-r~&nKW=?eN(5bqV5EPLU=xCXiCy|dDh8Y*6bbtO| d!%k%_z;}np9pACH!+LX|y^Z6UDl7l%{{}*5jMD%B literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;m;-!5T!HlRD%)E?im@cfFPOpM z*^M-ilB$r15|`BC)e_1!5cyiE*d|0 zq;uX!^CUx2Pwx&3;~?Y9#$F0CsjT7l;v3i)KHlcf^{%~V4K$R;)5S4_V`g%K#2p}S W0R!VxY5#RV7K5j&pUXO@geCygCOLEf diff --git a/modular_doppler/customization/species/lizards/icons/lizard_tail.dmi b/modular_doppler/customization/species/lizards/icons/lizard_tail.dmi deleted file mode 100644 index cf74d73796c8c6121c0818fdac74e4a7f0ab9a5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;m;-!5T!HlRD%)E?im@cfFPOpM z*^M-ilB$r15|`BC)e_1!5cyiE*d|0 zq;uX!^CUx2Pwx&3;~?Y9#$F0CsjT7l;v3i)KHlcf^{%~V4K$R;)5S4_V`g%K#2p}S W0R!VxY5#RV7K5j&pUXO@geCygCOLEf diff --git a/modular_doppler/customization/species/lizards/icons/lizard_tails.dmi b/modular_doppler/customization/species/lizards/icons/lizard_tails.dmi new file mode 100644 index 0000000000000000000000000000000000000000..93788db36611894ac31763fc4654478df4407265 GIT binary patch literal 7277 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 iLD((b%Qe zp)NtWJCebA4J3^Sv8UYS>5)3l>+(a*irvhR&^r*qL^}rG9>;i&O`;zhq-=+AyB?L? ze|PBJaL!q~iGfn5BeGg&6B`x7OM6Tcvufz#VmDLkm8CRxNVzGyQ>g);oS?d+OOu&C zGO%Y_&kr`#Bkn1DN><-ZJ5ujOTs|OoTTg$EDlr%2xdo`Dw;Bh?n%bYccl488{)TzR z!mv=5rvdp+aD`-CeOTc+66b?AB`ixz>IS+)$JZ*qrPN7}*1*R>5El!lgYaUv#n}sxK2O?#h{XuOohwoa5d75v zF6p$>Zs6LR99vuF30}QX+yJO=wg1kpKm-&jMw!?0g;CRXsgb^C8#{4Y#BVzRDQYvL zqm1nQ?YI(&+fVPus%snvmtkO&{1vd&XXqRCU4CbFe1G%?!5AVd<0tRyYEjP6N)ZQ?hkrzZY3VKEH%z0-v;HOx z?;7b&HKtx*bB{K&w8Cp&@WmxJFlyJQ`0%B_LT51qLG2qRc$OSqn2__3z;eb(%Y< zbj?QkYE+<{`U2+1&)TOJ)98-JNP^eoKYYH}WZ)To zb3GxmG$|u%0GC@`wctCnGoMytS(lhqc=Fn%Ez^g#9q{qpq~TFt%_m>RR6p!V^hkef zirz?eDx+rq-YyuzOOo$?)brA;PQ11BCx?1X?d0;6s`*I`y`im&vOaHZHGbjn7JB{k zfrOm^0?enS3;lSLCyb1j-!p(Vo$h|w41 zWwfG0oD9LeGgMxQ?>2557{unQvTt33yS5#N_-DbYOUN7VFZi7SMmEA;Y}6DyI!|@E zaK&Ouyz1#}uTZSOkMoOoSl@!Evg~KBf@pZ9)Cqs|cR7)n^I~4VZe0Gg6EQd!C^?hs zUQIEIT*m~+Lb^gX)=od9WGeLtMx~vk%Vt#|*dZw+!ulb*BN>CME%QGIw=YS(BmqMq zv1)A~A)&>6=5UU=onM3=g2e6*TtMZ}M=<7;%?BR!Xkt+K{6Xd(|JjKp*)ReZ?6~ZP z>KBn`UnlC%bQbw*`IZ(p-Vc&_WLaPm_wFU-P7xGI(mltWmU_V%Yr}KD>E8xh<1<(f z)Da0}n89FeaimpajJ0!h*p^1V+xfc^NYU}d0l%IOvEia(Hr(|R^$fVTZG8kO8f9dH uYO1DJ>?!79kA=|WUaG#K{^yRndR8n~eRBha7MsXF8iLuvZR)K26aEdCZN-NG diff --git a/modular_doppler/customization/species/scugs/icons/slugcat_tails.dmi b/modular_doppler/customization/species/scugs/icons/slugcat_tails.dmi index f9ed88b5e49c8389fd31d4a0d5b129eb48e77de9..991bea5a1e7715c2df1e0e0ac8521355dd72c89a 100644 GIT binary patch delta 3065 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 literal 3140 zcmaJ@c{tQ<7aoi>vW~9>G4+=0HL|5KSt2w-$TCBCWr>Qc(}bC<6%rvN+q}xsAWM{G zX3A2+@QN&Dgx7A68KW^Xzfa%R``7o!bI$dg^IX??&bjXEKKDI48w+t!IZ+S@ByMGC zW)A`hP4i?@B!_~ zDGi#n>IYCrN@~+7ZF}uO?emB7r!v|z91l5I-AmS1sw+G2UT0>?TK#;_g@l@Kq9M~L zsCMX7@*~vXbTZ0*>Zu#jkmn{fW_@>XcHhkEe$$Mq@9j)xkKu0`!Z>XuUFDb1_F*c) zE#JKSuiRUz?XK}%x!Kqk)Eidz7XyBe2#~fiamz^0&A(uC=&Vi#tjEm7nnXA@?^qIt zcBKx{g!35!StPnXuX%2#w><(@W+sl<{FSFSV~D4q2^UZzF6E&Fy+M%!f+FyE^&Vbz z?ZcG=RxN6fj}IP=vUz^gM-`5>&G;6}e4BVF)7^*vZK5PDY{OP+O;YiJ_cx++ut zsGa1n68Eo!B+20`cnTNn6o9?DiAQuugCc8l`r(8K`Y^wAcS_I+&RvU6eg5Y*Ej9FD zz+kJyT8ZYVXmEe}iDTI7ecbq#H~K5M6Ft?k(bXT$Yu69DDga@5$Ah^`WDOflPoo|*@T`#T381dL z`=Z`Gu^_`vx)o-m-Iz+g2>#j?MEMe+z}yqS%lzp3x(qc`l^j&77**Jtv`q5+$NvT- zWy-J_#v>ZYI<2HnXMuJ5a!J)Sx+D9UaWyBQA1?;mJ5eG@;E$(;03@?&`4^Nz-pxZM zGal!7X93OSI)gySZ>{&Z2&Bn0x=2#_J?>I9<`#<3kKZVT9Onr|!_Ji{j}$9^c0bh? zehJcM%5n*S%Ne%b!8ckzd?q4neZEY&43iZ|C<4M=uL*6r?vd(fjF3ONg&BA!*r}vL zoPv1)CtFP3<3$fT_7*OJE9=GunPZ|!!YL?!UnLNgEQW&$9;}|O5Iz|Cj;2Xvyl4J=IQuiq&%mUE{DpF+v=xV!73vce z%Bk#D(JP6#F7KRD)E;;A7ldXmn@JLHtN{}9#Q+v!gdIY5Z$Gw#omuJ`agYfRW1W-i zCw2zYtsTl6jp?&DcIU*bjOTp^%RACx#V`jFED~ev{n5&{<|>kFD`MDMKm=_HoSQxioU{qvZ+xvH97mX3z`B`g z8dH%9L~w)bTmJNcn67@g)J;Gf4VLLND`&rrv7eaFnCWMzxc2)Tj3cR!y(;FkFNPW?RuN3yd`#DE`Vb0@$-*#l$u+cdAb`yVe zGkb_`k>k_d(zmhzv1x$#PINgVygnLHio)HK=F1OSgjdW^6O$s2Xal5s zgR+yhNu)8a`_3?Nd2B)X+9}wvc@{V|h@D#D(ch4y=&R3JQHX*SuNit+u9;(k6)b(N z(5l4)sEpbdhkWLer6(-z`W;YevYGrUWB9w@mUZkJ#mS?fXoCE3Pxt8-Tv2>3L=nS% zYi=lL8Qix|>X!aFk-!c%yQZ0n=c!cqz`IeG{2VcXKCwY!cm z>8}Kskj10GacetQlaFAN)x-TWGM}7xbA=&pm2R;HJgeZzi90*QFk%pXJ9kjLQv%b_ z=^>QQ+?z;-MPLLMB`n-1P4RJWgfy2XXQB0Ifw%V_avIKqOa-Q)avjex8xDJ#G=lRd zyNaJhe8SI^zO(I0TTNBS0%Z$|>MgWn*`eS;lu`ZpDb_n+O55N`Q0J;wJ&a%V0h>}H zZWwgB4fpVG3tDfV?&Y_VX{^;6b)u)4Tw#rS-T$TQ>Q@D$*-IH#PJaw4HPU%m zi^q979@sNQ&kzIKB$Q&|M%- z=E(9Npm(!q9zS5=2k~Ke>gB2I(G${_`+H;W>>rIB;<(3`&ZUWJC|RFerrSczz2)YE zpOG3knQu2Nl(HdXJ}L!l$dky_23+u2>JQ?Ze2K&V5p+Aq`EmLaCvx)xM`K%gy08kr zEMszP3yYL_Q8Iid%jShf0>sII+*xt#J;#Fln#8XLFG4dPFk4_*N;uK9t<(N$0gU(N5Icn%P2x| zJ-tObOTE5|5E#=aNhgg#d^Hw8~ = { component: FeatureTriColorInput, }; - - export const has_moth_markings: FeatureToggle = { name: 'Add Part: Moth Markings', category: 'GAMEPLAY', @@ -158,6 +156,20 @@ export const wings_color: Feature = { component: FeatureTriColorInput, }; +export const has_moth_wings: FeatureToggle = { + name: 'Add Part: Moth Wings', + category: 'GAMEPLAY', + description: ` + When toggled, adds matrix-colored moth wings to your character. + `, + component: CheckboxInput, +}; + +export const moth_wings_color: Feature = { + name: 'Moth Wings Color', + component: FeatureTriColorInput, +}; + export const has_antennae: FeatureToggle = { @@ -169,6 +181,20 @@ export const has_antennae: FeatureToggle = { component: CheckboxInput, }; +export const antennae_color: Feature = { + name: 'Antennae Color', + component: FeatureTriColorInput, +}; + +export const has_moth_antennae: FeatureToggle = { + name: 'Add Part: Moth Antennae', + category: 'GAMEPLAY', + description: ` + When toggled, adds matrix-colored moth antennae to your character. + `, + component: CheckboxInput, +}; + export const moth_antennae_color: Feature = { name: 'Moth Antennae Color', component: FeatureTriColorInput, From 9ba9b6e99ebbfa367a879ce641f939017df13778 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 01:05:14 -0400 Subject: [PATCH 13/24] sacrifices to the CI gods --- code/modules/surgery/organs/external/tails.dm | 7 ++++++ .../code/accessory_overrides_lizard.dm | 25 +++++++++++-------- .../code/breasts.dm | 5 ++-- .../preferences/features/base.tsx | 2 +- .../dopplershift_preferences/erp_parts.tsx | 2 +- .../mutant_newparts.tsx | 2 +- .../mutant_tricolors.tsx | 2 +- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index cae83153bdc55..c6b322f3668cf 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -40,6 +40,13 @@ receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_wrong) /obj/item/organ/external/tail/on_bodypart_insert(obj/item/bodypart/bodypart) + /// DOPPLER SHIFT ADDITION BEGIN + // damnit TG your own code fails CI for reasons unclear + if(bodypart == null) + return ..() + if(bodypart.owner == null) + return ..() + /// DOPPLER SHIFT ADDITION END var/obj/item/organ/external/spines/our_spines = bodypart.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_SPINES) if(our_spines) try_insert_tail_spines(bodypart) diff --git a/modular_doppler/customization/code/accessory_overrides_lizard.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm index c70ffd111d590..48724b6fd22ba 100644 --- a/modular_doppler/customization/code/accessory_overrides_lizard.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -75,8 +75,9 @@ return TRUE return FALSE -/datum/preference/choiced/lizard_snout/create_default_value() - return pick(SSaccessories.snouts_list["None"]) +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/lizard_snout/create_default_value() + return pick(SSaccessories.snouts_list["None"])*/ @@ -142,8 +143,9 @@ return TRUE return FALSE -/datum/preference/choiced/lizard_horns/create_default_value() - return pick(SSaccessories.horns_list["None"]) +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/lizard_horns/create_default_value() + return pick(SSaccessories.horns_list["None"])*/ @@ -209,8 +211,9 @@ return TRUE return FALSE -/datum/preference/choiced/lizard_frills/create_default_value() - return pick(SSaccessories.frills_list["None"]) +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/lizard_frills/create_default_value() + return pick(SSaccessories.frills_list["None"])*/ @@ -292,8 +295,9 @@ return TRUE return FALSE -/datum/preference/choiced/lizard_tail/create_default_value() - return /datum/sprite_accessory/tails/lizard/none::name +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/lizard_tail/create_default_value() + return /datum/sprite_accessory/tails/lizard/none::name*/ /datum/preference/choiced/lizard_tail/icon_for(value) var/datum/sprite_accessory/sprite_accessory = SSaccessories.tails_list_lizard[value] @@ -363,8 +367,9 @@ return overlay return ..() -/datum/preference/choiced/lizard_body_markings/create_default_value() - return pick(SSaccessories.lizard_markings_list["None"]) +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/lizard_body_markings/create_default_value() + return pick(SSaccessories.lizard_markings_list["None"])*/ //toggle prefs /datum/preference/toggle/markings diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm index 89af26192374c..4ab6388aa460a 100644 --- a/modular_doppler/enterprise_resource_planning/code/breasts.dm +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -155,8 +155,9 @@ target.dna.features["breasts"] = value //to_chat(world, "Applied!") -/datum/preference/choiced/breasts/create_default_value() - return pick(SSaccessories.breasts_list["None"]) +//random isn't ideal but CI is forcing our hands here +/*/datum/preference/choiced/breasts/create_default_value() + return pick(SSaccessories.breasts_list["None"])*/ /datum/preference/choiced/breasts/is_accessible(datum/preferences/preferences) . = ..() diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx index 6893f5acf203a..ef3ddeff938eb 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx @@ -115,7 +115,7 @@ export const FeatureTriColorInput = (props: FeatureValueProps) => { ? props.value[index] : `#${props.value[index]}`, border: '2px solid white', - 'box-sizing': 'content-box', + boxSizing: 'content-box', height: '11px', width: '11px', ...(props.shrink diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx index ce3ff99894606..5bcc087af112a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx @@ -1,4 +1,4 @@ -import { FeatureTriColorInput, FeatureColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; +import { FeatureTriColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; export const penis_color: Feature = { name: 'Penis Color', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx index c60452ea64391..230ccd9e29923 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx @@ -1,4 +1,4 @@ -import { FeatureTriColorInput, FeatureColorInput, Feature } from '../base'; +import { FeatureTriColorInput, Feature } from '../base'; export const fluff_color: Feature = { name: 'Fluff Color', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx index 3b2fc3cc9533b..cd11833f5c609 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx @@ -1,4 +1,4 @@ -import { FeatureTriColorInput, FeatureColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; +import { FeatureTriColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; export const has_snout: FeatureToggle = { name: 'Add Part: Snout', From 5e80e4e9e6b075ad6ee38dbb9d2a51868d61a2ac Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 01:16:49 -0400 Subject: [PATCH 14/24] CI Snackrifices Continued WHY IS *TGUI SPECIFIC PRETTIER* MANDATORY TO PASS CI AUGHGHGH THEIR CODE STYLE IS GIANT BLOBS --- code/__DEFINES/~doppler/species.dm | 3 ++- code/modules/surgery/organs/external/tails.dm | 2 +- .../preferences/features/base.tsx | 7 ++--- .../dopplershift_preferences/erp_parts.tsx | 10 ++++--- .../mutant_newparts.tsx | 4 +-- .../mutant_tricolors.tsx | 27 +++++-------------- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/code/__DEFINES/~doppler/species.dm b/code/__DEFINES/~doppler/species.dm index 56a4d9de13dd8..77e3b78260ad1 100644 --- a/code/__DEFINES/~doppler/species.dm +++ b/code/__DEFINES/~doppler/species.dm @@ -1 +1,2 @@ -#define SPECIES_SLUGCAT "slugcat" \ No newline at end of file +// Slugcats, from Talon III. +#define SPECIES_SLUGCAT "slugcat" diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index c6b322f3668cf..ba3e711f15974 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -41,7 +41,7 @@ /obj/item/organ/external/tail/on_bodypart_insert(obj/item/bodypart/bodypart) /// DOPPLER SHIFT ADDITION BEGIN - // damnit TG your own code fails CI for reasons unclear + // damnit TG your own code fails CI for reasons unclear - TODO, stack trace this to eventually figure out how it's ending up with null owners if(bodypart == null) return ..() if(bodypart.owner == null) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx index ef3ddeff938eb..1cf104c681512 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx @@ -106,7 +106,8 @@ export const FeatureTriColorInput = (props: FeatureValueProps) => { preference: props.featureId, value: index + 1, }); - }}> + }} + > ) => { width: '11px', ...(props.shrink ? { - 'margin': '1px', - } + margin: '1px', + } : {}), }} /> diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx index 5bcc087af112a..7ec2287ea9985 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/erp_parts.tsx @@ -1,4 +1,9 @@ -import { FeatureTriColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; +import { + CheckboxInput, + Feature, + FeatureToggle, + FeatureTriColorInput, +} from '../base'; export const penis_color: Feature = { name: 'Penis Color', @@ -24,8 +29,7 @@ export const has_breasts: FeatureToggle = { component: CheckboxInput, }; - export const breasts_color: Feature = { name: 'Breasts Color', component: FeatureTriColorInput, -}; \ No newline at end of file +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx index 230ccd9e29923..66aa6197aa49f 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_newparts.tsx @@ -1,4 +1,4 @@ -import { FeatureTriColorInput, Feature } from '../base'; +import { Feature, FeatureTriColorInput } from '../base'; export const fluff_color: Feature = { name: 'Fluff Color', @@ -23,4 +23,4 @@ export const xenodorsal_color: Feature = { export const xenohead_color: Feature = { name: 'Xenohead Color', component: FeatureTriColorInput, -}; \ No newline at end of file +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx index cd11833f5c609..36adc9e2f725c 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dopplershift_preferences/mutant_tricolors.tsx @@ -1,4 +1,9 @@ -import { FeatureTriColorInput, Feature, CheckboxInput, FeatureToggle } from '../base'; +import { + CheckboxInput, + Feature, + FeatureToggle, + FeatureTriColorInput, +} from '../base'; export const has_snout: FeatureToggle = { name: 'Add Part: Snout', @@ -14,8 +19,6 @@ export const snout_color: Feature = { component: FeatureTriColorInput, }; - - export const has_horns: FeatureToggle = { name: 'Add Part: Horns', category: 'GAMEPLAY', @@ -30,8 +33,6 @@ export const horns_color: Feature = { component: FeatureTriColorInput, }; - - export const has_frills: FeatureToggle = { name: 'Add Part: Frills', category: 'GAMEPLAY', @@ -46,8 +47,6 @@ export const frills_color: Feature = { component: FeatureTriColorInput, }; - - export const has_tail: FeatureToggle = { name: 'Add Part: Tail', category: 'GAMEPLAY', @@ -62,8 +61,6 @@ export const tail_color: Feature = { component: FeatureTriColorInput, }; - - export const has_ears: FeatureToggle = { name: 'Add Part: Snout', category: 'GAMEPLAY', @@ -78,8 +75,6 @@ export const ears_color: Feature = { component: FeatureTriColorInput, }; - - export const has_spines: FeatureToggle = { name: 'Add Part: Spines', category: 'GAMEPLAY', @@ -94,8 +89,6 @@ export const spines_color: Feature = { component: FeatureTriColorInput, }; - - export const has_caps: FeatureToggle = { name: 'Add Part: Snout', category: 'GAMEPLAY', @@ -110,8 +103,6 @@ export const caps_color: Feature = { component: FeatureTriColorInput, }; - - export const has_markings: FeatureToggle = { name: 'Add Part: Basic Markings', category: 'GAMEPLAY', @@ -140,8 +131,6 @@ export const moth_markings_color: Feature = { component: FeatureTriColorInput, }; - - export const has_wings: FeatureToggle = { name: 'Add Part: Wings', category: 'GAMEPLAY', @@ -170,8 +159,6 @@ export const moth_wings_color: Feature = { component: FeatureTriColorInput, }; - - export const has_antennae: FeatureToggle = { name: 'Add Part: Antennae', category: 'GAMEPLAY', @@ -198,4 +185,4 @@ export const has_moth_antennae: FeatureToggle = { export const moth_antennae_color: Feature = { name: 'Moth Antennae Color', component: FeatureTriColorInput, -}; \ No newline at end of file +}; From 16187e9e0961d09f4b96d3b519e09094d512bbf4 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 02:13:23 -0400 Subject: [PATCH 15/24] Final CI sacrifices (Hopefully) --- ...nshot_humanoids__datum_species_slugcat.png | Bin 0 -> 1188 bytes .../code/accessory_overrides_lizard.dm | 25 +++++++----------- .../lizards/code/lizard_accessories.dm | 15 +++++++++++ .../code/breasts.dm | 5 ++-- 4 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_slugcat.png diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_slugcat.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_slugcat.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6605e4742d3b6e3705ae88faf375ab5b35708a GIT binary patch literal 1188 zcmV;V1Y7%wP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6# za*U0*I5Sc+(=$pSoZ^zil2jm5Nr{UyC9|j)q@Ig2ttc@!6~s2=QdV&Fa{-$O0Gj_8 z4mqJ=L;wH-ib+I4R9J=0m+f}jAPk22CT#&521(lO{;zYdu#>exxZUZGO+8JVyy!tz zh@=SdUzvRO`1iU}LQ7+e)O5+~7P_72@ODmn@3nJaFxyMz40Pj^xVUsAti%{0G&NmBQ`hay4izz9kQi>CONs%lqGygT_;!DOe@4v<$WO3yQC9OH9 zl5$>CVfDDK@L$(B(K7%U{&;3qKwm(B#f8&F$!W!+3UN)D0pt{yxGeaO6TL#n1wq6* zuIT!@AONI-(Gg*ZWe3pJ0Khxj9pE0ssEb;vxC8pDLC2@F`6Glu7sj_xcR&rzn?d(< z_dSPk@q>;9#?+EhO{r947(g(T!AN;DVFUzY!ufK2efxR6oax25K{#Kp@V;K5j{p&Z zpa?QWKre<68|f0?Ht22iC!-{$%$|~6R|J^q^jR0|!km&D!08^s0iY`GklX>qX{Emj zKnQN4YXZ1qKqZ3a30l$uO7#&y5J52nrKGMf(I0r*bP&)X9uU+^bi)A-I8nYe*8irv z4WZt7JCs7zaKJ+o4Ft~-NbdmSf%p@KyIK2%KLGkO2Y}jjT5ni@|OIy&o$ri!gaFAJJHLx4Z}c1}kG@<-WTB11smT~N(ZCCCgw&fB7O zm{O>1L8}E@901Z%Dm8j6A0y~(KYbQK+9rh|g4h9x0yqR9gwz3#NucIWMKgT{NVIAl zCpl{Vl?o~?nw*3{8dcUxGs2^awA6+v01=i+Nid{gG-!3qVMm-B%JSv%`ZkN;?e%g& z)o$m>tXfNJN9}#<|E-M!(q>NAa_GMkN}V)ECuJ>%{+&>&86(#AQAW=ywm=PTM&xb_z@qosTW_pXC8ufmvi6GGL)SEYr z2iv^R@YD8y0DoAQRd*uBhd$r7?mq?e5ux2TCi@M$H$SQ#YRb$20000 Date: Thu, 5 Sep 2024 02:51:24 -0400 Subject: [PATCH 16/24] The Nonening this should fix the screenshot tests --- .../subsystem/sprite_accessories.dm | 14 +++++----- code/datums/sprite_accessories.dm | 12 ++++++--- code/~doppler_earliest_defines.dm | 26 +++++++++++++++++++ .../code/accessory_overrides_lizard.dm | 10 +++---- .../lizards/code/lizard_accessories.dm | 24 ----------------- .../code/breasts.dm | 2 +- tgstation.dme | 1 + 7 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 code/~doppler_earliest_defines.dm diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index 8930976610877..2049a5d46c940 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -91,17 +91,17 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST] snouts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts)[DEFAULT_SPRITE_LIST] - horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = TRUE)[DEFAULT_SPRITE_LIST] - ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = TRUE)[DEFAULT_SPRITE_LIST] - wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank wings_open_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open)[DEFAULT_SPRITE_LIST] - frills_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, add_blank = TRUE)[DEFAULT_SPRITE_LIST] - spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST] - tail_spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/tail_spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + frills_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + tail_spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/tail_spines, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps)[DEFAULT_SPRITE_LIST] moth_wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings)[DEFAULT_SPRITE_LIST] moth_antennae_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_antennae)[DEFAULT_SPRITE_LIST] - moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank pod_hair_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair)[DEFAULT_SPRITE_LIST] /// This proc just intializes all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index 784e9422541bd..2c01857ee0ace 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1724,9 +1724,11 @@ /datum/sprite_accessory/lizard_markings icon = 'icons/mob/human/species/lizard/lizard_markings.dmi' -/datum/sprite_accessory/lizard_markings/none +/// DOPPLER SHIFT REMOVAL BEGIN +/*/datum/sprite_accessory/lizard_markings/none name = "None" - icon_state = "none" + icon_state = "none"*/ +/// DOPPLER SHIFT REMOVAL END /datum/sprite_accessory/lizard_markings/dtiger name = "Dark Tiger Body" @@ -1752,10 +1754,12 @@ icon = 'icons/mob/human/species/lizard/lizard_tails.dmi' spine_key = SPINE_KEY_LIZARD -/datum/sprite_accessory/tails/lizard/none +/// DOPPLER SHIFT REMOVAL BEGIN +/*/datum/sprite_accessory/tails/lizard/none name = SPRITE_ACCESSORY_NONE icon_state = "none" - natural_spawn = FALSE + natural_spawn = FALSE*/ +/// DOPPLER SHIFT REMOVAL END /datum/sprite_accessory/tails/lizard/smooth name = "Smooth" diff --git a/code/~doppler_earliest_defines.dm b/code/~doppler_earliest_defines.dm new file mode 100644 index 0000000000000..4e8042c51c12d --- /dev/null +++ b/code/~doppler_earliest_defines.dm @@ -0,0 +1,26 @@ +/// Hi! This file is here to work around some order-of-operations issues consistent humans & a couple other things have. +/// If our overrides aren't loaded in early enough default TG stuff will end up in the critical [1] slot and break things. +/datum/sprite_accessory/lizard_markings/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "No Markings" + icon_state = "none" + +/datum/sprite_accessory/snouts/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "No Snout" + icon_state = "none" + +/datum/sprite_accessory/frills/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "No Frills" + icon_state = "none" + +/datum/sprite_accessory/horns/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "No Horns" + icon_state = "none" + +/datum/sprite_accessory/tails/lizard/none + icon = 'modular_doppler/customization/icons/fallbacks.dmi' + name = "No Tail" + icon_state = "none" diff --git a/modular_doppler/customization/code/accessory_overrides_lizard.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm index 1d3c6840f5d9d..bd06fa3c2a85f 100644 --- a/modular_doppler/customization/code/accessory_overrides_lizard.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -76,7 +76,7 @@ return FALSE /datum/preference/choiced/lizard_snout/create_default_value() - return "None" + return /datum/sprite_accessory/snouts/none::name @@ -143,7 +143,7 @@ return FALSE /datum/preference/choiced/lizard_horns/create_default_value() - return "None" + return /datum/sprite_accessory/horns/none::name @@ -210,7 +210,7 @@ return FALSE /datum/preference/choiced/lizard_frills/create_default_value() - return "None" + return /datum/sprite_accessory/frills/none::name @@ -293,7 +293,7 @@ return FALSE /datum/preference/choiced/lizard_tail/create_default_value() - return "None" + return /datum/sprite_accessory/tails/lizard/none::name /datum/preference/choiced/lizard_tail/icon_for(value) var/datum/sprite_accessory/sprite_accessory = SSaccessories.tails_list_lizard[value] @@ -364,7 +364,7 @@ return ..() /datum/preference/choiced/lizard_body_markings/create_default_value() - return "None" + return /datum/sprite_accessory/lizard_markings/none::name //toggle prefs /datum/preference/toggle/markings diff --git a/modular_doppler/customization/species/lizards/code/lizard_accessories.dm b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm index 05daad21dd648..90a0771ffc063 100644 --- a/modular_doppler/customization/species/lizards/code/lizard_accessories.dm +++ b/modular_doppler/customization/species/lizards/code/lizard_accessories.dm @@ -2,39 +2,15 @@ /datum/sprite_accessory/lizard_markings icon = 'modular_doppler/customization/species/lizards/icons/lizard_markings.dmi' -/datum/sprite_accessory/lizard_markings/none - icon = 'modular_doppler/customization/icons/fallbacks.dmi' - name = "None" - icon_state = "none" - /datum/sprite_accessory/snouts icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' -/datum/sprite_accessory/snouts/none - icon = 'modular_doppler/customization/icons/fallbacks.dmi' - name = "None" - icon_state = "none" - /datum/sprite_accessory/frills icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' -/datum/sprite_accessory/frills/none - icon = 'modular_doppler/customization/icons/fallbacks.dmi' - name = "None" - icon_state = "none" - /datum/sprite_accessory/horns icon = 'modular_doppler/customization/species/lizards/icons/lizard_external.dmi' -/datum/sprite_accessory/horns/none - icon = 'modular_doppler/customization/icons/fallbacks.dmi' - name = "None" - icon_state = "none" - /datum/sprite_accessory/tails/lizard icon = 'modular_doppler/customization/species/lizards/icons/lizard_tails.dmi' -/datum/sprite_accessory/tails/lizard/none - icon = 'modular_doppler/customization/icons/fallbacks.dmi' - name = "None" - icon_state = "none" diff --git a/modular_doppler/enterprise_resource_planning/code/breasts.dm b/modular_doppler/enterprise_resource_planning/code/breasts.dm index b3bc6b545eab7..cf2a8ea4772cc 100644 --- a/modular_doppler/enterprise_resource_planning/code/breasts.dm +++ b/modular_doppler/enterprise_resource_planning/code/breasts.dm @@ -156,7 +156,7 @@ //to_chat(world, "Applied!") /datum/preference/choiced/breasts/create_default_value() - return "Bare" + return /datum/sprite_accessory/breasts/bare::name /datum/preference/choiced/breasts/is_accessible(datum/preferences/preferences) . = ..() diff --git a/tgstation.dme b/tgstation.dme index 37e80244dc15d..d0464a3ae13f2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -19,6 +19,7 @@ #include "code\_compile_options.dm" #include "code\_experiments.dm" #include "code\world.dm" +#include "code\~doppler_earliest_defines.dm" #include "code\__DEFINES\__globals.dm" #include "code\__DEFINES\_atoms.dm" #include "code\__DEFINES\_bitfields.dm" From 5ad43ddf659c22365650eb4e1e3296e04a1ac8e5 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 17:29:45 -0400 Subject: [PATCH 17/24] CI: The Fixening Continues --- .../code/accessory_overrides_lizard.dm | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/modular_doppler/customization/code/accessory_overrides_lizard.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm index bd06fa3c2a85f..2ac55f371e7b8 100644 --- a/modular_doppler/customization/code/accessory_overrides_lizard.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -47,7 +47,7 @@ /datum/preference/toggle/snout/apply_to_human(mob/living/carbon/human/target, value) if(value == FALSE) - target.dna.features["snout"] = "None" + target.dna.features["snout"] = /datum/sprite_accessory/snouts/none::name /datum/preference/toggle/snout/create_default_value() return FALSE @@ -55,7 +55,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["snout"]) - if(target.dna.features["snout"] != "None") + if(target.dna.features["snout"] != /datum/sprite_accessory/snouts/none::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/snout) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -114,7 +114,7 @@ /datum/preference/toggle/horns/apply_to_human(mob/living/carbon/human/target, value) if(value == FALSE) - target.dna.features["horns"] = "None" + target.dna.features["horns"] = /datum/sprite_accessory/horns/none::name /datum/preference/toggle/horns/create_default_value() return FALSE @@ -122,7 +122,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["horns"]) - if(target.dna.features["horns"] != "None") + if(target.dna.features["horns"] != /datum/sprite_accessory/horns/none::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/horns) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -181,7 +181,7 @@ /datum/preference/toggle/frills/apply_to_human(mob/living/carbon/human/target, value) if(value == FALSE) - target.dna.features["frills"] = "None" + target.dna.features["frills"] = /datum/sprite_accessory/frills/none::name /datum/preference/toggle/frills/create_default_value() return FALSE @@ -189,7 +189,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["frills"]) - if(target.dna.features["frills"] != "None") + if(target.dna.features["frills"] != /datum/sprite_accessory/frills/none::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/frills) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -258,7 +258,7 @@ /datum/preference/toggle/tail/apply_to_human(mob/living/carbon/human/target, value) if(value == FALSE) - target.dna.features["tail_lizard"] = "None" + target.dna.features["tail_lizard"] = /datum/sprite_accessory/tails/lizard/none::name /datum/preference/toggle/tail/create_default_value() return FALSE @@ -268,13 +268,12 @@ if(target == null) return if(target.dna.features["tail_lizard"]) - if(target.dna.features["tail_lizard"] != "None") + if(target.dna.features["tail_lizard"] != /datum/sprite_accessory/tails/lizard/none::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/tail/lizard) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . var/obj/item/organ/external/tail/lizard/old_part = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) if(istype(old_part)) - to_chat(world, "Removing old tail on [src] for [target]") old_part.Remove(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) old_part.moveToNullspace() @@ -375,7 +374,7 @@ /datum/preference/toggle/markings/apply_to_human(mob/living/carbon/human/target, value) if(value == FALSE) - target.dna.features["lizard_markings"] = "None" + target.dna.features["lizard_markings"] = /datum/sprite_accessory/lizard_markings/none::name /datum/preference/toggle/markings/create_default_value() return FALSE @@ -394,7 +393,7 @@ //manually adding them now /datum/species/add_body_markings(mob/living/carbon/human/hooman) . = ..() - if(hooman.dna.features["lizard_markings"] && hooman.dna.features["lizard_markings"] != "None") //loop through possible species markings + if(hooman.dna.features["lizard_markings"] && hooman.dna.features["lizard_markings"] != /datum/sprite_accessory/lizard_markings/none::name) //loop through possible species markings var/datum/bodypart_overlay/simple/body_marking/markings = new /datum/bodypart_overlay/simple/body_marking/lizard() // made to die... mostly because we cant use initial on lists but its convenient and organized var/accessory_name = hooman.dna.features[markings.dna_feature_key] //get the accessory name from dna var/datum/sprite_accessory/moth_markings/accessory = markings.get_accessory(accessory_name) //get the actual datum From 91926f95771397281893536b82413626926e1911 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 17:53:56 -0400 Subject: [PATCH 18/24] undoes edits in sprite_accessories this means there will be both None and Blank options but y'know fucking what we deal with it --- code/controllers/subsystem/sprite_accessories.dm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index 2049a5d46c940..8930976610877 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -91,17 +91,17 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST] snouts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts)[DEFAULT_SPRITE_LIST] - horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank - ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank - wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] wings_open_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open)[DEFAULT_SPRITE_LIST] - frills_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank - spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank - tail_spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/tail_spines, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + frills_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST] + tail_spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/tail_spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST] caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps)[DEFAULT_SPRITE_LIST] moth_wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings)[DEFAULT_SPRITE_LIST] moth_antennae_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_antennae)[DEFAULT_SPRITE_LIST] - moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = FALSE)[DEFAULT_SPRITE_LIST] /// DOPPLER SHIFT EDIT: we add our own blank + moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] pod_hair_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair)[DEFAULT_SPRITE_LIST] /// This proc just intializes all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name From ac3f08a0b16b3a6eaf24bbcb768aaad98178fe07 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 18:14:52 -0400 Subject: [PATCH 19/24] checks for core blank accessory ughhhhh all of this just to deal with CI-exclusive bugs --- .../customization/code/accessory_overrides_lizard.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modular_doppler/customization/code/accessory_overrides_lizard.dm b/modular_doppler/customization/code/accessory_overrides_lizard.dm index 2ac55f371e7b8..7ded20b493d71 100644 --- a/modular_doppler/customization/code/accessory_overrides_lizard.dm +++ b/modular_doppler/customization/code/accessory_overrides_lizard.dm @@ -55,7 +55,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["snout"]) - if(target.dna.features["snout"] != /datum/sprite_accessory/snouts/none::name) + if(target.dna.features["snout"] != /datum/sprite_accessory/snouts/none::name && target.dna.features["snout"] != /datum/sprite_accessory/blank::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/snout) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -122,7 +122,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["horns"]) - if(target.dna.features["horns"] != /datum/sprite_accessory/horns/none::name) + if(target.dna.features["horns"] != /datum/sprite_accessory/horns/none::name && target.dna.features["horns"] != /datum/sprite_accessory/blank::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/horns) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -189,7 +189,7 @@ /datum/species/regenerate_organs(mob/living/carbon/target, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE) . = ..() if(target.dna.features["frills"]) - if(target.dna.features["frills"] != /datum/sprite_accessory/frills/none::name) + if(target.dna.features["frills"] != /datum/sprite_accessory/frills/none::name && target.dna.features["frills"] != /datum/sprite_accessory/blank::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/frills) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -268,7 +268,7 @@ if(target == null) return if(target.dna.features["tail_lizard"]) - if(target.dna.features["tail_lizard"] != /datum/sprite_accessory/tails/lizard/none::name) + if(target.dna.features["tail_lizard"] != /datum/sprite_accessory/tails/lizard/none::name && target.dna.features["tail_lizard"] != /datum/sprite_accessory/blank::name) var/obj/item/organ/replacement = SSwardrobe.provide_type(/obj/item/organ/external/tail/lizard) replacement.Insert(target, special = TRUE, movement_flags = DELETE_IF_REPLACED) return . @@ -393,7 +393,7 @@ //manually adding them now /datum/species/add_body_markings(mob/living/carbon/human/hooman) . = ..() - if(hooman.dna.features["lizard_markings"] && hooman.dna.features["lizard_markings"] != /datum/sprite_accessory/lizard_markings/none::name) //loop through possible species markings + if(hooman.dna.features["lizard_markings"] && hooman.dna.features["lizard_markings"] != /datum/sprite_accessory/lizard_markings/none::name && hooman.dna.features["snout"] != /datum/sprite_accessory/blank::name) //loop through possible species markings var/datum/bodypart_overlay/simple/body_marking/markings = new /datum/bodypart_overlay/simple/body_marking/lizard() // made to die... mostly because we cant use initial on lists but its convenient and organized var/accessory_name = hooman.dna.features[markings.dna_feature_key] //get the accessory name from dna var/datum/sprite_accessory/moth_markings/accessory = markings.get_accessory(accessory_name) //get the actual datum From 6f5bf36c52fb0df067ed868858575ca5dc3033ed Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 18:33:00 -0400 Subject: [PATCH 20/24] updating screenshots time i truly do not give a flying fuck if the screenshot tests produce baldos righ tnow, someone else can deal with trying to prettify CI --- .../screenshot_antag_icons_bloodbrother.png | Bin 2389 -> 17690 bytes ...nshot_humanoids__datum_species_android.png | Bin 1018 -> 11263 bytes ...enshot_humanoids__datum_species_lizard.png | Bin 1368 -> 15752 bytes ...anoids__datum_species_lizard_ashwalker.png | Bin 1147 -> 14731 bytes ...oids__datum_species_lizard_silverscale.png | Bin 1181 -> 12909 bytes ...reenshot_humanoids__datum_species_moth.png | Bin 1648 -> 15724 bytes ...nshot_humanoids__datum_species_slugcat.png | Bin 1188 -> 14122 bytes 7 files changed, 0 insertions(+), 0 deletions(-) diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_bloodbrother.png index 61b7c36d94a02a3a1b98e72e668c47a640ef15b2..4af34b006d757b21e31bc4b77259e0b3df750762 100644 GIT binary patch literal 17690 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 Mp(tJ_Y8?Fk0Up-DEdT%j literal 2389 zcmZXWdpHy98^q&Qab(GklyaNCLNStu8KfPJc z{7V zm6y?b6ZW_s9jx8qUgcF~Ix*hmL<7@-*Dv34mT^8U7a@nk5iL9p-oCYY-AS_Oxg`_r zp&k(`>SLoIsu1jE04V5CR0GEVoB#l^k`wl}o`^hNKFs~TgJL_Mp>8WH;gW$!zajZh zyCl%wfyTu9`I?{dE(yZsgpO;{luDU6nxf`FB!e`Hy)f*mcY6>4)>q~q+wsOTObl#k~bC4WF?ah6v&CQQ8OtQJ^FIvZp`y}EY zTg>R4R%CXut{?x|Ul9P(w%^chkgyM~eT|h>Z+E}lsMg@3nwo1BD3%r^$;Dvrz}oTR$bIU{si#sZVyf5sYW8WR<#)Jv$O=k!k!x@izldPeC>p+cenJ zQp1x5XE^3}eyMRcuGu`lGp+LNELL!v>FhIs9Vox!#TInswnsW1-wFwJY@N%i63M_d zeHV}DtS;TgZSrh$4(zLQ2Y4tfBovrz)C!4bgGG9Ui=|xM#nli-a;usOE|4!15E^-5Iab-HRE+ zkpu1VX+^!@!q1JKGEpzD_n|5KfsbPXs{dg&3;J!Dm5z~Ycx&ekyeN;g9oTk~If0QX@#Ww-VK)%Nd)PC4bqI^KXLH=c^ z&ie8nhh-JEQPGbd1?+2GFpqk#a?A3cfFs5x*}BM#n~7Y7J<@oW!&y2rT1WQOjBnBV zSW~V$245D8dX((G%b9fF9xMb**EvnFsijgxpMqAW4BVAbu`Zj3J z=p{|IRzLo}z8k2YD#)}6pXT?o>(N@S$%)IUK-a%%lv!m^322*P?SRSy?$G12_dUWad~Y zpx6=ycO6JtZU}iW7Axg2Ry2yij1nUy90>5oh`#2*N*hR!VC6=l#)MIwxLSgI%^TJ8 z;k23yN)YTW5PRd}UI{c=`2I;mVHx@TC24{x3<)(>%^4lS(je%Bg~ zXgC=jlIEtoeW=13asFI*!3uealVnpJiM2=y>uj4kZ09 z2SeFJVQ0d0@lyVT(xU;^r+C! zx!`oPq^4hlxT<@q*#uhLWU98ar+q6*$8w7U)q``Z_A1q|%F5Yk{td*XoQvH)-;pWr zIxaG|e5bs{3v6EkNzB9MSxl{r0zl;W^ar7HS~K;NvhN>Jdl1YD_o?bDK{*c7|`#HjpVh&#-&7@a1KJ@M_ZNhu!Dwp$b--r^0RM zJa$zPUJgWA3@w0?lf7+3x!{sKT*LNX6bWlP>F;`a-#O<1cZ~@EO&PUiuO}n4i5`B- z)r~LNo!Xz1ADKMN}Nd S<2V0FfD;a`_7%s@CjSeJwVmbw diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_android.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_android.png index 20addbcdf8ec1871ec7b1cd5fc2c4f72ec21e2f1..7b9f46157fb5c8727e2f10f62d2f594809f62aaa 100644 GIT binary patch literal 11263 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 fcXK4)P(NT#MGk)?1krIeQG#v58> delta 1045 zcmV+w1nT>XbNdL8BL)ChP)t-slSwvLe--3mg#Z8m0d!JMQvg8b*k%9#0A+eqSad{X zb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1KAf1zPS z000AFNkl2;ra_f`xk(58R7-3m1?}@c7ib0nV^-7ew!ZzsCo6 z(oa!;ZEgkXKyo{3ZTm#KmUFX<65l)4DDxn|NFn!M-a3R4E=ey3B#n>fpe*`$sl(0ik#M&fRf~+2X@plA}Fmen}0^KJlWbihF4;;Xy z-Xm~i5Q9OmHwwblFFP7eW0YItLoM+zOYR@xjhW9u#I;e#2S8zkqA%eE+Ej407=UjR z1Wt98q1SlD2L$zM5xiE*ZX>TTc-nsz)3`JE;<$szG}#Aj3qMUFe}^%S9$^ZD!pD#> z+0DZn&UX~7;=kcUz1^Q|0`8POg8g>z_V2j|b|i?j7QsF(tv%RPppWE7*aQty>nOc5 zv@U9ZwkB(s563PUM|STm0L}&GZswzM!?nkr>RO4OXB2sZ0r{xgYuaOAK5ToA1_SEu z3^z-KBqIVQw?RwSf2FW&0V^3(>=2|m7Z!R9?-kUtpZ=sEwN9Z^5Gz5VfL#JeNR{Ar z5m@|bn(0pjiKCXjlVkBO*eJ?DgPkD6=&Xf3!YztrsZ|3C^S}~3G1$MBehn+d5tUC* zr>EzUg6F5x3Hw=(gI={{)xGlG>c48=Al0}idz`)ejR7r?e_kvU$F=0${K}AvecUhf zi?0%x623>!&0q8V*9d%NxY3|&6!mKaEUlk4T)2RAvI0xmF(g`2MvqXv?OnsAwFh)U z>e%&6X>)5U@{OXk2d!U#IPcBwpyj_1udvi47LZSMe(Mv41h2PaReu8y895C;3C-C6 P0000-WS*)iqAW51&cf; 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 C<^Bx- delta 1064 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 F{{h7EV(0(> delta 1380 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 XmWZCZZ&-RwRDi6cl0>E0`=I{=Ao*c5 delta 1086 zcmV-E1i|~NZlnp2BL)ChP)t-slj}2Ae=$hpv;Y7A0d!JMQvg8b*k%9#0A+eqSad{X zb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1KAf1zPS z000AuNklx zVUsAti%{0G&NmBQ`hay4izz9kQi>CONs%lqGygT_;!DOe@4v<$WO3yQC9OH9l5$>C zVfDDK@L$(B(K7%U{&;3qKwm(B#f8&F$!W!+3UN)D0pt{yxGeaO6TL#ne+5CrInCkRd7wp2Ek{iJ39>M{jD(;Zn0mW&hzX?DH zZlY@fxMM&ig60WY(gI5L5kL?@F$ATgt}xLbc-wRk&>S^G>wh?MMIT1n#rQZUa!dvP>{OwvsE=Wz-Hf6{jXO%SsYLD@cFO#M-@Yr$7` znnPp}a;YfptUo$8f2#Jpri!gaFAJJHLx4Z}c1}kG@<-WTB11smT~N(ZCCCgw&fB7O zm{O>1L8}E@901Z%Dm8j6A0y~(KYbQK+9rh|g4h9x0yqR9gwz3#NucIWMKgT{NVIAl zCpl{Vl?o~?nw*3{8dcUxGs2^awA6+v01=i+Nid{gG-!3qe_=O$*fvSYe(&U>;J8d1JY(r*K+8;6H1*lM<-=1hyI;Vs^t4KHLR}!*bu%8AbpF From 102ca650d4a0893551e96134aee517a10113398a Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 18:56:08 -0400 Subject: [PATCH 21/24] Update screenshot_humanoids__datum_species_slugcat.png why is the nose changing colors i HATE flaky tests --- ...nshot_humanoids__datum_species_slugcat.png | Bin 14122 -> 12618 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_slugcat.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_slugcat.png index acd183cc00d9ceacb91b4f45a5c77cfdcfa47b85..1d9bf938b78e05c2cdaefe72c938889e3356fbfb 100644 GIT binary patch delta 8742 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 Qr~m)}07*qoM6N<$f{8x4g8%>k delta 10453 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 LNkvXXu0mjf^iWAJ From 7e5753211341c9d10139fe689b7d298e948c09d8 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Thu, 5 Sep 2024 20:35:47 -0400 Subject: [PATCH 22/24] Update transformation_sting_appearances.png --- .../transformation_sting_appearances.png | Bin 1306 -> 11975 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/code/modules/unit_tests/screenshots/transformation_sting_appearances.png b/code/modules/unit_tests/screenshots/transformation_sting_appearances.png index e20d19d45b680428820cfba247d91108798fa606..5d526a0dedc76daf701ea20072f09330d24da40e 100644 GIT binary patch literal 11975 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 DH14Li delta 1288 zcmaJ>Sx{4F82z&t0s|(XkyNw^AiGv*08`QA1`{O|8D%RdLPXF66v85-M7%c%BC8_m zph#sgqSXZG$S7{*stlk~0%a*+Q5HdkB0+=5=56Xr-+G?TnX}CI^fm1%HYu=$!LA*C zK?3wE>{bCF0KROn!W<+7fxgRyAQu2<0NO!j4A|fdX4@OFfp)L}fCP-y*J2nZ3kL=a zR#!fdC4y+ca|3WBAQAyE26#LGL@*yw%`zl#DFOb002=MtZxGV7pwJY4O!B@Y2`o*K zB*X)7q$Dsznsj(ZA1Ixge(n6@I_K6FZD38XYddRTXsy=I=_yFc%dcaz0$3d^UuMZr zVMAdMGf*FZ56_}F2LPDUAYUwj8xD$@hVInIkD1*IBQ|-~9PDF|GSEBky9X&!eN?+kedWSXGe9!6$w40P zrr|olGs^a?J48A2Cx)eMeU!Ze*^!9!Nv(ouIP32OjsYIjZrT?+x;oCM3v?q|&y;%= zB>P=?+x_I_OJ?7s)sb?b79bed&qG)G)n5ugLOaz>%V>aej^x%~)pS#3ljnrKn1B_? z9%@(FRcG~I7VSjUdFE#FNo|Ned&L6j!RdH48S}vHWFpJeNdl83qHfsZM0qjTD6NQS z5r}wGC++ULs5)=nSb&$6ZFPUjdvF?5mM6Iv-q6JkEmuh{^qOlp7R^_oj`+5_IZpKc z`n}7)S*bX&I_w}QwT7&s_>sXdZE)Nw)w>hV7qu>~cQQx)vryg#2lS7*=P}Vz)?=lFv4ApztJo6gh{B5M!VxpDNFC>`O zS4N&oR~{$?qm%cRe$E(&N$(Y}>L4a(lG&DM=Fbp!QRvb+^xH+a%(#S8vxO`EsC`TD z(knfsbD)}0tLQKaT`Z%OaL{q1i2*&X_2t;*b|dyY?n~|*IFRtk5H48+m>?aw#emAx z6zQi_EapE!AfKDYwH_zRD>!H`g}I~Kh%IBW|MgMi>x^MCgv-u=crZgWtxUxmx?Pk$ zV?!&1D<)o}=;nBrWLp_MR~YVh*N+qC^-9uAOuFdW@g0WadwyZK*R3BT+@DsSvTf5+ m^dAX}3lNw4e-s;;m2;OMup87r8)JAuKq&C%S9yzYihlq&+D5ei From b33cfc818eeb72dca9e52ee1b2fe8ee3b0f9a0d9 Mon Sep 17 00:00:00 2001 From: CliffracerX Date: Fri, 6 Sep 2024 01:15:20 -0400 Subject: [PATCH 23/24] addressing Owl's review --- .../enterprise_resource_planning.dm | 0 code/__DEFINES/{~doppler => ~doppler_defines}/species.dm | 0 tgstation.dme | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename code/__DEFINES/{~doppler => ~doppler_defines}/enterprise_resource_planning.dm (100%) rename code/__DEFINES/{~doppler => ~doppler_defines}/species.dm (100%) diff --git a/code/__DEFINES/~doppler/enterprise_resource_planning.dm b/code/__DEFINES/~doppler_defines/enterprise_resource_planning.dm similarity index 100% rename from code/__DEFINES/~doppler/enterprise_resource_planning.dm rename to code/__DEFINES/~doppler_defines/enterprise_resource_planning.dm diff --git a/code/__DEFINES/~doppler/species.dm b/code/__DEFINES/~doppler_defines/species.dm similarity index 100% rename from code/__DEFINES/~doppler/species.dm rename to code/__DEFINES/~doppler_defines/species.dm diff --git a/tgstation.dme b/tgstation.dme index d0464a3ae13f2..4c8daa3e807a1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -396,8 +396,8 @@ #include "code\__DEFINES\traits\declarations.dm" #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" -#include "code\__DEFINES\~doppler\enterprise_resource_planning.dm" -#include "code\__DEFINES\~doppler\species.dm" +#include "code\__DEFINES\~doppler_defines\enterprise_resource_planning.dm" +#include "code\__DEFINES\~doppler_defines\species.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_dreamluau.dm" #include "code\__HELPERS\_lists.dm" From 0e82e8377395a1e694525f3791b5faf430719a14 Mon Sep 17 00:00:00 2001 From: "Lila S." Date: Fri, 6 Sep 2024 18:01:05 +0200 Subject: [PATCH 24/24] initial --- .../__DEFINES/~doppler_defines/keybindings.dm | 2 + code/__DEFINES/~doppler_defines/living.dm | 8 ++ .../pixel_shift/code/pixel_shift_component.dm | 100 ++++++++++++++++++ .../pixel_shift/code/pixel_shift_keybind.dm | 17 +++ .../pixel_shift/code/pixel_shift_mob.dm | 6 ++ modular_doppler/pixel_shift/living.dm | 7 ++ .../pixel_shift/living_movement.dm | 4 + tgstation.dme | 7 ++ 8 files changed, 151 insertions(+) create mode 100644 code/__DEFINES/~doppler_defines/keybindings.dm create mode 100644 code/__DEFINES/~doppler_defines/living.dm create mode 100644 modular_doppler/pixel_shift/code/pixel_shift_component.dm create mode 100644 modular_doppler/pixel_shift/code/pixel_shift_keybind.dm create mode 100644 modular_doppler/pixel_shift/code/pixel_shift_mob.dm create mode 100644 modular_doppler/pixel_shift/living.dm create mode 100644 modular_doppler/pixel_shift/living_movement.dm diff --git a/code/__DEFINES/~doppler_defines/keybindings.dm b/code/__DEFINES/~doppler_defines/keybindings.dm new file mode 100644 index 0000000000000..23bcff0827dc0 --- /dev/null +++ b/code/__DEFINES/~doppler_defines/keybindings.dm @@ -0,0 +1,2 @@ +#define COMSIG_KB_MOB_PIXEL_SHIFT_DOWN "keybinding_mob_pixel_shift_down" +#define COMSIG_KB_MOB_PIXEL_SHIFT_UP "keybinding_mob_pixel_shift_up" diff --git a/code/__DEFINES/~doppler_defines/living.dm b/code/__DEFINES/~doppler_defines/living.dm new file mode 100644 index 0000000000000..c92f403607b5f --- /dev/null +++ b/code/__DEFINES/~doppler_defines/living.dm @@ -0,0 +1,8 @@ +///from base of living/set_pull_offset(): (mob/living/pull_target, grab_state) +#define COMSIG_LIVING_SET_PULL_OFFSET "living_set_pull_offset" +///from base of living/reset_pull_offsets(): (mob/living/pull_target, override) +#define COMSIG_LIVING_RESET_PULL_OFFSETS "living_reset_pull_offsets" +///from base of living/CanAllowThrough(): (atom/movable/mover, border_dir) +#define COMSIG_LIVING_CAN_ALLOW_THROUGH "living_can_allow_through" +///Allow to movable atoms to pass through this living mob +#define COMPONENT_LIVING_PASSABLE (1<<0) diff --git a/modular_doppler/pixel_shift/code/pixel_shift_component.dm b/modular_doppler/pixel_shift/code/pixel_shift_component.dm new file mode 100644 index 0000000000000..9603d3d5a20ea --- /dev/null +++ b/modular_doppler/pixel_shift/code/pixel_shift_component.dm @@ -0,0 +1,100 @@ +/datum/component/pixel_shift + dupe_mode = COMPONENT_DUPE_UNIQUE + /// Whether the mob is pixel shifted or not + var/is_shifted = FALSE + /// If we are in the shifting setting. + var/shifting = TRUE + /// Takes the four cardinal direction defines. Any atoms moving into this atom's tile will be allowed to from the added directions. + var/passthroughable = NONE + /// The maximum amount of pixels allowed to move in the turf. + var/maximum_pixel_shift = 16 + /// The amount of pixel shift required to make the parent passthroughable. + var/passable_shift_threshold = 8 + +/datum/component/pixel_shift/Initialize(...) + . = ..() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/pixel_shift/RegisterWithParent() + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN, PROC_REF(pixel_shift_down)) + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP, PROC_REF(pixel_shift_up)) + RegisterSignals(parent, list(COMSIG_LIVING_RESET_PULL_OFFSETS, COMSIG_LIVING_SET_PULL_OFFSET, COMSIG_MOVABLE_MOVED), PROC_REF(unpixel_shift)) + RegisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(pre_move_check)) + RegisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH, PROC_REF(check_passable)) + +/datum/component/pixel_shift/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN) + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP) + UnregisterSignal(parent, COMSIG_LIVING_RESET_PULL_OFFSETS) + UnregisterSignal(parent, COMSIG_LIVING_SET_PULL_OFFSET) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + UnregisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) + UnregisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH) + +/// Overrides Move to Pixel Shift. +/datum/component/pixel_shift/proc/pre_move_check(mob/source, new_loc, direct) + SIGNAL_HANDLER + if(shifting) + pixel_shift(source, direct) + return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE + +/// Checks if the parent is considered passthroughable from a direction. Projectiles will ignore the check and hit. +/datum/component/pixel_shift/proc/check_passable(mob/source, atom/movable/mover, border_dir) + SIGNAL_HANDLER + if(!isprojectile(mover) && !mover.throwing && passthroughable & border_dir) + return COMPONENT_LIVING_PASSABLE + +/// Activates Pixel Shift on Keybind down. Only Pixel Shift movement will be allowed. +/datum/component/pixel_shift/proc/pixel_shift_down() + SIGNAL_HANDLER + shifting = TRUE + return COMSIG_KB_ACTIVATED + +/// Disables Pixel Shift on Keybind up. Allows to Move. +/datum/component/pixel_shift/proc/pixel_shift_up() + SIGNAL_HANDLER + shifting = FALSE + +/// Sets parent pixel offsets to default and deletes the component. +/datum/component/pixel_shift/proc/unpixel_shift() + SIGNAL_HANDLER + passthroughable = NONE + if(is_shifted) + var/mob/living/owner = parent + owner.pixel_x = owner.body_position_pixel_x_offset + owner.base_pixel_x + owner.pixel_y = owner.body_position_pixel_y_offset + owner.base_pixel_y + qdel(src) + +/// In-turf pixel movement which can allow things to pass through if the threshold is met. +/datum/component/pixel_shift/proc/pixel_shift(mob/source, direct) + passthroughable = NONE + var/mob/living/owner = parent + switch(direct) + if(NORTH) + if(owner.pixel_y <= maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y++ + is_shifted = TRUE + if(EAST) + if(owner.pixel_x <= maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x++ + is_shifted = TRUE + if(SOUTH) + if(owner.pixel_y >= -maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y-- + is_shifted = TRUE + if(WEST) + if(owner.pixel_x >= -maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x-- + is_shifted = TRUE + + // Yes, I know this sets it to true for everything if more than one is matched. + // Movement doesn't check diagonals, and instead just checks EAST or WEST, depending on where you are for those. + if(owner.pixel_y > passable_shift_threshold) + passthroughable |= EAST | SOUTH | WEST + else if(owner.pixel_y < -passable_shift_threshold) + passthroughable |= NORTH | EAST | WEST + if(owner.pixel_x > passable_shift_threshold) + passthroughable |= NORTH | SOUTH | WEST + else if(owner.pixel_x < -passable_shift_threshold) + passthroughable |= NORTH | EAST | SOUTH diff --git a/modular_doppler/pixel_shift/code/pixel_shift_keybind.dm b/modular_doppler/pixel_shift/code/pixel_shift_keybind.dm new file mode 100644 index 0000000000000..2375b350a33c7 --- /dev/null +++ b/modular_doppler/pixel_shift/code/pixel_shift_keybind.dm @@ -0,0 +1,17 @@ +/datum/keybinding/mob/pixel_shift + hotkey_keys = list("B") + name = "pixel_shift" + full_name = "Pixel Shift" + description = "Shift your characters offset." + category = CATEGORY_MOVEMENT + keybind_signal = COMSIG_KB_MOB_PIXEL_SHIFT_DOWN + +/datum/keybinding/mob/pixel_shift/down(client/user) + . = ..() + if(.) + return + user.mob.add_pixel_shift_component() + +/datum/keybinding/mob/pixel_shift/up(client/user) + . = ..() + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_SHIFT_UP) diff --git a/modular_doppler/pixel_shift/code/pixel_shift_mob.dm b/modular_doppler/pixel_shift/code/pixel_shift_mob.dm new file mode 100644 index 0000000000000..dbdd1e8d83f23 --- /dev/null +++ b/modular_doppler/pixel_shift/code/pixel_shift_mob.dm @@ -0,0 +1,6 @@ +/// Adds pixel_shift component on call. Default proc does nothing. +/mob/proc/add_pixel_shift_component() + return + +/mob/living/add_pixel_shift_component() + AddComponent(/datum/component/pixel_shift) diff --git a/modular_doppler/pixel_shift/living.dm b/modular_doppler/pixel_shift/living.dm new file mode 100644 index 0000000000000..04aea1e36421b --- /dev/null +++ b/modular_doppler/pixel_shift/living.dm @@ -0,0 +1,7 @@ +/mob/living/set_pull_offsets(mob/living/pull_target, grab_state) + . = ..() + SEND_SIGNAL(pull_target, COMSIG_LIVING_SET_PULL_OFFSET) + +/mob/living/reset_pull_offsets(mob/living/pull_target, override) + . = ..() + SEND_SIGNAL(pull_target, COMSIG_LIVING_RESET_PULL_OFFSETS) diff --git a/modular_doppler/pixel_shift/living_movement.dm b/modular_doppler/pixel_shift/living_movement.dm new file mode 100644 index 0000000000000..a2efb7be0ec51 --- /dev/null +++ b/modular_doppler/pixel_shift/living_movement.dm @@ -0,0 +1,4 @@ +/mob/living/CanAllowThrough(atom/movable/mover, border_dir) + if(SEND_SIGNAL(src, COMSIG_LIVING_CAN_ALLOW_THROUGH, mover, border_dir) & COMPONENT_LIVING_PASSABLE) + return TRUE + return ..() diff --git a/tgstation.dme b/tgstation.dme index 68246d851194b..bbf2d5d82e256 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -395,6 +395,8 @@ #include "code\__DEFINES\traits\declarations.dm" #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" +#include "code\__DEFINES\~doppler_defines\keybindings.dm" +#include "code\__DEFINES\~doppler_defines\living.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_dreamluau.dm" #include "code\__HELPERS\_lists.dm" @@ -6369,6 +6371,11 @@ #include "modular_doppler\modular_cosmetics\code\neck\collar.dm" #include "modular_doppler\modular_cosmetics\code\suits\jacket.dm" #include "modular_doppler\modular_cosmetics\GAGS\greyscale_configs_neck.dm" +#include "modular_doppler\pixel_shift\living.dm" +#include "modular_doppler\pixel_shift\living_movement.dm" +#include "modular_doppler\pixel_shift\code\pixel_shift_component.dm" +#include "modular_doppler\pixel_shift\code\pixel_shift_keybind.dm" +#include "modular_doppler\pixel_shift\code\pixel_shift_mob.dm" #include "modular_doppler\sprite_accessories\code\hair.dm" #include "modular_doppler\tableflip\tableflip.dm" #include "modular_doppler\wargaming\code\game_kit.dm"