From 11f12c8189f4017bae67a0c203ce068478efb5d4 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Fri, 27 May 2022 19:14:52 +1000 Subject: [PATCH 01/72] ol copy paste trick --- code/__SPLURTCODE/DEFINES/pregnancy.dm | 3 + code/__SPLURTCODE/DEFINES/traits.dm | 2 + code/modules/client/preferences.dm | 34 +++ code/modules/client/preferences_savefile.dm | 14 +- .../code/datums/status_effects/pregnancy.dm | 238 ++++++++++++++++++ .../code/game/objects/items/oviposition.dm | 28 +++ .../code/_globalvars/lists/pregnancy.dm | 3 + .../code/modules/arousal/arousal.dm | 11 + modular_splurt/icons/mob/screen_alert.dmi | Bin 0 -> 1319 bytes tgstation.dme | 4 + 10 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 code/__SPLURTCODE/DEFINES/pregnancy.dm create mode 100644 modular_eros/code/datums/status_effects/pregnancy.dm create mode 100644 modular_eros/code/game/objects/items/oviposition.dm create mode 100644 modular_splurt/code/_globalvars/lists/pregnancy.dm create mode 100644 modular_splurt/icons/mob/screen_alert.dmi diff --git a/code/__SPLURTCODE/DEFINES/pregnancy.dm b/code/__SPLURTCODE/DEFINES/pregnancy.dm new file mode 100644 index 0000000000..9ae55ea102 --- /dev/null +++ b/code/__SPLURTCODE/DEFINES/pregnancy.dm @@ -0,0 +1,3 @@ +#define PREGNANCY_CHANCE_ON_EJACULATION 10 +#define PREGNANCY_DURATION 15 MINUTES +#define PREGNANCY_STAGES 4 diff --git a/code/__SPLURTCODE/DEFINES/traits.dm b/code/__SPLURTCODE/DEFINES/traits.dm index 186cdb32d7..8c23a14c36 100644 --- a/code/__SPLURTCODE/DEFINES/traits.dm +++ b/code/__SPLURTCODE/DEFINES/traits.dm @@ -1,6 +1,8 @@ #define SLAVER_TRAIT "slaver" +#define PREGNANCY_TRAIT "pregnancy" #define TRAIT_HYPNOTIC_GAZE "Hypnotic Gaze" +#define TRAIT_PREGNANT "pregnant" #define TRAIT_FLOORED "floored" #define IGNORE_FAKE_Z_AXIS "ignore_fake_z_axis" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8a51c0d25d..b890f323f0 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -350,6 +350,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/list/tcg_cards = list() var/list/tcg_decks = list() + //SPLURT EDIT - gregnancy + /// Does john spaceman's cum actually impregnate people? + var/virility = FALSE + /// Can john spaceman get gregnant if all conditions are right? (has a womb and is not on contraceptives) + var/fertility = FALSE + /// Does john spaceman need a cesarian/live birth or will he shit out eggs? + var/oviposition = FALSE + /// Does john spaceman look like a gluttonous slob if he pregent? + var/pregnancy_inflation = FALSE + //SPLURT END + /datum/preferences/New(client/C) parent = C @@ -458,6 +469,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Preferred AI Core Display: [preferred_ai_core_display]
" dat += "Preferred Security Department: [prefered_security_department]
" dat += "
Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]
" + //SPLURT EDIT BEGIN - gregnancy preferences + dat += "
Fertility preferences:" + dat += "
Can impregnate: [virility ? "Enabled" : "Disabled"]
" + dat += "
Can get pregnant: [fertility ? "Enabled" : "Disabled"]
" + if(fertility) + dat += "
Pregnancy type: [oviposition ? "Oviposition" : "Live Birth"]
" + dat += "
Pregnancy inflation: [pregnancy_inflation ? "Enabled" : "Disabled"]
" + //SPLURT EDIT END dat += "" //Character Appearance @@ -2001,6 +2020,21 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(user) user.mind?.hide_ckey = hide_ckey + //SPLURT EDIT BEGIN - gregnancy + if("virility") + virility = !virility + + if("fertility") + fertility = !fertility + + if("oviposition") + oviposition = !oviposition + + if("pregnancy_inflation") + pregnancy_inflation = !pregnancy_inflation + + //SPLURT EDIT END + if("hair") var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null if(new_hair) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 095dbbe466..498799dc93 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1164,6 +1164,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN) belly_prefs = SANITIZE_LIST(belly_prefs) + //SPLURT EDIT BEGIN - gregnancy + S["virile"] >> virility + S["fertile"] >> fertility + S["oviposition"] >> oviposition + S["pregnancy_inflation"] >> pregnancy_inflation + //SPLURT EDIT END + cit_character_pref_load(S) return 1 @@ -1350,7 +1357,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(islist(modified_limbs)) WRITE_FILE(S["modified_limbs"] , safe_json_encode(modified_limbs)) WRITE_FILE(S["chosen_limb_id"], chosen_limb_id) - + //SPLURT EDIT BEGIN + WRITE_FILE(S["virile"], virility) + WRITE_FILE(S["fertile"], fertility) + WRITE_FILE(S["oviposition"], oviposition) + WRITE_FILE(S["pregnancy_inflation"], pregnancy_inflation) + //SPLURT EDIT END //gear loadout if(length(loadout_data)) diff --git a/modular_eros/code/datums/status_effects/pregnancy.dm b/modular_eros/code/datums/status_effects/pregnancy.dm new file mode 100644 index 0000000000..0b568b6977 --- /dev/null +++ b/modular_eros/code/datums/status_effects/pregnancy.dm @@ -0,0 +1,238 @@ +/** + * Who is the liar but he who denies that Jesus is the Christ? This is the antichrist, he who denies the Father and the Son. + * - John 2:22 + */ +/atom/movable/screen/alert/status_effect/pregnancy + name = "Pregnant" + desc = "Welp, you sure are pregnant." + icon = 'modular_splurt/icons/mob/screen_alert.dmi' + icon_state = "baby" + +/datum/status_effect/pregnancy + id = "pregnancy" + duration = -1 + tick_interval = 2 SECONDS + alert_type = /atom/movable/screen/alert/status_effect/pregnancy + /// duration of this pregnancy + var/pregnancy_duration = PREGNANCY_DURATION + /// type of baby the mother will plop out - needs to be subtype of /mob/living + var/baby_type = /mob/living/carbon/human + /// weakref to the father, if there is any + var/datum/weakref/father + /// world.time when gregnancy started + var/pregnancy_start = 0 + /// last world.time we ticked on + var/last_tick = 0 + /// this stores the old belly size in case king ass ripper already had a huge, gluttonous belly + var/old_belly_size = 0 + /// this boolean is for identifying whether this crime against nature is a live birth or oviposition + var/oviposition = FALSE + //this boolean is for saving whether or not we should inflate the belly if appropriate + var/pregnancy_inflation = TRUE + //whether or not our babby looks like us - if false, then it's gonna be like dad + var/like_mother_like_son = TRUE + //to avoid spam + var/stop_spamming_birth = FALSE + +/datum/status_effect/pregnancy/Destroy() + . = ..() + father = null + +/datum/status_effect/pregnancy/on_creation(mob/living/new_owner, baby_type, mob/living/father) + if(baby_type) + if(!ispath(baby_type, /mob/living)) + stack_trace("Invalid baby_type given to [type] status effect!") + qdel(src) + return + src.baby_type = baby_type + if(father) + if(!istype(father)) + stack_trace("Invalid father given to [type] status effect!") + qdel(src) + return + src.father = WEAKREF(father) + return ..() + +/datum/status_effect/pregnancy/on_apply() + . = ..() + if(owner.stat >= DEAD) + return FALSE + pregnancy_start = world.time + RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/fetus_mortus) + ADD_TRAIT(owner, TRAIT_PREGNANT, PREGNANCY_TRAIT) + if(ishuman(owner)) + return human_pragency_start(owner) + +/datum/status_effect/pregnancy/tick() + var/obj/item/organ/genital/belly/belly = owner.getorganslot(ORGAN_SLOT_BELLY) + var/pregnancy_time = world.time - pregnancy_start + var/preggy_stage_duration = round(pregnancy_duration/PREGNANCY_STAGES) + //oviposition only has one stage, the rest is handled by the egg + if(pregnancy_time >= preggy_stage_duration && (last_tick < preggy_stage_duration)) + if(!oviposition) + to_chat(owner, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) + if(belly && pregnancy_inflation) + belly.size = max(belly.size, 2) + belly.update() + owner.adjustStaminaLoss(10) + + if(oviposition && (pregnancy_time >= preggy_stage_duration)) + if(!stop_spamming_birth) + to_chat(owner, span_warning("Something presses hard against your anus! It's probably your egg!")) + owner.adjustStaminaLoss(30) + stop_spamming_birth = TRUE + else if(!(world.time % 30)) + to_chat(owner, span_warning("You REALLY need to get this egg out!")) + owner.adjustStaminaLoss(50) + if(prob(50)) + owner.emote("scream") + var/can_oviposit = TRUE + if(ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) + if(LAZYLEN(human_owner.clothingonpart(chest))) + can_oviposit = FALSE + if(can_oviposit) + new /obj/item/reagent_containers/food/snacks/egg/oviposition(owner.loc, src) + to_chat(owner, span_nicegreen("The egg came out!")) + qdel(src) + + if(oviposition) + last_tick = pregnancy_time + return + + if(pregnancy_time >= (preggy_stage_duration*2) && (last_tick < (preggy_stage_duration*2))) + to_chat(owner, span_warning("I can feel my belly getting bigger!")) + if(belly && pregnancy_inflation) + belly.size = max(belly.size, 3) + belly.update() + owner.adjustStaminaLoss(20) + + if(pregnancy_time >= (preggy_stage_duration*3) && (last_tick < (preggy_stage_duration*3))) + to_chat(owner, span_warning("The kicking is quite intense now!")) + if(belly && pregnancy_inflation) + belly.size = max(belly.size, 4) + belly.update() + owner.adjustStaminaLoss(30) + + if(pregnancy_time >= (preggy_stage_duration*4) && (last_tick < (preggy_stage_duration*4))) + to_chat(owner, span_warning("You're going into labor very soon! Get ready to give birth!")) + if(belly && pregnancy_inflation) + belly.size = max(belly.size, 5) + belly.update() + owner.adjustStaminaLoss(50) + + if(pregnancy_time >= (preggy_stage_duration*4)) + owner.adjustStaminaLoss(5) + + if(pregnancy_time >= ((preggy_stage_duration*4) + 20 SECONDS)) + if(!stop_spamming_birth) + to_chat(owner, span_warning("You're going into labor right now!")) + owner.adjustStaminaLoss(30) + stop_spamming_birth = TRUE + else if(!(world.time % 30)) + to_chat(owner, span_userdanger("It hurts! You need to get rid of that damn baby!")) + owner.adjustStaminaLoss(50) + if(prob(50)) + owner.emote("scream") + owner.adjustStaminaLoss(5) + var/can_birth = TRUE + if(ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) + if(LAZYLEN(human_owner.clothingonpart(chest))) + can_birth = FALSE + if(can_birth) + to_chat(owner, span_nicegreen("The baby came out!")) + var/mob/living/babby = new baby_type(owner.loc) + if(ishuman(babby)) + var/mob/living/carbon/human/progenitor = owner + var/mob/living/carbon/human/human_babby = babby + if(father && (!like_mother_like_son || !istype(progenitor))) + var/mob/living/carbon/human/daddy = father.resolve() + if(istype(daddy)) + progenitor = daddy + if(istype(progenitor)) + progenitor.dna.transfer_identity(human_babby) + INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, owner) + qdel(src) + + last_tick = pregnancy_time + +/datum/status_effect/pregnancy/on_remove() + REMOVE_TRAIT(owner, TRAIT_PREGNANT, PREGNANCY_TRAIT) + UnregisterSignal(owner, COMSIG_MOB_DEATH) + if(ishuman(owner)) + human_pragency_end(owner) + return ..() + +/datum/status_effect/pregnancy/proc/human_pragency_start(mob/living/carbon/human/gregnant) + //you need a womb even if male to get gragnet + if(!gregnant.getorganslot(ORGAN_SLOT_WOMB)) + return FALSE + if(gregnant.client?.prefs) + oviposition = gregnant.client.prefs.oviposition + pregnancy_inflation = gregnant.client.prefs.pregnancy_inflation + if(father && ispath(baby_type, /mob/living/carbon/human)) + INVOKE_ASYNC(src, .proc/progenitor_select) + if(pregnancy_inflation) + //give them a king ass ripper belly initially + var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = gregnant.give_genital(/obj/item/organ/genital/belly) + else + old_belly_size = belly.size + belly.size = max(belly.size, 1) + belly.update() + return TRUE + +/datum/status_effect/pregnancy/proc/human_pragency_end(mob/living/carbon/human/gregnant) + //get rid of king ass ripper belly + var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) + if(belly && pregnancy_inflation) + belly.size = old_belly_size + belly.update() + +/datum/status_effect/pregnancy/proc/progenitor_select() + var/list/buttons = list("Like me!", "Like dad!") + var/fatherful_input = tgui_input_list(owner, "You're pregnant! Who is the baby gonna look like?", "Pregnancy", buttons, 1 MINUTES) + if(fatherful_input == "Like dad!") + like_mother_like_son = FALSE + +/datum/status_effect/pregnancy/proc/fetus_mortus() + SIGNAL_HANDLER + + if(!QDELETED(owner) && isturf(owner.loc)) + if(!oviposition) + new /obj/effect/gibspawner/generic(owner.loc) + else + new /obj/effect/decal/cleanable/egg_smudge(owner.loc) + owner.visible_message(span_danger("[owner] has a miscarriage!"), \ + span_userdanger("Oh no! My baby is dead!")) + qdel(src) + +/datum/status_effect/pregnancy/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) + var/poll_message = "Do you want to play as [mommy]'s offspring?" + var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) + if(!LAZYLEN(candidates)) + babby.real_name = random_unique_name(babby.gender, FALSE) + babby.update_name() + return + + var/mob/player = pick(candidates) + player.transfer_ckey(babby, TRUE) + var/mommy_name = "someone" + if(!QDELETED(mommy)) + mommy_name = mommy.real_name + + to_chat(babby, "You are the son (or daughter) of [mommy_name]!") + var/time = world.time + var/name = input(babby, "What will be your name? (You have a minute to decide!)", "Name yourself") as null|text + if(world.time - time >= 1 MINUTES) + to_chat(babby, "You took too long to decide a name and have been given a random name instead.") + if(!name || (world.time - time >= 1 MINUTES)) + babby.real_name = random_unique_name(babby.gender, FALSE) + babby.update_name() + else + babby.real_name = name + babby.update_name() diff --git a/modular_eros/code/game/objects/items/oviposition.dm b/modular_eros/code/game/objects/items/oviposition.dm new file mode 100644 index 0000000000..e21668d007 --- /dev/null +++ b/modular_eros/code/game/objects/items/oviposition.dm @@ -0,0 +1,28 @@ +/obj/item/reagent_containers/food/snacks/egg/oviposition + var/baby_type = /mob/living/carbon/human + var/datum/dna/progenitor_dna + var/pregnancy_start = 0 + +/obj/item/reagent_containers/food/snacks/egg/oviposition/Initialize(datum/status_effect/pregnancy/pregnancy) + . = ..() + if(pregnancy) + inherit_pregnancy(pregnancy) + START_PROCESSING(SSobj, src) + else + pregnancy_start = world.time + +/obj/item/reagent_containers/food/snacks/egg/oviposition/process() + . = ..() + +/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/inherit_pregnancy(datum/status_effect/pregnancy/pregnancy) + pregnancy_start = pregnancy.pregnancy_start + baby_type = pregnancy.baby_type + if(ispath(baby_type, /mob/living/carbon/human)) + var/mob/living/carbon/human/progenitor = pregnancy.owner + if(pregnancy.father && (!pregnancy.like_mother_like_son || !istype(progenitor))) + var/mob/living/carbon/human/daddy = pregnancy.father.resolve() + if(istype(daddy)) + progenitor = daddy + if(istype(progenitor)) + progenitor_dna = new() + progenitor.dna.copy_dna(progenitor_dna) diff --git a/modular_splurt/code/_globalvars/lists/pregnancy.dm b/modular_splurt/code/_globalvars/lists/pregnancy.dm new file mode 100644 index 0000000000..c4d3ec6810 --- /dev/null +++ b/modular_splurt/code/_globalvars/lists/pregnancy.dm @@ -0,0 +1,3 @@ +GLOBAL_LIST_INIT(pregnancy_blocked_mob_typecache, typecacheof(list( + /mob/living/simple_animal/hostile/megafauna, +))) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index eadafbb6af..f16cffa8e8 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -5,6 +5,17 @@ /mob/living/receive_climax(mob/living/partner, obj/item/organ/genital/receiver, obj/item/organ/genital/source_gen, spill, forced) . = ..() + //gregnancy... + if(!spill && istype(source_gen, /obj/item/organ/genital/penis) && \ + istype(receiver, /obj/item/organ/genital/vagina) && prob(PREGNANCY_CHANCE_ON_EJACULATION)) + var/can_impregnate = TRUE + if(source_gen.owner.client?.prefs) + can_impregnate = source_gen.owner.client.prefs.virility + var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) + if(can_impregnate && can_get_pregnant) + apply_status_effect(/datum/status_effect/pregnancy, src.type, source_gen.owner) + to_chat(source_gen.owner, span_danger("That felt like a pregnancy nut!")) + to_chat(src, span_danger("That felt like a pregnancy nut!")) if(!receiver || spill || forced) return diff --git a/modular_splurt/icons/mob/screen_alert.dmi b/modular_splurt/icons/mob/screen_alert.dmi new file mode 100644 index 0000000000000000000000000000000000000000..c627ca9892a8194e2f32efa35e11b87891c66524 GIT binary patch literal 1319 zcmV+?1=#wDP)V=-0C=1w$Gr-GAQT4B+4~e9wMT!eOBmsh@1SUThYD1R-oByjoEp=-Xalus zxnsv8=`5akkV$4~+x zG2{@aZ>3OzDTG3xxiyzwdg`$>P)fn}rG?tY6ij`vH;1|^ZdFL_Qpt`jSgZC(vz9EQ z?LnUP?rLSZC5;~pyR$pH|IeTI|GXjd^Ya)TyH%FZ1cVcg2>AUS6~=Z^ zubVA@(3c*h#~E0fp0w^2CB&VM68QZc6#!PG9S*2!sA+Zr@nnhuKrW+k&jE+HG;)gq zfHpG)&Kd3L>2*2bL$SDR^&Jkhntfk-kghDu9cx%Xj7wd+NtdQ4@$_k)+9Tof5y$wp z5r`*KG?&r1s;Zs_hsVaPCE3icVfL%f0W>0YY2+4lN5UO}7bsQk2ZIU>gZq6x-$A8P zMYY;!=PzEND+_a6^xf_HdmquD(uod9Mu#LL9PLKB+D(|IiS_lr99h)Ff!^2OrT~!WA3!dn9c#o5qg--0(D-MAJ9bXAbbzs4 z2;)Je6O6GF8+5}o&BK2(&*uV;B~aB606?tmyZ1k(s;a`P{qn=N+-n)K%Zt!vra%Y* zA;j?wa1tY%TK*G-WHo)NHneOTG(@YuLx<^X7- ze*nW{<8(8>W-XiG#Ys8Plm(5ev+CtC8n|C@iT(i? Date: Sat, 28 May 2022 18:38:05 +1000 Subject: [PATCH 02/72] i hate the antichrist i hate the antichrist --- code/__SPLURTCODE/DEFINES/pregnancy.dm | 2 +- .../code/datums/status_effects/pregnancy.dm | 224 +--------------- .../code/game/objects/items/oviposition.dm | 71 +++-- .../code/datums/components/pregnancy.dm | 251 ++++++++++++++++++ .../code/modules/arousal/arousal.dm | 2 +- tgstation.dme | 1 + 6 files changed, 306 insertions(+), 245 deletions(-) create mode 100644 modular_splurt/code/datums/components/pregnancy.dm diff --git a/code/__SPLURTCODE/DEFINES/pregnancy.dm b/code/__SPLURTCODE/DEFINES/pregnancy.dm index 9ae55ea102..469e43572e 100644 --- a/code/__SPLURTCODE/DEFINES/pregnancy.dm +++ b/code/__SPLURTCODE/DEFINES/pregnancy.dm @@ -1,3 +1,3 @@ #define PREGNANCY_CHANCE_ON_EJACULATION 10 -#define PREGNANCY_DURATION 15 MINUTES #define PREGNANCY_STAGES 4 +#define PREGNANCY_STAGE_DURATION 5 MINUTES diff --git a/modular_eros/code/datums/status_effects/pregnancy.dm b/modular_eros/code/datums/status_effects/pregnancy.dm index 0b568b6977..b5bc6e7714 100644 --- a/modular_eros/code/datums/status_effects/pregnancy.dm +++ b/modular_eros/code/datums/status_effects/pregnancy.dm @@ -11,228 +11,6 @@ /datum/status_effect/pregnancy id = "pregnancy" duration = -1 - tick_interval = 2 SECONDS + tick = FALSE alert_type = /atom/movable/screen/alert/status_effect/pregnancy - /// duration of this pregnancy - var/pregnancy_duration = PREGNANCY_DURATION - /// type of baby the mother will plop out - needs to be subtype of /mob/living - var/baby_type = /mob/living/carbon/human - /// weakref to the father, if there is any - var/datum/weakref/father - /// world.time when gregnancy started - var/pregnancy_start = 0 - /// last world.time we ticked on - var/last_tick = 0 - /// this stores the old belly size in case king ass ripper already had a huge, gluttonous belly - var/old_belly_size = 0 - /// this boolean is for identifying whether this crime against nature is a live birth or oviposition - var/oviposition = FALSE - //this boolean is for saving whether or not we should inflate the belly if appropriate - var/pregnancy_inflation = TRUE - //whether or not our babby looks like us - if false, then it's gonna be like dad - var/like_mother_like_son = TRUE - //to avoid spam - var/stop_spamming_birth = FALSE -/datum/status_effect/pregnancy/Destroy() - . = ..() - father = null - -/datum/status_effect/pregnancy/on_creation(mob/living/new_owner, baby_type, mob/living/father) - if(baby_type) - if(!ispath(baby_type, /mob/living)) - stack_trace("Invalid baby_type given to [type] status effect!") - qdel(src) - return - src.baby_type = baby_type - if(father) - if(!istype(father)) - stack_trace("Invalid father given to [type] status effect!") - qdel(src) - return - src.father = WEAKREF(father) - return ..() - -/datum/status_effect/pregnancy/on_apply() - . = ..() - if(owner.stat >= DEAD) - return FALSE - pregnancy_start = world.time - RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/fetus_mortus) - ADD_TRAIT(owner, TRAIT_PREGNANT, PREGNANCY_TRAIT) - if(ishuman(owner)) - return human_pragency_start(owner) - -/datum/status_effect/pregnancy/tick() - var/obj/item/organ/genital/belly/belly = owner.getorganslot(ORGAN_SLOT_BELLY) - var/pregnancy_time = world.time - pregnancy_start - var/preggy_stage_duration = round(pregnancy_duration/PREGNANCY_STAGES) - //oviposition only has one stage, the rest is handled by the egg - if(pregnancy_time >= preggy_stage_duration && (last_tick < preggy_stage_duration)) - if(!oviposition) - to_chat(owner, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) - if(belly && pregnancy_inflation) - belly.size = max(belly.size, 2) - belly.update() - owner.adjustStaminaLoss(10) - - if(oviposition && (pregnancy_time >= preggy_stage_duration)) - if(!stop_spamming_birth) - to_chat(owner, span_warning("Something presses hard against your anus! It's probably your egg!")) - owner.adjustStaminaLoss(30) - stop_spamming_birth = TRUE - else if(!(world.time % 30)) - to_chat(owner, span_warning("You REALLY need to get this egg out!")) - owner.adjustStaminaLoss(50) - if(prob(50)) - owner.emote("scream") - var/can_oviposit = TRUE - if(ishuman(owner)) - var/mob/living/carbon/human/human_owner = owner - var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) - if(LAZYLEN(human_owner.clothingonpart(chest))) - can_oviposit = FALSE - if(can_oviposit) - new /obj/item/reagent_containers/food/snacks/egg/oviposition(owner.loc, src) - to_chat(owner, span_nicegreen("The egg came out!")) - qdel(src) - - if(oviposition) - last_tick = pregnancy_time - return - - if(pregnancy_time >= (preggy_stage_duration*2) && (last_tick < (preggy_stage_duration*2))) - to_chat(owner, span_warning("I can feel my belly getting bigger!")) - if(belly && pregnancy_inflation) - belly.size = max(belly.size, 3) - belly.update() - owner.adjustStaminaLoss(20) - - if(pregnancy_time >= (preggy_stage_duration*3) && (last_tick < (preggy_stage_duration*3))) - to_chat(owner, span_warning("The kicking is quite intense now!")) - if(belly && pregnancy_inflation) - belly.size = max(belly.size, 4) - belly.update() - owner.adjustStaminaLoss(30) - - if(pregnancy_time >= (preggy_stage_duration*4) && (last_tick < (preggy_stage_duration*4))) - to_chat(owner, span_warning("You're going into labor very soon! Get ready to give birth!")) - if(belly && pregnancy_inflation) - belly.size = max(belly.size, 5) - belly.update() - owner.adjustStaminaLoss(50) - - if(pregnancy_time >= (preggy_stage_duration*4)) - owner.adjustStaminaLoss(5) - - if(pregnancy_time >= ((preggy_stage_duration*4) + 20 SECONDS)) - if(!stop_spamming_birth) - to_chat(owner, span_warning("You're going into labor right now!")) - owner.adjustStaminaLoss(30) - stop_spamming_birth = TRUE - else if(!(world.time % 30)) - to_chat(owner, span_userdanger("It hurts! You need to get rid of that damn baby!")) - owner.adjustStaminaLoss(50) - if(prob(50)) - owner.emote("scream") - owner.adjustStaminaLoss(5) - var/can_birth = TRUE - if(ishuman(owner)) - var/mob/living/carbon/human/human_owner = owner - var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) - if(LAZYLEN(human_owner.clothingonpart(chest))) - can_birth = FALSE - if(can_birth) - to_chat(owner, span_nicegreen("The baby came out!")) - var/mob/living/babby = new baby_type(owner.loc) - if(ishuman(babby)) - var/mob/living/carbon/human/progenitor = owner - var/mob/living/carbon/human/human_babby = babby - if(father && (!like_mother_like_son || !istype(progenitor))) - var/mob/living/carbon/human/daddy = father.resolve() - if(istype(daddy)) - progenitor = daddy - if(istype(progenitor)) - progenitor.dna.transfer_identity(human_babby) - INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, owner) - qdel(src) - - last_tick = pregnancy_time - -/datum/status_effect/pregnancy/on_remove() - REMOVE_TRAIT(owner, TRAIT_PREGNANT, PREGNANCY_TRAIT) - UnregisterSignal(owner, COMSIG_MOB_DEATH) - if(ishuman(owner)) - human_pragency_end(owner) - return ..() - -/datum/status_effect/pregnancy/proc/human_pragency_start(mob/living/carbon/human/gregnant) - //you need a womb even if male to get gragnet - if(!gregnant.getorganslot(ORGAN_SLOT_WOMB)) - return FALSE - if(gregnant.client?.prefs) - oviposition = gregnant.client.prefs.oviposition - pregnancy_inflation = gregnant.client.prefs.pregnancy_inflation - if(father && ispath(baby_type, /mob/living/carbon/human)) - INVOKE_ASYNC(src, .proc/progenitor_select) - if(pregnancy_inflation) - //give them a king ass ripper belly initially - var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) - if(!belly) - belly = gregnant.give_genital(/obj/item/organ/genital/belly) - else - old_belly_size = belly.size - belly.size = max(belly.size, 1) - belly.update() - return TRUE - -/datum/status_effect/pregnancy/proc/human_pragency_end(mob/living/carbon/human/gregnant) - //get rid of king ass ripper belly - var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) - if(belly && pregnancy_inflation) - belly.size = old_belly_size - belly.update() - -/datum/status_effect/pregnancy/proc/progenitor_select() - var/list/buttons = list("Like me!", "Like dad!") - var/fatherful_input = tgui_input_list(owner, "You're pregnant! Who is the baby gonna look like?", "Pregnancy", buttons, 1 MINUTES) - if(fatherful_input == "Like dad!") - like_mother_like_son = FALSE - -/datum/status_effect/pregnancy/proc/fetus_mortus() - SIGNAL_HANDLER - - if(!QDELETED(owner) && isturf(owner.loc)) - if(!oviposition) - new /obj/effect/gibspawner/generic(owner.loc) - else - new /obj/effect/decal/cleanable/egg_smudge(owner.loc) - owner.visible_message(span_danger("[owner] has a miscarriage!"), \ - span_userdanger("Oh no! My baby is dead!")) - qdel(src) - -/datum/status_effect/pregnancy/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) - var/poll_message = "Do you want to play as [mommy]'s offspring?" - var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) - if(!LAZYLEN(candidates)) - babby.real_name = random_unique_name(babby.gender, FALSE) - babby.update_name() - return - - var/mob/player = pick(candidates) - player.transfer_ckey(babby, TRUE) - var/mommy_name = "someone" - if(!QDELETED(mommy)) - mommy_name = mommy.real_name - - to_chat(babby, "You are the son (or daughter) of [mommy_name]!") - var/time = world.time - var/name = input(babby, "What will be your name? (You have a minute to decide!)", "Name yourself") as null|text - if(world.time - time >= 1 MINUTES) - to_chat(babby, "You took too long to decide a name and have been given a random name instead.") - if(!name || (world.time - time >= 1 MINUTES)) - babby.real_name = random_unique_name(babby.gender, FALSE) - babby.update_name() - else - babby.real_name = name - babby.update_name() diff --git a/modular_eros/code/game/objects/items/oviposition.dm b/modular_eros/code/game/objects/items/oviposition.dm index e21668d007..f2a4cadf02 100644 --- a/modular_eros/code/game/objects/items/oviposition.dm +++ b/modular_eros/code/game/objects/items/oviposition.dm @@ -1,28 +1,59 @@ /obj/item/reagent_containers/food/snacks/egg/oviposition var/baby_type = /mob/living/carbon/human - var/datum/dna/progenitor_dna - var/pregnancy_start = 0 -/obj/item/reagent_containers/food/snacks/egg/oviposition/Initialize(datum/status_effect/pregnancy/pregnancy) + var/datum/dna/father_dna + var/datum/dna/mother_dna + + var/stage = -1 + var/max_stage = 2 + COOLDOWN_DECLARE(stage_time) + +/obj/item/reagent_containers/food/snacks/egg/oviposition/Initialize(datum/component/pregnancy/comp) . = ..() - if(pregnancy) - inherit_pregnancy(pregnancy) + if(comp) + inherit_pregnancy(comp) START_PROCESSING(SSobj, src) - else - pregnancy_start = world.time /obj/item/reagent_containers/food/snacks/egg/oviposition/process() - . = ..() + if(stage >= max_stage && prob(30)) + src.visible_message(span_warning("The egg starts hatching!")) + hatch() -/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/inherit_pregnancy(datum/status_effect/pregnancy/pregnancy) - pregnancy_start = pregnancy.pregnancy_start - baby_type = pregnancy.baby_type - if(ispath(baby_type, /mob/living/carbon/human)) - var/mob/living/carbon/human/progenitor = pregnancy.owner - if(pregnancy.father && (!pregnancy.like_mother_like_son || !istype(progenitor))) - var/mob/living/carbon/human/daddy = pregnancy.father.resolve() - if(istype(daddy)) - progenitor = daddy - if(istype(progenitor)) - progenitor_dna = new() - progenitor.dna.copy_dna(progenitor_dna) + if(COOLDOWN_FINISHED(src, stage_time)) + COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) + stage += 1 + stage = min(stage, max_stage) + + +/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/inherit_pregnancy(datum/component/pregnancy/comp) + if(comp.father_dna) + comp.father_dna.copy_dna(father_dna) + + if(iscarbon(comp.parent)) + var/mob/living/carbon/momma = comp.parent + momma.dna.copy_dna(mother_dna) + + baby_type = comp.baby_type + +/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/hatch() + var/mob/living/babby = new baby_type(src) + if(ishuman(babby)) + determine_baby_dna(babby) + sleep(10) + babby.forceMove(get_turf(src)) + qdel(src) + +/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/determine_baby_dna(mob/living/carbon/human/babby) + if(mother_dna && father_dna) + if(prob(50)) + mother_dna.transfer_identity(babby) + else + father_dna.transfer_identity(babby) + else if(mother_dna && !father_dna) + mother_dna.transfer_identity(babby) + else if(!mother_dna && father_dna) + father_dna.transfer_identity(babby) + else + var/datum/dna/rando = new + rando.initialize_dna(random_blood_type()) + rando.transfer_identity(babby) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm new file mode 100644 index 0000000000..7977d62c21 --- /dev/null +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -0,0 +1,251 @@ +/datum/component/pregnancy + + dupe_mode = COMPONENT_DUPE_UNIQUE + + /// type of baby the mother will plop out - needs to be subtype of /mob/living + var/baby_type = /mob/living/carbon/human + + var/datum/dna/father_dna + + var/stage = 0 + var/max_stage = PREGNANCY_STAGES + COOLDOWN_DECLARE(stage_time) + + /// this stores the old belly size in case king ass ripper already had a huge, gluttonous belly + var/old_belly_size = 0 + /// this boolean is for identifying whether this crime against nature is a live birth or oviposition + var/oviposition = FALSE + //this boolean is for saving whether or not we should inflate the belly if appropriate + var/pregnancy_inflation = TRUE + var/revealed = FALSE + +/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, need_wombs = TRUE) + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + + var/mob/living/preggo = parent + if(preggo.stat >= DEAD) + return COMPONENT_INCOMPATIBLE + + if(ispath(_baby_type, /mob/living)) + baby_type = _baby_type + else + stack_trace("Invalid baby_type given to pregnancy component!") + return COMPONENT_INCOMPATIBLE + + if(iscarbon(_father)) + var/mob/living/carbon/carbo = _father + father_dna = new + carbo.dna.copy_dna(father_dna) + + if(iscarbon(parent)) + var/mob/living/carbon/carbo = parent + if(!carbo.getorganslot(ORGAN_SLOT_WOMB) && need_wombs) + return COMPONENT_INCOMPATIBLE + + if(ishuman(parent)) + human_pragency_start(parent) + + ADD_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) + +/datum/component/pregnancy/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/fetus_mortus) + RegisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) + +/datum/component/pregnancy/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, COMSIG_MOB_DEATH) + UnregisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE) + +/datum/component/pregnancy/Destroy() + REMOVE_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) + var/mob/living/preggo = parent + preggo.remove_status_effect(/datum/status_effect/pregnancy) + if(ishuman(parent)) + human_pragency_end(parent) + return ..() + +/datum/component/pregnancy/proc/handle_life(seconds) + SIGNAL_HANDLER + if(ishuman(parent)) + handle_belly_stuff(parent) + + if(oviposition) + handle_ovi_preg() + else + handle_preg() + + if((stage > (max_stage / 2)) && !revealed) + revealed = TRUE + var/mob/living/preggo = parent + preggo.apply_status_effect(/datum/status_effect/pregnancy) + + if(COOLDOWN_FINISHED(src, stage_time)) + COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) + stage += 1 + stage = min(stage, max_stage) + +/datum/component/pregnancy/proc/handle_belly_stuff(mob/living/carbon/human/gregnant) + if(!(stage > (max_stage / 2))) + return + var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) + if(belly && pregnancy_inflation) + switch(stage) + if(2) + belly.size = max(belly.size, 2) + if(3) + belly.size = max(belly.size, 3) + if(4) + belly.size = max(belly.size, 4) + belly.update() + +/datum/component/pregnancy/proc/handle_preg() + var/mob/living/preggo = parent + + if(prob(10)) + switch(stage) + if(2) + to_chat(preggo, span_warning("You can feel your belly getting bigger!")) + if(3) + if(prob(50)) + to_chat(preggo, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) + else + to_chat(preggo, span_warning("The kicking is quite intense now!")) + preggo.adjustStaminaLoss(20) + if(4) + to_chat(preggo, span_warning("You feel like you're going into labor very soon! Get ready to give birth!")) + preggo.adjustStaminaLoss(50) + + if(prob(60)) + return + if(stage < max_stage) + return + + if(prob(50)) + to_chat(preggo, span_warning("You're going into labor right now!")) + preggo.adjustStaminaLoss(30) + else + to_chat(preggo, span_userdanger("It hurts! The baby is coming out!")) + preggo.adjustStaminaLoss(50) + preggo.emote("scream") + preggo.adjustStaminaLoss(5) + + var/can_birth = TRUE + if(ishuman(preggo)) + var/mob/living/carbon/human/human_owner =preggo + var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) + if(LAZYLEN(human_owner.clothingonpart(chest))) + can_birth = FALSE + if(can_birth) + playsound(parent, 'sound/effects/splat.ogg', 70, TRUE) + to_chat(preggo, span_nicegreen("The baby came out!")) + var/mob/living/babby = new baby_type(get_turf(preggo)) + if(ishuman(babby)) + determine_baby_dna(babby) + INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, preggo) + qdel(src) + +/datum/component/pregnancy/proc/handle_ovi_preg() + if(stage < (max_stage / 2)) + if(stage == 2 && prob(3)) + to_chat(parent, span_notice("You feel something pressing lightly inside")) + return + var/mob/living/preggo = parent + if(prob(50)) + to_chat(preggo, span_warning("Something presses hard against your anus! It's probably your egg!")) + preggo.adjustStaminaLoss(30) + else + to_chat(preggo, span_warning("You REALLY need to get this egg out!")) + preggo.adjustStaminaLoss(50) + preggo.emote("scream") + + var/can_oviposit = TRUE + if(ishuman(parent)) + var/mob/living/carbon/human/human_owner =parent + var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) + if(LAZYLEN(human_owner.clothingonpart(chest))) + can_oviposit = FALSE + if(can_oviposit) + playsound(parent, 'sound/effects/splat.ogg', 70, TRUE) + new /obj/item/reagent_containers/food/snacks/egg/oviposition(get_turf(preggo), src) + to_chat(parent, span_nicegreen("The egg came out!")) + qdel(src) + +//not how genetics work but okay +/datum/component/pregnancy/proc/determine_baby_dna(mob/living/carbon/human/babby) + var/mob/living/carbon/mommy = parent + var/datum/dna/mother_dna = mommy?.dna + if(mother_dna && father_dna) + if(prob(50)) + mother_dna.transfer_identity(babby) + else + father_dna.transfer_identity(babby) + else if(mother_dna && !father_dna) + mother_dna.transfer_identity(babby) + else if(!mother_dna && father_dna) + father_dna.transfer_identity(babby) + else + var/datum/dna/rando = new + rando.initialize_dna(random_blood_type()) + rando.transfer_identity(babby) + +/datum/component/pregnancy/proc/human_pragency_start(mob/living/carbon/human/gregnant) + if(gregnant.client?.prefs) + oviposition = gregnant.client.prefs.oviposition + pregnancy_inflation = gregnant.client.prefs.pregnancy_inflation + if(pregnancy_inflation) + //give them a king ass ripper belly initially + var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = gregnant.give_genital(/obj/item/organ/genital/belly) + else + old_belly_size = belly.size + belly.size = max(belly.size, 1) + belly.update() + return TRUE + +/datum/component/pregnancy/proc/human_pragency_end(mob/living/carbon/human/gregnant) + //get rid of king ass ripper belly + var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) + if(belly && pregnancy_inflation) + belly.size = 1 + belly.update() + +/datum/component/pregnancy/proc/fetus_mortus() + SIGNAL_HANDLER + var/mob/living/preggo = parent + if(!QDELETED(parent) && get_turf(preggo) && (stage > (max_stage / 2))) + if(!oviposition) + new /obj/effect/gibspawner/generic(get_turf(preggo)) + else + new /obj/effect/decal/cleanable/egg_smudge(get_turf(preggo)) + preggo.visible_message(span_danger("[parent] has a miscarriage!"), \ + span_userdanger("Oh no! My baby is dead!")) + qdel(src) + +/datum/component/pregnancy/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) + var/poll_message = "Do you want to play as [mommy]'s offspring?" + var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) + if(!LAZYLEN(candidates)) + babby.real_name = random_unique_name(babby.gender, FALSE) + babby.update_name() + return + + var/mob/player = pick(candidates) + player.transfer_ckey(babby, TRUE) + var/mommy_name = "someone" + if(!QDELETED(mommy)) + mommy_name = mommy.real_name + + to_chat(babby, "You are the son (or daughter) of [mommy_name]!") + var/time = world.time + var/name = input(babby, "What will be your name? (You have a minute to decide!)", "Name yourself") as null|text + if(world.time - time >= 1 MINUTES) + to_chat(babby, "You took too long to decide a name and have been given a random name instead.") + if(!name || (world.time - time >= 1 MINUTES)) + babby.real_name = random_unique_name(babby.gender, FALSE) + babby.update_name() + else + babby.real_name = name + babby.update_name() diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index f16cffa8e8..3fbf7d648a 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -13,7 +13,7 @@ can_impregnate = source_gen.owner.client.prefs.virility var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) if(can_impregnate && can_get_pregnant) - apply_status_effect(/datum/status_effect/pregnancy, src.type, source_gen.owner) + src.AddComponent(/datum/component/pregnancy, source_gen.owner, src.type) to_chat(source_gen.owner, span_danger("That felt like a pregnancy nut!")) to_chat(src, span_danger("That felt like a pregnancy nut!")) if(!receiver || spill || forced) diff --git a/tgstation.dme b/tgstation.dme index ab4bde613e..4c7fee4f7e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4226,6 +4226,7 @@ #include "modular_splurt\code\datums\status_effects.dm" #include "modular_splurt\code\datums\world_topic.dm" #include "modular_splurt\code\datums\components\chasm.dm" +#include "modular_splurt\code\datums\components\pregnancy.dm" #include "modular_splurt\code\datums\components\crafting\recipes\recipes_misc.dm" #include "modular_splurt\code\datums\components\crafting\recipes\recipes_primal.dm" #include "modular_splurt\code\datums\components\crafting\recipes\recipes_robot.dm" From c0f224efff2824d53213c539cf528b8fb788c72f Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 28 May 2022 20:18:09 +1000 Subject: [PATCH 03/72] some more crap --- code/__SPLURTCODE/DEFINES/signals.dm | 2 ++ code/game/objects/items/devices/scanners.dm | 1 + code/modules/surgery/organs/organ_internal.dm | 1 + .../chemistry/reagents/enlargement.dm | 4 +-- .../datums/interactions/lewd_definitions.dm | 6 ++++ modular_sand/code/datums/traits/neutral.dm | 3 +- modular_sand/code/modules/arousal/arousal.dm | 3 +- .../code/datums/components/pregnancy.dm | 35 +++++++++++++++++-- .../code/modules/arousal/arousal.dm | 33 +++++++++-------- .../hostile/deathclaw/funclaw.dm | 1 + 10 files changed, 69 insertions(+), 20 deletions(-) diff --git a/code/__SPLURTCODE/DEFINES/signals.dm b/code/__SPLURTCODE/DEFINES/signals.dm index 89e7a516c8..6316cf2b23 100644 --- a/code/__SPLURTCODE/DEFINES/signals.dm +++ b/code/__SPLURTCODE/DEFINES/signals.dm @@ -1 +1,3 @@ #define COMSIG_MOB_CAME "mob_came" +#define COMSIG_HEALTH_SCAN "health_scan" +#define COMSIG_ORGAN_REMOVED "organ_removed" diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 4528ecc473..1ad70b8d06 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -451,6 +451,7 @@ GENETICS SCANNER msg += "Detected cybernetic modifications:\n" msg += "[cyberimp_detect]\n" to_chat(user, examine_block(msg)) + SEND_SIGNAL(M, COMSIG_HEALTH_SCAN, user)//SPLURT EDIT ADD - gregnancy SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, FALSE) /proc/chemscan(mob/living/user, mob/living/M) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index d4a2663374..253c601a6d 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -82,6 +82,7 @@ var/datum/action/A = X A.Remove(owner) . = owner //for possible subtypes specific post-removal code. + SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED)//SPLURT EDIT ADD - gregnancy owner = null START_PROCESSING(SSobj, src) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 351037e973..24b0fc0a76 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -101,8 +101,8 @@ W = new W.Insert(M) - if(M.has_quirk(/datum/quirk/infertile)) - M.remove_quirk(/datum/quirk/infertile) + //if(M.has_quirk(/datum/quirk/infertile)) + // M.remove_quirk(/datum/quirk/infertile) return ..() diff --git a/modular_sand/code/datums/interactions/lewd_definitions.dm b/modular_sand/code/datums/interactions/lewd_definitions.dm index 93cc33976d..54f114fb5c 100644 --- a/modular_sand/code/datums/interactions/lewd_definitions.dm +++ b/modular_sand/code/datums/interactions/lewd_definitions.dm @@ -483,6 +483,9 @@ if(partner_carbon_check) target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) message = "cums in \the [partner]'s pussy." + var/obj/item/organ/genital/penis/peepee = getorganslot(ORGAN_SLOT_PENIS) + if(!peepee.equipment[GENITAL_EQUIPEMENT_CONDOM]) + partner.impregnate(src, partner.getorganslot(ORGAN_SLOT_WOMB), src.type) cumin = TRUE else message = "cums on \the [partner]'s belly." @@ -647,6 +650,9 @@ if(partner_carbon_check) target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) message = "cums in \the [partner]'s pussy." + var/obj/item/organ/genital/penis/peepee = last_genital + if(!peepee.equipment[GENITAL_EQUIPEMENT_CONDOM]) + partner.impregnate(src, partner.getorganslot(ORGAN_SLOT_WOMB), src.type) cumin = TRUE else message = "cums on \the [partner]'s belly." diff --git a/modular_sand/code/datums/traits/neutral.dm b/modular_sand/code/datums/traits/neutral.dm index bd161be5f4..33cc31da0d 100644 --- a/modular_sand/code/datums/traits/neutral.dm +++ b/modular_sand/code/datums/traits/neutral.dm @@ -11,7 +11,7 @@ var/datum/brain_trauma/severe/hypnotic_stupor/T = new() var/mob/living/carbon/human/H = quirk_holder H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE) - +/* /datum/quirk/infertile name = "Infertile" desc = "For one reason or another you simply don't seem able to get pregnant, no matter how hard you try." @@ -21,3 +21,4 @@ gain_text = "Your womb starts feeling dry and empty, all the life in it begins to fade away..." lose_text = "You feel the warm blow of life flooding your womb, full of newfound, vibrant fertility!" medical_record_text = "Patient doesn't seem able to ovulate properly..." +*/ diff --git a/modular_sand/code/modules/arousal/arousal.dm b/modular_sand/code/modules/arousal/arousal.dm index 6bab60ae74..6b7df9b07c 100644 --- a/modular_sand/code/modules/arousal/arousal.dm +++ b/modular_sand/code/modules/arousal/arousal.dm @@ -14,7 +14,7 @@ if(LAZYLEN(receivers_list)) var/obj/item/organ/genital/ret_organ = input(src, desc, title, null) as null|obj in receivers_list return ret_organ - +/* /mob/living/proc/receive_climax(mob/living/partner, obj/item/organ/genital/receiver = null, obj/item/organ/genital/source_gen, spill = TRUE) if(!ishuman(src)) return @@ -36,3 +36,4 @@ var/obj/item/organ/genital/breasts/B = h_self.getorganslot(ORGAN_SLOT_BREASTS) if(B) B.fluid_rate *= 2 +*/ diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 7977d62c21..3d0323186d 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -5,6 +5,8 @@ /// type of baby the mother will plop out - needs to be subtype of /mob/living var/baby_type = /mob/living/carbon/human + var/obj/item/organ/container + var/datum/dna/father_dna var/stage = 0 @@ -15,11 +17,12 @@ var/old_belly_size = 0 /// this boolean is for identifying whether this crime against nature is a live birth or oviposition var/oviposition = FALSE - //this boolean is for saving whether or not we should inflate the belly if appropriate + /// this boolean is for saving whether or not we should inflate the belly if appropriate var/pregnancy_inflation = TRUE + /// whether the pregnancy is revealed or not, scanners will reveal this no matter what var/revealed = FALSE -/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, need_wombs = TRUE) +/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -38,10 +41,15 @@ father_dna = new carbo.dna.copy_dna(father_dna) + if(container_organ) + container = container_organ + + /* if(iscarbon(parent)) var/mob/living/carbon/carbo = parent if(!carbo.getorganslot(ORGAN_SLOT_WOMB) && need_wombs) return COMPONENT_INCOMPATIBLE + */ if(ishuman(parent)) human_pragency_start(parent) @@ -52,11 +60,20 @@ . = ..() RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/fetus_mortus) RegisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) + RegisterSignal(parent, COMSIG_HEALTH_SCAN, .proc/on_scan) + RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, .proc/handle_damage) + if(container) + RegisterSignal(container, COMSIG_ORGAN_REMOVED, .proc/fetus_mortus) + /datum/component/pregnancy/UnregisterFromParent() . = ..() UnregisterSignal(parent, COMSIG_MOB_DEATH) UnregisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE) + UnregisterSignal(parent, COMSIG_HEALTH_SCAN) + UnregisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE) + if(container) + UnregisterSignal(container, COMSIG_ORGAN_REMOVED) /datum/component/pregnancy/Destroy() REMOVE_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) @@ -68,6 +85,7 @@ /datum/component/pregnancy/proc/handle_life(seconds) SIGNAL_HANDLER + if(ishuman(parent)) handle_belly_stuff(parent) @@ -214,6 +232,7 @@ /datum/component/pregnancy/proc/fetus_mortus() SIGNAL_HANDLER + var/mob/living/preggo = parent if(!QDELETED(parent) && get_turf(preggo) && (stage > (max_stage / 2))) if(!oviposition) @@ -224,6 +243,18 @@ span_userdanger("Oh no! My baby is dead!")) qdel(src) +/datum/component/pregnancy/proc/on_scan(datum/source, mob/user) + SIGNAL_HANDLER + + to_chat(user, span_notice("Pregnancy detected!")) + +//drop kicked +/datum/component/pregnancy/proc/handle_damage(datum/source, damage, damagetype, def_zone) + SIGNAL_HANDLER + + if(def_zone == BODY_ZONE_CHEST && damage > 25 && prob(40)) + fetus_mortus() + /datum/component/pregnancy/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) var/poll_message = "Do you want to play as [mommy]'s offspring?" var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index 3fbf7d648a..a7927d21a4 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -2,24 +2,29 @@ . = ..() L.receive_climax(src, Lgen, G, spillage, forced = forced) -/mob/living/receive_climax(mob/living/partner, obj/item/organ/genital/receiver, obj/item/organ/genital/source_gen, spill, forced) - . = ..() - +/mob/living/proc/receive_climax(mob/living/partner, obj/item/organ/genital/receiver, obj/item/organ/genital/source, spill, forced) //gregnancy... - if(!spill && istype(source_gen, /obj/item/organ/genital/penis) && \ - istype(receiver, /obj/item/organ/genital/vagina) && prob(PREGNANCY_CHANCE_ON_EJACULATION)) - var/can_impregnate = TRUE - if(source_gen.owner.client?.prefs) - can_impregnate = source_gen.owner.client.prefs.virility - var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) - if(can_impregnate && can_get_pregnant) - src.AddComponent(/datum/component/pregnancy, source_gen.owner, src.type) - to_chat(source_gen.owner, span_danger("That felt like a pregnancy nut!")) - to_chat(src, span_danger("That felt like a pregnancy nut!")) + if(!spill && istype(source, /obj/item/organ/genital/penis) && \ + istype(receiver, /obj/item/organ/genital/vagina) && getorganslot(ORGAN_SLOT_WOMB)) + var/obj/item/organ/genital/penis/peenus = source + if(!peenus.equipment[GENITAL_EQUIPEMENT_CONDOM]) + impregnate(partner, getorganslot(ORGAN_SLOT_WOMB), src.type) + if(!receiver || spill || forced) return - receiver.climax_modify_size(partner, source_gen) + receiver.climax_modify_size(partner, source) + +/mob/living/proc/impregnate(mob/living/partner, /obj/item/organ/W, baby_type) + if(!W) + return + if(prob(PREGNANCY_CHANCE_ON_EJACULATION)) + var/can_impregnate = TRUE + if(partner?.client?.prefs) + can_impregnate = partner.client.prefs.virility + var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) + if(can_impregnate && can_get_pregnant) + AddComponent(/datum/component/pregnancy, partner, baby_type, W) /mob/living/carbon/human/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill, cover = FALSE) if(!G) diff --git a/modular_splurt/code/modules/mob/living/carbon/human/simple_animal/hostile/deathclaw/funclaw.dm b/modular_splurt/code/modules/mob/living/carbon/human/simple_animal/hostile/deathclaw/funclaw.dm index dbf172435a..81af399f1f 100644 --- a/modular_splurt/code/modules/mob/living/carbon/human/simple_animal/hostile/deathclaw/funclaw.dm +++ b/modular_splurt/code/modules/mob/living/carbon/human/simple_animal/hostile/deathclaw/funclaw.dm @@ -160,6 +160,7 @@ if(CUM_TARGET_VAGINA) if(M.is_bottomless() && M.has_vagina()) message = "rams its meaty cock into \the [M]'s pussy and fills it with sperm." + M.impregnate(src, M.getorganslot(ORGAN_SLOT_WOMB), src.type) else message = "cums on \the [M]'s belly." if(CUM_TARGET_ANUS) From 0c7b24b7b3742c160b543a563c54951b91def396 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 28 May 2022 20:43:59 +1000 Subject: [PATCH 04/72] fix pref --- code/modules/client/preferences.dm | 19 +++++++++++-------- .../code/datums/components/pregnancy.dm | 12 ++++-------- .../code/modules/arousal/arousal.dm | 6 ++++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index b890f323f0..8c9b849829 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -469,14 +469,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Preferred AI Core Display: [preferred_ai_core_display]
" dat += "Preferred Security Department: [prefered_security_department]
" dat += "
Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]
" - //SPLURT EDIT BEGIN - gregnancy preferences - dat += "
Fertility preferences:" - dat += "
Can impregnate: [virility ? "Enabled" : "Disabled"]
" - dat += "
Can get pregnant: [fertility ? "Enabled" : "Disabled"]
" - if(fertility) - dat += "
Pregnancy type: [oviposition ? "Oviposition" : "Live Birth"]
" - dat += "
Pregnancy inflation: [pregnancy_inflation ? "Enabled" : "Disabled"]
" - //SPLURT EDIT END dat += "" //Character Appearance @@ -835,6 +827,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Lust tolerance:[lust_tolerance]" dat += "Sexual potency:[sexual_potency]" dat += "" + + dat += "" + //SPLURT EDIT BEGIN - gregnancy preferences + dat += "

Pregnancy preferences

" + dat += "Can impregnate:[virility ? "Enabled" : "Disabled"]" + dat += "Can get pregnant:[fertility ? "Enabled" : "Disabled"]" + if(fertility) + dat += "Pregnancy type:[oviposition ? "Oviposition" : "Live Birth"]" + dat += "Pregnancy inflation:[pregnancy_inflation ? "Enabled" : "Disabled"]" + //SPLURT EDIT END + dat += "" dat += APPEARANCE_CATEGORY_COLUMN if(NOGENITALS in pref_species.species_traits) dat += "Your species ([pref_species.name]) does not support genitals!
" diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 3d0323186d..462a9e22ef 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -22,7 +22,7 @@ /// whether the pregnancy is revealed or not, scanners will reveal this no matter what var/revealed = FALSE -/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ) +/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ, _oviposition, _pregnancy_inflation) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -41,16 +41,12 @@ father_dna = new carbo.dna.copy_dna(father_dna) + oviposition = oviposition + pregnancy_inflation = _pregnancy_inflation + if(container_organ) container = container_organ - /* - if(iscarbon(parent)) - var/mob/living/carbon/carbo = parent - if(!carbo.getorganslot(ORGAN_SLOT_WOMB) && need_wombs) - return COMPONENT_INCOMPATIBLE - */ - if(ishuman(parent)) human_pragency_start(parent) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index a7927d21a4..b7d165b8b1 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -15,7 +15,8 @@ receiver.climax_modify_size(partner, source) -/mob/living/proc/impregnate(mob/living/partner, /obj/item/organ/W, baby_type) +//handles impregnation, also prefs +/mob/living/proc/impregnate(mob/living/partner, obj/item/organ/W, baby_type) if(!W) return if(prob(PREGNANCY_CHANCE_ON_EJACULATION)) @@ -23,8 +24,9 @@ if(partner?.client?.prefs) can_impregnate = partner.client.prefs.virility var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) + if(can_impregnate && can_get_pregnant) - AddComponent(/datum/component/pregnancy, partner, baby_type, W) + AddComponent(/datum/component/pregnancy, partner, baby_type, W, client?.prefs?.oviposition, client?.prefs?.pregnancy_inflation) /mob/living/carbon/human/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill, cover = FALSE) if(!G) From a4ba64fc9036d889202f14a5b0d7aea133e06844 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 28 May 2022 20:45:31 +1000 Subject: [PATCH 05/72] comment madness --- code/modules/client/preferences.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8c9b849829..2f0db64b9a 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -828,16 +828,16 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Sexual potency:[sexual_potency]" dat += "" - dat += "" //SPLURT EDIT BEGIN - gregnancy preferences + dat += "" dat += "

Pregnancy preferences

" dat += "Can impregnate:[virility ? "Enabled" : "Disabled"]" dat += "Can get pregnant:[fertility ? "Enabled" : "Disabled"]" if(fertility) dat += "Pregnancy type:[oviposition ? "Oviposition" : "Live Birth"]" dat += "Pregnancy inflation:[pregnancy_inflation ? "Enabled" : "Disabled"]" - //SPLURT EDIT END dat += "" + //SPLURT EDIT END dat += APPEARANCE_CATEGORY_COLUMN if(NOGENITALS in pref_species.species_traits) dat += "Your species ([pref_species.name]) does not support genitals!
" From 96e4b4635c48338b8c1a2d3c5c2a03e05cb4752f Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 28 May 2022 20:48:40 +1000 Subject: [PATCH 06/72] move that to there --- modular_splurt/code/datums/components/pregnancy.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 462a9e22ef..853bcee9c5 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -82,7 +82,7 @@ /datum/component/pregnancy/proc/handle_life(seconds) SIGNAL_HANDLER - if(ishuman(parent)) + if(ishuman(parent) && pregnancy_inflation) handle_belly_stuff(parent) if(oviposition) @@ -104,7 +104,7 @@ if(!(stage > (max_stage / 2))) return var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) - if(belly && pregnancy_inflation) + if(belly) switch(stage) if(2) belly.size = max(belly.size, 2) From dad660ec61fa81f2c613c7b5ad1b4591d4cfe86c Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Mon, 30 May 2022 20:24:59 +1000 Subject: [PATCH 07/72] stun knockdown --- .../code/datums/components/pregnancy.dm | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 853bcee9c5..1970390a2a 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -147,13 +147,15 @@ var/can_birth = TRUE if(ishuman(preggo)) - var/mob/living/carbon/human/human_owner =preggo + var/mob/living/carbon/human/human_owner = preggo var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) if(LAZYLEN(human_owner.clothingonpart(chest))) can_birth = FALSE if(can_birth) - playsound(parent, 'sound/effects/splat.ogg', 70, TRUE) + playsound(preggo, 'sound/effects/splat.ogg', 70, TRUE) to_chat(preggo, span_nicegreen("The baby came out!")) + preggo.Knockdown(200, TRUE, TRUE) + preggo.Stun(200, TRUE, TRUE) var/mob/living/babby = new baby_type(get_turf(preggo)) if(ishuman(babby)) determine_baby_dna(babby) @@ -161,11 +163,11 @@ qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() + var/mob/living/preggo = parent if(stage < (max_stage / 2)) if(stage == 2 && prob(3)) - to_chat(parent, span_notice("You feel something pressing lightly inside")) + to_chat(preggo, span_notice("You feel something pressing lightly inside")) return - var/mob/living/preggo = parent if(prob(50)) to_chat(preggo, span_warning("Something presses hard against your anus! It's probably your egg!")) preggo.adjustStaminaLoss(30) @@ -175,15 +177,17 @@ preggo.emote("scream") var/can_oviposit = TRUE - if(ishuman(parent)) - var/mob/living/carbon/human/human_owner =parent + if(ishuman(preggo)) + var/mob/living/carbon/human/human_owner = preggo var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) if(LAZYLEN(human_owner.clothingonpart(chest))) can_oviposit = FALSE if(can_oviposit) - playsound(parent, 'sound/effects/splat.ogg', 70, TRUE) + playsound(preggo, 'sound/effects/splat.ogg', 70, TRUE) + preggo.Knockdown(200, TRUE, TRUE) + preggo.Stun(200, TRUE, TRUE) new /obj/item/reagent_containers/food/snacks/egg/oviposition(get_turf(preggo), src) - to_chat(parent, span_nicegreen("The egg came out!")) + to_chat(preggo, span_nicegreen("The egg came out!")) qdel(src) //not how genetics work but okay From f59bb6032eb4b155e50a5855cc42c11e9513dc6f Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Thu, 23 Jun 2022 20:07:12 +1000 Subject: [PATCH 08/72] get this stuff done --- code/__DEFINES/citadel_defines.dm | 3 + code/__DEFINES/dcs/signals.dm | 1 + code/__HELPERS/_cit_helpers.dm | 2 + code/datums/dna.dm | 64 ++++++ code/game/atoms.dm | 1 + code/modules/arousal/organs/vagina.dm | 3 + .../code/game/objects/items/oviposition.dm | 57 ------ .../interactions/interaction_interface.dm | 49 +++++ .../code/datums/components/pregnancy.dm | 191 +++++++++++------- modular_splurt/code/game/object/items.dm | 124 ++++++++++++ .../code/modules/arousal/arousal.dm | 2 +- tgstation.dme | 1 + .../tgui/interfaces/MobInteraction.tsx | 105 +++++++++- 13 files changed, 463 insertions(+), 140 deletions(-) create mode 100644 modular_splurt/code/game/object/items.dm diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 2857b4c1c1..4da76ceb15 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -83,6 +83,9 @@ #define GEN_VISIBLE_NO_UNDIES "Hidden by underwear" #define GEN_VISIBLE_NEVER "Always hidden" +#define GEN_REMOVE_EQUIPMENT "Remove Equipment" +#define GEN_INSERT_EQUIPMENT "Insert Equipment" + //Individual logging define #define INDIVIDUAL_LOOC_LOG "LOOC log" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index b3dbc46806..3155f9c508 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -114,6 +114,7 @@ ///from base of [/atom/update_icon]: (signalOut, did_anything) #define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon" #define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) +#define COMSIG_ATOM_ENTERING "atom_entering" #define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) #define COMPONENT_ATOM_BLOCK_EXIT 1 #define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index 3007178607..c5807aa788 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -66,6 +66,8 @@ GLOBAL_LIST_INIT(dick_nouns, list("phallus", "willy", "dick", "prick", "member", GLOBAL_LIST_INIT(genitals_visibility_toggles, list(GEN_VISIBLE_ALWAYS, GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER)) +GLOBAL_LIST_INIT(genitals_interactions, list(GEN_REMOVE_EQUIPMENT, GEN_INSERT_EQUIPMENT)) + GLOBAL_LIST_INIT(dildo_shapes, list( "Human" = "human", "Knotted" = "knotted", diff --git a/code/datums/dna.dm b/code/datums/dna.dm index c89ece5396..21a43e7a75 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -66,6 +66,70 @@ SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE) +#define TRANSFER_RANDOMIZED(destination, source1, source2) \ + if(prob(50)) { \ + destination = source1; \ + } else { \ + destination = source2; \ + } + +#define TRANSFER_RANDOMIZED_LIST(destination, source1, source2) \ + var/list/list1 = source1; \ + var/list/list2 = source2; \ + var/list/result = list(); \ + var/list/iter_len; \ + if(list1.len >= list2.len) { \ + iter_len = list1.len; \ + } else { \ + iter_len = list2.len; \ + } \ + for(var/i in 1 to iter_len) { \ + var/key1 = list1[i]; \ + var/val1 = list1[key1]; \ + var/key2 = list2[i]; \ + var/val2 = list2[key2]; \ + if(prob(50) && key1) { \ + result[key1] = val1; \ + } else if(key2) { \ + result[key2] = val2; \ + } \ + } \ + destination = result.Copy(); + + +/datum/dna/proc/transfer_identity_random(datum/dna/second_set, mob/living/carbon/destination) + if(!istype(destination)) + return + var/old_size = destination.dna.features["body_size"] + + TRANSFER_RANDOMIZED(destination.dna.blood_type, blood_type, second_set.blood_type) + TRANSFER_RANDOMIZED(destination.dna.skin_tone_override, skin_tone_override, second_set.skin_tone_override) + TRANSFER_RANDOMIZED_LIST(destination.dna.features, features, second_set.features) + TRANSFER_RANDOMIZED(destination.dna.real_name, real_name, second_set.real_name) + TRANSFER_RANDOMIZED(destination.dna.nameless, nameless, second_set.nameless) + TRANSFER_RANDOMIZED_LIST(destination.dna.temporary_mutations, temporary_mutations, second_set.temporary_mutations) + + if(prob(50)) + destination.set_species(species.type, icon_update=0) + destination.dna.species.say_mod = species.say_mod + destination.dna.custom_species = custom_species + else + destination.set_species(second_set.species.type, icon_update=0) + destination.dna.species.say_mod = second_set.species.say_mod + destination.dna.custom_species = second_set.custom_species + + if(ishuman(destination)) + var/mob/living/carbon/human/H = destination + H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA + + destination.update_size(get_size(destination), old_size) + + SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, FALSE) + SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, second_set, FALSE) + +#undef TRANSFER_RANDOMIZED +#undef TRANSFER_RANDOMIZED_LIST + /datum/dna/proc/copy_dna(datum/dna/new_dna) new_dna.unique_enzymes = unique_enzymes new_dna.mutation_index = mutation_index diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4077f86e52..343d7171b3 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1099,6 +1099,7 @@ /atom/Entered(atom/movable/AM, atom/oldLoc) SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc) + SEND_SIGNAL(AM, COMSIG_ATOM_ENTERING, src, oldLoc) /atom/Exit(atom/movable/AM, atom/newLoc) . = ..() diff --git a/code/modules/arousal/organs/vagina.dm b/code/modules/arousal/organs/vagina.dm index 58661bd3ec..5dea3fec00 100644 --- a/code/modules/arousal/organs/vagina.dm +++ b/code/modules/arousal/organs/vagina.dm @@ -74,3 +74,6 @@ color = "[D.features["vag_color"]]" shape = "[D.features["vag_shape"]]" toggle_visibility(D.features["vag_visibility"], FALSE) + +/obj/item/organ/genital/vagina/on_life() + for(var/obj/item/reagent_containers/food/snacks/egg/oviposition/egg in src.contents) diff --git a/modular_eros/code/game/objects/items/oviposition.dm b/modular_eros/code/game/objects/items/oviposition.dm index f2a4cadf02..f0e84e8f90 100644 --- a/modular_eros/code/game/objects/items/oviposition.dm +++ b/modular_eros/code/game/objects/items/oviposition.dm @@ -1,59 +1,2 @@ /obj/item/reagent_containers/food/snacks/egg/oviposition - var/baby_type = /mob/living/carbon/human - var/datum/dna/father_dna - var/datum/dna/mother_dna - - var/stage = -1 - var/max_stage = 2 - COOLDOWN_DECLARE(stage_time) - -/obj/item/reagent_containers/food/snacks/egg/oviposition/Initialize(datum/component/pregnancy/comp) - . = ..() - if(comp) - inherit_pregnancy(comp) - START_PROCESSING(SSobj, src) - -/obj/item/reagent_containers/food/snacks/egg/oviposition/process() - if(stage >= max_stage && prob(30)) - src.visible_message(span_warning("The egg starts hatching!")) - hatch() - - if(COOLDOWN_FINISHED(src, stage_time)) - COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) - stage += 1 - stage = min(stage, max_stage) - - -/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/inherit_pregnancy(datum/component/pregnancy/comp) - if(comp.father_dna) - comp.father_dna.copy_dna(father_dna) - - if(iscarbon(comp.parent)) - var/mob/living/carbon/momma = comp.parent - momma.dna.copy_dna(mother_dna) - - baby_type = comp.baby_type - -/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/hatch() - var/mob/living/babby = new baby_type(src) - if(ishuman(babby)) - determine_baby_dna(babby) - sleep(10) - babby.forceMove(get_turf(src)) - qdel(src) - -/obj/item/reagent_containers/food/snacks/egg/oviposition/proc/determine_baby_dna(mob/living/carbon/human/babby) - if(mother_dna && father_dna) - if(prob(50)) - mother_dna.transfer_identity(babby) - else - father_dna.transfer_identity(babby) - else if(mother_dna && !father_dna) - mother_dna.transfer_identity(babby) - else if(!mother_dna && father_dna) - father_dna.transfer_identity(babby) - else - var/datum/dna/rando = new - rando.initialize_dna(random_blood_type()) - rando.transfer_identity(babby) diff --git a/modular_sand/code/datums/interactions/interaction_interface.dm b/modular_sand/code/datums/interactions/interaction_interface.dm index 8b26b6c087..6579e4518e 100644 --- a/modular_sand/code/datums/interactions/interaction_interface.dm +++ b/modular_sand/code/datums/interactions/interaction_interface.dm @@ -117,6 +117,40 @@ genitals += list(simulated_ass) .["genitals"] = genitals + //Get their genitals + var/list/genital_fluids = list() + var/mob/living/carbon/target_genitals = target || self + if(istype(target_genitals)) + for(var/obj/item/organ/genital/genital in target_genitals.internal_organs) + if(!(CHECK_BITFIELD(genital.genital_flags, GENITAL_FUID_PRODUCTION))) + continue + var/fluids = genital?.reagents ? \ + (genital.reagents.total_volume / genital.reagents.maximum_volume) : null + if(!fluids) + continue + var/list/genital_entry = list() + genital_entry["name"] = "[genital.name]" + genital_entry["key"] = REF(genital) + genital_entry["fluid"] = fluids + genital_fluids += list(genital_entry) + .["genital_fluids"] = genital_fluids + + var/list/genital_interactibles = list() + if(istype(target_genitals)) + for(var/obj/item/organ/genital/genital in target_genitals.internal_organs) + if(CHECK_BITFIELD(genital.genital_flags, GENITAL_INTERNAL)) //Not those though + continue + var/list/equipment_names = list() + for(var/obj/equipment in genital.contents) + equipment_names += equipment.name + var/list/genital_entry = list() + genital_entry["name"] = "[genital.name]" + genital_entry["key"] = REF(genital) + genital_entry["possible_choices"] = GLOB.genitals_interactions + genital_entry["equipments"] = equipment_names + genital_interactibles += list(genital_entry) + .["genital_interactibles"] = genital_interactibles + var/datum/preferences/prefs = usr?.client.prefs if(prefs) //Getting char prefs @@ -180,6 +214,21 @@ return TRUE else return FALSE + if("genital_interaction") + var/mob/living/carbon/actual_target = target || usr + var/mob/user = usr + var/obj/item/organ/genital/genital = locate(params["genital"], actual_target.internal_organs) + if(!(genital && (genital in actual_target.internal_organs))) + return FALSE + switch(params["action"]) + if(GEN_INSERT_EQUIPMENT) + var/obj/item/stuff = user.get_active_held_item() + if(!istype(stuff)) + to_chat(user, span_warning("You need to hold an item to insert it!")) + return FALSE + stuff.insert_item_organ(user, target, genital) + if(GEN_REMOVE_EQUIPMENT) + if("char_pref") var/datum/preferences/prefs = usr.client.prefs var/value = num_to_pref(params["value"]) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 1970390a2a..254602e951 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -1,13 +1,16 @@ /datum/component/pregnancy dupe_mode = COMPONENT_DUPE_UNIQUE + can_transfer = TRUE /// type of baby the mother will plop out - needs to be subtype of /mob/living var/baby_type = /mob/living/carbon/human var/obj/item/organ/container + var/mob/living/carrier var/datum/dna/father_dna + var/datum/dna/mother_dna var/stage = 0 var/max_stage = PREGNANCY_STAGES @@ -22,12 +25,14 @@ /// whether the pregnancy is revealed or not, scanners will reveal this no matter what var/revealed = FALSE -/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ, _oviposition, _pregnancy_inflation) +/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE - var/mob/living/preggo = parent - if(preggo.stat >= DEAD) + var/mob/living/gregnant = parent + + //don't fuck dead bodies, pretty please + if(gregnant.stat >= DEAD) return COMPONENT_INCOMPATIBLE if(ispath(_baby_type, /mob/living)) @@ -37,48 +42,83 @@ return COMPONENT_INCOMPATIBLE if(iscarbon(_father)) - var/mob/living/carbon/carbo = _father + var/mob/living/carbon/cardad = _father father_dna = new - carbo.dna.copy_dna(father_dna) + cardad.dna.copy_dna(father_dna) - oviposition = oviposition - pregnancy_inflation = _pregnancy_inflation + if(iscarbon(parent)) + var/mob/living/carbon/carmom = parent + mother_dna = new + carmom.dna.copy_dna(mother_dna) + + oviposition = gregnant.client?.prefs?.oviposition + pregnancy_inflation = gregnant.client?.prefs?.pregnancy_inflation if(container_organ) container = container_organ + carrier = parent + if(ishuman(parent)) human_pragency_start(parent) - ADD_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) /datum/component/pregnancy/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/fetus_mortus) - RegisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) - RegisterSignal(parent, COMSIG_HEALTH_SCAN, .proc/on_scan) - RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, .proc/handle_damage) + RegisterSignal(carrier, COMSIG_MOB_DEATH, .proc/fetus_mortus) + RegisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) + RegisterSignal(carrier, COMSIG_HEALTH_SCAN, .proc/on_scan) + RegisterSignal(carrier, COMSIG_MOB_APPLY_DAMAGE, .proc/handle_damage) if(container) RegisterSignal(container, COMSIG_ORGAN_REMOVED, .proc/fetus_mortus) - /datum/component/pregnancy/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, COMSIG_MOB_DEATH) - UnregisterSignal(parent, COMSIG_LIVING_BIOLOGICAL_LIFE) - UnregisterSignal(parent, COMSIG_HEALTH_SCAN) - UnregisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE) + UnregisterSignal(carrier, COMSIG_MOB_DEATH) + UnregisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE) + UnregisterSignal(carrier, COMSIG_HEALTH_SCAN) + UnregisterSignal(carrier, COMSIG_MOB_APPLY_DAMAGE) if(container) UnregisterSignal(container, COMSIG_ORGAN_REMOVED) /datum/component/pregnancy/Destroy() - REMOVE_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) - var/mob/living/preggo = parent - preggo.remove_status_effect(/datum/status_effect/pregnancy) - if(ishuman(parent)) - human_pragency_end(parent) + if(carrier) + generic_pragency_end() return ..() +/datum/component/pregnancy/PreTransfer() + if(carrier) + generic_pragency_end() + UnregisterFromParent() + UnregisterSignal(parent, COMSIG_ATOM_ENTERING) + oviposition = FALSE + carrier = null + container = null + +/datum/component/pregnancy/PostTransfer() + if(isliving(parent)) + carrier = parent + RegisterWithParent() + else + RegisterSignal(parent, COMSIG_ATOM_ENTERING, .proc/on_entering) + +/datum/component/pregnancy/proc/on_entering(datum/source, atom/destination, atom/oldLoc) + SIGNAL_HANDLER + + if(istype(source, /obj/item/organ)) + var/obj/item/organ/preg_container = source + //severed wombs don't count, boyos + if(!preg_container.owner) + return + carrier = preg_container.owner + container = preg_container + pregnancy_inflation = carrier.client?.prefs?.pregnancy_inflation + RegisterWithParent() + generic_pragency_start() + else + generic_pragency_end() + UnregisterFromParent() + carrier = null + container = null + /datum/component/pregnancy/proc/handle_life(seconds) SIGNAL_HANDLER @@ -92,8 +132,7 @@ if((stage > (max_stage / 2)) && !revealed) revealed = TRUE - var/mob/living/preggo = parent - preggo.apply_status_effect(/datum/status_effect/pregnancy) + carrier.apply_status_effect(/datum/status_effect/pregnancy) if(COOLDOWN_FINISHED(src, stage_time)) COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) @@ -115,21 +154,19 @@ belly.update() /datum/component/pregnancy/proc/handle_preg() - var/mob/living/preggo = parent - if(prob(10)) switch(stage) if(2) - to_chat(preggo, span_warning("You can feel your belly getting bigger!")) + to_chat(carrier, span_warning("You can feel your belly getting bigger!")) if(3) if(prob(50)) - to_chat(preggo, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) + to_chat(carrier, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) else - to_chat(preggo, span_warning("The kicking is quite intense now!")) - preggo.adjustStaminaLoss(20) + to_chat(carrier, span_warning("The kicking is quite intense now!")) + carrier.adjustStaminaLoss(20) if(4) - to_chat(preggo, span_warning("You feel like you're going into labor very soon! Get ready to give birth!")) - preggo.adjustStaminaLoss(50) + to_chat(carrier, span_warning("You feel like you're going into labor very soon! Get ready to give birth!")) + carrier.adjustStaminaLoss(50) if(prob(60)) return @@ -137,68 +174,63 @@ return if(prob(50)) - to_chat(preggo, span_warning("You're going into labor right now!")) - preggo.adjustStaminaLoss(30) + to_chat(carrier, span_warning("You're going into labor right now!")) + carrier.adjustStaminaLoss(30) else - to_chat(preggo, span_userdanger("It hurts! The baby is coming out!")) - preggo.adjustStaminaLoss(50) - preggo.emote("scream") - preggo.adjustStaminaLoss(5) + to_chat(carrier, span_userdanger("It hurts! The baby is coming out!")) + carrier.adjustStaminaLoss(50) + carrier.emote("scream") + carrier.adjustStaminaLoss(5) var/can_birth = TRUE - if(ishuman(preggo)) - var/mob/living/carbon/human/human_owner = preggo + if(ishuman(carrier)) + var/mob/living/carbon/human/human_owner = carrier var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) if(LAZYLEN(human_owner.clothingonpart(chest))) can_birth = FALSE if(can_birth) - playsound(preggo, 'sound/effects/splat.ogg', 70, TRUE) - to_chat(preggo, span_nicegreen("The baby came out!")) - preggo.Knockdown(200, TRUE, TRUE) - preggo.Stun(200, TRUE, TRUE) - var/mob/living/babby = new baby_type(get_turf(preggo)) + playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) + to_chat(carrier, span_nicegreen("The baby came out!")) + carrier.Knockdown(200, TRUE, TRUE) + carrier.Stun(200, TRUE, TRUE) + var/mob/living/babby = new baby_type(get_turf(carrier)) if(ishuman(babby)) determine_baby_dna(babby) - INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, preggo) + INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, carrier) qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() - var/mob/living/preggo = parent if(stage < (max_stage / 2)) if(stage == 2 && prob(3)) - to_chat(preggo, span_notice("You feel something pressing lightly inside")) + to_chat(carrier, span_notice("You feel something pressing lightly inside")) return if(prob(50)) - to_chat(preggo, span_warning("Something presses hard against your anus! It's probably your egg!")) - preggo.adjustStaminaLoss(30) + to_chat(carrier, span_warning("Something presses hard against your anus! It's probably your egg!")) + carrier.adjustStaminaLoss(30) else - to_chat(preggo, span_warning("You REALLY need to get this egg out!")) - preggo.adjustStaminaLoss(50) - preggo.emote("scream") + to_chat(carrier, span_warning("You REALLY need to get this egg out!")) + carrier.adjustStaminaLoss(50) + carrier.emote("scream") var/can_oviposit = TRUE - if(ishuman(preggo)) - var/mob/living/carbon/human/human_owner = preggo + if(ishuman(carrier)) + var/mob/living/carbon/human/human_owner = carrier var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) if(LAZYLEN(human_owner.clothingonpart(chest))) can_oviposit = FALSE if(can_oviposit) - playsound(preggo, 'sound/effects/splat.ogg', 70, TRUE) - preggo.Knockdown(200, TRUE, TRUE) - preggo.Stun(200, TRUE, TRUE) - new /obj/item/reagent_containers/food/snacks/egg/oviposition(get_turf(preggo), src) - to_chat(preggo, span_nicegreen("The egg came out!")) - qdel(src) + playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) + carrier.Knockdown(200, TRUE, TRUE) + carrier.Stun(200, TRUE, TRUE) + var/obj/item/reagent_containers/food/snacks/egg/oviposition/eggo = new(get_turf(carrier)) + to_chat(carrier, span_nicegreen("The egg came out!")) + eggo.TakeComponent(src) //not how genetics work but okay /datum/component/pregnancy/proc/determine_baby_dna(mob/living/carbon/human/babby) var/mob/living/carbon/mommy = parent - var/datum/dna/mother_dna = mommy?.dna if(mother_dna && father_dna) - if(prob(50)) - mother_dna.transfer_identity(babby) - else - father_dna.transfer_identity(babby) + mother_dna.transfer_identity_random(father_dna, babby) else if(mother_dna && !father_dna) mother_dna.transfer_identity(babby) else if(!mother_dna && father_dna) @@ -208,10 +240,18 @@ rando.initialize_dna(random_blood_type()) rando.transfer_identity(babby) +/datum/component/pregnancy/proc/generic_pragency_start() + if(ishuman(carrier)) + human_pragency_start(carrier) + ADD_TRAIT(carrier, TRAIT_PREGNANT, PREGNANCY_TRAIT) + +/datum/component/pregnancy/proc/generic_pragency_end() + REMOVE_TRAIT(carrier, TRAIT_PREGNANT, PREGNANCY_TRAIT) + carrier.remove_status_effect(/datum/status_effect/pregnancy) + if(ishuman(carrier)) + human_pragency_end(carrier) + /datum/component/pregnancy/proc/human_pragency_start(mob/living/carbon/human/gregnant) - if(gregnant.client?.prefs) - oviposition = gregnant.client.prefs.oviposition - pregnancy_inflation = gregnant.client.prefs.pregnancy_inflation if(pregnancy_inflation) //give them a king ass ripper belly initially var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) @@ -233,13 +273,12 @@ /datum/component/pregnancy/proc/fetus_mortus() SIGNAL_HANDLER - var/mob/living/preggo = parent - if(!QDELETED(parent) && get_turf(preggo) && (stage > (max_stage / 2))) + if(!QDELETED(carrier) && get_turf(carrier) && (stage > (max_stage / 2))) if(!oviposition) - new /obj/effect/gibspawner/generic(get_turf(preggo)) + new /obj/effect/gibspawner/generic(get_turf(carrier)) else - new /obj/effect/decal/cleanable/egg_smudge(get_turf(preggo)) - preggo.visible_message(span_danger("[parent] has a miscarriage!"), \ + new /obj/effect/decal/cleanable/egg_smudge(get_turf(carrier)) + carrier.visible_message(span_danger("[carrier] has a miscarriage!"), \ span_userdanger("Oh no! My baby is dead!")) qdel(src) diff --git a/modular_splurt/code/game/object/items.dm b/modular_splurt/code/game/object/items.dm new file mode 100644 index 0000000000..cd1c2afd90 --- /dev/null +++ b/modular_splurt/code/game/object/items.dm @@ -0,0 +1,124 @@ +/obj/item/proc/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + to_chat(user, span_warning("You can't insert this item!")) + return + + /* + if(locate(src.type) in target_organ.contents) + to_chat(user, span_warning("You can't insert more of this item!")) + return + + user.visible_message(span_warning("\The [user] is trying to put [src] inside [target]'s [target_organ]"), \ + span_warning("\The [user] is trying to put [src] inside [target]'s [target_organ]")) + + if(!do_mob(user, target, 4 SECONDS)) + return + + if(!user.transferitemtoloc(src, target_organ)) + return + */ + +/obj/item/genital_equipment/condom/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!unwrapped) + to_chat(user, span_notice("You must remove the condom from the package first!")) + return + + var/obj/item/organ/genital/penis/ween = target_organ + if(!istype(ween)) + to_chat(user, span_notice("You can't put the condom on this genital!")) + return + + if(!target.has_penis(REQUIRE_EXPOSED)) + to_chat(user, span_notice("You can't find anywhere to put the condom!")) + return + + if(locate(src.type) in target_organ.contents) + to_chat(user, span_notice("\The [target] is already wearing a condom!")) + return + + target.visible_message(span_warning("\The [user] is trying to put a condom on \the [target]!"),\ + span_warning("\The [user] is trying to put a condom on you!")) + + if(!do_mob(user, target, 4 SECONDS)) + return + + if(!user.transferItemToLoc(src, target_organ)) + return + + playsound(target, 'modular_sand/sound/lewd/latex.ogg', 50, 1, -1) + to_chat(target, span_userlove("Your penis feels more safe!")) + +/obj/item/genital_equipment/sounding/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!unwrapped) + to_chat(user, span_notice("You must remove the rod from the package first!")) + return + + var/obj/item/organ/genital/penis/ween = target_organ + if(!istype(ween)) + to_chat(user, span_notice("You can't put the rod inside this genital!")) + return + + if(!target.has_penis(REQUIRE_EXPOSED)) + to_chat(user, span_notice("You can't find anywhere to put the rod!")) + return + + if(locate(src.type) in target_organ.contents) + to_chat(user, span_notice("\The [target]'s [target_organ] already has a rod inside!")) + return + + target.visible_message(span_warning("\The [user] is trying to insert a rod inside \the [target]!"),\ + span_warning("\The [user] is trying to insert a rod inside you!")) + + if(!do_mob(user, target, 4 SECONDS)) + return + + if(!user.transferItemToLoc(src, target_organ)) + return + + playsound(target, 'modular_sand/sound/lewd/champ_fingering.ogg', 50, 1, -1) + to_chat(target, span_userlove("Your penis feels stuffed and stretched!")) + owner = target + +/obj/item/electropack/vibrator/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(style == "long" && !(istype(target_organ, /obj/item/organ/genital/vagina))) //long vibrators dont fit on anything but vaginas, but small ones fit everywhere + to_chat(user, "[src] is too big to fit there, use a smaller version.") + return + + if(locate(src.type) in target_organ.contents) + to_chat(user, span_notice("\The [target]'s [target_organ] already has a vibrator inside!")) + return + + if(style == "long") + target.visible_message(span_warning("\The [user] is trying to insert a vibrator inside \the [target]!"),\ + span_warning("\The [user] is trying to insert a vibrator inside you!")) + else + target.visible_message(span_userlove("\The [user] is trying to attach a vibrator to \the [target]!"),\ + span_warning("\The [user] is trying to attach a vibrator to you!")) + + if(!do_mob(user, target, 5 SECONDS)) + return + + if(!user.transferItemToLoc(src, target_organ)) + return + + if(style == "long") + to_chat(user, span_userlove("You attach [src] to \The [target]'s [target_organ].")) + else + to_chat(user, span_userlove("You attach [src] to \The [target]'s [target_organ].")) + + playsound(target, 'modular_sand/sound/lewd/champ_fingering.ogg', 50, 1, -1) + inside = TRUE + + +/obj/item/reagent_containers/food/snacks/egg/oviposition/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + target.visible_message(span_warning("\The [user] is trying to insert an egg inside \the [target]!"),\ + span_warning("\The [user] is trying to insert an egg inside you!")) + + if(!do_mob(user, target, 5 SECONDS)) + return + + if(!user.transferItemToLoc(src, target_organ)) + return + + to_chat(target, span_userlove("Your [target_organ] feels stuffed and stretched!")) + + playsound(target, 'modular_sand/sound/lewd/champ_fingering.ogg', 50, 1, -1) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index 752524adcc..44dbc22d3a 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -26,7 +26,7 @@ var/can_get_pregnant = (client?.prefs?.fertility && !is_type_in_typecache(src.type, GLOB.pregnancy_blocked_mob_typecache)) if(can_impregnate && can_get_pregnant) - AddComponent(/datum/component/pregnancy, partner, baby_type, W, client?.prefs?.oviposition, client?.prefs?.pregnancy_inflation) + AddComponent(/datum/component/pregnancy, partner, baby_type, W) /mob/living/carbon/human/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill, cover = FALSE) if(!G) diff --git a/tgstation.dme b/tgstation.dme index 305aa7b235..a0b1737a78 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4294,6 +4294,7 @@ #include "modular_splurt\code\game\machinery\doors\shutters.dm" #include "modular_splurt\code\game\machinery\porta_turret\portable_turret.dm" #include "modular_splurt\code\game\mecha\combat\gygax.dm" +#include "modular_splurt\code\game\object\items.dm" #include "modular_splurt\code\game\object\effects\landmarks.dm" #include "modular_splurt\code\game\object\items\cards_ids.dm" #include "modular_splurt\code\game\object\items\cosmetics.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction.tsx b/tgui/packages/tgui/interfaces/MobInteraction.tsx index ca7146740b..b8d35b2658 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction.tsx @@ -2,7 +2,7 @@ import { filter, map, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { createSearch } from 'common/string'; import { useBackend, useLocalState } from '../backend'; -import { BlockQuote, Button, Flex, LabeledList, Icon, Input, Section, Table, Tabs, Stack } from '../components'; +import { BlockQuote, Button, LabeledList, Icon, Input, Section, Table, Tabs, Stack, ProgressBar, Divider } from '../components'; import { Window } from '../layouts'; type HeaderInfo = { @@ -33,6 +33,25 @@ type GenitalData = { possible_choices: string[], } +type GenitalManagerInfo = { + isTargetSelf: boolean; + genital_fluids: GenitalFluid[]; + genital_interactibles: GenitalInteractionInfos[]; +} + +type GenitalInteractionInfos = { + name: string, + key: string, + possible_choices: string[], + equipments: string[], +} + +type GenitalFluid = { + name: string, + key: string, + fluids: number, +} + type CharacterPrefsInfo = { erp_pref: number, noncon_pref: number, @@ -78,7 +97,7 @@ export const MobInteraction = (props, context) => { return ( @@ -122,6 +141,9 @@ export const MobInteraction = (props, context) => { setTabIndex(3)}> Preferences + setTabIndex(4)}> + Genital Manager + {tabIndex === 0 && ( @@ -131,6 +153,8 @@ export const MobInteraction = (props, context) => { ) || tabIndex === 3 && ( + ) || tabIndex === 4 && ( + ) || ("Somehow, you've got into an invalid page, please report this.")} @@ -220,7 +244,7 @@ const GenitalVisibilityTab = (props, context) => { const genitals = data.genitals || []; return ( genitals.length ? ( - + {genitals.map(genital => ( @@ -238,7 +262,7 @@ const GenitalVisibilityTab = (props, context) => { ))} - + ) : (
You don't seem to have any genitals... @@ -248,6 +272,75 @@ const GenitalVisibilityTab = (props, context) => { ); }; +const GenitalManagerTab = (props, context) => { + const { act, data } = useBackend(context); + const isTargetSelf = data.isTargetSelf; + const genital_fluids = data.genital_fluids || []; + const genital_interactibles = data.genital_interactibles || []; + return ( + genital_fluids.length || genital_interactibles.length ? ( + <> + + Genital fluids + + + {genital_fluids.map(genital => ( + + + + ))} + + + + Actions + + + {genital_interactibles.map(genital => ( + <> + { + genital.equipments.length ? ( + <> + Equipments: + + {genital.equipments.map(equipment => ( + equipment + ))} + + + ) : null + } + + {genital.possible_choices.map(choice => ( +
+
+ {genital_interactibles.map(genital => ( +
+ { + genital.equipments.length ? ( + <> + Equipments: + + {genital.equipments.map(equipment => ( + + {equipment} + + ))} +
+ + + ) : null + } + + {genital.possible_choices.map(choice => ( +
+ ))} +
) : (
From 203f21c3d6a16d2fd7a2d7ca8e4459082a3aa35f Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 18:11:35 +1000 Subject: [PATCH 14/72] things --- .../interactions/interaction_interface.dm | 2 +- .../code/datums/components/pregnancy.dm | 35 +++++++++++++++---- .../code/game/object/items/oviposition.dm | 3 +- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/modular_sand/code/datums/interactions/interaction_interface.dm b/modular_sand/code/datums/interactions/interaction_interface.dm index 050fadeff0..cdaa8ffe52 100644 --- a/modular_sand/code/datums/interactions/interaction_interface.dm +++ b/modular_sand/code/datums/interactions/interaction_interface.dm @@ -138,7 +138,7 @@ var/list/genital_interactibles = list() if(istype(target_genitals)) for(var/obj/item/organ/genital/genital in target_genitals.internal_organs) - if(CHECK_BITFIELD(genital.genital_flags, GENITAL_INTERNAL)) //Not those though + if(!genital.is_exposed()) continue var/list/equipment_names = list() for(var/obj/equipment in genital.contents) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 582ac24162..f593819893 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -64,6 +64,20 @@ ADD_TRAIT(parent, TRAIT_PREGNANT, PREGNANCY_TRAIT) /datum/component/pregnancy/RegisterWithParent() + if(carrier) + register_carrier() + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ATOM_ENTERING, .proc/on_entering) + RegisterSignal(parent, COMSIG_OBJ_BREAK, .proc/on_obj_break) + +/datum/component/pregnancy/UnregisterFromParent() + if(carrier) + unregister_carrier() + UnregisterSignal(parent, COMSIG_ATOM_ENTERING) + UnregisterSignal(parent, COMSIG_OBJ_BREAK) + + +/datum/component/pregnancy/proc/register_carrier() RegisterSignal(carrier, COMSIG_MOB_DEATH, .proc/fetus_mortus) RegisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) RegisterSignal(carrier, COMSIG_HEALTH_SCAN, .proc/on_scan) @@ -71,7 +85,7 @@ if(container) RegisterSignal(container, COMSIG_ORGAN_REMOVED, .proc/fetus_mortus) -/datum/component/pregnancy/UnregisterFromParent() +/datum/component/pregnancy/proc/unregister_carrier() UnregisterSignal(carrier, COMSIG_MOB_DEATH) UnregisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE) UnregisterSignal(carrier, COMSIG_HEALTH_SCAN) @@ -87,8 +101,7 @@ /datum/component/pregnancy/PreTransfer() if(carrier) generic_pragency_end() - UnregisterFromParent() - UnregisterSignal(parent, COMSIG_ATOM_ENTERING) + UnregisterFromParent() oviposition = FALSE carrier = null container = null @@ -97,8 +110,15 @@ if(isliving(parent)) carrier = parent RegisterWithParent() + else if(isitem(parent)) + RegisterWithParent() else - RegisterSignal(parent, COMSIG_ATOM_ENTERING, .proc/on_entering) + return COMPONENT_INCOMPATIBLE + +/datum/component/pregnancy/proc/on_obj_break(datum/source, damage_flag) + SIGNAL_HANDLER + + qdel(src) /datum/component/pregnancy/proc/on_entering(datum/source, atom/destination, atom/oldLoc) SIGNAL_HANDLER @@ -113,7 +133,7 @@ pregnancy_inflation = carrier.client?.prefs?.pregnancy_inflation RegisterWithParent() generic_pragency_start() - else + else if(carrier) generic_pragency_end() UnregisterFromParent() carrier = null @@ -222,7 +242,7 @@ playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) carrier.Knockdown(200, TRUE, TRUE) carrier.Stun(200, TRUE, TRUE) - var/obj/item/reagent_containers/food/snacks/egg/oviposition/eggo = new(get_turf(carrier)) + var/obj/item/oviposition_egg/eggo = new(get_turf(carrier)) to_chat(carrier, span_nicegreen("The egg came out!")) eggo.TakeComponent(src) @@ -284,7 +304,8 @@ /datum/component/pregnancy/proc/on_scan(datum/source, mob/user) SIGNAL_HANDLER - to_chat(user, span_notice("Pregnancy detected!")) + if(isliving(parent)) + to_chat(user, span_notice("Pregnancy detected!")) //drop kicked /datum/component/pregnancy/proc/handle_damage(datum/source, damage, damagetype, def_zone) diff --git a/modular_splurt/code/game/object/items/oviposition.dm b/modular_splurt/code/game/object/items/oviposition.dm index dc0e3487e1..c658505f29 100644 --- a/modular_splurt/code/game/object/items/oviposition.dm +++ b/modular_splurt/code/game/object/items/oviposition.dm @@ -1 +1,2 @@ -/obj/item/reagent_containers/food/snacks/egg/oviposition +/obj/item/oviposition_egg + integrity_failure = 0.9 From 41b591a382a3a4326f5c1d1cb0b2f381a2606ca1 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 18:17:32 +1000 Subject: [PATCH 15/72] item --- modular_splurt/code/datums/components/pregnancy.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index f593819893..99b2b6c2f0 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -217,6 +217,10 @@ if(ishuman(babby)) determine_baby_dna(babby) INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, carrier) + if(isitem(parent)) + var/obj/item = parent + item.obj_break(MELEE) + item.forceMove(get_turf(carrier)) qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() From 280214e53a5922f7d9fb5d7e428589a06f81f17f Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 18:20:45 +1000 Subject: [PATCH 16/72] this --- modular_splurt/code/datums/components/pregnancy.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 99b2b6c2f0..181731e125 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -219,9 +219,10 @@ INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, carrier) if(isitem(parent)) var/obj/item = parent - item.obj_break(MELEE) item.forceMove(get_turf(carrier)) - qdel(src) + item.obj_break(MELEE) + else + qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() if(stage < (max_stage / 2)) From 54df75d76f131e973ef48d74b159eb3d189a2ef4 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 18:23:48 +1000 Subject: [PATCH 17/72] give it icons --- modular_splurt/code/game/object/items/oviposition.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modular_splurt/code/game/object/items/oviposition.dm b/modular_splurt/code/game/object/items/oviposition.dm index c658505f29..a6f5df3bec 100644 --- a/modular_splurt/code/game/object/items/oviposition.dm +++ b/modular_splurt/code/game/object/items/oviposition.dm @@ -1,2 +1,6 @@ /obj/item/oviposition_egg + name = "egg" + desc = "An egg, this one looks suspiciously large though." + icon_state = "egg" + icon = 'icons/obj/food/food.dmi' integrity_failure = 0.9 From 96e42080e00a8796c755f4b8c11ab7acb46f6694 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 18:24:16 +1000 Subject: [PATCH 18/72] eg --- modular_splurt/code/game/object/items/oviposition.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modular_splurt/code/game/object/items/oviposition.dm b/modular_splurt/code/game/object/items/oviposition.dm index a6f5df3bec..22fda4441c 100644 --- a/modular_splurt/code/game/object/items/oviposition.dm +++ b/modular_splurt/code/game/object/items/oviposition.dm @@ -4,3 +4,7 @@ icon_state = "egg" icon = 'icons/obj/food/food.dmi' integrity_failure = 0.9 + +/obj/item/oviposition_egg/obj_break(damage_flag) + . = ..() + //implement later From 7f4f83e0823f6e8636d51bf0d6facbc47f108534 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 20:43:09 +1000 Subject: [PATCH 19/72] needed changes --- code/modules/arousal/arousal.dm | 4 +- code/modules/client/preferences.dm | 6 +++ code/modules/client/preferences_savefile.dm | 2 + .../datums/interactions/lewd_definitions.dm | 6 --- .../code/datums/components/pregnancy.dm | 47 ++++++++++--------- modular_splurt/code/game/object/items.dm | 18 ++++++- .../lewd_items/genital_equipment/condom.dm | 33 +++++++++---- .../lewd_items/genital_equipment/sounding.dm | 9 ++-- .../game/object/items/lewd_items/vibrator.dm | 4 +- .../code/modules/arousal/arousal.dm | 8 ++-- .../code/modules/cargo/bounties/assistant.dm | 9 +++- .../code/modules/cargo/exports/lewd.dm | 8 +++- 12 files changed, 103 insertions(+), 51 deletions(-) diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm index 542790b386..3cf0176d48 100644 --- a/code/modules/arousal/arousal.dm +++ b/code/modules/arousal/arousal.dm @@ -73,11 +73,11 @@ var/condomning if(istype(G, /obj/item/organ/genital/penis)) var/obj/item/organ/genital/penis/P = G - condomning = P.equipment[GENITAL_EQUIPEMENT_CONDOM] + condomning = locate(/obj/item/genital_equipment/condom) in P.contents G.generate_fluid(R) log_message("Climaxed using [G] with [target]", LOG_EMOTE) if(condomning) - to_chat(src, "You feel the condom bubble outwards and fill up with your spunk, plopping on the floor") + to_chat(src, "You feel the condom bubble outwards and fill up with your spunk") R.trans_to(condomclimax(), R.total_volume) else if(spill && R.total_volume >= 5) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index af3caa80a0..8670c00f65 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -366,6 +366,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/oviposition = FALSE /// Does john spaceman look like a gluttonous slob if he pregent? var/pregnancy_inflation = FALSE + /// Does john spaceman like being stuffed + var/egg_stuffing = FALSE //SPLURT END /datum/preferences/New(client/C) @@ -847,6 +849,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Pregnancy preferences

" dat += "Can impregnate:[virility ? "Enabled" : "Disabled"]" dat += "Can get pregnant:[fertility ? "Enabled" : "Disabled"]" + dat += "Can be stuffed with eggs:[egg_stuffing ? "Enabled" : "Disabled"]" if(fertility) dat += "Pregnancy type:[oviposition ? "Oviposition" : "Live Birth"]" dat += "Pregnancy inflation:[pregnancy_inflation ? "Enabled" : "Disabled"]" @@ -2061,6 +2064,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("pregnancy_inflation") pregnancy_inflation = !pregnancy_inflation + if("egg_stuffing") + egg_stuffing = !egg_stuffing + //SPLURT EDIT END if("hair") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 1fa1049913..2a63a088d9 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1192,6 +1192,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["fertile"] >> fertility S["oviposition"] >> oviposition S["pregnancy_inflation"] >> pregnancy_inflation + S["egg_stuffing"] >> egg_stuffing //SPLURT EDIT END cit_character_pref_load(S) @@ -1390,6 +1391,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["fertile"], fertility) WRITE_FILE(S["oviposition"], oviposition) WRITE_FILE(S["pregnancy_inflation"], pregnancy_inflation) + WRITE_FILE(S["egg_stuffing"], egg_stuffing) WRITE_FILE(S["headshot"], features["headshot_link"]) //SPLURT EDIT END diff --git a/modular_sand/code/datums/interactions/lewd_definitions.dm b/modular_sand/code/datums/interactions/lewd_definitions.dm index 54f114fb5c..93cc33976d 100644 --- a/modular_sand/code/datums/interactions/lewd_definitions.dm +++ b/modular_sand/code/datums/interactions/lewd_definitions.dm @@ -483,9 +483,6 @@ if(partner_carbon_check) target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) message = "cums in \the [partner]'s pussy." - var/obj/item/organ/genital/penis/peepee = getorganslot(ORGAN_SLOT_PENIS) - if(!peepee.equipment[GENITAL_EQUIPEMENT_CONDOM]) - partner.impregnate(src, partner.getorganslot(ORGAN_SLOT_WOMB), src.type) cumin = TRUE else message = "cums on \the [partner]'s belly." @@ -650,9 +647,6 @@ if(partner_carbon_check) target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA) message = "cums in \the [partner]'s pussy." - var/obj/item/organ/genital/penis/peepee = last_genital - if(!peepee.equipment[GENITAL_EQUIPEMENT_CONDOM]) - partner.impregnate(src, partner.getorganslot(ORGAN_SLOT_WOMB), src.type) cumin = TRUE else message = "cums on \the [partner]'s belly." diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 181731e125..2e6b1741fa 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -25,7 +25,7 @@ /// whether the pregnancy is revealed or not, scanners will reveal this no matter what var/revealed = FALSE -/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type, obj/item/organ/container_organ) +/datum/component/pregnancy/Initialize(mob/living/_father, _baby_type = /mob/living/carbon/human, obj/item/organ/container_organ) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -123,8 +123,8 @@ /datum/component/pregnancy/proc/on_entering(datum/source, atom/destination, atom/oldLoc) SIGNAL_HANDLER - if(istype(source, /obj/item/organ)) - var/obj/item/organ/preg_container = source + if(istype(destination, /obj/item/organ)) + var/obj/item/organ/preg_container = destination //severed wombs don't count, boyos if(!preg_container.owner) return @@ -155,9 +155,9 @@ carrier.apply_status_effect(/datum/status_effect/pregnancy) if(COOLDOWN_FINISHED(src, stage_time)) - COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) stage += 1 stage = min(stage, max_stage) + COOLDOWN_START(src, stage_time, PREGNANCY_STAGE_DURATION) /datum/component/pregnancy/proc/handle_belly_stuff(mob/living/carbon/human/gregnant) if(!(stage > (max_stage / 2))) @@ -183,7 +183,7 @@ to_chat(carrier, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) else to_chat(carrier, span_warning("The kicking is quite intense now!")) - carrier.adjustStaminaLoss(20) + carrier.adjustStaminaLoss(30) if(4) to_chat(carrier, span_warning("You feel like you're going into labor very soon! Get ready to give birth!")) carrier.adjustStaminaLoss(50) @@ -195,12 +195,10 @@ if(prob(50)) to_chat(carrier, span_warning("You're going into labor right now!")) - carrier.adjustStaminaLoss(30) else to_chat(carrier, span_userdanger("It hurts! The baby is coming out!")) - carrier.adjustStaminaLoss(50) - carrier.emote("scream") - carrier.adjustStaminaLoss(5) + + carrier.emote("scream") var/can_birth = TRUE if(ishuman(carrier)) @@ -213,10 +211,11 @@ to_chat(carrier, span_nicegreen("The baby came out!")) carrier.Knockdown(200, TRUE, TRUE) carrier.Stun(200, TRUE, TRUE) + carrier.adjustStaminaLoss(200) var/mob/living/babby = new baby_type(get_turf(carrier)) if(ishuman(babby)) determine_baby_dna(babby) - INVOKE_ASYNC(src, .proc/offer_control_to_babby, babby, carrier) + INVOKE_ASYNC(GLOBAL_PROC, .proc/offer_control_to_babby, babby, carrier) if(isitem(parent)) var/obj/item = parent item.forceMove(get_turf(carrier)) @@ -226,16 +225,16 @@ /datum/component/pregnancy/proc/handle_ovi_preg() if(stage < (max_stage / 2)) - if(stage == 2 && prob(3)) + if(stage == 2 && prob(10)) to_chat(carrier, span_notice("You feel something pressing lightly inside")) return + if(prob(50)) to_chat(carrier, span_warning("Something presses hard against your anus! It's probably your egg!")) - carrier.adjustStaminaLoss(30) else to_chat(carrier, span_warning("You REALLY need to get this egg out!")) - carrier.adjustStaminaLoss(50) - carrier.emote("scream") + + carrier.emote("scream") var/can_oviposit = TRUE if(ishuman(carrier)) @@ -247,6 +246,7 @@ playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) carrier.Knockdown(200, TRUE, TRUE) carrier.Stun(200, TRUE, TRUE) + carrier.adjustStaminaLoss(200) var/obj/item/oviposition_egg/eggo = new(get_turf(carrier)) to_chat(carrier, span_nicegreen("The egg came out!")) eggo.TakeComponent(src) @@ -291,7 +291,7 @@ //get rid of king ass ripper belly var/obj/item/organ/genital/belly/belly = gregnant.getorganslot(ORGAN_SLOT_BELLY) if(belly && pregnancy_inflation) - belly.size = 1 + belly.size = 0 belly.update() /datum/component/pregnancy/proc/fetus_mortus() @@ -319,7 +319,7 @@ if(def_zone == BODY_ZONE_CHEST && damage > 25 && prob(40)) fetus_mortus() -/datum/component/pregnancy/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) +/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) var/poll_message = "Do you want to play as [mommy]'s offspring?" var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) if(!LAZYLEN(candidates)) @@ -328,17 +328,22 @@ return var/mob/player = pick(candidates) + player.transfer_ckey(babby, TRUE) + var/mommy_name = "someone" if(!QDELETED(mommy)) mommy_name = mommy.real_name to_chat(babby, "You are the son (or daughter) of [mommy_name]!") - var/time = world.time - var/name = input(babby, "What will be your name? (You have a minute to decide!)", "Name yourself") as null|text - if(world.time - time >= 1 MINUTES) - to_chat(babby, "You took too long to decide a name and have been given a random name instead.") - if(!name || (world.time - time >= 1 MINUTES)) + + var/name + if(QDELETED(mommy)) + name = input(babby, "What will be your name?", "Name yourself") as null|text + else + name = input(mommy, "What will be your baby's name?", "Name the baby") as null|text + + if(!name) babby.real_name = random_unique_name(babby.gender, FALSE) babby.update_name() else diff --git a/modular_splurt/code/game/object/items.dm b/modular_splurt/code/game/object/items.dm index cd1c2afd90..3e44eb95fa 100644 --- a/modular_splurt/code/game/object/items.dm +++ b/modular_splurt/code/game/object/items.dm @@ -18,6 +18,10 @@ */ /obj/item/genital_equipment/condom/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!(target.client?.prefs?.erppref == "Yes")) + to_chat(user, span_warning("They don't want you to do that!")) + return + if(!unwrapped) to_chat(user, span_notice("You must remove the condom from the package first!")) return @@ -48,6 +52,10 @@ to_chat(target, span_userlove("Your penis feels more safe!")) /obj/item/genital_equipment/sounding/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!(target.client?.prefs?.erppref == "Yes")) + to_chat(user, span_warning("They don't want you to do that!")) + return + if(!unwrapped) to_chat(user, span_notice("You must remove the rod from the package first!")) return @@ -79,6 +87,10 @@ owner = target /obj/item/electropack/vibrator/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!(target.client?.prefs?.erppref == "Yes")) + to_chat(user, span_warning("They don't want you to do that!")) + return + if(style == "long" && !(istype(target_organ, /obj/item/organ/genital/vagina))) //long vibrators dont fit on anything but vaginas, but small ones fit everywhere to_chat(user, "[src] is too big to fit there, use a smaller version.") return @@ -109,7 +121,11 @@ inside = TRUE -/obj/item/reagent_containers/food/snacks/egg/oviposition/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) +/obj/item/oviposition_egg/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) + if(!target.client?.prefs?.egg_stuffing) + to_chat(user, span_warning("They don't want you to do that!")) + return + target.visible_message(span_warning("\The [user] is trying to insert an egg inside \the [target]!"),\ span_warning("\The [user] is trying to insert an egg inside you!")) diff --git a/modular_splurt/code/game/object/items/lewd_items/genital_equipment/condom.dm b/modular_splurt/code/game/object/items/lewd_items/genital_equipment/condom.dm index 77ae20ee86..f33c5cd052 100644 --- a/modular_splurt/code/game/object/items/lewd_items/genital_equipment/condom.dm +++ b/modular_splurt/code/game/object/items/lewd_items/genital_equipment/condom.dm @@ -7,7 +7,6 @@ icon = 'modular_splurt/icons/obj/condom.dmi' throwforce = 0 icon_state = "b_condom_wrapped" - equipment_slot = GENITAL_EQUIPEMENT_CONDOM var/unwrapped = 0 w_class = WEIGHT_CLASS_TINY @@ -27,6 +26,9 @@ icon_state = "b_condom_inflated_huge" ..() +/obj/item/genital_equipment/condom/on_reagent_change() + update_icon() + /obj/item/genital_equipment/condom/attack_self(mob/user) //Unwrap The Condom in hands if(!istype(user)) return @@ -37,13 +39,26 @@ to_chat(user, "You unwrap the condom.") playsound(user, 'sound/items/poster_ripped.ogg', 50, 1, -1) return + +/obj/item/genital_equipment/condom/throw_impact(atom/hit_atom) + . = ..() + if(!.) //if we're not being caught + splat(hit_atom) + +/obj/item/genital_equipment/condom/proc/splat(atom/movable/hit_atom) + if(isliving(loc)) + return + var/turf/T = get_turf(hit_atom) + new/obj/effect/decal/cleanable/semen(T) + playsound(T, 'sound/misc/splort.ogg', 50, TRUE) + qdel(src) // if(unwrapped == 1) // new /obj/item/clothing/head/condom(usr.loc) // qdel(src) // to_chat(user, "You roll the condom out.") // playsound(user, 'sound/lewd/latex.ogg', 50, 1, -1) // return - +/* /obj/item/genital_equipment/condom/attack(mob/living/carbon/C, mob/living/user) //apply the johnny on another person or yourself if(unwrapped == 0 ) @@ -73,6 +88,7 @@ return to_chat(user, "You can't find anywhere to put the condom on.") //Trying to put it on something without/or with a hidden +*/ /obj/item/clothing/head/condom //p name = "condom" @@ -93,7 +109,7 @@ /*P.colourtint = "" update_genitals()*/ */ - +/* /obj/item/genital_equipment/condom/filled name = "filled condom" icon_state = "b_condom_inflated" @@ -112,7 +128,8 @@ new/obj/effect/decal/cleanable/semen(T) playsound(T, 'sound/misc/splort.ogg', 50, TRUE) qdel(src) - +*/ +/* /obj/item/genital_equipment/condom/genital_remove_proccess(obj/item/organ/genital/G) if(!G.equipment[GENITAL_EQUIPEMENT_CONDOM]) return @@ -121,12 +138,12 @@ . = ..() qdel(src) +*/ + /mob/living/carbon/human/proc/condomclimax() - var/obj/item/genital_equipment/condom/filled/C = new var/obj/item/organ/genital/penis/P = getorganslot(ORGAN_SLOT_PENIS) - P.equipment.Remove(GENITAL_EQUIPEMENT_CONDOM) - C.loc = loc - return C + var/obj/item/genital_equipment/condom/condo = locate(/obj/item/genital_equipment/condom) in P.contents + return condo /* var/obj/item/genital_equipment/condom/filled/C = new diff --git a/modular_splurt/code/game/object/items/lewd_items/genital_equipment/sounding.dm b/modular_splurt/code/game/object/items/lewd_items/genital_equipment/sounding.dm index c57f00996e..d3aa33c6a9 100644 --- a/modular_splurt/code/game/object/items/lewd_items/genital_equipment/sounding.dm +++ b/modular_splurt/code/game/object/items/lewd_items/genital_equipment/sounding.dm @@ -5,7 +5,7 @@ throwforce = 0 icon_state = "sounding_wrapped" var/unwrapped = 0 - equipment_slot = GENITAL_EQUIPMENT_SOUNDING +// equipment_slot = GENITAL_EQUIPMENT_SOUNDING w_class = WEIGHT_CLASS_TINY /obj/item/genital_equipment/sounding/attack_self(mob/user) @@ -18,7 +18,7 @@ to_chat(user, "You unwrap the rod.") playsound(user, 'sound/items/poster_ripped.ogg', 50, 1, -1) return - +/* /obj/item/genital_equipment/sounding/attack(mob/living/carbon/C, mob/living/user) if(unwrapped == 0 ) @@ -53,7 +53,6 @@ . = ..() qdel(src) -/* /mob/living/carbon/human/proc/removesounding() var/obj/item/organ/genital/penis/P = getorganslot("penis") @@ -61,13 +60,13 @@ P.equipment.Remove(GENITAL_EQUIPMENT_SOUNDING) new /obj/item/genital_equipment/sounding/used_sounding(loc) to_chat(src, "The rod falls off from your penis.") -*/ + /obj/item/genital_equipment/sounding/used_sounding name = "sounding rod" icon_state = "sounding_rod" unwrapped = 2 w_class = WEIGHT_CLASS_TINY -/* + /mob/living/carbon/human/proc/soundingclimax() var/obj/item/organ/genital/penis/P = src.getorganslot("penis") diff --git a/modular_splurt/code/game/object/items/lewd_items/vibrator.dm b/modular_splurt/code/game/object/items/lewd_items/vibrator.dm index 6ef05c7dec..6d8a813c00 100644 --- a/modular_splurt/code/game/object/items/lewd_items/vibrator.dm +++ b/modular_splurt/code/game/object/items/lewd_items/vibrator.dm @@ -9,7 +9,6 @@ item_state = "vibe" w_class = WEIGHT_CLASS_SMALL //slot_flags = ITEM_SLOT_DENYPOCKET //no more pocket shockers - var/equipment_slot = GENITAL_EQUIPMENT_VIBRATOR var/mode = 1 var/style = "long" var/inside = FALSE @@ -59,7 +58,7 @@ Code: mode = 1 to_chat(user, "You twist the bottom of [src], setting it to the low setting.") return - +/* /obj/item/electropack/vibrator/attack(mob/living/carbon/C, mob/living/user) var/obj/item/organ/genital/picked_organ @@ -94,6 +93,7 @@ Code: else to_chat(user, "You don't see anywhere to attach this.") +*/ /obj/item/electropack/vibrator/receive_signal(datum/signal/signal) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index 44dbc22d3a..fe7f95293e 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -7,7 +7,7 @@ if(!spill && istype(source, /obj/item/organ/genital/penis) && \ istype(receiver, /obj/item/organ/genital/vagina) && getorganslot(ORGAN_SLOT_WOMB)) var/obj/item/organ/genital/penis/peenus = source - if(!peenus.equipment[GENITAL_EQUIPEMENT_CONDOM]) + if(!(locate(/obj/item/genital_equipment/condom) in peenus.contents)) impregnate(partner, getorganslot(ORGAN_SLOT_WOMB), src.type) if(!receiver || spill || forced) @@ -45,11 +45,11 @@ if(istype(G, /obj/item/organ/genital/penis)) var/obj/item/organ/genital/penis/bepis = G - if(bepis.equipment[GENITAL_EQUIPMENT_SOUNDING]) + if(locate(/obj/item/genital_equipment/sounding) in bepis.contents) spill = TRUE to_chat(src, "You feel your sounding rod being pushed out of your cockhole with the burst of jizz!") - bepis.equipment.Remove(GENITAL_EQUIPMENT_SOUNDING) - new /obj/item/genital_equipment/sounding/used_sounding(loc) + var/obj/item/genital_equipment/sounding/rod = locate(/obj/item/genital_equipment/sounding) in bepis.contents + rod.forceMove(get_turf(src)) if(cover) target.add_cum_overlay() diff --git a/modular_splurt/code/modules/cargo/bounties/assistant.dm b/modular_splurt/code/modules/cargo/bounties/assistant.dm index bd157042d9..42210acf6f 100644 --- a/modular_splurt/code/modules/cargo/bounties/assistant.dm +++ b/modular_splurt/code/modules/cargo/bounties/assistant.dm @@ -3,4 +3,11 @@ description = "Something wack is happening at Central Command, and now they requested some filled condoms?" reward = 1150 required_count = 5 - wanted_types = list(/obj/item/genital_equipment/condom/filled) + wanted_types = list(/obj/item/genital_equipment/condom) + +/datum/bounty/item/assistant/condom/applies_to(obj/O) + if(!..()) + return FALSE + var/obj/item/genital_equipment/condom/T = O + return T.reagents.total_volume > 0 + diff --git a/modular_splurt/code/modules/cargo/exports/lewd.dm b/modular_splurt/code/modules/cargo/exports/lewd.dm index 80ab9814f1..a6186671f1 100644 --- a/modular_splurt/code/modules/cargo/exports/lewd.dm +++ b/modular_splurt/code/modules/cargo/exports/lewd.dm @@ -2,5 +2,11 @@ /datum/export/gear/condom cost = 150 unit_name = "filled condom" - export_types = list(/obj/item/genital_equipment/condom/filled) + export_types = list(/obj/item/genital_equipment/condom) include_subtypes = TRUE + +/datum/export/gear/condom/applies_to(obj/O) + if(!..()) + return FALSE + var/obj/item/genital_equipment/condom/T = O + return T.reagents.total_volume > 0 From dd4a03878ebc3ea39f2739c670fc8ab127a881c4 Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Sat, 25 Jun 2022 21:47:45 +1000 Subject: [PATCH 20/72] eg --- code/__SPLURTCODE/DEFINES/signals.dm | 1 + code/modules/arousal/arousal.dm | 2 +- .../code/datums/components/pregnancy.dm | 64 +++++++++++++++---- .../code/modules/arousal/arousal.dm | 5 +- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/code/__SPLURTCODE/DEFINES/signals.dm b/code/__SPLURTCODE/DEFINES/signals.dm index 6316cf2b23..3d290d25ed 100644 --- a/code/__SPLURTCODE/DEFINES/signals.dm +++ b/code/__SPLURTCODE/DEFINES/signals.dm @@ -1,3 +1,4 @@ #define COMSIG_MOB_CAME "mob_came" #define COMSIG_HEALTH_SCAN "health_scan" #define COMSIG_ORGAN_REMOVED "organ_removed" +#define COMSIG_MOB_CLIMAX "mob_coomed" diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm index 3cf0176d48..5a8fcab9b2 100644 --- a/code/modules/arousal/arousal.dm +++ b/code/modules/arousal/arousal.dm @@ -121,7 +121,7 @@ to_chat(src,"You climax [(Lgen) ? "in [L]'s [Lgen.name]" : "with [L]"], your [G.name] spilling nothing.") to_chat(L,"[src] climaxes [(Lgen) ? "in your [Lgen.name]" : "with you"], [p_their()] [G.name] spilling nothing!") //SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) //Sandstorm edit - do_climax(fluid_source, spillage ? loc : L, G, spillage) + do_climax(fluid_source, spillage ? loc : L, G, spillage,, Lgen) //L.receive_climax(src, Lgen, G, spillage) /mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 2e6b1741fa..57fa5a614c 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -76,20 +76,23 @@ UnregisterSignal(parent, COMSIG_ATOM_ENTERING) UnregisterSignal(parent, COMSIG_OBJ_BREAK) - /datum/component/pregnancy/proc/register_carrier() RegisterSignal(carrier, COMSIG_MOB_DEATH, .proc/fetus_mortus) RegisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) RegisterSignal(carrier, COMSIG_HEALTH_SCAN, .proc/on_scan) RegisterSignal(carrier, COMSIG_MOB_APPLY_DAMAGE, .proc/handle_damage) + RegisterSignal(carrier, COMSIG_MOB_CLIMAX) if(container) RegisterSignal(container, COMSIG_ORGAN_REMOVED, .proc/fetus_mortus) + if(oviposition) + RegisterSignal(carrier, COMSIG_MOB_CLIMAX, .proc/on_climax) /datum/component/pregnancy/proc/unregister_carrier() UnregisterSignal(carrier, COMSIG_MOB_DEATH) UnregisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE) UnregisterSignal(carrier, COMSIG_HEALTH_SCAN) UnregisterSignal(carrier, COMSIG_MOB_APPLY_DAMAGE) + UnregisterSignal(carrier, COMSIG_MOB_CLIMAX) if(container) UnregisterSignal(container, COMSIG_ORGAN_REMOVED) @@ -111,10 +114,28 @@ carrier = parent RegisterWithParent() else if(isitem(parent)) + max_stage += 1 RegisterWithParent() else return COMPONENT_INCOMPATIBLE +/datum/component/pregnancy/proc/on_climax(datum/source, atom/target, obj/item/organ/genital/sender, obj/item/organ/genital/receiver, spill) + SIGNAL_HANDLER + + if(!oviposition) + return FALSE + + if(stage < 2) + return FALSE + + to_chat(carrier, span_userlove("You feel your egg sliding out slowly inside!")) + + if(receiver && isliving(target)) + var/mob/living/livingtarg = target + if(livingtarg.client?.prefs?.egg_stuffing) + return lay_eg(receiver) + return lay_eg(get_turf(carrier)) + /datum/component/pregnancy/proc/on_obj_break(datum/source, damage_flag) SIGNAL_HANDLER @@ -224,7 +245,7 @@ qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() - if(stage < (max_stage / 2)) + if(stage <= 2) if(stage == 2 && prob(10)) to_chat(carrier, span_notice("You feel something pressing lightly inside")) return @@ -236,20 +257,39 @@ carrier.emote("scream") - var/can_oviposit = TRUE + lay_eg(get_turf(carrier)) + +/datum/component/pregnancy/proc/lay_eg(atom/location) + if(isorgan(location)) + var/obj/item/organ/recv = location + if(!recv.owner) + return FALSE + if(ishuman(carrier)) var/mob/living/carbon/human/human_owner = carrier var/obj/item/bodypart/chest = human_owner.get_bodypart(BODY_ZONE_CHEST) if(LAZYLEN(human_owner.clothingonpart(chest))) - can_oviposit = FALSE - if(can_oviposit) - playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) - carrier.Knockdown(200, TRUE, TRUE) - carrier.Stun(200, TRUE, TRUE) - carrier.adjustStaminaLoss(200) - var/obj/item/oviposition_egg/eggo = new(get_turf(carrier)) - to_chat(carrier, span_nicegreen("The egg came out!")) - eggo.TakeComponent(src) + return FALSE + + playsound(carrier, 'sound/effects/splat.ogg', 70, TRUE) + carrier.Knockdown(200, TRUE, TRUE) + carrier.Stun(200, TRUE, TRUE) + carrier.adjustStaminaLoss(200) + + var/obj/item/oviposition_egg/eggo = new(carrier) + + eggo.TakeComponent(src) + eggo.forceMove(location) + + if(isorgan(location)) + var/obj/item/organ/recv = location + carrier.visible_message(span_userlove("[carrier] laid an egg!"), \ + span_userlove("You laid an egg inside [recv.owner]'s [recv]")) + else + carrier.visible_message(span_notice("[carrier] laid an egg!"), \ + span_nicegreen("The egg came out!")) + + return TRUE //not how genetics work but okay /datum/component/pregnancy/proc/determine_baby_dna(mob/living/carbon/human/babby) diff --git a/modular_splurt/code/modules/arousal/arousal.dm b/modular_splurt/code/modules/arousal/arousal.dm index fe7f95293e..189bbf5f03 100644 --- a/modular_splurt/code/modules/arousal/arousal.dm +++ b/modular_splurt/code/modules/arousal/arousal.dm @@ -28,12 +28,15 @@ if(can_impregnate && can_get_pregnant) AddComponent(/datum/component/pregnancy, partner, baby_type, W) -/mob/living/carbon/human/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill, cover = FALSE) +/mob/living/carbon/human/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill, cover = FALSE, obj/item/organ/genital/Lgen) if(!G) return if(!target || !R) return + if(SEND_SIGNAL(src, COMSIG_MOB_CLIMAX, target, G, Lgen, spill)) + return + var/cached_fluid if(isliving(target) && !spill) var/mob/living/L = target From d58455d08218e1f035fc79994b8a8f093379241c Mon Sep 17 00:00:00 2001 From: Pin-alternative Date: Mon, 27 Jun 2022 10:56:30 +1000 Subject: [PATCH 21/72] doin --- code/__SPLURTCODE/DEFINES/cit_defines.dm | 3 + code/__SPLURTCODE/DEFINES/signals.dm | 1 + code/modules/arousal/genitals.dm | 7 ++- code/modules/client/preferences.dm | 6 -- code/modules/client/preferences_savefile.dm | 2 - .../interactions/interaction_interface.dm | 7 +++ .../code/datums/components/pregnancy.dm | 63 +++++++++++++------ .../code/datums/mood_events/preg_events.dm | 8 +++ modular_splurt/code/game/object/items.dm | 4 +- .../code/game/object/items/oviposition.dm | 1 + modular_splurt/code/modules/paperwork/pen.dm | 7 +++ tgstation.dme | 1 + .../tgui/interfaces/MobInteraction.tsx | 15 +++++ 13 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 modular_splurt/code/datums/mood_events/preg_events.dm diff --git a/code/__SPLURTCODE/DEFINES/cit_defines.dm b/code/__SPLURTCODE/DEFINES/cit_defines.dm index 768bb61ea2..5a952148bd 100644 --- a/code/__SPLURTCODE/DEFINES/cit_defines.dm +++ b/code/__SPLURTCODE/DEFINES/cit_defines.dm @@ -4,4 +4,7 @@ #define GEN_REMOVE_EQUIPMENT "Remove Equipment" #define GEN_INSERT_EQUIPMENT "Insert Equipment" +#define GENITAL_CAN_STUFF (1<<14) +#define GEN_ALLOW_EGG_STUFFING "Allows egg stuffing" //SPLURT EDIT, EGG STUFFING + GLOBAL_LIST_INIT(genitals_interactions, list(GEN_REMOVE_EQUIPMENT, GEN_INSERT_EQUIPMENT)) diff --git a/code/__SPLURTCODE/DEFINES/signals.dm b/code/__SPLURTCODE/DEFINES/signals.dm index 3d290d25ed..9a44ad968d 100644 --- a/code/__SPLURTCODE/DEFINES/signals.dm +++ b/code/__SPLURTCODE/DEFINES/signals.dm @@ -2,3 +2,4 @@ #define COMSIG_HEALTH_SCAN "health_scan" #define COMSIG_ORGAN_REMOVED "organ_removed" #define COMSIG_MOB_CLIMAX "mob_coomed" +#define COMSIG_OBJ_WRITTEN_ON "written_on" diff --git a/code/modules/arousal/genitals.dm b/code/modules/arousal/genitals.dm index 723903b1a5..eb8bf76296 100644 --- a/code/modules/arousal/genitals.dm +++ b/code/modules/arousal/genitals.dm @@ -81,7 +81,8 @@ return owner.is_groin_exposed() /obj/item/organ/genital/proc/toggle_visibility(visibility, update = TRUE) - genital_flags &= ~(GENITAL_THROUGH_CLOTHES|GENITAL_HIDDEN|GENITAL_UNDIES_HIDDEN) + if(visibility != GEN_ALLOW_EGG_STUFFING) + genital_flags &= ~(GENITAL_THROUGH_CLOTHES|GENITAL_HIDDEN|GENITAL_UNDIES_HIDDEN) if(owner) owner.exposed_genitals -= src switch(visibility) @@ -101,6 +102,10 @@ genital_flags |= GENITAL_HIDDEN if(owner) owner.log_message("Hid their [src] completely",LOG_EMOTE) + if(GEN_ALLOW_EGG_STUFFING) + TOGGLE_BITFIELD(genital_flags, GENITAL_CAN_STUFF) + if(owner) + owner.log_message("Allowed egg stuffing in their [src]") if(update && owner && ishuman(owner)) //recast to use update genitals proc var/mob/living/carbon/human/H = owner diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8670c00f65..af3caa80a0 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -366,8 +366,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/oviposition = FALSE /// Does john spaceman look like a gluttonous slob if he pregent? var/pregnancy_inflation = FALSE - /// Does john spaceman like being stuffed - var/egg_stuffing = FALSE //SPLURT END /datum/preferences/New(client/C) @@ -849,7 +847,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Pregnancy preferences

" dat += "Can impregnate:[virility ? "Enabled" : "Disabled"]" dat += "Can get pregnant:[fertility ? "Enabled" : "Disabled"]" - dat += "Can be stuffed with eggs:[egg_stuffing ? "Enabled" : "Disabled"]" if(fertility) dat += "Pregnancy type:[oviposition ? "Oviposition" : "Live Birth"]" dat += "Pregnancy inflation:[pregnancy_inflation ? "Enabled" : "Disabled"]" @@ -2064,9 +2061,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("pregnancy_inflation") pregnancy_inflation = !pregnancy_inflation - if("egg_stuffing") - egg_stuffing = !egg_stuffing - //SPLURT EDIT END if("hair") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 2a63a088d9..1fa1049913 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1192,7 +1192,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["fertile"] >> fertility S["oviposition"] >> oviposition S["pregnancy_inflation"] >> pregnancy_inflation - S["egg_stuffing"] >> egg_stuffing //SPLURT EDIT END cit_character_pref_load(S) @@ -1391,7 +1390,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["fertile"], fertility) WRITE_FILE(S["oviposition"], oviposition) WRITE_FILE(S["pregnancy_inflation"], pregnancy_inflation) - WRITE_FILE(S["egg_stuffing"], egg_stuffing) WRITE_FILE(S["headshot"], features["headshot_link"]) //SPLURT EDIT END diff --git a/modular_sand/code/datums/interactions/interaction_interface.dm b/modular_sand/code/datums/interactions/interaction_interface.dm index cdaa8ffe52..a53453f0fb 100644 --- a/modular_sand/code/datums/interactions/interaction_interface.dm +++ b/modular_sand/code/datums/interactions/interaction_interface.dm @@ -97,8 +97,15 @@ visibility = "Always hidden" else visibility = "Hidden by clothes" + + var/extras = "None" + if(CHECK_BITFIELD(genital.genital_flags, GENITAL_CAN_STUFF)) + extras = "Allows egg stuffing" + + genital_entry["extras"] = extras genital_entry["visibility"] = visibility genital_entry["possible_choices"] = GLOB.genitals_visibility_toggles + genital_entry["extra_choices"] = list(GEN_ALLOW_EGG_STUFFING) genitals += list(genital_entry) if(iscarbon(self)) var/simulated_ass = list() diff --git a/modular_splurt/code/datums/components/pregnancy.dm b/modular_splurt/code/datums/components/pregnancy.dm index 57fa5a614c..e981ace27f 100644 --- a/modular_splurt/code/datums/components/pregnancy.dm +++ b/modular_splurt/code/datums/components/pregnancy.dm @@ -12,6 +12,8 @@ var/datum/dna/father_dna var/datum/dna/mother_dna + var/egg_name + var/stage = 0 var/max_stage = PREGNANCY_STAGES COOLDOWN_DECLARE(stage_time) @@ -69,12 +71,14 @@ if(isitem(parent)) RegisterSignal(parent, COMSIG_ATOM_ENTERING, .proc/on_entering) RegisterSignal(parent, COMSIG_OBJ_BREAK, .proc/on_obj_break) + RegisterSignal(parent, COMSIG_OBJ_WRITTEN_ON, .proc/name_egg) /datum/component/pregnancy/UnregisterFromParent() if(carrier) unregister_carrier() UnregisterSignal(parent, COMSIG_ATOM_ENTERING) UnregisterSignal(parent, COMSIG_OBJ_BREAK) + UnregisterSignal(parent, COMSIG_OBJ_WRITTEN_ON) /datum/component/pregnancy/proc/register_carrier() RegisterSignal(carrier, COMSIG_MOB_DEATH, .proc/fetus_mortus) @@ -108,6 +112,7 @@ oviposition = FALSE carrier = null container = null + egg_name = null /datum/component/pregnancy/PostTransfer() if(isliving(parent)) @@ -119,6 +124,11 @@ else return COMPONENT_INCOMPATIBLE +/datum/component/pregnancy/proc/name_egg(datum/source, name) + SIGNAL_HANDLER + + egg_name = name + /datum/component/pregnancy/proc/on_climax(datum/source, atom/target, obj/item/organ/genital/sender, obj/item/organ/genital/receiver, spill) SIGNAL_HANDLER @@ -131,8 +141,7 @@ to_chat(carrier, span_userlove("You feel your egg sliding out slowly inside!")) if(receiver && isliving(target)) - var/mob/living/livingtarg = target - if(livingtarg.client?.prefs?.egg_stuffing) + if(CHECK_BITFIELD(receiver.genital_flags, GENITAL_CAN_STUFF)) return lay_eg(receiver) return lay_eg(get_turf(carrier)) @@ -163,8 +172,8 @@ /datum/component/pregnancy/proc/handle_life(seconds) SIGNAL_HANDLER - if(ishuman(parent) && pregnancy_inflation) - handle_belly_stuff(parent) + if(ishuman(carrier) && pregnancy_inflation) + handle_belly_stuff(carrier) if(oviposition) handle_ovi_preg() @@ -175,6 +184,9 @@ revealed = TRUE carrier.apply_status_effect(/datum/status_effect/pregnancy) + if(stage > 3 && ishuman(carrier)) + SEND_SIGNAL(carrier, COMSIG_ADD_MOOD_EVENT, "pregnancy", /datum/mood_event/pregnant_negative) + if(COOLDOWN_FINISHED(src, stage_time)) stage += 1 stage = min(stage, max_stage) @@ -195,7 +207,7 @@ belly.update() /datum/component/pregnancy/proc/handle_preg() - if(prob(10)) + if(prob(2) && !isitem(parent)) switch(stage) if(2) to_chat(carrier, span_warning("You can feel your belly getting bigger!")) @@ -204,7 +216,7 @@ to_chat(carrier, span_warning("Oh! The kicking in my belly is getting a bit more intense!")) else to_chat(carrier, span_warning("The kicking is quite intense now!")) - carrier.adjustStaminaLoss(30) + carrier.adjustStaminaLoss(20) if(4) to_chat(carrier, span_warning("You feel like you're going into labor very soon! Get ready to give birth!")) carrier.adjustStaminaLoss(50) @@ -213,11 +225,16 @@ return if(stage < max_stage) return - - if(prob(50)) - to_chat(carrier, span_warning("You're going into labor right now!")) + if(!isitem(parent)) + if(prob(50)) + to_chat(carrier, span_warning("You're going into labor right now!")) + else + to_chat(carrier, span_userdanger("It hurts! The baby is coming out!")) else - to_chat(carrier, span_userdanger("It hurts! The baby is coming out!")) + if(prob(50)) + to_chat(carrier, span_warning("Something is moving inside you!")) + else + to_chat(carrier, span_userdanger("It hurts! Something is trying to come out!")) carrier.emote("scream") @@ -236,17 +253,17 @@ var/mob/living/babby = new baby_type(get_turf(carrier)) if(ishuman(babby)) determine_baby_dna(babby) - INVOKE_ASYNC(GLOBAL_PROC, .proc/offer_control_to_babby, babby, carrier) + INVOKE_ASYNC(GLOBAL_PROC, .proc/offer_control_to_babby, babby, carrier, egg_name) + SEND_SIGNAL(carrier, COMSIG_ADD_MOOD_EVENT, "pregnancy_end", /datum/mood_event/pregnant_positive) if(isitem(parent)) var/obj/item = parent item.forceMove(get_turf(carrier)) item.obj_break(MELEE) - else - qdel(src) + qdel(src) /datum/component/pregnancy/proc/handle_ovi_preg() if(stage <= 2) - if(stage == 2 && prob(10)) + if(stage == 2 && prob(2)) to_chat(carrier, span_notice("You feel something pressing lightly inside")) return @@ -278,9 +295,6 @@ var/obj/item/oviposition_egg/eggo = new(carrier) - eggo.TakeComponent(src) - eggo.forceMove(location) - if(isorgan(location)) var/obj/item/organ/recv = location carrier.visible_message(span_userlove("[carrier] laid an egg!"), \ @@ -289,6 +303,9 @@ carrier.visible_message(span_notice("[carrier] laid an egg!"), \ span_nicegreen("The egg came out!")) + eggo.TakeComponent(src) + eggo.forceMove(location) + return TRUE //not how genetics work but okay @@ -333,6 +350,7 @@ if(belly && pregnancy_inflation) belly.size = 0 belly.update() + SEND_SIGNAL(gregnant, COMSIG_CLEAR_MOOD_EVENT, "pregnancy") /datum/component/pregnancy/proc/fetus_mortus() SIGNAL_HANDLER @@ -342,6 +360,9 @@ new /obj/effect/gibspawner/generic(get_turf(carrier)) else new /obj/effect/decal/cleanable/egg_smudge(get_turf(carrier)) + carrier.Knockdown(200, TRUE, TRUE) + carrier.Stun(200, TRUE, TRUE) + carrier.adjustStaminaLoss(200) carrier.visible_message(span_danger("[carrier] has a miscarriage!"), \ span_userdanger("Oh no! My baby is dead!")) qdel(src) @@ -356,10 +377,10 @@ /datum/component/pregnancy/proc/handle_damage(datum/source, damage, damagetype, def_zone) SIGNAL_HANDLER - if(def_zone == BODY_ZONE_CHEST && damage > 25 && prob(40)) + if(def_zone == BODY_ZONE_CHEST && damage > 20 && prob(40)) fetus_mortus() -/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy) +/proc/offer_control_to_babby(mob/living/babby, mob/living/mommy, pre_named) var/poll_message = "Do you want to play as [mommy]'s offspring?" var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_RESPAWN, null, FALSE, 120, babby) if(!LAZYLEN(candidates)) @@ -378,7 +399,9 @@ to_chat(babby, "You are the son (or daughter) of [mommy_name]!") var/name - if(QDELETED(mommy)) + if(pre_named) + name = pre_named + else if(QDELETED(mommy)) name = input(babby, "What will be your name?", "Name yourself") as null|text else name = input(mommy, "What will be your baby's name?", "Name the baby") as null|text diff --git a/modular_splurt/code/datums/mood_events/preg_events.dm b/modular_splurt/code/datums/mood_events/preg_events.dm new file mode 100644 index 0000000000..35dcadfcd4 --- /dev/null +++ b/modular_splurt/code/datums/mood_events/preg_events.dm @@ -0,0 +1,8 @@ +/datum/mood_event/pregnant_negative + description = "THE BABY IS COMING OUT...\n" + mood_change = -7 + +/datum/mood_event/pregnant_positive + description = "The baby came out...phew\n" + mood_change = 3 + timeout = 2 MINUTES diff --git a/modular_splurt/code/game/object/items.dm b/modular_splurt/code/game/object/items.dm index 3e44eb95fa..238d8ea99f 100644 --- a/modular_splurt/code/game/object/items.dm +++ b/modular_splurt/code/game/object/items.dm @@ -122,8 +122,8 @@ /obj/item/oviposition_egg/insert_item_organ(mob/living/carbon/user, mob/living/carbon/target, obj/item/organ/genital/target_organ) - if(!target.client?.prefs?.egg_stuffing) - to_chat(user, span_warning("They don't want you to do that!")) + if(!(CHECK_BITFIELD(target_organ.genital_flags, GENITAL_CAN_STUFF))) + to_chat(user, span_warning("This genital can't be stuffed!")) return target.visible_message(span_warning("\The [user] is trying to insert an egg inside \the [target]!"),\ diff --git a/modular_splurt/code/game/object/items/oviposition.dm b/modular_splurt/code/game/object/items/oviposition.dm index 22fda4441c..f9b9740d6e 100644 --- a/modular_splurt/code/game/object/items/oviposition.dm +++ b/modular_splurt/code/game/object/items/oviposition.dm @@ -4,6 +4,7 @@ icon_state = "egg" icon = 'icons/obj/food/food.dmi' integrity_failure = 0.9 + obj_flags = UNIQUE_RENAME /obj/item/oviposition_egg/obj_break(damage_flag) . = ..() diff --git a/modular_splurt/code/modules/paperwork/pen.dm b/modular_splurt/code/modules/paperwork/pen.dm index e9e4d7c435..0e3fd48485 100644 --- a/modular_splurt/code/modules/paperwork/pen.dm +++ b/modular_splurt/code/modules/paperwork/pen.dm @@ -44,3 +44,10 @@ to_chat(user, "You write on your [BP:name].") else . = ..() + +/obj/item/pen/try_modify_object(obj/O, mob/living/user, proximity) + . = ..() + if(!O.renamedByPlayer) + return + if(O.name != initial(O.name)) + SEND_SIGNAL(O, COMSIG_OBJ_WRITTEN_ON, O.name) diff --git a/tgstation.dme b/tgstation.dme index b2bd50291e..b1f9627109 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4264,6 +4264,7 @@ #include "modular_splurt\code\datums\mood_events\generic_positive_events.dm" #include "modular_splurt\code\datums\mood_events\mood_event.dm" #include "modular_splurt\code\datums\mood_events\needs_events.dm" +#include "modular_splurt\code\datums\mood_events\preg_events.dm" #include "modular_splurt\code\datums\mutations\telekenisis.dm" #include "modular_splurt\code\datums\ruins\lavaland.dm" #include "modular_splurt\code\datums\ruins\station.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction.tsx b/tgui/packages/tgui/interfaces/MobInteraction.tsx index 1d14a31a58..84b95fe13a 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction.tsx @@ -31,6 +31,8 @@ type GenitalData = { name: string, key: string, visibility: string, + extras: string, + extra_choices: string[], possible_choices: string[], } @@ -238,6 +240,7 @@ const ModeToIcon = { "Hidden by clothes": "tshirt", "Hidden by underwear": "low-vision", "Always hidden": "eye-slash", + "Allows egg stuffing": "egg", }; const GenitalVisibilityTab = (props, context) => { @@ -260,6 +263,18 @@ const GenitalVisibilityTab = (props, context) => { visibility: choice, })} /> ))} + {genital.extra_choices instanceof Array + ? genital.extra_choices.map(choice => ( +