pick a carried item for pet to drop */
| 25 | |
| 26 | /* pick a carried item for pet to drop */ |
| 27 | struct obj * |
| 28 | droppables(struct monst *mon) |
| 29 | { |
| 30 | /* |
| 31 | * 'key|pickaxe|&c = &dummy' is used to make various creatures |
| 32 | * that can't use a key/pick-axe/&c behave as if they are already |
| 33 | * holding one so that any other such item in their inventory will |
| 34 | * be considered a duplicate and get treated as a normal candidate |
| 35 | * for dropping. |
| 36 | * |
| 37 | * This could be 'auto', but then 'gcc -O2' warns that this function |
| 38 | * might return the address of a local variable. It's mistaken, |
| 39 | * &dummy is never returned. 'static' is simplest way to shut it up. |
| 40 | */ |
| 41 | static struct obj dummy; |
| 42 | struct obj *obj, *wep, *pickaxe, *unihorn, *key; |
| 43 | |
| 44 | dummy = cg.zeroobj; |
| 45 | dummy.otyp = GOLD_PIECE; /* not STRANGE_OBJECT or tools of interest */ |
| 46 | dummy.oartifact = 1; /* so real artifact won't override "don't keep it" */ |
| 47 | pickaxe = unihorn = key = (struct obj *) 0; |
| 48 | wep = MON_WEP(mon); |
| 49 | |
| 50 | if (is_animal(mon->data) || mindless(mon->data)) { |
| 51 | /* won't hang on to any objects of these types */ |
| 52 | pickaxe = unihorn = key = &dummy; /* act as if already have them */ |
| 53 | } else { |
| 54 | /* don't hang on to pick-axe if can't use one or don't need one */ |
| 55 | if (!tunnels(mon->data) || !needspick(mon->data)) |
| 56 | pickaxe = &dummy; |
| 57 | /* don't hang on to key if can't open doors */ |
| 58 | if (nohands(mon->data) || verysmall(mon->data)) |
| 59 | key = &dummy; |
| 60 | } |
| 61 | if (wep) { |
| 62 | if (is_pick(wep)) |
| 63 | pickaxe = wep; |
| 64 | if (wep->otyp == UNICORN_HORN) |
| 65 | unihorn = wep; |
| 66 | /* don't need any wielded check for keys... */ |
| 67 | } |
| 68 | |
| 69 | for (obj = mon->minvent; obj; obj = obj->nobj) { |
| 70 | switch (obj->otyp) { |
| 71 | case DWARVISH_MATTOCK: |
| 72 | /* reject mattock if couldn't wield it */ |
| 73 | if (which_armor(mon, W_ARMS)) |
| 74 | break; |
| 75 | /* keep mattock in preference to pick unless pick is already |
| 76 | wielded or is an artifact and mattock isn't */ |
| 77 | if (pickaxe && pickaxe->otyp == PICK_AXE && pickaxe != wep |
| 78 | && (!pickaxe->oartifact || obj->oartifact)) |
| 79 | return pickaxe; /* drop the one we earlier decided to keep */ |
| 80 | FALLTHROUGH; |
| 81 | /*FALLTHRU*/ |
| 82 | case PICK_AXE: |
| 83 | if (!pickaxe || (obj->oartifact && !pickaxe->oartifact)) { |
| 84 | if (pickaxe) |
no test coverage detected