/* 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); } }
/* 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); } }
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); }
/* 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(); }