示例#1
0
/* drop one object taken from a (possibly dead) monster's inventory */
static void mdrop_obj(struct monst *mon, struct obj *obj, boolean verbosely)
{
    int omx = mon->mx, omy = mon->my;

    if (obj->owornmask) {
	/* perform worn item handling if the monster is still alive */
	if (mon->mhp > 0) {
	    mon->misc_worn_check &= ~obj->owornmask;
	    update_mon_intrinsics(level, mon, obj, FALSE, TRUE);
	 /* obj_no_longer_held(obj); -- done by place_object */
	    if (obj->owornmask & W_WEP) setmnotwielded(mon, obj);
	/* don't charge for an owned saddle on dead steed */
	} else if (mon->mtame && (obj->owornmask & W_SADDLE) && 
		!obj->unpaid && costly_spot(omx, omy)) {
	    obj->no_charge = 1;
	}
	obj->owornmask = 0L;
    }
    if (verbosely && cansee(omx, omy))
	pline("%s drops %s.", Monnam(mon), distant_name(obj, doname));
    if (!flooreffects(obj, omx, omy, "fall")) {
	place_object(obj, level, omx, omy);
	stackobj(obj);
    }
}
示例#2
0
/* drop one object taken from a (possibly dead) monster's inventory */
static void mdrop_obj (struct monst *mon, struct obj *obj, bool verbosely) {
    int omx = mon->mx, omy = mon->my;

    if (obj->owornmask) {
        /* perform worn item handling if the monster is still alive */
        if (mon->mhp > 0) {
            mon->misc_worn_check &= ~obj->owornmask;
            update_mon_intrinsics(mon, obj, false, true);
            /* obj_no_longer_held(obj); -- done by place_object */
            if (obj->owornmask & W_WEP) setmnotwielded(mon, obj);
            /* don't charge for an owned saddle on dead steed */
        } else if (mon->mtame && (obj->owornmask & W_SADDLE) &&
                !obj->unpaid && costly_spot(omx, omy)) {
            obj->no_charge = 1;
        }
        obj->owornmask = 0L;
    }
    if (verbosely && cansee(omx, omy)) {
        message_monster_object(MSG_M_DROPS_O, mon, obj);
    }
    if (!flooreffects(obj, omx, omy, "fall")) {
        place_object(obj, omx, omy);
        stackobj(obj);
    }
}
示例#3
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);
}
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);
}
示例#5
0
文件: lock.c 项目: FredrIQ/fiqhack
/* Called every turn during chest-forcing. The caller must set
   u.utracked[tos_lock] to the chest in question. */
static int
forcelock(void)
{
    struct monst *shkp;
    boolean costly;

    struct obj *otmp;
    struct obj *box = u.utracked[tos_lock];

    if (!obj_with_u(box))
        return reset_pick();

    if (!uwep_can_force()) /* prints the messages; ensures uwep != NULL */
        return reset_pick();

    if (u.uoccupation_progress[tos_lock]++ >= 50 ||
         nohands(youmonst.data)) {
        pline(msgc_failrandom, "You give up your attempt to force the lock.");
        if (!nohands(youmonst.data))
            exercise(is_blade(uwep) ? A_DEX : A_STR, TRUE);
        return reset_pick();
    }

    if (is_blade(uwep)) {
        if (rn2(1000 - (int)uwep->spe) > (992 - greatest_erosion(uwep) * 10) &&
            !uwep->cursed && !obj_resists(uwep, 0, 99)) {
            /* for a +0 weapon, probability that it survives an unsuccessful
               attempt to force the lock is (.992)^50 = .67 */
            pline(msgc_substitute, "%sour %s broke!",
                  (uwep->quan > 1L) ? "One of y" : "Y", xname(uwep));
            useup(uwep);
            pline_implied(msgc_failcurse,
                          "You can't exactly force that lock now.");
            exercise(A_DEX, TRUE);
            return reset_pick();
        }
    } else      /* blunt */
        wake_nearby(FALSE);  /* due to hammering on the container */

    if (rn2(100) >= objects[uwep->otyp].oc_wldam * 2)
        return 1;       /* still busy */

    pline(msgc_actionok, "You succeed in forcing the lock.");
    box->olocked = 0;
    box->obroken = 1;
    costly = (*u.ushops && costly_spot(youmonst.mx, youmonst.my));
    shkp = costly ? shop_keeper(level, *u.ushops) : 0;
    if (!is_blade(uwep) && !rn2(3)) {
        long loss = 0L;

        pline(msgc_substitute, "In fact, you've totally destroyed %s.",
              the(xname(box)));

        /* Put the contents on ground at the hero's feet. */
        while ((otmp = box->cobj) != 0) {
            obj_extract_self(otmp);
            if (!rn2(3) || otmp->oclass == POTION_CLASS) {
                chest_shatter_msg(otmp);
                if (costly)
                    loss +=
                        stolen_value(otmp, youmonst.mx, youmonst.my,
                                     (boolean) shkp->mpeaceful, TRUE);
                if (otmp->quan == 1L) {
                    obfree(otmp, NULL);
                    continue;
                }
                useup(otmp);
            }
            if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
                otmp->age = moves - otmp->age;  /* actual age */
                start_corpse_timeout(otmp);
            }
            place_object(otmp, level, youmonst.mx, youmonst.my);
            stackobj(otmp);
        }

        if (costly)
            loss +=
                stolen_value(box, youmonst.mx, youmonst.my, (boolean) shkp->mpeaceful,
                             TRUE);
        if (loss)
            pline(msgc_unpaid, "You owe %ld %s for objects destroyed.",
                  loss, currency(loss));
        delobj(box);
    } else {
        if (costly) {
            struct obj *cobjbak = box->cobj;

            box->cobj = (struct obj *)0;
            verbalize(msgc_unpaid, "You damage it, you bought it!");
            bill_dummy_object(box);
            box->cobj = cobjbak;
        }
    }
    exercise(is_blade(uwep) ? A_DEX : A_STR, TRUE);

    return reset_pick();
}