can't get code to automatically remove an object

I have an ATM machine on a street corner. Player has a debit card in a wallet. I have code that says if the player puts the debit card in the ATM machine, the ATM machine dispenses five $20 bills which are automatically put into the wallet.

So far, so good, code works.

But as a courtesy to the player, after the money is added to the wallet, I want code that automatically removes the debit card from the ATM and returns it to the wallet. (Yes, I know, it could add complexity if the player is required to remove the card before being allowed to move on. And I may decide that’s a better way to go. But I’d like that decision to be based on game play, not by a coding difficulty.)

The following code segment does work with one exception…


debitCard: Thing 'debit card*cards' 'debit card'
    "A bank-issued debit card"
    dobjFor(PutIn)
    {
        action()
        {
            atmAccount.loadWallet();
            atm.removeFromContents(debitCard);
            debitCard.moveInto(wallet);
        }

    }
;

The atmAccount.loadWallet() method results in the $20 dollar bills being added to the wallet, and debitCard.moveInto(wallet) results in the debit card being placed back in the wallet.

The problem is atm.removeFromContents(debitCard) line. That does not work.

I end up with a debit card in the wallet and a debit card still in the machine…

Street Corner
Corner of the street. There is an ATM in the building’s wall.

Harry sees an atm here. In the wallet, Harry sees a credit card and a debit card.

put debit card in atm
(first taking the debit card)
Done.

look
Street Corner

Corner of the street.
Harry sees an atm (which contains a debit card) here. In the wallet, Harry sees a credit card, five 20 dollar bills, and a debit card.

I am able to remove the debit card in the game window, with “Take debit card from atm.” How can I do that automatically from code so the player doesn’t have to remember to take it out?

Thanks.

Jerry

I think you want to override the iobjFor(PutIn) in the ATM machine, rather than the card’s (or maybe both). My guess is that the machine’s default iobjFor(PutIn) is undoing the hard work you performed in the dobjFor on the card.

You shouldn’t need to call atm.removeFromContents(), since the subsequent call to debitCard.moveInto() should in turn call removeFromContents() on the debit card’s current container.

The problem, however, may lie with however you’ve defined the atm object. I’m guessing you may have defined it as a Container, otherwise PUT DEBIT CARD IN ATM would be ruled out at the verify stage. If that’s the case then iobjFor(PutIn) on the atm will be moving the debit card into the atm, which may be conflicting with your definition of dobjFor(PutIn) on the debit card. I’m not sure how that would cause you to end up with the card apparently in two places at once, but the interaction of dobjFor(PutIn) and iobjFor(PutIn) is the first thing I’d check.

Honestly, I would consider PutIn to be an “alternate” phrasing of the real action, Use Card With Machine (or the otherway around), since you aren’t actually using the actual meaning of the verb, PutIn. I think if you were to do it as Use Machine with Card, you could probably take advantage of TADS magic such that “Use atm” would work as long as you have your card on with you. If you like this idea, you might look into remapTo as a way to make all of those effectively calling the same function.

Also, the code you’ve shown us will cause those things to happen no matter what container the player puts the card in. This is plainly not what you want.

Thanks all.

Got the original problem solved.

(Jim Aiken raises a new issue that I had not considered. I’ll work on it. Meanwhile…)

The earlier suggestions that I focus on the interplay between dobjFor(PutIn) and iobjFor(PutIn) set me on the right trail for getting the card back into the wallet.

By examining what happened in iobjFor(PutIn), I discovered I had layered too many objects in the code.

I had an atm object (a RestrictedContainer), a debitCard object (a Thing), and an atmAccount object (a Dispenser). It was the atmAccount object that was blocking the movement of the card back into the wallet.

The atmAccount object got added as an attempt to solve an earlier problem of the ATM showing its contents as five $20 bills upon examination. (ATMs don’t normally display their contents to passersby.) When I started fiddling with iobjFor(PutIn), I started seeing a message in the game window about not being able to move things through the atmAccount object when the card’s moveInto() method was called.

The problem the atmAccount object was meant to solve went away once I got the right code in place to dynamically create new bills on demand. There no longer was a need for the atmAccount, but there it was, a legacy object silently intercepting the movement of the debit card.

As for “use with,” mignon, I actually like the idea of requiring the user to put the debit card in the machine before it will dispense cash; I just think it’s overkill to then require that it be manually retrieved after the user got the machine to work.

But you are right, I think; “put in” is not really what comes to mind when operating an ATM. More likely, I think, is “insert card into the machine” and a remap is in order. I maybe also should intercept “Use” and give some hint that something needs to be done to the machine before it can be used. Thanks for the tip.

And thanks again all for the help.