mirror of
https://github.com/Sandstorm-Station/Sandstorm-Station-13.git
synced 2026-08-20 19:57:56 +01:00
Various ERP verb fixes (#53)
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
/*********************************
|
||||
*******Interactions code by HONKERTRON feat TestUnit********
|
||||
**Contains a lot ammount of ERP and MEHANOYEBLYA**
|
||||
**CREDIT TO ATMTA STATION FOR MOST OF THIS CODE, I ONLY MADE IT WORK IN /vg/ - Matt
|
||||
** Rewritten 30/08/16 by Zuhayr, sry if I removed anything important.
|
||||
**I removed ERP and replaced it with handholding. Nothing of worth was lost. - Vic
|
||||
**Fuck you, Vic. ERP is back. - TT
|
||||
**>using var/ on everything, also TRUE
|
||||
***********************************/
|
||||
|
||||
|
||||
// Rectum? Damn near killed 'em.
|
||||
var/list/interactions
|
||||
|
||||
/proc/make_interactions(interaction)
|
||||
if(!interactions)
|
||||
interactions = list()
|
||||
for(var/itype in subtypesof(/datum/interaction))
|
||||
var/datum/interaction/I = new itype()
|
||||
interactions[I.command] = I
|
||||
|
||||
/mob/living/proc/list_interaction_attributes()
|
||||
var/dat = ""
|
||||
if(has_hands())
|
||||
dat += "...have hands."
|
||||
if(has_mouth())
|
||||
if(dat != "")
|
||||
dat += "<br>"
|
||||
dat += "...have a mouth, which is [mouth_is_free() ? "uncovered" : "covered"]."
|
||||
return dat
|
||||
|
||||
/datum/interaction
|
||||
var/command = "interact"
|
||||
var/description = "Interact with them."
|
||||
var/simple_message
|
||||
var/simple_style = "notice"
|
||||
var/write_log_user
|
||||
var/write_log_target
|
||||
|
||||
var/interaction_sound
|
||||
|
||||
var/max_distance = 1
|
||||
var/require_ooc_consent = FALSE
|
||||
var/require_user_mouth
|
||||
var/require_user_hands
|
||||
var/require_target_mouth
|
||||
var/require_target_hands
|
||||
var/needs_physical_contact
|
||||
|
||||
var/user_is_target = FALSE //Boolean. Pretty self explanatory.
|
||||
|
||||
/datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE)
|
||||
if(user.get_refraction_dif())
|
||||
if(!silent) //bye spam
|
||||
to_chat(user, "<span class='warning'>You're still exhausted from the last time. You need to wait [DisplayTimeText(user.get_refraction_dif(), TRUE)] until you can do that!</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_mouth)
|
||||
if(!user.has_mouth() && !issilicon(user)) //Again, silicons do not have the required parts normally.
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have a mouth.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!user.mouth_is_free() && !issilicon(user)) //Borgs cannot wear mouthgear, bypassing the check.
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your mouth is covered.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_hands && !user.has_hands() && !issilicon(user)) //Edited to allow silicons to interact.
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have hands.</span>")
|
||||
return FALSE
|
||||
|
||||
if(user.last_interaction_time < world.time)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/interaction/proc/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
|
||||
if(!user_is_target)
|
||||
if(user == target)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You can't do that to yourself.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_mouth)
|
||||
if(!target.has_mouth())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have a mouth.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!target.mouth_is_free() && !issilicon(target))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their mouth is covered.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_hands && !target.has_hands() && !issilicon(target))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have hands.</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/interaction/proc/get_action_link_for(mob/living/user, mob/living/target)
|
||||
return "<a HREF='byond://?src=[REF(src)];action=1;action_user=[REF(user)];action_target=[REF(target)]'>[description]</a><br>"
|
||||
|
||||
/datum/interaction/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(href_list["action"])
|
||||
do_action(locate(href_list["action_user"]), locate(href_list["action_target"]))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/interaction/proc/do_action(mob/living/user, mob/living/target)
|
||||
if(!user_is_target)
|
||||
if(user == target) //tactical href fix
|
||||
to_chat(user, "<span class='warning'>You cannot target yourself.</span>")
|
||||
return
|
||||
if(get_dist(user, target) > max_distance)
|
||||
//user << "<span class='warning'>They are too far away.</span>"
|
||||
user.visible_message("<span class='warning'>They are too far away.</span>")
|
||||
return
|
||||
if(needs_physical_contact && !(user.Adjacent(target) && target.Adjacent(user)))
|
||||
//user << "<span class='warning'>You cannot get to them.</span>"
|
||||
user.visible_message("<span class='warning'>You cannot get to them.</span>")
|
||||
return
|
||||
if(!evaluate_user(user, silent = FALSE))
|
||||
return
|
||||
if(!evaluate_target(user, target, silent = FALSE))
|
||||
return
|
||||
|
||||
if(write_log_user)
|
||||
user.log_message("[write_log_user] [target]", INDIVIDUAL_ATTACK_LOG)
|
||||
if(write_log_target)
|
||||
target.log_message("[write_log_target] [user]", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
display_interaction(user, target)
|
||||
post_interaction(user, target)
|
||||
|
||||
//if(write_log_user)
|
||||
//add_logs(target, user, "fucked")
|
||||
//user.attack_log += text("\[[time_stamp()]\] <font color='red'>[write_log_user] [target.name] ([target.ckey])</font>")
|
||||
//if(write_log_target)
|
||||
//add_logs(target, user, "fucked2")
|
||||
//target.attack_log += text("\[[time_stamp()]\] <font color='orange'>[write_log_target] [user.name] ([user.ckey])</font>")
|
||||
|
||||
/datum/interaction/proc/display_interaction(mob/living/user, mob/living/target)
|
||||
if(simple_message)
|
||||
var/use_message = replacetext(simple_message, "USER", "\the [user]")
|
||||
use_message = replacetext(use_message, "TARGET", "\the [target]")
|
||||
user.visible_message("<span class='[simple_style]'>[capitalize(use_message)]</span>")
|
||||
|
||||
/datum/interaction/proc/post_interaction(mob/living/user, mob/living/target)
|
||||
user.last_interaction_time = world.time + 6
|
||||
if(interaction_sound)
|
||||
playsound(get_turf(user), interaction_sound, 50, 1, -1)
|
||||
return
|
||||
/*
|
||||
/atom/movable/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(can_buckle && buckled_mob)
|
||||
if(user_unbuckle_mob(user))
|
||||
return TRUE
|
||||
|
||||
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
. = ..()
|
||||
if(can_buckle && istype(M) && !buckled_mob)
|
||||
if(user_buckle_mob(M, user))
|
||||
return TRUE
|
||||
|
||||
|
||||
/atom/movable/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(can_buckle && buckled_mob)
|
||||
if(user_unbuckle_mob(user))
|
||||
return TRUE
|
||||
|
||||
/atom/movable/MouseDrop_T(mob/living/carbon/human/M, mob/living/user)
|
||||
. = ..()
|
||||
if(can_buckle && istype(M) && !buckled_mob)
|
||||
if(user_buckle_mob(M, user))
|
||||
return TRUE
|
||||
*/
|
||||
@@ -0,0 +1,71 @@
|
||||
/datum/interaction/handshake
|
||||
command = "handshake"
|
||||
description = "Shake their hand."
|
||||
simple_message = "USER shakes the hand of TARGET."
|
||||
require_user_hands = 1
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/pat
|
||||
command = "pat"
|
||||
description = "Pat their shoulder."
|
||||
simple_message = "USER pats TARGET's shoulder."
|
||||
require_user_hands = 1
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/cheer
|
||||
command = "cheer"
|
||||
description = "Cheer them on."
|
||||
require_user_mouth = 1
|
||||
simple_message = "USER cheers TARGET on!"
|
||||
|
||||
/datum/interaction/highfive
|
||||
command = "highfive"
|
||||
description = "Give them a high-five."
|
||||
require_user_mouth = 1
|
||||
simple_message = "USER high fives TARGET!"
|
||||
interaction_sound = 'sandcode/sound/interactions/slap.ogg'
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/headpat
|
||||
command = "headpat"
|
||||
description = "Pat their head. Aww..."
|
||||
require_user_hands = 1
|
||||
simple_message = "USER headpats TARGET!"
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/salute
|
||||
command = "salute"
|
||||
description = "Give them a firm salute!"
|
||||
require_user_hands = 1
|
||||
simple_message = "USER salutes TARGET sharply!"
|
||||
max_distance = 25
|
||||
|
||||
/datum/interaction/fistbump
|
||||
command = "fistbump"
|
||||
description = "Bump it!"
|
||||
require_user_hands = 1
|
||||
simple_message = "USER fistbumps TARGET! Yeah!"
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/pinkypromise
|
||||
command = "pinkypromise"
|
||||
description = "Make a pinky promise with them!"
|
||||
require_user_hands = 1
|
||||
simple_message = "USER hooks their pinky with TARGET's! Pinky Promise!"
|
||||
needs_physical_contact = 1
|
||||
|
||||
/datum/interaction/bird
|
||||
command = "bird"
|
||||
description = "Flip them the bird!"
|
||||
require_user_hands = 1
|
||||
simple_message = "USER gives TARGET the bird!"
|
||||
max_distance = 25
|
||||
|
||||
/datum/interaction/holdhand
|
||||
command = "holdhand"
|
||||
description = "Hold their hand."
|
||||
require_user_hands = 1
|
||||
simple_message = "USER holds TARGET's hand."
|
||||
max_distance = 25
|
||||
needs_physical_contact = 1
|
||||
max_distance = 25
|
||||
@@ -0,0 +1,84 @@
|
||||
/mob/proc/try_interaction()
|
||||
return
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/MouseDrop(var/mob/living/carbon/human/dropped_on, mob/living/carbon/human/user as mob)
|
||||
if(src != dropped_on && !src.restrained())
|
||||
try_interaction(dropped_on)
|
||||
return
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/mob/living/MouseDrop_T(mob/M as mob, mob/living/user as mob)
|
||||
. = ..()
|
||||
if(M == src || src == usr || M != usr)
|
||||
return
|
||||
if(usr.restrained())
|
||||
return
|
||||
|
||||
user.try_interaction(src)
|
||||
|
||||
/mob/living/verb/interact_with()
|
||||
set name = "Interact With"
|
||||
set desc = "Perform an interaction with someone."
|
||||
set category = "IC"
|
||||
set src in view()
|
||||
|
||||
if(!usr.restrained())
|
||||
usr.try_interaction(src)
|
||||
|
||||
/mob/living/silicon/robot/verb/toggle_gender() //Change to add silicon genderchanges. Experimental.
|
||||
set category = "IC"
|
||||
set name = "Set Gender"
|
||||
set desc = "Allows you to set your gender."
|
||||
|
||||
if(stat != CONSCIOUS)
|
||||
to_chat(usr, "<span class='warning'>You cannot toggle your gender while unconcious!</span>")
|
||||
return
|
||||
|
||||
var/choice = alert(src, "Select Gender.", "Gender", "Both", "Male", "Female")
|
||||
switch(choice)
|
||||
if("Both")
|
||||
src.has_penis = TRUE
|
||||
src.has_vagina = TRUE
|
||||
if("Male")
|
||||
src.has_penis = TRUE
|
||||
src.has_vagina = FALSE
|
||||
if("Female")
|
||||
src.has_penis = FALSE
|
||||
src.has_vagina = TRUE
|
||||
|
||||
/mob/living/try_interaction(mob/living/partner)
|
||||
var/dat
|
||||
if(partner != src)
|
||||
dat = "<B><HR><FONT size=3>Interacting with \the [partner]...</FONT></B><HR>"
|
||||
else
|
||||
dat = "<B><HR><FONT size=3>Interacting with yourself...</FONT></B><HR>"
|
||||
|
||||
dat += "You...<br>[list_interaction_attributes(src)]<hr>"
|
||||
if(partner != src)
|
||||
dat += "They...<br>[partner.list_interaction_attributes(src)]<hr>"
|
||||
|
||||
make_interactions()
|
||||
for(var/interaction_key in interactions)
|
||||
var/datum/interaction/I = interactions[interaction_key]
|
||||
if(I.evaluate_user(src) && I.evaluate_target(src, partner))
|
||||
dat += I.get_action_link_for(src, partner)
|
||||
|
||||
var/datum/browser/popup = new(usr, "interactions", "Interactions", 340, 480)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/*
|
||||
/atom/movable/attack_hand(mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(can_buckle && buckled_mob)
|
||||
if(user_unbuckle_mob(user))
|
||||
return 1
|
||||
|
||||
/atom/movable/MouseDrop_T(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(can_buckle && istype(M) && !buckled_mob)
|
||||
if(user_buckle_mob(M, user))
|
||||
return 1
|
||||
*/
|
||||
@@ -0,0 +1,50 @@
|
||||
/mob/living/proc/has_hands()
|
||||
return FALSE
|
||||
|
||||
/mob/living/has_hands()
|
||||
return TRUE//(can_use_hand("l_hand") || can_use_hand("r_hand"))
|
||||
|
||||
/mob/living/proc/has_mouth()
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/mouth_is_free()
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/foot_is_free()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/has_mouth()
|
||||
var/obj/item/bodypart/head/headass
|
||||
for(var/obj/item/bodypart/head/shoeonhead in bodyparts)
|
||||
headass = shoeonhead
|
||||
if(headass)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/mouth_is_free()
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
return !H.wear_mask
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/mob/living/foot_is_free()
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
return !H.shoes
|
||||
else
|
||||
return TRUE
|
||||
|
||||
///atom/movable/attack_hand(mob/living/carbon/human/user)
|
||||
// . = ..()
|
||||
// if(can_buckle && buckled_mob)
|
||||
// if(user_unbuckle_mob(user))
|
||||
// return 1
|
||||
/*
|
||||
/atom/movable/MouseDrop_T(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(can_buckle && istype(M) && !buckled_mob)
|
||||
if(user_buckle_mob(M, user))
|
||||
return TRUE
|
||||
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
/mob/living/proc/do_jackoff(mob/living/user)
|
||||
var/message
|
||||
var/t_His = p_their()
|
||||
var/t_Him = p_them()
|
||||
|
||||
if(user.is_fucking(src, CUM_TARGET_HAND))
|
||||
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(src, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_PENIS) ? user.getorganslot(ORGAN_SLOT_PENIS) : null)
|
||||
|
||||
playlewdinteractionsound(src, pick('sandcode/sound/interactions/bang1.ogg',
|
||||
'sandcode/sound/interactions/bang2.ogg',
|
||||
'sandcode/sound/interactions/bang3.ogg'), 70, 1, -1)
|
||||
visible_message(message = "<font color=purple><b>\The [src]</b> [message]</font>") //can't not consent to yourself, if you did it, you wanted it
|
||||
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
|
||||
|
||||
/mob/living/proc/do_fingerass_self(mob/living/user)
|
||||
var/t_His = p_their()
|
||||
var/t_Him = p_them()
|
||||
|
||||
visible_message(message = "<font color=purple><b>\The [src]</b> [pick("fingers [t_Him]self.",
|
||||
"fingers [t_His] asshole.",
|
||||
"fingers [t_Him]self hard.")]</font>") //can't not consent to yourself, if you did it, you wanted it
|
||||
playlewdinteractionsound(loc, 'sandcode/sound/interactions/champ_fingering.ogg', 50, 1, -1)
|
||||
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
|
||||
|
||||
/mob/living/proc/do_fingering_self(mob/living/user)
|
||||
var/t_His = p_their()
|
||||
|
||||
visible_message(message = "<font color=purple><b>\The [src]</b> [pick("fingers [t_His] pussy deep.",
|
||||
"fingers [t_His] pussy.",
|
||||
"plays with [t_His] pussy.",
|
||||
"fingers [t_His] own pussy hard.")]</font>") //can't not consent to yourself, if you did it, you wanted it
|
||||
playlewdinteractionsound(loc, 'sandcode/sound/interactions/champ_fingering.ogg', 50, 1, -1)
|
||||
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
|
||||
|
||||
/mob/living/proc/do_titgrope_self(mob/living/user)
|
||||
var/message
|
||||
var/t_His = 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.")]"
|
||||
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()))
|
||||
visible_message(message = "<font color=purple><b>\The [src]</b> [pick("shivers in arousal.",
|
||||
"moans quietly.",
|
||||
"breathes out a soft moan.",
|
||||
"gasps.",
|
||||
"shudders softly.",
|
||||
"trembles as [t_His] hands run across bare skin.")]</font>")
|
||||
visible_message(message = "<font color=purple><b>\The [src]</b> [message]</font>") //can't not consent to yourself, if you did it, you wanted it
|
||||
playlewdinteractionsound(loc, 'sandcode/sound/interactions/squelch1.ogg', 50, 1, -1)
|
||||
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
|
||||
@@ -0,0 +1,613 @@
|
||||
/datum/interaction/lewd
|
||||
var/list/blacklisted_mobs = list(/mob/living/simple_animal/pet,
|
||||
/mob/living/simple_animal/cockroach,
|
||||
/mob/living/simple_animal/babyKiwi,
|
||||
/mob/living/simple_animal/butterfly,
|
||||
/mob/living/simple_animal/chick,
|
||||
/mob/living/simple_animal/chicken,
|
||||
/mob/living/simple_animal/cow,
|
||||
/mob/living/simple_animal/crab,
|
||||
/mob/living/simple_animal/kiwi,
|
||||
/mob/living/simple_animal/parrot,
|
||||
/mob/living/simple_animal/sloth,
|
||||
/mob/living/simple_animal/pickle,
|
||||
/mob/living/simple_animal/hostile/retaliate/goat)
|
||||
|
||||
/datum/interaction/lewd/kiss
|
||||
command = "deepkiss"
|
||||
description = "Kiss them deeply."
|
||||
require_user_mouth = TRUE
|
||||
require_target_mouth = TRUE
|
||||
write_log_user = "kissed"
|
||||
write_log_target = "was kissed by"
|
||||
interaction_sound = null
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/kiss/post_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
. = ..()
|
||||
if(user.get_lust() < 5)
|
||||
user.set_lust(5)
|
||||
if(target.get_lust() < 5)
|
||||
target.set_lust(5)
|
||||
|
||||
/datum/interaction/lewd/kiss/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
if(user.get_lust() >= 3)
|
||||
user.visible_message("<font color=purple>\The <b>[user]</b> gives an intense, lingering kiss to \the <b>[target]</b>.</font>")
|
||||
else
|
||||
user.visible_message("<font color=purple>\The <b>[user]</b> kisses \the <b>[target]</b> deeply.</font>")
|
||||
|
||||
/datum/interaction/lewd/titgrope
|
||||
command = "titgrope"
|
||||
description = "Grope their breasts."
|
||||
require_target_breasts = REQUIRE_ANY
|
||||
write_log_user = "groped"
|
||||
write_log_target = "was groped by"
|
||||
interaction_sound = null
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/titgrope/post_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
. = ..()
|
||||
|
||||
/datum/interaction/lewd/titgrope/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[user]</b> gently gropes \the <b>[target]</b>'s breast.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> softly squeezes \the <b>[target]</b>'s breasts.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> grips \the <b>[target]</b>'s breasts.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> runs a few fingers over \the <b>[target]</b>'s breast.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> delicately teases \the <b>[target]</b>'s nipple.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> traces a touch across \the <b>[target]</b>'s breast.</font>"))
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[user]</b> aggressively gropes \the <b>[target]</b>'s breast.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> grabs \the <b>[target]</b>'s breasts.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> tightly squeezes \the <b>[target]</b>'s breasts.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> slaps at \the <b>[target]</b>'s breasts.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> gropes \the <b>[target]</b>'s breasts roughly.</font>"))
|
||||
if(prob(5 + target.get_lust()))
|
||||
if(target.a_intent == INTENT_HELP)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> shivers in arousal.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> moans quietly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> breathes out a soft moan.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> gasps.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> shudders softly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> trembles as hands run across bare skin.</font>"))
|
||||
if(target.get_lust() < 5)
|
||||
target.set_lust(5)
|
||||
if(target.a_intent == INTENT_DISARM)
|
||||
if (target.restrained())
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> twists playfully against the restraints.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from <b>[user]</b>'s hand.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> slides back from <b>[user]</b>'s roaming hand.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> thrusts bare breasts forward into <b>[user]</b>'s hands.</font>"))
|
||||
else
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> playfully bats at <b>[user]</b>'s hand.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from <b>[user]</b>'s hand.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> guides <b>[user]</b>'s hand across bare breasts.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> teasingly laces a few fingers over <b>[user]</b>'s knuckles.</font>"))
|
||||
if(target.get_lust() < 10)
|
||||
target.add_lust(1)
|
||||
if(target.a_intent == INTENT_GRAB)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> grips <b>[user]</b>'s wrist tight.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> digs nails into <b>[user]</b>'s arm.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> grabs <b>[user]</b>'s wrist for a second.</font>"))
|
||||
if(target.a_intent == INTENT_HARM)
|
||||
user.adjustBruteLoss(1)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> pushes <b>[user]</b> roughly away.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> digs nails angrily into <b>[user]</b>'s arm.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> fiercely struggles against <b>[user]</b>.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> claws <b>[user]</b>'s forearm, drawing blood.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> slaps <b>[user]</b>'s hand away.</font>"))
|
||||
return
|
||||
|
||||
/datum/interaction/lewd/nipsuck
|
||||
command = "nipsuck"
|
||||
description = "Suck their nipples."
|
||||
require_target_topless = TRUE
|
||||
require_user_mouth = TRUE
|
||||
write_log_user = "sucked nipples"
|
||||
write_log_target = "had their nipples sucked by"
|
||||
interaction_sound = null
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/nipsuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
if((user.a_intent == INTENT_HELP) || (user.a_intent == INTENT_DISARM))
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[user]</b> gently sucks on \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>",
|
||||
"<font color=purple>\The <b>[user]</b> gently nibs \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>",
|
||||
"<font color=purple>\The <b>[user]</b> licks \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>"))
|
||||
if(target.has_breasts(REQUIRE_EXPOSED))
|
||||
var/modifier = 1
|
||||
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
switch(B.size)
|
||||
if("c" || "d" || "e")
|
||||
modifier = 2
|
||||
if("f" || "g" || "h")
|
||||
modifier = 3
|
||||
if("i")
|
||||
modifier = 4
|
||||
if("j")
|
||||
modifier = 5
|
||||
else
|
||||
modifier = 1
|
||||
target.reagents.add_reagent(/datum/reagent/consumable/milk, rand(1,2 * modifier))
|
||||
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[user]</b> bites \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>",
|
||||
"<font color=purple>\The <b>[user]</b> aggressively sucks \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>"))
|
||||
if(target.has_breasts(REQUIRE_EXPOSED))
|
||||
var/modifier = 1
|
||||
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
switch(B.size)
|
||||
if("c" || "d" || "e")
|
||||
modifier = 2
|
||||
if("f" || "g" || "h")
|
||||
modifier = 3
|
||||
if("i")
|
||||
modifier = 4
|
||||
if("j")
|
||||
modifier = 5
|
||||
else
|
||||
modifier = 1
|
||||
target.reagents.add_reagent(/datum/reagent/consumable/milk, rand(1,3 * modifier)) //aggressive sucking leads to high rewards
|
||||
|
||||
if(user.a_intent == INTENT_GRAB)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[user]</b> sucks \the <b>[target]</b>'s [pick("nipple", "nipples")] intently.</font>",
|
||||
"<font color=purple>\The <b>[user]</b> feasts \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>",
|
||||
"<font color=purple>\The <b>[user]</b> glomps \the <b>[target]</b>'s [pick("nipple", "nipples")].</font>"))
|
||||
if(target.has_breasts(REQUIRE_EXPOSED))
|
||||
var/modifier = 1
|
||||
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
switch(B.size)
|
||||
if("c" || "d" || "e")
|
||||
modifier = 2
|
||||
if("f" || "g" || "h")
|
||||
modifier = 3
|
||||
if("i")
|
||||
modifier = 4
|
||||
if("j")
|
||||
modifier = 5
|
||||
else
|
||||
modifier = 1
|
||||
target.reagents.add_reagent(/datum/reagent/consumable/milk, rand(1,3 * modifier)) //aggressive sucking leads to high rewards
|
||||
|
||||
if(prob(5 + target.get_lust()))
|
||||
if(target.a_intent == INTENT_HELP)
|
||||
if(!target.has_breasts())
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> shivers in arousal.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> moans quietly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> breathes out a soft moan.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> gasps.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> shudders softly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> trembles as their chest gets molested.</font>"))
|
||||
else
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> shivers in arousal.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> moans quietly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> breathes out a soft moan.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> gasps.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> shudders softly.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> trembles as their breasts get molested.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> quivers in arousal as \the <b>[user]</b> delights themselves on their milk.</font>"))
|
||||
if(target.get_lust() < 5)
|
||||
target.set_lust(5)
|
||||
if(target.a_intent == INTENT_DISARM)
|
||||
if (target.restrained())
|
||||
if(!target.has_breasts())
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> twists playfully against the restraints.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> thrusts their bare chest forward into \the <b>[user]</b>'s mouth.</font>"))
|
||||
else
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> twists playfully against the restraints.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> thrust their bare breasts forward into \the <b>[user]</b>'s mouth.</font>"))
|
||||
else
|
||||
if(!target.has_breasts())
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> holds \the <b>[user]</b>'s head against their chest.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck.</font>"))
|
||||
else
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> holds \the <b>[user]</b>'s head against their breast.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> rubs their breasts against \the <b>[user]</b>'s head.</font>"))
|
||||
if(target.get_lust() < 10)
|
||||
target.add_lust(1)
|
||||
if(target.a_intent == INTENT_GRAB)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> grips \the <b>[user]</b>'s head tight.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> digs nails into \the <b>[user]</b>'s scalp.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> grabs and shoves \the <b>[user]</b>'s head away.</font>"))
|
||||
if(target.a_intent == INTENT_HARM)
|
||||
user.adjustBruteLoss(1)
|
||||
user.visible_message(
|
||||
pick("<font color=purple>\The <b>[target]</b> slaps \the <b>[user]</b> away.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> scratches <b>[user]</b>'s face.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> fiercely struggles against <b>[user]</b>.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> claws <b>[user]</b>'s face, drawing blood.</font>",
|
||||
"<font color=purple>\The <b>[target]</b> elbows <b>[user]</b>'s mouth away.</font>"))
|
||||
target.dir = get_dir(target, user)
|
||||
user.dir = get_dir(user, target)
|
||||
playlewdinteractionsound(user.loc, pick('sandcode/sound/interactions/oral1.ogg',
|
||||
'sandcode/sound/interactions/oral2.ogg'), 70, 1, -1)
|
||||
return
|
||||
|
||||
/datum/interaction/lewd/oral
|
||||
command = "suckvag"
|
||||
description = "Go down on them."
|
||||
require_user_mouth = TRUE
|
||||
require_target_vagina = REQUIRE_EXPOSED
|
||||
write_log_user = "gave head to"
|
||||
write_log_target = "was given head by"
|
||||
interaction_sound = null
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/oral/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_oral(target, "vagina")
|
||||
|
||||
/datum/interaction/lewd/oral/blowjob
|
||||
command = "suckcock"
|
||||
description = "Suck them off."
|
||||
require_target_vagina = REQUIRE_NONE
|
||||
require_target_penis = REQUIRE_EXPOSED
|
||||
target_not_tired = TRUE
|
||||
|
||||
/datum/interaction/lewd/oral/blowjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_oral(target, "penis")
|
||||
|
||||
/datum/interaction/lewd/fuck
|
||||
command = "fuckvag"
|
||||
description = "Fuck their pussy."
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_vagina = REQUIRE_EXPOSED
|
||||
write_log_user = "fucked"
|
||||
write_log_target = "was fucked by"
|
||||
interaction_sound = null
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/fuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_vaginal(target)
|
||||
|
||||
/datum/interaction/lewd/fuck/anal
|
||||
command = "fuckass"
|
||||
description = "Fuck their ass."
|
||||
require_target_vagina = REQUIRE_NONE
|
||||
require_target_anus = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
|
||||
/datum/interaction/lewd/fuck/anal/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_anal(target)
|
||||
|
||||
/datum/interaction/lewd/finger
|
||||
command = "finger"
|
||||
description = "Finger their pussy."
|
||||
require_user_hands = REQUIRE_ANY
|
||||
require_target_vagina = REQUIRE_EXPOSED
|
||||
interaction_sound = null
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/finger/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_fingering(target)
|
||||
|
||||
/datum/interaction/lewd/fingerass
|
||||
command = "fingerm"
|
||||
description = "Finger their ass."
|
||||
interaction_sound = null
|
||||
require_user_hands = REQUIRE_ANY
|
||||
require_target_anus = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/fingerass/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_fingerass(target)
|
||||
|
||||
|
||||
/datum/interaction/lewd/facefuck
|
||||
command = "facefuck"
|
||||
description = "Fuck their mouth."
|
||||
interaction_sound = null
|
||||
require_target_mouth = TRUE
|
||||
user_not_tired = TRUE
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/facefuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_facefuck(target)
|
||||
|
||||
/datum/interaction/lewd/throatfuck
|
||||
command = "throatfuck"
|
||||
description = "Fuck their throat. | Does oxy damage."
|
||||
interaction_sound = null
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_mouth = TRUE
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/throatfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_throatfuck(target)
|
||||
|
||||
/datum/interaction/lewd/handjob
|
||||
command = "handjob"
|
||||
description = "Jerk them off."
|
||||
interaction_sound = null
|
||||
require_user_hands = TRUE
|
||||
require_target_penis = REQUIRE_EXPOSED
|
||||
target_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/handjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_handjob(target)
|
||||
|
||||
/datum/interaction/lewd/breastfuck
|
||||
command = "breastfuck"
|
||||
description = "Fuck their breasts."
|
||||
interaction_sound = null
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
require_target_breasts = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/breastfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_breastfuck(target)
|
||||
|
||||
/datum/interaction/lewd/mount
|
||||
command = "mount"
|
||||
description = "Mount with your pussy."
|
||||
interaction_sound = null
|
||||
require_user_vagina = REQUIRE_EXPOSED
|
||||
require_target_penis = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
target_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/mount/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_mount(target)
|
||||
|
||||
/datum/interaction/lewd/mountass
|
||||
command = "mountm"
|
||||
description = "Mount with your ass."
|
||||
interaction_sound = null
|
||||
require_user_anus = REQUIRE_EXPOSED
|
||||
require_target_penis = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
target_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/mountass/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_mountass(target)
|
||||
|
||||
/datum/interaction/lewd/tribadism
|
||||
command = "tribadism"
|
||||
description = "Grind your pussy against theirs."
|
||||
interaction_sound = null
|
||||
require_target_vagina = REQUIRE_EXPOSED
|
||||
require_user_vagina = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/tribadism/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_tribadism(target)
|
||||
|
||||
/datum/interaction/lewd/rimjob
|
||||
command = "rimjob"
|
||||
description = "Lick their ass."
|
||||
interaction_sound = null
|
||||
require_user_mouth = TRUE
|
||||
require_target_anus = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/rimjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_rimjob(target)
|
||||
|
||||
/datum/interaction/lewd/mountface
|
||||
command = "mountface"
|
||||
description = "Ass to face."
|
||||
interaction_sound = null
|
||||
require_target_mouth = TRUE
|
||||
require_user_anus = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/mountface/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_mountface(target)
|
||||
|
||||
/datum/interaction/lewd/lickfeet
|
||||
command = "lickfeet"
|
||||
description = "Lick their feet."
|
||||
interaction_sound = null
|
||||
require_user_mouth = TRUE
|
||||
require_target_feet = REQUIRE_ANY
|
||||
require_target_num_feet = 1
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/lickfeet/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_lickfeet(target)
|
||||
|
||||
/datum/interaction/lewd/grindface
|
||||
command = "grindface"
|
||||
description = "Feet grind their face."
|
||||
interaction_sound = null
|
||||
require_target_mouth = TRUE
|
||||
require_user_num_feet = 1
|
||||
require_user_feet = REQUIRE_ANY
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/grindface/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_grindface(target)
|
||||
|
||||
/datum/interaction/lewd/grindmouth
|
||||
command = "grindmouth"
|
||||
description = "Feet grind their mouth."
|
||||
interaction_sound = null
|
||||
require_target_mouth = TRUE
|
||||
require_user_num_feet = 1
|
||||
require_user_feet = REQUIRE_ANY
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/grindmouth/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_grindmouth(target)
|
||||
|
||||
/datum/interaction/lewd/footfuck
|
||||
command = "footfuck"
|
||||
description = "Rub your cock on their foot."
|
||||
interaction_sound = null
|
||||
require_target_num_feet = 1
|
||||
require_target_feet = REQUIRE_ANY
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/footfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_footfuck(target)
|
||||
|
||||
/datum/interaction/lewd/footfuck/double
|
||||
command = "footfuckdouble"
|
||||
description = "Rub your cock between their feet."
|
||||
require_target_num_feet = 2
|
||||
|
||||
/datum/interaction/lewd/footfuck/double/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_dfootfuck(target)
|
||||
|
||||
/datum/interaction/lewd/footjob
|
||||
command = "footjob"
|
||||
description = "Jerk them off with your foot."
|
||||
interaction_sound = null
|
||||
require_user_num_feet = 1
|
||||
require_user_feet = REQUIRE_ANY
|
||||
require_target_penis = REQUIRE_EXPOSED
|
||||
target_not_tired = TRUE
|
||||
max_distance = 1
|
||||
|
||||
/datum/interaction/lewd/footjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_footjob(target)
|
||||
|
||||
/datum/interaction/lewd/footjob/double
|
||||
command = "footjob_double"
|
||||
description = "Jerk them off with both of your feet."
|
||||
require_user_num_feet = 2
|
||||
|
||||
/datum/interaction/lewd/footjob/double/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_dfootjob(target)
|
||||
|
||||
/datum/interaction/lewd/footjob/vagina
|
||||
command = "footjob_vaginal"
|
||||
description = "Rub their vagina with your foot."
|
||||
require_target_vagina = REQUIRE_EXPOSED
|
||||
require_target_penis = REQUIRE_NONE
|
||||
|
||||
/datum/interaction/lewd/footjob/vagina/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_footjob_v(target)
|
||||
|
||||
/datum/interaction/lewd/thighs
|
||||
command = "thigh_smother"
|
||||
description = "Smother them."
|
||||
max_distance = 1
|
||||
require_user_bottomless = TRUE
|
||||
require_target_mouth = TRUE
|
||||
interaction_sound = null
|
||||
user_not_tired = TRUE
|
||||
write_log_user = "thigh-trapped"
|
||||
write_log_target = "was smothered by"
|
||||
|
||||
/datum/interaction/lewd/thighs/display_interaction(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
|
||||
user.thigh_smother(target)
|
||||
|
||||
/datum/interaction/lewd/nuts
|
||||
command = "nut_face"
|
||||
description = "Nuts to face."
|
||||
interaction_sound = null
|
||||
require_user_balls = REQUIRE_EXPOSED
|
||||
require_target_mouth = TRUE
|
||||
max_distance = 1
|
||||
write_log_user = "make-them-suck-their-nuts"
|
||||
write_log_target = "was made to suck nuts by"
|
||||
|
||||
/datum/interaction/lewd/nuts/display_interaction(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
|
||||
user.nut_face(target)
|
||||
|
||||
/datum/interaction/lewd/nut_smack
|
||||
command = "smack_nuts"
|
||||
description = "Smack their nuts."
|
||||
interaction_sound = 'sandcode/sound/interactions/slap.ogg'
|
||||
simple_message = "USER slaps TARGET's nuts!"
|
||||
require_target_balls = REQUIRE_EXPOSED
|
||||
needs_physical_contact = TRUE
|
||||
max_distance = 1
|
||||
write_log_user = "slapped-nuts"
|
||||
write_log_target = "had their nuts slapped by"
|
||||
|
||||
//Weird shit section
|
||||
/datum/interaction/lewd/earfuck
|
||||
command = "earfuck"
|
||||
description = "Fuck their ear."
|
||||
interaction_sound = null
|
||||
simple_message = "USER penetrates TARGET's ear!"
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_ears = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
write_log_user = "earfucked"
|
||||
write_log_target = "had their ear fucked by"
|
||||
extreme = TRUE
|
||||
|
||||
/datum/interaction/lewd/earfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_earfuck(target)
|
||||
|
||||
/datum/interaction/lewd/earfuck/earsocketfuck
|
||||
command = "earsocketfuck"
|
||||
description = "Fuck their earsocket."
|
||||
interaction_sound = null
|
||||
simple_message = "USER penetrates TARGET's earsocket!"
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_earsockets = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
write_log_user = "earsocket fucked"
|
||||
write_log_target = "had their earsocket fucked by"
|
||||
extreme = TRUE
|
||||
|
||||
/datum/interaction/lewd/eyefuck
|
||||
command = "eyefuck"
|
||||
description = "Fuck their eye."
|
||||
interaction_sound = null
|
||||
simple_message = "USER penetrates TARGET's eye!"
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_eyes = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
write_log_user = "eyefucked"
|
||||
write_log_target = "had their eye fucked by"
|
||||
extreme = TRUE
|
||||
|
||||
/datum/interaction/lewd/eyefuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
user.do_eyefuck(target)
|
||||
|
||||
/datum/interaction/lewd/eyefuck/eyesocketfuck
|
||||
command = "eyesocketfuck"
|
||||
description = "Fuck their eyesocket."
|
||||
interaction_sound = null
|
||||
simple_message = "USER penetrates TARGET's eyesocket!"
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
require_target_eyesockets = REQUIRE_EXPOSED
|
||||
max_distance = 1
|
||||
write_log_user = "eyesocketfucked"
|
||||
write_log_target = "had their eyesocket fucked by"
|
||||
extreme = TRUE
|
||||
//
|
||||
@@ -0,0 +1,49 @@
|
||||
/datum/interaction/lewd/jack
|
||||
command = "jack"
|
||||
description = "Jerk yourself off."
|
||||
interaction_sound = null
|
||||
require_user_hands = REQUIRE_ANY
|
||||
require_user_penis = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
user_is_target = TRUE
|
||||
max_distance = 0
|
||||
|
||||
/datum/interaction/lewd/jack/display_interaction(mob/living/carbon/human/user)
|
||||
user.do_jackoff(user)
|
||||
|
||||
/datum/interaction/lewd/fingerass_self
|
||||
command = "fingerm_self"
|
||||
description = "Finger yourself."
|
||||
interaction_sound = null
|
||||
require_user_hands = REQUIRE_ANY
|
||||
require_user_anus = REQUIRE_EXPOSED
|
||||
user_not_tired = TRUE
|
||||
user_is_target = TRUE
|
||||
max_distance = 0
|
||||
|
||||
/datum/interaction/lewd/fingerass_self/display_interaction(mob/living/carbon/human/user)
|
||||
user.do_fingerass_self(user)
|
||||
|
||||
/datum/interaction/lewd/finger_self
|
||||
command = "finger_self"
|
||||
description = "Finger your own pussy."
|
||||
require_user_hands = REQUIRE_ANY
|
||||
require_user_vagina = REQUIRE_EXPOSED
|
||||
interaction_sound = null
|
||||
user_not_tired = TRUE
|
||||
user_is_target = TRUE
|
||||
max_distance = 0
|
||||
|
||||
/datum/interaction/lewd/finger_self/display_interaction(mob/living/carbon/human/user)
|
||||
user.do_fingering_self(user)
|
||||
|
||||
/datum/interaction/lewd/titgrope_self
|
||||
command = "titgrope_self"
|
||||
description = "Grope your own breasts."
|
||||
require_user_breasts = REQUIRE_ANY
|
||||
user_is_target = TRUE
|
||||
interaction_sound = null
|
||||
max_distance = 0
|
||||
|
||||
/datum/interaction/lewd/titgrope_self/display_interaction(mob/living/carbon/human/user)
|
||||
user.do_titgrope_self(user)
|
||||
@@ -0,0 +1,583 @@
|
||||
// If I could have gotten away with using a tilde in the type path, I would have.
|
||||
/datum/interaction/lewd
|
||||
command = "assslap"
|
||||
description = "Slap their ass."
|
||||
simple_message = "USER slaps TARGET right on the ass!"
|
||||
simple_style = "danger"
|
||||
interaction_sound = 'sound/weapons/slap.ogg'
|
||||
needs_physical_contact = TRUE
|
||||
require_ooc_consent = TRUE
|
||||
max_distance = 1
|
||||
|
||||
write_log_user = "ass-slapped"
|
||||
write_log_target = "was ass-slapped by"
|
||||
|
||||
var/user_not_tired
|
||||
var/target_not_tired
|
||||
//Avoid using these!
|
||||
//Should only really use in case there are no related organs
|
||||
//but you want the target or user to be topless/bottomless.
|
||||
//Example: Nipple licking/sucking.
|
||||
//Otherwise, simply use the "require" vars, which
|
||||
//i have changed to actually check for the appropriate organs.
|
||||
//This is better because it means that exposing a genital while still
|
||||
//wearing something actually means you can do the s*x.
|
||||
var/require_user_topless
|
||||
var/require_target_topless
|
||||
var/require_user_bottomless
|
||||
var/require_target_bottomless
|
||||
//
|
||||
|
||||
//REQUIRE_NONE for doesn't require.
|
||||
//REQUIRE_EXPOSED for requires exposed.
|
||||
//REQUIRE_ANY for both exposed and unexposed.
|
||||
//REQUIRE_UNEXPOSED for requires unexposed.
|
||||
var/require_user_penis
|
||||
var/require_user_anus
|
||||
var/require_user_vagina
|
||||
var/require_user_breasts
|
||||
var/require_user_feet
|
||||
var/require_user_balls
|
||||
|
||||
//Different from the others above. Use the number of required feet.
|
||||
var/require_user_num_feet
|
||||
|
||||
//Same logic presented before
|
||||
var/require_target_penis
|
||||
var/require_target_anus
|
||||
var/require_target_vagina
|
||||
var/require_target_breasts
|
||||
var/require_target_feet
|
||||
var/require_target_balls
|
||||
|
||||
var/require_target_num_feet
|
||||
|
||||
//"just fucking kill me" variables
|
||||
//also the same logic as before
|
||||
var/extreme = FALSE //Boolean. Used to hide extreme shit from those who do not want it.
|
||||
var/require_target_ears
|
||||
var/require_target_earsockets
|
||||
var/require_target_eyes
|
||||
var/require_target_eyesockets
|
||||
var/require_user_ears
|
||||
var/require_user_earsockets
|
||||
var/require_user_eyes
|
||||
var/require_user_eyesockets
|
||||
//
|
||||
|
||||
var/user_refractory_cost
|
||||
var/target_refractory_cost
|
||||
|
||||
/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE)
|
||||
if(..(user, silent))
|
||||
if(user_not_tired && user.get_refraction_dif())
|
||||
if(!silent) //bye spam
|
||||
to_chat(user, "<span class='warning'>You're still exhausted from the last time. You need to wait [DisplayTimeText(user.get_refraction_dif(), TRUE)] until you can do that!</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_bottomless && !user.is_bottomless())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your pants are in the way.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_topless && !user.is_topless())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your top is in the way.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_penis)
|
||||
switch(require_user_penis)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_penis(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your penis need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_penis(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have a penis.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_penis(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your penis need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_balls)
|
||||
switch(require_user_balls)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_balls(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your balls need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_balls(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have balls.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_balls(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your balls need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_anus)
|
||||
switch(require_user_anus)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_anus(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your anus need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_anus(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have an anus.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_anus(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your anus need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_vagina)
|
||||
switch(require_user_vagina)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_vagina(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your vagina need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_vagina(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have a vagina.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_vagina(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your vagina need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_breasts)
|
||||
switch(require_user_breasts)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_breasts(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your breasts need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_breasts(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have breasts.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_breasts(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your breasts need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_feet)
|
||||
switch(require_user_feet)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_feet(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your feet need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_feet(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have enough feet.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_feet(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your feet need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_num_feet && (user.get_num_feet() < require_user_num_feet))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have enough feet.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_eyes)
|
||||
switch(require_user_eyes)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_eyes(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your eyes need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_eyes(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_eyes(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your eyes need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_eyesockets)
|
||||
switch(require_user_eyesockets)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_eyesockets(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your eyesockets need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_eyesockets(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You still have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_eyesockets(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your eyesockets need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_ears)
|
||||
switch(require_user_ears)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_ears(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your ears need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_ears(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You don't have ears.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_ears(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your ears need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_user_earsockets)
|
||||
switch(require_user_earsockets)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!user.has_earsockets(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your earsockets need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!user.has_earsockets(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>You still have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!user.has_earsockets(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Your earsockets need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(extreme)
|
||||
var/client/cli = user.client
|
||||
if(cli)
|
||||
if(cli.prefs.extremepref == "No")
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>That's way too much for you.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_ooc_consent)
|
||||
if(user.client && user.client.prefs.toggles & VERB_CONSENT)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
|
||||
if(..(user, target, silent))
|
||||
if(target_not_tired && target.get_refraction_dif())
|
||||
if(!silent) //same with this
|
||||
to_chat(user, "<span class='warning'>They're still exhausted from the last time. They need to wait [DisplayTimeText(target.get_refraction_dif(), TRUE)] until you can do that!</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_penis)
|
||||
switch(require_target_penis)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_penis(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their penis needs to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_penis(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have a penis.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_penis(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their penis needs to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_balls)
|
||||
switch(require_target_balls)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_balls(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their balls need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_balls(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have balls.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_balls(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their balls need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_anus)
|
||||
switch(require_target_anus)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_anus(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their anus needs to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_anus(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have an anus.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_anus(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their anus needs to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_vagina)
|
||||
switch(require_target_vagina)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_vagina(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their vagina needs to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_vagina(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have a vagina.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_vagina(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their vagina needs to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_breasts)
|
||||
switch(require_target_breasts)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_breasts(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their breasts need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_breasts(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have breasts.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_breasts(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their breasts need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_feet)
|
||||
switch(require_target_feet)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_feet(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their feet need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_feet(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have enough feet.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_feet(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their feet need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_num_feet && (user.get_num_feet() < require_target_num_feet))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have enough feet.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_eyes)
|
||||
switch(require_target_eyes)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_eyes(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their eyes need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_eyes(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_eyes(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their eyes need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_eyesockets)
|
||||
switch(require_target_eyesockets)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_eyesockets(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their eyesockets need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_eyesockets(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They still have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_eyesockets(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their eyesockets need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_ears)
|
||||
switch(require_target_ears)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_ears(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their ears need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_ears(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They don't have ears.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_ears(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their ears need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_earsockets)
|
||||
switch(require_target_earsockets)
|
||||
if(REQUIRE_EXPOSED)
|
||||
if(!target.has_earsockets(REQUIRE_EXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their earsockets need to be exposed.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_ANY)
|
||||
if(!target.has_earsockets(REQUIRE_ANY))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>They still have eyes.</span>")
|
||||
return FALSE
|
||||
if(REQUIRE_UNEXPOSED)
|
||||
if(!target.has_earsockets(REQUIRE_UNEXPOSED))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their earsockets need to be unexposed.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_bottomless && !target.is_bottomless())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their clothes are in the way.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_topless && !target.is_topless())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their clothes are in the way.</span>")
|
||||
return FALSE
|
||||
|
||||
if(extreme)
|
||||
var/client/cli = target.client
|
||||
if(cli)
|
||||
if(target.client.prefs.extremepref == "No")
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>For some reason, you don't want to do this to [target].</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_target_bottomless && !target.is_bottomless())
|
||||
if(!silent)
|
||||
to_chat(user, "<span class = 'warning'>Their pants are in the way.</span>")
|
||||
return FALSE
|
||||
|
||||
if(require_ooc_consent)
|
||||
if(target.client && target.client.prefs.toggles & VERB_CONSENT)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/datum/interaction/lewd/post_interaction(mob/living/user, mob/living/target)
|
||||
if(user_refractory_cost)
|
||||
user.refractory_period = world.time + user_refractory_cost*10
|
||||
if(target_refractory_cost)
|
||||
target.refractory_period = world.time + target_refractory_cost*10
|
||||
user.last_lewd_datum = src
|
||||
if(user.cleartimer)
|
||||
deltimer(user.cleartimer)
|
||||
user.cleartimer = addtimer(CALLBACK(user, /mob/living/proc/clear_lewd_datum), 300, TIMER_STOPPABLE)
|
||||
return ..()
|
||||
|
||||
/datum/interaction/lewd/get_action_link_for(mob/living/user, mob/living/target)
|
||||
if(user.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>You cannot do that while deceased!</span>")
|
||||
return
|
||||
if(extreme)
|
||||
return "<font color='#FF0000'><b>EXTREME:</b></font> [..()]"
|
||||
return "<font color='#FF0000'><b>LEWD:</b></font> [..()]"
|
||||
|
||||
/mob/living/list_interaction_attributes(var/mob/living/LM)
|
||||
var/dat = ..()
|
||||
if(get_refraction_dif())
|
||||
dat += "<br>...are sexually exhausted for the time being."
|
||||
if(a_intent == INTENT_HELP)
|
||||
dat += "<br>...are acting gentle."
|
||||
else if (a_intent == INTENT_DISARM)
|
||||
dat += "<br>...are acting playful."
|
||||
else if (a_intent == INTENT_GRAB)
|
||||
dat += "<br>...are acting rough."
|
||||
else if(a_intent == INTENT_HARM)
|
||||
dat += "<br>...are fighting anyone who comes near."
|
||||
//Here comes the fucking weird shit.
|
||||
if(client)
|
||||
var/client/cli = client
|
||||
var/client/ucli = LM.client
|
||||
if(cli.prefs.extremepref != "No")
|
||||
if(!ucli || (ucli.prefs.extremepref != "No"))
|
||||
if(!get_item_by_slot(ITEM_SLOT_EARS))
|
||||
if(has_ears())
|
||||
dat += "<br>...have unprotected ears."
|
||||
else
|
||||
dat += "<br>...have a hole where their ears should be."
|
||||
else
|
||||
dat += "<br>...have covered ears."
|
||||
if(!get_item_by_slot(ITEM_SLOT_EYES))
|
||||
if(has_eyes())
|
||||
dat += "<br>...have exposed eyes."
|
||||
else
|
||||
dat += "<br>...have exposed eyesockets."
|
||||
else
|
||||
dat += "<br>...have covered eyes."
|
||||
//
|
||||
if(is_topless() && is_bottomless())
|
||||
dat += "<br>...are naked."
|
||||
else
|
||||
if((is_topless() && !is_bottomless()) || (!is_topless() && is_bottomless()))
|
||||
dat += "<br>...are partially clothed."
|
||||
else
|
||||
dat += "<br>...are clothed."
|
||||
if(has_breasts(REQUIRE_EXPOSED))
|
||||
dat += "<br>...have breasts."
|
||||
if(has_penis(REQUIRE_EXPOSED))
|
||||
dat += "<br>...have a penis."
|
||||
if(has_balls(REQUIRE_EXPOSED))
|
||||
dat += "<br>...have a ballsack."
|
||||
if(has_vagina(REQUIRE_EXPOSED))
|
||||
dat += "<br>...have a vagina."
|
||||
if(has_anus(REQUIRE_EXPOSED))
|
||||
dat += "<br>...have an anus."
|
||||
if(has_feet(REQUIRE_EXPOSED))
|
||||
switch(has_feet(REQUIRE_EXPOSED))
|
||||
if(2)
|
||||
dat += "<br>...have a pair of feet."
|
||||
if(1)
|
||||
dat += "<br>...have a single foot."
|
||||
return dat
|
||||
@@ -0,0 +1,16 @@
|
||||
/datum/species
|
||||
var/has_genitals = TRUE //if this goes to 2, blame coders
|
||||
var/has_anus = TRUE //same with this
|
||||
var/has_breasts = FALSE
|
||||
|
||||
/datum/species/proc/has_penis(mob/living/carbon/human/H)
|
||||
return has_genitals && H.has_penis
|
||||
|
||||
/datum/species/proc/has_vagina(mob/living/carbon/human/H)
|
||||
return has_genitals && H.has_vagina
|
||||
|
||||
/datum/species/proc/has_anus(mob/living/carbon/human/H)
|
||||
return has_anus
|
||||
|
||||
/datum/species/proc/has_breasts(mob/living/carbon/human/H)
|
||||
return has_breasts || (H.has_breasts)
|
||||
@@ -0,0 +1,171 @@
|
||||
//Dildo changes.
|
||||
/obj/item/dildo
|
||||
/*name = "dildo"
|
||||
desc = "Hmmm, deal throw."
|
||||
icon = 'honk/icons/obj/items/dildo.dmi'
|
||||
icon_state = "dildo_map"
|
||||
item_state = "dildo"
|
||||
throwforce = 0
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("slammed", "bashed", "whipped")*/
|
||||
|
||||
var/hole = CUM_TARGET_VAGINA
|
||||
|
||||
/*var/random_color = TRUE
|
||||
var/static/list/dildo_colors = list(
|
||||
"purple" = "#800080",
|
||||
"darkviolet" = "#9400D3",
|
||||
"red" = "#FF0000",
|
||||
"dimgray" = "#696969",
|
||||
"black" = "#000000", //dont kill me for this - lennuel
|
||||
"white" = "#ffffff", //racial equality
|
||||
"green" = "#008000",
|
||||
"pink" = "#FFC0CB",
|
||||
"lightpink" = "#ffc0cb",
|
||||
"blue" = "#7282e5"
|
||||
)
|
||||
|
||||
/obj/item/dildo/Initialize()
|
||||
. = ..()
|
||||
if(random_color) //random colors!
|
||||
icon_state = "dildo"
|
||||
var/our_color = pick(dildo_colors)
|
||||
add_atom_colour(dildo_colors[our_color], FIXED_COLOUR_PRIORITY)
|
||||
update_icon()
|
||||
|
||||
/obj/item/dildo/update_icon()
|
||||
if(!random_color) //icon override
|
||||
return
|
||||
cut_overlays()
|
||||
var/mutable_appearance/base_overlay = mutable_appearance(icon, "dildo_base")
|
||||
base_overlay.appearance_flags = RESET_COLOR
|
||||
add_overlay(base_overlay) */
|
||||
|
||||
/obj/item/dildo/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
var/message = ""
|
||||
if(istype(M, /mob/living/carbon/human) && user.zone_selected == BODY_ZONE_PRECISE_GROIN && M.is_bottomless())
|
||||
if(M.client && M.client.prefs)
|
||||
if(M.client.prefs.toggles & VERB_CONSENT)
|
||||
if(hole == CUM_TARGET_VAGINA && M.has_vagina())
|
||||
message = (user == M) ? pick("fucks their own pussy with \the [src]","shoves \the [src] into their pussy", "jams \the [src] into their pussy") : pick("fucks [M] right in the pussy with \the [src]", "jams \the [src] right into [M]'s pussy")
|
||||
else if(hole == CUM_TARGET_ANUS && M.has_anus())
|
||||
message = (user == M) ? pick("fucks their own ass with \the [src]","shoves \the [src] into their ass", "jams \the [src] into their ass") : pick("fucks [M]'s asshole with \the [src]", "jams \the [src] into [M]'s ass")
|
||||
else if(istype(M, /mob/living/carbon/human) && user.zone_selected == BODY_ZONE_PRECISE_MOUTH && M.mouth_is_free())
|
||||
if(M.client && M.client.prefs)
|
||||
if(M.client.prefs.toggles & VERB_CONSENT)
|
||||
if(M.has_mouth())
|
||||
message = (user == M) ? pick("fucks their own mouth with \the [src]", "shoves \the [src] into their mouth", "jams \the [src] into their mouth") : pick("fucks [M]'s mouth with \the [src]", "jams \the [src] into [M]'s mouth")
|
||||
if(message)
|
||||
user.visible_message("<font color=purple>[user] [message].</font>")
|
||||
M.handle_post_sex(5, null, user)
|
||||
playsound(loc, pick('sandcode/sound/interactions/bang4.ogg',
|
||||
'sandcode/sound/interactions/bang5.ogg',
|
||||
'sandcode/sound/interactions/bang6.ogg'), 70, 1, -1)
|
||||
else if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
/obj/item/dildo/attack_self(mob/living/carbon/human/user as mob)
|
||||
if(hole == CUM_TARGET_VAGINA)
|
||||
hole = CUM_TARGET_ANUS
|
||||
else
|
||||
hole = CUM_TARGET_VAGINA
|
||||
to_chat(user, "<span class='warning'>Hmmm. Maybe we should put it in \a [hole]?</span>")
|
||||
|
||||
//reagent here
|
||||
/*datum/reagent/consumable/cum // could probably be made /blood/consumable/cum to just inherit the DNA procs sometime
|
||||
name = "cum"
|
||||
id = "cum"
|
||||
description = "Where you found this is your own business."
|
||||
color = "#AAAAAA77"
|
||||
taste_description = "something with a tang"
|
||||
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
|
||||
taste_mult = 2
|
||||
reagent_state = LIQUID
|
||||
nutriment_factor = 0.5 * REAGENTS_METABOLISM
|
||||
glass_icon_state = "glass_white"
|
||||
glass_name = "glass of cream"
|
||||
glass_desc = "Smells suspicious."
|
||||
shot_glass_icon_state = "shotglasscream"
|
||||
|
||||
/datum/reagent/consumable/cum/reaction_turf(turf/T, reac_volume)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(reac_volume < 3)
|
||||
return
|
||||
|
||||
var/obj/effect/decal/cleanable/cum/S = locate() in T
|
||||
if(!S)
|
||||
S = new(T)
|
||||
S.reagents.add_reagent("cum", reac_volume)
|
||||
if(data["blood_DNA"])
|
||||
S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) //yes. STD
|
||||
|
||||
//cleanable here
|
||||
|
||||
/obj/effect/decal/cleanable/cum
|
||||
name = "cum"
|
||||
desc = "It's pie cream from a cream pie. Or not..."
|
||||
gender = PLURAL
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
density = 0
|
||||
icon = 'honk/icons/effects/cum.dmi'
|
||||
icon_state = "cum1"
|
||||
random_icon_states = list("cum1", "cum3", "cum4", "cum5", "cum6", "cum7", "cum8", "cum9", "cum10", "cum11", "cum12")
|
||||
mergeable_decal = TRUE
|
||||
blood_state = null
|
||||
bloodiness = null
|
||||
//var/blood_DNA = list()
|
||||
|
||||
/obj/effect/decal/cleanable/cum/Initialize()
|
||||
. = ..()
|
||||
dir = pick(1,2,4,8)
|
||||
reagents.add_reagent("cum", rand(8,13))
|
||||
add_blood_DNA(list("Unknown DNA" = "O+"))*/
|
||||
|
||||
//begin redds code
|
||||
/obj/item/dildo/cyborg
|
||||
name = "F.I.S.T.R. Machine"
|
||||
desc = "Fully Integrated Sexual Tension Relief Machine"
|
||||
|
||||
/obj/item/dildo/cyborg/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
var/message = ""
|
||||
if(istype(M, /mob/living/carbon/human) && M.is_bottomless())
|
||||
if(M.client && M.client.prefs)
|
||||
if(M.client.prefs.toggles & VERB_CONSENT)
|
||||
if(hole == CUM_TARGET_VAGINA && M.has_vagina())
|
||||
message = (user == M) ? pick("fucks their own pussy with \the [src]","shoves \the [src] into their pussy", "jams \the [src] into their pussy") : pick("fucks [M] right in the pussy with \the [src]", "jams \the [src] right into [M]'s pussy")
|
||||
else if(hole == CUM_TARGET_ANUS && M.has_anus())
|
||||
message = (user == M) ? pick("fucks their own ass with \the [src]","shoves \the [src] into their ass", "jams \the [src] into their ass") : pick("fucks [M]'s asshole with \the [src]", "jams \the [src] into [M]'s ass")
|
||||
else if(istype(M, /mob/living/carbon/human) && user.zone_selected == BODY_ZONE_PRECISE_MOUTH && M.mouth_is_free())
|
||||
if(M.client && M.client.prefs)
|
||||
if(M.client.prefs.toggles & VERB_CONSENT)
|
||||
if(M.has_mouth())
|
||||
message = (user == M) ? pick("fucks their own mouth with \the [src]", "shoves \the [src] into their mouth", "jams \the [src] into their mouth") : pick("fucks [M]'s mouth with \the [src]", "jams \the [src] into [M]'s mouth")
|
||||
if(message)
|
||||
user.visible_message("<font color=purple>[user] [message].</font>")
|
||||
M.handle_post_sex(5, null, user)
|
||||
playsound(loc, pick('sandcode/sound/interactions/bang4.ogg',
|
||||
'sandcode/sound/interactions/bang5.ogg',
|
||||
'sandcode/sound/interactions/bang6.ogg'), 70, 1, -1)
|
||||
else if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
//end redds code
|
||||
|
||||
/obj/item/pneumatic_cannon/dildo
|
||||
color = "#FFC0CB"
|
||||
name = "pneumatic cannon"
|
||||
desc = "A pneumatic cannon with a picture of a bus printed on the side that resembles an A-shape."
|
||||
automatic = TRUE
|
||||
selfcharge = TRUE
|
||||
gasPerThrow = 0
|
||||
checktank = FALSE
|
||||
fire_mode = PCANNON_FIFO
|
||||
throw_amount = 1
|
||||
maxWeightClass = 60
|
||||
var/static/list/dildo_typecache = typecacheof(/obj/item/dildo)
|
||||
charge_type = /obj/item/dildo
|
||||
|
||||
/obj/item/pneumatic_cannon/dildo/Initialize()
|
||||
. = ..()
|
||||
allowed_typecache = dildo_typecache
|
||||
Reference in New Issue
Block a user