Exemple #1
0
void rloco(struct obj *obj)
{
	xchar tx, ty, otx, oty;
	boolean restricted_fall;
	int try_limit = 4000;

	if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
	    if (revive_corpse(obj)) return;
	}

	obj_extract_self(obj);
	otx = obj->ox;
	oty = obj->oy;
	restricted_fall = (otx == 0 && level->dndest.lx);
	do {
	    tx = rn1(COLNO-3,2);
	    ty = rn2(ROWNO);
	    if (!--try_limit) break;
	} while (!goodpos(level, tx, ty, NULL, 0) ||
		/* bug: this lacks provision for handling the Wizard's tower */
		 (restricted_fall &&
		  (!within_bounded_area(tx, ty, level->dndest.lx, level->dndest.ly,
						level->dndest.hx, level->dndest.hy) ||
		   (level->dndest.nlx &&
		    within_bounded_area(tx, ty, level->dndest.nlx, level->dndest.nly,
						level->dndest.nhx, level->dndest.nhy)))));

	if (flooreffects(obj, tx, ty, "fall")) {
	    return;
	} else if (otx == 0 && oty == 0) {
	    ;	/* fell through a trap door; no update of old loc needed */
	} else {
	    if (costly_spot(otx, oty)
	      && (!costly_spot(tx, ty) ||
		  !strchr(in_rooms(level, tx, ty, 0), *in_rooms(level, otx, oty, 0)))) {
		if (costly_spot(u.ux, u.uy) &&
			    strchr(u.urooms, *in_rooms(level, otx, oty, 0)))
		    addtobill(obj, FALSE, FALSE, FALSE);
		else stolen_value(obj, otx, oty, FALSE, FALSE);
	    }
	    newsym(otx, oty);	/* update old location */
	}
	place_object(obj, level, tx, ty);
	newsym(tx, ty);
}
Exemple #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;
}
void
rloco(struct obj *obj)
{
    int tx, ty, otx, oty;

    otx = obj->ox;
    oty = obj->oy;

    if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
        if (revive_corpse(obj))
            return;
    }

    obj_extract_self(obj);
    rloco_pos(level, obj, &tx, &ty);

    if (flooreffects(obj, tx, ty, "fall")) {
        return;
    } else if (otx == 0 && oty == 0) {
        ;       /* fell through a trap door; no update of old loc needed */
    } else {
        if (costly_spot(otx, oty)
            && (!costly_spot(tx, ty) ||
                !strchr(in_rooms(level, tx, ty, 0),
                        *in_rooms(level, otx, oty, 0)))) {
            if (costly_spot(u.ux, u.uy) &&
                strchr(u.urooms, *in_rooms(level, otx, oty, 0)))
                addtobill(obj, FALSE, FALSE, FALSE);
            else
                stolen_value(obj, otx, oty, FALSE, FALSE);
        }
        newsym(otx, oty);       /* update old location */
    }
    place_object(obj, level, tx, ty);
    newsym(tx, ty);
}
Exemple #4
0
int doeat(void)
{
    struct obj *otmp;
    int tmp;

    // Is there some food (probably a heavy corpse) here on the ground?
    if (!Levitation)
	for (otmp = _level->objects; otmp; otmp = otmp->nobj) {
	    if (otmp->ox == _u.ux && otmp->oy == _u.uy && otmp->olet == FOOD_SYM) {
		pline("There %s %s here; eat %s? [ny] ", (otmp->quan == 1) ? "is" : "are", doname(otmp), (otmp->quan == 1) ? "it" : "one");
		if (readchar() == 'y') {
		    if (otmp->quan != 1)
			(void) splitobj(otmp, 1);
		    freeobj(otmp);
		    otmp = addinv(otmp);
		    addtobill(otmp);
		    goto gotit;
		}
	    }
	}
    otmp = getobj("%", "eat");
    if (!otmp)
	return 0;
  gotit:
    if (otmp->otyp == TIN) {
	if (uwep) {
	    switch (uwep->otyp) {
		case CAN_OPENER:
		    tmp = 1;
		    break;
		case DAGGER:
		    tmp = 3;
		    break;
		case PICK_AXE:
		case AXE:
		    tmp = 6;
		    break;
		default:
		    goto no_opener;
	    }
	    pline("Using your %s you try to open the tin.", aobjnam(uwep, NULL));
	} else {
	  no_opener:
	    pline("It is not so easy to open this tin.");
	    if (Glib) {
		pline("The tin slips out of your hands.");
		if (otmp->quan > 1) {
		    struct obj *obj;

		    obj = splitobj(otmp, 1);
		    if (otmp == uwep)
			setuwep(obj);
		}
		dropx(otmp);
		return 1;
	    }
	    tmp = 10 + rn2(1 + 500 / ((int) (_u.ulevel + _u.ustr)));
	}
	tin.reqtime = tmp;
	tin.usedtime = 0;
	tin.tin = otmp;
	occupation = opentin;
	occtxt = "opening the tin";
	return 1;
    }
    const struct objclass* ftmp = &c_Objects[otmp->otyp];
    multi = -ftmp->oc_delay;
    if (otmp->otyp >= CORPSE && eatcorpse(otmp))
	goto eatx;
    if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
	pline("Blecch!  Rotten food!");
	if (!rn2(4)) {
	    pline("You feel rather light headed.");
	    Confusion += d(2, 4);
	} else if (!rn2(4) && !Blind) {
	    pline("Everything suddenly goes dark.");
	    Blind = d(2, 10);
	    seeoff(0);
	} else if (!rn2(3)) {
	    if (Blind)
		pline("The world spins and you slap against the floor.");
	    else
		pline("The world spins and goes dark.");
	    nomul(-rnd(10));
	    nomovemsg = "You are conscious again.";
	}
	lesshungry(ftmp->nutrition / 4);
    } else {
	if (_u.uhunger >= 1500) {
	    pline("You choke over your food.");
	    pline("You die...");
	    killer = ftmp->oc_name;
	    done("choked");
	}
	switch (otmp->otyp) {
	    case FOOD_RATION:
		if (_u.uhunger <= 200)
		    pline("That food really hit the spot!");
		else if (_u.uhunger <= 700)
		    pline("That satiated your stomach!");
		else {
		    pline("You're having a hard time getting all that food down.");
		    multi -= 2;
		}
		lesshungry(ftmp->nutrition);
		if (multi < 0)
		    nomovemsg = "You finished your meal.";
		break;
	    case TRIPE_RATION:
		pline("Yak - dog food!");
		more_experienced(1, 0);
		_wflags.botl = 1;
		if (rn2(2)) {
		    pline("You vomit.");
		    morehungry(20);
		    if (Sick) {
			Sick = 0;	// David Neves
			pline("What a relief!");
		    }
		} else
		    lesshungry(ftmp->nutrition);
		break;
	    default:
		if (otmp->otyp >= CORPSE)
		    pline("That %s tasted terrible!", ftmp->oc_name);
		else
		    pline("That %s was delicious!", ftmp->oc_name);
		lesshungry(ftmp->nutrition);
		if (otmp->otyp == DEAD_LIZARD && (Confusion > 2))
		    Confusion = 2;
		else if (otmp->otyp == FORTUNE_COOKIE) {
		    if (Blind) {
			pline("This cookie has a scrap of paper inside!");
			pline("What a pity, that you cannot read it!");
		    } else
			print_rumor();
		} else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) {
		    // This stuff seems to be VERY healthy!
		    if (_u.ustrmax < 118)
			++_u.ustrmax;
		    if (_u.ustr < _u.ustrmax)
			++_u.ustr;
		    _u.uhp += rnd(20);
		    if (_u.uhp > _u.uhpmax) {
			if (!rn2(17))
			    ++_u.uhpmax;
			_u.uhp = _u.uhpmax;
		    }
		    heal_legs();
		}
		break;
	}
    }
  eatx:
    if (multi < 0 && !nomovemsg) {
	static char msgbuf[BUFSZ];
	sprintf(msgbuf, "You finished eating the %s.", ftmp->oc_name);
	nomovemsg = msgbuf;
    }
    useup(otmp);
    return 1;
}