@@ -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
|
||||
|
||||
Reference in New Issue
Block a user