OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / src / ball.c
index a55671d..e3e1196 100644 (file)
@@ -1,7 +1,13 @@
-/* NetHack 3.6 ball.c  $NHDT-Date: 1446808438 2015/11/06 11:13:58 $  $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ */
+/* NetHack 3.6 ball.c  $NHDT-Date: 1557088406 2019/05/05 20:33:26 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.36 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/*-Copyright (c) David Cohrs, 2006. */
 /* NetHack may be freely redistributed.  See license for details. */
 
+/* JNetHack Copyright */
+/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
+/* JNetHack may be freely redistributed.  See license for details. */
+
 /* Ball & Chain
  * =============================================================*/
 
@@ -26,12 +32,14 @@ boolean showmsg;
             setuswapwep((struct obj *) 0);
         if (uquiver == uball)
             setuqwep((struct obj *) 0);
-        ;
-        if (uwep != uball)
-            freeinv(uball);
+        /* [this used to test 'if (uwep != uball)' but that always passes
+           after the setuwep() above] */
+        freeinv(uball); /* remove from inventory but don't place on floor */
+        encumber_msg();
     }
 }
 
+/* ball&chain might hit hero when falling through a trap door */
 void
 ballfall()
 {
@@ -42,6 +50,7 @@ ballfall()
     ballrelease(TRUE);
     if (gets_hit) {
         int dmg = rn1(7, 25);
+
 /*JP
         pline_The("iron ball falls on your %s.", body_part(HEAD));
 */
@@ -57,7 +66,7 @@ ballfall()
 /*JP
                 pline("%s does not protect you.", Yname2(uarmh));
 */
-                Your("%s\82Å\82Í\8eç\82ê\82È\82¢\81D", Yname2(uarmh));
+                Your("%s\82Å\82Í\8eç\82ê\82È\82¢\81D", xname(uarmh));
         }
 #if 0 /*JP*/
         losehp(Maybe_Half_Phys(dmg), "crunched in the head by an iron ball",
@@ -128,9 +137,9 @@ placebc()
 
     (void) flooreffects(uchain, u.ux, u.uy, ""); /* chain might rust */
 
-    if (carried(uball)) /* the ball is carried */
+    if (carried(uball)) /* the ball is carried */
         u.bc_order = BCPOS_DIFFER;
-    else {
+    else {
         /* ball might rust -- already checked when carried */
         (void) flooreffects(uball, u.ux, u.uy, "");
         place_object(uball, u.ux, u.uy);
@@ -426,6 +435,7 @@ boolean allow_drag;
     /* only need to move the chain? */
     if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) {
         xchar oldchainx = uchain->ox, oldchainy = uchain->oy;
+
         *bc_control = BC_CHAIN;
         move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
         if (carried(uball)) {
@@ -599,7 +609,7 @@ boolean allow_drag;
         return TRUE;
     }
 
-drag:
+ drag:
 
     if (near_capacity() > SLT_ENCUMBER && dist2(x, y, u.ux, u.uy) <= 2) {
 #if 0 /*JP*/
@@ -619,8 +629,7 @@ drag:
              || !is_pool(uball->ox, uball->oy)
              || levl[uball->ox][uball->oy].typ == POOL))
         || ((t = t_at(uchain->ox, uchain->oy))
-            && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == HOLE
-                || t->ttyp == TRAPDOOR))) {
+            && (is_pit(t->ttyp) || is_hole(t->ttyp)))) {
         if (Levitation) {
 /*JP
             You_feel("a tug from the iron ball.");
@@ -637,11 +646,13 @@ drag:
             You("\93S\8b\85\82É\82®\82¢\82Æ\88ø\82Á\82Ï\82ç\82ê\82½\81I");
             if ((victim = m_at(uchain->ox, uchain->oy)) != 0) {
                 int tmp;
+                int dieroll = rnd(20);
 
                 tmp = -2 + Luck + find_mac(victim);
                 tmp += omon_adj(victim, uball, TRUE);
-                if (tmp >= rnd(20))
-                    (void) hmon(victim, uball, HMON_DRAGGED);
+
+                if (tmp >= dieroll)
+                    (void) hmon(victim, uball, HMON_DRAGGED, dieroll);
                 else
                     miss(xname(uball), victim);
 
@@ -728,14 +739,15 @@ xchar x, y;
     }
 
     if (x != u.ux || y != u.uy) {
-        struct trap *t;
 /*JP
-        const char *pullmsg = "The ball pulls you out of the %s!";
+        static const char *pullmsg = "The ball pulls you out of the %s!";
 */
-        const char *pullmsg = "\93S\8b\85\82Í%s\82©\82ç\82 \82È\82½\82ð\88ø\82Á\82Ï\82è\8fo\82µ\82½\81I";
+        static const char *pullmsg = "\93S\8b\85\82Í%s\82©\82ç\82 \82È\82½\82ð\88ø\82Á\82Ï\82è\8fo\82µ\82½\81I";
+        struct trap *t;
+        long side;
 
-        if (u.utrap && u.utraptype != TT_INFLOOR
-            && u.utraptype != TT_BURIEDBALL) {
+        if (u.utrap
+            && u.utraptype != TT_INFLOOR && u.utraptype != TT_BURIEDBALL) {
             switch (u.utraptype) {
             case TT_PIT:
 /*JP
@@ -756,12 +768,12 @@ xchar x, y;
                 break;
             case TT_LAVA:
 /*JP
-                pline(pullmsg, "lava");
+                pline(pullmsg, hliquid("lava"));
 */
-                pline(pullmsg, "\97n\8aâ");
+                pline(pullmsg, hliquid("\97n\8aâ"));
                 break;
-            case TT_BEARTRAP: {
-                register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
+            case TT_BEARTRAP:
+                side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
 /*JP
                 pline(pullmsg, "bear trap");
 */
@@ -789,8 +801,7 @@ xchar x, y;
                 }
                 break;
             }
-            }
-            u.utrap = 0;
+            reset_utrap(TRUE);
             fill_pit(u.ux, u.uy);
         }
 
@@ -799,8 +810,8 @@ xchar x, y;
         if (!Levitation && !MON_AT(x, y) && !u.utrap
             && (is_pool(x, y)
                 || ((t = t_at(x, y))
-                    && (t->ttyp == PIT || t->ttyp == SPIKED_PIT
-                        || t->ttyp == TRAPDOOR || t->ttyp == HOLE)))) {
+                    && (is_pit(t->ttyp)
+                        || is_hole(t->ttyp))))) {
             u.ux = x;
             u.uy = y;
         } else {
@@ -829,24 +840,29 @@ xchar x, y;
     }
 }
 
+/* ball&chain cause hero to randomly lose stuff from inventory */
 STATIC_OVL void
 litter()
 {
-    struct obj *otmp = invent, *nextobj;
+    struct obj *otmp, *nextobj = 0;
     int capacity = weight_cap();
 
-    while (otmp) {
+    for (otmp = invent; otmp; otmp = nextobj) {
         nextobj = otmp->nobj;
         if ((otmp != uball) && (rnd(capacity) <= (int) otmp->owt)) {
             if (canletgo(otmp, "")) {
-/*JP
-                pline("%s you down the stairs.", Yobjnam2(otmp, "follow"));
-*/
-                You("%s\82Æ\88ê\8f\8f\82É\8aK\92i\82ð\8d~\82è\82½\81D", xname(otmp));
+#if 0 /*JP*/
+                You("drop %s and %s %s down the stairs with you.",
+                    yname(otmp), (otmp->quan == 1L) ? "it" : "they",
+                    otense(otmp, "fall"));
+#else
+                You("%s\82ð\97\8e\82Æ\82µ\81C\82»\82ê\82Í\82 \82È\82½\82Æ\88ê\8f\8f\82É\8aK\92i\82ð\97\8e\82¿\82Ä\82¢\82Á\82½\81D",
+                    yname(otmp));
+#endif
                 dropx(otmp);
+                encumber_msg(); /* drop[xyz]() probably ought to to this... */
             }
         }
-        otmp = nextobj;
     }
 }
 
@@ -872,6 +888,9 @@ drag_down()
 */
         You("\93S\8b\85\82ð\8eè\82©\82ç\97\8e\82µ\82Ä\82µ\82Ü\82Á\82½\81D");
 
+    cls();  /* previous level is still displayed although you
+               went down the stairs. Avoids bug C343-20 */
+
     if (forward) {
         if (rn2(6)) {
 /*JP
@@ -915,4 +934,65 @@ drag_down()
     }
 }
 
+void
+bc_sanity_check()
+{
+    int otyp;
+    unsigned save_nameknown;
+    const char *onam;
+
+    if (Punished && (!uball || !uchain)) {
+        impossible("Punished without %s%s%s?",
+                   !uball ? "iron ball" : "",
+                   (!uball && !uchain) ? " and " : "",
+                   !uchain ? "attached chain" : "");
+    } else if (!Punished && (uball || uchain)) {
+        impossible("Attached %s%s%s without being Punished?",
+                   uchain ? "chain" : "",
+                   (uchain && uball) ? " and " : "",
+                   uball ? "iron ball" : "");
+    }
+    /* ball is free when swallowed, changing levels, other times? */
+    if (uball && (uball->otyp != HEAVY_IRON_BALL
+                  || (uball->where != OBJ_FLOOR
+                      && uball->where != OBJ_INVENT
+                      && uball->where != OBJ_FREE)
+                  || (uball->owornmask & W_BALL) == 0L
+                  || (uball->owornmask & ~(W_BALL | W_WEAPON)) != 0L)) {
+        otyp = uball->otyp;
+        if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
+            || !OBJ_NAME(objects[otyp])) {
+            onam = "glorkum";
+        } else {
+            save_nameknown = objects[otyp].oc_name_known;
+            objects[otyp].oc_name_known = 1;
+            onam = simple_typename(otyp);
+            objects[otyp].oc_name_known = save_nameknown;
+        }
+        impossible("uball: type %d (%s), where %d, wornmask=0x%08lx",
+                   otyp, onam, uball->where, uball->owornmask);
+    }
+    /* similar check to ball except can't be in inventory */
+    if (uchain && (uchain->otyp != IRON_CHAIN
+                   || (uchain->where != OBJ_FLOOR
+                       && uchain->where != OBJ_FREE)
+                   /* [could simplify this to owornmask != W_CHAIN] */
+                   || (uchain->owornmask & W_CHAIN) == 0L
+                   || (uchain->owornmask & ~W_CHAIN) != 0L)) {
+        otyp = uchain->otyp;
+        if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
+            || !OBJ_NAME(objects[otyp])) {
+            onam = "glorkum";
+        } else {
+            save_nameknown = objects[otyp].oc_name_known;
+            objects[otyp].oc_name_known = 1;
+            onam = simple_typename(otyp);
+            objects[otyp].oc_name_known = save_nameknown;
+        }
+        impossible("uchain: type %d (%s), where %d, wornmask=0x%08lx",
+                   otyp, onam, uchain->where, uchain->owornmask);
+    }
+    /* [check bc_order too?] */
+}
+
 /*ball.c*/