Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-05-17 12:06:58 -04:00
7 changed files with 195 additions and 15 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.1 $ $NHDT-Date: 1557569075 2019/05/11 10:04:35 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.3 $ $NHDT-Date: 1558045586 2019/05/16 22:26:26 $
This fixes36.3 file is here to capture information about updates in the 3.6.x This fixes36.3 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.2 in May 2019. Please note, however, lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -11,6 +11,10 @@ when place_object() puts a non-boulder on the map at a spot which contains
other objects, put it under all boulders in the pile rather than just other objects, put it under all boulders in the pile rather than just
under the top one; previously, map wasn't showing a boulder there if under the top one; previously, map wasn't showing a boulder there if
the top one got moved by means other than pushing the top one got moved by means other than pushing
when examining the map with '/' or ';', picking a symbol which is used for
more than 4 things yielded a sentence lacking its terminating period
billing and payment issue as a result of glob coalescing
glob pricing did not consider weight properly
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository

View File

@@ -2265,6 +2265,8 @@ E boolean FDECL(block_door, (XCHAR_P, XCHAR_P));
E boolean FDECL(block_entry, (XCHAR_P, XCHAR_P)); E boolean FDECL(block_entry, (XCHAR_P, XCHAR_P));
E char *FDECL(shk_your, (char *, struct obj *)); E char *FDECL(shk_your, (char *, struct obj *));
E char *FDECL(Shk_Your, (char *, struct obj *)); E char *FDECL(Shk_Your, (char *, struct obj *));
E void FDECL(globby_bill_fixup, (struct obj *, struct obj *));
E void FDECL(globby_donation, (struct obj *, struct obj *));
/* ### shknam.c ### */ /* ### shknam.c ### */

View File

@@ -715,7 +715,8 @@ struct obj **potmp, **pobj;
otmp->age = ((otmp->age * otmp->quan) + (obj->age * obj->quan)) otmp->age = ((otmp->age * otmp->quan) + (obj->age * obj->quan))
/ (otmp->quan + obj->quan); / (otmp->quan + obj->quan);
otmp->quan += obj->quan; if (!otmp->globby)
otmp->quan += obj->quan;
/* temporary special case for gold objects!!!! */ /* temporary special case for gold objects!!!! */
if (otmp->oclass == COIN_CLASS) if (otmp->oclass == COIN_CLASS)
otmp->owt = weight(otmp), otmp->bknown = 0; otmp->owt = weight(otmp), otmp->bknown = 0;

View File

@@ -2755,6 +2755,10 @@ struct obj **obj1, **obj2;
otmp1 = *obj1; otmp1 = *obj1;
otmp2 = *obj2; otmp2 = *obj2;
if (otmp1 && otmp2 && otmp1 != otmp2) { if (otmp1 && otmp2 && otmp1 != otmp2) {
if (otmp1->unpaid || otmp2->unpaid)
globby_bill_fixup(otmp1, otmp2);
else if (costly_spot(otmp1->ox, otmp1->oy))
globby_donation(otmp1, otmp2);
if (otmp1->bknown != otmp2->bknown) if (otmp1->bknown != otmp2->bknown)
otmp1->bknown = otmp2->bknown = 0; otmp1->bknown = otmp2->bknown = 0;
if (otmp1->rknown != otmp2->rknown) if (otmp1->rknown != otmp2->rknown)
@@ -2837,7 +2841,12 @@ struct obj *otmp2;
* they'll be out of our view (minvent or container) * they'll be out of our view (minvent or container)
* so don't actually show anything */ * so don't actually show anything */
} else if (onfloor || inpack) { } else if (onfloor || inpack) {
pline("The %s coalesce%s.", makeplural(obj_typename(otmp->otyp)), boolean adj = ((otmp->ox != u.ux || otmp->oy != u.uy) &&
(otmp2->ox != u.ux || otmp2->oy != u.uy));
pline("The %s%s coalesce%s.",
(onfloor && adj) ? "adjacent " : "",
makeplural(obj_typename(otmp->otyp)),
inpack ? " inside your pack" : ""); inpack ? " inside your pack" : "");
} }
} else { } else {

View File

@@ -25,6 +25,7 @@ STATIC_DCL boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P,
STATIC_DCL char *FDECL(singplur_compound, (char *)); STATIC_DCL char *FDECL(singplur_compound, (char *));
STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned)); STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
STATIC_DCL boolean FDECL(badman, (const char *, BOOLEAN_P)); STATIC_DCL boolean FDECL(badman, (const char *, BOOLEAN_P));
STATIC_DCL char *FDECL(globwt, (struct obj *, char *));
struct Jitem { struct Jitem {
int item; int item;
@@ -1214,11 +1215,12 @@ unsigned doname_flags;
} else if (with_price) { /* on floor or in container on floor */ } else if (with_price) { /* on floor or in container on floor */
int nochrg = 0; int nochrg = 0;
long price = get_cost_of_shop_item(obj, &nochrg); long price = get_cost_of_shop_item(obj, &nochrg);
char globbuf[BUFSZ];
if (price > 0L) if (price > 0L)
Sprintf(eos(bp), " (%s, %ld %s)", Sprintf(eos(bp), " (%s, %s%ld %s)",
nochrg ? "contents" : "for sale", nochrg ? "contents" : "for sale",
price, currency(price)); globwt(obj, globbuf), price, currency(price));
else if (nochrg > 0) else if (nochrg > 0)
Strcat(bp, " (no charge)"); Strcat(bp, " (no charge)");
} }
@@ -4195,4 +4197,16 @@ const char *lastR;
return qbuf; return qbuf;
} }
STATIC_OVL char *
globwt(otmp, buf)
struct obj *otmp;
char *buf;
{
if (otmp && buf && otmp->globby && otmp->quan == 1L) {
Sprintf(buf, "%ld aum, ", otmp->owt);
return buf;
}
return "";
}
/*objnam.c*/ /*objnam.c*/

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 pager.c $NHDT-Date: 1555627307 2019/04/18 22:41:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.151 $ */ /* NetHack 3.6 pager.c $NHDT-Date: 1558045586 2019/05/16 22:26:26 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.153 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2018. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1042,7 +1042,10 @@ struct permonst **for_supplement;
*/ */
if (found > 4) if (found > 4)
Sprintf(out_str, "%s", "That can be many things"); /* 3.6.3: this used to be "That can be many things" (without prefix)
which turned it into a sentence that lacked its terminating period;
we could add one below but reinstating the prefix here is better */
Sprintf(out_str, "%scan be many things", prefix);
didlook: didlook:
if (looked) { if (looked) {

163
src/shk.c
View File

@@ -74,6 +74,7 @@ STATIC_DCL void FDECL(deserted_shop, (char *));
STATIC_DCL boolean FDECL(special_stock, (struct obj *, struct monst *, STATIC_DCL boolean FDECL(special_stock, (struct obj *, struct monst *,
BOOLEAN_P)); BOOLEAN_P));
STATIC_DCL const char *FDECL(cad, (BOOLEAN_P)); STATIC_DCL const char *FDECL(cad, (BOOLEAN_P));
STATIC_DCL long FDECL(get_pricing_units, (struct obj *obj));
/* /*
invariants: obj->unpaid iff onbill(obj) [unless bp->useup] invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
@@ -2009,14 +2010,34 @@ int *nochrg; /* alternate return value: 1: no charge, 0: shop owned, */
items on freespot are implicitly 'no charge' */ items on freespot are implicitly 'no charge' */
*nochrg = (top->where == OBJ_FLOOR && (obj->no_charge || freespot)); *nochrg = (top->where == OBJ_FLOOR && (obj->no_charge || freespot));
if (carried(top) ? (int) obj->unpaid : !*nochrg) if (carried(top) ? (int) obj->unpaid : !*nochrg) {
cost = obj->quan * get_cost(obj, shkp); long per_unit_cost = get_cost(obj, shkp);
cost = get_pricing_units(obj) * per_unit_cost;
}
if (Has_contents(obj) && !freespot) if (Has_contents(obj) && !freespot)
cost += contained_cost(obj, shkp, 0L, FALSE, TRUE); cost += contained_cost(obj, shkp, 0L, FALSE, TRUE);
} }
return cost; return cost;
} }
STATIC_OVL long
get_pricing_units(obj)
struct obj *obj;
{
long units = obj->quan;
if (obj->globby) {
/* globs must be sold by weight not by volume */
int unit_weight = (int) objects[obj->otyp].oc_weight,
wt = (obj->owt > 0) ? obj->owt : weight(obj);
if (unit_weight)
units = wt / unit_weight;
}
return units;
}
/* decide whether to apply a surcharge (or hypothetically, a discount) to obj /* decide whether to apply a surcharge (or hypothetically, a discount) to obj
if it had ID number 'oid'; returns 1: increase, 0: normal, -1: decrease */ if it had ID number 'oid'; returns 1: increase, 0: normal, -1: decrease */
int int
@@ -2185,7 +2206,7 @@ boolean unpaid_only;
items on freespot are implicitly 'no charge' */ items on freespot are implicitly 'no charge' */
if (on_floor ? (!otmp->no_charge && !freespot) if (on_floor ? (!otmp->no_charge && !freespot)
: (otmp->unpaid || !unpaid_only)) : (otmp->unpaid || !unpaid_only))
price += get_cost(otmp, shkp) * otmp->quan; price += get_cost(otmp, shkp) * get_pricing_units(otmp);
} }
if (Has_contents(otmp)) if (Has_contents(otmp))
@@ -2298,7 +2319,9 @@ set_cost(obj, shkp)
register struct obj *obj; register struct obj *obj;
register struct monst *shkp; register struct monst *shkp;
{ {
long tmp = getprice(obj, TRUE) * obj->quan, multiplier = 1L, divisor = 1L; long tmp, unit_price = getprice(obj, TRUE), multiplier = 1L, divisor = 1L;
tmp = get_pricing_units(obj) * unit_price;
if (uarmh && uarmh->otyp == DUNCE_CAP) if (uarmh && uarmh->otyp == DUNCE_CAP)
divisor *= 3L; divisor *= 3L;
@@ -2474,6 +2497,9 @@ struct monst *shkp;
} else } else
bp->useup = 0; bp->useup = 0;
bp->price = get_cost(obj, shkp); bp->price = get_cost(obj, shkp);
if (obj->globby)
/* for globs, the amt charged for quan 1 depends on owt */
bp->price *= get_pricing_units(obj);
eshkp->billct++; eshkp->billct++;
obj->unpaid = 1; obj->unpaid = 1;
} }
@@ -2615,9 +2641,11 @@ boolean ininv, dummy, silent;
ltmp = cltmp = gltmp = 0L; ltmp = cltmp = gltmp = 0L;
container = Has_contents(obj); container = Has_contents(obj);
if (!obj->no_charge) if (!obj->no_charge) {
ltmp = get_cost(obj, shkp); ltmp = get_cost(obj, shkp);
if (obj->globby)
ltmp *= get_pricing_units(obj);
}
if (obj->no_charge && !container) { if (obj->no_charge && !container) {
obj->no_charge = 0; obj->no_charge = 0;
return; return;
@@ -2845,7 +2873,7 @@ boolean ininv;
if (billamt) if (billamt)
price += billamt; price += billamt;
else if (ininv ? otmp->unpaid : !otmp->no_charge) else if (ininv ? otmp->unpaid : !otmp->no_charge)
price += otmp->quan * get_cost(otmp, shkp); price += get_pricing_units(otmp) * get_cost(otmp, shkp);
if (Has_contents(otmp)) if (Has_contents(otmp))
price = stolen_container(otmp, shkp, price, ininv); price = stolen_container(otmp, shkp, price, ininv);
@@ -2892,7 +2920,7 @@ boolean peaceful, silent;
if (billamt) if (billamt)
value += billamt; value += billamt;
else if (!obj->no_charge) else if (!obj->no_charge)
value += obj->quan * get_cost(obj, shkp); value += get_pricing_units(obj) * get_cost(obj, shkp);
if (Has_contents(obj)) { if (Has_contents(obj)) {
boolean ininv = boolean ininv =
@@ -4264,6 +4292,8 @@ register struct obj *first_obj;
contentsonly = !cost; contentsonly = !cost;
if (Has_contents(otmp)) if (Has_contents(otmp))
cost += contained_cost(otmp, shkp, 0L, FALSE, FALSE); cost += contained_cost(otmp, shkp, 0L, FALSE, FALSE);
if (otmp->globby)
cost *= get_pricing_units(otmp); /* always quan 1, vary by wt */
if (!cost) { if (!cost) {
Strcpy(price, "no charge"); Strcpy(price, "no charge");
contentsonly = FALSE; contentsonly = FALSE;
@@ -4757,4 +4787,121 @@ sasc_bug(struct obj *op, unsigned x)
} }
#endif #endif
/*
* When one glob is absorbed by another glob, the two become
* become indistinguishable and the remaining glob grows in
* mass, the product of both.
*
* The original billed item is lost to the absorption and the
* original billed amount for the object being absorbed gets
* added to the cost owing for the absorber, and the separate
* cost for the absorbed object goes away.
*/
void
globby_bill_fixup(obj_absorber, obj_absorbed)
struct obj *obj_absorber, *obj_absorbed;
{
struct bill_x *bp, *bp_absorber = (struct bill_x *) 0;
struct monst *shkp = 0;
if (!obj_absorber->globby)
impossible("globby_bill_fixup called for non-globby object");
if (obj_absorber->unpaid) {
/* look for a shopkeeper who owns this object */
for (shkp = next_shkp(fmon, TRUE); shkp;
shkp = next_shkp(shkp->nmon, TRUE))
if (onbill(obj_absorber, shkp, TRUE))
break;
}
/* sanity check, in case obj is on bill but not marked 'unpaid' */
if (!shkp)
shkp = shop_keeper(*u.ushops);
if ((bp_absorber = onbill(obj_absorber, shkp, FALSE)) != 0) {
bp = onbill(obj_absorbed, shkp, FALSE);
if (bp) {
bp_absorber->price += bp->price;
ESHK(shkp)->billct--;
#ifdef DUMB
{
/* DRS/NS 2.2.6 messes up -- Peter Kendell */
int indx = ESHK(shkp)->billct;
*bp = ESHK(shkp)->bill_p[indx];
}
#else
*bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
#endif
clear_unpaid_obj(shkp, obj_absorbed);
} else {
/* should never happen */
bp_absorber->price += get_cost(obj_absorbed, shkp)
* get_pricing_units(obj_absorbed);
}
}
}
/*
* The caller is about to make obj_absorbed go away.
*
* There's no way for you (or a shopkeeper) to prevent globs
* from merging with each other on the floor due to the
* inherent nature of globs so it irretrievably becomes part
* of the floor glob mass.
*
* globby_donation() needs to handle whether/how to
* compensate you for that.
*
* unpaid globs don't end up here.
*/
void
globby_donation(obj_absorber, obj_absorbed)
struct obj *obj_absorber, *obj_absorbed;
{
if (obj_absorber->where == OBJ_FLOOR
&& costly_spot(obj_absorber->ox, obj_absorber->oy)) {
int x = obj_absorber->ox, y = obj_absorber->oy;
char *o_shop = in_rooms(x, y, SHOPBASE);
struct monst *shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
struct eshk *eshkp = ESHK(shkp);
long amount, per_unit_cost = get_cost(obj_absorbed, shkp);
if (saleable(shkp, obj_absorbed)) {
amount = get_pricing_units(obj_absorbed) * per_unit_cost;
if (eshkp->debit >= amount) {
if (eshkp->loan) { /* you carry shop's gold */
if (eshkp->loan >= amount)
eshkp->loan -= amount;
else
eshkp->loan = 0L;
}
eshkp->debit -= amount;
pline_The("donated %s %spays off your debt.",
obj_typename(obj_absorbed->otyp),
eshkp->debit ? "partially " : "");
} else {
long delta = amount - eshkp->debit;
eshkp->credit += delta;
if (eshkp->debit) {
eshkp->debit = 0L;
eshkp->loan = 0L;
Your("debt is paid off.");
}
if (eshkp->credit == delta)
pline_The("%s established %ld %s credit.",
obj_typename(obj_absorbed->otyp),
delta, currency(delta));
else
pline_The("%s added %ld %s %s %ld %s.",
obj_typename(obj_absorbed->otyp),
delta, currency(delta),
"to your credit; total is now",
eshkp->credit, currency(eshkp->credit));
}
}
}
}
/*shk.c*/ /*shk.c*/