diff --git a/code/citadel/cit_arousal.dm b/code/citadel/cit_arousal.dm
index 12245c05d5..cf47dab1da 100644
--- a/code/citadel/cit_arousal.dm
+++ b/code/citadel/cit_arousal.dm
@@ -6,7 +6,7 @@
var/arousal_rate = 1 //The base rate that arousal will increase in this mob.
var/arousal_loss_rate = 1 //How easily arousal can be relieved for this mob.
var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types.
- var/mb_cd_length = 50 //5 second cooldown for masturbating because fuck spam
+ var/mb_cd_length = 100 //5 second cooldown for masturbating because fuck spam.
var/mb_cd_timer = 0 //The timer itself
/mob/living/carbon/human
@@ -150,14 +150,14 @@
return 0
var/mob/living/M = usr
if(M.canbearoused)
- M.mob_masturbate()
+ M.mob_climax()
return 1
else
- M << "Arousal is disabled. Feature is unavailable."
+ to_chat(M, "Arousal is disabled. Feature is unavailable.")
-/mob/living/proc/mob_masturbate()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
+/mob/living/proc/mob_climax()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
set name = "Masturbate"
set category = "IC"
if(canbearoused && !restrained() && !stat)
@@ -179,45 +179,93 @@
PoolOrNew(/obj/effect/decal/cleanable/femcum, loc)
*/
else
- src << "You aren't aroused enough for that."
+ to_chat(src, "You aren't aroused enough for that.")
-/mob/living/carbon/human/mob_masturbate()
+/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
if(mb_cd_timer > world.time)
- src << "You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!"
+ if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
+ to_chat(src, "You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!")
return
+ mb_cd_timer = (world.time + mb_cd_length)
var/list/genitals_list = list()
var/obj/item/organ/genital/SG = null//originally selected_genital
var/list/containers_list = list()
var/obj/item/weapon/reagent_containers/SC = null
var/datum/reagents/fluid_source = null
var/into_container = 0
- var/arms = get_num_arms()
- var/free_hands = arms
+ var/free_hands = get_num_arms() //arms was only used to know if we had ANY at all
var/total_cum = 0
var/finished = 0
var/mb_time = 30
- mb_cd_timer = (world.time + mb_cd_length)
if(canbearoused && has_dna())
- if(restrained())
- src << "You can't do that while restrained!"
+ if(stat==2)
+ to_chat(src, "You can't do that while dead!")
return
- if(stat)
- src << "You must be conscious to do that!"
+ if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
+ for(var/obj/item/organ/genital/G in internal_organs)
+ if(G.can_masturbate_with) //All capable genitals will orgasm with this
+ var/unable_to_come = FALSE
+ switch(G.type)
+ if(/obj/item/organ/genital/penis)
+ var/obj/item/organ/genital/penis/P = G
+ if(!P.linked_balls)
+ unable_to_come = TRUE
+ else
+ fluid_source = P.linked_balls.reagents
+
+
+ if(/obj/item/organ/genital/vagina)
+ var/obj/item/organ/genital/vagina/V = G
+ if(!V.linked_womb)
+ unable_to_come = TRUE
+ else
+ fluid_source = V.linked_womb.reagents
+ else //Weird, undefined genitalia behaviour
+ unable_to_come = TRUE
+
+ if(unable_to_come)
+ src.visible_message("[src] shudders, their [G.name] unable to cum.", \
+ "Your [G.name] cannot cum, giving no relief.", \
+ "Your [G.name] cannot cum, giving no relief.")
+ else
+ if(fluid_source)
+ total_cum = fluid_source.total_volume
+ src.visible_message("[src] looks like they're about to cum.", \
+ "You feel yourself about to orgasm.", \
+ "You feel yourself about to orgasm.")
+ if(do_after(src, mb_time, target = src))
+ if(total_cum > 5)
+ fluid_source.reaction(src.loc, TOUCH, 1, 0)
+ fluid_source.clear_reagents()
+ fluid_source = null //cleanup so this can be used for the next genitalia
+
+ src.visible_message("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \
+ "You're forced to cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""] with your [G].", \
+ "Your [G] have been forced to climax.")
+ finished = 1
+ if(finished)
+ setArousalLoss(min_arousal)
+ return //Do not proceed to masturbating if all genitals have been forced to orgasm.
+ if(stat==1) //Sleeping people can be forced chemically or with electrical stimulants, for example.
+ to_chat(src, "You must be conscious to do that!")
+ return
+ if(restrained())
+ to_chat(src, "You can't do that while restrained!")
return
if(getArousalLoss() < 33)//flat number instead of percentage
- src << "You aren't aroused enough for that!"
+ to_chat(src, "You aren't aroused enough for that!")
return
if(!is_groin_exposed())
- src << "You need to undress, first!"
+ to_chat(src, "You need to undress, first!")
return
- if(!arms)
- src << "You need at least one arm."
+ if(!free_hands)
+ to_chat(src, "You need at least one free arm.")
return
for(var/helditem in held_items)//how many hands are free
if(isobj(helditem))
free_hands--
if(free_hands <= 0)
- src << "You need at least one free hand."
+ to_chat(src, "You need at least one free hand.")
return
for(var/obj/item/organ/genital/G in internal_organs)
if(G.can_masturbate_with)//filter out what you can't masturbate with
@@ -240,12 +288,12 @@
if(/obj/item/organ/genital/penis)
var/obj/item/organ/genital/penis/P = SG
if(!P.linked_balls)
- src << "Grow a pair!"
+ to_chat(src, "You need a pair of testicles to do this.")
return
fluid_source = P.linked_balls.reagents
total_cum = fluid_source.total_volume
if(into_container)//into a glass or beaker or whatever
- src.visible_message("[src] starts [pick("jerking off","stroking")] their [SG] over [SC].", \
+ src.visible_message("[src] starts [pick("jerking off","stroking")] their [SG.name] over [SC].", \
"You start jerking off over [SC.name].", \
"You start masturbating.")
if(do_after(src, mb_time, target = src) && in_range(src, SC))
@@ -254,16 +302,71 @@
"You cum into [SC].", \
"You have relieved yourself.")
finished = 1
-
+ else //Not in a container
+ if(src.pulling)
+ if(iscarbon(src.pulling))
+ var/mob/living/carbon/C = src.pulling
+ if(!C.is_groin_exposed())
+ to_chat(src, "You must undress someone to climax inside them.")
+ return
+ if(isliving(src.pulling)) //Gotta be alive to fuck it, don't wanna have to code fucking objects that ain't containers...
+ var/mob/living/partner = src.pulling
+ src.visible_message("[src] is about to climax inside [partner]!", \
+ "You're about to climax inside [partner]!", \
+ "You're preparing to climax inside someone!")
+ switch(grab_state)
+ if(GRAB_PASSIVE)
+ if(do_after(src, mb_time, target = src) && in_range(src, partner))
+ var/spillage = 0.5 //Leaks a bit on passive grab
+ var/did_spill = FALSE
+ fluid_source.trans_to(partner, total_cum*(1-spillage))
+ total_cum = total_cum*spillage
+ if(total_cum > 5)
+ fluid_source.reaction(partner.loc, TOUCH, 1, 0)
+ did_spill = TRUE
+ fluid_source.clear_reagents()
+
+ src.visible_message("[src] ejaculates inside [partner][did_spill ? ", overflowing and spilling":""]!", \
+ "You ejaculate inside [partner][did_spill ? ", spilling out of them":""].", \
+ "You have climaxed inside someone[did_spill ? ", spilling out of them":""].")
+ finished = 1
+ else //Aggressive or higher
+ if(do_after(src, mb_time, target = src) && in_range(src, partner))
+ var/spillage = 0.0 //Leakproofing seals
+ fluid_source.trans_to(partner, total_cum*(1-spillage))
+ total_cum = total_cum*spillage
+ if(total_cum > 5)
+ fluid_source.reaction(partner.loc, TOUCH, 1, 0)
+ fluid_source.clear_reagents()
+
+ src.visible_message("[src] ejaculates inside [partner], spilling nothing!", \
+ "You ejaculate inside [partner], spilling nothing.", \
+ "You have climaxed inside someone, spilling nothing.")
+ finished = 1
+ //Don't care, not coding you fucking a unanchored girder
+ else //No pulling, or pulling non-living things
+ src.visible_message("[src] starts [pick("jerking off","stroking")] their [SG].", \
+ "You start masturbating.", \
+ "You start masturbating.")
+ if(do_after(src, mb_time, target = src))
+ if(total_cum > 5)
+ fluid_source.reaction(src.loc, TOUCH, 1, 0)
+ fluid_source.clear_reagents()
+
+ src.visible_message("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \
+ "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].", \
+ "You have relieved yourself.")
+ finished = 1
+
if(/obj/item/organ/genital/vagina)
var/obj/item/organ/genital/vagina/V = SG
if(!V.linked_womb)
- src << "No womb!"
+ to_chat(src, "You need a womb to do this.")
return
fluid_source = V.linked_womb.reagents
total_cum = fluid_source.total_volume
if(into_container)//into a glass or beaker or whatever
- src.visible_message("[src] starts fingering their vagina over [SC].", \
+ src.visible_message("[src] starts fingering their [SG.name] over [SC].", \
"You start fingering over [SC.name].", \
"You start masturbating.")
if(do_after(src, mb_time, target = src) && in_range(src, SC))
@@ -272,7 +375,7 @@
"You cum into [SC].", \
"You have relieved yourself.")
finished = 1
-
+
else//not into a container
src.visible_message("[src] starts fingering their vagina.", \
"You start fingering your vagina.", \
@@ -297,10 +400,5 @@
setArousalLoss(min_arousal)
else
- src << "You have no genitals!"
+ to_chat(src, "You have no genitals!")
return
-
-/mob/living/carbon/proc/force_orgasm(intensity)
- if(canbearoused && has_dna() && (has_penis() || has_vagina()))
- return 1
- return 0
diff --git a/code/citadel/cit_reagents.dm b/code/citadel/cit_reagents.dm
index 2f421542ae..428729d30f 100644
--- a/code/citadel/cit_reagents.dm
+++ b/code/citadel/cit_reagents.dm
@@ -105,7 +105,7 @@
M.emote(pick("moan","blush"))
if(prob(5))
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
- M << "[aroused_message]"
+ to_chat(M, "[aroused_message]")
..()
/datum/reagent/aphrodisiacplus
@@ -128,15 +128,13 @@
else
M.emote(pick("moan","blush"))
if(prob(5))
+ var/aroused_message
if(M.getArousalLoss() > 90)
- var/aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
- M << "[aroused_message]"
+ aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
else
- var/aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
- M << "[aroused_message]"
-// if(iscarbon(M) && has_dna(M))
-// M.force_ejaculation()
- ..()
+ aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
+ to_chat(M, "[aroused_message]")
+
/datum/reagent/aphrodisiacplus/addiction_act_stage2(mob/living/M)
if(prob(30))
M.adjustBrainLoss(2)
@@ -152,11 +150,17 @@
..()
/datum/reagent/aphrodisiacplus/overdose_process(mob/living/M)
- if(prob(66))
+ if(prob(33))
+ if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
+ var/mob/living/carbon/human/H = M
+ to_chat(H, "Your libido is going haywire!")
+ H.mob_climax(forced_climax=TRUE)
if(M.min_arousal < 50)
M.min_arousal += 1
- if(M.max_arousal < 200)
- M.max_arousal += 1
+ to_chat(M, "You're having a hard time thinkin about things other than sex!")
+ if(M.min_arousal < M.max_arousal)
+ M.min_arousal += 1
+ to_chat(M, "You feel your libido permanently increasing.")
M.adjustArousalLoss(2)
..()
@@ -193,8 +197,10 @@
if(prob(33))
if(M.min_arousal > 0)
M.min_arousal -= 1
- if(M.max_arousal > 75)
+ to_chat(M, "You feel your libido returning to more normal levels.")
+ if(M.min_arousal > 50)
M.min_arousal -= 1
+ to_chat(M, "You feel like your overactive libido is calming down.")
M.adjustArousalLoss(-2)
..()
diff --git a/code/citadel/organs/breasts.dm b/code/citadel/organs/breasts.dm
index 5e3f312199..ce45b88cfb 100644
--- a/code/citadel/organs/breasts.dm
+++ b/code/citadel/organs/breasts.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/breasts
- name = "breasts"
+ name = "Breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'code/citadel/icons/breasts.dmi'
diff --git a/code/citadel/organs/eggsack.dm b/code/citadel/organs/eggsack.dm
index 1e53240e1a..718a353b87 100644
--- a/code/citadel/organs/eggsack.dm
+++ b/code/citadel/organs/eggsack.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/eggsack
- name = "egg sack"
+ name = "Egg sack"
desc = "An egg producing reproductive organ."
icon_state = "egg_sack"
icon = 'code/citadel/icons/ovipositor.dmi'
diff --git a/code/citadel/organs/ovipositor.dm b/code/citadel/organs/ovipositor.dm
index 9e46cff91c..3d684ee387 100644
--- a/code/citadel/organs/ovipositor.dm
+++ b/code/citadel/organs/ovipositor.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/ovipositor
- name = "ovipositor"
+ name = "Ovipositor"
desc = "An egg laying reproductive organ."
icon_state = "ovi_knotted_2"
icon = 'code/citadel/icons/ovipositor.dmi'
diff --git a/code/citadel/organs/penis.dm b/code/citadel/organs/penis.dm
index 3d99d6c939..d687b3e76a 100644
--- a/code/citadel/organs/penis.dm
+++ b/code/citadel/organs/penis.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/penis
- name = "penis"
+ name = "Penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'code/citadel/icons/penis.dmi'
diff --git a/code/citadel/organs/testicles.dm b/code/citadel/organs/testicles.dm
index 71e591f930..a759aeab52 100644
--- a/code/citadel/organs/testicles.dm
+++ b/code/citadel/organs/testicles.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/testicles
- name = "testicles"
+ name = "Testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'code/citadel/icons/penis.dmi'
diff --git a/code/citadel/organs/vagina.dm b/code/citadel/organs/vagina.dm
index c1924a3067..fa1f00bda2 100644
--- a/code/citadel/organs/vagina.dm
+++ b/code/citadel/organs/vagina.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/vagina
- name = "vagina"
+ name = "Vagina"
desc = "A female reproductive organ."
icon = 'code/citadel/icons/vagina.dmi'
icon_state = "vagina"
diff --git a/code/citadel/organs/womb.dm b/code/citadel/organs/womb.dm
index e1ea02a230..3ebe5c2f98 100644
--- a/code/citadel/organs/womb.dm
+++ b/code/citadel/organs/womb.dm
@@ -1,5 +1,5 @@
/obj/item/organ/genital/womb
- name = "womb"
+ name = "Womb"
desc = "A female reproductive organ."
icon = 'code/citadel/icons/vagina.dmi'
icon_state = "womb"
@@ -10,7 +10,7 @@
fluid_id = "femcum"
producing = TRUE
var/obj/item/organ/genital/vagina/linked_vag
-
+
/obj/item/organ/genital/womb/Initialize()
. = ..()
reagents.add_reagent(fluid_id, fluid_max_volume)