-/* NetHack 3.6 mon.c $NHDT-Date: 1543455827 2018/11/29 01:43:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.272 $ */
+/* NetHack 3.6 mon.c $NHDT-Date: 1544608467 2018/12/12 09:54:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.273 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
boolean chk_geno;
const char *msg;
{
- if (DEADMONSTER(mtmp))
- return;
if (mtmp->data < &mons[LOW_PM] || mtmp->data >= &mons[NUMMONS]) {
impossible("illegal mon data %s; mnum=%d (%s)",
fmt_ptr((genericptr_t) mtmp->data), mtmp->mnum, msg);
mtmp->mnum, mndx, msg);
mtmp->mnum = mndx;
}
+ if (DEADMONSTER(mtmp)) {
+ /* bad if not fmons list or if not vault guard */
+ if (strcmp(msg, "fmon") || !mtmp->isgd)
+ impossible("dead monster on %s; %s at <%d,%d>",
+ msg, mons[mndx].mname, mtmp->mx, mtmp->my);
+ return;
+ }
if (chk_geno && (mvitals[mndx].mvflags & G_GENOD) != 0)
impossible("genocided %s in play (%s)", mons[mndx].mname, msg);
}
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
sanity_check_single_mon(mtmp, TRUE, "fmon");
- if (DEADMONSTER(mtmp))
+ if (DEADMONSTER(mtmp) && !mtmp->isgd)
continue;
+
x = mtmp->mx, y = mtmp->my;
if (!isok(x, y) && !(mtmp->isgd && x == 0 && y == 0)) {
impossible("mon (%s) claims to be at <%d,%d>?",
break;
}
nmtmp = mtmp->nmon;
- /* one dead monster needs to perform a move after death:
- vault guard whose temporary corridor is still on the map */
- if (mtmp->isgd && !mtmp->mx && DEADMONSTER(mtmp))
+ /* one dead monster needs to perform a move after death: vault
+ guard whose temporary corridor is still on the map; live
+ guards who have led the hero back to civilization get moved
+ off the map too; gd_move() decides whether the temporary
+ corridor can be removed and guard discarded (via clearing
+ mon->isgd flag so that dmonsfree() will get rid of mon) */
+ if (mtmp->isgd && !mtmp->mx) {
+ /* parked at <0,0>; eventually isgd should get set to false */
(void) gd_move(mtmp);
+ continue;
+ }
if (DEADMONSTER(mtmp))
continue;
mtmp->mtrapped = 0;
mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
relobj(mtmp, 0, FALSE);
- if (onmap) {
+ if (onmap || mtmp == level.monsters[0][0]) {
if (mtmp->wormno)
remove_worm(mtmp);
else
-/* NetHack 3.6 vault.c $NHDT-Date: 1542765368 2018/11/21 01:56:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.55 $ */
+/* NetHack 3.6 vault.c $NHDT-Date: 1544608469 2018/12/12 09:54:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.57 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *, BOOLEAN_P));
STATIC_DCL void FDECL(blackout, (int, int));
STATIC_DCL void FDECL(restfakecorr, (struct monst *));
+STATIC_DCL void FDECL(parkguard, (struct monst *));
STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *, int, int));
STATIC_DCL void FDECL(move_gold, (struct obj *, int));
STATIC_DCL void FDECL(wallify_vault, (struct monst *));
if (!mtmp->mextra)
mtmp->mextra = newmextra();
if (!EGD(mtmp)) {
- EGD(mtmp) = (struct egd *) alloc(sizeof(struct egd));
- (void) memset((genericptr_t) EGD(mtmp), 0, sizeof(struct egd));
+ EGD(mtmp) = (struct egd *) alloc(sizeof (struct egd));
+ (void) memset((genericptr_t) EGD(mtmp), 0, sizeof (struct egd));
}
}
mtmp->isgd = 0;
}
+/* try to remove the temporary corridor (from vault to rest of map) being
+ maintained by guard 'grd'; if guard is still in it, removal will fail,
+ to be tried again later */
STATIC_OVL boolean
clear_fcorr(grd, forceshow)
struct monst *grd;
if (!on_level(&egrd->gdlevel, &u.uz))
return TRUE;
+ /* note: guard remains on 'fmons' list (alive or dead, at off-map
+ coordinate <0,0>), until temporary corridor from vault back to
+ civilization has been removed */
while ((fcbeg = egrd->fcbeg) < egrd->fcend) {
fcx = egrd->fakecorr[fcbeg].fx;
fcy = egrd->fakecorr[fcbeg].fy;
- if ((DEADMONSTER(grd) || !in_fcorridor(grd, u.ux, u.uy)) && egrd->gddone)
+ if ((DEADMONSTER(grd) || !in_fcorridor(grd, u.ux, u.uy))
+ && egrd->gddone)
forceshow = TRUE;
if ((u.ux == fcx && u.uy == fcy && !DEADMONSTER(grd))
|| (!forceshow && couldsee(fcx, fcy))
}
}
+/* move guard--dead to alive--to <0,0> until temporary corridor is removed */
+STATIC_OVL void
+parkguard(grd)
+struct monst *grd;
+{
+ /* either guard is dead or will now be treated as if so;
+ monster traversal loops should skip it */
+ if (grd == context.polearm.hitmon)
+ context.polearm.hitmon = 0;
+ if (grd->mx) {
+ remove_monster(grd->mx, grd->my);
+ newsym(grd->mx, grd->my);
+ place_monster(grd, 0, 0);
+ /* [grd->mx,my just got set to 0,0 by place_monster(), so this
+ just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */
+ EGD(grd)->ogx = grd->mx;
+ EGD(grd)->ogy = grd->my;
+ }
+}
+
/* called in mon.c */
boolean
grddead(grd)
if (!dispose) {
/* destroy guard's gold; drop any other inventory */
relobj(grd, 0, FALSE);
- /* guard is dead; monster traversal loops should skip it */
grd->mhp = 0;
- if (grd == context.polearm.hitmon)
- context.polearm.hitmon = 0;
- /* see comment by newpos in gd_move() */
- remove_monster(grd->mx, grd->my);
- newsym(grd->mx, grd->my);
- place_monster(grd, 0, 0);
- EGD(grd)->ogx = grd->mx;
- EGD(grd)->ogy = grd->my;
+ parkguard(grd);
dispose = clear_fcorr(grd, TRUE);
}
if (dispose)
u.uinvault = 0;
return;
}
-
vaultroom -= ROOMOFFSET;
guard = findgd();
if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
/* if time ok and no guard now. */
- char buf[BUFSZ] = DUMMY;
+ char buf[BUFSZ];
register int x, y, dd, gx, gy;
int lx = 0, ly = 0;
long umoney;
nomul(0);
unmul((char *) 0);
}
+ buf[0] = '\0';
trycount = 5;
do {
getlin(Deaf ? "You are required to supply your name. -"
}
if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
- || !strcmpi(buf, "Creosote")) {
+ || !strcmpi(buf, "Creosote")) { /* Discworld */
if (!mvitals[PM_CROESUS].died) {
if (Deaf) {
if (!Blind)
EGD(guard)->fcbeg = 0;
EGD(guard)->fakecorr[0].fx = x;
EGD(guard)->fakecorr[0].fy = y;
- if (IS_WALL(levl[x][y].typ))
+ if (IS_WALL(levl[x][y].typ)) {
EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
- else { /* the initial guard location is a dug door */
+ } else { /* the initial guard location is a dug door */
int vlt = EGD(guard)->vroom;
xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
int x, y, nx, ny, m, n;
int dx, dy, gx, gy, fci;
uchar typ;
+ struct rm *crm;
struct fakecorridor *fcp;
register 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(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
- boolean disappear_msg_seen = FALSE, semi_dead = (DEADMONSTER(grd));
- long umoney = money_cnt(invent);
- register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
- boolean see_guard, newspot = FALSE;
+ long umoney = 0L;
+ boolean goldincorridor = FALSE, u_in_vault = FALSE, grd_in_vault = FALSE,
+ disappear_msg_seen = FALSE, semi_dead = DEADMONSTER(grd),
+ u_carry_gold = FALSE, newspot = FALSE, see_guard;
if (!on_level(&(egrd->gdlevel), &u.uz))
return -1;
nx = ny = m = n = 0;
+ if (semi_dead || !grd->mx || egrd->gddone) {
+ egrd->gddone = 1;
+ goto cleanup;
+ }
+ debugpline1("gd_move: %s guard", grd->mpeaceful ? "peaceful" : "hostile");
+
+ u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE;
+ grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
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)))) {
grd->mpeaceful = 0;
return -1;
}
+
+ umoney = money_cnt(invent);
+ u_carry_gold = umoney > 0L || hidden_gold() > 0L;
if (egrd->fcend == 1) {
if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
if (egrd->warncnt == 3 && !Deaf)
} else {
if (!Deaf)
verbalize("Well, begone.");
- wallify_vault(grd);
egrd->gddone = 1;
goto cleanup;
}
fcp->fy = ny;
fcp->ftyp = typ;
newpos:
- gd_mv_monaway(grd, nx,ny);
+ gd_mv_monaway(grd, nx, ny);
if (egrd->gddone) {
/* The following is a kludge. We need to keep */
/* the guard around in order to be able to make */
/* At the end of the process, the guard is killed */
/* in restfakecorr(). */
cleanup:
- x = grd->mx;
- y = grd->my;
-
+ x = grd->mx, y = grd->my;
see_guard = canspotmon(grd);
+ parkguard(grd); /* move to <0,0> */
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);
+ debugpline2("gd_move: %scleanup%s",
+ grd->isgd ? "" : "final ",
+ grd->isgd ? " attempt" : "");
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));