diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 09c62e9cf2d..712f112b828 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -713,6 +713,7 @@ /datum/outfit/syndicatespace/syndicaptain name = "Syndicate Ship Captain" + uniform = /obj/item/clothing/under/syndicate/combat suit = /obj/item/clothing/suit/armor/vest/capcarapace/syndicate head = /obj/item/clothing/head/hos/beret/syndicate ears = /obj/item/radio/headset/syndicate/alt/leader diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm index 451741a25e9..437f1d84167 100644 --- a/code/modules/antagonists/fugitive/fugitive_outfits.dm +++ b/code/modules/antagonists/fugitive/fugitive_outfits.dm @@ -102,9 +102,9 @@ mask = /obj/item/clothing/mask/gas/hunter glasses = /obj/item/clothing/glasses/sunglasses/garb ears = /obj/item/radio/headset - l_pocket = /obj/item/tank/internals/plasma/full r_pocket = /obj/item/restraints/handcuffs/cable id = /obj/item/card/id + l_hand = /obj/item/tank/internals/plasma/full r_hand = /obj/item/flamethrower/full/tank /datum/outfit/bountyarmor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) diff --git a/code/modules/antagonists/gang/outfits.dm b/code/modules/antagonists/gang/outfits.dm index c3546c062b2..a9cf486d163 100644 --- a/code/modules/antagonists/gang/outfits.dm +++ b/code/modules/antagonists/gang/outfits.dm @@ -37,7 +37,8 @@ name = "Families: Armored Beat Cop" suit = /obj/item/clothing/suit/armor/vest/blueshirt head = /obj/item/clothing/head/helmet/blueshirt - belt = /obj/item/gun/ballistic/shotgun/automatic/combat + belt = null + l_hand = /obj/item/gun/ballistic/shotgun/automatic/combat backpack_contents = list(/obj/item/storage/box/handcuffs = 1, /obj/item/storage/box/teargas = 1, /obj/item/storage/box/flashbangs = 1, @@ -50,7 +51,8 @@ suit = /obj/item/clothing/suit/armor/riot head = /obj/item/clothing/head/helmet/riot gloves = /obj/item/clothing/gloves/combat - belt = /obj/item/gun/ballistic/shotgun/automatic/combat + belt = null + l_hand = /obj/item/gun/ballistic/shotgun/automatic/combat backpack_contents = list(/obj/item/storage/box/handcuffs = 1, /obj/item/storage/box/teargas = 1, /obj/item/storage/box/flashbangs = 1, diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index e0cb06733ca..a454771a34f 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -15,6 +15,7 @@ #include "card_mismatch.dm" #include "chain_pull_through_space.dm" #include "component_tests.dm" +#include "outfit_sanity.dm" #include "plantgrowth_tests.dm" #include "reagent_id_typos.dm" #include "reagent_recipe_collisions.dm" diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm new file mode 100644 index 00000000000..76656e96326 --- /dev/null +++ b/code/modules/unit_tests/outfit_sanity.dm @@ -0,0 +1,50 @@ +#define CHECK_OUTFIT_SLOT(outfit_key, slot_name) if (outfit.##outfit_key) { \ + H.equip_to_slot_or_del(new outfit.##outfit_key(H), ##slot_name, TRUE); \ + /* We don't check the result of equip_to_slot_or_del because it returns false for random jumpsuits, as they delete themselves on init */ \ + if (!H.get_item_by_slot(##slot_name)) { \ + Fail("[outfit.name]'s [#outfit_key] is invalid!"); \ + } \ +} + +/datum/unit_test/outfit_sanity/Run() + var/mob/living/carbon/human/H = allocate(/mob/living/carbon/human) + + for (var/outfit_type in subtypesof(/datum/outfit)) + // Only make one human and keep undressing it because it's much faster + for (var/obj/item/I in H.get_equipped_items(include_pockets = TRUE)) + qdel(I) + + var/datum/outfit/outfit = new outfit_type + outfit.pre_equip(H, TRUE) + + CHECK_OUTFIT_SLOT(uniform, ITEM_SLOT_ICLOTHING) + CHECK_OUTFIT_SLOT(suit, ITEM_SLOT_OCLOTHING) + CHECK_OUTFIT_SLOT(back, ITEM_SLOT_BACK) + CHECK_OUTFIT_SLOT(belt, ITEM_SLOT_BELT) + CHECK_OUTFIT_SLOT(gloves, ITEM_SLOT_GLOVES) + CHECK_OUTFIT_SLOT(shoes, ITEM_SLOT_FEET) + CHECK_OUTFIT_SLOT(head, ITEM_SLOT_HEAD) + CHECK_OUTFIT_SLOT(mask, ITEM_SLOT_MASK) + CHECK_OUTFIT_SLOT(neck, ITEM_SLOT_NECK) + CHECK_OUTFIT_SLOT(ears, ITEM_SLOT_EARS) + CHECK_OUTFIT_SLOT(glasses, ITEM_SLOT_EYES) + CHECK_OUTFIT_SLOT(id, ITEM_SLOT_ID) + CHECK_OUTFIT_SLOT(suit_store, ITEM_SLOT_SUITSTORE) + CHECK_OUTFIT_SLOT(l_pocket, ITEM_SLOT_LPOCKET) + CHECK_OUTFIT_SLOT(r_pocket, ITEM_SLOT_RPOCKET) + + if (outfit.backpack_contents || outfit.box) + var/list/backpack_contents = outfit.backpack_contents?.Copy() + if (outfit.box) + if (!backpack_contents) + backpack_contents = list() + backpack_contents.Insert(1, outfit.box) + backpack_contents[outfit.box] = 1 + + for (var/path in backpack_contents) + var/number = backpack_contents[path] || 1 + for (var/_ in 1 to number) + if (!H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE)) + Fail("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.") + +#undef CHECK_OUTFIT_SLOT