diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 854fa01e..eb44679a 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -186,6 +186,8 @@
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_sheath" = FALSE,
"sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
+ "has_belly" = FALSE,
+ "belly_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_balls" = FALSE,
"balls_internal" = FALSE,
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 1653fc96..a9a73b32 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -134,6 +134,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"cock_color" = "fff",
"has_sheath" = FALSE,
"sheath_color" = "fff",
+ "has_belly" = FALSE,
+ "belly_color" = "fff",
"has_balls" = FALSE,
"balls_internal" = FALSE,
"balls_color" = "fff",
@@ -891,6 +893,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Nothing?"
//This else is a safeguard for errors, and if it happened, they wouldn't be able to change this pref,
//DO NOT REMOVE IT UNLESS YOU HAVE A GOOD IDEA
+ dat += APPEARANCE_CATEGORY_COLUMN
+ dat += "
Belly
"
+ dat += "[features["has_belly"] == TRUE ? "Yes" : "No"]"
+ if(features["has_belly"])
+ if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
+ dat += "Color:
"
+ dat += " (Skin tone overriding)
"
+ else
+ dat += "Color:
"
+ dat += " Change
"
+
dat += ""
dat += ""
@@ -2170,6 +2183,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"Invalid color. Your color is not bright enough.")
+ if("belly_color")
+ var/new_bellycolor = input(user, "Belly Color:", "Character Preference") as color|null
+ if(new_bellycolor)
+ var/temp_hsv = RGBtoHSV(new_bellycolor)
+ if(new_bellycolor == "#000000")
+ features["belly_color"] = pref_species.default_color
+ else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
+ features["belly_color"] = sanitize_hexcolor(new_bellycolor)
+ else
+ to_chat(user,"Invalid color. Your color is not bright enough.")
+
if("balls_shape")
var/new_shape
new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list
@@ -2375,6 +2399,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_cock"] = !features["has_cock"]
if(features["has_cock"] == FALSE)
features["has_balls"] = FALSE
+ if("has_belly")
+ features["has_belly"] = !features["has_belly"]
if("has_balls")
features["has_balls"] = !features["has_balls"]
if("has_ovi")
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 1b33e6cb..bea01129 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -411,6 +411,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//womb features
S["feature_has_womb"] >> features["has_womb"]
S["feature_can_get_preg"] >> features["can_get_preg"] //hyperstation 13
+ //balls features
+ S["feature_has_belly"] >> features["has_belly"]
+ S["feature_belly_color"] >> features["belly_color"]
//flavor text
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:
if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists.
diff --git a/hyperstation/code/modules/arousal/arousalhud.dm b/hyperstation/code/modules/arousal/arousalhud.dm
index 15672682..da4acc80 100644
--- a/hyperstation/code/modules/arousal/arousalhud.dm
+++ b/hyperstation/code/modules/arousal/arousalhud.dm
@@ -26,6 +26,10 @@
if (B) //they have a boobiedoo
dat += "[B.mode == "hidden" ? "Breasts (Hidden)" : (B.mode == "clothes" ? "Breasts (Hidden by Clothes)" : (B.mode == "visable" ? "Breasts (Visable)" : "Breasts (Visable)"))]
"
+ var/obj/item/organ/genital/belly/E = user.getorganslot("belly")
+ if (E)
+ dat += "[E.mode == "hidden" ? "Belly (Hidden)" : (B.mode == "clothes" ? "Belly (Hidden by Clothes)" : (B.mode == "visable" ? "Belly (Visable)" : "Belly (Visable)"))]
"
+
dat += {"
Contexual Options
"}
//Options
dat += "Masturbate"
@@ -114,6 +118,11 @@
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
B.toggle_visibility(picked_visibility)
+ if(href_list["hidebelly"])
+ var/obj/item/organ/genital/belly/E = usr.getorganslot("belly")
+ var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
+ E.toggle_visibility(picked_visibility)
+
if(href_list["hidetesticles"])
var/obj/item/organ/genital/testicles/T = usr.getorganslot("testicles")
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
diff --git a/hyperstation/icons/obj/genitals/belly.dmi b/hyperstation/icons/obj/genitals/belly.dmi
new file mode 100644
index 00000000..8402984f
Binary files /dev/null and b/hyperstation/icons/obj/genitals/belly.dmi differ
diff --git a/modular_citadel/code/modules/arousal/organs/belly.dm b/modular_citadel/code/modules/arousal/organs/belly.dm
new file mode 100644
index 00000000..87048121
--- /dev/null
+++ b/modular_citadel/code/modules/arousal/organs/belly.dm
@@ -0,0 +1,47 @@
+/obj/item/organ/genital/belly //I know, I know a belly aint a genital. but it is in the sake of code.
+ name = "belly"
+ desc = "a belly."
+ icon_state = "belly"
+ icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
+ zone = "chest"
+ slot = "belly"
+ w_class = 3
+ size = 1
+ var/breast_values = list ("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "massive" = 17, "giga" = 25, "impossible" = 30, "flat" = 0) // Note: Do not forget to define new sizes.
+ var/statuscheck = FALSE
+ shape = "Pair"
+ can_masturbate_with = TRUE
+ masturbation_verb = "massage"
+ can_climax = TRUE
+ fluid_transfer_factor = 0.5
+ var/sent_full_message = TRUE //defaults to 1 since they're full to start
+
+/obj/item/organ/genital/belly/on_life()
+ if(QDELETED(src))
+ return
+ if(!owner)
+ return
+
+/obj/item/organ/genital/belly/update_appearance()
+ var/string
+ if(owner)
+ if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
+ if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
+ var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
+ color = "#[skintone2hex(H.skin_tone)]"
+ else
+ color = "#[owner.dna.features["belly_color"]]"
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ icon_state = sanitize_text(string)
+ H.update_genitals()
+
+ icon_state = sanitize_text(string)
+
+
+//Allows breasts to grow and change size, with sprite changes too.
+//maximum wah
+//Comical sizes slow you down in movement and actions.
+//Rediculous sizes makes you more cumbersome.
+//this is far too lewd wah
+
diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm
index 35d3675b..1564079c 100644
--- a/modular_citadel/code/modules/arousal/organs/genitals.dm
+++ b/modular_citadel/code/modules/arousal/organs/genitals.dm
@@ -61,6 +61,8 @@
switch(zone) //update as more genitals are added
if("chest")
return owner.is_chest_exposed()
+ if("belly")
+ return owner.is_chest_exposed()
if("groin")
return owner.is_groin_exposed()
@@ -154,15 +156,18 @@
make_breedable() //hyperstation set up the pregnancy stuff
if(dna.features["has_balls"])
give_balls()
- if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas.
- give_breasts()
if(dna.features["has_cock"])
give_penis()
+ if(dna.features["has_belly"])
+ give_belly()
+ if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas.
+ give_breasts()
if(dna.features["has_ovi"])
give_ovipositor()
if(dna.features["has_eggsack"])
give_eggsack()
+
/mob/living/carbon/human/proc/give_penis()
if(!dna)
return FALSE
@@ -209,6 +214,21 @@
T.fluid_efficiency = dna.features["balls_efficiency"]
T.update()
+/mob/living/carbon/human/proc/give_belly()
+ if(!dna)
+ return FALSE
+ if(NOGENITALS in dna.species.species_traits)
+ return FALSE
+ if(!getorganslot("belly"))
+ var/obj/item/organ/genital/belly/B = new
+ B.Insert(src)
+ if(B)
+ if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
+ B.color = "#[skintone2hex(skin_tone)]"
+ else
+ B.color = "#[dna.features["belly_color"]]"
+ B.update()
+
/mob/living/carbon/human/proc/give_breasts()
if(!dna)
return FALSE
@@ -361,15 +381,17 @@
var/size
var/aroused_state
var/colourtint
+ var/colourcode
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
+
//start scanning for genitals
for(var/obj/item/organ/O in H.internal_organs)
if(isgenital(O))
var/obj/item/organ/genital/G = O
if(G.hidden)
- return //we're gunna just hijack this for updates.
+ continue
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
genitals_to_add += H.getorganslot(G.slot)
//Now we added all genitals that aren't internal and should be rendered
@@ -390,23 +412,32 @@
S = GLOB.vagina_shapes_list[G.shape]
if(/obj/item/organ/genital/breasts)
S = GLOB.breasts_shapes_list[G.shape]
+ if(/obj/item/organ/genital/belly)
+ S = GLOB.breasts_shapes_list[G.shape]
if(!S || S.icon_state == "none")
continue
var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
+ colourcode = S.color_src
+
+ if(G.slot == "belly")
+ genital_overlay.icon = 'hyperstation/icons/obj/genitals/belly.dmi'
+ genital_overlay.icon_state = "belly"
+ colourcode = "belly_color"
+
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
if(use_skintones && H.dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
- genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
+// genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
if (colourtint)
genital_overlay.color = "#[colourtint]"
else
- switch(S.color_src)
+ switch(colourcode)
if("cock_color")
genital_overlay.color = "#[H.dna.features["cock_color"]]"
if (colourtint)
@@ -417,6 +448,8 @@
genital_overlay.color = "#[H.dna.features["breasts_color"]]"
if("vag_color")
genital_overlay.color = "#[H.dna.features["vag_color"]]"
+ if("belly_color")
+ genital_overlay.color = "#[H.dna.features["belly_color"]]"
standing += genital_overlay
@@ -425,4 +458,4 @@
standing = list()
for(var/L in relevant_layers)
- H.apply_overlay(L)
+ H.apply_overlay(L)
\ No newline at end of file
diff --git a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm
index d6f6dbe7..ae86c097 100644
--- a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm
+++ b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm
@@ -136,6 +136,15 @@
icon_state = "gaping"
name = "Gaping"
+//BREASTS BE HERE
+/datum/sprite_accessory/belly
+ icon = 'hyperstation/icons/obj/genitals/belly.dmi'
+ icon_state = "belly"
+ name = "belly"
+ gender_specific = 0
+ color_src = "belly_color"
+ locked = 0
+
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm
index a2d9056e..b4bd4ec1 100644
--- a/modular_citadel/code/modules/client/preferences_savefile.dm
+++ b/modular_citadel/code/modules/client/preferences_savefile.dm
@@ -13,7 +13,7 @@
features["mcolor3"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
features["mcolor2"] = sanitize_hexcolor(features["mcolor2"], 3, 0)
features["mcolor3"] = sanitize_hexcolor(features["mcolor3"], 3, 0)
-
+
S["alt_titles_preferences"] >> alt_titles_preferences
alt_titles_preferences = SANITIZE_LIST(alt_titles_preferences)
if(SSjob)
@@ -21,7 +21,7 @@
if(alt_titles_preferences[job.title])
if(!(alt_titles_preferences[job.title] in job.alt_titles))
alt_titles_preferences.Remove(job.title)
-
+
//gear loadout
var/text_to_load
S["loadout"] >> text_to_load
@@ -86,6 +86,9 @@
WRITE_FILE(S["feature_flavor_text"], features["flavor_text"])
//custom job titles
WRITE_FILE(S["alt_titles_preferences"], alt_titles_preferences)
+ //belly
+ WRITE_FILE(S["feature_has_belly"], features["has_belly"])
+ WRITE_FILE(S["feature_belly_color"], features["belly_color"])
//gear loadout
if(islist(chosen_gear))
diff --git a/tgstation.dme b/tgstation.dme
index 5d5cd039..9ea813c0 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3160,6 +3160,7 @@
#include "modular_citadel\code\modules\admin\holder2.dm"
#include "modular_citadel\code\modules\admin\secrets.dm"
#include "modular_citadel\code\modules\arousal\arousal.dm"
+#include "modular_citadel\code\modules\arousal\organs\belly.dm"
#include "modular_citadel\code\modules\arousal\organs\breasts.dm"
#include "modular_citadel\code\modules\arousal\organs\eggsack.dm"
#include "modular_citadel\code\modules\arousal\organs\genitals.dm"