Revert "pls"

This reverts commit 8c97511871.
This commit is contained in:
Fermi
2019-11-24 03:04:04 +00:00
parent 4c1c257035
commit c8b206a4cf
3003 changed files with 63963 additions and 157107 deletions
@@ -1,49 +1,26 @@
/obj/item/organ/genital/breasts
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = "chest"
slot = "breasts"
w_class = 3
size = BREASTS_SIZE_DEF //SHOULD BE A LETTER, starts as a number...???
var/cached_size = null //for enlargement SHOULD BE A NUMBER
var/prev_size //For flavour texts SHOULD BE A LETTER
//var/breast_sizes = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "huge", "flat")
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, "flat" = 0)
var/statuscheck = FALSE
fluid_id = "milk"
var/amount = 2
producing = TRUE
shape = "Pair"
can_masturbate_with = TRUE
masturbation_verb = "massage"
can_climax = TRUE
fluid_transfer_factor = 0.5
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_BREASTS
size = "c" //refer to the breast_values static list below for the cups associated number values
fluid_id = "milk"
shape = "pair"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION
masturbation_verb = "massage"
orgasm_verb = "leaking"
fluid_transfer_factor = 0.5
var/static/list/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, "flat" = 0)
var/cached_size //these two vars pertain size modifications and so should be expressed in NUMBERS.
var/prev_size //former cached_size value, to allow update_size() to early return should be there no significant changes.
/obj/item/organ/genital/breasts/on_life()
if(QDELETED(src))
return
if(!reagents || !owner)
return
reagents.maximum_volume = fluid_max_volume
if(fluid_id && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_milk()
/obj/item/organ/genital/breasts/proc/generate_milk()
if(owner.stat == DEAD)
return FALSE
consider_size()
reagents.isolate_reagent(fluid_id)
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))
/obj/item/organ/genital/breasts/Initialize(mapload, mob/living/carbon/human/H)
if(!H)
cached_size = breast_values[size]
prev_size = cached_size
return ..()
/obj/item/organ/genital/breasts/proc/consider_size()
if(!cached_size || cached_size < 1)
@@ -53,6 +30,7 @@
reagents.maximum_volume = fluid_max_volume
/obj/item/organ/genital/breasts/update_appearance()
. = ..()
var/lowershape = lowertext(shape)
switch(lowershape)
if("pair")
@@ -63,16 +41,15 @@
desc = "You see three sets of breasts, running from their chest to their belly."
else
desc = "You see some breasts, they seem to be quite exotic."
if(cached_size > 16)
if(size == "huge")
desc = "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(cached_size)]cm in diameter."
else if (!isnum(size))
else
if (size == "flat")
desc += " They're very small and flatchested, however."
else
desc += " You estimate that they're [uppertext(size)]-cups."
//string = "breasts_[lowertext(shape)]_[size]-s"
if(producing && aroused_state)
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION) && aroused_state)
desc += " They're leaking [fluid_id]."
var/string
if(owner)
@@ -88,57 +65,71 @@
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
/obj/item/organ/genital/breasts/update_size()//wah
if(!ishuman(owner) || !owner)
/obj/item/organ/genital/breasts/modify_size(modifier, min = -INFINITY, max = INFINITY)
var/new_value = CLAMP(cached_size + modifier, min, max)
if(new_value == cached_size)
return
if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
to_chat(owner, "<span class='warning'>You feel your breasts shrinking away from your body as your chest flattens out.</b></span>")
src.Remove(owner)
switch(round(cached_size))
if(0) //If flatchested
size = "flat"
if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = FALSE
if(1 to 8) //If modest size
size = breast_values[round(cached_size)]
if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = FALSE
if(9 to 15) //If massive
size = breast_values[round(cached_size)]
if(!owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.apply_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = TRUE
if(16 to INFINITY) //if Rediculous
size = cached_size
prev_size = cached_size
cached_size = new_value
update()
..()
if(round(cached_size) < 16)//Because byond doesn't count from 0, I have to do this.
if (prev_size == 0)
prev_size = "flat"
if(size == 0)//Bloody byond with it's counting from 1
/obj/item/organ/genital/breasts/update_size()//wah
var/rounded_cached = round(cached_size)
if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
if(owner)
to_chat(owner, "<span class='warning'>You feel your breasts shrinking away from your body as your chest flattens out.</span>")
QDEL_IN(src, 1)
return
var/enlargement = FALSE
switch(rounded_cached)
if(0) //flatchested
size = "flat"
if(isnum(prev_size))
prev_size = breast_values[prev_size]
if (breast_values[size] > breast_values[prev_size])
to_chat(owner, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
else if ((breast_values[size] < breast_values[prev_size]) && (breast_values[size] > 0.5))
to_chat(owner, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
prev_size = size
else if (cached_size >= 16)
size = "huge"
if(1 to 8) //modest
size = breast_values[rounded_cached]
if(9 to 15) //massive
size = breast_values[rounded_cached]
enlargement = TRUE
if(16 to INFINITY) //rediculous
size = "huge"
enlargement = TRUE
if(owner)
var/status_effect = owner.has_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
if(enlargement && !status_effect)
owner.apply_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
else if(!enlargement && status_effect)
owner.remove_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
if(rounded_cached < 16 && owner)//Because byond doesn't count from 0, I have to do this.
var/mob/living/carbon/human/H = owner
var/r_prev_size = round(prev_size)
if (rounded_cached > r_prev_size)
to_chat(H, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.</span>")
else if (rounded_cached < r_prev_size)
to_chat(H, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.</span>")
/obj/item/organ/genital/breasts/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[D.features["breasts_color"]]"
size = D.features["breasts_size"]
shape = D.features["breasts_shape"]
fluid_id = D.features["breasts_fluid"]
if(!D.features["breasts_producing"])
DISABLE_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION)
if(!isnum(size))
cached_size = breast_values[size]
else
cached_size = size
size = breast_values[size]
prev_size = cached_size
@@ -1,14 +1,14 @@
/obj/item/organ/genital/eggsack
name = "Egg sack"
desc = "An egg producing reproductive organ."
icon_state = "egg_sack"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = "groin"
slot = "testicles"
color = null //don't use the /genital color since it already is colored
internal = TRUE
name = "Egg sack"
desc = "An egg producing reproductive organ."
icon_state = "egg_sack"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_TESTICLES
genital_flags = GENITAL_INTERNAL|GENITAL_BLACKLISTED //unimplemented
linked_organ_slot = ORGAN_SLOT_PENIS
color = null //don't use the /genital color since it already is colored
var/egg_girth = EGG_GIRTH_DEF
var/cum_mult = CUM_RATE_MULT
var/cum_rate = CUM_RATE
var/cum_efficiency = CUM_EFFICIENCY
var/obj/item/organ/ovipositor/linked_ovi
@@ -1,414 +0,0 @@
/obj/item/organ/genital
color = "#fcccb3"
w_class = WEIGHT_CLASS_NORMAL
var/shape = "Human" //Changed to be uppercase, let me know if this breaks everything..!!
var/sensitivity = AROUSAL_START_VALUE
var/list/genital_flags = list()
var/can_masturbate_with = FALSE
var/masturbation_verb = "masturbate"
var/can_climax = FALSE
var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
var/size = 2 //can vary between num or text, just used in icon_state strings
var/fluid_id = null
var/fluid_max_volume = 15
var/fluid_efficiency = 1
var/fluid_rate = 1
var/fluid_mult = 1
var/producing = FALSE
var/aroused_state = FALSE //Boolean used in icon_state strings
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
var/obj/item/organ/genital/linked_organ
var/through_clothes = FALSE
var/internal = FALSE
var/hidden = FALSE
/obj/item/organ/genital/Initialize()
. = ..()
if(!reagents)
create_reagents(fluid_max_volume)
update()
/obj/item/organ/genital/Destroy()
remove_ref()
if(owner)
Remove(owner, 1)//this should remove references to it, so it can be GCd correctly
update_link()//this should remove any other links it has
return ..()
/obj/item/organ/genital/proc/update()
if(QDELETED(src))
return
update_size()
update_appearance()
update_link()
//exposure and through-clothing code
/mob/living/carbon
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
/obj/item/organ/genital/proc/is_exposed()
if(!owner)
return FALSE
if(hidden)
return FALSE
if(internal)
return FALSE
if(through_clothes)
return TRUE
switch(zone) //update as more genitals are added
if("chest")
return owner.is_chest_exposed()
if("groin")
return owner.is_groin_exposed()
return FALSE
/obj/item/organ/genital/proc/toggle_visibility(visibility)
switch(visibility)
if("Always visible")
through_clothes = TRUE
hidden = FALSE
if(!(src in owner.exposed_genitals))
owner.exposed_genitals += src
if("Hidden by clothes")
through_clothes = FALSE
hidden = TRUE
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if("Always hidden")
through_clothes = FALSE
hidden = TRUE
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if(ishuman(owner)) //recast to use update genitals proc
var/mob/living/carbon/human/H = owner
H.update_genitals()
/mob/living/carbon/verb/toggle_genitals()
set category = "IC"
set name = "Expose/Hide genitals"
set desc = "Allows you to toggle which genitals should show through clothes or not."
var/list/genital_list = list()
for(var/obj/item/organ/O in internal_organs)
if(isgenital(O))
var/obj/item/organ/genital/G = O
if(!G.internal)
genital_list += G
if(!genital_list.len) //There is nothing to expose
return
//Full list of exposable genitals created
var/obj/item/organ/genital/picked_organ
picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
if(picked_organ)
var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
picked_organ.toggle_visibility(picked_visibility)
return
/obj/item/organ/genital/proc/update_size()
return
/obj/item/organ/genital/proc/update_appearance()
return
/obj/item/organ/genital/proc/update_link()
return
/obj/item/organ/genital/proc/remove_ref()
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0)
..()
update()
/obj/item/organ/genital/Remove(mob/living/carbon/M, special = 0)
..()
update()
//proc to give a player their genitals and stuff when they log in
/mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
if(clean)
var/obj/item/organ/genital/GtoClean
for(GtoClean in internal_organs)
qdel(GtoClean)
if (NOGENITALS in dna.species.species_traits)
return
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
if(dna.features["has_vag"])
give_vagina()
if(dna.features["has_womb"])
give_womb()
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_ovi"])
give_ovipositor()
if(dna.features["has_eggsack"])
give_eggsack()
/mob/living/carbon/human/proc/give_penis()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("penis"))
var/obj/item/organ/genital/penis/P = new
P.Insert(src)
if(P)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
P.color = "#[skintone2hex(skin_tone)]"
else
P.color = "#[dna.features["cock_color"]]"
P.length = dna.features["cock_length"]
P.girth_ratio = dna.features["cock_girth_ratio"]
P.shape = dna.features["cock_shape"]
P.prev_length = P.length
P.cached_length = P.length
P.update()
/mob/living/carbon/human/proc/give_balls()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("testicles"))
var/obj/item/organ/genital/testicles/T = new
T.Insert(src)
if(T)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
T.color = "#[skintone2hex(skin_tone)]"
else
T.color = "#[dna.features["balls_color"]]"
T.size = dna.features["balls_size"]
T.sack_size = dna.features["balls_sack_size"]
T.shape = dna.features["balls_shape"]
if(dna.features["balls_shape"] == "Hidden")
T.internal = TRUE
else
T.internal = FALSE
T.fluid_id = dna.features["balls_fluid"]
T.fluid_rate = dna.features["balls_cum_rate"]
T.fluid_mult = dna.features["balls_cum_mult"]
T.fluid_efficiency = dna.features["balls_efficiency"]
T.update()
/mob/living/carbon/human/proc/give_breasts()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("breasts"))
var/obj/item/organ/genital/breasts/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["breasts_color"]]"
B.size = dna.features["breasts_size"]
if(!isnum(B.size))
if(B.size == "flat")
B.cached_size = 0
B.prev_size = 0
else if (B.cached_size == "huge")
B.prev_size = "huge"
else
B.cached_size = B.breast_values[B.size]
B.prev_size = B.size
else
B.cached_size = B.size
B.prev_size = B.size
B.shape = dna.features["breasts_shape"]
B.fluid_id = dna.features["breasts_fluid"]
B.producing = dna.features["breasts_producing"]
B.update()
/mob/living/carbon/human/proc/give_ovipositor()
return
/mob/living/carbon/human/proc/give_eggsack()
return
/mob/living/carbon/human/proc/give_vagina()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("vagina"))
var/obj/item/organ/genital/vagina/V = new
V.Insert(src)
if(V)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
V.color = "#[skintone2hex(skin_tone)]"
else
V.color = "[dna.features["vag_color"]]"
V.shape = "[dna.features["vag_shape"]]"
V.update()
/mob/living/carbon/human/proc/give_womb()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("womb"))
var/obj/item/organ/genital/womb/W = new
W.Insert(src)
if(W)
W.update()
/datum/species/proc/genitals_layertext(layer)
switch(layer)
if(GENITALS_BEHIND_LAYER)
return "BEHIND"
/*if(GENITALS_ADJ_LAYER)
return "ADJ"*/
if(GENITALS_FRONT_LAYER)
return "FRONT"
//procs to handle sprite overlays being applied to humans
/obj/item/equipped(mob/user, slot)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.update_genitals()
..()
/mob/living/carbon/human/doUnEquip(obj/item/I, force)
. = ..()
if(!.)
return
update_genitals()
/mob/living/carbon/human/proc/update_genitals()
if(src && !QDELETED(src))
dna.species.handle_genitals(src)
//fermichem procs
/mob/living/carbon/human/proc/Force_update_genitals(mob/living/carbon/human/H) //called in fermiChem
dna.species.handle_genitals(src)//should work.
//dna.species.handle_breasts(src)
//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
/mob/living/carbon/human/proc/emergent_genital_call()
var/organCheck = FALSE
var/breastCheck = FALSE
var/willyCheck = FALSE
if(!canbearoused)
ADD_TRAIT(src, TRAIT_PHARMA, "pharma")//Prefs prevent unwanted organs.
return
for(var/obj/item/organ/O in internal_organs)
if(istype(O, /obj/item/organ/genital))
organCheck = TRUE
if(/obj/item/organ/genital/penis)
//dna.features["has_cock"] = TRUE
willyCheck = TRUE
if(/obj/item/organ/genital/breasts)
//dna.features["has_breasts"] = TRUE//Goddamnit get in there.
breastCheck = TRUE
if(organCheck == FALSE)
if(ishuman(src) && dna.species.id == "human")
dna.features["genitals_use_skintone"] = TRUE
dna.species.use_skintones = TRUE
if(MUTCOLORS)
if(src.dna.species.fixed_mut_color)
dna.features["cock_color"] = "[src.dna.species.fixed_mut_color]"
dna.features["breasts_color"] = "[src.dna.species.fixed_mut_color]"
return
//So people who haven't set stuff up don't get rainbow surprises.
dna.features["cock_color"] = "[dna.features["mcolor"]]"
dna.features["breasts_color"] = "[dna.features["mcolor"]]"
else //If there's a new organ, make it the same colour.
if(breastCheck == FALSE)
dna.features["breasts_color"] = dna.features["cock_color"]
else if (willyCheck == FALSE)
dna.features["cock_color"] = dna.features["breasts_color"]
return
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
if(!H)//no args
CRASH("H = null")
if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done
return
if((NOGENITALS in species_traits) && (H.genital_override = FALSE))//golems and such - things that shouldn't
return
if(HAS_TRAIT(H, TRAIT_HUSK))
return
var/list/genitals_to_add = list()
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER) //GENITALS_ADJ_LAYER removed
var/list/standing = list()
var/size
var/aroused_state
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.
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
//start applying overlays
for(var/layer in relevant_layers)
var/layertext = genitals_layertext(layer)
for(var/obj/item/organ/genital/G in genitals_to_add)
var/datum/sprite_accessory/S
size = G.size
aroused_state = G.aroused_state
switch(G.type)
if(/obj/item/organ/genital/penis)
S = GLOB.cock_shapes_list[G.shape]
if(/obj/item/organ/genital/testicles)
S = GLOB.balls_shapes_list[G.shape]
if(/obj/item/organ/genital/vagina)
S = GLOB.vagina_shapes_list[G.shape]
if(/obj/item/organ/genital/breasts)
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]"
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]"
else
switch(S.color_src)
if("cock_color")
genital_overlay.color = "#[H.dna.features["cock_color"]]"
if("balls_color")
genital_overlay.color = "#[H.dna.features["balls_color"]]"
if("breasts_color")
genital_overlay.color = "#[H.dna.features["breasts_color"]]"
if("vag_color")
genital_overlay.color = "#[H.dna.features["vag_color"]]"
standing += genital_overlay
if(LAZYLEN(standing))
H.overlays_standing[layer] = standing.Copy()
standing = list()
for(var/L in relevant_layers)
H.apply_overlay(L)
@@ -1,166 +0,0 @@
/datum/sprite_accessory
var/alt_aroused = FALSE //CIT CODE if this is TRUE, then the genitals will use an alternate icon_state when aroused.
//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM
/datum/sprite_accessory/penis
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon_state = null
name = "penis" //the preview name of the accessory
gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
locked = 0
/datum/sprite_accessory/penis/human
icon_state = "human"
name = "Human"
/datum/sprite_accessory/penis/knotted
icon_state = "knotted"
name = "Knotted"
/datum/sprite_accessory/penis/flared
icon_state = "flared"
name = "Flared"
/datum/sprite_accessory/penis/barbknot
icon_state = "barbknot"
name = "Barbed, Knotted"
/datum/sprite_accessory/penis/tapered
icon_state = "tapered"
name = "Tapered"
/datum/sprite_accessory/penis/tentacle
icon_state = "tentacle"
name = "Tentacled"
/datum/sprite_accessory/penis/hemi
icon_state = "hemi"
name = "Hemi"
/datum/sprite_accessory/penis/hemiknot
icon_state = "hemiknot"
name = "Knotted Hemi"
////////////////////////
// Taur cocks go here //
////////////////////////
/datum/sprite_accessory/penis/taur_flared
icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width
icon_state = "flared"
name = "Taur, Flared"
center = TRUE //Center the image 'cause 2-tile wide.
dimension_x = 64
/datum/sprite_accessory/penis/taur_knotted
icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width
icon_state = "knotted"
name = "Taur, Knotted"
center = TRUE //Center the image 'cause 2-tile wide.
dimension_x = 64
/datum/sprite_accessory/penis/taur_tapered
icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi' //Needed larger width
icon_state = "tapered"
name = "Taur, Tapered"
center = TRUE //Center the image 'cause 2-tile wide.
dimension_x = 64
//Testicles
//These ones aren't inert
/datum/sprite_accessory/testicles
icon = 'modular_citadel/icons/obj/genitals/testicles_onmob.dmi'
icon_state = "testicle"
name = "testicle" //the preview name of the accessory
color_src = "balls_color"
locked = 0
/datum/sprite_accessory/testicles/hidden
icon_state = "hidden"
name = "Hidden"
alt_aroused = TRUE
/datum/sprite_accessory/testicles/single
icon_state = "single"
name = "Single"
alt_aroused = TRUE
//Vaginas
/datum/sprite_accessory/vagina
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
icon_state = null
name = "vagina"
gender_specific = 0
color_src = "vag_color"
locked = 0
alt_aroused = FALSE //if this is TRUE, then the genitals will use an alternate sprite for aroused states
/datum/sprite_accessory/vagina/human
icon_state = "human"
name = "Human"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/tentacles
icon_state = "tentacle"
name = "Tentacle"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/dentata
icon_state = "dentata"
name = "Dentata"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/hairy
icon_state = "hairy"
name = "Hairy"
/datum/sprite_accessory/vagina/spade
icon_state = "spade"
name = "Spade"
/datum/sprite_accessory/vagina/furred
icon_state = "furred"
name = "Furred"
/datum/sprite_accessory/vagina/gaping
icon_state = "gaping"
name = "Gaping"
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
icon_state = null
name = "breasts"
gender_specific = 0
color_src = "breasts_color"
locked = 0
/datum/sprite_accessory/breasts/pair
icon_state = "pair"
name = "Pair"
alt_aroused = TRUE
/datum/sprite_accessory/breasts/quad
icon_state = "quad"
name = "Quad"
alt_aroused = TRUE
/datum/sprite_accessory/breasts/sextuple
icon_state = "sextuple"
name = "Sextuple"
alt_aroused = TRUE
//OVIPOSITORS BE HERE
/datum/sprite_accessory/ovipositor
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon_state = null
name = "Ovipositor" //the preview name of the accessory
gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
locked = 0
/datum/sprite_accessory/ovipositor/knotted
icon_state = "knotted"
name = "Knotted"
@@ -3,14 +3,14 @@
desc = "An egg laying reproductive organ."
icon_state = "ovi_knotted_2"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = "groin"
slot = "penis"
w_class = 3
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_PENIS
genital_flags = GENITAL_BLACKLISTED //unimplemented
shape = "knotted"
size = 3
layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/girth = 0
var/girth_ratio = COCK_GIRTH_RATIO_DEF //citadel_defines.dm for these defines
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/oviflags = list()
var/obj/item/organ/eggsack/linked_eggsack
@@ -1,77 +1,78 @@
/obj/item/organ/genital/penis
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = "groin"
slot = ORGAN_SLOT_PENIS
can_masturbate_with = TRUE
masturbation_verb = "stroke"
can_climax = TRUE
fluid_transfer_factor = 0.5
size = 2 //arbitrary value derived from length and girth for sprites.
var/length = 6 //inches
var/cached_length //used to detect a change in length
var/girth = 4.38
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/dickflags = list()
var/list/knotted_types = list("knotted", "barbed, knotted")
var/prev_length = 6 //really should be renamed to prev_length
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_PENIS
masturbation_verb = "stroke"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
linked_organ_slot = ORGAN_SLOT_TESTICLES
fluid_transfer_factor = 0.5
size = 2 //arbitrary value derived from length and girth for sprites.
layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/prev_length = 6 //really should be renamed to prev_length
var/girth = 4.38
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
/obj/item/organ/genital/penis/Initialize()
. = ..()
/* I hate genitals.*/
/obj/item/organ/genital/penis/update_size()
var/mob/living/carbon/human/o = owner
if(!ishuman(o) || !o)
/obj/item/organ/genital/penis/modify_size(modifier, min = -INFINITY, max = INFINITY)
var/new_value = CLAMP(length + modifier, min, max)
if(new_value == length)
return
if(cached_length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
to_chat(o, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
P.Remove(o)
switch(round(cached_length))
if(0 to 4) //If modest size
length = cached_length
size = 1
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(5 to 10) //If modest size
length = cached_length
size = 2
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(11 to 20) //If massive
length = cached_length
size = 3
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(21 to 35) //If massive and due for large effects
length = cached_length
size = 3
if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
if(36 to INFINITY) //If comical
length = cached_length
size = 4 //no new sprites for anything larger yet
if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
if (round(length) > round(prev_length))
to_chat(o, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.</b></span>")
else if ((round(length) < round(prev_length)) && (length > 0.5))
to_chat(o, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.</b></span>")
prev_length = length
length = CLAMP(length + modifier, min, max)
update()
/obj/item/organ/genital/penis/update_size(modified = FALSE)
if(length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
if(owner)
to_chat(owner, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
QDEL_IN(src, 1)
if(linked_organ)
QDEL_IN(linked_organ, 1)
return
var/rounded_length = round(length)
var/new_size
var/enlargement = FALSE
switch(rounded_length)
if(0 to 6) //If modest size
new_size = 1
if(7 to 11) //If large
new_size = 2
if(12 to 20) //If massive
new_size = 3
if(21 to 34) //If massive and due for large effects
new_size = 3
enlargement = TRUE
if(35 to INFINITY) //If comical
new_size = 4 //no new sprites for anything larger yet
enlargement = TRUE
if(owner)
var/status_effect = owner.has_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
if(enlargement && !status_effect)
owner.apply_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
else if(!enlargement && status_effect)
owner.remove_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
if(linked_organ)
linked_organ.size = CLAMP(size + new_size, BALLS_SIZE_MIN, BALLS_SIZE_MAX)
linked_organ.update()
size = new_size
if(owner)
if (round(length) > round(prev_length))
to_chat(owner, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.</b></span>")
else if ((round(length) < round(prev_length)) && (length > 0.5))
to_chat(owner, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.</b></span>")
icon_state = sanitize_text("penis_[shape]_[size]")
girth = (length * girth_ratio)//Is it just me or is this ludicous, why not make it exponentially decay?
//I have no idea on how to update sprites and I hate it
/obj/item/organ/genital/penis/update_appearance()
. = ..()
var/string
var/lowershape = lowertext(shape)
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] [name]. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
if(owner)
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -87,13 +88,13 @@
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/penis/update_link()
if(owner)
linked_organ = (owner.getorganslot("testicles"))
if(linked_organ)
linked_organ.linked_organ = src
linked_organ.size = size
/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
color = "#[D.features["cock_color"]]"
length = D.features["cock_length"]
girth_ratio = D.features["cock_girth_ratio"]
shape = D.features["cock_shape"]
prev_length = length
@@ -1,82 +1,46 @@
/obj/item/organ/genital/testicles
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
zone = "groin"
slot = "testicles"
size = BALLS_SIZE_MIN
var/size_name = "average"
shape = "single"
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
producing = TRUE
can_masturbate_with = FALSE
masturbation_verb = "massage"
can_climax = TRUE
var/sent_full_message = TRUE //defaults to 1 since they're full to start
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_TESTICLES
size = BALLS_SIZE_MIN
linked_organ_slot = ORGAN_SLOT_PENIS
genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION
var/size_name = "average"
shape = "Single"
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
masturbation_verb = "massage"
layer_index = TESTICLES_LAYER_INDEX
/obj/item/organ/genital/testicles/on_life()
if(QDELETED(src))
return
if(reagents && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_cum()
/obj/item/organ/genital/testicles/proc/generate_cum()
reagents.maximum_volume = fluid_max_volume
if(reagents.total_volume >= reagents.maximum_volume)
if(!sent_full_message)
send_full_message()
sent_full_message = TRUE
/obj/item/organ/genital/testicles/generate_fluid()
if(!linked_organ && !update_link())
return FALSE
sent_full_message = FALSE
update_link()
if(!linked_organ)
return FALSE
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
. = ..()
if(. && reagents.holder_full())
to_chat(owner, "Your balls finally feel full, again.")
/obj/item/organ/genital/testicles/update_link()
if(owner && !QDELETED(src))
linked_organ = (owner.getorganslot("penis"))
if(linked_organ)
linked_organ.linked_organ = src
size = linked_organ.size
/obj/item/organ/genital/testicles/upon_link()
size = linked_organ.size
update_size()
update_appearance()
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
if(owner && istext(msg))
to_chat(owner, msg)
return TRUE
/obj/item/organ/genital/testicles/update_appearance()
/obj/item/organ/genital/testicles/update_size(modified = FALSE)
switch(size)
if(0.1 to 1)
if(BALLS_SIZE_MIN)
size_name = "average"
if(1.1 to 2)
if(BALLS_SIZE_DEF)
size_name = "enlarged"
if(2.1 to INFINITY)
if(BALLS_SIZE_MAX)
size_name = "engorged"
else
size_name = "nonexistant"
if(!internal)
desc = "You see an [size_name] pair of testicles."
else
desc = "They don't have any testicles you can see."
/obj/item/organ/genital/testicles/update_appearance()
. = ..()
desc = "You see an [size_name] pair of testicles."
if(owner)
var/string
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -91,3 +55,18 @@
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[D.features["balls_color"]]"
sack_size = D.features["balls_sack_size"]
shape = D.features["balls_shape"]
if(D.features["balls_shape"] == "Hidden")
ENABLE_BITFIELD(genital_flags, GENITAL_INTERNAL)
fluid_id = D.features["balls_fluid"]
fluid_rate = D.features["balls_cum_rate"]
fluid_mult = D.features["balls_cum_mult"]
fluid_efficiency = D.features["balls_efficiency"]
@@ -1,26 +1,25 @@
/obj/item/organ/genital/vagina
name = "vagina"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "vagina"
zone = "groin"
slot = "vagina"
size = 1 //There is only 1 size right now
can_masturbate_with = TRUE
masturbation_verb = "finger"
can_climax = TRUE
name = "vagina"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = ORGAN_SLOT_VAGINA
zone = BODY_ZONE_PRECISE_GROIN
slot = "vagina"
size = 1 //There is only 1 size right now
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
masturbation_verb = "finger"
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
w_class = 3
var/cap_length = 8//D E P T H (cap = capacity)
var/cap_girth = 12
layer_index = VAGINA_LAYER_INDEX
var/cap_length = 8//D E P T H (cap = capacity)
var/cap_girth = 12
var/cap_girth_ratio = 1.5
var/clits = 1
var/clit_diam = 0.25
var/clit_len = 0.25
var/clits = 1
var/clit_diam = 0.25
var/clit_len = 0.25
var/list/vag_types = list("tentacle", "dentata", "hairy", "spade", "furred")
/obj/item/organ/genital/vagina/update_appearance()
. = ..()
var/string //Keeping this code here, so making multiple sprites for the different kinds is easier.
var/lowershape = lowertext(shape)
var/details
@@ -63,12 +62,10 @@
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/vagina/update_link()
if(owner)
linked_organ = (owner.getorganslot("womb"))
if(linked_organ)
linked_organ.linked_organ = src
/obj/item/organ/genital/vagina/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
color = "[D.features["vag_color"]]"
shape = "[D.features["vag_shape"]]"
@@ -1,45 +1,10 @@
/obj/item/organ/genital/womb
name = "womb"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "womb"
zone = "groin"
slot = "womb"
internal = TRUE
fluid_id = "femcum"
producing = TRUE
/obj/item/organ/genital/womb/on_life()
if(QDELETED(src))
return
if(reagents && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_femcum()
/obj/item/organ/genital/womb/proc/generate_femcum()
reagents.maximum_volume = fluid_max_volume
update_link()
if(!linked_organ)
return FALSE
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
/obj/item/organ/genital/womb/update_link()
if(owner)
linked_organ = (owner.getorganslot("vagina"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/womb/Destroy()
return ..()
name = "womb"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "womb"
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_WOMB
genital_flags = GENITAL_INTERNAL|GENITAL_FUID_PRODUCTION
fluid_id = "femcum"
linked_organ_slot = ORGAN_SLOT_VAGINA