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
🆑
fix: Fix holodeck items from being eaten, crafted, recycled, juiced, or
grinded.
/🆑
This commit is contained in:
Tim
2023-10-21 13:39:01 -04:00
committed by GitHub
parent 7e1f5e609e
commit 491ac3ca8f
4 changed files with 80 additions and 46 deletions
+5 -2
View File
@@ -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()
+43 -26
View File
@@ -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
+4
View File
@@ -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
@@ -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