Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2018-06-18 20:14:41 -04:00
5 changed files with 73 additions and 57 deletions

View File

@@ -38,6 +38,7 @@ internals for 'sortloot' option have been changed to not reorder the actual
full-pack identify won't result in possibly skipping some items
give vault guards a cursed tin whistle since there is a shrill whistling
sound if hero teleports out of vault while being confronted by guard
polymorphing worn amulet triggers panic if it turns into amulet of change
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -2833,6 +2833,7 @@ E int FDECL(wseg_at, (struct monst *, int, int));
E void FDECL(setworn, (struct obj *, long));
E void FDECL(setnotworn, (struct obj *));
E struct obj *FDECL(wearmask_to_obj, (long));
E long FDECL(wearslot, (struct obj *));
E void FDECL(mon_set_minvis, (struct monst *));
E void FDECL(mon_adjust_speed, (struct monst *, int, struct obj *));

View File

@@ -1920,26 +1920,22 @@ dodip()
5, 95)) {
pline1(nothing_happens);
} else {
boolean was_wep, was_swapwep, was_quiver;
short save_otyp = obj->otyp;
/* KMH, conduct */
u.uconduct.polypiles++;
was_wep = (obj == uwep);
was_swapwep = (obj == uswapwep);
was_quiver = (obj == uquiver);
obj = poly_obj(obj, STRANGE_OBJECT);
if (was_wep)
setuwep(obj);
else if (was_swapwep)
setuswapwep(obj);
else if (was_quiver)
setuqwep(obj);
if (obj->otyp != save_otyp) {
/*
* obj might be gone:
* poly_obj() -> set_wear() -> Amulet_on() -> useup()
* if obj->otyp is worn amulet and becomes AMULET_OF_CHANGE.
*/
if (!obj) {
makeknown(POT_POLYMORPH);
return 1;
} else if (obj->otyp != save_otyp) {
makeknown(POT_POLYMORPH);
useup(potion);
prinv((char *) 0, obj, 0L);

View File

@@ -29,7 +29,8 @@ const struct worn {
{ W_TOOL, &ublindf },
{ W_BALL, &uball },
{ W_CHAIN, &uchain },
{ 0, 0 } };
{ 0, 0 }
};
/* This only allows for one blocking item per property */
#define w_blocks(o, m) \
@@ -142,6 +143,19 @@ register struct obj *obj;
update_inventory();
}
/* return item worn in slot indiciated by wornmask; needed by poly_obj() */
struct obj *
wearmask_to_obj(wornmask)
long wornmask;
{
const struct worn *wp;
for (wp = worn; wp->w_mask; wp++)
if (wp->w_mask & wornmask)
return *wp->w_obj;
return (struct obj *) 0;
}
/* return a bitmask of the equipment slot(s) a given item might be worn in */
long
wearslot(obj)

View File

@@ -1392,7 +1392,8 @@ struct obj *obj;
int id;
{
struct obj *otmp;
xchar ox, oy;
xchar ox = 0, oy = 0;
long old_wornmask, new_wornmask = 0L;
boolean can_merge = (id == STRANGE_OBJECT);
int obj_location = obj->where;
@@ -1567,41 +1568,12 @@ int id;
/* update the weight */
otmp->owt = weight(otmp);
/* handle polymorph of worn item: stone-to-flesh cast on self can
affect multiple objects at once, but their new forms won't
produce any side-effects; a single worn item dipped into potion
of polymorph can produce side-effects but those won't yield out
of sequence messages because current polymorph is finished */
if (obj_location == OBJ_INVENT && obj->owornmask) {
long old_wornmask = obj->owornmask & ~(W_ART | W_ARTI),
new_wornmask = wearslot(otmp);
boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap;
remove_worn_item(obj, TRUE);
/* if the new form can be worn in the same slot, make it so
[possible extension: if it could be worn in some other
slot which is currently unfilled, wear it there instead] */
if ((old_wornmask & W_QUIVER) != 0L) {
setuqwep(otmp);
} else if ((old_wornmask & W_SWAPWEP) != 0L) {
if (was_twohanded || !bimanual(otmp))
setuswapwep(otmp);
if (was_twoweap && uswapwep)
u.twoweap = TRUE;
} else if ((old_wornmask & W_WEP) != 0L) {
if (was_twohanded || !bimanual(otmp) || !uarms)
setuwep(otmp);
if (was_twoweap && uwep && !bimanual(uwep))
u.twoweap = TRUE;
} else if ((old_wornmask & new_wornmask) != 0L) {
new_wornmask &= old_wornmask;
setworn(otmp, new_wornmask);
set_wear(otmp); /* Armor_on() for side-effects */
}
}
/* ** we are now done adjusting the object ** */
/*
* ** we are now done adjusting the object (except possibly wearing it) **
*/
(void) get_obj_location(obj, &ox, &oy, BURIED_TOO | CONTAINED_TOO);
old_wornmask = obj->owornmask & ~(W_ART | W_ARTI);
/* swap otmp for obj */
replace_object(obj, otmp);
if (obj_location == OBJ_INVENT) {
@@ -1614,8 +1586,42 @@ int id;
freeinv_core(obj);
addinv_core1(otmp);
addinv_core2(otmp);
/*
* Handle polymorph of worn item. Stone-to-flesh cast on self can
* affect multiple objects at once, but their new forms won't
* produce any side-effects. A single worn item dipped into potion
* of polymorph can produce side-effects but those won't yield out
* of sequence messages because current polymorph is finished.
*/
if (old_wornmask) {
boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap;
/* wearslot() returns a mask which might have multiple bits set;
narrow that down to the bit(s) currently in use */
new_wornmask = wearslot(otmp) & old_wornmask;
remove_worn_item(obj, TRUE);
/* if the new form can be worn in the same slot, make it so */
if ((new_wornmask & W_WEP) != 0L) {
if (was_twohanded || !bimanual(otmp) || !uarms)
setuwep(otmp);
if (was_twoweap && uwep && !bimanual(uwep))
u.twoweap = TRUE;
} else if ((new_wornmask & W_SWAPWEP) != 0L) {
if (was_twohanded || !bimanual(otmp))
setuswapwep(otmp);
if (was_twoweap && uswapwep)
u.twoweap = TRUE;
} else if ((new_wornmask & W_QUIVER) != 0L) {
setuqwep(otmp);
} else if (new_wornmask) {
setworn(otmp, new_wornmask);
/* set_wear() might result in otmp being destroyed if
worn amulet has been turned into an amulet of change */
set_wear(otmp);
otmp = wearmask_to_obj(new_wornmask); /* might be Null */
}
} /* old_wornmask */
} else if (obj_location == OBJ_FLOOR) {
ox = otmp->ox, oy = otmp->oy; /* set by replace_object() */
if (obj->otyp == BOULDER && otmp->otyp != BOULDER
&& !does_block(ox, oy, &levl[ox][oy]))
unblock_point(ox, oy);
@@ -1624,11 +1630,9 @@ int id;
block_point(ox, oy);
}
if ((!carried(otmp) || obj->unpaid)
&& get_obj_location(otmp, &ox, &oy, BURIED_TOO | CONTAINED_TOO)
&& costly_spot(ox, oy)) {
register struct monst *shkp =
shop_keeper(*in_rooms(ox, oy, SHOPBASE));
/* note: if otmp is gone, billing for it was handled by useup() */
if (((otmp && !carried(otmp)) || obj->unpaid) && costly_spot(ox, oy)) {
struct monst *shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE));
if ((!obj->no_charge
|| (Has_contents(obj)
@@ -1636,8 +1640,8 @@ int id;
&& inhishop(shkp)) {
if (shkp->mpeaceful) {
if (*u.ushops
&& *in_rooms(u.ux, u.uy, 0)
== *in_rooms(shkp->mx, shkp->my, 0)
&& (*in_rooms(u.ux, u.uy, 0)
== *in_rooms(shkp->mx, shkp->my, 0))
&& !costly_spot(u.ux, u.uy)) {
make_angry_shk(shkp, ox, oy);
} else {