Files
Bubberstation/code/modules/unit_tests/human_through_recycler.dm
Time-Green 54ab1e3936 Organ movement refactor *Un-nullspaces your organs* (#79687)
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

closes #53931, #70916, #53931

## About The Pull Request

Organs were previously stored in nullspace. Now they are stored in their
prospective bodyparts. Bodyparts are now stored in the mob.

I've also had to refactor a lot of code concerning organ movement.
Previously, organs were only moved into bodyparts once the bodyparts
were removed. To accomodate this change, two major distinctions have
been made:

**Bodypart removal/insertion**
Called only when an organ is taken out of a bodypart. Bodypart overlays,
damage modifiers or other changes that should affect a bodypart itself
goes here.

**Mob insertion/removal**
Called when an organ is removed from a mob. This can either be directly,
by taking the organ out of a mob, or by removing the bodypart that
contains the organ. This lets you add and remove organ effects safely
without having to worry about the bodypart.

Now that we controle the movement of bodyparts and organs, we can fuck
around with them more. Summoning someones head or chest or heart will
actually kill them now (and quite violently I must say (chest summoning
gibs lol)).


https://github.com/tgstation/tgstation/assets/7501474/5efc9dd3-cfd5-4ce4-b70f-d0d74894626e

I´ve also added a unit test that violently tears apart and reconstructs
a person in different ways to see if they get put toghether the right
way

This will definitely need a testmerge. I've done a lot of testing to
make sure interactions work, but more niche stuff or my own incompetence
can always slip through.

## Why It's Good For The Game

<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->

A lot of organ work is quite restricted. You can't C4 someones heart,
you cant summon their organs and a lot of exceptions have to be made to
keep organs in nullspace. This lets organs (and bodyparts) play more
nicely with the rest of the game. This also makes it a lot easier to
move away from extorgans since a lot of their unique movement code has
been removed and or generalized.

I don't like making PRs of this size (I'm so sorry reviewers), but I was
in a unique position to replace the entire system in a way I couldn't
have done conveniently in multiple PRs

## Changelog

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

🆑
refactor: Your organs are now inside your body. Please report any issues
with bodypart and organ movement, including exotic organ, on github and
scream at me
fix: Cases of unexpected organ movement, such as teleporting bodyparts
and organs with spells, now invokes a proper reaction (usually violent
death)
runtime: Fixes HARS runtiming on activation/deactivation
fix: Fixes lag when species swapping
/🆑

<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
2023-12-09 17:50:46 +00:00

49 lines
4.6 KiB
Plaintext

/// Puts a consistent assistant into an emagged recycler, and verifies that all intended behavior of an emagged recycler occurs (chewing up all the clothing, applying a level of melee damage, etc.)
/datum/unit_test/human_through_recycler
/datum/unit_test/human_through_recycler/Run()
var/mob/living/carbon/human/assistant = allocate(/mob/living/carbon/human/consistent, run_loc_floor_bottom_left) // we should be in the bottom_left by default, but let's be sooper dooper sure :)
var/obj/machinery/recycler/chewer = allocate(/obj/machinery/recycler/deathtrap, get_step(run_loc_floor_bottom_left, EAST)) //already existing subtype that has emagged set to TRUE, so it shall CHEW. Put it directly right to the assistant to mimick a player entering the recycler.
assistant.equipOutfit(/datum/outfit/job/assistant/consistent) // consistent assistant juuuust in case
var/turf/open/stage = get_turf(chewer)
assistant.forceMove(stage) // put the assistant in the recycler, to ensure that the recycler still registers incoming input.
// okay, let's first test the basics of how an emagged recycler should operate
TEST_ASSERT_NULL(QDELETED(assistant), "Assistant was deleted by the emagged recycler!") // The assistant should not be deleted by the recycler.
if(assistant.stat < UNCONSCIOUS)
TEST_FAIL("Assistant was not made unconscious by the emagged recycler!") // crush_living() on the recycler should have made the assistant unconscious or worse.
// crush_living() on the recycler should have applied the crush_damage to the assistant.
var/damage_incurred = assistant.getBruteLoss()
TEST_ASSERT_EQUAL(damage_incurred, chewer.crush_damage, "Assistant did not take the expected amount of brute damage ([chewer.crush_damage]) from the emagged recycler! Took ([damage_incurred]) instead.")
TEST_ASSERT(chewer.bloody, "The emagged recycler did not become bloody after crushing the assistant!")
var/list/bad_contents = assistant.contents
for(var/obj/item/item in assistant.contents)
if(item.item_flags & ABSTRACT)
bad_contents -= item
// Now, let's test to see if all of their clothing got properly deleted.
TEST_ASSERT_EQUAL(length(bad_contents), 0, "Assistant still has items in its contents after being put through an emagged recycler!")
// Consistent Assistants will always have the following: ID, PDA, backpack, a uniform, a headset, and a pair of shoes. If any of these are still present, then the recycler did not properly delete the assistant's clothing.
// However, let's check for EVERYTHING just in case, because we don't want to miss anything.
// This is just what we expect to be deleted.
TEST_ASSERT_NULL(assistant.w_uniform, "Assistant still has a jumpsuit (undersuit) on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.wear_id, "Assistant still has an ID on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.shoes, "Assistant still has shoes on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.belt, "Assistant still has an item in their belt slot after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.back, "Assistant still has an item in their back slot (backpack) after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.ears, "Assistant still has a headset on after being put through an emagged recycler!")
// This category is stuff that shouldn't exist in the first place, but let's test it anyways in case we decide consistent assistants should have more clothing in the future.
// Short point short, if any of the following error and none of these are present in the datum for this outfit, what the fuck?
TEST_ASSERT_NULL(assistant.wear_suit, "Assistant still has an oversuit on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.gloves, "Assistant still has gloves on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.head, "Assistant still has a head covering item on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.wear_mask, "Assistant still has a mask on after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.l_store, "Assistant still has an item in their left pocket after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.r_store, "Assistant still has an item in their right pocket after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.s_store, "Assistant still has an item in their suit storage slot after being put through an emagged recycler!")
TEST_ASSERT_NULL(assistant.glasses, "Assistant still has glasses on after being put through an emagged recycler!")