From: Derek S. Ray Date: Wed, 1 Apr 2015 21:40:25 +0000 (-0400) Subject: Merge branch 'master' into derek-farming X-Git-Tag: NetHack-3.6.0_RC01~414^2~41^2~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af5ed436b81c1f9644e134df971094aa774a4fbf;p=nethack Merge branch 'master' into derek-farming * master: (160 commits) Add doors correctly bug fixes for nhsub Generate oracle monsters after subroom Generate minetown guards after subrooms ... Conflicts: src/do.c src/files.c src/hack.c src/mon.c src/vision.c --- af5ed436b81c1f9644e134df971094aa774a4fbf diff --cc src/do.c index d253af133,eae360425..fcb77525e --- a/src/do.c +++ b/src/do.c @@@ -1034,382 -1026,382 +1034,382 @@@ boolean at_stairs, falling, portal * -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 */ + /* initial movement of bubbles just before vision_recalc */ - if (Is_waterlevel(&u.uz)) + if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) - movebubbles(); + 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; } diff --cc src/files.c index e80799ed1,179cd3437..02843bd1f --- a/src/files.c +++ b/src/files.c @@@ -2164,304 -2166,307 +2164,307 @@@ int src # endif /* MICRO */ #endif /*NOCWD_ASSUMPTIONS*/ - } else if (match_varname(buf, "NAME", 4)) { - (void) strncpy(plname, bufp, PL_NSIZ-1); - plnamesuffix(); - } else if (match_varname(buf, "ROLE", 4) || - match_varname(buf, "CHARACTER", 4)) { - if ((len = str2role(bufp)) >= 0) - flags.initrole = len; - } else if (match_varname(buf, "DOGNAME", 3)) { - (void) strncpy(dogname, bufp, PL_PSIZ-1); - } else if (match_varname(buf, "CATNAME", 3)) { - (void) strncpy(catname, bufp, PL_PSIZ-1); + } else if (match_varname(buf, "NAME", 4)) { + (void) strncpy(plname, bufp, PL_NSIZ-1); + plnamesuffix(); + } else if (match_varname(buf, "ROLE", 4) || + match_varname(buf, "CHARACTER", 4)) { + if ((len = str2role(bufp)) >= 0) + flags.initrole = len; + } else if (match_varname(buf, "DOGNAME", 3)) { + (void) strncpy(dogname, bufp, PL_PSIZ-1); + } else if (match_varname(buf, "CATNAME", 3)) { + (void) strncpy(catname, bufp, PL_PSIZ-1); #ifdef SYSCF - } else if (src == SET_IN_SYS && match_varname(buf, "WIZARDS", 7)) { - if (sysopt.wizards) free(sysopt.wizards); - sysopt.wizards = dupstr(bufp); - } else if (src == SET_IN_SYS && match_varname(buf, "SHELLERS", 8)) { - if (sysopt.shellers) free(sysopt.shellers); - sysopt.shellers = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "WIZARDS", 7)) { + if (sysopt.wizards) free(sysopt.wizards); + sysopt.wizards = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "SHELLERS", 8)) { + if (sysopt.shellers) free(sysopt.shellers); + sysopt.shellers = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "EXPLORERS", 7)) { + if (sysopt.explorers) free(sysopt.explorers); + sysopt.explorers = dupstr(bufp); - } else if (src == SET_IN_SYS && match_varname(buf, "DEBUGFILES", 5)) { - if (sysopt.debugfiles) free(sysopt.debugfiles); - /* if showdebug() has already been called (perhaps we've added - some debugpline() calls to option processing) and has found - a value for getenv("DEBUGFILES"), don't override that */ - if (sysopt.env_dbgfl == 0) - sysopt.debugfiles = dupstr(bufp); - } else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) { - if (sysopt.support) free(sysopt.support); - sysopt.support = dupstr(bufp); - } else if (src == SET_IN_SYS && match_varname(buf, "RECOVER", 7)) { - if (sysopt.recover) free(sysopt.recover); - sysopt.recover = dupstr(bufp); - } else if (match_varname(buf, "SEDUCE", 6)) { - n = !!atoi(bufp); /* XXX this could be tighter */ - /* allow anyone to turn it off, but only sysconf to turn it on*/ - if (src != SET_IN_SYS && n != 0) { - raw_printf("Illegal value in SEDUCE"); - return 0; - } - sysopt.seduce = n; - sysopt_seduce_set(sysopt.seduce); - } else if (src == SET_IN_SYS && match_varname(buf, "MAXPLAYERS", 10)) { - n = atoi(bufp); - /* XXX to get more than 25, need to rewrite all lock code */ - if (n < 1 || n > 25) { - raw_printf("Illegal value in MAXPLAYERS (maximum is 25)."); - return 0; - } - sysopt.maxplayers = n; - } else if (src == SET_IN_SYS && match_varname(buf, "PERSMAX", 7)) { - n = atoi(bufp); - if (n < 1) { - raw_printf("Illegal value in PERSMAX (minimum is 1)."); - return 0; - } - sysopt.persmax = n; - } else if (src == SET_IN_SYS && match_varname(buf, "PERS_IS_UID", 11)) { - n = atoi(bufp); - if (n != 0 && n != 1) { - raw_printf("Illegal value in PERS_IS_UID (must be 0 or 1)."); - return 0; - } - sysopt.pers_is_uid = n; - } else if (src == SET_IN_SYS && match_varname(buf, "ENTRYMAX", 8)) { - n = atoi(bufp); - if (n < 10) { - raw_printf("Illegal value in ENTRYMAX (minimum is 10)."); - return 0; - } - sysopt.entrymax = n; - } else if ( (src==SET_IN_SYS) && match_varname(buf, "POINTSMIN", 9)) { - n = atoi(bufp); - if (n < 1) { - raw_printf("Illegal value in POINTSMIN (minimum is 1)."); - return 0; - } - sysopt.pointsmin = n; - } else if (src == SET_IN_SYS && match_varname(buf, "MAX_STATUENAME_RANK", 10)) { - n = atoi(bufp); - if (n < 1) { - raw_printf("Illegal value in MAX_STATUENAME_RANK (minimum is 1)."); - return 0; - } - sysopt.tt_oname_maxrank = n; + } else if (src == SET_IN_SYS && match_varname(buf, "DEBUGFILES", 5)) { + if (sysopt.debugfiles) free(sysopt.debugfiles); + /* if showdebug() has already been called (perhaps we've added + some debugpline() calls to option processing) and has found + a value for getenv("DEBUGFILES"), don't override that */ + if (sysopt.env_dbgfl == 0) + sysopt.debugfiles = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) { + if (sysopt.support) free(sysopt.support); + sysopt.support = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "RECOVER", 7)) { + if (sysopt.recover) free(sysopt.recover); + sysopt.recover = dupstr(bufp); + } else if (match_varname(buf, "SEDUCE", 6)) { + n = !!atoi(bufp); /* XXX this could be tighter */ + /* allow anyone to turn it off, but only sysconf to turn it on*/ + if (src != SET_IN_SYS && n != 0) { + raw_printf("Illegal value in SEDUCE"); + return 0; + } + sysopt.seduce = n; + sysopt_seduce_set(sysopt.seduce); + } else if (src == SET_IN_SYS && match_varname(buf, "MAXPLAYERS", 10)) { + n = atoi(bufp); + /* XXX to get more than 25, need to rewrite all lock code */ + if (n < 1 || n > 25) { + raw_printf("Illegal value in MAXPLAYERS (maximum is 25)."); + return 0; + } + sysopt.maxplayers = n; + } else if (src == SET_IN_SYS && match_varname(buf, "PERSMAX", 7)) { + n = atoi(bufp); + if (n < 1) { + raw_printf("Illegal value in PERSMAX (minimum is 1)."); + return 0; + } + sysopt.persmax = n; + } else if (src == SET_IN_SYS && match_varname(buf, "PERS_IS_UID", 11)) { + n = atoi(bufp); + if (n != 0 && n != 1) { + raw_printf("Illegal value in PERS_IS_UID (must be 0 or 1)."); + return 0; + } + sysopt.pers_is_uid = n; + } else if (src == SET_IN_SYS && match_varname(buf, "ENTRYMAX", 8)) { + n = atoi(bufp); + if (n < 10) { + raw_printf("Illegal value in ENTRYMAX (minimum is 10)."); + return 0; + } + sysopt.entrymax = n; + } else if ( (src==SET_IN_SYS) && match_varname(buf, "POINTSMIN", 9)) { + n = atoi(bufp); + if (n < 1) { + raw_printf("Illegal value in POINTSMIN (minimum is 1)."); + return 0; + } + sysopt.pointsmin = n; + } else if (src == SET_IN_SYS && match_varname(buf, "MAX_STATUENAME_RANK", 10)) { + n = atoi(bufp); + if (n < 1) { + raw_printf("Illegal value in MAX_STATUENAME_RANK (minimum is 1)."); + return 0; + } + sysopt.tt_oname_maxrank = n; # ifdef PANICTRACE - } else if (src == SET_IN_SYS && - match_varname(buf, "PANICTRACE_LIBC", 15)) { + } else if (src == SET_IN_SYS && + match_varname(buf, "PANICTRACE_LIBC", 15)) { # ifdef PANICTRACE_LIBC - n = atoi(bufp); - if (n < 0 || n > 2) { - raw_printf("Illegal value in PANICTRACE_LIBC (not 0,1,2)."); - return 0; - } - sysopt.panictrace_libc = n; + n = atoi(bufp); + if (n < 0 || n > 2) { + raw_printf("Illegal value in PANICTRACE_LIBC (not 0,1,2)."); + return 0; + } + sysopt.panictrace_libc = n; # endif /* PANICTRACE_LIBC */ - } else if (src == SET_IN_SYS && - match_varname(buf, "PANICTRACE_GDB", 14)) { - n = atoi(bufp); - if (n < 0 || n > 2) { - raw_printf("Illegal value in PANICTRACE_GDB (not 0,1,2)."); - return 0; - } - sysopt.panictrace_gdb = n; - } else if (src == SET_IN_SYS && match_varname(buf, "GDBPATH", 7)) { - if (!file_exists(bufp)) { - raw_printf("File specified in GDBPATH does not exist."); - return 0; - } - if (sysopt.gdbpath) free(sysopt.gdbpath); - sysopt.gdbpath = dupstr(bufp); - } else if (src == SET_IN_SYS && match_varname(buf, "GREPPATH", 7)) { - if (!file_exists(bufp)) { - raw_printf("File specified in GREPPATH does not exist."); - return 0; - } - if (sysopt.greppath) free(sysopt.greppath); - sysopt.greppath = dupstr(bufp); + } else if (src == SET_IN_SYS && + match_varname(buf, "PANICTRACE_GDB", 14)) { + n = atoi(bufp); + if (n < 0 || n > 2) { + raw_printf("Illegal value in PANICTRACE_GDB (not 0,1,2)."); + return 0; + } + sysopt.panictrace_gdb = n; + } else if (src == SET_IN_SYS && match_varname(buf, "GDBPATH", 7)) { + if (!file_exists(bufp)) { + raw_printf("File specified in GDBPATH does not exist."); + return 0; + } + if (sysopt.gdbpath) free(sysopt.gdbpath); + sysopt.gdbpath = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "GREPPATH", 7)) { + if (!file_exists(bufp)) { + raw_printf("File specified in GREPPATH does not exist."); + return 0; + } + if (sysopt.greppath) free(sysopt.greppath); + sysopt.greppath = dupstr(bufp); # endif /* PANICTRACE */ #endif /* SYSCF */ - } else if (match_varname(buf, "BOULDER", 3)) { - (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, - 1, "BOULDER"); - } else if (match_varname(buf, "WARNINGS", 5)) { - (void) get_uchars(fp, buf, bufp, translate, FALSE, - WARNCOUNT, "WARNINGS"); - assign_warnings(translate); - } else if (match_varname(buf, "SYMBOLS", 4)) { - char *op, symbuf[BUFSZ]; - boolean morelines; - do { - morelines = FALSE; - - /* strip leading and trailing white space */ - while (isspace(*bufp)) bufp++; - op = eos(bufp); - while (--op >= bufp && isspace(*op)) *op = '\0'; - - /* check for line continuation (trailing '\') */ - op = eos(bufp); - if (--op >= bufp && *op == '\\') { - *op = '\0'; - morelines = TRUE; - /* strip trailing space now that '\' is gone */ - while (--op >= bufp && isspace(*op)) *op = '\0'; - } - /* parse here */ - parsesymbols(bufp); - if (morelines) - do { - *symbuf = '\0'; - if (!fgets(symbuf, BUFSZ, fp)) { - morelines = FALSE; - break; - } - bufp = symbuf; - } while (*bufp == '#'); - } while (morelines); - switch_symbols(TRUE); - } else if (match_varname(buf, "WIZKIT", 6)) { - (void) strncpy(wizkit, bufp, WIZKIT_MAX-1); + } else if (match_varname(buf, "BOULDER", 3)) { + (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, + 1, "BOULDER"); + } else if (match_varname(buf, "WARNINGS", 5)) { + (void) get_uchars(fp, buf, bufp, translate, FALSE, + WARNCOUNT, "WARNINGS"); + assign_warnings(translate); + } else if (match_varname(buf, "SYMBOLS", 4)) { + char *op, symbuf[BUFSZ]; + boolean morelines; + do { + morelines = FALSE; + + /* strip leading and trailing white space */ + while (isspace(*bufp)) bufp++; + op = eos(bufp); + while (--op >= bufp && isspace(*op)) *op = '\0'; + + /* check for line continuation (trailing '\') */ + op = eos(bufp); + if (--op >= bufp && *op == '\\') { + *op = '\0'; + morelines = TRUE; + /* strip trailing space now that '\' is gone */ + while (--op >= bufp && isspace(*op)) *op = '\0'; + } + /* parse here */ + parsesymbols(bufp); + if (morelines) + do { + *symbuf = '\0'; + if (!fgets(symbuf, BUFSZ, fp)) { + morelines = FALSE; + break; + } + bufp = symbuf; + } while (*bufp == '#'); + } while (morelines); + switch_symbols(TRUE); + } else if (match_varname(buf, "WIZKIT", 6)) { + (void) strncpy(wizkit, bufp, WIZKIT_MAX-1); #ifdef AMIGA - } else if (match_varname(buf, "FONT", 4)) { - char *t; - - if( t = strchr( buf+5, ':' ) ) - { - *t = 0; - amii_set_text_font( buf+5, atoi( t + 1 ) ); - *t = ':'; - } - } else if (match_varname(buf, "PATH", 4)) { - (void) strncpy(PATH, bufp, PATHLEN-1); - } else if (match_varname(buf, "DEPTH", 5)) { - extern int amii_numcolors; - int val = atoi( bufp ); - amii_numcolors = 1L << min( DEPTH, val ); + } else if (match_varname(buf, "FONT", 4)) { + char *t; + + if( t = strchr( buf+5, ':' ) ) + { + *t = 0; + amii_set_text_font( buf+5, atoi( t + 1 ) ); + *t = ':'; + } + } else if (match_varname(buf, "PATH", 4)) { + (void) strncpy(PATH, bufp, PATHLEN-1); + } else if (match_varname(buf, "DEPTH", 5)) { + extern int amii_numcolors; + int val = atoi( bufp ); + amii_numcolors = 1L << min( DEPTH, val ); #if defined(SYSFLAGS) - } else if (match_varname(buf, "DRIPENS", 7)) { - int i, val; - char *t; - for (i = 0, t = strtok(bufp, ",/"); t != (char *)0; - i < 20 && (t = strtok((char*)0, ",/")), ++i) { - sscanf(t, "%d", &val ); - sysflags.amii_dripens[i] = val; - } -#endif - } else if (match_varname(buf, "SCREENMODE", 10 )) { - extern long amii_scrnmode; - if (!stricmp(bufp,"req")) - amii_scrnmode = 0xffffffff; /* Requester */ - else if( sscanf(bufp, "%x", &amii_scrnmode) != 1 ) - amii_scrnmode = 0; - } else if (match_varname(buf, "MSGPENS", 7)) { - extern int amii_msgAPen, amii_msgBPen; - char *t = strtok(bufp, ",/"); - if( t ) - { - sscanf(t, "%d", &amii_msgAPen); - if( t = strtok((char*)0, ",/") ) - sscanf(t, "%d", &amii_msgBPen); - } - } else if (match_varname(buf, "TEXTPENS", 8)) { - extern int amii_textAPen, amii_textBPen; - char *t = strtok(bufp, ",/"); - if( t ) - { - sscanf(t, "%d", &amii_textAPen); - if( t = strtok((char*)0, ",/") ) - sscanf(t, "%d", &amii_textBPen); - } - } else if (match_varname(buf, "MENUPENS", 8)) { - extern int amii_menuAPen, amii_menuBPen; - char *t = strtok(bufp, ",/"); - if( t ) - { - sscanf(t, "%d", &amii_menuAPen); - if( t = strtok((char*)0, ",/") ) - sscanf(t, "%d", &amii_menuBPen); - } - } else if (match_varname(buf, "STATUSPENS", 10)) { - extern int amii_statAPen, amii_statBPen; - char *t = strtok(bufp, ",/"); - if( t ) - { - sscanf(t, "%d", &amii_statAPen); - if( t = strtok((char*)0, ",/") ) - sscanf(t, "%d", &amii_statBPen); - } - } else if (match_varname(buf, "OTHERPENS", 9)) { - extern int amii_otherAPen, amii_otherBPen; - char *t = strtok(bufp, ",/"); - if( t ) - { - sscanf(t, "%d", &amii_otherAPen); - if( t = strtok((char*)0, ",/") ) - sscanf(t, "%d", &amii_otherBPen); - } - } else if (match_varname(buf, "PENS", 4)) { - extern unsigned short amii_init_map[ AMII_MAXCOLORS ]; - int i; - char *t; - - for (i = 0, t = strtok(bufp, ",/"); - i < AMII_MAXCOLORS && t != (char *)0; - t = strtok((char *)0, ",/"), ++i) - { - sscanf(t, "%hx", &amii_init_map[i]); - } - amii_setpens( amii_numcolors = i ); - } else if (match_varname(buf, "FGPENS", 6)) { - extern int foreg[ AMII_MAXCOLORS ]; - int i; - char *t; - - for (i = 0, t = strtok(bufp, ",/"); - i < AMII_MAXCOLORS && t != (char *)0; - t = strtok((char *)0, ",/"), ++i) - { - sscanf(t, "%d", &foreg[i]); - } - } else if (match_varname(buf, "BGPENS", 6)) { - extern int backg[ AMII_MAXCOLORS ]; - int i; - char *t; - - for (i = 0, t = strtok(bufp, ",/"); - i < AMII_MAXCOLORS && t != (char *)0; - t = strtok((char *)0, ",/"), ++i) - { - sscanf(t, "%d", &backg[i]); - } + } else if (match_varname(buf, "DRIPENS", 7)) { + int i, val; + char *t; + for (i = 0, t = strtok(bufp, ",/"); t != (char *)0; + i < 20 && (t = strtok((char*)0, ",/")), ++i) { + sscanf(t, "%d", &val ); + sysflags.amii_dripens[i] = val; + } +#endif + } else if (match_varname(buf, "SCREENMODE", 10 )) { + extern long amii_scrnmode; + if (!stricmp(bufp,"req")) + amii_scrnmode = 0xffffffff; /* Requester */ + else if( sscanf(bufp, "%x", &amii_scrnmode) != 1 ) + amii_scrnmode = 0; + } else if (match_varname(buf, "MSGPENS", 7)) { + extern int amii_msgAPen, amii_msgBPen; + char *t = strtok(bufp, ",/"); + if( t ) + { + sscanf(t, "%d", &amii_msgAPen); + if( t = strtok((char*)0, ",/") ) + sscanf(t, "%d", &amii_msgBPen); + } + } else if (match_varname(buf, "TEXTPENS", 8)) { + extern int amii_textAPen, amii_textBPen; + char *t = strtok(bufp, ",/"); + if( t ) + { + sscanf(t, "%d", &amii_textAPen); + if( t = strtok((char*)0, ",/") ) + sscanf(t, "%d", &amii_textBPen); + } + } else if (match_varname(buf, "MENUPENS", 8)) { + extern int amii_menuAPen, amii_menuBPen; + char *t = strtok(bufp, ",/"); + if( t ) + { + sscanf(t, "%d", &amii_menuAPen); + if( t = strtok((char*)0, ",/") ) + sscanf(t, "%d", &amii_menuBPen); + } + } else if (match_varname(buf, "STATUSPENS", 10)) { + extern int amii_statAPen, amii_statBPen; + char *t = strtok(bufp, ",/"); + if( t ) + { + sscanf(t, "%d", &amii_statAPen); + if( t = strtok((char*)0, ",/") ) + sscanf(t, "%d", &amii_statBPen); + } + } else if (match_varname(buf, "OTHERPENS", 9)) { + extern int amii_otherAPen, amii_otherBPen; + char *t = strtok(bufp, ",/"); + if( t ) + { + sscanf(t, "%d", &amii_otherAPen); + if( t = strtok((char*)0, ",/") ) + sscanf(t, "%d", &amii_otherBPen); + } + } else if (match_varname(buf, "PENS", 4)) { + extern unsigned short amii_init_map[ AMII_MAXCOLORS ]; + int i; + char *t; + + for (i = 0, t = strtok(bufp, ",/"); + i < AMII_MAXCOLORS && t != (char *)0; + t = strtok((char *)0, ",/"), ++i) + { + sscanf(t, "%hx", &amii_init_map[i]); + } + amii_setpens( amii_numcolors = i ); + } else if (match_varname(buf, "FGPENS", 6)) { + extern int foreg[ AMII_MAXCOLORS ]; + int i; + char *t; + + for (i = 0, t = strtok(bufp, ",/"); + i < AMII_MAXCOLORS && t != (char *)0; + t = strtok((char *)0, ",/"), ++i) + { + sscanf(t, "%d", &foreg[i]); + } + } else if (match_varname(buf, "BGPENS", 6)) { + extern int backg[ AMII_MAXCOLORS ]; + int i; + char *t; + + for (i = 0, t = strtok(bufp, ",/"); + i < AMII_MAXCOLORS && t != (char *)0; + t = strtok((char *)0, ",/"), ++i) + { + sscanf(t, "%d", &backg[i]); + } #endif #ifdef USER_SOUNDS - } else if (match_varname(buf, "SOUNDDIR", 8)) { - sounddir = dupstr(bufp); - } else if (match_varname(buf, "SOUND", 5)) { - add_sound_mapping(bufp); + } else if (match_varname(buf, "SOUNDDIR", 8)) { + sounddir = dupstr(bufp); + } else if (match_varname(buf, "SOUND", 5)) { + add_sound_mapping(bufp); #endif #ifdef QT_GRAPHICS - /* These should move to wc_ options */ - } else if (match_varname(buf, "QT_TILEWIDTH", 12)) { - extern char *qt_tilewidth; - if (qt_tilewidth == NULL) - qt_tilewidth = dupstr(bufp); - } else if (match_varname(buf, "QT_TILEHEIGHT", 13)) { - extern char *qt_tileheight; - if (qt_tileheight == NULL) - qt_tileheight = dupstr(bufp); - } else if (match_varname(buf, "QT_FONTSIZE", 11)) { - extern char *qt_fontsize; - if (qt_fontsize == NULL) - qt_fontsize = dupstr(bufp); - } else if (match_varname(buf, "QT_COMPACT", 10)) { - extern int qt_compact_mode; - qt_compact_mode = atoi(bufp); -#endif - } else - return 0; - return 1; + /* These should move to wc_ options */ + } else if (match_varname(buf, "QT_TILEWIDTH", 12)) { + extern char *qt_tilewidth; + if (qt_tilewidth == NULL) + qt_tilewidth = dupstr(bufp); + } else if (match_varname(buf, "QT_TILEHEIGHT", 13)) { + extern char *qt_tileheight; + if (qt_tileheight == NULL) + qt_tileheight = dupstr(bufp); + } else if (match_varname(buf, "QT_FONTSIZE", 11)) { + extern char *qt_fontsize; + if (qt_fontsize == NULL) + qt_fontsize = dupstr(bufp); + } else if (match_varname(buf, "QT_COMPACT", 10)) { + extern int qt_compact_mode; + qt_compact_mode = atoi(bufp); +#endif + } else + return 0; + return 1; } #ifdef USER_SOUNDS diff --cc src/hack.c index ef8c90a52,5e14a3fab..ebf1ce891 --- a/src/hack.c +++ b/src/hack.c @@@ -1101,491 -1101,491 +1101,491 @@@ struct trap *desttrap; /* nonnull if an void domove() { - register struct monst *mtmp; - register struct rm *tmpr; - register xchar x,y; + register struct monst *mtmp; + register struct rm *tmpr; + register xchar x,y; - struct trap *trap = NULL; + struct trap *trap = (struct trap *)0; - 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); + 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 */ diff --cc src/mon.c index 9e511670b,5fd4f22dd..93fef1b0c --- a/src/mon.c +++ b/src/mon.c @@@ -146,186 -146,168 +146,187 @@@ make_corpse(mtmp,corpseflags register struct monst *mtmp; unsigned corpseflags; { - register struct permonst *mdat = mtmp->data; - int num; - struct obj *obj = (struct obj *)0; - int x = mtmp->mx, y = mtmp->my; - int mndx = monsndx(mdat); - unsigned corpstatflags = corpseflags; - boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0); - - switch(mndx) { - case PM_GRAY_DRAGON: - case PM_SILVER_DRAGON: + register struct permonst *mdat = mtmp->data; + int num; + struct obj *obj = (struct obj *)0; + struct obj* otmp = (struct obj*)0; + int x = mtmp->mx, y = mtmp->my; + int mndx = monsndx(mdat); + unsigned corpstatflags = corpseflags; + boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0); + + switch(mndx) { + case PM_GRAY_DRAGON: + case PM_SILVER_DRAGON: #if 0 /* DEFERRED */ - case PM_SHIMMERING_DRAGON: + case PM_SHIMMERING_DRAGON: #endif - case PM_RED_DRAGON: - case PM_ORANGE_DRAGON: - case PM_WHITE_DRAGON: - case PM_BLACK_DRAGON: - case PM_BLUE_DRAGON: - case PM_GREEN_DRAGON: - case PM_YELLOW_DRAGON: - /* Make dragon scales. This assumes that the order of the */ - /* dragons is the same as the order of the scales. */ - if (!rn2(mtmp->mrevived ? 20 : 3)) { - num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON; - obj = mksobj_at(num, x, y, FALSE, FALSE); - obj->spe = 0; - obj->cursed = obj->blessed = FALSE; - } - goto default_1; - - case PM_WHITE_UNICORN: - case PM_GRAY_UNICORN: - case PM_BLACK_UNICORN: - if (mtmp->mrevived && rn2(2)) { - if (canseemon(mtmp)) - pline("%s recently regrown horn crumbles to dust.", - s_suffix(Monnam(mtmp))); - } else { - obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE); - if (obj && mtmp->mrevived) obj->degraded_horn = 1; - } - goto default_1; - case PM_LONG_WORM: - (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE); - goto default_1; - case PM_VAMPIRE: - case PM_VAMPIRE_LORD: - /* include mtmp in the mkcorpstat() call */ - num = undead_to_corpse(mndx); - corpstatflags |= CORPSTAT_INIT; - obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); - obj->age -= 100; /* this is an *OLD* corpse */ - break; - case PM_KOBOLD_MUMMY: - case PM_DWARF_MUMMY: - case PM_GNOME_MUMMY: - case PM_ORC_MUMMY: - case PM_ELF_MUMMY: - case PM_HUMAN_MUMMY: - case PM_GIANT_MUMMY: - case PM_ETTIN_MUMMY: - case PM_KOBOLD_ZOMBIE: - case PM_DWARF_ZOMBIE: - case PM_GNOME_ZOMBIE: - case PM_ORC_ZOMBIE: - case PM_ELF_ZOMBIE: - case PM_HUMAN_ZOMBIE: - case PM_GIANT_ZOMBIE: - case PM_ETTIN_ZOMBIE: - num = undead_to_corpse(mndx); - corpstatflags |= CORPSTAT_INIT; - obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); - obj->age -= 100; /* this is an *OLD* corpse */ - break; - case PM_IRON_GOLEM: - num = d(2,6); - while (num--) - obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); - free_mname(mtmp); /* don't christen obj */ - break; - case PM_GLASS_GOLEM: - num = d(2,4); /* very low chance of creating all glass gems */ - while (num--) - obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE); - free_mname(mtmp); - break; - case PM_CLAY_GOLEM: - obj = mksobj_at(ROCK, x, y, FALSE, FALSE); - obj->quan = (long)(rn2(20) + 50); - obj->owt = weight(obj); - free_mname(mtmp); - break; - case PM_STONE_GOLEM: - corpstatflags &= ~CORPSTAT_INIT; - obj = mkcorpstat(STATUE, (struct monst *)0, - mdat, x, y, corpstatflags); - break; - case PM_WOOD_GOLEM: - num = d(2,4); - while(num--) { - obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE); - } - free_mname(mtmp); - break; - case PM_LEATHER_GOLEM: - num = d(2,4); - while(num--) - obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE); - free_mname(mtmp); - break; - case PM_GOLD_GOLEM: - /* Good luck gives more coins */ - obj = mkgold((long)(200 - rnl(101)), x, y); - free_mname(mtmp); - break; - case PM_PAPER_GOLEM: - num = rnd(4); - while (num--) - obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE); - free_mname(mtmp); - break; - default_1: - default: - if (mvitals[mndx].mvflags & G_NOCORPSE) - return (struct obj *)0; - else { - corpstatflags |= CORPSTAT_INIT; - /* preserve the unique traits of some creatures */ - obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0, - mdat, x, y, corpstatflags); - if (burythem) { + case PM_RED_DRAGON: + case PM_ORANGE_DRAGON: + case PM_WHITE_DRAGON: + case PM_BLACK_DRAGON: + case PM_BLUE_DRAGON: + case PM_GREEN_DRAGON: + case PM_YELLOW_DRAGON: + /* Make dragon scales. This assumes that the order of the */ + /* dragons is the same as the order of the scales. */ + if (!rn2(mtmp->mrevived ? 20 : 3)) { + num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON; + obj = mksobj_at(num, x, y, FALSE, FALSE); + obj->spe = 0; + obj->cursed = obj->blessed = FALSE; + } + goto default_1; + + case PM_WHITE_UNICORN: + case PM_GRAY_UNICORN: + case PM_BLACK_UNICORN: + if (mtmp->mrevived && rn2(2)) { + if (canseemon(mtmp)) + pline("%s recently regrown horn crumbles to dust.", + s_suffix(Monnam(mtmp))); + } else { + obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE); + if (obj && mtmp->mrevived) obj->degraded_horn = 1; + } + goto default_1; + case PM_LONG_WORM: + (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE); + goto default_1; + case PM_VAMPIRE: + case PM_VAMPIRE_LORD: + /* include mtmp in the mkcorpstat() call */ + num = undead_to_corpse(mndx); + corpstatflags |= CORPSTAT_INIT; + obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); + obj->age -= 100; /* this is an *OLD* corpse */ + break; + case PM_KOBOLD_MUMMY: + case PM_DWARF_MUMMY: + case PM_GNOME_MUMMY: + case PM_ORC_MUMMY: + case PM_ELF_MUMMY: + case PM_HUMAN_MUMMY: + case PM_GIANT_MUMMY: + case PM_ETTIN_MUMMY: + case PM_KOBOLD_ZOMBIE: + case PM_DWARF_ZOMBIE: + case PM_GNOME_ZOMBIE: + case PM_ORC_ZOMBIE: + case PM_ELF_ZOMBIE: + case PM_HUMAN_ZOMBIE: + case PM_GIANT_ZOMBIE: + case PM_ETTIN_ZOMBIE: + num = undead_to_corpse(mndx); + corpstatflags |= CORPSTAT_INIT; + obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); + obj->age -= 100; /* this is an *OLD* corpse */ + break; + case PM_IRON_GOLEM: + num = d(2,6); + while (num--) + obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); + free_mname(mtmp); /* don't christen obj */ + break; + case PM_GLASS_GOLEM: + num = d(2,4); /* very low chance of creating all glass gems */ + while (num--) + obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE); + free_mname(mtmp); + break; + case PM_CLAY_GOLEM: + obj = mksobj_at(ROCK, x, y, FALSE, FALSE); + obj->quan = (long)(rn2(20) + 50); + obj->owt = weight(obj); + free_mname(mtmp); + break; + case PM_STONE_GOLEM: + corpstatflags &= ~CORPSTAT_INIT; + obj = mkcorpstat(STATUE, (struct monst *)0, + mdat, x, y, corpstatflags); + break; + case PM_WOOD_GOLEM: + num = d(2,4); + while(num--) { + obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE); + } + free_mname(mtmp); + break; + case PM_LEATHER_GOLEM: + num = d(2,4); + while(num--) + obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE); + free_mname(mtmp); + break; + case PM_GOLD_GOLEM: + /* Good luck gives more coins */ + obj = mkgold((long)(200 - rnl(101)), x, y); + free_mname(mtmp); + break; + case PM_PAPER_GOLEM: + num = rnd(4); + while (num--) + obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE); + free_mname(mtmp); + break; + /* expired puddings will congeal into a large blob + like dragons, relies on the order remaining consistent */ + case PM_GRAY_OOZE: + case PM_BROWN_PUDDING: + case PM_GREEN_SLIME: + case PM_BLACK_PUDDING: + /* we have to do this here because most other places + * expect there to be an object coming back; not this one */ + obj = mksobj_at(GLOB_OF_BLACK_PUDDING - (PM_BLACK_PUDDING - mndx), + x, y, TRUE, FALSE); + + while ((obj && (otmp = obj_nexto(obj)) != (struct obj*)0)) { + pline("The %s coalesce.", makeplural(obj_typename(obj->otyp))); + obj = obj_meld(&obj, &otmp); + } + free_mname(mtmp); + return obj; + break; + default_1: + default: + if (mvitals[mndx].mvflags & G_NOCORPSE) + return (struct obj *)0; + else { + corpstatflags |= CORPSTAT_INIT; + /* preserve the unique traits of some creatures */ + obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0, + mdat, x, y, corpstatflags); + if (burythem) { - (void) bury_an_obj(obj); + boolean dealloc; + (void) bury_an_obj(obj, &dealloc); - newsym(x, y); + newsym(x, y); - return obj; + return (dealloc ? NULL : obj); - } - } - break; - } - /* All special cases should precede the G_NOCORPSE check */ - - /* if polymorph or undead turning has killed this monster, - prevent the same attack beam from hitting its corpse */ - if (context.bypasses) bypass_obj(obj); - - if (has_mname(mtmp)) - obj = oname(obj, MNAME(mtmp)); - - /* Avoid "It was hidden under a green mold corpse!" - * during Blind combat. An unseen monster referred to as "it" - * could be killed and leave a corpse. If a hider then hid - * underneath it, you could be told the corpse type of a - * monster that you never knew was there without this. - * The code in hitmu() substitutes the word "something" - * if the corpses obj->dknown is 0. - */ - if (Blind && !sensemon(mtmp)) obj->dknown = 0; - - stackobj(obj); - newsym(x, y); - return obj; + } + } + break; + } + /* All special cases should precede the G_NOCORPSE check */ + + /* if polymorph or undead turning has killed this monster, + prevent the same attack beam from hitting its corpse */ + if (context.bypasses) bypass_obj(obj); + + if (has_mname(mtmp)) + obj = oname(obj, MNAME(mtmp)); + + /* Avoid "It was hidden under a green mold corpse!" + * during Blind combat. An unseen monster referred to as "it" + * could be killed and leave a corpse. If a hider then hid + * underneath it, you could be told the corpse type of a + * monster that you never knew was there without this. + * The code in hitmu() substitutes the word "something" + * if the corpses obj->dknown is 0. + */ + if (Blind && !sensemon(mtmp)) obj->dknown = 0; + + stackobj(obj); + newsym(x, y); + return obj; } /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */ diff --cc src/vision.c index 50570c736,8abf63c79..64661718b --- a/src/vision.c +++ b/src/vision.c @@@ -2359,13 -2372,15 +2359,16 @@@ left_side(row, left_mark, right, limits int row, left_mark, right; char *limits; { - int left, left_edge, nrow, deeper, result; - register int i; + int left, left_edge, nrow, deeper, result; + register int i; register char *rowp = NULL; - char *row_min = NULL, *row_max = NULL; - int lim_min; + char *row_min = NULL; + char *row_max = NULL; + int lim_min; + #ifdef GCC_WARN + rowp = row_min = row_max = 0; + #endif nrow = row+step; deeper = good_row(nrow) && (!limits || (*limits >= *(limits+1))); if(!vis_func) {