MCPcopy Create free account
hub / github.com/NetHack/NetHack / sortloot

Function sortloot

src/invent.c:592–643  ·  view source on GitHub ↗

* sortloot() - the story so far... * * The original implementation constructed and returned an array * of pointers to objects in the requested order. Callers had to * count the number of objects, allocate the array, pass one * object at a time to the routine which populates it, traverse * the objects via stepping through the array, then free the * array. The

Source from the content-addressed store, hash-verified

590 * instead of simple 'struct obj *' entries.
591 */
592Loot *
593sortloot(
594 struct obj **olist, /* old version might have changed *olist, we don't */
595 unsigned mode, /* flags for sortloot_cmp() */
596 boolean by_nexthere, /* T: traverse via obj->nexthere, F: via obj->nobj */
597 boolean (*filterfunc)(struct obj *)) /* optional filter */
598{
599 static Loot zerosli;
600 Loot *sliarray;
601 struct obj *o;
602 unsigned n, i;
603 boolean augment_filter;
604
605 for (n = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj)
606 ++n;
607 /* note: if there is a filter function, this might overallocate */
608 sliarray = (Loot *) alloc((n + 1) * sizeof *sliarray);
609
610 /* the 'keep cockatrice corpses' flag is overloaded with sort mode */
611 augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE;
612 mode &= ~SORTLOOT_PETRIFY; /* remove flag, leaving mode */
613 /* populate aliarray[0..n-1] */
614 for (i = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj) {
615 if (filterfunc && !(*filterfunc)(o)
616 /* caller may be asking us to override filterfunc (in order
617 to do a cockatrice corpse touch check during pickup even
618 if/when the filter rejects food class) */
619 && (!augment_filter || o->otyp != CORPSE
620 || !touch_petrifies(&mons[o->corpsenm])))
621 continue;
622 sliarray[i] = zerosli;
623 sliarray[i].obj = o, sliarray[i].indx = (int) i;
624 ++i;
625 }
626 n = i;
627 /* add a terminator so that we don't have to pass 'n' back to caller */
628 sliarray[n] = zerosli;
629 sliarray[n].indx = -1;
630
631 /* do the sort; if no sorting is requested, we'll just return
632 a sortloot_item array reflecting the current ordering */
633 if (mode && n > 1) {
634 gs.sortlootmode = mode; /* extra input for sortloot_cmp() */
635 qsort((genericptr_t) sliarray, n, sizeof *sliarray, sortloot_cmp);
636 gs.sortlootmode = 0; /* reset static mode flags */
637 /* if sortloot_cmp formatted any objects, discard their strings now */
638 for (i = 0; i < n; ++i)
639 if (sliarray[i].str)
640 free((genericptr_t) sliarray[i].str), sliarray[i].str = 0;
641 }
642 return sliarray;
643}
644
645/* sortloot() callers should use this to free up memory it allocates */
646void

Callers 5

container_contentsFunction · 0.85
getobjFunction · 0.85
askchainFunction · 0.85
invent.cFile · 0.85
query_objlistFunction · 0.85

Calls 3

qsortFunction · 0.85
sortloot_cmpFunction · 0.85
allocFunction · 0.70

Tested by

no test coverage detected