do something with object (drop, pick up, eat) at current position * returns 1 if object eaten (since that counts as dog's move), 2 if died */
| 397 | * returns 1 if object eaten (since that counts as dog's move), 2 if died |
| 398 | */ |
| 399 | staticfn int |
| 400 | dog_invent(struct monst *mtmp, struct edog *edog, int udist) |
| 401 | { |
| 402 | coordxy omx, omy; |
| 403 | int carryamt = 0; |
| 404 | struct obj *obj, *otmp; |
| 405 | |
| 406 | if (helpless(mtmp) || mtmp->meating) |
| 407 | return 0; |
| 408 | |
| 409 | omx = mtmp->mx; |
| 410 | omy = mtmp->my; |
| 411 | |
| 412 | /* If we are carrying something then we drop it (perhaps near @). |
| 413 | * Note: if apport == 1 then our behavior is independent of udist. |
| 414 | * Use udist+1 so steed won't cause divide by zero. |
| 415 | */ |
| 416 | if (droppables(mtmp)) { |
| 417 | assert(edog->apport > 0); |
| 418 | if (!rn2(udist + 1) || !rn2(edog->apport)) |
| 419 | if (rn2(10) < edog->apport) { |
| 420 | relobj(mtmp, (int) mtmp->minvis, TRUE); |
| 421 | if (edog->apport > 1) |
| 422 | edog->apport--; |
| 423 | edog->dropdist = udist; /* hpscdi!jon */ |
| 424 | edog->droptime = svm.moves; |
| 425 | } |
| 426 | } else { |
| 427 | if ((obj = svl.level.objects[omx][omy]) != 0 |
| 428 | && !strchr(nofetch, obj->oclass) |
| 429 | #ifdef MAIL_STRUCTURES |
| 430 | && obj->otyp != SCR_MAIL |
| 431 | #endif |
| 432 | /* avoid special items; once hero picks them up, they'll cease |
| 433 | being special and become eligible for normal monst activity */ |
| 434 | && !(is_mines_prize(obj) || is_soko_prize(obj))) { |
| 435 | int edible = dogfood(mtmp, obj); |
| 436 | |
| 437 | if ((edible <= CADAVER |
| 438 | /* starving pet is more aggressive about eating */ |
| 439 | || (edog->mhpmax_penalty && edible == ACCFOOD)) |
| 440 | && could_reach_item(mtmp, obj->ox, obj->oy)) |
| 441 | return dog_eat(mtmp, obj, omx, omy, FALSE); |
| 442 | |
| 443 | carryamt = can_carry(mtmp, obj); |
| 444 | if (carryamt > 0 && !obj->cursed |
| 445 | && could_reach_item(mtmp, obj->ox, obj->oy)) { |
| 446 | if (rn2(20) < edog->apport + 3) { |
| 447 | if (rn2(udist) || !rn2(edog->apport)) { |
| 448 | otmp = obj; |
| 449 | if (carryamt != obj->quan) |
| 450 | otmp = splitobj(obj, carryamt); |
| 451 | if (cansee(omx, omy)) { |
| 452 | /* call distant_name() for possible side-effects |
| 453 | even if the result won't be printed; should be |
| 454 | done before extract+pickup for distant_name() |
| 455 | -> doname() -> xname() -> find_artifact() |
| 456 | while otmp is still on floor */ |
no test coverage detected