Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ name: Run Tests
on:
push:
branches:
- dev
- stable
- staging
- trunk
pull_request:
branches:
- dev
- stable
- staging
- trunk
workflow_dispatch:

env:
BYOND_MAJOR: "515"
BYOND_MINOR: "1643"
BYOND_MAJOR: "516"
BYOND_MINOR: "1659"
SPACEMAN_DMM_VERSION: suite-1.9

jobs:
Expand Down
2 changes: 2 additions & 0 deletions maps/shaded_hills/shaded_hills.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "../../mods/content/fantasy/_fantasy.dme"
#include "../../mods/content/blacksmithy/_blacksmithy.dme"

#include "../../mods/content/sexcon/_sexcon.dme"

#include "areas/_areas.dm"
#include "areas/downlands.dm"
#include "areas/grassland.dm"
Expand Down
120 changes: 120 additions & 0 deletions mods/content/sexcon/_sexcon.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/decl/modpack/sexcon
name = "Sex Controller Content"

/decl/config/toggle/sexcon
uid = "toggle_sexcon"
desc = "Remove the # to enable sex mechanics."

/datum/client_preference/sexable
description = "Sex Mechanics"
key = "SEXCON_TOGGLE"
default_value = PREF_NO

/// DEFINES ///

#define SEX_ACTION(sex_action_type) RESOLVE_TO_DECL(sex_action_type)

#define MAX_AROUSAL 150
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are limited to just the modpack so it's probably fine, but i would personally prefer const vars on /datum/sex_controller or wherever else it's used, assuming it's only used on one type (if it's only used in one proc, it can be a proc-scope const even!)

#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 BLUEBALLS_GAIN_THRESHOLD 40
#define BLUEBALLS_LOOSE_THRESHOLD 35

#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

// GENITAL DEFINES //
#define BP_PENIS "penis"
#define BP_VAGINA "vagina"
#define BP_BREASTS "breasts"

#define SLOT_PENIS BITFLAG(20)
#define SLOT_BREASTS BITFLAG(21)
#define SLOT_VAGINA BITFLAG(22)

#define BREAST_MILK /decl/material/liquid/drink/milk/breast_milk

#define MIN_PENIS_SIZE 1
#define DEFAULT_PENIS_SIZE 2
#define MAX_PENIS_SIZE 3

#define PENIS_TYPE_PLAIN 1
#define PENIS_TYPE_KNOTTED 2
#define PENIS_TYPE_EQUINE 3
#define PENIS_TYPE_TAPERED 4
#define PENIS_TYPE_TAPERED_DOUBLE 5
#define PENIS_TYPE_TAPERED_DOUBLE_KNOTTED 6
#define PENIS_TYPE_BARBED 7
#define PENIS_TYPE_BARBED_KNOTTED 8
#define PENIS_TYPE_TENTACLE 9

#define SHEATH_TYPE_NONE 0
#define SHEATH_TYPE_NORMAL 1
#define SHEATH_TYPE_SLIT 2

#define ERECT_STATE_NONE 0
#define ERECT_STATE_PARTIAL 1
#define ERECT_STATE_HARD 2

#define MIN_TESTICLES_SIZE 1
#define DEFAULT_TESTICLES_SIZE 2
#define MAX_TESTICLES_SIZE 3

#define MIN_BREASTS_SIZE 0
#define DEFAULT_BREASTS_SIZE 3
#define MAX_BREASTS_SIZE 5

// SEX SOUND LISTS //
var/global/list/sex_moan_heavy = list(
'mods/content/sexcon/sounds/voices/female/sex/sex (1).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (2).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (3).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (4).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (5).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (6).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (7).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sex (8).ogg'
)
var/global/list/sex_moan_light = list(
'mods/content/sexcon/sounds/voices/female/sex/sexlight (1).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (2).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (3).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (4).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (5).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (6).ogg',
'mods/content/sexcon/sounds/voices/female/sex/sexlight (7).ogg'
)
60 changes: 60 additions & 0 deletions mods/content/sexcon/_sexcon.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef MODPACK_SEXCON
#define MODPACK_SEXCON
// BEGIN_INCLUDE
#include "_sexcon.dm"
#include "datum\genitals.dm"
#include "datum\sex_action.dm"
#include "datum\sexcon.dm"
#include "datum\sexcon_helpers.dm"
#include "datum\sex_actions\deviant\facesitting.dm"
#include "datum\sex_actions\deviant\footjob.dm"
#include "datum\sex_actions\deviant\force_thighjob.dm"
#include "datum\sex_actions\deviant\frotting.dm"
#include "datum\sex_actions\deviant\rub_body.dm"
#include "datum\sex_actions\deviant\scissoring.dm"
#include "datum\sex_actions\deviant\thighjob.dm"
#include "datum\sex_actions\deviant\titjob.dm"
#include "datum\sex_actions\deviant\tonguebath.dm"
#include "datum\sex_actions\force\force_blowjob.dm"
#include "datum\sex_actions\force\force_crotch_nuzzle.dm"
#include "datum\sex_actions\force\force_cunnilingus.dm"
#include "datum\sex_actions\force\force_foot_lick.dm"
#include "datum\sex_actions\force\force_footjob.dm"
#include "datum\sex_actions\force\force_nuzzle_armpit.dm"
#include "datum\sex_actions\force\force_rimming.dm"
#include "datum\sex_actions\force\force_suck_nipples.dm"
#include "datum\sex_actions\masturbate\masturbate_anus.dm"
#include "datum\sex_actions\masturbate\masturbate_breasts.dm"
#include "datum\sex_actions\masturbate\masturbate_other_anus.dm"
#include "datum\sex_actions\masturbate\masturbate_other_breasts.dm"
#include "datum\sex_actions\masturbate\masturbate_other_penis.dm"
#include "datum\sex_actions\masturbate\masturbate_other_vagina.dm"
#include "datum\sex_actions\masturbate\masturbate_other_vagina_finger.dm"
#include "datum\sex_actions\masturbate\masturbate_penis.dm"
#include "datum\sex_actions\masturbate\masturbate_penis_over.dm"
#include "datum\sex_actions\masturbate\masturbate_vagina.dm"
#include "datum\sex_actions\masturbate\masturbate_vagina_finger.dm"
#include "datum\sex_actions\oral\blowjob.dm"
#include "datum\sex_actions\oral\crotch_nuzzle.dm"
#include "datum\sex_actions\oral\cunnilingus.dm"
#include "datum\sex_actions\oral\foot_lick.dm"
#include "datum\sex_actions\oral\kissing.dm"
#include "datum\sex_actions\oral\nuzzle_armpit.dm"
#include "datum\sex_actions\oral\rimming.dm"
#include "datum\sex_actions\oral\suck_balls.dm"
#include "datum\sex_actions\oral\suck_nipples.dm"
#include "datum\sex_actions\sex\anal_ride_sex.dm"
#include "datum\sex_actions\sex\anal_sex.dm"
#include "datum\sex_actions\sex\throat_sex.dm"
#include "datum\sex_actions\sex\vaginal_ride_sex.dm"
#include "datum\sex_actions\sex\vaginal_sex.dm"
#include "datum\sex_actions\toy\toy_anal.dm"
#include "datum\sex_actions\toy\toy_helpers.dm"
#include "datum\sex_actions\toy\toy_oral.dm"
#include "datum\sex_actions\toy\toy_other_anal.dm"
#include "datum\sex_actions\toy\toy_other_oral.dm"
#include "datum\sex_actions\toy\toy_other_vaginal.dm"
#include "datum\sex_actions\toy\toy_vaginal.dm"
#include "items\dildo.dm"
// END_INCLUDE
#endif
148 changes: 148 additions & 0 deletions mods/content/sexcon/datum/genitals.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/obj/item/organ/external/groin/penis
name = "penis"
organ_tag = BP_PENIS
max_damage = 50
min_broken_damage = 35
w_class = ITEM_SIZE_SMALL
body_part = SLOT_PENIS
parent_organ = BP_GROIN
joint = "base"
amputation_point = "base"
artery_name = "vein"
arterial_bleed_severity = 0.3
limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_CAN_BREAK | ORGAN_FLAG_CAN_DISLOCATE

var/sheath_type = SHEATH_TYPE_NONE
var/erect_state = ERECT_STATE_NONE
var/penis_type = PENIS_TYPE_PLAIN
var/penis_size = DEFAULT_PENIS_SIZE
var/functional = TRUE

/obj/item/organ/external/groin/penis/proc/update_erect_state()
var/oldstate = erect_state
var/new_state = ERECT_STATE_NONE
if(owner)
if(!owner?.sexcon.can_use_penis())
new_state = ERECT_STATE_NONE
else if(owner.sexcon.arousal > 20)
new_state = ERECT_STATE_HARD
else if(owner.sexcon.arousal > 10)
new_state = ERECT_STATE_PARTIAL
else
new_state = ERECT_STATE_NONE

erect_state = new_state
if(oldstate != erect_state && owner)
owner.update_body(TRUE)

// For Garou
/obj/item/organ/external/groin/penis/knotted
name = "knotted penis"
penis_type = PENIS_TYPE_KNOTTED
sheath_type = SHEATH_TYPE_NORMAL

/obj/item/organ/external/groin/penis/knotted/big
penis_size = 3

/obj/item/organ/external/groin/vagina
name = "vagina"
organ_tag = BP_VAGINA
max_damage = 50
min_broken_damage = 35
w_class = ITEM_SIZE_SMALL
body_part = SLOT_VAGINA
parent_organ = BP_GROIN
joint = "hip"
artery_name = "vaginal artery"
arterial_bleed_severity = 0.3
limb_flags = ORGAN_FLAG_CAN_BREAK

var/pregnant = FALSE
var/fertility = TRUE

/obj/item/organ/external/groin/vagina/proc/be_impregnated()
if(pregnant)
return
if(!owner)
return
if(owner.stat == DEAD)
return
to_chat(owner, SPAN_PINK("I feel a surge of warmth in my belly, I'm definitely pregnant!"))
pregnant = TRUE

/obj/item/organ/external/chest/breasts
name = "breasts"
organ_tag = BP_BREASTS
max_damage = 50
min_broken_damage = 35
w_class = ITEM_SIZE_SMALL
body_part = SLOT_BREASTS
parent_organ = BP_CHEST
joint = "base"
amputation_point = "base"
artery_name = "internal thoracic artery"
limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_CAN_BREAK

var/breast_size = DEFAULT_BREASTS_SIZE
var/lactating = FALSE
/// Container for milk and MILK ONLY. Do not transfer other chems here.
var/datum/reagents/mammary_gland
var/milk_max = 75

/obj/item/organ/external/chest/breasts/Destroy()
. = ..()
QDEL_NULL(mammary_gland)

/decl/material/liquid/drink/milk/breast_milk
name = "breast milk"
uid = "chem_drink_breastmilk"

// Below is largely borrowed from human_blood.dm
/// Initializes the mammary gland.
/obj/item/organ/external/chest/breasts/proc/make_milk()
if(mammary_gland)
return

milk_max = clamp(breast_size * 100, 75, 500)
mammary_gland = new(milk_max, src)

if(!owner.should_have_organ(BP_BREASTS)) //We want the var for safety but we can do without the actual milk.
return

reset_milk()

/// Modifies milk content
/obj/item/organ/external/chest/breasts/proc/adjust_milk(amt, milk_data)
if(!mammary_gland)
make_milk()

if(!owner.should_have_organ(BP_BREASTS))
return

if(amt)
if(amt > 0)
mammary_gland.add_reagent(BREAST_MILK, amt, milk_data)
else
mammary_gland.remove_any(abs(amt))

//Resets breast milk data
/obj/item/organ/external/chest/breasts/proc/reset_milk()
if(!mammary_gland)
make_milk()

if(!owner.should_have_organ(BP_BREASTS))
mammary_gland.clear_reagents()
mammary_gland.maximum_volume = 0
return

if(mammary_gland.total_volume < milk_max)
mammary_gland.maximum_volume = milk_max
adjust_milk(milk_max - mammary_gland.total_volume)
else if(mammary_gland.total_volume > milk_max)
mammary_gland.remove_any(mammary_gland.total_volume - milk_max)
mammary_gland.maximum_volume = milk_max

LAZYSET(mammary_gland.reagent_data, BREAST_MILK, list(
DATA_MILK_DONOR = weakref(owner),
DATA_MILK_NAME = "breast milk",
))
Loading
Loading