void mpickgold(struct monst *mtmp) { struct gen *gold; gold = g_at(mtmp->mx, mtmp->my, fgold); while(gold != 0) { mtmp->mgold += gold->gflag; freegold(gold); if(levl[(int)mtmp->mx][(int)mtmp->my].scrsym == '$') { newsym(mtmp->mx, mtmp->my); } gold = g_at(mtmp->mx, mtmp->my, fgold); } }
void stealgold(struct monst *mtmp) { struct gold *gold = g_at(u.ux, u.uy); long tmp; if(gold && ( !u.ugold || gold->amount > u.ugold || !rn2(5))) { mtmp->mgold += gold->amount; freegold(gold); if(Invisible) newsym(u.ux, u.uy); pline("%s quickly snatches some gold from between your feet!", Monnam(mtmp)); if(!u.ugold || !rn2(5)) { rloc(mtmp); mtmp->mflee = 1; } } else if(u.ugold) { u.ugold -= (tmp = somegold()); pline("Your purse feels lighter."); mtmp->mgold += tmp; rloc(mtmp); mtmp->mflee = 1; flags.botl = 1; } }
static int goldincorridor() { int fci; for(fci = EGD->fcbeg; fci < EGD->fcend; fci++) if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy)) return(1); return(0); }
struct obj * mkgold(long int amount, int x, int y) { register struct obj *gold = g_at(x,y); if (amount <= 0L) amount = (long)(1 + rnd(level_difficulty()+2) * rnd(30)); if (gold) { gold->quan += amount; } else { gold = mksobj_at(GOLD_PIECE, x, y, TRUE, FALSE); gold->quan = amount; } gold->owt = weight(gold); return (gold); }
void mkgold(long num, int x, int y) { struct gold *gold; long amount = (num ? num : 1 + (rnd(dlevel+2) * rnd(30))); if((gold = g_at(x,y))) gold->amount += amount; else { gold = newgold(); gold->ngold = fgold; gold->gx = x; gold->gy = y; gold->amount = amount; fgold = gold; /* do sth with display? */ } }
void stealgold (struct monst *mtmp) { struct obj *gold = g_at(u.ux, u.uy); long tmp; if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) { mtmp->mgold += gold->quan; delobj(gold); newsym(u.ux, u.uy); message_monster(MSG_M_QUICKLY_SNATCHES_GOLD_FROM_BEETWEEN_YOUR_LEGS, mtmp); if(!u.ugold || !rn2(5)) { if (!tele_restrict(mtmp)) (void) rloc(mtmp, false); /* do not set mtmp->mavenge here; gold on the floor is fair game */ monflee(mtmp, 0, false, false); } } else if(u.ugold) { u.ugold -= (tmp = somegold()); Your("purse feels lighter."); mtmp->mgold += tmp; if (!tele_restrict(mtmp)) (void) rloc(mtmp, false); mtmp->mavenge = 1; monflee(mtmp, 0, false, false); } }
void dosounds() { register xchar hallu; register struct mkroom *sroom; register int vx, vy; hallu = Hallucination ? 1 : 0; if(!flags.soundok || u.uswallow || Underwater) return; if (level.flags.nfountains && !rn2(400)) { static const char *fountain_msg[4] = { "hear bubbling water.", "hear water falling on coins.", "hear the splashing of a naiad.", "hear a soda fountain!", }; You("%s",fountain_msg[rn2(3)+hallu]); } #ifdef SINK if (level.flags.nsinks && !rn2(300)) { static const char *sink_msg[3] = { "hear a slow drip.", "hear a gurgling noise.", "hear dishes being washed!", }; You("%s",sink_msg[rn2(2)+hallu]); } #endif if (level.flags.has_court && !rn2(200)) { static const char *throne_msg[4] = { "hear the tones of courtly conversation.", "hear a sceptre pounded in judgment.", "Someone shouts \"Off with %s head!\"", "hear Queen Beruthiel's cats!", }; int which = rn2(3)+hallu; if (which != 2) You("%s",throne_msg[which]); else pline(throne_msg[2], his[flags.female]); return; } if (level.flags.has_swamp && !rn2(200)) { static const char *swamp_msg[3] = { "hear mosquitoes!", "smell marsh gas!", /* so it's a smell...*/ "hear Donald Duck!", }; You("%s",swamp_msg[rn2(2)+hallu]); return; } if (level.flags.has_vault && !rn2(200)) { if (!(sroom = search_special(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 (g_at(vx, vy)) gold_in_vault = TRUE; if (vault_occupied(u.urooms) != (ROOM_INDEX(sroom) + ROOMOFFSET)) { if (gold_in_vault) You(!hallu ? "hear someone counting money." : "hear 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)) { 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_morgue && !rn2(200)) { switch (rn2(2)+hallu) { case 0: You("suddenly realize it is unnaturally quiet."); break; case 1: pline("The hair on the back of your %s stands up.", body_part(NECK)); break; case 2: pline("The hair on your %s seems to stand up.", body_part(HEAD)); break; } return; } #ifdef ARMY if (level.flags.has_barracks && !rn2(200)) { static const char *barracks_msg[4] = { "hear blades being honed.", "hear loud snoring.", "hear dice being thrown.", "hear General MacArthur!", }; You("%s",barracks_msg[rn2(3)+hallu]); return; } #endif /* ARMY */ if (level.flags.has_zoo && !rn2(200)) { static const char *zoo_msg[3] = { "hear a sound reminiscent of an elephant stepping on a peanut.", "hear a sound reminiscent of a seal barking.", "hear Doctor Doolittle!", }; You("%s",zoo_msg[rn2(2)+hallu]); return; } if (level.flags.has_shop && !rn2(200)) { if (!(sroom = search_special(ANY_SHOP))) { /* strange... */ level.flags.has_shop = 0; return; } if (tended_shop(sroom) && !index(u.ushops, ROOM_INDEX(sroom) + ROOMOFFSET)) { static const char *shop_msg[3] = { "hear someone cursing shoplifters.", "hear the chime of a cash register.", "hear Neiman and Marcus arguing!", }; You("%s",shop_msg[rn2(2)+hallu]); } return; } }
/* Return number of acceptable neighbour positions */ int mfndpos(struct monst *mon, coord poss[9], int info[9], int flag) { int x; int y; int nx; int ny; int cnt = 0; int tmp; struct monst *mtmp; x = mon->mx; y = mon->my; if(mon->mconf != 0) { flag |= ALLOW_ALL; flag &= ~NOTONL; } for(nx = x - 1; nx <= x + 1; ++nx) { for(ny = y - 1; ny <= y + 1; ++ny) { if((nx != x) || (ny != y)) { if(isok(nx, ny) != 0) { tmp = levl[nx][ny].typ; if(tmp >= DOOR) { if((nx == x) || (ny == y) || ((levl[x][y].typ != DOOR) && (tmp != DOOR))) { info[cnt] = 0; if((nx == u.ux) && (ny == u.uy)) { if((flag & ALLOW_U) == 0) { continue; } info[cnt] = ALLOW_U; } else { mtmp = m_at(nx, ny); if(mtmp != 0) { if((flag & ALLOW_M) == 0) { continue; } info[cnt] = ALLOW_M; } if(mtmp->mtame != 0) { if((flag & ALLOW_TM) == 0) { continue; } info[cnt] |= ALLOW_TM; } } if(sobj_at(CLOVE_OF_GARLIC, nx, ny) != 0) { if((flag & NOGARLIC) != 0) { continue; } info[cnt] |= NOGARLIC; } if((sobj_at(SCR_SCARE_MONSTER, nx, ny) != 0) || ((mon->mpeaceful == 0) && (sengr_at("Elbereth", nx, ny) != 0))) { if((flag & ALLOW_SSM) == 0) { continue; } info[cnt] |= ALLOW_SSM; } if(sobj_at(ENORMOUS_ROCK, nx, ny) != 0) { if((flag & ALLOW_ROCK) == 0) { continue; } info[cnt] |= ALLOW_ROCK; } if((Invis == 0) && (online(nx, ny) != 0)) { if((flag & NOTONL) != 0) { continue; } info[cnt] |= NOTONL; } /* We cannot avoid traps of an unknown kind */ struct gen *gtmp = g_at(nx, ny, ftrap); int tt; if(gtmp != NULL) { tt = 1 << (gtmp->gflag & ~SEEN); if((mon->mtrapseen & tt) != 0) { if((flag & tt) == 0) { continue; } info[cnt] |= tt; } } poss[cnt].x = nx; poss[cnt].y = ny; ++cnt; } } } } } } return cnt; }
/* * 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, gy, fci; unsigned char typ; struct fakecorridor *fcp; struct egd *egrd = EGD(grd); struct rm *crm; bool goldincorridor = false, u_in_vault = vault_occupied(u.urooms) ? true : false, grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? true : false; bool disappear_msg_seen = false, semi_dead = (grd->mhp <= 0); bool u_carry_gold = ((u.ugold + hidden_gold()) > 0L); bool 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)))) { (void)rloc(grd, false); wallify_vault(grd); (void)clear_fcorr(grd, true); goto letknow; } if (!in_fcorridor(grd, grd->mx, grd->my)) (void)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 ? (!u.ugold ? "drop that hidden gold and " : "drop that gold and ") : ""); if (egrd->warncnt == 7) { m = grd->mx; n = grd->my; verbalize("You've been warned, knave!"); mnexto(grd); levl[m][n].typ = egrd->fakecorr[0].ftyp; newsym(m, n); grd->mpeaceful = 0; return (-1); } /* not fair to get mad when (s)he's fainted or paralyzed */ if (!is_fainted() && multi >= 0) egrd->warncnt++; return (0); } if (!u_in_vault) { if (u_carry_gold) { /* player teleported */ m = grd->mx; n = grd->my; (void)rloc(grd, false); levl[m][n].typ = egrd->fakecorr[0].ftyp; newsym(m, n); grd->mpeaceful = 0; letknow: if (!cansee(grd->mx, grd->my) || !mon_visible(grd)) { You_hear("the shrill sound of a guard's whistle."); } else { const char * fmt = um_dist(grd->mx, grd->my, 2) ? "see an angry %s approaching." : "are confronted by an angry %s."; char name[BUFSZ]; g_monnam(name, BUFSZ, grd); You(fmt, name); } 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) && levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ == egrd->fakecorr[0].ftyp) { char name[BUFSZ]; g_monnam(name, BUFSZ, grd); pline_The("%s, confused, disappears.", name); 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!"); grd->mpeaceful = 0; return (-1); } } } for (fci = egrd->fcbeg; fci < egrd->fcend; fci++) if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) { m = egrd->fakecorr[fci].fx; n = egrd->fakecorr[fci].fy; goldincorridor = true; } if (goldincorridor && !egrd->gddone) { x = grd->mx; y = grd->my; if (m == u.ux && n == u.uy) { struct obj *gold = g_at(m, n); /* Grab the gold from between the hero's feet. */ grd->mgold += gold->quan; delobj(gold); newsym(m, n); } else if (m == x && n == y) { mpickgold(grd); /* does a newsym */ } else { /* just for insurance... */ if (MON_AT(m, n) && m != grd->mx && n != grd->my) { verbalize("Out of my way, scum!"); (void)rloc(m_at(m, n), false); } remove_monster(grd->mx, grd->my); newsym(grd->mx, grd->my); place_monster(grd, m, n); mpickgold(grd); /* does a newsym */ } if (cansee(m, n)) { char name[BUFSZ]; Monnam(name, BUFSZ, grd); pline("%s%s picks up the gold.", name, grd->mpeaceful ? " calms down and" : ""); } if (x != grd->mx || y != grd->my) { remove_monster(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 = &levl[nx][ny])->typ; if (!IS_STWALL(typ) && !IS_POOL(typ)) { if (in_fcorridor(grd, nx, ny)) goto nextnxy; if (*in_rooms(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->flags = 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 = &levl[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(levl[nx+nx-x][ny+ny-y].typ)) { crm->typ = DOOR; crm->flags = 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->flags = D_NODOOR; goto proceed; } break; } crm->typ = CORR; proceed: unblock_point(nx, ny); /* doesn't block light */ if (cansee(nx, ny)) newsym(nx, ny); fcp = &(egrd->fakecorr[egrd->fcend]); if (egrd->fcend++ == FCSIZ) impossible("fakecorr overflow"); fcp->fx = nx; fcp->fy = ny; fcp->ftyp = typ; 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(grd->mx, grd->my); newsym(grd->mx, grd->my); place_monster(grd, 0, 0); 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) { char name[BUFSZ]; g_monnam(name, BUFSZ, grd); pline("Suddenly, the %s disappears.", name); } return (1); } return (-2); } egrd->ogx = grd->mx; /* update old positions */ egrd->ogy = grd->my; remove_monster(grd->mx, grd->my); place_monster(grd, nx, ny); newsym(grd->mx, grd->my); restfakecorr(grd); return (1); }
static void wallify_vault(struct monst *grd) { int x, y, typ; int vlt = EGD(grd)->vroom; char tmp_viz; signed char lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1, loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1; struct monst *mon; struct obj *gold; struct trap *trap; bool fixed = false; bool 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(levl[x][y].typ) && !in_fcorridor(grd, x, y)) { if ((mon = m_at(x, y)) != 0 && mon != grd) { if (mon->mtame) yelp(mon); (void)rloc(mon, false); } if ((gold = g_at(x, y)) != 0) { move_gold(gold, EGD(grd)->vroom); movedgold = true; } if ((trap = t_at(x, y)) != 0) deltrap(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; levl[x][y].typ = typ; levl[x][y].flags = 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 (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my)) { char name[BUFSZ]; g_monnam(name, BUFSZ, grd); pline_The("%s whispers an incantation.", name); } else { You_hear("a distant chant."); } if (movedgold) pline("A mysterious force moves the gold into the vault."); if (fixed) pline_The("damaged vault's walls are magically restored!"); } }