From 6755a031e4b804a6651ba5dfdc0fa04284bef588 Mon Sep 17 00:00:00 2001 From: AlManiak Date: Fri, 31 Jan 2025 12:15:56 +0100 Subject: [PATCH 1/3] Initial commit collar works with food and drinks --- .../code/clothing/bluespace_collar.dm | 145 ++++++++++++++++++ code/datums/components/edible.dm | 18 ++- code/modules/food_and_drinks/drinks/drinks.dm | 38 +++-- code/modules/food_and_drinks/food/snacks.dm | 54 ++++--- tgstation.dme | 1 + 5 files changed, 215 insertions(+), 41 deletions(-) create mode 100644 GainStation13/code/clothing/bluespace_collar.dm diff --git a/GainStation13/code/clothing/bluespace_collar.dm b/GainStation13/code/clothing/bluespace_collar.dm new file mode 100644 index 0000000000..5a16a2ac3b --- /dev/null +++ b/GainStation13/code/clothing/bluespace_collar.dm @@ -0,0 +1,145 @@ +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver + name = "bluespace collar receiver" + desc = "A collar containing a miniaturized bluespace whitehole. Other bluespace transmitter collars can connect to this, causing the wearer to receive food from other transmitter collars directly into the stomach. " + slot_flags = ITEM_SLOT_NECK + var/mob/victim = 0 + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/equipped(mob/user, slot) + . = ..() + var/mob/living/carbon/wearer = user + if(!iscarbon(wearer) || slot !=ITEM_SLOT_NECK || !wearer?.client?.prefs?.weight_gain_items) + return FALSE + victim = user; + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/dropped(mob/user) + . = ..() + var/mob/living/carbon/wearer = user + if(!iscarbon(wearer) || !(wearer.get_item_by_slot(ITEM_SLOT_NECK) == src) || !wearer?.client?.prefs?.weight_gain_items) + return FALSE + victim = 0 + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/attackby(obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K, mob/user, params) + if(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + K.linked_receiver = src + var/mob/living/carbon/U = user + to_chat(U, "You link the bluespace collar with the other transmitter") + return + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter + name = "bluespace collar transmitter" + desc = "A collar containing a miniaturized bluespace blackhole. Can be connected to a bluespace collar receiver to transmit food to a linked receiver collar. " + slot_flags = ITEM_SLOT_NECK + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/linked_receiver = 0 + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/equipped(mob/user, slot) + . = ..() + var/mob/living/carbon/wearer = user + if(!iscarbon(wearer) || slot !=ITEM_SLOT_NECK || !wearer?.client?.prefs?.weight_gain_items) + return FALSE + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/dropped(mob/user) + . = ..() + var/mob/living/carbon/wearer = user + if(!iscarbon(wearer) || !(wearer.get_item_by_slot(ITEM_SLOT_NECK) == src) || !wearer?.client?.prefs?.weight_gain_items) + return FALSE + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/attackby(obj/item/K, mob/user, params) + if(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver)) + linked_receiver = K + var/mob/living/carbon/U = user + to_chat(U, "You link the bluespace collar to the other receiver") + return + +// For food +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_food(obj/item/reagent_containers/food/snacks/owner, mob/living/original_eater, mob/living/feeder) + if (!linked_receiver) + return FALSE + + var/mob/living/carbon/human/eater = linked_receiver.victim + if(owner.reagents) + if(eater.satiety > -200) + eater.satiety -= owner.junkiness + playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + playsound(original_eater.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + eater.visible_message("[eater]'s belly seems to visibly distend a bit further'!", "You feel your stomach get filled by something!") + var/bitevolume = 1 + if(HAS_TRAIT(original_eater, TRAIT_VORACIOUS)) + bitevolume = bitevolume * 0.67 + var/mob/living/carbon/human/human_eater = eater + if(istype(human_eater)) + human_eater.fullness += bitevolume; + + if(owner.reagents.total_volume) + SEND_SIGNAL(owner, COMSIG_FOOD_EATEN, eater, feeder) + var/fraction = min(owner.bitesize / owner.reagents.total_volume, 1) + owner.reagents.reaction(eater, INGEST, fraction) + owner.reagents.trans_to(eater, owner.bitesize, log = TRUE) + owner.bitecount++ + owner.On_Consume(eater) + owner.checkLiked(fraction, original_eater) + return TRUE + +// For the alternative edible functionality +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_edible(datum/component/edible/foodstuff, mob/living/original_eater, mob/living/feeder) + if (!linked_receiver) + return FALSE + + var/atom/owner = foodstuff.parent + var/mob/living/carbon/human/eater = linked_receiver.victim + + if(!owner?.reagents) + return FALSE + if(eater.satiety > -200) + eater.satiety -= foodstuff.junkiness + playsound(original_eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE) + playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE) + eater.visible_message("[eater]'s belly seems to visibly distend a bit further'!", "You feel your stomach get filled by something!") + var/mob/living/carbon/human/human_eater = original_eater + if(istype(human_eater)) + var/bitevolume = 1 + if(HAS_TRAIT(human_eater, TRAIT_VORACIOUS)) + bitevolume = bitevolume * 0.67 + if(istype(eater)) + eater.fullness += bitevolume; + + if(owner.reagents.total_volume) + SEND_SIGNAL(foodstuff.parent, COMSIG_FOOD_EATEN, eater, original_eater) + var/fraction = min(foodstuff.bite_consumption / owner.reagents.total_volume, 1) + owner.reagents.reaction(eater, INGEST, fraction) + owner.reagents.trans_to(eater, foodstuff.bite_consumption) + foodstuff.bitecount++ + foodstuff.On_Consume(eater) + foodstuff.checkLiked(fraction, original_eater) + + //Invoke our after eat callback if it is valid + if(foodstuff.after_eat) + foodstuff.after_eat.Invoke(eater, feeder) + return TRUE + +// For Drinks +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_drink(obj/item/reagent_containers/food/drinks/owner, mob/living/original_eater, mob/living/feeder) + if (!linked_receiver) + return FALSE + + var/mob/living/carbon/human/eater = linked_receiver.victim + var/fraction = min(owner.gulp_size/owner.reagents.total_volume, 1) + owner.checkLiked(fraction, eater) + owner.reagents.reaction(eater, INGEST, fraction) + owner.reagents.trans_to(eater, owner.gulp_size, log = TRUE) + //GS13 Port - Fullness + if(iscarbon(eater)) + var/mob/living/carbon/human/human_eater = eater + var/mob/living/carbon/human/human_original_eater = original_eater + if(HAS_TRAIT(human_original_eater, TRAIT_VORACIOUS)) + human_eater.fullness += min(owner.gulp_size * 0.67, owner.reagents.total_volume * 0.67) + else + human_eater.fullness += min(owner.gulp_size, owner.reagents.total_volume) // GS13 drinks will fill your stomach + playsound(original_eater.loc,'sound/items/drink.ogg', rand(10,50), 1) + playsound(eater.loc,'sound/items/drink.ogg', rand(10,50), 1) + eater.visible_message("[eater]'s belly seems to visibly distend a bit further, emitting an audible sloshing noise!", "You feel your stomach get filled by liquid, hearing sloshing noises coming from within!") + return TRUE + +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/attack_self(mob/user) + linked_receiver = 0 + var/mob/living/carbon/U = user + to_chat(U, "You remove the currently linked receiver collar from the buffer") diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm index 95ca5eaef6..a6cb4cfb53 100644 --- a/code/datums/components/edible.dm +++ b/code/datums/components/edible.dm @@ -111,12 +111,18 @@ Behavior that's still missing from this component that original food items had t . = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = human_eater.wear_neck //GS13 - Bluespace collar if(eater == feeder)//If you're eating it yourself. if(!do_mob(feeder, eater, eat_time)) //Gotta pass the minimal eat time return var/eatverb = pick(eatverbs) - if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS)) + //GS13 - Bluespace collar addition + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + eater.visible_message("[eater] effortlessly [eatverb]s \the [parent].", "You effortlessly [eatverb] \the [parent], feeling as if you haven't eaten anything at all.") + //GS13 - End + else if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS)) to_chat(eater, "You don't feel like eating any more junk food at the moment!") + return else if(fullness <= FULLNESS_LEVEL_HALF_FULL) eater.visible_message("[eater] hungrily [eatverb]s \the [parent], gobbling it down!", "You hungrily [eatverb] \the [parent], gobbling it down!") @@ -133,7 +139,12 @@ Behavior that's still missing from this component that original food items had t if(isbrain(eater)) to_chat(feeder, "[eater] doesn't seem to have a mouth!") return - if(fullness <= (600 * (1 + eater.overeatduration / 1000))) + //GS13 - Bluespace collar addition + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + eater.visible_message("[feeder] attempts to feed [eater] [parent].", \ + "[feeder] attempts to feed you [parent].") + //GS13 - End + else if(fullness <= (600 * (1 + eater.overeatduration / 1000))) eater.visible_message("[feeder] attempts to feed [eater] [parent].", \ "[feeder] attempts to feed you [parent].") else @@ -147,7 +158,8 @@ Behavior that's still missing from this component that original food items had t eater.visible_message("[feeder] forces [eater] to eat [parent]!", \ "[feeder] forces you to eat [parent]!") - TakeBite(eater, feeder) + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_food(src, eater, feeder))) + TakeBite(eater, feeder) ///This function lets the eater take a bite and transfers the reagents to the eater. /datum/component/edible/proc/TakeBite(mob/living/eater, mob/living/feeder) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 61a872fed9..49205a54a6 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -30,9 +30,17 @@ if (!is_drainable()) to_chat(user, "[src]'s lid hasn't been opened!") return FALSE - + //GS13 - Bluespace collar addition + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = 0 + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/human_eater = M + K = human_eater.wear_neck if(M == user) - user.visible_message("[user] swallows a gulp of [src].", "You swallow a gulp of [src].") + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + user.visible_message("[user] effortlessly swallows a gulp of [src].", "You effortlessly swallow a gulp of [src].") + //GS13 - End + else + user.visible_message("[user] swallows a gulp of [src].", "You swallow a gulp of [src].") else M.visible_message("[user] attempts to feed the contents of [src] to [M].", "[user] attempts to feed the contents of [src] to [M].") if(!do_mob(user, M)) @@ -41,19 +49,19 @@ return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds the contents of [src] to [M].", "[user] feeds the contents of [src] to [M].") log_combat(user, M, "fed", reagents.log_list()) - - var/fraction = min(gulp_size/reagents.total_volume, 1) - checkLiked(fraction, M) - reagents.reaction(M, INGEST, fraction) - reagents.trans_to(M, gulp_size, log = TRUE) - //GS13 Port - Fullness - if(iscarbon(M)) - var/mob/living/carbon/human/human_eater = M - if(HAS_TRAIT(M, TRAIT_VORACIOUS)) - human_eater.fullness += min(gulp_size * 0.67, reagents.total_volume * 0.67) - else - human_eater.fullness += min(gulp_size, reagents.total_volume) // GS13 drinks will fill your stomach - playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1) + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_drink(src, M, user))) //GS13 - Bluespace Collar + var/fraction = min(gulp_size/reagents.total_volume, 1) + checkLiked(fraction, M) + reagents.reaction(M, INGEST, fraction) + reagents.trans_to(M, gulp_size, log = TRUE) + //GS13 Port - Fullness + if(iscarbon(M)) + var/mob/living/carbon/human/human_eater = M + if(HAS_TRAIT(M, TRAIT_VORACIOUS)) + human_eater.fullness += min(gulp_size * 0.67, reagents.total_volume * 0.67) + else + human_eater.fullness += min(gulp_size, reagents.total_volume) // GS13 drinks will fill your stomach + playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1) return TRUE /obj/item/reagent_containers/food/drinks/CheckAttackCooldown(mob/user, atom/target) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index fbc8403bee..38c14fdc1a 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -122,9 +122,13 @@ All foods are distributed among various categories. Use common sense. var/mob/living/carbon/human/human_eater = M if(istype(human_eater)) fullness = human_eater.fullness - + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = human_eater.wear_neck //GS13 - Bluespace collar if(M == user) //If you're eating it yourself. - if(junkiness && M.satiety < -150 && M.nutrition > NUTRITION_LEVEL_STARVING + 50 ) + //GS13 - Bluespace collar addition + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + user.visible_message("[user] effortlessly [eatverb]s \the [src].", "You effortlessly [eatverb] \the [src], feeling as if you haven't eaten anything at all.") + //GS13 - End + else if(junkiness && M.satiety < -150 && M.nutrition > NUTRITION_LEVEL_STARVING + 50 ) to_chat(M, "You don't feel like eating any more junk food at the moment.") return FALSE else if(fullness <= 50) @@ -142,7 +146,12 @@ All foods are distributed among various categories. Use common sense. M.SetNextAction(CLICK_CD_MELEE * 0.5) //nom nom nom else if(!isbrain(M)) //If you're feeding it to someone else. - if(fullness <= (FULLNESS_LEVEL_BEEG * (1 + M.overeatduration / 1000))) + //GS13 - Bluespace collar addition + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + M.visible_message("[user] attempts to feed [M] [src].", \ + "[user] attempts to feed you [src].") + //GS13 - End + else if(fullness <= (FULLNESS_LEVEL_BEEG * (1 + M.overeatduration / 1000))) M.visible_message("[user] attempts to feed [M] [src].", \ "[user] attempts to feed [M] [src].") else @@ -159,27 +168,26 @@ All foods are distributed among various categories. Use common sense. else to_chat(user, "[M] doesn't seem to have a mouth!") return + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_food(src, M, user))) + if(reagents) //Handle ingestion of the reagent. + if(M.satiety > -200) + M.satiety -= junkiness + playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + var/bitevolume = 1 + if(HAS_TRAIT(M, TRAIT_VORACIOUS)) + bitevolume = bitevolume * 0.67 + if(istype(human_eater)) + human_eater.fullness += bitevolume; - if(reagents) //Handle ingestion of the reagent. - if(M.satiety > -200) - M.satiety -= junkiness - playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1) - var/bitevolume = 1 - if(HAS_TRAIT(M, TRAIT_VORACIOUS)) - bitevolume = bitevolume * 0.67 - human_eater.fullness += bitevolume; - if(istype(human_eater)) - human_eater.fullness += bitevolume; - - if(reagents.total_volume) - SEND_SIGNAL(src, COMSIG_FOOD_EATEN, M, user) - var/fraction = min(bitesize / reagents.total_volume, 1) - reagents.reaction(M, INGEST, fraction) - reagents.trans_to(M, bitesize, log = TRUE) - bitecount++ - On_Consume(M) - checkLiked(fraction, M) - return TRUE + if(reagents.total_volume) + SEND_SIGNAL(src, COMSIG_FOOD_EATEN, M, user) + var/fraction = min(bitesize / reagents.total_volume, 1) + reagents.reaction(M, INGEST, fraction) + reagents.trans_to(M, bitesize, log = TRUE) + bitecount++ + On_Consume(M) + checkLiked(fraction, M) + return TRUE return FALSE diff --git a/tgstation.dme b/tgstation.dme index e6836a43b0..1673ed4705 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3927,6 +3927,7 @@ #include "GainStation13\code\__HELPERS\transformation.dm" #include "GainStation13\code\clothing\accessory.dm" #include "GainStation13\code\clothing\backpacks.dm" +#include "GainStation13\code\clothing\bluespace_collar.dm" #include "GainStation13\code\clothing\calorite_collar.dm" #include "GainStation13\code\clothing\fat_mask.dm" #include "GainStation13\code\clothing\gloves.dm" From 00fb0f0fb2b5149fcd35ee5b0b14780c46c87156 Mon Sep 17 00:00:00 2001 From: AlManiak Date: Sat, 1 Feb 2025 00:44:39 +0100 Subject: [PATCH 2/3] Added most consuming procs for the collar Added research and design for collar --- .../code/clothing/bluespace_collar.dm | 73 ++++++++++++++++--- GainStation13/code/machinery/feeding_tube.dm | 13 +++- .../code/machinery/feeding_tube_industrial.dm | 16 +++- .../modules/research/designs/nutri_designs.dm | 22 ++++++ .../research/techweb/nutritech_nodes.dm | 2 +- code/datums/components/edible.dm | 9 +-- code/modules/food_and_drinks/drinks/drinks.dm | 4 +- code/modules/food_and_drinks/food/snacks.dm | 6 +- .../reagents/reagent_containers/glass.dm | 16 +++- 9 files changed, 127 insertions(+), 34 deletions(-) diff --git a/GainStation13/code/clothing/bluespace_collar.dm b/GainStation13/code/clothing/bluespace_collar.dm index 5a16a2ac3b..924c701c86 100644 --- a/GainStation13/code/clothing/bluespace_collar.dm +++ b/GainStation13/code/clothing/bluespace_collar.dm @@ -1,8 +1,8 @@ /obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver - name = "bluespace collar receiver" + name = "Bluespace collar receiver" desc = "A collar containing a miniaturized bluespace whitehole. Other bluespace transmitter collars can connect to this, causing the wearer to receive food from other transmitter collars directly into the stomach. " slot_flags = ITEM_SLOT_NECK - var/mob/victim = 0 + var/mob/living/carbon/victim = 0 /obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/equipped(mob/user, slot) . = ..() @@ -18,15 +18,23 @@ return FALSE victim = 0 +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/proc/isworn() + if(istype(victim, /mob/living/carbon)) + return TRUE + else + return FALSE + /obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/attackby(obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K, mob/user, params) if(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) K.linked_receiver = src var/mob/living/carbon/U = user to_chat(U, "You link the bluespace collar with the other transmitter") + . = ..() return + /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter - name = "bluespace collar transmitter" + name = "Bluespace collar transmitter" desc = "A collar containing a miniaturized bluespace blackhole. Can be connected to a bluespace collar receiver to transmit food to a linked receiver collar. " slot_flags = ITEM_SLOT_NECK var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver/linked_receiver = 0 @@ -48,11 +56,17 @@ linked_receiver = K var/mob/living/carbon/U = user to_chat(U, "You link the bluespace collar to the other receiver") + . = ..() return +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/islinked() + if (linked_receiver && linked_receiver.isworn()) + return TRUE + else + return FALSE // For food /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_food(obj/item/reagent_containers/food/snacks/owner, mob/living/original_eater, mob/living/feeder) - if (!linked_receiver) + if (!islinked()) return FALSE var/mob/living/carbon/human/eater = linked_receiver.victim @@ -81,7 +95,7 @@ // For the alternative edible functionality /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_edible(datum/component/edible/foodstuff, mob/living/original_eater, mob/living/feeder) - if (!linked_receiver) + if (!islinked()) return FALSE var/atom/owner = foodstuff.parent @@ -117,8 +131,8 @@ return TRUE // For Drinks -/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_drink(obj/item/reagent_containers/food/drinks/owner, mob/living/original_eater, mob/living/feeder) - if (!linked_receiver) +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_drink(obj/item/reagent_containers/food/drinks/owner, mob/living/original_eater) + if (!islinked()) return FALSE var/mob/living/carbon/human/eater = linked_receiver.victim @@ -139,7 +153,46 @@ eater.visible_message("[eater]'s belly seems to visibly distend a bit further, emitting an audible sloshing noise!", "You feel your stomach get filled by liquid, hearing sloshing noises coming from within!") return TRUE +// For containers +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_container(var/datum/reagents/reagents , fraction, mob/M, mob/user) + if (!islinked()) + return FALSE + + var/mob/living/carbon/human/eater = linked_receiver.victim + var/self_fed = M == user + reagents.reaction(eater, INGEST, fraction) + addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), eater, 5, null, null, null, self_fed? "self swallowed" : "fed by [user]"), 5) + eater.visible_message("[eater]'s belly seems to visibly distend a bit further, emitting an audible sloshing noise!", "You feel your stomach get filled by liquid, hearing sloshing noises coming from within!") + return TRUE + +// For industrial feeding tube +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_industrial_feeding(obj/item/reagent_containers/food/snacks/food, datum/reagents/food_reagents, mob/living/original_eater) + if (!islinked()) + return FALSE + var/mob/living/carbon/human/eater = linked_receiver.victim + var/food_size = food_reagents.total_volume //We're cramming the Whole Thing down your throat~ + food_reagents.reaction(eater, INGEST, food_size) + food_reagents.trans_to(eater, food_size) + eater.fullness += food_size + food.checkLiked(food_size, eater) //...Hopefully you like the taste. + eater.visible_message("[eater]'s belly seems to greatly distend, as if it was being inflated with large amounts of food.", "You feel an immense pressure in your stomach, as if food was pumped directly into you.") + return TRUE + +// For feeding tube +/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/proc/transpose_feeding(transfer_amount, var/obj/item/reagent_containers/beaker, mob/living/original_eater) + if (!islinked()) + return FALSE + var/mob/living/carbon/human/eater = linked_receiver.victim + var/fraction = min(transfer_amount/beaker.reagents.total_volume, 1) //the fraction that is transfered of the total volume + beaker.reagents.reaction(eater, INJECT, fraction, FALSE) //make reagents reacts, but don't spam messages + beaker.reagents.trans_to(eater, transfer_amount) + eater.fullness += transfer_amount //Added feeding tube's causing fullness (But ignores limits~) + if(prob(10)) + eater.visible_message("[eater]'s belly seems to visibly distend, emitting an audible sloshing noise!", "You feel your stomach get pumped full with liquid, hearing sloshing noises coming from within!") + return TRUE + /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/attack_self(mob/user) - linked_receiver = 0 - var/mob/living/carbon/U = user - to_chat(U, "You remove the currently linked receiver collar from the buffer") + linked_receiver = 0 + var/mob/living/carbon/U = user + to_chat(U, "You remove the currently linked receiver collar from the buffer") + . = ..() diff --git a/GainStation13/code/machinery/feeding_tube.dm b/GainStation13/code/machinery/feeding_tube.dm index 70f67d06b4..e87808dd4d 100644 --- a/GainStation13/code/machinery/feeding_tube.dm +++ b/GainStation13/code/machinery/feeding_tube.dm @@ -62,10 +62,17 @@ if(beaker) if(mode) if(beaker.reagents.total_volume) + // Check to see if the person is wearing a bluespace collar + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = 0 + if(istype(attached, /mob/living/carbon/human)) + var/mob/living/carbon/human/human_eater = attached + K = human_eater.wear_neck var/transfer_amount = 5 - var/fraction = min(transfer_amount/beaker.reagents.total_volume, 1) //the fraction that is transfered of the total volume - beaker.reagents.reaction(attached, INJECT, fraction, FALSE) //make reagents reacts, but don't spam messages - beaker.reagents.trans_to(attached, transfer_amount) + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_feeding(transfer_amount, beaker, attached))) //If wearing a BS collar, use BS proc. If not, continue as normal + var/fraction = min(transfer_amount/beaker.reagents.total_volume, 1) //the fraction that is transfered of the total volume + beaker.reagents.reaction(attached, INJECT, fraction, FALSE) //make reagents reacts, but don't spam messages + beaker.reagents.trans_to(attached, transfer_amount) + attached.fullness += transfer_amount //Added feeding tube's causing fullness (But ignores limits~) update_icon() else if(!beaker.reagents.total_volume && istype(beaker, /obj/item/reagent_containers/food)) diff --git a/GainStation13/code/machinery/feeding_tube_industrial.dm b/GainStation13/code/machinery/feeding_tube_industrial.dm index a79ee2b81f..cf29237855 100644 --- a/GainStation13/code/machinery/feeding_tube_industrial.dm +++ b/GainStation13/code/machinery/feeding_tube_industrial.dm @@ -256,10 +256,18 @@ SEND_SIGNAL(food, COMSIG_FOOD_EATEN, attached) - food_reagents.reaction(attached, INGEST, food_size) - food_reagents.trans_to(attached, food_size) - - food.checkLiked(food_size, attached) //...Hopefully you like the taste. + // Check to see if the person is wearing a bluespace collar + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = 0 + if(istype(attached, /mob/living/carbon/human)) + var/mob/living/carbon/human/human_eater = attached + K = human_eater.wear_neck + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_industrial_feeding(food, food_reagents, attached))) //If wearing a BS collar, use BS proc. If not, continue as normal + food_reagents.reaction(attached, INGEST, food_size) + food_reagents.trans_to(attached, food_size) + if(istype(attached, /mob/living/carbon/human)) + var/mob/living/carbon/human/human_eater = attached + human_eater.fullness += food_size //Added industrial feeding tube's causing fullness (But ignores limits~) + food.checkLiked(food_size, attached) //...Hopefully you like the taste. if(food.trash) //Lets make the trash the food's supposed to make, if it has any diff --git a/GainStation13/code/modules/research/designs/nutri_designs.dm b/GainStation13/code/modules/research/designs/nutri_designs.dm index 6ba48d0c46..89ac62e498 100644 --- a/GainStation13/code/modules/research/designs/nutri_designs.dm +++ b/GainStation13/code/modules/research/designs/nutri_designs.dm @@ -57,6 +57,28 @@ category = list("Equipment", "Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_ALL +/datum/design/bluespace_collar_receiver + name = "Bluespace collar receiver" + desc = "A collar containing a miniaturized bluespace whitehole. Other bluespace transmitter collars can connect to this, causing the wearer to receive food from other transmitter collars directly into the stomach." + id = "bluespace_collar_receiver" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/calorite = 2500, /datum/material/bluespace = 250) + construction_time = 75 + build_path = /obj/item/clothing/neck/petcollar/locked/bluespace_collar_receiver + category = list("Equipment", "Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/bluespace_collar_transmitter + name = "Bluespace collar transmitter" + desc = "A collar containing a miniaturized bluespace blackhole. Can be connected to a bluespace collar receiver to transmit food to a linked receiver collar. " + id = "bluespace_collar_transmitter" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/calorite = 1000, /datum/material/bluespace = 500) + construction_time = 75 + build_path = /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter + category = list("Equipment", "Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL + /datum/design/cyberimp_nutriment_turbo name = "Nutriment Pump Implant TURBO" desc = "This implant was meant to prevent people from going hungry, but due to a flaw in its designs, it permanently produces a small amount of nutriment overtime." diff --git a/GainStation13/code/modules/research/techweb/nutritech_nodes.dm b/GainStation13/code/modules/research/techweb/nutritech_nodes.dm index 258fe5f959..486ff6ffb8 100644 --- a/GainStation13/code/modules/research/techweb/nutritech_nodes.dm +++ b/GainStation13/code/modules/research/techweb/nutritech_nodes.dm @@ -5,7 +5,7 @@ display_name = "Nutri-Tech Tools" description = "Ending world hunger was never made easier!" prereq_ids = list("biotech", "adv_engi") - design_ids = list("calorite_collar", "ci-nutrimentturbo", "bluespace_belt", "adipoelectric_transformer", "cookie_synthesizer", "borg_upgrade_cookiesynthesizer", "borg_upgrade_feedingtube", "ci-fatmobility") + design_ids = list("calorite_collar", "ci-nutrimentturbo", "bluespace_belt", "adipoelectric_transformer", "cookie_synthesizer", "borg_upgrade_cookiesynthesizer", "borg_upgrade_feedingtube", "ci-fatmobility","bluespace_collar_receiver","bluespace_collar_transmitter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) boost_item_paths = list(/obj/item/gun/energy/fatoray, /obj/item/gun/energy/fatoray/cannon, /obj/item/trash/fatoray_scrap1, /obj/item/trash/fatoray_scrap2) hidden = TRUE diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm index a6cb4cfb53..9219116a60 100644 --- a/code/datums/components/edible.dm +++ b/code/datums/components/edible.dm @@ -117,7 +117,7 @@ Behavior that's still missing from this component that original food items had t return var/eatverb = pick(eatverbs) //GS13 - Bluespace collar addition - if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.islinked()) eater.visible_message("[eater] effortlessly [eatverb]s \the [parent].", "You effortlessly [eatverb] \the [parent], feeling as if you haven't eaten anything at all.") //GS13 - End else if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS)) @@ -139,12 +139,7 @@ Behavior that's still missing from this component that original food items had t if(isbrain(eater)) to_chat(feeder, "[eater] doesn't seem to have a mouth!") return - //GS13 - Bluespace collar addition - if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) - eater.visible_message("[feeder] attempts to feed [eater] [parent].", \ - "[feeder] attempts to feed you [parent].") - //GS13 - End - else if(fullness <= (600 * (1 + eater.overeatduration / 1000))) + if(fullness <= (600 * (1 + eater.overeatduration / 1000))) eater.visible_message("[feeder] attempts to feed [eater] [parent].", \ "[feeder] attempts to feed you [parent].") else diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 49205a54a6..ab57443baa 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -36,7 +36,7 @@ var/mob/living/carbon/human/human_eater = M K = human_eater.wear_neck if(M == user) - if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.islinked()) user.visible_message("[user] effortlessly swallows a gulp of [src].", "You effortlessly swallow a gulp of [src].") //GS13 - End else @@ -49,7 +49,7 @@ return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds the contents of [src] to [M].", "[user] feeds the contents of [src] to [M].") log_combat(user, M, "fed", reagents.log_list()) - if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_drink(src, M, user))) //GS13 - Bluespace Collar + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_drink(src, M))) //If wearing a BS collar, use BS proc. If not, continue as normal var/fraction = min(gulp_size/reagents.total_volume, 1) checkLiked(fraction, M) reagents.reaction(M, INGEST, fraction) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 38c14fdc1a..5a762c348e 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -125,7 +125,7 @@ All foods are distributed among various categories. Use common sense. var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = human_eater.wear_neck //GS13 - Bluespace collar if(M == user) //If you're eating it yourself. //GS13 - Bluespace collar addition - if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.islinked()) //Feeding with a collar ignores fullness or junkness user.visible_message("[user] effortlessly [eatverb]s \the [src].", "You effortlessly [eatverb] \the [src], feeling as if you haven't eaten anything at all.") //GS13 - End else if(junkiness && M.satiety < -150 && M.nutrition > NUTRITION_LEVEL_STARVING + 50 ) @@ -147,7 +147,7 @@ All foods are distributed among various categories. Use common sense. else if(!isbrain(M)) //If you're feeding it to someone else. //GS13 - Bluespace collar addition - if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter)) + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.islinked()) //Feeding with a collar ignores fullness M.visible_message("[user] attempts to feed [M] [src].", \ "[user] attempts to feed you [src].") //GS13 - End @@ -168,7 +168,7 @@ All foods are distributed among various categories. Use common sense. else to_chat(user, "[M] doesn't seem to have a mouth!") return - if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_food(src, M, user))) + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_food(src, M, user))) //If wearing a BS collar, use BS proc. If not, continue as normal if(reagents) //Handle ingestion of the reagent. if(M.satiety > -200) M.satiety -= junkiness diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 861c5872a9..2f7905346b 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -23,7 +23,11 @@ if(!reagents || !reagents.total_volume) to_chat(user, "[src] is empty!") return - + //GS13 - Bluespace collar addition + var/obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter/K = 0 + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/human_eater = M + K = human_eater.wear_neck if(istype(M)) if(user.a_intent == INTENT_HARM) M.visible_message("[user] splashes the contents of [src] onto [M]!", \ @@ -57,11 +61,15 @@ log_reagent("INGESTION: FED BY: [key_name(user)] (loc [user.loc] at [AREACOORD(UT)]) -> [key_name(M)] (loc [M.loc] at [AREACOORD(MT)]) - [reagents.log_list()]") else var/turf/T = get_turf(user) - to_chat(user, "You swallow a gulp of [src].") + if (istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.islinked()) + user.visible_message("[user] effortlessly swallows a gulp of [src].", "You effortlessly swallow a gulp of [src].") + else + to_chat(user, "You swallow a gulp of [src].") log_reagent("INGESTION: SELF: [key_name(user)] (loc [user.loc] at [AREACOORD(T)]) - [reagents.log_list()]") var/fraction = min(5/reagents.total_volume, 1) - reagents.reaction(M, INGEST, fraction) - addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), M, 5, null, null, null, self_fed? "self swallowed" : "fed by [user]"), 5) + if (!(istype(K, /obj/item/clothing/neck/petcollar/locked/bluespace_collar_transmitter) && K.transpose_container(reagents, fraction, M, user))) //If wearing a BS collar, use BS proc. If not, continue as normal + reagents.reaction(M, INGEST, fraction) + addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), M, 5, null, null, null, self_fed? "self swallowed" : "fed by [user]"), 5) playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1) /obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity) From 70b495d3bb336b6224ef6e52b8a6ee8446cd4d6c Mon Sep 17 00:00:00 2001 From: AlManiak Date: Sun, 2 Feb 2025 19:58:33 +0100 Subject: [PATCH 3/3] More specific description for food --- GainStation13/code/clothing/bluespace_collar.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GainStation13/code/clothing/bluespace_collar.dm b/GainStation13/code/clothing/bluespace_collar.dm index 924c701c86..098e6e542f 100644 --- a/GainStation13/code/clothing/bluespace_collar.dm +++ b/GainStation13/code/clothing/bluespace_collar.dm @@ -75,7 +75,7 @@ eater.satiety -= owner.junkiness playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), 1) playsound(original_eater.loc,'sound/items/eatfood.ogg', rand(10,50), 1) - eater.visible_message("[eater]'s belly seems to visibly distend a bit further'!", "You feel your stomach get filled by something!") + eater.visible_message("[eater]'s belly seems to visibly distend a bit further'!", "You feel your stomach get filled by food!") var/bitevolume = 1 if(HAS_TRAIT(original_eater, TRAIT_VORACIOUS)) bitevolume = bitevolume * 0.67 @@ -175,7 +175,7 @@ food_reagents.trans_to(eater, food_size) eater.fullness += food_size food.checkLiked(food_size, eater) //...Hopefully you like the taste. - eater.visible_message("[eater]'s belly seems to greatly distend, as if it was being inflated with large amounts of food.", "You feel an immense pressure in your stomach, as if food was pumped directly into you.") + eater.visible_message("[eater]'s belly seems to greatly distend, as if it was being inflated with large amounts of food.", "You feel an immense pressure in your stomach, as if large amounts of food were pumped directly into you.") return TRUE // For feeding tube