Example #1
0
/* copy the light source(s) attachted to src, and attach it/them to dest */
void obj_split_light_source(struct obj *src, struct obj *dest)
{
    light_source *ls, *new_ls;

    for (ls = level->lev_lights; ls; ls = ls->next)
	if (ls->type == LS_OBJECT && ls->id == src) {
	    /*
	     * Insert the new source at beginning of list.  This will
	     * never interfere us walking down the list - we are already
	     * past the insertion point.
	     */
	    new_ls = malloc(sizeof(light_source));
	    *new_ls = *ls;
	    if (Is_candle(src)) {
		/* split candles may emit less light than original group */
		ls->range = candle_light_range(src);
		new_ls->range = candle_light_range(dest);
		vision_full_recalc = 1;	/* in case range changed */
	    }
	    new_ls->id = dest;
	    new_ls->next = level->lev_lights;
	    level->lev_lights = new_ls;
	    dest->lamplit = 1;		/* now an active light source */
	}
}
Example #2
0
/*
 * Create a dummy duplicate to put on shop bill.  The duplicate exists
 * only in the billobjs chain.  This function is used when a shop object
 * is being altered, and a copy of the original is needed for billing
 * purposes.  For example, when eating, where an interruption will yield
 * an object which is different from what it started out as; the "I x"
 * command needs to display the original object.
 *
 * The caller is responsible for checking otmp->unpaid and
 * costly_spot(u.ux, u.uy).  This function will make otmp no charge.
 *
 * Note that check_unpaid_usage() should be used instead for partial
 * usage of an object.
 */
void bill_dummy_object(struct obj *otmp)
{
	struct obj *dummy;

	if (otmp->unpaid)
	    subfrombill(otmp, shop_keeper(level, *u.ushops));
	dummy = newobj(otmp->oxlth + otmp->onamelth);
	*dummy = *otmp;
	dummy->where = OBJ_FREE;
	dummy->o_id = flags.ident++;
	if (!dummy->o_id) dummy->o_id = flags.ident++;	/* ident overflowed */
	dummy->timed = 0;
	if (otmp->oxlth)
	    memcpy(dummy->oextra,
			otmp->oextra, otmp->oxlth);
	if (otmp->onamelth)
	    strncpy(ONAME(dummy), ONAME(otmp), (int)otmp->onamelth);
	if (Is_candle(dummy)) dummy->lamplit = 0;
	addtobill(dummy, FALSE, TRUE, TRUE);
	otmp->no_charge = 1;
	otmp->unpaid = 0;
	return;
}
Example #3
0
/* Candlelight is proportional to the number of candles;
   minimum range is 2 rather than 1 for playability. */
int
candle_light_range(struct obj *obj)
{
    int radius;

    if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
        /* 
         *      The special candelabrum emits more light than the
         *      corresponding number of candles would.
         *       1..3 candles, range 2 (minimum range);
         *       4..6 candles, range 3 (normal lamp range);
         *          7 candles, range 4 (bright).
         */
        radius = (obj->spe < 4) ? 2 : (obj->spe < 7) ? 3 : 4;
    } else if (Is_candle(obj)) {
        /* 
         *      Range is incremented by powers of 7 so that it will take
         *      wizard mode quantities of candles to get more light than
         *      from a lamp, without imposing an arbitrary limit.
         *       1..6   candles, range 2;
         *       7..48  candles, range 3;
         *      49..342 candles, range 4; &c.
         */
        long n = obj->quan;

        radius = 1;     /* always incremented at least once */
        do {
            radius++;
            n /= 7L;
        } while (n > 0L);
    } else {
        /* we're only called for lit candelabrum or candles */
        /* impossible("candlelight for %d?", obj->otyp); */
        radius = 3;     /* lamp's value */
    }
    return radius;
}