Cleaning up Arousal code & co.
This commit is contained in:
@@ -122,3 +122,8 @@
|
||||
#define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun"
|
||||
#define ORGAN_SLOT_TAIL "tail"
|
||||
#define ORGAN_SLOT_PENIS "penis"
|
||||
#define ORGAN_SLOT_WOMB "womb"
|
||||
#define ORGAN_SLOT_VAGINA "vagina"
|
||||
#define ORGAN_SLOT_TESTICLES "testicles"
|
||||
#define ORGAN_SLOT_BREASTS "breasts"
|
||||
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
#define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, border=0, color="#04080F")
|
||||
|
||||
//organ defines
|
||||
#define VAGINA_LAYER_INDEX 1
|
||||
#define TESTICLES_LAYER_INDEX 2
|
||||
#define GENITAL_LAYER_INDEX 3
|
||||
#define PENIS_LAYER_INDEX 4
|
||||
|
||||
#define GENITAL_LAYER_INDEX_LENGTH 4 //keep it updated with each new index added, thanks.
|
||||
|
||||
#define MASTURBATE_LINKED_ORGAN 2 //special value used to pass our mission to the linked organ
|
||||
|
||||
#define COCK_SIZE_MIN 1
|
||||
#define COCK_SIZE_MAX 20
|
||||
|
||||
|
||||
@@ -136,13 +136,14 @@
|
||||
#define TRAIT_SKITTISH "skittish"
|
||||
#define TRAIT_POOR_AIM "poor_aim"
|
||||
#define TRAIT_PROSOPAGNOSIA "prosopagnosia"
|
||||
#define TRAIT_DRUNK_HEALING "drunk_healing"
|
||||
#define TRAIT_TAGGER "tagger"
|
||||
#define TRAIT_PHOTOGRAPHER "photographer"
|
||||
#define TRAIT_MUSICIAN "musician"
|
||||
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
|
||||
#define TRAIT_DRUNK_HEALING "drunk_healing"
|
||||
#define TRAIT_TAGGER "tagger"
|
||||
#define TRAIT_PHOTOGRAPHER "photographer"
|
||||
#define TRAIT_MUSICIAN "musician"
|
||||
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
|
||||
#define TRAIT_NYMPHO "nymphomania"
|
||||
#define TRAIT_MASO "masochism"
|
||||
#define TRAIT_EXHIBITIONIST "exhibitionist"
|
||||
#define TRAIT_PARA "paraplegic"
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
|
||||
@@ -56,6 +56,7 @@ GLOBAL_LIST_EMPTY(ipc_screens_list)
|
||||
GLOBAL_LIST_EMPTY(ipc_antennas_list)
|
||||
|
||||
//Genitals and Arousal Lists
|
||||
GLOBAL_LIST_EMPTY(genitals_list)
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
|
||||
GLOBAL_LIST_EMPTY(balls_shapes_list)
|
||||
@@ -124,41 +125,39 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/mob/living/carbon/proc/has_penis()
|
||||
if(getorganslot("penis"))//slot shared with ovipositor
|
||||
if(istype(getorganslot("penis"), /obj/item/organ/genital/penis))
|
||||
return TRUE
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(G && istype(G, /obj/item/organ/genital/penis))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/has_balls()
|
||||
if(getorganslot("balls"))
|
||||
if(istype(getorganslot("balls"), /obj/item/organ/genital/testicles))
|
||||
return TRUE
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(G && istype(G, /obj/item/organ/genital/testicles))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/has_vagina()
|
||||
if(getorganslot("vagina"))
|
||||
if(getorganslot(ORGAN_SLOT_VAGINA))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/has_breasts()
|
||||
if(getorganslot("breasts"))
|
||||
if(getorganslot(ORGAN_SLOT_BREASTS))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/has_ovipositor()
|
||||
if(getorganslot("penis"))//shared slot
|
||||
if(istype(getorganslot("penis"), /obj/item/organ/genital/ovipositor))
|
||||
return TRUE
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(G && istype(G, /obj/item/organ/genital/ovipositor))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/has_eggsack()
|
||||
if(getorganslot("balls"))
|
||||
if(istype(getorganslot("balls"), /obj/item/organ/genital/eggsack))
|
||||
return TRUE
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(G && istype(G, /obj/item/organ/genital/eggsack))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/is_bodypart_exposed(bodypart)
|
||||
|
||||
/mob/living/carbon/proc/is_groin_exposed(var/list/L)
|
||||
if(!L)
|
||||
L = get_equipped_items()
|
||||
@@ -188,9 +187,9 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
message_admins("[src] gave everyone genitals.")
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(H.gender == MALE)
|
||||
H.give_penis()
|
||||
H.give_balls()
|
||||
H.give_genital(/obj/item/organ/genital/penis)
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
else
|
||||
H.give_vagina()
|
||||
H.give_womb()
|
||||
H.give_breasts()
|
||||
H.give_genital(/obj/item/organ/genital/vagina)
|
||||
H.give_genital(/obj/item/organ/genital/womb)
|
||||
H.give_genital(/obj/item/organ/genital/breasts)
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
for(var/K in GLOB.balls_shapes_list)
|
||||
var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K]
|
||||
GLOB.balls_shapes_icons[K] = value.icon_state
|
||||
|
||||
for(var/gpath in subtypesof(/obj/item/organ/genital))
|
||||
var/obj/item/organ/genital/G = gpath
|
||||
GLOB.genitals_list[initial(G.name)] = gpath
|
||||
//END OF CIT CHANGES
|
||||
|
||||
//Species
|
||||
|
||||
@@ -154,7 +154,6 @@
|
||||
"xenodorsal" = "Standard",
|
||||
"xenohead" = "Standard",
|
||||
"xenotail" = "Xenomorph Tail",
|
||||
"exhibitionist" = FALSE,
|
||||
"genitals_use_skintone" = FALSE,
|
||||
"has_cock" = FALSE,
|
||||
"cock_shape" = pick(GLOB.cock_shapes_list),
|
||||
|
||||
@@ -94,6 +94,41 @@
|
||||
lose_text = "<span class='notice'>You don't feel as prudish as before.</span>"
|
||||
medical_record_text = "Patient exhibits a special gene that makes them immune to Crocin and Hexacrocin."
|
||||
|
||||
/datum/quirk/libido
|
||||
name = "Nymphomania"
|
||||
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
|
||||
value = 0
|
||||
mob_trait = TRAIT_NYMPHO
|
||||
gain_text = "<span class='notice'>You are feeling extra wild.</span>"
|
||||
lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>"
|
||||
|
||||
/datum/quirk/libido/add()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = 16
|
||||
M.arousal_rate = 3
|
||||
|
||||
/datum/quirk/libido/remove()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = initial(M.min_arousal)
|
||||
M.arousal_rate = initial(M.arousal_rate)
|
||||
|
||||
/datum/quirk/maso
|
||||
name = "Masochism"
|
||||
desc = "You are aroused by pain."
|
||||
value = 0
|
||||
mob_trait = TRAIT_MASO
|
||||
gain_text = "<span class='notice'>You desire to be hurt.</span>"
|
||||
lose_text = "<span class='notice'>Pain has become less exciting for you.</span>"
|
||||
|
||||
/datum/quirk/exhibitionism
|
||||
name = "Exhibitionism"
|
||||
desc = "You don't mind showing off your bare body to strangers, in fact you find it quite satistying. Not the best excuse to break Space Law anyway." //as if they'd care anyway.
|
||||
value = 0
|
||||
medical_record_text = "Patient has been diagnosed with exhibitionistic disorder."
|
||||
mob_trait = TRAIT_EXHIBITIONIST
|
||||
gain_text = "<span class='notice'>You feel like exposing yourself to the world.</span>"
|
||||
lose_text = "<span class='notice'>Indecent exposure doesn't sound as charming to you anymore.</span>"
|
||||
|
||||
/datum/quirk/assblastusa
|
||||
name = "Buns of Steel"
|
||||
desc = "You've never skipped ass day. With this trait, you are completely immune to all forms of ass slapping and anyone who tries to slap your rock hard ass usually gets a broken hand."
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
H.facial_hair_color = H.hair_color
|
||||
H.eye_color = random_eye_color()
|
||||
H.dna.blood_type = random_blood_type()
|
||||
H.saved_underwear = H.underwear
|
||||
H.saved_undershirt = H.undershirt
|
||||
H.saved_socks = H.socks
|
||||
|
||||
// Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant.
|
||||
H.dna.features["mcolor"] = random_short_color()
|
||||
|
||||
@@ -108,7 +108,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"xenohead" = "Standard",
|
||||
"xenotail" = "Xenomorph Tail",
|
||||
"taur" = "None",
|
||||
"exhibitionist" = FALSE,
|
||||
"genitals_use_skintone" = FALSE,
|
||||
"has_cock" = FALSE,
|
||||
"cock_shape" = "Human",
|
||||
@@ -790,7 +789,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat +="<td width='300px' height='300px' valign='top'>"
|
||||
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
|
||||
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
|
||||
dat += "<b>Exhibitionist:</b><a href='?_src_=prefs;preference=exhibitionist'>[features["exhibitionist"] == TRUE ? "Yes" : "No"]</a><BR>"
|
||||
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
|
||||
@@ -2048,8 +2046,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["has_womb"] = FALSE
|
||||
if("has_womb")
|
||||
features["has_womb"] = !features["has_womb"]
|
||||
if("exhibitionist")
|
||||
features["exhibitionist"] = !features["exhibitionist"]
|
||||
if("widescreenpref")
|
||||
widescreenpref = !widescreenpref
|
||||
user.client.change_view(CONFIG_GET(string/default_view))
|
||||
|
||||
@@ -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 20
|
||||
#define SAVEFILE_VERSION_MAX 21
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -49,6 +49,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
pda_style = "mono"
|
||||
if(current_version < 20)
|
||||
pda_color = "#808000"
|
||||
if(current_version < 21 && S["feature_exhibitionist"])
|
||||
var/datum/quirk/exhibitionism/E
|
||||
var/quirk_name = initial(E.name)
|
||||
neutral_quirks += quirk_name
|
||||
all_quirks += quirk_name
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Citadel-specific Neutral Traits
|
||||
|
||||
/datum/quirk/libido
|
||||
name = "Nymphomania"
|
||||
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
|
||||
value = 0
|
||||
mob_trait = TRAIT_NYMPHO
|
||||
gain_text = "<span class='notice'>You are feeling extra wild.</span>"
|
||||
lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>"
|
||||
|
||||
/datum/quirk/libido/add()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = 16
|
||||
M.arousal_rate = 3
|
||||
|
||||
/datum/quirk/libido/remove()
|
||||
var/mob/living/M = quirk_holder
|
||||
M.min_arousal = initial(M.min_arousal)
|
||||
M.arousal_rate = initial(M.arousal_rate)
|
||||
|
||||
/datum/quirk/libido/on_process()
|
||||
var/mob/living/M = quirk_holder
|
||||
if(M.canbearoused == FALSE)
|
||||
to_chat(quirk_holder, "<span class='notice'>Having high libido is useless when you can't feel arousal at all!</span>")
|
||||
qdel(src)
|
||||
|
||||
/datum/quirk/maso
|
||||
name = "Masochism"
|
||||
desc = "You are aroused by pain."
|
||||
value = 0
|
||||
mob_trait = TRAIT_MASO
|
||||
gain_text = "<span class='notice'>You desire to be hurt.</span>"
|
||||
lose_text = "<span class='notice'>Pain has become less exciting for you.</span>"
|
||||
@@ -19,11 +19,6 @@
|
||||
var/hidden_undershirt = FALSE
|
||||
var/hidden_socks = FALSE
|
||||
|
||||
/mob/living/carbon/human/New()
|
||||
..()
|
||||
saved_underwear = underwear
|
||||
saved_undershirt = undershirt
|
||||
|
||||
//Species vars
|
||||
/datum/species
|
||||
var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused
|
||||
@@ -35,60 +30,53 @@
|
||||
//Mob procs
|
||||
/mob/living/carbon/human/proc/underwear_toggle()
|
||||
set name = "Toggle undergarments"
|
||||
set category = "Object"
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/humz = src
|
||||
var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel")
|
||||
if(confirm == "Top")
|
||||
humz.hidden_undershirt = !humz.hidden_undershirt
|
||||
set category = "IC"
|
||||
|
||||
if(confirm == "Bottom")
|
||||
humz.hidden_underwear = !humz.hidden_underwear
|
||||
var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling") as null|anything in list("Top", "Bottom", "Socks", "All")
|
||||
if(!confirm)
|
||||
return
|
||||
if(confirm == "Top")
|
||||
hidden_undershirt = !hidden_undershirt
|
||||
|
||||
if(confirm == "Socks")
|
||||
humz.hidden_socks = !humz.hidden_socks
|
||||
if(confirm == "Bottom")
|
||||
hidden_underwear = !hidden_underwear
|
||||
|
||||
if(confirm == "All")
|
||||
humz.hidden_undershirt = !humz.hidden_undershirt
|
||||
humz.hidden_underwear = !humz.hidden_underwear
|
||||
humz.hidden_socks = !humz.hidden_socks
|
||||
if(confirm == "Socks")
|
||||
hidden_socks = !hidden_socks
|
||||
|
||||
if(confirm == "Cancel")
|
||||
return
|
||||
src.update_body()
|
||||
if(confirm == "All")
|
||||
var/on_off = (hidden_undershirt || hidden_underwear || hidden_socks) ? FALSE : TRUE
|
||||
hidden_undershirt = on_off
|
||||
hidden_underwear = on_off
|
||||
hidden_socks = on_off
|
||||
|
||||
else
|
||||
to_chat(src, "Humans only. How the fuck did you get this verb anyway.")
|
||||
update_body()
|
||||
|
||||
/mob/living/proc/handle_arousal()
|
||||
|
||||
|
||||
/mob/living/carbon/handle_arousal()
|
||||
if(canbearoused && dna)
|
||||
var/datum/species/S
|
||||
S = dna.species
|
||||
if(S && !(SSmobs.times_fired % 36) && getArousalLoss() < max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
|
||||
adjustArousalLoss(arousal_rate * S.arousal_gain_rate)
|
||||
if(dna.features["exhibitionist"] && client)
|
||||
var/amt_nude = 0
|
||||
if(is_chest_exposed() && (getorganslot("breasts")))
|
||||
amt_nude++
|
||||
if(is_groin_exposed())
|
||||
if(getorganslot("penis"))
|
||||
amt_nude++
|
||||
if(getorganslot("vagina"))
|
||||
amt_nude++
|
||||
if(amt_nude)
|
||||
var/watchers = 0
|
||||
for(var/mob/_M in view(world.view, src))
|
||||
var/mob/living/M = _M
|
||||
if(!istype(M))
|
||||
continue
|
||||
if(M.client && !M.stat && !M.eye_blind && (locate(src) in viewers(world.view,M)))
|
||||
watchers++
|
||||
if(watchers)
|
||||
adjustArousalLoss((amt_nude * watchers) + S.arousal_gain_rate)
|
||||
/mob/living/proc/handle_arousal(times_fired)
|
||||
return
|
||||
|
||||
/mob/living/carbon/handle_arousal(times_fired)
|
||||
if(!canbearoused || !dna)
|
||||
return
|
||||
var/datum/species/S = dna.species
|
||||
if(!S || (times_fired % 36) || !getArousalLoss() >= max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
|
||||
return
|
||||
var/our_loss = arousal_rate * S.arousal_gain_rate
|
||||
if(HAS_TRAIT(src, TRAIT_EXHIBITIONIST) && client)
|
||||
var/amt_nude = 0
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.is_exposed())
|
||||
amt_nude++
|
||||
if(amt_nude)
|
||||
var/watchers = 0
|
||||
for(var/mob/living/L in view(world.view, src))
|
||||
if(!istype(L))
|
||||
continue
|
||||
if(L.client && !L.stat && !L.eye_blind && (locate(src) in viewers(world.view, L)))
|
||||
watchers++
|
||||
if(watchers)
|
||||
our_loss += (amt_nude * watchers) + S.arousal_gain_rate
|
||||
adjustArousalLoss(our_loss)
|
||||
|
||||
/mob/living/proc/getArousalLoss()
|
||||
return arousalloss
|
||||
@@ -138,8 +126,6 @@
|
||||
S = GLOB.breasts_shapes_list[G.shape]
|
||||
if(S?.alt_aroused)
|
||||
G.aroused_state = isPercentAroused(G.aroused_amount)
|
||||
if(getArousalLoss() >= ((max_arousal / 100) * 33))
|
||||
G.aroused_state = TRUE
|
||||
else
|
||||
G.aroused_state = FALSE
|
||||
G.update_appearance()
|
||||
@@ -147,54 +133,18 @@
|
||||
/mob/living/proc/update_arousal_hud()
|
||||
return FALSE
|
||||
|
||||
/datum/species/proc/update_arousal_hud(mob/living/carbon/human/H)
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/update_arousal_hud()
|
||||
if(!client || !hud_used)
|
||||
return FALSE
|
||||
if(dna.species.update_arousal_hud())
|
||||
if(!client || !(hud_used?.arousal))
|
||||
return FALSE
|
||||
if(!canbearoused)
|
||||
hud_used.arousal.icon_state = ""
|
||||
return FALSE
|
||||
if(stat == DEAD)
|
||||
hud_used.arousal.icon_state = "arousal0"
|
||||
else
|
||||
if(hud_used.arousal)
|
||||
if(stat == DEAD)
|
||||
hud_used.arousal.icon_state = "arousal0"
|
||||
return TRUE
|
||||
if(getArousalLoss() == max_arousal)
|
||||
hud_used.arousal.icon_state = "arousal100"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 90)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal90"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 80)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal80"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 70)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal70"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 60)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal60"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 50)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal50"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 40)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal40"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 30)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal30"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 20)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal10"
|
||||
return TRUE
|
||||
if(getArousalLoss() >= (max_arousal / 100) * 10)//M O D U L A R , W O W
|
||||
hud_used.arousal.icon_state = "arousal10"
|
||||
return TRUE
|
||||
else
|
||||
hud_used.arousal.icon_state = "arousal0"
|
||||
var/value = FLOOR(getPercentAroused(), 10)
|
||||
hud_used.arousal.icon_state = "arousal[value]"
|
||||
return TRUE
|
||||
|
||||
/obj/screen/arousal
|
||||
name = "arousal"
|
||||
@@ -213,7 +163,6 @@
|
||||
to_chat(M, "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>")
|
||||
|
||||
|
||||
|
||||
/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"
|
||||
@@ -221,212 +170,150 @@
|
||||
if(mb_cd_timer <= world.time)
|
||||
//start the cooldown even if it fails
|
||||
mb_cd_timer = world.time + mb_cd_length
|
||||
if(getArousalLoss() >= ((max_arousal / 100) * 33))//33% arousal or greater required
|
||||
src.visible_message("<span class='danger'>[src] starts masturbating!</span>", \
|
||||
if(getArousalLoss() >= 33)//one third of average max_arousal or greater required
|
||||
visible_message("<span class='danger'>[src] starts masturbating!</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, 30, target = src))
|
||||
src.visible_message("<span class='danger'>[src] relieves [p_them()]self!</span>", \
|
||||
visible_message("<span class='danger'>[src] relieves [p_them()]self!</span>", \
|
||||
"<span class='userdanger'>You have relieved yourself.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
setArousalLoss(min_arousal)
|
||||
else
|
||||
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
|
||||
|
||||
/obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found.
|
||||
if(producing)
|
||||
. = reagents
|
||||
else
|
||||
if(linked_organ)
|
||||
. = linked_organ.reagents
|
||||
else if(!silent)
|
||||
to_chat(H, "<span class='warning'>Your [name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
|
||||
/mob/living/carbon/human/proc/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill = TRUE)
|
||||
if(!G)
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(!target || !R)
|
||||
return
|
||||
var/turfing = isturf(target)
|
||||
if(spill & R.total_volume >= 5)
|
||||
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
|
||||
if(!turfing)
|
||||
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
|
||||
R.clear_reagents()
|
||||
|
||||
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
|
||||
//For all of these, we assume the arguments given are proper and have been checked beforehand.
|
||||
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
var/datum/reagents/fluid_source = G.climaxable(src)
|
||||
if(!fluid_source)
|
||||
return
|
||||
var/obj/item/organ/genital/PP = G.can_masturbate_with == MASTURBATE_LINKED_ORGAN ? G.linked_organ : G
|
||||
if(!PP)
|
||||
to_chat(src, "<span class='warning'>You shudder, unable to cum with your [name].</span>")
|
||||
if(mb_time)
|
||||
src.visible_message("<span class='love'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name].</span>", \
|
||||
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name].</span>")
|
||||
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='love'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='userlove'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='userlove'>You have relieved yourself.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
visible_message("<span class='love'>[src] orgasms, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""]!</span>", \
|
||||
"<span class='userlove'>You orgasm, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""].</span>")
|
||||
do_climax(fluid_source, loc, G)
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/unable_to_come = FALSE
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
if(unable_to_come)
|
||||
src.visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>", \
|
||||
var/datum/reagents/fluid_source = G.climaxable(src, TRUE)
|
||||
if(!fluid_source)
|
||||
visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
|
||||
else
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time) //as long as it's not instant, give a warning
|
||||
src.visible_message("<span class='love'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='userlove'>You feel yourself about to orgasm.</span>", \
|
||||
"<span class='userlove'>You feel yourself about to orgasm.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='love'>[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].</span>", \
|
||||
"<span class='userlove'>You climax using your [G.name].</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
return
|
||||
if(mb_time) //as long as it's not instant, give a warning
|
||||
visible_message("<span class='love'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='userlove'>You feel yourself about to orgasm.</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
visible_message("<span class='love'>[src] orgasms[isturf(loc) ? " onto [loc]" : ""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name].</span>")
|
||||
do_climax(fluid_source, loc, G)
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30) //Used for climaxing with any living thing
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
var/datum/reagents/fluid_source = G.climaxable(src)
|
||||
if(!fluid_source)
|
||||
return
|
||||
if(mb_time) //Skip warning if this is an instant climax.
|
||||
src.visible_message("<span class='love'>[src] is about to climax with [L]!</span>", \
|
||||
"<span class='userlove'>You're about to climax with [L]!</span>", \
|
||||
"<span class='userlove'>You're preparing to climax with someone!</span>")
|
||||
visible_message("<span class='love'>[src] is about to climax with [L]!</span>", \
|
||||
"<span class='userlove'>You're about to climax with [L]!</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !in_range(src, L) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
if(spillage)
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor)
|
||||
total_fluids -= total_fluids*G.fluid_transfer_factor
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(L.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='love'>[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].</span>", \
|
||||
"<span class='userlove'>You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
visible_message("<span class='love'>[src] climaxes with [L], overflowing and spilling, using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You orgasm with [L], spilling out of them, using your [G.name].</span>")
|
||||
else //knots and other non-spilling orgasms
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids)
|
||||
total_fluids = 0
|
||||
src.visible_message("<span class='love'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
|
||||
"<span class='userlove'>You ejaculate with [L], your [G.name] spilling nothing.</span>", \
|
||||
"<span class='userlove'>You have climaxed inside someone, your [G.name] spilling nothing.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
visible_message("<span class='love'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
|
||||
"<span class='userlove'>You ejaculate with [L], your [G.name] spilling nothing.</span>")
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
do_climax(fluid_source, spillage ? loc : L, G, spillage)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
var/datum/reagents/fluid_source = G.climaxable(src)
|
||||
if(!fluid_source)
|
||||
return
|
||||
if(mb_time)
|
||||
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
//if(!container) //Something weird happened
|
||||
// to_chat(src, "<span class='warning'>You need a container to do this!</span>")
|
||||
// return
|
||||
|
||||
src.visible_message("<span class='love'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over something.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, container))
|
||||
fluid_source.trans_to(container, total_fluids)
|
||||
src.visible_message("<span class='love'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
|
||||
"<span class='userlove'>You used your [G.name] to fill [container].</span>", \
|
||||
"<span class='userlove'>You have relieved some pressure.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
visible_message("<span class='love'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
|
||||
"<span class='userlove'>You used your [G.name] to fill [container].</span>")
|
||||
do_climax(fluid_source, container, G, FALSE)
|
||||
|
||||
/mob/living/carbon/human/proc/pick_masturbate_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(G.can_masturbate_with && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
|
||||
if(G.can_masturbate_with == MASTURBATE_LINKED_ORGAN && !G.linked_organ)
|
||||
continue
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
|
||||
var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_climax) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(G.can_climax && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
|
||||
var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_partner()
|
||||
var/list/partners = list()
|
||||
if(src.pulling)
|
||||
partners += src.pulling //Yes, even objects for now
|
||||
if(src.pulledby)
|
||||
partners += src.pulledby
|
||||
if(pulling)
|
||||
partners += pulling
|
||||
if(pulledby)
|
||||
partners += pulledby
|
||||
//Now we got both of them, let's check if they're proper
|
||||
for(var/I in partners)
|
||||
if(isliving(I))
|
||||
if(iscarbon(I))
|
||||
var/mob/living/carbon/C = I
|
||||
if(!C.exposed_genitals.len) //Nothing through_clothing
|
||||
if(!C.is_groin_exposed()) //No pants undone
|
||||
if(!C.is_chest_exposed()) //No chest exposed
|
||||
partners -= I //Then not proper, remove them
|
||||
else
|
||||
partners -= I //No fucking objects
|
||||
for(var/mob/living/L in partners)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed()) //Nothing through_clothing, no proper partner.
|
||||
partners -= C
|
||||
//NOW the list should only contain correct partners
|
||||
if(!partners.len)
|
||||
return null //No one left.
|
||||
return input(src, "With whom?", "Sexual partner", null) in partners //pick one, default to null
|
||||
return //No one left.
|
||||
var/mob/living/target = input(src, "With whom?", "Sexual partner", null) as null|anything in partners //pick one, default to null
|
||||
if(target && in_range(src, target))
|
||||
return target
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_container()
|
||||
var/obj/item/reagent_containers/SC = null
|
||||
var/list/containers_list = list()
|
||||
|
||||
for(var/obj/item/reagent_containers/container in held_items)
|
||||
@@ -434,12 +321,21 @@
|
||||
containers_list += container
|
||||
|
||||
if(containers_list.len)
|
||||
SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
|
||||
if(SC)
|
||||
if(in_range(src, SC))
|
||||
return SC
|
||||
var/obj/item/reagent_containers/SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
|
||||
if(SC && in_range(src, SC))
|
||||
return SC
|
||||
return null //If nothing correct, give null.
|
||||
|
||||
/mob/living/carbon/human/proc/available_rosie_palms(silent = FALSE)
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return FALSE
|
||||
if(!get_num_arms() || !get_empty_held_indexes())
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//Here's the main proc itself
|
||||
/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
|
||||
@@ -447,49 +343,47 @@
|
||||
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
|
||||
to_chat(src, "<span class='warning'>You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!</span>")
|
||||
return
|
||||
mb_cd_timer = (world.time + mb_cd_length)
|
||||
|
||||
mb_cd_timer = world.time + mb_cd_length
|
||||
|
||||
if(canbearoused && has_dna())
|
||||
if(stat==2)
|
||||
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
|
||||
if(stat == DEAD)
|
||||
if(!forced_climax)
|
||||
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
|
||||
return
|
||||
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/O in internal_organs)
|
||||
if(istype(O, /obj/item/organ/genital))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(!G.can_climax) //Skip things like wombs and testicles
|
||||
continue
|
||||
var/mob/living/partner
|
||||
var/check_target
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(!G.can_climax) //Skip things like wombs and testicles
|
||||
continue
|
||||
var/mob/living/partner
|
||||
var/check_target
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
if(G.is_exposed(worn_stuff))
|
||||
if(src.pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
|
||||
if(isliving(src.pulling)) //Don't fuck objects
|
||||
check_target = src.pulling
|
||||
if(src.pulledby && !check_target) //prioritise pulled over pulledby
|
||||
if(isliving(src.pulledby))
|
||||
check_target = src.pulledby
|
||||
//Now we should have a partner, or else we have to come alone
|
||||
if(check_target)
|
||||
if(iscarbon(check_target)) //carbons can have clothes
|
||||
var/mob/living/carbon/C = check_target
|
||||
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
|
||||
partner = C
|
||||
else //A cat is fine too
|
||||
partner = check_target
|
||||
if(partner) //Did they pass the clothing checks?
|
||||
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
|
||||
continue //You've climaxed once with this organ, continue on
|
||||
//not exposed OR if no partner was found while exposed, climax alone
|
||||
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
|
||||
if(G.is_exposed(worn_stuff))
|
||||
if(pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
|
||||
if(isliving(pulling)) //Don't fuck objects
|
||||
check_target = pulling
|
||||
if(pulledby && !check_target) //prioritise pulled over pulledby
|
||||
if(isliving(pulledby))
|
||||
check_target = pulledby
|
||||
//Now we should have a partner, or else we have to come alone
|
||||
if(check_target)
|
||||
if(iscarbon(check_target)) //carbons can have clothes
|
||||
var/mob/living/carbon/C = check_target
|
||||
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
|
||||
partner = C
|
||||
else //A cat is fine too
|
||||
partner = check_target
|
||||
if(partner) //Did they pass the clothing checks?
|
||||
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
|
||||
continue //You've climaxed once with this organ, continue on
|
||||
//not exposed OR if no partner was found while exposed, climax alone
|
||||
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
|
||||
//Now all genitals that could climax, have.
|
||||
//Since this was a forced climax, we do not need to continue with the other stuff
|
||||
return
|
||||
//If we get here, then this is not a forced climax and we gotta check a few things.
|
||||
|
||||
if(stat==1) //No sleep-masturbation, you're unconscious.
|
||||
if(stat == UNCONSCIOUS) //No sleep-masturbation, you're unconscious.
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
return
|
||||
if(getArousalLoss() < 33) //flat number instead of percentage
|
||||
@@ -497,91 +391,38 @@
|
||||
return
|
||||
|
||||
//Ok, now we check what they want to do.
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") as null|anything in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
|
||||
|
||||
switch(choice)
|
||||
if("Masturbate")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
if(!available_rosie_palms())
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ)
|
||||
var/obj/item/organ/genital/picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ && available_rosie_palms(TRUE))
|
||||
mob_masturbate(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot masturbate without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if("Climax alone")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
if(!available_rosie_palms())
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
|
||||
if(picked_organ && available_rosie_palms(TRUE))
|
||||
mob_climax_outside(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if("Climax with partner")
|
||||
//We need no hands, we can be restrained and so on, so let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
var/mob/living/partner = pick_partner() //Get someone
|
||||
if(partner)
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
|
||||
if(spillage == "Yes")
|
||||
mob_climax_partner(picked_organ, partner, TRUE)
|
||||
else
|
||||
mob_climax_partner(picked_organ, partner, FALSE)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as null|anything in list("Yes", "No")
|
||||
if(spillage && in_range(src, partner))
|
||||
mob_climax_partner(picked_organ, partner, spillage == "Yes" ? TRUE : FALSE)
|
||||
|
||||
if("Fill container")
|
||||
//We'll need hands and no restraints.
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
if(!available_rosie_palms())
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
@@ -589,14 +430,6 @@
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
var/obj/item/reagent_containers/fluid_container = pick_climax_container()
|
||||
if(fluid_container)
|
||||
if(fluid_container && available_rosie_palms(TRUE))
|
||||
mob_fill_container(picked_organ, fluid_container)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this without anything to fill.</span>")
|
||||
return
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing genitals.</span>")
|
||||
return
|
||||
else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled
|
||||
return //Just end it in that case.
|
||||
return
|
||||
+70
-143
@@ -6,8 +6,9 @@
|
||||
var/list/genital_flags = list()
|
||||
var/can_masturbate_with = FALSE
|
||||
var/masturbation_verb = "masturbate"
|
||||
var/orgasm_verb = "cumming" //present continous
|
||||
var/can_climax = FALSE
|
||||
var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
|
||||
var/fluid_transfer_factor = 0 //How much would a partner get in them if they climax using this?
|
||||
var/size = 2 //can vary between num or text, just used in icon_state strings
|
||||
var/fluid_id = null
|
||||
var/fluid_max_volume = 50
|
||||
@@ -18,48 +19,49 @@
|
||||
var/aroused_state = FALSE //Boolean used in icon_state strings
|
||||
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
|
||||
var/obj/item/organ/genital/linked_organ
|
||||
var/linked_organ_slot //only one of the two organs needs this to be set up. update_link() will handle linking the rest.
|
||||
var/through_clothes = FALSE
|
||||
var/internal = FALSE
|
||||
var/hidden = FALSE
|
||||
var/layer_index = GENITAL_LAYER_INDEX //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
|
||||
|
||||
/obj/item/organ/genital/Initialize()
|
||||
. = ..()
|
||||
if(!reagents)
|
||||
if(fluid_id)
|
||||
create_reagents(fluid_max_volume)
|
||||
if(producing)
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
update()
|
||||
|
||||
/obj/item/organ/genital/Destroy()
|
||||
remove_ref()
|
||||
if(linked_organ)
|
||||
update_link(TRUE)//this should remove any other links it has
|
||||
if(owner)
|
||||
Remove(owner, 1)//this should remove references to it, so it can be GCd correctly
|
||||
update_link()//this should remove any other links it has
|
||||
Remove(owner, TRUE)//this should remove references to it, so it can be GCd correctly
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/genital/proc/update()
|
||||
/obj/item/organ/genital/proc/update(removing = FALSE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
update_size()
|
||||
update_appearance()
|
||||
update_link()
|
||||
if(linked_organ_slot || (linked_organ && removing))
|
||||
update_link(removing)
|
||||
|
||||
//exposure and through-clothing code
|
||||
/mob/living/carbon
|
||||
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
|
||||
|
||||
/obj/item/organ/genital/proc/is_exposed()
|
||||
if(!owner)
|
||||
return FALSE
|
||||
if(hidden)
|
||||
return FALSE
|
||||
if(internal)
|
||||
if(!owner || hidden || internal)
|
||||
return FALSE
|
||||
if(through_clothes)
|
||||
return TRUE
|
||||
|
||||
switch(zone) //update as more genitals are added
|
||||
if("chest")
|
||||
if(BODY_ZONE_CHEST)
|
||||
return owner.is_chest_exposed()
|
||||
if("groin")
|
||||
if(BODY_ZONE_PRECISE_GROIN)
|
||||
return owner.is_groin_exposed()
|
||||
|
||||
return FALSE
|
||||
@@ -107,22 +109,37 @@
|
||||
picked_organ.toggle_visibility(picked_visibility)
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/genital/proc/update_size()
|
||||
return
|
||||
|
||||
/obj/item/organ/genital/proc/update_appearance()
|
||||
return
|
||||
|
||||
/obj/item/organ/genital/proc/update_link()
|
||||
return
|
||||
/obj/item/organ/genital/on_life()
|
||||
if(!reagents || !owner)
|
||||
return
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
if(fluid_id && producing)
|
||||
generate_fluid()
|
||||
|
||||
/obj/item/organ/genital/proc/remove_ref()
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
/obj/item/organ/genital/proc/generate_fluid()
|
||||
if(owner.stat != DEAD && reagents.total_volume < reagents.maximum_volume)
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/organ/genital/proc/update_link(removing = FALSE)
|
||||
if(!removing && owner)
|
||||
linked_organ = owner.getorganslot(linked_organ_slot)
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
return TRUE
|
||||
else
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
return FALSE
|
||||
|
||||
/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
@@ -130,127 +147,42 @@
|
||||
|
||||
/obj/item/organ/genital/Remove(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
update()
|
||||
update(TRUE)
|
||||
|
||||
//proc to give a player their genitals and stuff when they log in
|
||||
/mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
|
||||
/mob/living/carbon/human/proc/give_genitals(clean = FALSE)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
|
||||
if(clean)
|
||||
var/obj/item/organ/genital/GtoClean
|
||||
for(GtoClean in internal_organs)
|
||||
qdel(GtoClean)
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
qdel(G)
|
||||
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_vag"])
|
||||
give_vagina()
|
||||
give_genital(/obj/item/organ/genital/vagina)
|
||||
if(dna.features["has_womb"])
|
||||
give_womb()
|
||||
give_genital(/obj/item/organ/genital/womb)
|
||||
if(dna.features["has_balls"])
|
||||
give_balls()
|
||||
give_genital(/obj/item/organ/genital/testicles)
|
||||
if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas.
|
||||
give_breasts()
|
||||
give_genital(/obj/item/organ/genital/breasts)
|
||||
if(dna.features["has_cock"])
|
||||
give_penis()
|
||||
give_genital(/obj/item/organ/genital/penis)
|
||||
/*
|
||||
if(dna.features["has_ovi"])
|
||||
give_ovipositor()
|
||||
give_genital(/obj/item/organ/genital/ovipositor)
|
||||
if(dna.features["has_eggsack"])
|
||||
give_eggsack()
|
||||
give_genital(/obj/item/organ/genital/eggsack)
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/give_penis()
|
||||
if(!dna)
|
||||
/mob/living/carbon/human/proc/give_genital(obj/item/organ/genital/G)
|
||||
if(!dna || (NOGENITALS in dna.species.species_traits) || getorganslot(initial(G.slot)))
|
||||
return FALSE
|
||||
if(NOGENITALS in dna.species.species_traits)
|
||||
return FALSE
|
||||
if(!getorganslot("penis"))
|
||||
var/obj/item/organ/genital/penis/P = new
|
||||
P.Insert(src)
|
||||
if(P)
|
||||
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
|
||||
P.color = "#[skintone2hex(skin_tone)]"
|
||||
else
|
||||
P.color = "#[dna.features["cock_color"]]"
|
||||
P.length = dna.features["cock_length"]
|
||||
P.girth_ratio = dna.features["cock_girth_ratio"]
|
||||
P.shape = dna.features["cock_shape"]
|
||||
P.update()
|
||||
G = new
|
||||
if(istype(G, /obj/item/organ/genital)) //badminnery-proofing.
|
||||
G.get_features(src)
|
||||
G.Insert(src)
|
||||
|
||||
/mob/living/carbon/human/proc/give_balls()
|
||||
if(!dna)
|
||||
return FALSE
|
||||
if(NOGENITALS in dna.species.species_traits)
|
||||
return FALSE
|
||||
if(!getorganslot("testicles"))
|
||||
var/obj/item/organ/genital/testicles/T = new
|
||||
T.Insert(src)
|
||||
if(T)
|
||||
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
|
||||
T.color = "#[skintone2hex(skin_tone)]"
|
||||
else
|
||||
T.color = "#[dna.features["balls_color"]]"
|
||||
T.size = dna.features["balls_size"]
|
||||
T.sack_size = dna.features["balls_sack_size"]
|
||||
T.shape = dna.features["balls_shape"]
|
||||
if(dna.features["balls_shape"] == "Hidden")
|
||||
T.internal = TRUE
|
||||
else
|
||||
T.internal = FALSE
|
||||
T.fluid_id = dna.features["balls_fluid"]
|
||||
T.fluid_rate = dna.features["balls_cum_rate"]
|
||||
T.fluid_mult = dna.features["balls_cum_mult"]
|
||||
T.fluid_efficiency = dna.features["balls_efficiency"]
|
||||
T.update()
|
||||
|
||||
/mob/living/carbon/human/proc/give_breasts()
|
||||
if(!dna)
|
||||
return FALSE
|
||||
if(NOGENITALS in dna.species.species_traits)
|
||||
return FALSE
|
||||
if(!getorganslot("breasts"))
|
||||
var/obj/item/organ/genital/breasts/B = new
|
||||
B.Insert(src)
|
||||
if(B)
|
||||
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
|
||||
B.color = "#[skintone2hex(skin_tone)]"
|
||||
else
|
||||
B.color = "#[dna.features["breasts_color"]]"
|
||||
B.size = dna.features["breasts_size"]
|
||||
B.shape = dna.features["breasts_shape"]
|
||||
B.fluid_id = dna.features["breasts_fluid"]
|
||||
B.update()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/give_ovipositor()
|
||||
/obj/item/organ/genital/proc/get_features(datum/dna/D)
|
||||
return
|
||||
/mob/living/carbon/human/proc/give_eggsack()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/give_vagina()
|
||||
if(!dna)
|
||||
return FALSE
|
||||
if(NOGENITALS in dna.species.species_traits)
|
||||
return FALSE
|
||||
if(!getorganslot("vagina"))
|
||||
var/obj/item/organ/genital/vagina/V = new
|
||||
V.Insert(src)
|
||||
if(V)
|
||||
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
|
||||
V.color = "#[skintone2hex(skin_tone)]"
|
||||
else
|
||||
V.color = "[dna.features["vag_color"]]"
|
||||
V.shape = "[dna.features["vag_shape"]]"
|
||||
V.update()
|
||||
|
||||
/mob/living/carbon/human/proc/give_womb()
|
||||
if(!dna)
|
||||
return FALSE
|
||||
if(NOGENITALS in dna.species.species_traits)
|
||||
return FALSE
|
||||
if(!getorganslot("womb"))
|
||||
var/obj/item/organ/genital/womb/W = new
|
||||
W.Insert(src)
|
||||
if(W)
|
||||
W.update()
|
||||
|
||||
|
||||
/datum/species/proc/genitals_layertext(layer)
|
||||
switch(layer)
|
||||
@@ -267,7 +199,7 @@
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.update_genitals()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force)
|
||||
. = ..()
|
||||
@@ -276,20 +208,16 @@
|
||||
update_genitals()
|
||||
|
||||
/mob/living/carbon/human/proc/update_genitals()
|
||||
if(src && !QDELETED(src))
|
||||
if(!QDELETED(src))
|
||||
dna.species.handle_genitals(src)
|
||||
|
||||
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)
|
||||
if(!H)//no args
|
||||
CRASH("H = null")
|
||||
if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done
|
||||
return
|
||||
if(NOGENITALS in species_traits)//golems and such
|
||||
return
|
||||
if(HAS_TRAIT(H, TRAIT_HUSK))
|
||||
if(!LAZYLEN(H.internal_organs) || (NOGENITALS in species_traits) || HAS_TRAIT(H, TRAIT_HUSK))
|
||||
return
|
||||
|
||||
var/list/genitals_to_add = list()
|
||||
var/list/genitals_to_add[GENITAL_LAYER_INDEX_LENGTH]
|
||||
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER)
|
||||
var/list/standing = list()
|
||||
var/size
|
||||
@@ -300,18 +228,16 @@
|
||||
|
||||
//start scanning for genitals
|
||||
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
|
||||
for(var/obj/item/organ/O in H.internal_organs)
|
||||
if(isgenital(O))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(G.hidden)
|
||||
return //we're gunna just hijack this for updates.
|
||||
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
|
||||
genitals_to_add += H.getorganslot(G.slot)
|
||||
for(var/obj/item/organ/genital/G in H.internal_organs)
|
||||
if(G.hidden)
|
||||
return //we're gunna just hijack this for updates.
|
||||
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
|
||||
LAZYADD(genitals_to_add[G.layer_index], G)
|
||||
//Now we added all genitals that aren't internal and should be rendered
|
||||
|
||||
//start applying overlays
|
||||
for(var/layer in relevant_layers)
|
||||
var/layertext = genitals_layertext(layer)
|
||||
var/layertext = flatten_list(genitals_layertext(layer))
|
||||
for(var/obj/item/organ/genital/G in genitals_to_add)
|
||||
var/datum/sprite_accessory/S
|
||||
size = G.size
|
||||
@@ -357,3 +283,4 @@
|
||||
|
||||
for(var/L in relevant_layers)
|
||||
H.apply_overlay(L)
|
||||
|
||||
@@ -1,38 +1,20 @@
|
||||
/obj/item/organ/genital/breasts
|
||||
name = "breasts"
|
||||
desc = "Female milk producing organs."
|
||||
icon_state = "breasts"
|
||||
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
|
||||
zone = "chest"
|
||||
slot = "breasts"
|
||||
size = BREASTS_SIZE_DEF
|
||||
fluid_id = "milk"
|
||||
var/amount = 2
|
||||
producing = TRUE
|
||||
shape = "pair"
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "massage"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.5
|
||||
|
||||
/obj/item/organ/genital/breasts/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
|
||||
/obj/item/organ/genital/breasts/on_life()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!reagents || !owner)
|
||||
return
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
if(fluid_id && producing)
|
||||
generate_milk()
|
||||
|
||||
/obj/item/organ/genital/breasts/proc/generate_milk()
|
||||
if(owner.stat == DEAD)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))
|
||||
name = "breasts"
|
||||
desc = "Female milk producing organs."
|
||||
icon_state = "breasts"
|
||||
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_BREASTS
|
||||
size = BREASTS_SIZE_DEF
|
||||
fluid_id = "milk"
|
||||
var/amount = 2
|
||||
producing = TRUE
|
||||
shape = "pair"
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "massage"
|
||||
orgasm_verb = "leaking"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.5
|
||||
|
||||
/obj/item/organ/genital/breasts/update_appearance()
|
||||
var/lowershape = lowertext(shape)
|
||||
@@ -65,3 +47,13 @@
|
||||
var/mob/living/carbon/human/H = owner
|
||||
icon_state = sanitize_text(string)
|
||||
H.update_genitals()
|
||||
|
||||
/obj/item/organ/genital/breasts/get_features(mob/living/carbon/human/H)
|
||||
var/datum/dna/D = H.dna
|
||||
if(D.species.use_skintones && D.features["genitals_use_skintone"])
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
color = "#[D.features["breasts_color"]]"
|
||||
size = D.features["breasts_size"]
|
||||
shape = D.features["breasts_shape"]
|
||||
fluid_id = D.features["breasts_fluid"]
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/obj/item/organ/genital/eggsack
|
||||
name = "Egg sack"
|
||||
desc = "An egg producing reproductive organ."
|
||||
icon_state = "egg_sack"
|
||||
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
|
||||
zone = "groin"
|
||||
slot = "testicles"
|
||||
color = null //don't use the /genital color since it already is colored
|
||||
name = "Egg sack"
|
||||
desc = "An egg producing reproductive organ."
|
||||
icon_state = "egg_sack"
|
||||
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_TESTICLES
|
||||
linked_organ_slot = ORGAN_SLOT_PENIS
|
||||
color = null //don't use the /genital color since it already is colored
|
||||
internal = TRUE
|
||||
var/egg_girth = EGG_GIRTH_DEF
|
||||
var/cum_mult = CUM_RATE_MULT
|
||||
var/cum_rate = CUM_RATE
|
||||
var/cum_efficiency = CUM_EFFICIENCY
|
||||
var/obj/item/organ/ovipositor/linked_ovi
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM
|
||||
/datum/sprite_accessory/penis
|
||||
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
|
||||
icon_state = null
|
||||
name = "penis" //the preview name of the accessory
|
||||
gender_specific = 0 //Might be needed somewhere down the list.
|
||||
color_src = "cock_color"
|
||||
locked = 0
|
||||
alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/penis/human
|
||||
icon_state = "human"
|
||||
@@ -62,27 +60,21 @@
|
||||
icon_state = "testicle"
|
||||
name = "testicle" //the preview name of the accessory
|
||||
color_src = "balls_color"
|
||||
locked = 0
|
||||
|
||||
/datum/sprite_accessory/testicles/hidden
|
||||
icon_state = "hidden"
|
||||
icon_state = "none"
|
||||
name = "Hidden"
|
||||
alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/testicles/single
|
||||
icon_state = "single"
|
||||
name = "Single"
|
||||
alt_aroused = TRUE
|
||||
|
||||
//Vaginas
|
||||
/datum/sprite_accessory/vagina
|
||||
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
|
||||
icon_state = null
|
||||
name = "vagina"
|
||||
gender_specific = 0
|
||||
color_src = "vag_color"
|
||||
locked = 0
|
||||
alt_aroused = FALSE //if this is TRUE, then the genitals will use an alternate sprite for aroused states
|
||||
|
||||
/datum/sprite_accessory/vagina/human
|
||||
icon_state = "human"
|
||||
@@ -114,35 +106,28 @@
|
||||
//BREASTS BE HERE
|
||||
/datum/sprite_accessory/breasts
|
||||
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
|
||||
icon_state = null
|
||||
name = "breasts"
|
||||
gender_specific = 0
|
||||
color_src = "breasts_color"
|
||||
locked = 0
|
||||
alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/breasts/pair
|
||||
icon_state = "pair"
|
||||
name = "Pair"
|
||||
alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/breasts/quad
|
||||
icon_state = "quad"
|
||||
name = "Quad"
|
||||
alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/breasts/sextuple
|
||||
icon_state = "sextuple"
|
||||
name = "Sextuple"
|
||||
alt_aroused = TRUE
|
||||
|
||||
//OVIPOSITORS BE HERE
|
||||
/datum/sprite_accessory/ovipositor
|
||||
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
|
||||
icon_state = null
|
||||
name = "Ovipositor" //the preview name of the accessory
|
||||
gender_specific = 0 //Might be needed somewhere down the list.
|
||||
color_src = "cock_color"
|
||||
locked = 0
|
||||
|
||||
/datum/sprite_accessory/ovipositor/knotted
|
||||
icon_state = "knotted"
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
desc = "An egg laying reproductive organ."
|
||||
icon_state = "ovi_knotted_2"
|
||||
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
|
||||
zone = "groin"
|
||||
slot = "penis"
|
||||
w_class = 3
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_PENIS
|
||||
shape = "knotted"
|
||||
size = 3
|
||||
layer_index = PENIS_LAYER_INDEX
|
||||
var/length = 6 //inches
|
||||
var/girth = 0
|
||||
var/girth_ratio = COCK_GIRTH_RATIO_DEF //citadel_defines.dm for these defines
|
||||
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
|
||||
var/list/oviflags = list()
|
||||
var/obj/item/organ/eggsack/linked_eggsack
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
/obj/item/organ/genital/penis
|
||||
name = "penis"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "penis"
|
||||
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
|
||||
zone = "groin"
|
||||
slot = ORGAN_SLOT_PENIS
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "stroke"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.5
|
||||
size = 2 //arbitrary value derived from length and girth for sprites.
|
||||
var/length = 6 //inches
|
||||
var/cached_length //used to detect a change in length
|
||||
var/girth = 0
|
||||
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
|
||||
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
|
||||
var/list/dickflags = list()
|
||||
var/list/knotted_types = list("knotted", "barbed, knotted")
|
||||
name = "penis"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "penis"
|
||||
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_PENIS
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "stroke"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.5
|
||||
size = 2 //arbitrary value derived from length and girth for sprites.
|
||||
layer_index = PENIS_LAYER_INDEX
|
||||
var/length = 6 //inches
|
||||
var/cached_length //used to detect a change in length
|
||||
var/girth = 0
|
||||
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
|
||||
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
|
||||
var/list/dickflags = list()
|
||||
var/list/knotted_types = list("knotted", "barbed, knotted")
|
||||
|
||||
/obj/item/organ/genital/penis/update_size()
|
||||
if(length == cached_length)
|
||||
@@ -38,7 +39,7 @@
|
||||
/obj/item/organ/genital/penis/update_appearance()
|
||||
var/string
|
||||
var/lowershape = lowertext(shape)
|
||||
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
|
||||
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] [name]. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
|
||||
|
||||
if(owner)
|
||||
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
|
||||
@@ -54,13 +55,12 @@
|
||||
icon_state = sanitize_text(string)
|
||||
H.update_genitals()
|
||||
|
||||
/obj/item/organ/genital/penis/update_link()
|
||||
if(owner)
|
||||
linked_organ = (owner.getorganslot("testicles"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
linked_organ.size = size
|
||||
/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
|
||||
var/datum/dna/D = H.dna
|
||||
if(D.species.use_skintones && D.features["genitals_use_skintone"])
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
color = "#[D.features["cock_color"]]"
|
||||
length = D.features["cock_length"]
|
||||
girth_ratio = D.features["cock_girth_ratio"]
|
||||
shape = D.features["cock_shape"]
|
||||
|
||||
@@ -1,56 +1,34 @@
|
||||
/obj/item/organ/genital/testicles
|
||||
name = "testicles"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "testicles"
|
||||
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
|
||||
zone = "groin"
|
||||
slot = "testicles"
|
||||
size = BALLS_SIZE_MIN
|
||||
var/size_name = "average"
|
||||
shape = "single"
|
||||
var/sack_size = BALLS_SACK_SIZE_DEF
|
||||
fluid_id = "semen"
|
||||
producing = TRUE
|
||||
can_masturbate_with = FALSE
|
||||
masturbation_verb = "massage"
|
||||
can_climax = TRUE
|
||||
var/sent_full_message = TRUE //defaults to 1 since they're full to start
|
||||
name = "testicles"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "testicles"
|
||||
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_TESTICLES
|
||||
size = BALLS_SIZE_MIN
|
||||
linked_organ_slot = ORGAN_SLOT_PENIS
|
||||
var/size_name = "average"
|
||||
shape = "single"
|
||||
var/sack_size = BALLS_SACK_SIZE_DEF
|
||||
fluid_id = "semen"
|
||||
producing = TRUE
|
||||
can_masturbate_with = MASTURBATE_LINKED_ORGAN
|
||||
masturbation_verb = "massage"
|
||||
layer_index = TESTICLES_LAYER_INDEX
|
||||
var/size_linked = FALSE
|
||||
|
||||
/obj/item/organ/genital/testicles/Initialize()
|
||||
/obj/item/organ/genital/testicles/generate_fluid()
|
||||
if(!linked_organ && !update_link())
|
||||
return FALSE
|
||||
. = ..()
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
if(.)
|
||||
send_full_message()
|
||||
|
||||
/obj/item/organ/genital/testicles/on_life()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(reagents && producing)
|
||||
generate_cum()
|
||||
|
||||
/obj/item/organ/genital/testicles/proc/generate_cum()
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
if(reagents.total_volume >= reagents.maximum_volume)
|
||||
if(!sent_full_message)
|
||||
send_full_message()
|
||||
sent_full_message = TRUE
|
||||
return FALSE
|
||||
sent_full_message = FALSE
|
||||
update_link()
|
||||
if(!linked_organ)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
|
||||
/obj/item/organ/genital/testicles/update_link()
|
||||
if(owner && !QDELETED(src))
|
||||
linked_organ = (owner.getorganslot("penis"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
size = linked_organ.size
|
||||
|
||||
else
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
/obj/item/organ/genital/testicles/update_link(removing = FALSE)
|
||||
. = ..()
|
||||
if(. && !size_linked)
|
||||
size = linked_organ.size
|
||||
size_linked = TRUE
|
||||
|
||||
/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
|
||||
if(owner && istext(msg))
|
||||
@@ -59,19 +37,16 @@
|
||||
|
||||
/obj/item/organ/genital/testicles/update_appearance()
|
||||
switch(size)
|
||||
if(0.1 to 1)
|
||||
if(BALLS_SIZE_MIN)
|
||||
size_name = "average"
|
||||
if(1.1 to 2)
|
||||
if(BALLS_SIZE_DEF)
|
||||
size_name = "enlarged"
|
||||
if(2.1 to INFINITY)
|
||||
if(BALLS_SIZE_MAX)
|
||||
size_name = "engorged"
|
||||
else
|
||||
size_name = "nonexistant"
|
||||
|
||||
if(!internal)
|
||||
desc = "You see an [size_name] pair of testicles."
|
||||
else
|
||||
desc = "They don't have any testicles you can see."
|
||||
desc = "You see an [size_name] pair of testicles."
|
||||
|
||||
if(owner)
|
||||
var/string
|
||||
@@ -87,3 +62,21 @@
|
||||
var/mob/living/carbon/human/H = owner
|
||||
icon_state = sanitize_text(string)
|
||||
H.update_genitals()
|
||||
|
||||
/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
|
||||
var/datum/dna/D = H.dna
|
||||
if(D.species.use_skintones && D.features["genitals_use_skintone"])
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
color = "#[D.features["balls_color"]]"
|
||||
size = D.features["balls_size"]
|
||||
sack_size = D.features["balls_sack_size"]
|
||||
shape = D.features["balls_shape"]
|
||||
if(D.features["balls_shape"] == "Hidden")
|
||||
internal = TRUE
|
||||
else
|
||||
internal = FALSE
|
||||
fluid_id = D.features["balls_fluid"]
|
||||
fluid_rate = D.features["balls_cum_rate"]
|
||||
fluid_mult = D.features["balls_cum_mult"]
|
||||
fluid_efficiency = D.features["balls_efficiency"]
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
/obj/item/organ/genital/vagina
|
||||
name = "vagina"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = "vagina"
|
||||
zone = "groin"
|
||||
slot = "vagina"
|
||||
size = 1 //There is only 1 size right now
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "finger"
|
||||
can_climax = TRUE
|
||||
name = "vagina"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = ORGAN_SLOT_VAGINA
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = "vagina"
|
||||
size = 1 //There is only 1 size right now
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "finger"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
|
||||
w_class = 3
|
||||
var/cap_length = 8//D E P T H (cap = capacity)
|
||||
var/cap_girth = 12
|
||||
layer_index = VAGINA_LAYER_INDEX
|
||||
var/cap_length = 8//D E P T H (cap = capacity)
|
||||
var/cap_girth = 12
|
||||
var/cap_girth_ratio = 1.5
|
||||
var/clits = 1
|
||||
var/clit_diam = 0.25
|
||||
var/clit_len = 0.25
|
||||
var/clits = 1
|
||||
var/clit_diam = 0.25
|
||||
var/clit_len = 0.25
|
||||
var/list/vag_types = list("tentacle", "dentata", "hairy", "spade", "furred")
|
||||
|
||||
|
||||
/obj/item/organ/genital/vagina/update_appearance()
|
||||
var/string //Keeping this code here, so making multiple sprites for the different kinds is easier.
|
||||
var/lowershape = lowertext(shape)
|
||||
@@ -63,12 +62,10 @@
|
||||
icon_state = sanitize_text(string)
|
||||
H.update_genitals()
|
||||
|
||||
/obj/item/organ/genital/vagina/update_link()
|
||||
if(owner)
|
||||
linked_organ = (owner.getorganslot("womb"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
/obj/item/organ/genital/vagina/get_features(mob/living/carbon/human/H)
|
||||
var/datum/dna/D = H.dna
|
||||
if(D.species.use_skintones && D.features["genitals_use_skintone"])
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
color = "[D.features["vag_color"]]"
|
||||
shape = "[D.features["vag_shape"]]"
|
||||
|
||||
@@ -1,41 +1,11 @@
|
||||
/obj/item/organ/genital/womb
|
||||
name = "womb"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = "womb"
|
||||
zone = "groin"
|
||||
slot = "womb"
|
||||
internal = TRUE
|
||||
fluid_id = "femcum"
|
||||
producing = TRUE
|
||||
|
||||
/obj/item/organ/genital/womb/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
|
||||
/obj/item/organ/genital/womb/on_life()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(reagents && producing)
|
||||
generate_femcum()
|
||||
|
||||
/obj/item/organ/genital/womb/proc/generate_femcum()
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
update_link()
|
||||
if(!linked_organ)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
|
||||
/obj/item/organ/genital/womb/update_link()
|
||||
if(owner)
|
||||
linked_organ = (owner.getorganslot("vagina"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
else
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/womb/Destroy()
|
||||
return ..()
|
||||
name = "womb"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = "womb"
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_WOMB
|
||||
internal = TRUE
|
||||
fluid_id = "femcum"
|
||||
producing = TRUE
|
||||
linked_organ_slot = ORGAN_SLOT_VAGINA
|
||||
@@ -32,7 +32,6 @@
|
||||
WRITE_FILE(S["feature_ipc_antenna"], features["ipc_antenna"])
|
||||
//Citadel
|
||||
WRITE_FILE(S["feature_genitals_use_skintone"], features["genitals_use_skintone"])
|
||||
WRITE_FILE(S["feature_exhibitionist"], features["exhibitionist"])
|
||||
WRITE_FILE(S["feature_mcolor2"], features["mcolor2"])
|
||||
WRITE_FILE(S["feature_mcolor3"], features["mcolor3"])
|
||||
WRITE_FILE(S["feature_mam_body_markings"], features["mam_body_markings"])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/human/Life()
|
||||
/mob/living/carbon/human/Life(seconds, times_fired)
|
||||
//citadel code
|
||||
if(stat != DEAD)
|
||||
handle_arousal()
|
||||
handle_arousal(times_fired)
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
|
||||
@@ -78,42 +78,30 @@
|
||||
else
|
||||
H.facial_hair_style = "Shaved"
|
||||
//handle normal hair
|
||||
var/new_style = input(owner, "Select a hair style", "Hair Alterations") as null|anything in GLOB.hair_styles_list
|
||||
var/new_style = input(owner, "Select a hair style", "Hair Alterations") as null|anything in GLOB.hair_styles_list
|
||||
if(new_style)
|
||||
H.hair_style = new_style
|
||||
H.update_hair()
|
||||
else if (select_alteration == "Genitals")
|
||||
var/list/organs = list()
|
||||
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel")
|
||||
switch(operation)
|
||||
if("add sexual organ")
|
||||
var/new_organ = input("Select sexual organ:", "Organ Manipulation") in list("Penis", "Testicles", "Breasts", "Vagina", "Womb", "Cancel")
|
||||
if(new_organ == "Penis")
|
||||
H.give_penis()
|
||||
else if(new_organ == "Testicles")
|
||||
H.give_balls()
|
||||
else if(new_organ == "Breasts")
|
||||
H.give_breasts()
|
||||
else if(new_organ == "Vagina")
|
||||
H.give_vagina()
|
||||
else if(new_organ == "Womb")
|
||||
H.give_womb()
|
||||
else
|
||||
var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list
|
||||
if(!new_organ)
|
||||
return
|
||||
H.give_genital(GLOB.genitals_list[new_organ])
|
||||
|
||||
if("remove sexual organ")
|
||||
var/list/organs = list()
|
||||
for(var/obj/item/organ/genital/X in H.internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
organs["[I.name] ([I.type])"] = I
|
||||
var/obj/item/organ = input("Select sexual organ:", "Organ Manipulation", null) in organs
|
||||
organ = organs[organ]
|
||||
if(!organ)
|
||||
var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs
|
||||
var/obj/item/organ/genital/G = organs[O]
|
||||
if(!G)
|
||||
return
|
||||
var/obj/item/organ/genital/O
|
||||
if(isorgan(organ))
|
||||
O = organ
|
||||
O.Remove(H)
|
||||
organ.forceMove(get_turf(H))
|
||||
qdel(organ)
|
||||
G.forceMove(get_turf(H))
|
||||
qdel(G)
|
||||
H.update_genitals()
|
||||
|
||||
else if (select_alteration == "Ears")
|
||||
@@ -203,8 +191,8 @@
|
||||
if(new_shape)
|
||||
H.dna.features["cock_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.give_balls()
|
||||
H.give_penis()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
H.give_genital(/obj/item/organ/genital/penis)
|
||||
H.apply_overlay()
|
||||
|
||||
|
||||
@@ -216,8 +204,8 @@
|
||||
if(new_shape)
|
||||
H.dna.features["vag_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.give_womb()
|
||||
H.give_vagina()
|
||||
H.give_genital(/obj/item/organ/genital/womb)
|
||||
H.give_genital(/obj/item/organ/genital/vagina)
|
||||
H.apply_overlay()
|
||||
|
||||
else if (select_alteration == "Penis Length")
|
||||
@@ -229,8 +217,8 @@
|
||||
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_balls()
|
||||
H.give_penis()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
H.give_genital(/obj/item/organ/genital/penis)
|
||||
|
||||
else if (select_alteration == "Breast Size")
|
||||
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
|
||||
@@ -241,7 +229,7 @@
|
||||
H.dna.features["breasts_size"] = new_size
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_breasts()
|
||||
H.give_genital(/obj/item/organ/genital/breasts)
|
||||
|
||||
else if (select_alteration == "Breast Shape")
|
||||
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
|
||||
@@ -252,7 +240,7 @@
|
||||
H.dna.features["breasts_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_breasts()
|
||||
H.give_genital(/obj/item/organ/genital/breasts)
|
||||
|
||||
else
|
||||
return
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 759 B After Width: | Height: | Size: 562 B |
+1
-2
@@ -2844,7 +2844,6 @@
|
||||
#include "modular_citadel\code\datums\mood_events\moodular.dm"
|
||||
#include "modular_citadel\code\datums\mutations\hulk.dm"
|
||||
#include "modular_citadel\code\datums\status_effects\debuffs.dm"
|
||||
#include "modular_citadel\code\datums\traits\neutral.dm"
|
||||
#include "modular_citadel\code\datums\wires\airlock.dm"
|
||||
#include "modular_citadel\code\datums\wires\autoylathe.dm"
|
||||
#include "modular_citadel\code\game\area\cit_areas.dm"
|
||||
@@ -2912,9 +2911,9 @@
|
||||
#include "modular_citadel\code\modules\admin\secrets.dm"
|
||||
#include "modular_citadel\code\modules\admin\topic.dm"
|
||||
#include "modular_citadel\code\modules\arousal\arousal.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\_genitals.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\breasts.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\eggsack.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\genitals.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\genitals_sprite_accessories.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\ovipositor.dm"
|
||||
#include "modular_citadel\code\modules\arousal\organs\penis.dm"
|
||||
|
||||
Reference in New Issue
Block a user