From 491ac3ca8fbfd38d9796ec96ada632a0e5dd20fe Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 21 Oct 2023 12:39:01 -0500 Subject: [PATCH] Fix holodeck items from being eaten, crafted, recycled, juiced, or grinded (#79028) ## About The Pull Request - Fixes #74612 The holodeck edibles could be eaten by the crew giving them nutrition and medicine reagents. This could be done an infinite amount of times since holodeck programs can be reloaded instantly. Holodeck items no longer can be: - Eaten - Crafted as an ingredient - Juiced into reagents - Grinded into reagents - Recycled into material ## Why It's Good For The Game No more free infinite heals from holodeck or other silly exploits. ## Changelog :cl: fix: Fix holodeck items from being eaten, crafted, recycled, juiced, or grinded. /:cl: --- code/datums/components/crafting/crafting.dm | 7 +- code/datums/components/food/edible.dm | 69 ++++++++++++------- code/game/machinery/recycler.dm | 4 ++ .../chemistry/machinery/reagentgrinder.dm | 46 ++++++++----- 4 files changed, 80 insertions(+), 46 deletions(-) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 9f17b3d1d7e..7eb5b70232a 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -67,7 +67,11 @@ var/list/instances_list = list() for(var/instance_path in item_instances) if(ispath(instance_path, requirement_path)) - instances_list += item_instances[instance_path] + var/obj/item/item = item_instances[instance_path] + if(item.flags_1 & HOLOGRAM_1) + continue + + instances_list += item requirements_list[requirement_path] = instances_list @@ -108,7 +112,6 @@ continue . += AM - /datum/component/personal_crafting/proc/get_surroundings(atom/a, list/blacklist=null) . = list() .["tool_behaviour"] = list() diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index dd9c91c6ec5..1e724f0e404 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -487,19 +487,25 @@ Behavior that's still missing from this component that original food items had t return TRUE ///Checks whether or not the eater can actually consume the food -/datum/component/edible/proc/CanConsume(mob/living/eater, mob/living/feeder) +/datum/component/edible/proc/CanConsume(mob/living/carbon/eater, mob/living/feeder) if(!iscarbon(eater)) return FALSE - var/mob/living/carbon/C = eater - var/covered = "" - if(C.is_mouth_covered(ITEM_SLOT_HEAD)) - covered = "headgear" - else if(C.is_mouth_covered(ITEM_SLOT_MASK)) - covered = "mask" - if(covered) + if(eater.is_mouth_covered()) eater.balloon_alert(feeder, "mouth is covered!") return FALSE - if(SEND_SIGNAL(eater, COMSIG_CARBON_ATTEMPT_EAT, parent) & COMSIG_CARBON_BLOCK_EAT) + + var/atom/food = parent + + if(food.flags_1 & HOLOGRAM_1) + if(eater == feeder) + to_chat(eater, span_notice("You try to take a bite out of [food], but it fades away!")) + else + to_chat(feeder, span_notice("You try to feed [eater] [food], but it fades away!")) + + qdel(food) + return FALSE + + if(SEND_SIGNAL(eater, COMSIG_CARBON_ATTEMPT_EAT, food) & COMSIG_CARBON_BLOCK_EAT) return return TRUE @@ -636,24 +642,29 @@ Behavior that's still missing from this component that original food items had t qdel(parent) ///Ability to feed food to puppers -/datum/component/edible/proc/UseByAnimal(datum/source, mob/user) +/datum/component/edible/proc/UseByAnimal(datum/source, mob/living/basic/pet/dog/doggy) SIGNAL_HANDLER - var/atom/owner = parent - - if(!isdog(user)) + if(!isdog(doggy)) return - var/mob/living/L = user + + var/atom/food = parent + + if(food.flags_1 & HOLOGRAM_1) + to_chat(doggy, span_notice("You try to take a bite out of [food], but it fades away!")) + qdel(food) + return + if(bitecount == 0 || prob(50)) - L.manual_emote("nibbles away at \the [parent].") + doggy.manual_emote("nibbles away at \the [food].") bitecount++ . = COMPONENT_CANCEL_ATTACK_CHAIN - L.taste(owner.reagents) // why should carbons get all the fun? - if(bitecount >= 5) - var/satisfaction_text = pick("burps from enjoyment.", "yaps for more!", "woofs twice.", "looks at the area where \the [parent] was.") - L.manual_emote(satisfaction_text) - qdel(parent) + doggy.taste(food.reagents) // why should carbons get all the fun? + if(bitecount >= 5) + var/satisfaction_text = pick("burps from enjoyment.", "yaps for more!", "woofs twice.", "looks at the area where \the [food] was.") + doggy.manual_emote(satisfaction_text) + qdel(food) ///Ability to feed food to puppers /datum/component/edible/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) @@ -676,10 +687,16 @@ Behavior that's still missing from this component that original food items had t /datum/component/edible/proc/on_ooze_eat(datum/source, mob/eater, edible_flags) SIGNAL_HANDLER - if(foodtypes & edible_flags) - var/atom/eaten_food = parent - eaten_food.reagents.trans_to(eater, eaten_food.reagents.total_volume, transferred_by = eater) - eater.visible_message(span_warning("[src] eats [eaten_food]!"), span_notice("You eat [eaten_food].")) - playsound(get_turf(eater),'sound/items/eatfood.ogg', rand(30,50), TRUE) - qdel(eaten_food) + var/atom/food = parent + + if(food.flags_1 & HOLOGRAM_1) + to_chat(eater, span_notice("You try to take a bite out of [food], but it fades away!")) + qdel(food) + return COMPONENT_ATOM_EATEN + + if(foodtypes & edible_flags) + food.reagents.trans_to(eater, food.reagents.total_volume, transferred_by = eater) + eater.visible_message(span_warning("[src] eats [food]!"), span_notice("You eat [food].")) + playsound(get_turf(eater),'sound/items/eatfood.ogg', rand(30,50), TRUE) + qdel(food) return COMPONENT_ATOM_EATEN diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 99e7540a352..9e7c53392d5 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -129,6 +129,10 @@ return //I don't know how you called Crossed() but stop it. if(morsel.resistance_flags & INDESTRUCTIBLE) return + if(morsel.flags_1 & HOLOGRAM_1) + visible_message(span_notice("[morsel] fades away!")) + qdel(morsel) + return var/list/to_eat = (issilicon(morsel) ? list(morsel) : morsel.get_all_contents()) //eating borg contents leads to many bad things diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 26ebfa1d18d..d98044102d3 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -308,18 +308,23 @@ if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.holder_full()) return operate_for(50, juicing = TRUE) - for(var/obj/item/i in holdingitems) + for(var/obj/item/ingredient in holdingitems) if(beaker.reagents.holder_full()) break - var/obj/item/I = i - if(I.juice_typepath) - juice_item(I, user) -/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I, mob/user) //Juicing results can be found in respective object definitions - if(!I.juice(beaker.reagents, user)) - to_chat(usr, span_danger("[src] shorts out as it tries to juice up [I], and transfers it back to storage.")) + if(ingredient.flags_1 & HOLOGRAM_1) + to_chat(user, span_notice("You try to juice [ingredient], but it fades away!")) + qdel(ingredient) + continue + + if(ingredient.juice_typepath) + juice_item(ingredient, user) + +/obj/machinery/reagentgrinder/proc/juice_item(obj/item/ingredient, mob/user) //Juicing results can be found in respective object definitions + if(!ingredient.juice(beaker.reagents, user)) + to_chat(user, span_danger("[src] shorts out as it tries to juice up [ingredient], and transfers it back to storage.")) return - remove_object(I) + remove_object(ingredient) /obj/machinery/reagentgrinder/proc/grind(mob/user) power_change() @@ -327,21 +332,26 @@ return operate_for(60) warn_of_dust() // don't breathe this. - for(var/i in holdingitems) + for(var/obj/item/ingredient in holdingitems) if(beaker.reagents.holder_full()) break - var/obj/item/I = i - if(I.grind_results) - grind_item(i, user) -/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I, mob/user) //Grind results can be found in respective object definitions - if(!I.grind(beaker.reagents, user)) - if(isstack(I)) - to_chat(usr, span_notice("[src] attempts to grind as many pieces of [I] as possible.")) + if(ingredient.flags_1 & HOLOGRAM_1) + to_chat(user, span_notice("You try to grind [ingredient], but it fades away!")) + qdel(ingredient) + continue + + if(ingredient.grind_results) + grind_item(ingredient, user) + +/obj/machinery/reagentgrinder/proc/grind_item(obj/item/ingredient, mob/user) //Grind results can be found in respective object definitions + if(!ingredient.grind(beaker.reagents, user)) + if(isstack(ingredient)) + to_chat(user, span_notice("[src] attempts to grind as many pieces of [ingredient] as possible.")) else - to_chat(usr, span_danger("[src] shorts out as it tries to grind up [I], and transfers it back to storage.")) + to_chat(user, span_danger("[src] shorts out as it tries to grind up [ingredient], and transfers it back to storage.")) return - remove_object(I) + remove_object(ingredient) /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing