diff --git a/code/WorkInProgress/Mini/atmos_control.dm b/code/WorkInProgress/Mini/atmos_control.dm
index 60756fb2ee..8e9b63f9e5 100644
--- a/code/WorkInProgress/Mini/atmos_control.dm
+++ b/code/WorkInProgress/Mini/atmos_control.dm
@@ -35,7 +35,7 @@
if(current)
dat += specific()
else
- for(var/obj/machinery/alarm/alarm in machines)
+ for(var/obj/machinery/alarm/alarm in dd_sortedObjectList(machines))
dat += ""
switch(max(alarm.danger_level, alarm.alarm_area.atmosalm))
if (0)
@@ -44,7 +44,7 @@
dat += ""
if (2)
dat += ""
- dat += "[alarm]
"
+ dat += "[sanitize(alarm.name)]
"
user << browse(dat, "window=atmoscontrol")
/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob)
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index 5f559b62cb..ae85f2fc46 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -399,3 +399,131 @@ proc/listclearnulls(list/list)
var/list/out = insertion_sort_numeric_list_ascending(L)
//world.log << " output: [out.len]"
return reverselist(out)
+
+proc/dd_sortedObjectList(list/incoming)
+ /*
+ Use binary search to order by dd_SortValue().
+ This works by going to the half-point of the list, seeing if the node in
+ question is higher or lower cost, then going halfway up or down the list
+ and checking again. This is a very fast way to sort an item into a list.
+ */
+ var/list/sorted_list = new()
+ var/low_index
+ var/high_index
+ var/insert_index
+ var/midway_calc
+ var/current_index
+ var/current_item
+ var/current_item_value
+ var/current_sort_object_value
+ var/list/list_bottom
+
+ var/current_sort_object
+ for (current_sort_object in incoming)
+ low_index = 1
+ high_index = sorted_list.len
+ while (low_index <= high_index)
+ // Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
+ midway_calc = (low_index + high_index) / 2
+ current_index = round(midway_calc)
+ if (midway_calc > current_index)
+ current_index++
+ current_item = sorted_list[current_index]
+
+ current_item_value = current_item:dd_SortValue()
+ current_sort_object_value = current_sort_object:dd_SortValue()
+ if (current_sort_object_value < current_item_value)
+ high_index = current_index - 1
+ else if (current_sort_object_value > current_item_value)
+ low_index = current_index + 1
+ else
+ // current_sort_object == current_item
+ low_index = current_index
+ break
+
+ // Insert before low_index.
+ insert_index = low_index
+
+ // Special case adding to end of list.
+ if (insert_index > sorted_list.len)
+ sorted_list += current_sort_object
+ continue
+
+ // Because BYOND lists don't support insert, have to do it by:
+ // 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
+ list_bottom = sorted_list.Copy(insert_index)
+ sorted_list.Cut(insert_index)
+ sorted_list += current_sort_object
+ sorted_list += list_bottom
+ return sorted_list
+
+
+proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
+ // Returns a new list with the text values sorted.
+ // Use binary search to order by sortValue.
+ // This works by going to the half-point of the list, seeing if the node in question is higher or lower cost,
+ // then going halfway up or down the list and checking again.
+ // This is a very fast way to sort an item into a list.
+ var/list/sorted_text = new()
+ var/low_index
+ var/high_index
+ var/insert_index
+ var/midway_calc
+ var/current_index
+ var/current_item
+ var/list/list_bottom
+ var/sort_result
+
+ var/current_sort_text
+ for (current_sort_text in incoming)
+ low_index = 1
+ high_index = sorted_text.len
+ while (low_index <= high_index)
+ // Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
+ midway_calc = (low_index + high_index) / 2
+ current_index = round(midway_calc)
+ if (midway_calc > current_index)
+ current_index++
+ current_item = sorted_text[current_index]
+
+ if (case_sensitive)
+ sort_result = sorttextEx(current_sort_text, current_item)
+ else
+ sort_result = sorttext(current_sort_text, current_item)
+
+ switch(sort_result)
+ if (1)
+ high_index = current_index - 1 // current_sort_text < current_item
+ if (-1)
+ low_index = current_index + 1 // current_sort_text > current_item
+ if (0)
+ low_index = current_index // current_sort_text == current_item
+ break
+
+ // Insert before low_index.
+ insert_index = low_index
+
+ // Special case adding to end of list.
+ if (insert_index > sorted_text.len)
+ sorted_text += current_sort_text
+ continue
+
+ // Because BYOND lists don't support insert, have to do it by:
+ // 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
+ list_bottom = sorted_text.Copy(insert_index)
+ sorted_text.Cut(insert_index)
+ sorted_text += current_sort_text
+ sorted_text += list_bottom
+ return sorted_text
+
+
+proc/dd_sortedTextList(list/incoming)
+ var/case_sensitive = 1
+ return dd_sortedtextlist(incoming, case_sensitive)
+
+
+datum/proc/dd_SortValue()
+ return "[src]"
+
+/obj/machinery/dd_SortValue()
+ return "[sanitize(name)]"