Add 'pickup_stolen' option
Add pickup_stolen option to autopick items stolen from you by a nymph or monkey, even if they don't match your normal autopickup settings. Replace was_dropped, was_thrown with a 2-bit bitfield that can contain values LOST_DROPPED, LOST_THROWN, and LOST_STOLEN (or 0), since they should all be mutually exclusive anyway as they track the most recent way the item left the hero's inventory. [Rebase/merge conflict fixed up. PR]
This commit is contained in:
@@ -50,6 +50,7 @@ null allow nulls to be sent to your terminal [True]
|
||||
try turning this option off (forcing NetHack to use its own
|
||||
delay code) if moving objects seem to teleport across rooms
|
||||
perm_invent keep inventory in a permanent window [False]
|
||||
pickup_stolen override pickup_types for stolen objects [True]
|
||||
pickup_thrown override pickup_types for thrown objects [True]
|
||||
pushweapon when wielding a new weapon, put your previously [False]
|
||||
wielded weapon into the secondary weapon slot
|
||||
|
||||
@@ -4394,6 +4394,15 @@ level (Unencumbered, Burdened, streSsed, straiNed, overTaxed,
|
||||
or overLoaded), you will be asked if you want to continue.
|
||||
(Default \(oqS\(cq).
|
||||
Persistent.
|
||||
.lp pickup_stolen
|
||||
If this option is on and
|
||||
.op autopickup
|
||||
is also on, try to pick up things that a monster stole from you, even if they
|
||||
aren't in
|
||||
.op pickup_types
|
||||
or match an autopickup exception.
|
||||
Default is on.
|
||||
Persistent.
|
||||
.lp pickup_thrown
|
||||
If this option is on and
|
||||
.op autopickup
|
||||
|
||||
@@ -4815,6 +4815,14 @@ level (Unencumbered, Burdened, streSsed, straiNed, overTaxed,
|
||||
or overLoaded), you will be asked if you want to continue.
|
||||
(Default `S'). Persistent.
|
||||
%.lp
|
||||
\item[\ib{pickup\verb+_+stolen}]
|
||||
If this option is on and ``{\it autopickup\/}'' is also on, try to pick up
|
||||
things that a monster stole from you, even if they aren't in
|
||||
``{\it pickup\verb+_+types\/}'' or
|
||||
match an autopickup exception.
|
||||
Default is on.
|
||||
Persistent.
|
||||
%.lp
|
||||
\item[\ib{pickup\verb+_+thrown}]
|
||||
If this option is on and ``{\it autopickup\/}'' is also on, try to pick up
|
||||
things that you threw, even if they aren't in
|
||||
|
||||
@@ -48,6 +48,7 @@ struct flag {
|
||||
boolean nopick_dropped; /* items you dropped may be autopicked */
|
||||
boolean null; /* OK to send nulls to the terminal */
|
||||
boolean pickup; /* whether you pickup or move and look */
|
||||
boolean pickup_stolen; /* auto-pickup items stolen by a monster */
|
||||
boolean pickup_thrown; /* auto-pickup items you threw */
|
||||
boolean pushweapon; /* When wielding, push old weapon into second slot */
|
||||
boolean quick_farsight; /* True disables map browsing during random
|
||||
|
||||
@@ -124,10 +124,9 @@ struct obj {
|
||||
#define on_ice recharged /* corpse on ice */
|
||||
Bitfield(lamplit, 1); /* a light-source -- can be lit */
|
||||
Bitfield(globby, 1); /* combines with like types on adjacent squares */
|
||||
Bitfield(greased, 1); /* covered with grease */
|
||||
Bitfield(nomerge, 1); /* set temporarily to prevent merging */
|
||||
Bitfield(was_thrown, 1); /* thrown by hero since last picked up */
|
||||
Bitfield(was_dropped, 1); /* dropped deliberately by the hero */
|
||||
Bitfield(greased, 1); /* covered with grease */
|
||||
Bitfield(nomerge, 1); /* set temporarily to prevent merging */
|
||||
Bitfield(how_lost, 2); /* stolen by mon or thrown, dropped by hero */
|
||||
|
||||
Bitfield(in_use, 1); /* for magic items before useup items */
|
||||
Bitfield(bypass, 1); /* mark this as an object to be skipped by bhito() */
|
||||
@@ -459,6 +458,12 @@ struct obj {
|
||||
#define POTHIT_MONST_THROW 2 /* thrown by a monster */
|
||||
#define POTHIT_OTHER_THROW 3 /* propelled by some other means [scatter()] */
|
||||
|
||||
/* tracking how an item left your inventory */
|
||||
#define LOST_NONE 0 /* still in inventory, or method not covered below */
|
||||
#define LOST_THROWN 1 /* thrown or fired by the hero */
|
||||
#define LOST_DROPPED 2 /* dropped or tipped out of a container by the hero */
|
||||
#define LOST_STOLEN 3 /* stolen from hero's inventory by a monster */
|
||||
|
||||
/*
|
||||
* Notes for adding new oextra structures:
|
||||
*
|
||||
|
||||
@@ -534,6 +534,9 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
||||
NHOPTC(pickup_burden, Advanced, 20, opt_in, set_in_game,
|
||||
No, Yes, No, Yes, NoAlias,
|
||||
"maximum burden picked up before prompt")
|
||||
NHOPTB(pickup_stolen, Behavior, 0, opt_out, set_in_game,
|
||||
On, Yes, No, No, NoAlias, &flags.pickup_stolen, Term_False,
|
||||
"autopickup thrown items")
|
||||
NHOPTB(pickup_thrown, Behavior, 0, opt_out, set_in_game,
|
||||
On, Yes, No, No, NoAlias, &flags.pickup_thrown, Term_False,
|
||||
"autopickup thrown items")
|
||||
|
||||
@@ -107,8 +107,7 @@ resetobjs(struct obj *ochain, boolean restore)
|
||||
otmp->cknown = 0;
|
||||
otmp->invlet = 0;
|
||||
otmp->no_charge = 0;
|
||||
otmp->was_thrown = 0;
|
||||
otmp->was_dropped = 0;
|
||||
otmp->how_lost = LOST_NONE;
|
||||
|
||||
/* strip user-supplied names */
|
||||
/* Statue and some corpse names are left intact,
|
||||
|
||||
2
src/do.c
2
src/do.c
@@ -760,7 +760,7 @@ drop(struct obj *obj)
|
||||
if (!IS_ALTAR(levl[u.ux][u.uy].typ) && flags.verbose)
|
||||
You("drop %s.", doname(obj));
|
||||
}
|
||||
obj->was_dropped = 1;
|
||||
obj->how_lost = LOST_DROPPED;
|
||||
dropx(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
@@ -1504,7 +1504,7 @@ throwit(struct obj *obj,
|
||||
}
|
||||
|
||||
gt.thrownobj = obj;
|
||||
gt.thrownobj->was_thrown = 1;
|
||||
gt.thrownobj->how_lost = LOST_THROWN;
|
||||
iflags.returning_missile = AutoReturn(obj, wep_mask) ? (genericptr_t) obj
|
||||
: (genericptr_t) 0;
|
||||
/* NOTE: No early returns after this point or returning_missile
|
||||
@@ -1719,7 +1719,7 @@ throwit(struct obj *obj,
|
||||
if (tethered_weapon)
|
||||
tmp_at(DISP_END, 0);
|
||||
/* when this location is stepped on, the weapon will be
|
||||
auto-picked up due to 'obj->was_thrown' of 1;
|
||||
auto-picked up due to 'obj->how_lost' of LOST_THROWN;
|
||||
addinv() prevents thrown Mjollnir from being placed
|
||||
into the quiver slot, but an aklys will end up there if
|
||||
that slot is empty at the time; since hero will need to
|
||||
|
||||
10
src/invent.c
10
src/invent.c
@@ -942,7 +942,8 @@ merged(struct obj **potmp, struct obj **pobj)
|
||||
items, where this would be too spammy as such items get
|
||||
unidentified by monsters very frequently). */
|
||||
if (discovered && otmp->where == OBJ_INVENT
|
||||
&& !obj->was_thrown && !otmp->was_thrown) {
|
||||
&& obj->how_lost != LOST_THROWN
|
||||
&& otmp->how_lost != LOST_THROWN) {
|
||||
pline("You learn more about your items by comparing them.");
|
||||
}
|
||||
|
||||
@@ -1049,8 +1050,8 @@ addinv_core0(struct obj *obj, struct obj *other_obj,
|
||||
obj->no_charge = 0; /* should not be set in hero's invent */
|
||||
if (Has_contents(obj))
|
||||
picked_container(obj); /* clear no_charge */
|
||||
obj_was_thrown = obj->was_thrown;
|
||||
obj->was_thrown = obj->was_dropped = 0; /* not meaningful for invent */
|
||||
obj_was_thrown = (obj->how_lost == LOST_THROWN);
|
||||
obj->how_lost = LOST_NONE;
|
||||
|
||||
if (gl.loot_reset_justpicked) {
|
||||
gl.loot_reset_justpicked = FALSE;
|
||||
@@ -4823,8 +4824,7 @@ mergable(
|
||||
if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe
|
||||
|| obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken
|
||||
|| obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit
|
||||
|| obj->was_thrown != otmp->was_thrown
|
||||
|| obj->was_dropped != otmp->was_dropped)
|
||||
|| obj->how_lost != otmp->how_lost)
|
||||
return FALSE;
|
||||
|
||||
if (obj->oclass == FOOD_CLASS
|
||||
|
||||
@@ -2863,9 +2863,10 @@ objlist_sanity(struct obj *objlist, int wheretype, const char *mesg)
|
||||
for (obj = objlist; obj; obj = obj->nobj) {
|
||||
if (obj->where != wheretype)
|
||||
insane_object(obj, ofmt0, mesg, (struct monst *) 0);
|
||||
if (obj->was_thrown && obj->was_dropped) {
|
||||
insane_object(obj, "%s obj is both thrown and dropped! %s %s: %s",
|
||||
mesg, obj->ocarry);
|
||||
if (obj->where == OBJ_INVENT && obj->how_lost != LOST_NONE) {
|
||||
char lostbuf[40];
|
||||
Sprintf(lostbuf, "how_lost=%d obj in inventory!", obj->how_lost);
|
||||
insane_object(obj, ofmt0, lostbuf, (struct monst *) 0);
|
||||
}
|
||||
if (Has_contents(obj)) {
|
||||
if (wheretype == OBJ_ONBILL)
|
||||
|
||||
@@ -312,7 +312,7 @@ l_obj_to_table(lua_State *L)
|
||||
nhl_add_table_entry_int(L, "globby", obj->globby);
|
||||
nhl_add_table_entry_int(L, "greased", obj->greased);
|
||||
nhl_add_table_entry_int(L, "nomerge", obj->nomerge);
|
||||
nhl_add_table_entry_int(L, "was_thrown", obj->was_thrown);
|
||||
nhl_add_table_entry_int(L, "how_lost", obj->how_lost);
|
||||
nhl_add_table_entry_int(L, "in_use", obj->in_use);
|
||||
nhl_add_table_entry_int(L, "bypass", obj->bypass);
|
||||
nhl_add_table_entry_int(L, "cknown", obj->cknown);
|
||||
|
||||
@@ -8594,6 +8594,7 @@ doset_simple_menu(void)
|
||||
spelling of their names; emphasize what it means */
|
||||
if (allopt[i].idx == opt_pickup_types
|
||||
|| allopt[i].idx == opt_pickup_thrown
|
||||
|| allopt[i].idx == opt_pickup_stolen
|
||||
|| allopt[i].idx == opt_dropped_nopick)
|
||||
Strcat(buf, " (for autopickup)");
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||
|
||||
12
src/pickup.c
12
src/pickup.c
@@ -904,10 +904,12 @@ autopick_testobj(struct obj *otmp, boolean calc_costly)
|
||||
if (costly && !otmp->no_charge)
|
||||
return FALSE;
|
||||
|
||||
/* pickup_thrown/nopick_dropped override pickup_types and exceptions */
|
||||
if (flags.pickup_thrown && otmp->was_thrown)
|
||||
/* pickup_thrown/pickup_stolen/nopick_dropped override pickup_types and
|
||||
exceptions */
|
||||
if ((flags.pickup_thrown && otmp->how_lost == LOST_THROWN)
|
||||
|| (flags.pickup_stolen && otmp->how_lost == LOST_STOLEN))
|
||||
return TRUE;
|
||||
if (flags.nopick_dropped && otmp->was_dropped)
|
||||
if (flags.nopick_dropped && otmp->how_lost == LOST_DROPPED)
|
||||
return FALSE;
|
||||
|
||||
/* check for pickup_types */
|
||||
@@ -3667,7 +3669,7 @@ tipcontainer(struct obj *box) /* or bag */
|
||||
(void) add_to_container(targetbox, otmp);
|
||||
}
|
||||
} else if (highdrop) {
|
||||
otmp->was_dropped = 1;
|
||||
otmp->how_lost = LOST_DROPPED;
|
||||
/* might break or fall down stairs; handles altars itself */
|
||||
hitfloor(otmp, TRUE);
|
||||
} else {
|
||||
@@ -3680,7 +3682,7 @@ tipcontainer(struct obj *box) /* or bag */
|
||||
pline("%s%c", doname(otmp), nobj ? ',' : '.');
|
||||
iflags.last_msg = PLNMSG_OBJNAM_ONLY;
|
||||
}
|
||||
otmp->was_dropped = 1;
|
||||
otmp->how_lost = LOST_DROPPED;
|
||||
dropy(otmp);
|
||||
if (iflags.last_msg != PLNMSG_OBJNAM_ONLY)
|
||||
terse = FALSE; /* terse formatting has been interrupted */
|
||||
|
||||
@@ -527,6 +527,7 @@ steal(struct monst* mtmp, char* objnambuf)
|
||||
(void) encumber_msg();
|
||||
could_petrify = (otmp->otyp == CORPSE
|
||||
&& touch_petrifies(&mons[otmp->corpsenm]));
|
||||
otmp->how_lost = LOST_STOLEN;
|
||||
(void) mpickobj(mtmp, otmp); /* may free otmp */
|
||||
if (could_petrify && !(mtmp->misc_worn_check & W_ARMG)) {
|
||||
minstapetrify(mtmp, TRUE);
|
||||
|
||||
Reference in New Issue
Block a user