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)]"