-/* 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
* =============================================================*/
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()
{
ballrelease(TRUE);
if (gets_hit) {
int dmg = rn1(7, 25);
+
/*JP
pline_The("iron ball falls on your %s.", body_part(HEAD));
*/
/*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",
(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);
/* 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)) {
return TRUE;
}
-drag:
+ drag:
if (near_capacity() > SLT_ENCUMBER && dist2(x, y, u.ux, u.uy) <= 2) {
#if 0 /*JP*/
|| !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.");
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);
}
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
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");
*/
}
break;
}
- }
- u.utrap = 0;
+ reset_utrap(TRUE);
fill_pit(u.ux, u.uy);
}
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 {
}
}
+/* 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;
}
}
*/
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
}
}
+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*/