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