diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 44cd1141938..7e0303103b4 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -337,8 +337,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_CAN_SIGN_ON_COMMS "can_sign_on_comms" /// nobody can use martial arts on this mob #define TRAIT_MARTIAL_ARTS_IMMUNE "martial_arts_immune" -/// You've been cursed with a living duffelbag, and can't have more added -#define TRAIT_DUFFEL_CURSE_PROOF "duffel_cursed" /// Immune to being afflicted by time stop (spell) #define TRAIT_TIME_STOP_IMMUNE "time_stop_immune" /// Revenants draining you only get a very small benefit. @@ -1011,4 +1009,3 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define SPEAKING_FROM_TONGUE "tongue" ///trait source that sign language should use #define SPEAKING_FROM_HANDS "hands" - diff --git a/code/datums/components/curse_of_hunger.dm b/code/datums/components/curse_of_hunger.dm index 1d54f629772..8912b704662 100644 --- a/code/datums/components/curse_of_hunger.dm +++ b/code/datums/components/curse_of_hunger.dm @@ -32,16 +32,15 @@ . = ..() var/obj/item/cursed_item = parent RegisterSignal(cursed_item, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) - //checking slot_equipment_priority is the better way to decide if it should be an equip-curse (alternative being if it has slot_flags) - //because it needs to know where to equip to (and stuff like buckets and cones can be on_pickup curses despite having slots to equip to) - if(cursed_item.slot_equipment_priority) - RegisterSignal(cursed_item, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) - else - RegisterSignal(cursed_item, COMSIG_ITEM_PICKUP, PROC_REF(on_pickup)) + RegisterSignal(cursed_item, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) /datum/component/curse_of_hunger/UnregisterFromParent() . = ..() - UnregisterSignal(parent, list(COMSIG_PARENT_EXAMINE, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_POST_UNEQUIP, COMSIG_ITEM_PICKUP, COMSIG_ITEM_DROPPED)) + UnregisterSignal(parent, list( + COMSIG_PARENT_EXAMINE, + COMSIG_ITEM_EQUIPPED, + COMSIG_ITEM_DROPPED, + )) ///signal called on parent being examined /datum/component/curse_of_hunger/proc/on_examine(datum/source, mob/user, list/examine_list) @@ -57,23 +56,15 @@ /datum/component/curse_of_hunger/proc/on_equip(datum/source, mob/equipper, slot) SIGNAL_HANDLER var/obj/item/at_least_item = parent - if(!(at_least_item.slot_flags & slot)) + // Items with no slot flags curse on pickup (because hand slot) + if(at_least_item.slot_flags && !(at_least_item.slot_flags & slot)) return the_curse_begins(equipper) -///signal called from a successful unequip of parent -/datum/component/curse_of_hunger/proc/on_unequip(mob/living/unequipper, force, atom/newloc, no_move, invdrop, silent) - SIGNAL_HANDLER - the_curse_ends(unequipper) - -///signal called from picking up parent -/datum/component/curse_of_hunger/proc/on_pickup(datum/source, mob/grabber) - SIGNAL_HANDLER - the_curse_begins(grabber) - ///signal called from dropping parent /datum/component/curse_of_hunger/proc/on_drop(datum/source, mob/dropper) SIGNAL_HANDLER + the_curse_ends(dropper) /datum/component/curse_of_hunger/proc/the_curse_begins(mob/cursed) @@ -85,27 +76,24 @@ ADD_TRAIT(cursed, TRAIT_PACIFISM, CURSED_ITEM_TRAIT(cursed_item.type)) if(add_dropdel) cursed_item.item_flags |= DROPDEL - return - if(cursed_item.slot_equipment_priority) - RegisterSignal(cursed_item, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequip)) - else - RegisterSignal(cursed_item, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) + + RegisterSignal(cursed_item, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) /datum/component/curse_of_hunger/proc/the_curse_ends(mob/uncursed) - var/obj/item/at_least_item = parent + var/obj/item/cursed_item = parent STOP_PROCESSING(SSobj, src) - REMOVE_TRAIT(parent, TRAIT_NODROP, CURSED_ITEM_TRAIT(parent.type)) - REMOVE_TRAIT(uncursed, TRAIT_CLUMSY, CURSED_ITEM_TRAIT(at_least_item.type)) - REMOVE_TRAIT(uncursed, TRAIT_PACIFISM, CURSED_ITEM_TRAIT(at_least_item.type)) + REMOVE_TRAIT(cursed_item, TRAIT_NODROP, CURSED_ITEM_TRAIT(cursed_item.type)) + REMOVE_TRAIT(uncursed, TRAIT_CLUMSY, CURSED_ITEM_TRAIT(cursed_item.type)) + REMOVE_TRAIT(uncursed, TRAIT_PACIFISM, CURSED_ITEM_TRAIT(cursed_item.type)) //remove either one of the signals that could have called this proc - UnregisterSignal(parent, list(COMSIG_ITEM_POST_UNEQUIP, COMSIG_ITEM_DROPPED)) + UnregisterSignal(cursed_item, COMSIG_ITEM_DROPPED) - var/turf/vomit_turf = get_turf(at_least_item) + var/turf/vomit_turf = get_turf(cursed_item) playsound(vomit_turf, 'sound/effects/splat.ogg', 50, TRUE) new /obj/effect/decal/cleanable/vomit(vomit_turf) - uncursed.dropItemToGround(at_least_item, force = TRUE) - if(!QDELETED(at_least_item)) //gives a head start for the person to get away from the cursed item before it begins hunting again! + uncursed.dropItemToGround(cursed_item, force = TRUE) + if(!QDELING(cursed_item)) //gives a head start for the person to get away from the cursed item before it begins hunting again! addtimer(CALLBACK(src, PROC_REF(seek_new_target)), 10 SECONDS) ///proc called after a timer to awaken the AI in the cursed item if it doesn't have a target already. @@ -166,3 +154,6 @@ cursed.visible_message(span_danger("[cursed_item] bites [cursed]!"), span_userdanger("[cursed_item] bites you to sate [cursed_item.p_their()] hunger!")) cursed.apply_damage(60, BRUTE, BODY_ZONE_CHEST, wound_bonus = -20, bare_wound_bonus = 20) current_health = min(current_health + 1, max_health) + +#undef HUNGER_THRESHOLD_WARNING +#undef HUNGER_THRESHOLD_TRY_EATING diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm index 1880c0612c2..11b232f3ede 100644 --- a/code/datums/components/fantasy/suffixes.dm +++ b/code/datums/components/fantasy/suffixes.dm @@ -203,8 +203,7 @@ var/filter_color = "#8a0c0ca1" //clarified args var/new_name = pick(", eternally hungry", " of the glutton", " cursed with hunger", ", consumer of all", " of the feast") master.AddElement(/datum/element/curse_announcement, "[master] is cursed with the curse of hunger!", filter_color, new_name, comp) - var/add_dropdel = FALSE //clarified boolean - comp.appliedComponents += master.AddComponent(/datum/component/curse_of_hunger, add_dropdel) + comp.appliedComponents += master.AddComponent(/datum/component/curse_of_hunger) return newName //no spoilers! /datum/fantasy_affix/curse_of_hunger/remove(datum/component/fantasy/comp) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index b39edcb7a2d..e7bb13b148a 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -361,7 +361,6 @@ icon_state = "duffel-curse" inhand_icon_state = "duffel-curse" slowdown = 2 - item_flags = DROPDEL max_integrity = 100 /obj/item/storage/backpack/duffelbag/cursed/Initialize(mapload) diff --git a/code/modules/spells/spell_types/touch/duffelbag_curse.dm b/code/modules/spells/spell_types/touch/duffelbag_curse.dm index 1ca5d0e1ffc..8725d7daac7 100644 --- a/code/modules/spells/spell_types/touch/duffelbag_curse.dm +++ b/code/modules/spells/spell_types/touch/duffelbag_curse.dm @@ -41,7 +41,7 @@ victim.Knockdown(5 SECONDS) // If someone's already cursed, don't try to give them another - if(HAS_TRAIT(victim, TRAIT_DUFFEL_CURSE_PROOF)) + if(istype(victim.back, /obj/item/storage/backpack/duffelbag/cursed)) to_chat(caster, span_warning("The burden of [victim]'s duffel bag becomes too much, shoving them to the floor!")) to_chat(victim, span_warning("The weight of this bag becomes overburdening!")) return TRUE @@ -53,8 +53,6 @@ span_danger("You feel something attaching itself to you, and a strong desire to discuss your [pick(elaborate_backstory)] at length!"), ) - // This duffelbag is now cuuuurrrsseed! Equip it on them - ADD_TRAIT(conjured_duffel, TRAIT_DUFFEL_CURSE_PROOF, CURSED_ITEM_TRAIT(conjured_duffel.name)) conjured_duffel.pickup(victim) conjured_duffel.forceMove(victim) diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 50cc1f08586..a2eb5719b67 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -116,6 +116,7 @@ #include "heretic_rituals.dm" #include "holidays.dm" #include "human_through_recycler.dm" +#include "hunger_curse.dm" #include "hydroponics_extractor_storage.dm" #include "hydroponics_harvest.dm" #include "hydroponics_self_mutations.dm" diff --git a/code/modules/unit_tests/hunger_curse.dm b/code/modules/unit_tests/hunger_curse.dm new file mode 100644 index 00000000000..6c30ac4663d --- /dev/null +++ b/code/modules/unit_tests/hunger_curse.dm @@ -0,0 +1,18 @@ +/// Tests that the curse of hunger, from [/datum/component/curse_of_hunger], +/// is properly added when equipped to the correct slot and removed when dropped / deleted +/datum/unit_test/hunger_curse + +/datum/unit_test/hunger_curse/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + var/obj/item/storage/backpack/duffelbag/cursed/cursed_bag = allocate(/obj/item/storage/backpack/duffelbag/cursed) + + dummy.equip_to_appropriate_slot(cursed_bag) + + TEST_ASSERT(HAS_TRAIT(cursed_bag, TRAIT_NODROP), "The cursed bag wasn't NODROP after being cursed!") + TEST_ASSERT(HAS_TRAIT(dummy, TRAIT_CLUMSY), "Dummy wasn't clumsy after being cursed!") + TEST_ASSERT(HAS_TRAIT(dummy, TRAIT_PACIFISM), "Dummy wasn't a pacifist after being cursed!") + + QDEL_NULL(cursed_bag) + + TEST_ASSERT(!HAS_TRAIT(dummy, TRAIT_CLUMSY), "Dummy was still clumsy after being cured of its curse!") + TEST_ASSERT(!HAS_TRAIT(dummy, TRAIT_PACIFISM), "Dummy was still a pacifist after being cured of its curse!")