pay for the unpaid contents of a container without itemizing, and for the container itself if it is unpaid too; returns 0==successfully bought; 1==rejected, message given here; 2=rejected, caller should issue message */
| 2306 | returns 0==successfully bought; 1==rejected, message given here; |
| 2307 | 2=rejected, caller should issue message */ |
| 2308 | staticfn int |
| 2309 | buy_container( |
| 2310 | struct monst *shkp, |
| 2311 | int indx, |
| 2312 | int ibillct, |
| 2313 | Bill *ibill) |
| 2314 | { |
| 2315 | unsigned boid, boids[BILLSZ]; |
| 2316 | int i, j, buy, buycount = 0, boidsct = 0; |
| 2317 | struct eshk *eshkp = ESHK(shkp); |
| 2318 | int ebillct = eshkp->billct; |
| 2319 | struct bill_x *bp; |
| 2320 | struct obj *otmp, *otop, |
| 2321 | *container = ibill[indx].obj; |
| 2322 | unsigned unpaidcontainer = container->unpaid; |
| 2323 | long totalcost = ibill[indx].cost; |
| 2324 | boolean sightunseen = ibill[indx].usedup == UndisclosedContainer |
| 2325 | /* give feedback just for container+contents rather |
| 2326 | than for individiual contents even when those |
| 2327 | contents are known */ |
| 2328 | || ibill[indx].usedup == KnownContainer; |
| 2329 | |
| 2330 | /* check for no-gold first, then for not-enough-gold; feedback is |
| 2331 | different for the two cases */ |
| 2332 | if (insufficient_funds(shkp, container, 0L) |
| 2333 | || insufficient_funds(shkp, container, totalcost)) |
| 2334 | return 1; /* message given by insufficent_funds() */ |
| 2335 | |
| 2336 | /* check for partly intact portion of a not-yet-paid partly used item */ |
| 2337 | for (i = 0; i < ebillct; ++i) { |
| 2338 | bp = &eshkp->bill_p[i]; |
| 2339 | otmp = bp_to_obj(bp); /* ibill[bidx].obj is the container */ |
| 2340 | if (!otmp) { |
| 2341 | impossible("Can't find contained item on shop bill (#%d).", |
| 2342 | bp->bo_id); |
| 2343 | return 2; /* failure; have caller give a generic message */ |
| 2344 | } |
| 2345 | if (otmp->where != OBJ_CONTAINED && !Has_contents(otmp)) |
| 2346 | continue; |
| 2347 | /* otmp is contained, but possibly inside a different container */ |
| 2348 | for (otop = otmp; otop->where == OBJ_CONTAINED; |
| 2349 | otop = otop->ocontainer) |
| 2350 | continue; /* where==OBJ_CONTAINED loop */ |
| 2351 | if (otop != container) |
| 2352 | continue; /* 'i' loop */ |
| 2353 | /* now check for partly intact portion of partly used item */ |
| 2354 | if (otmp->quan < bp->bquan) { |
| 2355 | reject_purchase(shkp, otmp, bp->bquan); |
| 2356 | return 1; /* message given by reject_purchase() */ |
| 2357 | } |
| 2358 | /* record this for the second pass; unless it's the container--that |
| 2359 | will be deferred until after the loop so that it will be last */ |
| 2360 | if (bp->bo_id != container->o_id) |
| 2361 | boids[boidsct++] = bp->bo_id; |
| 2362 | } |
| 2363 | if (unpaidcontainer) |
| 2364 | boids[boidsct++] = container->o_id; |
| 2365 |
no test coverage detected