Esempio n. 1
0
/* Mark locations that are temporarily lit via mobile light sources. */
void do_light_sources(char **cs_rows)
{
    int x, y, min_x, max_x, max_y, offset;
    const char *limits;
    short at_hero_range = 0;
    light_source *ls;
    char *row;

    for (ls = level->lev_lights; ls; ls = ls->next) {
	ls->flags &= ~LSF_SHOW;

	/*
	 * Check for moved light sources.  It may be possible to
	 * save some effort if an object has not moved, but not in
	 * the current setup -- we need to recalculate for every
	 * vision recalc.
	 */
	if (ls->type == LS_OBJECT) {
	    if (get_obj_location((struct obj *) ls->id, &ls->x, &ls->y, 0))
		ls->flags |= LSF_SHOW;
	} else if (ls->type == LS_MONSTER) {
	    if (get_mon_location((struct monst *) ls->id, &ls->x, &ls->y, 0))
		ls->flags |= LSF_SHOW;
	}

	/* minor optimization: don't bother with duplicate light sources */
	/* at hero */
	if (ls->x == u.ux && ls->y == u.uy) {
	    if (at_hero_range >= ls->range)
		ls->flags &= ~LSF_SHOW;
	    else
		at_hero_range = ls->range;
	}

	if (ls->flags & LSF_SHOW) {
	    /*
	     * Walk the points in the circle and see if they are
	     * visible from the center.  If so, mark'em.
	     *
	     * Kevin's tests indicated that doing this brute-force
	     * method is faster for radius <= 3 (or so).
	     */
	    limits = circle_ptr(ls->range);
	    if ((max_y = (ls->y + ls->range)) >= ROWNO) max_y = ROWNO-1;
	    if ((y = (ls->y - ls->range)) < 0) y = 0;
	    for (; y <= max_y; y++) {
		row = cs_rows[y];
		offset = limits[abs(y - ls->y)];
		if ((min_x = (ls->x - offset)) < 0) min_x = 0;
		if ((max_x = (ls->x + offset)) >= COLNO) max_x = COLNO-1;

		if (ls->x == u.ux && ls->y == u.uy) {
		    /*
		     * If the light source is located at the hero, then
		     * we can use the COULD_SEE bits already calcualted
		     * by the vision system.  More importantly than
		     * this optimization, is that it allows the vision
		     * system to correct problems with clear_path().
		     * The function clear_path() is a simple LOS
		     * path checker that doesn't go out of its way
		     * make things look "correct".  The vision system
		     * does this.
		     */
		    for (x = min_x; x <= max_x; x++)
			if (row[x] & COULD_SEE)
			    row[x] |= TEMP_LIT;
		} else {
		    for (x = min_x; x <= max_x; x++)
			if ((ls->x == x && ls->y == y)
				|| clear_path((int)ls->x, (int) ls->y, x, y))
			    row[x] |= TEMP_LIT;
		}
	    }
	}
    }
}
Esempio n. 2
0
/* Mark locations that are temporarily lit via mobile light sources. */
void
do_light_sources(char **cs_rows)
{
    int x, y, min_x, max_x, max_y, offset;
    const char *limits;
    short at_hero_range = 0;
    light_source *ls;
    char *row;

    for (ls = level->lev_lights; ls; ls = ls->next) {
        ls->flags &= ~LSF_SHOW;

        /* 
         * Check for moved light sources.  It may be possible to
         * save some effort if an object has not moved, but not in
         * the current setup -- we need to recalculate for every
         * vision recalc.
         */
        if (ls->type == LS_OBJECT) {
            if (get_obj_location((struct obj *)ls->id, &ls->x, &ls->y, 0))
                ls->flags |= LSF_SHOW;
        } else if (ls->type == LS_MONSTER) {
            if (get_mon_location((struct monst *)ls->id, &ls->x, &ls->y, 0))
                ls->flags |= LSF_SHOW;
        }

        /* minor optimization: don't bother with duplicate light sources at
           hero */
        if (ls->x == u.ux && ls->y == u.uy) {
            if (at_hero_range >= ls->range)
                ls->flags &= ~LSF_SHOW;
            else
                at_hero_range = ls->range;
        }

        if (ls->flags & LSF_SHOW) {
            /* 
             * Walk the points in the circle and see if they are
             * visible from the center.  If so, mark'em.
             *
             * Kevin's tests indicated that doing this brute-force
             * method is faster for radius <= 3 (or so).
             */
            limits = circle_ptr(ls->range);
            if ((max_y = (ls->y + ls->range)) >= ROWNO)
                max_y = ROWNO - 1;
            if ((y = (ls->y - ls->range)) < 0)
                y = 0;
            for (; y <= max_y; y++) {
                row = cs_rows[y];
                offset = limits[abs(y - ls->y)];
                if ((min_x = (ls->x - offset)) < 0)
                    min_x = 0;
                if ((max_x = (ls->x + offset)) >= COLNO)
                    max_x = COLNO - 1;

                for (x = min_x; x <= max_x; x++)
                    if (clear_path((int)ls->x, (int)ls->y, x, y, cs_rows))
                        row[x] |= TEMP_LIT;
            }
        }
    }
}