diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm
index 06d39087..34c6dc44 100644
--- a/_maps/_basemap.dm
+++ b/_maps/_basemap.dm
@@ -1,4 +1,4 @@
-//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it.
+#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it.
#include "map_files\generic\CentCom.dmm"
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index ce17243b..5f6d0248 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -192,6 +192,7 @@
"inflatable_belly" = FALSE,
"belly_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_balls" = FALSE,
+ "has_anus" = FALSE,
"balls_internal" = FALSE,
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"balls_amount" = 2,
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ab40a77c..9bc42104 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -142,6 +142,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"hide_belly" = FALSE,
"inflatable_belly" = FALSE,
"belly_color" = "fff",
+ "has_anus" = FALSE,
"has_balls" = FALSE,
"balls_internal" = FALSE,
"balls_color" = "fff",
@@ -920,6 +921,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Inflation (Climax With):[features["inflatable_belly"] == 1 ? "Yes" : "No"]"
dat += ""
+
+ dat += APPEARANCE_CATEGORY_COLUMN
+ dat += "
Anus
"
+ dat += "[features["has_anus"] == TRUE ? "Yes" : "No"]"
+ dat += ""
+
dat += ""
dat += ""
@@ -2502,6 +2509,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(features["has_vag"] == FALSE)
features["has_womb"] = FALSE
features["can_get_preg"] = FALSE
+ if("has_anus")
+ features["has_anus"] = !features["has_anus"]
if("has_womb")
features["has_womb"] = !features["has_womb"]
if("can_get_preg")
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index ebd93b81..32c0f9e3 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 23
+#define SAVEFILE_VERSION_MAX 24
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -423,11 +423,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//womb features
S["feature_has_womb"] >> features["has_womb"]
S["feature_can_get_preg"] >> features["can_get_preg"] //hyperstation 13
- //balls features
+ //belly features
S["feature_has_belly"] >> features["has_belly"]
S["feature_belly_color"] >> features["belly_color"]
S["feature_hide_belly"] >> features["hide_belly"]
S["feature_inflatable_belly"] >> features["inflatable_belly"]
+ //anus features
+ S["feature_has_anus"] >> features["has_anus"]
//flavor text
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:
diff --git a/hyperstation/code/modules/arousal/arousalhud.dm b/hyperstation/code/modules/arousal/arousalhud.dm
index 92850f06..8f5b61f5 100644
--- a/hyperstation/code/modules/arousal/arousalhud.dm
+++ b/hyperstation/code/modules/arousal/arousalhud.dm
@@ -9,8 +9,9 @@
var/mob/living/carbon/U = user
for(var/obj/item/organ/genital/G in U.internal_organs)
- if(!G.dontlist)
- dat += "[G.mode == "hidden" ? "[G.name] (Hidden)" : (G.mode == "clothes" ? "[G.name] (Hidden by Clothes)" : (G.mode == "visable" ? "[G.name] (Visable)" : "[G.name] (Visable)"))]
"
+ if(!G.nochange)
+ if(!G.dontlist)
+ dat += "[G.mode == "hidden" ? "[G.name] (Hidden)" : (G.mode == "clothes" ? "[G.name] (Hidden by Clothes)" : (G.mode == "visable" ? "[G.name] (Visable)" : "[G.name] (Visable)"))]
"
dat += {"
Contexual Options
"}
var/obj/item/organ/genital/penis/P = user.getorganslot("penis")
diff --git a/hyperstation/code/obj/fleshlight.dm b/hyperstation/code/obj/fleshlight.dm
index 19aff71e..0befcc44 100644
--- a/hyperstation/code/obj/fleshlight.dm
+++ b/hyperstation/code/obj/fleshlight.dm
@@ -100,7 +100,7 @@
/obj/item/portallight/examine(mob/user)
. = ..()
if(!portalunderwear)
- . += "The device is unpaired, to pair, swipe against a pair of portal panties(TM). "
+ . += "The device is unpaired, to pair, swipe against a pair of portal panties. "
else
. += "The device is paired, and awaiting input. "
@@ -117,12 +117,12 @@
else
option = "Fuck"
- var/obj/item/organ/genital/vagina/V
- if(istype(portalunderwear.loc, /obj/item/organ/genital/vagina)) //Sanity check. Without this it will runtime.
- V = portalunderwear.loc
- if(!V)
+ var/obj/item/organ/genital/G
+ if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime error.
+ G = portalunderwear.loc
+ if(!G)
return
- var/mob/living/carbon/human/M = V.owner
+ var/mob/living/carbon/human/M = G.owner
if(option == "Fuck"&&!P.is_exposed()) //we are trying to fuck with no penis!
to_chat(user, "You don't see anywhere to use this on.")
@@ -156,7 +156,7 @@
M.emote("moan")
if(option == "Fuck")// normal fuck
- to_chat(M, "You feel a [P.shape] shaped penis pumping through the portal into your vagina.")//message your partner and kinky!
+ to_chat(M, "You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [G.name].")//message your partner, and kinky!
if(prob(30)) //30% chance to make them moan.
C.emote("moan")
if(prob(30)) //30% chance to make your partner moan.
@@ -166,10 +166,10 @@
M.do_jitter_animation() //make your partner shake too!
if (M.getArousalLoss() >= 100 && ishuman(M) && prob(5))//Why not have a probability to cum when someone's getting nailed with max arousal?~
- if(V.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
- M.mob_climax_outside(V, spillage = TRUE)
+ if(G.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
+ M.mob_climax_outside(G, spillage = TRUE)
else
- M.mob_climax_outside(V, spillage = FALSE)
+ M.mob_climax_outside(G, spillage = FALSE)
if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
var/mob/living/carbon/human/O = C
@@ -180,10 +180,10 @@
O.mob_climax_partner(P, M, FALSE, TRUE, FALSE, TRUE) //climax with their partner remotely, and impreg because people keep asking!
if(option == "Lick")
- to_chat(M, "You feel a tongue lick you through the portal against your vagina.")
+ to_chat(M, "You feel a tongue lick you through the portal against your [G.name].")
M.adjustArousalLoss(10)
if(option == "Touch")
- to_chat(M, "You feel someone touching your vagina through the portal.")
+ to_chat(M, "You feel someone touching your [G.name] through the portal.")
M.adjustArousalLoss(5)
return
@@ -193,13 +193,14 @@
//get their looks and vagina colour!
cut_overlays()//remove current overlays
- var/obj/item/organ/genital/vagina/V
- if(istype(portalunderwear.loc, /obj/item/organ/genital/vagina)) //Sanity check. Without this it will runtime.
- V = portalunderwear.loc
- if(!V)
+ var/obj/item/organ/genital/G
+ if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime.
+ G = portalunderwear.loc
+ if(!G)
useable = FALSE
return
- var/mob/living/carbon/human/H = V.owner
+
+ var/mob/living/carbon/human/H = G.owner
if(H) //if the portal panties are on someone.
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_normal")
@@ -215,8 +216,12 @@
sleeve.color = "#" + H.dna.features["mcolor"]
add_overlay(sleeve)
- organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
- organ.color = portalunderwear.loc.color
+ if(G.name == "vagina")
+ organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
+ organ.color = portalunderwear.loc.color
+ if(G.name == "anus")
+ organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus")
+ organ.color = "#" + H.dna.features["mcolor"]
useable = TRUE
add_overlay(organ)
@@ -224,7 +229,7 @@
useable = FALSE
//Hyperstation 13 portal underwear
-//can be attached to vagina, just like the vibrator, still requires pairing with the portallight
+//can be attached to vagina or anus, just like the vibrator, still requires pairing with the portallight
/obj/item/portalpanties
name = "portal panties"
@@ -235,6 +240,7 @@
w_class = WEIGHT_CLASS_SMALL
var/obj/item/portallight
var/attached = FALSE
+ var/shapetype = "vagina"
/obj/item/portalpanties/examine(mob/user)
. = ..()
@@ -267,33 +273,34 @@
var/obj/item/organ/genital/picked_organ
var/mob/living/carbon/human/S = user
var/mob/living/carbon/human/T = C
- picked_organ = S.target_genitals(T) //allowing to pick organ for anus down the line
+ picked_organ = S.target_genitals(T)
if(picked_organ)
C.visible_message("[user] is trying to attach [src] to [T]!",\
"[user] is trying to put [src] on you!")
- if(!do_mob(user, C, 5 SECONDS))//warn them and have a delay of 5 seconds to apply.
+ if(!do_mob(user, C, 3 SECONDS))//warn them and have a delay of 5 seconds to apply.
return
- if(!(picked_organ.name == "vagina")) //only fits on a vagina
- to_chat(user, "[src] can only be attached to a vagina.")
- return
+ if((picked_organ.name == "vagina")||(picked_organ.name == "anus")) //only fits on a vagina or anus
- if(!picked_organ.equipment)
- to_chat(user, "You wrap [src] around [T]'s [picked_organ.name].")
+ src.shapetype = picked_organ.name
+ if(!picked_organ.equipment)
+ to_chat(user, "You wrap [src] around [T]'s [picked_organ.name].")
+ else
+ to_chat(user, "They already have [picked_organ.equipment.name] there.")
+ return
+
+ if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
+ return
+ src.attached = TRUE
+ picked_organ.equipment = src
+
+ var/obj/item/portallight/P = portallight
+ //now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
+ if(P) //just to make sure
+ P.updatesleeve()
else
- to_chat(user, "They already have a [picked_organ.equipment.name] there.")
+ to_chat(user, "[src] can only be attached to a vagina or anus.")
return
-
- if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
- return
- src.attached = TRUE
- picked_organ.equipment = src
-
- var/obj/item/portallight/P = portallight
- //now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
- if(P) //just to make sure
- P.updatesleeve()
-
else
to_chat(user, "You don't see anywhere to attach this.")
diff --git a/hyperstation/code/obj/vibrator.dm b/hyperstation/code/obj/vibrator.dm
index b6655af9..51f49594 100644
--- a/hyperstation/code/obj/vibrator.dm
+++ b/hyperstation/code/obj/vibrator.dm
@@ -115,12 +115,10 @@ Code:
if(G)
switch(G.name) //just being fancy
- if("penis")
- to_chat(U, "[src] vibrates against your [G.name]!")
if("breasts")
to_chat(U, "[src] vibrates against your nipples!")
- if("vagina")
- to_chat(U, "[src] vibrates inside you!")
+ else
+ to_chat(U, "[src] vibrates against your [G.name]!")
var/intencity = 6*mode
U.adjustArousalLoss(intencity) //give pleasure
diff --git a/hyperstation/icons/obj/fleshlight.dmi b/hyperstation/icons/obj/fleshlight.dmi
index e40a8dd6..fe41d26e 100644
Binary files a/hyperstation/icons/obj/fleshlight.dmi and b/hyperstation/icons/obj/fleshlight.dmi differ
diff --git a/hyperstation/icons/obj/genitals/butt.dmi b/hyperstation/icons/obj/genitals/butt.dmi
new file mode 100644
index 00000000..cf74d737
Binary files /dev/null and b/hyperstation/icons/obj/genitals/butt.dmi differ
diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm
index beb5f8b9..4a9ff931 100644
--- a/modular_citadel/code/modules/arousal/arousal.dm
+++ b/modular_citadel/code/modules/arousal/arousal.dm
@@ -321,7 +321,7 @@
src.visible_message("[src] orgasms with [p_their()] [G.name]!", \
"You climax with your [G.name].", \
"You climax using your [G.name].")
-
+
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
@@ -522,10 +522,9 @@
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in T.internal_organs)
- if(G.can_climax) //filter out what you can't masturbate with
- if(G.is_exposed(worn_stuff)) //Nude or through_clothing
- if(!G.dontlist)
- genitals_list += G
+ if(G.is_exposed(worn_stuff)) //Nude or through_clothing
+ if(!G.dontlist)
+ genitals_list += G
if(genitals_list.len)
ret_organ = input(src, "", "Genitals", null) as null|obj in genitals_list
return ret_organ
diff --git a/modular_citadel/code/modules/arousal/organs/anus.dm b/modular_citadel/code/modules/arousal/organs/anus.dm
new file mode 100644
index 00000000..2652d361
--- /dev/null
+++ b/modular_citadel/code/modules/arousal/organs/anus.dm
@@ -0,0 +1,25 @@
+/obj/item/organ/genital/anus
+ name = "anus"
+ desc = ""
+ zone = "groin"
+ slot = "anus"
+ w_class = 3
+ size = 0
+ var/statuscheck = FALSE
+ masturbation_verb = "massage"
+ can_climax = FALSE //no poo poo 4 u
+ nochange = TRUE
+
+
+/obj/item/organ/genital/anus/Initialize()
+ . = ..()
+
+/obj/item/organ/genital/anus/on_life()
+ if(QDELETED(src))
+ return
+ if(!owner)
+ return
+
+
+
+
diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm
index 83bb73e8..9cba98e8 100644
--- a/modular_citadel/code/modules/arousal/organs/genitals.dm
+++ b/modular_citadel/code/modules/arousal/organs/genitals.dm
@@ -25,6 +25,7 @@
var/mode = "clothes"
var/obj/item/equipment //for fun stuff that goes on the gentials/maybe rings down the line
var/dontlist = FALSE
+ var/nochange = FALSE //stops people changing visablity.
/obj/item/organ/genital/Initialize()
. = ..()
@@ -67,6 +68,8 @@
return owner.is_chest_exposed()
if("groin")
return owner.is_groin_exposed()
+ if("anus")
+ return owner.is_groin_exposed()
return FALSE
@@ -150,6 +153,8 @@
if (NOGENITALS in dna.species.species_traits)
return
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
+ if(dna.features["has_anus"])
+ give_anus()
if(dna.features["has_vag"])
give_vagina()
if(dna.features["has_womb"])
@@ -239,6 +244,18 @@
if(dna.features["inflatable_belly"]) //autohide bellies if they have the option ticked.
B.inflatable = TRUE
+/mob/living/carbon/human/proc/give_anus()
+ if(!dna)
+ return FALSE
+ if(NOGENITALS in dna.species.species_traits)
+ return FALSE
+ if(!getorganslot("anus"))
+ var/obj/item/organ/genital/anus/A = new
+ A.Insert(src)
+ if(A)
+ A.color = "#[skintone2hex(skin_tone)]"
+ A.update()
+
/mob/living/carbon/human/proc/give_breasts()
diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm
index 7b09b997..e2a7383d 100644
--- a/modular_citadel/code/modules/client/preferences_savefile.dm
+++ b/modular_citadel/code/modules/client/preferences_savefile.dm
@@ -96,6 +96,8 @@
WRITE_FILE(S["feature_belly_color"], features["belly_color"])
WRITE_FILE(S["feature_hide_belly"], features["hide_belly"])
WRITE_FILE(S["feature_inflatable_belly"], features["inflatable_belly"])
+ //anus
+ WRITE_FILE(S["feature_has_anus"], features["has_anus"])
//gear loadout
if(islist(chosen_gear))
diff --git a/tgstation.dme b/tgstation.dme
index 0bca9ad0..cb439391 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3240,6 +3240,7 @@
#include "modular_citadel\code\modules\admin\holder2.dm"
#include "modular_citadel\code\modules\admin\secrets.dm"
#include "modular_citadel\code\modules\arousal\arousal.dm"
+#include "modular_citadel\code\modules\arousal\organs\anus.dm"
#include "modular_citadel\code\modules\arousal\organs\belly.dm"
#include "modular_citadel\code\modules\arousal\organs\breasts.dm"
#include "modular_citadel\code\modules\arousal\organs\eggsack.dm"