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:
+339
-199
@@ -181,224 +181,364 @@
|
||||
else
|
||||
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
|
||||
|
||||
|
||||
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
|
||||
//For all of these, we assume the arguments given are proper and have been checked beforehand.
|
||||
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time)
|
||||
src.visible_message("<span class='danger'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
|
||||
"<span class='green'>You start to [G.masturbation_verb] your [G.name].</span>", \
|
||||
"<span class='green'>You start to [G.masturbation_verb] your [G.name].</span>")
|
||||
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/unable_to_come = FALSE
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
if(unable_to_come)
|
||||
src.visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
|
||||
else
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time) //as long as it's not instant, give a warning
|
||||
src.visible_message("<span class='danger'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='green'>You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].</span>", \
|
||||
"<span class='green'>You climax using your [G.name].</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30) //Used for climaxing with any living thing
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time) //Skip warning if this is an instant climax.
|
||||
src.visible_message("[src] is about to climax with [L]!", \
|
||||
"You're about to climax with [L]!", \
|
||||
"<span class='danger'>You're preparing to climax with someone!</span>")
|
||||
if(spillage)
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor)
|
||||
total_fluids -= total_fluids*G.fluid_transfer_factor
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(L.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='green'>You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].</span>", \
|
||||
"<span class='green'>You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
else //knots and other non-spilling orgasms
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids)
|
||||
total_fluids = 0
|
||||
src.visible_message("<span class='danger'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
|
||||
"<span class='green'>You ejaculate with [L], your [G.name] spilling nothing.</span>", \
|
||||
"<span class='green'>You have climaxed inside someone, your [G.name] spilling nothing.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/weapon/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
//if(!container) //Something weird happened
|
||||
// to_chat(src, "<span class='warning'>You need a container to do this!</span>")
|
||||
// return
|
||||
|
||||
src.visible_message("<span class='danger'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
|
||||
"<span class='userdanger'>You start to [G.masturbation_verb] your [G.name] over [container].</span>", \
|
||||
"<span class='userdanger'>You start to [G.masturbation_verb] your [G.name] over something.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, container))
|
||||
fluid_source.trans_to(container, total_fluids)
|
||||
src.visible_message("<span class='danger'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
|
||||
"<span class='green'>You used your [G.name] to fill [container].</span>", \
|
||||
"<span class='green'>You have relieved some pressure.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
/mob/living/carbon/human/proc/pick_masturbate_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_climax) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_partner()
|
||||
var/list/partners = list()
|
||||
if(src.pulling)
|
||||
partners += src.pulling //Yes, even objects for now
|
||||
if(src.pulledby)
|
||||
partners += src.pulledby
|
||||
//Now we got both of them, let's check if they're proper
|
||||
for(var/I in partners)
|
||||
if(isliving(I))
|
||||
if(iscarbon(I))
|
||||
var/mob/living/carbon/C = I
|
||||
if(!C.exposed_genitals.len) //Nothing through_clothing
|
||||
if(!C.is_groin_exposed()) //No pants undone
|
||||
if(!C.is_chest_exposed()) //No chest exposed
|
||||
partners -= I //Then not proper, remove them
|
||||
else
|
||||
partners -= I //No fucking objects
|
||||
//NOW the list should only contain correct partners
|
||||
if(!partners.len)
|
||||
return null //No one left.
|
||||
return input(src, "With whom?", "Sexual partner", null) in partners //pick one, default to null
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_container()
|
||||
var/obj/item/weapon/reagent_containers/SC = null
|
||||
var/list/containers_list = list()
|
||||
|
||||
for(var/obj/item/weapon/reagent_containers/container in held_items)
|
||||
if(container.is_open_container() || istype(container, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
containers_list += container
|
||||
|
||||
if(containers_list.len)
|
||||
SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
|
||||
if(SC)
|
||||
if(in_range(src, SC))
|
||||
return SC
|
||||
return null //If nothing correct, give null.
|
||||
|
||||
|
||||
//Here's the main proc itself
|
||||
/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
|
||||
if(mb_cd_timer > world.time)
|
||||
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
|
||||
to_chat(src, "<span class='warning'>You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!</span>")
|
||||
return
|
||||
mb_cd_timer = (world.time + mb_cd_length)
|
||||
var/list/genitals_list = list()
|
||||
var/obj/item/organ/genital/SG = null//originally selected_genital
|
||||
var/list/containers_list = list()
|
||||
var/obj/item/weapon/reagent_containers/SC = null
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/into_container = 0
|
||||
var/free_hands = get_num_arms() //arms was only used to know if we had ANY at all
|
||||
var/total_cum = 0
|
||||
var/finished = 0
|
||||
var/mb_time = 30
|
||||
|
||||
|
||||
if(canbearoused && has_dna())
|
||||
if(stat==2)
|
||||
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
|
||||
return
|
||||
if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with) //All capable genitals will orgasm with this
|
||||
var/unable_to_come = FALSE
|
||||
switch(G.type)
|
||||
if(/obj/item/organ/genital/penis)
|
||||
var/obj/item/organ/genital/penis/P = G
|
||||
if(!P.linked_balls)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = P.linked_balls.reagents
|
||||
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.can_climax) //Skip things like wombs and testicles
|
||||
continue
|
||||
var/mob/living/partner
|
||||
var/check_target
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
if(G.is_exposed(worn_stuff))
|
||||
if(src.pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
|
||||
if(isliving(src.pulling)) //Don't fuck objects
|
||||
check_target = src.pulling
|
||||
if(src.pulledby && !check_target) //prioritise pulled over pulledby
|
||||
if(isliving(src.pulledby))
|
||||
check_target = src.pulledby
|
||||
//Now we should have a partner, or else we have to come alone
|
||||
if(check_target)
|
||||
if(iscarbon(check_target)) //carbons can have clothes
|
||||
var/mob/living/carbon/C = check_target
|
||||
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
|
||||
partner = C
|
||||
else //A cat is fine too
|
||||
partner = check_target
|
||||
if(partner) //Did they pass the clothing checks?
|
||||
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
|
||||
continue //You've climaxed once with this organ, continue on
|
||||
//not exposed OR if no partner was found while exposed, climax alone
|
||||
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
|
||||
//Now all genitals that could climax, have.
|
||||
//Since this was a forced climax, we do not need to continue with the other stuff
|
||||
return
|
||||
//If we get here, then this is not a forced climax and we gotta check a few things.
|
||||
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = G
|
||||
if(!V.linked_womb)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = V.linked_womb.reagents
|
||||
else //Weird, undefined genitalia behaviour
|
||||
unable_to_come = TRUE
|
||||
|
||||
if(unable_to_come)
|
||||
src.visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
|
||||
else
|
||||
if(fluid_source)
|
||||
total_cum = fluid_source.total_volume
|
||||
src.visible_message("<span class='danger'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
fluid_source = null //cleanup so this can be used for the next genitalia
|
||||
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You're forced to cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""] with your [G].</span>", \
|
||||
"<span class='green'>Your [G] have been forced to climax.</span>")
|
||||
finished = 1
|
||||
if(finished)
|
||||
setArousalLoss(min_arousal)
|
||||
return //Do not proceed to masturbating if all genitals have been forced to orgasm.
|
||||
if(stat==1) //Sleeping people can be forced chemically or with electrical stimulants, for example.
|
||||
if(stat==1) //No sleep-masturbation, you're unconscious.
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
return
|
||||
if(restrained())
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
if(getArousalLoss() < 33)//flat number instead of percentage
|
||||
if(getArousalLoss() < 33) //flat number instead of percentage
|
||||
to_chat(src, "<span class='warning'>You aren't aroused enough for that!</span>")
|
||||
return
|
||||
if(!is_groin_exposed())
|
||||
to_chat(src, "<span class='warning'>You need to undress, first!</span>")
|
||||
return
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You need at least one free hand.</span>")
|
||||
return
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with)//filter out what you can't masturbate with
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
SG = input(src, "with what?", "Masturbate") as null|obj in genitals_list
|
||||
if(SG)
|
||||
for(var/obj/item/weapon/reagent_containers/container in held_items)
|
||||
if(container.is_open_container() || istype(container, /obj/item/weapon/reagent_containers/food/snacks/pie))
|
||||
containers_list += container
|
||||
if(containers_list.len)
|
||||
SC = input(src, "Into or onto what?(Cancel for nowhere)", "Masturbate") as null|obj in containers_list
|
||||
if(SC)
|
||||
if(in_range(src, SC))
|
||||
into_container = 1
|
||||
SG.update()
|
||||
switch(SG.type)
|
||||
|
||||
//Penis
|
||||
if(/obj/item/organ/genital/penis)
|
||||
var/obj/item/organ/genital/penis/P = SG
|
||||
if(!P.linked_balls)
|
||||
to_chat(src, "<span class='warning'>You need a pair of testicles to do this.</span>")
|
||||
return
|
||||
fluid_source = P.linked_balls.reagents
|
||||
total_cum = fluid_source.total_volume
|
||||
if(into_container)//into a glass or beaker or whatever
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [SG.name] over [SC].</span>", \
|
||||
"<span class='userdanger'>You start jerking off over [SC.name].</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, SC))
|
||||
fluid_source.trans_to(SC, total_cum)
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!</span>", \
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
else //Not in a container
|
||||
if(src.pulling)
|
||||
if(iscarbon(src.pulling))
|
||||
var/mob/living/carbon/C = src.pulling
|
||||
if(!C.is_groin_exposed())
|
||||
to_chat(src, "<span class='warning'>You must undress someone to climax inside them.</span>")
|
||||
return
|
||||
if(isliving(src.pulling)) //Gotta be alive to fuck it, don't wanna have to code fucking objects that ain't containers...
|
||||
var/mob/living/partner = src.pulling
|
||||
src.visible_message("[src] is about to climax inside [partner]!", \
|
||||
"You're about to climax inside [partner]!", \
|
||||
"<span class='danger'>You're preparing to climax inside someone!</span>")
|
||||
switch(grab_state)
|
||||
if(GRAB_PASSIVE)
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, partner))
|
||||
var/spillage = 0.5 //Leaks a bit on passive grab
|
||||
var/did_spill = FALSE
|
||||
fluid_source.trans_to(partner, total_cum*(1-spillage))
|
||||
total_cum = total_cum*spillage
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(partner.loc, TOUCH, 1, 0)
|
||||
did_spill = TRUE
|
||||
fluid_source.clear_reagents()
|
||||
//Ok, now we check what they want to do.
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
|
||||
|
||||
src.visible_message("<span class='danger'>[src] ejaculates inside [partner][did_spill ? ", overflowing and spilling":""]!</span>", \
|
||||
"<span class='green'>You ejaculate inside [partner][did_spill ? ", spilling out of them":""].</span>", \
|
||||
"<span class='green'>You have climaxed inside someone[did_spill ? ", spilling out of them":""].</span>")
|
||||
finished = 1
|
||||
else //Aggressive or higher
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, partner))
|
||||
var/spillage = 0.0 //Leakproofing seals
|
||||
fluid_source.trans_to(partner, total_cum*(1-spillage))
|
||||
total_cum = total_cum*spillage
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(partner.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
switch(choice)
|
||||
if("Masturbate")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ)
|
||||
mob_masturbate(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot masturbate without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
src.visible_message("<span class='danger'>[src] ejaculates inside [partner], spilling nothing!</span>", \
|
||||
"<span class='green'>You ejaculate inside [partner], spilling nothing.</span>", \
|
||||
"<span class='green'>You have climaxed inside someone, spilling nothing.</span>")
|
||||
finished = 1
|
||||
//Don't care, not coding you fucking a unanchored girder
|
||||
else //No pulling, or pulling non-living things
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [SG].</span>", \
|
||||
"<span class='green'>You start masturbating.</span>", \
|
||||
"<span class='green'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
if("Climax alone")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
mob_climax_outside(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
if("Climax with partner")
|
||||
//We need no hands, we can be restrained and so on, so let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
var/mob/living/partner = pick_partner() //Get someone
|
||||
if(partner)
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
|
||||
if(spillage == "Yes")
|
||||
mob_climax_partner(picked_organ, partner, TRUE)
|
||||
else
|
||||
mob_climax_partner(picked_organ, partner, FALSE)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = SG
|
||||
if(!V.linked_womb)
|
||||
to_chat(src, "<span class='warning'>You need a womb to do this.</span>")
|
||||
return
|
||||
fluid_source = V.linked_womb.reagents
|
||||
total_cum = fluid_source.total_volume
|
||||
if(into_container)//into a glass or beaker or whatever
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their [SG.name] over [SC].</span>", \
|
||||
"<span class='userdanger'>You start fingering over [SC.name].</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, SC))
|
||||
fluid_source.trans_to(SC, total_cum)
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!</span>", \
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
else//not into a container
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their vagina.</span>", \
|
||||
"<span class='userdanger'>You start fingering your vagina.</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
else//backup message, just in case
|
||||
src.visible_message("<span class='danger'>[src] starts masturbating!</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
src.visible_message("<span class='danger'>[src] [pick("relieves themself!", "shudders and moans in orgasm!")]</span>", \
|
||||
"<span class='userdanger'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
if(finished)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You have no genitals!</span>")
|
||||
return
|
||||
if("Fill container")
|
||||
//We'll need hands and no restraints.
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
var/obj/item/weapon/reagent_containers/fluid_container = pick_climax_container()
|
||||
if(fluid_container)
|
||||
mob_fill_container(picked_organ, fluid_container)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this without anything to fill.</span>")
|
||||
return
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing genitals.</span>")
|
||||
return
|
||||
else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled
|
||||
return //Just end it in that case.
|
||||
|
||||
@@ -153,14 +153,13 @@
|
||||
if(prob(33))
|
||||
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
|
||||
var/mob/living/carbon/human/H = M
|
||||
to_chat(H, "<span class='love'>Your libido is going haywire!</span>")
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
if(prob(50)) //Less spam
|
||||
to_chat(H, "<span class='love'>Your libido is going haywire!</span>")
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
if(M.min_arousal < 50)
|
||||
M.min_arousal += 1
|
||||
to_chat(M, "<span class='love'>You're having a hard time thinkin about things other than sex!</span>")
|
||||
if(M.min_arousal < M.max_arousal)
|
||||
M.min_arousal += 1
|
||||
to_chat(M, "<span class='love'>You feel your libido permanently increasing.</span>")
|
||||
M.adjustArousalLoss(2)
|
||||
..()
|
||||
|
||||
@@ -197,10 +196,8 @@
|
||||
if(prob(33))
|
||||
if(M.min_arousal > 0)
|
||||
M.min_arousal -= 1
|
||||
to_chat(M, "<span class='notice'>You feel your libido returning to more normal levels.</span>")
|
||||
if(M.min_arousal > 50)
|
||||
M.min_arousal -= 1
|
||||
to_chat(M, "<span class='notice'>You feel like your overactive libido is calming down.</span>")
|
||||
M.adjustArousalLoss(-2)
|
||||
..()
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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 ..()
|
||||
|
||||
Reference in New Issue
Block a user