From 15d52e5b156fbdbf1ec6cfd2694efb4f2d42e0de Mon Sep 17 00:00:00 2001 From: SandPoot Date: Tue, 20 Jun 2023 15:39:24 -0300 Subject: [PATCH] update content --- code/modules/arousal/arousal.dm | 19 +- .../chemistry/reagents/drug_reagents.dm | 4 - .../chemistry/reagents/other_reagents.dm | 5 +- .../components/interaction_menu_granter.dm | 1 + .../code/datums/interactions/_interaction.dm | 3 + .../interaction_datums/lewd/self/breasts.dm | 73 +++- .../interaction_datums/lewd/self/finger.dm | 41 +- .../interaction_datums/lewd/self/jack.dm | 40 +- .../datums/interactions/lewd_definitions.dm | 388 ++++++++++-------- .../effects/decals/cleanable/lewd_decals.dm | 12 + modular_sand/code/modules/arousal/arousal.dm | 16 +- modular_sand/code/modules/arousal/creampie.dm | 11 - .../mob/living/carbon/human/human_defines.dm | 2 - .../modules/mob/living/carbon/human/life.dm | 6 - .../chemistry/reagents/drug_reagents.dm | 13 + .../chemistry/reagents/other_reagents.dm | 11 + tgstation.dme | 4 +- .../tgui/interfaces/MobInteraction.tsx | 17 +- 18 files changed, 416 insertions(+), 250 deletions(-) delete mode 100644 modular_sand/code/modules/arousal/creampie.dm delete mode 100644 modular_sand/code/modules/mob/living/carbon/human/human_defines.dm delete mode 100644 modular_sand/code/modules/mob/living/carbon/human/life.dm create mode 100644 modular_sand/code/modules/reagents/chemistry/reagents/drug_reagents.dm diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm index 95ddc3c955..332a5ff7c8 100644 --- a/code/modules/arousal/arousal.dm +++ b/code/modules/arousal/arousal.dm @@ -75,12 +75,18 @@ if(spill && R.total_volume >= 5) R.reaction(turfing ? target : target.loc, TOUCH, 1, 0) if(!turfing) - R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1), log = TRUE) + // sandstorm edit - advanced cum drip + var/amount_to_transfer = R.total_volume * (spill ? G.fluid_transfer_factor : 1) + R.trans_to(target, amount_to_transfer, log = TRUE) + if(ishuman(target)) + // Nope, on the mouth doesn't count. + if(!(istype(last_lewd_datum, /datum/interaction/lewd/facefuck) || istype(last_lewd_datum, /datum/interaction/lewd/throatfuck))) + var/datum/reagent/consumable/semen/salty_drink = target.reagents.get_reagent(/datum/reagent/consumable/semen) + salty_drink.amount_to_drip += amount_to_transfer + // G.last_orgasmed = world.time R.clear_reagents() - //skyrat edit - chock i am going to beat you to death - //this is not a joke i am actually going to break your - //ribcage + //sandstorm edit - gain momentum from dirty deeds. if(!Process_Spacemove(turn(dir, 180))) newtonian_move(turn(dir, 180)) // @@ -216,6 +222,11 @@ if(!client?.prefs.arousable || !has_dna()) return + + if(HAS_TRAIT(src, TRAIT_NEVERBONER)) + to_chat(src, span_warning("You don't feel like it at all.")) + return + if(stat == DEAD) if(!forced_climax) to_chat(src, "You can't do that while dead!") diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index c709fd09a7..d2b200ab73 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -562,7 +562,6 @@ description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac." taste_description = "strawberries" color = "#FFADFF"//PINK, rgb(255, 173, 255) - can_synth = FALSE /datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M) if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) @@ -588,7 +587,6 @@ color = "#FF2BFF"//dark pink addiction_threshold = 20 overdose_threshold = 20 - can_synth = FALSE /datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M) if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO)) @@ -644,7 +642,6 @@ taste_mult = 2 color = "#D9D9D9"//rgb(217, 217, 217) reagent_state = SOLID - can_synth = FALSE /datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M) if(M && M.client?.prefs.arousable && prob(16)) @@ -662,7 +659,6 @@ color = "#D9D9D9"//rgb(217, 217, 217) reagent_state = SOLID overdose_threshold = 20 - can_synth = FALSE /datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M) if(M && M.client?.prefs.arousable) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 73e3367260..f64ff9b934 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2517,8 +2517,9 @@ var/obj/effect/decal/cleanable/semen/S = locate() in T if(!S) S = new decal_path(T) - if(data["blood_DNA"]) - S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) + // Sandstorm edit - cum carries your genetic info (all of it) + if(data) + S.add_blood_DNA(data) /obj/effect/decal/cleanable/semen name = "semen" diff --git a/modular_sand/code/datums/components/interaction_menu_granter.dm b/modular_sand/code/datums/components/interaction_menu_granter.dm index e6a91c74f9..a88f96f24a 100644 --- a/modular_sand/code/datums/components/interaction_menu_granter.dm +++ b/modular_sand/code/datums/components/interaction_menu_granter.dm @@ -112,6 +112,7 @@ interaction["type"] = INTERACTION_LEWD else interaction["type"] = INTERACTION_NORMAL + interaction["additionalDetails"] = I.additional_details sent_interactions += list(interaction) .["interactions"] = sent_interactions diff --git a/modular_sand/code/datums/interactions/_interaction.dm b/modular_sand/code/datums/interactions/_interaction.dm index 5ba1efe8e8..cf00b85774 100644 --- a/modular_sand/code/datums/interactions/_interaction.dm +++ b/modular_sand/code/datums/interactions/_interaction.dm @@ -40,6 +40,9 @@ var/user_is_target = FALSE //Boolean. Pretty self explanatory. + /// Refuses to accept more than one entry for some reason, fix sometime + var/list/additional_details + /// Checks if user can do an interaction, action_check is for whether you're actually doing it or not (useful for the menu and not removing the buttons) /datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE) if(SSinteractions.is_blacklisted(user)) diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm index 5c91e50a3c..40d3d160d8 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm @@ -8,34 +8,73 @@ write_log_user = "groped own breasts" write_log_target = null + additional_details = list( + list( + "info" = "You can fill a container if you hold it in your hand or pull it", + "icon" = "flask", + "color" = "transparent" + ) + ) + /datum/interaction/lewd/titgrope_self/display_interaction(mob/living/user) var/message var/t_His = user.p_their() - if(user.a_intent == INTENT_HARM) - message = "[pick("aggressively gropes [t_His] breast.", - "grabs [t_His] breasts.", - "tightly squeezes [t_His] breasts.", - "slaps at [t_His] breasts.", - "gropes [t_His] breasts roughly.")]" + var/obj/item/reagent_containers/liquid_container + + var/obj/item/cached_item = user.get_active_held_item() + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item else - message = "[pick("gently gropes [t_His] breast.", - "softly squeezes [t_His] breasts.", - "grips [t_His] breasts.", - "runs a few fingers over [t_His] breast.", - "delicately teases [t_His] nipple.", - "traces a touch across [t_His] breast.")]" + cached_item = user.pulling + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item + + if(user.a_intent == INTENT_HARM) + message = pick("aggressively gropes [t_His] breast", + "grabs [t_His] breasts", + "tightly squeezes [t_His] breasts", + "slaps at [t_His] breasts", + "gropes [t_His] breasts roughly") + else + message = pick("gently gropes [t_His] breast", + "softly squeezes [t_His] breasts", + "grips [t_His] breasts", + "runs a few fingers over [t_His] breast", + "delicately teases [t_His] nipple", + "traces a touch across [t_His] breast") + if(prob(5 + user.get_lust())) - user.visible_message("\The [user] [pick("shivers in arousal.", + user.visible_message(span_lewd("\The [user] [pick( + "shivers in arousal.", "moans quietly.", "breathes out a soft moan.", "gasps.", "shudders softly.", - "trembles as [t_His] hands run across bare skin.")]") - user.visible_message(message = span_lewd("\The [user] [message]"), ignored_mobs = user.get_unconsenting()) - playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1) - user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user) + "trembles as [t_His] hands run across bare skin.")]")) + if(liquid_container) + message += " over \the [liquid_container]" + + var/obj/item/organ/genital/breasts/milkers = user.getorganslot(ORGAN_SLOT_BREASTS) + var/milktype = milkers?.fluid_id + + if(milkers && milktype) + var/modifier + switch(milkers.size) + if("c", "d", "e") + modifier = 2 + if("f", "g", "h") + modifier = 3 + else + if(milkers.size in milkers.breast_values) + modifier = clamp(milkers.breast_values[milkers.size] - 5, 0, INFINITY) + else + modifier = 1 + liquid_container.reagents.add_reagent(milktype, rand(1,3 * modifier)) + + user.visible_message(message = span_lewd("\The [user] [message]."), ignored_mobs = user.get_unconsenting()) + playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1) /datum/interaction/lewd/self_nipsuck description = "Suck your own nips." diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/finger.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/finger.dm index db59702933..09ea82cf94 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/finger.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/finger.dm @@ -12,9 +12,10 @@ var/t_His = user.p_their() var/t_Him = user.p_them() - user.visible_message("\The [user] [pick("fingers [t_Him]self.", + user.visible_message(span_lewd("\The [user] [pick( + "fingers [t_Him]self.", "fingers [t_His] asshole.", - "fingers [t_Him]self hard.")]", ignored_mobs = user.get_unconsenting()) + "fingers [t_Him]self hard.")]"), ignored_mobs = user.get_unconsenting()) playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user) @@ -28,12 +29,38 @@ write_log_user = "fingered own pussy" write_log_target = null + additional_details = list( + list( + "info" = "You can fill a container if you hold it in your hand or pull it", + "icon" = "flask", + "color" = "transparent" + ) + ) + /datum/interaction/lewd/finger_self/display_interaction(mob/living/user) var/t_His = user.p_their() - user.visible_message("\The [user] [pick("fingers [t_His] pussy deep.", - "fingers [t_His] pussy.", - "plays with [t_His] pussy.", - "fingers [t_His] own pussy hard.")]", ignored_mobs = user.get_unconsenting()) + var/obj/item/reagent_containers/liquid_container + + var/obj/item/cached_item = user.get_active_held_item() + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item + else + cached_item = user.pulling + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item + + var/message = pick( + "fingers [t_His] pussy deep", + "fingers [t_His] pussy", + "plays with [t_His] pussy", + "fingers [t_His] own pussy hard") + if(!user.is_fucking(user, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_VAGINA))) + user.set_is_fucking(user, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_VAGINA)) + + if(liquid_container) + message += " over \the [liquid_container]" + + user.visible_message(span_lewd("\The [user] [message]."), ignored_mobs = user.get_unconsenting()) playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1) - user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user) + user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, liquid_container ? liquid_container : user) diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/jack.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/jack.dm index 704797cd5d..8b5767b882 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/jack.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/jack.dm @@ -8,24 +8,44 @@ write_log_user = "jerked off" write_log_target = null + additional_details = list( + list( + "info" = "You can fill a container if you hold it in your hand or pull it", + "icon" = "flask", + "color" = "transparent" + ) + ) + /datum/interaction/lewd/jack/display_interaction(mob/living/user) var/message var/t_His = user.p_their() var/t_Him = user.p_them() - if(user.is_fucking(user, CUM_TARGET_HAND)) - message = "[pick("jerks [t_Him]self off.", - "works [t_His] shaft.", - "strokes [t_His] penis.", - "wanks [t_His] cock hard.")]" + var/obj/item/reagent_containers/liquid_container + + var/obj/item/cached_item = user.get_active_held_item() + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item else - message = "[pick("wraps [t_His] hand around [t_His] cock.", - "starts to stroke [t_His] cock.", - "starts playing with [t_His] cock.")]" + cached_item = user.pulling + if(istype(cached_item, /obj/item/reagent_containers)) + liquid_container = cached_item + + if(user.is_fucking(user, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_PENIS))) + message = "[pick("jerks [t_Him]self off", + "works [t_His] shaft", + "strokes [t_His] penis", + "wanks [t_His] cock hard")]" + else + message = "[pick("wraps [t_His] hand around [t_His] cock", + "starts to stroke [t_His] cock", + "starts playing with [t_His] cock")]" user.set_is_fucking(user, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_PENIS)) + if(liquid_container) + message += " over \the [liquid_container]" playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg', 'modular_sand/sound/interactions/bang2.ogg', 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1) - user.visible_message(message = span_lewd("\The [user] [message]"), ignored_mobs = user.get_unconsenting()) - user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user) + user.visible_message(message = span_lewd("\The [user] [message]."), ignored_mobs = user.get_unconsenting()) + user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, liquid_container ? liquid_container : user) diff --git a/modular_sand/code/datums/interactions/lewd_definitions.dm b/modular_sand/code/datums/interactions/lewd_definitions.dm index 8fee123a62..df9c5a136f 100644 --- a/modular_sand/code/datums/interactions/lewd_definitions.dm +++ b/modular_sand/code/datums/interactions/lewd_definitions.dm @@ -41,8 +41,10 @@ var/cleartimer //Timer for clearing the "last_lewd_datum". This prevents some oddities. /mob/living/proc/clear_lewd_datum() - last_lewd_datum = null + last_partner = null + last_orifice = null last_genital = null + last_lewd_datum = null /mob/living/Initialize(mapload) . = ..() @@ -378,6 +380,8 @@ lastmoan = moan /mob/living/proc/cum(mob/living/partner, target_orifice) + if(HAS_TRAIT(src, TRAIT_NEVERBONER)) + return FALSE var/message var/u_His = p_their() var/u_He = p_they() @@ -393,174 +397,11 @@ partner_carbon_check = TRUE if(src != partner) - if(!last_genital) - if(has_penis()) - if(!istype(partner)) - target_orifice = null - switch(target_orifice) - if(CUM_TARGET_MOUTH) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "cums right in \the [partner]'s mouth." - cumin = TRUE - else - message = "cums on \the [partner]'s face." - if(CUM_TARGET_THROAT) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "shoves deep into \the [partner]'s throat and cums." - cumin = TRUE - else - message = "cums on \the [partner]'s face." - if(CUM_TARGET_VAGINA) - if(partner.has_vagina(REQUIRE_EXPOSED)) - if(partner_carbon_check) - target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) - message = "cums in \the [partner]'s pussy." - cumin = TRUE - else - message = "cums on \the [partner]'s belly." - if(CUM_TARGET_ANUS) - if(partner.has_anus(REQUIRE_EXPOSED)) - message = "cums in \the [partner]'s asshole." - cumin = TRUE - else - message = "cums on \the [partner]'s backside." - if(CUM_TARGET_HAND) - if(partner.has_hand(REQUIRE_ANY)) - message = "cums in \the [partner]'s hand." - else - message = "cums on \the [partner]." - if(CUM_TARGET_BREASTS) - if(partner.has_breasts(REQUIRE_EXPOSED)) - message = "cums onto \the [partner]'s breasts." - else - message = "cums on \the [partner]'s chest and neck." - if(NUTS_TO_FACE) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "vigorously ruts [u_His] nutsack into \the [partner]'s mouth before shooting [u_His] thick, sticky jizz all over [t_His] eyes and hair." - if(THIGH_SMOTHERING) - 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 [u_His] thighs as [u_His] cock throbs, dumping its heavy load all over [t_His] face." - else - message = "reaches [u_His] peak, locking [u_His] legs around \the [partner]'s head extra hard as [u_He] cum[u_S] straight onto the head stuck between [u_His] thighs" - cumin = TRUE - if(CUM_TARGET_FEET) - if(!last_lewd_datum.require_target_num_feet) - if(partner.has_feet()) - message = "cums on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." - else - message = "cums on the floor!" - else - if(partner.has_feet()) - message = "cums on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]." - else - message = "cums on the floor!" - //weird shit goes here - if(CUM_TARGET_EARS) - if(partner.has_ears()) - message = "cums inside \the [partner]'s ear." - else - message = "cums inside \the [partner]'s earsocket." - cumin = TRUE - if(CUM_TARGET_EYES) - if(partner.has_eyes()) - message = "cums on \the [partner]'s eyeball." - else - 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()) - if(!istype(partner)) - target_orifice = null - - switch(target_orifice) - if(CUM_TARGET_MOUTH) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "squirts right in \the [partner]'s mouth." - cumin = TRUE - else - message = "squirts on \the [partner]'s face." - if(CUM_TARGET_THROAT) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "rubs [u_His] vagina against \the [partner]'s mouth and cums." - cumin = TRUE - else - message = "squirts on \the [partner]'s face." - if(CUM_TARGET_VAGINA) - if(partner.has_vagina(REQUIRE_EXPOSED)) - message = "squirts on \the [partner]'s pussy." - cumin = TRUE - else - message = "squirts on \the [partner]'s belly." - if(CUM_TARGET_ANUS) - if(partner.has_anus(REQUIRE_EXPOSED)) - message = "squirts on \the [partner]'s asshole." - cumin = TRUE - else - message = "squirts on \the [partner]'s backside." - if(CUM_TARGET_HAND) - if(partner.has_hand(REQUIRE_ANY)) - message = "squirts on \the [partner]'s hand." - else - message = "squirts on \the [partner]." - if(CUM_TARGET_BREASTS) - if(partner.has_breasts(REQUIRE_EXPOSED)) - message = "squirts onto \the [partner]'s breasts." - else - message = "squirts on \the [partner]'s chest and neck." - if(NUTS_TO_FACE) - if(partner.has_mouth() && partner.mouth_is_free()) - message = "vigorously ruts [u_His] clit into \the [partner]'s mouth before shooting [u_His] femcum all over [t_His] eyes and hair." - if(THIGH_SMOTHERING) - message = "keeps \the [partner] locked in [u_His] thighs as [u_He] orgasm[u_S], squirting over [t_His] face." - cumin = TRUE - if(CUM_TARGET_FEET) - if(!last_lewd_datum.require_target_num_feet) - if(partner.has_feet()) - message = "squirts on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." - else - message = "squirts on the floor!" - else - if(partner.has_feet()) - message = "squirts on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]." - else - message = "squirts on the floor!" - //weird shit goes here - if(CUM_TARGET_EARS) - if(partner.has_ears()) - message = "squirts on \the [partner]'s ear." - else - message = "squirts on \the [partner]'s earsocket." - cumin = TRUE - if(CUM_TARGET_EYES) - if(partner.has_eyes()) - message = "squirts on \the [partner]'s eyeball." - else - 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 - message = pick("orgasms violently!", "twists in orgasm.") - else - switch(last_genital.type) - if(/obj/item/organ/genital/penis) + if(ismob(partner)) + if(!last_genital) + if(has_penis()) if(!istype(partner)) target_orifice = null - switch(target_orifice) if(CUM_TARGET_MOUTH) if(partner.has_mouth() && partner.mouth_is_free()) @@ -589,12 +430,12 @@ else message = "cums on \the [partner]'s backside." if(CUM_TARGET_HAND) - if(partner.has_hand()) + if(partner.has_hand(REQUIRE_ANY)) message = "cums in \the [partner]'s hand." else message = "cums on \the [partner]." if(CUM_TARGET_BREASTS) - if(partner.is_topless() && partner.has_breasts()) + if(partner.has_breasts(REQUIRE_EXPOSED)) message = "cums onto \the [partner]'s breasts." else message = "cums on \the [partner]'s chest and neck." @@ -602,13 +443,13 @@ if(partner.has_mouth() && partner.mouth_is_free()) message = "vigorously ruts [u_His] nutsack into \the [partner]'s mouth before shooting [u_His] thick, sticky jizz all over [t_His] eyes and hair." if(THIGH_SMOTHERING) - if(has_penis()) //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 [u_His] thighs as [u_His] cock throbs, dumping its heavy load all over [t_His] face." else message = "reaches [u_His] peak, locking [u_His] legs around \the [partner]'s head extra hard as [u_He] cum[u_S] straight onto the head stuck between [u_His] thighs" cumin = TRUE if(CUM_TARGET_FEET) - if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet) + if(!last_lewd_datum.require_target_num_feet) if(partner.has_feet()) message = "cums on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." else @@ -639,7 +480,7 @@ message = "cums on the floor!" else message = "cums on the floor!" - if(/obj/item/organ/genital/vagina) + else if(has_vagina()) if(!istype(partner)) target_orifice = null @@ -669,7 +510,7 @@ else message = "squirts on \the [partner]'s backside." if(CUM_TARGET_HAND) - if(partner.has_hand()) + if(partner.has_hand(REQUIRE_ANY)) message = "squirts on \the [partner]'s hand." else message = "squirts on \the [partner]." @@ -681,12 +522,11 @@ if(NUTS_TO_FACE) if(partner.has_mouth() && partner.mouth_is_free()) message = "vigorously ruts [u_His] clit into \the [partner]'s mouth before shooting [u_His] femcum all over [t_His] eyes and hair." - if(THIGH_SMOTHERING) message = "keeps \the [partner] locked in [u_His] thighs as [u_He] orgasm[u_S], squirting over [t_His] face." - + cumin = TRUE if(CUM_TARGET_FEET) - if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet) + if(!last_lewd_datum.require_target_num_feet) if(partner.has_feet()) message = "squirts on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." else @@ -717,8 +557,179 @@ message = "squirts on the floor!" else message = "squirts on the floor!" + else message = pick("orgasms violently!", "twists in orgasm.") + else + switch(last_genital.type) + if(/obj/item/organ/genital/penis) + if(!istype(partner)) + target_orifice = null + + switch(target_orifice) + if(CUM_TARGET_MOUTH) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "cums right in \the [partner]'s mouth." + cumin = TRUE + else + message = "cums on \the [partner]'s face." + if(CUM_TARGET_THROAT) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "shoves deep into \the [partner]'s throat and cums." + cumin = TRUE + else + message = "cums on \the [partner]'s face." + if(CUM_TARGET_VAGINA) + if(partner.has_vagina(REQUIRE_EXPOSED)) + if(partner_carbon_check) + target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) + message = "cums in \the [partner]'s pussy." + cumin = TRUE + else + message = "cums on \the [partner]'s belly." + if(CUM_TARGET_ANUS) + if(partner.has_anus(REQUIRE_EXPOSED)) + message = "cums in \the [partner]'s asshole." + cumin = TRUE + else + message = "cums on \the [partner]'s backside." + if(CUM_TARGET_HAND) + if(partner.has_hand()) + message = "cums in \the [partner]'s hand." + else + message = "cums on \the [partner]." + if(CUM_TARGET_BREASTS) + if(partner.is_topless() && partner.has_breasts()) + message = "cums onto \the [partner]'s breasts." + else + message = "cums on \the [partner]'s chest and neck." + if(NUTS_TO_FACE) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "vigorously ruts [u_His] nutsack into \the [partner]'s mouth before shooting [u_His] thick, sticky jizz all over [t_His] eyes and hair." + if(THIGH_SMOTHERING) + 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 [u_His] thighs as [u_His] cock throbs, dumping its heavy load all over [t_His] face." + else + message = "reaches [u_His] peak, locking [u_His] legs around \the [partner]'s head extra hard as [u_He] cum[u_S] straight onto the head stuck between [u_His] thighs" + cumin = TRUE + if(CUM_TARGET_FEET) + if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet) + if(partner.has_feet()) + message = "cums on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." + else + message = "cums on the floor!" + else + if(partner.has_feet()) + message = "cums on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]." + else + message = "cums on the floor!" + //weird shit goes here + if(CUM_TARGET_EARS) + if(partner.has_ears()) + message = "cums inside \the [partner]'s ear." + else + message = "cums inside \the [partner]'s earsocket." + cumin = TRUE + if(CUM_TARGET_EYES) + if(partner.has_eyes()) + message = "cums on \the [partner]'s eyeball." + else + 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) + if(!istype(partner)) + target_orifice = null + + switch(target_orifice) + if(CUM_TARGET_MOUTH) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "squirts right in \the [partner]'s mouth." + cumin = TRUE + else + message = "squirts on \the [partner]'s face." + if(CUM_TARGET_THROAT) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "rubs [u_His] vagina against \the [partner]'s mouth and cums." + cumin = TRUE + else + message = "squirts on \the [partner]'s face." + if(CUM_TARGET_VAGINA) + if(partner.has_vagina(REQUIRE_EXPOSED)) + message = "squirts on \the [partner]'s pussy." + cumin = TRUE + else + message = "squirts on \the [partner]'s belly." + if(CUM_TARGET_ANUS) + if(partner.has_anus(REQUIRE_EXPOSED)) + message = "squirts on \the [partner]'s asshole." + cumin = TRUE + else + message = "squirts on \the [partner]'s backside." + if(CUM_TARGET_HAND) + if(partner.has_hand()) + message = "squirts on \the [partner]'s hand." + else + message = "squirts on \the [partner]." + if(CUM_TARGET_BREASTS) + if(partner.has_breasts(REQUIRE_EXPOSED)) + message = "squirts onto \the [partner]'s breasts." + else + message = "squirts on \the [partner]'s chest and neck." + if(NUTS_TO_FACE) + if(partner.has_mouth() && partner.mouth_is_free()) + message = "vigorously ruts [u_His] clit into \the [partner]'s mouth before shooting [u_His] femcum all over [t_His] eyes and hair." + + if(THIGH_SMOTHERING) + message = "keeps \the [partner] locked in [u_His] thighs as [u_He] orgasm[u_S], squirting over [t_His] face." + + if(CUM_TARGET_FEET) + if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet) + if(partner.has_feet()) + message = "squirts on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]." + else + message = "squirts on the floor!" + else + if(partner.has_feet()) + message = "squirts on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]." + else + message = "squirts on the floor!" + //weird shit goes here + if(CUM_TARGET_EARS) + if(partner.has_ears()) + message = "squirts on \the [partner]'s ear." + else + message = "squirts on \the [partner]'s earsocket." + cumin = TRUE + if(CUM_TARGET_EYES) + if(partner.has_eyes()) + message = "squirts on \the [partner]'s eyeball." + else + 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 + message = pick("orgasms violently!", "twists in orgasm.") + else if(istype(partner, /obj/item/reagent_containers)) + switch(last_genital.type) + if(/obj/item/organ/genital/penis) + message = "cums into \the [partner]" + if(/obj/item/organ/genital/vagina) + message = "squirts into \the [partner]" else //todo: better self cum messages message = "cums all over themselves!" if(gender == MALE) @@ -744,14 +755,31 @@ var/mob/living/carbon/human/H = src if(!partner) H.mob_climax(TRUE, "masturbation", "none") + else if(istype(partner, /obj/item/reagent_containers)) + H.mob_fill_container(last_genital, partner, 0) else H.mob_climax(TRUE, "sex", partner, !cumin, target_gen) set_lust(0) -/mob/living/proc/is_fucking(mob/living/partner, orifice) - if(partner == last_partner && orifice == last_orifice) - return TRUE - return FALSE + return TRUE + +/mob/living/proc/is_fucking(mob/living/partner, orifice, obj/item/organ/genital/genepool, datum/interaction/lewd/lewd_datum) + var/failed = FALSE + if(partner) + if(partner != last_partner) + failed++ + if(orifice) + if(orifice != last_orifice) + failed++ + if(genepool) + if(genepool != last_genital) + failed++ + if(lewd_datum) + if(lewd_datum != last_lewd_datum) + failed++ + if(failed) + return FALSE + return TRUE /mob/living/proc/set_is_fucking(mob/living/partner, orifice, obj/item/organ/genital/genepool) last_partner = partner diff --git a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm index baed1cc73a..1eef9c7dfc 100644 --- a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm +++ b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm @@ -7,3 +7,15 @@ icon = 'modular_sand/icons/obj/genitals/effects.dmi' icon_state = "drip1" random_icon_states = list("drip1", "drip2", "drip3", "drip4") + var/total_amount = 1 + +/obj/effect/decal/cleanable/semendrip/replace_decal(obj/effect/decal/cleanable/semendrip/C) + . = ..() + C.total_amount++ + C.transfer_blood_dna(src.blood_DNA) + if(C.total_amount >= 10) + var/obj/effect/decal/cleanable/semen/S = new(loc) + S.transfer_blood_dna(C.blood_DNA) + qdel(C) + + return TRUE diff --git a/modular_sand/code/modules/arousal/arousal.dm b/modular_sand/code/modules/arousal/arousal.dm index fc5de73f14..3433e346ff 100644 --- a/modular_sand/code/modules/arousal/arousal.dm +++ b/modular_sand/code/modules/arousal/arousal.dm @@ -2,6 +2,19 @@ . = ..() set_lust(0) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) + var/message_to_display + // We got pleased, let's get rid of some of it + var/crocin_amount = reagents.get_reagent_amount(/datum/reagent/drug/aphrodisiac) + if(crocin_amount) + reagents.remove_reagent(/datum/reagent/drug/aphrodisiac, rand(10, max(30, crocin_amount / 5))) + message_to_display = span_userlove("Mnn.. Yes...~") + // More potent, harder to get rid of + var/hexacrocin_amount = reagents.get_reagent_amount(/datum/reagent/drug/aphrodisiacplus) + if(hexacrocin_amount) + reagents.remove_reagent(/datum/reagent/drug/aphrodisiacplus, rand(2, max(15, hexacrocin_amount / 6))) + message_to_display = span_userlove("YES~!") + if(message_to_display) + to_chat(src, message_to_display) /mob/living/carbon/human/proc/pick_receiving_organ(mob/living/L) if (!iscarbon(L)) @@ -22,9 +35,6 @@ var/mob/living/carbon/human/h_self = src var/mob/living/carbon/human/h_partner = null - if(istype(source_gen, /obj/item/organ/genital/penis)) - h_self.cumdrip_rate += rand(5,10) - if(ishuman(partner)) h_partner = partner if(receiver) diff --git a/modular_sand/code/modules/arousal/creampie.dm b/modular_sand/code/modules/arousal/creampie.dm deleted file mode 100644 index c55162b1c8..0000000000 --- a/modular_sand/code/modules/arousal/creampie.dm +++ /dev/null @@ -1,11 +0,0 @@ -/mob/living/carbon/human/handle_creampie() - if(cumdrip_rate < 0) - cumdrip_rate = 0 - - if(bodytemperature >= TCRYO) - cumdrip_rate = cumdrip_rate - 1 - cumdrip() - -/mob/living/carbon/human/proc/cumdrip() - if(isturf(loc)) - new/obj/effect/decal/cleanable/semendrip(get_turf(src)) diff --git a/modular_sand/code/modules/mob/living/carbon/human/human_defines.dm b/modular_sand/code/modules/mob/living/carbon/human/human_defines.dm deleted file mode 100644 index cbfb36d839..0000000000 --- a/modular_sand/code/modules/mob/living/carbon/human/human_defines.dm +++ /dev/null @@ -1,2 +0,0 @@ -/mob/living/carbon/human - var/cumdrip_rate = 0 //how long are we dripping jizz for? diff --git a/modular_sand/code/modules/mob/living/carbon/human/life.dm b/modular_sand/code/modules/mob/living/carbon/human/life.dm deleted file mode 100644 index 0667b491f1..0000000000 --- a/modular_sand/code/modules/mob/living/carbon/human/life.dm +++ /dev/null @@ -1,6 +0,0 @@ -//Hyper change, adds cumdrip -/mob/living/carbon/human/BiologicalLife(seconds, times_fired) - if(!(. = ..())) - return - if(cumdrip_rate > 0 && stat != DEAD) - handle_creampie() diff --git a/modular_sand/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/modular_sand/code/modules/reagents/chemistry/reagents/drug_reagents.dm new file mode 100644 index 0000000000..7ed2ea282f --- /dev/null +++ b/modular_sand/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -0,0 +1,13 @@ +/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable) + M.add_lust(max(2, M.get_lust() / 5) * -1) + if(prob(0.5)) + to_chat(M, span_warning("You don't feel quite like it.")) + return ..() + +/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M) + if(M && M.client?.prefs.arousable) + M.add_lust(max(10, M.get_lust() / 4) * -1) + if(prob(0.2)) + to_chat(M, span_boldwarning("Nope, certainly don't feel like it.")) + return ..() diff --git a/modular_sand/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_sand/code/modules/reagents/chemistry/reagents/other_reagents.dm index 344087f408..762556b070 100644 --- a/modular_sand/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_sand/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -16,6 +16,17 @@ if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) L.ForceContractDisease(new /datum/disease/transformation/dragon(), FALSE, TRUE) +/datum/reagent/consumable/semen + // Prevents dripping from drinking a glass or other weird cases + var/amount_to_drip = 0 + +/datum/reagent/consumable/semen/on_mob_life(mob/living/carbon/M) + . = ..() + if(amount_to_drip && M.is_groin_exposed()) + amount_to_drip = max(0, amount_to_drip - metabolization_rate) + var/obj/effect/decal/cleanable/semendrip/drip = new(get_turf(M)) + drip.add_blood_DNA(data) + /*/datum/reagent/dragon_blood/admin name = "Special dragon blood" description = "It looks weird" diff --git a/tgstation.dme b/tgstation.dme index 210f7ee580..e66e53f694 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4087,7 +4087,6 @@ #include "modular_sand\code\modules\admin\verbs\fix_air.dm" #include "modular_sand\code\modules\admin\verbs\randomverbs.dm" #include "modular_sand\code\modules\arousal\arousal.dm" -#include "modular_sand\code\modules\arousal\creampie.dm" #include "modular_sand\code\modules\arousal\genital_sprite_accessories.dm" #include "modular_sand\code\modules\arousal\genitals.dm" #include "modular_sand\code\modules\arousal\organs\breasts.dm" @@ -4176,9 +4175,7 @@ #include "modular_sand\code\modules\mob\living\carbon\life.dm" #include "modular_sand\code\modules\mob\living\carbon\show.dm" #include "modular_sand\code\modules\mob\living\carbon\human\human.dm" -#include "modular_sand\code\modules\mob\living\carbon\human\human_defines.dm" #include "modular_sand\code\modules\mob\living\carbon\human\human_stripping.dm" -#include "modular_sand\code\modules\mob\living\carbon\human\life.dm" #include "modular_sand\code\modules\mob\living\carbon\human\species.dm" #include "modular_sand\code\modules\mob\living\carbon\human\species_types\anthropomorph.dm" #include "modular_sand\code\modules\mob\living\carbon\human\species_types\ipc.dm" @@ -4233,6 +4230,7 @@ #include "modular_sand\code\modules\reagents\chemistry\reagents\alcohol_reagents.dm" #include "modular_sand\code\modules\reagents\chemistry\reagents\cit_reagents.dm" #include "modular_sand\code\modules\reagents\chemistry\reagents\drink_reagents.dm" +#include "modular_sand\code\modules\reagents\chemistry\reagents\drug_reagents.dm" #include "modular_sand\code\modules\reagents\chemistry\reagents\fermi_reagents.dm" #include "modular_sand\code\modules\reagents\chemistry\reagents\medicine_reagents.dm" #include "modular_sand\code\modules\reagents\chemistry\reagents\other_reagents.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction.tsx b/tgui/packages/tgui/interfaces/MobInteraction.tsx index 1ba80715e8..21b1a960b5 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction.tsx @@ -25,6 +25,7 @@ type InteractionData = { key: string; desc: string; type: number; + additionalDetails: string[]; } type GenitalInfo = { @@ -195,7 +196,21 @@ const InteractionsTab = (props, context) => { mb={0.3} onClick={() => act('interact', { interaction: interaction.key, - })} /> + })}> + {interaction.additionalDetails && ( + interaction.additionalDetails.map(detail => ( + + )))} + )) ) : (