BagOfHolding (adv3lite)

The library code for BagOfHolding only concerns itself with the player character’s bulkCapacity … and stepping through the code, I can’t even see where it does that. I would also like it to concern itself with the number of items the PC is holding in her hands (let’s say 5 or 7), not just the PC’s bulkCapacity. If the PC is already holding 7 items including the Bag, then taking more items should ideally shift the oldest inventory items into the Bag (provided the Bag’s affinityFor(obj) allows it).

I have not the faintest idea how to do this. Can anyone suggest a way to approach it? At what point does the library check the bulkCapacity of gPlayerChar? If I knew that, possibly I could modify the library code to do what I need it to do.

I can slap together a short sample game, if anyone can volunteer to test this and offer suggestions.

In thing.t there is a method checkRoomToHold() in which (apart from other things) is:

        /*
         *   If the BagOfHolding class is defined and the actor doesn't have
         *   enough spare bulk capacity, see if the BagOfHolding class can deal
         *   with it by moving something to a BagOfHolding.
         */
        if(defined(BagOfHolding)
           && bulk > gActor.bulkCapacity - gActor.getCarriedBulk
           && BagOfHolding.tryHolding(self));

You could modify Thing class to write your own version of checkRoomToHold rewriting the condition to:

        if(defined(BagOfHolding)
           && (bulk > gActor.bulkCapacity - gActor.getCarriedBulk || 1 > gActor.countCapacity - gActor.getCarriedCount)
           && BagOfHolding.tryHolding(self));

And adding countCapacity and getCarriedCount to actor:

    countCapacity = 5
    getCarriedCount()
    {
        local totalCount = 0;
        foreach(local cur in directlyHeld)
        {
            totalCount++;
        }

        return totalCount;
    }

And similar changes to BagOfHolding’s method tryHolding(obj), ie. adding this next to same statment about bulk:

        local countToFree = gActor.getCarriedCount + 1 - gActor.countCapacity;

while((bulkToFree > 0 || countToFree > 0) && carriedList.length >= idx)

countToFree = gActor.getCarriedCount + 1 - gActor.countCapacity;

Untested. Btw. instead of stepping through the code in debugger try to fulltext search the library code.

Thanks for the suggestion. It doesn’t work, however. The bag of holding ends up not being utilized at all, no matter how many items I pick up.

After stepping through in the debugger, I think the problem is this: Once your modified code has detected a problem (too many objects being held), the library goes off to decide what to put in the bag of holding based on bulk. The library decides that bulkToFree is -55, so it doesn’t move anything.

Indeed, the PC still has plenty of spare bulk! So the bag is not used.

This is in the tryHolding(obj) method in BagOfHolding. There’s a pretty complicated while loop in that code. I’m nervous about trying to modify it, but I’ll give it a try. Any suggestions you might have would be appreciated!

Most of the “complicated” things in while loop is trying to find proper bag. No worry, just try those three lines in last code box. Before while loop you need to realize how much you need to free your hands based on count (put first line after bulkToFree), then you need to modify while condition to free hands not only wen too much bulk but also too much count (second line to replace original condition) and third line is to add near end of while where bulkToFree is recalculated.

In case of problems drop me a minimal working example and I’ll tune it for you.

Ah, I missed the third bit of your code! Sorry about the confusion. That does seem to be working – many thanks. Oddly enough, adding a modified tryHolding(obj) to my shoppingBag object itself doesn’t work. I have to modify the class itself. This is probably because when tryHolding(obj) is called, the code hasn’t yet decided which BagOfHolding to use.

I haven’t noticed this first time but the tiny difference lies in comment of that method. It’s a “class method”, ie. static function associated with the class itself and not with any specific object instance. In thing.t it is called as BagOfHolding.tryHolding(self); That’s like a PresentLater.makePresentByKey(‘some key’); in adv3, which you also call on class itself. These kind of methods are extremely rare in TADS.