Skip to content

Commit

Permalink
Adds some mapping testers
Browse files Browse the repository at this point in the history
  • Loading branch information
PowerfulBacon committed Aug 24, 2024
1 parent ded19de commit 3ea806e
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 10 deletions.
5 changes: 5 additions & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -4098,6 +4098,11 @@
#include "code\modules\tgui_panel\tgui_panel.dm"
#include "code\modules\tooltip\tooltip.dm"
#include "code\modules\unit_tests\_unit_tests.dm"
#include "code\modules\unit_tests\mapping\check_active_turfs.dm"
#include "code\modules\unit_tests\mapping\check_area_apc.dm"
#include "code\modules\unit_tests\mapping\check_camera_attachment.dm"
#include "code\modules\unit_tests\mapping\check_disposals.dm"
#include "code\modules\unit_tests\mapping\check_light_attachment.dm"
#include "code\modules\unit_tests\mapping\map_test.dm"
#include "code\modules\uplink\uplink_devices.dm"
#include "code\modules\uplink\uplink_items.dm"
Expand Down
37 changes: 37 additions & 0 deletions code/_globalvars/lists/flavor_misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,43 @@ GLOBAL_LIST_INIT(TAGGERLOCATIONS, list(
"Detective's Office",
))

#if defined(UNIT_TESTS) || defined(SPACEMAN_DMM)

GLOBAL_LIST_INIT(tagger_destination_areas, list(
"Disposals" = list(/area/maintenance/disposal),
"Cargo Bay" = list(/area/quartermaster),
"QM Office" = list(/area/quartermaster/qm, /area/quartermaster/qm_bedroom),
"Engineering" = list(/area/engine, /area/engineering),
"CE Office" = list(/area/crew_quarters/heads/chief),
"Atmospherics" = list(/area/engine/atmos, /area/engine/atmospherics_engine),
"Security" = list(/area/security),
"HoS Office" = list(/area/crew_quarters/heads/hos),
"Medbay" = list(/area/medical),
"CMO Office" = list(/area/crew_quarters/heads/cmo),
"Chemistry" = list(/area/medical/chemistry),
"Research" = list(/area/science),
"RD Office" = list(/area/crew_quarters/heads/hor),
"Robotics" = list(/area/science/robotics),
"HoP Office" = list(/area/crew_quarters/heads/hop),
"Library" = list(/area/library),
"Chapel" = list(/area/chapel),
"Theatre" = list(/area/crew_quarters/theatre),
"Bar" = list(/area/crew_quarters/bar),
"Kitchen" = list(/area/crew_quarters/kitchen),
"Hydroponics" = list(/area/hydroponics),
"Janitor Closet" = list(/area/janitor),
"Genetics" = list(/area/medical/genetics),
"Testing Range" = list(/area/science/misc_lab, /area/science/test_area, /area/science/mixing),
"Toxins" = list(/area/science/misc_lab, /area/science/test_area, /area/science/mixing),
"Dormitories" = list(/area/crew_quarters/dorms, /area/commons/dorms),
"Virology" = list(/area/medical/virology),
"Xenobiology" = list(/area/science/xenobiology),
"Law Office" = list(/area/lawoffice),
"Detective's Office" = list(/area/security/detectives_office),
))

#endif

GLOBAL_LIST_INIT(station_prefixes, world.file2list("strings/station_prefixes.txt") + "")

GLOBAL_LIST_INIT(station_names, world.file2list("strings/station_names.txt") + "")
Expand Down
6 changes: 6 additions & 0 deletions code/modules/unit_tests/mapping/check_active_turfs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/datum/unit_test/map_test/active_turfs/check_map()
var/list/failures = list()
for(var/turf/t in GLOB.active_turfs_startlist)
failures += "Roundstart active turf at ([t.x], [t.y], [t.z] in [t.loc])"
if (length(failures))
TEST_FAIL(jointext(failures, "\n"))
7 changes: 7 additions & 0 deletions code/modules/unit_tests/mapping/check_area_apc.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/datum/unit_test/map_test/apc/check_area(area/check_area)
if (!check_area.requires_power)
return
if (!check_area.apc && !check_area.always_unpowered)
return "No APC in an area that requires power"
if (check_area.apc && check_area.always_unpowered)
return "APC found in an always unpowered area"
8 changes: 8 additions & 0 deletions code/modules/unit_tests/mapping/check_camera_attachment.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/datum/unit_test/map_test/camera/check_turf(turf/check_turf, is_map_border)
var/found = FALSE
for (var/obj/machinery/camera/camera in check_turf)
if (found)
return "Multiple cameras detected"
if (!isclosedturf(get_step(check_turf, camera.dir)))
return "Camera not attached to a wall"
found = TRUE
73 changes: 73 additions & 0 deletions code/modules/unit_tests/mapping/check_disposals.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/obj/structure/disposalpipe/var/_traversed = 0

/datum/unit_test/map_test/check_disposals
var/failure_reason
var/is_sorting_network

// Find all entries into the disposal system
/datum/unit_test/map_test/check_disposals/collect_targets(list/turfs)
var/located = list()
for (var/turf/check_turf in turfs)
var/found = locate(/obj/machinery/disposal)
if (found)
located += found
return located

// Make sure that we can end up in the correct location
/datum/unit_test/map_test/check_disposals/check_target(obj/machinery/disposal/target)
var/list/failures = list()
failure_reason = null
is_sorting_network = FALSE
if (!target.trunk)
return "[target.name] not attached to a trunk"
// Create a terrible disposal holder object
var/obj/structure/disposalholder/holder = new()
traverse_loop(target.trunk, holder)
// Abuse byonds variables to get out (We can use pointers as an out variable in 515)
if (failure_reason)
failures += failure_reason
// This is fine, we probably are a bin that leads to space or something
if (!is_sorting_network)
return failures
holder.last_pipe = null
holder.current_pipe = null
failure_reason = null
// Since we have filters, lets make sure this is a proper, fully connected and fully functioning loop
// We should be able to enter the loop at any point from an input gate to get to our destination
for (var/sort_code in GLOB.TAGGERLOCATIONS)
holder.destinationTag = sort_code
var/obj/structure/disposaloutlet/destination = traverse_loop(target.trunk, holder)
if (failure_reason)
return failure_reason
var/arrived = FALSE
for (var/valid_destination in GLOB.tagger_destination_areas[sort_code])
if (istype(get_area(destination), valid_destination))
arrived = TRUE
break
if (!arrived)
failures += "Disposal track starting at [COORD(target)] does not end up in the correct destination. Expected [sort_code], got [get_area(destination)] at [COORD(destination)]"
return failures

/datum/unit_test/map_test/check_disposals/proc/traverse_loop(obj/structure/disposalholder/holder, obj/structure/disposalpipe/start)
// First check to ensure that we end up somewhere
var/obj/structure/disposalpipe/current = holder
while (current)
holder.current_pipe = current
var/turf/T = get_step(current, current.nextdir(holder))
current = locate(/obj/structure/disposalpipe) in T
// Found a valid ending
if (locate(/obj/structure/disposaloutlet) in T)
return locate(/obj/structure/disposaloutlet)
// Detect ending back at an input
if (locate(/obj/machinery/disposal) in T)
failure_reason = "Disposal loop starting at [COORD(start)] leads to an input node at [COORD(T)] but should lead to an outlet"
if (locate(/obj/structure/disposalpipe/sorting))
is_sorting_network = TRUE
// End detection
if (current == null)
failure_reason = "Disposal network starting at [COORD(start)] has a pipe with no output at [COORD(T)] but should lead to an outlet"
// Loop detection
if (current._traversed == 1)
failure_reason = "Disposal network starting at [COORD(start)] contains a loop at [COORD(T)] which is not allowed"
current._traversed = 1
holder.last_pipe = current
10 changes: 10 additions & 0 deletions code/modules/unit_tests/mapping/check_light_attachment.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/datum/unit_test/map_test/lights/check_turf(turf/check_turf, is_map_border)
var/found = FALSE
for (var/obj/machinery/light/light in check_turf)
if (istype(light, /obj/machinery/light/floor))
continue
if (found)
return "Multiple lights detected"
if (!isclosedturf(get_step(check_turf, light.dir)))
return "Light not attached to a wall"
found = TRUE
42 changes: 32 additions & 10 deletions code/modules/unit_tests/mapping/map_test.dm
Original file line number Diff line number Diff line change
@@ -1,38 +1,60 @@
/datum/unit_test/map_test/Run()
var/list/failures
var/list/areas = list()
var/list/turfs = list()
// Check turfs
for (var/z in 1 to world.maxz)
if (!is_station_level(z))
continue
for (var/x in 1 to world.maxx)
for (var/y in 1 to world.maxy)
var/turf/tile = locate(x, y, z)
turfs += tile
areas[tile.loc] = TRUE
var/result = check_tile(tile, x == 1 || x == world.maxx || y == 1 || y == world.maxy)
var/result = check_turf(tile, x == 1 || x == world.maxx || y == 1 || y == world.maxy)
if (result)
LAZYADD(failures, result)
LAZYADD(failures, "([x], [y], [z]): [result]")
// Check areas
for (var/area/A in areas)
var/result = check_area(A)
if (result)
LAZYADD(failures, result)
if (LAZYLEN(failures))
TEST_FAIL(jointext(failures, "\n"))
LAZYADD(failures, "([A.type]): [result]")
// Check Zs
for (var/z in 1 to world.maxz)
if (!is_station_level(z))
continue
var/result = check_z_level(z)
if (result)
LAZYADD(failures, result)
// Get things we want to specifically test for
var/list/targets = collect_targets(turfs)
for (var/target in targets)
var/result = check_target(target)
if (result)
LAZYADD(failures, result)
// Full map general checks
var/result = check_map()
if (result)
LAZYADD(failures, result)
// Fail if necessary
if (LAZYLEN(failures))
TEST_FAIL(jointext(failures, "\n"))

/// Return a string if failed, return null otherwise
/datum/unit_test/map_test/proc/check_turf(turf/check_turf, is_map_border)

/// Return a string if failed, return null otherwise
/datum/unit_test/map_test/proc/check_tile(turf/T, is_map_border)
/datum/unit_test/map_test/proc/check_map(turf/check_turf, is_map_border)

/// Return a string if failed, return null otherwise
/datum/unit_test/map_test/proc/check_area(area/T)
/datum/unit_test/map_test/proc/check_area(area/check_area)

/// Return a string if failed, return null otherwise
/datum/unit_test/map_test/proc/check_z_level(z_value)

/datum/unit_test/map_test/test/check_tile(turf/T, is_map_border)
if (istype(T, /turf/closed/wall))
return "[T.type] detected"
/// Returns a list of things that you want to specifically check
/datum/unit_test/map_test/proc/collect_targets(list/turfs)
return list()

/// Return a string if failed, return null otherwise
/datum/unit_test/map_test/proc/check_target(atom/target)

0 comments on commit 3ea806e

Please sign in to comment.