From f753617a0b374bfefa8fa613047b4e8f8236117a Mon Sep 17 00:00:00 2001 From: SandPoot <43283559+SandPoot@users.noreply.github.com> Date: Wed, 3 Nov 2021 13:59:02 -0300 Subject: [PATCH] Updates some lewd stuff (#189) --- code/modules/arousal/arousal.dm | 32 ++++++ .../code/datums/interactions/lewd/_lewd.dm | 100 ++++++++---------- .../datums/interactions/lewd/_lewd_extra.dm | 18 +++- .../datums/interactions/lewd/lewd_datums.dm | 5 +- .../interactions/lewd/lewd_datums_extra.dm | 22 +++- .../interactions/lewd/lewd_interactions.dm | 19 ++-- .../datums/interactions/lewd/lewd_species.dm | 11 ++ .../code/game/objects/items/fleshlight.dm | 53 ++++++++-- 8 files changed, 183 insertions(+), 77 deletions(-) diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm index 4563619f5b..07ff32a0e9 100644 --- a/code/modules/arousal/arousal.dm +++ b/code/modules/arousal/arousal.dm @@ -222,6 +222,38 @@ for(var/obj/item/organ/genital/G in internal_organs) if(!CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH)) //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(pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick + if(isliving(pulling)) //Don't fuck objects + check_target = pulling + if(pulledby && !check_target) //prioritise pulled over pulledby + if(isliving(pulledby)) + check_target = 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 + //skyrat edit + if(forced_partner) + if((forced_partner == "none") || (!istype(forced_partner))) + partner = null + else + partner = forced_partner + // + if(partner) //Did they pass the clothing checks? + //skyrat edit + mob_climax_partner(G, partner, spillage = forced_spillage, 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 diff --git a/modular_sand/code/datums/interactions/lewd/_lewd.dm b/modular_sand/code/datums/interactions/lewd/_lewd.dm index 037f0e00d7..321e6e7527 100644 --- a/modular_sand/code/datums/interactions/lewd/_lewd.dm +++ b/modular_sand/code/datums/interactions/lewd/_lewd.dm @@ -5,6 +5,7 @@ #define CUM_TARGET_HAND "hand" #define CUM_TARGET_BREASTS "breasts" #define CUM_TARGET_FEET "feet" +#define CUM_TARGET_PENIS "penis" //Weird defines go here #define CUM_TARGET_EARS "ears" #define CUM_TARGET_EYES "eyes" @@ -97,7 +98,7 @@ return dif /mob/living/proc/add_lust(add) - var/cur = src.get_lust() //GetLust handles per-time lust loss + var/cur = get_lust() //GetLust handles per-time lust loss if((cur + add) < 0) //in case we retract lust lust = 0 else @@ -121,7 +122,7 @@ /mob/living/proc/has_penis(var/nintendo = REQUIRE_ANY) var/mob/living/carbon/C = src - if(has_penis) + if(has_penis && !istype(C)) return TRUE if(istype(C)) var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_PENIS) @@ -167,7 +168,7 @@ /mob/living/proc/has_vagina(var/nintendo = REQUIRE_ANY) var/mob/living/carbon/C = src - if(has_vagina) + if(has_vagina && !istype(C)) return TRUE if(istype(C)) var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_VAGINA) @@ -191,7 +192,7 @@ /mob/living/proc/has_breasts(var/nintendo = REQUIRE_ANY) var/mob/living/carbon/C = src - if(has_breasts) + if(has_breasts && !istype(C)) return TRUE if(istype(C)) var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_BREASTS) @@ -214,7 +215,7 @@ return FALSE /mob/living/proc/has_anus(var/nintendo = REQUIRE_ANY) - if(has_anus) + if(has_anus && !iscarbon(src)) return TRUE switch(nintendo) if(REQUIRE_ANY) @@ -485,7 +486,7 @@ if(partner.has_mouth() && partner.mouth_is_free()) message = "vigorously ruts their nutsack into \the [partner]'s mouth before shooting their thick, sticky jizz all over their eyes and hair." if(THIGH_SMOTHERING) - if(src.has_penis(REQUIRE_EXPOSED)) //it already checks for the cock before, why the hell would you do this redundant shit + if(has_penis(REQUIRE_EXPOSED)) //it already checks for the cock before, why the hell would you do this redundant shit message = "keeps \the [partner] locked in their thighs as their cock throbs, dumping its heavy load all over their face." else message = "reaches their peak, locking their legs around \the [partner]'s head extra hard as they cum straight onto the head stuck between their thighs" @@ -515,7 +516,11 @@ message = "cums inside \the [partner]'s eyesocket." cumin = TRUE // - + if(CUM_TARGET_PENIS) + if(partner.has_penis(REQUIRE_EXPOSED)) + message = "cums on \the [partner]." + else + message = "cums on the floor!" else message = "cums on the floor!" else if(has_vagina()) @@ -588,7 +593,11 @@ message = "squirts on \the [partner]'s eyesocket." cumin = TRUE // - + if(CUM_TARGET_PENIS) + if(partner.has_penis(REQUIRE_EXPOSED)) + message = "squirts on \the [partner]'s penis" + else + message = "squirts on the floor!" else message = "squirts on the floor!" @@ -639,7 +648,7 @@ if(partner.has_mouth() && partner.mouth_is_free()) message = "vigorously ruts their nutsack into \the [partner]'s mouth before shooting their thick, sticky jizz all over their eyes and hair." if(THIGH_SMOTHERING) - if(src.has_penis()) //it already checks for the cock before, why the hell would you do this redundant shit + if(has_penis()) //it already checks for the cock before, why the hell would you do this redundant shit message = "keeps \the [partner] locked in their thighs as their cock throbs, dumping its heavy load all over their face." else message = "reaches their peak, locking their legs around \the [partner]'s head extra hard as they cum straight onto the head stuck between their thighs" @@ -669,6 +678,11 @@ message = "cums inside \the [partner]'s eyesocket." cumin = TRUE // + if(CUM_TARGET_PENIS) + if(partner.has_penis(REQUIRE_EXPOSED)) + message = "cums on \the [partner]." + else + message = "cums on the floor!" else message = "cums on the floor!" if(/obj/item/organ/genital/vagina) @@ -742,6 +756,11 @@ message = "squirts on \the [partner]'s eyesocket." cumin = TRUE // + if(CUM_TARGET_PENIS) + if(partner.has_penis(REQUIRE_EXPOSED)) + message = "squirts on \the [partner]'s penis" + else + message = "squirts on the floor!" else message = "squirts on the floor!" else @@ -767,17 +786,17 @@ if(multiorgasms > (sexual_potency * 0.34)) //AAAAA, WE DONT WANT NEGATIVES HERE, RE refractory_period = world.time + rand(300, 900) - sexual_potency//sex cooldown - src.set_drugginess(rand(20, 30)) + set_drugginess(rand(20, 30)) else refractory_period = world.time + rand(300, 900) - sexual_potency - src.set_drugginess(rand(5, 10)) + set_drugginess(rand(5, 10)) if(multiorgasms < sexual_potency) if(ishuman(src)) var/mob/living/carbon/human/H = src if(!partner) - H.mob_climax(TRUE, "none") + H.mob_climax(TRUE, "masturbation", "none") else - H.mob_climax(TRUE, partner, !cumin) + H.mob_climax(TRUE, "sex", partner, !cumin) set_lust(0) /mob/living/proc/is_fucking(mob/living/partner, orifice) @@ -906,7 +925,6 @@ 'modular_sand/sound/interactions/bj11.ogg'), 50, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(lust_increase, CUM_TARGET_MOUTH, src) - partner.dir = get_dir(partner,src) lust_increase = NORMAL_LUST //RESET IT REE /mob/living/proc/do_facefuck(mob/living/partner, var/fucktarget = "penis") @@ -928,7 +946,7 @@ "sways their hips, pushing their sex into \the [partner]'s face.", ) if(partner.a_intent == INTENT_HARM) - // src.adjustBruteLoss(5) + // adjustBruteLoss(5) retaliation_message = pick( "looks deeply displeased to be there.", "struggles to escape from between \the [src]'s thighs.", @@ -946,7 +964,7 @@ "rolls their hips hard, sinking into \the [partner]'s mouth.", ) if(partner.a_intent == INTENT_HARM) - // src.adjustBruteLoss(5) + // adjustBruteLoss(5) retaliation_message = pick( "stares up from between \the [src]'s knees, trying to squirm away.", "struggles to escape from between \the [src]'s legs.", @@ -963,7 +981,7 @@ "rolls their hips hard against \the [partner]'s face.", ) if(partner.a_intent == INTENT_HARM) - // src.adjustBruteLoss(5) + // adjustBruteLoss(5) retaliation_message = pick( "stares up from between \the [src]'s knees, trying to squirm away.", "struggles to escape from between \the [src]'s legs.", @@ -1002,7 +1020,6 @@ if(retaliation_message) visible_message(message = "\The [partner] [retaliation_message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/thigh_smother(mob/living/partner, var/fucktarget = "penis") var/message @@ -1064,11 +1081,9 @@ playlewdinteractionsound(loc, file, 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(lust_increase, THIGH_SMOTHERING, partner) - partner.dir = get_dir(partner,src) playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/oral1.ogg', 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1) handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_throatfuck(mob/living/partner) var/message @@ -1086,7 +1101,7 @@ var/mob/living/H = partner H.adjustOxyLoss(5) if(partner.a_intent == INTENT_HARM) - // src.adjustBruteLoss(5) + // adjustBruteLoss(5) retaliation_message = pick( "stares up from between \the [src]'s knees, trying to squirm away.", "struggles to escape from between \the [src]'s legs.", @@ -1110,7 +1125,6 @@ if(retaliation_message) visible_message(message = "\The [partner] [retaliation_message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_THROAT, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/nut_face(var/mob/living/partner) @@ -1134,7 +1148,6 @@ 'modular_sand/sound/interactions/nuts4.ogg'), 70, 1, -1)*/ //These files don't even exist but nobody noticed because double-quotes were used instead of single. visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(lust_increase, CUM_TARGET_MOUTH, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_anal(mob/living/partner) var/message @@ -1158,7 +1171,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, partner) partner.handle_post_sex(NORMAL_LUST, null, src) - partner.dir = get_dir(src, partner) /mob/living/proc/do_vaginal(mob/living/partner) var/message @@ -1178,7 +1190,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, partner) partner.handle_post_sex(NORMAL_LUST, null, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_mount(mob/living/partner) var/message @@ -1195,7 +1206,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, src) handle_post_sex(NORMAL_LUST, null, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_mountass(mob/living/partner) var/message @@ -1212,7 +1222,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, src) handle_post_sex(NORMAL_LUST, null, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_tribadism(mob/living/partner) var/message @@ -1231,7 +1240,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, src) handle_post_sex(NORMAL_LUST, null, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_fingering(mob/living/partner) visible_message(message = "\The [src] [pick("fingers \the [partner].", @@ -1239,7 +1247,6 @@ "fingers \the [partner] hard.")]", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) partner.handle_post_sex(NORMAL_LUST, null, src) - partner.dir = get_dir(partner, src) /mob/living/proc/do_fingerass(mob/living/partner) visible_message(message = "\The [src] [pick("fingers \the [partner].", @@ -1247,13 +1254,11 @@ "fingers \the [partner] hard.")]", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) partner.handle_post_sex(NORMAL_LUST, null, src) - partner.dir = get_dir(partner, src) /mob/living/proc/do_rimjob(mob/living/partner) visible_message(message = "\The [src] licks \the [partner]'s asshole.", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) partner.handle_post_sex(NORMAL_LUST, null, src) - partner.dir = get_dir(src, partner) /mob/living/proc/do_handjob(mob/living/partner) var/message @@ -1272,7 +1277,6 @@ 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_breastfuck(mob/living/partner) var/message @@ -1292,7 +1296,6 @@ 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_BREASTS, partner) - partner.dir = get_dir(partner,src) /mob/living/proc/do_mountface(mob/living/partner) var/message @@ -1311,7 +1314,6 @@ 'modular_sand/sound/interactions/squelch3.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(src, partner) /mob/living/proc/do_lickfeet(mob/living/partner) var/message @@ -1324,14 +1326,13 @@ playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(src, partner) /*Grinding YOUR feet in TARGET's face*/ /mob/living/proc/do_grindface(mob/living/partner) var/message if(is_fucking(partner, GRINDING_FACE_WITH_FEET)) - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("grinds their [get_shoes()] into [partner]'s face.", "presses their footwear down hard on [partner]'s face.", "rubs off the dirt from their [get_shoes()] onto [partner]'s face."))]" @@ -1341,7 +1342,7 @@ "runs the soles of their bare feet against [partner]'s lips."))]" else if(is_fucking(partner, GRINDING_MOUTH_WITH_FEET)) - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("pulls their [get_shoes()] out of [partner]'s mouth and puts them on their face.", "slowly retracts their [get_shoes()] from [partner]'s mouth, putting them on their face instead."))]" else @@ -1351,7 +1352,7 @@ set_is_fucking(partner , GRINDING_FACE_WITH_FEET, null) else - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("plants their [get_shoes()] ontop of [partner]'s face.", "rests their [get_shoes()] on [partner]'s face and presses down hard.", "harshly places their [get_shoes()] atop [partner]'s face."))]" @@ -1368,14 +1369,13 @@ 'modular_sand/sound/interactions/foot_dry4.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(src, partner) /*Grinding YOUR feet in TARGET's mouth*/ /mob/living/proc/do_grindmouth(mob/living/partner) var/message if(is_fucking(partner, GRINDING_MOUTH_WITH_FEET)) - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("roughly shoves their [get_shoes()] deeper into [partner]'s mouth.", "harshly forces another inch of their [get_shoes()] into [partner]'s mouth.", "presses their weight down, their [get_shoes()] prying deeper into [partner]'s mouth."))]" @@ -1385,7 +1385,7 @@ "roughly grinds their feet on [partner]'s tongue."))]" else if(is_fucking(partner, GRINDING_FACE_WITH_FEET)) - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("decides to force their [get_shoes()] deep into [partner]'s mouth.", "pressed the tip of their [get_shoes()] against [partner]'s lips and shoves inwards."))]" else @@ -1395,7 +1395,7 @@ set_is_fucking(partner , GRINDING_MOUTH_WITH_FEET, null) else - if(src.get_item_by_slot(SLOT_SHOES) != null) + if(get_item_by_slot(SLOT_SHOES) != null) message = "[pick(list("readies themselves and in one swift motion, shoves their [get_shoes()] into [partner]'s mouth.", "grinds the tip of their [get_shoes()] against [partner]'s mouth before pushing themselves in."))]" else @@ -1409,7 +1409,6 @@ 'modular_sand/sound/interactions/foot_wet3.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(src, partner) /mob/living/proc/do_footfuck(mob/living/partner) var/message @@ -1430,7 +1429,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_dfootfuck(mob/living/partner) var/message @@ -1451,7 +1449,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_vfootfuck(mob/living/partner) var/message @@ -1472,7 +1469,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_footjob(mob/living/partner) var/message @@ -1492,7 +1488,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_dfootjob(mob/living/partner) var/message @@ -1513,7 +1508,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_footjob_v(mob/living/partner) var/message @@ -1534,7 +1528,6 @@ 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1) visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src) - partner.dir = get_dir(partner,src) /mob/living/proc/get_shoes(var/singular = FALSE) var/obj/A = get_item_by_slot(SLOT_SHOES) @@ -1550,20 +1543,23 @@ txt = copytext(A.name, 1, length(A.name)) return txt +/// Handles the sex, if cumming returns true. /mob/living/proc/handle_post_sex(amount, orifice, mob/living/partner) if(stat != CONSCIOUS) - return + return FALSE if(amount) add_lust(amount) if(get_lust() >= lust_tolerance) if(prob(10)) to_chat(src, "You struggle to not orgasm!") - return + return FALSE if(lust >= lust_tolerance*3) cum(partner, orifice) + return TRUE else moan() + return FALSE /mob/living/proc/get_unconsenting(var/extreme = FALSE, var/list/ignored_mobs) var/list/nope = list() @@ -1607,7 +1603,6 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting(TRUE)) handle_post_sex(NORMAL_LUST, CUM_TARGET_EYES, partner) partner.handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(partner,src) /mob/living/proc/do_earfuck(mob/living/partner) var/message @@ -1636,4 +1631,3 @@ visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting(TRUE)) handle_post_sex(NORMAL_LUST, CUM_TARGET_EARS, partner) partner.handle_post_sex(LOW_LUST, null, src) - partner.dir = get_dir(partner,src) diff --git a/modular_sand/code/datums/interactions/lewd/_lewd_extra.dm b/modular_sand/code/datums/interactions/lewd/_lewd_extra.dm index 2c4d542a87..efa7682587 100644 --- a/modular_sand/code/datums/interactions/lewd/_lewd_extra.dm +++ b/modular_sand/code/datums/interactions/lewd/_lewd_extra.dm @@ -1,3 +1,13 @@ +/mob/living/proc/do_frot(mob/living/target) + var/message + var/t_His = p_their() + + message = "rubs [t_His] penis against [target]'s." + set_is_fucking(target, CUM_TARGET_PENIS, getorganslot(ORGAN_SLOT_PENIS)) + visible_message("\The [src] [message]", ignored_mobs = get_unconsenting()) + handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, target) + target.handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, src) + /mob/living/proc/do_jackoff(mob/living/user) var/message var/t_His = p_their() @@ -17,7 +27,7 @@ playlewdinteractionsound(src, pick('modular_sand/sound/interactions/bang1.ogg', 'modular_sand/sound/interactions/bang2.ogg', 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1) - visible_message(message = "\The [src] [message]") //can't not consent to yourself, if you did it, you wanted it + visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src) /mob/living/proc/do_fingerass_self(mob/living/user) @@ -26,7 +36,7 @@ visible_message(message = "\The [src] [pick("fingers [t_Him]self.", "fingers [t_His] asshole.", - "fingers [t_Him]self hard.")]") //can't not consent to yourself, if you did it, you wanted it + "fingers [t_Him]self hard.")]", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src) @@ -36,7 +46,7 @@ visible_message(message = "\The [src] [pick("fingers [t_His] pussy deep.", "fingers [t_His] pussy.", "plays with [t_His] pussy.", - "fingers [t_His] own pussy hard.")]") //can't not consent to yourself, if you did it, you wanted it + "fingers [t_His] own pussy hard.")]", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src) @@ -64,6 +74,6 @@ "gasps.", "shudders softly.", "trembles as [t_His] hands run across bare skin.")]") - visible_message(message = "\The [src] [message]") //can't not consent to yourself, if you did it, you wanted it + visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting()) playlewdinteractionsound(loc, 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1) user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src) diff --git a/modular_sand/code/datums/interactions/lewd/lewd_datums.dm b/modular_sand/code/datums/interactions/lewd/lewd_datums.dm index 9ed09dcff2..ffb40048fd 100644 --- a/modular_sand/code/datums/interactions/lewd/lewd_datums.dm +++ b/modular_sand/code/datums/interactions/lewd/lewd_datums.dm @@ -39,6 +39,7 @@ /datum/interaction/lewd/titgrope command = "titgrope" description = "Grope their breasts." + require_user_hands = TRUE require_target_breasts = REQUIRE_ANY write_log_user = "groped" write_log_target = "was groped by" @@ -299,7 +300,7 @@ /datum/interaction/lewd/finger command = "finger" description = "Finger their pussy." - require_user_hands = REQUIRE_ANY + require_user_hands = TRUE require_target_vagina = REQUIRE_EXPOSED interaction_sound = null user_not_tired = TRUE @@ -312,7 +313,7 @@ command = "fingerm" description = "Finger their ass." interaction_sound = null - require_user_hands = REQUIRE_ANY + require_user_hands = TRUE require_target_anus = REQUIRE_EXPOSED user_not_tired = TRUE max_distance = 1 diff --git a/modular_sand/code/datums/interactions/lewd/lewd_datums_extra.dm b/modular_sand/code/datums/interactions/lewd/lewd_datums_extra.dm index da55b95240..3704bc1a68 100644 --- a/modular_sand/code/datums/interactions/lewd/lewd_datums_extra.dm +++ b/modular_sand/code/datums/interactions/lewd/lewd_datums_extra.dm @@ -1,8 +1,23 @@ +/datum/interaction/lewd/frotting + command = "frotting" + description = "Rub your penis against theirs" + require_user_penis = REQUIRE_EXPOSED + require_target_penis = REQUIRE_EXPOSED + user_not_tired = TRUE + max_distance = 1 + +/datum/interaction/lewd/frotting/display_interaction(mob/living/user, mob/living/target) + user.do_frot(target) + +/** + * Self Interactions! + */ + /datum/interaction/lewd/jack command = "jack" description = "Jerk yourself off." interaction_sound = null - require_user_hands = REQUIRE_ANY + require_user_hands = TRUE require_user_penis = REQUIRE_EXPOSED user_not_tired = TRUE user_is_target = TRUE @@ -15,7 +30,7 @@ command = "fingerm_self" description = "Finger yourself." interaction_sound = null - require_user_hands = REQUIRE_ANY + require_user_hands = TRUE require_user_anus = REQUIRE_EXPOSED user_not_tired = TRUE user_is_target = TRUE @@ -27,7 +42,7 @@ /datum/interaction/lewd/finger_self command = "finger_self" description = "Finger your own pussy." - require_user_hands = REQUIRE_ANY + require_user_hands = TRUE require_user_vagina = REQUIRE_EXPOSED interaction_sound = null user_not_tired = TRUE @@ -40,6 +55,7 @@ /datum/interaction/lewd/titgrope_self command = "titgrope_self" description = "Grope your own breasts." + require_user_hands = TRUE require_user_breasts = REQUIRE_ANY user_is_target = TRUE interaction_sound = null diff --git a/modular_sand/code/datums/interactions/lewd/lewd_interactions.dm b/modular_sand/code/datums/interactions/lewd/lewd_interactions.dm index f359a05d4d..ad0f79b4d0 100644 --- a/modular_sand/code/datums/interactions/lewd/lewd_interactions.dm +++ b/modular_sand/code/datums/interactions/lewd/lewd_interactions.dm @@ -523,14 +523,15 @@ var/dat = ..() if(get_refraction_dif()) dat += "...are sexually exhausted for the time being." - if(a_intent == INTENT_HELP) - dat += "...are acting gentle." - else if (a_intent == INTENT_DISARM) - dat += "...are acting playful." - else if (a_intent == INTENT_GRAB) - dat += "...are acting rough." - else if(a_intent == INTENT_HARM) - dat += "...are fighting anyone who comes near." + switch(a_intent) + if(INTENT_HELP) + dat += "...are acting gentle." + if(INTENT_DISARM) + dat += "...are acting playful." + if(INTENT_GRAB) + dat += "...are acting rough." + if(INTENT_HARM) + dat += "...are fighting anyone who comes near." //Here comes the fucking weird shit. if(client) var/client/cli = client @@ -552,7 +553,7 @@ else dat += "...have covered eyes." // - if(is_topless() && is_bottomless()) + if(is_topless() && is_bottomless()) dat += "...are naked." else if((is_topless() && !is_bottomless()) || (!is_topless() && is_bottomless())) diff --git a/modular_sand/code/datums/interactions/lewd/lewd_species.dm b/modular_sand/code/datums/interactions/lewd/lewd_species.dm index 767b05ddba..bf8c9e55a9 100644 --- a/modular_sand/code/datums/interactions/lewd/lewd_species.dm +++ b/modular_sand/code/datums/interactions/lewd/lewd_species.dm @@ -1,3 +1,13 @@ +/** + * Seriously this is the worst way to do this, + * warn me if there's ANY reason i would ever + * use this. Humans have GENITALS, ACTUAL ORGANS, + * we don't need to check booleans! + * If this does not get an use sometime, + * i want this file gone. + */ + +/* /datum/species var/has_genitals = TRUE //if this goes to 2, blame coders var/has_anus = TRUE //same with this @@ -14,3 +24,4 @@ /datum/species/proc/has_breasts(mob/living/carbon/human/H) return has_breasts +*/ diff --git a/modular_sand/code/game/objects/items/fleshlight.dm b/modular_sand/code/game/objects/items/fleshlight.dm index 40e3d5023c..075579d7a4 100644 --- a/modular_sand/code/game/objects/items/fleshlight.dm +++ b/modular_sand/code/game/objects/items/fleshlight.dm @@ -74,7 +74,6 @@ */ /obj/item/portallight - name = "fleshlight" name = "portal fleshlight" desc = "A silver love(TM) fleshlight, used to stimulate someones penis, with bluespace tech that allows lovers to hump at a distance." icon = 'modular_sand/icons/obj/fleshlight.dmi' @@ -105,13 +104,15 @@ var/message = "" var/lust_amt = 0 var/arouse_only_target = FALSE + var/obj/item/organ/genital/penis/P + var/obj/item/organ/genital/vagina/V if(ishuman(M) && (M?.client?.prefs?.toggles & VERB_CONSENT) && useable) // I promise all those checks are worth it! switch(user.zone_selected) if(BODY_ZONE_PRECISE_GROIN) if(M.has_penis(REQUIRE_EXPOSED)) message = (user == M) ? pick("fucks into [src]") : pick("forces [M] to fuck into [src]") lust_amt = NORMAL_LUST - arouse_only_target = TRUE + P = M.getorganslot(ORGAN_SLOT_PENIS) if(BODY_ZONE_PRECISE_MOUTH) if(M.has_mouth() && !M.is_mouth_covered()) message = (user == M) ? pick("licks into [src]") : pick("forces [M] to lick into [src]") @@ -124,6 +125,7 @@ if(can_interact) message = (user == M) ? pick("touches softly against [src]") : pick("forces [M]'s finger on [src]") lust_amt = NORMAL_LUST + arouse_only_target = TRUE if(BODY_ZONE_L_ARM) if(M.has_hand(REQUIRE_ANY)) var/can_interact = FALSE @@ -132,14 +134,19 @@ if(can_interact) message = (user == M) ? pick("touches softly against [src]") : pick("forces [M]'s finger on [src]") lust_amt = NORMAL_LUST + arouse_only_target = TRUE if(!useable) to_chat(user, "It seems the device has failed or your partner is not wearing their device.") if(message) var/mob/living/carbon/human/portal_target = ishuman(portalunderwear.loc) && portalunderwear.current_equipped_slot == SLOT_W_UNDERWEAR ? portalunderwear.loc : null - if(portal_target && (portal_target?.client?.prefs.toggles & VERB_CONSENT)) + if(portalunderwear.targetting == "vagina") + V = portal_target.getorganslot(ORGAN_SLOT_VAGINA) + if(portal_target && (portal_target?.client?.prefs.toggles & VERB_CONSENT || !portal_target.ckey)) user.visible_message("[user] [message].") if(!arouse_only_target) - M.handle_post_sex(lust_amt, null, user) + if(M.handle_post_sex(lust_amt, null, null)) + if(P) + to_chat(portal_target, "You feel a [P.shape] penis of [P.length] inches go deep into your [portalunderwear.targetting] and cum!") switch(user.zone_selected) if(BODY_ZONE_PRECISE_GROIN) playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang4.ogg', @@ -156,8 +163,13 @@ if(M != user) message = replacetext(message, "[M]", "someone") message = replacetext(message, "[src]", "your [targeted]") - to_chat(portal_target, "You feel something on your panties, it [message].") - portal_target.handle_post_sex(lust_amt, null, M) + to_chat(portal_target, "You feel something on your panties, it [message][P ? ", it is a [P.shape] penis of [P.length] inches" : ""].") + if(portal_target.handle_post_sex(lust_amt, null, null)) + switch(portalunderwear.targetting) + if("vagina") + to_chat(M, "You feel the [V] squirt over your penis!") + if("anus") + to_chat(M, "You feel the anus constrict on your penis!") portal_target.do_jitter_animation() //make your partner shake too! else user.visible_message("\The [src] beeps and does not let [M] through.") @@ -208,6 +220,15 @@ else useable = FALSE +/obj/item/portallight/Destroy() + if(portalunderwear) + portalunderwear.portallight = null + if(isliving(portalunderwear.loc)) + portalunderwear.audible_message("[icon2html(portalunderwear, hearers(portalunderwear))] *beep* *beep* *beep*") + playsound(portalunderwear, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) + to_chat(portalunderwear.loc, "The panties beep as the link to the [src] is lost.") + . = ..() + /** * # Hyperstation 13 portal underwear * Wear it, cannot be worn if not pointing to the bits you have. @@ -277,11 +298,31 @@ update_portal() else update_portal() + RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/drop_out) /obj/item/clothing/underwear/briefs/panties/portalpanties/dropped(mob/user) + UnregisterSignal(user, COMSIG_PARENT_QDELETING) . = ..() update_portal() +/obj/item/clothing/underwear/briefs/panties/portalpanties/Destroy() + if(portallight) + var/obj/item/portallight/temp = portallight + moveToNullspace() // loc cannot be human so let's destroy ourselves out of anything + portallight.portalunderwear = null + temp.updatesleeve() + . = ..() + +/obj/item/clothing/underwear/briefs/panties/portalpanties/proc/drop_out() + var/mob/living/carbon/human/deleted + if(ishuman(loc)) + deleted = loc + forceMove(get_turf(loc)) + dropped(deleted) // Act like we've been dropped + plane = initial(plane) + layer = initial(layer) + update_portal() + /obj/item/clothing/underwear/briefs/panties/portalpanties/proc/update_portal() if(portallight) var/obj/item/portallight/P = portallight