From dbfa2261c2fcff0f18ac25dfb21d5c41a192fc29 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Thu, 10 Dec 2020 16:11:45 -0800 Subject: [PATCH] Moths can now consume clothes again (#55356) Fixes #55347. Because the food eating is invoked async-ly, the qdel was being run while you were still taking a bite. This means it was no longer edible, thus quitting the check after the timer was finished. This moves moths eating clothes behavior to instead lazily create the food item once chomped into, which is then preserved and reused until the clothing itself goes away. --- code/modules/clothing/clothing.dm | 53 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index fa3c58d41f1..e0a0c2e0f9f 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -1,3 +1,5 @@ +#define MOTH_EATING_CLOTHING_DAMAGE 15 + /obj/item/clothing name = "clothing" resistance_flags = FLAMMABLE @@ -54,6 +56,9 @@ /// How many zones (body parts, not precise) we have disabled so far, for naming purposes var/zones_disabled + /// A lazily initiated "food" version of the clothing for moths + var/obj/item/food/clothing/moth_snack + /obj/item/clothing/Initialize() if((clothing_flags & VOICEBOX_TOGGLABLE)) actions_types += /datum/action/item_action/toggle_voice_box @@ -76,21 +81,50 @@ var/atom/movable/screen/inventory/hand/H = over_object if(M.putItemFromInventoryInHandIfPossible(src, H.held_index)) add_fingerprint(usr) + //This code is cursed, moths are cursed, and someday I will destroy it. but today is not that day. /obj/item/food/clothing name = "temporary moth clothing snack item" desc = "If you're reading this it means I messed up. This is related to moths eating clothes and I didn't know a better way to do it than making a new food object. <--- stinky idiot wrote this" - food_reagents = list(/datum/reagent/consumable/nutriment = 1) + bite_consumption = 1 + // sigh, ok, so it's not ACTUALLY infinite nutrition. this is so you can eat clothes more than...once. + // bite_consumption limits how much you actually get, and the take_damage in after eat makes sure you can't abuse this. + // ...maybe this was a mistake after all. + food_reagents = list(/datum/reagent/consumable/nutriment = INFINITY) tastes = list("dust" = 1, "lint" = 1) foodtypes = CLOTH -/obj/item/clothing/attack(mob/M, mob/user, def_zone) - if(user.a_intent != INTENT_HARM && ismoth(M)) - var/obj/item/food/clothing/clothing_as_food = new //collective bruh moment - clothing_as_food.name = name - if(clothing_as_food.attack(M, user, def_zone)) //BRUUUUUUUUUUUUUUUUUUUUUUUUUUUUUH - take_damage(15, sound_effect=FALSE) - qdel(clothing_as_food) ///WHAT ARE THOOSEEE + /// A weak reference to the clothing that created us + var/datum/weakref/clothing + +/obj/item/food/clothing/MakeEdible() + AddComponent(/datum/component/edible,\ + initial_reagents = food_reagents,\ + food_flags = food_flags,\ + foodtypes = foodtypes,\ + volume = max_volume,\ + eat_time = eat_time,\ + tastes = tastes,\ + eatverbs = eatverbs,\ + bite_consumption = bite_consumption,\ + microwaved_type = microwaved_type,\ + junkiness = junkiness,\ + after_eat = CALLBACK(src, .proc/after_eat)) + +/obj/item/food/clothing/proc/after_eat(mob/eater) + var/obj/item/clothing/resolved_clothing = clothing.resolve() + if (resolved_clothing) + resolved_clothing.take_damage(MOTH_EATING_CLOTHING_DAMAGE, sound_effect = FALSE) + else + qdel(src) + +/obj/item/clothing/attack(mob/attacker, mob/user, def_zone) + if(user.a_intent != INTENT_HARM && ismoth(attacker)) + if (isnull(moth_snack)) + moth_snack = new + moth_snack.name = name + moth_snack.clothing = WEAKREF(src) + moth_snack.attack(attacker, user, def_zone) else return ..() @@ -201,6 +235,7 @@ /obj/item/clothing/Destroy() user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up + QDEL_NULL(moth_snack) return ..() /obj/item/clothing/dropped(mob/user) @@ -469,3 +504,5 @@ BLIND // can't see anything return if(prob(0.2)) to_chat(L, "The damaged threads on your [src.name] chafe!") + +#undef MOTH_EATING_CLOTHING_DAMAGE