diff --git a/code/__DEFINES/hyper_arousal.dm b/code/__DEFINES/hyper_arousal.dm index 438a97898..a0450b138 100644 --- a/code/__DEFINES/hyper_arousal.dm +++ b/code/__DEFINES/hyper_arousal.dm @@ -8,7 +8,6 @@ #define BUTT_MAX_SIZE_SELECTABLE 5 #define BUTT_MAX_SIZE 8 - #define GENITALS_HIDDEN "hidden" #define GENITALS_CLOTHES "clothes" #define GENITALS_VISIBLE "visible" diff --git a/hyperstation/code/obj/fleshlight.dm b/hyperstation/code/obj/fleshlight.dm index a7410a204..2bbd063db 100644 --- a/hyperstation/code/obj/fleshlight.dm +++ b/hyperstation/code/obj/fleshlight.dm @@ -94,7 +94,6 @@ var/paired = 0 var/obj/item/portalunderwear var/useable = FALSE - var/option = "" /obj/item/portallight/examine(mob/user) . = ..() @@ -104,103 +103,103 @@ . += "The device is paired, and awaiting input. " /obj/item/portallight/attack(mob/living/carbon/holder, mob/living/user) -//use portallight! nearly the same as the fleshlight apart from you have a buddy! - var/obj/item/organ/genital/penis/P = holder.getorganslot("penis") if(inuse) //just to stop stacking and causing people to cum instantly return - if(!useable) - to_chat(user, "It seems the device has failed or your partner is not wearing their device.") - if(holder == user)//if your using it on yourself, more options! otherwise, just fuck. - option = input(usr, "Choose action", "Portal Fleshlight", "Fuck") in list("Fuck", "Lick", "Touch") - else - option = "Fuck" - var/obj/item/organ/genital/target_genital - if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime error. - target_genital = portalunderwear.loc - if(!target_genital) + if(!UpdateUsability()) + to_chat(user, "\The [src] appears to be currently unusable.") return + var/option = "Fuck" + if(holder == user) + option = input(usr, "Choose action", "Portal Fleshlight", "Fuck") in list("Fuck", "Lick", "Touch") + var/obj/item/organ/genital/target_genital = portalunderwear.loc var/mob/living/carbon/human/target = target_genital.owner - if(option == "Fuck"&&!P.is_exposed()) //we are trying to fuck with no penis! + var/obj/item/organ/genital/penis/P = holder.getorganslot("penis") + if(option == "Fuck" && !P.is_exposed()) to_chat(user, "You don't see anywhere to use this on.") return - else //other options dont need checks - inuse = 1 - if(!(holder == user)) //if we are targeting someone else. - holder.visible_message("[user] is trying to use [src] on [holder]'s penis.", "[user] is trying to use [src] on your penis.") - if(!do_mob(user, holder, 3 SECONDS)) //3 second delay - inuse = 0 - return - //checked if not used on yourself, if not, carry on. - if(option == "Fuck") - playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound for fuck. - inuse = 0 - if(!(holder == user)) - holder.visible_message("[user] pumps [src] on [holder]'s penis.", "[user] pumps [src] up and down on your penis.") - else - if(option == "Fuck") - user.visible_message("[user] pumps [src] on their penis.", "You pump the fleshlight on your penis.") - if(option == "Lick") - user.visible_message("[user] licks into [src].", "You lick into [src].") - if(option == "Touch") - user.visible_message("[user] touches softly against [src].", "You touch softly on [src].") - if(prob(30)) //30% chance to make your partner moan. - target.emote("moan") - if(option == "Fuck")// normal fuck - to_chat(target, "You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [target_genital.name].")//message your partner, and kinky! - if(prob(30)) //30% chance to make them moan. + /* + WARMUP START - prevents spam/instant climax + */ + inuse = TRUE + if(holder != user) + holder.visible_message("[user] is trying to use [src] on [holder]'s penis.",\ + "[user] is trying to use [src] on your penis.") + if(!do_mob(user, holder, 3 SECONDS)) + inuse = FALSE + return + inuse = FALSE + /* + WARMUP END - proceed with the action + */ + switch(option) + if("Fuck") + playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) + if(holder == user) + user.visible_message("[user] pumps [src] on their penis.", + "You pump the fleshlight on your penis.") + else + holder.visible_message("[user] pumps [src] on [holder]'s penis.",\ + "[user] pumps [src] up and down on your penis.") + to_chat(target, "You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [target_genital.name].") + if(prob(30)) holder.emote("moan") - if(prob(30)) //30% chance to make your partner moan. - target.emote("moan") holder.adjustArousalLoss(20) target.adjustArousalLoss(20) - target.do_jitter_animation() //make your partner shake too! - // Why not have a probability to cum when someone's getting nailed with max arousal?~ - if (target.can_orgasm() && prob(5)) - // if vagina is not exposed, the climax will not cause a spill - target.mob_climax_outside(target_genital, target_genital.is_exposed()) - if (holder.can_orgasm()) + target.do_jitter_animation() + if(target.can_orgasm() && prob(5)) + target.mob_climax_outside(target_genital, spillage = target_genital.is_exposed()) + if(holder.can_orgasm()) var/mob/living/carbon/human/O = holder var/impreg_chance = target_genital.name == "vagina" && !P.condom && !P.sounding O.mob_climax_partner(P, target, FALSE, impreg_chance, FALSE, TRUE) - if(option == "Lick") + if("Lick") + user.visible_message("[user] licks into [src].",\ + "You lick into [src].") to_chat(target, "You feel a tongue lick you through the portal against your [target_genital.name].") target.adjustArousalLoss(10) - if(option == "Touch") + if("Touch") + user.visible_message("[user] touches softly against [src].",\ + "You touch softly on [src].") to_chat(target, "You feel someone touching your [target_genital.name] through the portal.") target.adjustArousalLoss(5) - return + if(prob(30)) + target.emote("moan") ..() /obj/item/portallight/proc/updatesleeve() //get their looks and vagina colour! - cut_overlays()//remove current overlays - var/obj/item/organ/genital/G - if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime. - G = portalunderwear.loc - if(!G) - useable = FALSE + cut_overlays() + if(!UpdateUsability()) return - var/mob/living/carbon/human/H = G.owner - if(H) //if the portal panties are on someone. - sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_normal") - if(H.dna.species.name == "Lizardperson") // lizard nerd - sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_lizard") - if(H.dna.species.name == "Slimeperson") // slime nerd - sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_slime") - if(H.dna.species.name == "Avian") // bird nerd - sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_avian") - sleeve.color = "#" + H.dna.features["mcolor"] - add_overlay(sleeve) - if(G.name == "vagina") - organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag") - organ.color = portalunderwear.loc.color - if(G.name == "anus") - organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus") - organ.color = "#" + H.dna.features["mcolor"] - useable = TRUE - add_overlay(organ) - else - useable = FALSE + var/obj/item/organ/genital/G = portalunderwear.loc + var/mob/living/carbon/human/H = G.owner // H is verified by UpdateUsability() + var/sleeve_species = "normal" + switch(H.dna.species.name) + if("Lizardperson") + sleeve_species = "lizard" + if("Slimeperson") + sleeve_species = "slime" + if("Avian") + sleeve_species = "avian" + sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_[sleeve_species]") + sleeve.color = "#" + H.dna.features["mcolor"] + add_overlay(sleeve) + if(G.name == "vagina") + organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag") + organ.color = portalunderwear.loc.color + if(G.name == "anus") + organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus") + organ.color = "#" + H.dna.features["mcolor"] + add_overlay(organ) + +/obj/item/portallight/proc/UpdateUsability() + var/useable = FALSE + if(portalunderwear && istype(portalunderwear.loc, /obj/item/organ/genital)) + var/obj/item/organ/genital/loc_genitals = portalunderwear.loc + if(loc_genitals.owner && ishuman(loc_genitals.owner)) + useable = TRUE + src.useable = useable + return useable //Hyperstation 13 portal underwear diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index e7f8b4f17..682edba75 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -285,7 +285,8 @@ setArousalLoss(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 +/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 @@ -736,21 +737,22 @@ continue // no wombs or testicles var/mob/living/carbon/partner var/check_target - if(current_genital.is_exposed()) - if(src.pulling) - if(iscarbon(src.pulling)) - check_target = src.pulling - else if(src.pulledby) - if(iscarbon(src.pulledby)) - check_target = src.pulledby - if(check_target) - var/mob/living/carbon/C = check_target - if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) - partner = C - if(partner) - user_human.mob_climax_partner(current_genital, partner, mb_time = 0) - continue - user_human.mob_climax_outside(current_genital, mb_time = 0) + if(!current_genital.is_exposed()) + user_human.mob_climax_outside(current_genital, mb_time = 0) + continue + if(src.pulling) + if(iscarbon(src.pulling)) + check_target = src.pulling + else if(src.pulledby) + if(iscarbon(src.pulledby)) + check_target = src.pulledby + if(check_target) + var/mob/living/carbon/C = check_target + if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) + partner = C + if(partner) + user_human.mob_climax_partner(current_genital, partner, mb_time = 0) + continue return