diff --git a/.travis.yml b/.travis.yml index da060b19fe..6f6829031b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,4 +36,8 @@ script: - (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; echo "$num escapes (expecting ${MACRO_COUNT} or less)"; [ $num -le ${MACRO_COUNT} ]) - source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup - python tools/TagMatcher/tag-matcher.py ../.. + - echo "#define UNIT_TEST 1" > code/_unit_tests.dm + - cp config/example/* config/ - DreamMaker polaris.dme + - DreamDaemon polaris.dmb -invisible -trusted -core 2>&1 | tee log.txt + - grep "All Unit Tests Passed" log.txt diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index 23119c69ad..f1a43ca277 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -82,6 +82,9 @@ /proc/log_misc(text) diary << "\[[time_stamp()]]MISC: [text][log_end]" +/proc/log_unit_test(text) + world.log << "## UNIT_TEST: [text]" + //pretty print a direction bitflag, can be useful for debugging. /proc/print_dir(var/dir) var/list/comps = list() diff --git a/code/_unit_tests.dm b/code/_unit_tests.dm new file mode 100644 index 0000000000..88eebd5aec --- /dev/null +++ b/code/_unit_tests.dm @@ -0,0 +1,10 @@ +/* + * + * This file is used by Travis to indicate that Unit Tests are to be ran. + * Do not add anything but the UNIT_TEST definition here as it will be overwritten by Travis when running tests. + * + * + * Should you wish to edit set UNIT_TEST to 1 like so: + * #define UNIT_TEST 1 + */ +#define UNIT_TEST 0 diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index f10e3ae472..85ace41452 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -395,7 +395,7 @@ /datum/design/item/mecha/drill name = "Drill" - id = "drill" + id = "mech_drill" build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill /datum/design/item/mecha/extinguisher diff --git a/code/unit_tests/loadout_tests.dm b/code/unit_tests/loadout_tests.dm new file mode 100644 index 0000000000..7ca778655a --- /dev/null +++ b/code/unit_tests/loadout_tests.dm @@ -0,0 +1,23 @@ +/datum/unit_test/loadout_test_shall_have_name_cost_path + name = "LOADOUT: Entries shall have name, cost, and path definitions" + +/datum/unit_test/loadout_test_shall_have_name_cost_path/start_test() + var/failed = 0 + for(var/geartype in typesof(/datum/gear) - /datum/gear) + var/datum/gear/G = geartype + + if(!initial(G.display_name)) + log_unit_test("[G]: Loadout - Missing display name.") + failed = 1 + else if(!initial(G.cost)) + log_unit_test("[G]: Loadout - Missing cost.") + failed = 1 + else if(!initial(G.path)) + log_unit_test("[G]: Loadout - Missing path definition.") + failed = 1 + + if(failed) + fail("One or more /datum/gear definitions had invalid display names, costs, or path definitions") + else + pass("All /datum/gear definitions had correct settings.") + return 1 diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm new file mode 100644 index 0000000000..97d4909833 --- /dev/null +++ b/code/unit_tests/map_tests.dm @@ -0,0 +1,99 @@ +/datum/unit_test/apc_area_test + name = "MAP: Area Test APC / Scrubbers / Vents Z level 1" + +/datum/unit_test/apc_area_test/start_test() + var/list/bad_areas = list() + var/area_test_count = 0 + var/list/exempt_areas = typesof(/area/space, + /area/syndicate_station, + /area/skipjack_station, + /area/solar, + /area/shuttle, + /area/holodeck, + /area/supply/station, + /area/mine, + /area/vacant/vacant_shop + ) + + var/list/exempt_from_atmos = typesof(/area/maintenance, + /area/storage, + /area/engineering/atmos/storage, + /area/rnd/test_area, + /area/construction, + /area/server, + /area/mine, + /area/vacant/vacant_shop, + /area/rnd/research_storage, // This should probably be fixed, + /area/security/riot_control // This should probably be fixed, + ) + + var/list/exempt_from_apc = typesof(/area/construction, + /area/medical/genetics, + /area/mine, + /area/vacant/vacant_shop + ) + + for(var/area/A in world) + if(A.z == 1 && !(A.type in exempt_areas)) + area_test_count++ + var/area_good = 1 + var/bad_msg = "--------------- [A.name]([A.type])" + + + if(isnull(A.apc) && !(A.type in exempt_from_apc)) + log_unit_test("[bad_msg] lacks an APC.") + area_good = 0 + + if(!A.air_scrub_info.len && !(A.type in exempt_from_atmos)) + log_unit_test("[bad_msg] lacks an Air scrubber.") + area_good = 0 + + if(!A.air_vent_info.len && !(A.type in exempt_from_atmos)) + log_unit_test("[bad_msg] lacks an Air vent.") + area_good = 0 + + if(!area_good) + bad_areas.Add(A) + + if(bad_areas.len) + fail("\[[bad_areas.len]/[area_test_count]\]Some areas lacked APCs, Air Scrubbers, or Air vents.") + else + pass("All \[[area_test_count]\] areas contained APCs, Air scrubbers, and Air vents.") + + return 1 + +/datum/unit_test/wire_test + name = "MAP: Cable Test Z level 1" + +/datum/unit_test/wire_test/start_test() + var/wire_test_count = 0 + var/bad_tests = 0 + var/turf/T = null + var/obj/structure/cable/C = null + var/list/cable_turfs = list() + var/list/dirs_checked = list() + + for(C in world) + T = null + + T = get_turf(C) + if(T && T.z == 1) + cable_turfs |= get_turf(C) + + for(T in cable_turfs) + var/bad_msg = "--------------- [T.name] \[[T.x] / [T.y] / [T.z]\]" + dirs_checked.Cut() + for(C in T) + wire_test_count++ + var/combined_dir = "[C.d1]-[C.d2]" + if(combined_dir in dirs_checked) + bad_tests++ + log_unit_test("[bad_msg] Contains multiple wires with same direction on top of each other.") + dirs_checked.Add(combined_dir) + + if(bad_tests) + fail("\[[bad_tests] / [wire_test_count]\] Some turfs had overlapping wires going the same direction.") + else + pass("All \[[wire_test_count]\] wires had no overlapping cables going the same direction.") + + return 1 diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm new file mode 100644 index 0000000000..c6b21e5d36 --- /dev/null +++ b/code/unit_tests/mob_tests.dm @@ -0,0 +1,29 @@ +/datum/unit_test/space_suffocation + name = "MOB: human mob suffocates in space" + + var/startOxyloss + var/endOxyloss + var/mob/living/carbon/human/H + async = 1 + +/datum/unit_test/space_suffocation/start_test() + var/turf/space/T = locate() + + H = new(T) + startOxyloss = H.getOxyLoss() + + return 1 + +/datum/unit_test/space_suffocation/check_result() + if(H.life_tick < 10) + return 0 + + endOxyloss = H.getOxyLoss() + + if(startOxyloss < endOxyloss) + pass("Human mob takes oxygen damage in space. (Before: [startOxyloss]; after: [endOxyloss])") + else + fail("Human mob is not taking oxygen damage in space. (Before: [startOxyloss]; after: [endOxyloss])") + + qdel(H) + return 1 diff --git a/code/unit_tests/research_tests.dm b/code/unit_tests/research_tests.dm new file mode 100644 index 0000000000..34c63b9d10 --- /dev/null +++ b/code/unit_tests/research_tests.dm @@ -0,0 +1,42 @@ +/datum/unit_test/research_designs_shall_be_unique + name = "RESEARCH: Designs Shall Be Unique" + +/datum/unit_test/research_designs_shall_be_unique/start_test() + var/list/ids = list() + var/list/build_paths = list() + + for(var/design_type in typesof(/datum/design) - /datum/design) + var/datum/design/design = design_type + if(initial(design.id) == "id") + continue + + group_by(ids, design, initial(design.id)) + group_by(build_paths, design, initial(design.build_path)) + + var/number_of_issues = number_of_issues(ids, "IDs") + number_of_issues += number_of_issues(build_paths, "Build Paths") + + if(number_of_issues) + fail("[number_of_issues] issues with research designs found.") + else + pass("All research designs are unique.") + + return 1 + +/datum/unit_test/research_designs_shall_be_unique/proc/group_by(var/list/entries, var/datum/design/entry, var/value) + var/designs = entries[value] + if(!designs) + designs = list() + entries[value] = designs + + designs += entry + +/datum/unit_test/research_designs_shall_be_unique/proc/number_of_issues(var/list/entries, var/type) + var/issues = 0 + for(var/value in entries) + var/list/list_of_designs = entries[value] + if(list_of_designs.len > 1) + log_unit_test("[type] - The following entries have the same value - [value]: " + english_list(list_of_designs)) + issues++ + + return issues diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm new file mode 100644 index 0000000000..35700f191f --- /dev/null +++ b/code/unit_tests/unit_test.dm @@ -0,0 +1,99 @@ +var/all_unit_tests_passed = 1 +var/failed_unit_tests = 0 +var/total_unit_tests = 0 + +/datum/unit_test + var/name = "template" + var/disabled = "" + var/async = 0 + var/reported = 0 + +/datum/unit_test/proc/fail(var/message) + all_unit_tests_passed = 0 + failed_unit_tests++ + reported = 1 + log_unit_test("!! FAILURE !! \[[name]\]: [message]") + +/datum/unit_test/proc/pass(var/message) + reported = 1 + log_unit_test("** SUCCESS ** \[[name]\]: [message]") + +/datum/unit_test/proc/start_test() + fail("No test proc.") + +/datum/unit_test/proc/check_result() + fail("No check results proc.") + return 1 + + +/proc/initialize_unit_tests() + log_unit_test("Initializing Unit Testing") + + if(!ticker) + crash_with("No Ticker") + world.Del() + + var/said_msg = 0 + while(ticker.pregame_timeleft && ticker.pregame_timeleft > 160) // Make sure the initial startup is complete. + if(ticker.pregame_timeleft < 175 && !said_msg) + said_msg = 1 + log_unit_test("Pregame Count down has started, giving it 20 seconds to finish.") + sleep(1) + + world.save_mode("extended") + + sleep(1) + + ticker.current_state = GAME_STATE_SETTING_UP + + log_unit_test("Round has been started. Waiting 10 seconds to start tests.") + sleep(100) + + var/list/test_datums = typesof(/datum/unit_test) + + var/list/async_test = list() + var/list/started_tests = list() + + log_unit_test("Testing Started.") + + for(var/test in test_datums) + var/datum/unit_test/d = new test() + + if(d.disabled) + d.pass("Check Disabled: [d.disabled]") + continue + + if(findtext(d.name, "template")) + continue + + if(isnull(d.start_test())) // Start the test. + d.fail("Test Runtimed") + + if(d.async) // If it's async then we'll need to check back on it later. + async_test.Add(d) + total_unit_tests++ + + // + // Check the async tests to see if they are finished. + // + + while(async_test.len) + for(var/datum/unit_test/test in async_test) + if(test.check_result()) + async_test.Remove(test) + sleep(1) + + // + // Make sure all Unit Tests reported a result + // + + for(var/datum/unit_test/test in started_tests) + if(!test.reported) + test.fail("Test failed to report a result.") + + if(all_unit_tests_passed) + log_unit_test("*** All Unit Tests Passed \[[total_unit_tests]\] ***") + world.Del() + else + log_unit_test("!!! \[[failed_unit_tests]\\[total_unit_tests]\] Unit Tests Failed !!!") + world.Del() \ No newline at end of file diff --git a/code/unit_tests/zas_tests.dm b/code/unit_tests/zas_tests.dm new file mode 100644 index 0000000000..a28abaa881 --- /dev/null +++ b/code/unit_tests/zas_tests.dm @@ -0,0 +1,119 @@ +#define UT_NORMAL 1 +#define UT_VACUUM 2 +#define UT_NORMAL_COLD 3 + +/datum/unit_test/zas_area_test + name = "ZAS: Area Test Template" + var/area_path = null + var/expectation = UT_NORMAL + +/datum/unit_test/zas_area_test/proc/test_air_in_area(var/test_area, var/expectation = UT_NORMAL) + var/test_result = list("result" = 0, "msg" = "") + + var/area/A = locate(test_area) + + if(!istype(A, test_area)) + test_result["msg"] = "Unable to get [test_area]" + return test_result + + var/list/GM_checked = list() + + for(var/turf/simulated/T in A) + if(!istype(T) || isnull(T.zone) || istype(T, /turf/simulated/floor/airless)) + continue + if(T.zone.air in GM_checked) + continue + + var/t_msg = "Turf: [T] | Location: [T.x] // [T.y] // [T.z]" + + var/datum/gas_mixture/GM = T.return_air() + var/pressure = GM.return_pressure() + var/temp = GM.temperature + + switch(expectation) + + if(UT_VACUUM) + if(pressure > 10) + test_result["msg"] = "Pressure out of bounds: [pressure] | [t_msg]" + return test_result + + + if(UT_NORMAL || UT_NORMAL_COLD) + if(abs(pressure - ONE_ATMOSPHERE) > 10) + test_result["msg"] = "Pressure out of bounds: [pressure] | [t_msg]" + return test_result + + if(expectation == UT_NORMAL) + + if(abs(temp - T20C) > 10) + test_result["msg"] = "Temperature out of bounds: [temp] | [t_msg]" + return test_result + + if(expectation == UT_NORMAL_COLD) + + if(temp > 120) + test_result["msg"] = "Temperature out of bounds: [temp] | [t_msg]" + return test_result + + GM_checked.Add(GM) + + if(GM_checked.len) + test_result["result"] = 1 + test_result["msg"] = "Checked [GM_checked.len] zones" + else + test_result["msg"] = "No zones checked." + + return test_result + +/datum/unit_test/zas_area_test/start_test() + var/list/test = test_air_in_area(area_path, expectation) + + if(isnull(test)) + fail("Check Runtimed") + + if(test["result"] == 1) + pass(test["msg"]) + else + fail(test["msg"]) + return 1 + +/datum/unit_test/zas_area_test/supply_centcomm + name = "ZAS: Supply Shuttle (CentComm)" + area_path = /area/supply/dock + +/datum/unit_test/zas_area_test/emergency_shuttle + name = "ZAS: Emergency Shuttle" + area_path = /area/shuttle/escape/centcom + +/datum/unit_test/zas_area_test/ai_chamber + name = "ZAS: AI Chamber" + area_path = /area/ai + +/datum/unit_test/zas_area_test/mining_shuttle_at_station + name = "ZAS: Mining Shuttle (Station)" + area_path = /area/shuttle/mining/station + +/datum/unit_test/zas_area_test/cargo_maint + name = "ZAS: Cargo Maintenance" + area_path = /area/maintenance/cargo + +/datum/unit_test/zas_area_test/eng_shuttle + name = "ZAS: Construction Site Shuttle (Station)" + area_path = /area/shuttle/constructionsite/station + +/datum/unit_test/zas_area_test/virology + name = "ZAS: Virology" + area_path = /area/medical/virology + +/datum/unit_test/zas_area_test/xenobio + name = "ZAS: Xenobiology" + area_path = /area/rnd/xenobiology + +/datum/unit_test/zas_area_test/mining_area + name = "ZAS: Mining Area (Vacuum)" + area_path = /area/mine/explored + expectation = UT_VACUUM + +/datum/unit_test/zas_area_test/cargo_bay + name = "ZAS: Cargo Bay" + area_path = /area/quartermaster/storage diff --git a/code/world.dm b/code/world.dm index 136228ccfc..4f89288c62 100644 --- a/code/world.dm +++ b/code/world.dm @@ -64,7 +64,12 @@ var/global/datum/global_init/init = new () . = ..() +#if UNIT_TEST + log_unit_test("Unit Tests Enabled. This will destroy the world when testing is complete.") + log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm") +#else sleep_offline = 1 +#endif // Set up roundstart seed list. plant_controller = new() @@ -105,6 +110,9 @@ var/global/datum/global_init/init = new () processScheduler.deferSetupFor(/datum/controller/process/ticker) processScheduler.setup() master_controller.setup() +#if UNIT_TEST + initialize_unit_tests() +#endif spawn(3000) //so we aren't adding to the round-start lag if(config.ToRban) diff --git a/maps/polaris-1.dmm b/maps/polaris-1.dmm index 7cd93084a0..2ea323af06 100644 --- a/maps/polaris-1.dmm +++ b/maps/polaris-1.dmm @@ -1656,7 +1656,7 @@ "aFR" = (/obj/structure/mopbucket,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light{dir = 1},/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/tiled,/area/janitor) "aFS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/security/warden) "aFT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/warden) -"aFU" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access = list(3)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/dark,/area/security/warden) +"aFU" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access = list(3)},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/dark,/area/security/warden) "aFV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/warden) "aFW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/warden) "aFX" = (/turf/simulated/wall,/area/security/warden) @@ -3548,7 +3548,7 @@ "bql" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/medical/sleeper) "bqm" = (/obj/effect/floor_decal/corner/paleblue{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/sleeper) "bqn" = (/obj/machinery/recharge_station,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/sleeper) -"bqo" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/bodybags{pixel_x = 1; pixel_y = 2},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/corner/mauve{dir = 5},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/machinery/light_switch{pixel_x = -36; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/medical/genetics_cloning) +"bqo" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/bodybags{pixel_x = 1; pixel_y = 2},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/effect/floor_decal/corner/mauve{dir = 5},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/machinery/light_switch{pixel_x = -36; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/medical/genetics_cloning) "bqp" = (/obj/machinery/camera/network/security{c_tag = "SEC - Secure Armory Armor"; dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled/dark,/area/security/armoury) "bqq" = (/obj/structure/window/reinforced{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/medical/genetics_cloning) "bqr" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/camera/network/medbay{c_tag = "MED - Cloning"; dir = 2},/turf/simulated/floor/tiled,/area/medical/genetics_cloning) @@ -3765,7 +3765,7 @@ "buu" = (/obj/structure/filingcabinet/chestdrawer{name = "Medical Forms"},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/reception) "buv" = (/obj/structure/filingcabinet/medical{desc = "A large cabinet with hard copy medical records."; name = "Medical Records"},/obj/machinery/alarm{pixel_y = 22},/obj/effect/floor_decal/corner/paleblue/full{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/tiled/white,/area/medical/reception) "buw" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/effect/floor_decal/corner/paleblue/full{dir = 8},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) -"bux" = (/obj/structure/table/standard,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) +"bux" = (/obj/structure/table/standard,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "buy" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/syringes{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/syringes,/obj/machinery/alarm{pixel_y = 22},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "buz" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/masks{pixel_y = 0},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "buA" = (/obj/structure/closet/secure_closet/medical3,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) diff --git a/polaris.dme b/polaris.dme index 1dd7061f51..239337353b 100644 --- a/polaris.dme +++ b/polaris.dme @@ -11,6 +11,7 @@ // END_PREFERENCES // BEGIN_INCLUDE #include "code\_macros.dm" +#include "code\_unit_tests.dm" #include "code\global.dm" #include "code\hub.dm" #include "code\names.dm" @@ -1858,6 +1859,12 @@ #include "code\modules\virus2\items_devices.dm" #include "code\modules\xgm\xgm_gas_data.dm" #include "code\modules\xgm\xgm_gas_mixture.dm" +#include "code\unit_tests\loadout_tests.dm" +#include "code\unit_tests\map_tests.dm" +#include "code\unit_tests\mob_tests.dm" +#include "code\unit_tests\research_tests.dm" +#include "code\unit_tests\unit_test.dm" +#include "code\unit_tests\zas_tests.dm" #include "code\ZAS\_docs.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Atom.dm"