예제 #1
0
파일: engrave.c 프로젝트: DanielT/NitroHack
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;
}
예제 #2
0
파일: engrave.c 프로젝트: DanielT/NitroHack
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";
}
예제 #3
0
static void trv_door_startopen (void)
{
  FAR struct trv_rect_data_s *rect;

  /* Check if a door is already opening */

  if (g_opendoor.state == DOOR_IDLE)
    {
      /* Test if there is a door within three steps in front of the player */
      /* Try the X planes first */

      rect = trv_ray_test_xplane(&g_player, 3*STEP_DISTANCE,
                                 g_player.yaw, g_player_height);

      /* If there is no X door in front of the player, then try the Y Planes
       * (it is assumed that there would not be doors this close in both
       * planes!)
       */

      if (!rect || !IS_DOOR(rect))
        {
          rect = trv_ray_test_yplane(&g_player, 3*STEP_DISTANCE,
                                     g_player.yaw, g_player_height);
        }

      /* Check if we found a door in either the X or Y plane. */

      if (rect && IS_DOOR(rect))
        {
          /* We now have found a door to open.  Set the door open sequence
           * in motion
           */

          g_opendoor.rect    = rect;
          g_opendoor.state   = DOOR_OPENING;
          g_opendoor.zbottom = rect->vstart;
          g_opendoor.zdist   = 0;

          /* Mark the door's attribute to indicate that it is in motion */

          rect->attribute |= MOVING_DOOR_PLANE;
        }
    }
}
예제 #4
0
파일: play.c 프로젝트: Grimy/ChoregraphAI
// Pretty-prints the tile at the given position.
static void display_tile(Coords pos)
{
	Tile *tile = &TILE(pos);

	int light = shadowed(pos) ? 0 :
		L2(pos - player.pos) <= player.radius ? 7777 :
		min(tile->light, 7777);
	printf("\033[38;5;%dm", 232 + light / 338);
	print_at(pos, tile_glyphs[tile->type]);

	if (IS_DIGGABLE(pos) && !IS_DOOR(pos))
		display_wall(pos);
	if (IS_WIRE(pos) && !IS_DOOR(pos))
		display_wire(pos);
	if (tile->item)
		print_at(pos, item_glyphs[tile->item]);
	if (!tile->revealed)
		print_at(pos, " ");
}
예제 #5
0
STATIC_OVL boolean
iswall(int x, int y)
{
    register int type;

    if (!isok(x,y)) return FALSE;
    type = levl[x][y].typ;
    return (IS_WALL(type) || IS_DOOR(type) ||
            type == SDOOR || type == IRONBARS);
}
예제 #6
0
STATIC_OVL boolean
iswall_or_stone(int x, int y)
{
    register int type;

    /* out of bounds = stone */
    if (!isok(x,y)) return TRUE;

    type = levl[x][y].typ;
    return (type == STONE || IS_WALL(type) || IS_DOOR(type) ||
            type == SDOOR || type == IRONBARS);
}
예제 #7
0
bool 
nexttodoor (int sx, int sy)
{
        int dx, dy;
        struct rm *lev;
        for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) {
                if(!isok(sx+dx, sy+dy)) continue;
                if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
                    lev->typ == SDOOR)
                        return(true);
        }
        return(false);
}
예제 #8
0
boolean
nexttodoor(struct level * lev, int sx, int sy)
{
    int dx, dy;
    struct rm *loc;

    for (dx = -1; dx <= 1; dx++)
        for (dy = -1; dy <= 1; dy++) {
            if (!isok(sx + dx, sy + dy))
                continue;
            if (IS_DOOR((loc = &lev->locations[sx + dx][sy + dy])->typ) ||
                loc->typ == SDOOR)
                return TRUE;
        }
    return FALSE;
}
예제 #9
0
/*
 * 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;
}
예제 #10
0
파일: lock.c 프로젝트: FredrIQ/fiqhack
/* try to close a door */
int
doclose(const struct nh_cmd_arg *arg)
{
    struct rm *door;
    struct monst *mtmp;
    coord cc;
    schar dx, dy, dz;

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You can't close anything -- you have no hands!");
        return 0;
    }

    if (u.utrap && u.utraptype == TT_PIT) {
        pline(msgc_cancelled, "You can't reach over the edge of the pit.");
        return 0;
    }

    if (!getargdir(arg, NULL, &dx, &dy, &dz))
        return 0;

    cc.x = youmonst.mx + dx;
    cc.y = youmonst.my + dy;
    if (!isok(cc.x, cc.y))
        return 0;

    if ((cc.x == youmonst.mx) && (cc.y == youmonst.my)) {
        pline(msgc_cancelled1, "You are in the way!");
        return 1;
    }

    if ((mtmp = m_at(level, cc.x, cc.y)) && mtmp->m_ap_type == M_AP_FURNITURE &&
        (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) &&
        !Protection_from_shape_changers) {

        stumble_onto_mimic(mtmp, dx, dy);
        return 1;
    }

    door = &level->locations[cc.x][cc.y];

    if (!IS_DOOR(door->typ)) {
        if (door->typ == DRAWBRIDGE_DOWN)
            pline(msgc_cancelled,
                  "There is no obvious way to close the drawbridge.");
        else
            pline(msgc_mispaste, "You %s no door there.",
                  Blind ? "feel" : "see");
        return 0;
    }

    if (door->doormask == D_NODOOR) {
        pline(msgc_cancelled, "This doorway has no door.");
        return 0;
    }

    if (obstructed(cc.x, cc.y, msgc_cancelled))
        return 0;

    if (door->doormask == D_BROKEN) {
        pline(msgc_cancelled, "This door is broken.");
        return 0;
    }

    if (door->doormask & (D_CLOSED | D_LOCKED)) {
        pline(msgc_cancelled, "This door is already closed.");
        return 0;
    }

    if (door->doormask == D_ISOPEN) {
        if (verysmall(youmonst.data) && !u.usteed) {
            pline(msgc_cancelled, "You're too small to push the door closed.");
            return 0;
        }
        if (u.usteed ||
            rn2(25) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
            pline(msgc_actionok, "The door closes.");
            door->doormask = D_CLOSED;
            door->mem_door_l = 1;
            /* map_background here sets the mem_door flags correctly; and it's
               redundant to both feel_location and newsym with a door.
               Exception: if we remember an invisible monster on the door
               square, but in this case, we want to set the memory of a door
               there anyway because we know there's a door there because we
               just closed it, and in Nitro this doesn't clash with keeping the 
               I there. */
            map_background(cc.x, cc.y, TRUE);
            if (Blind)
                feel_location(cc.x, cc.y);   /* the hero knows she closed it */
            else
                newsym(cc.x, cc.y);
            block_point(cc.x, cc.y);    /* vision: no longer see there */
        } else {
            exercise(A_STR, TRUE);
            pline(msgc_failrandom, "The door resists!");
        }
    }

    return 1;
}
예제 #11
0
파일: lock.c 프로젝트: FredrIQ/fiqhack
/* try to open a door */
int
doopen(const struct nh_cmd_arg *arg)
{
    coord cc;
    struct rm *door;
    struct monst *mtmp;
    schar dx, dy, dz;

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You can't open, close, or unlock anything "
              "-- you have no hands!");
        return 0;
    }

    if (u.utrap && u.utraptype == TT_PIT) {
        pline(msgc_cancelled, "You can't reach over the edge of the pit.");
        return 0;
    }

    if (!getargdir(arg, NULL, &dx, &dy, &dz))
        return 0;

    cc.x = youmonst.mx + dx;
    cc.y = youmonst.my + dy;
    if (!isok(cc.x, cc.y))
        return 0;

    if ((cc.x == youmonst.mx) && (cc.y == youmonst.my))
        return 0;

    if ((mtmp = m_at(level, cc.x, cc.y)) && mtmp->m_ap_type == M_AP_FURNITURE &&
        (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) &&
        !Protection_from_shape_changers) {

        stumble_onto_mimic(mtmp, cc.x - youmonst.mx, cc.y - youmonst.my);
        return 1;
    }

    door = &level->locations[cc.x][cc.y];

    if (!IS_DOOR(door->typ)) {
        if (is_db_wall(cc.x, cc.y)) {
            pline(msgc_cancelled,
                  "There is no obvious way to open the drawbridge.");
            return 0;
        }
        pline(msgc_mispaste, "You %s no door there.", Blind ? "feel" : "see");
        return 0;
    }

    if (door->doormask == D_ISOPEN) {
        struct nh_cmd_arg newarg;
        arg_from_delta(dx, dy, dz, &newarg);
        return doclose(&newarg);
    }

    if (!(door->doormask & D_CLOSED)) {
        const char *mesg;

        switch (door->doormask) {
        case D_BROKEN:
            mesg = " is broken";
            break;
        case D_NODOOR:
            mesg = "way has no door";
            break;
        case D_ISOPEN:
            mesg = " is already open";
            break;
        default:
            if (last_command_was("open") && door->mem_door_l) {

                /* With the "open" command given explicitly (rather than
                   implicitly via doorbumping), unlock the door. */
                struct obj *bestpick = get_current_unlock_tool();
                struct nh_cmd_arg newarg;

                arg_from_delta(dx, dy, dz, &newarg);
                if (!bestpick)
                    pline(msgc_cancelled,
                          "You have nothing to unlock that with.");
                else if (!bestpick->lastused)
                    /* not msgc_controlhelp, or many players would get
                       no message */
                    pline(msgc_hint,
                          "Use an unlocking tool manually so I know "
                          "which one you want to use.");
                else
                    return pick_lock(bestpick, &newarg);
            }
            door->mem_door_l = 1;
            map_background(cc.x, cc.y, TRUE);
            mesg = " is locked";
            break;
        }
        pline(msgc_cancelled, "This door%s.", mesg);
        if (Blind)
            feel_location(cc.x, cc.y);
        return 0;
    }

    if (verysmall(youmonst.data)) {
        pline(msgc_cancelled, "You're too small to pull the door open.");
        return 0;
    }

    /* door is known to be CLOSED */
    if (rnl(20) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
        pline(msgc_actionok, "The door opens.");
        if (door->doormask & D_TRAPPED) {
            b_trapped("door", FINGER);
            door->doormask = D_NODOOR;
            if (*in_rooms(level, cc.x, cc.y, SHOPBASE))
                add_damage(cc.x, cc.y, 0L);
        } else
            door->doormask = D_ISOPEN;
        if (Blind)
            feel_location(cc.x, cc.y);  /* the hero knows she opened it */
        else
            newsym(cc.x, cc.y);
        unblock_point(cc.x, cc.y);      /* vision: new see through there */
    } else {
        exercise(A_STR, TRUE);
        door->mem_door_l = 1;
        map_background(cc.x, cc.y, TRUE);
        pline(msgc_failrandom, "The door resists!");
    }

    return 1;
}
예제 #12
0
파일: lock.c 프로젝트: FredrIQ/fiqhack
/* pick a lock on a chest or door with a given object */
int
pick_lock(struct obj *pick, const struct nh_cmd_arg *arg)
{
    int picktyp, c;
    coord cc;
    schar dx, dy, dz;
    struct rm *door;
    struct obj *otmp;
    const char *qbuf;

    if (!getargdir(arg, NULL, &dx, &dy, &dz))
        return 0;
    cc.x = youmonst.mx + dx;
    cc.y = youmonst.my + dy;
    if (!isok(cc.x, cc.y))
        return 0;

    picktyp = pick->otyp;
    pick->lastused = moves;

    /* Check whether we're resuming an interrupted previous attempt.  For a
       floor pick, we have u.utracked[tos_lock] as a non-zeroobj and dx and dy
       as 0.  For a door, we have u.utracked_location[tl_lock] specifying the
       location and u.utracked[tos_lock] as &zeroobj. */
    if (u.uoccupation_progress[tos_lock] &&
        ((u.utracked_location[tl_lock].x == cc.x &&
          u.utracked_location[tl_lock].y == cc.y &&
          u.utracked[tos_lock] == &zeroobj) ||
         (dx == 0 && dy == 0 && u.utracked[tos_lock] != &zeroobj))) {
        static const char no_longer[] =
            "Unfortunately, you can no longer %s %s.";

        if (nohands(youmonst.data)) {
            const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";

            if (picktyp == CREDIT_CARD)
                what = "card";
            pline(msgc_interrupted, no_longer, "hold the", what);
            return reset_pick();
        } else if (u.utracked[tos_lock] != &zeroobj && !can_reach_floor()) {
            pline(msgc_interrupted, no_longer, "reach the", "lock");
            return reset_pick();
        } else {
            const char *action = lock_action();

            if (turnstate.continue_message)
                pline(msgc_occstart, "You resume your attempt at %s.", action);

            one_occupation_turn(picklock, "picking the lock", occ_lock);
            return 1;
        }
    }

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You can't hold %s -- you have no hands!",
              doname(pick));
        return 0;
    }

    if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD &&
         picktyp != SKELETON_KEY)) {
        impossible("picking lock with object %d?", picktyp);
        return 0;
    }

    if (!dx && !dy) { /* pick lock on a container */
        const char *verb;
        boolean it;
        int count;

        if (dz < 0) {
            pline(msgc_cancelled, "There isn't any sort of lock up %s.",
                  Levitation ? "here" : "there");
            return 0;
        } else if (is_lava(level, youmonst.mx, youmonst.my)) {
            pline(msgc_cancelled, "Doing that would probably melt your %s.",
                  xname(pick));
            return 0;
        } else if (is_pool(level, youmonst.mx, youmonst.my) && !Underwater) {
            /* better YAFM - AIS */
            pline(msgc_cancelled,
                  "Canals might have locks, but this water doesn't.");
            return 0;
        }

        count = 0;
        c = 'n';        /* in case there are no boxes here */
        for (otmp = level->objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
            if (Is_box(otmp)) {
                ++count;
                if (!can_reach_floor()) {
                    pline(msgc_cancelled, "You can't reach %s from up here.",
                          the(xname(otmp)));
                    return 0;
                }
                it = 0;
                if (otmp->obroken)
                    verb = "fix";
                else if (!otmp->olocked)
                    verb = "lock", it = 1;
                else if (picktyp != LOCK_PICK)
                    verb = "unlock", it = 1;
                else
                    verb = "pick";
                qbuf = msgprintf(
                    "There is %s here, %s %s?",
                    safe_qbuf("",
                              sizeof ("There is  here, unlock its lock?"),
                              doname(otmp), an(simple_typename(otmp->otyp)),
                              "a box"), verb, it ? "it" : "its lock");

                c = ynq(qbuf);
                if (c == 'q')
                    return 0;
                if (c == 'n')
                    continue;

                if (otmp->obroken) {
                    pline(msgc_cancelled,
                          "You can't fix its broken lock with %s.",
                          doname(pick));
                    return 0;
                } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
                    /* credit cards are only good for unlocking */
                    pline(msgc_cancelled, "You can't do that with %s.",
                          doname(pick));
                    return 0;
                }

                u.utracked[tos_lock] = otmp;
                u.uoccupation_progress[tos_lock] = 0;
                break;
            }
        if (c != 'y') {
            if (!count)
                pline(msgc_cancelled,
                      "There doesn't seem to be any sort of lock here.");
            return 0;   /* decided against all boxes */
        }
    } else {    /* pick the lock in a door */
        struct monst *mtmp;

        if (u.utrap && u.utraptype == TT_PIT) {
            pline(msgc_cancelled,
                  "You can't reach over the edge of the pit.");
            return 0;
        }

        door = &level->locations[cc.x][cc.y];
        if ((mtmp = m_at(level, cc.x, cc.y)) && canseemon(mtmp)) {
            if (picktyp == CREDIT_CARD &&
                (mx_eshk(mtmp) || mtmp->data == &mons[PM_ORACLE]))
                verbalize(msgc_npcvoice, "No checks, no credit, no problem.");
            else
                pline(msgc_mispaste, "I don't think %s would appreciate that.",
                      mon_nam(mtmp));
            return 0;
        }
        if (mtmp && (mtmp->m_ap_type == M_AP_FURNITURE) &&
            (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) &&
            !Protection_from_shape_changers) {
            stumble_onto_mimic(mtmp, dx, dy);
            return 1;
        }
        if (!IS_DOOR(door->typ)) {
            if (is_drawbridge_wall(cc.x, cc.y) >= 0)
                pline(msgc_cancelled, "You %s no lock on the drawbridge.",
                      Blind ? "feel" : "see");
            else
                pline(msgc_mispaste, "You %s no door there.",
                      Blind ? "feel" : "see");
            return 0;
        }
        switch (door->doormask) {
        case D_NODOOR:
            pline(msgc_cancelled, "This doorway has no door.");
            return 0;
        case D_ISOPEN:
            pline(msgc_cancelled, "You cannot lock an open door.");
            return 0;
        case D_BROKEN:
            pline(msgc_cancelled, "This door is broken.");
            return 0;
        default:
            /* credit cards are only good for unlocking */
            if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
                pline(msgc_cancelled,
                      "You can't lock a door with a credit card.");
                return 0;
            }

            /* At this point, the player knows that the door is a door, and
               whether it's locked, but not whether it's trapped; to do this,
               we set the mem_door_l flag and call map_background, which will
               clear it if necessary (i.e. not a door after all). */
            level->locations[cc.x][cc.y].mem_door_l = 1;
            map_background(cc.x, cc.y, TRUE);

            u.utracked[tos_lock] = &zeroobj;
            u.utracked_location[tl_lock] = cc;
            u.uoccupation_progress[tos_lock] = 0;
        }
    }

    one_occupation_turn(picklock, "picking the lock", occ_lock);
    return 1;
}
예제 #13
0
파일: priest.c 프로젝트: FredrIQ/nhfourk
/* when attacking "priest" in his temple */
void
ghod_hitsu(struct monst *priest)
{
    int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
    struct mkroom *troom;

    if (!roomno || !has_shrine(priest))
        return;

    ax = x = CONST_EPRI(priest)->shrpos.x;
    ay = y = CONST_EPRI(priest)->shrpos.y;
    troom = &level->rooms[roomno - ROOMOFFSET];

    if ((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
        if (IS_DOOR(level->locations[u.ux][u.uy].typ)) {

            if (u.ux == troom->lx - 1) {
                x = troom->hx;
                y = u.uy;
            } else if (u.ux == troom->hx + 1) {
                x = troom->lx;
                y = u.uy;
            } else if (u.uy == troom->ly - 1) {
                x = u.ux;
                y = troom->hy;
            } else if (u.uy == troom->hy + 1) {
                x = u.ux;
                y = troom->ly;
            }
        } else {
            switch (rn2(4)) {
            case 0:
                x = u.ux;
                y = troom->ly;
                break;
            case 1:
                x = u.ux;
                y = troom->hy;
                break;
            case 2:
                x = troom->lx;
                y = u.uy;
                break;
            default:
                x = troom->hx;
                y = u.uy;
                break;
            }
        }
        if (!linedup(u.ux, u.uy, x, y))
            return;
    }

    switch (rn2(3)) {
    case 0:
        pline("%s roars in anger:  \"Thou shalt suffer!\"", a_gname_at(ax, ay));
        break;
    case 1:
        pline("%s voice booms:  \"How darest thou harm my servant!\"",
              s_suffix(a_gname_at(ax, ay)));
        break;
    default:
        pline("%s roars:  \"Thou dost profane my shrine!\"",
              a_gname_at(ax, ay));
        break;
    }

    /* bolt of lightning */
    buzz(-10 - (AD_ELEC - 1), 6, x, y, sgn(tbx), sgn(tby), 0);
}
예제 #14
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);
	}
    }
}
예제 #15
0
static void trv_ray_ycaster34(FAR struct trv_raycast_s *result)
{
  struct trv_rect_list_s *list; /* Points to the current P plane rectangle */
  struct trv_rect_data_s *rect; /* Points to the rectangle data */
  trv_coord_t rely;             /* Relative position of the Y plane */
  trv_coord_t absx;             /* Absolute X position at rely given yaw */
  trv_coord_t absz;             /* Absolute Z position at rely given pitch */
  trv_coord_t lastrely1 = -1;   /* Last relative Y position processed */
  trv_coord_t lastrely2 = -1;   /* Last relative Y position processed */
  int32_t dxdy;                 /* Rate of change of X wrt Y (double) */
  int32_t dzdy;                 /* Rate of change of Z wrt Y (double) */

  /* At a viewing angle of 180 degrees, no intersections with the line x = bXi
   * are possible!
   */

  if (g_camera.yaw == ANGLE_180)
    {
      return;
    }

  /* Pre-calculate the rate of change of X and Z with respect to Y */
  /* The negative inverted tangent is equal to the rate of change of X with
   * respect to the Y-axis.  The cotangent is stored at double the the
   * "normal" scaling.
   */

  dxdy = -g_cot_table(g_camera.yaw - ANGLE_180);

  /* Determine the rate of change of the Z with respect to Y.  The tangent
   * is "double" precision; the cosecant is "double" precision.  dzdy will
   * be retained as "double" precision.
   */

  dzdy = qTOd(g_adj_tanpitch * ABS(g_csc_table[g_camera.yaw]));

  /* Look at every rectangle lying in a Y plane */
  /* This logic should be improved at some point so that non-visible planes
   * are "pruned" from the list prior to ray casting!
   */

  for (list = g_ray_yplane.tail; list; list = list->blink)
    {
      rect = &list->d;

      /* Search for a rectangle which lies "before" the current camera
       * position
       */

      if (rect->plane < g_camera.y)
        {
          /* get the Y distance to the plane */

          rely = g_camera.y - rect->plane;

          /* g_ray_yplane is an ordered list, if we have already hit something
           * closer, then we can abort the casting now.
           */

          if (rely > result->ydist)
            {
              return;
            }

          /* Calculate the Y position at this relative X position.  We can skip
           * this step if we are processing another rectangle at the same relx
           * distance.
           */

           if (rely != lastrely1)
            {
              int32_t deltax;  /* Scale == "triple" */

              /* The dxdy is stored at double the"normal" scaling -- so deltax
               * is "triple" precision
               */

              deltax    = dxdy * ((int32_t) rely);
              absx      = tTOs(deltax) + g_camera.x; /* back to "single" */
              lastrely1 = rely;
            }

          /* Check if this X position intersects the rectangle */

          if (absx >= rect->hstart && absx <= rect->hend)
            {

              /* The X position lies in the rectangle.  Now, calculate the
               * Z position at this relative X position.  We can skip this
               * step if we are processing another rectangle at the same
               * relx distance.
               */

              if (rely != lastrely2)
                {
                  int32_t deltaz;      /* Scale == TRIPLE */

                  /* The dzdy is stored at double the"normal" scaling -- so
                   * deltaz is "triple" precision
                   */

                  deltaz    = dzdy * ((int32_t) rely);
                  absz      = tTOs(deltaz) + g_camera.z; /* Back to single */
                  lastrely2 = rely;
                }

              /* Check if this Z position intersects the rectangle */

              if (absz >= rect->vstart && absz <= rect->vend)
                {

                  /* We've got a potential hit, let's see what it is */
                  /* Check if we just hit an ordinary opaque wall */

                  if (IS_NORMAL(rect))
                    {
                      /* Yes..Save the parameters associated with the normal
                       * wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                      result->xpos = absx;
                      result->ypos = absz;

                      result->xdist = ABS(absx - g_camera.x);
                      result->ydist = rely;
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate Y casting */

                      return;
                    }
                  else if (IS_DOOR(rect))
                    {
                      /* Check if the door is in motion. */

                      if (!IS_MOVING_DOOR(rect))
                        {
                          /* Save the parameters associated with the normal
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                          result->xpos = absx;
                          result->ypos = absz;

                          result->xdist = ABS(absx - g_camera.x);
                          result->ydist = rely;
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate Y casting */

                          return;
                        }

                      /* The door is in motion, the Z-position to see if we can
                       * see under the door
                       */

                      else if (absz > g_opendoor.zbottom)
                        {
                          /* Save the parameters associated with the moving
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                          result->xpos = absx;
                          result->ypos = absz - g_opendoor.zdist;

                          result->xdist = ABS(absx - g_camera.x);
                          result->ydist = rely;
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate Y casting */

                          return;
                        }
                    }

                  /* Otherwise, it must be a transparent wall.  We'll need to
                   * make our decision based upon the pixel that we hit
                   */

                  /* Check if the pixel at this location is visible */

                  else if (GET_BACK_PIXEL(rect, absx, absz) != INVISIBLE_PIXEL)
                    {
                      /* Its visible, save the parameters associated with the
                       * transparent wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                      result->xpos = absx;
                      result->ypos = absz;

                      result->xdist = ABS(absx - g_camera.x);
                      result->ydist = rely;
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate Y casting */

                      return;
                    }
                }
            }
        }
    }
}
예제 #16
0
static void trv_ray_xcaster14(FAR struct trv_raycast_s *result)
{
  struct trv_rect_list_s *list; /* Points to the current X plane rectangle */
  struct trv_rect_data_s *rect; /* Points to the rectangle data */
  trv_coord_t relx;             /* Relative position of the X plane */
  trv_coord_t absy;             /* Absolute Y position at relx given yaw */
  trv_coord_t absz;             /* Absolute Z position at relx given pitch */
  trv_coord_t lastrelx1 = -1;   /* Last relative X position processed */
  trv_coord_t lastrelx2 = -1;   /* Last relative X position processed */
  int32_t dydx;                 /* Rate of change of Y wrt X (double) */
  int32_t dzdx;                 /* Rate of change of Z wrt X (double) */

  /* At a viewing angle of 270 degrees, no intersections with the g_ray_xplanes
   * are possible!
   */

  if (g_camera.yaw == ANGLE_270)
    {
      return;
    }

  /* Pre-calculate the rate of change of Y and Z with respect to X */
  /* The tangent is equal to the rate of change of Y with respect to the
   * X-axis.  The tangent is stored at double the "normal" scaling.
   */

  dydx = TAN(g_camera.yaw);

  /* Determine the rate of change of the Z with respect to X. The tangent is
   * "double" precision; the secant is "double" precision.  dzdx will be
   * retained as "double" precision.
   */

  dzdx = qTOd(g_adj_tanpitch * ABS(g_sec_table[g_camera.yaw]));

  /* Look at every rectangle lying in the X plane */
  /* This logic should be improved at some point so that non-visible planes
   * are "pruned" from the list prior to ray casting!
   */

  for (list = g_ray_xplane.head; list; list = list->flink)
    {
      rect = &list->d;

      /* Search for a rectangle which lies "beyond" the current camera
       * position
       */

      if (rect->plane > g_camera.x)
        {
          /* get the X distance to the plane */

          relx = rect->plane - g_camera.x;

#if 0
          /* g_ray_xplane is an ordered list, if we have already hit something
           * closer, then we can abort the casting now.
           */

          if (relx > result->xdist)
            {
              return;
            }
#endif

          /* Calculate the Y position at this relative X position.  We can skip
           * this step if we are processing another rectangle at the same relx
           * distance.
           */

          if (relx != lastrelx1)
            {
              int32_t deltay;  /* Scale == "triple" */

              /* The dydx is stored at double the"normal" scaling -- so
               * deltay is "triple" precision
               */

              deltay    = dydx * ((int32_t) relx);
              absy      = tTOs(deltay) + g_camera.y; /* back to "single" */
              lastrelx1 = relx;
            }

          /* Check if this Y position intersects the rectangle */

          if (absy >= rect->hstart && absy <= rect->hend)
            {
              /* The Y position lies in the rectangle.  Now, calculate the
               * theZ position at this relative X position.  We can skip
               * this step if we are processing another rectangle at the
               * same relx distance.
               */

              if (relx != lastrelx2)
                {
                  int32_t deltaz;      /* Scale == TRIPLE */

                  /* The dzdx is stored at double the"normal" scaling -- so
                   * deltaz is "triple" precision
                   */

                  deltaz    = dzdx * ((int32_t) relx);
                  absz      = tTOs(deltaz) + g_camera.z; /* Back to single */
                  lastrelx2 = relx;
                }

              /* Check if this Z position intersects the rectangle */

              if (absz >= rect->vstart && absz <= rect->vend)
                {
                  /* We've got a potential hit, let's see what it is */
                  /* Check if we just hit an ordinary opaque wall */

                  if (IS_NORMAL(rect))
                    {
                      /* Yes..Save the parameters associated with the normal
                       * wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                      result->xpos = absy;
                      result->ypos = absz;

                      result->xdist = relx;
                      result->ydist = ABS(absy - g_camera.y);
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate X casting */

                      return;
                    }
                  else if (IS_DOOR(rect))
                    {
                      /* Check if the door is in motion. */

                      if (!IS_MOVING_DOOR(rect))
                        {
                          /* Save the parameters associated with the normal
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                          result->xpos = absy;
                          result->ypos = absz;

                          result->xdist = relx;
                          result->ydist = ABS(absy - g_camera.y);
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate X casting */

                          return;
                        }

                      /* The door is in motion, the Z-position to see if we can
                       * see under the door
                       */

                      else if (absz > g_opendoor.zbottom)
                        {
                          /* Save the parameters associated with the moving
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                          result->xpos = absy;
                          result->ypos = absz - g_opendoor.zdist;

                          result->xdist = relx;
                          result->ydist = ABS(absy - g_camera.y);
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate X casting */

                          return;
                        }
                    }

                  /* Otherwise, it must be a transparent wall.  We'll need to
                   * make our decision based upon the pixel that we hit
                   */

                  /* Check if the pixel at this location is visible */

                  else if (GET_FRONT_PIXEL(rect, absy, absz) != INVISIBLE_PIXEL)
                    {
                      /* Its visible, save the parameters associated with the
                       * transparent wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                      result->xpos = absy;
                      result->ypos = absz;

                      result->xdist = relx;
                      result->ydist = ABS(absy - g_camera.y);
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate X casting */

                      return;
                    }
                }
            }
        }
    }
}