* -1 11.46 12.50 12.5
* -2 5.21 4.17 0.0
* -3 2.08 0.0 0.0
- */
- if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&
- (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
- if (!rn2(4)) {
- int odds = 3 + (int)u.ualign.type, /* 2..4 */
- diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
-
- if (diff != 0) {
- assign_rnd_level(newlevel, &u.uz, diff);
- /* if inside the tower, stay inside */
- if (was_in_W_tower &&
- !On_W_tower_level(newlevel)) diff = 0;
- }
- if (diff == 0)
- assign_level(newlevel, &u.uz);
-
- new_ledger = ledger_no(newlevel);
-
- pline("A mysterious force momentarily surrounds you...");
- if (on_level(newlevel, &u.uz)) {
- (void) safe_teleds(FALSE);
- (void) next_to_u();
- return;
- } else
- at_stairs = at_ladder = FALSE;
- }
- }
+ */
+ if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&
+ (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
+ if (!rn2(4)) {
+ int odds = 3 + (int)u.ualign.type, /* 2..4 */
+ diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
+
+ if (diff != 0) {
+ assign_rnd_level(newlevel, &u.uz, diff);
+ /* if inside the tower, stay inside */
+ if (was_in_W_tower &&
+ !On_W_tower_level(newlevel)) diff = 0;
+ }
+ if (diff == 0)
+ assign_level(newlevel, &u.uz);
+
+ new_ledger = ledger_no(newlevel);
+
+ pline("A mysterious force momentarily surrounds you...");
+ if (on_level(newlevel, &u.uz)) {
+ (void) safe_teleds(FALSE);
+ (void) next_to_u();
+ return;
+ } else
+ at_stairs = at_ladder = FALSE;
+ }
+ }
- /* Prevent the player from going past the first quest level unless
- * (s)he has been given the go-ahead by the leader.
- */
- if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) {
- pline("A mysterious force prevents you from descending.");
- return;
- }
+ /* Prevent the player from going past the first quest level unless
+ * (s)he has been given the go-ahead by the leader.
+ */
+ if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) {
+ pline("A mysterious force prevents you from descending.");
+ return;
+ }
- if (on_level(newlevel, &u.uz)) return; /* this can happen */
-
- /* tethered movement makes level change while trapped feasible */
- if (u.utrap && u.utraptype == TT_BURIEDBALL)
- buried_ball_to_punishment(); /* (before we save/leave old level) */
-
- fd = currentlevel_rewrite();
- if (fd < 0) return;
-
- if (falling) /* assuming this is only trap door or hole */
- impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel);
-
- check_special_room(TRUE); /* probably was a trap door */
- if (Punished) unplacebc();
- u.utrap = 0; /* needed in level_tele */
- fill_pit(u.ux, u.uy);
- u.ustuck = 0; /* idem */
- u.uinwater = 0;
- u.uundetected = 0; /* not hidden, even if means are available */
- keepdogs(FALSE);
- if (u.uswallow) /* idem */
- u.uswldtim = u.uswallow = 0;
- recalc_mapseen(); /* recalculate map overview before we leave the level */
- /*
- * We no longer see anything on the level. Make sure that this
- * follows u.uswallow set to null since uswallow overrides all
- * normal vision.
- */
- vision_recalc(2);
-
- /*
- * Save the level we're leaving. If we're entering the endgame,
- * we can get rid of all existing levels because they cannot be
- * reached any more. We still need to use savelev()'s cleanup
- * for the level being left, to recover dynamic memory in use and
- * to avoid dangling timers and light sources.
- */
- cant_go_back = (newdungeon && In_endgame(newlevel));
- if (!cant_go_back) {
- update_mlstmv(); /* current monsters are becoming inactive */
- bufon(fd); /* use buffered output */
- }
- savelev(fd, ledger_no(&u.uz),
- cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE));
- bclose(fd);
- if (cant_go_back) {
- /* discard unreachable levels; keep #0 */
- for (l_idx = maxledgerno(); l_idx > 0; --l_idx)
- delete_levelfile(l_idx);
- /* mark #overview data for all dungeon branches as uninteresting */
- for (l_idx = 0; l_idx < n_dgns; ++l_idx)
- remdun_mapseen(l_idx);
- }
+ if (on_level(newlevel, &u.uz)) return; /* this can happen */
+
+ /* tethered movement makes level change while trapped feasible */
+ if (u.utrap && u.utraptype == TT_BURIEDBALL)
+ buried_ball_to_punishment(); /* (before we save/leave old level) */
+
+ fd = currentlevel_rewrite();
+ if (fd < 0) return;
+
+ if (falling) /* assuming this is only trap door or hole */
+ impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel);
+
+ check_special_room(TRUE); /* probably was a trap door */
+ if (Punished) unplacebc();
+ u.utrap = 0; /* needed in level_tele */
+ fill_pit(u.ux, u.uy);
+ u.ustuck = 0; /* idem */
+ u.uinwater = 0;
+ u.uundetected = 0; /* not hidden, even if means are available */
+ keepdogs(FALSE);
+ if (u.uswallow) /* idem */
+ u.uswldtim = u.uswallow = 0;
+ recalc_mapseen(); /* recalculate map overview before we leave the level */
+ /*
+ * We no longer see anything on the level. Make sure that this
+ * follows u.uswallow set to null since uswallow overrides all
+ * normal vision.
+ */
+ vision_recalc(2);
+
+ /*
+ * Save the level we're leaving. If we're entering the endgame,
+ * we can get rid of all existing levels because they cannot be
+ * reached any more. We still need to use savelev()'s cleanup
+ * for the level being left, to recover dynamic memory in use and
+ * to avoid dangling timers and light sources.
+ */
+ cant_go_back = (newdungeon && In_endgame(newlevel));
+ if (!cant_go_back) {
+ update_mlstmv(); /* current monsters are becoming inactive */
+ bufon(fd); /* use buffered output */
+ }
+ savelev(fd, ledger_no(&u.uz),
+ cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE));
+ bclose(fd);
+ if (cant_go_back) {
+ /* discard unreachable levels; keep #0 */
+ for (l_idx = maxledgerno(); l_idx > 0; --l_idx)
+ delete_levelfile(l_idx);
+ /* mark #overview data for all dungeon branches as uninteresting */
+ for (l_idx = 0; l_idx < n_dgns; ++l_idx)
+ remdun_mapseen(l_idx);
+ }
- if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
- assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARY);
+ if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
+ assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARY);
#ifdef USE_TILES
- substitute_tiles(newlevel);
+ substitute_tiles(newlevel);
#endif
- /* record this level transition as a potential seen branch unless using
- * some non-standard means of transportation (level teleport).
- */
- if ((at_stairs || falling || portal) && (u.uz.dnum != newlevel->dnum))
- recbranch_mapseen(&u.uz, newlevel);
- assign_level(&u.uz0, &u.uz);
- assign_level(&u.uz, newlevel);
- assign_level(&u.utolev, newlevel);
- u.utotype = 0;
- if (dunlev_reached(&u.uz) < dunlev(&u.uz))
- dunlev_reached(&u.uz) = dunlev(&u.uz);
- reset_rndmonst(NON_PM); /* u.uz change affects monster generation */
-
- /* set default level change destination areas */
- /* the special level code may override these */
- (void) memset((genericptr_t) &updest, 0, sizeof updest);
- (void) memset((genericptr_t) &dndest, 0, sizeof dndest);
-
- if (!(level_info[new_ledger].flags & LFILE_EXISTS)) {
- /* entering this level for first time; make it now */
- if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) {
- impossible("goto_level: returning to discarded level?");
- level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED);
- }
- mklev();
- new = TRUE; /* made the level */
- } else {
- /* returning to previously visited level; reload it */
- fd = open_levelfile(new_ledger, whynot);
- if (fd < 0) {
- pline1(whynot);
- pline("Probably someone removed it.");
- Strcpy(killer.name, whynot);
- done(TRICKED);
- /* we'll reach here if running in wizard mode */
- error("Cannot continue this game.");
- }
- minit(); /* ZEROCOMP */
- getlev(fd, hackpid, new_ledger, FALSE);
- (void) close(fd);
- oinit(); /* reassign level dependent obj probabilities */
- }
- /* do this prior to level-change pline messages */
- vision_reset(); /* clear old level's line-of-sight */
- vision_full_recalc = 0; /* don't let that reenable vision yet */
- flush_screen(-1); /* ensure all map flushes are postponed */
-
- if (portal && !In_endgame(&u.uz)) {
- /* find the portal on the new level */
- register struct trap *ttrap;
-
- for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap)
- if (ttrap->ttyp == MAGIC_PORTAL) break;
-
- if (!ttrap) panic("goto_level: no corresponding portal!");
- seetrap(ttrap);
- u_on_newpos(ttrap->tx, ttrap->ty);
- } else if (at_stairs && !In_endgame(&u.uz)) {
- if (up) {
- if (at_ladder)
- u_on_newpos(xdnladder, ydnladder);
- else if (newdungeon)
- u_on_sstairs(1);
- else
- u_on_dnstairs();
- /* you climb up the {stairs|ladder};
- fly up the stairs; fly up along the ladder */
- pline("%s %s up%s the %s.",
- (Punished && !Levitation) ? "With great effort you" :
- "You",
- Flying ? "fly" : "climb",
- (Flying && at_ladder) ? " along" : "",
- at_ladder ? "ladder" : "stairs");
- } else { /* down */
- if (at_ladder)
- u_on_newpos(xupladder, yupladder);
- else if (newdungeon)
- u_on_sstairs(0);
- else
- u_on_upstairs();
- if (!u.dz) {
- ; /* stayed on same level? (no transit effects) */
- } else if (Flying) {
- if (flags.verbose)
- You("fly down %s.",
- at_ladder ? "along the ladder" : "the stairs");
- } else if (near_capacity() > UNENCUMBERED ||
- Punished || Fumbling) {
- You("fall down the %s.", at_ladder ? "ladder" : "stairs");
- if (Punished) {
- drag_down();
- if (carried(uball)) {
- if (uwep == uball)
- setuwep((struct obj *)0);
- if (uswapwep == uball)
- setuswapwep((struct obj *)0);
- if (uquiver == uball)
- setuqwep((struct obj *)0);
- freeinv(uball);
- }
- }
- /* falling off steed has its own losehp() call */
- if (u.usteed)
- dismount_steed(DISMOUNT_FELL);
- else
- losehp(Maybe_Half_Phys(rnd(3)),
- at_ladder ? "falling off a ladder" :
- "tumbling down a flight of stairs",
- KILLED_BY);
- selftouch("Falling, you");
- } else { /* ordinary descent */
- if (flags.verbose)
- You("%s.", at_ladder ? "climb down the ladder" :
- "descend the stairs");
- }
- }
- } else { /* trap door or level_tele or In_endgame */
- u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0));
- if (falling) {
- if (Punished) ballfall();
- selftouch("Falling, you");
- }
- }
+ /* record this level transition as a potential seen branch unless using
+ * some non-standard means of transportation (level teleport).
+ */
+ if ((at_stairs || falling || portal) && (u.uz.dnum != newlevel->dnum))
+ recbranch_mapseen(&u.uz, newlevel);
+ assign_level(&u.uz0, &u.uz);
+ assign_level(&u.uz, newlevel);
+ assign_level(&u.utolev, newlevel);
+ u.utotype = 0;
+ if (dunlev_reached(&u.uz) < dunlev(&u.uz))
+ dunlev_reached(&u.uz) = dunlev(&u.uz);
+ reset_rndmonst(NON_PM); /* u.uz change affects monster generation */
+
+ /* set default level change destination areas */
+ /* the special level code may override these */
+ (void) memset((genericptr_t) &updest, 0, sizeof updest);
+ (void) memset((genericptr_t) &dndest, 0, sizeof dndest);
+
+ if (!(level_info[new_ledger].flags & LFILE_EXISTS)) {
+ /* entering this level for first time; make it now */
+ if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) {
+ impossible("goto_level: returning to discarded level?");
+ level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED);
+ }
+ mklev();
+ new = TRUE; /* made the level */
+ } else {
+ /* returning to previously visited level; reload it */
+ fd = open_levelfile(new_ledger, whynot);
+ if (fd < 0) {
+ pline1(whynot);
+ pline("Probably someone removed it.");
+ Strcpy(killer.name, whynot);
+ done(TRICKED);
+ /* we'll reach here if running in wizard mode */
+ error("Cannot continue this game.");
+ }
+ minit(); /* ZEROCOMP */
+ getlev(fd, hackpid, new_ledger, FALSE);
+ (void) close(fd);
+ oinit(); /* reassign level dependent obj probabilities */
+ }
+ /* do this prior to level-change pline messages */
+ vision_reset(); /* clear old level's line-of-sight */
+ vision_full_recalc = 0; /* don't let that reenable vision yet */
+ flush_screen(-1); /* ensure all map flushes are postponed */
+
+ if (portal && !In_endgame(&u.uz)) {
+ /* find the portal on the new level */
+ register struct trap *ttrap;
+
+ for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap)
+ if (ttrap->ttyp == MAGIC_PORTAL) break;
+
+ if (!ttrap) panic("goto_level: no corresponding portal!");
+ seetrap(ttrap);
+ u_on_newpos(ttrap->tx, ttrap->ty);
+ } else if (at_stairs && !In_endgame(&u.uz)) {
+ if (up) {
+ if (at_ladder)
+ u_on_newpos(xdnladder, ydnladder);
+ else if (newdungeon)
+ u_on_sstairs(1);
+ else
+ u_on_dnstairs();
+ /* you climb up the {stairs|ladder};
+ fly up the stairs; fly up along the ladder */
+ pline("%s %s up%s the %s.",
+ (Punished && !Levitation) ? "With great effort you" :
+ "You",
+ Flying ? "fly" : "climb",
+ (Flying && at_ladder) ? " along" : "",
+ at_ladder ? "ladder" : "stairs");
+ } else { /* down */
+ if (at_ladder)
+ u_on_newpos(xupladder, yupladder);
+ else if (newdungeon)
+ u_on_sstairs(0);
+ else
+ u_on_upstairs();
+ if (!u.dz) {
+ ; /* stayed on same level? (no transit effects) */
+ } else if (Flying) {
+ if (flags.verbose)
+ You("fly down %s.",
+ at_ladder ? "along the ladder" : "the stairs");
+ } else if (near_capacity() > UNENCUMBERED ||
+ Punished || Fumbling) {
+ You("fall down the %s.", at_ladder ? "ladder" : "stairs");
+ if (Punished) {
+ drag_down();
+ if (carried(uball)) {
+ if (uwep == uball)
+ setuwep((struct obj *)0);
+ if (uswapwep == uball)
+ setuswapwep((struct obj *)0);
+ if (uquiver == uball)
+ setuqwep((struct obj *)0);
+ freeinv(uball);
+ }
+ }
+ /* falling off steed has its own losehp() call */
+ if (u.usteed)
+ dismount_steed(DISMOUNT_FELL);
+ else
+ losehp(Maybe_Half_Phys(rnd(3)),
+ at_ladder ? "falling off a ladder" :
+ "tumbling down a flight of stairs",
+ KILLED_BY);
+ selftouch("Falling, you");
+ } else { /* ordinary descent */
+ if (flags.verbose)
+ You("%s.", at_ladder ? "climb down the ladder" :
+ "descend the stairs");
+ }
+ }
+ } else { /* trap door or level_tele or In_endgame */
+ u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0));
+ if (falling) {
+ if (Punished) ballfall();
+ selftouch("Falling, you");
+ }
+ }
- if (Punished) placebc();
- obj_delivery(FALSE);
- losedogs();
- kill_genocided_monsters(); /* for those wiped out while in limbo */
- /*
- * Expire all timers that have gone off while away. Must be
- * after migrating monsters and objects are delivered
- * (losedogs and obj_delivery).
- */
- run_timers();
-
- initrack();
-
- if ((mtmp = m_at(u.ux, u.uy)) != 0 && mtmp != u.usteed) {
- /* There's a monster at your target destination; it might be one
- which accompanied you--see mon_arrive(dogmove.c)--or perhaps
- it was already here. Randomly move you to an adjacent spot
- or else the monster to any nearby location. Prior to 3.3.0
- the latter was done unconditionally. */
- coord cc;
-
- if (!rn2(2) &&
- enexto(&cc, u.ux, u.uy, youmonst.data) &&
- distu(cc.x, cc.y) <= 2)
- u_on_newpos(cc.x, cc.y); /*[maybe give message here?]*/
- else
- mnexto(mtmp);
-
- if ((mtmp = m_at(u.ux, u.uy)) != 0) {
- /* there was an unconditional impossible("mnearto failed")
- here, but it's not impossible and we're prepared to cope
- with the situation, so only say something when debugging */
- if (wizard) pline("(monster in hero's way)");
- if (!rloc(mtmp, TRUE))
- /* no room to move it; send it away, to return later */
- migrate_to_level(mtmp, ledger_no(&u.uz),
- MIGR_RANDOM, (coord *)0);
- }
- }
+ if (Punished) placebc();
+ obj_delivery(FALSE);
+ losedogs();
+ kill_genocided_monsters(); /* for those wiped out while in limbo */
+ /*
+ * Expire all timers that have gone off while away. Must be
+ * after migrating monsters and objects are delivered
+ * (losedogs and obj_delivery).
+ */
+ run_timers();
+
+ initrack();
+
+ if ((mtmp = m_at(u.ux, u.uy)) != 0 && mtmp != u.usteed) {
+ /* There's a monster at your target destination; it might be one
+ which accompanied you--see mon_arrive(dogmove.c)--or perhaps
+ it was already here. Randomly move you to an adjacent spot
+ or else the monster to any nearby location. Prior to 3.3.0
+ the latter was done unconditionally. */
+ coord cc;
+
+ if (!rn2(2) &&
+ enexto(&cc, u.ux, u.uy, youmonst.data) &&
+ distu(cc.x, cc.y) <= 2)
+ u_on_newpos(cc.x, cc.y); /*[maybe give message here?]*/
+ else
+ mnexto(mtmp);
+
+ if ((mtmp = m_at(u.ux, u.uy)) != 0) {
+ /* there was an unconditional impossible("mnearto failed")
+ here, but it's not impossible and we're prepared to cope
+ with the situation, so only say something when debugging */
+ if (wizard) pline("(monster in hero's way)");
+ if (!rloc(mtmp, TRUE))
+ /* no room to move it; send it away, to return later */
+ migrate_to_level(mtmp, ledger_no(&u.uz),
+ MIGR_RANDOM, (coord *)0);
+ }
+ }
- /* initial movement of bubbles just before vision_recalc */
- if (Is_waterlevel(&u.uz))
- movebubbles();
+ /* initial movement of bubbles just before vision_recalc */
+ if (Is_waterlevel(&u.uz))
+ movebubbles();
- if (level_info[new_ledger].flags & FORGOTTEN) {
- forget_map(ALL_MAP); /* forget the map */
- forget_traps(); /* forget all traps too */
- familiar = TRUE;
- level_info[new_ledger].flags &= ~FORGOTTEN;
- }
+ if (level_info[new_ledger].flags & FORGOTTEN) {
+ forget_map(ALL_MAP); /* forget the map */
+ forget_traps(); /* forget all traps too */
+ familiar = TRUE;
+ level_info[new_ledger].flags &= ~FORGOTTEN;
+ }
- /* Reset the screen. */
- vision_reset(); /* reset the blockages */
- docrt(); /* does a full vision recalc */
- flush_screen(-1);
+ /* Reset the screen. */
+ vision_reset(); /* reset the blockages */
+ docrt(); /* does a full vision recalc */
+ flush_screen(-1);
- /*
- * Move all plines beyond the screen reset.
- */
+ /*
+ * Move all plines beyond the screen reset.
+ */
- /* special levels can have a custom arrival message */
- deliver_splev_message();
+ /* special levels can have a custom arrival message */
+ deliver_splev_message();
- /* give room entrance message, if any */
- check_special_room(FALSE);
+ /* give room entrance message, if any */
+ check_special_room(FALSE);
- /* deliver objects traveling with player */
- obj_delivery(TRUE);
+ /* deliver objects traveling with player */
+ obj_delivery(TRUE);
- /* Check whether we just entered Gehennom. */
- if (!In_hell(&u.uz0) && Inhell) {
- if (Is_valley(&u.uz)) {
- You("arrive at the Valley of the Dead...");
- pline_The("odor of burnt flesh and decay pervades the air.");
+ /* Check whether we just entered Gehennom. */
+ if (!In_hell(&u.uz0) && Inhell) {
+ if (Is_valley(&u.uz)) {
+ You("arrive at the Valley of the Dead...");
+ pline_The("odor of burnt flesh and decay pervades the air.");
#ifdef MICRO
- display_nhwindow(WIN_MESSAGE, FALSE);
+ display_nhwindow(WIN_MESSAGE, FALSE);
#endif
- You_hear("groans and moans everywhere.");
- } else pline("It is hot here. You smell smoke...");
+ You_hear("groans and moans everywhere.");
+ } else pline("It is hot here. You smell smoke...");
u.uachieve.enter_gehennom = 1;
- }
- /* in case we've managed to bypass the Valley's stairway down */
- if (Inhell && !Is_valley(&u.uz)) u.uevent.gehennom_entered = 1;
-
- if (familiar) {
- static const char * const fam_msgs[4] = {
- "You have a sense of deja vu.",
- "You feel like you've been here before.",
- "This place %s familiar...",
- 0 /* no message */
- };
- static const char * const halu_fam_msgs[4] = {
- "Whoa! Everything %s different.",
- "You are surrounded by twisty little passages, all alike.",
- "Gee, this %s like uncle Conan's place...",
- 0 /* no message */
- };
- const char *mesg;
- char buf[BUFSZ];
- int which = rn2(4);
-
- if (Hallucination)
- mesg = halu_fam_msgs[which];
- else
- mesg = fam_msgs[which];
- if (mesg && index(mesg, '%')) {
- Sprintf(buf, mesg, !Blind ? "looks" : "seems");
- mesg = buf;
- }
- if (mesg) pline1(mesg);
- }
+ }
+ /* in case we've managed to bypass the Valley's stairway down */
+ if (Inhell && !Is_valley(&u.uz)) u.uevent.gehennom_entered = 1;
+
+ if (familiar) {
+ static const char * const fam_msgs[4] = {
+ "You have a sense of deja vu.",
+ "You feel like you've been here before.",
+ "This place %s familiar...",
+ 0 /* no message */
+ };
+ static const char * const halu_fam_msgs[4] = {
+ "Whoa! Everything %s different.",
+ "You are surrounded by twisty little passages, all alike.",
+ "Gee, this %s like uncle Conan's place...",
+ 0 /* no message */
+ };
+ const char *mesg;
+ char buf[BUFSZ];
+ int which = rn2(4);
+
+ if (Hallucination)
+ mesg = halu_fam_msgs[which];
+ else
+ mesg = fam_msgs[which];
+ if (mesg && index(mesg, '%')) {
+ Sprintf(buf, mesg, !Blind ? "looks" : "seems");
+ mesg = buf;
+ }
+ if (mesg) pline1(mesg);
+ }
- /* special location arrival messages/events */
- if (In_endgame(&u.uz)) {
- if (new && on_level(&u.uz, &astral_level))
- final_level(); /* guardian angel,&c */
- else if (newdungeon && u.uhave.amulet)
- resurrect(); /* force confrontation with Wizard */
- } else if (In_quest(&u.uz)) {
- onquest(); /* might be reaching locate|goal level */
- } else if (In_V_tower(&u.uz)) {
- if (newdungeon && In_hell(&u.uz0))
- pline_The("heat and smoke are gone.");
- } else if (Is_knox(&u.uz)) {
- /* alarm stops working once Croesus has died */
- if (new || !mvitals[PM_CROESUS].died) {
- You("have penetrated a high security area!");
- pline("An alarm sounds!");
- for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
- if (DEADMONSTER(mtmp)) continue;
- mtmp->msleeping = 0;
- }
- }
- } else {
- if (new && Is_rogue_level(&u.uz))
- You("enter what seems to be an older, more primitive world.");
- /* main dungeon message from your quest leader */
- if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") &&
- !(u.uevent.qcompleted || u.uevent.qexpelled ||
- quest_status.leader_is_dead)) {
- if (!u.uevent.qcalled) {
- u.uevent.qcalled = 1;
- com_pager(2); /* main "leader needs help" message */
- } else { /* reminder message */
- com_pager(Role_if(PM_ROGUE) ? 4 : 3);
- }
- }
- }
+ /* special location arrival messages/events */
+ if (In_endgame(&u.uz)) {
+ if (new && on_level(&u.uz, &astral_level))
+ final_level(); /* guardian angel,&c */
+ else if (newdungeon && u.uhave.amulet)
+ resurrect(); /* force confrontation with Wizard */
+ } else if (In_quest(&u.uz)) {
+ onquest(); /* might be reaching locate|goal level */
+ } else if (In_V_tower(&u.uz)) {
+ if (newdungeon && In_hell(&u.uz0))
+ pline_The("heat and smoke are gone.");
+ } else if (Is_knox(&u.uz)) {
+ /* alarm stops working once Croesus has died */
+ if (new || !mvitals[PM_CROESUS].died) {
+ You("have penetrated a high security area!");
+ pline("An alarm sounds!");
+ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
+ if (DEADMONSTER(mtmp)) continue;
+ mtmp->msleeping = 0;
+ }
+ }
+ } else {
+ if (new && Is_rogue_level(&u.uz))
+ You("enter what seems to be an older, more primitive world.");
+ /* main dungeon message from your quest leader */
+ if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") &&
+ !(u.uevent.qcompleted || u.uevent.qexpelled ||
+ quest_status.leader_is_dead)) {
+ if (!u.uevent.qcalled) {
+ u.uevent.qcalled = 1;
+ com_pager(2); /* main "leader needs help" message */
+ } else { /* reminder message */
+ com_pager(Role_if(PM_ROGUE) ? 4 : 3);
+ }
+ }
+ }
- assign_level(&u.uz0, &u.uz); /* reset u.uz0 */
+ assign_level(&u.uz0, &u.uz); /* reset u.uz0 */
#ifdef INSURANCE
- save_currentstate();
+ save_currentstate();
#endif
- /* assume this will always return TRUE when changing level */
- (void) in_out_region(u.ux, u.uy);
- (void) pickup(1);
+ /* assume this will always return TRUE when changing level */
+ (void) in_out_region(u.ux, u.uy);
+ (void) pickup(1);
+ context.polearm.hitmon = NULL;
}
STATIC_OVL void
void
domove()
{
- register struct monst *mtmp;
- register struct rm *tmpr;
- register xchar x,y;
- struct trap *trap;
- int wtcap;
- boolean on_ice;
- xchar chainx, chainy, ballx, bally; /* ball&chain new positions */
- int bc_control; /* control for ball&chain */
- boolean cause_delay = FALSE; /* dragging ball will skip a move */
-
- u_wipe_engr(rnd(5));
-
- if (context.travel) {
- if (!findtravelpath(FALSE))
- (void) findtravelpath(TRUE);
- context.travel1 = 0;
- }
-
- if(((wtcap = near_capacity()) >= OVERLOADED
- || (wtcap > SLT_ENCUMBER &&
- (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
- : (u.uhp < 10 && u.uhp != u.uhpmax))))
- && !Is_airlevel(&u.uz)) {
- if(wtcap < OVERLOADED) {
- You("don't have enough stamina to move.");
- exercise(A_CON, FALSE);
- } else
- You("collapse under your load.");
- nomul(0);
- return;
- }
- if(u.uswallow) {
- u.dx = u.dy = 0;
- u.ux = x = u.ustuck->mx;
- u.uy = y = u.ustuck->my;
- mtmp = u.ustuck;
- } else {
- if (Is_airlevel(&u.uz) && rn2(4) &&
- !Levitation && !Flying) {
- switch(rn2(3)) {
- case 0:
- You("tumble in place.");
- exercise(A_DEX, FALSE);
- break;
- case 1:
- You_cant("control your movements very well."); break;
- case 2:
- pline("It's hard to walk in thin air.");
- exercise(A_DEX, TRUE);
- break;
- }
- return;
- }
-
- /* check slippery ice */
- on_ice = !Levitation && is_ice(u.ux, u.uy);
- if (on_ice) {
- static int skates = 0;
- if (!skates) skates = find_skates();
- if ((uarmf && uarmf->otyp == skates)
- || resists_cold(&youmonst) || Flying
- || is_floater(youmonst.data) || is_clinger(youmonst.data)
- || is_whirly(youmonst.data))
- on_ice = FALSE;
- else if (!rn2(Cold_resistance ? 3 : 2)) {
- HFumbling |= FROMOUTSIDE;
- HFumbling &= ~TIMEOUT;
- HFumbling += 1; /* slip on next move */
- }
- }
- if (!on_ice && (HFumbling & FROMOUTSIDE))
- HFumbling &= ~FROMOUTSIDE;
-
- x = u.ux + u.dx;
- y = u.uy + u.dy;
- if(Stunned || (Confusion && !rn2(5))) {
- register int tries = 0;
-
- do {
- if(tries++ > 50) {
- nomul(0);
- return;
- }
- confdir();
- x = u.ux + u.dx;
- y = u.uy + u.dy;
- } while(!isok(x, y) || bad_rock(youmonst.data, x, y));
- }
- /* turbulence might alter your actual destination */
- if (u.uinwater) {
- water_friction();
- if (!u.dx && !u.dy) {
- nomul(0);
- return;
- }
- x = u.ux + u.dx;
- y = u.uy + u.dy;
- }
- if(!isok(x, y)) {
- nomul(0);
- return;
- }
- if (((trap = t_at(x, y)) && trap->tseen) ||
- (Blind && !Levitation && !Flying &&
- !is_clinger(youmonst.data) &&
- is_pool_or_lava(x, y) && levl[x][y].seenv)) {
- if(context.run >= 2) {
- nomul(0);
- context.move = 0;
- return;
- } else
- nomul(0);
- }
-
- if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
- if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
- /* perhaps it fled (or was teleported or ... ) */
- u.ustuck = 0;
- } else if (sticks(youmonst.data)) {
- /* When polymorphed into a sticking monster,
- * u.ustuck means it's stuck to you, not you to it.
- */
- You("release %s.", mon_nam(u.ustuck));
- u.ustuck = 0;
- } else {
- /* If holder is asleep or paralyzed:
- * 37.5% chance of getting away,
- * 12.5% chance of waking/releasing it;
- * otherwise:
- * 7.5% chance of getting away.
- * [strength ought to be a factor]
- * If holder is tame and there is no conflict,
- * guaranteed escape.
- */
- switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
- case 0: case 1: case 2:
- pull_free:
- You("pull free from %s.", mon_nam(u.ustuck));
- u.ustuck = 0;
- break;
- case 3:
- if (!u.ustuck->mcanmove) {
- /* it's free to move on next turn */
- u.ustuck->mfrozen = 1;
- u.ustuck->msleeping = 0;
- }
- /*FALLTHRU*/
- default:
- if (u.ustuck->mtame &&
- !Conflict && !u.ustuck->mconf)
- goto pull_free;
- You("cannot escape from %s!", mon_nam(u.ustuck));
- nomul(0);
- return;
- }
- }
- }
-
- mtmp = m_at(x,y);
- if (mtmp) {
- /* Don't attack if you're running, and can see it */
- /* We should never get here if forcefight */
- if (context.run &&
- ((!Blind && mon_visible(mtmp) &&
- ((mtmp->m_ap_type != M_AP_FURNITURE &&
- mtmp->m_ap_type != M_AP_OBJECT) ||
- Protection_from_shape_changers)) ||
- sensemon(mtmp))) {
- nomul(0);
- context.move = 0;
- return;
- }
- }
- }
-
- u.ux0 = u.ux;
- u.uy0 = u.uy;
- bhitpos.x = x;
- bhitpos.y = y;
- tmpr = &levl[x][y];
-
- /* attack monster */
- if(mtmp) {
- nomul(0);
- /* only attack if we know it's there */
- /* or if we used the 'F' command to fight blindly */
- /* or if it hides_under, in which case we call attack() to print
- * the Wait! message.
- * This is different from ceiling hiders, who aren't handled in
- * attack().
- */
-
- /* If they used a 'm' command, trying to move onto a monster
- * prints the below message and wastes a turn. The exception is
- * if the monster is unseen and the player doesn't remember an
- * invisible monster--then, we fall through to attack() and
- * attack_check(), which still wastes a turn, but prints a
- * different message and makes the player remember the monster. */
- if(context.nopick &&
- (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){
- if(mtmp->m_ap_type && !Protection_from_shape_changers
- && !sensemon(mtmp))
- stumble_onto_mimic(mtmp);
- else if (mtmp->mpeaceful && !Hallucination)
- pline("Pardon me, %s.", m_monnam(mtmp));
- else
- You("move right into %s.", mon_nam(mtmp));
- return;
- }
- if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
- ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
- !is_safepet(mtmp))){
- /* try to attack; note that it might evade */
- /* also, we don't attack tame when _safepet_ */
- if(attack(mtmp)) return;
- }
- }
-
- /* specifying 'F' with no monster wastes a turn */
- if (context.forcefight ||
- /* remembered an 'I' && didn't use a move command */
- (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
- struct obj *boulder = sobj_at(BOULDER, x, y);
- boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
- solid = !accessible(x, y);
- int glyph = glyph_at(x, y); /* might be monster */
- char buf[BUFSZ];
-
- /* if a statue is displayed at the target location,
- player is attempting to attack it [and boulder
- handlng below is suitable for handling that] */
- if (glyph_is_statue(glyph) ||
- (Hallucination && glyph_is_monster(glyph)))
- boulder = sobj_at(STATUE, x, y);
-
- /* force fight at boulder/statue or wall/door while wielding
- pick: start digging to break the boulder or wall */
- if (context.forcefight &&
- /* can we dig? */
- uwep && dig_typ(uwep, x, y) &&
- /* should we dig? */
- !glyph_is_invisible(glyph) &&
- !glyph_is_monster(glyph)) {
- (void)use_pick_axe2(uwep);
- return;
- }
-
- if (boulder)
- Strcpy(buf, ansimpleoname(boulder));
- else if (solid)
- Strcpy(buf, the(defsyms[glyph_to_cmap(glyph)].explanation));
- else if (!Underwater)
- Strcpy(buf, "thin air");
- else if (is_pool(x, y))
- Strcpy(buf, "empty water");
- else /* Underwater, targetting non-water */
- Sprintf(buf, "a vacant spot on the %s", surface(x,y));
- You("%s%s %s.",
- !(boulder || solid) ? "" :
- !explo ? "harmlessly " : "futilely ",
- explo ? "explode at" : "attack",
- buf);
- unmap_object(x, y); /* known empty -- remove 'I' if present */
- if (boulder) map_object(boulder, TRUE);
- newsym(x, y);
- nomul(0);
- if (explo) {
- wake_nearby();
- u.mh = -1; /* dead in the current form */
- rehumanize();
- }
- return;
- }
- if (glyph_is_invisible(levl[x][y].glyph)) {
- unmap_object(x, y);
- newsym(x, y);
- }
- /* not attacking an animal, so we try to move */
- if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
- nomul(0);
- return;
- }
- if(!youmonst.data->mmove) {
- You("are rooted %s.",
- Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
- "in place" : "to the ground");
- nomul(0);
- return;
- }
- if(u.utrap) {
- if (!trapmove(x, y, trap)) return;
- }
-
- if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) {
- context.move = 0;
- nomul(0);
- return;
- }
-
- /* Move ball and chain. */
- if (Punished)
- if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy,
- &cause_delay, TRUE))
- return;
-
- /* Check regions entering/leaving */
- if (!in_out_region(x,y))
- return;
-
- /* now move the hero */
- mtmp = m_at(x, y);
- u.ux += u.dx;
- u.uy += u.dy;
- /* Move your steed, too */
- if (u.usteed) {
- u.usteed->mx = u.ux;
- u.usteed->my = u.uy;
- exercise_steed();
- }
-
- /*
- * If safepet at destination then move the pet to the hero's
- * previous location using the same conditions as in attack().
- * there are special extenuating circumstances:
- * (1) if the pet dies then your god angers,
- * (2) if the pet gets trapped then your god may disapprove,
- * (3) if the pet was already trapped and you attempt to free it
- * not only do you encounter the trap but you may frighten your
- * pet causing it to go wild! moral: don't abuse this privilege.
- *
- * Ceiling-hiding pets are skipped by this section of code, to
- * be caught by the normal falling-monster code.
- */
- if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
- /* if trapped, there's a chance the pet goes wild */
- if (mtmp->mtrapped) {
- if (!rn2(mtmp->mtame)) {
- mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
- if (mtmp->mleashed) m_unleash(mtmp, TRUE);
- growl(mtmp);
- } else {
- yelp(mtmp);
- }
- }
- mtmp->mundetected = 0;
- if (mtmp->m_ap_type) seemimic(mtmp);
- else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my);
-
- if (mtmp->mtrapped &&
- (trap = t_at(mtmp->mx, mtmp->my)) != 0 &&
- (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&
- sobj_at(BOULDER, trap->tx, trap->ty)) {
- /* can't swap places with pet pinned in a pit by a boulder */
- u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
- } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
- /* can't swap places when pet can't move to your spot */
- u.ux = u.ux0, u.uy = u.uy0;
- You("stop. %s can't move diagonally.",
- upstart(y_monnam(mtmp)));
- } else if (u.ux0 != x && u.uy0 != y &&
- bad_rock(mtmp->data, x, u.uy0) &&
- bad_rock(mtmp->data, u.ux0, y) &&
- (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
- /* can't swap places when pet won't fit thru the opening */
- u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
- You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
- } else {
- char pnambuf[BUFSZ];
-
- /* save its current description in case of polymorph */
- Strcpy(pnambuf, y_monnam(mtmp));
- mtmp->mtrapped = 0;
- remove_monster(x, y);
- place_monster(mtmp, u.ux0, u.uy0);
- newsym(x, y);
- newsym(u.ux0, u.uy0);
-
- You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
- pnambuf);
-
- /* check for displacing it into pools and traps */
- switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
- case 0:
- break;
- case 1: /* trapped */
- case 3: /* changed levels */
- /* there's already been a trap message, reinforce it */
- abuse_dog(mtmp);
- adjalign(-3);
- break;
- case 2:
- /* drowned or died...
- * you killed your pet by direct action, so get experience
- * and possibly penalties;
- * we want the level gain message, if it happens, to occur
- * before the guilt message below
- */
- {
- /* minliquid() and mintrap() call mondead() rather than
- killed() so we duplicate some of the latter here */
- int tmp, mndx;
-
- u.uconduct.killer++;
- mndx = monsndx(mtmp->data);
- tmp = experience(mtmp, (int)mvitals[mndx].died);
- more_experienced(tmp, 0);
- newexplevel(); /* will decide if you go up */
- }
- /* That's no way to treat a pet! Your god gets angry.
- *
- * [This has always been pretty iffy. Why does your
- * patron deity care at all, let alone enough to get mad?]
- */
- if (rn2(4)) {
- You_feel("guilty about losing your pet like this.");
- u.ugangr++;
- adjalign(-15);
- }
- break;
- default:
- pline("that's strange, unknown mintrap result!");
- break;
- }
- }
- }
-
- reset_occupations();
- if (context.run) {
- if ( context.run < 8 )
- if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) ||
- IS_FURNITURE(tmpr->typ))
- nomul(0);
- }
-
- if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) ||
- u.dx || u.dy)
- (void) hideunder(&youmonst);
-
- /*
- * Mimics (or whatever) become noticeable if they move and are
- * imitating something that doesn't move. We could extend this
- * to non-moving monsters...
- */
- if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT
- || youmonst.m_ap_type == M_AP_FURNITURE))
- youmonst.m_ap_type = M_AP_NOTHING;
-
- check_leash(u.ux0,u.uy0);
-
- if(u.ux0 != u.ux || u.uy0 != u.uy) {
- u.umoved = TRUE;
- /* Clean old position -- vision_recalc() will print our new one. */
- newsym(u.ux0,u.uy0);
- /* Since the hero has moved, adjust what can be seen/unseen. */
- vision_recalc(1); /* Do the work now in the recover time. */
- invocation_message();
- }
-
- if (Punished) /* put back ball and chain */
- move_bc(0,bc_control,ballx,bally,chainx,chainy);
-
- spoteffects(TRUE);
-
- /* delay next move because of ball dragging */
- /* must come after we finished picking up, in spoteffects() */
- if (cause_delay) {
- nomul(-2);
+ register struct monst *mtmp;
+ register struct rm *tmpr;
+ register xchar x,y;
+ struct trap *trap = NULL;
+ int wtcap;
+ boolean on_ice;
+ xchar chainx, chainy, ballx, bally; /* ball&chain new positions */
+ int bc_control; /* control for ball&chain */
+ boolean cause_delay = FALSE; /* dragging ball will skip a move */
+
+ u_wipe_engr(rnd(5));
+
+ if (context.travel) {
+ if (!findtravelpath(FALSE))
+ (void) findtravelpath(TRUE);
+ context.travel1 = 0;
+ }
+
+ if(((wtcap = near_capacity()) >= OVERLOADED
+ || (wtcap > SLT_ENCUMBER &&
+ (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
+ : (u.uhp < 10 && u.uhp != u.uhpmax))))
+ && !Is_airlevel(&u.uz)) {
+ if(wtcap < OVERLOADED) {
+ You("don't have enough stamina to move.");
+ exercise(A_CON, FALSE);
+ } else
+ You("collapse under your load.");
+ nomul(0);
+ return;
+ }
+ if(u.uswallow) {
+ u.dx = u.dy = 0;
+ u.ux = x = u.ustuck->mx;
+ u.uy = y = u.ustuck->my;
+ mtmp = u.ustuck;
+ } else {
+ if (Is_airlevel(&u.uz) && rn2(4) &&
+ !Levitation && !Flying) {
+ switch(rn2(3)) {
+ case 0:
+ You("tumble in place.");
+ exercise(A_DEX, FALSE);
+ break;
+ case 1:
+ You_cant("control your movements very well."); break;
+ case 2:
+ pline("It's hard to walk in thin air.");
+ exercise(A_DEX, TRUE);
+ break;
+ }
+ return;
+ }
+
+ /* check slippery ice */
+ on_ice = !Levitation && is_ice(u.ux, u.uy);
+ if (on_ice) {
+ static int skates = 0;
+ if (!skates) skates = find_skates();
+ if ((uarmf && uarmf->otyp == skates)
+ || resists_cold(&youmonst) || Flying
+ || is_floater(youmonst.data) || is_clinger(youmonst.data)
+ || is_whirly(youmonst.data))
+ on_ice = FALSE;
+ else if (!rn2(Cold_resistance ? 3 : 2)) {
+ HFumbling |= FROMOUTSIDE;
+ HFumbling &= ~TIMEOUT;
+ HFumbling += 1; /* slip on next move */
+ }
+ }
+ if (!on_ice && (HFumbling & FROMOUTSIDE))
+ HFumbling &= ~FROMOUTSIDE;
+
+ x = u.ux + u.dx;
+ y = u.uy + u.dy;
+ if(Stunned || (Confusion && !rn2(5))) {
+ register int tries = 0;
+
+ do {
+ if(tries++ > 50) {
+ nomul(0);
+ return;
+ }
+ confdir();
+ x = u.ux + u.dx;
+ y = u.uy + u.dy;
+ } while(!isok(x, y) || bad_rock(youmonst.data, x, y));
+ }
+ /* turbulence might alter your actual destination */
+ if (u.uinwater) {
+ water_friction();
+ if (!u.dx && !u.dy) {
+ nomul(0);
+ return;
+ }
+ x = u.ux + u.dx;
+ y = u.uy + u.dy;
+ }
+ if(!isok(x, y)) {
+ nomul(0);
+ return;
+ }
+ if (((trap = t_at(x, y)) && trap->tseen) ||
+ (Blind && !Levitation && !Flying &&
+ !is_clinger(youmonst.data) &&
+ is_pool_or_lava(x, y) && levl[x][y].seenv)) {
+ if(context.run >= 2) {
+ nomul(0);
+ context.move = 0;
+ return;
+ } else
+ nomul(0);
+ }
+
+ if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
+ if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
+ /* perhaps it fled (or was teleported or ... ) */
+ u.ustuck = 0;
+ } else if (sticks(youmonst.data)) {
+ /* When polymorphed into a sticking monster,
+ * u.ustuck means it's stuck to you, not you to it.
+ */
+ You("release %s.", mon_nam(u.ustuck));
+ u.ustuck = 0;
+ } else {
+ /* If holder is asleep or paralyzed:
+ * 37.5% chance of getting away,
+ * 12.5% chance of waking/releasing it;
+ * otherwise:
+ * 7.5% chance of getting away.
+ * [strength ought to be a factor]
+ * If holder is tame and there is no conflict,
+ * guaranteed escape.
+ */
+ switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
+ case 0: case 1: case 2:
+ pull_free:
+ You("pull free from %s.", mon_nam(u.ustuck));
+ u.ustuck = 0;
+ break;
+ case 3:
+ if (!u.ustuck->mcanmove) {
+ /* it's free to move on next turn */
+ u.ustuck->mfrozen = 1;
+ u.ustuck->msleeping = 0;
+ }
+ /*FALLTHRU*/
+ default:
+ if (u.ustuck->mtame &&
+ !Conflict && !u.ustuck->mconf)
+ goto pull_free;
+ You("cannot escape from %s!", mon_nam(u.ustuck));
+ nomul(0);
+ return;
+ }
+ }
+ }
+
+ mtmp = m_at(x,y);
+ if (mtmp) {
+ /* Don't attack if you're running, and can see it */
+ /* We should never get here if forcefight */
+ if (context.run &&
+ ((!Blind && mon_visible(mtmp) &&
+ ((mtmp->m_ap_type != M_AP_FURNITURE &&
+ mtmp->m_ap_type != M_AP_OBJECT) ||
+ Protection_from_shape_changers)) ||
+ sensemon(mtmp))) {
+ nomul(0);
+ context.move = 0;
+ return;
+ }
+ }
+ }
+
+ u.ux0 = u.ux;
+ u.uy0 = u.uy;
+ bhitpos.x = x;
+ bhitpos.y = y;
+ tmpr = &levl[x][y];
+
+ /* attack monster */
+ if(mtmp) {
+ nomul(0);
+ /* only attack if we know it's there */
+ /* or if we used the 'F' command to fight blindly */
+ /* or if it hides_under, in which case we call attack() to print
+ * the Wait! message.
+ * This is different from ceiling hiders, who aren't handled in
+ * attack().
+ */
+
+ /* If they used a 'm' command, trying to move onto a monster
+ * prints the below message and wastes a turn. The exception is
+ * if the monster is unseen and the player doesn't remember an
+ * invisible monster--then, we fall through to attack() and
+ * attack_check(), which still wastes a turn, but prints a
+ * different message and makes the player remember the monster. */
+ if(context.nopick &&
+ (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){
+ if(mtmp->m_ap_type && !Protection_from_shape_changers
+ && !sensemon(mtmp))
+ stumble_onto_mimic(mtmp);
+ else if (mtmp->mpeaceful && !Hallucination)
+ pline("Pardon me, %s.", m_monnam(mtmp));
+ else
+ You("move right into %s.", mon_nam(mtmp));
+ return;
+ }
+ if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
+ ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
+ !is_safepet(mtmp))){
+ /* try to attack; note that it might evade */
+ /* also, we don't attack tame when _safepet_ */
+ if(attack(mtmp)) return;
+ }
+ }
+
+ /* specifying 'F' with no monster wastes a turn */
+ if (context.forcefight ||
+ /* remembered an 'I' && didn't use a move command */
+ (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
+ struct obj *boulder = sobj_at(BOULDER, x, y);
+ boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
+ solid = !accessible(x, y);
+ int glyph = glyph_at(x, y); /* might be monster */
+ char buf[BUFSZ];
+
+ /* if a statue is displayed at the target location,
+ player is attempting to attack it [and boulder
+ handlng below is suitable for handling that] */
+ if (glyph_is_statue(glyph) ||
+ (Hallucination && glyph_is_monster(glyph)))
+ boulder = sobj_at(STATUE, x, y);
+
+ /* force fight at boulder/statue or wall/door while wielding
+ pick: start digging to break the boulder or wall */
+ if (context.forcefight &&
+ /* can we dig? */
+ uwep && dig_typ(uwep, x, y) &&
+ /* should we dig? */
+ !glyph_is_invisible(glyph) &&
+ !glyph_is_monster(glyph)) {
+ (void)use_pick_axe2(uwep);
+ return;
+ }
+
+ if (boulder)
+ Strcpy(buf, ansimpleoname(boulder));
+ else if (solid)
+ Strcpy(buf, the(defsyms[glyph_to_cmap(glyph)].explanation));
+ else if (!Underwater)
+ Strcpy(buf, "thin air");
+ else if (is_pool(x, y))
+ Strcpy(buf, "empty water");
+ else /* Underwater, targetting non-water */
+ Sprintf(buf, "a vacant spot on the %s", surface(x,y));
+ You("%s%s %s.",
+ !(boulder || solid) ? "" :
+ !explo ? "harmlessly " : "futilely ",
+ explo ? "explode at" : "attack",
+ buf);
+ unmap_object(x, y); /* known empty -- remove 'I' if present */
+ if (boulder) map_object(boulder, TRUE);
+ newsym(x, y);
+ nomul(0);
+ if (explo) {
+ wake_nearby();
+ u.mh = -1; /* dead in the current form */
+ rehumanize();
+ }
+ return;
+ }
+ if (glyph_is_invisible(levl[x][y].glyph)) {
+ unmap_object(x, y);
+ newsym(x, y);
+ }
+ /* not attacking an animal, so we try to move */
+ if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
+ nomul(0);
+ return;
+ }
+ if(!youmonst.data->mmove) {
+ You("are rooted %s.",
+ Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
+ "in place" : "to the ground");
+ nomul(0);
+ return;
+ }
+ if(u.utrap) {
+ if (!trapmove(x, y, trap)) return;
+ }
+
+ if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) {
+ context.move = 0;
+ nomul(0);
+ return;
+ }
+
+ /* Move ball and chain. */
+ if (Punished)
+ if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy,
+ &cause_delay, TRUE))
+ return;
+
+ /* Check regions entering/leaving */
+ if (!in_out_region(x,y))
+ return;
+
+ /* now move the hero */
+ mtmp = m_at(x, y);
+ u.ux += u.dx;
+ u.uy += u.dy;
+ /* Move your steed, too */
+ if (u.usteed) {
+ u.usteed->mx = u.ux;
+ u.usteed->my = u.uy;
+ exercise_steed();
+ }
+
+ /*
+ * If safepet at destination then move the pet to the hero's
+ * previous location using the same conditions as in attack().
+ * there are special extenuating circumstances:
+ * (1) if the pet dies then your god angers,
+ * (2) if the pet gets trapped then your god may disapprove,
+ * (3) if the pet was already trapped and you attempt to free it
+ * not only do you encounter the trap but you may frighten your
+ * pet causing it to go wild! moral: don't abuse this privilege.
+ *
+ * Ceiling-hiding pets are skipped by this section of code, to
+ * be caught by the normal falling-monster code.
+ */
+ if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
+ /* if trapped, there's a chance the pet goes wild */
+ if (mtmp->mtrapped) {
+ if (!rn2(mtmp->mtame)) {
+ mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
+ if (mtmp->mleashed) m_unleash(mtmp, TRUE);
+ growl(mtmp);
+ } else {
+ yelp(mtmp);
+ }
+ }
+ mtmp->mundetected = 0;
+ if (mtmp->m_ap_type) seemimic(mtmp);
+ else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my);
+
+ if (mtmp->mtrapped &&
+ (trap = t_at(mtmp->mx, mtmp->my)) != 0 &&
+ (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&
+ sobj_at(BOULDER, trap->tx, trap->ty)) {
+ /* can't swap places with pet pinned in a pit by a boulder */
+ u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
+ } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
+ /* can't swap places when pet can't move to your spot */
+ u.ux = u.ux0, u.uy = u.uy0;
+ You("stop. %s can't move diagonally.",
+ upstart(y_monnam(mtmp)));
+ } else if (u.ux0 != x && u.uy0 != y &&
+ bad_rock(mtmp->data, x, u.uy0) &&
+ bad_rock(mtmp->data, u.ux0, y) &&
+ (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
+ /* can't swap places when pet won't fit thru the opening */
+ u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
+ You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
+ } else {
+ char pnambuf[BUFSZ];
+
+ /* save its current description in case of polymorph */
+ Strcpy(pnambuf, y_monnam(mtmp));
+ mtmp->mtrapped = 0;
+ remove_monster(x, y);
+ place_monster(mtmp, u.ux0, u.uy0);
+ newsym(x, y);
+ newsym(u.ux0, u.uy0);
+
+ You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
+ pnambuf);
+
+ /* check for displacing it into pools and traps */
+ switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
+ case 0:
+ break;
+ case 1: /* trapped */
+ case 3: /* changed levels */
+ /* there's already been a trap message, reinforce it */
+ abuse_dog(mtmp);
+ adjalign(-3);
+ break;
+ case 2:
+ /* drowned or died...
+ * you killed your pet by direct action, so get experience
+ * and possibly penalties;
+ * we want the level gain message, if it happens, to occur
+ * before the guilt message below
+ */
+ {
+ /* minliquid() and mintrap() call mondead() rather than
+ killed() so we duplicate some of the latter here */
+ int tmp, mndx;
+
+ u.uconduct.killer++;
+ mndx = monsndx(mtmp->data);
+ tmp = experience(mtmp, (int)mvitals[mndx].died);
+ more_experienced(tmp, 0);
+ newexplevel(); /* will decide if you go up */
+ }
+ /* That's no way to treat a pet! Your god gets angry.
+ *
+ * [This has always been pretty iffy. Why does your
+ * patron deity care at all, let alone enough to get mad?]
+ */
+ if (rn2(4)) {
+ You_feel("guilty about losing your pet like this.");
+ u.ugangr++;
+ adjalign(-15);
+ }
+ break;
+ default:
+ pline("that's strange, unknown mintrap result!");
+ break;
+ }
+ }
+ }
+
+ reset_occupations();
+ if (context.run) {
+ if ( context.run < 8 )
+ if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) ||
+ IS_FURNITURE(tmpr->typ))
+ nomul(0);
+ }
+
+ if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) ||
+ u.dx || u.dy)
+ (void) hideunder(&youmonst);
+
+ /*
+ * Mimics (or whatever) become noticeable if they move and are
+ * imitating something that doesn't move. We could extend this
+ * to non-moving monsters...
+ */
+ if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT
+ || youmonst.m_ap_type == M_AP_FURNITURE))
+ youmonst.m_ap_type = M_AP_NOTHING;
+
+ check_leash(u.ux0,u.uy0);
+
+ if(u.ux0 != u.ux || u.uy0 != u.uy) {
+ u.umoved = TRUE;
+ /* Clean old position -- vision_recalc() will print our new one. */
+ newsym(u.ux0,u.uy0);
+ /* Since the hero has moved, adjust what can be seen/unseen. */
+ vision_recalc(1); /* Do the work now in the recover time. */
+ invocation_message();
+ }
+
+ if (Punished) /* put back ball and chain */
+ move_bc(0,bc_control,ballx,bally,chainx,chainy);
+
+ spoteffects(TRUE);
+
+ /* delay next move because of ball dragging */
+ /* must come after we finished picking up, in spoteffects() */
+ if (cause_delay) {
+ nomul(-2);
+ multi_reason = "dragging an iron ball";
- nomovemsg = "";
- }
-
- if (context.run && flags.runmode != RUN_TPORT) {
- /* display every step or every 7th step depending upon mode */
- if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
- if (flags.time) context.botl = 1;
- curs_on_u();
- delay_output();
- if (flags.runmode == RUN_CRAWL) {
- delay_output();
- delay_output();
- delay_output();
- delay_output();
- }
- }
- }
+ nomovemsg = "";
+ }
+
+ if (context.run && flags.runmode != RUN_TPORT) {
+ /* display every step or every 7th step depending upon mode */
+ if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
+ if (flags.time) context.botl = 1;
+ curs_on_u();
+ delay_output();
+ if (flags.runmode == RUN_CRAWL) {
+ delay_output();
+ delay_output();
+ delay_output();
+ delay_output();
+ }
+ }
+ }
}
/* combat increases metabolism */
int
dopickup()
{
- int count;
- struct trap *traphere = t_at(u.ux, u.uy);
- /* awful kludge to work around parse()'s pre-decrement */
- count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
- multi = 0; /* always reset */
- /* uswallow case added by GAN 01/29/87 */
- if(u.uswallow) {
- if (!u.ustuck->minvent) {
- if (is_animal(u.ustuck->data)) {
- You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck)));
- pline("But it's kind of slimy, so you drop it.");
- } else
- You("don't %s anything in here to pick up.",
- Blind ? "feel" : "see");
- return(1);
- } else {
- int tmpcount = -count;
- return loot_mon(u.ustuck, &tmpcount, (boolean *)0);
- }
- }
- if(is_pool(u.ux, u.uy)) {
- if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
- || (Flying && !Breathless)) {
- You("cannot dive into the water to pick things up.");
- return(0);
- } else if (!Underwater) {
- You_cant("even see the bottom, let alone pick up %s.",
- something);
- return(0);
- }
- }
- if (is_lava(u.ux, u.uy)) {
- if (Wwalking || is_floater(youmonst.data) ||
- is_clinger(youmonst.data) || (Flying && !Breathless)) {
- You_cant("reach the bottom to pick things up.");
- return(0);
- } else if (!likes_lava(youmonst.data)) {
- You("would burn to a crisp trying to pick things up.");
- return(0);
- }
- }
- if (!OBJ_AT(u.ux, u.uy)) {
+ int count;
+ struct trap *traphere = t_at(u.ux, u.uy);
+ /* awful kludge to work around parse()'s pre-decrement */
+ count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
+ multi = 0; /* always reset */
+ /* uswallow case added by GAN 01/29/87 */
+ if(u.uswallow) {
+ if (!u.ustuck->minvent) {
+ if (is_animal(u.ustuck->data)) {
+ You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck)));
+ pline("But it's kind of slimy, so you drop it.");
+ } else
+ You("don't %s anything in here to pick up.",
+ Blind ? "feel" : "see");
+ return(1);
+ } else {
+ int tmpcount = -count;
+ return loot_mon(u.ustuck, &tmpcount, (boolean *)0);
+ }
+ }
+ if(is_pool(u.ux, u.uy)) {
+ if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
+ || (Flying && !Breathless)) {
+ You("cannot dive into the water to pick things up.");
+ return(0);
+ } else if (!Underwater) {
+ You_cant("even see the bottom, let alone pick up %s.",
+ something);
+ return(0);
+ }
+ }
+ if (is_lava(u.ux, u.uy)) {
+ if (Wwalking || is_floater(youmonst.data) ||
+ is_clinger(youmonst.data) || (Flying && !Breathless)) {
+ You_cant("reach the bottom to pick things up.");
+ return(0);
+ } else if (!likes_lava(youmonst.data)) {
+ You("would burn to a crisp trying to pick things up.");
+ return(0);
+ }
+ }
+ if (!OBJ_AT(u.ux, u.uy)) {
- There("is nothing here to pick up.");
+ register struct rm *lev = &levl[u.ux][u.uy];
+ if (IS_THRONE(lev->typ))
+ pline("It must weigh%s a ton!",
+ lev->looted ? " almost" : "");
+ else if (IS_SINK(lev->typ))
+ pline_The("plumbing connects it to the floor.");
+ else if (IS_GRAVE(lev->typ))
+ You("don't need a gravestone. Yet.");
+ else if (IS_FOUNTAIN(lev->typ))
+ You("could drink the water...");
+ else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
+ pline("It won't come off the hinges.");
+ else There("is nothing here to pick up.");
- return 0;
- }
- if (!can_reach_floor(TRUE)) {
- if (traphere && uteetering_at_seen_pit(traphere))
- You("cannot reach the bottom of the pit.");
- else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
- rider_cant_reach();
- else if (Blind && !can_reach_floor(TRUE))
- You("cannot reach anything here.");
- else
- You("cannot reach the %s.", surface(u.ux,u.uy));
- return 0;
- }
-
- return (pickup(-count));
+ return 0;
+ }
+ if (!can_reach_floor(TRUE)) {
+ if (traphere && uteetering_at_seen_pit(traphere))
+ You("cannot reach the bottom of the pit.");
+ else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
+ rider_cant_reach();
+ else if (Blind && !can_reach_floor(TRUE))
+ You("cannot reach anything here.");
+ else
+ You("cannot reach the %s.", surface(u.ux,u.uy));
+ return 0;
+ }
+
+ return (pickup(-count));
}
/* stop running if we see something interesting */
void
nomul(nval)
- register int nval;
+ register int nval;
{
- if(multi < nval) return; /* This is a bug fix by ab@unido */
- u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
- u.usleep = 0;
- multi = nval;
+ if(multi < nval) return; /* This is a bug fix by ab@unido */
+ u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
+ u.usleep = 0;
+ multi = nval;
+ if (nval == 0) multi_reason = NULL;
- context.travel = context.travel1 = context.mv = context.run = 0;
+ context.travel = context.travel1 = context.mv = context.run = 0;
}
/* called when a non-movement, multi-turn action has completed */
unmul(msg_override)
const char *msg_override;
{
- multi = 0; /* caller will usually have done this already */
- if (msg_override) nomovemsg = msg_override;
- else if (!nomovemsg) nomovemsg = You_can_move_again;
- if (*nomovemsg) pline1(nomovemsg);
- nomovemsg = 0;
- u.usleep = 0;
+ multi = 0; /* caller will usually have done this already */
+ if (msg_override) nomovemsg = msg_override;
+ else if (!nomovemsg) nomovemsg = You_can_move_again;
+ if (*nomovemsg) pline1(nomovemsg);
+ nomovemsg = 0;
+ u.usleep = 0;
+ multi_reason = NULL;
- if (afternmv) (*afternmv)();
- afternmv = 0;
+ if (afternmv) (*afternmv)();
+ afternmv = 0;
}
STATIC_OVL void
getobj(let,word)
register const char *let,*word;
{
- register struct obj *otmp;
- register char ilet;
- char buf[BUFSZ], qbuf[QBUFSZ];
- char lets[BUFSZ], altlets[BUFSZ], *ap;
- register int foo = 0;
- register char *bp = buf;
- xchar allowcnt = 0; /* 0, 1 or 2 */
- struct obj *firstobj = invent;
- boolean usegold = FALSE; /* can't use gold because its illegal */
- boolean allowall = FALSE;
- boolean allownone = FALSE;
- boolean useboulder = FALSE;
- xchar foox = 0;
- long cnt, prevcnt;
- boolean prezero;
- long dummymask;
-
- if(*let == ALLOW_COUNT) let++, allowcnt = 1;
- if(*let == COIN_CLASS) let++, usegold = TRUE;
-
- /* Equivalent of an "ugly check" for gold */
- if (usegold && !strcmp(word, "eat") &&
- (!metallivorous(youmonst.data)
- || youmonst.data == &mons[PM_RUST_MONSTER]))
- usegold = FALSE;
-
- if(*let == ALL_CLASSES) let++, allowall = TRUE;
- if(*let == ALLOW_NONE) let++, allownone = TRUE;
- /* "ugly check" for reading fortune cookies, part 1 */
- /* The normal 'ugly check' keeps the object on the inventory list.
- * We don't want to do that for shirts/cookies, so the check for
- * them is handled a bit differently (and also requires that we set
- * allowall in the caller)
- */
- if(allowall && !strcmp(word, "read")) allowall = FALSE;
-
- /* another ugly check: show boulders (not statues) */
- if(*let == WEAPON_CLASS &&
- !strcmp(word, "throw") && throws_rocks(youmonst.data))
- useboulder = TRUE;
-
- if(allownone) *bp++ = '-';
- if(bp > buf && bp[-1] == '-') *bp++ = ' ';
- ap = altlets;
-
- if (!flags.invlet_constant) reassign();
-
- for (otmp = firstobj; otmp; otmp = otmp->nobj) {
- if (&bp[foo] == &buf[sizeof buf - 1] ||
- ap == &altlets[sizeof altlets - 1]) {
- /* we must have a huge number of NOINVSYM items somehow */
- impossible("getobj: inventory overflow");
- break;
- }
+ register struct obj *otmp;
+ register char ilet;
+ char buf[BUFSZ], qbuf[QBUFSZ];
+ char lets[BUFSZ], altlets[BUFSZ], *ap;
+ register int foo = 0;
+ register char *bp = buf;
+ xchar allowcnt = 0; /* 0, 1 or 2 */
+ struct obj *firstobj = invent;
+ boolean usegold = FALSE; /* can't use gold because its illegal */
+ boolean allowall = FALSE;
+ boolean allownone = FALSE;
+ boolean useboulder = FALSE;
+ xchar foox = 0;
+ long cnt, prevcnt;
+ boolean prezero;
+ long dummymask;
+
+ if(*let == ALLOW_COUNT) let++, allowcnt = 1;
+ if(*let == COIN_CLASS) let++, usegold = TRUE;
+
+ /* Equivalent of an "ugly check" for gold */
+ if (usegold && !strcmp(word, "eat") &&
+ (!metallivorous(youmonst.data)
+ || youmonst.data == &mons[PM_RUST_MONSTER]))
+ usegold = FALSE;
+
+ if(*let == ALL_CLASSES) let++, allowall = TRUE;
+ if(*let == ALLOW_NONE) let++, allownone = TRUE;
+ /* "ugly check" for reading fortune cookies, part 1 */
+ /* The normal 'ugly check' keeps the object on the inventory list.
+ * We don't want to do that for shirts/cookies, so the check for
+ * them is handled a bit differently (and also requires that we set
+ * allowall in the caller)
+ */
+ if(allowall && !strcmp(word, "read")) allowall = FALSE;
+
+ /* another ugly check: show boulders (not statues) */
+ if(*let == WEAPON_CLASS &&
+ !strcmp(word, "throw") && throws_rocks(youmonst.data))
+ useboulder = TRUE;
+
+ if(allownone) *bp++ = '-';
+ if(bp > buf && bp[-1] == '-') *bp++ = ' ';
+ ap = altlets;
+
+ if (!flags.invlet_constant) reassign();
- if (!*let || index(let, otmp->oclass)
- || (usegold && otmp->invlet == GOLD_SYM)
- || (useboulder && otmp->otyp == BOULDER)
- ) {
- register int otyp = otmp->otyp;
- bp[foo++] = otmp->invlet;
-
- /* ugly check: remove inappropriate things */
- if ((taking_off(word) &&
- !(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
- || (putting_on(word) &&
- (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
- /* already worn */
+ for (otmp = firstobj; otmp; otmp = otmp->nobj) {
+ if (&bp[foo] == &buf[sizeof buf - 1] ||
+ ap == &altlets[sizeof altlets - 1]) {
+ /* we must have a huge number of NOINVSYM items somehow */
+ impossible("getobj: inventory overflow");
+ break;
+ }
+
+ if (!*let || index(let, otmp->oclass)
+ || (usegold && otmp->invlet == GOLD_SYM)
+ || (useboulder && otmp->otyp == BOULDER)
+ ) {
+ register int otyp = otmp->otyp;
+ bp[foo++] = otmp->invlet;
+
+ /* ugly check: remove inappropriate things */
+ if ((taking_off(word) &&
+ !(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
+ || (putting_on(word) &&
+ (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
+ /* already worn */
#if 0 /* 3.4.1 -- include currently wielded weapon among the choices */
- || (!strcmp(word, "wield") &&
- (otmp->owornmask & W_WEP))
+ || (!strcmp(word, "wield") &&
+ (otmp->owornmask & W_WEP))
#endif
- || (!strcmp(word, "ready") &&
- (otmp == uwep || (otmp == uswapwep && u.twoweap)))
- || ((!strcmp(word, "dip") || !strcmp(word, "grease")) &&
- inaccessible_equipment(otmp, (const char *)0 , FALSE))
- ) {
- foo--;
- foox++;
- }
-
- /* Second ugly check; unlike the first it won't trigger an
- * "else" in "you don't have anything else to ___".
- */
- else if ((putting_on(word) &&
- ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING) ||
- (otmp->oclass == TOOL_CLASS &&
- otyp != BLINDFOLD && otyp != TOWEL && otyp != LENSES)))
- || (!strcmp(word, "wield") &&
- (otmp->oclass == TOOL_CLASS && !is_weptool(otmp)))
- || (!strcmp(word, "eat") && !is_edible(otmp))
- || (!strcmp(word, "sacrifice") &&
- (otyp != CORPSE &&
- otyp != AMULET_OF_YENDOR && otyp != FAKE_AMULET_OF_YENDOR))
- || (!strcmp(word, "write with") &&
- (otmp->oclass == TOOL_CLASS &&
- otyp != MAGIC_MARKER && otyp != TOWEL))
- || (!strcmp(word, "tin") &&
- (otyp != CORPSE || !tinnable(otmp)))
- || (!strcmp(word, "rub") &&
- ((otmp->oclass == TOOL_CLASS &&
- otyp != OIL_LAMP && otyp != MAGIC_LAMP &&
- otyp != BRASS_LANTERN) ||
- (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
- || ((!strcmp(word, "use or apply") ||
- !strcmp(word, "untrap with")) &&
- /* Picks, axes, pole-weapons, bullwhips */
- ((otmp->oclass == WEAPON_CLASS && !is_pick(otmp) &&
- !is_axe(otmp) && !is_pole(otmp) && otyp != BULLWHIP) ||
- (otmp->oclass == POTION_CLASS &&
- /* only applicable potion is oil, and it will only
- be offered as a choice when already discovered */
- (otyp != POT_OIL || !otmp->dknown ||
- !objects[POT_OIL].oc_name_known)) ||
- (otmp->oclass == FOOD_CLASS &&
- otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF) ||
- (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
- || (!strcmp(word, "invoke") &&
- (!otmp->oartifact && !objects[otyp].oc_unique &&
- (otyp != FAKE_AMULET_OF_YENDOR || otmp->known) &&
- otyp != CRYSTAL_BALL && /* #invoke synonym for apply */
- /* note: presenting the possibility of invoking non-artifact
- mirrors and/or lamps is a simply a cruel deception... */
- otyp != MIRROR && otyp != MAGIC_LAMP &&
- (otyp != OIL_LAMP || /* don't list known oil lamp */
- (otmp->dknown && objects[OIL_LAMP].oc_name_known))))
- || (!strcmp(word, "untrap with") &&
- (otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE))
- || (!strcmp(word, "tip") && !Is_container(otmp) &&
- /* include horn of plenty if sufficiently discovered */
- (otmp->otyp != HORN_OF_PLENTY || !otmp->dknown ||
- !objects[HORN_OF_PLENTY].oc_name_known))
- || (!strcmp(word, "charge") && !is_chargeable(otmp))
- || (!strcmp(word, "call") && !objtyp_is_callable(otyp))
- )
- foo--;
- /* ugly check for unworn armor that can't be worn */
- else if ((putting_on(word) && *let == ARMOR_CLASS &&
- !canwearobj(otmp, &dummymask, FALSE))
- /* or unsuitable items rubbed on known touchstone */
- || (!strncmp(word, "rub on the stone", 16) &&
- *let == GEM_CLASS &&
- otmp->dknown && objects[otyp].oc_name_known)
- /* suppress corpses on astral, amulets elsewhere */
- || (!strcmp(word, "sacrifice") &&
- /* (!astral && amulet) || (astral && !amulet) */
- (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
- /* suppress container being stashed into */
- || (!strcmp(word, "stash") && !ck_bag(otmp))
- /* worn armor or accessory covered by cursed worn armor */
- || (taking_off(word) &&
- inaccessible_equipment(otmp, (const char *)0, TRUE))
- ) {
- /* acceptable but not listed as likely candidate */
- foo--;
- allowall = TRUE;
- *ap++ = otmp->invlet;
- }
- } else {
-
- /* "ugly check" for reading fortune cookies, part 2 */
- if ((!strcmp(word, "read")
+ || (!strcmp(word, "ready") &&
+ (otmp == uwep || (otmp == uswapwep && u.twoweap)))
+ || ((!strcmp(word, "dip") || !strcmp(word, "grease")) &&
+ inaccessible_equipment(otmp, (const char *)0 , FALSE))
+ ) {
+ foo--;
+ foox++;
+ }
+
+ /* Second ugly check; unlike the first it won't trigger an
+ * "else" in "you don't have anything else to ___".
+ */
+ else if ((putting_on(word) &&
+ ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING) ||
+ (otmp->oclass == TOOL_CLASS &&
+ otyp != BLINDFOLD && otyp != TOWEL && otyp != LENSES)))
+ || (!strcmp(word, "wield") &&
+ (otmp->oclass == TOOL_CLASS && !is_weptool(otmp)))
+ || (!strcmp(word, "eat") && !is_edible(otmp))
+ || (!strcmp(word, "sacrifice") &&
+ (otyp != CORPSE &&
+ otyp != AMULET_OF_YENDOR && otyp != FAKE_AMULET_OF_YENDOR))
+ || (!strcmp(word, "write with") &&
+ (otmp->oclass == TOOL_CLASS &&
+ otyp != MAGIC_MARKER && otyp != TOWEL))
+ || (!strcmp(word, "tin") &&
+ (otyp != CORPSE || !tinnable(otmp)))
+ || (!strcmp(word, "rub") &&
+ ((otmp->oclass == TOOL_CLASS &&
+ otyp != OIL_LAMP && otyp != MAGIC_LAMP &&
+ otyp != BRASS_LANTERN) ||
+ (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
+ || ((!strcmp(word, "use or apply") ||
+ !strcmp(word, "untrap with")) &&
+ /* Picks, axes, pole-weapons, bullwhips */
+ ((otmp->oclass == WEAPON_CLASS && !is_pick(otmp) &&
+ !is_axe(otmp) && !is_pole(otmp) && otyp != BULLWHIP) ||
+ (otmp->oclass == POTION_CLASS &&
+ /* only applicable potion is oil, and it will only
+ be offered as a choice when already discovered */
+ (otyp != POT_OIL || !otmp->dknown ||
+ !objects[POT_OIL].oc_name_known)) ||
+ (otmp->oclass == FOOD_CLASS &&
+ otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF) ||
+ (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
+ || (!strcmp(word, "invoke") &&
+ (!otmp->oartifact && !objects[otyp].oc_unique &&
+ (otyp != FAKE_AMULET_OF_YENDOR || otmp->known) &&
+ otyp != CRYSTAL_BALL && /* #invoke synonym for apply */
+ /* note: presenting the possibility of invoking non-artifact
+ mirrors and/or lamps is a simply a cruel deception... */
+ otyp != MIRROR && otyp != MAGIC_LAMP &&
+ (otyp != OIL_LAMP || /* don't list known oil lamp */
+ (otmp->dknown && objects[OIL_LAMP].oc_name_known))))
+ || (!strcmp(word, "untrap with") &&
+ (otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE))
+ || (!strcmp(word, "tip") && !Is_container(otmp) &&
+ /* include horn of plenty if sufficiently discovered */
+ (otmp->otyp != HORN_OF_PLENTY || !otmp->dknown ||
+ !objects[HORN_OF_PLENTY].oc_name_known))
+ || (!strcmp(word, "charge") && !is_chargeable(otmp))
+ || (!strcmp(word, "call") && !objtyp_is_callable(otyp))
+ )
+ foo--;
+ /* ugly check for unworn armor that can't be worn */
+ else if ((putting_on(word) && *let == ARMOR_CLASS &&
+ !canwearobj(otmp, &dummymask, FALSE))
+ /* or unsuitable items rubbed on known touchstone */
+ || (!strncmp(word, "rub on the stone", 16) &&
+ *let == GEM_CLASS &&
+ otmp->dknown && objects[otyp].oc_name_known)
+ /* suppress corpses on astral, amulets elsewhere */
+ || (!strcmp(word, "sacrifice") &&
+ /* (!astral && amulet) || (astral && !amulet) */
+ (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
+ /* suppress container being stashed into */
+ || (!strcmp(word, "stash") && !ck_bag(otmp))
+ /* worn armor or accessory covered by cursed worn armor */
+ || (taking_off(word) &&
+ inaccessible_equipment(otmp, (const char *)0, TRUE))
+ ) {
+ /* acceptable but not listed as likely candidate */
+ foo--;
+ allowall = TRUE;
+ *ap++ = otmp->invlet;
+ }
+ } else {
+
+ /* "ugly check" for reading fortune cookies, part 2 */
+ if ((!strcmp(word, "read")
- && (otmp->otyp == FORTUNE_COOKIE || otmp->otyp == T_SHIRT)))
- allowall = TRUE;
+ && is_readable(otmp)))
+ allowall = usegold = TRUE;
- }
- }
- bp[foo] = 0;
- if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
- Strcpy(lets, bp); /* necessary since we destroy buf */
- if(foo > 5) /* compactify string */
- compactify(bp);
- *ap = '\0';
-
- if(!foo && !allowall && !allownone) {
- You("don't have anything %sto %s.",
- foox ? "else " : "", word);
- return((struct obj *)0);
- }
- for(;;) {
- cnt = 0;
- if (allowcnt == 2) allowcnt = 1; /* abort previous count */
- prezero = FALSE;
- if(!buf[0]) {
- Sprintf(qbuf, "What do you want to %s? [*]", word);
- } else {
- Sprintf(qbuf, "What do you want to %s? [%s or ?*]",
- word, buf);
- }
- if (in_doagain)
- ilet = readchar();
- else
- ilet = yn_function(qbuf, (char *)0, '\0');
- if (digit(ilet) && !allowcnt) {
- pline("No count allowed with this command.");
- continue;
- }
- if (ilet == '0') prezero = TRUE;
- while (digit(ilet)) {
- if (ilet != '?' && ilet != '*') savech(ilet);
- /* accumulate unless cnt has overflowed */
- if (allowcnt < 3) {
- prevcnt = cnt;
- cnt = 10L * cnt + (long)(ilet - '0');
- /* signal presence of cnt */
- allowcnt = (cnt >= prevcnt) ? 2 : 3;
- }
- ilet = readchar();
- }
- if (allowcnt == 3) {
- /* overflow detected; force cnt to be invalid */
- cnt = -1L;
- allowcnt = 2;
- }
- if(index(quitchars,ilet)) {
- if(flags.verbose)
- pline1(Never_mind);
- return((struct obj *)0);
- }
- if(ilet == '-') {
+ }
+ }
+ bp[foo] = 0;
+ if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
+ Strcpy(lets, bp); /* necessary since we destroy buf */
+ if(foo > 5) /* compactify string */
+ compactify(bp);
+ *ap = '\0';
+
+ if(!foo && !allowall && !allownone) {
+ You("don't have anything %sto %s.",
+ foox ? "else " : "", word);
+ return((struct obj *)0);
+ }
+ for(;;) {
+ cnt = 0;
+ if (allowcnt == 2) allowcnt = 1; /* abort previous count */
+ prezero = FALSE;
+ if(!buf[0]) {
+ Sprintf(qbuf, "What do you want to %s? [*]", word);
+ } else {
+ Sprintf(qbuf, "What do you want to %s? [%s or ?*]",
+ word, buf);
+ }
+ if (in_doagain)
+ ilet = readchar();
+ else
+ ilet = yn_function(qbuf, (char *)0, '\0');
+ if (digit(ilet) && !allowcnt) {
+ pline("No count allowed with this command.");
+ continue;
+ }
+ if (ilet == '0') prezero = TRUE;
+ while (digit(ilet)) {
+ if (ilet != '?' && ilet != '*') savech(ilet);
+ /* accumulate unless cnt has overflowed */
+ if (allowcnt < 3) {
+ prevcnt = cnt;
+ cnt = 10L * cnt + (long)(ilet - '0');
+ /* signal presence of cnt */
+ allowcnt = (cnt >= prevcnt) ? 2 : 3;
+ }
+ ilet = readchar();
+ }
+ if (allowcnt == 3) {
+ /* overflow detected; force cnt to be invalid */
+ cnt = -1L;
+ allowcnt = 2;
+ }
+ if(index(quitchars,ilet)) {
+ if(flags.verbose)
+ pline1(Never_mind);
+ return((struct obj *)0);
+ }
+ if(ilet == '-') {
if (!allownone) {
char *suf = NULL;
strcpy(buf, word);
*/
int
meatmetal(mtmp)
- register struct monst *mtmp;
+ register struct monst *mtmp;
{
- register struct obj *otmp;
- struct permonst *ptr;
- int poly, grow, heal, mstone;
+ register struct obj *otmp;
+ struct permonst *ptr;
+ int poly, grow, heal, mstone;
- /* If a pet, eating is handled separately, in dog.c */
- if (mtmp->mtame) return 0;
+ /* If a pet, eating is handled separately, in dog.c */
+ if (mtmp->mtame) return 0;
- /* Eats topmost metal object if it is there */
- for (otmp = level.objects[mtmp->mx][mtmp->my];
- otmp; otmp = otmp->nexthere) {
+ /* Eats topmost metal object if it is there */
+ for (otmp = level.objects[mtmp->mx][mtmp->my];
+ otmp; otmp = otmp->nexthere) {
- if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
+ /* Don't eat indigestible/choking/inappropriate objects */
+ if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) ||
+ (otmp->otyp == AMULET_OF_STRANGULATION) ||
+ (otmp->otyp == RIN_SLOW_DIGESTION))
- continue;
- if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
- touch_artifact(otmp,mtmp)) {
- if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
- if (canseemon(mtmp) && flags.verbose) {
- pline("%s eats %s!",
- Monnam(mtmp),
- distant_name(otmp,doname));
- }
- /* The object's rustproofing is gone now */
- otmp->oerodeproof = 0;
- mtmp->mstun = 1;
- if (canseemon(mtmp) && flags.verbose) {
- pline("%s spits %s out in disgust!",
- Monnam(mtmp), distant_name(otmp,doname));
- }
+ continue;
+ if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
+ touch_artifact(otmp,mtmp)) {
+ if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
+ if (canseemon(mtmp) && flags.verbose) {
+ pline("%s eats %s!",
+ Monnam(mtmp),
+ distant_name(otmp,doname));
+ }
+ /* The object's rustproofing is gone now */
+ otmp->oerodeproof = 0;
+ mtmp->mstun = 1;
+ if (canseemon(mtmp) && flags.verbose) {
+ pline("%s spits %s out in disgust!",
+ Monnam(mtmp), distant_name(otmp,doname));
+ }
- /* KMH -- Don't eat indigestible/choking objects */
- } else if (otmp->otyp != AMULET_OF_STRANGULATION &&
- otmp->otyp != RIN_SLOW_DIGESTION) {
+ } else {
- if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
- pline("%s eats %s!", Monnam(mtmp),
- distant_name(otmp,doname));
- else if (flags.verbose)
- You_hear("a crunching sound.");
- mtmp->meating = otmp->owt/2 + 1;
- /* Heal up to the object's weight in hp */
- if (mtmp->mhp < mtmp->mhpmax) {
- mtmp->mhp += objects[otmp->otyp].oc_weight;
- if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
- }
- if(otmp == uball) {
- unpunish();
- delobj(otmp);
- } else if (otmp == uchain) {
- unpunish(); /* frees uchain */
- } else {
- poly = polyfodder(otmp);
- grow = mlevelgain(otmp);
- heal = mhealup(otmp);
- mstone = mstoning(otmp);
- delobj(otmp);
- ptr = mtmp->data;
- if (poly) {
- if (newcham(mtmp, (struct permonst *)0,
- FALSE, FALSE))
- ptr = mtmp->data;
- } else if (grow) {
- ptr = grow_up(mtmp, (struct monst *)0);
- } else if (mstone) {
- if (poly_when_stoned(ptr)) {
- mon_to_stone(mtmp);
- ptr = mtmp->data;
- } else if (!resists_ston(mtmp)) {
- if (canseemon(mtmp))
- pline("%s turns to stone!", Monnam(mtmp));
- monstone(mtmp);
- ptr = (struct permonst *)0;
- }
- } else if (heal) {
- mtmp->mhp = mtmp->mhpmax;
- }
- if (!ptr) return 2; /* it died */
- }
- /* Left behind a pile? */
- if (rnd(25) < 3)
- (void)mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
- newsym(mtmp->mx, mtmp->my);
- return 1;
- }
- }
- }
- return 0;
+ if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
+ pline("%s eats %s!", Monnam(mtmp),
+ distant_name(otmp,doname));
+ else if (flags.verbose)
+ You_hear("a crunching sound.");
+ mtmp->meating = otmp->owt/2 + 1;
+ /* Heal up to the object's weight in hp */
+ if (mtmp->mhp < mtmp->mhpmax) {
+ mtmp->mhp += objects[otmp->otyp].oc_weight;
+ if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
+ }
+ if(otmp == uball) {
+ unpunish();
+ delobj(otmp);
+ } else if (otmp == uchain) {
+ unpunish(); /* frees uchain */
+ } else {
+ poly = polyfodder(otmp);
+ grow = mlevelgain(otmp);
+ heal = mhealup(otmp);
+ mstone = mstoning(otmp);
+ delobj(otmp);
+ ptr = mtmp->data;
+ if (poly) {
+ if (newcham(mtmp, (struct permonst *)0,
+ FALSE, FALSE))
+ ptr = mtmp->data;
+ } else if (grow) {
+ ptr = grow_up(mtmp, (struct monst *)0);
+ } else if (mstone) {
+ if (poly_when_stoned(ptr)) {
+ mon_to_stone(mtmp);
+ ptr = mtmp->data;
+ } else if (!resists_ston(mtmp)) {
+ if (canseemon(mtmp))
+ pline("%s turns to stone!", Monnam(mtmp));
+ monstone(mtmp);
+ ptr = (struct permonst *)0;
+ }
+ } else if (heal) {
+ mtmp->mhp = mtmp->mhpmax;
+ }
+ if (!ptr) return 2; /* it died */
+ }
+ /* Left behind a pile? */
+ if (rnd(25) < 3)
+ (void)mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
+ newsym(mtmp->mx, mtmp->my);
+ return 1;
+ }
+ }
+ }
+ return 0;
}
/* monster eats a pile of objects */
int count = 0;
for (mtmp = &fmon; *mtmp;) {
- freetmp = *mtmp;
- if (freetmp->mhp <= 0 && !freetmp->isgd) {
+ freetmp = *mtmp;
+ if (freetmp->mhp <= 0 && !freetmp->isgd) {
+ if (freetmp == context.polearm.hitmon)
+ context.polearm.hitmon = NULL;
- *mtmp = freetmp->nmon;
- dealloc_monst(freetmp);
- count++;
- } else
- mtmp = &(freetmp->nmon);
+ *mtmp = freetmp->nmon;
+ dealloc_monst(freetmp);
+ count++;
+ } else
+ mtmp = &(freetmp->nmon);
}
if (count != iflags.purge_monsters)
xname(obj)
register struct obj *obj;
{
- register char *buf;
- register int typ = obj->otyp;
- register struct objclass *ocl = &objects[typ];
- int nn = ocl->oc_name_known, omndx = obj->corpsenm;
- const char *actualn = OBJ_NAME(*ocl);
- const char *dn = OBJ_DESCR(*ocl);
- const char *un = ocl->oc_uname;
- boolean pluralize = (obj->quan != 1L);
- boolean known, dknown, bknown;
-
- buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
- if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
- actualn = Japanese_item_name(typ);
-
- buf[0] = '\0';
- /*
- * clean up known when it's tied to oc_name_known, eg after AD_DRIN
- * This is only required for unique objects since the article
- * printed for the object is tied to the combination of the two
- * and printing the wrong article gives away information.
- */
- if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
- if (!Blind) obj->dknown = TRUE;
- if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
+ register char *buf;
+ register int typ = obj->otyp;
+ register struct objclass *ocl = &objects[typ];
+ int nn = ocl->oc_name_known, omndx = obj->corpsenm;
+ const char *actualn = OBJ_NAME(*ocl);
+ const char *dn = OBJ_DESCR(*ocl);
+ const char *un = ocl->oc_uname;
+ boolean pluralize = (obj->quan != 1L);
+ boolean known, dknown, bknown;
+
+ buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
+ if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
+ actualn = Japanese_item_name(typ);
+
+ buf[0] = '\0';
+ /*
+ * clean up known when it's tied to oc_name_known, eg after AD_DRIN
+ * This is only required for unique objects since the article
+ * printed for the object is tied to the combination of the two
+ * and printing the wrong article gives away information.
+ */
+ if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
+ if (!Blind) obj->dknown = TRUE;
+ if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
- if (iflags.override_ID) {
- known = dknown = bknown = TRUE;
- nn = 1;
- } else {
- known = obj->known;
- dknown = obj->dknown;
- bknown = obj->bknown;
- }
+ if (iflags.override_ID) {
+ known = dknown = bknown = TRUE;
+ nn = 1;
+ } else {
+ known = obj->known;
+ dknown = obj->dknown;
+ bknown = obj->bknown;
+ }
- if (obj_is_pname(obj))
- goto nameit;
- switch (obj->oclass) {
- case AMULET_CLASS:
- if (!dknown)
- Strcpy(buf, "amulet");
- else if (typ == AMULET_OF_YENDOR ||
- typ == FAKE_AMULET_OF_YENDOR)
- /* each must be identified individually */
- Strcpy(buf, known ? actualn : dn);
- else if (nn)
- Strcpy(buf, actualn);
- else if (un)
- Sprintf(buf,"amulet called %s", un);
- else
- Sprintf(buf,"%s amulet", dn);
- break;
- case WEAPON_CLASS:
- if (is_poisonable(obj) && obj->opoisoned)
- Strcpy(buf, "poisoned ");
- case VENOM_CLASS:
- case TOOL_CLASS:
- if (typ == LENSES)
- Strcpy(buf, "pair of ");
-
- if (!dknown)
- Strcat(buf, dn ? dn : actualn);
- else if (nn)
- Strcat(buf, actualn);
- else if (un) {
- Strcat(buf, dn ? dn : actualn);
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else
- Strcat(buf, dn ? dn : actualn);
- /* If we use an() here we'd have to remember never to use */
- /* it whenever calling doname() or xname(). */
- if (typ == FIGURINE && omndx != NON_PM)
- Sprintf(eos(buf), " of a%s %s",
- index(vowels, *mons[omndx].mname) ? "n" : "",
- mons[omndx].mname);
- break;
- case ARMOR_CLASS:
- /* depends on order of the dragon scales objects */
- if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
- Sprintf(buf, "set of %s", actualn);
- break;
- }
- if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
-
- if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
- && !dknown) {
- Strcpy(buf, "shield");
- break;
- }
- if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
- Strcpy(buf, "smooth shield");
- break;
- }
-
- if(nn) Strcat(buf, actualn);
- else if(un) {
- if(is_boots(obj))
- Strcat(buf,"boots");
- else if(is_gloves(obj))
- Strcat(buf,"gloves");
- else if(is_cloak(obj))
- Strcpy(buf,"cloak");
- else if(is_helmet(obj))
- Strcpy(buf,"helmet");
- else if(is_shield(obj))
- Strcpy(buf,"shield");
- else
- Strcpy(buf,"armor");
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else Strcat(buf, dn);
- break;
- case FOOD_CLASS:
- if (typ == SLIME_MOLD) {
- register struct fruit *f;
-
- for(f=ffruit; f; f = f->nextf) {
- if(f->fid == obj->spe) {
- Strcpy(buf, f->fname);
- break;
- }
- }
- if (!f) {
- impossible("Bad fruit #%d?", obj->spe);
- Strcpy(buf, "fruit");
- } else if (pluralize) {
- /* ick; already pluralized fruit names
- are allowed--we want to try to avoid
- adding a redundant plural suffix */
- Strcpy(buf, makeplural(makesingular(buf)));
- pluralize = FALSE;
- }
- break;
- }
-
- Strcpy(buf, actualn);
- if (typ == TIN && known)
- tin_details(obj, omndx, buf);
- break;
- case COIN_CLASS:
- case CHAIN_CLASS:
- Strcpy(buf, actualn);
- break;
- case ROCK_CLASS:
- if (typ == STATUE && omndx != NON_PM)
- Sprintf(buf, "%s%s of %s%s",
- (Role_if(PM_ARCHEOLOGIST) &&
- (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
- actualn,
- type_is_pname(&mons[omndx]) ? "" :
- the_unique_pm(&mons[omndx]) ? "the " :
- index(vowels, *mons[omndx].mname) ? "an " : "a ",
- mons[omndx].mname);
- else Strcpy(buf, actualn);
- break;
- case BALL_CLASS:
- Sprintf(buf, "%sheavy iron ball",
- (obj->owt > ocl->oc_weight) ? "very " : "");
- break;
- case POTION_CLASS:
- if (dknown && obj->odiluted)
- Strcpy(buf, "diluted ");
- if(nn || un || !dknown) {
- Strcat(buf, "potion");
- if(!dknown) break;
- if(nn) {
- Strcat(buf, " of ");
- if (typ == POT_WATER &&
- bknown && (obj->blessed || obj->cursed)) {
- Strcat(buf, obj->blessed ? "holy " : "unholy ");
- }
- Strcat(buf, actualn);
- } else {
- Strcat(buf, " called ");
- Strcat(buf, un);
- }
- } else {
- Strcat(buf, dn);
- Strcat(buf, " potion");
- }
- break;
- case SCROLL_CLASS:
- Strcpy(buf, "scroll");
- if(!dknown) break;
- if(nn) {
- Strcat(buf, " of ");
- Strcat(buf, actualn);
- } else if(un) {
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else if (ocl->oc_magic) {
- Strcat(buf, " labeled ");
- Strcat(buf, dn);
- } else {
- Strcpy(buf, dn);
- Strcat(buf, " scroll");
- }
- break;
- case WAND_CLASS:
- if(!dknown)
- Strcpy(buf, "wand");
- else if(nn)
- Sprintf(buf, "wand of %s", actualn);
- else if(un)
- Sprintf(buf, "wand called %s", un);
- else
- Sprintf(buf, "%s wand", dn);
- break;
- case SPBOOK_CLASS:
- if (!dknown) {
- Strcpy(buf, "spellbook");
- } else if (nn) {
- if (typ != SPE_BOOK_OF_THE_DEAD)
- Strcpy(buf, "spellbook of ");
- Strcat(buf, actualn);
- } else if (un) {
- Sprintf(buf, "spellbook called %s", un);
- } else
- Sprintf(buf, "%s spellbook", dn);
- break;
- case RING_CLASS:
- if(!dknown)
- Strcpy(buf, "ring");
- else if(nn)
- Sprintf(buf, "ring of %s", actualn);
- else if(un)
- Sprintf(buf, "ring called %s", un);
- else
- Sprintf(buf, "%s ring", dn);
- break;
- case GEM_CLASS:
- {
- const char *rock =
- (ocl->oc_material == MINERAL) ? "stone" : "gem";
- if (!dknown) {
- Strcpy(buf, rock);
- } else if (!nn) {
- if (un) Sprintf(buf,"%s called %s", rock, un);
- else Sprintf(buf, "%s %s", dn, rock);
- } else {
- Strcpy(buf, actualn);
- if (GemStone(typ)) Strcat(buf, " stone");
- }
- break;
- }
- default:
- Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
- }
- if (pluralize) Strcpy(buf, makeplural(buf));
+ if (obj_is_pname(obj))
+ goto nameit;
+ switch (obj->oclass) {
+ case AMULET_CLASS:
+ if (!dknown)
+ Strcpy(buf, "amulet");
+ else if (typ == AMULET_OF_YENDOR ||
+ typ == FAKE_AMULET_OF_YENDOR)
+ /* each must be identified individually */
+ Strcpy(buf, known ? actualn : dn);
+ else if (nn)
+ Strcpy(buf, actualn);
+ else if (un)
+ Sprintf(buf,"amulet called %s", un);
+ else
+ Sprintf(buf,"%s amulet", dn);
+ break;
+ case WEAPON_CLASS:
+ if (is_poisonable(obj) && obj->opoisoned)
+ Strcpy(buf, "poisoned ");
+ case VENOM_CLASS:
+ case TOOL_CLASS:
+ if (typ == LENSES)
+ Strcpy(buf, "pair of ");
+
+ if (!dknown)
+ Strcat(buf, dn ? dn : actualn);
+ else if (nn)
+ Strcat(buf, actualn);
+ else if (un) {
+ Strcat(buf, dn ? dn : actualn);
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else
+ Strcat(buf, dn ? dn : actualn);
+ /* If we use an() here we'd have to remember never to use */
+ /* it whenever calling doname() or xname(). */
+ if (typ == FIGURINE && omndx != NON_PM)
+ Sprintf(eos(buf), " of a%s %s",
+ index(vowels, *mons[omndx].mname) ? "n" : "",
+ mons[omndx].mname);
+ break;
+ case ARMOR_CLASS:
+ /* depends on order of the dragon scales objects */
+ if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
+ Sprintf(buf, "set of %s", actualn);
+ break;
+ }
+ if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
+
+ if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
+ && !dknown) {
+ Strcpy(buf, "shield");
+ break;
+ }
+ if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
+ Strcpy(buf, "smooth shield");
+ break;
+ }
+
+ if(nn) Strcat(buf, actualn);
+ else if(un) {
+ if(is_boots(obj))
+ Strcat(buf,"boots");
+ else if(is_gloves(obj))
+ Strcat(buf,"gloves");
+ else if(is_cloak(obj))
+ Strcpy(buf,"cloak");
+ else if(is_helmet(obj))
+ Strcpy(buf,"helmet");
+ else if(is_shield(obj))
+ Strcpy(buf,"shield");
+ else
+ Strcpy(buf,"armor");
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else Strcat(buf, dn);
+ break;
+ case FOOD_CLASS:
+ if (typ == SLIME_MOLD) {
+ register struct fruit *f;
+
+ for(f=ffruit; f; f = f->nextf) {
+ if(f->fid == obj->spe) {
+ Strcpy(buf, f->fname);
+ break;
+ }
+ }
+ if (!f) {
+ impossible("Bad fruit #%d?", obj->spe);
+ Strcpy(buf, "fruit");
+ } else if (pluralize) {
+ /* ick; already pluralized fruit names
+ are allowed--we want to try to avoid
+ adding a redundant plural suffix */
+ Strcpy(buf, makeplural(makesingular(buf)));
+ pluralize = FALSE;
+ }
+ break;
+ }
+ if (Is_pudding(obj)) {
+ Sprintf(buf, "%s%s",
+ obj->owt < 100 ? "small "
+ : obj->owt > 500 ? "very large "
+ : obj->owt > 300 ? "large "
+ : "", actualn);
+ break;
+ }
+
+ Strcpy(buf, actualn);
+ if (typ == TIN && known)
+ tin_details(obj, omndx, buf);
+ break;
+ case COIN_CLASS:
+ case CHAIN_CLASS:
+ Strcpy(buf, actualn);
+ break;
+ case ROCK_CLASS:
+ if (typ == STATUE && omndx != NON_PM)
+ Sprintf(buf, "%s%s of %s%s",
+ (Role_if(PM_ARCHEOLOGIST) &&
+ (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
+ actualn,
+ type_is_pname(&mons[omndx]) ? "" :
+ the_unique_pm(&mons[omndx]) ? "the " :
+ index(vowels, *mons[omndx].mname) ? "an " : "a ",
+ mons[omndx].mname);
+ else Strcpy(buf, actualn);
+ break;
+ case BALL_CLASS:
+ Sprintf(buf, "%sheavy iron ball",
+ (obj->owt > ocl->oc_weight) ? "very " : "");
+ break;
+ case POTION_CLASS:
+ if (dknown && obj->odiluted)
+ Strcpy(buf, "diluted ");
+ if(nn || un || !dknown) {
+ Strcat(buf, "potion");
+ if(!dknown) break;
+ if(nn) {
+ Strcat(buf, " of ");
+ if (typ == POT_WATER &&
+ bknown && (obj->blessed || obj->cursed)) {
+ Strcat(buf, obj->blessed ? "holy " : "unholy ");
+ }
+ Strcat(buf, actualn);
+ } else {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ }
+ } else {
+ Strcat(buf, dn);
+ Strcat(buf, " potion");
+ }
+ break;
+ case SCROLL_CLASS:
+ Strcpy(buf, "scroll");
+ if(!dknown) break;
+ if(nn) {
+ Strcat(buf, " of ");
+ Strcat(buf, actualn);
+ } else if(un) {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else if (ocl->oc_magic) {
+ Strcat(buf, " labeled ");
+ Strcat(buf, dn);
+ } else {
+ Strcpy(buf, dn);
+ Strcat(buf, " scroll");
+ }
+ break;
+ case WAND_CLASS:
+ if(!dknown)
+ Strcpy(buf, "wand");
+ else if(nn)
+ Sprintf(buf, "wand of %s", actualn);
+ else if(un)
+ Sprintf(buf, "wand called %s", un);
+ else
+ Sprintf(buf, "%s wand", dn);
+ break;
+ case SPBOOK_CLASS:
+ if (!dknown) {
+ Strcpy(buf, "spellbook");
+ } else if (nn) {
+ if (typ != SPE_BOOK_OF_THE_DEAD)
+ Strcpy(buf, "spellbook of ");
+ Strcat(buf, actualn);
+ } else if (un) {
+ Sprintf(buf, "spellbook called %s", un);
+ } else
+ Sprintf(buf, "%s spellbook", dn);
+ break;
+ case RING_CLASS:
+ if(!dknown)
+ Strcpy(buf, "ring");
+ else if(nn)
+ Sprintf(buf, "ring of %s", actualn);
+ else if(un)
+ Sprintf(buf, "ring called %s", un);
+ else
+ Sprintf(buf, "%s ring", dn);
+ break;
+ case GEM_CLASS:
+ {
+ const char *rock =
+ (ocl->oc_material == MINERAL) ? "stone" : "gem";
+ if (!dknown) {
+ Strcpy(buf, rock);
+ } else if (!nn) {
+ if (un) Sprintf(buf,"%s called %s", rock, un);
+ else Sprintf(buf, "%s %s", dn, rock);
+ } else {
+ Strcpy(buf, actualn);
+ if (GemStone(typ)) Strcat(buf, " stone");
+ }
+ break;
+ }
+ default:
+ Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
+ }
+ if (pluralize) Strcpy(buf, makeplural(buf));
- if (has_oname(obj) && dknown) {
- Strcat(buf, " named ");
+ if (obj->otyp == T_SHIRT && program_state.gameover) {
+ char tmpbuf[BUFSZ];
+ Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
+ }
+
+ if (has_oname(obj) && dknown) {
+ Strcat(buf, " named ");
nameit:
- Strcat(buf, ONAME(obj));
- }
+ Strcat(buf, ONAME(obj));
+ }
- if (!strncmpi(buf, "the ", 4)) buf += 4;
- return(buf);
+ if (!strncmpi(buf, "the ", 4)) buf += 4;
+ return(buf);
}
/* similar to simple_typename but minimal_xname operates on a particular
doname(obj)
register struct obj *obj;
{
- boolean ispoisoned = FALSE;
- boolean known, cknown, bknown, lknown;
- int omndx = obj->corpsenm;
- char prefix[PREFIX];
- char tmpbuf[PREFIX+1];
- /* when we have to add something at the start of prefix instead of the
- * end (Strcat is used on the end)
- */
- register char *bp = xname(obj);
+ boolean ispoisoned = FALSE;
+ boolean known, cknown, bknown, lknown;
+ int omndx = obj->corpsenm;
+ char prefix[PREFIX];
+ char tmpbuf[PREFIX+1];
+ /* when we have to add something at the start of prefix instead of the
+ * end (Strcat is used on the end)
+ */
+ register char *bp = xname(obj);
- if (iflags.override_ID) known = cknown = bknown = lknown = TRUE;
- else {
+ if (iflags.override_ID) {
+ known = cknown = bknown = lknown = TRUE;
+ } else {
- known = obj->known;
- cknown = obj->cknown;
- bknown = obj->bknown;
- lknown = obj->lknown;
- }
+ known = obj->known;
+ cknown = obj->cknown;
+ bknown = obj->bknown;
+ lknown = obj->lknown;
+ }
- /* When using xname, we want "poisoned arrow", and when using
- * doname, we want "poisoned +0 arrow". This kludge is about the only
- * way to do it, at least until someone overhauls xname() and doname(),
- * combining both into one function taking a parameter.
- */
- /* must check opoisoned--someone can have a weirdly-named fruit */
- if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
- bp += 9;
- ispoisoned = TRUE;
- }
+ /* When using xname, we want "poisoned arrow", and when using
+ * doname, we want "poisoned +0 arrow". This kludge is about the only
+ * way to do it, at least until someone overhauls xname() and doname(),
+ * combining both into one function taking a parameter.
+ */
+ /* must check opoisoned--someone can have a weirdly-named fruit */
+ if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
+ bp += 9;
+ ispoisoned = TRUE;
+ }
- if(obj->quan != 1L)
- Sprintf(prefix, "%ld ", obj->quan);
- else if (obj->otyp == CORPSE)
- /* skip article prefix for corpses [else corpse_xname()
- would have to be taught how to strip it off again] */
- *prefix = '\0';
- else if (obj_is_pname(obj) || the_unique_obj(obj)) {
- if (!strncmpi(bp, "the ", 4))
- bp += 4;
- Strcpy(prefix, "the ");
- } else
- Strcpy(prefix, "a ");
-
- /* "empty" goes at the beginning, but item count goes at the end */
- if (cknown &&
+ if(obj->quan != 1L)
+ Sprintf(prefix, "%ld ", obj->quan);
+ else if (obj->otyp == CORPSE)
+ /* skip article prefix for corpses [else corpse_xname()
+ would have to be taught how to strip it off again] */
+ *prefix = '\0';
+ else if (obj_is_pname(obj) || the_unique_obj(obj)) {
+ if (!strncmpi(bp, "the ", 4))
+ bp += 4;
+ Strcpy(prefix, "the ");
+ } else
+ Strcpy(prefix, "a ");
+
+ /* "empty" goes at the beginning, but item count goes at the end */
+ if (cknown &&
- (Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj))
+ /* bag of tricks: include "empty" prefix if it's known to
+ be empty but its precise number of charges isn't known
+ (when that is known, suffix of "(n:0)" will be appended,
+ making the prefix be redundant; note that 'known' flag
+ isn't set when emptiness gets discovered because then
+ charging magic would yield known number of new charges) */
+ (obj->otyp == BAG_OF_TRICKS ? (obj->spe == 0 && !obj->known) :
+ /* not bag of tricks: empty if container which has no contents */
+ (Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj)))
- Strcat(prefix, "empty ");
-
- if (bknown &&
- obj->oclass != COIN_CLASS &&
- (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
- || (!obj->cursed && !obj->blessed))) {
- /* allow 'blessed clear potion' if we don't know it's holy water;
- * always allow "uncursed potion of water"
- */
- if (obj->cursed)
- Strcat(prefix, "cursed ");
- else if (obj->blessed)
- Strcat(prefix, "blessed ");
- else if ((!known || !objects[obj->otyp].oc_charged ||
- (obj->oclass == ARMOR_CLASS ||
- obj->oclass == RING_CLASS))
- /* For most items with charges or +/-, if you know how many
- * charges are left or what the +/- is, then you must have
- * totally identified the item, so "uncursed" is unneccesary,
- * because an identified object not described as "blessed" or
- * "cursed" must be uncursed.
- *
- * If the charges or +/- is not known, "uncursed" must be
- * printed to avoid ambiguity between an item whose curse
- * status is unknown, and an item known to be uncursed.
- */
+ Strcat(prefix, "empty ");
+
+ if (bknown &&
+ obj->oclass != COIN_CLASS &&
+ (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
+ || (!obj->cursed && !obj->blessed))) {
+ /* allow 'blessed clear potion' if we don't know it's holy water;
+ * always allow "uncursed potion of water"
+ */
+ if (obj->cursed)
+ Strcat(prefix, "cursed ");
+ else if (obj->blessed)
+ Strcat(prefix, "blessed ");
+ else if ((!known || !objects[obj->otyp].oc_charged ||
+ (obj->oclass == ARMOR_CLASS ||
+ obj->oclass == RING_CLASS))
+ /* For most items with charges or +/-, if you know how many
+ * charges are left or what the +/- is, then you must have
+ * totally identified the item, so "uncursed" is unneccesary,
+ * because an identified object not described as "blessed" or
+ * "cursed" must be uncursed.
+ *
+ * If the charges or +/- is not known, "uncursed" must be
+ * printed to avoid ambiguity between an item whose curse
+ * status is unknown, and an item known to be uncursed.
+ */
#ifdef MAIL
- && obj->otyp != SCR_MAIL
+ && obj->otyp != SCR_MAIL
#endif
- && obj->otyp != FAKE_AMULET_OF_YENDOR
- && obj->otyp != AMULET_OF_YENDOR
- && !Role_if(PM_PRIEST))
- Strcat(prefix, "uncursed ");
- }
+ && obj->otyp != FAKE_AMULET_OF_YENDOR
+ && obj->otyp != AMULET_OF_YENDOR
+ && !Role_if(PM_PRIEST))
+ Strcat(prefix, "uncursed ");
+ }
- if (lknown && Is_box(obj)) {
- if (obj->obroken)
- Strcat(prefix, "unlockable ");
- else if (obj->olocked)
- Strcat(prefix, "locked ");
- else
- Strcat(prefix, "unlocked ");
- }
+ if (lknown && Is_box(obj)) {
+ if (obj->obroken)
+ Strcat(prefix, "unlockable ");
+ else if (obj->olocked)
+ Strcat(prefix, "locked ");
+ else
+ Strcat(prefix, "unlocked ");
+ }
- if (obj->greased) Strcat(prefix, "greased ");
+ if (obj->greased) Strcat(prefix, "greased ");
- if (cknown && Has_contents(obj)) {
- /* we count all objects (obj->quantity); perhaps we should
- count seperate stacks instead (or even introduce a user
- preference option to choose between the two alternatives)
- since it's somewhat odd so see "containing 1002 items"
- when there are 2 scrolls plus 1000 gold pieces */
- long itemcount = count_contents(obj, FALSE, TRUE, TRUE);
+ if (cknown && Has_contents(obj)) {
+ /* we count all objects (obj->quantity); perhaps we should
+ count seperate stacks instead (or even introduce a user
+ preference option to choose between the two alternatives)
+ since it's somewhat odd so see "containing 1002 items"
+ when there are 2 scrolls plus 1000 gold pieces */
+ long itemcount = count_contents(obj, FALSE, TRUE, TRUE);
- Sprintf(eos(bp), " containing %ld item%s",
- itemcount, plur(itemcount));
- }
+ Sprintf(eos(bp), " containing %ld item%s",
+ itemcount, plur(itemcount));
+ }
- switch(obj->oclass) {
- case AMULET_CLASS:
- if(obj->owornmask & W_AMUL)
- Strcat(bp, " (being worn)");
- break;
- case WEAPON_CLASS:
- if(ispoisoned)
- Strcat(prefix, "poisoned ");
+ switch(obj->oclass) {
+ case AMULET_CLASS:
+ if(obj->owornmask & W_AMUL)
+ Strcat(bp, " (being worn)");
+ break;
+ case WEAPON_CLASS:
+ if(ispoisoned)
+ Strcat(prefix, "poisoned ");
plus:
- add_erosion_words(obj, prefix);
- if(known) {
- Strcat(prefix, sitoa(obj->spe));
- Strcat(prefix, " ");
- }
- break;
- case ARMOR_CLASS:
- if(obj->owornmask & W_ARMOR)
- Strcat(bp, (obj == uskin) ? " (embedded in your skin)" :
- " (being worn)");
- goto plus;
- case TOOL_CLASS:
- /* weptools already get this done when we go to the +n code */
- if (!is_weptool(obj))
- add_erosion_words(obj, prefix);
- if(obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) {
- Strcat(bp, " (being worn)");
- break;
- }
- if (obj->otyp == LEASH && obj->leashmon != 0) {
- Strcat(bp, " (in use)");
- break;
- }
- if (is_weptool(obj))
- goto plus;
- if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
- if (!obj->spe)
- Strcpy(tmpbuf, "no");
- else
- Sprintf(tmpbuf, "%d", obj->spe);
- Sprintf(eos(bp), " (%s candle%s%s)",
- tmpbuf, plur(obj->spe),
- !obj->lamplit ? " attached" : ", lit");
- break;
- } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
- obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
- if (Is_candle(obj) &&
- obj->age < 20L * (long)objects[obj->otyp].oc_cost)
- Strcat(prefix, "partly used ");
- if(obj->lamplit)
- Strcat(bp, " (lit)");
- break;
- }
- if(objects[obj->otyp].oc_charged)
- goto charges;
- break;
- case WAND_CLASS:
- add_erosion_words(obj, prefix);
+ add_erosion_words(obj, prefix);
+ if(known) {
+ Strcat(prefix, sitoa(obj->spe));
+ Strcat(prefix, " ");
+ }
+ break;
+ case ARMOR_CLASS:
+ if(obj->owornmask & W_ARMOR)
+ Strcat(bp, (obj == uskin) ? " (embedded in your skin)" :
+ " (being worn)");
+ goto plus;
+ case TOOL_CLASS:
+ /* weptools already get this done when we go to the +n code */
+ if (!is_weptool(obj))
+ add_erosion_words(obj, prefix);
+ if(obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) {
+ Strcat(bp, " (being worn)");
+ break;
+ }
+ if (obj->otyp == LEASH && obj->leashmon != 0) {
+ Strcat(bp, " (in use)");
+ break;
+ }
+ if (is_weptool(obj))
+ goto plus;
+ if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
+ if (!obj->spe)
+ Strcpy(tmpbuf, "no");
+ else
+ Sprintf(tmpbuf, "%d", obj->spe);
+ Sprintf(eos(bp), " (%s candle%s%s)",
+ tmpbuf, plur(obj->spe),
+ !obj->lamplit ? " attached" : ", lit");
+ break;
+ } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
+ obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
+ if (Is_candle(obj) &&
+ obj->age < 20L * (long)objects[obj->otyp].oc_cost)
+ Strcat(prefix, "partly used ");
+ if(obj->lamplit)
+ Strcat(bp, " (lit)");
+ break;
+ }
+ if(objects[obj->otyp].oc_charged)
+ goto charges;
+ break;
+ case WAND_CLASS:
+ add_erosion_words(obj, prefix);
charges:
- if(known)
- Sprintf(eos(bp), " (%d:%d)", (int)obj->recharged, obj->spe);
- break;
- case POTION_CLASS:
- if (obj->otyp == POT_OIL && obj->lamplit)
- Strcat(bp, " (lit)");
- break;
- case RING_CLASS:
- add_erosion_words(obj, prefix);
+ if(known)
+ Sprintf(eos(bp), " (%d:%d)", (int)obj->recharged, obj->spe);
+ break;
+ case POTION_CLASS:
+ if (obj->otyp == POT_OIL && obj->lamplit)
+ Strcat(bp, " (lit)");
+ break;
+ case RING_CLASS:
+ add_erosion_words(obj, prefix);
ring:
- if(obj->owornmask & W_RINGR) Strcat(bp, " (on right ");
- if(obj->owornmask & W_RINGL) Strcat(bp, " (on left ");
- if(obj->owornmask & W_RING) {
- Strcat(bp, body_part(HAND));
- Strcat(bp, ")");
- }
- if(known && objects[obj->otyp].oc_charged) {
- Strcat(prefix, sitoa(obj->spe));
- Strcat(prefix, " ");
- }
- break;
- case FOOD_CLASS:
- if (obj->oeaten)
- Strcat(prefix, "partly eaten ");
- if (obj->otyp == CORPSE) {
- Sprintf(prefix, "%s ",
- corpse_xname(obj, prefix,
- CXN_ARTICLE|CXN_NOCORPSE));
- } else if (obj->otyp == EGG) {
+ if(obj->owornmask & W_RINGR) Strcat(bp, " (on right ");
+ if(obj->owornmask & W_RINGL) Strcat(bp, " (on left ");
+ if(obj->owornmask & W_RING) {
+ Strcat(bp, body_part(HAND));
+ Strcat(bp, ")");
+ }
+ if(known && objects[obj->otyp].oc_charged) {
+ Strcat(prefix, sitoa(obj->spe));
+ Strcat(prefix, " ");
+ }
+ break;
+ case FOOD_CLASS:
+ if (obj->oeaten)
+ Strcat(prefix, "partly eaten ");
+ if (obj->otyp == CORPSE) {
+ Sprintf(prefix, "%s ",
+ corpse_xname(obj, prefix,
+ CXN_ARTICLE|CXN_NOCORPSE));
+ } else if (obj->otyp == EGG) {
#if 0 /* corpses don't tell if they're stale either */
- if (known && stale_egg(obj))
- Strcat(prefix, "stale ");
+ if (known && stale_egg(obj))
+ Strcat(prefix, "stale ");
#endif
- if (omndx >= LOW_PM && (known ||
- (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
- Strcat(prefix, mons[omndx].mname);
- Strcat(prefix, " ");
- if (obj->spe)
- Strcat(bp, " (laid by you)");
- }
- }
- if (obj->otyp == MEAT_RING) goto ring;
- break;
- case BALL_CLASS:
- case CHAIN_CLASS:
- add_erosion_words(obj, prefix);
- if(obj->owornmask & W_BALL)
- Strcat(bp, " (chained to you)");
- break;
- }
+ if (omndx >= LOW_PM && (known ||
+ (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
+ Strcat(prefix, mons[omndx].mname);
+ Strcat(prefix, " ");
+ if (obj->spe)
+ Strcat(bp, " (laid by you)");
+ }
+ }
+ if (wizard) {
+ Sprintf(eos(bp), " (%d aum)", obj->owt);
+ }
+ if (obj->otyp == MEAT_RING) goto ring;
+ break;
+ case BALL_CLASS:
+ case CHAIN_CLASS:
+ add_erosion_words(obj, prefix);
+ if(obj->owornmask & W_BALL)
+ Strcat(bp, " (chained to you)");
+ break;
+ }
- if((obj->owornmask & W_WEP) && !mrg_to_wielded) {
- if (obj->quan != 1L) {
- Strcat(bp, " (wielded)");
- } else {
- const char *hand_s = body_part(HAND);
+ if((obj->owornmask & W_WEP) && !mrg_to_wielded) {
+ if (obj->quan != 1L) {
+ Strcat(bp, " (wielded)");
+ } else {
+ const char *hand_s = body_part(HAND);
- if (bimanual(obj)) hand_s = makeplural(hand_s);
- Sprintf(eos(bp), " (weapon in %s)", hand_s);
- }
- }
- if(obj->owornmask & W_SWAPWEP) {
- if (u.twoweap)
- Sprintf(eos(bp), " (wielded in other %s)",
- body_part(HAND));
- else
- Strcat(bp, " (alternate weapon; not wielded)");
- }
- if(obj->owornmask & W_QUIVER){
- switch(obj->oclass){
- case WEAPON_CLASS:
- if(is_ammo(obj)){
- if(objects[obj->otyp].oc_skill == -P_BOW){
- /* Ammo for a bow */
- Strcat(bp, " (in quiver)");
- break;
- } else {
- /* Ammo not for a bow */
- Strcat(bp, " (in quiver pouch)");
- break;
- }
- } else {
- /* Weapons not considered ammo */
- Strcat(bp, " (at the ready)");
- break;
- }
-
- /* Small things and ammo not for a bow */
- case RING_CLASS:
- case AMULET_CLASS:
- case WAND_CLASS:
- case COIN_CLASS:
- case GEM_CLASS:
- Strcat(bp, " (in quiver pouch)");
- break;
- default: /* odd things */
- Strcat(bp, " (at the ready)");
- }
- }
- if (!iflags.suppress_price && is_unpaid(obj)) {
- long quotedprice = unpaid_cost(obj, TRUE);
+ if (bimanual(obj)) hand_s = makeplural(hand_s);
+ Sprintf(eos(bp), " (weapon in %s)", hand_s);
+ }
+ }
+ if(obj->owornmask & W_SWAPWEP) {
+ if (u.twoweap)
+ Sprintf(eos(bp), " (wielded in other %s)",
+ body_part(HAND));
+ else
+ Strcat(bp, " (alternate weapon; not wielded)");
+ }
+ if(obj->owornmask & W_QUIVER){
+ switch(obj->oclass){
+ case WEAPON_CLASS:
+ if(is_ammo(obj)){
+ if(objects[obj->otyp].oc_skill == -P_BOW){
+ /* Ammo for a bow */
+ Strcat(bp, " (in quiver)");
+ break;
+ } else {
+ /* Ammo not for a bow */
+ Strcat(bp, " (in quiver pouch)");
+ break;
+ }
+ } else {
+ /* Weapons not considered ammo */
+ Strcat(bp, " (at the ready)");
+ break;
+ }
+
+ /* Small things and ammo not for a bow */
+ case RING_CLASS:
+ case AMULET_CLASS:
+ case WAND_CLASS:
+ case COIN_CLASS:
+ case GEM_CLASS:
+ Strcat(bp, " (in quiver pouch)");
+ break;
+ default: /* odd things */
+ Strcat(bp, " (at the ready)");
+ }
+ }
+ if (!iflags.suppress_price && is_unpaid(obj)) {
+ long quotedprice = unpaid_cost(obj, TRUE);
- Sprintf(eos(bp), " (%s, %ld %s)",
- obj->unpaid ? "unpaid" : "contents",
- quotedprice, currency(quotedprice));
- }
- if (!strncmp(prefix, "a ", 2) &&
- index(vowels, *(prefix+2) ? *(prefix+2) : *bp)
- && (*(prefix+2) || (strncmp(bp, "uranium", 7)
- && strncmp(bp, "unicorn", 7)
- && strncmp(bp, "eucalyptus", 10)))) {
- Strcpy(tmpbuf, prefix);
- Strcpy(prefix, "an ");
- Strcpy(prefix+3, tmpbuf+2);
- }
- bp = strprepend(bp, prefix);
- return(bp);
+ Sprintf(eos(bp), " (%s, %ld %s)",
+ obj->unpaid ? "unpaid" : "contents",
+ quotedprice, currency(quotedprice));
+ }
+ if (!strncmp(prefix, "a ", 2) &&
+ index(vowels, *(prefix+2) ? *(prefix+2) : *bp)
+ && (*(prefix+2) || (strncmp(bp, "uranium", 7)
+ && strncmp(bp, "unicorn", 7)
+ && strncmp(bp, "eucalyptus", 10)))) {
+ Strcpy(tmpbuf, prefix);
+ Strcpy(prefix, "an ");
+ Strcpy(prefix+3, tmpbuf+2);
+ }
+ bp = strprepend(bp, prefix);
+ return(bp);
}
/* used from invent.c */