diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index 8d17fd4664a..7ea05093501 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -350,11 +350,11 @@ var/turf/destination = get_turf(destination_landmark) //BUBBERSTATION EDIT - if(is_species(sac_target, /datum/species/protean)) + if(isprotean(sac_target)) var/obj/item/organ/brain/protean/brain = sac_target.get_organ_slot(ORGAN_SLOT_BRAIN) if(brain) brain.revive() - brain.leave_modsuit() + brain.leave_modsuit(TRUE) //BUBBERSTATION EDIT END sac_target.visible_message(span_danger("[sac_target] begins to shudder violenty as dark tendrils begin to drag them into thin air!")) sac_target.equip_to_slot_or_del(new /obj/item/restraints/handcuffs/cult, ITEM_SLOT_HANDCUFFED, indirect_action = TRUE) diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 7dff31a99cf..33575aa8454 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -373,6 +373,7 @@ #include "~skyrat\digitigrade_sprites.dm" #include "~skyrat\nanite_designs.dm" #include "~skyrat\opposing_force.dm" +#include "~skyrat\proteans.dm" // SKYRAT EDIT END // END_INCLUDE #ifdef REFERENCE_TRACKING_DEBUG //Don't try and parse this file if ref tracking isn't turned on. IE: don't parse ref tracking please mr linter diff --git a/code/modules/unit_tests/~skyrat/proteans.dm b/code/modules/unit_tests/~skyrat/proteans.dm new file mode 100644 index 00000000000..ac967b00c28 --- /dev/null +++ b/code/modules/unit_tests/~skyrat/proteans.dm @@ -0,0 +1,27 @@ +/** + * Tests Protean suit transformation and species handling. Makes sure any storage is dropped and its contents not deleted. + */ +/datum/unit_test/protean_species_handling/Run() + var/mob/living/carbon/human/consistent/protean = EASY_ALLOCATE() + var/obj/item/stack/sheet/iron/twenty/iron = EASY_ALLOCATE() + var/obj/item/storage/backpack/bag = EASY_ALLOCATE() + protean.equip_to_slot_if_possible(bag, ITEM_SLOT_BACK, TRUE, TRUE, TRUE, TRUE, TRUE) + protean.equip_to_storage(iron, ITEM_SLOT_BACK) + + protean.set_species(/datum/species/protean) + var/datum/species/protean/p_species = protean.dna.species + var/backslot = protean.get_item_by_slot(ITEM_SLOT_BACK) + var/obj/item/mod/core/protean/core = p_species.species_modsuit.core + TEST_ASSERT_EQUAL(p_species.owner, protean, "Protean species did not assign dummy as its owner.") + TEST_ASSERT(istype(backslot, /obj/item/mod/control/pre_equipped/protean), "Protean species did not assign /obj/item/mod/control/protean to ITEM_SLOT_BACK. Backslot: [isnull(backslot) ? "Null" : "[backslot]"]") + TEST_ASSERT_NOTNULL(p_species.species_modsuit, "Protean species failed to link to modsuit.") + TEST_ASSERT_EQUAL(core.linked_species, p_species, "Protean modsuit core failed to link to its species.") + + TEST_ASSERT(isturf(bag.loc), "[bag::name] did not drop onto a turf! Location: [isnull(bag.loc) ? "Nullspace" : "[bag.loc]"]") + TEST_ASSERT(locate(/obj/item/stack/sheet/iron/twenty) in bag.contents, "[iron::name] are not inside [bag::name]") + + protean.equip_to_storage(iron, ITEM_SLOT_BACK) + TEST_ASSERT_EQUAL(iron.loc, p_species.species_modsuit.atom_storage.real_location, "[iron::name] did not enter [p_species.species_modsuit.name] storage. Does it have a storage module?") + + protean.set_species(/datum/species/human) + TEST_ASSERT(isturf(iron.loc), "[iron::name] has not dropped to a turf after species loss. Location: [isnull(iron.loc) ? "Nullspace" : "[iron.loc]"]") diff --git a/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm b/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm index b0f8566214c..bc5a0b253f7 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm @@ -85,14 +85,6 @@ /mob/living/carbon/human/species/protean race = /datum/species/protean -/datum/species/protean/Destroy(force) - if(!QDELETED(species_modsuit)) - INVOKE_ASYNC(src, PROC_REF(unassimilate_modsuit), null, TRUE) - QDEL_NULL(species_modsuit) - QDEL_NULL(protean_action) - owner = null - return ..() - /datum/species/protean/on_species_gain(mob/living/carbon/human/gainer, datum/species/old_species, pref_load, regenerate_icons = TRUE) . = ..() owner = gainer @@ -126,16 +118,18 @@ organ.balloon_alert_to_viewers("rejected!", vision_distance = 1) /datum/species/protean/on_species_loss(mob/living/carbon/human/gainer, datum/species/new_species, pref_load) + . = ..() if(gainer) UnregisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN) if(species_modsuit.stored_modsuit) species_modsuit.stored_modsuit.forceMove(get_turf(gainer)) unassimilate_modsuit(null, TRUE) if(species_modsuit) + if(species_modsuit.atom_storage) + species_modsuit.atom_storage.remove_all(owner.drop_location()) QDEL_NULL(species_modsuit) protean_action.Remove(owner) owner = null - return ..() /datum/species/protean/proc/equip_modsuit(mob/living/carbon/human/gainer) species_modsuit = new() @@ -166,13 +160,7 @@ assimilate_modsuit(owner, suit, TRUE) species_modsuit.quick_activation() - LAZYINITLIST(outfit.backpack_contents) - if(istype(outfit, /datum/outfit/job)) - owner.equip_to_storage(SSwardrobe.provide_type(/obj/item/stack/sheet/iron/twenty, owner), ITEM_SLOT_BACK, TRUE, FALSE) - return - outfit.backpack_contents += /obj/item/stack/sheet/iron/twenty - for(var/path in outfit.backpack_contents) - owner.equip_to_storage(SSwardrobe.provide_type(path, owner), ITEM_SLOT_BACK, TRUE, TRUE) + owner.equip_to_storage(SSwardrobe.provide_type(/obj/item/stack/sheet/iron/twenty, owner), ITEM_SLOT_BACK, TRUE, FALSE) if(outfit.suit_store) owner.equip_to_slot_if_possible(SSwardrobe.provide_type(outfit.suit_store, owner), ITEM_SLOT_SUITSTORE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE) diff --git a/modular_zubbers/code/modules/customization/species/proteans/organs/protean_brain.dm b/modular_zubbers/code/modules/customization/species/proteans/organs/protean_brain.dm index 184a4e49476..87fc6d6161c 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/organs/protean_brain.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/organs/protean_brain.dm @@ -67,7 +67,7 @@ /datum/movespeed_modifier/protean_slowdown variable = TRUE -/obj/item/organ/brain/protean/proc/go_into_suit(forced) +/obj/item/organ/brain/protean/proc/go_into_suit(forced = FALSE) var/datum/species/protean/protean = owner.dna?.species if(!istype(protean) || owner.loc == protean.species_modsuit) return @@ -84,10 +84,11 @@ owner.remove_status_effect(/datum/status_effect/protean_low_power_mode/low_power) suit.drop_suit() owner.forceMove(suit) - sleep(12) //Sleep is fine here because I'm not returning anything and if the brain gets deleted within 12 ticks of this being ran, we have some other serious issues. + if(!forced) + sleep(12) //Sleep is fine here because I'm not returning anything and if the brain gets deleted within 12 ticks of this being ran, we have some other serious issues. owner.invisibility = initial(owner.invisibility) -/obj/item/organ/brain/protean/proc/leave_modsuit() +/obj/item/organ/brain/protean/proc/leave_modsuit(forced = FALSE) var/datum/species/protean/protean = owner.dna?.species if(!istype(protean)) return @@ -95,8 +96,9 @@ if(dead) to_chat(owner, span_warning("Your mass is destroyed. You are unable to leave.")) return - if(!do_after(owner, 5 SECONDS, suit, IGNORE_INCAPACITATED)) - return + if(!forced) + if(!do_after(owner, 5 SECONDS, suit, IGNORE_INCAPACITATED)) + return if(istype(suit.loc, /obj/item/reagent_containers/cup/soup_pot)) // If protean inside of soup pot var/obj/item/reagent_containers/cup/soup_pot/pot = suit.loc pot.remove_first_ingredient(null) @@ -108,7 +110,8 @@ storage.remove_single(null, suit, get_turf(suit), TRUE) suit.invisibility = 101 new /obj/effect/temp_visual/protean_from_suit(suit.loc, owner.dir) - sleep(12) //Same as above + if(!forced) + sleep(12) //Same as above suit.drop_suit() owner.forceMove(suit.loc) if(owner.get_item_by_slot(ITEM_SLOT_BACK))