//GS13 Port - Oh boy this has changed /mob/living var/arousal = 0 //How aroused the mob is. var/min_arousal = AROUSAL_MINIMUM_DEFAULT //The lowest this mobs arousal will get. default = 0 var/max_arousal = AROUSAL_MAXIMUM_DEFAULT //The highest this mobs arousal will get. default = 100 var/arousal_rate = AROUSAL_START_VALUE //The base rate that arousal will increase in this mob. var/arousal_loss_rate = AROUSAL_START_VALUE //How easily arousal can be relieved for this mob. var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types. var/mb_cd_length = 5 SECONDS //5 second cooldown for masturbating because fuck spam. var/mb_cd_timer = 0 //The timer itself /mob/living/carbon/human canbearoused = TRUE var/saved_underwear = ""//saves their underwear so it can be toggled later var/saved_undershirt = "" var/saved_socks = "" var/hidden_underwear = FALSE var/hidden_undershirt = FALSE var/hidden_socks = FALSE /mob/living/carbon/human/New() ..() saved_underwear = underwear saved_undershirt = undershirt //Species vars /datum/species var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused var/arousal_lose_rate = AROUSAL_START_VALUE //Multiplier for how easily arousal can be relieved var/list/cum_fluids = list(/datum/reagent/consumable/semen) var/list/milk_fluids = list(/datum/reagent/consumable/milk) var/list/femcum_fluids = list(/datum/reagent/consumable/semen/femcum) //Mob procs /mob/living/carbon/human/verb/underwear_toggle() set name = "Toggle undergarments" set category = "IC" var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling") as null|anything in list("Top", "Bottom", "Socks", "All") if(!confirm) return if(confirm == "Top") hidden_undershirt = !hidden_undershirt log_message("[hidden_undershirt ? "removed" : "put on" ] [p_their()] undershirt.", LOG_EMOTE) if(confirm == "Bottom") hidden_underwear = !hidden_underwear log_message("[hidden_underwear ? "removed" : "put on"] [p_their()] underwear.", LOG_EMOTE) if(confirm == "Socks") hidden_socks = !hidden_socks log_message("[hidden_socks ? "removed" : "put on"] [p_their()] socks.", LOG_EMOTE) if(confirm == "All") var/on_off = (hidden_undershirt || hidden_underwear || hidden_socks) ? FALSE : TRUE hidden_undershirt = on_off hidden_underwear = on_off hidden_socks = on_off log_message("[on_off ? "removed" : "put on"] all [p_their()] undergarments.", LOG_EMOTE) update_body(TRUE) /mob/living/proc/handle_arousal() /mob/living/carbon/handle_arousal() if(canbearoused && dna) var/datum/species/S S = dna.species if(S) if(!(SSmobs.times_fired % 36)) if(getArousal() < max_arousal) //if(S && !(SSmobs.times_fired % 36) && getArousal() < max_arousal)//Totally stolen from breathing code. Do this every 36 ticks. adjustArousal(arousal_rate * S.arousal_gain_rate) if(dna.features["exhibitionist"] && client) var/amt_nude = 0 if(is_chest_exposed() && (getorganslot("breasts"))) amt_nude++ if(is_groin_exposed()) if(getorganslot("penis")) amt_nude++ if(getorganslot("vagina")) amt_nude++ if(is_butt_exposed()) if(getorganslot("anus")) amt_nude++ if(amt_nude) var/watchers = 0 for(var/mob/_M in view(world.view, src)) var/mob/living/M = _M if(!istype(M)) continue if(M.client && !M.stat && !M.eye_blind && (locate(src) in viewers(world.view,M))) watchers++ if(watchers) adjustArousal((amt_nude * watchers) + S.arousal_gain_rate) /mob/living/proc/getArousal() return arousal /mob/living/proc/adjustArousal(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return FALSE arousal = clamp(arousal + amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/setArousal(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return FALSE arousal = clamp(amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/getPercentAroused() var/percentage = ((100 / max_arousal) * arousal) return percentage /mob/living/proc/isPercentAroused(percentage)//returns true if the mob's arousal (measured in a percent of 100) is greater than the arg percentage. if(!isnum(percentage) || percentage > 100 || percentage < 0) CRASH("Provided percentage is invalid") if(getPercentAroused() >= percentage) return TRUE return FALSE //H U D// /mob/living/proc/updatearousal() update_arousal_hud() /mob/living/carbon/updatearousal() . = ..() for(var/obj/item/organ/genital/G in internal_organs) if(istype(G)) var/datum/sprite_accessory/S 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?.alt_aroused) G.aroused_state = isPercentAroused(G.aroused_amount) if(getArousal() >= ((max_arousal / 100) * 33)) G.aroused_state = TRUE else G.aroused_state = FALSE G.update_appearance() /mob/living/proc/update_arousal_hud() return FALSE /datum/species/proc/update_arousal_hud(mob/living/carbon/human/H) return FALSE /mob/living/carbon/human/update_arousal_hud() if(!client || !hud_used) return FALSE if(dna.species.update_arousal_hud()) return FALSE if(!canbearoused) hud_used.arousal.icon_state = "" return FALSE else if(hud_used.arousal) if(stat == DEAD) hud_used.arousal.icon_state = "arousal0" return TRUE if(getArousal() == max_arousal) hud_used.arousal.icon_state = "arousal100" return TRUE if(getArousal() >= (max_arousal / 100) * 90)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal90" return TRUE if(getArousal() >= (max_arousal / 100) * 80)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal80" return TRUE if(getArousal() >= (max_arousal / 100) * 70)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal70" return TRUE if(getArousal() >= (max_arousal / 100) * 60)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal60" return TRUE if(getArousal() >= (max_arousal / 100) * 50)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal50" return TRUE if(getArousal() >= (max_arousal / 100) * 40)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal40" return TRUE if(getArousal() >= (max_arousal / 100) * 30)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal30" return TRUE if(getArousal() >= (max_arousal / 100) * 20)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal10" return TRUE if(getArousal() >= (max_arousal / 100) * 10)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal10" return TRUE else hud_used.arousal.icon_state = "arousal0" //GS13 Port - Arousal menu /atom/movable/screen/arousal name = "arousal" icon_state = "arousal0" icon = 'icons/obj/genitals/hud.dmi' screen_loc = ui_arousal /atom/movable/screen/arousal/Click() if(!isliving(usr)) return FALSE if(isobserver(usr)) return var/mob/living/M = usr if(M.canbearoused) ui_interact(usr) /mob/living/carbon/human/proc/adjust_arousal(strength, cause = "manual toggle", aphro = FALSE,maso = FALSE) // returns all genitals that were adjust var/list/obj/item/organ/genital/genit_list = list() if(!client?.prefs.arousable || (aphro && (client?.prefs.cit_toggles & NO_APHRO)) || (maso && !HAS_TRAIT(src, TRAIT_MASO))) return // no adjusting made here var/enabling = strength > 0 for(var/obj/item/organ/genital/G in internal_organs) if(G.genital_flags & GENITAL_CAN_AROUSE && !G.aroused_state && prob(abs(strength)*G.sensitivity * arousal_rate)) G.set_aroused_state(enabling,cause) G.update_appearance() if(G.aroused_state) genit_list += G return genit_list /obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found. if((genital_flags & GENITAL_FUID_PRODUCTION)) . = reagents else if(linked_organ) . = linked_organ.reagents if(!. && !silent) to_chat(H, "Your [name] is unable to produce it's own fluids, it's missing the organs for it.") //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, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.") return fluid_source = G.linked_organ.reagents total_fluids = fluid_source.total_volume if(mb_time) src.visible_message("[src] starts to [G.masturbation_verb] [p_their()] [G.name].", \ "You start to [G.masturbation_verb] your [G.name].", \ "You start to [G.masturbation_verb] your [G.name].") 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("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \ "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].", \ "You have relieved yourself.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousal(min_arousal) /mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30, spillage = TRUE) //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("[src] shudders, their [G.name] unable to cum.", \ "Your [G.name] cannot cum, giving no relief.", \ "Your [G.name] cannot cum, giving no relief.") else total_fluids = fluid_source.total_volume if(mb_time) //as long as it's not instant, give a warning src.visible_message("[src] looks like they're about to cum.", \ "You feel yourself about to orgasm.", \ "You feel yourself about to orgasm.") if(do_after(src, mb_time, target = src)) if(spillage) if(total_fluids > 5) fluid_source.reaction(src.loc, TOUCH, 1, 0) fluid_source.clear_reagents() src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], with [p_their()] [G.name]!", \ "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].", \ "You climax using your [G.name].") else //Else from spillage check, also note subtle text change src.visible_message("[src] orgasms with [p_their()] [G.name]!", \ "You climax with your [G.name].", \ "You climax using your [G.name].") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousal(min_arousal) /mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, impreg = FALSE,cover = FALSE,remote = FALSE, 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, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.") return fluid_source = G.linked_organ.reagents total_fluids = fluid_source.total_volume if(mb_time && !remote) //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]!", \ "You're preparing to climax with something!") if(remote) src.visible_message("[src] is about to climax with someone!", \ "You're about to climax with someone!", \ "You're preparing to climax with something!") if(cover)//covering the partner in cum, this overrides other options. 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 > 80) // now thats a big cum! if(isliving(L)) var/mutable_appearance/cumoverlaylarge = mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi') cumoverlaylarge.icon_state = "cum_large" L.add_overlay(cumoverlaylarge) if(total_fluids > 5) fluid_source.reaction(L.loc, TOUCH, 1, 0) var/mob/living/carbon/human/H = L if(H) H.cumdrip_rate += rand(5,10) fluid_source.clear_reagents() src.visible_message("[src] climaxes over [L], using [p_their()] [G.name]!", \ "You orgasm over [L], using your [G.name].", \ "You have climaxed over something, using your [G.name].") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(isliving(L)) var/mutable_appearance/cumoverlay = mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi') cumoverlay.icon_state = "cum_normal" L.add_overlay(cumoverlay) else L.add_cum_overlay() setArousal(min_arousal) if(G.can_climax) setArousal(min_arousal) if(spillage && !cover) if(do_after(src, mb_time, target = src)) if(!in_range(src, L) && !remote) return 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) var/mob/living/carbon/human/H = L if(H) H.cumdrip_rate += rand(5,10) fluid_source.clear_reagents() src.visible_message("[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!", \ "You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].", \ "You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousal(min_arousal) else //knots, portal fleshlights, and other non-spilling orgasms if(!cover) if(!remote && !in_range(src, L)) return if(do_after(src, mb_time, target = src)) if(!spillage) //hyper inflation var/obj/item/organ/genital/belly/B = L.getorganslot("belly") if(B) if(B.inflatable && total_fluids > 80) //requires a big cumshot to expand. if(B.size < 3) B.size += 1 to_chat(L, "You feel your belly expand.") else to_chat(L, "You feel your belly strain.") fluid_source.trans_to(L, total_fluids) total_fluids = 0 if(!remote) src.visible_message("[src] climaxes with [L], [p_their()] [G.name] spilling nothing!", \ "You ejaculate with [L], your [G.name] spilling nothing.", \ "You have climaxed inside someone, your [G.name] spilling nothing.") else src.visible_message("[src] climaxes with someone, using [p_their()] [G.name]!", \ "You ejaculate with someone, using your [G.name].", \ "You have climaxed inside someone, using your [G.name].") to_chat(L, "You feel someone ejaculate inside you.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousal(min_arousal) //Hyper - antag code /*if(src.mind.special_role == ROLE_LEWD_TRAITOR) for(var/datum/objective/obj in src.mind.objectives) if (L.mind == obj.target) L.mind.sexed = TRUE //sexed to_chat(src, "You feel deep satisfaction with yourself.") */ //Hyper - impreg // if(impreg) // //Role them odds, only people with the dicks can send the chance to the person with the settings enabled at the momment. // if(prob(L.impregchance)) // var/obj/item/organ/genital/womb/W = L.getorganslot("womb") // if(W) //check if they have a womb. // if (L.breedable == 1 && W.pregnant == 0) //Dont get pregnant again, if you are pregnant. // log_game("Debug: [L] has been impregnated by [src]") // to_chat(L, "You feel your hormones change, and a motherly instinct take over.") //leting them know magic has happened. // W.pregnant = 1 // if (HAS_TRAIT(L, TRAIT_HEAT)) // SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "heat", /datum/mood_event/heat) //well done you perv. // REMOVE_TRAIT(L, TRAIT_HEAT, ROUNDSTART_TRAIT) //take the heat away, you satisfied it! // //Make breasts produce quicker. // var/obj/item/organ/genital/breasts/B = L.getorganslot("breasts") // if (B.fluid_mult < 0.5 && B) // B.fluid_mult = 0.5 /mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/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, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.") return fluid_source = G.linked_organ.reagents total_fluids = fluid_source.total_volume if(!container) //Something weird happened to_chat(src, "You need a container to do this!") return src.visible_message("[src] starts to [G.masturbation_verb] their [G.name] over [container].", \ "You start to [G.masturbation_verb] your [G.name] over [container].", \ "You start to [G.masturbation_verb] your [G.name] over something.") if(do_after(src, mb_time, target = src) && in_range(src, container)) fluid_source.trans_to(container, total_fluids) src.visible_message("[src] uses [p_their()] [G.name] to fill [container]!", \ "You used your [G.name] and fill [container] with a total of [total_fluids]u's.", \ "You have relieved some pressure.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) container.add_cum_overlay() //your aim is bad... if(G.can_climax) setArousal(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.genital_flags & CAN_MASTURBATE_WITH) //filter out what you can't masturbate with if(G.is_exposed(worn_stuff)) //Nude or through_clothing if(!G.dontlist) 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/target_genitals(mob/living/carbon/human/T) //used for targeting others 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 T.internal_organs) if(G.is_exposed(worn_stuff)) //Nude or through_clothing if(!G.dontlist) genitals_list += G if(genitals_list.len) ret_organ = input(src, "", "Genitals", 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 if(!G.dontlist) 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_overide() //used for cumming on people without genitals exposed 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)) 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_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/reagent_containers/SC = null var/list/containers_list = list() for(var/obj/item/reagent_containers/container in held_items) if(container.is_open_container() || istype(container, /obj/item/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, cause = "none") //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, "You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!") return mb_cd_timer = (world.time + mb_cd_length) if(canbearoused && has_dna()) if(stat==2) to_chat(src, "You can't do that while dead!") 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/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(stat==1) //No sleep-masturbation, you're unconscious. to_chat(src, "You must be conscious to do that!") return if(getArousal() < 33) //flat number instead of percentage to_chat(src, "You aren't aroused enough for that!") return //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","Climax over partner", "Fill container") switch(choice) if("Masturbate") if(restrained(TRUE)) //TRUE ignores grabs to_chat(src, "You can't do that while restrained!") return var/free_hands = get_num_arms() if(!free_hands) to_chat(src, "You need at least one free arm.") return for(var/helditem in held_items)//how many hands are free if(isobj(helditem)) free_hands-- if(free_hands <= 0) to_chat(src, "You're holding too many things.") 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, "You cannot masturbate without choosing genitals.") return if("Climax alone") if(restrained(TRUE)) //TRUE ignores grabs to_chat(src, "You can't do that while restrained!") return var/free_hands = get_num_arms() if(!free_hands) to_chat(src, "You need at least one free arm.") return for(var/helditem in held_items)//how many hands are free if(isobj(helditem)) free_hands-- if(free_hands <= 0) to_chat(src, "You're holding too many things.") 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, "You cannot climax without choosing genitals.") return 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) /*GS13 Port - De we need breeding? For now disable it for inital porting var/obj/item/organ/genital/penis/P = picked_organ if(partner.breedable == 1 && picked_organ.name == "penis") var/impreg = input(src, "Would this action carry the risk of pregnancy?", "Choose a option", "Yes") as anything in list("Yes", "No") if(impreg == "Yes") //If we are impregging 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, TRUE, FALSE) else mob_climax_partner(picked_organ, partner, FALSE, TRUE, FALSE) else 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, FALSE, FALSE) else mob_climax_partner(picked_organ, partner, FALSE, FALSE, FALSE) //Wow, im trash at coding, I need to find a better way of coding this, ill rewrite it later.-quote return else //If we arent impregging 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, FALSE, FALSE) else mob_climax_partner(picked_organ, partner, FALSE, FALSE, FALSE) return */ 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, FALSE, FALSE) else mob_climax_partner(picked_organ, partner, FALSE, FALSE, FALSE) return else to_chat(src, "You cannot do this alone.") return else //They either lack organs that can masturbate, or they didn't pick one. to_chat(src, "You cannot climax without choosing genitals.") return if("Climax over partner") var/obj/item/organ/genital/picked_organ picked_organ = pick_climax_genitals() if(picked_organ) var/mob/living/partner = pick_partner_overide() //Get your partner, clothed or not. if(partner) mob_climax_partner(picked_organ, partner, FALSE, FALSE, TRUE) else to_chat(src, "You cannot do this alone.") if("Fill container") //We'll need hands and no restraints. if(restrained(TRUE)) //TRUE ignores grabs to_chat(src, "You can't do that while restrained!") return var/free_hands = get_num_arms() if(!free_hands) to_chat(src, "You need at least one free arm.") return for(var/helditem in held_items)//how many hands are free if(isobj(helditem)) free_hands-- if(free_hands <= 0) to_chat(src, "You're holding too many things.") 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/reagent_containers/fluid_container = pick_climax_container() if(fluid_container) mob_fill_container(picked_organ, fluid_container) return else to_chat(src, "You cannot do this without anything to fill.") return else //They either lack organs that can climax, or they didn't pick one. to_chat(src, "You cannot fill anything without choosing genitals.") return else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled return //Just end it in that case.