Пример #1
0
int
seek_gold(object *monster)
{
    short i, j, rn, s;

    if ((rn = get_room_number(monster->row, monster->col)) < 0) {
	return 0;
    }
    for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) {
	for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) {
	    if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) {
		monster->m_flags |= CAN_FLIT;
		s = mon_can_go(monster, i, j);
		monster->m_flags &= (~CAN_FLIT);
		if (s) {
		    move_mon_to(monster, i, j);
		    monster->m_flags |= ASLEEP;
		    monster->m_flags &= (~(WAKENS | SEEKS_GOLD));
		    return 1;
		}
		monster->m_flags &= (~SEEKS_GOLD);
		monster->m_flags |= CAN_FLIT;
		mv_monster(monster, i, j);
		monster->m_flags &= (~CAN_FLIT);
		monster->m_flags |= SEEKS_GOLD;
		return 1;
	    }
	}
    }
    return 0;
}
Пример #2
0
/* 
 * Steal gold coins only.  Leprechauns don't care for lesser coins.
 */
void stealgold(struct monst *mtmp)
{
	struct obj *fgold = gold_at(level, u.ux, u.uy);
	struct obj *ygold;
	long tmp;

        /* skip lesser coins on the floor */        
        while (fgold && fgold->otyp != GOLD_PIECE) fgold = fgold->nexthere; 

        /* Do you have real gold? */
        ygold = findgold(invent);

	if (fgold && ( !ygold || fgold->quan > ygold->quan || !rn2(5))) {
            obj_extract_self(fgold);
	    add_to_minv(mtmp, fgold);
	    newsym(u.ux, u.uy);
	    pline("%s quickly snatches some gold from between your %s!",
		    Monnam(mtmp), makeplural(body_part(FOOT)));
	    if (!ygold || !rn2(5)) {
		if (!tele_restrict(mtmp)) rloc(level, mtmp, FALSE);
		monflee(mtmp, 0, FALSE, FALSE);
	    }
	} else if (ygold) {
            const int gold_price = objects[GOLD_PIECE].oc_cost;
	    tmp = (somegold(money_cnt(invent)) + gold_price - 1) / gold_price;
	    tmp = min(tmp, ygold->quan);
            if (tmp < ygold->quan) ygold = splitobj(ygold, tmp);
            freeinv(ygold);
            add_to_minv(mtmp, ygold);
	    pline("Your purse feels lighter.");
	    if (!tele_restrict(mtmp)) rloc(level, mtmp, FALSE);
	    monflee(mtmp, 0, FALSE, FALSE);
	    iflags.botl = 1;
	}
}
Пример #3
0
struct obj *mkgold(long amount, struct level *lev, int x, int y)
{
    struct obj *gold = gold_at(lev, x, y);

    if (amount <= 0L)
	amount = (long)(1 + rnd(level_difficulty(&lev->z)+2) * rnd(30));
    if (gold) {
	gold->quan += amount;
    } else {
	gold = mksobj_at(GOLD_PIECE, lev, x, y, TRUE, FALSE);
	gold->quan = amount;
    }
    gold->owt = weight(gold);
    return gold;
}
Пример #4
0
Char loc_symbol(Short x, Short y) // Equivalent of "news0"
{
  obj_t *otmp;
  trap_t *ttmp;
  UChar cell_type;
  Char c;
  Boolean blind = Blind;

  if (OUT_OF_BOUNDS(x,y)) return ' ';
  cell_type = get_cell_type(floor_info[x][y]);
  if (!get_cell_seen(floor_info[x][y]))
    c = ' ';
  else if (cell_type == POOL)
    c = POOL_SYM;
  else if (!blind && (otmp = obj_at(x,y)))
    c = otmp->olet;
  else if (!blind && gold_at(x,y))
    c = GOLD_SYM;
  else if (x == xupstair && y == yupstair)
    c = UPSTAIR_SYM;
  else if (x == xdnstair && y == ydnstair)
    c = DOWNSTAIR_SYM;
  else if ((ttmp = trap_at(x,y)) && get_trap_seen(ttmp->trap_info))
    c = TRAP_SYM;
  else switch(cell_type) {
  case HWALL: c = HWALL_SYM;  break;
  case VWALL: c = VWALL_SYM;  break;
  case CORR:  c = CORR_SYM;   break;
  case SCORR: case SDOOR:
    c = floor_symbol[x][y];	/* %% wrong after killing mimic ! */
    break;
  case LDOOR: case DOOR:
    c = DOOR_SYM;
    break;
  case ROOM:
    // the 'blind' here seems strange to me:
    if (get_cell_lit(floor_info[x][y]) || cansee(x,y) || blind) c = ROOM_SYM;
    else c = ' ';
    break;
  default:
    c = ERRCHAR;
  }
  return c;
}
Пример #5
0
void
dosounds(void)
{
    struct mkroom *sroom;
    int hallu, vx, vy;
    struct monst *mtmp;

    if (!canhear() || Engulfed || Underwater)
        return;

    hallu = Hallucination ? 1 : 0;

    if (has_terrain(level, FOUNTAIN) && !rn2(400)) {
        static const char *const fountain_msg[4] = {
            "bubbling water.",
            "water falling on coins.",
            "the splashing of a naiad.",
            "a soda fountain!",
        };
        You_hear("%s", fountain_msg[rn2(3) + hallu]);
    }

    if (has_terrain(level, SINK) && !rn2(300)) {
        static const char *const sink_msg[3] = {
            "a slow drip.",
            "a gurgling noise.",
            "dishes being washed!",
        };
        You_hear("%s", sink_msg[rn2(2) + hallu]);
    }

    if (search_special(level, COURT) && !rn2(200)) {
        static const char *const throne_msg[4] = {
            "the tones of courtly conversation.",
            "a sceptre pounded in judgment.",
            "Someone shouts \"Off with %s head!\"",
            "Queen Beruthiel's cats!",
        };
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->msleeping || is_lord(mtmp->data) ||
                 is_prince(mtmp->data)) && !is_animal(mtmp->data) &&
                mon_in_room(mtmp, COURT)) {
                /* finding one is enough, at least for now */
                int which = rn2(3) + hallu;

                if (which != 2)
                    You_hear("%s", throne_msg[which]);
                else
                    pline(throne_msg[2], uhis());
                return;
            }
        }
    }
    if (search_special(level, SWAMP) && !rn2(200)) {
        static const char *const swamp_msg[3] = {
            "You hear mosquitoes!",
            "You smell marsh gas!",     /* so it's a smell... */
            "You hear Donald Duck!",
        };
        pline("%s", swamp_msg[rn2(2) + hallu]);
        return;
    }
    if ((sroom = search_special(level, VAULT)) && !rn2(200)) {
        if (gd_sound())
            switch (rn2(2) + hallu) {
            case 1:{
                    boolean gold_in_vault = FALSE;

                    for (vx = sroom->lx; vx <= sroom->hx; vx++)
                        for (vy = sroom->ly; vy <= sroom->hy; vy++)
                            if (gold_at(level, vx, vy))
                                gold_in_vault = TRUE;
                    if (vault_occupied(u.urooms) !=
                        (ROOM_INDEX(sroom) + ROOMOFFSET)) {
                        if (gold_in_vault)
                            You_hear(!hallu ? "someone counting money." :
                                     "the quarterback calling the play.");
                        else
                            You_hear("someone searching.");
                        break;
                    }
                    /* fall into... (yes, even for hallucination) */
                }
            case 0:
                You_hear("the footsteps of a guard on patrol.");
                break;
            case 2:
                You_hear("Ebenezer Scrooge!");
                break;
            }
        return;
    }
    if (search_special(level, BEEHIVE) && !rn2(200)) {
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->data->mlet == S_ANT && is_flyer(mtmp->data)) &&
                mon_in_room(mtmp, BEEHIVE)) {
                switch (rn2(2) + hallu) {
                case 0:
                    You_hear("a low buzzing.");
                    break;
                case 1:
                    You_hear("an angry drone.");
                    break;
                case 2:
                    You_hear("bees in your %sbonnet!",
                             uarmh ? "" : "(nonexistent) ");
                    break;
                }
                return;
            }
        }
    }
    if (search_special(level, MORGUE) && !rn2(200)) {
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if (is_undead(mtmp->data) && mon_in_room(mtmp, MORGUE)) {
                switch (rn2(2) + hallu) {
                case 1:
                    if (!strcmp(body_part(HAIR), "hair")) {
                        pline("The %s on the back of your %s stands up.",
                              body_part(HAIR), body_part(NECK));
                        break;
                    }
                    /* fall through */
                case 2:
                    if (!strcmp(body_part(HAIR), "hair")) {
                        pline("The %s on your %s seems to stand up.",
                              body_part(HAIR), body_part(HEAD));
                        break;
                    }
                    /* fall through */
                case 0:
                    pline("You suddenly realize it is unnaturally quiet.");
                    break;
                }
                return;
            }
        }
    }
    if (search_special(level, BARRACKS) && !rn2(200)) {
        static const char *const barracks_msg[4] = {
            "blades being honed.",
            "loud snoring.",
            "dice being thrown.",
            "General MacArthur!",
        };
        int count = 0;

        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if (is_mercenary(mtmp->data) && mon_in_room(mtmp, BARRACKS) &&
                /* sleeping implies not-yet-disturbed (usually) */
                (mtmp->msleeping || ++count > 5)) {
                You_hear("%s", barracks_msg[rn2(3) + hallu]);
                return;
            }
        }
    }
    if (search_special(level, ZOO) && !rn2(200)) {
        static const char *const zoo_msg[3] = {
            "a sound reminiscent of an elephant stepping on a peanut.",
            "a sound reminiscent of a seal barking.",
            "Doctor Dolittle!",
        };
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->msleeping || is_animal(mtmp->data)) &&
                mon_in_room(mtmp, ZOO)) {
                You_hear("%s", zoo_msg[rn2(2) + hallu]);
                return;
            }
        }
    }
    if ((sroom = search_special(level, ANY_SHOP)) && !rn2(200)) {
        if (tended_shop(sroom) &&
            !strchr(u.ushops, ROOM_INDEX(sroom) + ROOMOFFSET)) {
            static const char *const shop_msg[3] = {
                "someone cursing shoplifters.",
                "the chime of a cash register.",
                "Neiman and Marcus arguing!",
            };
            You_hear("%s", shop_msg[rn2(2) + hallu]);
        }
        return;
    }
    if (search_special(level, DELPHI) && !rn2(400)) {
        /* make sure the Oracle is still here */
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
            if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_POTTER])
                break;
        /* and don't produce silly effects when he's clearly visible */
        if (mtmp && (hallu || !canseemon(mtmp))) {
            static const char *const ora_msg[5] = {
                "political commentary.",
                "convulsive ravings about WLAN controllers.",
                "an Adirondack woodsman.",
                "someone ask you for your punchcards.", /* if(hallucinating) */
                "loud praise for Netgear devices." /* if(hallucinating) */
            };
            You_hear("%s", ora_msg[rn2(3) + hallu * 2]);
        }
        return;
    }
}
Пример #6
0
void dosounds(void)
{
    struct mkroom *sroom;
    int hallu, vx, vy;
    struct monst *mtmp;

    if (!flags.soundok || u.uswallow || Underwater) return;

    if (level->sounds && !rn2(level->sounds->freq)) {
	int idx = rn2(level->sounds->n_sounds);
	char *buf;
	struct lvl_sound_bite *snd = &level->sounds->sounds[idx];
	buf = string_subst(snd->msg);
	switch (snd->flags) {
	default:
	case LVLSND_HEARD:	You_hear(buf);			break;
	case LVLSND_PLINED:	pline(buf);			break;
	case LVLSND_VERBAL:	verbalize(buf);			break;
	case LVLSND_FELT:	pline("You feel %s", buf);	break;
	}
    }

    hallu = Hallucination ? 1 : 0;

    if (level->flags.nfountains && !rn2(400)) {
	static const char * const fountain_msg[4] = {
		"bubbling water.",
		"water falling on coins.",
		"the splashing of a naiad.",
		"a soda fountain!",
	};
	You_hear(fountain_msg[rn2(3)+hallu]);
    }

    if (level->flags.nsinks && !rn2(300)) {
	static const char * const sink_msg[3] = {
		"a slow drip.",
		"a gurgling noise.",
		"dishes being washed!",
	};
	You_hear(sink_msg[rn2(2)+hallu]);
    }

    if (level->flags.has_court && !rn2(200)) {
	static const char * const throne_msg[4] = {
		"the tones of courtly conversation.",
		"a sceptre pounded in judgment.",
		"Someone shouts \"Off with %s head!\"",
		"Queen Beruthiel's cats!",
	};
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if ((mtmp->msleeping ||
			is_lord(mtmp->data) || is_prince(mtmp->data)) &&
		!is_animal(mtmp->data) &&
		mon_in_room(mtmp, COURT)) {
		/* finding one is enough, at least for now */
		int which = rn2(3)+hallu;

		if (which != 2) You_hear(throne_msg[which]);
		else		pline(throne_msg[2], uhis());
		return;
	    }
	}
    }
    if (level->flags.has_garden && !rn2(200)) {
	static const char * const garden_msg[4] = {
		"crickets chirping.",
		"birds singing.",
		"grass growing!",
		"wind in the willows!",
	};
	You_hear(garden_msg[rn2(2) + 2 * hallu]);
	return;
    }
    if (level->flags.has_swamp && !rn2(200)) {
	static const char * const swamp_msg[3] = {
		"You hear mosquitoes!",
		"You smell marsh gas!",	/* so it's a smell...*/
		"You hear Donald Duck!",
	};
	pline(swamp_msg[rn2(2)+hallu]);
	return;
    }
    if (level->flags.has_vault && !rn2(200)) {
	if (!(sroom = search_special(level, VAULT))) {
	    /* strange ... */
	    level->flags.has_vault = 0;
	    return;
	}
	if (gd_sound())
	    switch (rn2(2)+hallu) {
		case 1: {
		    boolean gold_in_vault = FALSE;

		    for (vx = sroom->lx;vx <= sroom->hx; vx++)
			for (vy = sroom->ly; vy <= sroom->hy; vy++)
			    if (gold_at(level, vx, vy))
				gold_in_vault = TRUE;
		    if (vault_occupied(u.urooms) !=
			 (ROOM_INDEX(sroom) + ROOMOFFSET))
		    {
			if (gold_in_vault)
			    You_hear(!hallu ? "someone counting money." :
				"the quarterback calling the play.");
			else
			    You_hear("someone searching.");
			break;
		    }
		    /* fall into... (yes, even for hallucination) */
		}
		case 0:
		    You_hear("the footsteps of a guard on patrol.");
		    break;
		case 2:
		    You_hear("Ebenezer Scrooge!");
		    break;
	    }
	return;
    }
    if (level->flags.has_beehive && !rn2(200)) {
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if ((mtmp->data->mlet == S_ANT && is_flyer(mtmp->data)) &&
		mon_in_room(mtmp, BEEHIVE)) {
		switch (rn2(2)+hallu) {
		    case 0:
			You_hear("a low buzzing.");
			break;
		    case 1:
			You_hear("an angry drone.");
			break;
		    case 2:
			You_hear("bees in your %sbonnet!",
			    uarmh ? "" : "(nonexistent) ");
			break;
		}
		return;
	    }
	}
    }
    if (level->flags.has_lemurepit && !rn2(20)) {
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if (mtmp->data == &mons[PM_LEMURE] &&
		mon_in_room(mtmp, LEMUREPIT)) {
		if (hallu) {
		    switch (rn2(3)) {
			case 0:
			    You_hear("screams of lust!");
			    break;
			case 1:
			    You_hear("the crack of your mistress's whip!");
			    break;
			case 2:
			    You_hear("a weeping willow!");
			    break;
		    }
		} else {
		    switch (rn2(6)) {
			case 0:
			    You_hear("the crack of a barbed whip!");
			    break;
			case 1:
			    You_hear("the screams of tortured souls!");
			    break;
			case 2:
			    You_hear("a wail of eternal anguish!");
			    break;
			case 3:
			    You_hear("diabolical laughter!");
			    break;
			case 4:
			    You_hear("cries of repentance!");
			    break;
			case 5:
			    You_hear("futile pleas for mercy!");
			    break;
		    }
		}
		return;
	    }
	}
    }
    if (level->flags.has_morgue && !rn2(200)) {
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if (is_undead(mtmp->data) &&
		mon_in_room(mtmp, MORGUE)) {
		switch (rn2(2)+hallu) {
		    case 1:
			if (!strcmp(body_part(HAIR), "hair")) {
			    pline("The %s on the back of your %s stands up.",
				body_part(HAIR), body_part(NECK));
			    break;
			}
			/* fall through */
		    case 2:
			if (!strcmp(body_part(HAIR), "hair")) {
			    pline("The %s on your %s seems to stand up.",
				    body_part(HAIR), body_part(HEAD));
			    break;
			}
			/* fall through */
		    case 0:
			pline("You suddenly realize it is unnaturally quiet.");
			break;
		}
		return;
	    }
	}
    }
    if (level->flags.has_barracks && !rn2(200)) {
	static const char * const barracks_msg[4] = {
		"blades being honed.",
		"loud snoring.",
		"dice being thrown.",
		"General MacArthur!",
	};
	int count = 0;

	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if (is_mercenary(mtmp->data) &&
		mon_in_room(mtmp, BARRACKS) &&
		/* sleeping implies not-yet-disturbed (usually) */
		(mtmp->msleeping || ++count > 5)) {
		You_hear(barracks_msg[rn2(3)+hallu]);
		return;
	    }
	}
    }
    if (level->flags.has_zoo && !rn2(200)) {
	static const char * const zoo_msg[3] = {
		"a sound reminiscent of an elephant stepping on a peanut.",
		"a sound reminiscent of a seal barking.",
		"Doctor Dolittle!",
	};
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if ((mtmp->msleeping || is_animal(mtmp->data)) &&
		    mon_in_room(mtmp, ZOO)) {
		You_hear(zoo_msg[rn2(2)+hallu]);
		return;
	    }
	}
    }
    if (level->flags.has_shop && !rn2(200)) {
	if (!(sroom = search_special(level, ANY_SHOP))) {
	    /* strange... */
	    level->flags.has_shop = 0;
	    return;
	}
	if (tended_shop(sroom) &&
		!strchr(u.ushops, ROOM_INDEX(sroom) + ROOMOFFSET)) {
	    static const char * const shop_msg[3] = {
		    "someone cursing shoplifters.",
		    "the chime of a cash register.",
		    "Neiman and Marcus arguing!",
	    };
	    You_hear(shop_msg[rn2(2)+hallu]);
	}
	return;
    }
    if (Is_oracle_level(&u.uz) && !rn2(400)) {
	/* make sure the Oracle is still here */
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
	    if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_ORACLE])
		break;
	/* and don't produce silly effects when she's clearly visible */
	if (mtmp && (hallu || !canseemon(level, mtmp))) {
	    static const char * const ora_msg[5] = {
		    "a strange wind.",		/* Jupiter at Dodona */
		    "convulsive ravings.",	/* Apollo at Delphi */
		    "snoring snakes.",		/* AEsculapius at Epidaurus */
		    "someone say \"No more woodchucks!\"",
		    "a loud ZOT!"		/* both rec.humor.oracle */
	    };
	    You_hear(ora_msg[rn2(3)+hallu*2]);
	}
	return;
    }
    if (!Is_blackmarket(&u.uz) && at_dgn_entrance(&u.uz, "One-eyed Sam's Market") &&
	!rn2(200)) {
	static const char *blkmar_msg[3] = {
	    "You hear someone complaining about the prices.",
	    "Somebody whispers: \"Food rations? Only 900 zorkmids.\"",
	    "You feel like searching for more gold.",
	};
	pline(blkmar_msg[rn2(2)+hallu]);
    }
}
Пример #7
0
/*
 * return  1: guard moved,  0: guard didn't,  -1: let m_move do it,  -2: died
 */
int
gd_move(struct monst *grd)
{
    int x, y, nx, ny, m, n;
    int dx, dy, gx = 0, gy = 0, fci;
    uchar typ;
    struct fakecorridor *fcp;
    struct egd *egrd = EGD(grd);
    struct rm *crm;
    boolean goldincorridor = FALSE, u_in_vault =
        vault_occupied(u.urooms) ? TRUE : FALSE, grd_in_vault =
        *in_rooms(level, grd->mx, grd->my, VAULT) ? TRUE : FALSE;
    boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
    long umoney = money_cnt(invent);
    boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
    boolean see_guard;

    if (!on_level(&(egrd->gdlevel), &u.uz))
        return -1;
    nx = ny = m = n = 0;
    if (!u_in_vault && !grd_in_vault)
        wallify_vault(grd);
    if (!grd->mpeaceful) {
        if (semi_dead) {
            egrd->gddone = 1;
            goto newpos;
        }
        if (!u_in_vault &&
            (grd_in_vault ||
             (in_fcorridor(grd, grd->mx, grd->my) &&
              !in_fcorridor(grd, u.ux, u.uy)))) {
            rloc(grd, FALSE);
            wallify_vault(grd);
            clear_fcorr(grd, TRUE);
            goto letknow;
        }
        if (!in_fcorridor(grd, grd->mx, grd->my))
            clear_fcorr(grd, TRUE);
        return -1;
    }
    if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
        return -1;      /* teleported guard - treat as monster */
    if (egrd->fcend == 1) {
        if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
            if (egrd->warncnt == 3)
                verbalize("I repeat, %sfollow me!",
                          u_carry_gold ? (!umoney ?
                                          "drop that hidden money and " :
                                          "drop that money and ") : "");
            if (egrd->warncnt == 7) {
                m = grd->mx;
                n = grd->my;
                verbalize("You've been warned, knave!");
                mnexto(grd);
                level->locations[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                msethostility(grd, TRUE, FALSE);
                return -1;
            }
            /* not fair to get mad when (s)he's fainted or paralyzed */
            if (!u_helpless(hm_all))
                egrd->warncnt++;
            return 0;
        }

        if (!u_in_vault) {
            if (u_carry_gold) { /* player teleported */
                m = grd->mx;
                n = grd->my;
                rloc(grd, FALSE);
                level->locations[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                msethostility(grd, TRUE, FALSE);
            letknow:
                if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
                    You_hear("the shrill sound of a guard's whistle.");
                else
                    pline(um_dist(grd->mx, grd->my, 2) ?
                          "You see an angry guard approaching." :
                          "You are confronted by an angry guard.");
                return -1;
            } else {
                verbalize("Well, begone.");
                wallify_vault(grd);
                egrd->gddone = 1;
                goto cleanup;
            }
        }
    }

    if (egrd->fcend > 1) {
        if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
            !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
            level->locations[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ ==
            egrd->fakecorr[0].ftyp) {
            if (canseemon(grd)) {
                pline("%s, confused, disappears.", Monnam(grd));
                disappear_msg_seen = TRUE;
            }
            goto cleanup;
        }
        if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy) ||
                             /* cover a 'blind' spot */
                             (egrd->fcend > 1 && u_in_vault))) {
            if (!grd->mx) {
                restfakecorr(grd);
                return -2;
            }
            if (egrd->warncnt < 6) {
                egrd->warncnt = 6;
                verbalize("Drop all your gold, scoundrel!");
                return 0;
            } else {
                verbalize("So be it, rogue!");
                msethostility(grd, TRUE, FALSE);
                return -1;
            }
        }
    }
    for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
        if (gold_at(level, egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
            m = egrd->fakecorr[fci].fx;
            n = egrd->fakecorr[fci].fy;
            goldincorridor = TRUE;
        }
    if (goldincorridor && !egrd->gddone) {
        boolean yours = FALSE;

        x = grd->mx;
        y = grd->my;
        if (m == u.ux && n == u.uy) {
            struct obj *gold = gold_at(level, m, n);

            yours = TRUE;
            /* Grab the gold from between the hero's feet.  */
            obj_extract_self(gold);
            add_to_minv(grd, gold);
            newsym(m, n);
        } else if (m == x && n == y) {
            mpickgold(grd);     /* does a newsym */
        } else {
            /* just for insurance... */
            if (MON_AT(level, m, n) && m != grd->mx && n != grd->my) {
                verbalize("Out of my way, scum!");
                rloc(m_at(level, m, n), FALSE);
            }
            remove_monster(level, grd->mx, grd->my);
            newsym(grd->mx, grd->my);
            place_monster(grd, m, n);
            mpickgold(grd);     /* does a newsym */
        }
        if (cansee(m, n)) {
            if (yours) {
                pline("%s%s picks up the gold.", Monnam(grd),
                      grd->mpeaceful ? " calms down and" : "");
            } else {
                pline("%s picks up some gold.", Monnam(grd));
            }
        }
        if (x != grd->mx || y != grd->my) {
            remove_monster(level, grd->mx, grd->my);
            newsym(grd->mx, grd->my);
            place_monster(grd, x, y);
            newsym(x, y);
        }
        if (!grd->mpeaceful)
            return -1;
        else {
            egrd->warncnt = 5;
            return 0;
        }
    }
    if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
        if (!egrd->gddone && !rn2(10))
            verbalize("Move along!");
        restfakecorr(grd);
        return 0;       /* didn't move */
    }
    x = grd->mx;
    y = grd->my;

    if (u_in_vault)
        goto nextpos;

    /* look around (hor & vert only) for accessible places */
    for (nx = x - 1; nx <= x + 1; nx++)
        for (ny = y - 1; ny <= y + 1; ny++) {
            if ((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {

                typ = (crm = &level->locations[nx][ny])->typ;
                if (!IS_STWALL(typ) && !IS_POOL(typ)) {

                    if (in_fcorridor(grd, nx, ny))
                        goto nextnxy;

                    if (*in_rooms(level, nx, ny, VAULT))
                        continue;

                    /* seems we found a good place to leave him alone */
                    egrd->gddone = 1;
                    if (ACCESSIBLE(typ))
                        goto newpos;
                    crm->typ = (typ == SCORR) ? CORR : DOOR;
                    if (crm->typ == DOOR)
                        crm->doormask = D_NODOOR;
                    goto proceed;
                }
            }
        nextnxy:;
        }
nextpos:
    nx = x;
    ny = y;
    gx = egrd->gdx;
    gy = egrd->gdy;
    dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
    dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
    if (abs(gx - x) >= abs(gy - y))
        nx += dx;
    else
        ny += dy;

    while ((typ = (crm = &level->locations[nx][ny])->typ) != 0) {
        /* in view of the above we must have IS_WALL(typ) or typ == POOL */
        /* must be a wall here */
        if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ) &&
            IS_ROOM(level->locations[nx + nx - x][ny + ny - y].typ)) {
            crm->typ = DOOR;
            crm->doormask = D_NODOOR;
            goto proceed;
        }
        if (dy && nx != x) {
            nx = x;
            ny = y + dy;
            continue;
        }
        if (dx && ny != y) {
            ny = y;
            nx = x + dx;
            dy = 0;
            continue;
        }
        /* I don't like this, but ... */
        if (IS_ROOM(typ)) {
            crm->typ = DOOR;
            crm->doormask = D_NODOOR;
            goto proceed;
        }
        break;
    }
    crm->typ = CORR;
proceed:
    unblock_point(nx, ny);      /* doesn't block light */
    if (cansee(nx, ny))
        newsym(nx, ny);

    if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) {
        fcp = &(egrd->fakecorr[egrd->fcend]);
        if (egrd->fcend++ == FCSIZ)
            panic("fakecorr overflow");
        fcp->fx = nx;
        fcp->fy = ny;
        fcp->ftyp = typ;
    } else if (!egrd->gddone) {
        /* We're stuck, so try to find a new destination. */
        if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy) ||
            (egrd->gdx == gx && egrd->gdy == gy)) {
            pline("%s, confused, disappears.", Monnam(grd));
            disappear_msg_seen = TRUE;
            goto cleanup;
        } else
            goto nextpos;
    }
newpos:
    if (egrd->gddone) {
        /* The following is a kludge.  We need to keep the guard around in order
           to be able to make the fake corridor disappear as the player moves
           out of it, but we also need the guard out of the way.  We send the
           guard to never-never land.  We set ogx ogy to mx my in order to avoid
           a check at the top of this function.  At the end of the process, the
           guard is killed in restfakecorr().  */
    cleanup:
        x = grd->mx;
        y = grd->my;

        see_guard = canspotmon(grd);
        wallify_vault(grd);
        remove_monster(level, grd->mx, grd->my);
        newsym(grd->mx, grd->my);
        grd->mx = COLNO;
        grd->my = ROWNO;
        egrd->ogx = grd->mx;
        egrd->ogy = grd->my;
        restfakecorr(grd);
        if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
            if (!disappear_msg_seen && see_guard)
                pline("Suddenly, %s disappears.", noit_mon_nam(grd));
            return 1;
        }
        return -2;
    }
    egrd->ogx = grd->mx;        /* update old positions */
    egrd->ogy = grd->my;
    remove_monster(level, grd->mx, grd->my);
    place_monster(grd, nx, ny);
    newsym(grd->mx, grd->my);
    restfakecorr(grd);
    return 1;
}
Пример #8
0
static void
wallify_vault(struct monst *grd)
{
    int x, y, typ;
    int vlt = EGD(grd)->vroom;
    char tmp_viz;
    xchar lox = level->rooms[vlt].lx - 1, hix = level->rooms[vlt].hx + 1, loy =
        level->rooms[vlt].ly - 1, hiy = level->rooms[vlt].hy + 1;
    struct monst *mon;
    struct obj *gold;
    struct trap *trap;
    boolean fixed = FALSE;
    boolean movedgold = FALSE;

    for (x = lox; x <= hix; x++)
        for (y = loy; y <= hiy; y++) {
            /* if not on the room boundary, skip ahead */
            if (x != lox && x != hix && y != loy && y != hiy)
                continue;

            if (!IS_WALL(level->locations[x][y].typ) &&
                !in_fcorridor(grd, x, y)) {
                if ((mon = m_at(level, x, y)) != 0 && mon != grd) {
                    if (mon->mtame)
                        yelp(mon);
                    rloc(mon, FALSE);
                }
                if ((gold = gold_at(level, x, y)) != 0) {
                    move_gold(gold, EGD(grd)->vroom);
                    movedgold = TRUE;
                }
                if ((trap = t_at(level, x, y)) != 0)
                    deltrap(level, trap);
                if (x == lox)
                    typ = (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
                else if (x == hix)
                    typ = (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
                else    /* not left or right side, must be top or bottom */
                    typ = HWALL;
                level->locations[x][y].typ = typ;
                level->locations[x][y].doormask = 0;
                /* 
                 * hack: player knows walls are restored because of the
                 * message, below, so show this on the screen.
                 */
                tmp_viz = viz_array[y][x];
                viz_array[y][x] = IN_SIGHT | COULD_SEE;
                newsym(x, y);
                viz_array[y][x] = tmp_viz;
                block_point(x, y);
                fixed = TRUE;
            }
        }

    if (movedgold || fixed) {
        if (mon_visible(grd))
            pline("%s whispers an incantation.", Monnam(grd));
        else
            You_hear("a %s chant.", in_fcorridor(grd, grd->mx, grd->my)
                     ? "nearby" : "distant");
        if (movedgold)
            pline("A mysterious force moves the gold into the vault.");
        if (fixed)
            pline("The damaged vault's walls are magically restored!");
    }
}