]> granicus.if.org Git - nethack/commitdiff
sync changes since last snapshot
authorcohrs <cohrs>
Mon, 7 Jan 2002 02:12:04 +0000 (02:12 +0000)
committercohrs <cohrs>
Mon, 7 Jan 2002 02:12:04 +0000 (02:12 +0000)
51 files changed:
dat/opthelp
doc/Guidebook.mn
doc/Guidebook.tex
doc/buglist
doc/fixes33.2
include/decl.h
include/extern.h
include/flag.h
include/hack.h
src/allmain.c
src/apply.c
src/ball.c
src/decl.c
src/do.c
src/dokick.c
src/dothrow.c
src/eat.c
src/end.c
src/explode.c
src/files.c
src/hack.c
src/invent.c
src/makemon.c
src/mkobj.c
src/monmove.c
src/monst.c
src/mthrowu.c
src/objects.c
src/objnam.c
src/options.c
src/pickup.c
src/potion.c
src/rip.c
src/rumors.c
src/shk.c
src/sp_lev.c
src/steal.c
src/teleport.c
src/trap.c
src/uhitm.c
src/worn.c
src/zap.c
sys/amiga/amirip.c
win/Qt/qt_win.cpp
win/X11/NetHack.ad
win/X11/winX.c
win/X11/wintext.c
win/gnome/gnbind.c
win/tty/getline.c
win/tty/topl.c
win/tty/wintty.c

index 599a5db4ffa7bcc1c93e4aa036d0ae861121913f..58848482d24bc6fb1a0ec1401f6be9de35e31c9f 100644 (file)
@@ -71,6 +71,9 @@ timed_delay    on unix and VMS, use a timer instead of sending
                display effect.  on MSDOS without the termcap
                lib, whether or not to pause for visual effect.    [TRUE]
 
+Boolean option if TTY_GRAPHICS was set at compile time:
+msg_window show previous messages in a screen-size window         [FALSE]
+
 Boolean option if USE_TILES was set at compile time (MSDOS protected mode only):
 preload_tiles  control whether tiles get pre-loaded into RAM at the
                start of the game.  Doing so enhances performance
index af446c05f5a009bd3428cf070a91711bb0261cfd..69e1cd7468a8c14a28d8954c6b3b7d04fe9cef6b 100644 (file)
@@ -1863,6 +1863,9 @@ Cannot be set with the `O' command.
 .lp msghistory
 The number of top line messages to save (and recall with ^P) (default 20).
 Cannot be set with the `O' command.
+.lp msg_window
+Use a screen-size window to show the previous messages with ^P instead of 
+showing them one at a time.  (Currently implemented for tty only.)
 .lp "name    "
 Set your character's name (defaults to your user name).  You can also
 set your character's role by appending a dash and one or more letters of
index db6ef27840ea3d49fb2e29e0424be652e74e7460..4fcfd77ff01cf0595c449818d486e722cbafa4b4 100644 (file)
@@ -2299,6 +2299,10 @@ Cannot be set with the `{\tt O}' command.
 The number of top line messages to save (and recall with `{\tt \^{}P}')
 (default 20). Cannot be set with the `{\tt O}' command.
 %.lp
+\item[\ib{msg\_window}]
+Use a screen-size window to show the previous messages with `{\tt \^{}P}'
+instead of showing them one at a time.  (Currently implemented for tty only.)
+%.lp
 \item[\ib{name}]
 Set your character's name (defaults to your user name).  You can also
 set your character's role by appending a dash and one or more letters of
index 26aa1c3060c27d81d5a927bfb6c434d38b00741c..6f45283cb005b4434aea97ca2d7db88903ce61e7 100644 (file)
@@ -51,9 +51,6 @@ Drain life requires you to reach floor to wipe an engraving.
 
 Orc monsters should be given poison res? [psmith@spod-central.org]
 
-Ninja monsters should get multishot bonuses with yumi-ya? 
-[psmith@spod-central.org]
-
 Chromatic Dragon should have reflection? [psmith@spod-central.org]
 
 stone-to-flesh monsters' inventory? [psmith@spod-central.org]
@@ -61,15 +58,6 @@ stone-to-flesh monsters' inventory? [psmith@spod-central.org]
 Releasing your pet from a bear trap by displacing is silly.
 [eino.keskitalo@purkki.mbnet.fi]
 
-When punished, being teleported always places the iron ball underneath you
-even when you land at a spot that's within range of the current ball&chain
-position.  Since the teleport mechanism is used for crawling out of water,
-this can produce an even stranger effect:  if you're carrying the attached
-ball when you step into water and it happens to be chosen as an item to
-drop in order to lighten your load, it will end up crawling out of the
-water with you.  (Ie, it will end up underneath you on land rather than in
-the adjacent water where it was actually dropped.)
-
 Monster spellcasting is in serious need of overhaul.
 Clerical spell `case 1' has ``if (...) {} /* else fall into default */''
 but the default case has been moved away so the comment is a lie.
@@ -96,18 +84,6 @@ inefficient when multiple objects are migrating. It might be better to place
 all of the migrating objects that are being scattered onto a special obj 
 chain which scatter() could easily be changed to accomodate.
 
-Occasionally an eating attempt which gets interrupted will produce a
-food object that is not flagged as partially eaten, even though it did
-get split out of a merged group.  (Observed in both 3.1.3 and 3.2.2), 
-for ordinary food rations carried in the player's inventory.)
-
-Occasionally player will get messages about become encumbered while eating,
-when they didn't begin eating encumbered, but they return to proper encum-
-berance when finished eating.  There is also a problem with partly eaten
-food rations carrying the wrong nutritional value (player can start out weak,
-get interrupted, finish the partly eaten ration, and end up satiated) which is
-likely the same bug.
-
 For "traditional" menu style, pickup and #loot/apply can't accept an 'm'
 response to bring up a menu upon request when all items involved are of
 the same class, because the prompt where that response is allowed only
@@ -128,9 +104,7 @@ The resistance delays are very slow on some machines and fine on others, with
 no apparent pattern.  There is a proposal to do timing in a different manner.
 
 Monsters do not get affected by special properties of many types of armor,
-like levitation boots.  They do get affected by speed boots, but do not
-consider such items to be any better than other shoes which grant 1 point
-of AC when deciding whether to wear them.
+like levitation boots.
 
 Corpses buried under ice ought to be handled as if they were inside an
 ice box.
index e76df65faf1817e22eb94b2e8fc22c77463b05b0..5944b039e58b4f9373460c7d014b32458c712850 100644 (file)
@@ -349,6 +349,25 @@ make blindness with just 1 turn remaining be a candicate for repair by
 healing potions/spells shouldn't fix being creamed
 make pie throwing and venom spitting by the player be consistent with the
        effects of those attacks by monsters
+offering & tinning corpses on altars should work even while riding
+It was possible to faint after eating a fortune cookie and still read
+       the fortune's text despite being unconscious
+when filling a pit containing a vortex, a surviving vortex gets untrapped
+teleporting no longer moves the iron ball to under you if that's not necessary;
+       prevents odd ball movement when crawling out of water
+monsters now prefer to wear speed boots over other boots
+prevent crash when loading a special level specifying a mimic using m_object
+prevent crashes caused by dropping or shipping quivered or secondary weapons
+don't trigger spurious encumbrance messages on last turn of a multi-turn meal
+prevent food being restored to untouched status if interrupted while eating
+troll revival shouldn't increment the troll creation counter
+breaking mirrors and your eggs should be bad luck when kicking chests as well
+       as throwing
+vampires should be G_NOCORPSE so you can't wish for them
+glass objects should break when thrown, just like when kicked in chests
+rocks/gems shouldn't be hard to throw by hand because they are ammo
+avoid all cases where splitting an object would result in two objects being
+       quivered, wielded or otherwise having its owornflag set
 
 
 Platform- and/or Interface-Specific Fixes
@@ -378,6 +397,7 @@ X11: allow extra space added to map widget to be removed if widget shrinks
 Gnome: workaround for GTK+ attempts to disallow setgid executables
 X11: general solution to the problem that the meaning of font height varies
        among different implementations of X11
+X11: make "slow" mode the default since it seems to be very prevalent
 
 
 General New Features
@@ -433,6 +453,8 @@ blessed gold detection now detects anything made of gold, not just
 new T-shirt messages from Scott Bigham
 option to get rid of resistance 'sparkle' (shieldeffect) (Scott Bigham)
 glowing Sunsword (inspired by Slashem)
+msg_window option for ^P in TTY mode (Jay Tilton)
+ninjas should get multishot bonus with yumi and ya (Dylan O'Donnell)
 
 
 Platform- and/or Interface-Specific New Features
index 4a42858b48d2763ffd37fa1cba79f9a6f00dd10e..db8a47f5ca750679b5c95cdb0b8b6a1e5e9a2c0b 100644 (file)
@@ -171,6 +171,9 @@ E NEARDATA char *save_cm;
 E NEARDATA int killer_format;
 E const char *killer;
 E const char *delayed_killer;
+#ifdef GOLDOBJ
+E long done_money;
+#endif
 E char killer_buf[BUFSZ];
 E const char *configfile;
 E NEARDATA char plname[PL_NSIZ];
index ecfd02a74cb20e02b72e24a2f47728729ae50bae..e6879155b513009035947dce0d5755099cc50411 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)extern.h   3.3     2001/09/06      */
+/*     SCCS Id: @(#)extern.h   3.3     2002/01/04      */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -521,6 +521,8 @@ E int FDECL(eaten_stat, (int,struct obj *));
 E void FDECL(food_disappears, (struct obj *));
 E void FDECL(food_substitution, (struct obj *,struct obj *));
 E void NDECL(fix_petrification);
+E void FDECL(consume_oeaten, (struct obj *,int));
+E boolean FDECL(maybe_finished_meal, (BOOLEAN_P));
 
 /* ### end.c ### */
 
@@ -751,7 +753,7 @@ E void FDECL(identify_pack, (int));
 E int FDECL(askchain, (struct obj **,const char *,int,int (*)(OBJ_P),
                        int (*)(OBJ_P),int,const char *));
 E void FDECL(prinv, (const char *,struct obj *,long));
-E char *FDECL(xprname, (struct obj *,const char *,CHAR_P,BOOLEAN_P,long));
+E char *FDECL(xprname, (struct obj *,const char *,CHAR_P,BOOLEAN_P,long,long));
 E int NDECL(ddoinv);
 E char FDECL(display_inventory, (const char *,BOOLEAN_P));
 E int FDECL(display_binventory, (int,int,BOOLEAN_P));
index 457c49e477b3aff38e00887a740a23d04e4267fa..67d044ca6ee1c61de5d3ed229905efc10ba21cd2 100644 (file)
@@ -216,6 +216,9 @@ struct instance_flags {
        boolean lan_mail_fetched; /* mail is awaiting display */
 #endif
        uchar bouldersym;       /* alternative boulder symbol */
+#ifdef TTY_GRAPHICS
+       boolean prevmsg_window; /* show more old messages at a time */
+#endif
 };
 
 extern NEARDATA struct flag flags;
index dd163e6f9e5c5f8f3d802b824bb2ffedaf366de3..2142d26265fb2affd37c80216d9e6881fac35e76 100644 (file)
@@ -138,6 +138,7 @@ NEARDATA extern coord bhitpos;      /* place where throw or zap hits or stops */
 #define MM_EMIN                  0x08  /* add emin structure */
 #define MM_ANGRY         0x10  /* monster is created angry */
 #define MM_NONAME        0x20  /* monster is not christened */
+#define MM_NOCOUNTBIRTH          0x40  /* don't increment born counter (for revival) */
 
 /* flags for special ggetobj status returns */
 #define ALL_FINISHED     0x01  /* called routine already finished the job */
index 2bfdb772b804d042269e7a3594f743a623f25ef4..d42e2658a95ec0c9b31116e86c88acebdc9dd8b4 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)allmain.c  3.3     2000/05/05      */
+/*     SCCS Id: @(#)allmain.c  3.3     2002/01/04      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -415,7 +415,8 @@ void
 stop_occupation()
 {
        if(occupation) {
-               You("stop %s.", occtxt);
+               if (!maybe_finished_meal(TRUE))
+                   You("stop %s.", occtxt);
                occupation = 0;
                flags.botl = 1; /* in case u.uhs changed */
 /* fainting stops your occupation, there's no reason to sync.
index a2462bde0cc5ec71c1e189966665b1c8ec21bd09..19a73a3eb13083cb1fa8d3ba7da5beac88e455bf 100644 (file)
@@ -936,7 +936,7 @@ register struct obj *obj;
                return;
        } else {
                if ((long)otmp->spe + obj->quan > 7L)
-                   (void)splitobj(obj, 7L - (long)otmp->spe);
+                   obj = splitobj(obj, 7L - (long)otmp->spe);
                You("attach %ld%s candle%s to %s.",
                    obj->quan, !otmp->spe ? "" : " more",
                    plur(obj->quan), the(xname(otmp)));
@@ -1107,7 +1107,7 @@ light_cocktail(obj)
        makeknown(obj->otyp);
 
        if (obj->quan > 1L) {
-           (void) splitobj(obj, 1L);
+           obj = splitobj(obj, 1L);
            begin_burn(obj, FALSE);     /* burn before free to get position */
            obj_extract_self(obj);      /* free from inv */
 
index 30a7fdfb9c567b6e81b6295aeb2774456a0ab4d7..6f9536e97ddc6ffbfba5b3c8798f5ac7978ceb34 100644 (file)
@@ -345,7 +345,8 @@ xchar ballx, bally, chainx, chainy; /* only matter !before */
 
 /* return TRUE if ball could be dragged
  *
- *  Should not be called while swallowed.
+ *  Should not be called while swallowed.  Should be called before movement,
+ *  because we might want to move the ball or chain to the hero's old position.
  */
 boolean
 drag_ball(x, y, bc_control, ballx, bally, chainx, chainy, cause_delay)
@@ -368,27 +369,108 @@ boolean *cause_delay;
            return TRUE;
        }
 
-       if (carried(uball) || dist2(x, y, uball->ox, uball->oy) < 3 ||
-               (uball->ox == uchain->ox && uball->oy == uchain->oy)) {
-           /*
-            * Case where the ball doesn't move but the chain can't just move
-            * to the player's position:
-            *   @                                             _
-            *    _    moving southwest becomes  @_  and not  @
-            *   0                                0            0
-            */
+       /* only need to move the chain? */
+       if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) {
            *bc_control = BC_CHAIN;
            move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
-           if (dist2(x, y, uball->ox, uball->oy) == 2 &&
-                   dist2(x, y, uchain->ox, uchain->oy) == 4) {
-               if (uchain->oy == y)
-                   *chainx = uball->ox;
-               else
-                   *chainy = uball->oy;
-           } else {
-               *chainx = u.ux;
-               *chainy = u.uy;
+           if (carried(uball)) {
+               /* move chain only if necessary; assume they didn't teleport */
+               if (distmin(x, y, uchain->ox, uchain->oy) > 1) {
+                   *chainx = u.ux;
+                   *chainy = u.uy;
+               }
+               return TRUE;
+           }
+#define CHAIN_IN_MIDDLE(chx, chy) \
+(distmin(x, y, chx, chy) <= 1 && distmin(chx, chy, uball->ox, uball->oy) <= 1)
+           switch(dist2(x, y, uball->ox, uball->oy)) {
+               /* two spaces diagonal from ball, move chain inbetween */
+               case 8:
+                   *chainx = (uball->ox + x)/2;
+                   *chainy = (uball->oy + y)/2;
+                   break;
+
+               /* player is distance 2/1 from ball; move chain to one of the
+                * two spaces between
+                *   @
+                *   __
+                *    0
+                */
+               case 5: {
+                   xchar tempx, tempy, tempx2, tempy2;
+
+                   /* find position closest to current position of chain */
+                   /* no effect if current position is already OK */
+                   if (abs(x - uball->ox) == 1) {
+                       tempx = x;
+                       tempx2 = uball->ox;
+                       tempy = tempy2 = (uball->oy + y)/2;
+                   } else {
+                       tempx = tempx2 = (uball->ox + x)/2;
+                       tempy = y;
+                       tempy2 = uball->oy;
+                   }
+                   if (dist2(tempx, tempy, uchain->ox, uchain->oy) <
+                        dist2(tempx2, tempy2, uchain->ox, uchain->oy) ||
+                      ((dist2(tempx, tempy, uchain->ox, uchain->oy) ==
+                        dist2(tempx2, tempy2, uchain->ox, uchain->oy)) && rn2(2))) {
+                       *chainx = tempx;
+                       *chainy = tempy;
+                   } else {
+                       *chainx = tempx2;
+                       *chainy = tempy2;
+                   }
+                   break;
+               }
+
+               /* ball is two spaces horizontal or vertical from player; move*/
+               /* chain inbetween *unless* current chain position is OK */
+               case 4:
+                   if (CHAIN_IN_MIDDLE(uchain->ox, uchain->oy))
+                       break;
+                   *chainx = (x + uchain->ox)/2;
+                   *chainy = (y + uchain->oy)/2;
+                   break;
+               
+               /* ball is one space diagonal from player.  Check for the
+                * following special case:
+                *   @
+                *    _    moving southwest becomes  @_
+                *   0                                0
+                * (This will also catch teleporting that happens to resemble
+                * this case, but oh well.)  Otherwise fall through.
+                */
+               case 2:
+                   if (dist2(x, y, uball->ox, uball->oy) == 2 &&
+                           dist2(x, y, uchain->ox, uchain->oy) == 4) {
+                       if (uchain->oy == y)
+                           *chainx = uball->ox;
+                       else
+                           *chainy = uball->oy;
+                       break;
+                   }
+                   /* fall through */
+               case 1:
+               case 0:
+                   /* do nothing if possible */
+                   if (CHAIN_IN_MIDDLE(uchain->ox, uchain->oy))
+                       break;
+                   /* otherwise try to drag chain to player's old position */
+                   if (CHAIN_IN_MIDDLE(u.ux, u.uy)) {
+                       *chainx = u.ux;
+                       *chainy = u.uy;
+                       break;
+                   }
+                   /* otherwise use player's new position (they must have
+                      teleported, for this to happen) */
+                   *chainx = x;
+                   *chainy = y;
+                   break;
+               
+               default: impossible("bad chain movement");
+                   break;
            }
+#undef CHAIN_IN_MIDDLE
            return TRUE;
        }
 
index 770c95aee6188279c4438240ab325574e15d364e..a079c67e84b633388d49a40ed893ed62703a7c75 100644 (file)
@@ -48,6 +48,9 @@ NEARDATA char *save_cm = 0;
 NEARDATA int killer_format = 0;
 const char *killer = 0;
 const char *delayed_killer = 0;
+#ifdef GOLDOBJ
+NEARDATA long done_money = 0;
+#endif
 char killer_buf[BUFSZ] = DUMMY;
 const char *nomovemsg = 0;
 const char nul[40] = DUMMY;                    /* contains zeros */
index cbf78d087549aa1f235a9d390ca5a0cf3de42b8c..11b2c40c83f5a27e377e939968083a980318ccb4 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -171,9 +171,10 @@ const char *verb;
                    if (mtmp) {
                        if (!passes_walls(mtmp->data) &&
                                !throws_rocks(mtmp->data)) {
-                           if (hmon(mtmp, obj, TRUE))
+                           if (hmon(mtmp, obj, TRUE) && !is_whirly(mtmp->data))
                                return FALSE;   /* still alive */
-                       } else mtmp->mtrapped = 0;
+                       }
+                       mtmp->mtrapped = 0;
                    } else {
                        if (!Passes_walls && !throws_rocks(youmonst.data)) {
                            losehp(rnd(15), "squished under a boulder",
@@ -523,31 +524,35 @@ void
 dropy(obj)
 register struct obj *obj;
 {
+       if (obj == uwep) setuwep((struct obj *)0);
+       if (obj == uquiver) setuqwep((struct obj *)0);
+       if (obj == uswapwep) setuswapwep((struct obj *)0);
+
        if (!u.uswallow && flooreffects(obj,u.ux,u.uy,"drop")) return;
        /* uswallow check done by GAN 01/29/87 */
        obj_no_longer_held(obj);
        if(u.uswallow) {
-               boolean could_petrify;
-               if (obj != uball) {             /* mon doesn't pick up ball */
-                   could_petrify = obj->otyp == CORPSE &&
-                                   touch_petrifies(&mons[obj->corpsenm]);
-                   (void) mpickobj(u.ustuck,obj);
-                   if (could_petrify && is_animal(u.ustuck->data)) {
-                       minstapetrify(u.ustuck, TRUE);
-                       /* Don't leave a cockatrice corpse available in a statue */
-                       if (!u.uswallow) delobj(obj);
-                   }
+           boolean could_petrify;
+           if (obj != uball) {         /* mon doesn't pick up ball */
+               could_petrify = obj->otyp == CORPSE &&
+                   touch_petrifies(&mons[obj->corpsenm]);
+               (void) mpickobj(u.ustuck,obj);
+               if (could_petrify && is_animal(u.ustuck->data)) {
+                   minstapetrify(u.ustuck, TRUE);
+                   /* Don't leave a cockatrice corpse available in a statue */
+                   if (!u.uswallow) delobj(obj);
                }
+           }
        } else  {
-               place_object(obj, u.ux, u.uy);
-               if (obj == uball)
-                   drop_ball(u.ux,u.uy);
-               else
-                   sellobj(obj, u.ux, u.uy);
-               stackobj(obj);
-               if(Blind && Levitation)
-                   map_object(obj, 0);
-               newsym(u.ux,u.uy);      /* remap location under self */
+           place_object(obj, u.ux, u.uy);
+           if (obj == uball)
+               drop_ball(u.ux,u.uy);
+           else
+               sellobj(obj, u.ux, u.uy);
+           stackobj(obj);
+           if(Blind && Levitation)
+               map_object(obj, 0);
+           newsym(u.ux,u.uy);  /* remap location under self */
        }
 }
 
@@ -597,7 +602,10 @@ int retry;
 {
     int n, i, n_dropped = 0;
     long cnt;
-    struct obj *otmp, *otmp2, *u_gold = 0;
+    struct obj *otmp, *otmp2;
+#ifndef GOLDOBJ
+    struct obj *u_gold = 0;
+#endif
     menu_item *pick_list;
     boolean all_categories = TRUE;
     boolean drop_everything = FALSE;
@@ -657,11 +665,7 @@ int retry;
                cnt = pick_list[i].count;
                if (cnt < otmp->quan && !welded(otmp) &&
                        (!otmp->cursed || otmp->otyp != LOADSTONE)) {
-                   otmp2 = splitobj(otmp, cnt);
-                   /* assume other worn items aren't mergable */
-                   if (otmp == uwep) setuwep(otmp2);
-                       if (otmp == uquiver) setuqwep(otmp2);
-                       if (otmp == uswapwep) setuswapwep(otmp2);
+                   otmp = splitobj(otmp, cnt);
                }
                n_dropped += drop(otmp);
            }
index 2ed9ad52be8095580349de9f003aec4692bd5013..66a1369af3be95e6384dac79f5c12eef32a27fd2 100644 (file)
@@ -431,6 +431,11 @@ xchar x, y;
                                result = "cracking";
                        }
                        if (result) {
+                               if (otmp->otyp == MIRROR)
+                                   change_luck(-2);
+                               /* eggs laid by you */
+                               if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
+                                   change_luck(-5);
                                You_hear("a muffled %s.",result);
                                if(costly) loss += stolen_value(otmp, x, y,
                                            (boolean)shkp->mpeaceful, TRUE);
@@ -512,7 +517,7 @@ xchar x, y;
            return(!rn2(3) || martial());
        }
 
-       if (kickobj->quan > 1L && !isgold) (void) splitobj(kickobj, 1L);
+       if (kickobj->quan > 1L && !isgold) kickobj = splitobj(kickobj, 1L);
 
        if (slide && !Blind)
            pline("Whee!  %s slide%s across the %s.", Doname2(kickobj),
@@ -1267,6 +1272,10 @@ boolean shop_floor_obj;
                otmp->no_charge = 0;
        }
 
+       if (otmp == uwep) setuwep((struct obj *)0);
+       if (otmp == uquiver) setuqwep((struct obj *)0);
+       if (otmp == uswapwep) setuswapwep((struct obj *)0);
+
        add_to_migration(otmp);
        otmp->ox = cc.x;
        otmp->oy = cc.y;
index 799f3c48a31ad87f0042d9eafd0a29a5e888149c..f398795c455d7be49a537b86bd71c40696af02c3 100644 (file)
@@ -52,7 +52,12 @@ int shotlimit;
 
        if(obj->oclass == GOLD_CLASS) return(throw_gold(obj));
 #else
-       if (!getdir((char *)0)) return(0);
+       if (!getdir((char *)0)) {
+           /* obj might need to be merged back into the singular gold object */
+           freeinv(obj);
+           addinv(obj);
+           return(0);
+       }
 
         /*
          Throwing money is usually for getting rid of it when
@@ -157,8 +162,7 @@ int shotlimit;
            twoweap = u.twoweap;
            /* split this object off from its slot if necessary */
            if (obj->quan > 1L) {
-               otmp = splitobj(obj, obj->quan - 1L);
-               otmp->owornmask = 0L;
+               otmp = splitobj(obj, 1L);
            } else {
                otmp = obj;
                if (otmp->owornmask && otmp != uball)
@@ -846,7 +850,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
                if (is_ammo(obj)) {
                    if (ammo_and_launcher(obj, uwep))
                        range++;
-                   else
+                   else if (obj->oclass != GEM_CLASS)
                        range /= 2;
                }
 
@@ -1482,9 +1486,10 @@ breaktest(obj)
 struct obj *obj;
 {
        if (obj_resists(obj, 1, 99)) return 0;
+       if (objects[obj->otyp].oc_material == GLASS && !obj->oartifact &&
+               obj->oclass != GEM_CLASS)
+           return 1;
        switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
-               case MIRROR:
-               case CRYSTAL_BALL:
 #ifdef TOURIST
                case EXPENSIVE_CAMERA:
 #endif
@@ -1508,6 +1513,11 @@ boolean in_view;
 
        to_pieces = "";
        switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
+               default: /* glass or crystal wand */
+                   if (obj->oclass != WAND_CLASS)
+                       impossible("breaking odd object?");
+               case CRYSTAL_PLATE_MAIL:
+               case LENSES:
                case MIRROR:
                case CRYSTAL_BALL:
 #ifdef TOURIST
index 05a89d4767a4cb3f124d688eaac017ac7e2fbe21..e02a4c61c5646b81369249c95a96dc703b5c8285 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)eat.c      3.3     2001/11/28      */
+/*     SCCS Id: @(#)eat.c      3.3     2002/01/02      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -40,7 +40,7 @@ STATIC_DCL int FDECL(edibility_prompts, (struct obj *));
 STATIC_DCL int FDECL(rottenfood, (struct obj *));
 STATIC_DCL void NDECL(eatspecial);
 STATIC_DCL void FDECL(eataccessory, (struct obj *));
-STATIC_DCL const char * FDECL(foodword, (struct obj *));
+STATIC_DCL const char *FDECL(foodword, (struct obj *));
 
 char msgbuf[BUFSZ];
 
@@ -303,9 +303,9 @@ register struct obj *otmp;
 {
        if (otmp->quan > 1L) {
            if(!carried(otmp))
-               (void) splitobj(otmp, 1L);
+               (void) splitobj(otmp, otmp->quan - 1L);
            else
-               otmp = splitobj(otmp, otmp->quan - 1L);
+               otmp = splitobj(otmp, 1L);
 #ifdef DEBUG
            debugpline("split object,");
 #endif
@@ -1097,11 +1097,7 @@ no_opener:
                        pline_The("tin slips from your %s.",
                              makeplural(body_part(FINGER)));
                        if(otmp->quan > 1L) {
-                               register struct obj *obj;
-                               obj = splitobj(otmp, 1L);
-                               if (otmp == uwep) setuwep(obj);
-                               if (otmp == uswapwep) setuswapwep(obj);
-                               if (otmp == uquiver) setuqwep(obj);
+                           otmp = splitobj(otmp, 1L);
                        }
                        if (carried(otmp)) dropx(otmp);
                        else stackobj(otmp);
@@ -1233,7 +1229,7 @@ eatcorpse(otmp)           /* called when a corpse is selected as food */
                (void)touchfood(otmp);
                retcode = 1;
            } else
-               otmp->oeaten >>= 2;
+               consume_oeaten(otmp, 2);        /* oeaten >>= 2 */
        } else {
            pline("%s%s %s!",
                  !uniq ? "This " : !type_is_pname(&mons[mnum]) ? "The " : "",
@@ -1800,10 +1796,10 @@ doeat()         /* generic "eat" command funtion (see cmd.c) */
            u.umonnum == PM_RUST_MONSTER && otmp->oerodeproof) {
                otmp->rknown = TRUE;
                if (otmp->quan > 1L) {
-                       if(!carried(otmp))
-                               (void) splitobj(otmp, 1L);
-                       else
-                               otmp = splitobj(otmp, otmp->quan - 1L);
+                   if(!carried(otmp))
+                       (void) splitobj(otmp, otmp->quan - 1L);
+                   else
+                       otmp = splitobj(otmp, 1L);
                }
                pline("Ulch - That %s was rustproofed!", xname(otmp));
                /* The regurgitated object's rustproofing is gone now */
@@ -1926,7 +1922,7 @@ doeat()           /* generic "eat" command funtion (see cmd.c) */
                    otmp->orotten = TRUE;
                    dont_start = TRUE;
                }
-               otmp->oeaten >>= 1;
+               consume_oeaten(otmp, 1);        /* oeaten >>= 1 */
            } else fprefx(otmp);
        }
 
@@ -1979,10 +1975,10 @@ bite()
        force_save_hs = TRUE;
        if(victual.nmod < 0) {
                lesshungry(-victual.nmod);
-               victual.piece->oeaten -= -victual.nmod;
+               consume_oeaten(victual.piece, victual.nmod); /* -= -nmod */
        } else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) {
                lesshungry(1);
-               victual.piece->oeaten--;
+               consume_oeaten(victual.piece, -1);                /* -= 1 */
        }
        force_save_hs = FALSE;
        recalc_wt();
@@ -2279,7 +2275,7 @@ floorfood(verb,corpsecheck)       /* get food from floor or pack */
        /* if we can't touch floor objects then use invent food only */
        if (!can_reach_floor() ||
 #ifdef STEED
-               u.usteed ||             /* can't eat off floor while riding */
+               (feeding && u.usteed) || /* can't eat off floor while riding */
 #endif
                ((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) &&
                    (Wwalking || is_clinger(youmonst.data) ||
@@ -2382,6 +2378,74 @@ register struct obj *obj;
        return (base < 1) ? 1 : base;
 }
 
+/* reduce obj's oeaten field, making sure it never hits or passes 0 */
+void
+consume_oeaten(obj, amt)
+struct obj *obj;
+int amt;
+{
+    /*
+     * This is a hack to try to squelch several long standing mystery
+     * food bugs.  A better solution would be to rewrite the entire
+     * victual handling mechanism from scratch using a less complex
+     * model.  Alternatively, this routine could call done_eating()
+     * or food_disappears() but its callers would need revisions to
+     * cope with victual.piece unexpectedly going away.
+     *
+     * Multi-turn eating operates by setting the food's oeaten field
+     * to its full nutritional value and then running a counter which
+     * independently keeps track of whether there is any food left.
+     * The oeaten field can reach exactly zero on the last turn, and
+     * the object isn't removed from inventory until the next turn
+     * when the "you finish eating" message gets delivered, so the
+     * food would be restored to the status of untouched during that
+     * interval.  This resulted in unexpected encumbrance messages
+     * at the end of a meal (if near enough to a threshold) and would
+     * yield full food if there was an interruption on the critical
+     * turn.  Also, there have been reports over the years of food
+     * becoming massively heavy or producing unlimited satiation;
+     * this would occur if reducing oeaten via subtraction attempted
+     * to drop it below 0 since its unsigned type would produce a
+     * huge positive value instead.  So far, no one has figured out
+     * _why_ that inappropriate subtraction might sometimes happen.
+     */
+
+    if (amt > 0) {
+       /* bit shift to divide the remaining amount of food */
+       obj->oeaten >>= amt;
+    } else {
+       /* simple decrement; value is negative so we actually add it */
+       if ((int) obj->oeaten > -amt)
+           obj->oeaten += amt;
+       else
+           obj->oeaten = 0;
+    }
+
+    if (obj->oeaten == 0) {
+       if (obj == victual.piece)       /* always true unless wishing... */
+           victual.reqtime = victual.usedtime; /* no bites left */
+       obj->oeaten = 1;        /* smallest possible positive value */
+    }
+}
+
 #endif /* OVLB */
+#ifdef OVL1
+
+/* called when eatfood occupation has been interrupted,
+   or in the case of theft, is about to be interrupted */
+boolean
+maybe_finished_meal(stopping)
+boolean stopping;
+{
+       /* in case consume_oeaten() has decided that the food is all gone */
+       if (occupation == eatfood && victual.usedtime >= victual.reqtime) {
+           if (stopping) occupation = 0;       /* for do_reset_eat */
+           (void) eatfood(); /* calls done_eating() to use up victual.piece */
+           return TRUE;
+       }
+       return FALSE;
+}
+
+#endif /* OVL1 */
 
 /*eat.c*/
index 6dacd8a43e9f2d3c27bccb90177c06e114e30c5e..2986ade84caf0611fb8df1ad7fef981deea0e33e 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -662,7 +662,7 @@ die:
 #ifndef GOLDOBJ
        u.ugold = umoney;
 #else
-       /* FIXME */
+       done_money = umoney;
 #endif
 
        /* clean up unneeded windows */
index a16c3e8d7be465cda59301a83932e55fb298e04e..de3160487078230e6e8cd644fe7c442400ed7f0a 100644 (file)
@@ -416,20 +416,18 @@ struct obj *obj;                  /* only scatter this obj        */
                qtmp = otmp->quan - 1;
                if (qtmp > LARGEST_INT) qtmp = LARGEST_INT;
                qtmp = (long)rnd((int)qtmp);
-               (void) splitobj(otmp, qtmp);
-               if (qtmp < otmp->quan)
-                       split_up = TRUE;
+               otmp = splitobj(otmp, qtmp);
+               if (rn2(qtmp))
+                   split_up = TRUE;
                else
-                       split_up = FALSE;
-           }
+                   split_up = FALSE;
+           } else
+               split_up = FALSE;
            if (individual_object) {
-               if (split_up) {
-                       if (otmp->where == OBJ_FLOOR)
-                               obj = otmp->nexthere;
-                       else
-                               obj = otmp->nobj;
+               if (split_up) {
+                   obj = otmp;
                } else
-                       obj = (struct obj *)0;
+                   obj = (struct obj *)0;
            }
            obj_extract_self(otmp);
            used_up = FALSE;
index ab959491a0ef60dd1e5c7d1023c623f14c0b3424..9f6a503801e24cade64b91755a4a106d39d68c44 100644 (file)
@@ -730,7 +730,7 @@ boolean uncomp;
         * end up being displayed after the error message.
         */
        if (istty)
-           fflush(stdout);
+           wait_synch();
 # endif
        if (f == 0) {   /* child */
 # ifdef TTY_GRAPHICS
@@ -740,7 +740,7 @@ boolean uncomp;
                 * invisible if there are no error messages.
                 */
                if (istty)
-                   raw_printf("");
+                   raw_print("");
 # endif
                /* run compressor without privileges, in case other programs
                 * have surprises along the line of gzip once taking filenames
index 10b9b09b9ba5d1d459be44ea3d85f15abffd971c..9639c6fbd8279b884799ddf0ec9f7fba84169be8 100644 (file)
@@ -160,7 +160,11 @@ moverock()
                    continue;
                case HOLE:
                case TRAPDOOR:
-                   pline("%s %s and plugs a %s in the %s!",
+                   if (Blind)
+                       pline("Kerplunk!  You no longer feel %s.",
+                               the(xname(otmp)));
+                   else 
+                       pline("%s %s and plugs a %s in the %s!",
                          The(xname(otmp)),
                          (ttmp->ttyp == TRAPDOOR) ? "triggers" : "falls into",
                          (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole",
index 92ceaeec8b16b7fe6fd161ed551ff36432a67d35..de29ca9a7dd13a0807f8a3ea6086a2828a4bcd65 100644 (file)
@@ -51,8 +51,10 @@ register struct obj *otmp;
 
 #ifdef GOLDOBJ
         /* There is only one of these in inventory... */        
-        if (otmp->oclass == GOLD_CLASS) otmp->invlet = GOLD_SYM;
-        return;
+        if (otmp->oclass == GOLD_CLASS) {
+           otmp->invlet = GOLD_SYM;
+           return;
+       }
 #endif
 
        for(i = 0; i < 52; i++) inuse[i] = FALSE;
@@ -395,10 +397,7 @@ const char *drop_fmt, *drop_arg, *hold_msg;
                        if (drop_fmt) pline(drop_fmt, drop_arg);
                        /* undo any merge which took place */
                        if (obj->quan > oquan) {
-                           struct obj *otmp = splitobj(obj, oquan);
-                           /* might have merged with weapon */
-                           if (obj->owornmask)
-                               setworn(otmp, obj->owornmask);
+                           obj = splitobj(obj, oquan);
                        }
                        dropx(obj);
                } else {
@@ -914,23 +913,26 @@ register const char *let,*word;
        pline_The("LRS would be very interested to know you have that much.");
                                return(struct obj *)0;
                        }
-#ifndef GOLDOBJ
 
+#ifndef GOLDOBJ
                        if(!(allowcnt == 2 && cnt < u.ugold))
                                cnt = u.ugold;
                        return(mkgoldobj(cnt));
 #endif
                }
                if(allowcnt == 2 && !strcmp(word,"throw")) {
-                       /* permit counts for throwing gold, but don't accept
-                        * counts for other things since the throw code will
-                        * split off a single item anyway */
+                   /* permit counts for throwing gold, but don't accept
+                    * counts for other things since the throw code will
+                    * split off a single item anyway */
+#ifdef GOLDOBJ
+                   if (ilet != def_oc_syms[GOLD_CLASS])
+#endif
                        allowcnt = 1;
-                       if(cnt == 0 && prezero) return((struct obj *)0);
-                       if(cnt > 1) {
-                           You("can only throw one item at a time.");
-                           continue;
-                       }
+                   if(cnt == 0 && prezero) return((struct obj *)0);
+                   if(cnt > 1) {
+                       You("can only throw one item at a time.");
+                       continue;
+                   }
                }
 #ifdef GOLDOBJ
                flags.botl = 1; /* May have changed the amount of money */
@@ -975,20 +977,17 @@ register const char *let,*word;
                return((struct obj *)0);
        }
        if(allowcnt == 2) {     /* cnt given */
-               if(cnt == 0) return (struct obj *)0;
-               if(cnt != otmp->quan) {
-                       register struct obj *obj = splitobj(otmp, cnt);
+           if(cnt == 0) return (struct obj *)0;
+           if(cnt != otmp->quan) {
+               otmp = splitobj(otmp, cnt);
                /* Very ugly kludge necessary to prevent someone from trying
                 * to drop one of several loadstones and having the loadstone
                 * now be separate.
                 */
-                       if (!strcmp(word, "drop") &&
-                           obj->otyp == LOADSTONE && obj->cursed)
-                               otmp->corpsenm = obj->invlet;
-                       if(otmp == uwep) setuwep(obj);
-                       else if (otmp == uquiver) setuqwep(obj);
-                       if (otmp == uswapwep) setuswapwep(obj);
-               }
+               if (!strcmp(word, "drop") &&
+                   otmp->otyp == LOADSTONE && otmp->cursed)
+                   otmp->corpsenm = otmp->invlet;
+           }
        }
        return(otmp);
 }
@@ -1230,7 +1229,7 @@ nextclass:
                if (ckfn && !(*ckfn)(otmp)) continue;
                if (!allflag) {
                        Strcpy(qbuf, !ininv ? doname(otmp) :
-                               xprname(otmp, (char *)0, ilet, !nodot, 0L));
+                               xprname(otmp, (char *)0, ilet, !nodot, 0L, 0L));
                        Strcat(qbuf, "?");
                        sym = (takeoff || ident || otmp->quan < 2L) ?
                                nyaq(qbuf) : nyNaq(qbuf);
@@ -1250,13 +1249,7 @@ nextclass:
                        sym = 'y';
                        if (yn_number < otmp->quan && !welded(otmp) &&
                            (!otmp->cursed || otmp->otyp != LOADSTONE)) {
-                           struct obj *otmpx = splitobj(otmp, yn_number);
-                           if (!otmpx || otmpx->nobj != otmp2)
-                               impossible("bad object split in askchain");
-                           /* assume other worn items aren't mergable */
-                           if (otmp == uwep) setuwep(otmpx);
-                               if (otmp == uquiver) setuqwep(otmpx);
-                               if (otmp == uswapwep) setuswapwep(otmpx);
+                           otmp = splitobj(otmp, yn_number);
                        }
                    }
                }
@@ -1411,32 +1404,33 @@ const char *prefix;
 register struct obj *obj;
 long quan;
 {
-       long savequan = obj->quan;
-       if (quan) obj->quan = quan;
        if (!prefix) prefix = "";
        pline("%s%s%s",
              prefix, *prefix ? " " : "",
-             xprname(obj, (char *)0, obj_to_let(obj), TRUE, 0L));
-       if (quan) obj->quan = savequan;
+             xprname(obj, (char *)0, obj_to_let(obj), TRUE, 0L, quan));
 }
 
 #endif /* OVL2 */
 #ifdef OVL1
 
 char *
-xprname(obj, txt, let, dot, cost)
+xprname(obj, txt, let, dot, cost, quan)
 struct obj *obj;
 const char *txt;       /* text to print instead of obj */
 char let;              /* inventory letter */
 boolean dot;           /* append period; (dot && cost => Iu) */
 long cost;             /* cost (for inventory of unpaid or expended items) */
+long quan;             /* if non-0, print this quantity, not obj->quan */
 {
 #ifdef LINT    /* handle static char li[BUFSZ]; */
-       char li[BUFSZ];
+    char li[BUFSZ];
 #else
-       static char li[BUFSZ];
+    static char li[BUFSZ];
 #endif
-       boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM;
+    boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM;
+    long savequan = obj->quan;
+
+    if (quan) obj->quan = quan;
     /*
      * If let is:
      * *  Then obj == null and we are printing a total amount.
@@ -1458,6 +1452,8 @@ long cost;                /* cost (for inventory of unpaid or expended items) */
                (use_invlet ? obj->invlet : let),
                (txt ? txt : doname(obj)), (dot ? "." : ""));
     }
+    if (quan) obj->quan = savequan;
+
     return li;
 }
 
@@ -1566,8 +1562,8 @@ boolean want_reply;
            for (otmp = invent; otmp; otmp = otmp->nobj) {
                if (otmp->invlet == lets[0]) {
                    ret = message_menu(lets[0],
-                                 want_reply ? PICK_ONE : PICK_NONE,
-                                 xprname(otmp, (char *)0, lets[0], TRUE, 0L));
+                         want_reply ? PICK_ONE : PICK_NONE,
+                         xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L));
                    break;
                }
            }
@@ -1658,7 +1654,7 @@ dounpaid()
 
        pline("%s", xprname(otmp, distant_name(otmp, doname),
                            marker ? otmp->invlet : CONTAINED_SYM,
-                           TRUE, unpaid_cost(otmp)));
+                           TRUE, unpaid_cost(otmp), 0L));
        return;
     }
 
@@ -1683,7 +1679,7 @@ dounpaid()
                    save_unpaid = otmp->unpaid;
                    otmp->unpaid = 0;
                    putstr(win, 0, xprname(otmp, distant_name(otmp, doname),
-                                          ilet, TRUE, cost));
+                                          ilet, TRUE, cost, 0L));
                    otmp->unpaid = save_unpaid;
                    num_so_far++;
                }
@@ -1709,7 +1705,7 @@ dounpaid()
                    marker->unpaid = 0;    /* suppress "(unpaid)" suffix */
                    putstr(win, 0,
                           xprname(marker, distant_name(marker, doname),
-                                  CONTAINED_SYM, TRUE, cost));
+                                  CONTAINED_SYM, TRUE, cost, 0L));
                    marker->unpaid = save_unpaid;
                }
            }
@@ -1717,7 +1713,7 @@ dounpaid()
     }
 
     putstr(win, 0, "");
-    putstr(win, 0, xprname((struct obj *)0, "Total:", '*', FALSE, totcost));
+    putstr(win, 0, xprname((struct obj *)0, "Total:", '*', FALSE, totcost, 0L));
     display_nhwindow(win, FALSE);
     destroy_nhwindow(win);
 }
@@ -2291,7 +2287,7 @@ long numused;
        /* burn_floor_paper() keeps an object pointer that it tries to
         * useupf() multiple times, so obj must survive if plural */
        if (obj->quan > numused)
-               otmp = splitobj(obj, obj->quan - numused);
+               otmp = splitobj(obj, numused);
        else
                otmp = obj;
        if(costly_spot(otmp->ox, otmp->oy)) {
index 55a092b201bb73b6e954de58cf704d02cb7eed5e..b5127dc6c89456c07e1023fe81cb4493c63e1a9e 100644 (file)
@@ -751,6 +751,7 @@ register int        mmflags;
        boolean anymon = (!ptr);
        boolean byyou = (x == u.ux && y == u.uy);
        boolean allow_minvent = ((mmflags & NO_MINVENT) == 0);
+       boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
        uchar lim;
 
        /* if caller wants random location, do it here */
@@ -818,10 +819,10 @@ register int      mmflags;
         * the caller manually decrement mvitals if the monster is created
         * under circumstances where one would not logically expect the
         * creation to reduce the supply of wild monsters.  Monster cloning
-        * might be one such case, but we go against logic there in order to
+        * might be one such case, but we go against logic there in order to
         * reduce the possibility of abuse.
         */
-       if (mvitals[mndx].born < 255) mvitals[mndx].born++;
+       if (mvitals[mndx].born < 255 && countbirth) mvitals[mndx].born++;
        lim = mbirth_limit(mndx);
        if ((int) mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN) &&
                !(mvitals[mndx].mvflags & G_EXTINCT)) {
index a6d192088b46704c99d0abfc970b7e6fe78f5939..b3592618db2d9bec1dd411d7f4c4269628e9cb74 100644 (file)
@@ -217,10 +217,10 @@ rndmonnum()       /* select a random, common monster type */
 }
 
 /*
- * Split obj so that it gets size num. The remainder is put in the object
- * structure delivered by this call.  The object is positioned just
- * following the original in the nobj chain (and nexthere chain when on
- * the floor).
+ * Split obj so that it gets size gets reduced by num. The quantity num is
+ * put in the object structure delivered by this call.  The returned object
+ * has its wornmask cleared and is positioned just following the original
+ * in the nobj chain (and nexthere chain when on the floor).
  */
 struct obj *
 splitobj(obj, num)
@@ -229,7 +229,7 @@ long num;
 {
        struct obj *otmp;
 
-       if (obj->cobj || num <= 0L || obj->quan < num)
+       if (obj->cobj || num <= 0L || obj->quan <= num)
            panic("splitobj");  /* can't split containers */
        otmp = newobj(obj->oxlth + obj->onamelth);
        *otmp = *obj;           /* copies whole structure */
@@ -237,9 +237,10 @@ long num;
        if (!otmp->o_id) otmp->o_id = flags.ident++;    /* ident overflowed */
        otmp->timed = 0;        /* not timed, yet */
        otmp->lamplit = 0;      /* ditto */
-       obj->quan = num;
+       otmp->owornmask = 0L;   /* new object isn't worn */
+       obj->quan -= num;
        obj->owt = weight(obj);
-       otmp->quan -= num;
+       otmp->quan = num;
        otmp->owt = weight(otmp);       /* -= obj->owt ? */
        obj->nobj = otmp;
        /* Only set nexthere when on the floor, nexthere is also used */
index 513a31ddd973394367e7a7e9152fcc013f5fdf2a..9aca9b07f46aeef0da5fb3a21bfeffb802541671 100644 (file)
@@ -297,7 +297,7 @@ register struct monst *mtmp;
        register int tmp=0;
        int inrange, nearby, scared;
 #ifdef GOLDOBJ
-        struct obj *ygold, *lepgold;
+        struct obj *ygold = 0, *lepgold = 0;
 #endif
 
 /*     Pre-movement adjustments        */
@@ -474,8 +474,8 @@ toofar:
           (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
 #else
         if (mdat->mlet == S_LEPRECHAUN) {
-               ygold = findgold(invent);
-                lepgold = findgold(mtmp->minvent);
+           ygold = findgold(invent);
+           lepgold = findgold(mtmp->minvent);
        }
 
        if(!nearby || mtmp->mflee || scared ||
index 3009968e7ba22df6fc005f86f9b7e38466f7d127..ed0a85e672bf19d44a237b1c76413ba06f5b4e5d 100644 (file)
@@ -1987,7 +1987,7 @@ struct permonst _mons2[] = {
  * Vampires
  */
     MON("vampire", S_VAMPIRE,
-       LVL(10, 12, 1, 25, -8), (G_GENO|1),
+       LVL(10, 12, 1, 25, -8), (G_GENO|G_NOCORPSE|1),
        A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_BITE, AD_DRLI, 1, 6),
          NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
        SIZ(WT_HUMAN, 400, 0, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP|MR_POISON, 0,
@@ -1995,7 +1995,7 @@ struct permonst _mons2[] = {
        M2_UNDEAD|M2_STALK|M2_HOSTILE|M2_STRONG|M2_NASTY, M3_INFRAVISIBLE,
        CLR_RED),
     MON("vampire lord", S_VAMPIRE,
-       LVL(12, 14, 0, 50, -9), (G_GENO|1),
+       LVL(12, 14, 0, 50, -9), (G_GENO|G_NOCORPSE|1),
        A(ATTK(AT_CLAW, AD_PHYS, 1, 8), ATTK(AT_BITE, AD_DRLI, 1, 8),
          NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
        SIZ(WT_HUMAN, 400, 0, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP|MR_POISON, 0,
@@ -2004,7 +2004,7 @@ struct permonst _mons2[] = {
        M3_INFRAVISIBLE, CLR_BLUE),
 #if 0  /* DEFERRED */
     MON("vampire mage", S_VAMPIRE,
-       LVL(20, 14, -4, 50, -9), (G_GENO|1),
+       LVL(20, 14, -4, 50, -9), (G_GENO|G_NOCORPSE|1),
        A(ATTK(AT_CLAW, AD_DRLI, 2, 8), ATTK(AT_BITE, AD_DRLI, 1, 8),
          ATTK(AT_MAGC, AD_SPEL, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK),
        SIZ(WT_HUMAN, 400, 0, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP|MR_POISON, 0,
index 0ab90c99fb71bc141a503dd2197d723808718411..09b85f5eb5e8412762bb304bd0391b9f75502ce6 100644 (file)
@@ -282,7 +282,7 @@ m_throw(mon, x, y, dx, dy, range, obj)
            singleobj = obj;
            obj = (struct obj *) 0;
        } else {
-           singleobj = splitobj(obj, obj->quan - 1L);
+           singleobj = splitobj(obj, 1L);
            obj_extract_self(singleobj);
        }
 
@@ -557,6 +557,7 @@ struct monst *mtmp;
            case PM_ROGUE:
                    if (skill == P_DAGGER) multishot++;
                    break;
+           case PM_NINJA:
            case PM_SAMURAI:
                    if (otmp->otyp == YA && mwep &&
                        mwep->otyp == YUMI) multishot++;
index 7db3dc55b1803717eb2029bc93d72bb7c32dae0e..caa8e3ae75cd6eae877217f570ac2fa5247dc41b 100644 (file)
@@ -875,10 +875,10 @@ WAND((char *)0,        "jeweled",   0, 150, 1, 0,         IRON,     HI_MINERAL),
 #undef WAND
 
 /* coins ... - so far, gold is all there is */
-#define COIN(name,prob,metal) OBJECT( \
+#define COIN(name,prob,metal,worth) OBJECT( \
                OBJ(name,(char *)0), BITS(0,1,0,0,0,0,0,0,0,0,0,P_NONE,metal), 0, \
-               GOLD_CLASS, prob, 0, 1, 0, 0, 0, 0, 0, 0, HI_GOLD )
-       COIN("gold piece",      1000, GOLD),
+               GOLD_CLASS, prob, 0, 1, worth, 0, 0, 0, 0, 0, HI_GOLD )
+       COIN("gold piece",      1000, GOLD,1),
 #undef COIN
 
 /* gems ... - includes stones and rocks but not boulders */
index 056ff944ad9033206d3e7f6c902879260d45562a..0ad9650c879e1aea366e498c09bd28c42c83b3c0 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)objnam.c   3.3     2001/10/29      */
+/*     SCCS Id: @(#)objnam.c   3.3     2002/01/04      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2430,17 +2430,16 @@ typfnd:
                  makeplural(body_part(HAND)));
        }
 
-       otmp->owt = weight(otmp);
-       if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
        if (halfeaten && otmp->oclass == FOOD_CLASS) {
                if (otmp->otyp == CORPSE)
                        otmp->oeaten = mons[otmp->corpsenm].cnutrit;
                else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
-               otmp->owt /= 2;
-               otmp->oeaten /= 2;
-               if (!otmp->owt) otmp->owt = 1;
-               if (!otmp->oeaten) otmp->oeaten = 1;
+               /* (do this adjustment before setting up object's weight) */
+               consume_oeaten(otmp, 1);
        }
+       otmp->owt = weight(otmp);
+       if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
+
        return(otmp);
 }
 
index a9516f533be3de309ea2e922d0d7636b9bc4b4e9..5e256906a337b077a39fdfb571180c49b8866a88 100644 (file)
@@ -115,6 +115,11 @@ static struct Bool_Opt
 #else
        {"mail", (boolean *)0, TRUE},
 #endif
+#ifdef TTY_GRAPHICS
+       {"msg_window", &iflags.prevmsg_window, FALSE},
+#else
+       {"msg_window", (boolean *)0, FALSE},
+#endif
 #ifdef NEWS
        {"news", &iflags.news, TRUE},
 #else
index 35442ec7a8ef582e2e6f1c21eafd75034892c877..92b84c47ca656801c55660368d7d0248cf1e9095 100644 (file)
@@ -1081,11 +1081,10 @@ long count;
 boolean telekinesis;   /* not picking it up directly by hand */
 {
        int res, nearload;
-#ifdef GOLDOBJ
-       long umoney = money_cnt(invent);
-#endif
+#ifndef GOLDOBJ
        const char *where = (obj->ox == u.ux && obj->oy == u.uy) ?
                            "here" : "there";
+#endif
 
        if (obj->quan < count) {
            impossible("pickup_object: count %ld > quan %ld?",
@@ -1191,13 +1190,14 @@ boolean telekinesis;    /* not picking it up directly by hand */
        if (obj->oclass == GOLD_CLASS) flags.botl = 1;
 #endif
        if (obj->quan != count && obj->otyp != LOADSTONE)
-           (void) splitobj(obj, count);
+           obj = splitobj(obj, count);
 
        obj = pick_obj(obj);
 
        if (uwep && uwep == obj) mrg_to_wielded = TRUE;
        nearload = near_capacity();
-       prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0, obj, count);
+       prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0,
+             obj, count);
        mrg_to_wielded = FALSE;
        return 1;
 }
@@ -1406,12 +1406,15 @@ lootcont:
            struct obj *goldob = mkgoldobj(contribution);
 #else
        struct obj *goldob;
-        /* Find a money object to mess with */
-        for (goldob = invent; goldob; goldob = goldob->nobj) ;
+       /* Find a money object to mess with */
+       for (goldob = invent; goldob; goldob = goldob->nobj) {
+           if (goldob->oclass == GOLD_CLASS) break;
+       }
        if (goldob){
            long contribution = rnd((int)min(LARGEST_INT, goldob->quan));
-           if (contribution < goldob->quan) (void)splitobj(goldob, contribution);
-            freeinv(goldob);
+           if (contribution < goldob->quan)
+               goldob = splitobj(goldob, contribution);
+           freeinv(goldob);
 #endif
            if (IS_THRONE(levl[u.ux][u.uy].typ)){
                struct obj *coffers;
@@ -1515,11 +1518,12 @@ struct monst *mtmp;
 int *passed_info;
 boolean *prev_loot;
 {
-    struct obj *otmp;
     int c = -1;
     int timepassed = 0;
-    char qbuf[QBUFSZ];
 #ifdef STEED
+    struct obj *otmp;
+    char qbuf[QBUFSZ];
+
     /* 3.3.1 introduced the ability to remove saddle from a steed             */
     /*         *passed_info is set to TRUE if a loot query was given.               */
     /* *prev_loot is set to TRUE if something was actually acquired in here. */
@@ -1789,7 +1793,7 @@ register struct obj *obj;
            return res;
 
        if (obj->quan != count && obj->otyp != LOADSTONE)
-           (void) splitobj(obj, count);
+           obj = splitobj(obj, count);
 
        /* Remove the object from the list. */
        obj_extract_self(obj);
@@ -1822,7 +1826,9 @@ register struct obj *obj;
              otmp, count);
 
        if (is_gold) {
+#ifndef GOLDOBJ
                dealloc_obj(obj);
+#endif
                bot();  /* update character's gold piece count immediately */
        }
        return 1;
@@ -2109,11 +2115,8 @@ boolean put_in;
                    otmp = pick_list[i].item.a_obj;
                    count = pick_list[i].count;
                    if (count > 0 && count < otmp->quan) {
-                       otmp2 = splitobj(otmp, count);
+                       otmp = splitobj(otmp, count);
                        /* special split case also handled by askchain() */
-                       if (otmp == uwep) setuwep(otmp2);
-                       if (otmp == uquiver) setuqwep(otmp2);
-                       if (otmp == uswapwep) setuswapwep(otmp2);
                    }
                    res = put_in ? in_container(otmp) : out_container(otmp);
                    if (res < 0)
index 03bb108faa1610cd1440197a791801a9fab7f053..e94b941f5479d275557d6682f83acd0e6a7bc31c 100644 (file)
@@ -1817,7 +1817,7 @@ dodip()
                /* with multiple merged potions, split off one and
                   just clear it */
                if (potion->quan > 1L) {
-                       singlepotion = splitobj(potion, potion->quan - 1L);
+                   singlepotion = splitobj(potion, 1L);
                } else singlepotion = potion;
                
                if(singlepotion->unpaid && costly_spot(u.ux, u.uy)) {
index bda08ca9e44a2d0e844bb8e3ffbcfa8672add377..bb65e097e3e4f67af63f803c0141ee83075a3d10 100644 (file)
--- a/src/rip.c
+++ b/src/rip.c
@@ -111,10 +111,7 @@ int how;
 #ifndef GOLDOBJ
        Sprintf(buf, "%ld Au", u.ugold);
 #else
-       /* FIXME: this neglects gold in containers (which will be gone by
-          now if bones have been saved).  For the !GOLDOBJ configuration,
-          any such gold gets added into u.ugold by done(). */
-       Sprintf(buf, "%ld Au", money_cnt(invent));
+       Sprintf(buf, "%ld Au", done_money);
 #endif
        buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */
        center(GOLD_LINE, buf);
index 387f9c3943058e70b777f49023dcf0861b07bbb6..6265d74a9da0891e5579bf416a9a7c6d4f5141f3 100644 (file)
@@ -146,11 +146,16 @@ int mechanism;
        boolean reading = (mechanism == BY_COOKIE ||
                           mechanism == BY_PAPER);
 
-       if (reading && Blind) {
+       if (reading) {
+           /* deal with various things that prevent reading */
+           if (is_fainted() && mechanism == BY_COOKIE)
+               return;
+           else if (Blind) {
                if (mechanism == BY_COOKIE)
                        pline(fortune_msg);
                pline("What a pity that you cannot read it!");
-               return;
+               return;
+           }
        }
        line = getrumor(truth, buf, reading ? FALSE : TRUE);
        if (!*line)
index 3bbdf6b5506afe4c585647a6bd2fdfc7c6508251..f9f464bfcacc050fcde0611346e65b19297128b5 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -103,7 +103,7 @@ long amount;
                return 0;
        }
         
-        if (ygold->quan > amount) splitobj(ygold, amount);
+        if (ygold->quan > amount) ygold = splitobj(ygold, amount);
         freeinv(ygold);
        add_to_minv(mon, ygold);
         flags.botl = 1;
@@ -131,7 +131,7 @@ long amount;
                 return;
         }
    
-        if (mongold->quan > amount) splitobj(mongold, amount);
+        if (mongold->quan > amount) mongold = splitobj(mongold, amount);
         obj_extract_self(mongold);
 
         if (!merge_choice(invent, mongold) && inv_cnt() >= 52) {
@@ -2748,11 +2748,9 @@ int mode;                /* 0: deliver count 1: paged */
                uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
                thisused = bp->price * uquan;
                totused += thisused;
-               obj->quan = uquan;              /* cheat doname */
                obj->unpaid = 0;                /* ditto */
                /* Why 'x'?  To match `I x', more or less. */
-               buf_p = xprname(obj, (char *)0, 'x', FALSE, thisused);
-               obj->quan = oquan;              /* restore value */
+               buf_p = xprname(obj, (char *)0, 'x', FALSE, thisused, uquan);
 #ifdef __SASC
                                /* SAS/C 6.2 can't cope for some reason */
                sasc_bug(obj,save_unpaid);
@@ -2768,10 +2766,10 @@ int mode;               /* 0: deliver count 1: paged */
            totused += eshkp->debit;
            buf_p = xprname((struct obj *)0,
                            "usage charges and/or other fees",
-                           GOLD_SYM, FALSE, eshkp->debit);
+                           GOLD_SYM, FALSE, eshkp->debit, 0L);
            putstr(datawin, 0, buf_p);
        }
-       buf_p = xprname((struct obj *)0, "Total:", '*', FALSE, totused);
+       buf_p = xprname((struct obj *)0, "Total:", '*', FALSE, totused, 0L);
        putstr(datawin, 0, "");
        putstr(datawin, 0, buf_p);
        display_nhwindow(datawin, FALSE);
index 9b1c7196742460577eb04c6c2b9ae924ae206558..07ee028bc235c91322d46b571bda77decbfbbb0c 100644 (file)
@@ -850,8 +850,8 @@ struct mkroom       *croom;
 
                    case M_AP_OBJECT:
                        for (i = 0; i < NUM_OBJECTS; i++)
-                           if (!strcmp(OBJ_NAME(objects[i]),
-                                       m->appear_as.str))
+                           if (OBJ_NAME(objects[i]) &&
+                               !strcmp(OBJ_NAME(objects[i]),m->appear_as.str))
                                break;
                        if (i == NUM_OBJECTS) {
                            impossible(
index 665c87710ed13a76c6c5325f1f60e0ca0717108e..a519bbdb3bf8942f9eab91812e0825cadda74f12 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)steal.c    3.3     2001/10/15      */
+/*     SCCS Id: @(#)steal.c    3.3     2002/01/04      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -123,7 +123,7 @@ register struct monst *mtmp;
             const int gold_price = objects[GOLD_PIECE].oc_cost;
            tmp = (somegold(money_cnt(invent)) + gold_price - 1) / gold_price;
            tmp = min(tmp, ygold->quan);
-            if (tmp < ygold->quan) splitobj(ygold, tmp);
+            if (tmp < ygold->quan) ygold = splitobj(ygold, tmp);
             freeinv(ygold);
             add_to_minv(mtmp, ygold);
            Your("purse feels lighter.");
@@ -229,6 +229,11 @@ char *objnambuf;
        /* the following is true if successful on first of two attacks. */
        if(!monnear(mtmp, u.ux, u.uy)) return(0);
 
+       /* food being eaten might already be used up but will not have
+          been removed from inventory yet; we don't want to steal that,
+          so this will cause it to be removed now */
+       if (occupation) (void) maybe_finished_meal(FALSE);
+
        if (!invent || (inv_cnt() == 1 && uskin)) {
 nothing_to_steal:
            /* Not even a thousand men in armor can strip a naked man. */
index b347464c0afed3da9a2d536d6dbb0eeba65c7c67..8d63c3e8ee022eb4c0a17ee57c5c5a1c2843eef6 100644 (file)
@@ -204,7 +204,19 @@ void
 teleds(nux, nuy)
 register int nux,nuy;
 {
-       if (Punished) unplacebc();
+       boolean dont_teleport_ball = FALSE;
+
+       if (Punished) {
+           /* If they're teleporting to a position where the ball doesn't need
+            * to be moved, don't place the ball.  Especially useful when this
+            * function is being called for crawling out of water instead of
+            * real teleportation.
+            */
+           if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2)
+               dont_teleport_ball = TRUE;
+           else
+               unplacebc();
+       }
        u.utrap = 0;
        u.ustuck = 0;
        u.ux0 = u.ux;
@@ -228,7 +240,19 @@ register int nux,nuy;
                u.uswldtim = u.uswallow = 0;
                docrt();
        }
-       if (Punished) placebc();
+       if (Punished) {
+           if (dont_teleport_ball) {
+               int bc_control;
+               xchar ballx, bally, chainx, chainy;
+               boolean cause_delay;
+
+               /* this should only drag the chain (and never give a near-
+                  capacity message) since we already checked ball distance */
+               drag_ball(u.ux, u.uy, &bc_control, &ballx, &bally, &chainx, &chainy, &cause_delay);
+               move_bc(0, bc_control, ballx, bally, chainx, chainy);
+           } else
+                placebc();
+       }
        initrack(); /* teleports mess up tracking monsters without this */
        update_player_regions();
 #ifdef STEED
index 9150c062e9c8a50a86f3c67242e5067542954e4a..0df175e05576a2b46cd2134e103f52407cf61ce4 100644 (file)
@@ -1160,7 +1160,7 @@ int style;
            singleobj = otmp;
            otmp = (struct obj *) 0;
        } else {
-           singleobj = splitobj(otmp, otmp->quan - 1L);
+           singleobj = splitobj(otmp, 1L);
            obj_extract_self(singleobj);
        }
        newsym(x1,y1);
index 5167d818c34881bbb282f197a5dbbebdcfb14451..ee0d0017294c92fb93991d22c98cca2b1455a092 100644 (file)
@@ -634,7 +634,7 @@ int thrown;
                }
            } else if(obj->oclass == POTION_CLASS) {
                if (obj->quan > 1L)
-                   setworn(splitobj(obj, 1L), W_WEP);
+                   obj = splitobj(obj, 1L);
                else
                    setuwep((struct obj *)0);
                freeinv(obj);
index d468aaaba2d0eff2eb9e5b2d36a90bb717e1017a..8c1aa14fe7b0dbcc60f3ef1a9f33d1a247dd686a 100644 (file)
@@ -6,6 +6,7 @@
 
 STATIC_DCL void FDECL(m_lose_armor, (struct monst *,struct obj *));
 STATIC_DCL void FDECL(m_dowear_type, (struct monst *,long,BOOLEAN_P));
+STATIC_DCL int FDECL(extra_pref, (struct monst *, struct obj *));
 
 const struct worn {
        long w_mask;
@@ -114,16 +115,16 @@ register struct obj *obj;
        if (!obj) return;
        if (obj == uwep || obj == uswapwep) u.twoweap = 0;
        for(wp = worn; wp->w_mask; wp++)
-               if(obj == *(wp->w_obj)) {
-                       *(wp->w_obj) = 0;
-                       p = objects[obj->otyp].oc_oprop;
-                       u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask;
-                       obj->owornmask &= ~wp->w_mask;
-                       if (obj->oartifact)
-                           set_artifact_intrinsic(obj, 0, wp->w_mask);
-                       if ((p = w_blocks(obj,wp->w_mask)) != 0)
-                           u.uprops[p].blocked &= ~wp->w_mask;
-               }
+           if(obj == *(wp->w_obj)) {
+               *(wp->w_obj) = 0;
+               p = objects[obj->otyp].oc_oprop;
+               u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask;
+               obj->owornmask &= ~wp->w_mask;
+               if (obj->oartifact)
+                   set_artifact_intrinsic(obj, 0, wp->w_mask);
+               if ((p = w_blocks(obj,wp->w_mask)) != 0)
+                   u.uprops[p].blocked &= ~wp->w_mask;
+           }
        update_inventory();
 }
 
@@ -404,7 +405,8 @@ boolean creation;
             * it would forget spe and once again think the object is better
             * than what it already has.
             */
-           if (best && (ARM_BONUS(best) >= ARM_BONUS(obj))) continue;
+           if (best && (ARM_BONUS(best) + extra_pref(mon,best) >= ARM_BONUS(obj) + extra_pref(mon,obj)))
+               continue;
            best = obj;
        }
 outer_break:
@@ -667,4 +669,16 @@ boolean polyspot;
        return;
 }
 
+/* bias a monster's preferences towards armor that has special benefits. */
+/* currently only does speed boots, but might be expanded if monsters get to
+   use more armor abilities */
+static int
+extra_pref(struct monst *mon, struct obj *obj)
+{
+    if (obj) {
+       if (obj->otyp == SPEED_BOOTS && mon->permspeed != MFAST)
+           return 20;
+    }
+    return 0;
+}
 /*worn.c*/
index d0f73a8086b25e1aac24ecf71401b0f67436d38c..8c44d94f41ad011431f8d9bdab9b29543fc71063 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -140,6 +140,7 @@ struct obj *otmp;
        case SPE_SLOW_MONSTER:
                if (!resist(mtmp, otmp->oclass, 0, NOTELL)) {
                        mon_adjust_speed(mtmp, -1);
+                       m_dowear(mtmp, FALSE); /* might want speed boots */
                        if (u.uswallow && (mtmp == u.ustuck) &&
                            is_whirly(mtmp->data)) {
                                You("disrupt %s!", mon_nam(mtmp));
@@ -149,8 +150,10 @@ struct obj *otmp;
                }
                break;
        case WAN_SPEED_MONSTER:
-               if (!resist(mtmp, otmp->oclass, 0, NOTELL))
+               if (!resist(mtmp, otmp->oclass, 0, NOTELL)) {
                        mon_adjust_speed(mtmp, 1);
+                       m_dowear(mtmp, FALSE); /* might want speed boots */
+               }
                break;
        case WAN_UNDEAD_TURNING:
        case SPE_TURN_UNDEAD:
@@ -450,7 +453,7 @@ coord *cc;
                if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data))
                        return (struct monst *)0;
                mtmp = makemon(mtmp2->data,
-                               cc->x, cc->y, NO_MINVENT|MM_NOWAIT);
+                               cc->x, cc->y, NO_MINVENT|MM_NOWAIT|MM_NOCOUNTBIRTH);
                if (!mtmp) return mtmp;
 
                /* heal the monster */
@@ -610,7 +613,7 @@ register struct obj *obj;
                                wary_dog(mtmp, TRUE);
                    } else
                            mtmp = makemon(&mons[montype], x, y,
-                                      NO_MINVENT|MM_NOWAIT);
+                                      NO_MINVENT|MM_NOWAIT|MM_NOCOUNTBIRTH);
                    if (mtmp) {
                        if (obj->oxlth && (obj->oattached == OATTACHED_M_ID)) {
                            unsigned m_id;
@@ -666,7 +669,7 @@ register struct obj *obj;
                                x = obj->ox,  y = obj->oy;
                                /* not useupf(), which charges */
                                if (obj->quan > 1L)
-                                   (void) splitobj(obj, 1L);
+                                   obj = splitobj(obj, 1L);
                                delobj(obj);
                                newsym(x, y);
                                break;
@@ -1134,9 +1137,9 @@ struct obj *obj;
        /* if quan > 1 then some will survive intact */
        if (obj->quan > 1L) {
            if (obj->quan > LARGEST_INT)
-               (void) splitobj(obj, (long)rnd(30000));
+               obj = splitobj(obj, (long)rnd(30000));
            else
-               (void) splitobj(obj, (long)rnd((int)obj->quan - 1));
+               obj = splitobj(obj, (long)rnd((int)obj->quan - 1));
        }
 
        /* appropriately add damage to bill */
@@ -2504,10 +2507,13 @@ register const char *str;
 register struct monst *mtmp;
 register const char *force;            /* usually either "." or "!" */
 {
+       int pl = strcmp(str, makesingular(str));
+
        if((!cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp))
           || !flags.verbose)
-           pline("%s hits it.", The(str));
-       else pline("%s hits %s%s", The(str), mon_nam(mtmp), force);
+           pline("%s %s it.", The(str), pl ? "hit" : "hits");
+       else pline("%s %s %s%s", The(str), pl ? "hit" : "hits",
+                  mon_nam(mtmp), force);
 }
 
 void
@@ -2515,7 +2521,9 @@ miss(str,mtmp)
 register const char *str;
 register struct monst *mtmp;
 {
-       pline("%s misses %s.", The(str),
+       int pl = strcmp(str, makesingular(str));
+
+       pline("%s %s %s.", The(str), pl ? "miss" : "misses",
              ((cansee(bhitpos.x,bhitpos.y) || canspotmon(mtmp))
               && flags.verbose) ?
              mon_nam(mtmp) : "it");
index bd60aa321870d0663f8fc77b00cd6a3172cd37a9..c41110a4faddd83e1ace14d8c74b1f79d19988f7 100644 (file)
@@ -199,7 +199,7 @@ int how;
 #ifndef GOLDOBJ
                u.ugold);
 #else
-               money_cnt(invent));
+               done_money);
 #endif
     buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */
     tomb_text(buf);
index dd0f190e25fb406e2f40d47793b258af65c0c4b0..ac9c3b172f621806df8a8a4fbc55d41e92e556e0 100644 (file)
@@ -2441,7 +2441,11 @@ void NetHackQtStatusWindow::updateStats()
        dlevel.setLabel(buf,(long)depth(&u.uz));
     }
 
-    gold.setLabel("Au:",(long)u.ugold);
+#ifndef GOLDOBJ
+    gold.setLabel("Au:", u.ugold);
+#else
+    gold.setLabel("Au:", money_cnt(invent));
+#endif
     if (u.mtimedone) {
        // You're a monster!
 
@@ -3166,7 +3170,11 @@ static char** rip_line=0;
     Sprintf(rip_line[NAME_LINE], "%s", plname);
 
     /* Put $ on stone */
+#ifndef GOLDOBJ
     Sprintf(rip_line[GOLD_LINE], "%ld Au", u.ugold);
+#else
+    Sprintf(rip_line[GOLD_LINE], "%ld Au", done_money);
+#endif
 
     /* Put together death description */
     switch (killer_format) {
index dc1ab1768bcd112bd883bd0c883376ae800874b0..df017456df50c86c10e1e56a2abb89498b7e7d46 100644 (file)
@@ -59,10 +59,10 @@ NetHack*message*translations:       <KeyPress>: input()
 ! It is not guaranteed that the window manager will honor the icon selection.
 !NetHack*icon: nh56
 !
-! If True, a popup for single character prompts such as y/n questions is _not_
-! used.
-!NetHack*slow: True
-!
+! If True, the default, a popup for single character prompts such as y/n
+! questions is _not_ used.
+NetHack*slow: True
+
 ! The number of lines the message window will show without scrolling.
 !NetHack*message_lines: 12
 !
index 0b43eb97075863533bbc76cd7457d06619418a80..2d767f2a6ebaee7e49def575919e0aeffbe78e35 100644 (file)
@@ -902,7 +902,7 @@ static XtActionsRec actions[] = {
 
 static XtResource resources[] = {
     { "slow", "Slow", XtRBoolean, sizeof(Boolean),
-      XtOffset(AppResources *,slow), XtRString, "False" },
+      XtOffset(AppResources *,slow), XtRString, "True" },
     { "autofocus", "AutoFocus", XtRBoolean, sizeof(Boolean),
       XtOffset(AppResources *,autofocus), XtRString, "False" },
     { "message_line", "Message_line", XtRBoolean, sizeof(Boolean),
index ee0d7533cadb0fd8dc983776682cf23efd6cb80c..21203ebccc4f184c536b0ce44d321a8204acf321 100644 (file)
@@ -471,7 +471,7 @@ calculate_rip_text(int how)
 #ifndef GOLDOBJ
                u.ugold);
 #else
-               money_cnt(invent));
+               done_money);
 #endif
        /* Put together death description */
        switch (killer_format) {
index 3fed89b245bcf252d297974e154460625d306ce7..a874fde2c342fb0ed69a1433ad1ad8e62cf785c1 100644 (file)
@@ -977,7 +977,7 @@ void gnome_outrip(winid wid, int how)
 #ifndef GOLDOBJ
                u.ugold);
 #else
-               money_cnt(invent));
+               done_money);
 #endif
     Strcat(ripString, buf);
 
index 1d9a725c0d3e95d023cf158ceefbe80d53f071f7..3bee369c3d6fae4fd476714c354310589bbb29eb 100644 (file)
@@ -72,12 +72,22 @@ getlin_hook_proc hook;
                    *bufp = 0;
                }
                if(c == '\020') { /* ctrl-P */
-                   if(!doprev)
-                       (void) tty_doprev_message(); /* need two initially */
-                   (void) tty_doprev_message();
-                   doprev = 1;
-                   continue;
-               } else if(doprev) {
+                   if (iflags.prevmsg_window) {
+                       (void) tty_doprev_message();
+                       tty_clear_nhwindow(WIN_MESSAGE);
+                       cw->maxcol = cw->maxrow;
+                       addtopl(query);
+                       addtopl(" ");
+                       *bufp = 0;
+                       addtopl(obufp);
+                   } else {
+                       if (!doprev)
+                           (void) tty_doprev_message();/* need two initially */
+                       (void) tty_doprev_message();
+                       doprev = 1;
+                       continue;
+                   }
+               } else if (doprev && !iflags.prevmsg_window) {
                    tty_clear_nhwindow(WIN_MESSAGE);
                    cw->maxcol = cw->maxrow;
                    doprev = 0;
index 98d4248e5aca3f21495fa66cfa466860f0aa5ad3..02d0df0291f26786fef9011d2f0bdab4a60a2ca8 100644 (file)
@@ -26,19 +26,37 @@ tty_doprev_message()
 {
     register struct WinDesc *cw = wins[WIN_MESSAGE];
 
-    ttyDisplay->dismiss_more = C('p'); /* <ctrl/P> allowed at --More-- */
-    do {
-       morc = 0;
-       if (cw->maxcol == cw->maxrow)
-           redotoplin(toplines);
-       else if (cw->data[cw->maxcol])
-           redotoplin(cw->data[cw->maxcol]);
-       cw->maxcol--;
-       if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
-       if (!cw->data[cw->maxcol])
-           cw->maxcol = cw->maxrow;
-    } while (morc == C('p'));
-    ttyDisplay->dismiss_more = 0;
+    winid prevmsg_win;
+    int i;
+
+    if (iflags.prevmsg_window) {
+       prevmsg_win = create_nhwindow(NHW_MENU);
+       putstr(prevmsg_win, 0, "Message History");
+       putstr(prevmsg_win, 0, "");
+       i = cw->maxcol;
+       do {
+           if(cw->data[i] && strcmp(cw->data[i], "") )
+               putstr(prevmsg_win, 0, cw->data[i]);
+           i = (i + 1) % cw->rows;
+       } while (i != cw->maxcol);
+       putstr(prevmsg_win, 0, toplines);
+       display_nhwindow(prevmsg_win, TRUE);
+       destroy_nhwindow(prevmsg_win);
+    } else {
+       ttyDisplay->dismiss_more = C('p');  /* <ctrl/P> allowed at --More-- */
+       do {
+           morc = 0;
+           if (cw->maxcol == cw->maxrow)
+               redotoplin(toplines);
+           else if (cw->data[cw->maxcol])
+               redotoplin(cw->data[cw->maxcol]);
+           cw->maxcol--;
+           if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
+           if (!cw->data[cw->maxcol])
+               cw->maxcol = cw->maxrow;
+       } while (morc == C('p'));
+       ttyDisplay->dismiss_more = 0;
+    }
     return 0;
 }
 
@@ -147,7 +165,9 @@ update_topl(bp)
        /* If there is room on the line, print message on same line */
        /* But messages like "You die..." deserve their own line */
        n0 = strlen(bp);
-       if(ttyDisplay->toplin == 1 && cw->cury == 0 &&
+       if( (ttyDisplay->toplin == 1 || 
+               (cw->flags & WIN_STOP && iflags.prevmsg_window)) &&
+           cw->cury == 0 &&
            n0 + (int)strlen(toplines) + 3 < CO-8 &&  /* room for --More-- */
            (notdied = strncmp(bp, "You die", 7))) {
                Strcat(toplines, "  ");
@@ -156,7 +176,7 @@ update_topl(bp)
                if(!(cw->flags & WIN_STOP))
                    addtopl(bp);
                return;
-       } else if(!(cw->flags & WIN_STOP)) {
+       } else if (!(cw->flags & WIN_STOP && !iflags.prevmsg_window)) {
            if(ttyDisplay->toplin == 1) more();
            else if(cw->cury) { /* for when flags.toplin == 2 && cury > 1 */
                docorner(1, cw->cury+1); /* reset cury = 0 if redraw screen */
@@ -279,9 +299,16 @@ char def;
        do {    /* loop until we get valid input */
            q = lowc(readchar());
            if (q == '\020') { /* ctrl-P */
-               if(!doprev) (void) tty_doprev_message(); /* need two initially */
-               (void) tty_doprev_message();
-               doprev = 1;
+               if (iflags.prevmsg_window) {
+                   (void) tty_doprev_message();
+                   tty_clear_nhwindow(WIN_MESSAGE);
+                   cw->maxcol = cw->maxrow;
+                   addtopl(prompt);
+               } else {
+                   if(!doprev) (void) tty_doprev_message(); /* need two initially */
+                   (void) tty_doprev_message();
+                   doprev = 1;
+               }
                q = '\0';       /* force another loop iteration */
                continue;
            } else if (doprev) {
index 0387e56fa2d57a42bad0355e6eaf0137ea6999e8..b281e982213ba3323d1e252e6d4f6469ccd615be 100644 (file)
@@ -1732,7 +1732,9 @@ tty_putstr(window, attr, str)
        return;
     }
 
-    if(str == (const char*)0 || (cw->flags & WIN_CANCELLED))
+    if(str == (const char*)0 ||
+       ( (cw->flags & WIN_CANCELLED) && 
+         (cw->type != NHW_MESSAGE || !iflags.prevmsg_window) ))
        return;
     if(cw->type != NHW_MESSAGE)
        str = compress_str(str);
@@ -2215,7 +2217,8 @@ tty_wait_synch()
            /* this can only happen if we were reading and got interrupted */
            ttyDisplay->toplin = 3;
            /* do this twice; 1st time gets the Quit? message again */
-           (void) tty_doprev_message();
+           if (!iflags.prevmsg_window)
+               (void) tty_doprev_message();
            (void) tty_doprev_message();
            ttyDisplay->intr++;
            (void) fflush(stdout);