diff --git a/code/__DEFINES/~skyrat_defines/DNA.dm b/code/__DEFINES/~skyrat_defines/DNA.dm index bec7a87da318c..628e4218ddfd4 100644 --- a/code/__DEFINES/~skyrat_defines/DNA.dm +++ b/code/__DEFINES/~skyrat_defines/DNA.dm @@ -72,11 +72,11 @@ #define PENIS_MAX_GIRTH 20 #define PENIS_DEFAULT_GIRTH 5 // a lil big but not by much #define PENIS_MIN_LENGTH 1 -#define PENIS_MAX_LENGTH 36 +#define PENIS_MAX_LENGTH 128 #define PENIS_DEFAULT_LENGTH 6 //still a lil long but not insane -#define TESTICLES_MIN_SIZE 0 -#define TESTICLES_MAX_SIZE 6 +#define TESTICLES_MIN_SIZE 1 +#define TESTICLES_MAX_SIZE 5 #define SHEATH_NONE "None" #define SHEATH_NORMAL "Sheath" diff --git a/code/__DEFINES/~skyrat_defines/lewd_defines.dm b/code/__DEFINES/~skyrat_defines/lewd_defines.dm index 7674131b09003..fc36f5315ac62 100644 --- a/code/__DEFINES/~skyrat_defines/lewd_defines.dm +++ b/code/__DEFINES/~skyrat_defines/lewd_defines.dm @@ -29,4 +29,7 @@ #define BREAST_SIZE_N "N" #define BREAST_SIZE_O "O" #define BREAST_SIZE_P "P" +#define BREAST_SIZE_R "R" +#define BREAST_SIZE_S "S" +#define BREAST_SIZE_T "T" #define BREAST_SIZE_BEYOND_MEASUREMENT "beyond measurement" diff --git a/code/__DEFINES/~~~splurt_defines/DNA.dm b/code/__DEFINES/~~~splurt_defines/DNA.dm index 5f6e5f3bfe859..3ef6db3d55a33 100644 --- a/code/__DEFINES/~~~splurt_defines/DNA.dm +++ b/code/__DEFINES/~~~splurt_defines/DNA.dm @@ -1,4 +1,11 @@ -///arachnid organ slots +//sex +#define ORGAN_SLOT_BUTT "butt" +#define ORGAN_SLOT_BELLY "belly" +//arachnid organ slots #define ORGAN_SLOT_EXTERNAL_MANDIBLES "mandibles" #define ORGAN_SLOT_EXTERNAL_SPINNERET "spinneret" #define ORGAN_SLOT_EXTERNAL_SPIDER_LEGS "spider_legs" + + +#define BUTT_MIN_SIZE 1 +#define BUTT_MAX_SIZE 8 diff --git a/modular_skyrat/modules/customization/__DEFINES/lists.dm b/modular_skyrat/modules/customization/__DEFINES/lists.dm index 8e15c8a3f9bc7..13ad4b200946e 100644 --- a/modular_skyrat/modules/customization/__DEFINES/lists.dm +++ b/modular_skyrat/modules/customization/__DEFINES/lists.dm @@ -6,7 +6,9 @@ GLOBAL_LIST_INIT(possible_genitals, list( ORGAN_SLOT_TESTICLES, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS, - ORGAN_SLOT_PENIS + ORGAN_SLOT_PENIS, + ORGAN_SLOT_BUTT, + ORGAN_SLOT_BELLY )) GLOBAL_LIST_EMPTY(body_markings) diff --git a/modular_skyrat/modules/customization/_globalvars/lists.dm b/modular_skyrat/modules/customization/_globalvars/lists.dm index e4a9043ef1598..f02e993f191f8 100644 --- a/modular_skyrat/modules/customization/_globalvars/lists.dm +++ b/modular_skyrat/modules/customization/_globalvars/lists.dm @@ -19,6 +19,9 @@ GLOBAL_LIST_INIT(breast_size_translation, list( "14" = BREAST_SIZE_N, "15" = BREAST_SIZE_O, "16" = BREAST_SIZE_P, + "17" = BREAST_SIZE_R, + "18" = BREAST_SIZE_S, + "19" = BREAST_SIZE_T, )) GLOBAL_LIST_INIT(breast_size_to_number, list( @@ -39,16 +42,17 @@ GLOBAL_LIST_INIT(breast_size_to_number, list( BREAST_SIZE_N = 14, BREAST_SIZE_O = 15, BREAST_SIZE_P = 16, + BREAST_SIZE_R = 17, + BREAST_SIZE_S = 18, + BREAST_SIZE_T = 19, )) GLOBAL_LIST_INIT(balls_size_translation, list( - "0" = "Small", - "1" = "Average", - "2" = "Big", - "3" = "Very Big", + "1" = "Small", + "2" = "Average", + "3" = "Big", "4" = "Enormous", - "5" = "Immense", - "6" = "Gargantuan" + "5" = "Gargantuan" )) GLOBAL_LIST_INIT(marking_zone_to_bitflag, list( @@ -77,9 +81,7 @@ GLOBAL_LIST_INIT(preference_balls_sizes, list( "Small", "Average", "Big", - "Very Big", "Enormous", - "Immense", "Gargantuan" )) diff --git a/modular_zzplurt/code/modules/client/preferences/genitals.dm b/modular_zzplurt/code/modules/client/preferences/genitals.dm new file mode 100644 index 0000000000000..13e51b42e1b75 --- /dev/null +++ b/modular_zzplurt/code/modules/client/preferences/genitals.dm @@ -0,0 +1,161 @@ +//butt +/datum/preference/choiced/genital/butt + savefile_key = "feature_butt" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + default_accessory_type = /datum/sprite_accessory/genital/butt/none + +/datum/preference/toggle/genital_skin_tone/butt + savefile_key = "butt_skin_tone" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + genital_pref_type = /datum/preference/choiced/genital/butt + +/datum/preference/toggle/genital_skin_tone/butt/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["butt_uses_skintones"] = value + +/datum/preference/toggle/genital_skin_color/butt + savefile_key = "butt_skin_color" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + genital_pref_type = /datum/preference/choiced/genital/butt + +/datum/preference/toggle/genital_skin_color/butt/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + if(!..()) // Don't apply it if it failed the check in the parent. + value = FALSE + + target.dna.features["butt_uses_skincolor"] = value + +/datum/preference/numeric/butt_size + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "butt_size" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + minimum = BUTT_MIN_SIZE + maximum = BUTT_MAX_SIZE + +/datum/preference/numeric/butt_size/is_accessible(datum/preferences/preferences) + var/passed_initial_check = ..(preferences) + var/allowed = preferences.read_preference(/datum/preference/toggle/allow_mismatched_parts) + var/erp_allowed = preferences.read_preference(/datum/preference/toggle/master_erp_preferences) && preferences.read_preference(/datum/preference/toggle/allow_genitals) + var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/butt)) + return erp_allowed && part_enabled && (passed_initial_check || allowed) + +/datum/preference/numeric/butt_size/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["butt_size"] = value + +/datum/preference/numeric/butt_size/create_default_value() + return BUTT_MIN_SIZE + +/datum/preference/tri_color/genital/butt + savefile_key = "butt_color" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + type_to_check = /datum/preference/choiced/genital/butt + skin_color_type = /datum/preference/toggle/genital_skin_color/butt + +/datum/preference/tri_bool/genital/butt + savefile_key = "butt_emissive" + relevant_mutant_bodypart = ORGAN_SLOT_BUTT + type_to_check = /datum/preference/choiced/genital/butt + skin_color_type = /datum/preference/toggle/genital_skin_color/butt + + + +//butthole +/datum/preference/choiced/genital/anus + savefile_key = "feature_anus" + relevant_mutant_bodypart = ORGAN_SLOT_ANUS + default_accessory_type = /datum/sprite_accessory/genital/anus/none + +/datum/preference/choiced/genital/anus/is_accessible(datum/preferences/preferences) + return ..() && preferences.read_preference(/datum/preference/choiced/genital/butt) != "None" + +/datum/preference/toggle/genital_skin_tone/anus + savefile_key = "anus_skin_tone" + relevant_mutant_bodypart = ORGAN_SLOT_ANUS + genital_pref_type = /datum/preference/choiced/genital/anus + +/datum/preference/toggle/genital_skin_tone/anus/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["anus_uses_skintones"] = value + +/datum/preference/toggle/genital_skin_color/anus + savefile_key = "anus_skin_color" + relevant_mutant_bodypart = ORGAN_SLOT_ANUS + genital_pref_type = /datum/preference/choiced/genital/anus + +/datum/preference/toggle/genital_skin_color/anus/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + if(!..()) // Don't apply it if it failed the check in the parent. + value = FALSE + + target.dna.features["anus_uses_skincolor"] = value + + +/datum/preference/tri_color/genital/anus + savefile_key = "anus_color" + relevant_mutant_bodypart = ORGAN_SLOT_ANUS + type_to_check = /datum/preference/choiced/genital/anus + skin_color_type = /datum/preference/toggle/genital_skin_color/anus + +/datum/preference/tri_bool/genital/anus + savefile_key = "anus_emissive" + relevant_mutant_bodypart = ORGAN_SLOT_ANUS + type_to_check = /datum/preference/choiced/genital/anus + skin_color_type = /datum/preference/toggle/genital_skin_color/anus + + +//belly +/datum/preference/choiced/genital/belly + savefile_key = "feature_belly" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + default_accessory_type = /datum/sprite_accessory/genital/belly/none + +/datum/preference/numeric/belly_size + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "belly_size" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + minimum = 1 + maximum = 10 + +/datum/preference/numeric/belly_size/create_default_value() + return 1 + +/datum/preference/numeric/belly_size/is_accessible(datum/preferences/preferences) + var/passed_initial_check = ..(preferences) + var/allowed = preferences.read_preference(/datum/preference/toggle/allow_mismatched_parts) + var/erp_allowed = preferences.read_preference(/datum/preference/toggle/master_erp_preferences) && preferences.read_preference(/datum/preference/toggle/allow_genitals) + var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/belly)) + return erp_allowed && part_enabled && (passed_initial_check || allowed) + +/datum/preference/numeric/belly_size/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["belly_size"] = value + + +/datum/preference/toggle/genital_skin_tone/belly + savefile_key = "belly_skin_tone" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + genital_pref_type = /datum/preference/choiced/genital/belly + +/datum/preference/toggle/genital_skin_tone/belly/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["belly_uses_skintones"] = value + +/datum/preference/toggle/genital_skin_color/belly + savefile_key = "belly_skin_color" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + genital_pref_type = /datum/preference/choiced/genital/belly + +/datum/preference/toggle/genital_skin_color/belly/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + if(!..()) // Don't apply it if it failed the check in the parent. + value = FALSE + + target.dna.features["belly_uses_skincolor"] = value + + +/datum/preference/tri_color/genital/belly + savefile_key = "belly_color" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + type_to_check = /datum/preference/choiced/genital/belly + skin_color_type = /datum/preference/toggle/genital_skin_color/belly + +/datum/preference/tri_bool/genital/belly + savefile_key = "belly_emissive" + relevant_mutant_bodypart = ORGAN_SLOT_BELLY + type_to_check = /datum/preference/choiced/genital/belly + skin_color_type = /datum/preference/toggle/genital_skin_color/belly diff --git a/modular_zzplurt/code/modules/sprite_accessories/genitals.dm b/modular_zzplurt/code/modules/sprite_accessories/genitals.dm new file mode 100644 index 0000000000000..97e960c6f45b5 --- /dev/null +++ b/modular_zzplurt/code/modules/sprite_accessories/genitals.dm @@ -0,0 +1,73 @@ +/datum/sprite_accessory/genital/penis + icon = 'modular_zzplurt/icons/mob/human/genitals/penis.dmi' + +/datum/sprite_accessory/genital/testicles + icon = 'modular_zzplurt/icons/mob/human/genitals/testicles.dmi' + +/datum/sprite_accessory/genital/vagina + icon = 'modular_zzplurt/icons/mob/human/genitals/vagina.dmi' + +/datum/sprite_accessory/genital/breasts + icon = 'modular_zzplurt/icons/mob/human/genitals/breasts.dmi' + +/datum/sprite_accessory/genital/butt + icon = 'modular_zzplurt/icons/mob/human/genitals/butt.dmi' + organ_type = /obj/item/organ/external/genital/butt + associated_organ_slot = ORGAN_SLOT_BUTT + key = ORGAN_SLOT_BUTT + color_src = USE_MATRIXED_COLORS + always_color_customizable = TRUE + relevent_layers = list(BODY_ADJ_LAYER) + genetic = TRUE + + +/datum/sprite_accessory/genital/butt/none + icon_state = "none" + name = SPRITE_ACCESSORY_NONE + factual = FALSE + color_src = null + +/datum/sprite_accessory/genital/butt/pair + icon_state = "pair" + name = "Pair" + + + +/datum/sprite_accessory/genital/anus + icon = 'modular_zzplurt/icons/mob/human/genitals/anus.dmi' + organ_type = /obj/item/organ/external/genital/anus + associated_organ_slot = ORGAN_SLOT_BUTT // :3 + key = ORGAN_SLOT_ANUS + color_src = USE_MATRIXED_COLORS + always_color_customizable = TRUE + relevent_layers = list(BODY_FRONT_LAYER) + genetic = TRUE + +/datum/sprite_accessory/genital/anus/normal + icon_state = "donut" + color_src = USE_MATRIXED_COLORS + name = "Donut" + +/datum/sprite_accessory/genital/anus/squished + icon_state = "squished" + name = "Squished" + color_src = USE_MATRIXED_COLORS + + +/datum/sprite_accessory/genital/belly + icon = 'modular_zzplurt/icons/mob/human/genitals/belly.dmi' + organ_type = /obj/item/organ/external/genital/belly + associated_organ_slot = ORGAN_SLOT_BELLY + key = ORGAN_SLOT_BELLY + genetic = TRUE + +/datum/sprite_accessory/genital/belly/none + icon_state = "none" + name = SPRITE_ACCESSORY_NONE + factual = FALSE + color_src = null + +/datum/sprite_accessory/genital/belly/normal + icon_state = "pair" //???? + name = "Belly" + color_src = null diff --git a/modular_zzplurt/code/modules/surgery/organs/genitals/anus.dm b/modular_zzplurt/code/modules/surgery/organs/genitals/anus.dm new file mode 100644 index 0000000000000..6322a030d42f2 --- /dev/null +++ b/modular_zzplurt/code/modules/surgery/organs/genitals/anus.dm @@ -0,0 +1,18 @@ +/obj/item/organ/external/genital/anus/get_description_string(datum/sprite_accessory/genital/gas) + var/u_His = owner?.p_their() || "their" + + desc = "You see [u_His] squishy [lowertext(gas.icon_state)] pucker parting [u_His] asscheeks" + +/obj/item/organ/external/genital/anus/get_sprite_size_string() + . = "[genital_type]_[floor(genital_size)]" + if(uses_skintones) + . += "_s" + +/obj/item/organ/external/genital/anus/build_from_dna(datum/dna/DNA, associated_key) + set_size(DNA.features["butt_size"]) // yes + uses_skin_color = DNA.features["anus_uses_skincolor"] + + return ..() + +/datum/bodypart_overlay/mutant/genital/anus + layers = EXTERNAL_FRONT diff --git a/modular_zzplurt/code/modules/surgery/organs/genitals/belly.dm b/modular_zzplurt/code/modules/surgery/organs/genitals/belly.dm new file mode 100644 index 0000000000000..5535a3da2ec43 --- /dev/null +++ b/modular_zzplurt/code/modules/surgery/organs/genitals/belly.dm @@ -0,0 +1,63 @@ +/obj/item/organ/external/genital/belly + name = "belly" + desc = "You see a belly on their midsection." + //icon = 'modular_zzplurt/icons/obj/metical/organs/belly.dmi' //apparently theres no organ sprite? + icon_state = "belly" + drop_when_organ_spilling = FALSE + slot = ORGAN_SLOT_BELLY + zone = BODY_ZONE_CHEST + bodypart_overlay = /datum/bodypart_overlay/mutant/genital/belly + genital_location = CHEST + + mutantpart_key = ORGAN_SLOT_BELLY + mutantpart_info = list(MUTANT_INDEX_NAME = "Belly", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB")) + +/obj/item/organ/external/genital/belly/get_sprite_size_string() + . = "[genital_type]_[floor(genital_size)]" + if(uses_skintones) + . += "_s" + +/obj/item/organ/external/genital/belly/set_size(size) + var/old_size = genital_size + . = ..() + if(size > old_size) + to_chat(owner, span_warning("Your guts [pick("swell up to", "gurgle into", "expand into", "plump up into", "grow eagerly into", "fatten up into", "distend into")] a larger midsection.")) + else + to_chat(owner, span_warning("Your guts [pick("shrink down to", "decrease into", "wobble down into", "diminish into", "deflate into", "contracts into")] a smaller midsection.")) + + +/obj/item/organ/external/genital/belly/build_from_dna(datum/dna/DNA, associated_key) + uses_skin_color = DNA.features["belly_uses_skincolor"] + set_size(DNA.features["belly_size"]) + + return ..() + +/obj/item/organ/external/genital/belly/get_description_string(datum/sprite_accessory/genital/gas) + var/size_name + switch(round(genital_size)) + if(1) + size_name = "average" + if(2) + size_name = "round" + if(3) + size_name = "squishable" + if(4) + size_name = "fat" + if(5) + size_name = "sagging" + if(6) + size_name = "gigantic" + if(7 to INFINITY) + size_name = pick("massive", "unfathomably bulging", "enormous", "very generous", "humongous", "big bubbly") + else + size_name = "nonexistent" + + desc = "You see a [size_name] [round(genital_size) >= 4 ? "belly, it bounces around and gurgles as [owner] walks" : "belly in [owner?.p_their() ? owner?.p_their() : "their"] midsection"]." + + +/datum/bodypart_overlay/mutant/genital/belly + feature_key = ORGAN_SLOT_BELLY + layers = EXTERNAL_FRONT | EXTERNAL_BEHIND + +/datum/bodypart_overlay/mutant/genital/belly/get_global_feature_list() + return SSaccessories.sprite_accessories[ORGAN_SLOT_BELLY] diff --git a/modular_zzplurt/code/modules/surgery/organs/genitals/butt.dm b/modular_zzplurt/code/modules/surgery/organs/genitals/butt.dm new file mode 100644 index 0000000000000..3108b52897c96 --- /dev/null +++ b/modular_zzplurt/code/modules/surgery/organs/genitals/butt.dm @@ -0,0 +1,62 @@ +/obj/item/organ/external/genital/butt + name = "butt" + desc = "You see a pair of asscheeks." + icon = 'modular_zzplurt/icons/obj/medical/organs/butt.dmi' + icon_state = "butt" + slot = ORGAN_SLOT_BUTT + zone = BODY_ZONE_PRECISE_GROIN + bodypart_overlay = /datum/bodypart_overlay/mutant/genital/butt + + mutantpart_key = ORGAN_SLOT_BUTT + mutantpart_info = list(MUTANT_INDEX_NAME = "Pair", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB")) + +/obj/item/organ/external/genital/butt/get_description_string(datum/sprite_accessory/genital/gas) + var/size_name + switch(round(genital_size)) + if(1) + size_name = "average" + if(2) + size_name = "sizable" + if(3) + size_name = "squeezable" + if(4) + size_name = "hefty" + if(5) + size_name = pick("massive", "very generous") + if(6) + size_name = pick("gigantic", "big bubbly", "enormous") + if(7) + size_name = pick("unfathomably large", "extreme") + if(8) + size_name = pick("absolute dumptruck", "humongous", "dummy thick") + else + size_name = "nonexistent" + + return "You see a [lowertext(gas.icon_state)] of [size_name] asscheeks." + +/obj/item/organ/external/genital/butt/set_size(size) + . = ..() + spawn(0) //set_size is called by build_from_dna.. which executes before Insert assigns owner. This gets around that + var/obj/item/organ/external/genital/anus/anus = owner.get_organ_slot(ORGAN_SLOT_ANUS) + if(!anus) + return + + anus.set_size(size) + +/obj/item/organ/external/genital/butt/get_sprite_size_string() + . = "[genital_type]_[floor(genital_size)]" + if(uses_skintones) + . += "_s" + +/obj/item/organ/external/genital/butt/build_from_dna(datum/dna/DNA, associated_key) + uses_skin_color = DNA.features["butt_uses_skincolor"] + set_size(DNA.features["butt_size"]) + + return ..() + +/datum/bodypart_overlay/mutant/genital/butt + feature_key = ORGAN_SLOT_BUTT + layers = EXTERNAL_ADJACENT + +/datum/bodypart_overlay/mutant/genital/butt/get_global_feature_list() + return SSaccessories.sprite_accessories[ORGAN_SLOT_BUTT] diff --git a/modular_zzplurt/code/modules/surgery/organs/genitals/penis.dm b/modular_zzplurt/code/modules/surgery/organs/genitals/penis.dm new file mode 100644 index 0000000000000..156a0f720ba7a --- /dev/null +++ b/modular_zzplurt/code/modules/surgery/organs/genitals/penis.dm @@ -0,0 +1,22 @@ +/obj/item/organ/external/genital/penis/get_sprite_size_string() + if(aroused != AROUSAL_FULL && sheath != SHEATH_NONE) + return ..() + + var/size_affix + var/measured_size = max(floor(genital_size), 1) + var/is_erect = !!aroused + switch(measured_size) + if(1 to 6) + size_affix = "1" + if(7 to 11) + size_affix = "2" + if(12 to 36) + size_affix = "3" + if(37 to 48) + size_affix = "4" + else + size_affix = "5" + + . = "[genital_type]_[size_affix]_[is_erect]" + if(uses_skintones) + . += "_s" diff --git a/modular_zzplurt/icons/mob/human/genitals/anus.dmi b/modular_zzplurt/icons/mob/human/genitals/anus.dmi new file mode 100644 index 0000000000000..3f1f2182c0fa9 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/anus.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/belly.dmi b/modular_zzplurt/icons/mob/human/genitals/belly.dmi new file mode 100644 index 0000000000000..806b2711a7128 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/belly.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/breasts.dmi b/modular_zzplurt/icons/mob/human/genitals/breasts.dmi new file mode 100644 index 0000000000000..8c33af6fecca6 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/breasts.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/butt.dmi b/modular_zzplurt/icons/mob/human/genitals/butt.dmi new file mode 100644 index 0000000000000..77caa457831a9 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/butt.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/penis.dmi b/modular_zzplurt/icons/mob/human/genitals/penis.dmi new file mode 100644 index 0000000000000..0a1c31e737c12 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/penis.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/testicles.dmi b/modular_zzplurt/icons/mob/human/genitals/testicles.dmi new file mode 100644 index 0000000000000..c7e3d98022969 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/testicles.dmi differ diff --git a/modular_zzplurt/icons/mob/human/genitals/vagina.dmi b/modular_zzplurt/icons/mob/human/genitals/vagina.dmi new file mode 100644 index 0000000000000..5c6ebaab3bef5 Binary files /dev/null and b/modular_zzplurt/icons/mob/human/genitals/vagina.dmi differ diff --git a/modular_zzplurt/icons/obj/medical/organs/butt.dmi b/modular_zzplurt/icons/obj/medical/organs/butt.dmi new file mode 100644 index 0000000000000..304a8424bb8aa Binary files /dev/null and b/modular_zzplurt/icons/obj/medical/organs/butt.dmi differ diff --git a/tgstation.dme b/tgstation.dme index a04d89b6cdca0..028199c6457ce 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9318,6 +9318,7 @@ #include "modular_zzplurt\code\modules\client\click.dm" #include "modular_zzplurt\code\modules\client\client_procs.dm" #include "modular_zzplurt\code\modules\client\preferences\clothing.dm" +#include "modular_zzplurt\code\modules\client\preferences\genitals.dm" #include "modular_zzplurt\code\modules\client\preferences\mutant_parts.dm" #include "modular_zzplurt\code\modules\client\preferences\player_panel.dm" #include "modular_zzplurt\code\modules\client\verbs\looc.dm" @@ -9360,9 +9361,14 @@ #include "modular_zzplurt\code\modules\species\teshari.dm" #include "modular_zzplurt\code\modules\species\xeno.dm" #include "modular_zzplurt\code\modules\sprite_accessories\arachnid.dm" +#include "modular_zzplurt\code\modules\sprite_accessories\genitals.dm" #include "modular_zzplurt\code\modules\surgery\bodyparts\parts.dm" #include "modular_zzplurt\code\modules\surgery\bodyparts\species_parts\arachnid_parts.dm" #include "modular_zzplurt\code\modules\surgery\organs\external\arachnid.dm" +#include "modular_zzplurt\code\modules\surgery\organs\genitals\anus.dm" +#include "modular_zzplurt\code\modules\surgery\organs\genitals\belly.dm" +#include "modular_zzplurt\code\modules\surgery\organs\genitals\butt.dm" +#include "modular_zzplurt\code\modules\surgery\organs\genitals\penis.dm" #include "modular_zzplurt\code\modules\surgery\organs\internal\eyes\_eyes.dm" #include "modular_zzplurt\code\modules\surgery\organs\internal\tongue\_tongue.dm" #include "modular_zzplurt\code\modules\wiremod\core\integrated_circuit.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx index 28ae2fe2179c5..d7999bf866d25 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx @@ -236,3 +236,97 @@ export const erp_status_pref_mechanics: FeatureChoiced = { name: 'ERP Mechanical Status', component: FeatureDropdownInput, }; + + +export const feature_butt: Feature = { + name: 'Butt Choice', + component: ( + props: FeatureValueProps, + ) => { + return ; + }, +}; + +export const butt_skin_tone: FeatureToggle = { + name: 'Butt uses Skin Tone', + component: CheckboxInput, +}; + +export const butt_skin_color: FeatureToggle = { + name: 'Butt uses Skin Color', + component: CheckboxInput, +}; + +export const butt_color: Feature = { + name: 'Butt Color', + component: FeatureTriColorInput, +}; + +export const butt_emissive: Feature = { + name: 'Butt Emissives', + description: 'Emissive parts glow in the dark.', + component: FeatureTriBoolInput, +}; + +export const butt_size: FeatureNumeric = { + name: 'Butt Size', + component: FeatureNumberInput, +}; + + +export const anus_skin_tone: FeatureToggle = { + name: 'Anus uses Skin Tone', + component: CheckboxInput, +}; + +export const anus_skin_color: FeatureToggle = { + name: 'Anus uses Skin Color', + component: CheckboxInput, +}; + +export const anus_color: Feature = { + name: 'Anus Color', + component: FeatureTriColorInput, +}; + +export const anus_emissive: Feature = { + name: 'Anus Emissives', + description: 'Emissive parts glow in the dark.', + component: FeatureTriBoolInput, +}; + + +export const feature_belly: Feature = { + name: 'Belly Choice', + component: ( + props: FeatureValueProps, + ) => { + return ; + }, +}; + +export const belly_size: FeatureNumeric = { + name: 'Belly Size', + component: FeatureNumberInput, +}; + +export const belly_skin_tone: FeatureToggle = { + name: 'Belly uses Skin Tone', + component: CheckboxInput, +}; + +export const belly_skin_color: FeatureToggle = { + name: 'Belly uses Skin Color', + component: CheckboxInput, +}; + +export const belly_color: Feature = { + name: 'Belly Color', + component: FeatureTriColorInput, +}; + +export const belly_emissive: Feature = { + name: 'Belly Emissives', + description: 'Emissive parts glow in the dark.', + component: FeatureTriBoolInput, +};