const char *surface(int x, int y) { struct rm *loc = &level->locations[x][y]; if ((x == u.ux) && (y == u.uy) && u.uswallow && is_animal(u.ustuck->data)) return "maw"; else if (IS_AIR(loc->typ) && Is_airlevel(&u.uz)) return "air"; else if (is_pool(level, x, y)) return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water"; else if (is_ice(level, x, y)) return "ice"; else if (is_lava(level, x, y)) return "lava"; else if (loc->typ == DRAWBRIDGE_DOWN) return "bridge"; else if (IS_ALTAR(level->locations[x][y].typ)) return "altar"; else if (IS_GRAVE(level->locations[x][y].typ)) return "headstone"; else if (IS_FOUNTAIN(level->locations[x][y].typ)) return "fountain"; else if ((IS_ROOM(loc->typ) && !Is_earthlevel(&u.uz)) || IS_WALL(loc->typ) || IS_DOOR(loc->typ) || loc->typ == SDOOR) return "floor"; else return "ground"; }
const char *ceiling(int x, int y) { struct rm *loc = &level->locations[x][y]; const char *what; /* other room types will no longer exist when we're interested -- * see check_special_room() */ if (*in_rooms(level, x, y, VAULT)) what = "vault's ceiling"; else if (*in_rooms(level, x, y, TEMPLE)) what = "temple's ceiling"; else if (*in_rooms(level, x, y, SHOPBASE)) what = "shop's ceiling"; else if (IS_AIR(loc->typ)) what = "sky"; else if (Underwater) what = "water's surface"; else if ((IS_ROOM(loc->typ) && !Is_earthlevel(&u.uz)) || IS_WALL(loc->typ) || IS_DOOR(loc->typ) || loc->typ == SDOOR) what = "ceiling"; else what = "rock above"; return what; }
/* * use a flooding algorithm to find all locations that should * have the same rm number as the current location. * if anyroom is TRUE, use IS_ROOM to check room membership instead of * exactly matching level->locations[sx][sy].typ and walls are included as well. */ void flood_fill_rm(struct level *lev, int sx, int sy, int rmno, boolean lit, boolean anyroom) { int i; int nx; schar fg_typ = lev->locations[sx][sy].typ; /* back up to find leftmost uninitialized location */ while (sx >= 0 && (anyroom ? IS_ROOM(lev->locations[sx][sy].typ) : lev->locations[sx][sy].typ == fg_typ) && (int)lev->locations[sx][sy].roomno != rmno) sx--; sx++; /* compensate for extra decrement */ /* assume sx,sy is valid */ if (sx < min_rx) min_rx = sx; if (sy < min_ry) min_ry = sy; for (i = sx; i <= WIDTH && lev->locations[i][sy].typ == fg_typ; i++) { lev->locations[i][sy].roomno = rmno; lev->locations[i][sy].lit = lit; if (anyroom) { /* add walls to room as well */ int ii, jj; for (ii = (i == sx ? i - 1 : i); ii <= i + 1; ii++) for (jj = sy - 1; jj <= sy + 1; jj++) if (isok(ii, jj) && (IS_WALL(lev->locations[ii][jj].typ) || IS_DOOR(lev->locations[ii][jj].typ))) { lev->locations[ii][jj].edge = 1; if (lit) lev->locations[ii][jj].lit = lit; if ((int)lev->locations[ii][jj].roomno != rmno) lev->locations[ii][jj].roomno = SHARED; } } n_loc_filled++; } nx = i; if (isok(sx, sy - 1)) { for (i = sx; i < nx; i++) if (lev->locations[i][sy - 1].typ == fg_typ) { if ((int)lev->locations[i][sy - 1].roomno != rmno) flood_fill_rm(lev, i, sy - 1, rmno, lit, anyroom); } else { if ((i > sx || isok(i - 1, sy - 1)) && lev->locations[i - 1][sy - 1].typ == fg_typ) { if ((int)lev->locations[i - 1][sy - 1].roomno != rmno) flood_fill_rm(lev, i - 1, sy - 1, rmno, lit, anyroom); } if ((i < nx - 1 || isok(i + 1, sy - 1)) && lev->locations[i + 1][sy - 1].typ == fg_typ) { if ((int)lev->locations[i + 1][sy - 1].roomno != rmno) flood_fill_rm(lev, i + 1, sy - 1, rmno, lit, anyroom); } } } if (isok(sx, sy + 1)) { for (i = sx; i < nx; i++) if (lev->locations[i][sy + 1].typ == fg_typ) { if ((int)lev->locations[i][sy + 1].roomno != rmno) flood_fill_rm(lev, i, sy + 1, rmno, lit, anyroom); } else { if ((i > sx || isok(i - 1, sy + 1)) && lev->locations[i - 1][sy + 1].typ == fg_typ) { if ((int)lev->locations[i - 1][sy + 1].roomno != rmno) flood_fill_rm(lev, i - 1, sy + 1, rmno, lit, anyroom); } if ((i < nx - 1 || isok(i + 1, sy + 1)) && lev->locations[i + 1][sy + 1].typ == fg_typ) { if ((int)lev->locations[i + 1][sy + 1].roomno != rmno) flood_fill_rm(lev, i + 1, sy + 1, rmno, lit, anyroom); } } } if (nx > max_rx) max_rx = nx - 1; /* nx is just past valid region */ if (sy > max_ry) max_ry = sy; }
/* called with dx = dy = 0 with vertical bolts */ void buzz(int type, xchar sx, xchar sy, int dx, int dy) { int abstype = abs(type); const char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype]; struct rm *lev; xchar range; struct monst *mon; if(u.uswallow) { int tmp; if(type < 0) return; tmp = zhit(u.ustuck, type); pline("The %s rips into %s%s", fltxt, monnam(u.ustuck), exclam(tmp)); return; } if(type < 0) pru(); range = rn1(7,7); Tmp_at(-1, dirlet(dx,dy)); /* open call */ while(range-- > 0) { sx += dx; sy += dy; if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy); else { int bounce = 0; if(cansee(sx-dx,sy-dy)) pline("The %s bounces!", fltxt); if(ZAP_POS(levl[sx][sy-dy].typ)) bounce = 1; if(ZAP_POS(levl[sx-dx][sy].typ)) { if(!bounce || rn2(2)) bounce = 2; } switch(bounce){ case 0: dx = -dx; dy = -dy; continue; case 1: dy = -dy; sx -= dx; break; case 2: dx = -dx; sy -= dy; break; } Tmp_at(-2,dirlet(dx,dy)); continue; } if(lev->typ == POOL && abstype == 1 /* fire */) { range -= 3; lev->typ = ROOM; if(cansee(sx,sy)) { mnewsym(sx,sy); pline("The water evaporates."); } else pline("You hear a hissing sound."); } if((mon = m_at(sx,sy)) && (type != -1 || mon->data->mlet != 'D')) { wakeup(mon); if(rnd(20) < 18 + mon->data->ac) { int tmp = zhit(mon,abstype); if(mon->mhp < 1) { if(type < 0) { if(cansee(mon->mx,mon->my)) pline("%s is killed by the %s!", Monnam(mon), fltxt); mondied(mon); } else killed(mon); } else hit(fltxt, mon, exclam(tmp)); range -= 2; } else miss(fltxt,mon); } else if(sx == u.ux && sy == u.uy) { nomul(0); if(rnd(20) < 18+u.uac) { int dam = 0; range -= 2; pline("The %s hits you!",fltxt); switch(abstype) { case 0: dam = d(2,6); break; case 1: if(Fire_resistance) pline("You don't feel hot!"); else dam = d(6,6); if(!rn2(3)) burn_scrolls(); break; case 2: nomul(-rnd(25)); /* sleep ray */ break; case 3: if(Cold_resistance) pline("You don't feel cold!"); else dam = d(6,6); break; case 4: u.uhp = -1; } losehp(dam,fltxt); } else pline("The %s whizzes by you!",fltxt); stop_occupation(); } if(!ZAP_POS(lev->typ)) { int bounce = 0, rmn; if(cansee(sx,sy)) pline("The %s bounces!",fltxt); range--; if(!dx || !dy || !rn2(20)){ dx = -dx; dy = -dy; } else { if(ZAP_POS(rmn = levl[sx][sy-dy].typ) && (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ))) bounce = 1; if(ZAP_POS(rmn = levl[sx-dx][sy].typ) && (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ))) if(!bounce || rn2(2)) bounce = 2; switch(bounce){ case 0: dy = -dy; dx = -dx; break; case 1: dy = -dy; break; case 2: dx = -dx; break; } Tmp_at(-2, dirlet(dx,dy)); } } } Tmp_at(-1,-1); }
/* return 0 (no move), 1 (move) or 2 (dead) */ int dog_move(struct monst *mtmp, int after) { int nx, ny, omx, omy, appr, nearer, j; int udist, chi, i, whappr; struct monst *mtmp2; struct permonst *mdat = mtmp->data; struct edog *edog = EDOG(mtmp); struct obj *obj; struct trap *trap; xchar cnt, chcnt, nix, niy; schar dogroom, uroom; xchar gx, gy, gtyp, otyp; /* current goal */ coord poss[9]; int info[9]; #define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) #define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) if(moves <= edog->eattime) return(0); /* dog is still eating */ omx = mtmp->mx; omy = mtmp->my; whappr = (moves - EDOG(mtmp)->whistletime < 5); if(moves > edog->hungrytime + 500 && !mtmp->mconf){ mtmp->mconf = 1; mtmp->mhpmax /= 3; if(mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; if(cansee(omx,omy)) pline("%s is confused from hunger.", Monnam(mtmp)); else pline("You feel worried about %s.", monnam(mtmp)); } else if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){ if(cansee(omx,omy)) pline("%s dies from hunger.", Monnam(mtmp)); else pline("You have a sad feeling for a moment, then it passes."); mondied(mtmp); return(2); } dogroom = inroom(omx,omy); uroom = inroom(u.ux,u.uy); udist = dist(omx,omy); /* maybe we tamed him while being swallowed --jgm */ if(!udist) return(0); /* if we are carrying sth then we drop it (perhaps near @) */ /* Note: if apport == 1 then our behaviour is independent of udist */ if(mtmp->minvent){ if(!rn2(udist) || !rn2((int) edog->apport)) if(rn2(10) < edog->apport){ relobj(mtmp, (int) mtmp->minvis); if(edog->apport > 1) edog->apport--; edog->dropdist = udist; /* hpscdi!jon */ edog->droptime = moves; } } else { if ((obj = o_at(omx,omy))) if(!strchr("0_", obj->olet)){ if((otyp = dogfood(obj)) <= CADAVER){ nix = omx; niy = omy; goto eatobj; } if (obj->owt < 10*mtmp->data->mlevel) if (rn2(20) < edog->apport+3) if (rn2(udist) || !rn2((int) edog->apport)){ freeobj(obj); unpobj(obj); /* if(levl[omx][omy].scrsym == obj->olet) newsym(omx,omy); */ mpickobj(mtmp,obj); } } } /* first we look for food */ gtyp = UNDEF; /* no goal as yet */ gx = gy = 0; for(obj = fobj; obj; obj = obj->nobj) { otyp = dogfood(obj); if(otyp > gtyp || otyp == UNDEF) continue; if(inroom(obj->ox,obj->oy) != dogroom) continue; if(otyp < MANFOOD && (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) { if(otyp < gtyp || (otyp == gtyp && DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){ gx = obj->ox; gy = obj->oy; gtyp = otyp; } } else if(gtyp == UNDEF && dogroom >= 0 && uroom == dogroom && !mtmp->minvent && edog->apport > rn2(8)){ gx = obj->ox; gy = obj->oy; gtyp = APPORT; } } if(gtyp == UNDEF || (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){ if(dogroom < 0 || dogroom == uroom){ gx = u.ux; gy = u.uy; #ifndef QUEST } else { int tmp = rooms[(int)dogroom].fdoor; cnt = rooms[(int)dogroom].doorct; gx = gy = FAR; /* random, far away */ while(cnt--){ if(dist(gx,gy) > dist(doors[tmp].x, doors[tmp].y)){ gx = doors[tmp].x; gy = doors[tmp].y; } tmp++; } /* here gx == FAR e.g. when dog is in a vault */ if(gx == FAR || (gx == omx && gy == omy)){ gx = u.ux; gy = u.uy; } #endif /* QUEST */ } appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; if(after && udist <= 4 && gx == u.ux && gy == u.uy) return(0); if(udist > 1){ if (!IS_ROOM(levl[(int)u.ux][(int)u.uy].typ) || !rn2(4) || whappr || (mtmp->minvent && rn2((int) edog->apport))) appr = 1; } /* if you have dog food he'll follow you more closely */ if (appr == 0) { obj = invent; while(obj){ if(obj->otyp == TRIPE_RATION){ appr = 1; break; } obj = obj->nobj; } } } else appr = 1; /* gtyp != UNDEF */ if(mtmp->mconf) appr = 0; if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){ coord *cp; cp = gettrack(omx,omy); if(cp){ gx = cp->x; gy = cp->y; } } nix = omx; niy = omy; cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS); chcnt = 0; chi = -1; for(i=0; i<cnt; i++){ nx = poss[i].x; ny = poss[i].y; if(info[i] & ALLOW_M){ mtmp2 = m_at(nx,ny); if(mtmp2->data->mlevel >= mdat->mlevel+2 || mtmp2->data->mlet == 'c') continue; if(after) return(0); /* hit only once each move */ if(hitmm(mtmp, mtmp2) == 1 && rn2(4) && mtmp2->mlstmv != moves && hitmm(mtmp2,mtmp) == 2) return(2); return(0); } /* dog avoids traps */ /* but perhaps we have to pass a trap in order to follow @ */ if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){ if(!trap->tseen && rn2(40)) continue; if(rn2(10)) continue; } /* dog eschewes cursed objects */ /* but likes dog food */ obj = fobj; while(obj){ if(obj->ox != nx || obj->oy != ny) goto nextobj; if(obj->cursed) goto nxti; if(obj->olet == FOOD_SYM && (otyp = dogfood(obj)) < MANFOOD && (otyp < ACCFOOD || edog->hungrytime <= moves)){ /* Note: our dog likes the food so much that he might eat it even when it conceals a cursed object */ nix = nx; niy = ny; chi = i; eatobj: edog->eattime = moves + obj->quan * objects[obj->otyp].oc_delay; if(edog->hungrytime < moves) edog->hungrytime = moves; edog->hungrytime += 5*obj->quan * objects[obj->otyp].nutrition; mtmp->mconf = 0; if(cansee(nix,niy)) pline("%s ate %s.", Monnam(mtmp), doname(obj)); /* perhaps this was a reward */ if(otyp != CADAVER) edog->apport += 200/(edog->dropdist+moves-edog->droptime); delobj(obj); goto newdogpos; } nextobj: obj = obj->nobj; } for(j=0; j<MTSZ && j<cnt-1; j++) if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) if(rn2(4*(cnt-j))) goto nxti; /* Some stupid C compilers cannot compute the whole expression at once. */ nearer = GDIST(nx,ny); nearer -= GDIST(nix,niy); nearer *= appr; if((nearer == 0 && !rn2(++chcnt)) || nearer<0 || (nearer > 0 && !whappr && ((omx == nix && omy == niy && !rn2(3)) || !rn2(12)) )){ nix = nx; niy = ny; if(nearer < 0) chcnt = 0; chi = i; } nxti: ; } newdogpos: if(nix != omx || niy != omy){ if(info[chi] & ALLOW_U){ (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1); return(0); } mtmp->mx = nix; mtmp->my = niy; for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; mtmp->mtrack[0].x = omx; mtmp->mtrack[0].y = omy; } if(mintrap(mtmp) == 2) /* he died */ return(2); pmon(mtmp); return(1); }
/* * Move for priests and shopkeepers. Called from shk_move() and pri_move(). * Valid returns are 1: moved 0: didn't -1: let m_move do it -2: died. */ int move_special(struct monst *mtmp, boolean in_his_shop, schar appr, boolean uondoor, boolean avoid, xchar omx, xchar omy, xchar gx, xchar gy) { xchar nx, ny, nix, niy; schar i; schar chcnt, cnt; coord poss[9]; long info[9]; long allowflags; struct obj *ib = NULL; if (omx == gx && omy == gy) return 0; if (mtmp->mconf) { avoid = FALSE; appr = 0; } nix = omx; niy = omy; if (mtmp->isshk) allowflags = ALLOW_SSM; else allowflags = ALLOW_SSM | ALLOW_SANCT; if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK | ALLOW_WALL); if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK; if (tunnels(mtmp->data)) allowflags |= ALLOW_DIG; if (!nohands(mtmp->data) && !verysmall(mtmp->data)) { allowflags |= OPENDOOR; if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR; } if (is_giant(mtmp->data)) allowflags |= BUSTDOOR; cnt = mfndpos(mtmp, poss, info, allowflags); if (mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */ for (i = 0; i < cnt; i++) if (!(info[i] & NOTONL)) goto pick_move; avoid = FALSE; } #define GDIST(x,y) (dist2(x,y,gx,gy)) pick_move: chcnt = 0; for (i = 0; i < cnt; i++) { nx = poss[i].x; ny = poss[i].y; if (IS_ROOM(level->locations[nx][ny].typ) || (mtmp->isshk && (!in_his_shop || ESHK(mtmp)->following))) { if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rn2(++chcnt)) || (appr && GDIST(nx, ny) < GDIST(nix, niy))) { nix = nx; niy = ny; } } } if (mtmp->ispriest && avoid && nix == omx && niy == omy && onlineu(omx, omy)) { /* might as well move closer as long it's going to stay lined up */ avoid = FALSE; goto pick_move; } if (nix != omx || niy != omy) { remove_monster(level, omx, omy); place_monster(mtmp, nix, niy); newsym(nix, niy); if (mtmp->isshk && !in_his_shop && inhishop(mtmp)) check_special_room(FALSE); if (ib) { if (cansee(mtmp->mx, mtmp->my)) pline("%s picks up %s.", Monnam(mtmp), distant_name(ib, doname)); obj_extract_self(ib); mpickobj(mtmp, ib); } return 1; } return 0; }
void noegnud_render_map_tile () { int x, y; int xs,xe,xd; int ys,ye,yd; GLfloat current_alpha; float nx, ny; float realangle; GLfloat light_position[4]; ys=0; ye=MAX_MAP_Y; yd=1; xs=0; xe=MAX_MAP_X; xd=1; realangle=(noegnud_options_render_opengl_view_angle_x_current->value+(noegnud_activetileset->iso?0:noegnud_render_bullettime_angle)); while (realangle>=360) realangle-=360; while (realangle<0) realangle+=360; if ((realangle>=90)&&(realangle<270)) { ys=MAX_MAP_Y-1; ye=-1; yd=-1; } if ((realangle<=180)) { xs=MAX_MAP_X-1; xe=-1; xd=-1; } if (noegnud_render_selection_busy) { glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); } if (noegnud_activetileset->iso) { glEnable (GL_BLEND); glDisable (GL_DEPTH_TEST); } else { glDisable (GL_BLEND); if (noegnud_options_render_features_cardboardcutout->value&&noegnud_activetileset->isalphatileset) { glEnable (GL_DEPTH_TEST); } else glDisable (GL_DEPTH_TEST); } if (noegnud_options_render_opengl_lighting_method->value==NOEGNUD_RENDER_LIGHTING_METHOD_CHEAP) { glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHT0); if ((noegnud_options_input_mouse_3d_light->value)&&noegnud_render_mouse_map_x!=-1) { glEnable(GL_LIGHT1); } else { glDisable(GL_LIGHT1); } } x=noegnud_clip_x; y=noegnud_clip_y; ny = -(y - (noegnud_render_middle_y)); nx = x - (noegnud_render_middle_x); light_position[0]=noegnud_activetileset->glwidth/2; light_position[1]=noegnud_activetileset->glheight*3/2; light_position[2]=noegnud_activetileset->glheight; light_position[3]=1; glTranslatef ( (noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x, 0, -((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y); glLightfv(GL_LIGHT0,GL_POSITION,light_position); if (noegnud_options_input_mouse_3d_light->value) { ny = -(noegnud_render_mouse_map_y - (noegnud_render_middle_y)); nx = (noegnud_render_mouse_map_x-1) - (noegnud_render_middle_x); light_position[0]+=(noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x; light_position[2]+=-((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y; glLightfv(GL_LIGHT1,GL_POSITION,light_position); } for (y = 0; y < MAX_MAP_Y; y++) { ny = -(y - (noegnud_render_middle_y)); for (x = 0; x < MAX_MAP_X; x++) { nx = x - (noegnud_render_middle_x); glPopMatrix (); glPushMatrix (); glTranslatef ( (noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x, 0, -((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y); glLoadName(y*256+x); glBegin(GL_LINES); glEnd(); /* if (noegnud_options_input_mouse_3d_light->value&&((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glLightfv(GL_LIGHT1,GL_POSITION,light_position); } */ if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.25,1.0,0.25,1.0); } else if ((x == noegnud_clip_x) && (y == noegnud_clip_y)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,1.0); } else if ((!noegnud_activetileset->isalphatileset)&&iflags.hilite_pet&&(noegnud_map[x][y].glyph_primary!=MAX_GLYPH)&&(noegnud_map[x][y].special_primary & MG_PET)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,1.0); } else glColor4f(1.0,1.0,1.0,1.0); if (noegnud_render_selection_busy) { noegnud_render_map_single_selection_tile (noegnud_map[x][y].tile_primary,1); } else if (noegnud_options_mode_tileset_caverns->value&&(!noegnud_activetileset->iso)&&noegnud_image_dungeon&&(noegnud_map[x][y].glyph_primary==MAX_GLYPH||(glyph_to_cmap(noegnud_map[x][y].glyph_primary)==S_stone&&levl[x+1][y].lit))) { if (levl[x+1][y].seenv) { if (noegnud_options_render_features_cardboardcutout->value && noegnud_options_mode_tileset_caverns_cutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value&&(!IS_ROOM(levl[x+1][y].typ))) { glPushMatrix (); noegnud_render_map_single_tile_raised_walls_texture( noegnud_image_dungeon->block[0][0]->image, noegnud_options_render_features_cardboardcutout_wall_height->value, current_alpha, !((y>0)&&noegnud_map[x][y-1].high), !((y<MAX_MAP_Y-1)&&noegnud_map[x][y+1].high), !((x>0)&&noegnud_map[x-1][y].high), !((x<MAX_MAP_X-1)&&noegnud_map[x+1][y].high)); glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_wall_height->value,0); } if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.25,1.0,0.25,1.0); } else { glColor4f(1.0,1.0,1.0,current_alpha); } } else { if (noegnud_options_render_features_cardboardcutout->value && noegnud_options_mode_tileset_caverns_cutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_wall_height->value,0); } if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.125,0.5,0.125,1.0); } else glColor4f(0.5,0.5,0.5,current_alpha); } if (levl[x+1][y].seenv) { if (IS_ROOM(levl[x+1][y].typ)) { } else { glBindTexture (GL_TEXTURE_2D, noegnud_image_dungeon->block[0][0]->image); glBegin (GL_QUADS); glNormal3f(0,1,0); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx1, noegnud_image_dungeon->block[0][0]->fy2); glVertex3f (0, 0, noegnud_activetileset->glheight); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx2, noegnud_image_dungeon->block[0][0]->fy2); glVertex3f (noegnud_activetileset->glwidth, 0, noegnud_activetileset->glheight); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx2, noegnud_image_dungeon->block[0][0]->fy1); glVertex3f (noegnud_activetileset->glwidth, 0, 0); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx1, noegnud_image_dungeon->block[0][0]->fy1); glVertex3f (0, 0, 0); glEnd (); } } else { if (noegnud_options_mode_tileset_caverns_unexplored->value) { glBindTexture (GL_TEXTURE_2D, noegnud_image_dungeon->block[0][0]->image); glBegin (GL_QUADS); glNormal3f(0,1,0); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx1, noegnud_image_dungeon->block[0][0]->fy2); glVertex3f (0, 0, noegnud_activetileset->glheight); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx2, noegnud_image_dungeon->block[0][0]->fy2); glVertex3f (noegnud_activetileset->glwidth, 0, noegnud_activetileset->glheight); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx2, noegnud_image_dungeon->block[0][0]->fy1); glVertex3f (noegnud_activetileset->glwidth, 0, 0); glTexCoord2f (noegnud_image_dungeon->block[0][0]->fx1, noegnud_image_dungeon->block[0][0]->fy1); glVertex3f (0, 0, 0); glEnd (); } } if (levl[x+1][y].seenv) { if (noegnud_options_render_features_cardboardcutout->value && noegnud_options_mode_tileset_caverns_cutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value&&(!IS_ROOM(levl[x+1][y].typ))) { glPopMatrix (); } } } if ( ((!noegnud_activetileset->isalphatileset) && (noegnud_map[x][y].glyph_primary!=MAX_GLYPH))) { noegnud_render_map_single_tile (noegnud_map[x][y].tile_primary,1); if ((((x == noegnud_clip_x) && (y == noegnud_clip_y))||(((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y))) || // if (((x == noegnud_clip_x) && (y == noegnud_clip_y)) || (noegnud_map[x][y].glyph_primary!=MAX_GLYPH&&iflags.hilite_pet&&(noegnud_map[x][y].special_primary & MG_PET))) { glEnable (GL_BLEND); noegnud_render_map_tile_highlight_block (); glDisable (GL_BLEND); } } else if (noegnud_activetileset->isalphatileset) { if ( noegnud_options_render_features_cardboardcutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value && noegnud_map[x][y].low && (!noegnud_activetileset->iso)) { if ((noegnud_map[x][y].glyph_primary!=MAX_GLYPH)||(noegnud_map[x][y].glyph_primary==MAX_GLYPH&&noegnud_options_mode_tileset_caverns_cutout->value)) glTranslatef(0,-noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); } if ( noegnud_map[x][y].glyph_back != MAX_GLYPH && (!noegnud_map[x][y].high)) noegnud_render_map_single_tile (noegnud_map[x][y].tile_back,1); if ((!noegnud_render_selection_busy)&&noegnud_options_render_features_cardboardcutout->value&&noegnud_options_render_features_cardboardcutout_raise_walls->value&&(!noegnud_activetileset->iso)&&noegnud_map[x][y].low) { //glTranslatef(0,-noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); noegnud_render_map_single_tile_sunken_walls ( noegnud_map[x][y].tile_back, noegnud_options_render_features_cardboardcutout_hole_depth->value, current_alpha, !((y>0)&&noegnud_map[x][y-1].low), !((y<MAX_MAP_Y-1)&&noegnud_map[x][y+1].low), !((x>0)&&noegnud_map[x-1][y].low), !((x<MAX_MAP_X-1)&&noegnud_map[x][y].low)); } } } } if (noegnud_render_selection_busy) return; glEnable (GL_BLEND); if (noegnud_activetileset->isalphatileset) for (y = 0; y < MAX_MAP_Y; y++) { ny = -(y - (noegnud_render_middle_y)); for (x = 0; x < MAX_MAP_X; x++) { nx = x - (noegnud_render_middle_x); if ( ( ((noegnud_activetileset->iso)) /*|| (noegnud_options_render_features_cardboardcutout->value&&noegnud_activetileset->isalphatileset&&(!noegnud_activetileset->iso)) */ )&& (y >= noegnud_clip_y)&& (!((x == noegnud_clip_x) && (y == noegnud_clip_y)))&& (!glyph_is_object(noegnud_map[x][y].glyph_primary))&& (!glyph_is_monster(noegnud_map[x][y].glyph_primary))&& (!glyph_is_trap(noegnud_map[x][y].glyph_primary))&& (sqrt((noegnud_clip_y-y)*(noegnud_clip_y-y)+(noegnud_clip_x-x)*(noegnud_clip_x-x))<3) ) { current_alpha=noegnud_options_mode_tileset_iso_opacity->value; } else { current_alpha=1.0; } glPopMatrix (); glPushMatrix (); glTranslatef ((noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x, 0, -((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y); glBegin(GL_LINES); glEnd(); if (noegnud_image_dungeon&&(noegnud_map[x][y].glyph_primary==MAX_GLYPH||(glyph_to_cmap(noegnud_map[x][y].glyph_primary)==S_stone&&levl[x+1][y].lit))) { if (levl[x+1][y].seenv) { if (noegnud_options_render_features_cardboardcutout->value && noegnud_options_mode_tileset_caverns_cutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value&&(!IS_ROOM(levl[x+1][y].typ))) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_wall_height->value,0); } } else { if (noegnud_options_render_features_cardboardcutout->value && noegnud_options_mode_tileset_caverns_cutout->value && noegnud_options_render_features_cardboardcutout_raise_walls->value) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_wall_height->value,0);} } } else if (noegnud_map[x][y].glyph_primary!=MAX_GLYPH&&noegnud_options_render_features_cardboardcutout->value&&noegnud_options_render_features_cardboardcutout_raise_walls->value&&noegnud_activetileset->isalphatileset&&(!noegnud_activetileset->iso)) { if (noegnud_map[x][y].high) { if (IS_DOOR(level.locations[x+1][y].typ)) { noegnud_render_map_single_tile_raised_walls ( noegnud_map[x][y].tile_middle, noegnud_options_render_features_cardboardcutout_wall_height->value, current_alpha, !((y>0)&&noegnud_map[x][y-1].high), !((y<MAX_MAP_Y-1)&&noegnud_map[x][y+1].high), !((x>0)&&noegnud_map[x-1][y].high), !((x<MAX_MAP_X-1)&&noegnud_map[x+1][y].high)); } else { noegnud_render_map_single_tile_raised_walls ( noegnud_map[x][y].tile_back, noegnud_options_render_features_cardboardcutout_wall_height->value, current_alpha, !((y>0)&&noegnud_map[x][y-1].high), !((y<MAX_MAP_Y-1)&&noegnud_map[x][y+1].high), !((x>0)&&noegnud_map[x-1][y].high), !((x<MAX_MAP_X-1)&&noegnud_map[x+1][y].high)); } glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_wall_height->value,0); } else if (noegnud_map[x][y].low) { glTranslatef(0,-noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); if (noegnud_map[x][y].translucent) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value*noegnud_options_render_features_cardboardcutout_liquid_depth->value,0); current_alpha=0.5; } } } if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.25,1.0,0.25,1.0); } else if ((x == noegnud_clip_x) && (y == noegnud_clip_y)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,current_alpha); } else if (iflags.hilite_pet&&(noegnud_map[x][y].glyph_primary!=MAX_GLYPH)&&(noegnud_map[x][y].special_primary & MG_PET)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,current_alpha); } else { glColor4f(1.0,1.0,1.0,current_alpha); } if (noegnud_activetileset->isalphatileset) { if (noegnud_map[x][y].glyph_middle != MAX_GLYPH) { noegnud_render_map_single_tile (noegnud_map[x][y].tile_middle,1); } if (noegnud_activetileset->iso&&noegnud_map[x][y].glyph_fore != MAX_GLYPH) { noegnud_render_map_single_tile (noegnud_map[x][y].tile_fore,1); } if (((x == noegnud_clip_x) && (y == noegnud_clip_y)) || (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) || (noegnud_map[x][y].glyph_primary!=MAX_GLYPH&&iflags.hilite_pet&&(noegnud_map[x][y].special_primary & MG_PET))) { if (noegnud_options_render_features_cardboardcutout->value) glTranslatef(0,0.02,0); noegnud_render_map_tile_highlight_block (); } } } } if ((noegnud_activetileset->isalphatileset)&&(!noegnud_activetileset->iso)) { if (noegnud_options_render_features_cardboardcutout->value) glDisable(GL_CULL_FACE); if (noegnud_options_render_features_cardboardcutout->value&&noegnud_options_render_features_cardboardcutout_wall_translucency_current->value>0) { glDisable(GL_DEPTH_TEST); for (y = ys; y != ye; y+=yd) { ny = -(y - (noegnud_render_middle_y)); for (x = xs; x != xe; x+=xd) { nx = x - (noegnud_render_middle_x); glPopMatrix (); glPushMatrix (); if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.25,1.0,0.25,noegnud_options_render_features_cardboardcutout_wall_translucency_current->value); } else { glColor4f(1.0,1.0,1.0,noegnud_options_render_features_cardboardcutout_wall_translucency_current->value); } glTranslatef ((noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x, 0, -((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y); glBegin(GL_LINES); glEnd(); if (!(noegnud_map[x][y].high||noegnud_map[x][y].low)) { if (noegnud_map[x][y].glyph_back!=MAX_GLYPH) { if (noegnud_options_render_opengl_lighting_method->value==NOEGNUD_RENDER_LIGHTING_METHOD_CHEAP) { glEnable(GL_LIGHTING); } noegnud_render_map_single_tile (noegnud_map[x][y].tile_back,1); if (noegnud_options_render_opengl_lighting_method->value==NOEGNUD_RENDER_LIGHTING_METHOD_CHEAP) { glDisable(GL_LIGHTING); } } if (noegnud_map[x][y].glyph_middle!=MAX_GLYPH) { noegnud_render_map_single_tile (noegnud_map[x][y].tile_middle,1); } } if (noegnud_map[x][y].glyph_fore != MAX_GLYPH) { if ((x==(u.ux-1)&&y==u.uy)&&Levitation) { if (noegnud_map[x][y].low) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); } glTranslatef(0,noegnud_activetileset->glheight/2,0); } if (noegnud_map[x][y].low) glTranslatef(0,-noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); if (((glyph_is_monster(noegnud_map[x][y].glyph_fore)&&noegnud_options_render_features_cardboardcutout_raise_monsters->value)||(glyph_is_object(noegnud_map[x][y].glyph_fore)&&noegnud_options_render_features_cardboardcutout_raise_objects->value))) { glTranslatef (0,noegnud_activetileset->glheight,noegnud_activetileset->glheight/2); glRotatef (90, 1, 0, 0); if (noegnud_options_render_features_autoface->value) { glTranslatef ( noegnud_activetileset->glwidth/2, 0,0); glRotatef ((noegnud_options_render_opengl_view_angle_x_current->value+noegnud_render_bullettime_angle), 0, 0, 1); glTranslatef ( -noegnud_activetileset->glwidth/2, 0,0); } glRotatef (-20, 1, 0, 0); } noegnud_render_map_single_tile (noegnud_map[x][y].tile_fore,1); } } } glEnable(GL_DEPTH_TEST); } if (noegnud_options_render_opengl_lighting_method->value==NOEGNUD_RENDER_LIGHTING_METHOD_CHEAP) { glDisable(GL_LIGHTING); } for (y = ys; y != ye; y+=yd) { ny = -(y - (noegnud_render_middle_y)); for (x = xs; x != xe; x+=xd) { nx = x - (noegnud_render_middle_x); if ((noegnud_activetileset->iso)&&(y >= noegnud_clip_y)&&(!((x == noegnud_clip_x) && (y == noegnud_clip_y)))&&(!glyph_is_object(noegnud_map[x][y].glyph_primary))&&(!glyph_is_monster(noegnud_map[x][y].glyph_primary))&&(sqrt((noegnud_clip_y-y)*(noegnud_clip_y-y)+(noegnud_clip_x-x)*(noegnud_clip_x-x))<3)) { current_alpha=0.3; } else { current_alpha=1.0; } glPopMatrix (); glPushMatrix (); glTranslatef ((noegnud_activetileset->xdeltax) * (nx) + (noegnud_activetileset->ydeltax) * (ny) + noegnud_render_offset_x, 0, -((noegnud_activetileset->xdeltay) * (nx) + (noegnud_activetileset->ydeltay) * (ny)) + noegnud_render_offset_y); glBegin(GL_LINES); glEnd(); if (((noegnud_render_mouse_map_x-1)==x)&&(noegnud_render_mouse_map_y==y)) { glColor4f(0.25,1.0,0.25,1.0); } else if ((x == noegnud_clip_x) && (y == noegnud_clip_y)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,current_alpha); } else if (iflags.hilite_pet&&(noegnud_map[x][y].glyph_primary!=MAX_GLYPH)&&(noegnud_map[x][y].special_primary & MG_PET)) { glColor4f(noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,noegnud_render_highlight_strobe/2+0.5,current_alpha); } else { glColor4f(1.0,1.0,1.0,current_alpha); } if (noegnud_map[x][y].glyph_fore != MAX_GLYPH) { if ((x==(u.ux-1)&&y==u.uy)&&(!noegnud_activetileset->iso)&&Levitation) { if (noegnud_map[x][y].low) { glTranslatef(0,noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); } glTranslatef(0,noegnud_activetileset->glheight/2,0); } if (noegnud_map[x][y].low&&(!noegnud_activetileset->iso)) glTranslatef(0,-noegnud_activetileset->glheight*noegnud_options_render_features_cardboardcutout_hole_depth->value,0); if (noegnud_options_render_features_cardboardcutout->value&&((glyph_is_monster(noegnud_map[x][y].glyph_fore)&&noegnud_options_render_features_cardboardcutout_raise_monsters->value)||(glyph_is_object(noegnud_map[x][y].glyph_fore)&&noegnud_options_render_features_cardboardcutout_raise_objects->value))) { glTranslatef (0,noegnud_activetileset->glheight,noegnud_activetileset->glheight/2); glRotatef (90, 1, 0, 0); if (noegnud_options_render_features_autoface->value) { glTranslatef ( noegnud_activetileset->glwidth/2, 0,0); glRotatef ((noegnud_options_render_opengl_view_angle_x_current->value+noegnud_render_bullettime_angle), 0, 0, 1); glTranslatef ( -noegnud_activetileset->glwidth/2, 0,0); } glRotatef (-20, 1, 0, 0); } noegnud_render_map_single_tile (noegnud_map[x][y].tile_fore,1); } } } if (noegnud_options_render_features_cardboardcutout->value) glEnable(GL_CULL_FACE); } else { if (noegnud_options_render_opengl_lighting_method->value==NOEGNUD_RENDER_LIGHTING_METHOD_CHEAP) { glDisable(GL_LIGHTING); } } }
boolean check_flood_anyroom(int x, int y, schar fg_typ, boolean anyroom) { if (!isok(x,y)) return FALSE; return (anyroom ? IS_ROOM(levl[x][y].typ) : levl[x][y].typ == fg_typ); }
/* * 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); }
/* * 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; }