Climaxing/masturbation changes, exposing through clothing, breastmilk and masturbation (#2357)

* Genital refactoring and masturbation rework

Refactors a lot of genitalia code.
Reworks masturbation code.
Adds the ability to expose onself through clothing (Still bugfixing it).

* Fixes it so everything works

Toggling exposing your genitals now works properly. You can now expose
genitals through clothing.
Genitalia is rendered a bit more modularly and less hardcoded.
Genitalia no longer has linked_penis and such, but instead linked_organ.
More variables made general for genitals.
Breasts can now be used to masturbate and climax, also letting you fill
beakers and others with milk.
Both being pulled and pulling someone can let you count them as a
partner for climaxing verbs.
Mob_climax split up into more sub-procs.
Hexacrocin made less verbose, and not as spam-happy with forced orgasms.
Hexacamphor also made less verbose.

* Removes outcommented code

Forgot to remove the old masturbation code that I commented out.

* Changes one tab further on line 248

As pointed out to me ^^.

* Climaxing with partner tabulation

Also copied the command for the spillage version.

* capitalisation and timers

Removed timers from forced climaxes and made it a default value
parameter instead, so it's adjustable.
Changed capitalisation of genitals and the mentions of them now use the
.name to avoid including a "The" in the mention.

* I accidentally runtimestation

Accidentally committed changing the map to runtimestation when I
debugged my code.
Changed it back to basemap now.
This commit is contained in:
ktccd
2017-08-19 19:01:02 -07:00
committed by kevinz000
parent 6541ea749c
commit 5731ea7cad
9 changed files with 495 additions and 295 deletions
+12 -2
View File
@@ -1,5 +1,5 @@
/obj/item/organ/genital/breasts
name = "Breasts"
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'code/citadel/icons/breasts.dmi'
@@ -11,6 +11,10 @@
var/amount = 2
producing = TRUE
shape = "pair"
can_masturbate_with = TRUE
masturbation_verb = "massage"
can_climax = TRUE
fluid_transfer_factor =0.5
/obj/item/organ/genital/breasts/Initialize()
. = ..()
@@ -54,4 +58,10 @@
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["breasts_color"]]"
color = "#[owner.dna.features["breasts_color"]]"
/obj/item/organ/genital/breasts/is_exposed()
. = ..()
if(.)
return TRUE
return owner.is_chest_exposed()
+1 -1
View File
@@ -7,7 +7,7 @@
slot = "testicles"
color = null //don't use the /genital color since it already is colored
w_class = 3
var/internal = TRUE
internal = TRUE
var/egg_girth = EGG_GIRTH_DEF
var/cum_mult = CUM_RATE_MULT
var/cum_rate = CUM_RATE
+76 -23
View File
@@ -3,7 +3,10 @@
var/shape = "human"
var/sensitivity = 1
var/list/genital_flags = list()
var/can_masturbate_with = 0
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 = 50
@@ -13,6 +16,9 @@
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
/obj/item/organ/genital/Initialize()
. = ..()
@@ -34,6 +40,52 @@
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(internal)
return FALSE
if(through_clothes)
return TRUE
/obj/item/organ/genital/proc/toggle_through_clothes()
if(through_clothes)
through_clothes = FALSE
owner.exposed_genitals -= src
else
through_clothes = TRUE
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(istype(O, /obj/item/organ/genital))
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, "Expose/Hide genitals", "Choose which genitalia to expose/hide", null) in genital_list
if(picked_organ)
picked_organ.toggle_through_clothes()
return
/obj/item/organ/genital/proc/update_size()
/obj/item/organ/genital/proc/update_appearance()
@@ -41,6 +93,9 @@
/obj/item/organ/genital/proc/update_link()
/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)
..()
@@ -58,21 +113,21 @@
var/obj/item/organ/genital/GtoClean
for(GtoClean in internal_organs)
qdel(GtoClean)
if(dna.features["has_cock"])
give_penis()
if(dna.features["has_balls"])
give_balls()
else if(dna.features["has_ovi"])
give_ovipositor()
if(dna.features["has_eggsack"])
give_eggsack()
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
if(dna.features["has_breasts"])
give_breasts()
if(dna.features["has_vag"])
give_vagina()
if(dna.features["has_womb"])
give_womb()
if(dna.features["has_womb"])
give_womb()
if(dna.features["has_balls"])
give_balls()
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)
@@ -208,17 +263,15 @@
if(H.disabilities & HUSK)
return
//start scanning for genitals
var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
if(H.is_groin_exposed(worn_stuff))
//ORDER is important here. Vaginas first, theoretical testes after, and penis LAST.
//The latter is always drawn on top of the former.
if(H.has_vagina())
genitals_to_add += H.getorganslot("vagina")
if(H.has_penis())
genitals_to_add += H.getorganslot("penis")
if(H.is_chest_exposed(worn_stuff))
if(H.has_breasts())
genitals_to_add += H.getorganslot("breasts")
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
for(var/obj/item/organ/O in H.internal_organs)
if(istype(O, /obj/item/organ/genital))
var/obj/item/organ/genital/G = O
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
var/image/I
//start applying overlays
for(var/layer in relevant_layers)
+29 -26
View File
@@ -1,21 +1,23 @@
/obj/item/organ/genital/penis
name = "Penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'code/citadel/icons/penis.dmi'
zone = "groin"
slot = "penis"
w_class = 3
can_masturbate_with = 1
size = 2 //arbitrary value derived from length and girth for sprites.
var/length = 6 //inches
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'code/citadel/icons/penis.dmi'
zone = "groin"
slot = "penis"
w_class = 3
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 = 0
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", "barbknot")
var/obj/item/organ/genital/testicles/linked_balls
var/girth = 0
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", "barbknot")
/obj/item/organ/genital/penis/update_size()
if(length == cached_length)
@@ -55,15 +57,16 @@
/obj/item/organ/genital/penis/update_link()
if(owner)
linked_balls = (owner.getorganslot("testicles"))
if(linked_balls)
linked_balls.linked_penis = src
linked_organ = (owner.getorganslot("testicles"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_balls)
linked_balls.linked_penis = null
linked_balls = null
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/penis/remove_ref()
if(linked_balls)
linked_balls.linked_penis = null
linked_balls = null
/obj/item/organ/genital/penis/is_exposed()
. = ..()
if(.)
return TRUE
return owner.is_groin_exposed()
+9 -10
View File
@@ -1,18 +1,17 @@
/obj/item/organ/genital/testicles
name = "Testicles"
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'code/citadel/icons/penis.dmi'
zone = "groin"
slot = "testicles"
w_class = 3
var/internal = FALSE
internal = TRUE
size = BALLS_SIZE_DEF
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
producing = TRUE
var/sent_full_message = 1 //defaults to 1 since they're full to start
var/obj/item/organ/genital/penis/linked_penis
/obj/item/organ/genital/testicles/Initialize()
. = ..()
@@ -33,20 +32,20 @@
return FALSE
sent_full_message = 0
update_link()
if(!linked_penis)
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/testicles/update_link()
if(owner && !QDELETED(src))
linked_penis = (owner.getorganslot("penis"))
if(linked_penis)
linked_penis.linked_balls = src
linked_organ = (owner.getorganslot("penis"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_penis)
linked_penis.linked_balls = null
linked_penis = null
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))
+16 -13
View File
@@ -1,12 +1,15 @@
/obj/item/organ/genital/vagina
name = "Vagina"
name = "vagina"
desc = "A female reproductive organ."
icon = 'code/citadel/icons/vagina.dmi'
icon_state = "vagina"
zone = "groin"
slot = "vagina"
size = 1 //There is only 1 size right now
can_masturbate_with = 1
can_masturbate_with = TRUE
masturbation_verb = "finger"
can_climax = TRUE
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
@@ -15,7 +18,6 @@
var/clit_diam = 0.25
var/clit_len = 0.25
var/list/vag_types = list("tentacle", "dentata", "hairy")
var/obj/item/organ/genital/womb/linked_womb
/obj/item/organ/genital/vagina/update_appearance()
@@ -56,15 +58,16 @@
/obj/item/organ/genital/vagina/update_link()
if(owner)
linked_womb = (owner.getorganslot("womb"))
if(linked_womb)
linked_womb.linked_vag = src
linked_organ = (owner.getorganslot("womb"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_womb)
linked_womb.linked_vag = null
linked_womb = null
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/vagina/remove_ref()
if(linked_womb)
linked_womb.linked_vag = null
linked_womb = null
/obj/item/organ/genital/vagina/is_exposed()
. = ..()
if(.)
return TRUE
return owner.is_groin_exposed()
+10 -15
View File
@@ -1,15 +1,15 @@
/obj/item/organ/genital/womb
name = "Womb"
name = "womb"
desc = "A female reproductive organ."
icon = 'code/citadel/icons/vagina.dmi'
icon_state = "womb"
zone = "groin"
slot = "womb"
w_class = 3
var/internal = FALSE
internal = TRUE
fluid_id = "femcum"
producing = TRUE
var/obj/item/organ/genital/vagina/linked_vag
/obj/item/organ/genital/womb/Initialize()
. = ..()
@@ -24,25 +24,20 @@
/obj/item/organ/genital/womb/proc/generate_femcum()
reagents.maximum_volume = fluid_max_volume
update_link()
if(!linked_vag)
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_vag = (owner.getorganslot("vagina"))
if(linked_vag)
linked_vag.linked_womb = src
linked_organ = (owner.getorganslot("vagina"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_vag)
linked_vag.linked_womb = null
linked_vag = null
/obj/item/organ/genital/womb/remove_ref()
if(linked_vag)
linked_vag.linked_womb = null
linked_vag = null
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/womb/Destroy()
return ..()