try to find the stack obj was split from, then merge them back together; returns the combined object if unsplit is successful, null otherwise */
| 553 | /* try to find the stack obj was split from, then merge them back together; |
| 554 | returns the combined object if unsplit is successful, null otherwise */ |
| 555 | struct obj * |
| 556 | unsplitobj(struct obj *obj) |
| 557 | { |
| 558 | unsigned target_oid = 0; |
| 559 | struct obj *oparent = 0, *ochild = 0, *list = 0; |
| 560 | |
| 561 | /* |
| 562 | * We don't operate on floor objects (we're following o->nobj rather |
| 563 | * than o->nexthere), on free objects (don't know which list to use when |
| 564 | * looking for obj's parent or child), on bill objects (too complicated, |
| 565 | * not needed), or on buried or migrating objects (not needed). |
| 566 | * [This could be improved, but at present additional generality isn't |
| 567 | * necessary.] |
| 568 | */ |
| 569 | switch (obj->where) { |
| 570 | case OBJ_FREE: |
| 571 | case OBJ_FLOOR: |
| 572 | case OBJ_ONBILL: |
| 573 | case OBJ_MIGRATING: |
| 574 | case OBJ_BURIED: |
| 575 | default: |
| 576 | return (struct obj *) 0; |
| 577 | case OBJ_INVENT: |
| 578 | list = gi.invent; |
| 579 | break; |
| 580 | case OBJ_MINVENT: |
| 581 | list = obj->ocarry->minvent; |
| 582 | break; |
| 583 | case OBJ_CONTAINED: |
| 584 | list = obj->ocontainer->cobj; |
| 585 | break; |
| 586 | } |
| 587 | |
| 588 | /* first try the expected case; obj is split from another stack */ |
| 589 | if (obj->o_id == svc.context.objsplit.child_oid) { |
| 590 | /* parent probably precedes child and will require list traversal */ |
| 591 | ochild = obj; |
| 592 | target_oid = svc.context.objsplit.parent_oid; |
| 593 | if (obj->nobj && obj->nobj->o_id == target_oid) |
| 594 | oparent = obj->nobj; |
| 595 | } else if (obj->o_id == svc.context.objsplit.parent_oid) { |
| 596 | /* alternate scenario: another stack was split from obj; |
| 597 | child probably follows parent and will be found here */ |
| 598 | oparent = obj; |
| 599 | target_oid = svc.context.objsplit.child_oid; |
| 600 | if (obj->nobj && obj->nobj->o_id == target_oid) |
| 601 | ochild = obj->nobj; |
| 602 | } |
| 603 | /* if we have only half the split, scan obj's list to find other half */ |
| 604 | if (ochild && !oparent) { |
| 605 | /* expected case */ |
| 606 | for (obj = list; obj; obj = obj->nobj) |
| 607 | if (obj->o_id == target_oid) { |
| 608 | oparent = obj; |
| 609 | break; |
| 610 | } |
| 611 | } else if (oparent && !ochild) { |
| 612 | /* alternate scenario */ |
no test coverage detected