fix #H7205, #H7120, #H5216 - sortloot

H7205 - full-pack identify might skip items if perm_invent is on
        because updating the inventory window might reorder 'invent'
        while the identify code is in the midst of traversing it;
H7120 - pickup that doesn't pick anything up can change the glyph
        shown on the map because the pile might be reordered such
        that a different item is on top;
H5216 - performing a sortloot operation on a pile and then switching
        back to sortloot:none doesn't restore pile's original order.

The 'revamp' that changed the contributed sortloot feature to switch
to simpler usage (object list itself was sorted rather than having a
parallel array that needed to be constructed, sorted, traversed, and
discarded) turns out to have too many problems.  This reverts to a
hybrid solution that constructs an array for traversal, leaving the
linked list in its original order, but hides most of the details of
that from sortloot() callers.  The 'revamp' benefit of being able to
use normal list traversal is lost, as is the potential to skip
sorting when the list turns out to already be in the desired order.

This could stand to have a lot more testing than it's had so far.
This commit is contained in:
PatR
2018-06-09 18:03:37 -07:00
parent fc2d38ed50
commit c7f357e783
7 changed files with 176 additions and 41 deletions

View File

@@ -934,7 +934,9 @@ E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
/* ### invent.c ### */
E void FDECL(sortloot, (struct obj **, unsigned, BOOLEAN_P));
E Loot *FDECL(sortloot, (struct obj **, unsigned, BOOLEAN_P,
boolean (*)(OBJ_P)));
E void FDECL(unsortloot, (Loot **));
E void FDECL(assigninvlet, (struct obj *));
E struct obj *FDECL(merge_choice, (struct obj *, struct obj *));
E int FDECL(merged, (struct obj **, struct obj **));
@@ -2841,6 +2843,7 @@ E void FDECL(bypass_obj, (struct obj *));
E void NDECL(clear_bypasses);
E void FDECL(bypass_objlist, (struct obj *, BOOLEAN_P));
E struct obj *FDECL(nxt_unbypassed_obj, (struct obj *));
E struct obj *FDECL(nxt_unbypassed_loot, (Loot *, struct obj *));
E int FDECL(racial_exception, (struct monst *, struct obj *));
/* ### write.c ### */