fix "object lost" panic after query_objlist
Reported directly to devteam for recent git code, the "sortloot revamp" patch could trigger an object lost panic after calling query_objlist() when menustyle was full or partial and player picked up a subset of available items. Modified head-of-list was not being propagated to its source in pickup(). Use an extra layer of indirection.
This commit is contained in:
@@ -192,6 +192,7 @@ female gnome who gains level can grow up into male-only gnome lord; give an
|
|||||||
an alternate message instead of prohibiting the promotion
|
an alternate message instead of prohibiting the promotion
|
||||||
kicked weapon which successfully hits monster vanishes from play
|
kicked weapon which successfully hits monster vanishes from play
|
||||||
unseen landmine explosion could result in "The <monst-type> statue crumbles."
|
unseen landmine explosion could result in "The <monst-type> statue crumbles."
|
||||||
|
post-3.6.0: fix "object lost" panic during pickup caused by sortloot revamp
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
+12
-11
@@ -464,7 +464,7 @@ int what; /* should be a long */
|
|||||||
int i, n, res, count, n_tried = 0, n_picked = 0;
|
int i, n, res, count, n_tried = 0, n_picked = 0;
|
||||||
menu_item *pick_list = (menu_item *) 0;
|
menu_item *pick_list = (menu_item *) 0;
|
||||||
boolean autopickup = what > 0;
|
boolean autopickup = what > 0;
|
||||||
struct obj *objchain;
|
struct obj **objchain_p;
|
||||||
int traverse_how;
|
int traverse_how;
|
||||||
|
|
||||||
/* we might have arrived here while fainted or sleeping, via
|
/* we might have arrived here while fainted or sleeping, via
|
||||||
@@ -522,10 +522,10 @@ int what; /* should be a long */
|
|||||||
|
|
||||||
add_valid_menu_class(0); /* reset */
|
add_valid_menu_class(0); /* reset */
|
||||||
if (!u.uswallow) {
|
if (!u.uswallow) {
|
||||||
objchain = level.objects[u.ux][u.uy];
|
objchain_p = &level.objects[u.ux][u.uy];
|
||||||
traverse_how = BY_NEXTHERE;
|
traverse_how = BY_NEXTHERE;
|
||||||
} else {
|
} else {
|
||||||
objchain = u.ustuck->minvent;
|
objchain_p = &u.ustuck->minvent;
|
||||||
traverse_how = 0; /* nobj */
|
traverse_how = 0; /* nobj */
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -535,7 +535,7 @@ int what; /* should be a long */
|
|||||||
* to make things less confusing.
|
* to make things less confusing.
|
||||||
*/
|
*/
|
||||||
if (autopickup) {
|
if (autopickup) {
|
||||||
n = autopick(objchain, traverse_how, &pick_list);
|
n = autopick(*objchain_p, traverse_how, &pick_list);
|
||||||
goto menu_pickup;
|
goto menu_pickup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,16 +547,17 @@ int what; /* should be a long */
|
|||||||
|
|
||||||
Sprintf(qbuf, "Pick %d of what?", count);
|
Sprintf(qbuf, "Pick %d of what?", count);
|
||||||
val_for_n_or_more = count; /* set up callback selector */
|
val_for_n_or_more = count; /* set up callback selector */
|
||||||
n = query_objlist(qbuf, &objchain, traverse_how,
|
n = query_objlist(qbuf, objchain_p, traverse_how,
|
||||||
&pick_list, PICK_ONE, n_or_more);
|
&pick_list, PICK_ONE, n_or_more);
|
||||||
/* correct counts, if any given */
|
/* correct counts, if any given */
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
pick_list[i].count = count;
|
pick_list[i].count = count;
|
||||||
} else {
|
} else {
|
||||||
n = query_objlist("Pick up what?", &objchain,
|
n = query_objlist("Pick up what?", objchain_p,
|
||||||
(traverse_how | FEEL_COCKATRICE),
|
(traverse_how | FEEL_COCKATRICE),
|
||||||
&pick_list, PICK_ANY, all_but_uchain);
|
&pick_list, PICK_ANY, all_but_uchain);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu_pickup:
|
menu_pickup:
|
||||||
n_tried = n;
|
n_tried = n;
|
||||||
for (n_picked = i = 0; i < n; i++) {
|
for (n_picked = i = 0; i < n; i++) {
|
||||||
@@ -582,12 +583,12 @@ int what; /* should be a long */
|
|||||||
selective = FALSE; /* ask for each item */
|
selective = FALSE; /* ask for each item */
|
||||||
|
|
||||||
/* check for more than one object */
|
/* check for more than one object */
|
||||||
for (obj = objchain; obj; obj = FOLLOW(obj, traverse_how))
|
for (obj = *objchain_p; obj; obj = FOLLOW(obj, traverse_how))
|
||||||
ct++;
|
ct++;
|
||||||
|
|
||||||
if (ct == 1 && count) {
|
if (ct == 1 && count) {
|
||||||
/* if only one thing, then pick it */
|
/* if only one thing, then pick it */
|
||||||
obj = objchain;
|
obj = *objchain_p;
|
||||||
lcount = min(obj->quan, (long) count);
|
lcount = min(obj->quan, (long) count);
|
||||||
n_tried++;
|
n_tried++;
|
||||||
if (pickup_object(obj, lcount, FALSE) > 0)
|
if (pickup_object(obj, lcount, FALSE) > 0)
|
||||||
@@ -599,14 +600,14 @@ int what; /* should be a long */
|
|||||||
|
|
||||||
There("are %s objects here.", (ct <= 10) ? "several" : "many");
|
There("are %s objects here.", (ct <= 10) ? "several" : "many");
|
||||||
if (!query_classes(oclasses, &selective, &all_of_a_type,
|
if (!query_classes(oclasses, &selective, &all_of_a_type,
|
||||||
"pick up", objchain,
|
"pick up", *objchain_p,
|
||||||
(traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
|
(traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
|
||||||
&via_menu)) {
|
&via_menu)) {
|
||||||
if (!via_menu)
|
if (!via_menu)
|
||||||
return 0;
|
return 0;
|
||||||
if (selective)
|
if (selective)
|
||||||
traverse_how |= INVORDER_SORT;
|
traverse_how |= INVORDER_SORT;
|
||||||
n = query_objlist("Pick up what?", &objchain, traverse_how,
|
n = query_objlist("Pick up what?", objchain_p, traverse_how,
|
||||||
&pick_list, PICK_ANY,
|
&pick_list, PICK_ANY,
|
||||||
(via_menu == -2) ? allow_all
|
(via_menu == -2) ? allow_all
|
||||||
: allow_category);
|
: allow_category);
|
||||||
@@ -614,7 +615,7 @@ int what; /* should be a long */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (obj = objchain; obj; obj = obj2) {
|
for (obj = *objchain_p; obj; obj = obj2) {
|
||||||
obj2 = FOLLOW(obj, traverse_how);
|
obj2 = FOLLOW(obj, traverse_how);
|
||||||
if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
|
if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user