From c4deafd012e0c544593429414e266d4b42150fd5 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 22:49:07 -0700 Subject: [PATCH 01/33] the real basic edits --- code/datums/sexcon/sex_action.dm | 37 + .../sexcon/sex_actions/deviant/facesitting.dm | 47 ++ .../sexcon/sex_actions/deviant/frotting.dm | 41 + .../sexcon/sex_actions/deviant/scissoring.dm | 42 + .../sexcon/sex_actions/deviant/thighjob.dm | 73 ++ .../sexcon/sex_actions/deviant/titjob.dm | 38 + .../masturbate/masturbate_other.dm | 114 +++ .../masturbate/masturbate_penis_over.dm | 44 ++ .../sex_actions/masturbate/masturbate_self.dm | 114 +++ code/datums/sexcon/sex_actions/oral.dm | 125 +++ .../datums/sexcon/sex_actions/sex/anal_sex.dm | 105 +++ .../sexcon/sex_actions/sex/throat_sex.dm | 54 ++ .../sexcon/sex_actions/sex/vaginal_sex.dm | 118 +++ code/datums/sexcon/sexcon.dm | 723 ++++++++++++++++++ code/datums/sexcon/sexcon_helpers.dm | 86 +++ stonekeep.dme | 22 + 16 files changed, 1783 insertions(+) create mode 100644 code/datums/sexcon/sex_action.dm create mode 100644 code/datums/sexcon/sex_actions/deviant/facesitting.dm create mode 100644 code/datums/sexcon/sex_actions/deviant/frotting.dm create mode 100644 code/datums/sexcon/sex_actions/deviant/scissoring.dm create mode 100644 code/datums/sexcon/sex_actions/deviant/thighjob.dm create mode 100644 code/datums/sexcon/sex_actions/deviant/titjob.dm create mode 100644 code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm create mode 100644 code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm create mode 100644 code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm create mode 100644 code/datums/sexcon/sex_actions/oral.dm create mode 100644 code/datums/sexcon/sex_actions/sex/anal_sex.dm create mode 100644 code/datums/sexcon/sex_actions/sex/throat_sex.dm create mode 100644 code/datums/sexcon/sex_actions/sex/vaginal_sex.dm create mode 100644 code/datums/sexcon/sexcon.dm create mode 100644 code/datums/sexcon/sexcon_helpers.dm diff --git a/code/datums/sexcon/sex_action.dm b/code/datums/sexcon/sex_action.dm new file mode 100644 index 00000000000..e6fb0446b82 --- /dev/null +++ b/code/datums/sexcon/sex_action.dm @@ -0,0 +1,37 @@ +/datum/sex_action + abstract_type = /datum/sex_action + var/name = "Zodomize" + /// Time to do the act, modified by up to 2.5x speed by the speed toggle + var/do_time = 3.3 SECONDS + /// Whether the act is continous and will be done on repeat + var/continous = TRUE + /// Stamina cost per action, modified by up to 2.5x cost by the force toggle + var/stamina_cost = 0.5 + /// Whether the action requires both participants to be on the same tile + var/check_same_tile = TRUE + /// Whether the same tile check can be bypassed by an aggro grab on the person + var/aggro_grab_instead_same_tile = TRUE + /// Whether the action is forbidden from being done while incapacitated (stun, handcuffed) + var/check_incapacitated = TRUE + /// Whether the action requires an aggressive grab on the victim + var/require_grab = FALSE + /// If a grab is required, this is the required state of it + var/required_grab_state = GRAB_AGGRESSIVE + +/datum/sex_action/proc/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + return TRUE + +/datum/sex_action/proc/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + return + +/datum/sex_action/proc/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + return + +/datum/sex_action/proc/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + return + +/datum/sex_action/proc/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + return FALSE + +/datum/sex_action/proc/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/facesitting.dm b/code/datums/sexcon/sex_actions/deviant/facesitting.dm new file mode 100644 index 00000000000..51325172275 --- /dev/null +++ b/code/datums/sexcon/sex_actions/deviant/facesitting.dm @@ -0,0 +1,47 @@ +/datum/sex_action/facesitting + name = "Sit on their face" + +/datum/sex_action/facesitting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + return TRUE + +/datum/sex_action/facesitting/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_MOUTH)) + return FALSE + // Need to stand up + if(!(user.mobility_flags & MOBILITY_STAND)) + return FALSE + // Target can't stand up + if(target.mobility_flags & MOBILITY_STAND) + return FALSE + return TRUE + +/datum/sex_action/facesitting/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] sits their butt on [target]'s face!")) + +/datum/sex_action/facesitting/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + var/verbstring = pick(list("rubs", "smushes", "forces")) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [verbstring] their butt against [target] face.")) + target.make_sucking_noise() + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 1, 3, TRUE) + user.sexcon.handle_passive_ejaculation() + + user.sexcon.perform_deepthroat_oxyloss(target, 1.3) + user.sexcon.perform_sex_action(target, 0, 2, FALSE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/facesitting/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] gets off [target]'s face.")) + +/datum/sex_action/facesitting/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/deviant/frotting.dm b/code/datums/sexcon/sex_actions/deviant/frotting.dm new file mode 100644 index 00000000000..5b99c3c6a18 --- /dev/null +++ b/code/datums/sexcon/sex_actions/deviant/frotting.dm @@ -0,0 +1,41 @@ +/datum/sex_action/frotting + name = "Frot them" + +/datum/sex_action/frotting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return + return TRUE + +/datum/sex_action/frotting/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/frotting/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] shoves his cock against [target]'s own!")) + +/datum/sex_action/frotting/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] frots cocks together with [target]'s.")) + playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 1, 4, TRUE) + user.sexcon.handle_passive_ejaculation() + + user.sexcon.perform_sex_action(target, 1, 4, TRUE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/frotting/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] lets go off both their cocks.")) diff --git a/code/datums/sexcon/sex_actions/deviant/scissoring.dm b/code/datums/sexcon/sex_actions/deviant/scissoring.dm new file mode 100644 index 00000000000..a44354c1d48 --- /dev/null +++ b/code/datums/sexcon/sex_actions/deviant/scissoring.dm @@ -0,0 +1,42 @@ +/datum/sex_action/scissoring + name = "Scissor them" + +/datum/sex_action/scissoring/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return + return TRUE + +/datum/sex_action/scissoring/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/scissoring/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] spreads her legs and aligns her cunt against [target]'s own!")) + +/datum/sex_action/scissoring/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] scissors with [target]'s cunt.")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 1, 4, TRUE) + user.sexcon.handle_passive_ejaculation() + + user.sexcon.perform_sex_action(target, 1, 4, TRUE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/scissoring/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops scissoring with [target].")) diff --git a/code/datums/sexcon/sex_actions/deviant/thighjob.dm b/code/datums/sexcon/sex_actions/deviant/thighjob.dm new file mode 100644 index 00000000000..8f86476ceb9 --- /dev/null +++ b/code/datums/sexcon/sex_actions/deviant/thighjob.dm @@ -0,0 +1,73 @@ +/datum/sex_action/thighjob + name = "Use their thighs to get off" + +/datum/sex_action/thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return + return TRUE + +/datum/sex_action/thighjob/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/thighjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] grabs [target]'s thighs and shoves his cock inbetween!")) + +/datum/sex_action/thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s thighs.")) + playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 2, 4, TRUE) + user.sexcon.handle_passive_ejaculation() + +/datum/sex_action/thighjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] pulls his cock out from inbetween [target]'s thighs.")) + +/datum/sex_action/force_thighjob + name = "Jerk them off with thighs" + +/datum/sex_action/force_thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/force_thighjob/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/force_thighjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] moves their thighs between [target]'s cock...")) + +/datum/sex_action/force_thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock with their thighs...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(target, user) + + user.sexcon.perform_sex_action(target, 2, 4, TRUE) + + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/force_thighjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops jerking [target]'s off with their thighs...")) + +/datum/sex_action/force_thighjob/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm new file mode 100644 index 00000000000..531e2211f83 --- /dev/null +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -0,0 +1,38 @@ +/datum/sex_action/titjob + name = "Use their tits to get off" + +/datum/sex_action/titjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return + if(!target.getorganslot(ORGAN_SLOT_BREASTS)) + return + return TRUE + +/datum/sex_action/titjob/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_CHEST)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_BREASTS)) + return FALSE + return TRUE + +/datum/sex_action/titjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] grabs [target]'s tits and shoves his cock inbetween!")) + +/datum/sex_action/titjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s tits.")) + playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 2, 4, TRUE) + user.sexcon.handle_passive_ejaculation() + +/datum/sex_action/titjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] pulls his cock out from inbetween [target]'s tits.")) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm new file mode 100644 index 00000000000..6ff667ba0ff --- /dev/null +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -0,0 +1,114 @@ +/datum/sex_action/masturbate_other_vagina + name = "Stroke their clit" + check_same_tile = FALSE + +/datum/sex_action/masturbate_other_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_other_vagina/can_perform(mob/living/user, mob/living/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_other_vagina/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts stroking [target]'s clit...")) + +/datum/sex_action/masturbate_other_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes [target]'s clit...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(target, 2, 4, TRUE) + + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_other_vagina/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops stroking [target]'s clit.")) + +/datum/sex_action/masturbate_other_vagina/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/masturbate_penis_other + name = "Jerk them off" + check_same_tile = FALSE + +/datum/sex_action/masturbate_penis_other/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_penis_other/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_penis_other/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts jerking [target]'s off...")) + +/datum/sex_action/masturbate_penis_other/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock off...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(target, 2, 0, TRUE) + + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_penis_other/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops jerking [target]'s off.")) + +/datum/sex_action/masturbate_penis_other/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/masturbate_other_anus + name = "Finger their butt" + check_same_tile = FALSE + +/datum/sex_action/masturbate_other_anus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + return TRUE + +/datum/sex_action/masturbate_other_anus/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_other_anus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts fingering [target]'s butt...")) + +/datum/sex_action/masturbate_other_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers [target]'s butt...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(target, 2, 6, TRUE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_other_anus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops fingering [target]'s butt.")) + +/datum/sex_action/masturbate_other_anus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm new file mode 100644 index 00000000000..02dea61f65c --- /dev/null +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -0,0 +1,44 @@ +/datum/sex_action/masturbate_penis_over + name = "Jerk over them" + check_same_tile = FALSE + +/datum/sex_action/masturbate_penis_over/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_penis_over/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!user.sexcon.can_use_penis()) + return + return TRUE + +/datum/sex_action/masturbate_penis_over/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts jerking over [target]...")) + +/datum/sex_action/masturbate_penis_over/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb] over [target]")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 2, 4, TRUE) + + if(user.sexcon.check_active_ejaculation()) + user.visible_message(span_lovebold("[user] cums over [target]'s body!")) + user.sexcon.cum_onto() + +/datum/sex_action/masturbate_penis_over/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops jerking off.")) + +/datum/sex_action/masturbate_penis_over/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm new file mode 100644 index 00000000000..5b5c55dbe36 --- /dev/null +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -0,0 +1,114 @@ +/datum/sex_action/masturbate_vagina + name = "Stroke clit" + +/datum/sex_action/masturbate_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user != target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_vagina/can_perform(mob/living/user, mob/living/target) + if(user != target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_vagina/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts stroking her clit...")) + +/datum/sex_action/masturbate_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes her clit...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 2, 4, TRUE) + + user.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_vagina/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops stroking.")) + +/datum/sex_action/masturbate_vagina/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/masturbate_penis + name = "Jerk off" + +/datum/sex_action/masturbate_penis/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user != target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_penis/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user != target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!user.sexcon.can_use_penis()) + return + return TRUE + +/datum/sex_action/masturbate_penis/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts jerking off...")) + +/datum/sex_action/masturbate_penis/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb]...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 2, 0, TRUE) + + user.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_penis/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops jerking off.")) + +/datum/sex_action/masturbate_penis/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/masturbate_anus + name = "Finger butt" + +/datum/sex_action/masturbate_anus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user != target) + return FALSE + return TRUE + +/datum/sex_action/masturbate_anus/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user != target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + return TRUE + +/datum/sex_action/masturbate_anus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts fingering their butt...")) + +/datum/sex_action/masturbate_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers their butt...")) + playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + + user.sexcon.perform_sex_action(user, 2, 6, TRUE) + user.sexcon.handle_passive_ejaculation() + +/datum/sex_action/masturbate_anus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops fingering their butt.")) + +/datum/sex_action/masturbate_anus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm new file mode 100644 index 00000000000..e7a8a7f4167 --- /dev/null +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -0,0 +1,125 @@ +/datum/sex_action/cunnilingus + name = "Suck their cunt off" + +/datum/sex_action/cunnilingus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/cunnilingus/can_perform(mob/living/user, mob/living/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + return TRUE + +/datum/sex_action/cunnilingus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts sucking [target]'s clit...")) + +/datum/sex_action/cunnilingus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] sucks [target]'s clit...")) + user.make_sucking_noise() + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(target, 2, 3, TRUE) + if(target.sexcon.check_active_ejaculation()) + target.visible_message(span_lovebold("[target] ejaculates into [user]'s mouth!")) + target.sexcon.cum_into() + +/datum/sex_action/cunnilingus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops sucking [target]'s clit ...")) + +/datum/sex_action/cunnilingus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/blowjob + name = "Suck them off" + check_same_tile = FALSE + +/datum/sex_action/blowjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/blowjob/can_perform(mob/living/user, mob/living/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/blowjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts sucking [target]'s cock...")) + +/datum/sex_action/blowjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] sucks [target]'s cock...")) + user.make_sucking_noise() + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(target, 2, 0, TRUE) + if(!target.sexcon.considered_limp()) + user.sexcon.perform_deepthroat_oxyloss(user, 1.3) + if(target.sexcon.check_active_ejaculation()) + target.visible_message(span_lovebold("[target] cums into [user]'s mouth!")) + target.sexcon.cum_into() + +/datum/sex_action/blowjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops sucking [target]'s cock ...")) + +/datum/sex_action/blowjob/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/rimming + name = "Rim them" + +/datum/sex_action/rimming/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + return TRUE + +/datum/sex_action/rimming/can_perform(mob/living/user, mob/living/target) + if(user == target) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) + return FALSE + return TRUE + +/datum/sex_action/rimming/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] starts rimming [target]'s butt...")) + +/datum/sex_action/rimming/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rims [target]'s butt...")) + user.make_sucking_noise() + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(target, 2, 0, TRUE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/rimming/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] stops rimming [target]'s butt ...")) + +/datum/sex_action/rimming/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(target.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/sex/anal_sex.dm b/code/datums/sexcon/sex_actions/sex/anal_sex.dm new file mode 100644 index 00000000000..18b0a39983a --- /dev/null +++ b/code/datums/sexcon/sex_actions/sex/anal_sex.dm @@ -0,0 +1,105 @@ +/datum/sex_action/anal_sex + name = "Sodomize them" + stamina_cost = 1.0 + +/datum/sex_action/anal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/anal_sex/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!user.sexcon.can_use_penis()) + return + return TRUE + +/datum/sex_action/anal_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] slides his cock into [target]'s butt!")) + playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) + +/datum/sex_action/anal_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s ass.")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 2, 0, TRUE) + if(user.sexcon.check_active_ejaculation()) + user.visible_message(span_lovebold("[user] cums into [target]'s butt!")) + user.sexcon.cum_into() + user.virginity = FALSE + + if(user.sexcon.considered_limp()) + user.sexcon.perform_sex_action(target, 1.2, 4, FALSE) + else + user.sexcon.perform_sex_action(target, 2.4, 9, FALSE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/anal_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] pulls his cock out of [target]'s butt.")) + +/datum/sex_action/anal_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/anal_ride_sex + name = "Ride them anally" + stamina_cost = 1.0 + aggro_grab_instead_same_tile = FALSE + +/datum/sex_action/anal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/anal_ride_sex/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/anal_ride_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] gets on top of [target] and begins riding them with their butt!")) + playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) + +/datum/sex_action/anal_ride_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rides [target].")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + if(target.sexcon.considered_limp()) + user.sexcon.perform_sex_action(target, 1.2, 4, TRUE) + else + user.sexcon.perform_sex_action(target, 2.4, 9, TRUE) + user.sexcon.handle_passive_ejaculation() + + user.sexcon.perform_sex_action(target, 2, 4, FALSE) + if(target.sexcon.check_active_ejaculation()) + target.visible_message(span_lovebold("[target] cums into [user]'s butt!")) + target.sexcon.cum_into() + target.virginity = FALSE + +/datum/sex_action/anal_ride_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] gets off [target].")) + +/datum/sex_action/anal_ride_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm new file mode 100644 index 00000000000..99b7340671c --- /dev/null +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -0,0 +1,54 @@ +/datum/sex_action/throat_sex + name = "Fuck their throat" + stamina_cost = 1.0 + +/datum/sex_action/throat_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/throat_sex/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_MOUTH)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!user.sexcon.can_use_penis()) + return + return TRUE + +/datum/sex_action/throat_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] slides his cock into [target]'s throat!")) + playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) + +/datum/sex_action/throat_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s throat.")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 2, 0, TRUE) + if(user.sexcon.check_active_ejaculation()) + user.visible_message(span_lovebold("[user] cums into [target]'s throat!")) + user.sexcon.cum_into() + user.virginity = FALSE + + if(user.sexcon.considered_limp()) + user.sexcon.perform_sex_action(target, 0, 2, FALSE) + else + user.sexcon.perform_sex_action(target, 0, 7, FALSE) + user.sexcon.perform_deepthroat_oxyloss(target, 2.3) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/throat_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] pulls his cock out of [target]'s throat.")) + +/datum/sex_action/throat_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm new file mode 100644 index 00000000000..9c43a2407a5 --- /dev/null +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -0,0 +1,118 @@ +/datum/sex_action/vaginal_sex + name = "Fuck their cunt" + stamina_cost = 1.0 + +/datum/sex_action/vaginal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/vaginal_sex/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + if(!user.sexcon.can_use_penis()) + return + return TRUE + +/datum/sex_action/vaginal_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] slides his cock into [target]'s cunt!")) + playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) + +/datum/sex_action/vaginal_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s cunt.")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + user.sexcon.perform_sex_action(user, 2, 0, TRUE) + if(user.sexcon.check_active_ejaculation()) + user.visible_message(span_lovebold("[user] cums into [target]'s cunt!")) + user.sexcon.cum_into() + user.try_impregnate(target) + user.virginity = FALSE + target.virginity = FALSE + + if(user.sexcon.considered_limp()) + user.sexcon.perform_sex_action(target, 1.2, 3, FALSE) + else + user.sexcon.perform_sex_action(target, 2.4, 7, FALSE) + target.sexcon.handle_passive_ejaculation() + +/datum/sex_action/vaginal_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] pulls his cock out of [target]'s cunt.")) + +/datum/sex_action/vaginal_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE + +/datum/sex_action/vaginal_ride_sex + name = "Ride them" + stamina_cost = 1.0 + aggro_grab_instead_same_tile = FALSE + +/datum/sex_action/vaginal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/vaginal_ride_sex/can_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user == target) + return FALSE + if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) + return FALSE + if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(!target.getorganslot(ORGAN_SLOT_PENIS)) + return FALSE + return TRUE + +/datum/sex_action/vaginal_ride_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] gets on top of [target] and begins riding them with their cunt!")) + playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) + +/datum/sex_action/vaginal_ride_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.do_message_signature("[type]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rides [target].")) + playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) + do_thrust_animate(user, target) + + if(target.sexcon.considered_limp()) + user.sexcon.perform_sex_action(user, 1.2, 3, TRUE) + else + user.sexcon.perform_sex_action(user, 2.4, 7, TRUE) + user.sexcon.handle_passive_ejaculation() + + user.sexcon.perform_sex_action(target, 2, 4, FALSE) + if(target.sexcon.check_active_ejaculation()) + target.visible_message(span_lovebold("[target] cums into [user]'s cunt!")) + target.sexcon.cum_into() + target.try_impregnate(user) + target.virginity = FALSE + user.virginity = FALSE + +/datum/sex_action/vaginal_ride_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) + user.visible_message(span_warning("[user] gets off [target].")) + +/datum/sex_action/vaginal_ride_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) + if(user.sexcon.finished_check()) + return TRUE + return FALSE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm new file mode 100644 index 00000000000..582dbb6b11e --- /dev/null +++ b/code/datums/sexcon/sexcon.dm @@ -0,0 +1,723 @@ +/datum/sex_controller + /// The user and the owner of the controller + var/mob/living/carbon/human/user + /// Target of our actions, can be ourself + var/mob/living/carbon/human/target + /// Whether the user desires to stop his current action + var/desire_stop = FALSE + /// What is the current performed action + var/current_action = null + /// Enum of desired speed + var/speed = SEX_SPEED_MID + /// Enum of desired force + var/force = SEX_FORCE_MID + /// Enum of manual arousal state + var/manual_arousal = SEX_MANUAL_AROUSAL_DEFAULT + /// Our arousal + var/arousal = 0 + /// Our charge gauge + var/charge = SEX_MAX_CHARGE + /// Whether we want to screw until finished, or non stop + var/do_until_finished = TRUE + var/last_arousal_increase_time = 0 + var/last_ejaculation_time = 0 + var/last_moan = 0 + var/last_pain = 0 + var/msg_signature = "" + var/last_msg_signature = 0 + +/datum/sex_controller/New(mob/living/carbon/human/owner) + user = owner + +/datum/sex_controller/Destroy() + user = null + target = null + . = ..() + +/proc/do_thrust_animate(atom/movable/user, atom/movable/target, pixels = 4, time = 2.7) + var/oldx = user.pixel_x + var/oldy = user.pixel_y + var/target_x = oldx + var/target_y = oldy + var/dir = get_dir(user, target) + if(user.loc == target.loc) + dir = user.dir + switch(dir) + if(NORTH) + target_y += pixels + if(SOUTH) + target_y -= pixels + if(WEST) + target_x -= pixels + if(EAST) + target_x += pixels + + animate(user, pixel_x = target_x, pixel_y = target_y, time = time) + animate(pixel_x = oldx, pixel_y = oldy, time = time) + +/datum/sex_controller/proc/do_message_signature(sigkey) + var/properkey = "[speed][force][sigkey]" + if(properkey == msg_signature && last_msg_signature + 4.0 SECONDS >= world.time) + return FALSE + msg_signature = properkey + last_msg_signature = world.time + return TRUE + +/datum/sex_controller/proc/is_spent() + if(charge < CHARGE_FOR_CLIMAX) + return TRUE + return FALSE + +/datum/sex_controller/proc/finished_check() + if(!do_until_finished) + return FALSE + if(!just_ejaculated()) + return FALSE + return TRUE + +/datum/sex_controller/proc/can_violate_victim(mob/living/carbon/human/victim) + if(!victim.mind) + return FALSE + if(!victim.mind.key) + return FALSE + if(!user.client.prefs.violated[victim.mind.key]) + return FALSE + if(user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME < world.time) + return FALSE + return TRUE + +/datum/sex_controller/proc/need_to_be_violated(mob/living/carbon/human/victim) + // Dont need to violate self + if(user == victim) + return FALSE + // If user and victim both are not defiant, then no violation needs to happen + if(!user.defiant && !victim.defiant) + return FALSE + // Need to violate AFK clients + if(victim.mind && victim.mind.key && !victim.client) + return TRUE + // Need to violate combat mode people + if(victim.cmode) + return TRUE + return FALSE + +/datum/sex_controller/proc/violate_victim(mob/living/carbon/human/victim) + if(!user.client) + return + if(!victim.mind) + return + if(!victim.mind.key) + return + if(user.client.prefs.violated[victim.mind.key] && user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME >= world.time) + return + var/pq_warning = pick(list("If I continue down this road, my soul will be burdened.", "I feel a terrible omen watching me...", "The forces of dark feel heavy on my soul.")) + to_chat(user, span_userdanger(pq_warning)) + var/alert = alert(user, "Do I really want to do this?", "Violate", "Yes", "No") + if(alert != "Yes") + return + user.visible_message(span_boldwarning("[user] begins to violate [victim]!")) + if(!do_after(user, 5 SECONDS, target = victim)) + return + if(!need_to_be_violated(victim)) + return + if(!user.client) + return + if(!victim.mind) + return + if(!victim.mind.key) + return + if(user.client.prefs.violated[victim.mind.key] && user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME >= world.time) + return + // ZAPED + to_chat(user, span_boldwarning(pick(list("I feel tainted...", "I feel less human...")))) + log_combat(user, victim, "Initiated rape against") + adjust_playerquality(-4, user.ckey, reason = "Initiated rape on an AFK/resisting person.") + user.client.prefs.violated[victim.mind.key] = world.time + +/datum/sex_controller/proc/adjust_speed(amt) + speed = clamp(speed + amt, SEX_SPEED_MIN, SEX_SPEED_MAX) + +/datum/sex_controller/proc/adjust_force(amt) + force = clamp(force + amt, SEX_FORCE_MIN, SEX_FORCE_MAX) + +/datum/sex_controller/proc/adjust_arousal_manual(amt) + manual_arousal = clamp(manual_arousal + amt, SEX_MANUAL_AROUSAL_MIN, SEX_MANUAL_AROUSAL_MAX) + +/datum/sex_controller/proc/update_pink_screen() + var/severity = 0 + switch(arousal) + if(1 to 10) + severity = 1 + if(10 to 20) + severity = 2 + if(20 to 30) + severity = 3 + if(30 to 40) + severity = 4 + if(40 to 50) + severity = 5 + if(50 to 60) + severity = 6 + if(60 to 70) + severity = 7 + if(70 to 80) + severity = 8 + if(80 to 90) + severity = 9 + if(90 to INFINITY) + severity = 10 + if(severity > 0) + user.overlay_fullscreen("horny", /atom/movable/screen/fullscreen/love, severity) + else + user.clear_fullscreen("horny") + +/datum/sex_controller/proc/start(mob/living/carbon/human/new_target) + if(!ishuman(new_target)) + return + set_target(new_target) + show_ui() + +/datum/sex_controller/proc/cum_onto() + log_combat(user, target, "Came onto the target") + playsound(target, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) + add_cum_floor(get_turf(target)) + after_ejaculation() + +/datum/sex_controller/proc/cum_into(oral = FALSE) + log_combat(user, target, "Came inside the target") + if(oral) + playsound(target, pick(list('sound/misc/mat/mouthend (1).ogg','sound/misc/mat/mouthend (2).ogg')), 100, FALSE, ignore_walls = FALSE) + else + playsound(target, 'sound/misc/mat/endin.ogg', 50, TRUE, ignore_walls = FALSE) + after_ejaculation() + if(!oral) + after_intimate_climax() + +/datum/sex_controller/proc/ejaculate() + log_combat(user, user, "Ejaculated") + user.visible_message(span_lovebold("[user] makes a mess!")) + playsound(user, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) + add_cum_floor(get_turf(user)) + after_ejaculation() + +/datum/sex_controller/proc/after_ejaculation() + set_arousal(40) + adjust_charge(-CHARGE_FOR_CLIMAX) + user.emote("sexmoanhvy", forced = TRUE) + user.playsound_local(user, 'sound/misc/mat/end.ogg', 100) + last_ejaculation_time = world.time + SSticker.cums++ + +/datum/sex_controller/proc/after_intimate_climax() + if(user == target) + return + if(HAS_TRAIT(target, TRAIT_GOODLOVER)) + if(!user.mob_timers["cumtri"]) + user.mob_timers["cumtri"] = world.time + user.adjust_triumphs(1) + to_chat(user, span_love("Our loving is a true TRIUMPH!")) + if(HAS_TRAIT(user, TRAIT_GOODLOVER)) + if(!target.mob_timers["cumtri"]) + target.mob_timers["cumtri"] = world.time + target.adjust_triumphs(1) + to_chat(target, span_love("Our loving is a true TRIUMPH!")) + +/datum/sex_controller/proc/just_ejaculated() + return (last_ejaculation_time + 2 SECONDS >= world.time) + +/datum/sex_controller/proc/set_charge(amount) + var/empty = (charge < CHARGE_FOR_CLIMAX) + charge = clamp(amount, 0, SEX_MAX_CHARGE) + var/after_empty = (charge < CHARGE_FOR_CLIMAX) + if(empty && !after_empty) + to_chat(user, span_notice("I feel like I'm not so spent anymore")) + if(!empty && after_empty) + to_chat(user, span_notice("I'm spent!")) + +/datum/sex_controller/proc/adjust_charge(amount) + set_charge(charge + amount) + +/datum/sex_controller/proc/handle_charge(dt) + adjust_charge(dt * CHARGE_RECHARGE_RATE) + if(is_spent()) + if(arousal > 60) + to_chat(user, span_warning("I'm too spent!")) + adjust_arousal(-20) + adjust_arousal(-dt * SPENT_AROUSAL_RATE) + +/datum/sex_controller/proc/set_arousal(amount) + if(amount > arousal) + last_arousal_increase_time = world.time + arousal = clamp(amount, 0, MAX_AROUSAL) + update_pink_screen() + update_blueballs() + update_erect_state() + +/datum/sex_controller/proc/update_erect_state() + var/obj/item/organ/penis/penis = user.getorganslot(ORGAN_SLOT_PENIS) + if(penis) + penis.update_erect_state() + +/datum/sex_controller/proc/adjust_arousal(amount) + set_arousal(arousal + amount) + +/datum/sex_controller/proc/perform_deepthroat_oxyloss(mob/living/carbon/human/action_target, oxyloss_amt) + var/oxyloss_multiplier = 0 + switch(force) + if(SEX_FORCE_LOW) + oxyloss_multiplier = 0 + if(SEX_FORCE_MID) + oxyloss_multiplier = 0 + if(SEX_FORCE_HIGH) + oxyloss_multiplier = 1.0 + if(SEX_FORCE_EXTREME) + oxyloss_multiplier = 2.0 + oxyloss_amt *= oxyloss_multiplier + if(oxyloss_amt <= 0) + return + action_target.adjustOxyLoss(oxyloss_amt) + // Indicate someone is choking through sex + if(action_target.oxyloss >= 50 && prob(33)) + action_target.emote(pick(list("gag", "choke", "gasp")), forced = TRUE) + +/datum/sex_controller/proc/perform_sex_action(mob/living/carbon/human/action_target, arousal_amt, pain_amt, giving) + action_target.sexcon.receive_sex_action(arousal_amt, pain_amt, giving, force, speed) + +/datum/sex_controller/proc/receive_sex_action(arousal_amt, pain_amt, giving, applied_force, applied_speed) + arousal_amt *= get_force_pleasure_multiplier(applied_force, giving) + pain_amt *= get_force_pain_multiplier(applied_force) + pain_amt *= get_speed_pain_multiplier(applied_speed) + + if(user.stat == DEAD) + arousal_amt = 0 + pain_amt = 0 + + adjust_arousal(arousal_amt) + + damage_from_pain(pain_amt) + try_do_moan(arousal_amt, pain_amt, applied_force, giving) + try_do_pain_effect(pain_amt, giving) + +/datum/sex_controller/proc/damage_from_pain(pain_amt) + if(pain_amt < PAIN_MINIMUM_FOR_DAMAGE) + return + var/damage = (pain_amt / PAIN_DAMAGE_DIVISOR) + var/obj/item/bodypart/part = user.get_bodypart(BODY_ZONE_CHEST) + if(!part) + return + user.apply_damage(damage, BRUTE, part) + +/datum/sex_controller/proc/try_do_moan(arousal_amt, pain_amt, applied_force, giving) + if(arousal_amt < 1.5) + return + if(user.stat != CONSCIOUS) + return + if(last_moan + MOAN_COOLDOWN >= world.time) + return + if(prob(50)) + return + var/chosen_emote + switch(arousal_amt) + if(0 to 5) + chosen_emote = "sexmoanlight" + if(5 to INFINITY) + chosen_emote = "sexmoanhvy" + + if(pain_amt >= PAIN_MILD_EFFECT) + if(giving) + if(prob(30)) + chosen_emote = "groan" + else + if(prob(40)) + chosen_emote = "painmoan" + if(pain_amt >= PAIN_MED_EFFECT) + if(giving) + if(prob(50)) + chosen_emote = "groan" + else + if(prob(60)) + // Because males have atrocious whimper noise + if(user.gender == FEMALE && prob(50)) + chosen_emote = "whimper" + else + chosen_emote = "cry" + + last_moan = world.time + user.emote(chosen_emote, forced = TRUE) + +/datum/sex_controller/proc/try_do_pain_effect(pain_amt, giving) + if(pain_amt < PAIN_MILD_EFFECT) + return + if(last_pain + PAIN_COOLDOWN >= world.time) + return + if(prob(50)) + return + last_pain = world.time + if(pain_amt >= PAIN_HIGH_EFFECT) + var/pain_msg = pick(list("IT HURTS!!!", "IT NEEDS TO STOP!!!", "I CAN'T TAKE IT ANYMORE!!!")) + to_chat(user, span_boldwarning(pain_msg)) + user.flash_fullscreen("redflash2") + if(prob(70) && user.stat == CONSCIOUS) + user.visible_message(span_warning("[user] shudders in pain!")) + else if(pain_amt >= PAIN_MED_EFFECT) + var/pain_msg = pick(list("It hurts!", "It pains me!")) + to_chat(user, span_boldwarning(pain_msg)) + user.flash_fullscreen("redflash1") + if(prob(40) && user.stat == CONSCIOUS) + user.visible_message(span_warning("[user] shudders in pain!")) + else + var/pain_msg = pick(list("It hurts a little...", "It stings...", "I'm aching...")) + to_chat(user, span_warning(pain_msg)) + +/datum/sex_controller/proc/update_blueballs() + if(arousal >= BLUEBALLS_GAIN_THRESHOLD) + user.add_stress(/datum/stressevent/blueb) + else if (arousal <= BLUEBALLS_LOOSE_THRESHOLD) + user.remove_stress(/datum/stressevent/blueb) + +/datum/sex_controller/proc/check_active_ejaculation() + if(arousal < ACTIVE_EJAC_THRESHOLD) + return FALSE + if(is_spent()) + return FALSE + if(!can_ejaculate()) + return FALSE + return TRUE + +/datum/sex_controller/proc/can_ejaculate() + if(!user.getorganslot(ORGAN_SLOT_TESTICLES) && !user.getorganslot(ORGAN_SLOT_VAGINA)) + return FALSE + if(HAS_TRAIT(user, TRAIT_LIMPDICK)) + return FALSE + return TRUE + +/datum/sex_controller/proc/handle_passive_ejaculation() + if(arousal < PASSIVE_EJAC_THRESHOLD) + return + if(is_spent()) + return + if(!can_ejaculate()) + return FALSE + ejaculate() + +/datum/sex_controller/proc/can_use_penis() + if(HAS_TRAIT(user, TRAIT_LIMPDICK)) + return FALSE + return TRUE + +/datum/sex_controller/proc/considered_limp() + if(arousal >= AROUSAL_HARD_ON_THRESHOLD) + return FALSE + return TRUE + +/datum/sex_controller/proc/process_sexcon(dt) + handle_arousal_unhorny(dt) + handle_charge(dt) + handle_passive_ejaculation() + +/datum/sex_controller/proc/handle_arousal_unhorny(dt) + if(!can_ejaculate()) + adjust_arousal(-dt * IMPOTENT_AROUSAL_LOSS_RATE) + if(last_arousal_increase_time + AROUSAL_TIME_TO_UNHORNY >= world.time) + return + var/rate + switch(arousal) + if(-INFINITY to 25) + rate = AROUSAL_LOW_UNHORNY_RATE + if(25 to 40) + rate = AROUSAL_MID_UNHORNY_RATE + if(40 to INFINITY) + rate = AROUSAL_HIGH_UNHORNY_RATE + adjust_arousal(-dt * rate) + +/datum/sex_controller/proc/show_ui() + var/list/dat = list() + var/force_name = get_force_string() + var/speed_name = get_speed_string() + var/manual_arousal_name = get_manual_arousal_string() + if(!user.getorganslot(ORGAN_SLOT_PENIS)) + dat += "
\< [speed_name] \> ~|~ \< [force_name] \>
" + else + dat += "
\< [speed_name] \> ~|~ \< [force_name] \> ~|~ \< [manual_arousal_name] \>
" + dat += "
| [do_until_finished ? "UNTIL IM FINISHED" : "UNTIL I STOP"] |
" + if(target == user) + dat += "
Doing unto yourself
" + else + dat += "
Doing unto [target]'s
" + if(current_action) + dat += "
Stop
" + else + dat += "
" + dat += "" + var/i = 0 + for(var/action_type in GLOB.sex_actions) + var/datum/sex_action/action = SEX_ACTION(action_type) + if(!action.shows_on_menu(user, target)) + continue + dat += "" + i++ + if(i >= 2) + i = 0 + dat += "" + + dat += "
" + var/link = "" + if(!can_perform_action(action_type)) + link = "linkOff" + if(current_action == action_type) + link = "linkOn" + dat += "
[action.name]
" + dat += "
" + var/datum/browser/popup = new(user, "sexcon", "
Sate Desire
", 490, 550) + popup.set_content(dat.Join()) + popup.open() + return + +/datum/sex_controller/Topic(href, href_list) + if(usr != user) + return + switch(href_list["task"]) + if("action") + var/action_path = text2path(href_list["action_type"]) + var/datum/sex_action/action = SEX_ACTION(action_path) + if(!action) + return + try_start_action(action_path) + if("stop") + try_stop_current_action() + if("speed_up") + adjust_speed(1) + if("speed_down") + adjust_speed(-1) + if("force_up") + adjust_force(1) + if("force_down") + adjust_force(-1) + if("manual_arousal_up") + adjust_arousal_manual(1) + if("manual_arousal_down") + adjust_arousal_manual(-1) + if("toggle_finished") + do_until_finished = !do_until_finished + show_ui() + +/datum/sex_controller/proc/try_stop_current_action() + if(!current_action) + return + desire_stop = TRUE + user.doing = FALSE + +/datum/sex_controller/proc/stop_current_action() + if(!current_action) + return + var/datum/sex_action/action = SEX_ACTION(current_action) + action.on_finish(user, target) + desire_stop = FALSE + user.doing = FALSE + current_action = null + +/datum/sex_controller/proc/try_start_action(action_type) + if(action_type == current_action) + try_stop_current_action() + return + if(current_action != null) + try_stop_current_action() + return + if(!action_type) + return + if(!can_perform_action(action_type)) + return + if(need_to_be_violated(target) && !can_violate_victim(target)) + violate_victim(target) + if(need_to_be_violated(target) && !can_violate_victim(target)) + return + // Set vars + desire_stop = FALSE + current_action = action_type + var/datum/sex_action/action = SEX_ACTION(current_action) + log_combat(user, target, "Started sex action: [action.name]") + INVOKE_ASYNC(src, PROC_REF(sex_action_loop)) + +/datum/sex_controller/proc/sex_action_loop() + // Do action loop + var/performed_action_type = current_action + var/datum/sex_action/action = SEX_ACTION(current_action) + action.on_start(user, target) + while(TRUE) + if(!user.rogfat_add(action.stamina_cost * get_stamina_cost_multiplier())) + break + if(!do_after(user, (action.do_time / get_speed_multiplier()), target = target)) + break + if(current_action == null || performed_action_type != current_action) + break + if(need_to_be_violated(target) && !can_violate_victim(target)) + break + if(!can_perform_action(current_action)) + break + if(action.is_finished(user, target)) + break + if(desire_stop) + break + action.on_perform(user, target) + // It could want to finish afterwards the performed action + if(action.is_finished(user, target)) + break + if(!action.continous) + break + stop_current_action() + +/datum/sex_controller/proc/can_perform_action(action_type) + if(!action_type) + return FALSE + var/datum/sex_action/action = SEX_ACTION(action_type) + if(!inherent_perform_check(action_type)) + return FALSE + if(!action.can_perform(user, target)) + return FALSE + return TRUE + +/datum/sex_controller/proc/inherent_perform_check(action_type) + var/datum/sex_action/action = SEX_ACTION(action_type) + if(!target) + return FALSE + if(user.stat != CONSCIOUS) + return FALSE + if(!user.Adjacent(target)) + return FALSE + if(action.check_incapacitated && user.incapacitated()) + return FALSE + if(action.check_same_tile) + var/same_tile = (get_turf(user) == get_turf(target)) + var/grab_bypass = (action.aggro_grab_instead_same_tile && user.get_highest_grab_state_on(target) == GRAB_AGGRESSIVE) + if(!same_tile && !grab_bypass) + return FALSE + if(action.require_grab) + var/grabstate = user.get_highest_grab_state_on(target) + if(grabstate == null || grabstate < action.required_grab_state) + return FALSE + return TRUE + +/datum/sex_controller/proc/set_target(mob/living/carbon/human/new_target) + target = new_target + +/datum/sex_controller/proc/get_speed_multiplier() + switch(speed) + if(SEX_SPEED_LOW) + return 1.0 + if(SEX_SPEED_MID) + return 1.5 + if(SEX_SPEED_HIGH) + return 2.0 + if(SEX_SPEED_EXTREME) + return 2.5 + +/datum/sex_controller/proc/get_stamina_cost_multiplier() + switch(force) + if(SEX_FORCE_LOW) + return 1.0 + if(SEX_FORCE_MID) + return 1.5 + if(SEX_FORCE_HIGH) + return 2.0 + if(SEX_SPEED_EXTREME) + return 2.5 + +/datum/sex_controller/proc/get_force_pleasure_multiplier(passed_force, giving) + switch(passed_force) + if(SEX_FORCE_LOW) + if(giving) + return 0.8 + else + return 0.8 + if(SEX_FORCE_MID) + if(giving) + return 1.2 + else + return 1.2 + if(SEX_FORCE_HIGH) + if(giving) + return 1.6 + else + return 1.2 + if(SEX_FORCE_EXTREME) + if(giving) + return 2.0 + else + return 0.8 + +/datum/sex_controller/proc/get_force_pain_multiplier(passed_force) + switch(passed_force) + if(SEX_FORCE_LOW) + return 0.5 + if(SEX_FORCE_MID) + return 1.0 + if(SEX_FORCE_HIGH) + return 2.0 + if(SEX_FORCE_EXTREME) + return 3.0 + +/datum/sex_controller/proc/get_speed_pain_multiplier(passed_speed) + switch(passed_speed) + if(SEX_SPEED_LOW) + return 0.8 + if(SEX_SPEED_MID) + return 1.0 + if(SEX_SPEED_HIGH) + return 1.2 + if(SEX_SPEED_EXTREME) + return 1.4 + +/datum/sex_controller/proc/get_force_string() + switch(force) + if(SEX_FORCE_LOW) + return "GENTLE" + if(SEX_FORCE_MID) + return "FIRM" + if(SEX_FORCE_HIGH) + return "ROUGH" + if(SEX_FORCE_EXTREME) + return "BRUTAL" + +/datum/sex_controller/proc/get_speed_string() + switch(speed) + if(SEX_SPEED_LOW) + return "SLOW" + if(SEX_SPEED_MID) + return "STEADY" + if(SEX_SPEED_HIGH) + return "QUICK" + if(SEX_SPEED_EXTREME) + return "UNRELENTING" + +/datum/sex_controller/proc/get_manual_arousal_string() + switch(manual_arousal) + if(SEX_MANUAL_AROUSAL_DEFAULT) + return "NATURAL" + if(SEX_MANUAL_AROUSAL_UNAROUSED) + return "UNAROUSED" + if(SEX_MANUAL_AROUSAL_PARTIAL) + return "PARTIALLY ERECT" + if(SEX_MANUAL_AROUSAL_FULL) + return "FULLY ERECT" + +/datum/sex_controller/proc/get_generic_force_adjective() + switch(force) + if(SEX_FORCE_LOW) + return pick(list("gently", "carefully", "tenderly", "gingerly", "delicately", "lazingly")) + if(SEX_FORCE_MID) + return pick(list("firmly", "vigorously", "eagerly", "steadily", "intently")) + if(SEX_FORCE_HIGH) + return pick(list("roughly", "carelessly", "forcefully", "fervently", "fiercely")) + if(SEX_FORCE_EXTREME) + return pick(list("brutally", "violently", "relentlessly", "savagely", "mercilessly")) + +/datum/sex_controller/proc/spanify_force(string) + switch(force) + if(SEX_FORCE_LOW) + return "[string]" + if(SEX_FORCE_MID) + return "[string]" + if(SEX_FORCE_HIGH) + return "[string]" + if(SEX_FORCE_EXTREME) + return "[string]" diff --git a/code/datums/sexcon/sexcon_helpers.dm b/code/datums/sexcon/sexcon_helpers.dm new file mode 100644 index 00000000000..eaeb81aa623 --- /dev/null +++ b/code/datums/sexcon/sexcon_helpers.dm @@ -0,0 +1,86 @@ +/datum/looping_sound/femhornylite + mid_sounds = list('sound/vo/female/gen/se/horny1loop (1).ogg') + mid_length = 470 + volume = 20 + extra_range = -4 + +/datum/looping_sound/femhornylitealt + mid_sounds = list('sound/vo/female/gen/se/horny1loop (2).ogg') + mid_length = 360 + volume = 20 + extra_range = -4 + +/datum/looping_sound/femhornymed + mid_sounds = list('sound/vo/female/gen/se/horny2loop (1).ogg') + mid_length = 420 + volume = 20 + extra_range = -4 + +/datum/looping_sound/femhornymedalt + mid_sounds = list('sound/vo/female/gen/se/horny2loop (2).ogg') + mid_length = 350 + volume = 20 + extra_range = -4 + +/datum/looping_sound/femhornyhvy + mid_sounds = list('sound/vo/female/gen/se/horny3loop (1).ogg') + mid_length = 440 + volume = 20 + extra_range = -4 + +/datum/looping_sound/femhornyhvyalt + mid_sounds = list('sound/vo/female/gen/se/horny3loop (2).ogg') + mid_length = 390 + volume = 20 + extra_range = -4 + +/mob/living + var/can_do_sex = TRUE + var/virginity = FALSE + var/defiant = FALSE + +/mob/living/carbon/human/MiddleMouseDrop_T(mob/living/target, mob/living/user) + if(user.mmb_intent) + return ..() + if(!istype(target)) + return + if(target != user) + return + if(!user.can_do_sex()) + to_chat(user, "I can't do this.") + return + user.sexcon.start(src) + +/mob/living/proc/can_do_sex() + return TRUE + +/mob/living/carbon/human/proc/make_sucking_noise() + if(gender == FEMALE) + playsound(src, pick('sound/misc/mat/girlmouth (1).ogg','sound/misc/mat/girlmouth (2).ogg'), 25, TRUE, ignore_walls = FALSE) + else + playsound(src, pick('sound/misc/mat/guymouth (1).ogg','sound/misc/mat/guymouth (2).ogg','sound/misc/mat/guymouth (3).ogg','sound/misc/mat/guymouth (4).ogg','sound/misc/mat/guymouth (5).ogg'), 35, TRUE, ignore_walls = FALSE) + +/mob/living/carbon/human/proc/try_impregnate(mob/living/carbon/human/wife) + var/obj/item/organ/testicles/testes = getorganslot(ORGAN_SLOT_TESTICLES) + if(!testes) + return + var/obj/item/organ/vagina/vag = wife.getorganslot(ORGAN_SLOT_VAGINA) + if(!vag) + return + if(prob(25)) + vag.be_impregnated(src) + +/mob/living/carbon/human/proc/get_highest_grab_state_on(mob/living/carbon/human/victim) + var/grabstate = null + if(r_grab && r_grab.grabbed == victim) + if(grabstate == null || r_grab.grab_state > grabstate) + grabstate = r_grab.grab_state + if(l_grab && l_grab.grabbed == victim) + if(grabstate == null || l_grab.grab_state > grabstate) + grabstate = l_grab.grab_state + return grabstate + +/proc/add_cum_floor(turfu) + if(!turfu || !isturf(turfu)) + return + new /obj/effect/decal/cleanable/coom(turfu) diff --git a/stonekeep.dme b/stonekeep.dme index 67d85546459..76c3f37a009 100644 --- a/stonekeep.dme +++ b/stonekeep.dme @@ -710,6 +710,28 @@ #include "code\datums\pollutants\generic.dm" #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" +#include "code\datums\sexcon\sex_action.dm" +#include "code\datums\sexcon\sexcon.dm" +#include "code\datums\sexcon\sexcon_helpers.dm" +#include "code\datums\sexcon\sex_actions\oral.dm" +#include "code\datums\sexcon\sex_actions\deviant\facesitting.dm" +#include "code\datums\sexcon\sex_actions\deviant\frotting.dm" +#include "code\datums\sexcon\sex_actions\deviant\scissoring.dm" +#include "code\datums\sexcon\sex_actions\deviant\thighjob.dm" +#include "code\datums\sexcon\sex_actions\deviant\titjob.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_other.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_other_penis.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_other_vagina.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_penis.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_penis_over.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_self.dm" +#include "code\datums\sexcon\sex_actions\masturbate\masturbate_vagina.dm" +#include "code\datums\sexcon\sex_actions\oral\blowjob.dm" +#include "code\datums\sexcon\sex_actions\oral\cunnilingus.dm" +#include "code\datums\sexcon\sex_actions\oral\rimming.dm" +#include "code\datums\sexcon\sex_actions\sex\anal_sex.dm" +#include "code\datums\sexcon\sex_actions\sex\throat_sex.dm" +#include "code\datums\sexcon\sex_actions\sex\vaginal_sex.dm" #include "code\datums\skills\_skill.dm" #include "code\datums\skills\combat.dm" #include "code\datums\skills\craft.dm" From 8bed4fcb7de53d9f5b128f946ba1b03e92d24f6d Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 22:52:48 -0700 Subject: [PATCH 02/33] defines --- code/__DEFINES/sexcon_defines.dm | 65 ++++++++++++++++++++++++++++++++ stonekeep.dme | 8 +--- 2 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 code/__DEFINES/sexcon_defines.dm diff --git a/code/__DEFINES/sexcon_defines.dm b/code/__DEFINES/sexcon_defines.dm new file mode 100644 index 00000000000..4e472a0cc27 --- /dev/null +++ b/code/__DEFINES/sexcon_defines.dm @@ -0,0 +1,65 @@ +GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) + +#define SEX_ACTION(sex_action_type) GLOB.sex_actions[sex_action_type] + +#define MAX_AROUSAL 150 +#define PASSIVE_EJAC_THRESHOLD 108 +#define ACTIVE_EJAC_THRESHOLD 100 +#define SEX_MAX_CHARGE 300 +#define CHARGE_FOR_CLIMAX 100 +#define AROUSAL_HARD_ON_THRESHOLD 20 +#define CHARGE_RECHARGE_RATE (CHARGE_FOR_CLIMAX / (5 MINUTES)) +#define AROUSAL_TIME_TO_UNHORNY (5 SECONDS) +#define SPENT_AROUSAL_RATE (3 / (1 SECONDS)) +#define IMPOTENT_AROUSAL_LOSS_RATE (3 / (1 SECONDS)) + + +#define AROUSAL_HIGH_UNHORNY_RATE (1.5 / (1 SECONDS)) +#define AROUSAL_MID_UNHORNY_RATE (0.4 / (1 SECONDS)) +#define AROUSAL_LOW_UNHORNY_RATE (0.2 / (1 SECONDS)) + +#define MOAN_COOLDOWN 3 SECONDS +#define PAIN_COOLDOWN 6 SECONDS + +#define SEX_SPEED_LOW 1 +#define SEX_SPEED_MID 2 +#define SEX_SPEED_HIGH 3 +#define SEX_SPEED_EXTREME 4 + +#define SEX_SPEED_MIN 1 +#define SEX_SPEED_MAX 4 + +#define SEX_FORCE_LOW 1 +#define SEX_FORCE_MID 2 +#define SEX_FORCE_HIGH 3 +#define SEX_FORCE_EXTREME 4 + +#define SEX_FORCE_MIN 1 +#define SEX_FORCE_MAX 4 + +#define SEX_MANUAL_AROUSAL_DEFAULT 1 +#define SEX_MANUAL_AROUSAL_UNAROUSED 2 +#define SEX_MANUAL_AROUSAL_PARTIAL 3 +#define SEX_MANUAL_AROUSAL_FULL 4 + +#define SEX_MANUAL_AROUSAL_MIN 1 +#define SEX_MANUAL_AROUSAL_MAX 4 + +#define BLUEBALLS_GAIN_THRESHOLD 15 +#define BLUEBALLS_LOOSE_THRESHOLD 10 + +#define PAIN_MILD_EFFECT 10 +#define PAIN_MED_EFFECT 20 +#define PAIN_HIGH_EFFECT 30 +#define PAIN_MINIMUM_FOR_DAMAGE PAIN_MED_EFFECT +#define PAIN_DAMAGE_DIVISOR 50 + +#define VIOLATED_ALLOWED_TIME (10 MINUTES) + +/proc/build_sex_actions() + . = list() + for(var/path in typesof(/datum/sex_action)) + if(is_abstract(path)) + continue + .[path] = new path() + return . diff --git a/stonekeep.dme b/stonekeep.dme index 76c3f37a009..08c5acff99c 100644 --- a/stonekeep.dme +++ b/stonekeep.dme @@ -96,6 +96,7 @@ #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\rust_g.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\sexcon_defines.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\skills.dm" @@ -720,15 +721,8 @@ #include "code\datums\sexcon\sex_actions\deviant\thighjob.dm" #include "code\datums\sexcon\sex_actions\deviant\titjob.dm" #include "code\datums\sexcon\sex_actions\masturbate\masturbate_other.dm" -#include "code\datums\sexcon\sex_actions\masturbate\masturbate_other_penis.dm" -#include "code\datums\sexcon\sex_actions\masturbate\masturbate_other_vagina.dm" -#include "code\datums\sexcon\sex_actions\masturbate\masturbate_penis.dm" #include "code\datums\sexcon\sex_actions\masturbate\masturbate_penis_over.dm" #include "code\datums\sexcon\sex_actions\masturbate\masturbate_self.dm" -#include "code\datums\sexcon\sex_actions\masturbate\masturbate_vagina.dm" -#include "code\datums\sexcon\sex_actions\oral\blowjob.dm" -#include "code\datums\sexcon\sex_actions\oral\cunnilingus.dm" -#include "code\datums\sexcon\sex_actions\oral\rimming.dm" #include "code\datums\sexcon\sex_actions\sex\anal_sex.dm" #include "code\datums\sexcon\sex_actions\sex\throat_sex.dm" #include "code\datums\sexcon\sex_actions\sex\vaginal_sex.dm" From 5f7092f2f865a93fda18c7af9aec0fd0caf454f0 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 22:59:13 -0700 Subject: [PATCH 03/33] de-zape --- code/datums/sexcon/sexcon.dm | 59 --------------------------- code/datums/stress/negative_events.dm | 5 --- 2 files changed, 64 deletions(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 582dbb6b11e..563d039c6fa 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -75,65 +75,6 @@ return FALSE return TRUE -/datum/sex_controller/proc/can_violate_victim(mob/living/carbon/human/victim) - if(!victim.mind) - return FALSE - if(!victim.mind.key) - return FALSE - if(!user.client.prefs.violated[victim.mind.key]) - return FALSE - if(user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME < world.time) - return FALSE - return TRUE - -/datum/sex_controller/proc/need_to_be_violated(mob/living/carbon/human/victim) - // Dont need to violate self - if(user == victim) - return FALSE - // If user and victim both are not defiant, then no violation needs to happen - if(!user.defiant && !victim.defiant) - return FALSE - // Need to violate AFK clients - if(victim.mind && victim.mind.key && !victim.client) - return TRUE - // Need to violate combat mode people - if(victim.cmode) - return TRUE - return FALSE - -/datum/sex_controller/proc/violate_victim(mob/living/carbon/human/victim) - if(!user.client) - return - if(!victim.mind) - return - if(!victim.mind.key) - return - if(user.client.prefs.violated[victim.mind.key] && user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME >= world.time) - return - var/pq_warning = pick(list("If I continue down this road, my soul will be burdened.", "I feel a terrible omen watching me...", "The forces of dark feel heavy on my soul.")) - to_chat(user, span_userdanger(pq_warning)) - var/alert = alert(user, "Do I really want to do this?", "Violate", "Yes", "No") - if(alert != "Yes") - return - user.visible_message(span_boldwarning("[user] begins to violate [victim]!")) - if(!do_after(user, 5 SECONDS, target = victim)) - return - if(!need_to_be_violated(victim)) - return - if(!user.client) - return - if(!victim.mind) - return - if(!victim.mind.key) - return - if(user.client.prefs.violated[victim.mind.key] && user.client.prefs.violated[victim.mind.key] + VIOLATED_ALLOWED_TIME >= world.time) - return - // ZAPED - to_chat(user, span_boldwarning(pick(list("I feel tainted...", "I feel less human...")))) - log_combat(user, victim, "Initiated rape against") - adjust_playerquality(-4, user.ckey, reason = "Initiated rape on an AFK/resisting person.") - user.client.prefs.violated[victim.mind.key] = world.time - /datum/sex_controller/proc/adjust_speed(amt) speed = clamp(speed + amt, SEX_SPEED_MIN, SEX_SPEED_MAX) diff --git a/code/datums/stress/negative_events.dm b/code/datums/stress/negative_events.dm index bc304df7fa0..407f958255c 100644 --- a/code/datums/stress/negative_events.dm +++ b/code/datums/stress/negative_events.dm @@ -164,11 +164,6 @@ max_stacks = 3 desc = "I puked on myself!" -/datum/stressevent/cumbad - timer = 5 MINUTES - stressadd = 5 - desc = "I was violated." - /datum/stressevent/blueb timer = 1 MINUTES stressadd = 2 From 88919d661dbd57378bba12f5c48ccceb1f8a52fb Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 23:32:12 -0700 Subject: [PATCH 04/33] and that's for dedicated coder than me to fight an uphill battle against --- code/__DEFINES/sexcon_defines.dm | 4 +- code/datums/sexcon.dm | 1209 ----------------- .../sexcon/sex_actions/deviant/facesitting.dm | 1 - .../sexcon/sex_actions/deviant/frotting.dm | 8 +- .../sexcon/sex_actions/deviant/thighjob.dm | 8 +- .../sexcon/sex_actions/deviant/titjob.dm | 4 +- .../masturbate/masturbate_other.dm | 4 +- .../masturbate/masturbate_penis_over.dm | 4 +- .../sex_actions/masturbate/masturbate_self.dm | 4 +- code/datums/sexcon/sex_actions/oral.dm | 6 +- .../datums/sexcon/sex_actions/sex/anal_sex.dm | 8 +- .../sexcon/sex_actions/sex/throat_sex.dm | 7 +- .../sexcon/sex_actions/sex/vaginal_sex.dm | 8 +- code/datums/sexcon/sexcon.dm | 128 +- stonekeep.dme | 1 - 15 files changed, 35 insertions(+), 1369 deletions(-) delete mode 100644 code/datums/sexcon.dm diff --git a/code/__DEFINES/sexcon_defines.dm b/code/__DEFINES/sexcon_defines.dm index 4e472a0cc27..685389997b1 100644 --- a/code/__DEFINES/sexcon_defines.dm +++ b/code/__DEFINES/sexcon_defines.dm @@ -19,7 +19,6 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define AROUSAL_LOW_UNHORNY_RATE (0.2 / (1 SECONDS)) #define MOAN_COOLDOWN 3 SECONDS -#define PAIN_COOLDOWN 6 SECONDS #define SEX_SPEED_LOW 1 #define SEX_SPEED_MID 2 @@ -32,10 +31,9 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define SEX_FORCE_LOW 1 #define SEX_FORCE_MID 2 #define SEX_FORCE_HIGH 3 -#define SEX_FORCE_EXTREME 4 #define SEX_FORCE_MIN 1 -#define SEX_FORCE_MAX 4 +#define SEX_FORCE_MAX 3 #define SEX_MANUAL_AROUSAL_DEFAULT 1 #define SEX_MANUAL_AROUSAL_UNAROUSED 2 diff --git a/code/datums/sexcon.dm b/code/datums/sexcon.dm deleted file mode 100644 index 264417f7549..00000000000 --- a/code/datums/sexcon.dm +++ /dev/null @@ -1,1209 +0,0 @@ -/datum/sex_controller - var/mob/living/owner - //intruders - var/mob/living/inpussy - var/mob/living/inmouth - var/mob/living/inass - var/mob/living/eatingus //eating is someone else sucking, we are not forcing them to - var/mob/living/ontits - var/obj/item/grabbing/fapping - var/lastfap - var/fapspeed = 12 - //ours - var/mob/living/fucking //what we are inside of - var/fuckspeed = 12 - var/lastfuck - var/mob/living/weeating - var/eatspeed = 12 - var/lasteat - var/mob/living/riding - var/horny - var/maxhorny - var/lasthorny - var/draining - var/blueballs - var/gender = MALE - var/last_clothing_check - var/last_silence_check - -/datum/sex_controller/New(Target) - . = ..() - if(ismob(Target)) - owner = Target - -/datum/sex_controller/Destroy() - ..() - cancel_all_sex() - -/datum/sex_controller/male - gender = MALE - -/datum/sex_controller/female - gender = FEMALE - var/curplaying - var/datum/looping_sound/femmoans - -/mob - var/can_do_sex = 2 - -/mob/proc/can_do_sex() - if(can_do_sex != 2) - return can_do_sex - if(!client) - return FALSE - if(get_playerquality(client.ckey) <= -10) - return FALSE - if(client.blacklisted()) - can_do_sex = 0 - return can_do_sex - can_do_sex = 1 - return can_do_sex - -/mob/living/carbon/MiddleMouseDrop_T(mob/living/target, mob/living/user) - // SELF ONTO SELF - if(user.mmb_intent) - return ..() - if(!istype(target)) - return - if(!user.can_do_sex()) - to_chat(user, "I can't do this.") - return - if(!can_do_sex()) -// to_chat(user, "I can't do this.") - return - if(target == src && src == user) //drag us onto ourselves - var/obj/item/bodypart/chest = get_bodypart(BODY_ZONE_CHEST) - for(var/obj/item/grabbing/G in grabbedby) - if(G.limb_grabbed == chest) - if(G.grabbee == user) - if(G.sublimb_grabbed == BODY_ZONE_PRECISE_GROIN) - var/yea = list("pleasure self") - var/td = input(user, "pleasures","") as null|anything in yea - if(td == "fap") - sexcon.begin_fapping(G, user) - //US ONTO VICTIM - if(src != target && target == user) - var/what2do = list() - var/theirgroin = TRUE - var/ourgroin = TRUE - var/ourmouth = TRUE - var/theirmouth = TRUE - if(!get_location_accessible(src, BODY_ZONE_PRECISE_MOUTH)) - theirmouth = FALSE - if(!get_location_accessible(src, BODY_ZONE_PRECISE_GROIN)) - theirgroin = FALSE - if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) - ourmouth = FALSE - if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) - ourgroin = FALSE - if(ourmouth && theirgroin) - what2do += "mouth service" - if(ourgroin && theirmouth) - if(user.gender == MALE) - what2do += "mouth feed" - else - if(!user.lying && src.lying) - what2do += "mouth ride" - if(ourgroin) - if(user.gender == MALE) - if(gender == FEMALE) - if(get_location_accessible(src, BODY_ZONE_CHEST)) - what2do += "taff chest" - if(user.gender == MALE) - if(ourgroin && theirgroin) - what2do += "taff the front" - what2do += "taff the back" - if(user.gender == FEMALE) - if(ourgroin && theirgroin) - if(!user.lying && src.lying) - what2do += "ride" - var/obj/item/bodypart/chest = get_bodypart(BODY_ZONE_CHEST) - var/obj/G - for(var/obj/item/grabbing/A in grabbedby) - if(A.limb_grabbed == chest) - if(A.grabbee == user) - if(A.sublimb_grabbed == BODY_ZONE_PRECISE_GROIN) - G = A - what2do += "service" - var/td = input(user, "pleasures","") as null|anything in what2do - switch(td) - if("mouth service") - user.sexcon.begin_eating(src) - if("ride") - user.sexcon.begin_riding(src) - if("mouth feed") - user.sexcon.begin_mouthfuck(src) - if("mouth ride") - user.sexcon.begin_mouthride(src) - if("use chest") - user.sexcon.begin_titfuck(src) - if("taff back") - user.sexcon.begin_assfuck(src) - if("taff front") - user.sexcon.begin_fuck(src) - if("service") - if(G) - src.sexcon.begin_fapping(G, user) - -/datum/sex_controller/proc/begin_fuck(mob/living/user) - testing("fuckstart") - if(!user) - testing("fuckfail") - return - if(gender == FEMALE) - testing("fuckfail2") - return - if(user.loc != owner.loc) - testing("fuckfailloc") - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - testing("fuckfail3") - return - if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) - testing("fuckfail4") - return - if(HAS_TRAIT(owner, TRAIT_LIMPDICK)) - to_chat(owner, "My soldier won't stand up for me.") - return - if(user.sexcon.inpussy) - if(user.sexcon.inpussy != owner) - testing("fuckfail5") - return - if(eatingus) - testing("fuckfail6") - return - if(fucking) - if(fucking == user) - if(fucking.sexcon.riding == owner) - testing("fuckfail7") - fucking.sexcon.stop_riding() - if(fucking) - if(fucking == user) - if(fuckspeed == initial(fuckspeed)) - fuckspeed = max(round(fuckspeed / 2), 1) - to_chat(owner, "I speed up.") - else - fuckspeed = initial(fuckspeed) - to_chat(owner, "I slow down.") - else - stop_fucking() - return - if(horny < 0) - to_chat(owner, "I'm spent.") - return - fuckspeed = initial(fuckspeed) - lastfuck = world.time - fucking = user - user.sexcon.inpussy = owner - if(user.cmode) - user.emote("embed", forced = TRUE) - playsound(owner, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] taffs [user].") - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.virginity) - user.visible_message("[user] loses her purity!") - H.flash_fullscreen("redflash3") - H.on_virgin_loss() - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/mob/living/carbon/human/proc/on_virgin_loss() - var/mob/living/carbon/P = src - virginity = FALSE - if(mind) - switch(mind.assigned_role) - if("Priest") - P.add_stress(/datum/stressevent/virginchurch) - adjust_triumphs(-2) - if("Acolyte") - P.add_stress(/datum/stressevent/virginchurch) - adjust_triumphs(-3) - if("Cleric") - P.add_stress(/datum/stressevent/virginchurch) - adjust_triumphs(-2) - -/datum/sex_controller/proc/begin_assfuck(mob/living/user) - if(!user) - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - return - if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) - return - if(user.sexcon.inass) - if(user.sexcon.inass != owner) - return - if(gender == FEMALE) - testing("fuckfail2") - return - if(eatingus) - return - if(HAS_TRAIT(owner, TRAIT_LIMPDICK)) - to_chat(owner, "My soldier won't stand up for me.") - return - if(user.loc != owner.loc) - return - if(fucking) - if(fucking == user) - if(fucking.sexcon.riding == owner) - fucking.sexcon.stop_riding() - if(fucking) - if(fucking == user) - if(fuckspeed == initial(fuckspeed)) - fuckspeed = max(round(fuckspeed / 2), 1) - to_chat(owner, "I speed up.") - else - fuckspeed = initial(fuckspeed) - to_chat(owner, "I slow down.") - else - stop_fucking() - return - if(horny < 0) - to_chat(owner, "I'm spent.") - return - fuckspeed = initial(fuckspeed) - lastfuck = world.time - fucking = user - user.sexcon.inass = owner - if(user.cmode) - user.emote("embed", forced = TRUE) - playsound(owner, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] taffs [user] from behind.") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/begin_titfuck(mob/living/user) - if(!user) - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - return - if(!get_location_accessible(user, BODY_ZONE_CHEST)) - return - if(user.gender != FEMALE || gender != MALE) - return - if(user.sexcon.ontits) - if(user.sexcon.ontits != owner) - testing("tfuckfail") - return - if(eatingus) - testing("tfuckfail2") - return - if(HAS_TRAIT(owner, TRAIT_LIMPDICK)) - to_chat(owner, "My soldier won't stand up for me.") - return - if(!user.lying && !user.wallpressed && !owner.wallpressed && !owner.lying) - return - if(user.loc != owner.loc) - return - if(fucking) - if(fucking == user) - if(fucking.sexcon.riding == owner) - fucking.sexcon.stop_riding() - if(fucking) - if(fucking == user) - if(fuckspeed == initial(fuckspeed)) - fuckspeed = max(round(fuckspeed / 2), 1) - to_chat(owner, "I speed up.") - else - fuckspeed = initial(fuckspeed) - to_chat(owner, "I slow down.") - else - stop_fucking() - return - if(horny < 0) - to_chat(owner, "I'm spent.") - return - fuckspeed = initial(fuckspeed) - lastfuck = world.time - fucking = user - user.sexcon.ontits = owner - owner.visible_message("[owner] uses [user]'s chest.") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/begin_mouthfuck(mob/living/user) - if(!user) - testing("mfuckfail") - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_MOUTH)) - return - if(user.sexcon.inmouth) - if(user.sexcon.inmouth != owner) - testing("mfuckfail2") - return - if(user.cmode) - if(!user.stat) - to_chat(owner, "Not through clenched teeth.") - return - if(user.sexcon.weeating) - testing("mfuckfail3") - if(user.sexcon.weeating != owner) - return - else - user.sexcon.stop_eating() - if(user.loc != owner.loc) - return - if(HAS_TRAIT(owner, TRAIT_LIMPDICK)) - to_chat(owner, "My soldier won't stand up for me.") - return - if(gender != MALE) - return - if(fucking) - testing("mfuckfail4") - if(fucking == user) - if(fuckspeed == initial(fuckspeed)) - fuckspeed = max(round(fuckspeed / 2), 1) - to_chat(owner, "I speed up.") - else - fuckspeed = initial(fuckspeed) - to_chat(owner, "I slow down.") - else - stop_fucking() - return - if(horny < 0) - to_chat(owner, "I'm spent.") - return - fuckspeed = initial(fuckspeed) - lastfuck = world.time - fucking = user - user.sexcon.inmouth = owner - playsound(owner, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] feeds [user].") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/begin_mouthride(mob/living/user) - if(!user) - testing("mridefail") - return - if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - return - if(gender != FEMALE) - return - if(user.loc != owner.loc) - return - if(!user.lying || owner.lying) - return - if(inpussy) - testing("mridefail2") - return - if(eatingus) - testing("mridefail3") - if(eatingus != user) //someone is eating us already that isnt the user so we cant change - testing("mridefail4") - return - else - testing("mridefail5") - stop_eating_us() - if(user.sexcon.weeating) - if(user.sexcon.weeating != owner) //they are eating someone else - testing("mridefail6") - return - else - user.sexcon.stop_eating() - if(riding) - testing("mridefail7") - if(riding == user) - if(user.sexcon.eatspeed == initial(user.sexcon.eatspeed)) - user.sexcon.eatspeed = max(round(user.sexcon.eatspeed / 2), 1) - to_chat(owner, "I speed up.") - else - user.sexcon.eatspeed = initial(user.sexcon.eatspeed) - to_chat(owner, "I slow down.") - else - stop_riding() - return - if(horny < 0) - to_chat(owner, "I'm spent.") - return - user.sexcon.eatspeed = initial(user.sexcon.eatspeed) - user.sexcon.lasteat = world.time - user.sexcon.weeating = owner - riding = user - owner.visible_message("[owner] rides [riding]'s face.") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -//basically fucking but we can control the speed too -/datum/sex_controller/proc/begin_riding(mob/living/user) - if(!user) - testing("ridefail") - return - if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) - testing("ridefail2") - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - testing("ridefail3") - return - if(!user.lying || owner.lying) - return - if(user.sexcon.gender != MALE) - testing("ridefail4") - return - if(gender != FEMALE) - testing("ridefail5") - return - if(HAS_TRAIT(user, TRAIT_LIMPDICK)) - to_chat(owner, "The soldier won't stand up for me.") - return - if(inpussy && !riding) - if(inpussy != user) - return - else - user.sexcon.stop_fucking() //start riding instead - if(eatingus) - testing("ridefail6") - return - if(riding) - testing("ridefail7") - if(riding == user) - if(riding.sexcon.weeating != owner) - testing("ridefail8") - if(user.sexcon.fuckspeed == initial(user.sexcon.fuckspeed)) - user.sexcon.fuckspeed = max(round(user.sexcon.fuckspeed / 2), 1) - to_chat(owner, "I speed up.") - else - user.sexcon.fuckspeed = initial(user.sexcon.fuckspeed) - to_chat(owner, "I slow down.") - else - stop_riding() - else - stop_riding() - return -// if(horny < 0) -// to_chat(owner, "I'm spent.") -// return - user.sexcon.fuckspeed = initial(user.sexcon.fuckspeed) - user.sexcon.fucking = owner - user.sexcon.lastfuck = world.time - riding = user - inpussy = user - playsound(owner, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] rides [riding].") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/begin_eating(mob/living/user) - if(!user) - testing("eatfail1") - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_MOUTH)) - testing("eatfail12") - return - if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) - testing("eatfail13") - return - if(eatingus) - if(eatingus == user) - if(!(user.lying && owner.lying)) - testing("eatfail1lyy") - return - if(user.sexcon.eatingus) //someone else eating us - testing("eatfail14") - if(user.sexcon.eatingus != owner) - testing("eatfail5") - return - else if(user.sexcon.riding == owner) //start eating instead - testing("eatfail6") - user.sexcon.stop_riding() - if(user.sexcon.gender == MALE) //start sucking instead - testing("eatfail7") - if(user.sexcon.fucking) - if(user.sexcon.fucking == owner) - if(inmouth == user) - user.sexcon.stop_fucking() - else - return - if(weeating) - testing("sp1") - if(weeating == user) - if(eatspeed == initial(eatspeed)) - eatspeed = max(round(eatspeed / 2), 1) - to_chat(owner, "I speed up.") - else - eatspeed = initial(eatspeed) - to_chat(owner, "I slow down.") - else - stop_eating() - return - eatspeed = initial(eatspeed) - weeating = user - user.sexcon.lasteat = world.time - user.sexcon.eatingus = owner - if(weeating.gender == MALE) - owner.visible_message("[owner] sucks [weeating].") - else - owner.visible_message("[owner] eats [weeating].") - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/begin_fapping(obj/item/grabbing/G, mob/living/user) - if(!G) - testing("fapfail1") - return - if(fucking) - testing("fapfail2") - return - if(eatingus) - testing("fapfail3") - return - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - testing("fapfail4") - return - if(HAS_TRAIT(owner, TRAIT_LIMPDICK)) - to_chat(user, "The soldier won't stand up for me.") - return - if(fapping) - testing("fapfail6") - if(fapping == G) - testing("fapfail7") - if(fapspeed == initial(fapspeed)) - fapspeed = max(round(fapspeed / 2), 1) - to_chat(user, "I speed up.") - else - fapspeed = initial(fapspeed) - to_chat(user, "I slow down.") - return - if(user == owner) - owner.visible_message("[owner] faps.") - if(horny < 0) - to_chat(owner, "I'm spent.") - return - fapspeed = initial(fapspeed) - lastfap = world.time - fapping = G - G.handaction = "fapping" - if(user != owner) - if(gender == MALE) - owner.visible_message("[fapping.grabbee] jerks [owner].") - else - owner.visible_message("[fapping.grabbee] rubs [owner].") - G.dependents += src - START_PROCESSING(SSsex, user.sexcon) - START_PROCESSING(SSsex, src) - -/datum/sex_controller/grabdropped(obj/item/grabbing/G) - ..() - if(fapping == G) - if(G.grabbee == owner) - stop_fapping() - else - stop_fapping_us() - -/datum/sex_controller/proc/mob_moved() - cancel_others_actions() - cancel_our_actions(TRUE) - -/datum/sex_controller/proc/cancel_all_sex() - cancel_others_actions() - cancel_our_actions() - -/datum/sex_controller/proc/cancel_others_actions() - var/datum/sex_controller/D - if(fapping) - stop_fapping_us() - if(eatingus) - D = eatingus.sexcon - if(D.weeating == owner) - D.stop_eating() - if(ontits) - D = ontits.sexcon - if(D.fucking == owner) - D.stop_fucking() - if(inmouth) - D = inmouth.sexcon - if(D.fucking == owner) - D.stop_fucking() - if(inass) - D = inass.sexcon - if(D.fucking == owner) - D.stop_fucking() - if(inpussy) - D = inpussy.sexcon - if(D.fucking == owner) - D.stop_fucking() - if(fucking) - D = fucking.sexcon - if(D.riding == owner) - D.stop_riding() - -/datum/sex_controller/proc/cancel_our_actions(checkfap) - var/cancelled - var/datum/sex_controller/D - if(!checkfap) - if(fapping) - cancelled = TRUE - stop_fapping() - if(riding) - stop_riding() - if(fucking) - stop_fucking() - if(weeating) - D = weeating.sexcon - if(D.eatingus == owner) - D.eatingus = null - weeating = null - cancelled = TRUE - if(cancelled) - return TRUE - -/datum/sex_controller/proc/can_change_dir() - if(fucking || inass || inpussy || ontits || inmouth || weeating || riding || (fapping && fapping.grabbee != owner)) - return FALSE - return TRUE - -/datum/sex_controller/proc/stop_fucking() - if(fucking) - var/datum/sex_controller/D = fucking.sexcon - var/stopped = TRUE - if(D.inass == owner) - D.inass = null - if(D.ontits == owner) - D.ontits = null - if(D.inmouth == owner) - D.inmouth = null - if(D.riding == owner) //we didn't truly stop fucking - stopped = FALSE - else if(D.inpussy == owner) - D.inpussy = null - if(stopped) - fucking = null - -/datum/sex_controller/proc/stop_riding() - if(riding && riding.sexcon.fucking == owner) - riding.sexcon.fucking = null - riding = null - inpussy = null - if(riding && riding.sexcon.weeating == owner) - riding.sexcon.weeating = null - riding = null - -/datum/sex_controller/proc/stop_eating_us() - testing("stopeatingus") - if(eatingus && eatingus.sexcon.weeating == owner) - eatingus.sexcon.weeating = null - eatingus = null - -/datum/sex_controller/proc/stop_eating() - if(weeating && weeating.sexcon.eatingus == owner) - weeating.sexcon.eatingus = null - weeating = null - -/datum/sex_controller/proc/stop_fapping_us() - testing("fapping us") - if(fapping && fapping.grabbee != owner) - fapping.handaction = null - fapping = null - -/datum/sex_controller/proc/stop_fapping() - testing("fapping st") - if(fapping && fapping.grabbee == owner) - fapping.handaction = null - fapping = null - -/datum/sex_controller/process() - if(!owner) - STOP_PROCESSING(SSsex, src) - return - - var/doing - if(eatingus || fapping || fucking) - if(world.time > last_clothing_check + 8 SECONDS) - last_clothing_check = world.time - if(!get_location_accessible(owner, BODY_ZONE_PRECISE_GROIN)) - if(fucking) - stop_fucking() - if(fapping) - stop_fapping() - stop_fapping_us() - if(riding) - stop_riding() - if(eatingus) - stop_eating_us() - if(fucking) - var/datum/sex_controller/D = fucking.sexcon - if(D) - doing = TRUE - if(world.time > lastfuck + max(fuckspeed + rand(-3,3), 1)) - lastfuck = world.time - if(D.riding == owner) - if(fuckspeed != initial(fuckspeed)) - if(!D.owner.rogfat_add(2)) - D.stop_riding() - if(fucking) - playsound(owner, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - fucking.visible_message("[fucking] rides [owner].") - var/usedsource = "insidepussy" - D.adjust_horny(4, "pussyfucked") - if(adjust_horny(3, usedsource)) - D.adjust_horny(50, "pussyfucked") - D.stop_riding() - else if(D.inpussy == owner) - if(fuckspeed != initial(fuckspeed)) - if(!owner.rogfat_add(2)) - stop_fucking() - if(fucking) - playsound(owner, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - fucking.visible_message("[owner] taffs [fucking].") - var/usedsource = "insidepussy" - if(D.owner.stat != CONSCIOUS) - usedsource = "sleepingbeauty" - if(D.owner.cmode) - D.owner.flash_fullscreen("redflash1") - D.adjust_horny(4, "pussyfucked") - if(adjust_horny(3, usedsource)) - if(!D.owner.cmode) - D.adjust_horny(50, "pussyfucked") - stop_fucking() - if(D.inass == owner) - if(fuckspeed != initial(fuckspeed)) - if(!owner.rogfat_add(2)) - stop_fucking() - if(fucking) - playsound(owner, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - fucking.visible_message("[owner] taffs [fucking] from behind.") -// D.owner.Immobilize(10) - var/usedsource = "insideass" - if(D.owner.cmode) - D.owner.flash_fullscreen("redflash1") - if(D.owner.cmode) - if(D.gender == FEMALE) - D.adjust_horny(1, "assfucked") - else - D.adjust_horny(2, "assfucked") - if(adjust_horny(2, usedsource)) - if(!D.owner.cmode) - D.adjust_horny(50, "assfucked") - stop_fucking() - if(D.ontits == owner) - if(fuckspeed != initial(fuckspeed)) - if(!owner.rogfat_add(2)) - stop_fucking() - if(fucking) - playsound(owner, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - fucking.visible_message("[owner] taffs [fucking]'s chest.") - var/usedsource = "ontits" - if(adjust_horny(2, usedsource)) - stop_fucking() -// D.owner.Immobilize(10) - if(D.inmouth == owner) - - if(fuckspeed != initial(fuckspeed)) - if(!owner.rogfat_add(2)) - stop_fucking() - if(!fucking.rogfat_add(3, "gag", FALSE)) - stop_fucking() - if(fucking) - if(gender == FEMALE) - playsound(fucking, pick('sound/misc/mat/girlmouth (1).ogg','sound/misc/mat/girlmouth (2).ogg'), 10, TRUE, ignore_walls = FALSE) - else - playsound(fucking, pick('sound/misc/mat/guymouth (1).ogg','sound/misc/mat/guymouth (2).ogg','sound/misc/mat/guymouth (3).ogg','sound/misc/mat/guymouth (4).ogg','sound/misc/mat/guymouth (5).ogg'), 20, TRUE, ignore_walls = FALSE) - if(prob(33)) - fucking.visible_message("[owner] thrusts in [fucking]'s mouth.") -// D.owner.Immobilize(10) - var/usedsource = "fuckmouth" - if(adjust_horny(3, usedsource)) - stop_fucking() - if(riding) - if(riding.sexcon.weeating == owner) - var/datum/sex_controller/D = riding.sexcon - doing = TRUE - if(world.time > D.lasteat + max(D.eatspeed + rand(-3,3), 1)) - D.lasteat = world.time - if(D.eatspeed != initial(D.eatspeed)) - if(!riding.rogfat_add(1, "gag", FALSE)) - stop_riding() - playsound(D.owner, pick('sound/misc/mat/girlmouth (1).ogg','sound/misc/mat/girlmouth (2).ogg'), 100, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - owner.visible_message("[owner] rides [riding]'s face.") - if(adjust_horny(3, "suckedoff")) - stop_riding() - if(eatingus) - if(eatingus.sexcon.weeating != owner) - eatingus = null - if(eatingus) - doing = TRUE - if(world.time > eatingus.sexcon.lasteat + max(eatingus.sexcon.eatspeed + rand(-3,3), 1)) - eatingus.sexcon.lasteat = world.time - if(eatingus.sexcon.eatspeed != initial(eatingus.sexcon.eatspeed)) - if(!eatingus.rogfat_add(1, "gag", FALSE)) - stop_eating_us() - if(gender == FEMALE) - playsound(eatingus, pick('sound/misc/mat/girlmouth (1).ogg','sound/misc/mat/girlmouth (2).ogg'), 100, TRUE, -2, ignore_walls = FALSE) - else - playsound(eatingus, pick('sound/misc/mat/guymouth (1).ogg','sound/misc/mat/guymouth (2).ogg','sound/misc/mat/guymouth (3).ogg','sound/misc/mat/guymouth (4).ogg','sound/misc/mat/guymouth (5).ogg'), 100, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - if(owner.gender == MALE) - owner.visible_message("[eatingus] sucks off [owner].") - else - owner.visible_message("[eatingus] eats out [owner].") - if(adjust_horny(3, "suckedoff")) - stop_eating_us() - if(fapping) - if(!fapping.grabbee) - fapping = null - if(fapping) - doing = TRUE - if(world.time > lastfap + max(fapspeed + rand(-3,3), 1)) - lastfap = world.time - if(fapping.grabbee == owner) - if(fapspeed != initial(fapspeed)) - if(!owner.rogfat_add(3)) - stop_fapping() - if(fapping) - playsound(owner, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - owner.visible_message("[owner] pleasures themself.") - if(adjust_horny(1, "fapself")) - stop_fapping() - else - if(fapspeed != initial(fapspeed)) - if(!fapping.grabbee.rogfat_add(1)) - stop_fapping_us() - if(fapping) - playsound(owner, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) - if(prob(33)) - if(gender == MALE) - fapping.grabbee.visible_message("[fapping.grabbee] jerks [owner].") - else - fapping.grabbee.visible_message("[fapping.grabbee] rubs [owner].") - if(adjust_horny(2, "otherfapping")) - stop_fapping_us() - if(!doing) - STOP_PROCESSING(SSsex, src) - -/datum/sex_controller/proc/handle_sex() - if(!draining) - if(world.time > lasthorny + 3 SECONDS) - draining = TRUE - - var/severity = 0 - switch(horny) - if(150 to 160) - severity = 1 - if(160 to 170) - severity = 2 - if(170 to 180) - severity = 3 - if(180 to 190) - severity = 4 - if(190 to 200) - severity = 5 - if(200 to 210) - severity = 6 - if(210 to 220) - severity = 7 - if(220 to 230) - severity = 8 - if(230 to 240) - severity = 9 - if(240 to 300) - severity = 10 - owner.overlay_fullscreen("horny", /atom/movable/screen/fullscreen/love, severity) - else - owner.clear_fullscreen("horny") - - if(horny > 0) - adjust_horny(-1) - else if(horny < 0) - adjust_horny(1) - - if(owner.stat != CONSCIOUS) - cancel_our_actions() - -/datum/sex_controller/male/handle_sex() - . = ..() - if(horny > 30 && !blueballs) - blueballs = TRUE - -/datum/sex_controller/female/handle_sex() - . = ..() - -/datum/sex_controller/proc/adjust_horny(amt, source) - if(!amt) - return - if(!owner) - return - if(owner.stat == DEAD) - return - if(amt < 0) - lasthorny = 0 - draining = TRUE -// cancel_our_actions() - if(amt > 0) - if(owner.cmode) - amt = round(amt/2) - amt = max(amt + rand(-1,1), 1) - if(source != "otherfapping") - owner.AdjustSleeping(-50) - horny = clamp(horny + amt, -100, 250) -// owner.update_horny_hud() - if(amt > 0) - lasthorny = world.time - draining = FALSE - if(horny >= 250) - cum(source) - owner.playsound_local(owner, 'sound/misc/mat/end.ogg', 100) - return TRUE - -/datum/sex_controller/male/adjust_horny(amt, source) - var/oldhorny = horny - if(owner.mind) - if(owner.mind.has_antag_datum(/datum/antagonist/obsessed)) - return - . = ..() - var/mob/living/carbon/C = owner - if(horny <= 0 && oldhorny > 0 && blueballs && !source) - C.add_stress(/datum/stressevent/blueb) - horny = clamp(horny - 80, -100, 250) - -/datum/sex_controller/proc/cum(source) - if(!owner) - return - if(owner.mind) - if(owner.mind.has_antag_datum(/datum/antagonist/obsessed)) - return - SSticker.cums++ - blueballs = FALSE - adjust_horny(-350) - var/mob/living/carbon/C = owner - switch(source) - if("fapself") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - C.add_stress(/datum/stressevent/cumok) - if("otherfapping") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - C.add_stress(/datum/stressevent/cumok) - if("assfucked") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - if(!owner.cmode) - C.add_stress(/datum/stressevent/cumok) - else - C.add_stress(/datum/stressevent/cumbad) - -/datum/sex_controller/male/cum(source) - ..() - var/mob/living/carbon/C = owner - switch(source) - if("ontits") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - C.add_stress(/datum/stressevent/cumok) - playsound(owner, 'sound/misc/mat/endout.ogg', 1, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] paints [fucking]!") - add_cum_floor(get_turf(fucking)) - if("suckedoff") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - C.add_stress(/datum/stressevent/cumgood) - owner.visible_message("[owner] feeds [fucking]!") - playsound(owner, pick('sound/misc/mat/mouthend (1).ogg','sound/misc/mat/mouthend (2).ogg'), 100, FALSE, ignore_walls = FALSE) - add_cum_floor(get_turf(fucking)) - if("fuckmouth") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - C.add_stress(/datum/stressevent/cummid) - playsound(owner, pick('sound/misc/mat/mouthend (1).ogg','sound/misc/mat/mouthend (2).ogg'), 100, FALSE, ignore_walls = FALSE) - owner.visible_message("[owner] feeds [fucking]!") - add_cum_floor(get_turf(fucking)) - if("insideass") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.virginity) - H.on_virgin_loss() - if(fucking && fucking.cmode) - var/wuzantag - if(H.mind) - if(H.mind.antag_datums) - if(H.mind.antag_datums.len) - wuzantag = TRUE - if(!wuzantag) - adjust_playerquality(-2, H.ckey, reason="Raped as a non villain.") - C.add_stress(/datum/stressevent/cumok) - owner.visible_message("[owner] tightens in ecstasy!") - playsound(owner, 'sound/misc/mat/endin.ogg', 100, TRUE, ignore_walls = FALSE) - add_cum_floor(get_turf(fucking)) - if("insidepussy") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.virginity) - H.on_virgin_loss() - if(fucking && !fucking.cmode) - var/yee - if(ishuman(owner) && ishuman(fucking)) - var/mob/living/carbon/human/H = owner - var/mob/living/carbon/human/F = fucking - if((F.IsWedded() && !F.RomanticPartner(H)) || (H.IsWedded() && !H.RomanticPartner(F))) - if(SSticker.cuckers) - SSticker.cuckers += ", [F.real_name] (with [H.real_name])" - else - SSticker.cuckers += "[F.real_name] (with [H.real_name])" - if(H.RomanticPartner(F)) - yee = 1 - C.add_stress(/datum/stressevent/cumlove) - if(HAS_TRAIT(F, TRAIT_GOODLOVER)) - if(!H.mob_timers["cumtri"]) - H.mob_timers["cumtri"] = world.time - H.adjust_triumphs(1) - if(HAS_TRAIT(H, TRAIT_GOODLOVER)) - if(!F.mob_timers["cumtri"]) - F.mob_timers["cumtri"] = world.time - F.adjust_triumphs(1) - if(!yee) - C.add_stress(/datum/stressevent/cummax) - else - C.add_stress(/datum/stressevent/cumok) - var/mob/living/M = owner - var/wuzantag - if(M.mind) - if(M.mind.antag_datums) - if(M.mind.antag_datums.len) - wuzantag = TRUE - if(!wuzantag) - adjust_playerquality(-2, M.ckey, reason="Raped as a non villain.") - to_chat(GLOB.admins, " [fucking] resisted [owner] during sex") - playsound(fucking, 'sound/misc/mat/endin.ogg', 100, TRUE, ignore_walls = FALSE) - owner.visible_message("[owner] tightens in ecstasy!") - add_cum_floor(get_turf(fucking)) - - if("sleepingbeauty") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.virginity) - H.on_virgin_loss() - if(fucking) - var/wuzantag - if(H.mind) - if(H.mind.antag_datums) - if(H.mind.antag_datums.len) - wuzantag = TRUE - if(!wuzantag) - adjust_playerquality(-1, H.ckey, reason="Fucked a sleeping player as a non-villain.") - to_chat(GLOB.admins, "[owner] fucked [fucking] while they were asleep.") - C.add_stress(/datum/stressevent/cumok) - playsound(fucking, 'sound/misc/mat/endin.ogg', 100, TRUE, ignore_walls = FALSE) - add_cum_floor(get_turf(fucking)) - owner.visible_message("[owner] tightens in ecstasy!") - - if("fapself") - add_cum_floor(get_turf(owner)) - owner.visible_message("[owner] spills something on the floor!") - playsound(owner, 'sound/misc/mat/endout.ogg', 100, TRUE, ignore_walls = FALSE) - if("otherfapping") - add_cum_floor(get_turf(fapping.grabbee)) - owner.visible_message("[owner] spills something on the floor!") - playsound(owner, 'sound/misc/mat/endout.ogg', 100, TRUE, ignore_walls = FALSE) - if("assfucked") - add_cum_floor(get_turf(owner)) - owner.visible_message("[owner] spills something on the floor!") - playsound(owner, 'sound/misc/mat/endout.ogg', 100, TRUE, ignore_walls = FALSE) - - -/datum/sex_controller/female/adjust_horny(amt, source) - . = ..() - if((amt > 0) && prob(80)) - switch(source) - if("pussyfucked") - if(!owner.cmode) - owner.emote("sexmoanhvy") - else - owner.emote("sexmoanlight") - if("assfucked") - if(!owner.cmode) - owner.emote("sexmoanlight") - if("otherfapping") - if(prob(23)) - owner.emote("sexmoanlight") - if("suckedoff") - owner.emote("sexmoanlight") - -/datum/sex_controller/female/cum(source) - var/mob/living/carbon/C = owner - . = ..() - switch(source) - if("pussyfucked") - if(owner.has_flaw(/datum/charflaw/addiction/lovefiend)) - owner.sate_addiction() - if(!owner.cmode) - if(inpussy && !inpussy.cmode) - var/yee - if(ishuman(owner) && ishuman(inpussy)) - var/mob/living/carbon/human/H = inpussy - var/mob/living/carbon/human/F = owner - if(H.RomanticPartner(F)) - yee = 1 - C.add_stress(/datum/stressevent/cumlove) - if(!yee) - C.add_stress(/datum/stressevent/cummax) - else - C.add_stress(/datum/stressevent/cummid) - else - C.add_stress(/datum/stressevent/cumbad) - if(!owner.cmode) - owner.visible_message("[owner] tightens in pleasure!") - else - owner.visible_message("[owner] tightens in release!") - if(curplaying) - curplaying = null - if(femmoans) - femmoans.stop() - -/datum/sex_controller/proc/add_cum_floor(turfu) - if(!turfu || !isturf(turfu)) - return - var/turf/T = turfu - new /obj/effect/decal/cleanable/coom(T) - -/datum/looping_sound/femhornylite - mid_sounds = list('sound/vo/female/gen/se/horny1loop (1).ogg') - mid_length = 470 - volume = 20 - extra_range = -4 - -/datum/looping_sound/femhornylitealt - mid_sounds = list('sound/vo/female/gen/se/horny1loop (2).ogg') - mid_length = 360 - volume = 20 - extra_range = -4 - -/datum/looping_sound/femhornymed - mid_sounds = list('sound/vo/female/gen/se/horny2loop (1).ogg') - mid_length = 420 - volume = 20 - extra_range = -4 - -/datum/looping_sound/femhornymedalt - mid_sounds = list('sound/vo/female/gen/se/horny2loop (2).ogg') - mid_length = 350 - volume = 20 - extra_range = -4 - -/datum/looping_sound/femhornyhvy - mid_sounds = list('sound/vo/female/gen/se/horny3loop (1).ogg') - mid_length = 440 - volume = 20 - extra_range = -4 - -/datum/looping_sound/femhornyhvyalt - mid_sounds = list('sound/vo/female/gen/se/horny3loop (2).ogg') - mid_length = 390 - volume = 20 - extra_range = -4 diff --git a/code/datums/sexcon/sex_actions/deviant/facesitting.dm b/code/datums/sexcon/sex_actions/deviant/facesitting.dm index 51325172275..1b8a443c6e5 100644 --- a/code/datums/sexcon/sex_actions/deviant/facesitting.dm +++ b/code/datums/sexcon/sex_actions/deviant/facesitting.dm @@ -34,7 +34,6 @@ user.sexcon.perform_sex_action(user, 1, 3, TRUE) user.sexcon.handle_passive_ejaculation() - user.sexcon.perform_deepthroat_oxyloss(target, 1.3) user.sexcon.perform_sex_action(target, 0, 2, FALSE) target.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/deviant/frotting.dm b/code/datums/sexcon/sex_actions/deviant/frotting.dm index 5b99c3c6a18..0a51674e6d9 100644 --- a/code/datums/sexcon/sex_actions/deviant/frotting.dm +++ b/code/datums/sexcon/sex_actions/deviant/frotting.dm @@ -4,9 +4,9 @@ /datum/sex_action/frotting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return return TRUE @@ -17,9 +17,9 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/thighjob.dm b/code/datums/sexcon/sex_actions/deviant/thighjob.dm index 8f86476ceb9..67e587524b6 100644 --- a/code/datums/sexcon/sex_actions/deviant/thighjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/thighjob.dm @@ -4,7 +4,7 @@ /datum/sex_action/thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return return TRUE @@ -13,7 +13,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -38,7 +38,7 @@ /datum/sex_action/force_thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -47,7 +47,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index 531e2211f83..2584f25c040 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -4,7 +4,7 @@ /datum/sex_action/titjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return if(!target.getorganslot(ORGAN_SLOT_BREASTS)) return @@ -17,7 +17,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_CHEST)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!target.getorganslot(ORGAN_SLOT_BREASTS)) return FALSE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index 6ff667ba0ff..391c0bdc6bf 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -45,7 +45,7 @@ /datum/sex_action/masturbate_penis_other/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -54,7 +54,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm index 02dea61f65c..d16b67c7f7e 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -5,7 +5,7 @@ /datum/sex_action/masturbate_penis_over/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -14,7 +14,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!user.sexcon.can_use_penis()) return diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index 5b5c55dbe36..0cfd2f0b7af 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -43,7 +43,7 @@ /datum/sex_action/masturbate_penis/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -52,7 +52,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!user.sexcon.can_use_penis()) return diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index e7a8a7f4167..9ace5e27a05 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -48,7 +48,7 @@ /datum/sex_action/blowjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -59,7 +59,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -73,8 +73,6 @@ do_thrust_animate(user, target) user.sexcon.perform_sex_action(target, 2, 0, TRUE) - if(!target.sexcon.considered_limp()) - user.sexcon.perform_deepthroat_oxyloss(user, 1.3) if(target.sexcon.check_active_ejaculation()) target.visible_message(span_lovebold("[target] cums into [user]'s mouth!")) target.sexcon.cum_into() diff --git a/code/datums/sexcon/sex_actions/sex/anal_sex.dm b/code/datums/sexcon/sex_actions/sex/anal_sex.dm index 18b0a39983a..ab8ebe2f34f 100644 --- a/code/datums/sexcon/sex_actions/sex/anal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/anal_sex.dm @@ -5,7 +5,7 @@ /datum/sex_action/anal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -16,7 +16,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!user.sexcon.can_use_penis()) return @@ -60,7 +60,7 @@ /datum/sex_action/anal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -71,7 +71,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm index 99b7340671c..fe383a4a410 100644 --- a/code/datums/sexcon/sex_actions/sex/throat_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -5,7 +5,7 @@ /datum/sex_action/throat_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -16,7 +16,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!user.sexcon.can_use_penis()) return @@ -40,9 +40,6 @@ if(user.sexcon.considered_limp()) user.sexcon.perform_sex_action(target, 0, 2, FALSE) - else - user.sexcon.perform_sex_action(target, 0, 7, FALSE) - user.sexcon.perform_deepthroat_oxyloss(target, 2.3) target.sexcon.handle_passive_ejaculation() /datum/sex_action/throat_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 9c43a2407a5..c46c06823b0 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -7,7 +7,7 @@ return FALSE if(!target.getorganslot(ORGAN_SLOT_VAGINA)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE return TRUE @@ -20,7 +20,7 @@ return FALSE if(!target.getorganslot(ORGAN_SLOT_VAGINA)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) return FALSE if(!user.sexcon.can_use_penis()) return @@ -68,7 +68,7 @@ return FALSE if(!user.getorganslot(ORGAN_SLOT_VAGINA)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE @@ -81,7 +81,7 @@ return FALSE if(!user.getorganslot(ORGAN_SLOT_VAGINA)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_PENIS)) + if(!target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 563d039c6fa..4e5cc8b109a 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -22,7 +22,6 @@ var/last_arousal_increase_time = 0 var/last_ejaculation_time = 0 var/last_moan = 0 - var/last_pain = 0 var/msg_signature = "" var/last_msg_signature = 0 @@ -202,53 +201,20 @@ /datum/sex_controller/proc/adjust_arousal(amount) set_arousal(arousal + amount) -/datum/sex_controller/proc/perform_deepthroat_oxyloss(mob/living/carbon/human/action_target, oxyloss_amt) - var/oxyloss_multiplier = 0 - switch(force) - if(SEX_FORCE_LOW) - oxyloss_multiplier = 0 - if(SEX_FORCE_MID) - oxyloss_multiplier = 0 - if(SEX_FORCE_HIGH) - oxyloss_multiplier = 1.0 - if(SEX_FORCE_EXTREME) - oxyloss_multiplier = 2.0 - oxyloss_amt *= oxyloss_multiplier - if(oxyloss_amt <= 0) - return - action_target.adjustOxyLoss(oxyloss_amt) - // Indicate someone is choking through sex - if(action_target.oxyloss >= 50 && prob(33)) - action_target.emote(pick(list("gag", "choke", "gasp")), forced = TRUE) +/datum/sex_controller/proc/perform_sex_action(mob/living/carbon/human/action_target, arousal_amt, giving) + action_target.sexcon.receive_sex_action(arousal_amt, giving, force, speed) -/datum/sex_controller/proc/perform_sex_action(mob/living/carbon/human/action_target, arousal_amt, pain_amt, giving) - action_target.sexcon.receive_sex_action(arousal_amt, pain_amt, giving, force, speed) - -/datum/sex_controller/proc/receive_sex_action(arousal_amt, pain_amt, giving, applied_force, applied_speed) +/datum/sex_controller/proc/receive_sex_action(arousal_amt, giving, applied_force, applied_speed) arousal_amt *= get_force_pleasure_multiplier(applied_force, giving) - pain_amt *= get_force_pain_multiplier(applied_force) - pain_amt *= get_speed_pain_multiplier(applied_speed) if(user.stat == DEAD) arousal_amt = 0 - pain_amt = 0 adjust_arousal(arousal_amt) - damage_from_pain(pain_amt) - try_do_moan(arousal_amt, pain_amt, applied_force, giving) - try_do_pain_effect(pain_amt, giving) - -/datum/sex_controller/proc/damage_from_pain(pain_amt) - if(pain_amt < PAIN_MINIMUM_FOR_DAMAGE) - return - var/damage = (pain_amt / PAIN_DAMAGE_DIVISOR) - var/obj/item/bodypart/part = user.get_bodypart(BODY_ZONE_CHEST) - if(!part) - return - user.apply_damage(damage, BRUTE, part) + try_do_moan(arousal_amt, applied_force, giving) -/datum/sex_controller/proc/try_do_moan(arousal_amt, pain_amt, applied_force, giving) +/datum/sex_controller/proc/try_do_moan(arousal_amt, applied_force, giving) if(arousal_amt < 1.5) return if(user.stat != CONSCIOUS) @@ -264,52 +230,9 @@ if(5 to INFINITY) chosen_emote = "sexmoanhvy" - if(pain_amt >= PAIN_MILD_EFFECT) - if(giving) - if(prob(30)) - chosen_emote = "groan" - else - if(prob(40)) - chosen_emote = "painmoan" - if(pain_amt >= PAIN_MED_EFFECT) - if(giving) - if(prob(50)) - chosen_emote = "groan" - else - if(prob(60)) - // Because males have atrocious whimper noise - if(user.gender == FEMALE && prob(50)) - chosen_emote = "whimper" - else - chosen_emote = "cry" - last_moan = world.time user.emote(chosen_emote, forced = TRUE) -/datum/sex_controller/proc/try_do_pain_effect(pain_amt, giving) - if(pain_amt < PAIN_MILD_EFFECT) - return - if(last_pain + PAIN_COOLDOWN >= world.time) - return - if(prob(50)) - return - last_pain = world.time - if(pain_amt >= PAIN_HIGH_EFFECT) - var/pain_msg = pick(list("IT HURTS!!!", "IT NEEDS TO STOP!!!", "I CAN'T TAKE IT ANYMORE!!!")) - to_chat(user, span_boldwarning(pain_msg)) - user.flash_fullscreen("redflash2") - if(prob(70) && user.stat == CONSCIOUS) - user.visible_message(span_warning("[user] shudders in pain!")) - else if(pain_amt >= PAIN_MED_EFFECT) - var/pain_msg = pick(list("It hurts!", "It pains me!")) - to_chat(user, span_boldwarning(pain_msg)) - user.flash_fullscreen("redflash1") - if(prob(40) && user.stat == CONSCIOUS) - user.visible_message(span_warning("[user] shudders in pain!")) - else - var/pain_msg = pick(list("It hurts a little...", "It stings...", "I'm aching...")) - to_chat(user, span_warning(pain_msg)) - /datum/sex_controller/proc/update_blueballs() if(arousal >= BLUEBALLS_GAIN_THRESHOLD) user.add_stress(/datum/stressevent/blueb) @@ -376,7 +299,7 @@ var/force_name = get_force_string() var/speed_name = get_speed_string() var/manual_arousal_name = get_manual_arousal_string() - if(!user.getorganslot(ORGAN_SLOT_PENIS)) + if(!user.gender == MALE) dat += "
\< [speed_name] \> ~|~ \< [force_name] \>
" else dat += "
\< [speed_name] \> ~|~ \< [force_name] \> ~|~ \< [manual_arousal_name] \>
" @@ -468,10 +391,6 @@ return if(!can_perform_action(action_type)) return - if(need_to_be_violated(target) && !can_violate_victim(target)) - violate_victim(target) - if(need_to_be_violated(target) && !can_violate_victim(target)) - return // Set vars desire_stop = FALSE current_action = action_type @@ -491,8 +410,6 @@ break if(current_action == null || performed_action_type != current_action) break - if(need_to_be_violated(target) && !can_violate_victim(target)) - break if(!can_perform_action(current_action)) break if(action.is_finished(user, target)) @@ -580,33 +497,6 @@ return 1.6 else return 1.2 - if(SEX_FORCE_EXTREME) - if(giving) - return 2.0 - else - return 0.8 - -/datum/sex_controller/proc/get_force_pain_multiplier(passed_force) - switch(passed_force) - if(SEX_FORCE_LOW) - return 0.5 - if(SEX_FORCE_MID) - return 1.0 - if(SEX_FORCE_HIGH) - return 2.0 - if(SEX_FORCE_EXTREME) - return 3.0 - -/datum/sex_controller/proc/get_speed_pain_multiplier(passed_speed) - switch(passed_speed) - if(SEX_SPEED_LOW) - return 0.8 - if(SEX_SPEED_MID) - return 1.0 - if(SEX_SPEED_HIGH) - return 1.2 - if(SEX_SPEED_EXTREME) - return 1.4 /datum/sex_controller/proc/get_force_string() switch(force) @@ -616,8 +506,6 @@ return "FIRM" if(SEX_FORCE_HIGH) return "ROUGH" - if(SEX_FORCE_EXTREME) - return "BRUTAL" /datum/sex_controller/proc/get_speed_string() switch(speed) @@ -649,8 +537,6 @@ return pick(list("firmly", "vigorously", "eagerly", "steadily", "intently")) if(SEX_FORCE_HIGH) return pick(list("roughly", "carelessly", "forcefully", "fervently", "fiercely")) - if(SEX_FORCE_EXTREME) - return pick(list("brutally", "violently", "relentlessly", "savagely", "mercilessly")) /datum/sex_controller/proc/spanify_force(string) switch(force) @@ -660,5 +546,3 @@ return "[string]" if(SEX_FORCE_HIGH) return "[string]" - if(SEX_FORCE_EXTREME) - return "[string]" diff --git a/stonekeep.dme b/stonekeep.dme index 08c5acff99c..34f2d144a6b 100644 --- a/stonekeep.dme +++ b/stonekeep.dme @@ -408,7 +408,6 @@ #include "code\datums\recipe.dm" #include "code\datums\ruins.dm" #include "code\datums\saymode.dm" -#include "code\datums\sexcon.dm" #include "code\datums\shuttles.dm" #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" From 160b8582820c9c999eafa91e41d9b74e712ae1eb Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 23:36:20 -0700 Subject: [PATCH 05/33] this too. also removes pregnancy --- code/datums/sexcon/sex_actions/deviant/scissoring.dm | 8 ++++---- .../sexcon/sex_actions/masturbate/masturbate_other.dm | 4 ++-- .../sexcon/sex_actions/masturbate/masturbate_self.dm | 4 ++-- code/datums/sexcon/sex_actions/oral.dm | 4 ++-- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 8 ++++---- code/datums/sexcon/sexcon.dm | 2 +- code/datums/sexcon/sexcon_helpers.dm | 10 ---------- 7 files changed, 15 insertions(+), 25 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/scissoring.dm b/code/datums/sexcon/sex_actions/deviant/scissoring.dm index a44354c1d48..4dc150ed225 100644 --- a/code/datums/sexcon/sex_actions/deviant/scissoring.dm +++ b/code/datums/sexcon/sex_actions/deviant/scissoring.dm @@ -4,9 +4,9 @@ /datum/sex_action/scissoring/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return return TRUE @@ -17,9 +17,9 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index 391c0bdc6bf..58c17fdbafe 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -5,7 +5,7 @@ /datum/sex_action/masturbate_other_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE return TRUE @@ -14,7 +14,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index 0cfd2f0b7af..bde9f9fe5e0 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -4,7 +4,7 @@ /datum/sex_action/masturbate_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return FALSE return TRUE @@ -13,7 +13,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index 9ace5e27a05..ea6bfdfedce 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -4,7 +4,7 @@ /datum/sex_action/cunnilingus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE return TRUE @@ -15,7 +15,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index c46c06823b0..9733bd39318 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -5,7 +5,7 @@ /datum/sex_action/vaginal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE if(!user.gender == MALE) return FALSE @@ -18,7 +18,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.getorganslot(ORGAN_SLOT_VAGINA)) + if(!target.gender == FEMALE) return FALSE if(!user.gender == MALE) return FALSE @@ -66,7 +66,7 @@ /datum/sex_action/vaginal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return FALSE if(!target.gender == MALE) return FALSE @@ -79,7 +79,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == FEMALE) return FALSE if(!target.gender == MALE) return FALSE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 4e5cc8b109a..71506ff228e 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -249,7 +249,7 @@ return TRUE /datum/sex_controller/proc/can_ejaculate() - if(!user.getorganslot(ORGAN_SLOT_TESTICLES) && !user.getorganslot(ORGAN_SLOT_VAGINA)) + if(!user.gender == MALE) return FALSE if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE diff --git a/code/datums/sexcon/sexcon_helpers.dm b/code/datums/sexcon/sexcon_helpers.dm index eaeb81aa623..b3093352834 100644 --- a/code/datums/sexcon/sexcon_helpers.dm +++ b/code/datums/sexcon/sexcon_helpers.dm @@ -60,16 +60,6 @@ else playsound(src, pick('sound/misc/mat/guymouth (1).ogg','sound/misc/mat/guymouth (2).ogg','sound/misc/mat/guymouth (3).ogg','sound/misc/mat/guymouth (4).ogg','sound/misc/mat/guymouth (5).ogg'), 35, TRUE, ignore_walls = FALSE) -/mob/living/carbon/human/proc/try_impregnate(mob/living/carbon/human/wife) - var/obj/item/organ/testicles/testes = getorganslot(ORGAN_SLOT_TESTICLES) - if(!testes) - return - var/obj/item/organ/vagina/vag = wife.getorganslot(ORGAN_SLOT_VAGINA) - if(!vag) - return - if(prob(25)) - vag.be_impregnated(src) - /mob/living/carbon/human/proc/get_highest_grab_state_on(mob/living/carbon/human/victim) var/grabstate = null if(r_grab && r_grab.grabbed == victim) From 50f3b211fe94deaccedad7768e9aa1b4cd438cc6 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 23:38:38 -0700 Subject: [PATCH 06/33] NO LOVE(BOLD) DEEP WEB --- .../sexcon/sex_actions/masturbate/masturbate_penis_over.dm | 2 +- code/datums/sexcon/sex_actions/oral.dm | 4 ++-- code/datums/sexcon/sex_actions/sex/anal_sex.dm | 4 ++-- code/datums/sexcon/sex_actions/sex/throat_sex.dm | 2 +- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 4 ++-- code/datums/sexcon/sexcon.dm | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm index d16b67c7f7e..39f2fe9e1bc 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -32,7 +32,7 @@ user.sexcon.perform_sex_action(user, 2, 4, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_lovebold("[user] cums over [target]'s body!")) + user.visible_message(span_love("[user] cums over [target]'s body!")) user.sexcon.cum_onto() /datum/sex_action/masturbate_penis_over/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index ea6bfdfedce..bc22cc2b461 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -30,7 +30,7 @@ user.sexcon.perform_sex_action(target, 2, 3, TRUE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_lovebold("[target] ejaculates into [user]'s mouth!")) + target.visible_message(span_love("[target] ejaculates into [user]'s mouth!")) target.sexcon.cum_into() /datum/sex_action/cunnilingus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -74,7 +74,7 @@ user.sexcon.perform_sex_action(target, 2, 0, TRUE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_lovebold("[target] cums into [user]'s mouth!")) + target.visible_message(span_love("[target] cums into [user]'s mouth!")) target.sexcon.cum_into() /datum/sex_action/blowjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) diff --git a/code/datums/sexcon/sex_actions/sex/anal_sex.dm b/code/datums/sexcon/sex_actions/sex/anal_sex.dm index ab8ebe2f34f..44e4317b418 100644 --- a/code/datums/sexcon/sex_actions/sex/anal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/anal_sex.dm @@ -34,7 +34,7 @@ user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_lovebold("[user] cums into [target]'s butt!")) + user.visible_message(span_love("[user] cums into [target]'s butt!")) user.sexcon.cum_into() user.virginity = FALSE @@ -92,7 +92,7 @@ user.sexcon.perform_sex_action(target, 2, 4, FALSE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_lovebold("[target] cums into [user]'s butt!")) + target.visible_message(span_love("[target] cums into [user]'s butt!")) target.sexcon.cum_into() target.virginity = FALSE diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm index fe383a4a410..383c1e6926d 100644 --- a/code/datums/sexcon/sex_actions/sex/throat_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -34,7 +34,7 @@ user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_lovebold("[user] cums into [target]'s throat!")) + user.visible_message(span_love("[user] cums into [target]'s throat!")) user.sexcon.cum_into() user.virginity = FALSE diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 9733bd39318..74ef7411375 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -38,7 +38,7 @@ user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_lovebold("[user] cums into [target]'s cunt!")) + user.visible_message(span_love("[user] cums into [target]'s cunt!")) user.sexcon.cum_into() user.try_impregnate(target) user.virginity = FALSE @@ -103,7 +103,7 @@ user.sexcon.perform_sex_action(target, 2, 4, FALSE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_lovebold("[target] cums into [user]'s cunt!")) + target.visible_message(span_love("[target] cums into [user]'s cunt!")) target.sexcon.cum_into() target.try_impregnate(user) target.virginity = FALSE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 71506ff228e..e3762096385 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -135,7 +135,7 @@ /datum/sex_controller/proc/ejaculate() log_combat(user, user, "Ejaculated") - user.visible_message(span_lovebold("[user] makes a mess!")) + user.visible_message(span_love("[user] makes a mess!")) playsound(user, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) add_cum_floor(get_turf(user)) after_ejaculation() From d4e52c79b78183a80969fb922f24fde670155fab Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Tue, 3 Dec 2024 23:47:58 -0700 Subject: [PATCH 07/33] i guess sound file replacements --- code/datums/sexcon/sex_actions/deviant/frotting.dm | 2 +- code/datums/sexcon/sex_actions/deviant/titjob.dm | 4 ++-- code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm | 2 +- code/datums/sexcon/sexcon.dm | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/frotting.dm b/code/datums/sexcon/sex_actions/deviant/frotting.dm index 0a51674e6d9..4c5db72df8e 100644 --- a/code/datums/sexcon/sex_actions/deviant/frotting.dm +++ b/code/datums/sexcon/sex_actions/deviant/frotting.dm @@ -29,7 +29,7 @@ /datum/sex_action/frotting/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] frots cocks together with [target]'s.")) - playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 20, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 1, 4, TRUE) user.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index 2584f25c040..56a20a1d510 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -6,7 +6,7 @@ return FALSE if(!user.gender == MALE) return - if(!target.getorganslot(ORGAN_SLOT_BREASTS)) + if(!target.gender == FEMALE) return return TRUE @@ -19,7 +19,7 @@ return FALSE if(!user.gender == MALE) return FALSE - if(!target.getorganslot(ORGAN_SLOT_BREASTS)) + if(!target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index bde9f9fe5e0..9fc6cdd32ca 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -23,7 +23,7 @@ /datum/sex_action/masturbate_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes her clit...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index e3762096385..17c7578fde6 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -194,7 +194,7 @@ update_erect_state() /datum/sex_controller/proc/update_erect_state() - var/obj/item/organ/penis/penis = user.getorganslot(ORGAN_SLOT_PENIS) + var/obj/item/organ/penis/penis = user.gender == MALE if(penis) penis.update_erect_state() From 97f5c4f3e8dab85c4ba20b0ba3d90ee8dedc32c0 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:03:19 -0700 Subject: [PATCH 08/33] a whole lot of cleanups --- code/datums/sexcon/sex_actions/deviant/thighjob.dm | 4 ++-- code/datums/sexcon/sex_actions/deviant/titjob.dm | 2 +- .../sex_actions/masturbate/masturbate_other.dm | 6 +++--- .../sex_actions/masturbate/masturbate_penis_over.dm | 2 +- .../sex_actions/masturbate/masturbate_self.dm | 4 ++-- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 2 -- code/datums/sexcon/sexcon_helpers.dm | 2 -- code/modules/client/preferences.dm | 2 +- code/modules/mob/dead/new_player/new_player.dm | 6 ------ code/modules/mob/living/living.dm | 13 ------------- code/modules/mob/living/living_movement.dm | 2 -- code/modules/mob/mob.dm | 3 --- 12 files changed, 10 insertions(+), 38 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/thighjob.dm b/code/datums/sexcon/sex_actions/deviant/thighjob.dm index 67e587524b6..7b6282e2b1d 100644 --- a/code/datums/sexcon/sex_actions/deviant/thighjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/thighjob.dm @@ -23,7 +23,7 @@ /datum/sex_action/thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s thighs.")) - playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/segso.ogg', 20, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) user.sexcon.perform_sex_action(user, 2, 4, TRUE) @@ -57,7 +57,7 @@ /datum/sex_action/force_thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock with their thighs...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(target, user) user.sexcon.perform_sex_action(target, 2, 4, TRUE) diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index 56a20a1d510..bd9f9340be9 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -29,7 +29,7 @@ /datum/sex_action/titjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s tits.")) - playsound(user, 'sound/misc/mat/fingering.ogg', 20, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 20, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) user.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index 58c17fdbafe..ff89ec03ab7 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -24,7 +24,7 @@ /datum/sex_action/masturbate_other_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes [target]'s clit...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 4, TRUE) @@ -64,7 +64,7 @@ /datum/sex_action/masturbate_penis_other/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock off...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 0, TRUE) @@ -100,7 +100,7 @@ /datum/sex_action/masturbate_other_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers [target]'s butt...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 6, TRUE) target.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm index 39f2fe9e1bc..ee8394f15c6 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -27,7 +27,7 @@ var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb] over [target]")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index 9fc6cdd32ca..f5af4c32bcd 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -65,7 +65,7 @@ var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb]...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 0, TRUE) @@ -100,7 +100,7 @@ /datum/sex_action/masturbate_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers their butt...")) - playsound(user, 'sound/misc/mat/fingering.ogg', 30, TRUE, -2, ignore_walls = FALSE) + playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 6, TRUE) user.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 74ef7411375..9caf1778fb7 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -40,7 +40,6 @@ if(user.sexcon.check_active_ejaculation()) user.visible_message(span_love("[user] cums into [target]'s cunt!")) user.sexcon.cum_into() - user.try_impregnate(target) user.virginity = FALSE target.virginity = FALSE @@ -105,7 +104,6 @@ if(target.sexcon.check_active_ejaculation()) target.visible_message(span_love("[target] cums into [user]'s cunt!")) target.sexcon.cum_into() - target.try_impregnate(user) target.virginity = FALSE user.virginity = FALSE diff --git a/code/datums/sexcon/sexcon_helpers.dm b/code/datums/sexcon/sexcon_helpers.dm index b3093352834..74ed75f063d 100644 --- a/code/datums/sexcon/sexcon_helpers.dm +++ b/code/datums/sexcon/sexcon_helpers.dm @@ -36,8 +36,6 @@ /mob/living var/can_do_sex = TRUE - var/virginity = FALSE - var/defiant = FALSE /mob/living/carbon/human/MiddleMouseDrop_T(mob/living/target, mob/living/user) if(user.mmb_intent) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 1f71dc1eb5b..c56d8c0d30c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1982,7 +1982,7 @@ Slots: [job.spawn_positions]
var/result = input(user, "Select a flaw", "Roguetown") as null|anything in coom if(result) if(result == "Love-Fiend") - if(!user.can_do_sex()) + if(!can_do_sex()) coom -= "Love-Fiend" result = pick(coom) result = coom[result] diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 61ba663f5c4..135ec79f2cc 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -699,12 +699,6 @@ GLOBAL_LIST_INIT(roleplay_readme, world.file2list("strings/rt/Lore_Primer.txt")) return /mob/living/carbon/human/after_creation() -#ifdef MATURESERVER - if(gender == MALE) - sexcon = new/datum/sex_controller/male(src) - else - sexcon = new/datum/sex_controller/female(src) -#endif if(dna?.species) dna.species.after_creation(src) roll_stats() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bf63cbceee0..8b1cdc6a968 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -719,8 +719,6 @@ resting = rest update_resting() if(rest == resting) - if(sexcon) - sexcon.mob_moved() if(resting) if(m_intent == MOVE_INTENT_RUN) toggle_rogmove_intent(MOVE_INTENT_WALK, TRUE) @@ -950,8 +948,6 @@ stop_looking() if(doing) doing = 0 - if(sexcon) - sexcon.mob_moved() if(client) update_vision_cone() @@ -1038,10 +1034,6 @@ changeNext_move(CLICK_CD_RESIST) - if(sexcon) - if(sexcon.cancel_our_actions()) - return - if(atkswinging) stop_attack(FALSE) @@ -1052,11 +1044,6 @@ resist_grab() return - if(!restrained(ignore_grab = 1) && !pulledby) - if(sexcon) - if(sexcon.cancel_others_actions()) - return - //unbuckling yourself if(buckled && last_special <= world.time) resist_buckle() diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index a31ddec1e76..6684316f483 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -2,8 +2,6 @@ . = ..() stop_looking() update_turf_movespeed(loc) - if(sexcon) - sexcon.mob_moved() if(m_intent == MOVE_INTENT_RUN) consider_ambush() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index fe618766ae6..774f0bfef60 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -855,9 +855,6 @@ GLOBAL_VAR_INIT(mobids, 1) return if(pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE) //the reason this isn't a mobility_flags check is because you want them to be able to change dir if you're passively grabbing them return FALSE - if(sexcon) - if(!sexcon.can_change_dir()) - return FALSE if(IsImmobilized()) return FALSE return ..() From 07131dad502612fb8732afa3c942554b08b125fc Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:05:03 -0700 Subject: [PATCH 09/33] a fucking penis overlay? --- code/datums/sexcon/sexcon.dm | 5 ----- code/modules/client/preferences.dm | 4 ---- 2 files changed, 9 deletions(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 17c7578fde6..9dc5368ad16 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -193,11 +193,6 @@ update_blueballs() update_erect_state() -/datum/sex_controller/proc/update_erect_state() - var/obj/item/organ/penis/penis = user.gender == MALE - if(penis) - penis.update_erect_state() - /datum/sex_controller/proc/adjust_arousal(amount) set_arousal(arousal + amount) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c56d8c0d30c..41f44bbe75c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1981,10 +1981,6 @@ Slots: [job.spawn_positions]
var/list/coom = GLOB.character_flaws.Copy() var/result = input(user, "Select a flaw", "Roguetown") as null|anything in coom if(result) - if(result == "Love-Fiend") - if(!can_do_sex()) - coom -= "Love-Fiend" - result = pick(coom) result = coom[result] var/datum/charflaw/C = new result() charflaw = C From 44dbb316c7f2aff2e87986caec173d17016bce6e Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:06:05 -0700 Subject: [PATCH 10/33] unpenis 2 --- code/datums/sexcon/sexcon.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 9dc5368ad16..03036d5be76 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -191,7 +191,6 @@ arousal = clamp(amount, 0, MAX_AROUSAL) update_pink_screen() update_blueballs() - update_erect_state() /datum/sex_controller/proc/adjust_arousal(amount) set_arousal(arousal + amount) From 494b458445529c296a6b7176b39a933a154430ed Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:31:30 -0700 Subject: [PATCH 11/33] a whole lot of wording changes --- .../sexcon/sex_actions/deviant/facesitting.dm | 5 ++--- .../sexcon/sex_actions/deviant/frotting.dm | 8 ++++---- .../sexcon/sex_actions/deviant/scissoring.dm | 8 ++++---- .../sexcon/sex_actions/deviant/thighjob.dm | 16 ++++++++-------- .../masturbate/masturbate_penis_over.dm | 9 ++++----- code/datums/sexcon/sex_actions/sex/throat_sex.dm | 8 ++++---- .../datums/sexcon/sex_actions/sex/vaginal_sex.dm | 16 ++++++++-------- 7 files changed, 34 insertions(+), 36 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/facesitting.dm b/code/datums/sexcon/sex_actions/deviant/facesitting.dm index 1b8a443c6e5..ef2555f919d 100644 --- a/code/datums/sexcon/sex_actions/deviant/facesitting.dm +++ b/code/datums/sexcon/sex_actions/deviant/facesitting.dm @@ -22,12 +22,11 @@ return TRUE /datum/sex_action/facesitting/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] sits their butt on [target]'s face!")) + user.visible_message(span_warning("[user] sits on [target]'s face.")) /datum/sex_action/facesitting/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) - var/verbstring = pick(list("rubs", "smushes", "forces")) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [verbstring] their butt against [target] face.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rides [target]'s face.")) target.make_sucking_noise() do_thrust_animate(user, target) diff --git a/code/datums/sexcon/sex_actions/deviant/frotting.dm b/code/datums/sexcon/sex_actions/deviant/frotting.dm index 4c5db72df8e..a2665a520a7 100644 --- a/code/datums/sexcon/sex_actions/deviant/frotting.dm +++ b/code/datums/sexcon/sex_actions/deviant/frotting.dm @@ -1,5 +1,5 @@ /datum/sex_action/frotting - name = "Frot them" + name = "frotteurism" /datum/sex_action/frotting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -24,11 +24,11 @@ return TRUE /datum/sex_action/frotting/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] shoves his cock against [target]'s own!")) + user.visible_message(span_warning("[user] starts to rub against [target].")) /datum/sex_action/frotting/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] frots cocks together with [target]'s.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] frots against [target].")) playsound(user, 'sound/misc/mat/fap.ogg', 20, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 1, 4, TRUE) @@ -38,4 +38,4 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/frotting/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] lets go off both their cocks.")) + user.visible_message(span_warning("[user] pulls away from [target].")) diff --git a/code/datums/sexcon/sex_actions/deviant/scissoring.dm b/code/datums/sexcon/sex_actions/deviant/scissoring.dm index 4dc150ed225..db2dc794c04 100644 --- a/code/datums/sexcon/sex_actions/deviant/scissoring.dm +++ b/code/datums/sexcon/sex_actions/deviant/scissoring.dm @@ -1,5 +1,5 @@ /datum/sex_action/scissoring - name = "Scissor them" + name = "tribadism" /datum/sex_action/scissoring/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -24,11 +24,11 @@ return TRUE /datum/sex_action/scissoring/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] spreads her legs and aligns her cunt against [target]'s own!")) + user.visible_message(span_warning("[user] presses against [target].")) /datum/sex_action/scissoring/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] scissors with [target]'s cunt.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rubs against [target].")) playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) @@ -39,4 +39,4 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/scissoring/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops scissoring with [target].")) + user.visible_message(span_warning("[user] stops rubbing against [target].")) diff --git a/code/datums/sexcon/sex_actions/deviant/thighjob.dm b/code/datums/sexcon/sex_actions/deviant/thighjob.dm index 7b6282e2b1d..e1af2b40b1b 100644 --- a/code/datums/sexcon/sex_actions/deviant/thighjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/thighjob.dm @@ -1,5 +1,5 @@ /datum/sex_action/thighjob - name = "Use their thighs to get off" + name = "use thighs" /datum/sex_action/thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -18,11 +18,11 @@ return TRUE /datum/sex_action/thighjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] grabs [target]'s thighs and shoves his cock inbetween!")) + user.visible_message(span_warning("[user] slides between [target]'s thighs.")) /datum/sex_action/thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s thighs.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] uses [target]'s thighs.")) playsound(user, 'sound/misc/mat/segso.ogg', 20, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) @@ -30,10 +30,10 @@ user.sexcon.handle_passive_ejaculation() /datum/sex_action/thighjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] pulls his cock out from inbetween [target]'s thighs.")) + user.visible_message(span_warning("[user] slides out from between [target]'s thighs.")) /datum/sex_action/force_thighjob - name = "Jerk them off with thighs" + name = "use own thighs" /datum/sex_action/force_thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -52,11 +52,11 @@ return TRUE /datum/sex_action/force_thighjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] moves their thighs between [target]'s cock...")) + user.visible_message(span_warning("[user] envelops [target] with their thighs.")) /datum/sex_action/force_thighjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock with their thighs...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target] with their thighs.")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(target, user) @@ -65,7 +65,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/force_thighjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops jerking [target]'s off with their thighs...")) + user.visible_message(span_warning("[user] stops jerking [target] their thighs.")) /datum/sex_action/force_thighjob/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm index ee8394f15c6..befd0ecb925 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -1,5 +1,5 @@ /datum/sex_action/masturbate_penis_over - name = "Jerk over them" + name = "pleasure self over them" check_same_tile = FALSE /datum/sex_action/masturbate_penis_over/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -24,19 +24,18 @@ user.visible_message(span_warning("[user] starts jerking over [target]...")) /datum/sex_action/masturbate_penis_over/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) - var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb] over [target]")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] pleasures himself over [target]")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_love("[user] cums over [target]'s body!")) + user.visible_message(span_love("[user] paints [target]'s body!")) user.sexcon.cum_onto() /datum/sex_action/masturbate_penis_over/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops jerking off.")) + user.visible_message(span_warning("[user] stops pleasuring himself.")) /datum/sex_action/masturbate_penis_over/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm index 383c1e6926d..eb058249b88 100644 --- a/code/datums/sexcon/sex_actions/sex/throat_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -23,18 +23,18 @@ return TRUE /datum/sex_action/throat_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] slides his cock into [target]'s throat!")) + user.visible_message(span_warning("[user] starts to feed [target].")) playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) /datum/sex_action/throat_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s throat.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] feeds [target].")) playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_love("[user] cums into [target]'s throat!")) + user.visible_message(span_love("[user] tightens in pleasure!")) user.sexcon.cum_into() user.virginity = FALSE @@ -43,7 +43,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/throat_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] pulls his cock out of [target]'s throat.")) + user.visible_message(span_warning("[user] stops feeding [target].")) /datum/sex_action/throat_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 9caf1778fb7..41b2b9d2787 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -1,5 +1,5 @@ /datum/sex_action/vaginal_sex - name = "Fuck their cunt" + name = "taff the front" stamina_cost = 1.0 /datum/sex_action/vaginal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -27,18 +27,18 @@ return TRUE /datum/sex_action/vaginal_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] slides his cock into [target]'s cunt!")) + user.visible_message(span_warning("[user] enters [target].")) playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) /datum/sex_action/vaginal_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s cunt.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] taffs [target].")) playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_love("[user] cums into [target]'s cunt!")) + user.visible_message(span_love("[user] tightens in ecstasy!")) user.sexcon.cum_into() user.virginity = FALSE target.virginity = FALSE @@ -50,7 +50,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/vaginal_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] pulls his cock out of [target]'s cunt.")) + user.visible_message(span_warning("[user] pulls out of [target].")) /datum/sex_action/vaginal_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) @@ -58,7 +58,7 @@ return FALSE /datum/sex_action/vaginal_ride_sex - name = "Ride them" + name = "ride" stamina_cost = 1.0 aggro_grab_instead_same_tile = FALSE @@ -85,7 +85,7 @@ return TRUE /datum/sex_action/vaginal_ride_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] gets on top of [target] and begins riding them with their cunt!")) + user.visible_message(span_warning("[user] starts to ride [target].")) playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) /datum/sex_action/vaginal_ride_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -102,7 +102,7 @@ user.sexcon.perform_sex_action(target, 2, 4, FALSE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_love("[target] cums into [user]'s cunt!")) + target.visible_message(span_love("[target] tightens in ecstasy!")) target.sexcon.cum_into() target.virginity = FALSE user.virginity = FALSE From 787a654faee819a42ae9dafcfc81f5ecf12105f8 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:32:28 -0700 Subject: [PATCH 12/33] [in stodgy aristocrat voice] bosom --- code/datums/sexcon/sex_actions/deviant/titjob.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index bd9f9340be9..9a1768b9f1c 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -1,5 +1,5 @@ /datum/sex_action/titjob - name = "Use their tits to get off" + name = "use bosom" /datum/sex_action/titjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -24,15 +24,15 @@ return TRUE /datum/sex_action/titjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] grabs [target]'s tits and shoves his cock inbetween!")) + user.visible_message(span_warning("[user] slides between [target]'s bosom.")) /datum/sex_action/titjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s tits.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] taffs [target]'s bosom.")) playsound(user, 'sound/misc/mat/fap.ogg', 20, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) user.sexcon.handle_passive_ejaculation() /datum/sex_action/titjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] pulls his cock out from inbetween [target]'s tits.")) + user.visible_message(span_warning("[user] slides out from between [target]'s bosom.")) From 9773f55d72947c8cb100622137d3f87d514c4bf2 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 00:59:40 -0700 Subject: [PATCH 13/33] well there once were two cowboys all alone out on the trail --- .../masturbate/masturbate_other.dm | 24 ++++++++--------- .../sex_actions/masturbate/masturbate_self.dm | 23 ++++++++-------- code/datums/sexcon/sex_actions/oral.dm | 26 +++++++++---------- .../datums/sexcon/sex_actions/sex/anal_sex.dm | 16 ++++++------ 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index ff89ec03ab7..5cff14e6966 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -1,5 +1,5 @@ /datum/sex_action/masturbate_other_vagina - name = "Stroke their clit" + name = "service" check_same_tile = FALSE /datum/sex_action/masturbate_other_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -19,11 +19,11 @@ return TRUE /datum/sex_action/masturbate_other_vagina/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts stroking [target]'s clit...")) + user.visible_message(span_warning("[user] starts rubbing [target].")) /datum/sex_action/masturbate_other_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes [target]'s clit...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rubs [target].")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 4, TRUE) @@ -31,7 +31,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/masturbate_other_vagina/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops stroking [target]'s clit.")) + user.visible_message(span_warning("[user] stops rubbing [target].")) /datum/sex_action/masturbate_other_vagina/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) @@ -39,7 +39,7 @@ return FALSE /datum/sex_action/masturbate_penis_other - name = "Jerk them off" + name = "service" check_same_tile = FALSE /datum/sex_action/masturbate_penis_other/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -59,11 +59,11 @@ return TRUE /datum/sex_action/masturbate_penis_other/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts jerking [target]'s off...")) + user.visible_message(span_warning("[user] starts jerking [target].")) /datum/sex_action/masturbate_penis_other/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target]'s cock off...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] jerks [target].")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 0, TRUE) @@ -71,7 +71,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/masturbate_penis_other/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops jerking [target]'s off.")) + user.visible_message(span_warning("[user] stops jerking [target].")) /datum/sex_action/masturbate_penis_other/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) @@ -79,7 +79,7 @@ return FALSE /datum/sex_action/masturbate_other_anus - name = "Finger their butt" + name = "service whistler" check_same_tile = FALSE /datum/sex_action/masturbate_other_anus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -95,18 +95,18 @@ return TRUE /datum/sex_action/masturbate_other_anus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts fingering [target]'s butt...")) + user.visible_message(span_warning("[user] starts to rub [target]'s whistler.")) /datum/sex_action/masturbate_other_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers [target]'s butt...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rubs [target]'s whistler.")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(target, 2, 6, TRUE) target.sexcon.handle_passive_ejaculation() /datum/sex_action/masturbate_other_anus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops fingering [target]'s butt.")) + user.visible_message(span_warning("[user] stops rubbing [target]'s whistler.")) /datum/sex_action/masturbate_other_anus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index f5af4c32bcd..90ad8955c0c 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -1,5 +1,5 @@ /datum/sex_action/masturbate_vagina - name = "Stroke clit" + name = "pleasure self" /datum/sex_action/masturbate_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) @@ -18,11 +18,11 @@ return TRUE /datum/sex_action/masturbate_vagina/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts stroking her clit...")) + user.visible_message(span_warning("[user] starts to pleasure herself.")) /datum/sex_action/masturbate_vagina/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] strokes her clit...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] pleasures herself.")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 4, TRUE) @@ -38,7 +38,7 @@ return FALSE /datum/sex_action/masturbate_penis - name = "Jerk off" + name = "pleasure self" /datum/sex_action/masturbate_penis/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) @@ -59,12 +59,11 @@ return TRUE /datum/sex_action/masturbate_penis/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts jerking off...")) + user.visible_message(span_warning("[user] starts to pleasure himself.")) /datum/sex_action/masturbate_penis/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) - var/chosen_verb = pick(list("jerks his cock", "strokes his cock", "masturbates", "jerks off")) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] [chosen_verb]...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] pleasures himself.")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 0, TRUE) @@ -72,7 +71,7 @@ user.sexcon.handle_passive_ejaculation() /datum/sex_action/masturbate_penis/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops jerking off.")) + user.visible_message(span_warning("[user] stops pleasuring himself.")) /datum/sex_action/masturbate_penis/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) @@ -80,7 +79,7 @@ return FALSE /datum/sex_action/masturbate_anus - name = "Finger butt" + name = "pleasure whistler" /datum/sex_action/masturbate_anus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) @@ -95,18 +94,18 @@ return TRUE /datum/sex_action/masturbate_anus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts fingering their butt...")) + user.visible_message(span_warning("[user] starts pleasuring their whistler.")) /datum/sex_action/masturbate_anus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fingers their butt...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] pleasures their whistler.")) playsound(user, 'sound/misc/mat/fap.ogg', 30, TRUE, -2, ignore_walls = FALSE) user.sexcon.perform_sex_action(user, 2, 6, TRUE) user.sexcon.handle_passive_ejaculation() /datum/sex_action/masturbate_anus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops fingering their butt.")) + user.visible_message(span_warning("[user] stops pleasuring their whistler.")) /datum/sex_action/masturbate_anus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index bc22cc2b461..7f382871a61 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -1,5 +1,5 @@ /datum/sex_action/cunnilingus - name = "Suck their cunt off" + name = "mouth service" /datum/sex_action/cunnilingus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -20,17 +20,17 @@ return TRUE /datum/sex_action/cunnilingus/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts sucking [target]'s clit...")) + user.visible_message(span_warning("[user] starts to eat [target].")) /datum/sex_action/cunnilingus/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] sucks [target]'s clit...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] eats [target].")) user.make_sucking_noise() do_thrust_animate(user, target) user.sexcon.perform_sex_action(target, 2, 3, TRUE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_love("[target] ejaculates into [user]'s mouth!")) + target.visible_message(span_love("[target] tightens in ectasy!")) target.sexcon.cum_into() /datum/sex_action/cunnilingus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -42,7 +42,7 @@ return FALSE /datum/sex_action/blowjob - name = "Suck them off" + name = "mouth service" check_same_tile = FALSE /datum/sex_action/blowjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -64,21 +64,21 @@ return TRUE /datum/sex_action/blowjob/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts sucking [target]'s cock...")) + user.visible_message(span_warning("[user] starts to suck off [target].")) /datum/sex_action/blowjob/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] sucks [target]'s cock...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] sucks off [target].")) user.make_sucking_noise() do_thrust_animate(user, target) user.sexcon.perform_sex_action(target, 2, 0, TRUE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_love("[target] cums into [user]'s mouth!")) + target.visible_message(span_love("[target] tightens in ectasy!")) target.sexcon.cum_into() /datum/sex_action/blowjob/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops sucking [target]'s cock ...")) + user.visible_message(span_warning("[user] stops sucking off [target].")) /datum/sex_action/blowjob/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) @@ -86,7 +86,7 @@ return FALSE /datum/sex_action/rimming - name = "Rim them" + name = "mouth service on whistler" /datum/sex_action/rimming/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) @@ -103,11 +103,11 @@ return TRUE /datum/sex_action/rimming/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] starts rimming [target]'s butt...")) + user.visible_message(span_warning("[user] starts licking [target]'s whistler.")) /datum/sex_action/rimming/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] rims [target]'s butt...")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] licks [target]'s whistler.")) user.make_sucking_noise() do_thrust_animate(user, target) @@ -115,7 +115,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/rimming/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops rimming [target]'s butt ...")) + user.visible_message(span_warning("[user] stops licking [target]'s whistler.")) /datum/sex_action/rimming/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) diff --git a/code/datums/sexcon/sex_actions/sex/anal_sex.dm b/code/datums/sexcon/sex_actions/sex/anal_sex.dm index 44e4317b418..7a84c346e5e 100644 --- a/code/datums/sexcon/sex_actions/sex/anal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/anal_sex.dm @@ -1,5 +1,5 @@ /datum/sex_action/anal_sex - name = "Sodomize them" + name = "taff whistler" stamina_cost = 1.0 /datum/sex_action/anal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -23,18 +23,18 @@ return TRUE /datum/sex_action/anal_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] slides his cock into [target]'s butt!")) + user.visible_message(span_warning("[user] enters [target] from behind.")) playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) /datum/sex_action/anal_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.do_message_signature("[type]")) - user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] fucks [target]'s ass.")) + user.visible_message(user.sexcon.spanify_force("[user] [user.sexcon.get_generic_force_adjective()] taffs [target] from behind.")) playsound(target, 'sound/misc/mat/segso.ogg', 50, TRUE, -2, ignore_walls = FALSE) do_thrust_animate(user, target) user.sexcon.perform_sex_action(user, 2, 0, TRUE) if(user.sexcon.check_active_ejaculation()) - user.visible_message(span_love("[user] cums into [target]'s butt!")) + user.visible_message(span_love("[user] tightens in ecstasy!")) user.sexcon.cum_into() user.virginity = FALSE @@ -45,7 +45,7 @@ target.sexcon.handle_passive_ejaculation() /datum/sex_action/anal_sex/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] pulls his cock out of [target]'s butt.")) + user.visible_message(span_warning("[user] pulls out of [target].")) /datum/sex_action/anal_sex/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user.sexcon.finished_check()) @@ -53,7 +53,7 @@ return FALSE /datum/sex_action/anal_ride_sex - name = "Ride them anally" + name = "ride with whistler" stamina_cost = 1.0 aggro_grab_instead_same_tile = FALSE @@ -76,7 +76,7 @@ return TRUE /datum/sex_action/anal_ride_sex/on_start(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] gets on top of [target] and begins riding them with their butt!")) + user.visible_message(span_warning("[user] starts to ride [target] with their whistler.")) playsound(target, list('sound/misc/mat/insert (1).ogg','sound/misc/mat/insert (2).ogg'), 20, TRUE, ignore_walls = FALSE) /datum/sex_action/anal_ride_sex/on_perform(mob/living/carbon/human/user, mob/living/carbon/human/target) @@ -92,7 +92,7 @@ user.sexcon.perform_sex_action(target, 2, 4, FALSE) if(target.sexcon.check_active_ejaculation()) - target.visible_message(span_love("[target] cums into [user]'s butt!")) + target.visible_message(span_love("[target] tightens in ecstasy!")) target.sexcon.cum_into() target.virginity = FALSE From 75942442d460174ec5013f59aeaebc89745002ef Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 01:18:20 -0700 Subject: [PATCH 14/33] a life thing --- code/modules/mob/living/carbon/human/life.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 76bf8f86e0d..0b165d8a0c3 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -109,6 +109,9 @@ //Update our name based on whether our face is obscured/disfigured name = get_visible_name() + if(sexcon) + sexcon.process_sexcon(1 SECONDS) + if(stat != DEAD) return 1 From 87dbae1675faac5a9671df5f774bc88a2fc07a63 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 01:21:09 -0700 Subject: [PATCH 15/33] a few XTREEEEEME deletions --- code/datums/sexcon/sexcon.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 03036d5be76..893a4ca279f 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -460,8 +460,6 @@ return 1.5 if(SEX_SPEED_HIGH) return 2.0 - if(SEX_SPEED_EXTREME) - return 2.5 /datum/sex_controller/proc/get_stamina_cost_multiplier() switch(force) @@ -471,8 +469,6 @@ return 1.5 if(SEX_FORCE_HIGH) return 2.0 - if(SEX_SPEED_EXTREME) - return 2.5 /datum/sex_controller/proc/get_force_pleasure_multiplier(passed_force, giving) switch(passed_force) @@ -509,8 +505,6 @@ return "STEADY" if(SEX_SPEED_HIGH) return "QUICK" - if(SEX_SPEED_EXTREME) - return "UNRELENTING" /datum/sex_controller/proc/get_manual_arousal_string() switch(manual_arousal) From 836065f8ef603f529eea7172f08608bcbf99178a Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 01:38:06 -0700 Subject: [PATCH 16/33] i'm honestly not too sure how this works --- code/__DEFINES/sexcon_defines.dm | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/code/__DEFINES/sexcon_defines.dm b/code/__DEFINES/sexcon_defines.dm index 685389997b1..8b8abff8559 100644 --- a/code/__DEFINES/sexcon_defines.dm +++ b/code/__DEFINES/sexcon_defines.dm @@ -23,10 +23,9 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define SEX_SPEED_LOW 1 #define SEX_SPEED_MID 2 #define SEX_SPEED_HIGH 3 -#define SEX_SPEED_EXTREME 4 #define SEX_SPEED_MIN 1 -#define SEX_SPEED_MAX 4 +#define SEX_SPEED_MAX 3 #define SEX_FORCE_LOW 1 #define SEX_FORCE_MID 2 @@ -46,14 +45,6 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define BLUEBALLS_GAIN_THRESHOLD 15 #define BLUEBALLS_LOOSE_THRESHOLD 10 -#define PAIN_MILD_EFFECT 10 -#define PAIN_MED_EFFECT 20 -#define PAIN_HIGH_EFFECT 30 -#define PAIN_MINIMUM_FOR_DAMAGE PAIN_MED_EFFECT -#define PAIN_DAMAGE_DIVISOR 50 - -#define VIOLATED_ALLOWED_TIME (10 MINUTES) - /proc/build_sex_actions() . = list() for(var/path in typesof(/datum/sex_action)) From e692cc0ec7737f1762378b9603a1fed124ab2faa Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 17:53:12 -0700 Subject: [PATCH 17/33] a small define --- code/modules/mob/living/carbon/human/human.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a3d1cb44c19..df50dedccd5 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -57,6 +57,9 @@ #endif /mob/living/carbon/human/Initialize() +#ifdef MATURESERVER + sexcon = new /datum/sex_controller(src) +#endif verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down From e8f38b4657562bf34b05c98e715e03a034105579 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 19:55:01 -0700 Subject: [PATCH 18/33] more wording edits --- code/datums/sexcon/sex_actions/deviant/facesitting.dm | 2 +- code/datums/sexcon/sex_actions/sex/throat_sex.dm | 2 +- code/datums/sexcon/sexcon.dm | 6 ++++-- stonekeep.dme | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/facesitting.dm b/code/datums/sexcon/sex_actions/deviant/facesitting.dm index ef2555f919d..0232f9372b7 100644 --- a/code/datums/sexcon/sex_actions/deviant/facesitting.dm +++ b/code/datums/sexcon/sex_actions/deviant/facesitting.dm @@ -1,5 +1,5 @@ /datum/sex_action/facesitting - name = "Sit on their face" + name = "mouth ride" /datum/sex_action/facesitting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm index eb058249b88..01e9c8d8946 100644 --- a/code/datums/sexcon/sex_actions/sex/throat_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -1,5 +1,5 @@ /datum/sex_action/throat_sex - name = "Fuck their throat" + name = "use their throat" stamina_cost = 1.0 /datum/sex_action/throat_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 893a4ca279f..678765a1ff8 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -135,7 +135,7 @@ /datum/sex_controller/proc/ejaculate() log_combat(user, user, "Ejaculated") - user.visible_message(span_love("[user] makes a mess!")) + user.visible_message(span_love("[user] spills on the floor!")) playsound(user, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) add_cum_floor(get_turf(user)) after_ejaculation() @@ -261,6 +261,8 @@ /datum/sex_controller/proc/can_use_penis() if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE + if(!user.gender == MALE) + return FALSE return TRUE /datum/sex_controller/proc/considered_limp() @@ -326,7 +328,7 @@ dat += "" dat += "" - var/datum/browser/popup = new(user, "sexcon", "
Sate Desire
", 490, 550) + var/datum/browser/popup = new(user, "sexcon", "
Pleasures
", 490, 550) popup.set_content(dat.Join()) popup.open() return diff --git a/stonekeep.dme b/stonekeep.dme index 34f2d144a6b..ea6ecddb815 100644 --- a/stonekeep.dme +++ b/stonekeep.dme @@ -724,6 +724,7 @@ #include "code\datums\sexcon\sex_actions\masturbate\masturbate_self.dm" #include "code\datums\sexcon\sex_actions\sex\anal_sex.dm" #include "code\datums\sexcon\sex_actions\sex\throat_sex.dm" +#include "code\datums\sexcon\sex_actions\sex\vaginal_ride_sex.dm" #include "code\datums\sexcon\sex_actions\sex\vaginal_sex.dm" #include "code\datums\skills\_skill.dm" #include "code\datums\skills\combat.dm" From afe9b88ffc4975ee593e2f33529a6d995e2f54bb Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 4 Dec 2024 22:26:10 -0700 Subject: [PATCH 19/33] deletes manual arousal cuz that was an overlay thing --- code/__DEFINES/sexcon_defines.dm | 8 -------- code/_compile_options.dm | 2 +- code/datums/sexcon/sexcon.dm | 30 +++--------------------------- stonekeep.dme | 1 - 4 files changed, 4 insertions(+), 37 deletions(-) diff --git a/code/__DEFINES/sexcon_defines.dm b/code/__DEFINES/sexcon_defines.dm index 8b8abff8559..2d573bbaad2 100644 --- a/code/__DEFINES/sexcon_defines.dm +++ b/code/__DEFINES/sexcon_defines.dm @@ -34,14 +34,6 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define SEX_FORCE_MIN 1 #define SEX_FORCE_MAX 3 -#define SEX_MANUAL_AROUSAL_DEFAULT 1 -#define SEX_MANUAL_AROUSAL_UNAROUSED 2 -#define SEX_MANUAL_AROUSAL_PARTIAL 3 -#define SEX_MANUAL_AROUSAL_FULL 4 - -#define SEX_MANUAL_AROUSAL_MIN 1 -#define SEX_MANUAL_AROUSAL_MAX 4 - #define BLUEBALLS_GAIN_THRESHOLD 15 #define BLUEBALLS_LOOSE_THRESHOLD 10 diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 9fd75373a99..cec32bf94e8 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -1,4 +1,4 @@ -//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this +#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this //uncommented, but not visible in the release version) //#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 678765a1ff8..b37a4122339 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -11,8 +11,6 @@ var/speed = SEX_SPEED_MID /// Enum of desired force var/force = SEX_FORCE_MID - /// Enum of manual arousal state - var/manual_arousal = SEX_MANUAL_AROUSAL_DEFAULT /// Our arousal var/arousal = 0 /// Our charge gauge @@ -80,9 +78,6 @@ /datum/sex_controller/proc/adjust_force(amt) force = clamp(force + amt, SEX_FORCE_MIN, SEX_FORCE_MAX) -/datum/sex_controller/proc/adjust_arousal_manual(amt) - manual_arousal = clamp(manual_arousal + amt, SEX_MANUAL_AROUSAL_MIN, SEX_MANUAL_AROUSAL_MAX) - /datum/sex_controller/proc/update_pink_screen() var/severity = 0 switch(arousal) @@ -259,10 +254,10 @@ ejaculate() /datum/sex_controller/proc/can_use_penis() - if(HAS_TRAIT(user, TRAIT_LIMPDICK)) - return FALSE if(!user.gender == MALE) return FALSE + if(HAS_TRAIT(user, TRAIT_LIMPDICK)) + return FALSE return TRUE /datum/sex_controller/proc/considered_limp() @@ -294,11 +289,7 @@ var/list/dat = list() var/force_name = get_force_string() var/speed_name = get_speed_string() - var/manual_arousal_name = get_manual_arousal_string() - if(!user.gender == MALE) - dat += "
\< [speed_name] \> ~|~ \< [force_name] \>
" - else - dat += "
\< [speed_name] \> ~|~ \< [force_name] \> ~|~ \< [manual_arousal_name] \>
" + dat += "
\< [speed_name] \> ~|~ \< [force_name] \>
" dat += "
| [do_until_finished ? "UNTIL IM FINISHED" : "UNTIL I STOP"] |
" if(target == user) dat += "
Doing unto yourself
" @@ -353,10 +344,6 @@ adjust_force(1) if("force_down") adjust_force(-1) - if("manual_arousal_up") - adjust_arousal_manual(1) - if("manual_arousal_down") - adjust_arousal_manual(-1) if("toggle_finished") do_until_finished = !do_until_finished show_ui() @@ -508,17 +495,6 @@ if(SEX_SPEED_HIGH) return "QUICK" -/datum/sex_controller/proc/get_manual_arousal_string() - switch(manual_arousal) - if(SEX_MANUAL_AROUSAL_DEFAULT) - return "NATURAL" - if(SEX_MANUAL_AROUSAL_UNAROUSED) - return "UNAROUSED" - if(SEX_MANUAL_AROUSAL_PARTIAL) - return "PARTIALLY ERECT" - if(SEX_MANUAL_AROUSAL_FULL) - return "FULLY ERECT" - /datum/sex_controller/proc/get_generic_force_adjective() switch(force) if(SEX_FORCE_LOW) diff --git a/stonekeep.dme b/stonekeep.dme index ea6ecddb815..34f2d144a6b 100644 --- a/stonekeep.dme +++ b/stonekeep.dme @@ -724,7 +724,6 @@ #include "code\datums\sexcon\sex_actions\masturbate\masturbate_self.dm" #include "code\datums\sexcon\sex_actions\sex\anal_sex.dm" #include "code\datums\sexcon\sex_actions\sex\throat_sex.dm" -#include "code\datums\sexcon\sex_actions\sex\vaginal_ride_sex.dm" #include "code\datums\sexcon\sex_actions\sex\vaginal_sex.dm" #include "code\datums\skills\_skill.dm" #include "code\datums\skills\combat.dm" From b6d21c02aaa526795ef22e8c06edcdf1bda4f2a1 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 00:24:29 -0700 Subject: [PATCH 20/33] turns out the variables were fucked --- code/datums/sexcon/sex_actions/deviant/frotting.dm | 8 ++++---- code/datums/sexcon/sex_actions/deviant/thighjob.dm | 8 ++++---- code/datums/sexcon/sex_actions/deviant/titjob.dm | 4 ++-- .../sex_actions/masturbate/masturbate_other.dm | 4 ++-- .../masturbate/masturbate_penis_over.dm | 4 ++-- .../sex_actions/masturbate/masturbate_self.dm | 4 ++-- code/datums/sexcon/sex_actions/oral.dm | 4 ++-- code/datums/sexcon/sex_actions/sex/anal_sex.dm | 8 ++++---- code/datums/sexcon/sex_actions/sex/throat_sex.dm | 6 ++---- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 14 ++++++-------- code/datums/sexcon/sexcon.dm | 4 ++-- 11 files changed, 32 insertions(+), 36 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/frotting.dm b/code/datums/sexcon/sex_actions/deviant/frotting.dm index a2665a520a7..b38058eda5e 100644 --- a/code/datums/sexcon/sex_actions/deviant/frotting.dm +++ b/code/datums/sexcon/sex_actions/deviant/frotting.dm @@ -4,9 +4,9 @@ /datum/sex_action/frotting/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return - if(!target.gender == MALE) + if(target.gender == FEMALE) return return TRUE @@ -17,9 +17,9 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/thighjob.dm b/code/datums/sexcon/sex_actions/deviant/thighjob.dm index e1af2b40b1b..1fc84cfc68a 100644 --- a/code/datums/sexcon/sex_actions/deviant/thighjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/thighjob.dm @@ -4,7 +4,7 @@ /datum/sex_action/thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return return TRUE @@ -13,7 +13,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE return TRUE @@ -38,7 +38,7 @@ /datum/sex_action/force_thighjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE @@ -47,7 +47,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index 9a1768b9f1c..84ae7d9afd6 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -4,7 +4,7 @@ /datum/sex_action/titjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return if(!target.gender == FEMALE) return @@ -17,7 +17,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_CHEST)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(!target.gender == FEMALE) return FALSE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index 5cff14e6966..fb1cb9abdf2 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -45,7 +45,7 @@ /datum/sex_action/masturbate_penis_other/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE @@ -54,7 +54,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm index befd0ecb925..13e9fb03910 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_penis_over.dm @@ -5,7 +5,7 @@ /datum/sex_action/masturbate_penis_over/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE return TRUE @@ -14,7 +14,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(!user.sexcon.can_use_penis()) return diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index 90ad8955c0c..91bd5b58171 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -43,7 +43,7 @@ /datum/sex_action/masturbate_penis/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user != target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE return TRUE @@ -52,7 +52,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(!user.sexcon.can_use_penis()) return diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index 7f382871a61..baa49be23a5 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -48,7 +48,7 @@ /datum/sex_action/blowjob/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE @@ -59,7 +59,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/sex/anal_sex.dm b/code/datums/sexcon/sex_actions/sex/anal_sex.dm index 7a84c346e5e..00eb701800d 100644 --- a/code/datums/sexcon/sex_actions/sex/anal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/anal_sex.dm @@ -5,7 +5,7 @@ /datum/sex_action/anal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE return TRUE @@ -16,7 +16,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(!user.sexcon.can_use_penis()) return @@ -60,7 +60,7 @@ /datum/sex_action/anal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE @@ -71,7 +71,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/sex/throat_sex.dm b/code/datums/sexcon/sex_actions/sex/throat_sex.dm index 01e9c8d8946..ebe60fbe506 100644 --- a/code/datums/sexcon/sex_actions/sex/throat_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/throat_sex.dm @@ -5,7 +5,7 @@ /datum/sex_action/throat_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE return TRUE @@ -16,9 +16,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!user.gender == MALE) - return FALSE - if(!user.sexcon.can_use_penis()) + if(user.gender == FEMALE) return return TRUE diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 41b2b9d2787..2a545634fd6 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -5,9 +5,9 @@ /datum/sex_action/vaginal_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == FEMALE) + if(user.gender == FEMALE) return FALSE - if(!user.gender == MALE) + if(target.gender == MALE) return FALSE return TRUE @@ -18,11 +18,9 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE - if(!user.gender == MALE) - return FALSE - if(!user.sexcon.can_use_penis()) + if(user.gender == FEMALE) return return TRUE @@ -67,7 +65,7 @@ return FALSE if(!user.gender == FEMALE) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE @@ -80,7 +78,7 @@ return FALSE if(!user.gender == FEMALE) return FALSE - if(!target.gender == MALE) + if(target.gender == FEMALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index b37a4122339..d0695b10b4a 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -238,7 +238,7 @@ return TRUE /datum/sex_controller/proc/can_ejaculate() - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE @@ -254,7 +254,7 @@ ejaculate() /datum/sex_controller/proc/can_use_penis() - if(!user.gender == MALE) + if(user.gender == FEMALE) return FALSE if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE From eaed6761242d78022a2773aa5fb0668ac11a300e Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 01:20:05 -0700 Subject: [PATCH 21/33] delete endless sexo and makes undies cover you properly --- code/datums/sexcon/sex_actions/deviant/scissoring.dm | 4 ++-- code/datums/sexcon/sex_actions/deviant/titjob.dm | 4 ++-- .../sexcon/sex_actions/masturbate/masturbate_other.dm | 4 ++-- code/datums/sexcon/sex_actions/oral.dm | 6 +++--- code/datums/sexcon/sexcon.dm | 8 +------- code/game/objects/items/rogueitems/undies.dm | 2 ++ 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/scissoring.dm b/code/datums/sexcon/sex_actions/deviant/scissoring.dm index db2dc794c04..6c59946e1e9 100644 --- a/code/datums/sexcon/sex_actions/deviant/scissoring.dm +++ b/code/datums/sexcon/sex_actions/deviant/scissoring.dm @@ -6,7 +6,7 @@ return FALSE if(!user.gender == FEMALE) return - if(!target.gender == FEMALE) + if(target.gender == MALE) return return TRUE @@ -19,7 +19,7 @@ return FALSE if(!user.gender == FEMALE) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/deviant/titjob.dm b/code/datums/sexcon/sex_actions/deviant/titjob.dm index 84ae7d9afd6..d821b600528 100644 --- a/code/datums/sexcon/sex_actions/deviant/titjob.dm +++ b/code/datums/sexcon/sex_actions/deviant/titjob.dm @@ -6,7 +6,7 @@ return FALSE if(user.gender == FEMALE) return - if(!target.gender == FEMALE) + if(target.gender == MALE) return return TRUE @@ -19,7 +19,7 @@ return FALSE if(user.gender == FEMALE) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm index fb1cb9abdf2..5af595f7b0a 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_other.dm @@ -5,7 +5,7 @@ /datum/sex_action/masturbate_other_vagina/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE @@ -14,7 +14,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index baa49be23a5..de43bf3e870 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -4,7 +4,7 @@ /datum/sex_action/cunnilingus/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE @@ -15,7 +15,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_MOUTH)) return FALSE - if(!target.gender == FEMALE) + if(target.gender == MALE) return FALSE return TRUE @@ -34,7 +34,7 @@ target.sexcon.cum_into() /datum/sex_action/cunnilingus/on_finish(mob/living/carbon/human/user, mob/living/carbon/human/target) - user.visible_message(span_warning("[user] stops sucking [target]'s clit ...")) + user.visible_message(span_warning("[user] stops eating [target].")) /datum/sex_action/cunnilingus/is_finished(mob/living/carbon/human/user, mob/living/carbon/human/target) if(target.sexcon.finished_check()) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index d0695b10b4a..6b2c98f7aa8 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -16,7 +16,6 @@ /// Our charge gauge var/charge = SEX_MAX_CHARGE /// Whether we want to screw until finished, or non stop - var/do_until_finished = TRUE var/last_arousal_increase_time = 0 var/last_ejaculation_time = 0 var/last_moan = 0 @@ -66,8 +65,6 @@ return FALSE /datum/sex_controller/proc/finished_check() - if(!do_until_finished) - return FALSE if(!just_ejaculated()) return FALSE return TRUE @@ -165,7 +162,7 @@ charge = clamp(amount, 0, SEX_MAX_CHARGE) var/after_empty = (charge < CHARGE_FOR_CLIMAX) if(empty && !after_empty) - to_chat(user, span_notice("I feel like I'm not so spent anymore")) + to_chat(user, span_notice("I feel like I'm not so spent anymore.")) if(!empty && after_empty) to_chat(user, span_notice("I'm spent!")) @@ -290,7 +287,6 @@ var/force_name = get_force_string() var/speed_name = get_speed_string() dat += "
\< [speed_name] \> ~|~ \< [force_name] \>
" - dat += "
| [do_until_finished ? "UNTIL IM FINISHED" : "UNTIL I STOP"] |
" if(target == user) dat += "
Doing unto yourself
" else @@ -344,8 +340,6 @@ adjust_force(1) if("force_down") adjust_force(-1) - if("toggle_finished") - do_until_finished = !do_until_finished show_ui() /datum/sex_controller/proc/try_stop_current_action() diff --git a/code/game/objects/items/rogueitems/undies.dm b/code/game/objects/items/rogueitems/undies.dm index de67c54746a..d8a75d655eb 100644 --- a/code/game/objects/items/rogueitems/undies.dm +++ b/code/game/objects/items/rogueitems/undies.dm @@ -1,6 +1,7 @@ /obj/item/undies name = "smallclothes" desc = "An Eoran designed undergarment to cover the loins." + body_parts_covered = GROIN icon = 'icons/roguetown/items/misc.dmi' icon_state = "undies" resistance_flags = FLAMMABLE @@ -17,6 +18,7 @@ /obj/item/undies/f name = "women's smallclothes" desc = "An Eoran designed undergarment to cover the privates and chest." + body_parts_covered = CHEST|GROIN icon_state = "girlundies" gendered = FEMALE From b2888fecb3eb1ccfdc83a84417f03c95fbdf6480 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 12:44:10 -0700 Subject: [PATCH 22/33] increases pleasure modifier so you don't have to goon --- code/__DEFINES/sexcon_defines.dm | 2 +- .../sex_actions/masturbate/masturbate_self.dm | 2 +- code/datums/sexcon/sexcon.dm | 15 +++++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/__DEFINES/sexcon_defines.dm b/code/__DEFINES/sexcon_defines.dm index 2d573bbaad2..c18436654ab 100644 --- a/code/__DEFINES/sexcon_defines.dm +++ b/code/__DEFINES/sexcon_defines.dm @@ -3,7 +3,7 @@ GLOBAL_LIST_INIT(sex_actions, build_sex_actions()) #define SEX_ACTION(sex_action_type) GLOB.sex_actions[sex_action_type] #define MAX_AROUSAL 150 -#define PASSIVE_EJAC_THRESHOLD 108 +#define PASSIVE_EJAC_THRESHOLD 100 #define ACTIVE_EJAC_THRESHOLD 100 #define SEX_MAX_CHARGE 300 #define CHARGE_FOR_CLIMAX 100 diff --git a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm index 91bd5b58171..4c81a0d6a35 100644 --- a/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm +++ b/code/datums/sexcon/sex_actions/masturbate/masturbate_self.dm @@ -13,7 +13,7 @@ return FALSE if(!get_location_accessible(user, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == FEMALE) + if(user.gender == MALE) return FALSE return TRUE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 6b2c98f7aa8..d791a6580d0 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -16,6 +16,7 @@ /// Our charge gauge var/charge = SEX_MAX_CHARGE /// Whether we want to screw until finished, or non stop + var/do_until_finished = TRUE var/last_arousal_increase_time = 0 var/last_ejaculation_time = 0 var/last_moan = 0 @@ -65,6 +66,8 @@ return FALSE /datum/sex_controller/proc/finished_check() + if(!do_until_finished) + return FALSE if(!just_ejaculated()) return FALSE return TRUE @@ -457,19 +460,19 @@ switch(passed_force) if(SEX_FORCE_LOW) if(giving) - return 0.8 + return 2.0 else - return 0.8 + return 2.0 if(SEX_FORCE_MID) if(giving) - return 1.2 + return 2.2 else - return 1.2 + return 2.2 if(SEX_FORCE_HIGH) if(giving) - return 1.6 + return 2.6 else - return 1.2 + return 2.2 /datum/sex_controller/proc/get_force_string() switch(force) From a3c402aa3651c09317155512ac3bd3df677a9bf9 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 13:54:13 -0700 Subject: [PATCH 23/33] the sex... it's real!! --- code/datums/sexcon/sexcon.dm | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index d791a6580d0..428cfe2fb78 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -1,3 +1,11 @@ +/* Sex controller documentation notes: +You click with middle mouse on someone and drag them to your preferred target to open up the sex menu, where you select a sex action to perform. +The sex actions you can perform are gender-locked, as opposed to being specificially genital-locked, because Stonekeep doesn't have penis/testicles/vagina/breast organ slots like Ratwood and Azure Peak do. +If you want to lock an action to one sex, don't do if(!user.gender == [gender]), do if(user.gender == [gender]). I don't know why, but ! doesn't work on that and specifically that. +If, say, you wanted to seperate sex and gender without going to the trouble of adding cocks and pussies, you could simply code seperate variables for your sex and gender identity (based on pronouns or some shit IDK). +ejaculate() is actually just orgasm, for both sexes. I found this out the hard way after somehow making female characters unable to finish while testing this for the first time. +*/ + /datum/sex_controller /// The user and the owner of the controller var/mob/living/carbon/human/user @@ -129,11 +137,15 @@ after_intimate_climax() /datum/sex_controller/proc/ejaculate() - log_combat(user, user, "Ejaculated") - user.visible_message(span_love("[user] spills on the floor!")) - playsound(user, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) - add_cum_floor(get_turf(user)) - after_ejaculation() + log_combat(user, user, "Orgasmed") + if(user.gender == FEMALE) + user.visible_message(span_love("[user] tightens in ecstasy!")) + after_ejaculation() + if(user.gender == MALE) + user.visible_message(span_love("[user] spills on the floor!")) + playsound(user, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) + add_cum_floor(get_turf(user)) + after_ejaculation() /datum/sex_controller/proc/after_ejaculation() set_arousal(40) @@ -238,8 +250,6 @@ return TRUE /datum/sex_controller/proc/can_ejaculate() - if(user.gender == FEMALE) - return FALSE if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE return TRUE From f9636da56c9897e5e6ff1398cd03bea82ee19b1d Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 18:00:41 -0700 Subject: [PATCH 24/33] anti-zape controls and some adminlogs --- code/datums/sexcon/sexcon.dm | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 428cfe2fb78..6d21a97b6da 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -4,7 +4,7 @@ The sex actions you can perform are gender-locked, as opposed to being specifici If you want to lock an action to one sex, don't do if(!user.gender == [gender]), do if(user.gender == [gender]). I don't know why, but ! doesn't work on that and specifically that. If, say, you wanted to seperate sex and gender without going to the trouble of adding cocks and pussies, you could simply code seperate variables for your sex and gender identity (based on pronouns or some shit IDK). ejaculate() is actually just orgasm, for both sexes. I found this out the hard way after somehow making female characters unable to finish while testing this for the first time. -*/ +Admin logging is provided for orgasms and if you try to initiate sex with corpses, sleeping people, or people in combat mode. You can't bang in combat mode, as anti-zape protection.*/ /datum/sex_controller /// The user and the owner of the controller @@ -117,6 +117,18 @@ ejaculate() is actually just orgasm, for both sexes. I found this out the hard w /datum/sex_controller/proc/start(mob/living/carbon/human/new_target) if(!ishuman(new_target)) return + if(new_target.living == FALSE) + log_combat(user, target, "Tried to initiate sex with dead mob") + user.visible_message(span_warning("That's a corpse...")) + return FALSE + if(new_target.IsUnconscious()) + log_combat(user, target, "Tried to initiate sex with unconscious mob") + user.visible_message(span_warning("They're asleep.")) + return FALSE + if(new_target.cmode) + log_combat(user, target, "Tried to initiate sex with mob in combat mode") + user.visible_message(span_warning("They're unwilling.")) + return FALSE set_target(new_target) show_ui() @@ -448,6 +460,20 @@ ejaculate() is actually just orgasm, for both sexes. I found this out the hard w /datum/sex_controller/proc/set_target(mob/living/carbon/human/new_target) target = new_target +/mob/living/carbon/human/proc/on_virgin_loss() + var/mob/living/carbon/P = src + virginity = FALSE + if(mind) + switch(mind.assigned_role) + if("Priest") + P.add_stress(/datum/stressevent/virginchurch) + if("Acolyte") + P.add_stress(/datum/stressevent/virginchurch) + if("Cleric") + P.add_stress(/datum/stressevent/virginchurch) + if("Paladin") + P.add_stress(/datum/stressevent/virginchurch) + /datum/sex_controller/proc/get_speed_multiplier() switch(speed) if(SEX_SPEED_LOW) From 25ad16be46b72878654637c1ebb688c671d9be3d Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 20:38:56 -0700 Subject: [PATCH 25/33] GETS THE LOGS WORKING --- .../sexcon/sex_actions/deviant/scissoring.dm | 4 ++-- code/datums/sexcon/sexcon.dm | 18 +++--------------- code/datums/sexcon/sexcon_helpers.dm | 14 +++++++++++++- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/code/datums/sexcon/sex_actions/deviant/scissoring.dm b/code/datums/sexcon/sex_actions/deviant/scissoring.dm index 6c59946e1e9..4adbc7845cf 100644 --- a/code/datums/sexcon/sex_actions/deviant/scissoring.dm +++ b/code/datums/sexcon/sex_actions/deviant/scissoring.dm @@ -4,7 +4,7 @@ /datum/sex_action/scissoring/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == FEMALE) + if(user.gender == MALE) return if(target.gender == MALE) return @@ -17,7 +17,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == FEMALE) + if(user.gender == MALE) return FALSE if(target.gender == MALE) return FALSE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 6d21a97b6da..2bde846941e 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -117,29 +117,17 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse /datum/sex_controller/proc/start(mob/living/carbon/human/new_target) if(!ishuman(new_target)) return - if(new_target.living == FALSE) - log_combat(user, target, "Tried to initiate sex with dead mob") - user.visible_message(span_warning("That's a corpse...")) - return FALSE - if(new_target.IsUnconscious()) - log_combat(user, target, "Tried to initiate sex with unconscious mob") - user.visible_message(span_warning("They're asleep.")) - return FALSE - if(new_target.cmode) - log_combat(user, target, "Tried to initiate sex with mob in combat mode") - user.visible_message(span_warning("They're unwilling.")) - return FALSE set_target(new_target) show_ui() /datum/sex_controller/proc/cum_onto() - log_combat(user, target, "Came onto the target") + log_combat(user, target, "came onto the target") playsound(target, 'sound/misc/mat/endout.ogg', 50, TRUE, ignore_walls = FALSE) add_cum_floor(get_turf(target)) after_ejaculation() /datum/sex_controller/proc/cum_into(oral = FALSE) - log_combat(user, target, "Came inside the target") + log_combat(user, target, "came inside the target") if(oral) playsound(target, pick(list('sound/misc/mat/mouthend (1).ogg','sound/misc/mat/mouthend (2).ogg')), 100, FALSE, ignore_walls = FALSE) else @@ -149,7 +137,7 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse after_intimate_climax() /datum/sex_controller/proc/ejaculate() - log_combat(user, user, "Orgasmed") + log_combat(user, user, "orgasmed") if(user.gender == FEMALE) user.visible_message(span_love("[user] tightens in ecstasy!")) after_ejaculation() diff --git a/code/datums/sexcon/sexcon_helpers.dm b/code/datums/sexcon/sexcon_helpers.dm index 74ed75f063d..ab2ef6b19b7 100644 --- a/code/datums/sexcon/sexcon_helpers.dm +++ b/code/datums/sexcon/sexcon_helpers.dm @@ -45,8 +45,20 @@ if(target != user) return if(!user.can_do_sex()) - to_chat(user, "I can't do this.") + user.visible_message(span_warning("I can't do this.")) return + if(stat != CONSCIOUS) + log_combat(user, target, "tried to initiate sex with unconscious mob") + user.visible_message(span_warning("They're asleep.")) + return + if(stat != DEAD) + log_combat(user, target, "tried to initiate sex with dead mob") + user.visible_message(span_warning("That's a corpse...")) + return + if(target.cmode) + log_combat(user, target, "tried to initiate sex with mob in combat mode") + user.visible_message(span_warning("They're unwilling.")) + return FALSE user.sexcon.start(src) /mob/living/proc/can_do_sex() From 2826c91005efe719d1d8b25caabbfd9b3b3e42d5 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 20:40:22 -0700 Subject: [PATCH 26/33] untest --- code/_compile_options.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_compile_options.dm b/code/_compile_options.dm index cec32bf94e8..9fd75373a99 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -1,4 +1,4 @@ -#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this +//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this //uncommented, but not visible in the release version) //#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. From 52a2f5b722b94f70a8faba7ef2d04c4a562b5b9b Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Thu, 5 Dec 2024 22:41:39 -0700 Subject: [PATCH 27/33] minor fix here --- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index 2a545634fd6..b44dcf249f9 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -63,7 +63,7 @@ /datum/sex_action/vaginal_ride_sex/shows_on_menu(mob/living/carbon/human/user, mob/living/carbon/human/target) if(user == target) return FALSE - if(!user.gender == FEMALE) + if(user.gender == MALE) return FALSE if(target.gender == FEMALE) return FALSE From 2abf97aba60cb4a0d698c6863e38aa01645e5e3d Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Fri, 6 Dec 2024 14:53:41 -0700 Subject: [PATCH 28/33] FUCK FUCK FUCK --- code/datums/sexcon/sexcon_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/sexcon/sexcon_helpers.dm b/code/datums/sexcon/sexcon_helpers.dm index ab2ef6b19b7..5064950a0b1 100644 --- a/code/datums/sexcon/sexcon_helpers.dm +++ b/code/datums/sexcon/sexcon_helpers.dm @@ -51,7 +51,7 @@ log_combat(user, target, "tried to initiate sex with unconscious mob") user.visible_message(span_warning("They're asleep.")) return - if(stat != DEAD) + if(stat == DEAD) log_combat(user, target, "tried to initiate sex with dead mob") user.visible_message(span_warning("That's a corpse...")) return From f5b8d7384b95dc586a16afbaec9892c6609621d5 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Sat, 7 Dec 2024 01:34:29 -0700 Subject: [PATCH 29/33] lowers a pleasure modifier --- code/datums/sexcon/sex_actions/sex/vaginal_sex.dm | 2 +- code/datums/sexcon/sexcon.dm | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm index b44dcf249f9..79ed40d2efe 100644 --- a/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm +++ b/code/datums/sexcon/sex_actions/sex/vaginal_sex.dm @@ -76,7 +76,7 @@ return FALSE if(!get_location_accessible(target, BODY_ZONE_PRECISE_GROIN)) return FALSE - if(!user.gender == FEMALE) + if(user.gender == MALE) return FALSE if(target.gender == FEMALE) return FALSE diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 2bde846941e..d05832f3d24 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -235,6 +235,8 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse user.emote(chosen_emote, forced = TRUE) /datum/sex_controller/proc/update_blueballs() + if(user.gender == FEMALE) + return FALSE if(arousal >= BLUEBALLS_GAIN_THRESHOLD) user.add_stress(/datum/stressevent/blueb) else if (arousal <= BLUEBALLS_LOOSE_THRESHOLD) @@ -484,19 +486,19 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse switch(passed_force) if(SEX_FORCE_LOW) if(giving) - return 2.0 + return 1.0 else - return 2.0 + return 0.8 if(SEX_FORCE_MID) if(giving) - return 2.2 + return 1.2 else - return 2.2 + return 1.0 if(SEX_FORCE_HIGH) if(giving) - return 2.6 + return 1.5 else - return 2.2 + return 1.0 /datum/sex_controller/proc/get_force_string() switch(force) From 0c7c9f1c345c7d0440280c8548649d5c8b373987 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Mon, 9 Dec 2024 21:02:59 -0700 Subject: [PATCH 30/33] rejigging the way churchy virginity loss happens --- code/datums/sexcon/sexcon.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index d05832f3d24..6112ba2ecc8 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -451,14 +451,20 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse target = new_target /mob/living/carbon/human/proc/on_virgin_loss() - var/mob/living/carbon/P = src + var/mob/living/carbon/human/P = src virginity = FALSE + if((P.patron != /datum/patron/divine/astrata) || (P.patron != /datum/patron/divine/noc) || (P.patron != /datum/patron/divine/malum) || (P.patron != /datum/patron/forgotten)) + return FALSE + if(P.IsWedded()) + return FALSE if(mind) switch(mind.assigned_role) if("Priest") P.add_stress(/datum/stressevent/virginchurch) if("Acolyte") P.add_stress(/datum/stressevent/virginchurch) + if("Templar") + P.add_stress(/datum/stressevent/virginchurch) if("Cleric") P.add_stress(/datum/stressevent/virginchurch) if("Paladin") From 323c9b72a3dac363cd9982bb776bb924770f93c2 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Fri, 13 Dec 2024 14:33:20 -0700 Subject: [PATCH 31/33] a final slight edit for the typists out there --- code/datums/sexcon/sexcon.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index 6112ba2ecc8..b6d99c403c7 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -492,17 +492,17 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse switch(passed_force) if(SEX_FORCE_LOW) if(giving) - return 1.0 - else return 0.8 + else + return 0.6 if(SEX_FORCE_MID) if(giving) - return 1.2 - else return 1.0 + else + return 0.8 if(SEX_FORCE_HIGH) if(giving) - return 1.5 + return 1.2 else return 1.0 From 5317259188b0c94e5c812e643c179291e7f9a057 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 18 Dec 2024 15:44:40 -0700 Subject: [PATCH 32/33] MONO'S DICK-BITING CODE I AM SO SORRY --- code/__DEFINES/traits.dm | 1 + code/datums/sexcon/sex_actions/oral.dm | 30 ++++++++++++++++++++++++++ code/datums/sexcon/sexcon.dm | 4 ++++ 3 files changed, 35 insertions(+) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 379c41f7d27..41ee6c720ef 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -53,6 +53,7 @@ #define TRAIT_VAMPMANSION "vampiremansion" #define TRAIT_INHUMENCAMP "inhumencamp" #define TRAIT_LIMPDICK "limp_dick" +#define TRAIT_MINCED "minced" // from monochrome/catalaria. your dick fell off #define TRAIT_SEXPASS "sexpass" #define TRAIT_INTRAINING "intraining" //allows certain roles to bypass the average skill limitation of training dummies #define TRAIT_STEELHEARTED "steelhearted" //no bad mood from dismembering or seeing this diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index de43bf3e870..2c7f48a94e9 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -28,6 +28,21 @@ user.make_sucking_noise() do_thrust_animate(user, target) + if(ishuman(target)) // Yep, dick-biting code if you're a Kaizoku changeling. From Mono. + var/mob/living/carbon/human/H = user + if(H.dna?.species?.name == "Changeling") + if(prob(15)) + target.visible_message(span_danger("OH GODS! THAT FREEK TORE IT APART!")) + user.visible_message(span_danger("The fleshy taste drives you into a trance, involuntary, carnivorous hunger! Your jaws loosen!")) + playsound(target, 'sound/combat/dismemberment/dismem (1).ogg', 100, TRUE, ignore_walls = FALSE) + ADD_TRAIT(target, TRAIT_MINCED, TRAIT_GENERIC) + target.emote("scream") + target.apply_damage(80, BRUTE, BODY_ZONE_PRECISE_GROIN) + target.Stun(60) + return + else + user.visible_message(span_info("You suppress the primal instinct, though this strain feels unnatural to your biology.")) + user.sexcon.perform_sex_action(target, 2, 3, TRUE) if(target.sexcon.check_active_ejaculation()) target.visible_message(span_love("[target] tightens in ectasy!")) @@ -72,6 +87,21 @@ user.make_sucking_noise() do_thrust_animate(user, target) + if(ishuman(target)) // Yep, dick-biting code if you're a Kaizoku changeling. From Mono. + var/mob/living/carbon/human/H = user + if(H.dna?.species?.name == "Changeling") + if(prob(15)) + target.visible_message(span_danger("OH GODS! THAT FREEK TORE IT APART!")) + user.visible_message(span_danger("The fleshy taste drives you into a trance, involuntary, carnivorous hunger! Your jaws loosen!")) + playsound(target, 'sound/combat/dismemberment/dismem (1).ogg', 100, TRUE, ignore_walls = FALSE) + ADD_TRAIT(target, TRAIT_MINCED, TRAIT_GENERIC) + target.emote("scream") + target.apply_damage(80, BRUTE, BODY_ZONE_PRECISE_GROIN) + target.Stun(60) + return + else + user.visible_message(span_info("You suppress the primal instinct, though this strain feels unnatural to your biology.")) + user.sexcon.perform_sex_action(target, 2, 0, TRUE) if(target.sexcon.check_active_ejaculation()) target.visible_message(span_love("[target] tightens in ectasy!")) diff --git a/code/datums/sexcon/sexcon.dm b/code/datums/sexcon/sexcon.dm index b6d99c403c7..a1056dffe38 100644 --- a/code/datums/sexcon/sexcon.dm +++ b/code/datums/sexcon/sexcon.dm @@ -254,6 +254,8 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse /datum/sex_controller/proc/can_ejaculate() if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE + if(HAS_TRAIT(user, TRAIT_MINCED)) + return FALSE return TRUE /datum/sex_controller/proc/handle_passive_ejaculation() @@ -270,6 +272,8 @@ Admin logging is provided for orgasms and if you try to initiate sex with corpse return FALSE if(HAS_TRAIT(user, TRAIT_LIMPDICK)) return FALSE + if(HAS_TRAIT(user, TRAIT_MINCED)) + return FALSE return TRUE /datum/sex_controller/proc/considered_limp() From bc02401079648a95b8352d1f9145f3bca35b7fa0 Mon Sep 17 00:00:00 2001 From: La Villa Strangiato Date: Wed, 18 Dec 2024 16:00:28 -0700 Subject: [PATCH 33/33] crunchy code for the other oral bits --- .../sexcon/sex_actions/deviant/facesitting.dm | 15 +++++++++++++++ code/datums/sexcon/sex_actions/oral.dm | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/code/datums/sexcon/sex_actions/deviant/facesitting.dm b/code/datums/sexcon/sex_actions/deviant/facesitting.dm index 0232f9372b7..f2b6d6e6e75 100644 --- a/code/datums/sexcon/sex_actions/deviant/facesitting.dm +++ b/code/datums/sexcon/sex_actions/deviant/facesitting.dm @@ -30,6 +30,21 @@ target.make_sucking_noise() do_thrust_animate(user, target) + if(ishuman(user)) // Yep, dick-biting code if you're a Kaizoku changeling. From Mono. + var/mob/living/carbon/human/H = target + if(H.dna?.species?.name == "Changeling") + if(prob(15)) + user.visible_message(span_danger("OH GODS! THAT FREEK TORE IT APART!")) + target.visible_message(span_danger("The fleshy taste drives you into a trance, involuntary, carnivorous hunger! Your jaws loosen!")) + playsound(target, 'sound/combat/dismemberment/dismem (1).ogg', 100, TRUE, ignore_walls = FALSE) + ADD_TRAIT(target, TRAIT_MINCED, TRAIT_GENERIC) + user.emote("scream") + user.apply_damage(80, BRUTE, BODY_ZONE_PRECISE_GROIN) + user.Stun(60) + return + else + user.visible_message(span_info("You suppress the primal instinct, though this strain feels unnatural to your biology.")) + user.sexcon.perform_sex_action(user, 1, 3, TRUE) user.sexcon.handle_passive_ejaculation() diff --git a/code/datums/sexcon/sex_actions/oral.dm b/code/datums/sexcon/sex_actions/oral.dm index 2c7f48a94e9..25fbdc6fcb0 100644 --- a/code/datums/sexcon/sex_actions/oral.dm +++ b/code/datums/sexcon/sex_actions/oral.dm @@ -141,6 +141,21 @@ user.make_sucking_noise() do_thrust_animate(user, target) + if(ishuman(target)) // Yep, dick-biting code if you're a Kaizoku changeling. From Mono. + var/mob/living/carbon/human/H = user + if(H.dna?.species?.name == "Changeling") + if(prob(15)) + target.visible_message(span_danger("OH GODS! THAT FREEK TORE IT APART!")) + user.visible_message(span_danger("The fleshy taste drives you into a trance, involuntary, carnivorous hunger! Your jaws loosen!")) + playsound(target, 'sound/combat/dismemberment/dismem (1).ogg', 100, TRUE, ignore_walls = FALSE) + ADD_TRAIT(target, TRAIT_MINCED, TRAIT_GENERIC) + target.emote("scream") + target.apply_damage(80, BRUTE, BODY_ZONE_PRECISE_GROIN) + target.Stun(60) + return + else + user.visible_message(span_info("You suppress the primal instinct, though this strain feels unnatural to your biology.")) + user.sexcon.perform_sex_action(target, 2, 0, TRUE) target.sexcon.handle_passive_ejaculation()