mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
[MODULARIZING] Partial Refactoring of Organic Interface Code (#16019)
This took a long time to review, but at long last, it's done. * HUD clutter, good bye, you will not be missed. * Oh my god so much pain * No commented code. Bad. * Uwaaaa * Add a couple of warning messages for common scenarios, use defines * AAAAA * AAAAAAAAAAA * UWAAAA * UUUUWAAAA, DOCUMENTED SNOWFLAKE CODE * FUCK * Apply suggestions! * Apply suggestions part one! Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> * Apply suggestions part two! * Static list I think this is how it works, it compiles, sooo * Split the giga monolith that's known as technical_stuff_for_lewd into two parts, human_helpers, and whatever else isn't a human helper. Also add a helper proc for mass update_inv on organic interface slots. * I can't believe you did this * Did you know that organic interface code didn't clean up it's defines? Neither did I! * Less ifs * Apply last suggestion that I know how to * That was a lie * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA I HAVEN'T EVEN TOUCHED THE WORST CODE * Oops * Pain * No copypaste * Proc is 🦀 * No, bad, no commenting code. * List prittification for chems, reduces the sheer amount of update_body calls * Allow non-lewd empath users to not have to suffer raunchy inspect messages * Oop * DEEEEEEEEEEEEFINES * Oh yea, that review. Definitely remembered. * Formatting * Breast defines * MUCH cleaner and MUCH MUCH EASIER to expand incubus draft code * Credit myself if I'm gonna spend days of my time combing through this * Oops * Chems cleanup * Whyyyyyyy * Climax rework, suffering. * Wtf is this name * Oh yea, arousal clamping. * Haha, oops * Bad, this is stupid easy to modularize * Why is body_size in here * List formatting, grammar stuff, and also breast size is now letters * This took too long for me to figure out and I'm not proud * Even I can make shitcode! * Oops, typo * You know, this makes more sense. * Mhhh, this shouldn't be named like this * Wrong file * Rename `adjustPain` * Dead code go yeet * Y U NO READ DOCS * Doc proc, minor optimisation * Reviews part 1 * Whoever made this should read good coding practices. For any language. * DEEEEFINNNEEEEESSSS * SUFFER * No more fluids * EEEEEEEEEEE * AAAAAAAAAAAAAAA * MOB IS 🦀 * AAAAAAAAAAAAAAAAAA * AAAAAA * UWA * And also solve tastfish's reviews! * Partial revert, cause DM hates that * I am very smart * EEE * AAAAAA * Haha keyboard go click clack * CODE * FUCK * FUUUUUCK * PERFORMANCE * Reset horny to 0 if erp disabled * Arousal minimum is now 0, cause negatives are dumb and I hate them Also cuts out some code that isn't needed as far as I can tell. * Apply suggestions! Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> * AAAAA * AAAAAAAAAA I CAN'T CODE * Aaaaa * WHY GIT * I am very smart part... uh, four? * Minor formatting changes * Oops, fix potential cause of multiple climax attempts * WAIT, WHY AREN'T YOU USING THE DEFINE?! * Magic number slightly less magicky, sorta. Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
This commit is contained in:
co-authored by
GoldenAlpharex
parent
4ece9155a6
commit
f58cf51ae4
@@ -61,22 +61,8 @@
|
||||
/// Legcuff slot (bolas, beartraps)
|
||||
#define ITEM_SLOT_LEGCUFFED (1<<19)
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP UPDATE
|
||||
/// Penis slot
|
||||
#define ITEM_SLOT_PENIS (1<<20)
|
||||
/// Vagina slot
|
||||
#define ITEM_SLOT_VAGINA (1<<21)
|
||||
/// Anus slot
|
||||
#define ITEM_SLOT_ANUS (1<<22)
|
||||
/// Nipples slot
|
||||
#define ITEM_SLOT_NIPPLES (1<<23)
|
||||
//SKYRATE EDIT ADDITION END
|
||||
|
||||
/// Total amount of slots
|
||||
//SKYRAT EDIT CHANGE BEGIN
|
||||
// #define SLOTS_AMT 20 // Keep this up to date! - SKYRAT EDIT - ORIGINAL
|
||||
#define SLOTS_AMT 24 // Keep this up to date!
|
||||
//SKYRAT EDIT CHANGE END
|
||||
#define SLOTS_AMT 20 // Keep this up to date!
|
||||
|
||||
//SLOT GROUP HELPERS
|
||||
#define ITEM_SLOT_POCKETS (ITEM_SLOT_LPOCKET|ITEM_SLOT_RPOCKET)
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
#define ORGAN_SLOT_TESTICLES "testicles"
|
||||
#define ORGAN_SLOT_BREASTS "breasts"
|
||||
#define ORGAN_SLOT_ANUS "anus"
|
||||
#define ORGAN_SLOT_NIPPLES "nipples"
|
||||
|
||||
#define ORGAN_SLOT_WINGS "wings"
|
||||
|
||||
@@ -4,3 +4,9 @@
|
||||
#define STYLE_TAUR_HOOF (1<<4)
|
||||
#define STYLE_TAUR_ALL (STYLE_TAUR_SNAKE|STYLE_TAUR_PAW|STYLE_TAUR_HOOF)
|
||||
#define STYLE_TESHARI (1<<6) //teshari clothes and shit
|
||||
|
||||
// We don't use the HUD for these, they have their own menu.
|
||||
#define LEWD_SLOT_VAGINA (1<<0)
|
||||
#define LEWD_SLOT_PENIS (1<<1)
|
||||
#define LEWD_SLOT_ANUS (1<<2)
|
||||
#define LEWD_SLOT_NIPPLES (1<<3)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/// To prevent an issue with stupidly low negative values.
|
||||
#define AROUSAL_MINIMUM 0
|
||||
#define AROUSAL_MINIMUM_DETECTABLE 10
|
||||
#define AROUSAL_LOW 30
|
||||
#define AROUSAL_MEDIUM 70
|
||||
#define AROUSAL_HIGH 85
|
||||
#define AROUSAL_AUTO_CLIMAX_THRESHOLD 90
|
||||
#define AROUSAL_LIMIT 100
|
||||
|
||||
#define REQUIRE_GENITAL_EXPOSED 1
|
||||
#define REQUIRE_GENITAL_UNEXPOSED 2
|
||||
#define REQUIRE_GENITAL_ANY 3
|
||||
|
||||
#define TRAIT_MASOCHISM "masochism"
|
||||
#define TRAIT_SADISM "sadism"
|
||||
#define TRAIT_NEVERBONER "neverboner"
|
||||
#define TRAIT_BIMBO "bimbo"
|
||||
#define TRAIT_RIGGER "rigger"
|
||||
#define TRAIT_ROPEBUNNY "rope bunny"
|
||||
///traits gained by brain traumas, can be removed if the brain trauma is gone
|
||||
#define APHRO_TRAIT "aphro"
|
||||
///traits gained by quirks, cannot be removed unless the quirk itself is gone
|
||||
#define LEWDQUIRK_TRAIT "lewdquirks"
|
||||
///traits gained by chemicals, you get the idea
|
||||
#define LEWDCHEM_TRAIT "lewdchem"
|
||||
|
||||
#define STRAPON_TRAIT "strapon"
|
||||
|
||||
#define CONDOM_BROKEN "broken"
|
||||
|
||||
#define BREAST_SIZE_FLATCHESTED "Flatchested"
|
||||
#define BREAST_SIZE_A "A"
|
||||
#define BREAST_SIZE_B "B"
|
||||
#define BREAST_SIZE_C "C"
|
||||
#define BREAST_SIZE_D "D"
|
||||
// Ouch, my back.
|
||||
#define BREAST_SIZE_E "E"
|
||||
#define BREAST_SIZE_F "F"
|
||||
#define BREAST_SIZE_G "G"
|
||||
#define BREAST_SIZE_H "H"
|
||||
#define BREAST_SIZE_I "I"
|
||||
#define BREAST_SIZE_J "J"
|
||||
#define BREAST_SIZE_K "K"
|
||||
#define BREAST_SIZE_L "L"
|
||||
#define BREAST_SIZE_M "M"
|
||||
#define BREAST_SIZE_N "N"
|
||||
#define BREAST_SIZE_O "O"
|
||||
#define BREAST_SIZE_P "P"
|
||||
#define BREAST_SIZE_BEYOND_MEASUREMENT "beyond measurement"
|
||||
@@ -244,14 +244,6 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,
|
||||
if(ITEM_SLOT_LEGCUFFED)
|
||||
return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(ITEM_SLOT_PENIS, ITEM_SLOT_VAGINA, ITEM_SLOT_ANUS)
|
||||
return BODY_ZONE_PRECISE_GROIN
|
||||
|
||||
if(ITEM_SLOT_NIPPLES)
|
||||
return BODY_ZONE_CHEST
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
/proc/heat2colour(temp)
|
||||
return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp))
|
||||
|
||||
@@ -223,9 +223,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list(
|
||||
pull_icon = null
|
||||
|
||||
QDEL_LIST(toggleable_inventory)
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
QDEL_LIST(erp_toggleable_inventory) // Destroy ERP stuff
|
||||
//SKYRAT EDIT ADDITION END
|
||||
QDEL_LIST(hotkeybuttons)
|
||||
throw_icon = null
|
||||
QDEL_LIST(infodisplay)
|
||||
@@ -321,10 +318,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list(
|
||||
screenmob.client.screen += static_inventory
|
||||
if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown)
|
||||
screenmob.client.screen += toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(erp_toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.ERP_inventory_shown && screenmob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
screenmob.client.screen += erp_toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION END
|
||||
if(hotkeybuttons.len && !hotkey_ui_hidden)
|
||||
screenmob.client.screen += hotkeybuttons
|
||||
if(infodisplay.len)
|
||||
@@ -341,10 +334,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list(
|
||||
screenmob.client.screen -= static_inventory
|
||||
if(toggleable_inventory.len)
|
||||
screenmob.client.screen -= toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(erp_toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.ERP_inventory_shown && screenmob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
screenmob.client.screen -= erp_toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION END
|
||||
if(hotkeybuttons.len)
|
||||
screenmob.client.screen -= hotkeybuttons
|
||||
if(infodisplay.len)
|
||||
@@ -365,10 +354,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list(
|
||||
screenmob.client.screen -= static_inventory
|
||||
if(toggleable_inventory.len)
|
||||
screenmob.client.screen -= toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.ERP_inventory_shown && screenmob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
screenmob.client.screen -= erp_toggleable_inventory
|
||||
//SKYRAT EDIT ADDITION END
|
||||
if(hotkeybuttons.len)
|
||||
screenmob.client.screen -= hotkeybuttons
|
||||
if(infodisplay.len)
|
||||
@@ -430,21 +415,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list(
|
||||
ui_style = new_ui_style
|
||||
build_hand_slots()
|
||||
|
||||
//SKYRAT EDIT - ADDITION - ERP ICONS FIX
|
||||
|
||||
/datum/hud/proc/update_erp_ui_style(new_erp_ui_style)
|
||||
// do nothing if overridden by a subtype or already on that style
|
||||
if (initial(erp_ui_style) || erp_ui_style == new_erp_ui_style)
|
||||
return
|
||||
|
||||
for(var/atom/item in erp_toggleable_inventory)
|
||||
if (item.icon == erp_ui_style)
|
||||
item.icon = new_erp_ui_style
|
||||
|
||||
erp_ui_style = new_erp_ui_style
|
||||
|
||||
//SKYRAT EDIT - ADDITION - ERP ICONS FIX - END
|
||||
|
||||
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
|
||||
/mob/verb/button_pressed_F12()
|
||||
set name = "F12"
|
||||
|
||||
@@ -21,37 +21,6 @@
|
||||
usr.hud_used.inventory_shown = TRUE
|
||||
usr.client.screen += targetmob.hud_used.toggleable_inventory
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(usr.hud_used.inventory_shown && targetmob.hud_used)
|
||||
for (var/atom/movable/screen/human/using in targetmob.hud_used.static_inventory)
|
||||
if(using.screen_loc == ui_erp_inventory)
|
||||
using.screen_loc = ui_erp_inventory_up // Move up ERP inventory button
|
||||
for (var/atom/movable/screen/inventory/inv in targetmob.hud_used.erp_toggleable_inventory)
|
||||
// Move up ERP hud slots
|
||||
if(inv.screen_loc == ui_vagina_down)
|
||||
inv.screen_loc = ui_vagina
|
||||
if(inv.screen_loc == ui_anus_down)
|
||||
inv.screen_loc = ui_anus
|
||||
if(inv.screen_loc == ui_nipples_down)
|
||||
inv.screen_loc = ui_nipples
|
||||
if(inv.screen_loc == ui_penis_down)
|
||||
inv.screen_loc = ui_penis
|
||||
else
|
||||
for (var/atom/movable/screen/human/using in targetmob.hud_used.static_inventory)
|
||||
if(using.screen_loc == ui_erp_inventory_up)
|
||||
using.screen_loc = ui_erp_inventory // Move down ERP inventory button
|
||||
for (var/atom/movable/screen/inventory/inv in targetmob.hud_used.erp_toggleable_inventory)
|
||||
// Move up ERP hud slots
|
||||
if(inv.screen_loc == ui_vagina)
|
||||
inv.screen_loc = ui_vagina_down
|
||||
if(inv.screen_loc == ui_anus)
|
||||
inv.screen_loc = ui_anus_down
|
||||
if(inv.screen_loc == ui_nipples)
|
||||
inv.screen_loc = ui_nipples_down
|
||||
if(inv.screen_loc == ui_penis)
|
||||
inv.screen_loc = ui_penis_down
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
targetmob.hud_used.hidden_inventory_update(usr)
|
||||
|
||||
/atom/movable/screen/human/equip
|
||||
@@ -233,17 +202,6 @@
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
using = new /atom/movable/screen/human/erp_toggle()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_erp_inventory
|
||||
using.hud = src
|
||||
// When creating a character, we will check if the ERP is enabled on the client, if not, then the ERP button is immediately invisible
|
||||
if(!owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
using.invisibility = 100
|
||||
static_inventory += using
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
using = new /atom/movable/screen/human/equip()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_equip_position(mymob)
|
||||
@@ -305,44 +263,6 @@
|
||||
inv_box.hud = src
|
||||
static_inventory += inv_box
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
inv_box = new /atom/movable/screen/inventory()
|
||||
inv_box.name = "vagina"
|
||||
inv_box.icon = erp_ui_style
|
||||
inv_box.icon_state = "vagina"
|
||||
inv_box.screen_loc = ui_vagina_down
|
||||
inv_box.slot_id = ITEM_SLOT_VAGINA
|
||||
inv_box.hud = src
|
||||
erp_toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /atom/movable/screen/inventory()
|
||||
inv_box.name = "anus"
|
||||
inv_box.icon = erp_ui_style
|
||||
inv_box.icon_state = "anus"
|
||||
inv_box.screen_loc = ui_anus_down
|
||||
inv_box.slot_id = ITEM_SLOT_ANUS
|
||||
inv_box.hud = src
|
||||
erp_toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /atom/movable/screen/inventory()
|
||||
inv_box.name = "nipples"
|
||||
inv_box.icon = erp_ui_style
|
||||
inv_box.icon_state = "nipples"
|
||||
inv_box.screen_loc = ui_nipples_down
|
||||
inv_box.slot_id = ITEM_SLOT_NIPPLES
|
||||
inv_box.hud = src
|
||||
erp_toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /atom/movable/screen/inventory()
|
||||
inv_box.name = "penis"
|
||||
inv_box.icon = erp_ui_style
|
||||
inv_box.icon_state = "penis"
|
||||
inv_box.screen_loc = ui_penis_down
|
||||
inv_box.slot_id = ITEM_SLOT_PENIS
|
||||
inv_box.hud = src
|
||||
erp_toggleable_inventory += inv_box
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
throw_icon = new /atom/movable/screen/throw_catch()
|
||||
throw_icon.icon = ui_style
|
||||
throw_icon.screen_loc = ui_drop_throw
|
||||
@@ -461,42 +381,6 @@
|
||||
if(H.wear_neck) screenmob.client.screen -= H.wear_neck
|
||||
if(H.head) screenmob.client.screen -= H.head
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(screenmob.hud_used.ERP_inventory_shown && screenmob.hud_used.hud_shown && H.client.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(H.vagina)
|
||||
// This shity code need for hanlde an moving UI stuff when default inventory expand/collapse
|
||||
if(screenmob.hud_used.inventory_shown && screenmob.hud_used)
|
||||
H.vagina.screen_loc = ui_vagina
|
||||
else
|
||||
H.vagina.screen_loc = ui_vagina_down
|
||||
screenmob.client.screen += H.vagina
|
||||
if(H.anus)
|
||||
if(screenmob.hud_used.inventory_shown && screenmob.hud_used)
|
||||
H.anus.screen_loc = ui_anus
|
||||
else
|
||||
H.anus.screen_loc = ui_anus_down
|
||||
screenmob.client.screen += H.anus
|
||||
if(H.nipples)
|
||||
if(screenmob.hud_used.inventory_shown && screenmob.hud_used)
|
||||
H.nipples.screen_loc = ui_nipples
|
||||
else
|
||||
H.nipples.screen_loc = ui_nipples_down
|
||||
screenmob.client.screen += H.nipples
|
||||
if(H.penis)
|
||||
if(screenmob.hud_used.inventory_shown && screenmob.hud_used)
|
||||
H.penis.screen_loc = ui_penis
|
||||
else
|
||||
H.penis.screen_loc = ui_penis_down
|
||||
screenmob.client.screen += H.penis
|
||||
else
|
||||
if(H.vagina) screenmob.client.screen -= H.vagina
|
||||
if(H.anus) screenmob.client.screen -= H.anus
|
||||
if(H.nipples) screenmob.client.screen -= H.nipples
|
||||
if(H.penis) screenmob.client.screen -= H.penis
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
|
||||
|
||||
/datum/hud/human/persistent_inventory_update(mob/viewer)
|
||||
if(!mymob)
|
||||
return
|
||||
@@ -526,22 +410,6 @@
|
||||
H.r_store.screen_loc = ui_storage2
|
||||
screenmob.client.screen += H.r_store
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(H.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(H.vagina)
|
||||
H.vagina.screen_loc = ui_vagina
|
||||
screenmob.client.screen += H.vagina
|
||||
if(H.anus)
|
||||
H.anus.screen_loc = ui_anus
|
||||
screenmob.client.screen += H.anus
|
||||
if(H.nipples)
|
||||
H.nipples.screen_loc = ui_nipples
|
||||
screenmob.client.screen += H.nipples
|
||||
if(H.penis)
|
||||
H.penis.screen_loc = ui_penis
|
||||
screenmob.client.screen += H.penis
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
else
|
||||
if(H.s_store)
|
||||
screenmob.client.screen -= H.s_store
|
||||
@@ -556,17 +424,6 @@
|
||||
if(H.r_store)
|
||||
screenmob.client.screen -= H.r_store
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(H.vagina)
|
||||
screenmob.client.screen -= H.vagina
|
||||
if(H.anus)
|
||||
screenmob.client.screen -= H.anus
|
||||
if(H.nipples)
|
||||
screenmob.client.screen -= H.nipples
|
||||
if(H.penis)
|
||||
screenmob.client.screen -= H.penis
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
if(hud_version != HUD_STYLE_NOHUD)
|
||||
for(var/obj/item/I in H.held_items)
|
||||
I.screen_loc = ui_hand_position(H.get_held_index_of_item(I))
|
||||
|
||||
@@ -876,17 +876,6 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
if(flags & ITEM_SLOT_NECK)
|
||||
owner.update_worn_neck()
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(flags & ITEM_SLOT_VAGINA)
|
||||
owner.update_inv_vagina()
|
||||
if(flags & ITEM_SLOT_ANUS)
|
||||
owner.update_inv_anus()
|
||||
if(flags & ITEM_SLOT_NIPPLES)
|
||||
owner.update_inv_nipples()
|
||||
if(flags & ITEM_SLOT_PENIS)
|
||||
owner.update_inv_penis()
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
///Returns the temperature of src. If you want to know if an item is hot use this proc.
|
||||
/obj/item/proc/get_temperature()
|
||||
return heat
|
||||
|
||||
@@ -24,4 +24,3 @@
|
||||
|
||||
/datum/preference/choiced/ui_style/apply_to_client(client/client, value)
|
||||
client.mob?.hud_used?.update_ui_style(ui_style2icon(value))
|
||||
client.mob?.hud_used?.update_erp_ui_style(erp_ui_style2icon(value)) //SKYRAT EDIT - ADDITION - ERP ICONS FIX
|
||||
|
||||
@@ -473,7 +473,7 @@
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
for(var/genital in list("penis", "testicles", "vagina", "breasts", "anus"))
|
||||
for(var/genital in possible_genitals)
|
||||
if(dna.species.mutant_bodyparts[genital])
|
||||
var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]]
|
||||
if(G)
|
||||
|
||||
@@ -25,16 +25,6 @@
|
||||
return r_store
|
||||
if(ITEM_SLOT_SUITSTORE)
|
||||
return s_store
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(ITEM_SLOT_VAGINA)
|
||||
return vagina
|
||||
if(ITEM_SLOT_ANUS)
|
||||
return anus
|
||||
if(ITEM_SLOT_NIPPLES)
|
||||
return nipples
|
||||
if(ITEM_SLOT_PENIS)
|
||||
return penis
|
||||
//SKYRAT EDIT ADDITION END
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_slot_by_item(obj/item/looking_for)
|
||||
@@ -175,13 +165,6 @@
|
||||
|
||||
if(I.flags_inv & HIDEJUMPSUIT)
|
||||
update_worn_undersuit()
|
||||
//SKYRAT EDIT ADDITION - ERP UPDATE
|
||||
if(I.flags_inv & HIDESEXTOY)
|
||||
update_inv_anus()
|
||||
update_inv_vagina()
|
||||
update_inv_penis()
|
||||
update_inv_nipples()
|
||||
//SKYRAT EDIT ADDITION END
|
||||
if(wear_suit.breakouttime) //when equipping a straightjacket
|
||||
ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
|
||||
stop_pulling() //can't pull if restrained
|
||||
@@ -205,44 +188,6 @@
|
||||
s_store = I
|
||||
update_suit_storage()
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(ITEM_SLOT_PENIS)
|
||||
if(src.is_bottomless())
|
||||
if(penis)
|
||||
return
|
||||
penis = I
|
||||
update_inv_penis()
|
||||
else
|
||||
to_chat(usr, "[src] is not bottomless, you cannot access [usr == src ? "your" : src.p_their()] penis!")
|
||||
|
||||
if(ITEM_SLOT_VAGINA)
|
||||
if(src.is_bottomless())
|
||||
if(vagina)
|
||||
return
|
||||
vagina = I
|
||||
update_inv_vagina()
|
||||
else
|
||||
to_chat(usr, "[src] is not bottomless, you cannot access [usr == src ? "your" : src.p_their()] vagina!")
|
||||
|
||||
if(ITEM_SLOT_ANUS)
|
||||
if(src.is_bottomless())
|
||||
if(anus)
|
||||
return
|
||||
anus = I
|
||||
update_inv_anus()
|
||||
else
|
||||
to_chat(usr, "[src] is not bottomless, you cannot access [usr == src ? "your" : src.p_their()] anus!")
|
||||
|
||||
if(ITEM_SLOT_NIPPLES)
|
||||
if(src.is_topless())
|
||||
if(nipples)
|
||||
return
|
||||
nipples = I
|
||||
update_inv_nipples()
|
||||
else
|
||||
to_chat(usr, "[src] is not topless, you cannot access [usr == src ? "your" : src.p_their()] nipples!")
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
else
|
||||
to_chat(src, span_danger("You are trying to equip this item to an unsupported inventory slot. Report this to a coder!"))
|
||||
|
||||
@@ -281,12 +226,9 @@
|
||||
if(I.flags_inv & HIDEJUMPSUIT)
|
||||
update_worn_undersuit()
|
||||
|
||||
// SKYRAT EDIT ADDITION START
|
||||
// SKYRAT EDIT ADDITION START - ERP Overlays
|
||||
if(I.flags_inv & HIDESEXTOY)
|
||||
update_inv_anus()
|
||||
update_inv_vagina()
|
||||
update_inv_penis()
|
||||
update_inv_nipples()
|
||||
update_inv_lewd()
|
||||
// SKYRAT EDIT ADDITION END
|
||||
|
||||
update_worn_oversuit()
|
||||
@@ -358,25 +300,6 @@
|
||||
if(!QDELETED(src))
|
||||
update_suit_storage()
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
else if(I == vagina)
|
||||
vagina = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_vagina()
|
||||
else if(I == anus)
|
||||
anus = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_anus()
|
||||
else if(I == nipples)
|
||||
nipples = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_nipples()
|
||||
else if(I == penis)
|
||||
penis = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_penis()
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
update_equipment_speed_mods()
|
||||
|
||||
// Send a signal for when we unequip an item that used to cover our feet/shoes. Used for bloody feet
|
||||
|
||||
@@ -987,30 +987,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - ERP_SLOT_SYSTEM
|
||||
if(ITEM_SLOT_VAGINA)
|
||||
if(H.is_bottomless())
|
||||
if(H.getorganslot(ORGAN_SLOT_VAGINA))
|
||||
return equip_delay_self_check(I, H, bypass_equip_delay_self)
|
||||
return FALSE
|
||||
return FALSE
|
||||
if(ITEM_SLOT_ANUS)
|
||||
if(H.is_bottomless())
|
||||
if(H.getorganslot(ORGAN_SLOT_ANUS))
|
||||
return equip_delay_self_check(I, H, bypass_equip_delay_self)
|
||||
return FALSE
|
||||
if(ITEM_SLOT_NIPPLES)
|
||||
if(H.is_topless())
|
||||
return equip_delay_self_check(I, H, bypass_equip_delay_self)
|
||||
return FALSE
|
||||
if(ITEM_SLOT_PENIS)
|
||||
if(H.is_bottomless())
|
||||
if(H.getorganslot(ORGAN_SLOT_PENIS))
|
||||
return equip_delay_self_check(I, H, bypass_equip_delay_self)
|
||||
return FALSE
|
||||
return FALSE
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
return FALSE //Unsupported slot
|
||||
|
||||
/datum/species/proc/equip_delay_self_check(obj/item/I, mob/living/carbon/human/H, bypass_equip_delay_self)
|
||||
@@ -1402,6 +1378,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
H.update_damage_overlays()
|
||||
else//no bodypart, we deal damage with a more general method.
|
||||
H.adjustBruteLoss(damage_amount)
|
||||
INVOKE_ASYNC(H, /mob/living/carbon/human/.proc/adjust_pain, damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
|
||||
if(BURN)
|
||||
H.damageoverlaytemp = 20
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
|
||||
@@ -1410,6 +1387,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
H.update_damage_overlays()
|
||||
else
|
||||
H.adjustFireLoss(damage_amount)
|
||||
INVOKE_ASYNC(H, /mob/living/carbon/human/.proc/adjust_pain, damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
|
||||
if(TOX)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
|
||||
H.adjustToxLoss(damage_amount)
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
if(hud_used)
|
||||
hud_used.show_hud(hud_used.hud_version)
|
||||
hud_used.update_ui_style(ui_style2icon(client.prefs?.read_preference(/datum/preference/choiced/ui_style)))
|
||||
hud_used.update_erp_ui_style(erp_ui_style2icon(client.prefs?.read_preference(/datum/preference/choiced/ui_style))) //SKYRAT EDIT - ADDITION - ERP ICONS FIX
|
||||
|
||||
next_move = 1
|
||||
|
||||
|
||||
@@ -212,14 +212,6 @@ Primarily used in reagents/reaction_agents
|
||||
|
||||
/// Called when an overdose starts
|
||||
/datum/reagent/proc/overdose_start(mob/living/M)
|
||||
///SKYRAT EDIT ADDITION: Because these chemicals shouldn't bear the same weight as normal / debatably more harmful chemicals.
|
||||
if(name == "dopamine")///This one also shouldn't have any negative mood effect.
|
||||
return
|
||||
if(name == "succubus milk" || name == "incubus draft" || name == "Camphor" || name == "Pentacamphor")
|
||||
to_chat(M, span_userdanger("You feel like you took too much [name]!"))
|
||||
M.add_mood_event("[type]_overdose", /datum/mood_event/minor_overdose, name)
|
||||
return
|
||||
///SKYRAT EDIT END
|
||||
to_chat(M, span_userdanger("You feel like you took too much of [name]!"))
|
||||
M.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/datum/preference/numeric/body_size
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "body_size"
|
||||
minimum = BODY_SIZE_MIN
|
||||
maximum = BODY_SIZE_MAX
|
||||
step = 0.01
|
||||
|
||||
/datum/preference/numeric/body_size/is_accessible(datum/preferences/preferences)
|
||||
var/passed_initial_check = ..(preferences)
|
||||
return passed_initial_check
|
||||
|
||||
/datum/preference/numeric/body_size/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["body_size"] = value
|
||||
|
||||
/datum/preference/numeric/body_size/create_default_value()
|
||||
return BODY_SIZE_NORMAL
|
||||
@@ -53,9 +53,35 @@
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/datum/preference/toggle/erp/apply_to_client_updated(client/client, value)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = client?.mob
|
||||
if(!value && istype(target))
|
||||
target.arousal = 0
|
||||
target.pain = 0
|
||||
target.pleasure = 0
|
||||
|
||||
/datum/preference/toggle/erp/sex_toy
|
||||
savefile_key = "sextoy_pref"
|
||||
|
||||
/datum/preference/toggle/erp/sex_toy/apply_to_client_updated(client/client, value)
|
||||
apply_to_client(client, value)
|
||||
if(!value)
|
||||
if(ishuman(client.mob))
|
||||
var/mob/living/carbon/human/target = client.mob
|
||||
if(target.vagina != null)
|
||||
target.dropItemToGround(target.vagina, TRUE, target.loc, TRUE, FALSE, TRUE)
|
||||
if(target.anus != null)
|
||||
target.dropItemToGround(target.anus, TRUE, target.loc, TRUE, FALSE, TRUE)
|
||||
if(target.nipples != null)
|
||||
target.dropItemToGround(target.nipples, TRUE, target.loc, TRUE, FALSE, TRUE)
|
||||
if(target.penis != null)
|
||||
target.dropItemToGround(target.penis, TRUE, target.loc, TRUE, FALSE, TRUE)
|
||||
|
||||
|
||||
client.mob.hud_used.hidden_inventory_update(client.mob)
|
||||
client.mob.hud_used.persistent_inventory_update(client.mob)
|
||||
|
||||
/datum/preference/toggle/erp/bimbofication
|
||||
savefile_key = "bimbofication_pref"
|
||||
|
||||
@@ -77,6 +103,9 @@
|
||||
/datum/preference/toggle/erp/autoemote
|
||||
savefile_key = "autoemote_pref"
|
||||
|
||||
/datum/preference/toggle/erp/new_genitalia_growth
|
||||
savefile_key = "new_genitalia_growth_pref"
|
||||
|
||||
/datum/preference/choiced/erp_status
|
||||
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
|
||||
+38
-57
@@ -95,7 +95,7 @@
|
||||
|
||||
/datum/preference/choiced/genital/penis
|
||||
savefile_key = "feature_penis"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
|
||||
/datum/preference/choiced/genital/penis/create_default_value()
|
||||
var/datum/sprite_accessory/genital/penis/none/default = /datum/sprite_accessory/genital/penis/none
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/penis
|
||||
savefile_key = "penis_skin_tone"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
genital_pref_type = /datum/preference/choiced/genital/penis
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/penis/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/penis
|
||||
savefile_key = "penis_skin_color"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
genital_pref_type = /datum/preference/choiced/genital/penis
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/penis/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -121,7 +121,7 @@
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "penis_length"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
minimum = PENIS_MIN_LENGTH
|
||||
maximum = PENIS_MAX_LENGTH
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "penis_girth"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
minimum = PENIS_MIN_LENGTH
|
||||
maximum = PENIS_MAX_GIRTH
|
||||
|
||||
@@ -159,13 +159,13 @@
|
||||
|
||||
/datum/preference/tri_color/genital/penis
|
||||
savefile_key = "penis_color"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
type_to_check = /datum/preference/choiced/genital/penis
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/penis
|
||||
|
||||
/datum/preference/tri_bool/genital/penis
|
||||
savefile_key = "penis_emissive"
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
type_to_check = /datum/preference/choiced/genital/penis
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/penis
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "penis_taur_mode_toggle"
|
||||
default_value = FALSE
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
|
||||
/datum/preference/toggle/penis_taur_mode/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
target.dna.features["penis_taur"] = value
|
||||
@@ -191,7 +191,7 @@
|
||||
savefile_key = "penis_sheath"
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
relevant_mutant_bodypart = "penis"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_PENIS
|
||||
|
||||
/datum/preference/choiced/penis_sheath/is_accessible(datum/preferences/preferences)
|
||||
var/passed_initial_check = ..(preferences)
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
/datum/preference/choiced/genital/testicles
|
||||
savefile_key = "feature_testicles"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
|
||||
/datum/preference/choiced/genital/testicles/create_default_value()
|
||||
var/datum/sprite_accessory/genital/testicles/none/default = /datum/sprite_accessory/genital/testicles/none
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/testicles
|
||||
savefile_key = "testicles_skin_tone"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
genital_pref_type = /datum/preference/choiced/genital/testicles
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/testicles/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/testicles
|
||||
savefile_key = "testicles_skin_color"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
genital_pref_type = /datum/preference/choiced/genital/testicles
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/testicles/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -236,13 +236,13 @@
|
||||
|
||||
/datum/preference/tri_color/genital/testicles
|
||||
savefile_key = "testicles_color"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
type_to_check = /datum/preference/choiced/genital/testicles
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/testicles
|
||||
|
||||
/datum/preference/tri_bool/genital/testicles
|
||||
savefile_key = "testicles_emissive"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
type_to_check = /datum/preference/choiced/genital/testicles
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/testicles
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "balls_size"
|
||||
relevant_mutant_bodypart = "testicles"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES
|
||||
minimum = 0
|
||||
maximum = 3
|
||||
|
||||
@@ -270,11 +270,11 @@
|
||||
|
||||
/datum/preference/choiced/genital/vagina
|
||||
savefile_key = "feature_vagina"
|
||||
relevant_mutant_bodypart = "vagina"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_VAGINA
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/vagina
|
||||
savefile_key = "vagina_skin_tone"
|
||||
relevant_mutant_bodypart = "vagina"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_VAGINA
|
||||
genital_pref_type = /datum/preference/choiced/genital/vagina
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/vagina/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -282,7 +282,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/vagina
|
||||
savefile_key = "vagina_skin_color"
|
||||
relevant_mutant_bodypart = "vagina"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_VAGINA
|
||||
genital_pref_type = /datum/preference/choiced/genital/vagina
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/vagina/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -294,13 +294,13 @@
|
||||
|
||||
/datum/preference/tri_color/genital/vagina
|
||||
savefile_key = "vagina_color"
|
||||
relevant_mutant_bodypart = "vagina"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_VAGINA
|
||||
type_to_check = /datum/preference/choiced/genital/vagina
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/vagina
|
||||
|
||||
/datum/preference/tri_bool/genital/vagina
|
||||
savefile_key = "vagina_emissive"
|
||||
relevant_mutant_bodypart = "vagina"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_VAGINA
|
||||
type_to_check = /datum/preference/choiced/genital/vagina
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/vagina
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
|
||||
/datum/preference/choiced/genital/womb
|
||||
savefile_key = "feature_womb"
|
||||
relevant_mutant_bodypart = "womb"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_WOMB
|
||||
|
||||
/datum/preference/choiced/genital/womb/create_default_value()
|
||||
var/datum/sprite_accessory/genital/womb/none/default = /datum/sprite_accessory/genital/womb/none
|
||||
@@ -318,7 +318,7 @@
|
||||
|
||||
/datum/preference/choiced/genital/breasts
|
||||
savefile_key = "feature_breasts"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
|
||||
/datum/preference/choiced/genital/breasts/create_default_value()
|
||||
var/datum/sprite_accessory/genital/breasts/none/default = /datum/sprite_accessory/genital/breasts/none
|
||||
@@ -326,7 +326,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/breasts
|
||||
savefile_key = "breasts_skin_tone"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
genital_pref_type = /datum/preference/choiced/genital/breasts
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone/breasts/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -334,7 +334,7 @@
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/breasts
|
||||
savefile_key = "breasts_skin_color"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
genital_pref_type = /datum/preference/choiced/genital/breasts
|
||||
|
||||
/datum/preference/toggle/genital_skin_color/breasts/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
@@ -342,13 +342,13 @@
|
||||
|
||||
/datum/preference/tri_color/genital/breasts
|
||||
savefile_key = "breasts_color"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
type_to_check = /datum/preference/choiced/genital/breasts
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/breasts
|
||||
|
||||
/datum/preference/tri_bool/genital/breasts
|
||||
savefile_key = "breasts_emissive"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
type_to_check = /datum/preference/choiced/genital/breasts
|
||||
skin_color_type = /datum/preference/toggle/genital_skin_color/breasts
|
||||
|
||||
@@ -357,7 +357,7 @@
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "breasts_lactation_toggle"
|
||||
default_value = FALSE
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
|
||||
/datum/preference/toggle/breasts_lactation/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||
target.dna.features["breasts_lactation"] = value
|
||||
@@ -368,52 +368,33 @@
|
||||
var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/breasts))
|
||||
return part_enabled && (passed_initial_check || allowed)
|
||||
|
||||
/datum/preference/numeric/breasts_size
|
||||
/datum/preference/choiced/breasts_size
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "breasts_size"
|
||||
relevant_mutant_bodypart = "breasts"
|
||||
minimum = 0
|
||||
maximum = 16
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_BREASTS
|
||||
|
||||
/datum/preference/numeric/breasts_size/is_accessible(datum/preferences/preferences)
|
||||
/datum/preference/choiced/breasts_size/init_possible_values()
|
||||
return GLOB.preference_breast_sizes
|
||||
|
||||
/datum/preference/choiced/breasts_size/is_accessible(datum/preferences/preferences)
|
||||
var/passed_initial_check = ..(preferences)
|
||||
var/allowed = preferences.read_preference(/datum/preference/toggle/allow_mismatched_parts)
|
||||
var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/breasts))
|
||||
return ((passed_initial_check || allowed) && part_enabled)
|
||||
|
||||
/datum/preference/numeric/breasts_size/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["breasts_size"] = value
|
||||
/datum/preference/choiced/breasts_size/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["breasts_size"] = GLOB.breast_size_to_number[value]
|
||||
|
||||
/datum/preference/numeric/breasts_size/create_default_value()
|
||||
return 4
|
||||
/datum/preference/choiced/breasts_size/create_default_value()
|
||||
return BREAST_SIZE_C
|
||||
|
||||
// ANUS
|
||||
|
||||
/datum/preference/choiced/genital/anus
|
||||
savefile_key = "feature_anus"
|
||||
relevant_mutant_bodypart = "anus"
|
||||
relevant_mutant_bodypart = ORGAN_SLOT_ANUS
|
||||
|
||||
/datum/preference/choiced/genital/anus/create_default_value()
|
||||
var/datum/sprite_accessory/genital/anus/none/default = /datum/sprite_accessory/genital/anus/none
|
||||
return initial(default.name)
|
||||
|
||||
// OTHER
|
||||
|
||||
/datum/preference/numeric/body_size
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
savefile_key = "body_size"
|
||||
minimum = BODY_SIZE_MIN
|
||||
maximum = BODY_SIZE_MAX
|
||||
step = 0.01
|
||||
|
||||
/datum/preference/numeric/body_size/is_accessible(datum/preferences/preferences)
|
||||
var/passed_initial_check = ..(preferences)
|
||||
return passed_initial_check
|
||||
|
||||
/datum/preference/numeric/body_size/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["body_size"] = value
|
||||
|
||||
/datum/preference/numeric/body_size/create_default_value()
|
||||
return BODY_SIZE_NORMAL
|
||||
@@ -3,7 +3,7 @@
|
||||
* You can't really use the non-modular version, least you eventually want asinine merge
|
||||
* conflicts and/or potentially disastrous issues to arise, so here's your own.
|
||||
*/
|
||||
#define MODULAR_SAVEFILE_VERSION_MAX 1
|
||||
#define MODULAR_SAVEFILE_VERSION_MAX 2
|
||||
|
||||
#define MODULAR_SAVEFILE_UP_TO_DATE -1
|
||||
|
||||
@@ -110,6 +110,13 @@
|
||||
for(var/pref_type in subtypesof(/datum/preference/toggle/genital_skin_tone))
|
||||
write_preference(GLOB.preference_entries[pref_type], TRUE)
|
||||
|
||||
if(current_version < 2)
|
||||
var/list/old_breast_prefs
|
||||
READ_FILE(save["breasts_size"], old_breast_prefs)
|
||||
if(old_breast_prefs) // Can't be too careful
|
||||
// You weren't meant to be able to pick sizes over this anyways.
|
||||
write_preference(GLOB.preference_entries[/datum/preference/choiced/breasts_size], min(GLOB.breast_size_translation["[old_breast_prefs]"], 10))
|
||||
|
||||
/datum/preferences/proc/check_migration()
|
||||
if(!tgui_prefs_migration)
|
||||
to_chat(parent, examine_block(span_redtext("CRITICAL FAILURE IN PREFERENCE MIGRATION, REPORT THIS IMMEDIATELY.")))
|
||||
|
||||
@@ -1,67 +1,115 @@
|
||||
//DO NOT CHANGE THOSE LISTS UNLESS YOU KNOW WHAT YOURE DOING (will mess savefiles)
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(breasts_size_translation, list("0" = "Flatchested",
|
||||
"1" = "A",
|
||||
"2" = "B",
|
||||
"3" = "C",
|
||||
"4" = "D",
|
||||
"5" = "E",
|
||||
"6" = "F",
|
||||
"7" = "G",
|
||||
"8" = "H",
|
||||
"9" = "I",
|
||||
"10" = "J",
|
||||
"11" = "K",
|
||||
"12" = "L",
|
||||
"13" = "M",
|
||||
"14" = "N",
|
||||
"15" = "O",
|
||||
"16" = "P",
|
||||
))
|
||||
GLOBAL_LIST_INIT(breast_size_translation, list(
|
||||
"0" = BREAST_SIZE_FLATCHESTED,
|
||||
"1" = BREAST_SIZE_A,
|
||||
"2" = BREAST_SIZE_B,
|
||||
"3" = BREAST_SIZE_C,
|
||||
"4" = BREAST_SIZE_D,
|
||||
"5" = BREAST_SIZE_E,
|
||||
"6" = BREAST_SIZE_F,
|
||||
"7" = BREAST_SIZE_G,
|
||||
"8" = BREAST_SIZE_H,
|
||||
"9" = BREAST_SIZE_I,
|
||||
"10" = BREAST_SIZE_J,
|
||||
"11" = BREAST_SIZE_K, // Succubus milk moment.
|
||||
"12" = BREAST_SIZE_L,
|
||||
"13" = BREAST_SIZE_M,
|
||||
"14" = BREAST_SIZE_N,
|
||||
"15" = BREAST_SIZE_O,
|
||||
"16" = BREAST_SIZE_P,
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(balls_size_translation, list("0" = "Small",
|
||||
"1" = "Average",
|
||||
"2" = "Big",
|
||||
"3" = "Enormous"
|
||||
))
|
||||
GLOBAL_LIST_INIT(breast_size_to_number, list(
|
||||
BREAST_SIZE_FLATCHESTED = 0,
|
||||
BREAST_SIZE_A = 1,
|
||||
BREAST_SIZE_B = 2,
|
||||
BREAST_SIZE_C = 3,
|
||||
BREAST_SIZE_D = 4,
|
||||
BREAST_SIZE_E = 5,
|
||||
BREAST_SIZE_F = 6,
|
||||
BREAST_SIZE_G = 7,
|
||||
BREAST_SIZE_H = 8,
|
||||
BREAST_SIZE_I = 9,
|
||||
BREAST_SIZE_J = 10,
|
||||
BREAST_SIZE_K = 11, // Succubus milk moment.
|
||||
BREAST_SIZE_L = 12,
|
||||
BREAST_SIZE_M = 13,
|
||||
BREAST_SIZE_N = 14,
|
||||
BREAST_SIZE_O = 15,
|
||||
BREAST_SIZE_P = 16,
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(marking_zone_to_bitflag, list(BODY_ZONE_HEAD = HEAD,
|
||||
BODY_ZONE_CHEST = CHEST,
|
||||
BODY_ZONE_L_LEG = LEG_LEFT,
|
||||
BODY_ZONE_R_LEG = LEG_RIGHT,
|
||||
BODY_ZONE_L_ARM = ARM_LEFT,
|
||||
BODY_ZONE_R_ARM = ARM_RIGHT,
|
||||
BODY_ZONE_PRECISE_L_HAND = HAND_LEFT,
|
||||
BODY_ZONE_PRECISE_R_HAND = HAND_RIGHT
|
||||
))
|
||||
GLOBAL_LIST_INIT(balls_size_translation, list(
|
||||
"0" = "Small",
|
||||
"1" = "Average",
|
||||
"2" = "Big",
|
||||
"3" = "Enormous"
|
||||
))
|
||||
|
||||
//GLOBAL_LIST_INIT(marking_zones, list("Head","Chest","Left Leg","Right Leg","Left Arm","Right Arm","Left Hand","Right Hand"))
|
||||
GLOBAL_LIST_INIT(marking_zone_to_bitflag, list(
|
||||
BODY_ZONE_HEAD = HEAD,
|
||||
BODY_ZONE_CHEST = CHEST,
|
||||
BODY_ZONE_L_LEG = LEG_LEFT,
|
||||
BODY_ZONE_R_LEG = LEG_RIGHT,
|
||||
BODY_ZONE_L_ARM = ARM_LEFT,
|
||||
BODY_ZONE_R_ARM = ARM_RIGHT,
|
||||
BODY_ZONE_PRECISE_L_HAND = HAND_LEFT,
|
||||
BODY_ZONE_PRECISE_R_HAND = HAND_RIGHT
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(marking_zones, list(BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_L_LEG,BODY_ZONE_R_LEG,BODY_ZONE_L_ARM,BODY_ZONE_R_ARM,BODY_ZONE_PRECISE_L_HAND,BODY_ZONE_PRECISE_R_HAND))
|
||||
GLOBAL_LIST_INIT(marking_zones, list(
|
||||
BODY_ZONE_HEAD,
|
||||
BODY_ZONE_CHEST,
|
||||
BODY_ZONE_L_LEG,
|
||||
BODY_ZONE_R_LEG,
|
||||
BODY_ZONE_L_ARM,
|
||||
BODY_ZONE_R_ARM,
|
||||
BODY_ZONE_PRECISE_L_HAND,
|
||||
BODY_ZONE_PRECISE_R_HAND,
|
||||
))
|
||||
|
||||
///Those are the values available from prefs
|
||||
GLOBAL_LIST_INIT(preference_breast_sizes, list("Flatchested","A","B","C","D","E","F","G","H","I","J"))
|
||||
GLOBAL_LIST_INIT(preference_breast_sizes, list(
|
||||
BREAST_SIZE_FLATCHESTED,
|
||||
BREAST_SIZE_A,
|
||||
BREAST_SIZE_B,
|
||||
BREAST_SIZE_C,
|
||||
BREAST_SIZE_D,
|
||||
BREAST_SIZE_E,
|
||||
BREAST_SIZE_F,
|
||||
BREAST_SIZE_G,
|
||||
BREAST_SIZE_H,
|
||||
BREAST_SIZE_I,
|
||||
BREAST_SIZE_J,
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(preference_balls_sizes, list("Small","Average","Big","Enormous"))
|
||||
GLOBAL_LIST_INIT(preference_balls_sizes, list(
|
||||
"Small",
|
||||
"Average",
|
||||
"Big",
|
||||
"Enormous",
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(robotic_styles_list, list("None" = "None",
|
||||
"Surplus" = 'icons/mob/augmentation/surplus_augments.dmi',
|
||||
"Cyborg" = 'icons/mob/augmentation/augments.dmi',
|
||||
"Engineering" = 'icons/mob/augmentation/augments_engineer.dmi',
|
||||
"Mining" = 'icons/mob/augmentation/augments_mining.dmi',
|
||||
"Security" = 'icons/mob/augmentation/augments_security.dmi',
|
||||
"Morpheus Cyberkinetics" = 'modular_skyrat/master_files/icons/mob/augmentation/mcgipc.dmi',
|
||||
"Bishop Cyberkinetics" = 'modular_skyrat/master_files/icons/mob/augmentation/bshipc.dmi',
|
||||
"Bishop Cyberkinetics 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/bs2ipc.dmi',
|
||||
"Hephaestus Industries" = 'modular_skyrat/master_files/icons/mob/augmentation/hsiipc.dmi',
|
||||
"Hephaestus Industries 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/hi2ipc.dmi',
|
||||
"Shellguard Munitions Standard Series" = 'modular_skyrat/master_files/icons/mob/augmentation/sgmipc.dmi',
|
||||
"Ward-Takahashi Manufacturing" = 'modular_skyrat/master_files/icons/mob/augmentation/wtmipc.dmi',
|
||||
"Xion Manufacturing Group" = 'modular_skyrat/master_files/icons/mob/augmentation/xmgipc.dmi',
|
||||
"Xion Manufacturing Group 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/xm2ipc.dmi',
|
||||
"Zeng-Hu Pharmaceuticals" = 'modular_skyrat/master_files/icons/mob/augmentation/zhpipc.dmi'
|
||||
))
|
||||
GLOBAL_LIST_INIT(robotic_styles_list, list(
|
||||
"None" = "None",
|
||||
"Surplus" = 'icons/mob/augmentation/surplus_augments.dmi',
|
||||
"Cyborg" = 'icons/mob/augmentation/augments.dmi',
|
||||
"Engineering" = 'icons/mob/augmentation/augments_engineer.dmi',
|
||||
"Mining" = 'icons/mob/augmentation/augments_mining.dmi',
|
||||
"Security" = 'icons/mob/augmentation/augments_security.dmi',
|
||||
"Morpheus Cyberkinetics" = 'modular_skyrat/master_files/icons/mob/augmentation/mcgipc.dmi',
|
||||
"Bishop Cyberkinetics" = 'modular_skyrat/master_files/icons/mob/augmentation/bshipc.dmi',
|
||||
"Bishop Cyberkinetics 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/bs2ipc.dmi',
|
||||
"Hephaestus Industries" = 'modular_skyrat/master_files/icons/mob/augmentation/hsiipc.dmi',
|
||||
"Hephaestus Industries 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/hi2ipc.dmi',
|
||||
"Shellguard Munitions Standard Series" = 'modular_skyrat/master_files/icons/mob/augmentation/sgmipc.dmi',
|
||||
"Ward-Takahashi Manufacturing" = 'modular_skyrat/master_files/icons/mob/augmentation/wtmipc.dmi',
|
||||
"Xion Manufacturing Group" = 'modular_skyrat/master_files/icons/mob/augmentation/xmgipc.dmi',
|
||||
"Xion Manufacturing Group 2.0" = 'modular_skyrat/master_files/icons/mob/augmentation/xm2ipc.dmi',
|
||||
"Zeng-Hu Pharmaceuticals" = 'modular_skyrat/master_files/icons/mob/augmentation/zhpipc.dmi'
|
||||
))
|
||||
|
||||
//ghoul colors
|
||||
GLOBAL_LIST_INIT(color_list_ghoul, list( \
|
||||
|
||||
+6
-6
@@ -35,7 +35,7 @@
|
||||
icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/penis_onmob.dmi'
|
||||
organ_type = /obj/item/organ/external/genital/penis
|
||||
associated_organ_slot = ORGAN_SLOT_PENIS
|
||||
key = "penis"
|
||||
key = ORGAN_SLOT_PENIS
|
||||
color_src = USE_MATRIXED_COLORS
|
||||
always_color_customizable = TRUE
|
||||
center = TRUE
|
||||
@@ -117,7 +117,7 @@
|
||||
icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/testicles_onmob.dmi'
|
||||
organ_type = /obj/item/organ/external/genital/testicles
|
||||
associated_organ_slot = ORGAN_SLOT_TESTICLES
|
||||
key = "testicles"
|
||||
key = ORGAN_SLOT_TESTICLES
|
||||
always_color_customizable = TRUE
|
||||
special_icon_case = TRUE
|
||||
special_x_dimension = TRUE
|
||||
@@ -168,7 +168,7 @@
|
||||
icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/vagina_onmob.dmi'
|
||||
organ_type = /obj/item/organ/external/genital/vagina
|
||||
associated_organ_slot = ORGAN_SLOT_VAGINA
|
||||
key = "vagina"
|
||||
key = ORGAN_SLOT_VAGINA
|
||||
always_color_customizable = TRUE
|
||||
default_color = "#FFCCCC"
|
||||
relevent_layers = list(BODY_FRONT_LAYER)
|
||||
@@ -224,7 +224,7 @@
|
||||
/datum/sprite_accessory/genital/womb
|
||||
organ_type = /obj/item/organ/external/genital/womb
|
||||
associated_organ_slot = ORGAN_SLOT_WOMB
|
||||
key = "womb"
|
||||
key = ORGAN_SLOT_WOMB
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/womb/none
|
||||
@@ -241,7 +241,7 @@
|
||||
/datum/sprite_accessory/genital/anus
|
||||
organ_type = /obj/item/organ/external/genital/anus
|
||||
associated_organ_slot = ORGAN_SLOT_ANUS
|
||||
key = "anus"
|
||||
key = ORGAN_SLOT_ANUS
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/anus/is_hidden(mob/living/carbon/human/owner, obj/item/bodypart/bodypart)
|
||||
@@ -264,7 +264,7 @@
|
||||
icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/breasts_onmob.dmi'
|
||||
organ_type = /obj/item/organ/external/genital/breasts
|
||||
associated_organ_slot = ORGAN_SLOT_BREASTS
|
||||
key = "breasts"
|
||||
key = ORGAN_SLOT_BREASTS
|
||||
always_color_customizable = TRUE
|
||||
default_color = DEFAULT_SKIN_OR_PRIMARY
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/mob/living/carbon/human
|
||||
var/static/list/possible_genitals = list(ORGAN_SLOT_PENIS, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_VAGINA, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS)
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
@@ -5,7 +8,7 @@
|
||||
switch(href_list["lookup_info"])
|
||||
if("genitals")
|
||||
var/list/line = list()
|
||||
for(var/genital in list("penis", "testicles", "vagina", "breasts", "anus"))
|
||||
for(var/genital in possible_genitals)
|
||||
if(!dna.species.mutant_bodyparts[genital])
|
||||
continue
|
||||
var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]]
|
||||
|
||||
@@ -262,12 +262,12 @@ GLOBAL_LIST_EMPTY(customizable_races)
|
||||
/datum/species/New()
|
||||
. = ..()
|
||||
if(can_have_genitals)
|
||||
default_mutant_bodyparts["vagina"] = "None"
|
||||
default_mutant_bodyparts["womb"] = "None"
|
||||
default_mutant_bodyparts["testicles"] = "None"
|
||||
default_mutant_bodyparts["breasts"] = "None"
|
||||
default_mutant_bodyparts["anus"] = "None"
|
||||
default_mutant_bodyparts["penis"] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_VAGINA] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_WOMB] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_TESTICLES] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_BREASTS] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_ANUS] = "None"
|
||||
default_mutant_bodyparts[ORGAN_SLOT_PENIS] = "None"
|
||||
|
||||
/datum/species/dullahan
|
||||
mutant_bodyparts = list()
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/penis.dmi'
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_PENIS
|
||||
mutantpart_key = "penis"
|
||||
mutantpart_key = ORGAN_SLOT_PENIS
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Human", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB"))
|
||||
drop_when_organ_spilling = FALSE
|
||||
var/girth = 9
|
||||
@@ -181,7 +181,7 @@
|
||||
uses_skintones = accessory.has_skintone_shading
|
||||
|
||||
/obj/item/organ/external/genital/penis/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["penis"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_PENIS]
|
||||
|
||||
|
||||
/obj/item/organ/external/genital/testicles
|
||||
@@ -189,7 +189,7 @@
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "testicles"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/testicles.dmi'
|
||||
mutantpart_key = "testicles"
|
||||
mutantpart_key = ORGAN_SLOT_TESTICLES
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Pair", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB"))
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_TESTICLES
|
||||
@@ -228,7 +228,7 @@
|
||||
return passed_string
|
||||
|
||||
/obj/item/organ/external/genital/testicles/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["testicles"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_TESTICLES]
|
||||
|
||||
|
||||
/obj/item/organ/external/genital/testicles/proc/balls_size_to_description(number)
|
||||
@@ -236,7 +236,7 @@
|
||||
number = 0
|
||||
var/returned = GLOB.balls_size_translation["[number]"]
|
||||
if(!returned)
|
||||
returned = "beyond measurement"
|
||||
returned = BREAST_SIZE_BEYOND_MEASUREMENT
|
||||
return returned
|
||||
|
||||
/obj/item/organ/external/genital/testicles/proc/balls_description_to_size(cup)
|
||||
@@ -250,7 +250,7 @@
|
||||
name = "vagina"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = "vagina"
|
||||
mutantpart_key = "vagina"
|
||||
mutantpart_key = ORGAN_SLOT_VAGINA
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Human", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB"))
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_VAGINA
|
||||
@@ -285,7 +285,7 @@
|
||||
uses_skintones = accessory.has_skintone_shading
|
||||
|
||||
/obj/item/organ/external/genital/vagina/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["vagina"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_VAGINA]
|
||||
|
||||
|
||||
/obj/item/organ/external/genital/womb
|
||||
@@ -293,7 +293,7 @@
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/vagina.dmi'
|
||||
icon_state = "womb"
|
||||
mutantpart_key = "womb"
|
||||
mutantpart_key = ORGAN_SLOT_WOMB
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Normal", MUTANT_INDEX_COLOR_LIST = list("FFEEBB"))
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_WOMB
|
||||
@@ -303,7 +303,7 @@
|
||||
drop_when_organ_spilling = FALSE
|
||||
|
||||
/obj/item/organ/external/genital/womb/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["womb"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_WOMB]
|
||||
|
||||
|
||||
/obj/item/organ/external/genital/anus
|
||||
@@ -311,7 +311,7 @@
|
||||
desc = "What do you want me to tell you?"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/anus.dmi'
|
||||
icon_state = "anus"
|
||||
mutantpart_key = "anus"
|
||||
mutantpart_key = ORGAN_SLOT_ANUS
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Normal", MUTANT_INDEX_COLOR_LIST = list("FEB"))
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_ANUS
|
||||
@@ -327,7 +327,7 @@
|
||||
return returned_string
|
||||
|
||||
/obj/item/organ/external/genital/anus/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["anus"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_ANUS]
|
||||
|
||||
|
||||
/obj/item/organ/external/genital/breasts
|
||||
@@ -336,7 +336,7 @@
|
||||
icon_state = "breasts"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/genitals/breasts.dmi'
|
||||
genital_type = "pair"
|
||||
mutantpart_key = "breasts"
|
||||
mutantpart_key = ORGAN_SLOT_BREASTS
|
||||
mutantpart_info = list(MUTANT_INDEX_NAME = "Pair", MUTANT_INDEX_COLOR_LIST = list("#FFEEBB"))
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_BREASTS
|
||||
@@ -349,9 +349,9 @@
|
||||
var/size_description
|
||||
var/translation = breasts_size_to_cup(genital_size)
|
||||
switch(translation)
|
||||
if("Flatchested")
|
||||
if(BREAST_SIZE_FLATCHESTED)
|
||||
size_description = " They are small and flat, however."
|
||||
if("beyond measurement")
|
||||
if(BREAST_SIZE_BEYOND_MEASUREMENT)
|
||||
size_description = " Their size is enormous, you estimate they're around [genital_size] inches in diameter."
|
||||
else
|
||||
size_description = " You estimate they are [translation]-cups."
|
||||
@@ -400,19 +400,19 @@
|
||||
uses_skintones = accessory.has_skintone_shading
|
||||
|
||||
/obj/item/organ/external/genital/breasts/get_global_feature_list()
|
||||
return GLOB.sprite_accessories["breasts"]
|
||||
return GLOB.sprite_accessories[ORGAN_SLOT_BREASTS]
|
||||
|
||||
/obj/item/organ/external/genital/breasts/proc/breasts_size_to_cup(number)
|
||||
if(number < 0)
|
||||
number = 0
|
||||
var/returned = GLOB.breasts_size_translation["[number]"]
|
||||
var/returned = GLOB.breast_size_translation["[number]"]
|
||||
if(!returned)
|
||||
returned = "beyond measurement"
|
||||
returned = BREAST_SIZE_BEYOND_MEASUREMENT
|
||||
return returned
|
||||
|
||||
/obj/item/organ/external/genital/breasts/proc/breasts_cup_to_size(cup)
|
||||
for(var/key in GLOB.breasts_size_translation)
|
||||
if(GLOB.breasts_size_translation[key] == cup)
|
||||
for(var/key in GLOB.breast_size_translation)
|
||||
if(GLOB.breast_size_translation[key] == cup)
|
||||
return text2num(key)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -505,9 +505,9 @@
|
||||
log_data += "Sex: [iterating_human.gender]"
|
||||
log_data += "Age: [iterating_human.age]"
|
||||
log_data += "Body Type: [iterating_human.physique]"
|
||||
log_data += "Penis: [iterating_human.dna.mutant_bodyparts["penis"]["name"]]"
|
||||
log_data += "Vagina: [iterating_human.dna.mutant_bodyparts["vagina"]["name"]]"
|
||||
log_data += "Breasts: [iterating_human.dna.mutant_bodyparts["breasts"]["name"]]"
|
||||
log_data += "Penis: [iterating_human.dna.mutant_bodyparts[ORGAN_SLOT_PENIS]["name"]]"
|
||||
log_data += "Vagina: [iterating_human.dna.mutant_bodyparts[ORGAN_SLOT_VAGINA]["name"]]"
|
||||
log_data += "Breasts: [iterating_human.dna.mutant_bodyparts[ORGAN_SLOT_BREASTS]["name"]]"
|
||||
log_data += "Body size: [iterating_human.dna.features["body_size"]]"
|
||||
log_data += "END ENTRY"
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
return TRUE
|
||||
|
||||
/// UI Control
|
||||
|
||||
/datum/component/interactable/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
@@ -95,8 +94,39 @@
|
||||
data["self"] = self.name
|
||||
data["block_interact"] = interact_next >= world.time
|
||||
data["interactions"] = categories
|
||||
|
||||
var/list/parts = list()
|
||||
|
||||
if(ishuman(user) && can_lewd_strip(user, self))
|
||||
if(self.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(self.has_vagina())
|
||||
parts += list(generate_strip_entry(ORGAN_SLOT_VAGINA, self, user, self.vagina))
|
||||
if(self.has_penis())
|
||||
parts += list(generate_strip_entry(ORGAN_SLOT_PENIS, self, user, self.penis))
|
||||
if(self.has_anus())
|
||||
parts += list(generate_strip_entry(ORGAN_SLOT_ANUS, self, user, self.anus))
|
||||
parts += list(generate_strip_entry(ORGAN_SLOT_NIPPLES, self, user, self.nipples))
|
||||
|
||||
data["lewd_slots"] = parts
|
||||
|
||||
return data
|
||||
|
||||
/**
|
||||
* Takes the organ slot name, along with a target and source, along with the item on the target that the source can potentially interact with.
|
||||
* If the source can't interact with said slot, or there is no item in the first place, it'll set the icon to null to indicate that TGUI should put a placeholder sprite.
|
||||
*
|
||||
* Arguments:
|
||||
* * name - The name of slot to check and return inside the generated list.
|
||||
* * target - The mob that's being interacted with.
|
||||
* * source - The mob that's interacting.
|
||||
* * item - The item that's currently inside said slot. Can be null.
|
||||
*/
|
||||
/datum/component/interactable/proc/generate_strip_entry(name, mob/living/carbon/human/target, mob/living/carbon/human/source, obj/item/clothing/sextoy/item)
|
||||
return list(
|
||||
"name" = name,
|
||||
"img" = (item && can_lewd_strip(source, target, name)) ? icon2base64(icon(item.icon, item.icon_state, SOUTH, 1)) : null
|
||||
)
|
||||
|
||||
/datum/component/interactable/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -113,4 +143,85 @@
|
||||
interact_next = interaction_component.interact_last + INTERACTION_COOLDOWN
|
||||
interaction_component.interact_next = interact_next
|
||||
return TRUE
|
||||
|
||||
if(params["item_slot"])
|
||||
// This code should be easy enough to follow... I hope.
|
||||
var/item_index = params["item_slot"]
|
||||
var/mob/living/carbon/human/source = locate(params["userref"])
|
||||
var/mob/living/carbon/human/target = locate(params["selfref"])
|
||||
var/obj/item/new_item = source.get_active_held_item()
|
||||
var/obj/item/existing_item = target.vars[item_index]
|
||||
|
||||
if(!existing_item && !new_item)
|
||||
source.show_message(span_warning("No item to insert or remove!"))
|
||||
return
|
||||
|
||||
if(!existing_item && !istype(new_item, /obj/item/clothing/sextoy))
|
||||
source.show_message(span_warning("The item you're holding is not a toy!"))
|
||||
return
|
||||
|
||||
if(can_lewd_strip(source, target, item_index) && is_toy_compatible(new_item, item_index))
|
||||
var/internal = (item_index in list(ORGAN_SLOT_VAGINA, ORGAN_SLOT_ANUS))
|
||||
var/insert_or_attach = internal ? "insert" : "attach"
|
||||
var/into_or_onto = internal ? "into" : "onto"
|
||||
|
||||
if(existing_item)
|
||||
source.visible_message(span_purple("[source.name] starts trying to remove something from [target.name]'s [item_index]."), span_purple("You start to remove [existing_item.name] from [target.name]'s [item_index]."), span_purple("You hear someone trying to remove something from someone nearby."), vision_distance = 1, ignored_mobs = list(target))
|
||||
else if (new_item)
|
||||
source.visible_message(span_purple("[source.name] starts trying to [insert_or_attach] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You start to [insert_or_attach] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You hear someone trying to [insert_or_attach] something [into_or_onto] someone nearby."), vision_distance = 1, ignored_mobs = list(target))
|
||||
if (source != target)
|
||||
target.show_message(span_warning("[source.name] is trying to [existing_item ? "remove the [existing_item.name] [internal ? "in" : "on"]" : new_item ? "is trying to [insert_or_attach] the [new_item.name] [into_or_onto]" : span_alert("What the fuck, impossible condition? interaction_component.dm!")] your [item_index]!"))
|
||||
if(do_after(
|
||||
source,
|
||||
5 SECONDS,
|
||||
target,
|
||||
interaction_key = "interation_[item_index]"
|
||||
) && can_lewd_strip(source, target, item_index))
|
||||
|
||||
if(existing_item)
|
||||
source.visible_message(span_purple("[source.name] removes [existing_item.name] from [target.name]'s [item_index]."), span_purple("You remove [existing_item.name] from [target.name]'s [item_index]."), span_purple("You hear someone remove something from someone nearby."), vision_distance = 1)
|
||||
target.dropItemToGround(existing_item, force = TRUE) // Force is true, cause nodrop shouldn't affect lewd items.
|
||||
target.vars[item_index] = null
|
||||
else if (new_item)
|
||||
source.visible_message(span_purple("[source.name] [internal ? "inserts" : "attaches"] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You [insert_or_attach] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You hear someone [insert_or_attach] something [into_or_onto] someone nearby."), vision_distance = 1)
|
||||
target.vars[item_index] = new_item
|
||||
new_item.forceMove(target)
|
||||
target.update_inv_lewd()
|
||||
|
||||
else
|
||||
source.show_message(span_warning("Failed to adjust [target.name]'s toys!"))
|
||||
|
||||
return TRUE
|
||||
|
||||
message_admins("Unhandled interaction '[params["interaction"]]'. Inform coders.")
|
||||
|
||||
/// Checks if the target has ERP toys enabled, and can be logially reached by the user.
|
||||
/datum/component/interactable/proc/can_lewd_strip(mob/living/carbon/human/source, mob/living/carbon/human/target, slot_index)
|
||||
if(!target.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return FALSE
|
||||
if(!(source.loc == target.loc || source.Adjacent(target)))
|
||||
return FALSE
|
||||
if(!source.has_arms())
|
||||
return FALSE
|
||||
if(!slot_index) // This condition is for the UI to decide if the button is shown at all. Slot index should never be null otherwise.
|
||||
return TRUE
|
||||
if(slot_index == ORGAN_SLOT_NIPPLES && !target.is_topless())
|
||||
return FALSE
|
||||
return target.is_bottomless()
|
||||
|
||||
/// Decides if a player should be able to insert or remove an item from a provided lewd slot_index.
|
||||
/datum/component/interactable/proc/is_toy_compatible(obj/item/clothing/sextoy/item, slot_index)
|
||||
if(!item) // Used for UI code, should never be actually null during actual logic code.
|
||||
return TRUE
|
||||
|
||||
switch(slot_index)
|
||||
if(ORGAN_SLOT_VAGINA)
|
||||
return item.lewd_slot_flags & LEWD_SLOT_VAGINA
|
||||
if(ORGAN_SLOT_PENIS)
|
||||
return item.lewd_slot_flags & LEWD_SLOT_PENIS
|
||||
if(ORGAN_SLOT_ANUS)
|
||||
return item.lewd_slot_flags & LEWD_SLOT_ANUS
|
||||
if(ORGAN_SLOT_NIPPLES)
|
||||
return item.lewd_slot_flags & LEWD_SLOT_NIPPLES
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -119,12 +119,12 @@ GLOBAL_LIST_EMPTY_TYPED(interaction_instances, /datum/interaction)
|
||||
SEND_SOUND(sound_cache, mob)
|
||||
|
||||
if(lewd)
|
||||
user.adjustPleasure(user_pleasure)
|
||||
user.adjustArousal(user_arousal)
|
||||
user.adjustPain(user_pain)
|
||||
target.adjustPleasure(target_pleasure)
|
||||
target.adjustArousal(target_arousal)
|
||||
target.adjustPain(target_pain)
|
||||
user.adjust_pleasure(user_pleasure)
|
||||
user.adjust_arousal(user_arousal)
|
||||
user.adjust_pain(user_pain)
|
||||
target.adjust_pleasure(target_pleasure)
|
||||
target.adjust_arousal(target_arousal)
|
||||
target.adjust_pain(target_pain)
|
||||
|
||||
/datum/interaction/proc/load_from_json(path)
|
||||
var/fpath = path
|
||||
|
||||
@@ -1,880 +0,0 @@
|
||||
#define AROUS_SYS_LITTLE 30
|
||||
#define AROUS_SYS_STRONG 70
|
||||
#define AROUS_SYS_READYTOCUM 90
|
||||
#define PAIN_SYS_LIMIT 50
|
||||
#define PLEAS_SYS_EDGE 85
|
||||
|
||||
#define CUM_MALE 1
|
||||
#define CUM_FEMALE 2
|
||||
// #define ITEM_SLOT_PENIS (1<<20)
|
||||
|
||||
#define TRAIT_MASOCHISM "masochism"
|
||||
#define TRAIT_SADISM "sadism"
|
||||
#define TRAIT_NEVERBONER "neverboner"
|
||||
#define TRAIT_BIMBO "bimbo"
|
||||
#define TRAIT_RIGGER "rigger"
|
||||
#define TRAIT_ROPEBUNNY "rope bunny"
|
||||
#define APHRO_TRAIT "aphro" ///traits gained by brain traumas, can be removed if the brain trauma is gone
|
||||
#define LEWDQUIRK_TRAIT "lewdquirks" ///traits gained by quirks, cannot be removed unless the quirk itself is gone
|
||||
#define LEWDCHEM_TRAIT "lewdchem" ///traits gained by chemicals, you get the idea
|
||||
|
||||
#define STRAPON_TRAIT "strapon"
|
||||
|
||||
/*
|
||||
* DECALS
|
||||
*/
|
||||
|
||||
/obj/effect/decal/cleanable/cum
|
||||
name = "cum"
|
||||
desc = "Ew... Gross."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_decals/lewd_decals.dmi'
|
||||
icon_state = "cum_1"
|
||||
random_icon_states = list("cum_1", "cum_2", "cum_3", "cum_4")
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/cum/femcum
|
||||
name = "female cum"
|
||||
desc = "Uhh... Someone had fun..."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_decals/lewd_decals.dmi'
|
||||
icon_state = "femcum_1"
|
||||
random_icon_states = list("femcum_1", "femcum_2", "femcum_3", "femcum_4")
|
||||
beauty = -50
|
||||
|
||||
/*
|
||||
* REAGENTS
|
||||
*/
|
||||
|
||||
/datum/reagent/consumable/girlcum
|
||||
name = "girlcum"
|
||||
description = "Uhh... Someone had fun."
|
||||
taste_description = "astringent and sweetish"
|
||||
color = "#ffffffb0"
|
||||
glass_name = "glass of girlcum"
|
||||
glass_desc = "A strange white liquid... Ew!"
|
||||
reagent_state = LIQUID
|
||||
shot_glass_icon_state = "shotglasswhite"
|
||||
|
||||
/datum/reagent/consumable/cum
|
||||
name = "cum"
|
||||
description = "A fluid secreted by the sexual organs of many species."
|
||||
taste_description = "musky and salty"
|
||||
color = "#ffffffff"
|
||||
glass_name = "glass of cum"
|
||||
glass_desc = "O-oh, my...~"
|
||||
reagent_state = LIQUID
|
||||
shot_glass_icon_state = "shotglasswhite"
|
||||
|
||||
/datum/reagent/consumable/breast_milk
|
||||
name = "breast milk"
|
||||
description = "This looks familiar... Wait, it's milk!"
|
||||
taste_description = "warm and creamy"
|
||||
color = "#ffffffff"
|
||||
glass_icon_state = "glass_white"
|
||||
glass_name = "glass of breast milk"
|
||||
glass_desc = "almost like normal milk."
|
||||
reagent_state = LIQUID
|
||||
|
||||
/datum/reagent/drug/dopamine
|
||||
name = "dopamine"
|
||||
description = "Pure happiness"
|
||||
taste_description = "passion fruit, banana and hint of apple"
|
||||
color = "#97ffee"
|
||||
glass_name = "dopamine"
|
||||
glass_desc = "A deliciously flavored reagent. You feel happy even looking at it."
|
||||
reagent_state = LIQUID
|
||||
overdose_threshold = 10
|
||||
|
||||
/datum/reagent/drug/dopamine/on_mob_add(mob/living/carbon/human/affected_mob)
|
||||
affected_mob.add_mood_event("[type]_start", /datum/mood_event/orgasm, name)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/dopamine/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
|
||||
affected_mob.set_drugginess(2 SECONDS * REM * delta_time)
|
||||
if(prob(7))
|
||||
affected_mob.try_lewd_autoemote(pick("shaking", "moan"))
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/dopamine/overdose_start(mob/living/carbon/human/human_mob)
|
||||
if(HAS_TRAIT(human_mob, TRAIT_BIMBO))
|
||||
return
|
||||
to_chat(human_mob, span_userdanger("You don't want to cum anymore!"))
|
||||
human_mob.add_mood_event("[type]_overdose", /datum/mood_event/overgasm, name)
|
||||
|
||||
/datum/reagent/drug/dopamine/overdose_process(mob/living/carbon/human/affected_mob)
|
||||
affected_mob.adjustArousal(0.5)
|
||||
affected_mob.adjustPleasure(0.3)
|
||||
affected_mob.adjustPain(-0.5)
|
||||
if(prob(2))
|
||||
affected_mob.try_lewd_autoemote(pick("moan", "twitch_s"))
|
||||
return
|
||||
|
||||
/*
|
||||
* INITIALISE
|
||||
*/
|
||||
|
||||
/obj/item/organ/external/genital
|
||||
var/datum/reagents/internal_fluids
|
||||
var/list/contained_item
|
||||
var/obj/item/inserted_item //Used for toys
|
||||
|
||||
/obj/item/organ/external/genital/breasts/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
var/breasts_count = 0
|
||||
var/size = 0.5
|
||||
if(DNA.features["breasts_size"] > 0)
|
||||
size = DNA.features["breasts_size"]
|
||||
|
||||
switch(genital_type)
|
||||
if("pair")
|
||||
breasts_count = 2
|
||||
if("quad")
|
||||
breasts_count = 2.5
|
||||
if("sextuple")
|
||||
breasts_count = 3
|
||||
internal_fluids = new /datum/reagents(size * breasts_count * 60)
|
||||
|
||||
/obj/item/organ/external/genital/testicles/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
var/size = 0.5
|
||||
if(DNA.features["balls_size"] > 0)
|
||||
size = DNA.features["balls_size"]
|
||||
|
||||
internal_fluids = new /datum/reagents(size * 20)
|
||||
|
||||
/obj/item/organ/external/genital/vagina/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
internal_fluids = new /datum/reagents(10)
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/arousal = 0
|
||||
var/pleasure = 0
|
||||
var/pain = 0
|
||||
|
||||
var/pain_limit = 0
|
||||
var/arousal_status = AROUSAL_NONE
|
||||
|
||||
/mob/living/carbon/human/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!istype(src, /mob/living/carbon/human/species/monkey))
|
||||
apply_status_effect(/datum/status_effect/aroused)
|
||||
apply_status_effect(/datum/status_effect/body_fluid_regen)
|
||||
|
||||
/*
|
||||
* VERBS
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/verb/arousal_panel()
|
||||
set name = "Climax"
|
||||
set category = "IC"
|
||||
|
||||
if(!has_status_effect(/datum/status_effect/climax_cooldown))
|
||||
if(tgui_alert(usr, "Are you sure you want to cum?", "Climax", list("Yes", "No")) == "Yes")
|
||||
if(stat != CONSCIOUS)
|
||||
to_chat(usr, span_warning("You can't climax right now..."))
|
||||
return
|
||||
else
|
||||
climax(TRUE)
|
||||
else
|
||||
to_chat(src, span_warning("You can't cum right now!"))
|
||||
|
||||
//Removing ERP IC verb depending on config
|
||||
/mob/living/carbon/human/Initialize(mapload)
|
||||
. = ..()
|
||||
if(CONFIG_GET(flag/disable_erp_preferences))
|
||||
verbs -= /mob/living/carbon/human/verb/arousal_panel
|
||||
|
||||
/*
|
||||
* FLUIDS
|
||||
*/
|
||||
|
||||
/datum/status_effect/body_fluid_regen
|
||||
id = "body fluid regen"
|
||||
tick_interval = 50
|
||||
duration = -1
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/body_fluid_regen/tick()
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
if(owner.stat != DEAD && affected_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
var/obj/item/organ/external/genital/testicles/balls = owner.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/breasts/breasts = owner.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
var/obj/item/organ/external/genital/vagina/vagina = owner.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
|
||||
var/interval = 5
|
||||
if(balls)
|
||||
if(affected_mob.arousal >= AROUS_SYS_LITTLE)
|
||||
var/regen = (affected_mob.arousal / 25) * (balls.internal_fluids.maximum_volume / 235) * interval
|
||||
balls.internal_fluids.add_reagent(/datum/reagent/consumable/cum, regen)
|
||||
|
||||
if(breasts)
|
||||
if(breasts.lactates == TRUE)
|
||||
var/regen = ((owner.nutrition / (NUTRITION_LEVEL_WELL_FED / 100)) / 100) * (breasts.internal_fluids.maximum_volume / 11000) * interval
|
||||
if(!breasts.internal_fluids.holder_full())
|
||||
owner.adjust_nutrition(-regen / 2)
|
||||
breasts.internal_fluids.add_reagent(/datum/reagent/consumable/breast_milk, regen)
|
||||
|
||||
if(vagina)
|
||||
if(affected_mob.arousal >= AROUS_SYS_LITTLE)
|
||||
var/regen = (affected_mob.arousal / 25) * (vagina.internal_fluids.maximum_volume / 250) * interval
|
||||
vagina.internal_fluids.add_reagent(/datum/reagent/consumable/girlcum, regen)
|
||||
if(vagina.internal_fluids.holder_full() && regen >= 0.15)
|
||||
regen = regen
|
||||
else
|
||||
vagina.internal_fluids.remove_any(0.05)
|
||||
|
||||
/*
|
||||
* AROUSAL
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/get_arousal()
|
||||
return arousal
|
||||
|
||||
/mob/living/carbon/human/proc/adjustArousal(arous = 0)
|
||||
if(stat != DEAD && client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
arousal += arous
|
||||
|
||||
var/arousal_flag = AROUSAL_NONE
|
||||
if(arousal >= AROUS_SYS_STRONG)
|
||||
arousal_flag = AROUSAL_FULL
|
||||
else if(arousal >= AROUS_SYS_LITTLE)
|
||||
arousal_flag = AROUSAL_PARTIAL
|
||||
|
||||
if(arousal_status != arousal_flag) // Set organ arousal status
|
||||
arousal_status = arousal_flag
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/target = src
|
||||
for(var/i = 1, i <= target.external_organs.len, i++)
|
||||
if(istype(target.external_organs[i], /obj/item/organ/external/genital))
|
||||
var/obj/item/organ/external/genital/target_genital = target.external_organs[i]
|
||||
if(!target_genital.aroused == AROUSAL_CANT)
|
||||
target_genital.aroused = arousal_status
|
||||
target_genital.update_sprite_suffix()
|
||||
target.update_body()
|
||||
else
|
||||
arousal -= abs(arous)
|
||||
|
||||
arousal = min(max(arousal, 0), 100)
|
||||
|
||||
/datum/status_effect/aroused
|
||||
id = "aroused"
|
||||
tick_interval = 10
|
||||
duration = -1
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/aroused/tick()
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
var/temp_arousal = -0.1
|
||||
var/temp_pleasure = -0.5
|
||||
var/temp_pain = -0.5
|
||||
if(affected_mob.stat != DEAD)
|
||||
|
||||
var/obj/item/organ/external/genital/testicles/balls = affected_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(balls)
|
||||
if(balls.internal_fluids.holder_full())
|
||||
temp_arousal += 0.08
|
||||
|
||||
if(HAS_TRAIT(affected_mob, TRAIT_MASOCHISM))
|
||||
temp_pain -= 0.5
|
||||
if(HAS_TRAIT(affected_mob, TRAIT_NEVERBONER))
|
||||
temp_pleasure -= 50
|
||||
temp_arousal -= 50
|
||||
|
||||
if(affected_mob.pain > affected_mob.pain_limit)
|
||||
temp_arousal -= 0.1
|
||||
if(affected_mob.arousal >= AROUS_SYS_STRONG && affected_mob.stat != DEAD)
|
||||
if(prob(3))
|
||||
affected_mob.try_lewd_autoemote(pick("moan", "blush"))
|
||||
temp_pleasure += 0.1
|
||||
//moan
|
||||
if(affected_mob.pleasure >= PLEAS_SYS_EDGE && affected_mob.stat != DEAD)
|
||||
if(prob(3))
|
||||
affected_mob.try_lewd_autoemote(pick("moan", "twitch_s"))
|
||||
//moan x2
|
||||
|
||||
affected_mob.adjustArousal(temp_arousal)
|
||||
affected_mob.adjustPleasure(temp_pleasure)
|
||||
affected_mob.adjustPain(temp_pain)
|
||||
|
||||
/*
|
||||
* PAIN
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/get_pain()
|
||||
return pain
|
||||
|
||||
/mob/living/carbon/human/proc/adjustPain(change_amount = 0)
|
||||
if(stat != DEAD && client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
if(pain > pain_limit || change_amount > pain_limit / 10) // pain system // YOUR SYSTEM IS PAIN, WHY WE'RE GETTING AROUSED BY STEPPING ON ANTS?!
|
||||
if(HAS_TRAIT(src, TRAIT_MASOCHISM))
|
||||
var/arousal_adjustment = change_amount - (pain_limit / 10)
|
||||
if(arousal_adjustment > 0)
|
||||
adjustArousal(-arousal_adjustment)
|
||||
else
|
||||
if(change_amount > 0)
|
||||
adjustArousal(-change_amount)
|
||||
if(prob(2) && pain > pain_limit && change_amount > pain_limit / 10)
|
||||
try_lewd_autoemote(pick("scream", "shiver")) //SCREAM!!!
|
||||
else
|
||||
if(change_amount > 0)
|
||||
adjustArousal(change_amount)
|
||||
if(HAS_TRAIT(src, TRAIT_MASOCHISM))
|
||||
var/pleasure_adjustment = change_amount / 2
|
||||
adjustPleasure(pleasure_adjustment)
|
||||
pain += change_amount
|
||||
else
|
||||
pain -= abs(change_amount)
|
||||
pain = min(max(pain, 0), 100)
|
||||
|
||||
/*
|
||||
* PLEASURE
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/get_pleasure()
|
||||
return pleasure
|
||||
|
||||
/mob/living/carbon/human/proc/adjustPleasure(pleas = 0)
|
||||
if(stat != DEAD && client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
pleasure += pleas
|
||||
if(pleasure >= 100) // lets cum
|
||||
climax(FALSE)
|
||||
else
|
||||
pleasure -= abs(pleas)
|
||||
pleasure = min(max(pleasure, 0), 100)
|
||||
|
||||
// Get damage for pain system
|
||||
/datum/species/apply_damage(damage, damagetype, def_zone, blocked, mob/living/carbon/human/affected_mob, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness, attack_direction)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(affected_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
var/hit_percent = (100 - (blocked + armor)) / 100
|
||||
hit_percent = (hit_percent * (100 - affected_mob.physiology.damage_resistance)) / 100
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
var/amount = forced ? damage : damage * hit_percent * brutemod * affected_mob.physiology.brute_mod
|
||||
INVOKE_ASYNC(affected_mob, /mob/living/carbon/human/.proc/adjustPain, amount)
|
||||
if(BURN)
|
||||
var/amount = forced ? damage : damage * hit_percent * burnmod * affected_mob.physiology.burn_mod
|
||||
INVOKE_ASYNC(affected_mob, /mob/living/carbon/human/.proc/adjustPain, amount)
|
||||
|
||||
/*
|
||||
* CLIMAX
|
||||
*/
|
||||
|
||||
/datum/mood_event/orgasm
|
||||
description = span_purple("Woah... This pleasant tiredness... I love it.\n")
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/datum/mood_event/climaxself
|
||||
description = span_purple("I just came in my own underwear. Messy.\n")
|
||||
timeout = 4 MINUTES
|
||||
|
||||
/datum/mood_event/overgasm
|
||||
description = span_warning("Uhh... I don't want to be horny anymore.\n") //Me too, buddy. Me too.
|
||||
timeout = 10 MINUTES
|
||||
|
||||
/mob/living/carbon/human/proc/climax(manual = TRUE)
|
||||
if (CONFIG_GET(flag/disable_erp_preferences))
|
||||
return
|
||||
|
||||
if(!client?.prefs?.read_preference(/datum/preference/toggle/erp/autocum) && manual != TRUE)
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/genital/penis/penis = getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/obj/item/organ/external/genital/testicles/testicles = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/vagina/vagina = getorganslot(ORGAN_SLOT_VAGINA)
|
||||
|
||||
if(!has_status_effect(/datum/status_effect/climax_cooldown) && client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(!HAS_TRAIT(src, TRAIT_NEVERBONER) && !has_status_effect(/datum/status_effect/climax_cooldown))
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
playsound(get_turf(src), pick('modular_skyrat/modules/modular_items/lewd_items/sounds/final_m1.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_m2.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_m3.ogg'), 50, TRUE, ignore_walls = FALSE)
|
||||
if(FEMALE)
|
||||
playsound(get_turf(src), pick('modular_skyrat/modules/modular_items/lewd_items/sounds/final_f1.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_f2.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_f3.ogg'), 50, TRUE, ignore_walls = FALSE)
|
||||
if(penis)
|
||||
if(!testicles) //If we have no god damn balls, we can't cum anywhere... GET BALLS!
|
||||
visible_message(span_userlove("[src] orgasms, but nothing comes out of [p_their()] dick!"), \
|
||||
span_userlove("You orgasm, it feels great, but nothing comes out of your dick!"))
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
add_mood_event("orgasm", /datum/mood_event/climaxself)
|
||||
return TRUE
|
||||
|
||||
if(!is_bottomless() && penis.visibility_preference != GENITAL_ALWAYS_SHOW)
|
||||
visible_message(span_userlove("[src] cums into their clothes!"), \
|
||||
span_userlove("You shoot your load, but you weren't naked, so you mess up your clothes!"))
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
add_mood_event("orgasm", /datum/mood_event/climaxself)
|
||||
return TRUE
|
||||
|
||||
var/list/interactable_inrange_humans = list()
|
||||
|
||||
for(var/mob/living/carbon/human/iterating_human in view(1, src))
|
||||
if(iterating_human == src)
|
||||
continue
|
||||
//if(iterating_human.client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
interactable_inrange_humans[iterating_human.name] = iterating_human
|
||||
|
||||
var/list/buttons = list("On the floor")
|
||||
|
||||
if(interactable_inrange_humans.len)
|
||||
buttons += "Inside/on someone"
|
||||
|
||||
var/climax_choice = tgui_alert(src, "You are cumming, choose where to shoot your load.", "Load preference!", buttons)
|
||||
|
||||
visible_message(span_purple("[src] is cumming!"), span_purple("You are cumming!"))
|
||||
|
||||
var/create_cum_decal = FALSE
|
||||
|
||||
if(!climax_choice || climax_choice == "On the floor")
|
||||
if(wear_condom())
|
||||
var/obj/item/clothing/sextoy/condom/condom = get_item_by_slot(ITEM_SLOT_PENIS)
|
||||
if(condom.condom_state == "broken")
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots [p_their()] load into [condom], sending cum onto the floor!"), \
|
||||
span_userlove("You shoot string after string of cum, but it sprays out of [condom], hitting the floor!"))
|
||||
else
|
||||
condom.condom_use()
|
||||
visible_message(span_userlove("[src] shoots [p_their()] load into [condom], filling it up!"), \
|
||||
span_userlove("You shoot your thick load into [condom] and it catches it all!"))
|
||||
else
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
else
|
||||
var/target_choice = tgui_input_list(src, "Choose a person to cum in or on~", "Choose target!", interactable_inrange_humans)
|
||||
if(!target_choice)
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
else
|
||||
var/mob/living/carbon/human/target_human = interactable_inrange_humans[target_choice]
|
||||
var/obj/item/organ/external/genital/vagina/target_vagina = target_human.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
var/obj/item/organ/external/genital/anus/target_anus = target_human.getorganslot(ORGAN_SLOT_ANUS)
|
||||
var/obj/item/organ/external/genital/penis/target_penis = target_human.getorganslot(ORGAN_SLOT_PENIS)
|
||||
|
||||
var/list/target_buttons = list()
|
||||
|
||||
if(!target_human.wear_mask)
|
||||
target_buttons += "mouth"
|
||||
|
||||
if(target_vagina && target_vagina?.is_exposed())
|
||||
target_buttons += "vagina"
|
||||
|
||||
if(target_anus && target_anus?.is_exposed())
|
||||
target_buttons += "asshole"
|
||||
|
||||
if(target_penis && target_penis.is_exposed() && target_penis.sheath != "None")
|
||||
target_buttons += "sheath"
|
||||
|
||||
target_buttons += "On them"
|
||||
|
||||
var/climax_into_choice = tgui_input_list(src, "Where on or in [target_human] do you wish to cum?", "Final frontier!", target_buttons)
|
||||
|
||||
if(!climax_into_choice)
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
else if(climax_into_choice == "On them")
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto the [target_human]!"), \
|
||||
span_userlove("You shoot string after string of hot cum onto [target_human]!"))
|
||||
else
|
||||
visible_message(span_userlove("[src] hilts [p_their()] cock into [target_human]'s [climax_into_choice], shooting cum into it!"), \
|
||||
span_userlove("You hilt your cock into [target_human]'s [climax_into_choice], shooting cum into it!"))
|
||||
to_chat(target_human, span_userlove("Your [climax_into_choice] fills with warm cum as [src] shoots [p_their()] load into it."))
|
||||
try_lewd_autoemote("moan")
|
||||
testicles.reagents.remove_all(testicles.reagents.total_volume * 0.6)
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
if(create_cum_decal)
|
||||
add_cum_splatter_floor(get_turf(src))
|
||||
return TRUE
|
||||
if(vagina)
|
||||
if(is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW)
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
visible_message(span_purple("[src] is cumming!"), span_purple("You are cumming!"))
|
||||
var/turf/our_turf = get_turf(src)
|
||||
add_cum_splatter_floor(our_turf, female = TRUE)
|
||||
else
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
visible_message(span_purple("[src] cums in their underwear!"), \
|
||||
span_purple("You cum in your underwear! Eww."))
|
||||
add_mood_event("orgasm", /datum/mood_event/climaxself)
|
||||
return TRUE
|
||||
else
|
||||
visible_message(span_purple("[src] twitches, trying to cum, but with no result."), \
|
||||
span_purple("You can't have an orgasm!"))
|
||||
return TRUE
|
||||
|
||||
// Let's not force lewd emotes from folk who don't want them, mmm~?
|
||||
/mob/living/carbon/proc/try_lewd_autoemote(emote)
|
||||
if(!client?.prefs?.read_preference(/datum/preference/toggle/erp/autoemote))
|
||||
return
|
||||
emote(emote)
|
||||
|
||||
/datum/status_effect/climax_cooldown
|
||||
id = "climax_cooldown"
|
||||
tick_interval = 10
|
||||
duration = 30 SECONDS
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/climax_cooldown/tick()
|
||||
var/obj/item/organ/external/genital/vagina/vagina = owner.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
var/obj/item/organ/external/genital/testicles/balls = owner.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/testicles/penis = owner.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/obj/item/organ/external/genital/testicles/anus = owner.getorganslot(ORGAN_SLOT_ANUS)
|
||||
|
||||
if(penis)
|
||||
penis.aroused = AROUSAL_NONE
|
||||
if(vagina)
|
||||
vagina.aroused = AROUSAL_NONE
|
||||
if(balls)
|
||||
balls.aroused = AROUSAL_NONE
|
||||
if(anus)
|
||||
anus.aroused = AROUSAL_NONE
|
||||
|
||||
/datum/status_effect/masturbation_climax
|
||||
id = "climax"
|
||||
tick_interval = 10
|
||||
duration = 50 //Multiplayer better than singleplayer mode.
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/masturbation_climax/tick() //this one should not leave decals on the floor. Used in case if character cumming in beaker.
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
if(affected_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
var/temp_arousal = -12
|
||||
var/temp_pleasure = -12
|
||||
var/temp_stamina = 8
|
||||
|
||||
owner.reagents.add_reagent(/datum/reagent/drug/dopamine, 0.3)
|
||||
owner.adjustStaminaLoss(temp_stamina)
|
||||
affected_mob.adjustArousal(temp_arousal)
|
||||
affected_mob.adjustPleasure(temp_pleasure)
|
||||
|
||||
/datum/status_effect/climax
|
||||
id = "climax"
|
||||
tick_interval = 10
|
||||
duration = 100
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/climax/tick()
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
if(affected_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
var/temp_arousal = -12
|
||||
var/temp_pleasure = -12
|
||||
var/temp_stamina = 15
|
||||
|
||||
owner.reagents.add_reagent(/datum/reagent/drug/dopamine, 0.5)
|
||||
owner.adjustStaminaLoss(temp_stamina)
|
||||
affected_mob.adjustArousal(temp_arousal)
|
||||
affected_mob.adjustPleasure(temp_pleasure)
|
||||
|
||||
/*
|
||||
* SPANKING
|
||||
*/
|
||||
|
||||
//Hips are red after spanking
|
||||
/datum/status_effect/spanked
|
||||
id = "spanked"
|
||||
duration = 300 SECONDS
|
||||
alert_type = null
|
||||
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/affected_mob = user
|
||||
if(stat != DEAD && !HAS_TRAIT(src, TRAIT_FAKEDEATH) && src != affected_mob)
|
||||
if(src != user)
|
||||
if(has_status_effect(/datum/status_effect/spanked) && is_bottomless())
|
||||
. += span_purple("[user.p_their(TRUE)] butt has a red tint to it.") + "\n"
|
||||
|
||||
//Mood boost for masochist
|
||||
/datum/mood_event/perv_spanked
|
||||
description = span_purple("Ah, yes! More! Punish me!\n")
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/*
|
||||
* SUBSPACE EFFECT
|
||||
*/
|
||||
|
||||
/datum/status_effect/subspace
|
||||
id = "subspace"
|
||||
tick_interval = 10
|
||||
duration = 5 MINUTES
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/subspace/on_apply()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.add_mood_event("subspace", /datum/mood_event/subspace)
|
||||
|
||||
/datum/status_effect/subspace/on_remove()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.clear_mood_event("subspace")
|
||||
|
||||
/datum/mood_event/subspace
|
||||
description = span_purple("Everything is so woozy... Pain feels so... Awesome.\n")
|
||||
|
||||
/datum/status_effect/ropebunny
|
||||
id = "ropebunny"
|
||||
tick_interval = 10
|
||||
duration = INFINITE
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/ropebunny/on_apply()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.add_mood_event("ropebunny", /datum/mood_event/ropebunny)
|
||||
|
||||
/datum/status_effect/ropebunny/on_remove()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.clear_mood_event("ropebunny")
|
||||
|
||||
/datum/mood_event/ropebunny
|
||||
description = span_purple("I'm tied! Cannot move! These ropes... Ah!~")
|
||||
mood_change = 0 // I don't want to doom the station to sonic-speed perverts, but still want to keep this as mood modifier.
|
||||
|
||||
/*
|
||||
* AROUSAL INDICATOR
|
||||
*/
|
||||
|
||||
/obj/item/organ/internal/brain/on_life(delta_time, times_fired) //All your horny is here *points to the head*
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/brain_owner = owner
|
||||
if(istype(brain_owner, /mob/living/carbon/human) && brain_owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(!(organ_flags & ORGAN_FAILING))
|
||||
brain_owner.dna.species.handle_arousal(brain_owner, delta_time, times_fired)
|
||||
|
||||
//screen alert
|
||||
|
||||
/atom/movable/screen/alert/aroused_x
|
||||
name = "Aroused"
|
||||
desc = "It's a little hot in here"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi'
|
||||
icon_state = "arousal_small"
|
||||
var/mutable_appearance/pain_overlay
|
||||
var/mutable_appearance/pleasure_overlay
|
||||
var/pain_level = "small"
|
||||
var/pleasure_level = "small"
|
||||
|
||||
/atom/movable/screen/alert/aroused_x/Initialize(mapload)
|
||||
.=..()
|
||||
pain_overlay = update_pain()
|
||||
pleasure_overlay = update_pleasure()
|
||||
|
||||
/atom/movable/screen/alert/aroused_x/proc/update_pain()
|
||||
if(pain_level)
|
||||
return mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi', "pain_[pain_level]")
|
||||
|
||||
/atom/movable/screen/alert/aroused_x/proc/update_pleasure()
|
||||
if(pleasure_level)
|
||||
return mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi', "pleasure_[pleasure_level]")
|
||||
|
||||
/datum/species/proc/throw_arousalalert(level, atom/movable/screen/alert/aroused_x/arousal_alert, mob/living/carbon/human/targeted_human)
|
||||
targeted_human.throw_alert("aroused", /atom/movable/screen/alert/aroused_x)
|
||||
arousal_alert?.icon_state = level
|
||||
arousal_alert?.update_icon()
|
||||
|
||||
/datum/species/proc/overlay_pain(level, atom/movable/screen/alert/aroused_x/arousal_alert)
|
||||
arousal_alert?.cut_overlay(arousal_alert.pain_overlay)
|
||||
arousal_alert?.pain_level = level
|
||||
arousal_alert?.pain_overlay = arousal_alert.update_pain()
|
||||
arousal_alert?.add_overlay(arousal_alert.pain_overlay)
|
||||
arousal_alert?.update_overlays()
|
||||
|
||||
/datum/species/proc/overlay_pleasure(level, atom/movable/screen/alert/aroused_x/arousal_alert)
|
||||
arousal_alert?.cut_overlay(arousal_alert.pleasure_overlay)
|
||||
arousal_alert?.pleasure_level = level
|
||||
arousal_alert?.pleasure_overlay = arousal_alert.update_pleasure()
|
||||
arousal_alert?.add_overlay(arousal_alert.pleasure_overlay)
|
||||
arousal_alert?.update_overlays()
|
||||
|
||||
/datum/species/proc/handle_arousal(mob/living/carbon/human/target_human, atom/movable/screen/alert/aroused_x)
|
||||
var/atom/movable/screen/alert/aroused_x/arousal_alert = target_human.alerts["aroused"]
|
||||
if(target_human.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
switch(target_human.arousal)
|
||||
if(-100 to 1)
|
||||
target_human.clear_alert("aroused", /atom/movable/screen/alert/aroused_x)
|
||||
if(1 to 25)
|
||||
throw_arousalalert("arousal_small", arousal_alert, target_human)
|
||||
if(25 to 50)
|
||||
throw_arousalalert("arousal_medium", arousal_alert, target_human)
|
||||
if(50 to 75)
|
||||
throw_arousalalert("arousal_high", arousal_alert, target_human)
|
||||
if(75 to INFINITY) //to prevent that 101 arousal that can make icon disappear or something.
|
||||
throw_arousalalert("arousal_max", arousal_alert, target_human)
|
||||
|
||||
if(target_human.arousal > 1)
|
||||
switch(target_human.pain)
|
||||
if(-100 to 1) //to prevent same thing with pain
|
||||
arousal_alert?.cut_overlay(arousal_alert.pain_overlay)
|
||||
if(1 to 25)
|
||||
overlay_pain("small", arousal_alert)
|
||||
if(25 to 50)
|
||||
overlay_pain("medium", arousal_alert)
|
||||
if(50 to 75)
|
||||
overlay_pain("high", arousal_alert)
|
||||
if(75 to INFINITY)
|
||||
overlay_pain("max", arousal_alert)
|
||||
|
||||
if(target_human.arousal > 1)
|
||||
switch(target_human.pleasure)
|
||||
if(-100 to 1) //to prevent same thing with pleasure
|
||||
arousal_alert?.cut_overlay(arousal_alert.pleasure_overlay)
|
||||
if(1 to 25)
|
||||
overlay_pleasure("small", arousal_alert)
|
||||
if(25 to 60)
|
||||
overlay_pleasure("medium", arousal_alert)
|
||||
if(60 to 85)
|
||||
overlay_pleasure("high", arousal_alert)
|
||||
if(85 to INFINITY)
|
||||
overlay_pleasure("max", arousal_alert)
|
||||
else
|
||||
if(arousal_alert?.pleasure_level in list("small", "medium", "high", "max"))
|
||||
arousal_alert.cut_overlay(arousal_alert.pleasure_overlay)
|
||||
if(arousal_alert?.pain_level in list("small", "medium", "high", "max"))
|
||||
arousal_alert.cut_overlay(arousal_alert.pain_overlay)
|
||||
|
||||
/datum/emote/living/cum
|
||||
key = "cum"
|
||||
key_third_person = "cums"
|
||||
cooldown = 30 SECONDS
|
||||
|
||||
/datum/emote/living/cum/check_config()
|
||||
return !CONFIG_GET(flag/disable_erp_preferences)
|
||||
|
||||
/datum/emote/living/cum/can_run_emote(mob/user, status_check = TRUE, intentional = FALSE)
|
||||
if (!check_config())
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/datum/emote/living/cum/run_emote(mob/living/user, params, type_override, intentional)
|
||||
if (!check_config())
|
||||
return
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
|
||||
var/obj/item/coomer = new /obj/item/hand_item/coom(user)
|
||||
var/mob/living/carbon/human/target = user
|
||||
var/obj/item/held = user.get_active_held_item()
|
||||
var/obj/item/unheld = user.get_inactive_held_item()
|
||||
if(user.put_in_hands(coomer) && target.dna.species.mutant_bodyparts["testicles"] && target.dna.species.mutant_bodyparts["penis"])
|
||||
if(held || unheld)
|
||||
if(!((held.name == "cum" && held.item_flags == DROPDEL | ABSTRACT | HAND_ITEM) || (unheld.name == "cum" && unheld.item_flags == DROPDEL | ABSTRACT | HAND_ITEM)))
|
||||
to_chat(user, span_notice("You mentally prepare yourself to masturbate."))
|
||||
else
|
||||
qdel(coomer)
|
||||
else
|
||||
to_chat(user, span_notice("You mentally prepare yourself to masturbate."))
|
||||
else
|
||||
qdel(coomer)
|
||||
to_chat(user, span_warning("You're incapable of masturbating."))
|
||||
|
||||
/obj/item/hand_item/coom
|
||||
name = "cum"
|
||||
desc = "C-can I watch...?"
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "eggplant"
|
||||
inhand_icon_state = "nothing"
|
||||
|
||||
/obj/item/hand_item/coom/attack(mob/living/target, mob/user, proximity)
|
||||
if (CONFIG_GET(flag/disable_erp_preferences))
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(!ishuman(target))
|
||||
return
|
||||
if(user.stat == DEAD)
|
||||
return
|
||||
var/mob/living/carbon/human/human_cumvictim = target
|
||||
if(!human_cumvictim.client)
|
||||
to_chat(user, span_warning("You can't cum onto [target]."))
|
||||
return
|
||||
var/mob/living/carbon/human/affected_human = user
|
||||
var/obj/item/organ/external/genital/testicles/testicles = affected_human.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/penis/penis = affected_human.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/datum/sprite_accessory/genital/penis_accessory = GLOB.sprite_accessories["penis"][affected_human.dna.species.mutant_bodyparts["penis"][MUTANT_INDEX_NAME]]
|
||||
if(penis_accessory.is_hidden(affected_human))
|
||||
to_chat(user, span_notice("You need to expose yourself in order to masturbate."))
|
||||
return
|
||||
else if(penis.aroused != AROUSAL_FULL)
|
||||
to_chat(user, span_notice("You need to be aroused in order to masturbate."))
|
||||
return
|
||||
var/cum_volume = testicles.genital_size * 5 + 5
|
||||
var/datum/reagents/applied_reagents = new/datum/reagents(50)
|
||||
applied_reagents.add_reagent(/datum/reagent/consumable/cum, cum_volume)
|
||||
if(target == user)
|
||||
user.visible_message(span_warning("[user] starts masturbating onto [target.p_them()]self!"), span_danger("You start masturbating onto yourself!"))
|
||||
else
|
||||
user.visible_message(span_warning("[user] starts masturbating onto [target]!"), span_danger("You start masturbating onto [target]!"))
|
||||
if(do_after(user, 60, target))
|
||||
if(target == user)
|
||||
user.visible_message(span_warning("[user] cums on [target.p_them()]self!"), span_danger("You cum on yourself!"))
|
||||
else
|
||||
user.visible_message(span_warning("[user] cums on [target]!"), span_danger("You cum on [target]!"))
|
||||
applied_reagents.expose(target, TOUCH)
|
||||
log_combat(user, target, "came on")
|
||||
if(prob(40))
|
||||
affected_human.try_lewd_autoemote("moan")
|
||||
qdel(src)
|
||||
|
||||
// Jerk off into bottles
|
||||
/obj/item/hand_item/coom/afterattack(obj/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if (CONFIG_GET(flag/disable_erp_preferences))
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(ishuman(target))
|
||||
return
|
||||
if(user.stat == DEAD)
|
||||
return
|
||||
var/mob/living/carbon/human/affected_human = user
|
||||
var/obj/item/organ/external/genital/testicles/testicles = affected_human.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/penis/penis = affected_human.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/datum/sprite_accessory/genital/spriteP = GLOB.sprite_accessories["penis"][affected_human.dna.species.mutant_bodyparts["penis"][MUTANT_INDEX_NAME]]
|
||||
if(spriteP.is_hidden(affected_human))
|
||||
to_chat(user, span_notice("You need to expose yourself in order to masturbate."))
|
||||
return
|
||||
else if(penis.aroused != AROUSAL_FULL)
|
||||
to_chat(user, span_notice("You need to be aroused in order to masturbate."))
|
||||
return
|
||||
if(target.is_refillable() && target.is_drainable())
|
||||
var/cum_volume = testicles.genital_size*5+5
|
||||
if(target.reagents.holder_full())
|
||||
to_chat(user, span_warning("[target] is full."))
|
||||
return
|
||||
var/datum/reagents/applied_reagents = new/datum/reagents(50)
|
||||
applied_reagents.add_reagent(/datum/reagent/consumable/cum, cum_volume)
|
||||
user.visible_message(span_warning("[user] starts masturbating into [target]!"), span_danger("You start masturbating into [target]!"))
|
||||
if(do_after(user, 60))
|
||||
user.visible_message(span_warning("[user] cums into [target]!"), span_danger("You cum into [target]!"))
|
||||
playsound(target, SFX_DESECRATION, 50, TRUE, ignore_walls = FALSE)
|
||||
applied_reagents.trans_to(target, cum_volume)
|
||||
if(prob(40))
|
||||
affected_human.try_lewd_autoemote("moan")
|
||||
qdel(src)
|
||||
else
|
||||
user.visible_message(span_warning("[user] starts masturbating onto [target]!"), span_danger("You start masturbating onto [target]!"))
|
||||
if(do_after(user, 60))
|
||||
user.visible_message(span_warning("[user] cums on [target]!"), span_danger("You cum on [target]!"))
|
||||
playsound(target, SFX_DESECRATION, 50, TRUE, ignore_walls = FALSE)
|
||||
affected_human.add_cum_splatter_floor(get_turf(target))
|
||||
if(prob(40))
|
||||
affected_human.try_lewd_autoemote("moan")
|
||||
|
||||
if(target.icon_state=="stickyweb1"|target.icon_state=="stickyweb2")
|
||||
target.icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_decals/lewd_decals.dmi'
|
||||
qdel(src)
|
||||
@@ -0,0 +1,15 @@
|
||||
/obj/effect/decal/cleanable/cum
|
||||
name = "cum"
|
||||
desc = "Ew... Gross."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_decals/lewd_decals.dmi'
|
||||
icon_state = "cum_1"
|
||||
random_icon_states = list("cum_1", "cum_2", "cum_3", "cum_4")
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/cum/femcum
|
||||
name = "female cum"
|
||||
desc = "Uhh... Someone had fun..."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_decals/lewd_decals.dmi'
|
||||
icon_state = "femcum_1"
|
||||
random_icon_states = list("femcum_1", "femcum_2", "femcum_3", "femcum_4")
|
||||
beauty = -50
|
||||
@@ -0,0 +1,22 @@
|
||||
/mob/living/carbon/human/proc/adjust_arousal(arous = 0)
|
||||
if(stat >= DEAD || !client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
return
|
||||
|
||||
var/arousal_flag = AROUSAL_NONE
|
||||
if(arousal >= AROUSAL_MEDIUM)
|
||||
arousal_flag = AROUSAL_FULL
|
||||
else if(arousal >= AROUSAL_LOW)
|
||||
arousal_flag = AROUSAL_PARTIAL
|
||||
|
||||
if(arousal_status != arousal_flag) // Set organ arousal status
|
||||
arousal_status = arousal_flag
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/target = src
|
||||
for(var/obj/item/organ/external/genital/target_genital in target.external_organs)
|
||||
if(!target_genital.aroused == AROUSAL_CANT)
|
||||
target_genital.aroused = arousal_status
|
||||
target_genital.update_sprite_suffix()
|
||||
target.update_body()
|
||||
|
||||
arousal = clamp(arousal + arous, AROUSAL_MINIMUM, AROUSAL_LIMIT)
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
#define CLIMAX_VAGINA "Vagina"
|
||||
#define CLIMAX_PENIS "Penis"
|
||||
#define CLIMAX_BOTH "Both"
|
||||
|
||||
#define CLIMAX_ON_FLOOR "On the floor"
|
||||
#define CLIMAX_IN_OR_ON "Climax in or on someone"
|
||||
|
||||
/mob/living/carbon/human/proc/climax(manual = TRUE)
|
||||
if (CONFIG_GET(flag/disable_erp_preferences))
|
||||
return
|
||||
|
||||
if(!client?.prefs?.read_preference(/datum/preference/toggle/erp/autocum) && !manual)
|
||||
return
|
||||
|
||||
if(has_status_effect(/datum/status_effect/climax_cooldown) || !client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_NEVERBONER) || has_status_effect(/datum/status_effect/climax_cooldown) || (!has_vagina() && !has_penis()))
|
||||
visible_message(span_purple("[src] twitches, trying to cum, but with no result."), \
|
||||
span_purple("You can't have an orgasm!"))
|
||||
return TRUE
|
||||
|
||||
// Reduce pop-ups and make it slightly more frictionless (lewd).
|
||||
var/climax_choice = has_penis() ? CLIMAX_PENIS : CLIMAX_VAGINA
|
||||
|
||||
if(manual)
|
||||
var/list/genitals = list()
|
||||
if(has_vagina())
|
||||
genitals.Add(CLIMAX_VAGINA)
|
||||
if(has_penis())
|
||||
genitals.Add(CLIMAX_PENIS)
|
||||
genitals.Add(CLIMAX_BOTH)
|
||||
else if(has_penis())
|
||||
genitals.Add(CLIMAX_PENIS)
|
||||
climax_choice = tgui_alert(src, "You are climaxing, choose which genitalia to climax with.", "Genitalia Preference!", genitals)
|
||||
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
playsound(get_turf(src), pick('modular_skyrat/modules/modular_items/lewd_items/sounds/final_m1.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_m2.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_m3.ogg'), 50, TRUE, ignore_walls = FALSE)
|
||||
if(FEMALE)
|
||||
playsound(get_turf(src), pick('modular_skyrat/modules/modular_items/lewd_items/sounds/final_f1.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_f2.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/final_f3.ogg'), 50, TRUE, ignore_walls = FALSE)
|
||||
|
||||
var/self_orgasm = FALSE
|
||||
var/self_their = p_their()
|
||||
|
||||
if(climax_choice == CLIMAX_PENIS || climax_choice == CLIMAX_BOTH)
|
||||
var/obj/item/organ/external/genital/penis/penis = getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(!getorganslot(ORGAN_SLOT_TESTICLES)) //If we have no god damn balls, we can't cum anywhere... GET BALLS!
|
||||
visible_message(span_userlove("[src] orgasms, but nothing comes out of [self_their] penis!"), \
|
||||
span_userlove("You orgasm, it feels great, but nothing comes out of your penis!"))
|
||||
|
||||
else if(is_wearing_condom())
|
||||
var/obj/item/clothing/sextoy/condom/condom = get_item_by_slot(LEWD_SLOT_PENIS)
|
||||
condom.condom_use()
|
||||
visible_message(span_userlove("[src] shoots [self_their] load into the [condom], filling it up!"), \
|
||||
span_userlove("You shoot your thick load into the [condom] and it catches it all!"))
|
||||
|
||||
else if(!is_bottomless() && penis.visibility_preference != GENITAL_ALWAYS_SHOW)
|
||||
visible_message(span_userlove("[src] cums inside [self_their] clothes!"), \
|
||||
span_userlove("You shoot your load, but you weren't naked, so you mess up your clothes!"))
|
||||
self_orgasm = TRUE
|
||||
|
||||
else
|
||||
var/list/interactable_inrange_humans = list()
|
||||
|
||||
// Unfortunately prefs can't be checked here, because byond/tgstation moment.
|
||||
for(var/mob/living/carbon/human/iterating_human in (view(1, src) - src))
|
||||
interactable_inrange_humans[iterating_human.name] = iterating_human
|
||||
|
||||
var/list/buttons = list(CLIMAX_ON_FLOOR)
|
||||
if(interactable_inrange_humans.len)
|
||||
buttons += CLIMAX_IN_OR_ON
|
||||
|
||||
var/penis_climax_choice = tgui_alert(src, "Choose where to shoot your load.", "Load preference!", buttons)
|
||||
|
||||
var/create_cum_decal = FALSE
|
||||
|
||||
if(!penis_climax_choice || penis_climax_choice == CLIMAX_ON_FLOOR)
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots [self_their] sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
|
||||
else
|
||||
var/target_choice = tgui_input_list(src, "Choose a person to cum in or on.", "Choose target!", interactable_inrange_humans)
|
||||
if(!target_choice)
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots [self_their] sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
else
|
||||
var/mob/living/carbon/human/target_human = interactable_inrange_humans[target_choice]
|
||||
var/target_human_them = target_human.p_them()
|
||||
|
||||
var/list/target_buttons = list()
|
||||
|
||||
if(!target_human.wear_mask)
|
||||
target_buttons += "mouth"
|
||||
if(target_human.has_vagina(REQUIRE_GENITAL_EXPOSED))
|
||||
target_buttons += ORGAN_SLOT_VAGINA
|
||||
if(target_human.has_anus(REQUIRE_GENITAL_EXPOSED))
|
||||
target_buttons += "asshole"
|
||||
if(target_human.has_penis(REQUIRE_GENITAL_EXPOSED))
|
||||
var/obj/item/organ/external/genital/penis/other_penis = target_human.getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(other_penis.sheath != "None")
|
||||
target_buttons += "sheath"
|
||||
target_buttons += "On [target_human_them]"
|
||||
|
||||
var/climax_into_choice = tgui_input_list(src, "Where on or in [target_human] do you wish to cum?", "Final frontier!", target_buttons)
|
||||
|
||||
if(!climax_into_choice)
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto the floor!"), \
|
||||
span_userlove("You shoot string after string of hot cum, hitting the floor!"))
|
||||
else if(climax_into_choice == "On [target_human_them]")
|
||||
create_cum_decal = TRUE
|
||||
visible_message(span_userlove("[src] shoots their sticky load onto [target_human]!"), \
|
||||
span_userlove("You shoot string after string of hot cum onto [target_human]!"))
|
||||
else
|
||||
visible_message(span_userlove("[src] hilts [self_their] cock into [target_human]'s [climax_into_choice], shooting cum into [target_human_them]!"), \
|
||||
span_userlove("You hilt your cock into [target_human]'s [climax_into_choice], shooting cum into [target_human_them]!"))
|
||||
to_chat(target_human, span_userlove("Your [climax_into_choice] fills with warm cum as [src] shoots [self_their] load into it."))
|
||||
|
||||
var/obj/item/organ/external/genital/testicles/testicles = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
testicles.reagents.remove_all(testicles.reagents.total_volume * 0.6)
|
||||
if(create_cum_decal)
|
||||
add_cum_splatter_floor(get_turf(src))
|
||||
|
||||
try_lewd_autoemote("moan")
|
||||
if(climax_choice == CLIMAX_PENIS)
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
if(self_orgasm)
|
||||
add_mood_event("orgasm", /datum/mood_event/climaxself)
|
||||
return TRUE
|
||||
|
||||
if(climax_choice == CLIMAX_VAGINA || climax_choice == CLIMAX_BOTH)
|
||||
var/obj/item/organ/external/genital/vagina/vagina = getorganslot(ORGAN_SLOT_VAGINA)
|
||||
if(is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW)
|
||||
visible_message(span_userlove("[src] twitches and moans as [p_they()] climax from their vagina!"), span_userlove("You twitch and moan as you climax from your vagina!"))
|
||||
add_cum_splatter_floor(get_turf(src), female = TRUE)
|
||||
else
|
||||
visible_message(span_userlove("[src] cums in [self_their] underwear from [self_their] vagina!"), \
|
||||
span_userlove("You cum in your underwear from your vagina! Eww."))
|
||||
self_orgasm = TRUE
|
||||
|
||||
apply_status_effect(/datum/status_effect/climax)
|
||||
apply_status_effect(/datum/status_effect/climax_cooldown)
|
||||
if(self_orgasm)
|
||||
add_mood_event("orgasm", /datum/mood_event/climaxself)
|
||||
return TRUE
|
||||
|
||||
#undef CLIMAX_VAGINA
|
||||
#undef CLIMAX_PENIS
|
||||
#undef CLIMAX_BOTH
|
||||
#undef CLIMAX_ON_FLOOR
|
||||
#undef CLIMAX_IN_OR_ON
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/mood_event/orgasm
|
||||
description = span_purple("Woah... This pleasant tiredness... I love it.\n")
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/datum/mood_event/climaxself
|
||||
description = span_purple("I just came in my own underwear. Messy.\n")
|
||||
timeout = 4 MINUTES
|
||||
|
||||
/datum/mood_event/overgasm
|
||||
description = span_warning("Uhh... I don't want to be horny anymore.\n") //Me too, buddy. Me too.
|
||||
timeout = 10 MINUTES
|
||||
@@ -0,0 +1,25 @@
|
||||
// I guess some people enjoy it.
|
||||
|
||||
/// Adds or removes pain, this should be used instead of the modifying the var, due to quirk logic.
|
||||
/// Makes the human scream and shiver when pain hits the soft limit, provided autoemote is enabled.
|
||||
/mob/living/carbon/human/proc/adjust_pain(change_amount = 0)
|
||||
if(stat >= DEAD || !client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
return
|
||||
|
||||
if(pain > pain_limit || change_amount > pain_limit / 10) // pain system // YOUR SYSTEM IS PAIN, WHY WE'RE GETTING AROUSED BY STEPPING ON ANTS?!
|
||||
if(HAS_TRAIT(src, TRAIT_MASOCHISM))
|
||||
var/arousal_adjustment = change_amount - (pain_limit / 10)
|
||||
if(arousal_adjustment > 0)
|
||||
adjust_arousal(-arousal_adjustment)
|
||||
else
|
||||
if(change_amount > 0)
|
||||
adjust_arousal(-change_amount)
|
||||
if(prob(2) && pain > pain_limit && change_amount > pain_limit / 10)
|
||||
try_lewd_autoemote(pick("scream", "shiver")) //SCREAM!!!
|
||||
|
||||
else if(HAS_TRAIT(src, TRAIT_MASOCHISM))
|
||||
if(change_amount > 0)
|
||||
adjust_arousal(change_amount)
|
||||
adjust_pleasure(change_amount / 2)
|
||||
|
||||
pain = clamp(pain + change_amount, AROUSAL_MINIMUM, AROUSAL_LIMIT)
|
||||
@@ -0,0 +1,8 @@
|
||||
/mob/living/carbon/human/proc/adjust_pleasure(pleas = 0)
|
||||
if(stat >= DEAD || !client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
return
|
||||
|
||||
pleasure = clamp(pleasure + pleas, AROUSAL_MINIMUM, AROUSAL_LIMIT)
|
||||
|
||||
if(pleasure >= AROUSAL_AUTO_CLIMAX_THRESHOLD) // lets cum
|
||||
climax(manual = FALSE)
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#define AUTO_EMOTE_CHANCE 3
|
||||
|
||||
#define MASOCHISM_PAIN_OFFSET 0.5
|
||||
#define NEVERBONER_PLEASURE_OFFSET 50
|
||||
|
||||
#define BLUEBALL_AROUSAL_MODIFIER 0.08
|
||||
#define TOO_MUCH_PAIN_MODIFIER 0.1
|
||||
#define ITS_PRETTY_HOT_IN_HERE_MODIFIER 0.1
|
||||
|
||||
#define BASE_AROUSAL_ADJUSTMENT -0.1
|
||||
#define BASE_PAIN_AND_PLEASURE_ADJUSTMENT -0.5
|
||||
|
||||
/datum/status_effect/aroused
|
||||
id = "aroused"
|
||||
tick_interval = 10
|
||||
duration = -1
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/aroused/tick()
|
||||
if(owner.stat >= DEAD || !owner.client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
var/temp_arousal = BASE_AROUSAL_ADJUSTMENT
|
||||
var/temp_pleasure = BASE_PAIN_AND_PLEASURE_ADJUSTMENT
|
||||
var/temp_pain = BASE_PAIN_AND_PLEASURE_ADJUSTMENT
|
||||
|
||||
var/obj/item/organ/external/genital/testicles/balls = affected_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(balls && balls.internal_fluid_full())
|
||||
temp_arousal += BLUEBALL_AROUSAL_MODIFIER
|
||||
|
||||
if(HAS_TRAIT(affected_mob, TRAIT_MASOCHISM))
|
||||
temp_pain -= MASOCHISM_PAIN_OFFSET
|
||||
if(HAS_TRAIT(affected_mob, TRAIT_NEVERBONER))
|
||||
temp_pleasure -= NEVERBONER_PLEASURE_OFFSET
|
||||
temp_arousal -= NEVERBONER_PLEASURE_OFFSET
|
||||
|
||||
if(affected_mob.pain > affected_mob.pain_limit)
|
||||
temp_arousal -= TOO_MUCH_PAIN_MODIFIER
|
||||
if(affected_mob.arousal >= AROUSAL_MEDIUM)
|
||||
if(prob(AUTO_EMOTE_CHANCE))
|
||||
affected_mob.try_lewd_autoemote(pick("moan", "blush"))
|
||||
temp_pleasure += ITS_PRETTY_HOT_IN_HERE_MODIFIER
|
||||
//moan
|
||||
if(affected_mob.pleasure >= AROUSAL_HIGH && prob(AUTO_EMOTE_CHANCE))
|
||||
affected_mob.try_lewd_autoemote(pick("moan", "twitch_s"))
|
||||
//moan x2
|
||||
|
||||
affected_mob.adjust_arousal(temp_arousal)
|
||||
affected_mob.adjust_pleasure(temp_pleasure)
|
||||
affected_mob.adjust_pain(temp_pain)
|
||||
|
||||
#undef AUTO_EMOTE_CHANCE
|
||||
|
||||
#undef MASOCHISM_PAIN_OFFSET
|
||||
#undef NEVERBONER_PLEASURE_OFFSET
|
||||
|
||||
#undef BLUEBALL_AROUSAL_MODIFIER
|
||||
#undef TOO_MUCH_PAIN_MODIFIER
|
||||
#undef ITS_PRETTY_HOT_IN_HERE_MODIFIER
|
||||
|
||||
#undef BASE_AROUSAL_ADJUSTMENT
|
||||
#undef BASE_PAIN_AND_PLEASURE_ADJUSTMENT
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#define AROUSAL_REMOVAL_AMOUNT -12
|
||||
#define STAMINA_REMOVAL_AMOUNT_EXTERNAL 15
|
||||
#define STAMINA_REMOVAL_AMOUNT_SELF 8
|
||||
|
||||
// Lowers arousal and pleasure by a bunch to not chain climax.
|
||||
|
||||
/datum/status_effect/climax
|
||||
id = "climax"
|
||||
tick_interval = 1 SECONDS
|
||||
duration = 10 SECONDS
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/climax/tick()
|
||||
if(!owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
|
||||
owner.reagents.add_reagent(/datum/reagent/drug/aphrodisiac/dopamine, 0.5)
|
||||
owner.adjustStaminaLoss(STAMINA_REMOVAL_AMOUNT_EXTERNAL)
|
||||
affected_mob.adjust_arousal(AROUSAL_REMOVAL_AMOUNT)
|
||||
affected_mob.adjust_pleasure(AROUSAL_REMOVAL_AMOUNT)
|
||||
|
||||
// Likely ready to be deprecated code that could be removed, due to nymphomaniac not existing anymore.
|
||||
/datum/status_effect/masturbation_climax
|
||||
id = "climax"
|
||||
tick_interval = 1 SECONDS
|
||||
duration = 5 SECONDS // Multiplayer better than singleplayer mode.
|
||||
alert_type = null
|
||||
|
||||
// This one should not leave decals on the floor. Used in case if character cumming in beaker.
|
||||
/datum/status_effect/masturbation_climax/tick()
|
||||
if(!owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
|
||||
owner.reagents.add_reagent(/datum/reagent/drug/aphrodisiac/dopamine, 0.3)
|
||||
owner.adjustStaminaLoss(STAMINA_REMOVAL_AMOUNT_SELF)
|
||||
affected_mob.adjust_arousal(AROUSAL_REMOVAL_AMOUNT)
|
||||
affected_mob.adjust_pleasure(AROUSAL_REMOVAL_AMOUNT)
|
||||
|
||||
// A second step in preventing chain climax, and also prevents spam.
|
||||
/datum/status_effect/climax_cooldown
|
||||
id = "climax_cooldown"
|
||||
tick_interval = 1 SECONDS
|
||||
duration = 30 SECONDS
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/climax_cooldown/tick()
|
||||
var/obj/item/organ/external/genital/vagina/vagina = owner.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
var/obj/item/organ/external/genital/testicles/balls = owner.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/testicles/penis = owner.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/obj/item/organ/external/genital/testicles/anus = owner.getorganslot(ORGAN_SLOT_ANUS)
|
||||
|
||||
if(penis)
|
||||
penis.aroused = AROUSAL_NONE
|
||||
if(vagina)
|
||||
vagina.aroused = AROUSAL_NONE
|
||||
if(balls)
|
||||
balls.aroused = AROUSAL_NONE
|
||||
if(anus)
|
||||
anus.aroused = AROUSAL_NONE
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// These are effectively magic numbers.
|
||||
#define AROUSAL_MULTIPLIER 25
|
||||
#define BALLS_MULTIPLIER 235
|
||||
#define NUTRITION_MULTIPLIER 100
|
||||
#define NUTRITION_COST_MULTIPLIER 2
|
||||
// Breasts have ungodly scaling at larger sizes, so the massive multiplier to ensure there's no runaway production makes sense here.
|
||||
#define BREASTS_MULTIPLIER 11000
|
||||
#define VAGINA_MULTIPLIER 250
|
||||
#define VAGINA_FLUID_REMOVAL_AMOUNT -0.05
|
||||
#define BASE_MULTIPLIER 5
|
||||
|
||||
/datum/status_effect/body_fluid_regen
|
||||
id = "body fluid regen"
|
||||
tick_interval = 5 SECONDS
|
||||
duration = -1
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/body_fluid_regen/tick()
|
||||
if(owner.stat >= DEAD || !owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
var/obj/item/organ/external/genital/testicles/balls = owner.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/breasts/breasts = owner.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
var/obj/item/organ/external/genital/vagina/vagina = owner.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
|
||||
if(balls)
|
||||
if(affected_mob.arousal >= AROUSAL_LOW)
|
||||
var/regen = (affected_mob.arousal / AROUSAL_MULTIPLIER) * (balls.internal_fluid_maximum / BALLS_MULTIPLIER) * BASE_MULTIPLIER
|
||||
balls.internal_fluid_count += regen
|
||||
|
||||
if(breasts)
|
||||
if(breasts.lactates == TRUE)
|
||||
var/regen = ((owner.nutrition / (NUTRITION_LEVEL_WELL_FED / NUTRITION_MULTIPLIER)) / NUTRITION_MULTIPLIER) * (breasts.internal_fluid_maximum / BREASTS_MULTIPLIER) * BASE_MULTIPLIER
|
||||
if(!breasts.internal_fluid_full())
|
||||
owner.adjust_nutrition(-regen / NUTRITION_COST_MULTIPLIER)
|
||||
breasts.adjust_internal_fluid(regen)
|
||||
|
||||
if(vagina)
|
||||
if(affected_mob.arousal >= AROUSAL_LOW)
|
||||
var/regen = (affected_mob.arousal / AROUSAL_MULTIPLIER) * (vagina.internal_fluid_maximum / VAGINA_MULTIPLIER) * BASE_MULTIPLIER
|
||||
vagina.adjust_internal_fluid(regen)
|
||||
else
|
||||
vagina.adjust_internal_fluid(VAGINA_FLUID_REMOVAL_AMOUNT)
|
||||
|
||||
#undef AROUSAL_MULTIPLIER
|
||||
#undef BALLS_MULTIPLIER
|
||||
#undef NUTRITION_MULTIPLIER
|
||||
#undef NUTRITION_COST_MULTIPLIER
|
||||
#undef BREASTS_MULTIPLIER
|
||||
#undef VAGINA_MULTIPLIER
|
||||
#undef VAGINA_FLUID_REMOVAL_AMOUNT
|
||||
#undef BASE_MULTIPLIER
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/datum/status_effect/ropebunny
|
||||
id = "ropebunny"
|
||||
tick_interval = 10
|
||||
duration = INFINITE
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/ropebunny/on_apply()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.add_mood_event("ropebunny", /datum/mood_event/ropebunny)
|
||||
|
||||
/datum/status_effect/ropebunny/on_remove()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.clear_mood_event("ropebunny")
|
||||
|
||||
/datum/mood_event/ropebunny
|
||||
description = span_purple("I'm tied! Cannot move! These ropes... Ah!~")
|
||||
mood_change = 0 // I don't want to doom the station to sonic-speed perverts, but still want to keep this as mood modifier.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// This name means nothing. What does this even do?
|
||||
|
||||
/datum/status_effect/subspace
|
||||
id = "subspace"
|
||||
tick_interval = 10
|
||||
duration = 5 MINUTES
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/subspace/on_apply()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.add_mood_event("subspace", /datum/mood_event/subspace)
|
||||
|
||||
/datum/status_effect/subspace/on_remove()
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
target.clear_mood_event("subspace")
|
||||
|
||||
/datum/mood_event/subspace
|
||||
description = span_purple("Everything is so woozy... Pain feels so... Awesome.\n")
|
||||
|
||||
|
||||
//Hips are red after spanking
|
||||
/datum/status_effect/spanked
|
||||
id = "spanked"
|
||||
duration = 300 SECONDS
|
||||
alert_type = null
|
||||
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
. = ..()
|
||||
if(stat >= DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH) || src == user || !has_status_effect(/datum/status_effect/spanked) || !is_bottomless())
|
||||
return
|
||||
|
||||
. += span_purple("[user.p_their(TRUE)] butt has a red tint to it.") + "\n"
|
||||
|
||||
//Mood boost for masochist
|
||||
/datum/mood_event/perv_spanked
|
||||
description = span_purple("Ah, yes! More! Punish me!\n")
|
||||
timeout = 5 MINUTES
|
||||
-742
@@ -1,742 +0,0 @@
|
||||
// The base ERP chem. It handles pref and human type checks for you, so ALL chems relating to ERP should be subtypes of this.
|
||||
/datum/reagent/drug/aphrodisiac
|
||||
name = "liquid ERP"
|
||||
description = "ERP in its liquified form. Complain to a coder."
|
||||
|
||||
/// What preference you need enabled for effects on life
|
||||
var/life_pref_datum = /datum/preference/toggle/erp
|
||||
/// What preference you need enabled for effects on overdose
|
||||
var/overdose_pref_datum = /datum/preference/toggle/erp
|
||||
|
||||
/// The amount to adjust the mob's arousal by
|
||||
var/arousal_adjust_amount = 1
|
||||
/// The amount to adjust the mob's pleasure by
|
||||
var/pleasure_adjust_amount = 0
|
||||
/// The amount to adjust the mob's pain by
|
||||
var/pain_adjust_amount = 0
|
||||
|
||||
// Vars for enlargement chems from here on
|
||||
/// Counts up to a threshold before triggering enlargement effects
|
||||
var/enlargement_amount = 0
|
||||
/// How much to increase the count by each process
|
||||
var/enlarger_increase_step = 5
|
||||
/// Count to reach before effects
|
||||
var/enlargement_threshold = 100
|
||||
|
||||
/// % chance for damage to be applied when the organ is too large and the mob is clothed
|
||||
var/damage_chance = 20
|
||||
|
||||
/// Largest length the chem can make a mob's penis
|
||||
var/penis_max_length = PENIS_MAX_LENGTH
|
||||
/// Smallest size the chem can make a mob's penis
|
||||
var/penis_min_length = PENIS_MIN_LENGTH
|
||||
/// How much the penis is increased in size each time it's run
|
||||
var/penis_length_increase_step = 1
|
||||
/// How much the penis is increased in girth each time it's run
|
||||
var/penis_girth_increase_step = 1
|
||||
/// Largest girth the chem can make a mob's penis
|
||||
var/penis_max_girth = PENIS_MAX_GIRTH
|
||||
/// Smallest girth the chem can make a mob's penis
|
||||
var/penis_minimum_girth = 2
|
||||
/// How much to reduce the size of the penis each time it's run
|
||||
var/penis_size_reduction_step = 2
|
||||
/// How much to reduce the girth of the penis each time it's run
|
||||
var/penis_girth_reduction_step = 2
|
||||
|
||||
/// Largest size the chem can make a mob's breasts
|
||||
var/max_breast_size = 16
|
||||
/// How much breasts are increased in size each time it's run
|
||||
var/breast_size_increase_step = 1
|
||||
/// Smallest size the chem can make a mob's breasts
|
||||
var/breast_minimum_size = 2
|
||||
/// How much to reduce the size of the breasts each time it's run
|
||||
var/breast_size_reduction_step = 1
|
||||
|
||||
/// Runs on life after preference checks. Use this instead of on_mob_life
|
||||
/datum/reagent/drug/aphrodisiac/proc/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
return
|
||||
|
||||
/// Runs on OD process after preference checks. Use this instead of overdose_process
|
||||
/datum/reagent/drug/aphrodisiac/proc/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
return
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(life_pref_datum && exposed_mob.client?.prefs.read_preference(life_pref_datum) && ishuman(exposed_mob))
|
||||
life_effects(exposed_mob)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(overdose_pref_datum && exposed_mob.client?.prefs.read_preference(overdose_pref_datum) && ishuman(exposed_mob))
|
||||
overdose_effects(exposed_mob)
|
||||
|
||||
/*
|
||||
* APHRODISIACS
|
||||
*/
|
||||
|
||||
///To notify, but not harm the player in terms of mood. Used for camphor, pentacamphor, succubus milk, and incubus draft.
|
||||
/datum/mood_event/minor_overdose
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/datum/mood_event/minor_overdose/add_effects(drug_name)
|
||||
description = "<span class='warning'>I think I took a bit too much [drug_name]...</span>\n"
|
||||
|
||||
//Crocin. Basic aphrodisiac with no consequences
|
||||
/datum/reagent/drug/aphrodisiac/crocin
|
||||
name = "crocin"
|
||||
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
|
||||
taste_description = "strawberries"
|
||||
color = "#FFADFF"
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = 1
|
||||
pleasure_adjust_amount = 0
|
||||
pain_adjust_amount = 0
|
||||
|
||||
/// Probability of the chem triggering an emote, as a %, run on mob life
|
||||
var/emote_probability = 3
|
||||
/// Probability of the chem triggering a to_chat, as a %, run on mob life
|
||||
var/thought_probability = 2
|
||||
|
||||
/// A list of possible emotes the chem is able to trigger
|
||||
var/list/possible_aroused_emotes = list("moan", "blush")
|
||||
|
||||
/// A list of possible to_chat messages the chem is able to trigger
|
||||
var/list/possible_aroused_thoughts = list("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
|
||||
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(prob(emote_probability))
|
||||
exposed_mob.emote(pick(possible_aroused_emotes))
|
||||
if(prob(thought_probability))
|
||||
var/displayed_thought = pick(possible_aroused_thoughts)
|
||||
to_chat(exposed_mob, span_notice("[displayed_thought]"))
|
||||
|
||||
exposed_mob.adjustArousal(arousal_adjust_amount)
|
||||
exposed_mob.adjustPleasure(pleasure_adjust_amount)
|
||||
exposed_mob.adjustPain(pain_adjust_amount)
|
||||
|
||||
for(var/obj/item/organ/external/genital/mob_genitals in exposed_mob.external_organs)
|
||||
if(!mob_genitals.aroused == AROUSAL_CANT)
|
||||
mob_genitals.aroused = AROUSAL_FULL
|
||||
mob_genitals.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
|
||||
//Hexacrocin. Advanced aphrodisiac that can cause brain traumas.
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin
|
||||
name = "hexacrocin"
|
||||
description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive for most animals.\
|
||||
Addiction withdrawals can cause brain damage and shortness of breath. Overdose can lead to brain traumas."
|
||||
taste_description = "liquid desire"
|
||||
color = "#FF2BFF"
|
||||
overdose_threshold = 25
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/bimbofication
|
||||
|
||||
emote_probability = 5
|
||||
thought_probability = 5
|
||||
arousal_adjust_amount = 2
|
||||
pleasure_adjust_amount = 1.5
|
||||
pain_adjust_amount = 0.2
|
||||
possible_aroused_thoughts = list("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
|
||||
|
||||
/// A list of possible to_chat messages the chem is able to trigger after enough cycles in the mobs system
|
||||
var/list/extreme_aroused_thoughts = list("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
|
||||
/// How many cycles the chem has to be in the mob's system before triggering extreme effects
|
||||
var/extreme_thought_threshold = 25
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(prob(thought_probability) && current_cycle >= extreme_thought_threshold)
|
||||
var/displayed_extreme_thought = pick(extreme_aroused_thoughts)
|
||||
to_chat(exposed_mob, span_purple("[displayed_extreme_thought]"))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(prob(95) || HAS_TRAIT(exposed_mob, TRAIT_BIMBO))
|
||||
return ..()
|
||||
|
||||
to_chat(exposed_mob, span_purple("Your libido is going haywire! It feels like speaking is much harder..."))
|
||||
exposed_mob.gain_trauma(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_BASIC)
|
||||
ADD_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT)
|
||||
|
||||
//Dopamine. Generates in character after orgasm.
|
||||
/datum/reagent/drug/aphrodisiac/dopamine
|
||||
name = "dopamine...?"
|
||||
description = "Pure happiness"
|
||||
taste_description = "an indescribable, slightly sour taste. Something in it relaxes you, filling you with pleasure."
|
||||
color = "#97ffee"
|
||||
glass_name = "dopamine"
|
||||
glass_desc = "Delicious flavored reagent. You feel happy even looking at it."
|
||||
reagent_state = LIQUID
|
||||
overdose_threshold = 10
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = 0.5
|
||||
pleasure_adjust_amount = 0.3
|
||||
pain_adjust_amount = -0.5
|
||||
|
||||
/// How druggy the chem will make the mob
|
||||
var/drugginess_amount = 5 SECONDS
|
||||
/// How likely the drug is to make the mob druggy per life process
|
||||
var/drugginess_chance = 7
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/on_mob_add(mob/living/carbon/human/exposed_mob)
|
||||
if(!(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/aphro)))
|
||||
return ..()
|
||||
exposed_mob.add_mood_event("[type]_start", /datum/mood_event/orgasm, name)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
exposed_mob.set_drugginess(drugginess_amount)
|
||||
if(prob(drugginess_chance))
|
||||
exposed_mob.emote(pick("twitch", "drool", "moan", "giggle", "shaking"))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/overdose_start(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
to_chat(exposed_mob, span_purple("You feel so happy!"))
|
||||
exposed_mob.add_mood_event("[type]_overdose", /datum/mood_event/overgasm, name)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(!(exposed_mob.hallucination < volume && prob(20)))
|
||||
return ..()
|
||||
exposed_mob.adjustArousal(arousal_adjust_amount)
|
||||
exposed_mob.adjustPleasure(pleasure_adjust_amount)
|
||||
exposed_mob.adjustPain(pain_adjust_amount)
|
||||
if(prob(2))
|
||||
exposed_mob.emote(pick("moan", "twitch_s"))
|
||||
|
||||
/*
|
||||
* ANAPHRODISIACS
|
||||
*/
|
||||
|
||||
//Camphor. Used to reduce libido.
|
||||
///Able to reset one's genital size back to normal upon OD, or alternatively, if the user sets the size and then disables the organ, that size.
|
||||
/datum/reagent/drug/aphrodisiac/camphor
|
||||
name = "Camphor"
|
||||
description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When ingested by most animals it acts as an anaphrodisiac, \
|
||||
reducing libido and calming them. Non-habit forming and non-addictive."
|
||||
taste_description = "dull bitterness"
|
||||
taste_mult = 2
|
||||
color = "#D9D9D9"//rgb(157, 157, 157)
|
||||
reagent_state = SOLID
|
||||
overdose_threshold = 25 ///OD will reset sizes of genitals back to normal.
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = -12
|
||||
pleasure_adjust_amount = -3
|
||||
overdose_pref_datum = /datum/preference/toggle/erp ///This will work without having aphrodisiacs enabled.
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
var/old_arousal = exposed_mob.arousal
|
||||
exposed_mob.adjustArousal(arousal_adjust_amount)
|
||||
exposed_mob.adjustPleasure(pleasure_adjust_amount)
|
||||
if(exposed_mob.arousal <= 0 && old_arousal > 0)
|
||||
to_chat(exposed_mob, span_notice("You no longer feel aroused."))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
///Grows and shrinks organs depending on prefs, returning to normal. Offers a way of resetting succubus milk / incubus draft sizes, but not organs.
|
||||
|
||||
///Resets gender if prefs enabled.
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/gender_change))
|
||||
if(exposed_mob.gender != exposed_mob.client?.prefs?.read_preference(/datum/preference/choiced/gender))
|
||||
exposed_mob.set_gender(exposed_mob.client?.prefs?.read_preference(/datum/preference/choiced/gender))
|
||||
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_BREASTS))
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/breasts_size))
|
||||
var/original_breast_size = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/breasts_size)
|
||||
if(mob_breasts?.genital_size > original_breast_size)
|
||||
mob_breasts.genital_size -= breast_size_reduction_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
if(mob_breasts?.genital_size < original_breast_size)
|
||||
mob_breasts.genital_size += breast_size_increase_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_PENIS))
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/numeric/penis_length))
|
||||
var/original_penis_length = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/penis_length)
|
||||
var/original_penis_girth = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/penis_girth)
|
||||
///Run to go through girth first.
|
||||
if(mob_penis?.girth > original_penis_girth)
|
||||
mob_penis.girth -= penis_girth_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
if(mob_penis?.girth < original_penis_girth)
|
||||
mob_penis.girth += penis_girth_increase_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
///No returns in order to continue code.
|
||||
if(mob_penis?.genital_size > original_penis_length)
|
||||
mob_penis.genital_size -= penis_size_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
if(mob_penis?.genital_size < original_penis_length)
|
||||
mob_penis.genital_size += penis_length_increase_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES))
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/numeric/balls_size))
|
||||
var/original_ball_size = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/balls_size)
|
||||
if(mob_testicles?.genital_size > original_ball_size)
|
||||
mob_testicles.genital_size -= 1
|
||||
mob_testicles.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
if(mob_testicles?.genital_size < original_ball_size)
|
||||
mob_testicles.genital_size += 1
|
||||
mob_testicles.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
|
||||
// Pentacamphor. Used to purge crocin and hexacrocin. Can permanently disable arousal or cure bimbofication on overdose.
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor
|
||||
name = "Pentacamphor"
|
||||
description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive."
|
||||
taste_description = "tranquil celibacy"
|
||||
color = "#D9D9D9"//rgb(255, 255, 255)
|
||||
reagent_state = SOLID
|
||||
overdose_threshold = 20
|
||||
arousal_adjust_amount = -18
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
|
||||
/// How much of the given reagent to remove per operation
|
||||
var/reagent_reduction_amount = 20
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(exposed_mob.reagents.has_reagent(/datum/reagent/drug/aphrodisiac/crocin))
|
||||
exposed_mob.reagents.remove_reagent(/datum/reagent/drug/aphrodisiac/crocin, reagent_reduction_amount)
|
||||
if(exposed_mob.reagents.has_reagent(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin))
|
||||
exposed_mob.reagents.remove_reagent(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin, reagent_reduction_amount)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor/overdose_start(mob/living/carbon/human/exposed_mob)
|
||||
if(!HAS_TRAIT(exposed_mob, TRAIT_NEVERBONER))
|
||||
to_chat(exposed_mob, span_notice("You feel like you'll never feel aroused again..."))
|
||||
ADD_TRAIT(exposed_mob, TRAIT_NEVERBONER, LEWDCHEM_TRAIT)
|
||||
if(!HAS_TRAIT(exposed_mob, TRAIT_BIMBO))
|
||||
return
|
||||
exposed_mob.cure_trauma_type(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
to_chat(exposed_mob, span_notice("Your mind is free. Your thoughts are pure and innocent once more."))
|
||||
REMOVE_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT)
|
||||
|
||||
/*
|
||||
* GENITAL ENLARGEMENT CHEMICALS
|
||||
*/
|
||||
|
||||
/*
|
||||
* BREAST ENLARGEMENT
|
||||
* Normal function increases the player's breast size.
|
||||
* If the player's breasts are near or at the maximum size and they're wearing clothing, they press against the player's clothes and causes brute and oxygen damage.
|
||||
* If gender change preference is enabled: Overdosing makes you female if male, makes the player grow breasts, sets the player's testicles to the minimum size, and shrinks the player's penis to a minimum size.
|
||||
* If the gender change preference is not enabled: Overdosing will just make you grow breasts if you don't have any.
|
||||
* Credit to Citadel for the original code before modification
|
||||
*/
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/breast_enlarger
|
||||
name = "succubus milk"
|
||||
description = "A volatile collodial mixture derived from milk that encourages mammary production via a potent estrogen mix."
|
||||
color = "#E60584" // rgb: 96, 0, 255
|
||||
taste_description = "a milky ice cream like flavour" /// Edited so it doesn't trail off and act strangely with other taste descriptions.
|
||||
overdose_threshold = 20
|
||||
metabolization_rate = 0.25
|
||||
life_pref_datum = /datum/preference/toggle/erp/breast_enlargement
|
||||
overdose_pref_datum = /datum/preference/toggle/erp ///Changed from breast_enlargement in order to have gender swapping as a separate feature within overdose.
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/breast_enlarger/life_effects(mob/living/carbon/human/exposed_mob) //Increases breast size
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
enlargement_amount += enlarger_increase_step
|
||||
/// Adds a check for breasts in the first place. I HATE ERRORS.
|
||||
if(!mob_breasts)
|
||||
return
|
||||
if(enlargement_amount >= enlargement_threshold)
|
||||
if(mob_breasts?.genital_size >= max_breast_size)
|
||||
return
|
||||
mob_breasts.genital_size += breast_size_increase_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
|
||||
/// Words for the breasts when huge.
|
||||
var/static/list/words_for_bigger = list("huge", "massive", "squishy", "gigantic", "rather large", "jiggly", "hefty", )
|
||||
/// Synonyms for breasts.
|
||||
var/static/list/boob_text_list = list("boobs", "tits", "breasts", )
|
||||
/// Synonyms for the chest.
|
||||
var/static/list/covered_boobs_list = list("bust", "chest", "bosom", )
|
||||
/// Synonyms for bigger breasts.
|
||||
var/static/list/bigger_boob_text_list = list("jigglies", "melons", "jugs", "boobies", "milkers", "boobs", "tits", "breasts", )
|
||||
/// Wording chosen to expand the breasts, shown only to the mob.
|
||||
var/static/list/action_text_list = list("expand outward to ", "grow out to ", "begin to enlarge, growing to ", "suddenly expand to ", "swell out to ", )
|
||||
/// Wording chosen to be seen by other mobs, regardless of whether mob is clothed/unclothed.
|
||||
var/static/list/public_bigger_action_text_list = list("expand and jiggle outward.", "grow a bit larger, bouncing about.", "seem a bit bigger than they were before.", "bounce and jiggle as they suddenly expand.", )
|
||||
/// Wording chosen to be seen by other mobs, while mob is unclothed.
|
||||
var/static/list/public_action_text_list = list("expand outward.", "seem to grow a bit larger.", "appear a bit bigger than they were before.", "bounce and jiggle as they suddenly expand.", )
|
||||
/// Wording chosen to be seen by other mobs, while mob is clothed.
|
||||
var/static/list/notice_boobs = list("seems to be a bit tighter.", "appears to be a bit bigger.", "seems to swell outward a bit.", )
|
||||
/// Checks for cup size.
|
||||
var/translation = mob_breasts.breasts_size_to_cup(mob_breasts.genital_size)
|
||||
|
||||
if(mob_breasts.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_topless())
|
||||
switch(translation)
|
||||
if("Flatchested")
|
||||
return
|
||||
if("beyond measurement")
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [mob_breasts.genital_size] inches in diameter."))
|
||||
return
|
||||
else
|
||||
if(mob_breasts?.genital_size >= (max_breast_size - 2))
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
switch(translation)
|
||||
if("Flatchested")
|
||||
return
|
||||
if("beyond measurement")
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [mob_breasts.genital_size] inches in diameter."))
|
||||
return
|
||||
else
|
||||
if(mob_breasts?.genital_size >= (max_breast_size - 2))
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("The area around [exposed_mob]'s [pick(covered_boobs_list)] [pick(notice_boobs)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
|
||||
if((mob_breasts?.genital_size >= (max_breast_size - 2)) && (exposed_mob.w_uniform || exposed_mob.wear_suit))
|
||||
var/target_bodypart = exposed_mob.get_bodypart(BODY_ZONE_CHEST)
|
||||
if(prob(damage_chance))
|
||||
to_chat(exposed_mob, span_danger("Your breasts begin to strain against your clothes!"))
|
||||
exposed_mob.adjustOxyLoss(5, 0)
|
||||
exposed_mob.apply_damage(1, BRUTE, target_bodypart)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/breast_enlarger/overdose_effects(mob/living/carbon/human/exposed_mob) //Turns you into a female if character is male. Also supposed to add breasts but enlargement_amount'm too dumb to figure out how to make it work
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/breast_enlargement))
|
||||
/// Makes above comment actually work.
|
||||
if(!exposed_mob.getorganslot(ORGAN_SLOT_BREASTS))
|
||||
var/obj/item/organ/path = /obj/item/organ/external/genital/breasts
|
||||
exposed_mob.dna.mutant_bodyparts["breasts"][MUTANT_INDEX_NAME] = "Pair"
|
||||
path = new /obj/item/organ/external/genital/breasts
|
||||
path.build_from_dna(exposed_mob.dna, "breasts")
|
||||
path.Insert(exposed_mob, 0, FALSE)
|
||||
var/obj/item/organ/external/genital/new_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
new_breasts.genital_size = 2
|
||||
new_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
if(new_breasts.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_topless())
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s bust suddenly expands!"))
|
||||
to_chat(exposed_mob, span_purple("Your chest feels warm, tingling with sensitivity as it expands outward."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("The area around [exposed_mob]'s chest suddenly bounces a bit."))
|
||||
to_chat(exposed_mob, span_purple("Your chest feels warm, tingling with sensitivity as it strains against your clothes."))
|
||||
return
|
||||
///Separates gender change stuff from breast growth.
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/gender_change))
|
||||
if(exposed_mob.gender == MALE)
|
||||
exposed_mob.set_gender(FEMALE)
|
||||
exposed_mob.physique = exposed_mob.gender
|
||||
exposed_mob.update_body()
|
||||
exposed_mob.update_mutations_overlay()
|
||||
if(!mob_penis)
|
||||
return
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/penis_enlargement)) ///To do cock shrinkage, check if prefs allow for this.
|
||||
if(mob_penis.genital_size > penis_min_length)
|
||||
mob_penis.genital_size -= penis_size_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
if(mob_penis.girth > penis_minimum_girth)
|
||||
mob_penis.girth -= penis_girth_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
if(!mob_testicles || mob_testicles.genital_size <= 1)
|
||||
return
|
||||
mob_testicles.genital_size -= 1
|
||||
return
|
||||
|
||||
/*
|
||||
* PENIS ENLARGEMENT
|
||||
* Normal function increases the player's penis size.
|
||||
* If the player's penis is near or at the maximum size and they're wearing clothing, it presses against the player's clothes and causes brute damage.
|
||||
* If gender change preference is enabled: Overdosing makes you male if female, makes the player grow a cock, and shrinks the player's breasts to a minimum size.
|
||||
* If the gender change preference is not enabled: Overdosing will just make you grow a cock if you don't have one.
|
||||
*/
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/penis_enlarger
|
||||
name = "incubus draft"
|
||||
description = "A volatile collodial mixture derived from various masculine solutions that encourages a larger gentleman's package via a potent testosterone mix."
|
||||
color = "#888888"
|
||||
taste_description = "chinese dragon powder"
|
||||
overdose_threshold = 20 ///ODing makes you male and shrinks female genitals if gender change prefs are enabled. Otherwise, grows a cock.
|
||||
metabolization_rate = 0.25
|
||||
life_pref_datum = /datum/preference/toggle/erp/penis_enlargement
|
||||
overdose_pref_datum = /datum/preference/toggle/erp ///Changed from penis_enlargement in order to have gender swapping as a separate feature within overdose.
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/penis_enlarger/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
enlargement_amount += enlarger_increase_step
|
||||
/// Add yet another check because I hate errors!!
|
||||
if(!mob_penis)
|
||||
return
|
||||
if(enlargement_amount >= enlargement_threshold)
|
||||
if(mob_penis?.genital_size >= penis_max_length)
|
||||
return ..()
|
||||
mob_penis.genital_size += penis_length_increase_step
|
||||
///Improvision to girth to not make it random chance.
|
||||
if(mob_penis?.girth < penis_max_girth) ///Because any higher is ridiculous. However, should still allow for regular penis growth.
|
||||
mob_penis.girth = round(mob_penis.girth + (mob_penis.genital_size/mob_penis.girth))
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
/// Words for the cock when huge.
|
||||
var/static/list/words_for_bigger_cock = list("huge", "massive", "gigantic", "rather lengthy", "colossal", "hefty", )
|
||||
/// Synonyms for cock.
|
||||
var/static/list/cock_text_list = list("cock", "penis", "dick", "member", "richard", "johnston", "johnson", )
|
||||
/// Synonyms for bigger cock.
|
||||
var/static/list/bigger_cock_text_list = list("rod", "shaft", "cock", "penis", "dick", "member", "richard", "johnston", "johnson", )
|
||||
/// Wording chosen to extend the cock, shown only to the mob.
|
||||
var/static/list/cock_action_text_list = list("extends to ", "grows out to ", "begins to enlarge, growing to ", "suddenly expands to ", "lengthens out to ", )
|
||||
/// Wording chosen to be seen by other mobs, while mob is unclothed.
|
||||
var/static/list/public_cock_action_text_list = list("expands by an inch or so.", "appears to grow a bit longer.", "seems a bit bigger than it was before.", "suddenly lengthens about an inch or two.", )
|
||||
|
||||
if(mob_penis.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_bottomless())
|
||||
if(mob_penis?.genital_size >= (penis_max_length - 2))
|
||||
if(exposed_mob.dna.features["penis_sheath"] == SHEATH_SLIT)
|
||||
if(mob_penis.aroused != AROUSAL_FULL)
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(public_cock_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
if(exposed_mob.dna.features["penis_sheath"] == SHEATH_SLIT)
|
||||
if(mob_penis.aroused != AROUSAL_FULL)
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(cock_text_list)] [pick(public_cock_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
if(mob_penis?.genital_size >= (penis_max_length - 2))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
|
||||
if((mob_penis?.genital_size >= (penis_max_length - 2)) && (exposed_mob.w_uniform || exposed_mob.wear_suit))
|
||||
var/target_bodypart = exposed_mob.get_bodypart(BODY_ZONE_PRECISE_GROIN)
|
||||
if(prob(damage_chance))
|
||||
to_chat(exposed_mob, span_danger("You feel a tightness in your pants!"))
|
||||
exposed_mob.apply_damage(1, BRUTE, target_bodypart)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/penis_enlarger/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/penis_enlargement))
|
||||
if(!exposed_mob.getorganslot(ORGAN_SLOT_PENIS))
|
||||
///Check if human. If not do messy code. (This only supports lizards and human penises (for now))
|
||||
exposed_mob.dna.features["penis_sheath"] = SHEATH_NONE
|
||||
exposed_mob.dna.mutant_bodyparts["penis"][MUTANT_INDEX_NAME] = "Human"
|
||||
exposed_mob.dna.mutant_bodyparts["testicles"][MUTANT_INDEX_NAME] = "Pair"
|
||||
if((exposed_mob.dna.species.id == SPECIES_HUMAN) && (exposed_mob.dna.species.id != SPECIES_LIZARD) && (exposed_mob.dna.species.id != SPECIES_LIZARD_ASH))
|
||||
if (!exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES))
|
||||
var/obj/item/organ/balls_path = /obj/item/organ/external/genital/testicles
|
||||
balls_path = new /obj/item/organ/external/genital/testicles
|
||||
balls_path.build_from_dna(exposed_mob.dna, "testicles")
|
||||
balls_path.Insert(exposed_mob, 0, FALSE)
|
||||
var/obj/item/organ/external/genital/new_balls = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
new_balls.genital_size = 1
|
||||
new_balls.update_sprite_suffix()
|
||||
if((exposed_mob.dna.species.id == SPECIES_LIZARD) || (exposed_mob.dna.species.id == SPECIES_LIZARD_ASH))
|
||||
exposed_mob.dna.features["penis_sheath"] = SHEATH_SLIT
|
||||
exposed_mob.dna.mutant_bodyparts["penis"][MUTANT_INDEX_NAME] = "Flared"
|
||||
exposed_mob.dna.mutant_bodyparts["penis"][MUTANT_INDEX_COLOR_LIST] = list("#FFB6C1")
|
||||
exposed_mob.dna.mutant_bodyparts["testicles"][MUTANT_INDEX_NAME] = "Internal"
|
||||
if (!exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES))
|
||||
var/obj/item/organ/balls_path = /obj/item/organ/external/genital/testicles
|
||||
balls_path = new /obj/item/organ/external/genital/testicles
|
||||
balls_path.build_from_dna(exposed_mob.dna, "testicles")
|
||||
balls_path.Insert(exposed_mob, 0, FALSE)
|
||||
var/obj/item/organ/external/genital/new_balls = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
new_balls.genital_size = 1
|
||||
new_balls.update_sprite_suffix()
|
||||
var/obj/item/organ/cock_path = /obj/item/organ/external/genital/penis
|
||||
cock_path = new /obj/item/organ/external/genital/penis
|
||||
cock_path.build_from_dna(exposed_mob.dna, "penis")
|
||||
cock_path.Insert(exposed_mob, 0, FALSE)
|
||||
var/obj/item/organ/external/genital/penis/new_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
new_penis.genital_size = 4
|
||||
new_penis.girth = 3
|
||||
new_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
to_chat(exposed_mob, span_purple("Your crotch feels warm as something suddenly sprouts between your legs."))
|
||||
///Makes the balls bigger if they're small.
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(mob_testicles)
|
||||
if(mob_testicles.genital_size > 2)
|
||||
return
|
||||
mob_testicles.genital_size = 2
|
||||
///Separates gender change stuff from cock growth.
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/gender_change))
|
||||
if(exposed_mob.gender == FEMALE)
|
||||
exposed_mob.set_gender(MALE)
|
||||
exposed_mob.physique = exposed_mob.gender
|
||||
exposed_mob.update_body()
|
||||
exposed_mob.update_mutations_overlay()
|
||||
if(!mob_breasts)
|
||||
return
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/breast_enlargement)) ///To do breast shrinkage, check if prefs allow for this.
|
||||
if(mob_breasts.genital_size > breast_minimum_size)
|
||||
mob_breasts.genital_size -= breast_size_reduction_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
|
||||
/*
|
||||
* CHEMICAL REACTIONS
|
||||
*/
|
||||
|
||||
/datum/chemical_reaction
|
||||
/// Will this reaction be disabled by the ERP config being turned off?
|
||||
var/erp_reaction = FALSE
|
||||
|
||||
/datum/chemical_reaction/crocin
|
||||
results = list(/datum/reagent/drug/aphrodisiac/crocin = 6)
|
||||
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/water = 1)
|
||||
required_temp = 400
|
||||
mix_message = "The mixture boils off a pink vapor..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/hexacrocin
|
||||
results = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 1)
|
||||
required_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 6, /datum/reagent/phenol = 1)
|
||||
required_temp = 600
|
||||
mix_message = "The mixture rapidly condenses and darkens in color..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/camphor
|
||||
results = list(/datum/reagent/drug/aphrodisiac/camphor = 6)
|
||||
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/sulfur = 1)
|
||||
required_temp = 400
|
||||
mix_message = "The mixture boils off a yellow, smelly vapor..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/pentacamphor
|
||||
results = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 1)
|
||||
required_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 5, /datum/reagent/acetone = 1)
|
||||
required_temp = 500
|
||||
mix_message = "The mixture thickens and heats up slighty..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/cum
|
||||
results = list(/datum/reagent/consumable/cum = 5)
|
||||
required_reagents = list(/datum/reagent/blood = 2, /datum/reagent/consumable/milk = 2, /datum/reagent/consumable/salt = 1)
|
||||
mix_message = "The mixture turns into a gooey, musky white liquid..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/breast_enlarger
|
||||
results = list(/datum/reagent/drug/aphrodisiac/breast_enlarger = 8)
|
||||
required_reagents = list(/datum/reagent/medicine/salglu_solution = 1, /datum/reagent/consumable/milk = 1, /datum/reagent/medicine/c2/synthflesh = 2, /datum/reagent/silicon = 3, /datum/reagent/drug/aphrodisiac/crocin = 3)
|
||||
mix_message = "the reaction gives off a mist of milk."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/datum/chemical_reaction/penis_enlarger
|
||||
results = list(/datum/reagent/drug/aphrodisiac/penis_enlarger = 8)
|
||||
required_reagents = list(/datum/reagent/blood = 5, /datum/reagent/medicine/c2/synthflesh = 2, /datum/reagent/carbon = 2, /datum/reagent/drug/aphrodisiac/crocin = 2, /datum/reagent/medicine/salglu_solution = 1)
|
||||
mix_message = "the reaction gives off a mist of milk."
|
||||
erp_reaction = TRUE
|
||||
|
||||
/*
|
||||
* PREMADE CONTAINERS
|
||||
*/
|
||||
|
||||
// BOTTLES
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/crocin
|
||||
name = "crocin bottle"
|
||||
desc = "A bottle of mild aphrodisiac. Increases libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/hexacrocin
|
||||
name = "hexacrocin bottle"
|
||||
desc = "A bottle of strong aphrodisiac. Increases libido. Potentially dangerous."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/dopamine
|
||||
name = "dopamine bottle"
|
||||
desc = "Pure pleasure and happines in a bottle."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/dopamine = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/camphor
|
||||
name = "camphor bottle"
|
||||
desc = "A bottle of mild anaphrodisiac. Reduces libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/pentacamphor
|
||||
name = "pentacamphor bottle"
|
||||
desc = "A bottle of strong anaphrodisiac. Reduces libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/breast_enlarger
|
||||
name = "succubus milk bottle"
|
||||
desc = "A bottle of strong breast enlargement reagent."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/breast_enlarger = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/penis_enlarger
|
||||
name = "incubus draft bottle"
|
||||
desc = "A bottle of strong penis enlargement reagent."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/penis_enlarger = 30)
|
||||
|
||||
|
||||
// PILLS
|
||||
|
||||
/obj/item/reagent_containers/pill/crocin
|
||||
name = "crocin pill (10u)"
|
||||
desc = "I've fallen, and I can't get it up!"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "crocin"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/hexacrocin
|
||||
name = "hexacrocin pill (10u)"
|
||||
desc = "Pill in creepy heart form."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "hexacrocin"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/dopamine
|
||||
name = "dopamine pill (5u)"
|
||||
desc = "Feelings of orgasm, contained in a pill... Weird."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "dopamine"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/dopamine = 5)
|
||||
|
||||
/obj/item/reagent_containers/pill/camphor
|
||||
name = "camphor pill (10u)"
|
||||
desc = "For the early bird."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "camphor"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/pentacamphor
|
||||
name = "pentacamphor pill (10u)"
|
||||
desc = "The chemical equivalent of horny jail."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "pentacamphor"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 10)
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/reagent_containers/cup/bottle/crocin
|
||||
name = "crocin bottle"
|
||||
desc = "A bottle of mild aphrodisiac. Increases libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/hexacrocin
|
||||
name = "hexacrocin bottle"
|
||||
desc = "A bottle of strong aphrodisiac. Increases libido. Potentially dangerous."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/dopamine
|
||||
name = "dopamine bottle"
|
||||
desc = "Pure pleasure and happines in a bottle."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/dopamine = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/camphor
|
||||
name = "camphor bottle"
|
||||
desc = "A bottle of mild anaphrodisiac. Reduces libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/pentacamphor
|
||||
name = "pentacamphor bottle"
|
||||
desc = "A bottle of strong anaphrodisiac. Reduces libido."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/succubus_milk
|
||||
name = "succubus milk bottle"
|
||||
desc = "A bottle of strong breast enlargement reagent."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/succubus_milk = 30)
|
||||
|
||||
/obj/item/reagent_containers/cup/bottle/incubus_draft
|
||||
name = "incubus draft bottle"
|
||||
desc = "A bottle of strong penis enlargement reagent."
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/incubus_draft = 30)
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/reagent_containers/pill/crocin
|
||||
name = "crocin pill (10u)"
|
||||
desc = "I've fallen, and I can't get it up!"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "crocin"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/hexacrocin
|
||||
name = "hexacrocin pill (10u)"
|
||||
desc = "Pill in creepy heart form."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "hexacrocin"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/dopamine
|
||||
name = "dopamine pill (5u)"
|
||||
desc = "Feelings of orgasm, contained in a pill... Weird."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "dopamine"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/dopamine = 5)
|
||||
|
||||
/obj/item/reagent_containers/pill/camphor
|
||||
name = "camphor pill (10u)"
|
||||
desc = "For the early bird."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "camphor"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 10)
|
||||
|
||||
/obj/item/reagent_containers/pill/pentacamphor
|
||||
name = "pentacamphor pill (10u)"
|
||||
desc = "The chemical equivalent of horny jail."
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_pills.dmi'
|
||||
icon_state = "pentacamphor"
|
||||
list_reagents = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 10)
|
||||
@@ -0,0 +1,6 @@
|
||||
///To notify, but not harm the player in terms of mood. Used for camphor, pentacamphor, succubus milk, and incubus draft.
|
||||
/datum/mood_event/minor_overdose
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/datum/mood_event/minor_overdose/add_effects(drug_name)
|
||||
description = "<span class='warning'>I think I took a bit too much [drug_name]...</span>\n"
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// The base ERP chem. It handles pref and human type checks for you, so ALL chems relating to ERP should be subtypes of this.
|
||||
/datum/reagent/drug/aphrodisiac
|
||||
name = "liquid ERP"
|
||||
description = "ERP in its liquified form. Complain to a coder."
|
||||
|
||||
/// What preference you need enabled for effects on life
|
||||
var/life_pref_datum = /datum/preference/toggle/erp
|
||||
/// What preference you need enabled for effects on overdose
|
||||
var/overdose_pref_datum = /datum/preference/toggle/erp
|
||||
|
||||
/// The amount to adjust the mob's arousal by
|
||||
var/arousal_adjust_amount = 1
|
||||
/// The amount to adjust the mob's pleasure by
|
||||
var/pleasure_adjust_amount = 0
|
||||
/// The amount to adjust the mob's pain by
|
||||
var/pain_adjust_amount = 0
|
||||
|
||||
// Vars for enlargement chems from here on
|
||||
/// Counts up to a threshold before triggering enlargement effects
|
||||
var/enlargement_amount = 0
|
||||
/// How much to increase the count by each process
|
||||
var/enlarger_increase_step = 5
|
||||
/// Count to reach before effects
|
||||
var/enlargement_threshold = 100
|
||||
|
||||
/// % chance for damage to be applied when the organ is too large and the mob is clothed
|
||||
var/damage_chance = 20
|
||||
|
||||
/// Largest length the chem can make a mob's penis
|
||||
var/penis_max_length = PENIS_MAX_LENGTH
|
||||
/// Smallest size the chem can make a mob's penis
|
||||
var/penis_min_length = PENIS_MIN_LENGTH
|
||||
/// How much the penis is increased in size each time it's run
|
||||
var/penis_length_increase_step = 1
|
||||
/// How much the penis is increased in girth each time it's run
|
||||
var/penis_girth_increase_step = 1
|
||||
/// Largest girth the chem can make a mob's penis
|
||||
var/penis_max_girth = PENIS_MAX_GIRTH
|
||||
/// Smallest girth the chem can make a mob's penis
|
||||
var/penis_minimum_girth = 2
|
||||
/// How much to reduce the size of the penis each time it's run
|
||||
var/penis_size_reduction_step = 2
|
||||
/// How much to reduce the girth of the penis each time it's run
|
||||
var/penis_girth_reduction_step = 2
|
||||
|
||||
/// Largest size the chem can make a mob's breasts
|
||||
var/max_breast_size = 16
|
||||
/// How much breasts are increased in size each time it's run
|
||||
var/breast_size_increase_step = 1
|
||||
/// Smallest size the chem can make a mob's breasts
|
||||
var/breast_minimum_size = 2
|
||||
/// How much to reduce the size of the breasts each time it's run
|
||||
var/breast_size_reduction_step = 1
|
||||
|
||||
/// Runs on life after preference checks. Use this instead of on_mob_life
|
||||
/datum/reagent/drug/aphrodisiac/proc/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
return
|
||||
|
||||
/// Runs on OD process after preference checks. Use this instead of overdose_process
|
||||
/datum/reagent/drug/aphrodisiac/proc/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
return
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(life_pref_datum && exposed_mob.client?.prefs.read_preference(life_pref_datum) && ishuman(exposed_mob))
|
||||
life_effects(exposed_mob)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(overdose_pref_datum && exposed_mob.client?.prefs.read_preference(overdose_pref_datum) && ishuman(exposed_mob))
|
||||
overdose_effects(exposed_mob)
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
/datum/chemical_reaction
|
||||
/// Will this reaction be disabled by the ERP config being turned off?
|
||||
var/erp_reaction = FALSE
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
/datum/reagent/consumable/breast_milk
|
||||
name = "breast milk"
|
||||
description = "This looks familiar... Wait, it's milk!"
|
||||
taste_description = "warm and creamy"
|
||||
color = "#ffffffff"
|
||||
glass_icon_state = "glass_white"
|
||||
glass_name = "glass of breast milk"
|
||||
glass_desc = "almost like normal milk."
|
||||
reagent_state = LIQUID
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// Camphor. Used to reduce libido.
|
||||
/// Able to reset one's genital size back to normal upon OD, or alternatively, if the user sets the size and then disables the organ, that size.
|
||||
/datum/reagent/drug/aphrodisiac/camphor
|
||||
name = "Camphor"
|
||||
description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When ingested by most animals it acts as an anaphrodisiac, \
|
||||
reducing libido and calming them. Non-habit forming and non-addictive. This is not an aphrodisiac."
|
||||
taste_description = "dull bitterness"
|
||||
taste_mult = 2
|
||||
color = "#D9D9D9"
|
||||
reagent_state = SOLID
|
||||
overdose_threshold = 25 // OD will reset sizes of genitals back to normal.
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = -12
|
||||
pleasure_adjust_amount = -3
|
||||
overdose_pref_datum = /datum/preference/toggle/erp // This will work without having aphrodisiacs enabled.
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
var/old_arousal = exposed_mob.arousal
|
||||
exposed_mob.adjust_arousal(arousal_adjust_amount)
|
||||
exposed_mob.adjust_pleasure(pleasure_adjust_amount)
|
||||
if(exposed_mob.arousal <= 0 && old_arousal > 0)
|
||||
to_chat(exposed_mob, span_notice("You no longer feel aroused."))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
var/modified_genitals = FALSE
|
||||
// Grows and shrinks organs depending on prefs, returning to normal. Offers a way of resetting succubus milk / incubus draft sizes, but not organs.
|
||||
|
||||
// Resets gender if prefs enabled.
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/gender_change) && exposed_mob.gender != exposed_mob.client?.prefs?.read_preference(/datum/preference/choiced/gender))
|
||||
exposed_mob.set_gender(exposed_mob.client?.prefs?.read_preference(/datum/preference/choiced/gender))
|
||||
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_BREASTS))
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
var/original_breast_size = GLOB.breast_size_to_number[exposed_mob.client?.prefs.read_preference(/datum/preference/choiced/breasts_size)]
|
||||
if(original_breast_size)
|
||||
if(mob_breasts?.genital_size > original_breast_size)
|
||||
mob_breasts.genital_size -= breast_size_reduction_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if(mob_breasts?.genital_size < original_breast_size)
|
||||
mob_breasts.genital_size += breast_size_increase_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_PENIS))
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/numeric/penis_length))
|
||||
var/original_penis_length = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/penis_length)
|
||||
var/original_penis_girth = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/penis_girth)
|
||||
// Run to go through girth first.
|
||||
if(mob_penis?.girth > original_penis_girth)
|
||||
mob_penis.girth -= penis_girth_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if(mob_penis?.girth < original_penis_girth)
|
||||
mob_penis.girth += penis_girth_increase_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if(mob_penis?.genital_size > original_penis_length)
|
||||
mob_penis.genital_size -= penis_size_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if(mob_penis?.genital_size < original_penis_length)
|
||||
mob_penis.genital_size += penis_length_increase_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
|
||||
if(exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES))
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/numeric/balls_size))
|
||||
var/original_ball_size = exposed_mob.client?.prefs.read_preference(/datum/preference/numeric/balls_size)
|
||||
if(mob_testicles?.genital_size > original_ball_size)
|
||||
mob_testicles.genital_size -= 1
|
||||
mob_testicles.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if(mob_testicles?.genital_size < original_ball_size)
|
||||
mob_testicles.genital_size += 1
|
||||
mob_testicles.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
|
||||
if(modified_genitals)
|
||||
exposed_mob.update_body()
|
||||
|
||||
// Notify the user that they're overdosing. Doesn't affect their mood.
|
||||
/datum/reagent/drug/aphrodisiac/camphor/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
to_chat(exposed_mob, span_userdanger("You feel like you took too much [name]!"))
|
||||
exposed_mob.add_mood_event("[type]_overdose", /datum/mood_event/minor_overdose, name)
|
||||
|
||||
/datum/chemical_reaction/camphor
|
||||
results = list(/datum/reagent/drug/aphrodisiac/camphor = 6)
|
||||
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/sulfur = 1)
|
||||
required_temp = 400
|
||||
mix_message = "The mixture boils off a yellow, smelly vapor..."
|
||||
erp_reaction = TRUE
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Crocin. Basic aphrodisiac with no consequences
|
||||
/datum/reagent/drug/aphrodisiac/crocin
|
||||
name = "crocin"
|
||||
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
|
||||
taste_description = "strawberries"
|
||||
color = "#FFADFF"
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = 1
|
||||
pleasure_adjust_amount = 0
|
||||
pain_adjust_amount = 0
|
||||
|
||||
/// Probability of the chem triggering an emote, as a %, run on mob life
|
||||
var/emote_probability = 3
|
||||
/// Probability of the chem triggering a to_chat, as a %, run on mob life
|
||||
var/thought_probability = 2
|
||||
|
||||
/// A list of possible emotes the chem is able to trigger
|
||||
var/list/possible_aroused_emotes = list("moan", "blush")
|
||||
|
||||
/// A list of possible to_chat messages the chem is able to trigger
|
||||
var/list/possible_aroused_thoughts = list(
|
||||
"You feel frisky.",
|
||||
"You're having trouble suppressing your urges.",
|
||||
"You feel in the mood.",
|
||||
)
|
||||
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(prob(emote_probability))
|
||||
exposed_mob.emote(pick(possible_aroused_emotes))
|
||||
if(prob(thought_probability))
|
||||
var/displayed_thought = pick(possible_aroused_thoughts)
|
||||
to_chat(exposed_mob, span_notice("[displayed_thought]"))
|
||||
|
||||
exposed_mob.adjust_arousal(arousal_adjust_amount)
|
||||
exposed_mob.adjust_pleasure(pleasure_adjust_amount)
|
||||
exposed_mob.adjust_pain(pain_adjust_amount)
|
||||
|
||||
var/modified_genitals = FALSE
|
||||
for(var/obj/item/organ/external/genital/mob_genitals in exposed_mob.external_organs)
|
||||
if(!mob_genitals.aroused == AROUSAL_CANT)
|
||||
mob_genitals.aroused = AROUSAL_FULL
|
||||
mob_genitals.update_sprite_suffix()
|
||||
modified_genitals = TRUE
|
||||
if (modified_genitals)
|
||||
exposed_mob.update_body()
|
||||
|
||||
/datum/chemical_reaction/crocin
|
||||
results = list(/datum/reagent/drug/aphrodisiac/crocin = 6)
|
||||
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/water = 1)
|
||||
required_temp = 400
|
||||
mix_message = "The mixture boils off a pink vapor..."
|
||||
erp_reaction = TRUE
|
||||
@@ -0,0 +1,25 @@
|
||||
/datum/reagent/consumable/femcum
|
||||
name = "femcum"
|
||||
description = "Uhh... Someone had fun."
|
||||
taste_description = "astringent and sweetish"
|
||||
color = "#ffffffb0"
|
||||
glass_name = "glass of girlcum"
|
||||
glass_desc = "A strange white liquid... Ew!"
|
||||
reagent_state = LIQUID
|
||||
shot_glass_icon_state = "shotglasswhite"
|
||||
|
||||
/datum/reagent/consumable/cum
|
||||
name = "cum"
|
||||
description = "A fluid secreted by the sexual organs of many species."
|
||||
taste_description = "musky and salty"
|
||||
color = "#ffffffff"
|
||||
glass_name = "glass of cum"
|
||||
glass_desc = "O-oh, my...~"
|
||||
reagent_state = LIQUID
|
||||
shot_glass_icon_state = "shotglasswhite"
|
||||
|
||||
/datum/chemical_reaction/cum
|
||||
results = list(/datum/reagent/consumable/cum = 5)
|
||||
required_reagents = list(/datum/reagent/blood = 2, /datum/reagent/consumable/milk = 2, /datum/reagent/consumable/salt = 1) // Iiiinteresting...
|
||||
mix_message = "The mixture turns into a gooey, musky white liquid..."
|
||||
erp_reaction = TRUE
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Dopamine. Generates in character after orgasm.
|
||||
/datum/reagent/drug/aphrodisiac/dopamine
|
||||
name = "dopamine...?"
|
||||
description = "Pure happiness"
|
||||
taste_description = "an indescribable, slightly sour taste. Something in it relaxes you, filling you with pleasure."
|
||||
color = "#97ffee"
|
||||
glass_name = "dopamine"
|
||||
glass_desc = "Delicious flavored reagent. You feel happy even looking at it."
|
||||
reagent_state = LIQUID
|
||||
overdose_threshold = 10
|
||||
life_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
arousal_adjust_amount = 0.5
|
||||
pleasure_adjust_amount = 0.3
|
||||
pain_adjust_amount = -0.5
|
||||
|
||||
/// How druggy the chem will make the mob
|
||||
var/drugginess_amount = 5 SECONDS
|
||||
/// How likely the drug is to make the mob druggy per life process
|
||||
var/drugginess_chance = 7
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/on_mob_add(mob/living/carbon/human/exposed_mob)
|
||||
if(!(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/aphro)))
|
||||
return ..()
|
||||
exposed_mob.add_mood_event("[type]_start", /datum/mood_event/orgasm, name)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
exposed_mob.set_drugginess(drugginess_amount)
|
||||
if(prob(drugginess_chance))
|
||||
exposed_mob.emote(pick("twitch", "drool", "moan", "giggle", "shaking"))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/overdose_start(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
to_chat(exposed_mob, span_purple("You feel so happy!"))
|
||||
exposed_mob.add_mood_event("[type]_overdose", /datum/mood_event/overgasm, name)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(!(exposed_mob.hallucination < volume && prob(20)))
|
||||
return ..()
|
||||
exposed_mob.adjust_arousal(arousal_adjust_amount)
|
||||
exposed_mob.adjust_pleasure(pleasure_adjust_amount)
|
||||
exposed_mob.adjust_pain(pain_adjust_amount)
|
||||
if(prob(2))
|
||||
exposed_mob.emote(pick("moan", "twitch_s"))
|
||||
|
||||
// This chem shouldn't affect user's mood negatively.
|
||||
/datum/reagent/drug/aphrodisiac/dopamine/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
return
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#define OD_CHANCE_NO_TRAUMA 95
|
||||
|
||||
// Hexacrocin. Advanced aphrodisiac that can cause brain traumas.
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin
|
||||
name = "hexacrocin"
|
||||
description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive for most animals.\
|
||||
Addiction withdrawals can cause brain damage and shortness of breath. Overdose can lead to brain traumas."
|
||||
taste_description = "liquid desire"
|
||||
color = "#FF2BFF"
|
||||
overdose_threshold = 25
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/bimbofication
|
||||
|
||||
emote_probability = 5
|
||||
thought_probability = 5
|
||||
arousal_adjust_amount = 2
|
||||
pleasure_adjust_amount = 1.5
|
||||
pain_adjust_amount = 0.2
|
||||
possible_aroused_thoughts = list(
|
||||
"You feel a bit hot.",
|
||||
"You feel strong sexual urges.",
|
||||
"You feel in the mood.",
|
||||
"You're ready to go down on someone.",
|
||||
)
|
||||
|
||||
/// A list of possible to_chat messages the chem is able to trigger after enough cycles in the mobs system
|
||||
var/list/extreme_aroused_thoughts = list(
|
||||
"You need to fuck someone!",
|
||||
"You're bursting with sexual tension!",
|
||||
"You can't get sex off your mind!",
|
||||
)
|
||||
/// How many cycles the chem has to be in the mob's system before triggering extreme effects
|
||||
var/extreme_thought_threshold = 25
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(prob(thought_probability) && current_cycle >= extreme_thought_threshold)
|
||||
var/displayed_extreme_thought = pick(extreme_aroused_thoughts)
|
||||
to_chat(exposed_mob, span_purple("[displayed_extreme_thought]"))
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/crocin/hexacrocin/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(prob(OD_CHANCE_NO_TRAUMA) || HAS_TRAIT(exposed_mob, TRAIT_BIMBO))
|
||||
return ..()
|
||||
|
||||
to_chat(exposed_mob, span_purple("Your libido is going haywire! It feels like speaking is much harder..."))
|
||||
exposed_mob.gain_trauma(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_BASIC)
|
||||
ADD_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT)
|
||||
|
||||
/datum/chemical_reaction/hexacrocin
|
||||
results = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 1)
|
||||
required_reagents = list(/datum/reagent/drug/aphrodisiac/crocin = 6, /datum/reagent/phenol = 1)
|
||||
required_temp = 600
|
||||
mix_message = "The mixture rapidly condenses and darkens in color..."
|
||||
erp_reaction = TRUE
|
||||
|
||||
#undef OD_CHANCE_NO_TRAUMA
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* PENIS ENLARGEMENT
|
||||
* Normal function increases the player's penis size.
|
||||
* If the player's penis is near or at the maximum size and they're wearing clothing, it presses against the player's clothes and causes brute damage.
|
||||
* If gender change preference is enabled: Overdosing makes you male if female, makes the player grow a cock, and shrinks the player's breasts to a minimum size.
|
||||
* If the gender change preference is not enabled: Overdosing will just make you grow a cock if you don't have one.
|
||||
*/
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/incubus_draft
|
||||
name = "incubus draft"
|
||||
description = "A volatile collodial mixture derived from various masculine solutions that encourages a larger gentleman's package via a potent testosterone mix."
|
||||
color = "#888888"
|
||||
taste_description = "chinese dragon powder"
|
||||
overdose_threshold = 20 // ODing makes you male and shrinks female genitals if gender change prefs are enabled. Otherwise, grows a cock.
|
||||
metabolization_rate = 0.25
|
||||
life_pref_datum = /datum/preference/toggle/erp/penis_enlargement
|
||||
overdose_pref_datum = /datum/preference/toggle/erp
|
||||
|
||||
// Not important at all, really, but I don't want folk complaining about a removed feature.
|
||||
var/static/list/species_to_penis = list(
|
||||
SPECIES_HUMAN = list(
|
||||
"sheath" = SHEATH_NONE,
|
||||
"mutant_index" = "Human",
|
||||
"balls" = "Pair"
|
||||
),
|
||||
SPECIES_LIZARD = list(
|
||||
"sheath" = SHEATH_SLIT,
|
||||
"color" = "#FFB6C1",
|
||||
"mutant_index" = "Flared",
|
||||
"balls" = "Internal"
|
||||
),
|
||||
SPECIES_LIZARD_ASH = list(
|
||||
"sheath" = SHEATH_SLIT,
|
||||
"color" = "#FFB6C1",
|
||||
"mutant_index" = "Flared",
|
||||
"balls" = "Internal"
|
||||
),
|
||||
)
|
||||
|
||||
/// Words for the cock when huge.
|
||||
var/static/list/words_for_bigger_cock = list(
|
||||
"huge",
|
||||
"massive",
|
||||
"gigantic",
|
||||
"rather lengthy",
|
||||
"colossal",
|
||||
"hefty",
|
||||
)
|
||||
/// Synonyms for cock.
|
||||
var/static/list/cock_text_list = list(
|
||||
"cock",
|
||||
"penis",
|
||||
"dick",
|
||||
"member",
|
||||
"richard",
|
||||
"johnston",
|
||||
"johnson",
|
||||
)
|
||||
/// Synonyms for bigger cock.
|
||||
var/static/list/bigger_cock_text_list = list(
|
||||
"rod",
|
||||
"shaft",
|
||||
"cock",
|
||||
"penis",
|
||||
"dick",
|
||||
"member",
|
||||
"richard",
|
||||
"johnston",
|
||||
"johnson",
|
||||
)
|
||||
/// Wording chosen to extend the cock, shown only to the mob.
|
||||
var/static/list/cock_action_text_list = list(
|
||||
"extends to ",
|
||||
"grows out to ",
|
||||
"begins to enlarge, growing to ",
|
||||
"suddenly expands to ",
|
||||
"lengthens out to ",
|
||||
)
|
||||
/// Wording chosen to be seen by other mobs, while mob is unclothed.
|
||||
var/static/list/public_cock_action_text_list = list(
|
||||
"expands by an inch or so.",
|
||||
"appears to grow a bit longer.",
|
||||
"seems a bit bigger than it was before.",
|
||||
"suddenly lengthens about an inch or two.",
|
||||
)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/incubus_draft/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
enlargement_amount += enlarger_increase_step
|
||||
// Add yet another check because I hate errors!!
|
||||
if(!mob_penis)
|
||||
return
|
||||
if(enlargement_amount >= enlargement_threshold)
|
||||
if(mob_penis?.genital_size >= penis_max_length)
|
||||
return ..()
|
||||
mob_penis.genital_size += penis_length_increase_step
|
||||
// Improvision to girth to not make it random chance.
|
||||
if(mob_penis?.girth < penis_max_girth) // Because any higher is ridiculous. However, should still allow for regular penis growth.
|
||||
mob_penis.girth = round(mob_penis.girth + (mob_penis.genital_size/mob_penis.girth))
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
|
||||
if(mob_penis.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_bottomless())
|
||||
if(mob_penis?.genital_size >= (penis_max_length - 2))
|
||||
if(exposed_mob.dna.features["penis_sheath"] == SHEATH_SLIT)
|
||||
if(mob_penis.aroused != AROUSAL_FULL)
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(public_cock_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
if(exposed_mob.dna.features["penis_sheath"] == SHEATH_SLIT)
|
||||
if(mob_penis.aroused != AROUSAL_FULL)
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(cock_text_list)] [pick(public_cock_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
if(mob_penis?.genital_size >= (penis_max_length - 2))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger_cock)] [pick(bigger_cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
else
|
||||
to_chat(exposed_mob, span_purple("Your [pick(cock_text_list)] [pick(cock_action_text_list)]about [mob_penis.genital_size] inches long, and [mob_penis.girth] inches in circumference."))
|
||||
return
|
||||
|
||||
if((mob_penis?.genital_size >= (penis_max_length - 2)) && (exposed_mob.w_uniform || exposed_mob.wear_suit))
|
||||
var/target_bodypart = exposed_mob.get_bodypart(BODY_ZONE_PRECISE_GROIN)
|
||||
if(prob(damage_chance))
|
||||
to_chat(exposed_mob, span_danger("You feel a tightness in your pants!"))
|
||||
exposed_mob.apply_damage(1, BRUTE, target_bodypart)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/incubus_draft/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/penis_enlargement))
|
||||
if(!exposed_mob.getorganslot(ORGAN_SLOT_PENIS) && exposed_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/new_genitalia_growth))
|
||||
var/list/data = species_to_penis[exposed_mob.dna.species.id]
|
||||
if(!data)
|
||||
data = species_to_penis[SPECIES_HUMAN]
|
||||
|
||||
exposed_mob.dna.features["penis_sheath"] = data["sheath"]
|
||||
exposed_mob.dna.mutant_bodyparts[ORGAN_SLOT_PENIS][MUTANT_INDEX_NAME] = data["index_name"]
|
||||
exposed_mob.dna.mutant_bodyparts[ORGAN_SLOT_TESTICLES][MUTANT_INDEX_NAME] = data["balls"]
|
||||
var/colour = data["colour"]
|
||||
if(colour)
|
||||
exposed_mob.dna.mutant_bodyparts[ORGAN_SLOT_PENIS][MUTANT_INDEX_COLOR_LIST] = list(colour)
|
||||
|
||||
if(!exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES))
|
||||
var/obj/item/organ/balls_path = /obj/item/organ/external/genital/testicles
|
||||
balls_path = new /obj/item/organ/external/genital/testicles
|
||||
balls_path.build_from_dna(exposed_mob.dna, ORGAN_SLOT_TESTICLES)
|
||||
balls_path.Insert(exposed_mob, 0, FALSE)
|
||||
var/obj/item/organ/external/genital/new_balls = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
new_balls.genital_size = 1
|
||||
new_balls.update_sprite_suffix()
|
||||
|
||||
var/obj/item/organ/external/genital/penis/new_penis = new /obj/item/organ/external/genital/penis
|
||||
new_penis.build_from_dna(exposed_mob.dna, ORGAN_SLOT_PENIS)
|
||||
new_penis.Insert(exposed_mob, 0, FALSE)
|
||||
new_penis.genital_size = 4
|
||||
new_penis.girth = 3
|
||||
new_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
to_chat(exposed_mob, span_purple("Your crotch feels warm as something suddenly sprouts between your legs."))
|
||||
// Makes the balls bigger if they're small.
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(mob_testicles)
|
||||
if(mob_testicles.genital_size > 2)
|
||||
return
|
||||
mob_testicles.genital_size = 2
|
||||
// Separates gender change stuff from cock growth.
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/gender_change))
|
||||
if(exposed_mob.gender == FEMALE)
|
||||
exposed_mob.set_gender(MALE)
|
||||
exposed_mob.physique = exposed_mob.gender
|
||||
exposed_mob.update_body()
|
||||
exposed_mob.update_mutations_overlay()
|
||||
if(!mob_breasts)
|
||||
return
|
||||
if(exposed_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp/breast_enlargement)) // To do breast shrinkage, check if prefs allow for this.
|
||||
if(mob_breasts.genital_size > breast_minimum_size)
|
||||
mob_breasts.genital_size -= breast_size_reduction_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
return
|
||||
|
||||
// Notify the user that they're overdosing. Doesn't affect their mood.
|
||||
/datum/reagent/drug/aphrodisiac/incubus_draft/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
to_chat(exposed_mob, span_userdanger("You feel like you took too much [name]!"))
|
||||
exposed_mob.add_mood_event("[type]_overdose", /datum/mood_event/minor_overdose, name)
|
||||
|
||||
/datum/chemical_reaction/incubus_draft
|
||||
results = list(/datum/reagent/drug/aphrodisiac/incubus_draft = 8)
|
||||
required_reagents = list(/datum/reagent/blood = 5, /datum/reagent/medicine/c2/synthflesh = 2, /datum/reagent/carbon = 2, /datum/reagent/drug/aphrodisiac/crocin = 2, /datum/reagent/medicine/salglu_solution = 1)
|
||||
mix_message = "the reaction gives off a mist of milk."
|
||||
erp_reaction = TRUE
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// Pentacamphor. Used to purge crocin and hexacrocin. Can permanently disable arousal or cure bimbofication on overdose.
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor
|
||||
name = "Pentacamphor"
|
||||
description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive."
|
||||
taste_description = "tranquil celibacy"
|
||||
color = "#D9D9D9"//rgb(255, 255, 255)
|
||||
reagent_state = SOLID
|
||||
overdose_threshold = 20
|
||||
arousal_adjust_amount = -18
|
||||
overdose_pref_datum = /datum/preference/toggle/erp/aphro
|
||||
|
||||
/// How much of the given reagent to remove per operation
|
||||
var/reagent_reduction_amount = 20
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor/life_effects(mob/living/carbon/human/exposed_mob)
|
||||
. = ..()
|
||||
if(exposed_mob.reagents.has_reagent(/datum/reagent/drug/aphrodisiac/crocin))
|
||||
exposed_mob.reagents.remove_reagent(/datum/reagent/drug/aphrodisiac/crocin, reagent_reduction_amount)
|
||||
if(exposed_mob.reagents.has_reagent(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin))
|
||||
exposed_mob.reagents.remove_reagent(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin, reagent_reduction_amount)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/camphor/pentacamphor/overdose_start(mob/living/carbon/human/exposed_mob)
|
||||
if(HAS_TRAIT(exposed_mob, TRAIT_BIMBO))
|
||||
exposed_mob.cure_trauma_type(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
to_chat(exposed_mob, span_notice("Your mind is free. Your thoughts are pure and innocent once more."))
|
||||
REMOVE_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT)
|
||||
return
|
||||
if(!HAS_TRAIT(exposed_mob, TRAIT_NEVERBONER))
|
||||
to_chat(exposed_mob, span_notice("You feel like you'll never feel aroused again..."))
|
||||
ADD_TRAIT(exposed_mob, TRAIT_NEVERBONER, LEWDCHEM_TRAIT)
|
||||
|
||||
/datum/chemical_reaction/pentacamphor
|
||||
results = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 1)
|
||||
required_reagents = list(/datum/reagent/drug/aphrodisiac/camphor = 5, /datum/reagent/acetone = 1)
|
||||
required_temp = 500
|
||||
mix_message = "The mixture thickens and heats up slighty..."
|
||||
erp_reaction = TRUE
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* BREAST ENLARGEMENT
|
||||
* Normal function increases the player's breast size.
|
||||
* If the player's breasts are near or at the maximum size and they're wearing clothing, they press against the player's clothes and causes brute and oxygen damage.
|
||||
* If gender change preference is enabled: Overdosing makes you female if male, makes the player grow breasts, sets the player's testicles to the minimum size, and shrinks the player's penis to a minimum size.
|
||||
* If the gender change preference is not enabled: Overdosing will just make you grow breasts if you don't have any.
|
||||
* Credit to Citadel for the original code before modification
|
||||
*/
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/succubus_milk
|
||||
name = "succubus milk"
|
||||
description = "A volatile collodial mixture derived from milk that encourages mammary production via a potent estrogen mix."
|
||||
color = "#E60584"
|
||||
taste_description = "a milky ice cream like flavour"
|
||||
overdose_threshold = 20
|
||||
metabolization_rate = 0.25
|
||||
life_pref_datum = /datum/preference/toggle/erp/breast_enlargement
|
||||
overdose_pref_datum = /datum/preference/toggle/erp
|
||||
|
||||
/// Words for the breasts when huge.
|
||||
var/static/list/words_for_bigger = list(
|
||||
"huge",
|
||||
"massive",
|
||||
"squishy",
|
||||
"gigantic",
|
||||
"rather large",
|
||||
"jiggly",
|
||||
"hefty",
|
||||
)
|
||||
/// Synonyms for breasts.
|
||||
var/static/list/boob_text_list = list(
|
||||
"boobs",
|
||||
"tits",
|
||||
"breasts",
|
||||
)
|
||||
/// Synonyms for the chest.
|
||||
var/static/list/covered_boobs_list = list(
|
||||
"bust",
|
||||
"chest",
|
||||
"bosom",
|
||||
)
|
||||
/// Synonyms for bigger breasts.
|
||||
var/static/list/bigger_boob_text_list = list(
|
||||
"jigglies",
|
||||
"melons",
|
||||
"jugs",
|
||||
"boobies",
|
||||
"milkers",
|
||||
"boobs",
|
||||
"tits",
|
||||
"breasts",
|
||||
)
|
||||
/// Wording chosen to expand the breasts,shown only to the mob.
|
||||
var/static/list/action_text_list = list(
|
||||
"expand outward to ",
|
||||
"grow out to ",
|
||||
"begin to enlarge, growing to ",
|
||||
"suddenly expand to ",
|
||||
"swell out to ",
|
||||
)
|
||||
/// Wording chosen to be seen by other mobs, regardless of whether mob is clothed/unclothed.
|
||||
var/static/list/public_bigger_action_text_list = list(
|
||||
"expand and jiggle outward.",
|
||||
"grow a bit larger, bouncing about.",
|
||||
"seem a bit bigger than they were before.",
|
||||
"bounce and jiggle as they suddenly expand.",
|
||||
)
|
||||
/// Wording chosen to be seen by other mobs, while mob is unclothed.
|
||||
var/static/list/public_action_text_list = list(
|
||||
"expand outward.",
|
||||
"seem to grow a bit larger.",
|
||||
"appear a bit bigger than they were before.",
|
||||
"bounce and jiggle as they suddenly expand.",
|
||||
)
|
||||
/// Wording chosen to be seen by other mobs, while mob is clothed.
|
||||
var/static/list/notice_boobs = list(
|
||||
"seems to be a bit tighter.",
|
||||
"appears to be a bit bigger.",
|
||||
"seems to swell outward a bit.",
|
||||
)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/succubus_milk/life_effects(mob/living/carbon/human/exposed_mob) //Increases breast size
|
||||
var/obj/item/organ/external/genital/breasts/mob_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
enlargement_amount += enlarger_increase_step
|
||||
// Adds a check for breasts in the first place.
|
||||
if(!mob_breasts)
|
||||
return
|
||||
if(enlargement_amount >= enlargement_threshold)
|
||||
if(mob_breasts?.genital_size >= max_breast_size)
|
||||
return
|
||||
mob_breasts.genital_size += breast_size_increase_step
|
||||
mob_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
|
||||
// Checks for cup size.
|
||||
var/translation = mob_breasts.breasts_size_to_cup(mob_breasts.genital_size)
|
||||
|
||||
if(mob_breasts.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_topless())
|
||||
switch(translation)
|
||||
if(BREAST_SIZE_FLATCHESTED)
|
||||
return
|
||||
if(BREAST_SIZE_BEYOND_MEASUREMENT)
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [mob_breasts.genital_size] inches in diameter."))
|
||||
return
|
||||
else
|
||||
if(mob_breasts?.genital_size >= (max_breast_size - 2))
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
switch(translation)
|
||||
if(BREAST_SIZE_FLATCHESTED)
|
||||
return
|
||||
if(BREAST_SIZE_BEYOND_MEASUREMENT)
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [mob_breasts.genital_size] inches in diameter."))
|
||||
return
|
||||
else
|
||||
if(mob_breasts?.genital_size >= (max_breast_size - 2))
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s [pick(boob_text_list)] [pick(public_bigger_action_text_list)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(words_for_bigger)] [pick(bigger_boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("The area around [exposed_mob]'s [pick(covered_boobs_list)] [pick(notice_boobs)]"))
|
||||
to_chat(exposed_mob, span_purple("Your [pick(boob_text_list)] [pick(action_text_list)]about [translation]-cups."))
|
||||
return
|
||||
|
||||
if((mob_breasts?.genital_size >= (max_breast_size - 2)) && (exposed_mob.w_uniform || exposed_mob.wear_suit))
|
||||
if(prob(damage_chance))
|
||||
to_chat(exposed_mob, span_danger("Your breasts begin to strain against your clothes!"))
|
||||
exposed_mob.adjustOxyLoss(5)
|
||||
exposed_mob.apply_damage(1, BRUTE, exposed_mob.get_bodypart(BODY_ZONE_CHEST))
|
||||
|
||||
// Turns you into a female if character is male. Also adds breasts.
|
||||
/datum/reagent/drug/aphrodisiac/succubus_milk/overdose_effects(mob/living/carbon/human/exposed_mob)
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/breast_enlargement))
|
||||
if(!exposed_mob.getorganslot(ORGAN_SLOT_BREASTS) && exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/new_genitalia_growth))
|
||||
var/obj/item/organ/path = /obj/item/organ/external/genital/breasts
|
||||
exposed_mob.dna.mutant_bodyparts[ORGAN_SLOT_BREASTS][MUTANT_INDEX_NAME] = "Pair"
|
||||
path = new /obj/item/organ/external/genital/breasts
|
||||
path.build_from_dna(exposed_mob.dna, ORGAN_SLOT_BREASTS)
|
||||
path.Insert(exposed_mob, FALSE, FALSE)
|
||||
var/obj/item/organ/external/genital/new_breasts = exposed_mob.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
new_breasts.genital_size = 2
|
||||
new_breasts.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
enlargement_amount = 0
|
||||
if(new_breasts.visibility_preference == GENITAL_ALWAYS_SHOW || exposed_mob.is_topless())
|
||||
exposed_mob.visible_message(span_notice("[exposed_mob]'s bust suddenly expands!"))
|
||||
to_chat(exposed_mob, span_purple("Your chest feels warm, tingling with sensitivity as it expands outward."))
|
||||
return
|
||||
else
|
||||
exposed_mob.visible_message(span_notice("The area around [exposed_mob]'s chest suddenly bounces a bit."))
|
||||
to_chat(exposed_mob, span_purple("Your chest feels warm, tingling with sensitivity as it strains against your clothes."))
|
||||
return
|
||||
// Separates gender change stuff from breast growth.
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/gender_change))
|
||||
var/obj/item/organ/external/genital/penis/mob_penis = exposed_mob.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/obj/item/organ/external/genital/testicles/mob_testicles = exposed_mob.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(exposed_mob.gender == MALE)
|
||||
exposed_mob.set_gender(FEMALE)
|
||||
exposed_mob.physique = exposed_mob.gender
|
||||
exposed_mob.update_body()
|
||||
exposed_mob.update_mutations_overlay()
|
||||
if(!mob_penis)
|
||||
return
|
||||
if(exposed_mob.client?.prefs.read_preference(/datum/preference/toggle/erp/penis_enlargement)) // To do cock shrinkage, check if prefs allow for this.
|
||||
if(mob_penis.genital_size > penis_min_length)
|
||||
mob_penis.genital_size -= penis_size_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
if(mob_penis.girth > penis_minimum_girth)
|
||||
mob_penis.girth -= penis_girth_reduction_step
|
||||
mob_penis.update_sprite_suffix()
|
||||
exposed_mob.update_body()
|
||||
if(!mob_testicles || mob_testicles.genital_size <= 1)
|
||||
return
|
||||
mob_testicles.genital_size -= 1
|
||||
return
|
||||
|
||||
// Notify the user that they're overdosing. Doesn't affect their mood.
|
||||
/datum/reagent/drug/aphrodisiac/succubus_milk/overdose_process(mob/living/carbon/human/exposed_mob)
|
||||
to_chat(exposed_mob, span_userdanger("You feel like you took too much [name]!"))
|
||||
exposed_mob.add_mood_event("[type]_overdose", /datum/mood_event/minor_overdose, name)
|
||||
|
||||
/datum/chemical_reaction/succubus_milk
|
||||
results = list(/datum/reagent/drug/aphrodisiac/succubus_milk = 8)
|
||||
required_reagents = list(/datum/reagent/medicine/salglu_solution = 1, /datum/reagent/consumable/milk = 1, /datum/reagent/medicine/c2/synthflesh = 2, /datum/reagent/silicon = 3, /datum/reagent/drug/aphrodisiac/crocin = 3)
|
||||
mix_message = "the reaction gives off a mist of milk."
|
||||
erp_reaction = TRUE
|
||||
@@ -82,8 +82,8 @@
|
||||
//chems
|
||||
/obj/item/reagent_containers/pill/crocin,
|
||||
/obj/item/reagent_containers/pill/camphor,
|
||||
/obj/item/reagent_containers/cup/bottle/breast_enlarger,
|
||||
/obj/item/reagent_containers/cup/bottle/penis_enlarger,
|
||||
/obj/item/reagent_containers/cup/bottle/succubus_milk,
|
||||
/obj/item/reagent_containers/cup/bottle/incubus_draft,
|
||||
/obj/item/reagent_containers/pill/hexacrocin,
|
||||
/obj/item/reagent_containers/pill/pentacamphor,
|
||||
/obj/item/reagent_containers/cup/bottle/hexacrocin,
|
||||
|
||||
@@ -92,6 +92,6 @@
|
||||
/obj/item/clothing/under/misc/latex_catsuit/Initialize(mapload)
|
||||
. = ..()
|
||||
breasts_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_uniform/lewd_uniform.dmi', "none", ABOVE_MOB_LAYER)
|
||||
breasts_overlay.icon_state = "breasts"
|
||||
breasts_overlay.icon_state = ORGAN_SLOT_BREASTS
|
||||
breasts_icon_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_uniform.dmi', "none")
|
||||
breasts_icon_overlay.icon_state = "breasts"
|
||||
breasts_icon_overlay.icon_state = ORGAN_SLOT_BREASTS
|
||||
|
||||
+11
-11
@@ -87,11 +87,11 @@
|
||||
src.dropped(hooman)
|
||||
return PROCESS_KILL
|
||||
if(tightness == SHIBARI_TIGHTNESS_LOW && hooman.arousal < 15)
|
||||
hooman.adjustArousal(0.6 * delta_time)
|
||||
hooman.adjust_arousal(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_MED && hooman.arousal < 25)
|
||||
hooman.adjustArousal(0.6 * delta_time)
|
||||
hooman.adjust_arousal(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_HIGH && hooman.arousal < 30)
|
||||
hooman.adjustArousal(0.6 * delta_time)
|
||||
hooman.adjust_arousal(0.6 * delta_time)
|
||||
|
||||
//stuff to apply processing on equip and add mood event for perverts
|
||||
/obj/item/clothing/under/shibari/equipped(mob/user, slot)
|
||||
@@ -133,7 +133,7 @@
|
||||
return PROCESS_KILL
|
||||
var/mob/living/carbon/human/hooman = loc
|
||||
if(tightness == SHIBARI_TIGHTNESS_HIGH && hooman.pain < 25)
|
||||
hooman.adjustPain(0.6 * delta_time)
|
||||
hooman.adjust_pain(0.6 * delta_time)
|
||||
|
||||
/obj/item/clothing/under/shibari/groin
|
||||
name = "crotch rope shibari"
|
||||
@@ -161,11 +161,11 @@
|
||||
return PROCESS_KILL
|
||||
var/mob/living/carbon/human/hooman = loc
|
||||
if(tightness == SHIBARI_TIGHTNESS_LOW && hooman.pleasure < 20)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_MED && hooman.pleasure < 60)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_HIGH)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
|
||||
/obj/item/clothing/under/shibari/full
|
||||
name = "shibari fullbody ropes"
|
||||
@@ -188,13 +188,13 @@
|
||||
return PROCESS_KILL
|
||||
var/mob/living/carbon/human/hooman = loc
|
||||
if(tightness == SHIBARI_TIGHTNESS_LOW && hooman.pleasure< 20)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_MED && hooman.pleasure < 60)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
if(tightness == SHIBARI_TIGHTNESS_HIGH)
|
||||
hooman.adjustPleasure(0.6 * delta_time)
|
||||
hooman.adjust_pleasure(0.6 * delta_time)
|
||||
if(hooman.pain < 40)
|
||||
hooman.adjustPain(0.6 * delta_time)
|
||||
hooman.adjust_pain(0.6 * delta_time)
|
||||
|
||||
#undef SHIBARI_TIGHTNESS_LOW
|
||||
#undef SHIBARI_TIGHTNESS_MED
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
created_sparks.start()
|
||||
|
||||
affected_mob.Paralyze(30)
|
||||
affected_mob.adjustPain(10)
|
||||
affected_mob.adjust_pain(10)
|
||||
affected_mob.adjust_stutter(30 SECONDS)
|
||||
|
||||
if(master)
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
return
|
||||
|
||||
else if(held == null)
|
||||
if(unheld.name =="strapon" && unheld.item_flags == ABSTRACT | HAND_ITEM)
|
||||
if(istype(unheld, /obj/item/strapon_dildo) && unheld.item_flags == ABSTRACT | HAND_ITEM)
|
||||
if(src == user.belt)
|
||||
qdel(unheld)
|
||||
//CODE FOR PUTTING STRAPON IN HANDS
|
||||
@@ -201,8 +201,8 @@
|
||||
if(vagina)
|
||||
if(hit_mob.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW)
|
||||
message = pick("delicately rubs [hit_mob]'s vagina with [src]", "uses [src] to fuck [hit_mob]'s vagina", "jams [hit_mob]'s pussy with [src]", "teases [hit_mob]'s pussy with [src]")
|
||||
hit_mob.adjustArousal(6)
|
||||
hit_mob.adjustPleasure(8)
|
||||
hit_mob.adjust_arousal(6)
|
||||
hit_mob.adjust_pleasure(8)
|
||||
if(prob(40))
|
||||
hit_mob.try_lewd_autoemote(pick("twitch_s", "moan"))
|
||||
user.visible_message(span_purple("[user] [message]!"))
|
||||
@@ -222,8 +222,8 @@
|
||||
if(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES) //Mouth only. Sorry, perverts. No eye/ear penetration for you today.
|
||||
if(!hit_mob.is_mouth_covered())
|
||||
message = pick("fucks [hit_mob]'s mouth with [src]", "chokes [hit_mob] by inserting [src] into [hit_mob.p_their()] throat", "forces [hit_mob] to suck [src]", "inserts [src] into [hit_mob]'s throat")
|
||||
hit_mob.adjustArousal(4)
|
||||
hit_mob.adjustPleasure(1)
|
||||
hit_mob.adjust_arousal(4)
|
||||
hit_mob.adjust_pleasure(1)
|
||||
hit_mob.adjustOxyLoss(1.5)
|
||||
if(prob(70))
|
||||
hit_mob.try_lewd_autoemote(pick("gasp", "moan"))
|
||||
@@ -242,8 +242,8 @@
|
||||
else
|
||||
if(hit_mob.is_bottomless())
|
||||
message = pick("fucks [hit_mob]'s ass with [src]", "uses [src] to fuck [hit_mob]'s anus", "jams [hit_mob]'s ass with [src]", "roughly fucks [hit_mob]'s ass with [src], causing their eyes to roll back")
|
||||
hit_mob.adjustArousal(5)
|
||||
hit_mob.adjustPleasure(5)
|
||||
hit_mob.adjust_arousal(5)
|
||||
hit_mob.adjust_pleasure(5)
|
||||
if(prob(60))
|
||||
hit_mob.try_lewd_autoemote(pick("twitch_s", "moan", "shiver"))
|
||||
user.visible_message(span_purple("[user] [message]!"))
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/// Helper proc for adding overrides to bodyparts to hide them if a catsuit or sleeping bag is worn. Allows for overrides for each, in case a part shouldn't be hidden.
|
||||
/datum/sprite_accessory/proc/lewd_is_hidden(mob/living/carbon/human/target_human, hide_if_catsuit = TRUE, hide_if_sleeping_bag = TRUE)
|
||||
if(target_human.wear_suit && istype(target_human.wear_suit, /obj/item/clothing/suit/straight_jacket/kinky_sleepbag))
|
||||
var/obj/item/clothing/suit/straight_jacket/kinky_sleepbag/sleeping_bag = target_human.wear_suit
|
||||
if(sleeping_bag.state_thing == "inflated")
|
||||
return hide_if_sleeping_bag
|
||||
return FALSE
|
||||
else if(target_human.w_uniform && istype(target_human.w_uniform, /obj/item/clothing/under/misc/latex_catsuit))
|
||||
return hide_if_catsuit
|
||||
return FALSE
|
||||
|
||||
// Extends default proc check for hidden ears for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/ears/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
// First lets proc default code
|
||||
. = ..()
|
||||
if(!.) // If true, ears already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden frills for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/frills/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, frills already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden head accessory for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/head_accessory/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, head accessory already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden horns for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/horns/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, horns already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden antenna for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/antenna/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, antenna already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden moth antenna for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/moth_antennae/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, moth antenna already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden skrell hair for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/skrell_hair/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, skrell hair already hidden
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
// Extends default proc check for hidden skrell hair for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/tails/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.) // If true, tail already hidden
|
||||
return lewd_is_hidden(target_human, hide_if_catsuit = FALSE)
|
||||
|
||||
/datum/sprite_accessory/xenodorsal/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
/datum/sprite_accessory/xenohead/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return lewd_is_hidden(target_human, hide_if_catsuit = FALSE, hide_if_sleeping_bag = FALSE)
|
||||
|
||||
// Extends default proc check for hidden wings for supporting our sleepbag and catsuit too
|
||||
/datum/sprite_accessory/wings/is_hidden(mob/living/carbon/human/target_human, obj/item/bodypart/bodypart)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return lewd_is_hidden(target_human)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Let's not force lewd emotes from folk who don't want them, mmm~?
|
||||
/mob/living/carbon/proc/try_lewd_autoemote(emote)
|
||||
if(!client?.prefs?.read_preference(/datum/preference/toggle/erp/autoemote))
|
||||
return
|
||||
emote(emote)
|
||||
@@ -0,0 +1,378 @@
|
||||
/mob/living/carbon/human
|
||||
var/arousal = 0
|
||||
var/pleasure = 0
|
||||
var/pain = 0
|
||||
|
||||
var/pain_limit = 0
|
||||
var/arousal_status = AROUSAL_NONE
|
||||
|
||||
// Add variables for slots to the human class
|
||||
var/obj/item/vagina = null
|
||||
var/obj/item/anus = null
|
||||
var/obj/item/nipples = null
|
||||
var/obj/item/penis = null
|
||||
|
||||
var/has_penis = FALSE
|
||||
var/has_vagina = FALSE
|
||||
var/has_breasts = FALSE
|
||||
var/has_anus = FALSE
|
||||
|
||||
|
||||
// For tracking arousal and fluid regen.
|
||||
/mob/living/carbon/human/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!istype(src, /mob/living/carbon/human/species/monkey))
|
||||
apply_status_effect(/datum/status_effect/aroused)
|
||||
apply_status_effect(/datum/status_effect/body_fluid_regen)
|
||||
|
||||
/*
|
||||
* This code needed to determine if the human is naked in that part of body or not
|
||||
* You can use this for your own stuff if you want, haha.
|
||||
*/
|
||||
|
||||
/// Are we wearing something that covers our chest?
|
||||
/mob/living/carbon/human/proc/is_topless()
|
||||
return (!(wear_suit) || !(wear_suit.body_parts_covered & CHEST)) && (!(w_uniform) || !(w_uniform.body_parts_covered & CHEST))
|
||||
|
||||
/// Are we wearing something that covers our groin?
|
||||
/mob/living/carbon/human/proc/is_bottomless()
|
||||
return (!(wear_suit) || !(wear_suit.body_parts_covered & GROIN)) && (!(w_uniform) || !(w_uniform.body_parts_covered & GROIN))
|
||||
|
||||
/// Are we wearing something that covers our shoes?
|
||||
/mob/living/carbon/human/proc/is_barefoot()
|
||||
return (!(wear_suit) || !(wear_suit.body_parts_covered & GROIN)) && (!(shoes) || !(shoes.body_parts_covered & FEET))
|
||||
|
||||
/mob/living/carbon/human/proc/is_hands_uncovered()
|
||||
return (gloves?.body_parts_covered & ARMS)
|
||||
|
||||
/mob/living/carbon/human/proc/is_head_uncovered()
|
||||
return (head?.body_parts_covered & HEAD)
|
||||
|
||||
/// Returns true if the human has an accessible penis for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_penis(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/external/genital/genital = getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return genital.visibility_preference == GENITAL_ALWAYS_SHOW || is_bottomless()
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return genital.visibility_preference != GENITAL_ALWAYS_SHOW && !is_bottomless()
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has a accessible balls for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_balls(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/external/genital/genital = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return genital.visibility_preference == GENITAL_ALWAYS_SHOW || is_bottomless()
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return genital.visibility_preference != GENITAL_ALWAYS_SHOW && !is_bottomless()
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has an accessible vagina for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_vagina(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/external/genital/genital = getorganslot(ORGAN_SLOT_VAGINA)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return genital.visibility_preference == GENITAL_ALWAYS_SHOW || is_bottomless()
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return genital.visibility_preference != GENITAL_ALWAYS_SHOW && !is_bottomless()
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has a accessible breasts for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_breasts(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/external/genital/genital = getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return genital.visibility_preference == GENITAL_ALWAYS_SHOW || is_topless()
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return genital.visibility_preference != GENITAL_ALWAYS_SHOW && !is_topless()
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has an accessible anus for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_anus(required_state = REQUIRE_GENITAL_ANY)
|
||||
if(issilicon(src))
|
||||
return TRUE
|
||||
var/obj/item/organ/external/genital/genital = getorganslot(ORGAN_SLOT_ANUS)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return genital.visibility_preference == GENITAL_ALWAYS_SHOW || is_bottomless()
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return genital.visibility_preference != GENITAL_ALWAYS_SHOW && !is_bottomless()
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has a accessible feet for the parameter, returning the number of feet the human has if they do. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_arms(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/hand_count = 0
|
||||
var/covered = 0
|
||||
var/is_covered = FALSE
|
||||
for(var/obj/item/bodypart/l_arm/left_arm in bodyparts)
|
||||
hand_count++
|
||||
for(var/obj/item/bodypart/r_arm/right_arm in bodyparts)
|
||||
hand_count++
|
||||
if(get_item_by_slot(ITEM_SLOT_HANDS))
|
||||
var/obj/item/clothing/gloves/worn_gloves = get_item_by_slot(ITEM_SLOT_HANDS)
|
||||
covered = worn_gloves.body_parts_covered
|
||||
if(covered & HANDS)
|
||||
is_covered = TRUE
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return hand_count
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
if(is_covered)
|
||||
return FALSE
|
||||
else
|
||||
return hand_count
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
if(!is_covered)
|
||||
return FALSE
|
||||
else
|
||||
return hand_count
|
||||
else
|
||||
return hand_count
|
||||
|
||||
/// Returns true if the human has a accessible feet for the parameter, returning the number of feet the human has if they do. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_feet(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/feet_count = 0
|
||||
|
||||
for(var/obj/item/bodypart/l_leg/left_leg in bodyparts)
|
||||
feet_count++
|
||||
for(var/obj/item/bodypart/r_leg/right_leg in bodyparts)
|
||||
feet_count++
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return feet_count
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
if(!is_barefoot())
|
||||
return FALSE
|
||||
else
|
||||
return feet_count
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
if(is_barefoot())
|
||||
return FALSE
|
||||
else
|
||||
return feet_count
|
||||
else
|
||||
return feet_count
|
||||
|
||||
/// Gets the number of feet the human has.
|
||||
/mob/living/carbon/human/proc/get_num_feet()
|
||||
return has_feet(REQUIRE_GENITAL_ANY)
|
||||
|
||||
/// Returns true if the human has a accessible ears for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_ears(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/genital = getorganslot(ORGAN_SLOT_EARS)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return !get_item_by_slot(ITEM_SLOT_EARS)
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return get_item_by_slot(ITEM_SLOT_EARS)
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/// Returns true if the human has accessible eyes for the parameter. Accepts any of the `REQUIRE_GENITAL_` defines.
|
||||
/mob/living/carbon/human/proc/has_eyes(required_state = REQUIRE_GENITAL_ANY)
|
||||
var/obj/item/organ/genital = getorganslot(ORGAN_SLOT_EYES)
|
||||
if(!genital)
|
||||
return FALSE
|
||||
|
||||
switch(required_state)
|
||||
if(REQUIRE_GENITAL_ANY)
|
||||
return TRUE
|
||||
if(REQUIRE_GENITAL_EXPOSED)
|
||||
return !get_item_by_slot(ITEM_SLOT_EYES)
|
||||
if(REQUIRE_GENITAL_UNEXPOSED)
|
||||
return get_item_by_slot(ITEM_SLOT_EYES)
|
||||
else
|
||||
return TRUE
|
||||
|
||||
|
||||
/*
|
||||
* This code needed for changing character's gender by chems
|
||||
*/
|
||||
|
||||
/// Sets the gender of the human, respecting prefs unless it's forced. Do not force in non-admin operations.
|
||||
/mob/living/carbon/human/proc/set_gender(ngender = NEUTER, silent = FALSE, update_icon = TRUE, forced = FALSE)
|
||||
var/bender = gender != ngender
|
||||
if((!client?.prefs?.read_preference(/datum/preference/toggle/erp/gender_change) && !forced) || !dna || !bender)
|
||||
return FALSE
|
||||
|
||||
if(ngender == MALE || ngender == FEMALE)
|
||||
dna.features["body_model"] = ngender
|
||||
if(!silent)
|
||||
var/adj = ngender == MALE ? "masculine" : "feminine"
|
||||
visible_message(span_boldnotice("[src] suddenly looks more [adj]!"), span_boldwarning("You suddenly feel more [adj]!"))
|
||||
else if(ngender == NEUTER)
|
||||
dna.features["body_model"] = MALE
|
||||
gender = ngender
|
||||
if(update_icon)
|
||||
update_body()
|
||||
|
||||
/*
|
||||
* ICON UPDATING EXTENTION
|
||||
*/
|
||||
|
||||
/// Updating vagina slot
|
||||
/mob/living/carbon/human/proc/update_inv_vagina()
|
||||
// on_mob stuff
|
||||
remove_overlay(VAGINA_LAYER)
|
||||
|
||||
var/obj/item/clothing/sextoy/sex_toy = vagina
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDESEXTOY)) // You can add proper flags here if required
|
||||
return
|
||||
|
||||
var/icon_file = vagina?.worn_icon
|
||||
var/mutable_appearance/vagina_overlay
|
||||
|
||||
if(!vagina_overlay)
|
||||
vagina_overlay = sex_toy?.build_worn_icon(default_layer = VAGINA_LAYER, default_icon_file = 'icons/mob/clothing/under/default.dmi', isinhands = FALSE, override_file = icon_file)
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
vagina_overlay?.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
|
||||
vagina_overlay?.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
|
||||
overlays_standing[VAGINA_LAYER] = vagina_overlay
|
||||
|
||||
apply_overlay(VAGINA_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/// Updating anus slot
|
||||
/mob/living/carbon/human/proc/update_inv_anus()
|
||||
// on_mob stuff
|
||||
remove_overlay(ANUS_LAYER)
|
||||
|
||||
var/obj/item/clothing/sextoy/sex_toy = anus
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDESEXTOY)) // You can add proper flags here if required
|
||||
return
|
||||
|
||||
var/icon_file = anus?.worn_icon
|
||||
var/mutable_appearance/anus_overlay
|
||||
|
||||
if(!anus_overlay)
|
||||
anus_overlay = sex_toy?.build_worn_icon(default_layer = ANUS_LAYER, default_icon_file = 'icons/mob/clothing/under/default.dmi', isinhands = FALSE, override_file = icon_file)
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
anus_overlay?.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
|
||||
anus_overlay?.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
|
||||
overlays_standing[ANUS_LAYER] = anus_overlay
|
||||
|
||||
apply_overlay(ANUS_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/// Updating nipples slot
|
||||
/mob/living/carbon/human/proc/update_inv_nipples()
|
||||
// on_mob stuff
|
||||
remove_overlay(NIPPLES_LAYER)
|
||||
|
||||
var/obj/item/clothing/sextoy/sex_toy = nipples
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDESEXTOY)) // You can add proper flags here if required
|
||||
return
|
||||
|
||||
var/icon_file = nipples?.worn_icon
|
||||
var/mutable_appearance/nipples_overlay
|
||||
|
||||
if(!nipples_overlay)
|
||||
nipples_overlay = sex_toy?.build_worn_icon(default_layer = NIPPLES_LAYER, default_icon_file = 'icons/mob/clothing/under/default.dmi', isinhands = FALSE, override_file = icon_file)
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
nipples_overlay?.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
|
||||
nipples_overlay?.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
|
||||
overlays_standing[NIPPLES_LAYER] = nipples_overlay
|
||||
|
||||
apply_overlay(NIPPLES_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/// Updating penis slot
|
||||
/mob/living/carbon/human/proc/update_inv_penis()
|
||||
// on_mob stuff
|
||||
remove_overlay(PENIS_LAYER)
|
||||
|
||||
var/obj/item/clothing/sextoy/sex_toy = penis
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDESEXTOY)) // You can add proper flags here if required
|
||||
return
|
||||
|
||||
var/icon_file = penis?.worn_icon
|
||||
var/mutable_appearance/penis_overlay
|
||||
|
||||
if(!penis_overlay)
|
||||
penis_overlay = sex_toy?.build_worn_icon(default_layer = PENIS_LAYER, default_icon_file = 'icons/mob/clothing/under/default.dmi', isinhands = FALSE, override_file = icon_file)
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
penis_overlay?.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
|
||||
penis_overlay?.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
|
||||
overlays_standing[PENIS_LAYER] = penis_overlay
|
||||
|
||||
apply_overlay(PENIS_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/// Helper proc for calling all the lewd slot update_inv_ procs.
|
||||
/mob/living/carbon/human/proc/update_inv_lewd()
|
||||
update_inv_vagina()
|
||||
update_inv_anus()
|
||||
update_inv_nipples()
|
||||
update_inv_penis()
|
||||
|
||||
/*
|
||||
* MISC LOGIC
|
||||
*/
|
||||
|
||||
// Handles breaking out of gloves that restrain people.
|
||||
/mob/living/carbon/human/resist_restraints()
|
||||
if(gloves?.breakouttime)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
cuff_resist(gloves)
|
||||
else
|
||||
..()
|
||||
|
||||
/// Checks if the human is wearing a condom, and also hasn't broken it.
|
||||
/mob/living/carbon/human/proc/is_wearing_condom()
|
||||
if(!penis || !istype(penis, /obj/item/clothing/sextoy/condom))
|
||||
return FALSE
|
||||
|
||||
var/obj/item/clothing/sextoy/condom/condom = penis
|
||||
return condom.condom_state == CONDOM_BROKEN
|
||||
|
||||
// For handling things that don't already have handcuff handlers.
|
||||
/mob/living/carbon/human/set_handcuffed(new_value)
|
||||
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/straight_jacket/kinky_sleepbag))
|
||||
return FALSE
|
||||
..()
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Looping sound for vibrating stuff
|
||||
*/
|
||||
|
||||
/datum/looping_sound/vibrator
|
||||
start_sound = 'modular_skyrat/modules/modular_items/lewd_items/sounds/bzzz-loop-1.ogg'
|
||||
start_length = 1
|
||||
mid_sounds = 'modular_skyrat/modules/modular_items/lewd_items/sounds/bzzz-loop-1.ogg'
|
||||
mid_length = 1
|
||||
end_sound = 'modular_skyrat/modules/modular_items/lewd_items/sounds/bzzz-loop-1.ogg'
|
||||
falloff_distance = 1
|
||||
falloff_exponent = 5
|
||||
extra_range = SILENCED_SOUND_EXTRARANGE
|
||||
ignore_walls = FALSE
|
||||
|
||||
/datum/looping_sound/vibrator/low
|
||||
volume = 80
|
||||
|
||||
/datum/looping_sound/vibrator/medium
|
||||
volume = 90
|
||||
|
||||
/datum/looping_sound/vibrator/high
|
||||
volume = 100
|
||||
|
||||
/*
|
||||
* Dancing pole code.
|
||||
*/
|
||||
|
||||
/atom
|
||||
var/pseudo_z_axis
|
||||
|
||||
/atom/proc/get_fake_z()
|
||||
return pseudo_z_axis
|
||||
|
||||
/obj/structure/table
|
||||
pseudo_z_axis = 8
|
||||
|
||||
/turf/open/get_fake_z()
|
||||
var/objschecked
|
||||
for(var/obj/structure/structurestocheck in contents)
|
||||
objschecked++
|
||||
if(structurestocheck.pseudo_z_axis)
|
||||
return structurestocheck.pseudo_z_axis
|
||||
if(objschecked >= 25)
|
||||
break
|
||||
return pseudo_z_axis
|
||||
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
pseudo_z_axis = newloc.get_fake_z()
|
||||
pixel_z = pseudo_z_axis
|
||||
|
||||
/// Used to add a cum decal to the floor while transferring viruses and DNA to it
|
||||
/mob/living/proc/add_cum_splatter_floor(turf/the_turf, female = FALSE)
|
||||
if(!the_turf)
|
||||
the_turf = get_turf(src)
|
||||
|
||||
var/selected_type = female ? /obj/effect/decal/cleanable/cum/femcum : /obj/effect/decal/cleanable/cum
|
||||
var/atom/stain = new selected_type(the_turf, get_static_viruses())
|
||||
|
||||
stain.transfer_mob_blood_dna(src) //I'm not adding a new forensics category for cumstains
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/item/organ/internal/brain/on_life(delta_time, times_fired) //All your horny is here *points to the head*
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/brain_owner = owner
|
||||
if(istype(brain_owner, /mob/living/carbon/human) && brain_owner.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
if(!(organ_flags & ORGAN_FAILING))
|
||||
brain_owner.dna.species.handle_arousal(brain_owner, delta_time, times_fired)
|
||||
@@ -0,0 +1,91 @@
|
||||
#define AROUSED_ALERT "aroused"
|
||||
#define AROUSED_SMALL "small"
|
||||
#define AROUSED_MEDIUM "medium"
|
||||
#define AROUSED_HIGH "high"
|
||||
#define AROUSED_MAX "max"
|
||||
|
||||
/// Sends an icon to the screen that gives an approximate indication of the mob's arousal.
|
||||
/datum/species/proc/throw_arousal_alert(level, atom/movable/screen/alert/aroused/arousal_alert, mob/living/carbon/human/targeted_human)
|
||||
targeted_human.throw_alert(AROUSED_ALERT, /atom/movable/screen/alert/aroused)
|
||||
arousal_alert?.icon_state = "arousal_[level]"
|
||||
arousal_alert?.update_icon()
|
||||
|
||||
/// Sends an icon to the screen that gives an approximate indication of the mob's pain. Looks like spikes/barbed wire.
|
||||
/datum/species/proc/overlay_pain(level, atom/movable/screen/alert/aroused/arousal_alert)
|
||||
arousal_alert?.cut_overlay(arousal_alert.pain_overlay)
|
||||
arousal_alert?.pain_level = level
|
||||
arousal_alert?.pain_overlay = arousal_alert.update_pain()
|
||||
arousal_alert?.add_overlay(arousal_alert.pain_overlay)
|
||||
arousal_alert?.update_overlays()
|
||||
|
||||
/// Sends an icon to the screen that gives an approximate indication of the mob's pleasure. Looks like a pink-white border on the arousal alert heart.
|
||||
/datum/species/proc/overlay_pleasure(level, atom/movable/screen/alert/aroused/arousal_alert)
|
||||
arousal_alert?.cut_overlay(arousal_alert.pleasure_overlay)
|
||||
arousal_alert?.pleasure_level = level
|
||||
arousal_alert?.pleasure_overlay = arousal_alert.update_pleasure()
|
||||
arousal_alert?.add_overlay(arousal_alert.pleasure_overlay)
|
||||
arousal_alert?.update_overlays()
|
||||
|
||||
/// Handles throwing the arousal alerts to screen.
|
||||
/datum/species/proc/handle_arousal(mob/living/carbon/human/target_human, atom/movable/screen/alert/aroused)
|
||||
if(!target_human.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy))
|
||||
return
|
||||
|
||||
var/atom/movable/screen/alert/aroused/arousal_alert = target_human.alerts[AROUSED_ALERT]
|
||||
|
||||
var/alert_state
|
||||
switch(target_human.arousal)
|
||||
if(-INFINITY to AROUSAL_MINIMUM_DETECTABLE)
|
||||
target_human.clear_alert(AROUSED_ALERT, /atom/movable/screen/alert/aroused)
|
||||
if(target_human.arousal < AROUSAL_MINIMUM)
|
||||
target_human.arousal = AROUSAL_MINIMUM // To prevent massively negative values that break the lewd system for some.
|
||||
if(AROUSAL_MINIMUM_DETECTABLE to AROUSAL_LOW)
|
||||
alert_state = AROUSED_SMALL
|
||||
if(AROUSAL_LOW to AROUSAL_MEDIUM)
|
||||
alert_state = AROUSED_MEDIUM
|
||||
if(AROUSAL_HIGH to AROUSAL_AUTO_CLIMAX_THRESHOLD)
|
||||
alert_state = AROUSED_HIGH
|
||||
if(AROUSAL_AUTO_CLIMAX_THRESHOLD to INFINITY) //to prevent that 101 arousal that can make icon disappear or something.
|
||||
alert_state = AROUSED_MAX
|
||||
if(alert_state)
|
||||
throw_arousal_alert(alert_state, arousal_alert, target_human)
|
||||
alert_state = null
|
||||
|
||||
switch(target_human.pain)
|
||||
if(-INFINITY to AROUSAL_MINIMUM_DETECTABLE) //to prevent same thing with pain
|
||||
arousal_alert?.cut_overlay(arousal_alert.pain_overlay)
|
||||
if(target_human.pain < AROUSAL_MINIMUM)
|
||||
target_human.pain = AROUSAL_MINIMUM // To prevent massively negative values that break the lewd system for some.
|
||||
if(AROUSAL_MINIMUM_DETECTABLE to AROUSAL_LOW)
|
||||
alert_state = AROUSED_SMALL
|
||||
if(AROUSAL_LOW to AROUSAL_MEDIUM)
|
||||
alert_state = AROUSED_MEDIUM
|
||||
if(AROUSAL_HIGH to AROUSAL_AUTO_CLIMAX_THRESHOLD)
|
||||
alert_state = AROUSED_HIGH
|
||||
if(AROUSAL_AUTO_CLIMAX_THRESHOLD to INFINITY)
|
||||
alert_state = AROUSED_MAX
|
||||
if(alert_state)
|
||||
overlay_pain(alert_state, arousal_alert)
|
||||
alert_state = null
|
||||
|
||||
switch(target_human.pleasure)
|
||||
if(-INFINITY to AROUSAL_MINIMUM_DETECTABLE) //to prevent same thing with pleasure
|
||||
arousal_alert?.cut_overlay(arousal_alert.pleasure_overlay)
|
||||
if(target_human.pleasure < AROUSAL_MINIMUM)
|
||||
target_human.pleasure = AROUSAL_MINIMUM // To prevent massively negative values that break the lewd system for some.
|
||||
if(AROUSAL_MINIMUM_DETECTABLE to AROUSAL_LOW)
|
||||
alert_state = AROUSED_SMALL
|
||||
if(AROUSAL_LOW to AROUSAL_MEDIUM)
|
||||
alert_state = AROUSED_MEDIUM
|
||||
if(AROUSAL_HIGH to AROUSAL_AUTO_CLIMAX_THRESHOLD)
|
||||
alert_state = AROUSED_HIGH
|
||||
if(AROUSAL_AUTO_CLIMAX_THRESHOLD to INFINITY)
|
||||
alert_state = AROUSED_MAX
|
||||
if(alert_state)
|
||||
overlay_pleasure(alert_state, arousal_alert)
|
||||
|
||||
#undef AROUSED_ALERT
|
||||
#undef AROUSED_SMALL
|
||||
#undef AROUSED_MEDIUM
|
||||
#undef AROUSED_HIGH
|
||||
#undef AROUSED_MAX
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
// Milking machine
|
||||
/obj/item/storage/box/milking_kit
|
||||
name = "DIY milking machine kit"
|
||||
desc = "Contains everything you need to build your own milking machine!"
|
||||
|
||||
/obj/item/storage/box/milking_kit/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/milking_machine/constructionkit = 1)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
// X-Stand
|
||||
/obj/item/storage/box/xstand_kit
|
||||
name = "DIY x-stand kit"
|
||||
desc = "Contains everything you need to build your own X-stand!"
|
||||
|
||||
/obj/item/storage/box/xstand_kit/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/x_stand_kit = 1)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
// BDSM bed
|
||||
/obj/item/storage/box/bdsmbed_kit
|
||||
name = "DIY BDSM bed kit"
|
||||
desc = "Contains everything you need to build your own BDSM bed!"
|
||||
|
||||
/obj/item/storage/box/bdsmbed_kit/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/bdsm_bed_kit = 1)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
// Striptease pole
|
||||
/obj/item/storage/box/strippole_kit
|
||||
name = "DIY stripper pole kit"
|
||||
desc = "Contains everything you need to build your own stripper pole!"
|
||||
|
||||
/obj/item/storage/box/strippole_kit/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/polepack = 1)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
// Shibari stand
|
||||
/obj/item/storage/box/shibari_stand
|
||||
name = "DIY shibari stand kit"
|
||||
desc = "Contains everything you need to build your own shibari stand!"
|
||||
|
||||
/obj/item/storage/box/shibari_stand/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/shibari_stand_kit = 1,
|
||||
/obj/item/paper/shibari_kit_instructions = 1)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
// Paper instructions for shibari kit
|
||||
|
||||
/obj/item/paper/shibari_kit_instructions
|
||||
default_raw_text = "Hello! Congratulations on your purchase of the shibari kit by LustWish! Some newbies may get confused by our ropes, so we prepared a small instructions for you! First of all, you have to have a wrench to construct the stand itself. Secondly, you can use screwdrivers to change the color of your shibari stand. Just replace the plastic fittings! Thirdly, if you want to tie somebody to a bondage stand you need to fully tie their body, on both groin and chest!. To do that you need to use rope on body and then on groin of character, then you can just buckle them to the stand like any chair. Don't forget to have some ropes on your hand to actually tie them to the stand, as there's no ropes included with it! And that's it!"
|
||||
@@ -0,0 +1,63 @@
|
||||
#define CUM_VOLUME_MULTIPLIER 5 + 5
|
||||
|
||||
/obj/item/hand_item/coom
|
||||
name = "cum"
|
||||
desc = "C-can I watch...?"
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "eggplant"
|
||||
inhand_icon_state = "nothing"
|
||||
|
||||
// Jerk off into bottles and onto people.
|
||||
/obj/item/hand_item/coom/afterattack(obj/target, mob/user, proximity)
|
||||
. = ..()
|
||||
do_masturbate(target, user, proximity)
|
||||
|
||||
/// Handles masturbation onto a living mob, or an atom.
|
||||
/// Attempts to fill the atom's reagent container, if it has one, and it isn't full.
|
||||
/obj/item/hand_item/coom/proc/do_masturbate(obj/target, mob/user, proximity)
|
||||
if (CONFIG_GET(flag/disable_erp_preferences) || !proximity || user.stat >= DEAD)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/affected_human = user
|
||||
var/obj/item/organ/external/genital/testicles/testicles = affected_human.getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
var/obj/item/organ/external/genital/penis/penis = affected_human.getorganslot(ORGAN_SLOT_PENIS)
|
||||
var/datum/sprite_accessory/genital/penis_sprite = GLOB.sprite_accessories[ORGAN_SLOT_PENIS][affected_human.dna.species.mutant_bodyparts[ORGAN_SLOT_PENIS][MUTANT_INDEX_NAME]]
|
||||
if(penis_sprite.is_hidden(affected_human))
|
||||
to_chat(user, span_notice("You need to expose yourself in order to masturbate."))
|
||||
return
|
||||
else if(penis.aroused != AROUSAL_FULL)
|
||||
to_chat(user, span_notice("You need to be aroused in order to masturbate."))
|
||||
return
|
||||
var/cum_volume = testicles.genital_size * CUM_VOLUME_MULTIPLIER
|
||||
if(target == user)
|
||||
user.visible_message(span_warning("[user] starts masturbating onto [target.p_them()]self!"), span_danger("You start masturbating onto yourself!"))
|
||||
|
||||
else if(target.is_refillable() && target.is_drainable())
|
||||
if(target.reagents.holder_full())
|
||||
to_chat(user, span_warning("[target] is full."))
|
||||
return
|
||||
user.visible_message(span_warning("[user] starts masturbating into [target]!"), span_danger("You start masturbating into [target]!"))
|
||||
else
|
||||
user.visible_message(span_warning("[user] starts masturbating onto [target]!"), span_danger("You start masturbating onto [target]!"))
|
||||
|
||||
if(do_after(user, 6 SECONDS, target))
|
||||
if(target == user)
|
||||
user.visible_message(span_warning("[user] cums on [target.p_them()]self!"), span_danger("You cum on yourself!"))
|
||||
|
||||
else if(target.is_refillable() && target.is_drainable())
|
||||
var/datum/reagents/applied_reagents = new/datum/reagents(50)
|
||||
applied_reagents.add_reagent(/datum/reagent/consumable/cum, cum_volume)
|
||||
user.visible_message(span_warning("[user] cums into [target]!"), span_danger("You cum into [target]!"))
|
||||
playsound(target, SFX_DESECRATION, 50, TRUE, ignore_walls = FALSE)
|
||||
applied_reagents.trans_to(target, cum_volume)
|
||||
else
|
||||
user.visible_message(span_warning("[user] cums on [target]!"), span_danger("You cum on [target]!"))
|
||||
playsound(target, SFX_DESECRATION, 50, TRUE, ignore_walls = FALSE)
|
||||
affected_human.add_cum_splatter_floor(get_turf(target))
|
||||
|
||||
log_combat(user, target, "came on")
|
||||
if(prob(40))
|
||||
affected_human.try_lewd_autoemote("moan")
|
||||
qdel(src)
|
||||
|
||||
#undef CUM_VOLUME_MULTIPLIER
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/clothing/sextoy
|
||||
name = "sextoy"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi'
|
||||
worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi'
|
||||
equip_sound = 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang1.ogg'
|
||||
drop_sound = 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang2.ogg'
|
||||
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
|
||||
/// This is used to decide what lewd slot a toy should be able to be inserted into.
|
||||
/// The currently accepted defines are all prefixes with LEWD_SLOT_, and there is one for each lewd organ.
|
||||
/// See code/__DEFINES/~skyrat_defines/inventory.dm for the full list.
|
||||
var/lewd_slot_flags = NONE
|
||||
|
||||
/obj/item/clothing/sextoy/dropped(mob/user)
|
||||
..()
|
||||
|
||||
update_appearance()
|
||||
if(!ishuman(loc))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/holder = loc
|
||||
holder.update_inv_lewd()
|
||||
holder.fan_hud_set_fandom()
|
||||
|
||||
/// A check to confirm if you can open the toy's color/design radial menu
|
||||
/obj/item/clothing/sextoy/proc/check_menu(mob/living/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Returns if the item is inside a lewd slot.
|
||||
/obj/item/clothing/sextoy/proc/is_inside_lewd_slot(mob/living/carbon/human/target)
|
||||
return (src == target.penis || src == target.vagina || src == target.anus || src == target.nipples)
|
||||
+9
-9
@@ -10,7 +10,7 @@
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi'
|
||||
lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi'
|
||||
righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi'
|
||||
slot_flags = ITEM_SLOT_PENIS | ITEM_SLOT_VAGINA | ITEM_SLOT_NIPPLES | ITEM_SLOT_ANUS
|
||||
lewd_slot_flags = LEWD_SLOT_PENIS | LEWD_SLOT_VAGINA | LEWD_SLOT_NIPPLES | LEWD_SLOT_ANUS
|
||||
clothing_flags = INEDIBLE_CLOTHING
|
||||
/// Is the toy currently on
|
||||
var/toy_on = FALSE
|
||||
@@ -113,7 +113,7 @@
|
||||
. = ..()
|
||||
if(!istype(user))
|
||||
return
|
||||
if(is_in_genital(user))
|
||||
if(is_inside_lewd_slot(user))
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/sextoy/eggvib/dropped(mob/user, silent)
|
||||
@@ -127,14 +127,14 @@
|
||||
if(!istype(target))
|
||||
return
|
||||
if(vibration_mode == "low")
|
||||
target.adjustArousal(0.5 * delta_time)
|
||||
target.adjustPleasure(0.5 * delta_time)
|
||||
target.adjust_arousal(0.5 * delta_time)
|
||||
target.adjust_pleasure(0.5 * delta_time)
|
||||
if(vibration_mode == "medium")
|
||||
target.adjustArousal(0.6 * delta_time)
|
||||
target.adjustPleasure(0.6 * delta_time)
|
||||
target.adjust_arousal(0.6 * delta_time)
|
||||
target.adjust_pleasure(0.6 * delta_time)
|
||||
if(vibration_mode == "high")
|
||||
target.adjustArousal(0.7 * delta_time)
|
||||
target.adjustPleasure(0.7 * delta_time)
|
||||
target.adjust_arousal(0.7 * delta_time)
|
||||
target.adjust_pleasure(0.7 * delta_time)
|
||||
|
||||
/*
|
||||
* SIGNALLER CONTROLLED EGG
|
||||
@@ -249,7 +249,7 @@
|
||||
to_chat(vibrated, span_purple("You feel pleasant vibrations deep below..."))
|
||||
else if(src == vibrated.nipples)
|
||||
to_chat(vibrated, span_purple("You feel pleasant stimulation in your nipples."))
|
||||
else if(!toy_on && is_in_genital(vibrated))
|
||||
else if(!toy_on && is_inside_lewd_slot(vibrated))
|
||||
to_chat(vibrated, span_purple("The vibrating toy no longer drives you mad."))
|
||||
|
||||
if(!master)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi'
|
||||
lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi'
|
||||
righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi'
|
||||
slot_flags = ITEM_SLOT_ANUS|ITEM_SLOT_VAGINA
|
||||
lewd_slot_flags = LEWD_SLOT_ANUS | LEWD_SLOT_VAGINA
|
||||
/// Current color of the toy, can be changed, affects sprite
|
||||
var/current_color = "pink"
|
||||
/// Current size of the toy, can be changed, affects sprite and arousal
|
||||
@@ -106,14 +106,14 @@
|
||||
return
|
||||
// I tried using switch here, but it need static value, and u.arousal can't be it. So fuck switches. Reject it, embrace the IFs
|
||||
if(current_size == "small" && target.arousal < 30)
|
||||
target.adjustArousal(0.6 * delta_time)
|
||||
target.adjustPleasure(0.7 * delta_time)
|
||||
target.adjust_arousal(0.6 * delta_time)
|
||||
target.adjust_pleasure(0.7 * delta_time)
|
||||
else if(current_size == "medium" && target.arousal < 40)
|
||||
target.adjustArousal(0.8 * delta_time)
|
||||
target.adjustPleasure(0.8 * delta_time)
|
||||
target.adjust_arousal(0.8 * delta_time)
|
||||
target.adjust_pleasure(0.8 * delta_time)
|
||||
else if(current_size == "big" && target.arousal < 50)
|
||||
target.adjustArousal(1 * delta_time)
|
||||
target.adjustPleasure(1 * delta_time)
|
||||
target.adjust_arousal(delta_time)
|
||||
target.adjust_pleasure(delta_time)
|
||||
if(!(target.pain < 22.5)) //yeah, this will cause pain. No buttplug gib intended, sry
|
||||
return
|
||||
target.adjustPain(target*delta_time)
|
||||
target.adjust_pain(target * delta_time)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_state = "clamps"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_NIPPLES
|
||||
lewd_slot_flags = LEWD_SLOT_NIPPLES
|
||||
/// What kind are the wearer's breasts?
|
||||
var/breast_type = null
|
||||
/// What size are the wearer's breasts?
|
||||
@@ -73,12 +73,12 @@
|
||||
var/obj/item/organ/external/genital/breasts/target_breast = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(!target || !target_breast)
|
||||
return
|
||||
target.adjustArousal(1 * delta_time)
|
||||
target.adjust_arousal(1 * delta_time)
|
||||
if(target.pain < 27.5) //To prevent maxing pain by just pair of clamps.
|
||||
target.adjustPain(1 * delta_time)
|
||||
target.adjust_pain(1 * delta_time)
|
||||
|
||||
if(target.arousal < 15)
|
||||
target.adjustArousal(1 * delta_time)
|
||||
target.adjust_arousal(1 * delta_time)
|
||||
|
||||
if(target_breast.aroused != AROUSAL_CANT)
|
||||
target_breast.aroused = AROUSAL_FULL //Clamps keeping nipples aroused
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/current_color = "pink"
|
||||
var/condom_state = "unused"
|
||||
slot_flags = ITEM_SLOT_PENIS
|
||||
lewd_slot_flags = LEWD_SLOT_PENIS
|
||||
|
||||
/obj/item/clothing/sextoy/condom/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -72,20 +72,20 @@
|
||||
condom_state = "dirty"
|
||||
if(prob(10)) //chance of condom to break on first time.
|
||||
name = "broken condom"
|
||||
condom_state = "broken"
|
||||
condom_state = CONDOM_BROKEN
|
||||
update_icon_state()
|
||||
update_icon()
|
||||
|
||||
if("dirty")
|
||||
name = "broken condom"
|
||||
condom_state = "broken"
|
||||
condom_state = CONDOM_BROKEN
|
||||
update_icon_state()
|
||||
update_icon()
|
||||
|
||||
//When condom equipped we doing stuff
|
||||
/obj/item/clothing/sextoy/condom/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if((slot & ITEM_SLOT_PENIS) && condom_state == "unused")
|
||||
if((slot == LEWD_SLOT_PENIS) && condom_state == "unused")
|
||||
condom_state = "used"
|
||||
update_icon_state()
|
||||
update_icon()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/// If the toy can have its sprite changed
|
||||
var/change_sprite = TRUE
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_ANUS|ITEM_SLOT_VAGINA
|
||||
lewd_slot_flags = LEWD_SLOT_ANUS | LEWD_SLOT_VAGINA
|
||||
clothing_flags = INEDIBLE_CLOTHING
|
||||
|
||||
/// Create an assoc list of designs for the radial color/design menu
|
||||
@@ -81,14 +81,14 @@
|
||||
if(!istype(user))
|
||||
return
|
||||
if(poly_size == "small" && user.arousal < (AROUSAL_REGULAR_THRESHOLD * 0.8))
|
||||
user.adjustArousal(0.6 * delta_time)
|
||||
user.adjustPleasure(0.6 * delta_time)
|
||||
user.adjust_arousal(0.6 * delta_time)
|
||||
user.adjust_pleasure(0.6 * delta_time)
|
||||
else if(poly_size == "medium" && user.arousal < AROUSAL_REGULAR_THRESHOLD)
|
||||
user.adjustArousal(0.8 * delta_time)
|
||||
user.adjustPleasure(0.8 * delta_time)
|
||||
user.adjust_arousal(0.8 * delta_time)
|
||||
user.adjust_pleasure(0.8 * delta_time)
|
||||
else if(poly_size == "big" && user.arousal < (AROUSAL_REGULAR_THRESHOLD * 1.2))
|
||||
user.adjustArousal(1 * delta_time)
|
||||
user.adjustPleasure(1 * delta_time)
|
||||
user.adjust_arousal(1 * delta_time)
|
||||
user.adjust_pleasure(1 * delta_time)
|
||||
|
||||
/obj/item/clothing/sextoy/dildo/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
@@ -110,32 +110,32 @@
|
||||
return
|
||||
message = (user == target) ? pick("rubs [target.p_their()] vagina with [src]", "gently jams [target.p_their()] pussy with [src]", "fucks [target.p_their()] vagina with a [src]") : pick("delicately rubs [target]'s vagina with [src]", "uses [src] to fuck [target]'s vagina", "jams [target]'s pussy with [src]", "teasing [target]'s pussy with [src]")
|
||||
if(poly_size == "small")
|
||||
target.adjustArousal(4)
|
||||
target.adjustPleasure(5)
|
||||
target.adjust_arousal(4)
|
||||
target.adjust_pleasure(5)
|
||||
if(prob(20) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote("moan")
|
||||
else if(poly_size == "medium")
|
||||
target.adjustArousal(6)
|
||||
target.adjustPleasure(8)
|
||||
target.adjust_arousal(6)
|
||||
target.adjust_pleasure(8)
|
||||
if(prob(40) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan"))
|
||||
else if(poly_size == "big")
|
||||
target.adjustArousal(8)
|
||||
target.adjustPleasure(10)
|
||||
target.adjustPain(2)
|
||||
target.adjust_arousal(8)
|
||||
target.adjust_pleasure(10)
|
||||
target.adjust_pain(2)
|
||||
if(prob(60) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan", "gasp"))
|
||||
if(side_double)
|
||||
user.adjustArousal(6)
|
||||
user.adjustPleasure(8)
|
||||
user.adjust_arousal(6)
|
||||
user.adjust_pleasure(8)
|
||||
|
||||
if(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES) //Mouth only. Sorry, perverts. No eye/ear penetration for you today.
|
||||
if(!target.is_mouth_covered())
|
||||
to_chat(user, span_danger("Looks like [target]'s mouth is covered!"))
|
||||
return
|
||||
message = (user == target) ? pick("licks [src] erotically", "sucks on [src], slowly inserting it into [target.p_their()] throat") : pick("fucks [target]'s mouth with [src]", "inserts [src] into [target]'s throat, choking [target.p_them()]", "forces [target] to suck [src]", "inserts [src] into [target]'s throat")
|
||||
target.adjustArousal(4)
|
||||
target.adjustPleasure(1)
|
||||
target.adjust_arousal(4)
|
||||
target.adjust_pleasure(1)
|
||||
if(prob(70) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("gasp", "moan"))
|
||||
|
||||
@@ -145,8 +145,8 @@
|
||||
to_chat(user, span_danger("[target]'s anus is covered!"))
|
||||
return
|
||||
message = (user == target) ? pick("puts [src] into [target.p_their()] anus", "slowly inserts [src] into [target.p_their()] ass") : pick("fucks [target]'s ass with [src]", "uses [src] to fuck [target]'s anus", "jams [target]'s ass with [src]", "roughly fucks [target]'s ass with [src], making [target.p_their()] eyes roll back")
|
||||
target.adjustArousal(5)
|
||||
target.adjustPleasure(5)
|
||||
target.adjust_arousal(5)
|
||||
target.adjust_pleasure(5)
|
||||
if(prob(60) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan", "shiver"))
|
||||
|
||||
@@ -190,7 +190,7 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
|
||||
|
||||
var/static/list/dildo_sizes = list()
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_ANUS|ITEM_SLOT_VAGINA
|
||||
lewd_slot_flags = LEWD_SLOT_ANUS | LEWD_SLOT_VAGINA
|
||||
|
||||
/obj/item/clothing/sextoy/dildo/custom_dildo/populate_dildo_designs()
|
||||
dildo_sizes = list(
|
||||
@@ -256,7 +256,7 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
|
||||
lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi'
|
||||
righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_ANUS|ITEM_SLOT_VAGINA
|
||||
lewd_slot_flags = LEWD_SLOT_ANUS | LEWD_SLOT_VAGINA
|
||||
actions_types = list(/datum/action/item_action/take_dildo)
|
||||
/// If one end of the toy is in your hand
|
||||
var/in_hands = FALSE
|
||||
@@ -370,8 +370,8 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
|
||||
if(!istype(user))
|
||||
return
|
||||
if(user.arousal < AROUSAL_REGULAR_THRESHOLD)
|
||||
user.adjustArousal(0.8 * delta_time)
|
||||
user.adjustPleasure(0.8 * delta_time)
|
||||
user.adjust_arousal(0.8 * delta_time)
|
||||
user.adjust_pleasure(0.8 * delta_time)
|
||||
|
||||
/obj/item/clothing/sextoy/dildo/double_dildo/dropped(mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
target.do_jitter_animation()
|
||||
target.adjustStaminaLoss(4)
|
||||
target.add_mood_event("tickled", /datum/mood_event/tickled)
|
||||
target.adjustArousal(3)
|
||||
target.adjust_arousal(3)
|
||||
user.visible_message(span_purple("[user] [message]!"))
|
||||
playsound(loc, pick('sound/items/handling/cloth_drop.ogg', // I duplicate this part of code because im useless shitcoder that can't make it work properly without tons of repeating code blocks
|
||||
'sound/items/handling/cloth_pickup.ogg', // If you can make it better - go ahead, modify it, please.
|
||||
|
||||
@@ -72,8 +72,8 @@
|
||||
if(!(prob(40) && (target.stat != DEAD)))
|
||||
return
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan", "blush"))
|
||||
target.adjustArousal(6)
|
||||
target.adjustPleasure(9)
|
||||
target.adjust_arousal(6)
|
||||
target.adjust_pleasure(9)
|
||||
user.visible_message(span_purple("[user] [message]!"))
|
||||
playsound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/bang1.ogg',
|
||||
'modular_skyrat/modules/modular_items/lewd_items/sounds/bang2.ogg',
|
||||
|
||||
@@ -283,5 +283,5 @@
|
||||
target.try_lewd_autoemote(pick("twitch", "twitch_s", "shiver", "scream"))
|
||||
target.do_jitter_animation()
|
||||
target.adjustStaminaLoss(3)
|
||||
target.adjustPain(9)
|
||||
target.adjust_pain(9)
|
||||
target.adjust_stutter(30 SECONDS)
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.Paralyze(1)//don't touch it. It's domination tool, it should have ability to put someone on kneels. I already inserted check for PREF YOU CAN'T ABUSE THIS ITEM
|
||||
target.adjustPain(5)
|
||||
target.adjust_pain(5)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 100)
|
||||
else
|
||||
message = (user == target) ? pick("knocks [target.p_them()]self down with [src]", "gently uses [src] to knock [target.p_them()]self on the ground") : pick("drops [target] to the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees")
|
||||
@@ -186,7 +186,7 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.Paralyze(1)
|
||||
target.adjustPain(3)
|
||||
target.adjust_pain(3)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 60)
|
||||
|
||||
if(BODY_ZONE_R_LEG)
|
||||
@@ -202,7 +202,7 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.Paralyze(1)//don't touch it. It's domination tool, it should have ability to put someone on kneels. I already inserted check for PREF YOU CAN'T ABUSE THIS ITEM
|
||||
target.adjustPain(5)
|
||||
target.adjust_pain(5)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 100)
|
||||
else
|
||||
message = (user == target) ? pick("Knocks [target.p_them()]self down with [src]", "gently uses [src] to knock [target.p_them()]self on the ground") : pick("drops [target] to the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees")
|
||||
@@ -212,7 +212,7 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.Paralyze(1)
|
||||
target.adjustPain(3)
|
||||
target.adjust_pain(3)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 60)
|
||||
|
||||
if(BODY_ZONE_HEAD)
|
||||
@@ -220,8 +220,8 @@
|
||||
message = (user == target) ? pick("wraps [src] around [target.p_their()] neck, choking [target.p_them()]self", "chokes [target.p_them()]self with [src]") : pick("chokes [target] with [src]", "twines [src] around [target]'s neck!")
|
||||
if(prob(70) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("gasp", "choke", "moan"))
|
||||
target.adjustArousal(3)
|
||||
target.adjustPain(5)
|
||||
target.adjust_arousal(3)
|
||||
target.adjust_pain(5)
|
||||
playsound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/latex.ogg', 80)
|
||||
|
||||
if(BODY_ZONE_PRECISE_GROIN)
|
||||
@@ -236,8 +236,8 @@
|
||||
target.try_lewd_autoemote(pick("moan", "twitch"))
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.adjustArousal(5)
|
||||
target.adjustPain(5)
|
||||
target.adjust_arousal(5)
|
||||
target.adjust_pain(5)
|
||||
target.apply_status_effect(/datum/status_effect/spanked)
|
||||
if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO))
|
||||
target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked)
|
||||
@@ -250,8 +250,8 @@
|
||||
target.try_lewd_autoemote(pick("moan", "twitch", "twitch_s", "scream"))
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.adjustArousal(3)
|
||||
target.adjustPain(8)
|
||||
target.adjust_arousal(3)
|
||||
target.adjust_pain(8)
|
||||
target.apply_status_effect(/datum/status_effect/spanked)
|
||||
if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO))
|
||||
target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked)
|
||||
@@ -265,7 +265,7 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.do_jitter_animation()
|
||||
target.adjustPain(7)
|
||||
target.adjust_pain(7)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 100)
|
||||
|
||||
else
|
||||
@@ -276,8 +276,8 @@
|
||||
if(prob(10))
|
||||
target.apply_status_effect(/datum/status_effect/subspace)
|
||||
target.do_jitter_animation()
|
||||
target.adjustPain(4)
|
||||
target.adjustArousal(5)
|
||||
target.adjust_pain(4)
|
||||
target.adjust_arousal(5)
|
||||
playsound(loc, 'sound/weapons/whip.ogg', 60)
|
||||
if(!targetedsomewhere)
|
||||
return
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/// Mutable appearance for the human overlay of this itme
|
||||
var/mutable_appearance/magicwand_overlay
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_VAGINA|ITEM_SLOT_PENIS
|
||||
lewd_slot_flags = LEWD_SLOT_VAGINA | LEWD_SLOT_PENIS
|
||||
clothing_flags = INEDIBLE_CLOTHING
|
||||
|
||||
//some stuff for making overlay of this item. Why? Because.
|
||||
@@ -74,14 +74,14 @@
|
||||
return
|
||||
// I tried using switch here, but it need static value, and u.arousal can't be it. So fuck switches. Reject it, embrace the IFs
|
||||
if(vibration_mode == "low" && vibrated.arousal < 30)
|
||||
vibrated.adjustArousal(0.6 * delta_time)
|
||||
vibrated.adjustPleasure(0.7 * delta_time)
|
||||
vibrated.adjust_arousal(0.6 * delta_time)
|
||||
vibrated.adjust_pleasure(0.7 * delta_time)
|
||||
else if(vibration_mode == "medium" && vibrated.arousal < 60)
|
||||
vibrated.adjustArousal(0.8 * delta_time)
|
||||
vibrated.adjustPleasure(0.8 * delta_time)
|
||||
vibrated.adjust_arousal(0.8 * delta_time)
|
||||
vibrated.adjust_pleasure(0.8 * delta_time)
|
||||
else if(vibration_mode == "hard")
|
||||
vibrated.adjustArousal(1 * delta_time)
|
||||
vibrated.adjustPleasure(1 * delta_time)
|
||||
vibrated.adjust_arousal(1 * delta_time)
|
||||
vibrated.adjust_pleasure(1 * delta_time)
|
||||
|
||||
/obj/item/clothing/sextoy/magic_wand/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
@@ -124,17 +124,18 @@
|
||||
to_chat(user, span_danger("Looks like [target]'s groin is covered!"))
|
||||
return
|
||||
message = (user == target) ? pick("massages their pussy with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their pussy with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s pussy with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s pussy", "leans the vibrator against [target]'s pussy")
|
||||
target.adjustArousal((vibration_mode == "low" ? 4 : (vibration_mode == "hard" ? 8 : 5)))
|
||||
target.adjustPleasure((vibration_mode == "low" ? 2 : (vibration_mode == "hard" ? 10 : 5)))
|
||||
target.adjust_arousal((vibration_mode == "low" ? 4 : (vibration_mode == "hard" ? 8 : 5)))
|
||||
target.adjust_pleasure((vibration_mode == "low" ? 2 : (vibration_mode == "hard" ? 10 : 5)))
|
||||
|
||||
if(BODY_ZONE_CHEST)
|
||||
var/obj/item/organ/external/genital/breasts = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(!(target.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW))
|
||||
to_chat(user, span_danger("Looks like [target]'s chest is covered!"))
|
||||
return
|
||||
message = (user == target) ? pick("massages their [breasts ? "breasts" : "nipples"] with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their [breasts ? "tits" : "nipples"] with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] teases [target]'s [breasts ? "breasts" : "nipples"] with [src]", "uses [src] to[vibration_mode == "low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : "nipples"]", "uses [src] to tease [target]'s [breasts ? "boobs" : "nipples"]")
|
||||
target.adjustArousal((vibration_mode == "low" ? 3 : (vibration_mode == "hard" ? 7 : 4)))
|
||||
target.adjustPleasure((vibration_mode == "low" ? 1 : (vibration_mode == "hard" ? 9 : 4)))
|
||||
var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES
|
||||
message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] teases [target]'s [breasts_or_nipples] with [src]", "uses [src] to[vibration_mode == "low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]")
|
||||
target.adjust_arousal((vibration_mode == "low" ? 3 : (vibration_mode == "hard" ? 7 : 4)))
|
||||
target.adjust_pleasure((vibration_mode == "low" ? 1 : (vibration_mode == "hard" ? 9 : 4)))
|
||||
|
||||
if(prob(30) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan"))
|
||||
|
||||
@@ -72,8 +72,8 @@
|
||||
message = (user == target) ? pick("spanks themselves with [src]", "uses [src] to slap their hips") : pick("slaps [target]'s hips with [src]", "uses [src] to slap [target]'s butt", "spanks [target] with [src], making a loud slapping noise", "slaps [target]'s thighs with [src]")
|
||||
if(prob(40) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan", "blush", "gasp"))
|
||||
target.adjustArousal(2)
|
||||
target.adjustPain(4)
|
||||
target.adjust_arousal(2)
|
||||
target.adjust_pain(4)
|
||||
target.apply_status_effect(/datum/status_effect/spanked)
|
||||
if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO))
|
||||
target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked)
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
"drips hot wax from the [src] onto [attacked]'s genitalia, causing [attacked.p_them()] to shiver",
|
||||
"tilts [src], dripping wax right onto [attacked]'s genitals, causing [attacked.p_them()] to moan",
|
||||
"drips some wax onto [attacked]'s genitals, making [attacked.p_them()] moan in pleasure")
|
||||
attacked.adjustPain(PAIN_DEFAULT)
|
||||
attacked.adjust_pain(PAIN_DEFAULT)
|
||||
|
||||
else if(penis && (attacked.is_bottomless() || penis.visibility_preference == GENITAL_ALWAYS_SHOW))
|
||||
message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] penis, causing [attacked.p_them()] to moan in pleasure",
|
||||
@@ -160,15 +160,15 @@
|
||||
"drips wax right on [attacked]'s penis. It slightly itches.",
|
||||
"drips hot wax from the [src] on the [attacked]'s penis, he slightly shivers.",
|
||||
"tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s penis, made him moan.")
|
||||
attacked.adjustPain(PAIN_DEFAULT)
|
||||
attacked.adjust_pain(PAIN_DEFAULT)
|
||||
|
||||
else if(vagina && (attacked.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW))
|
||||
message = (user == attacked) ? pick("drips some wax on themselves, letting it reach his vagina. He moans in pleasure.", "drips some wax on the [attacked]'s pussy, he moans in pleasure") : pick("drips some wax on the [attacked]'s vagina, he moans in pleasure", "tilts the candle. Wax slowly goes down, reaching the [attacked]'s vagina.", "tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s pussy, made him moan.")
|
||||
attacked.adjustPain(PAIN_DEFAULT)
|
||||
attacked.adjust_pain(PAIN_DEFAULT)
|
||||
|
||||
else if(attacked.is_bottomless())
|
||||
message = (user == attacked) ? pick("drips some wax on themselves, letting it reach his belly. He moans in pleasure.", "drips some wax on the [attacked]'s tummy, he moans in pleasure") : pick("drips some wax on the [attacked]'s belly, he moans in pleasure", "tilts the candle. Wax slowly goes down, reaching the [attacked]'s tummy.", "tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s groin, made him moan.")
|
||||
attacked.adjustPain(PAIN_DEFAULT)
|
||||
attacked.adjust_pain(PAIN_DEFAULT)
|
||||
|
||||
else
|
||||
to_chat(user, span_danger("Looks like [attacked]'s groin is covered!"))
|
||||
@@ -178,8 +178,9 @@
|
||||
targeted_somewhere = TRUE
|
||||
var/obj/item/organ/external/genital/breasts = attacked.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(attacked.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW)
|
||||
message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] [breasts ? "breasts" : "nipples"], releasing all [attacked.p_their()] lustness", "drips some wax right on [attacked.p_their()] [breasts ? "tits" : "chest"], making [attacked.p_their()] feel faint.") : pick("pours the wax that is slowly dripping from [src] onto [attacked]'s [breasts ? "breasts" : "nipples"], [attacked.p_they()] shows pure enjoyment.", "tilts the candle. Right in the moment when wax drips on [attacked]'s [breasts ? "breasts" : "nipples"], [attacked.p_they()] shivers", "tilts the candle. Just when hot drops of wax fell on [attacked]'s [breasts ? "breasts" : "nipples"], [attacked.p_they()] quietly moans in pleasure")
|
||||
attacked.adjustPain(PAIN_DEFAULT * 0.66)
|
||||
var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES
|
||||
message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] [breasts_or_nipples], releasing all [attacked.p_their()] lustness", "drips some wax right on [attacked.p_their()] [breasts ? "tits" : "chest"], making [attacked.p_their()] feel faint.") : pick("pours the wax that is slowly dripping from [src] onto [attacked]'s [breasts_or_nipples], [attacked.p_they()] shows pure enjoyment.", "tilts the candle. Right in the moment when wax drips on [attacked]'s [breasts_or_nipples], [attacked.p_they()] shivers", "tilts the candle. Just when hot drops of wax fell on [attacked]'s [breasts_or_nipples], [attacked.p_they()] quietly moans in pleasure")
|
||||
attacked.adjust_pain(PAIN_DEFAULT * 0.66)
|
||||
|
||||
else
|
||||
to_chat(user, span_danger("Looks like [attacked]'s chest is covered!"))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi'
|
||||
lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi'
|
||||
righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi'
|
||||
slot_flags = ITEM_SLOT_VAGINA | ITEM_SLOT_ANUS
|
||||
lewd_slot_flags = LEWD_SLOT_VAGINA | LEWD_SLOT_ANUS
|
||||
/// If the toy is on or not
|
||||
var/toy_on = FALSE
|
||||
/// Current color of the toy, can be changed and affects sprite
|
||||
@@ -94,17 +94,17 @@
|
||||
return
|
||||
if(toy_on)
|
||||
if(vibration_mode == "low" && user.arousal < 40) //prevent non-stop cumming from wearing this thing
|
||||
user.adjustArousal(0.7 * delta_time)
|
||||
user.adjustPleasure(0.7 * delta_time)
|
||||
user.adjust_arousal(0.7 * delta_time)
|
||||
user.adjust_pleasure(0.7 * delta_time)
|
||||
if(vibration_mode == "medium" && user.arousal < 70)
|
||||
user.adjustArousal(1 * delta_time)
|
||||
user.adjustPleasure(1 * delta_time)
|
||||
user.adjust_arousal(1 * delta_time)
|
||||
user.adjust_pleasure(1 * delta_time)
|
||||
if(vibration_mode == "hard") //no mercy
|
||||
user.adjustArousal(1.5 * delta_time)
|
||||
user.adjustPleasure(1.5 * delta_time)
|
||||
user.adjust_arousal(1.5 * delta_time)
|
||||
user.adjust_pleasure(1.5 * delta_time)
|
||||
else if(!toy_on && user.arousal < 30)
|
||||
user.adjustArousal(0.5 * delta_time)
|
||||
user.adjustPleasure(0.5 * delta_time)
|
||||
user.adjust_arousal(0.5 * delta_time)
|
||||
user.adjust_pleasure(0.5 * delta_time)
|
||||
|
||||
//SHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODE
|
||||
/obj/item/clothing/sextoy/vibrator/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
@@ -128,18 +128,18 @@
|
||||
var/obj/item/organ/external/genital/vagina = target.getorganslot(ORGAN_SLOT_VAGINA)
|
||||
if((vagina && penis) && (vagina.visibility_preference == GENITAL_ALWAYS_SHOW && penis.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless()))
|
||||
message = (user == target) ? pick("massages their vagina with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their pussy with [src]", "massages their penis with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their penis with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s vagina with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s crotch", "leans the massager against [target]'s pussy", "[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s penis with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s penis", "leans the massager against [target]'s penis")
|
||||
target.adjustArousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjustPleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
target.adjust_arousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
|
||||
else if(vagina && (vagina.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless()))
|
||||
message = (user == target) ? pick("massages their vagina with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their pussy with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s vagina with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s crotch", "leans the massager against [target]'s pussy")
|
||||
target.adjustArousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjustPleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
target.adjust_arousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
|
||||
else if(penis && (penis.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless()))
|
||||
message = (user == target) ? pick("massages their penis with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their penis with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s penis with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s penis", "leans the massager against [target]'s penis")
|
||||
target.adjustArousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjustPleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
target.adjust_arousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE)
|
||||
|
||||
else
|
||||
to_chat(user, span_danger("Looks like [target]'s groin is covered!"))
|
||||
@@ -152,9 +152,10 @@
|
||||
targetedsomewhere = TRUE
|
||||
var/obj/item/organ/external/genital/breasts = target.getorganslot(ORGAN_SLOT_BREASTS)
|
||||
if(target.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW)
|
||||
message = (user == target) ? pick("massages their [breasts ? "breasts" : "nipples"] with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their tits with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] teases [target]'s [breasts ? "breasts" : "nipples"] with [src]", "uses [src] to[vibration_mode == "low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : "nipples"]", "uses [src] to tease [target]'s [breasts ? "boobs" : "nipples"]", "rubs [target]'s [breasts ? "tits" : "nipples"] with [src]")
|
||||
target.adjustArousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjustPleasure(DEFAULT_PLEASURE_INCREASE * 0.5)
|
||||
var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES
|
||||
message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their tits with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] teases [target]'s [breasts_or_nipples] with [src]", "uses [src] to[vibration_mode == "low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]", "rubs [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]")
|
||||
target.adjust_arousal(DEFAULT_AROUSAL_INCREASE)
|
||||
target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE * 0.5)
|
||||
if(prob(30) && (target.stat != DEAD))
|
||||
target.try_lewd_autoemote(pick("twitch_s", "moan"))
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
/// Looping sound called on process
|
||||
var/datum/looping_sound/vibrator/medium/soundloop
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_PENIS
|
||||
lewd_slot_flags = LEWD_SLOT_PENIS
|
||||
clothing_flags = INEDIBLE_CLOTHING
|
||||
|
||||
/obj/item/clothing/sextoy/vibroring/attack_self(mob/user)
|
||||
@@ -84,7 +84,7 @@
|
||||
var/obj/item/organ/external/genital/testicles/balls = user.getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(!toy_on || !balls)
|
||||
return
|
||||
user.adjustArousal(1 * delta_time)
|
||||
user.adjustPleasure(1 * delta_time)
|
||||
user.adjust_arousal(1 * delta_time)
|
||||
user.adjust_pleasure(1 * delta_time)
|
||||
if(balls.aroused != AROUSAL_CANT)
|
||||
balls.aroused = AROUSAL_FULL //Vibroring keep penis erected.
|
||||
|
||||
+2
-2
@@ -97,8 +97,8 @@
|
||||
/obj/item/reagent_containers/pill/camphor = 10,
|
||||
/obj/item/reagent_containers/cup/bottle/crocin = 6,
|
||||
/obj/item/reagent_containers/cup/bottle/camphor = 3,
|
||||
/obj/item/reagent_containers/cup/bottle/breast_enlarger = 6, //Those are legal 'cause you can just turn off prefs in round in "CLOWN SMOKE MACHINE+PENIS ENLARGEMENT CHEMICAL CASE". Yes, i have special code-phrase for this. I've seen some shit.
|
||||
/obj/item/reagent_containers/cup/bottle/penis_enlarger = 6,
|
||||
/obj/item/reagent_containers/cup/bottle/succubus_milk = 6, //Those are legal 'cause you can just turn off prefs in round in "CLOWN SMOKE MACHINE+PENIS ENLARGEMENT CHEMICAL CASE". Yes, i have special code-phrase for this. I've seen some shit.
|
||||
/obj/item/reagent_containers/cup/bottle/incubus_draft = 6,
|
||||
|
||||
//special
|
||||
/obj/item/clothing/glasses/nice_goggles = 1, //easter egg, don't touch plz)
|
||||
+8
-23
@@ -530,13 +530,6 @@
|
||||
used_item.play_tool_sound(src, 50)
|
||||
deconstruct(TRUE)
|
||||
|
||||
// // Object disassembly handler by wrench
|
||||
// /obj/structure/chair/milking_machine/default_unfasten_wrench(mob/user, obj/item/used_item, time = 20)
|
||||
// . = !(flags_1 & NODECONSTRUCT_1) && used_item.tool_behaviour == TOOL_WRENCH
|
||||
// if(.)
|
||||
// used_item.play_tool_sound(src, 50)
|
||||
// deconstruct(TRUE)
|
||||
|
||||
// Machine Workflow Processor
|
||||
/obj/structure/chair/milking_machine/process(delta_time)
|
||||
|
||||
@@ -546,8 +539,6 @@
|
||||
pump_state = pump_state_list[1]
|
||||
update_all_visuals()
|
||||
return
|
||||
// if(current_mode == mode_list[1] && pump_state == pump_state_list[1])
|
||||
// cell.give(charge_rate * delta_time)
|
||||
|
||||
// Check if the machine should work
|
||||
if(!current_mob)
|
||||
@@ -600,17 +591,17 @@
|
||||
|
||||
if(istype(current_selected_organ, /obj/item/organ/external/genital/breasts))
|
||||
if(current_selected_organ.reagents.total_volume > 0)
|
||||
current_selected_organ.internal_fluids.trans_to(milk_vessel, milk_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
current_selected_organ.transfer_internal_fluid(milk_vessel, milk_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
else
|
||||
return
|
||||
else if (istype(current_selected_organ, /obj/item/organ/external/genital/vagina))
|
||||
if(current_selected_organ.reagents.total_volume > 0)
|
||||
current_selected_organ.internal_fluids.trans_to(girlcum_vessel, girlcum_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
current_selected_organ.transfer_internal_fluid(girlcum_vessel, girlcum_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
else
|
||||
return
|
||||
else if (istype(current_selected_organ, /obj/item/organ/external/genital/testicles))
|
||||
if(current_selected_organ.reagents.total_volume > 0)
|
||||
current_selected_organ.internal_fluids.trans_to(semen_vessel, semen_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
current_selected_organ.transfer_internal_fluid(semen_vessel, semen_retrive_amount[current_mode] * fluid_multiplier * delta_time)
|
||||
else
|
||||
return
|
||||
else
|
||||
@@ -619,9 +610,9 @@
|
||||
|
||||
// Handling the process of the impact of the machine on the organs of the mob
|
||||
/obj/structure/chair/milking_machine/proc/increase_current_mob_arousal(delta_time)
|
||||
src.current_mob.adjustArousal(src.arousal_amounts[src.current_mode] * delta_time)
|
||||
src.current_mob.adjustPleasure(src.pleasure_amounts[src.current_mode] * delta_time)
|
||||
src.current_mob.adjustPain(src.pain_amounts[src.current_mode] * delta_time)
|
||||
current_mob.adjust_arousal(arousal_amounts[current_mode] * delta_time)
|
||||
current_mob.adjust_pleasure(pleasure_amounts[current_mode] * delta_time)
|
||||
current_mob.adjust_pain(pain_amounts[current_mode] * delta_time)
|
||||
|
||||
// Energy consumption processor
|
||||
/obj/structure/chair/milking_machine/proc/draw_power_from_cell(delta_time)
|
||||
@@ -765,7 +756,7 @@
|
||||
organ_overlay.icon_state = organ_overlay_new_icon_state
|
||||
|
||||
if(istype(current_selected_organ, /obj/item/organ/external/genital/testicles))
|
||||
current_selected_organ_type = "penis"
|
||||
current_selected_organ_type = ORGAN_SLOT_PENIS
|
||||
current_selected_organ_size = current_selected_organ.genital_size
|
||||
if(current_mode == mode_list[1])
|
||||
pump_state = pump_state_list[1]
|
||||
@@ -779,7 +770,7 @@
|
||||
organ_overlay.icon_state = organ_overlay_new_icon_state
|
||||
|
||||
if(istype(current_selected_organ, /obj/item/organ/external/genital/vagina))
|
||||
current_selected_organ_type = "vagina"
|
||||
current_selected_organ_type = ORGAN_SLOT_VAGINA
|
||||
current_selected_organ_size = current_selected_organ.genital_size
|
||||
if(current_mode == mode_list[1])
|
||||
pump_state = pump_state_list[1]
|
||||
@@ -859,12 +850,6 @@
|
||||
/obj/structure/chair/milking_machine/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
|
||||
/* Standard behavior. Uncomment for UI debugging
|
||||
if(!ui)
|
||||
ui = new(user, src, "MilkingMachine", name)
|
||||
ui.open()
|
||||
*/
|
||||
|
||||
//Block the interface if we are in the machine. Use in production
|
||||
if(LAZYLEN(buckled_mobs))
|
||||
if(user != src.buckled_mobs[1])
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/obj/item/organ/external/genital
|
||||
/// The fluid count of the genital.
|
||||
var/internal_fluid_count = 0
|
||||
|
||||
/// The maximum amount of fluid that can be stored in the genital.
|
||||
var/internal_fluid_maximum = 0
|
||||
|
||||
/// The datum to be used for the tracked fluid, should it need to be added to a fluid container.
|
||||
var/internal_fluid_datum
|
||||
|
||||
/// The currently inserted sex toy.
|
||||
var/obj/item/inserted_item
|
||||
|
||||
/// Helper proc for checking if internal fluids are full or not.
|
||||
/obj/item/organ/external/genital/proc/internal_fluid_full()
|
||||
return internal_fluid_count >= internal_fluid_maximum
|
||||
|
||||
/// Adds the given amount to the internal fluid count, clamping it between 0 and internal_fluid_maximum.
|
||||
/obj/item/organ/external/genital/proc/adjust_internal_fluid(amount)
|
||||
internal_fluid_count = clamp(internal_fluid_count + amount, 0, internal_fluid_maximum)
|
||||
|
||||
/// Tries to add the specified amount to the target reagent container. Keeps in mind internal_fluid_count.
|
||||
/obj/item/organ/external/genital/proc/transfer_internal_fluid(datum/reagents/reagent_container, attempt_amount)
|
||||
if(!internal_fluid_datum || !internal_fluid_count || !internal_fluid_maximum)
|
||||
return
|
||||
|
||||
attempt_amount = clamp(attempt_amount, 0, internal_fluid_count)
|
||||
reagent_container.add_reagent(internal_fluid_datum, attempt_amount)
|
||||
internal_fluid_count -= attempt_amount
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/obj/item/organ/external/genital/breasts
|
||||
internal_fluid_datum = /datum/reagent/consumable/breast_milk
|
||||
|
||||
/obj/item/organ/external/genital/breasts/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
var/breasts_capacity = 0
|
||||
var/size = 0.5
|
||||
if(DNA.features["breasts_size"] > 0)
|
||||
size = DNA.features["breasts_size"]
|
||||
|
||||
switch(genital_type)
|
||||
if("pair")
|
||||
breasts_capacity = 2
|
||||
if("quad")
|
||||
breasts_capacity = 2.5
|
||||
if("sextuple")
|
||||
breasts_capacity = 3
|
||||
internal_fluid_maximum = size * breasts_capacity * 60 // This seems like it could balloon drastically out of proportion with larger breast sizes.
|
||||
@@ -0,0 +1,10 @@
|
||||
/obj/item/organ/external/genital/testicles
|
||||
internal_fluid_datum = /datum/reagent/consumable/cum
|
||||
|
||||
/obj/item/organ/external/genital/testicles/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
var/size = 0.5
|
||||
if(DNA.features["balls_size"] > 0)
|
||||
size = DNA.features["balls_size"]
|
||||
|
||||
internal_fluid_maximum = size * 20
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/item/organ/external/genital/vagina
|
||||
internal_fluid_datum = /datum/reagent/consumable/femcum
|
||||
|
||||
/obj/item/organ/external/genital/vagina/build_from_dna(datum/dna/DNA, associated_key)
|
||||
. = ..()
|
||||
internal_fluid_maximum = 10
|
||||
@@ -93,9 +93,9 @@
|
||||
else
|
||||
stress = clamp(stress + 1, 0, 300)
|
||||
|
||||
human_owner.adjustArousal(10)
|
||||
human_owner.adjust_arousal(10)
|
||||
if(human_owner.pleasure < 80)
|
||||
human_owner.adjustPleasure(5)
|
||||
human_owner.adjust_pleasure(5)
|
||||
|
||||
//Anything beyond this obeys a cooldown system because we don't want to spam it
|
||||
if(!COOLDOWN_FINISHED(src, desire_cooldown))
|
||||
@@ -260,7 +260,7 @@
|
||||
/datum/brain_trauma/very_special/sadism/on_life(delta_time, times_fired)
|
||||
var/mob/living/carbon/human/affected_mob = owner
|
||||
if(someone_suffering() && affected_mob.client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
affected_mob.adjustArousal(2)
|
||||
affected_mob.adjust_arousal(2)
|
||||
owner.add_mood_event("sadistic", /datum/mood_event/sadistic)
|
||||
else
|
||||
owner.clear_mood_event("sadistic")
|
||||
@@ -327,19 +327,22 @@
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/examiner = user
|
||||
if(stat != DEAD && !HAS_TRAIT(src, TRAIT_FAKEDEATH) && src != examiner)
|
||||
if(src != user)
|
||||
if(HAS_TRAIT(examiner, TRAIT_EMPATH))
|
||||
switch(arousal)
|
||||
if(11 to 21)
|
||||
. += span_purple("[p_they()] [p_are()] excited.") + "\n"
|
||||
if(21.01 to 41)
|
||||
. += span_purple("[p_they()] [p_are()] slightly blushed.") + "\n"
|
||||
if(41.01 to 51)
|
||||
. += span_purple("[p_they()] [p_are()] quite aroused and seems to be stirring up lewd thoughts in [p_their()] head.") + "\n"
|
||||
if(51.01 to 61)
|
||||
. += span_purple("[p_they()] [p_are()] very aroused and [p_their()] movements are seducing.") + "\n"
|
||||
if(61.01 to 91)
|
||||
. += span_purple("[p_they()] [p_are()] aroused as hell.") + "\n"
|
||||
if(91.01 to INFINITY)
|
||||
. += span_purple("[p_they()] [p_are()] extremely excited, exhausting from entolerable desire.") + "\n"
|
||||
if(stat >= DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH) || src == examiner || !HAS_TRAIT(examiner, TRAIT_EMPATH))
|
||||
return
|
||||
|
||||
if(examiner.client?.prefs?.read_preference(/datum/preference/toggle/erp))
|
||||
var/arousal_message
|
||||
switch(arousal)
|
||||
if(AROUSAL_MINIMUM_DETECTABLE to AROUSAL_LOW)
|
||||
arousal_message = span_purple("[p_they()] [p_are()] slightly blushed.") + "\n"
|
||||
if(AROUSAL_LOW to AROUSAL_MEDIUM)
|
||||
arousal_message = span_purple("[p_they()] [p_are()] quite aroused and seems to be stirring up lewd thoughts in [p_their()] head.") + "\n"
|
||||
if(AROUSAL_HIGH to AROUSAL_AUTO_CLIMAX_THRESHOLD)
|
||||
arousal_message = span_purple("[p_they()] [p_are()] aroused as hell.") + "\n"
|
||||
if(AROUSAL_AUTO_CLIMAX_THRESHOLD to INFINITY)
|
||||
arousal_message = span_purple("[p_they()] [p_are()] extremely excited, exhausting from entolerable desire.") + "\n"
|
||||
if(arousal_message)
|
||||
. += arousal_message
|
||||
else if(arousal > AROUSAL_MINIMUM_DETECTABLE)
|
||||
. += span_purple("[p_they()] [p_are()] slightly blushed.") + "\n"
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//screen alert
|
||||
|
||||
/atom/movable/screen/alert/aroused
|
||||
name = "Aroused"
|
||||
desc = "It's a little hot in here"
|
||||
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi'
|
||||
icon_state = "arousal_small"
|
||||
var/mutable_appearance/pain_overlay
|
||||
var/mutable_appearance/pleasure_overlay
|
||||
var/pain_level = "small"
|
||||
var/pleasure_level = "small"
|
||||
|
||||
/atom/movable/screen/alert/aroused/Initialize(mapload)
|
||||
.=..()
|
||||
pain_overlay = update_pain()
|
||||
pleasure_overlay = update_pleasure()
|
||||
|
||||
/atom/movable/screen/alert/aroused/proc/update_pain()
|
||||
if(pain_level)
|
||||
return mutable_appearance(icon, "pain_[pain_level]")
|
||||
|
||||
/atom/movable/screen/alert/aroused/proc/update_pleasure()
|
||||
if(pleasure_level)
|
||||
return mutable_appearance(icon, "pleasure_[pleasure_level]")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
/mob/living/carbon/human/verb/climax_verb()
|
||||
set name = "Climax"
|
||||
set category = "IC"
|
||||
|
||||
if(!has_status_effect(/datum/status_effect/climax_cooldown))
|
||||
if(tgui_alert(usr, "Are you sure you want to cum?", "Climax", list("Yes", "No")) == "Yes")
|
||||
if(stat != CONSCIOUS)
|
||||
to_chat(usr, span_warning("You can't climax right now..."))
|
||||
return
|
||||
else
|
||||
climax(TRUE)
|
||||
else
|
||||
to_chat(src, span_warning("You can't cum right now!"))
|
||||
|
||||
/mob/living/carbon/human/Initialize(mapload)
|
||||
. = ..()
|
||||
if(CONFIG_GET(flag/disable_erp_preferences))
|
||||
verbs -= /mob/living/carbon/human/verb/climax_verb
|
||||
@@ -29,3 +29,4 @@ A modular folder for various single-item additions that don't deserve their own
|
||||
Ranged66 - Material pouch ported
|
||||
KathrinBailey - Pretty much a whole bunch of clothes.
|
||||
mel-byond - Ported Baystation12 Aviators
|
||||
RimiNosha - Fixing up code no one else would touch.
|
||||
|
||||
+45
-6
@@ -325,6 +325,7 @@
|
||||
#include "code\__DEFINES\~skyrat_defines\jobs.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\keybindings.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\layers.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\lewd_defines.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\liquids.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\loadouts.dm"
|
||||
#include "code\__DEFINES\~skyrat_defines\logging.dm"
|
||||
@@ -4906,14 +4907,15 @@
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\_preference.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\auto_dementor.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\be_antag.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\body_size.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\clothing.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\cursed_shit.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\delete_sparks.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\emote_overlay.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\emote_panel.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\erp_preferences.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\face_cursor_combat_mode.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\flavor_text.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\genitals.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\headshot.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\laugh.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\client\preferences\loadout_override_preference.dm"
|
||||
@@ -5864,11 +5866,34 @@
|
||||
#include "modular_skyrat\modules\modular_items\code\summon_beacon.dm"
|
||||
#include "modular_skyrat\modules\modular_items\code\tailoring.dm"
|
||||
#include "modular_skyrat\modules\modular_items\code\thieving_gloves.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\arousal_system.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\decals.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_quirks.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_remove_erp_items.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\technical_stuff_for_lewd.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\chemistry_for_ERP.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\screen_icons.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\verbs.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\arousal.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\climax.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\mood_events.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\pain.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\pleasure.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\status_effects\aroused.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\status_effects\climax.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\status_effects\fluid_generation.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\status_effects\ropebunny.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_arousal\status_effects\spank_related.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\mood_events.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\items\bottles.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\items\pills.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\_aphrodisiac.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\_chemical_reaction.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\breast_milk.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\camphor.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\crocin.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\cum.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\dopamine.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\hexacrocin.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\incubus_draft.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\pentacamphor.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_chemistry\reagents\succubus_milk.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\ballgag.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\bdsm_mask.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\corset.dm"
|
||||
@@ -5893,6 +5918,16 @@
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\shockcollar.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\strapon.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_clothing\stripper_outfit.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\appearance.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\carbon.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\human.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\misc.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\organs.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_helpers\species.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\_erp_disabled_item_enforcement.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\_kits.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\_masturbation_item.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\_sex_toy.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\attachable_vibrator.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\buttplug.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\clamps.dm"
|
||||
@@ -5912,10 +5947,14 @@
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\torture_candle.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\vibrator.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_items\vibroring.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_machinery\lustwish.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_machinery\milking_machine.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_organs\_genital.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_organs\breasts.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_organs\testicles.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_organs\vagina.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_structures\bdsm_furniture.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_structures\dancing_pole.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_structures\lustwish.dm"
|
||||
#include "modular_skyrat\modules\modular_items\lewd_items\code\lewd_structures\pillow.dm"
|
||||
#include "modular_skyrat\modules\modular_reagents\code\alert.dm"
|
||||
#include "modular_skyrat\modules\modular_reagents\code\reagents\medicine.dm"
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Button, NoticeBox, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const InteractionMenu = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { categories, interactions, descriptions, colors } = data;
|
||||
const { self, ref_self, ref_user } = data;
|
||||
const { block_interact } = data;
|
||||
|
||||
return (
|
||||
<Window width={400} height={600} title={'Interact - ' + self}>
|
||||
<Window.Content scrollable>
|
||||
{(block_interact && <NoticeBox>Unable to Interact</NoticeBox>) || (
|
||||
<NoticeBox>Able to Interact</NoticeBox>
|
||||
)}
|
||||
<Section key="interactions">
|
||||
{categories.map((category) => (
|
||||
<Section key={category} title={category}>
|
||||
{interactions[category].map((interaction) => (
|
||||
<Section key={interaction}>
|
||||
<left>
|
||||
<Button
|
||||
margin={0}
|
||||
padding={0}
|
||||
disabled={block_interact}
|
||||
color={block_interact ? 'grey' : colors[interaction]}
|
||||
content={interaction}
|
||||
icon="exclamation-circle"
|
||||
onClick={() =>
|
||||
act('interact', {
|
||||
interaction: interaction,
|
||||
selfref: ref_self,
|
||||
userref: ref_user,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<br />
|
||||
{descriptions[interaction]}
|
||||
</left>
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,123 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Button, NoticeBox, Section, Icon, Box, Stack } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
class Interaction {
|
||||
categories;
|
||||
interactions;
|
||||
descriptions;
|
||||
colors;
|
||||
lewd_slots: LewdSlot[];
|
||||
self;
|
||||
ref_self;
|
||||
ref_user;
|
||||
block_interact;
|
||||
}
|
||||
|
||||
class LewdSlot {
|
||||
img;
|
||||
name;
|
||||
}
|
||||
|
||||
export const InteractionMenu = (props, context) => {
|
||||
const { act, data } = useBackend<Interaction>(context);
|
||||
const {
|
||||
categories,
|
||||
interactions,
|
||||
descriptions,
|
||||
colors,
|
||||
lewd_slots,
|
||||
self,
|
||||
ref_self,
|
||||
ref_user,
|
||||
block_interact,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Window width={400} height={600} title={'Interact - ' + self}>
|
||||
<Window.Content scrollable>
|
||||
{(block_interact && <NoticeBox>Unable to Interact</NoticeBox>) || (
|
||||
<NoticeBox>Able to Interact</NoticeBox>
|
||||
)}
|
||||
<Section key="interactions">
|
||||
{categories.map((category) => (
|
||||
<Section key={category} title={category}>
|
||||
{interactions[category].map((interaction) => (
|
||||
<Section key={interaction}>
|
||||
<Button
|
||||
margin={0}
|
||||
padding={0}
|
||||
disabled={block_interact}
|
||||
color={block_interact ? 'grey' : colors[interaction]}
|
||||
content={interaction}
|
||||
icon="exclamation-circle"
|
||||
onClick={() =>
|
||||
act('interact', {
|
||||
interaction: interaction,
|
||||
selfref: ref_self,
|
||||
userref: ref_user,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<br />
|
||||
{descriptions[interaction]}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
{lewd_slots.length > 0 ? (
|
||||
<Section key="item_slots" title={'Lewd Slots'}>
|
||||
<Stack fill>
|
||||
{lewd_slots.map((element: LewdSlot) => {
|
||||
return (
|
||||
<Stack.Item key={element.name}>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('remove_lewd_item', {
|
||||
item_slot: element.name,
|
||||
selfref: ref_self,
|
||||
userref: ref_user,
|
||||
})
|
||||
}
|
||||
tooltip={element.name}>
|
||||
<Box
|
||||
style={{
|
||||
'width': '32px',
|
||||
'height': '32px',
|
||||
'margin': '0.5em 0',
|
||||
}}>
|
||||
{element.img ? (
|
||||
<img
|
||||
src={'data:image/png;base64,' + element.img}
|
||||
style={{
|
||||
'-ms-interpolation-mode': 'nearest-neighbor',
|
||||
'width': '100%',
|
||||
'height': '100%',
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Icon
|
||||
name="eye-slash"
|
||||
size={2}
|
||||
ml={0}
|
||||
mt={0.75}
|
||||
style={{
|
||||
'text-align': 'center',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
</Section>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
+9
-9
@@ -106,38 +106,38 @@ export const feature_womb: Feature<string> = {
|
||||
};
|
||||
|
||||
export const feature_breasts: Feature<string> = {
|
||||
name: 'Breasts Choice',
|
||||
name: 'Breast Choice',
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
|
||||
export const breasts_skin_tone: FeatureToggle = {
|
||||
name: 'Breasts uses Skin Tone',
|
||||
name: 'Breasts use Skin Tone',
|
||||
component: CheckboxInput,
|
||||
};
|
||||
|
||||
export const breasts_skin_color: FeatureToggle = {
|
||||
name: 'Breasts uses Skin Color',
|
||||
name: 'Breasts use Skin Color',
|
||||
component: CheckboxInput,
|
||||
};
|
||||
|
||||
export const breasts_color: Feature<string[]> = {
|
||||
name: 'Breasts Color',
|
||||
name: 'Breast Color',
|
||||
component: FeatureTriColorInput,
|
||||
};
|
||||
|
||||
export const breasts_emissive: Feature<boolean[]> = {
|
||||
name: 'Breasts Emissives',
|
||||
name: 'Breast Emissives',
|
||||
component: FeatureTriBoolInput,
|
||||
};
|
||||
|
||||
export const breasts_lactation_toggle: FeatureToggle = {
|
||||
name: 'Breasts Lactation',
|
||||
name: 'Breast Lactation',
|
||||
component: CheckboxInput,
|
||||
};
|
||||
|
||||
export const breasts_size: FeatureNumeric = {
|
||||
name: 'Breasts Size',
|
||||
component: FeatureNumberInput,
|
||||
export const breasts_size: Feature<string> = {
|
||||
name: 'Breast Size',
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
|
||||
export const feature_anus: Feature<string> = {
|
||||
+8
@@ -83,3 +83,11 @@ export const erp_sexuality_pref: FeatureChoiced = {
|
||||
'Determines what sexual content you see, limited use. None will show all content.',
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
|
||||
export const new_genitalia_growth_pref: FeatureToggle = {
|
||||
name: 'ERP New Genitalia Growth',
|
||||
category: 'ERP',
|
||||
description:
|
||||
'If checked, allows drugs to grow new genitalia on your character.',
|
||||
component: CheckboxInput,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user