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"