Wearing backup - TADS3.1

I want my player to be able to only ‘wear’ a backpack and not be able to ‘take’ or ‘get’ it; using a command such as ‘wear pack’. The pack will be initially in a large wooden box. I know it’s an easy problem but I’ve been doing my research and manual reading and can’t find the answer to solve it.

Could use some help, once again.

RonG

Depending on which you want to do you could either remap Take to wear using

dobjFor(Take) remapTo (Wear)

Or failing that if you want to make it so the player can’t pick it up you could use

dobjFor(Take)
   {
   action()
      {
      "You don't think the backpack will fit in your pockets very well";
      }
   }

I haven’t tried either of those but they should work fine though you could try using this instead of action()

   check()
      {
      illogicalAlready ('You don't think the backpack will fit in your pockets very well');
      }

Hope that helps :slight_smile:

That usage of remapTo won’t work. What you want is:

dobjFor(Take) asDobjFor(Wear)

The remapTo macro is used when you want the action to be applied to a different object. As such, it requires both an action name and the intended object (or, if it’s a TIAction, both the direct object and the indirect object). You could do this, I suppose:

dobjFor(Take) remapTo (Wear, self)

…but it looks dodgy to me. I wouldn’t want to try it.

My mistake, I glanced at a bit of code I had on screen and assumed it was the right bit.

I knew it was one or the other :slight_smile: thanks for clearing that up

I’m sorry to say that none of the suggestions I received for wearing the pack worked :unamused: :unamused:
I did notice that when I use ‘wear pack’, the response says (first taking the pack) and then it says that I am now wearing the pack. That’s probably what is causing the problem. Perhaps, some type of ‘if’ statement will assure that the game will only accept a ‘wear pack’ command.

So, I’m still looking for ideas. What I need is some type of ‘worn/wear only’ condition for the pack instead of an 'alwaysWorn ’ condition. I’m still checking the manuals.

RonG

The problem with dobjFor(Take) asDobjFor(Wear) is that wear will use an implicit take to satisfy the objHeld precondition, with unfortunate but amusing results.

There are several ways to break the circularity. Here is one:

+ backpack: Wearable 'backpack' 'backpack'
	"A backpack. "
	
	dobjFor(Take) {
		action() {
			inherited();
			makeWornBy(gActor);
			mainReport(&okayWearMsg);
		}
	}

	dobjFor(Doff) {
		action() {
			inherited();
			gActor.getDropDestination(self, nil).receiveDrop(self, dropTypeDrop);
			mainReport(&okayDoffMsg);
		}
	}

	dobjFor(Wear) asDobjFor(Take)
	dobjFor(Drop) asDobjFor(Doff)
;

Produces this output:

If this doesn’t work for you, you’ll need to post the full code for your backpack object.

Since you only want to be able to wear it but not take it, let’s disallow taking it:

dobjFor(Take)
{
    check()
    {
        "It's not for the taking. You can wear it though. ";
        exit;
    }
}

Now to deal with the “wear” action’s precondition that objects must be held before being worn. By default, the Wearable class has this:

preCond = [objHeld]

in its dobjFor(Wear) handler. You need to remove that precondition for your backpack. However, removing it means that you can wear it without taking it (duh!), which in turn means that after you wear it, the backpack is still located in the room rather than in the player. So you need to move it into the player manually now:

dobjFor(Wear)
{
    // By default, objects must be held before being worn. We don't want that in this case.
    preCond = [];
        
    action()
    {
        // Move the backpack into the player.
        self.moveInto(gPlayerChar);
        // Continue with whatever this action would have done by default.
        inherited();
    }
}

This does what you want. However, now you need to think about what happens when the player tries to remove (doff) the backpack. By default, it will doff it and leave it the player’s inventory. I assume this is not what you want? Do you want to drop the backpack in this case, or disallow removing it completely? In both cases, you will need to provide that behavior in the backpack’s dobjFor(Doff) handler (which also has a default precondition, namely “preCond = [roomToHoldObj]”.)

The Wearable class is defined in objects.t, btw, where you can see what happens by default.

I tried using the code by bcressey but it didn’t work correctly. When I compiled it, I got a bunch of warnings. However, The game ran but when I tried anything but wearing the pack, an inventory told me that I was ‘holding’ the pack. Go figure! Perhaps some checking code it the beginning of the pack code should tell me that I should ‘wear’ the pack rather than take (etc.) it.

At any rate, I’ve included my code.

backpack : BagOfHolding, Attachable, Wearable, OpenableContainer
'pack/backpack' 'backpack'
"It is a standard military backpack, allowing a sleeping bag to be attached to
 it at the bottom. Its large main compartment can be opened or closed from the
 top, and, if you wear this pack, you can store many objects in it, allowing you
 to possess a much larger number of items than if you carried them in your
 hands. "  
 location = box.subContainer
 bulkCapacity = 3000
 minBulk = 1
 dobjFor(Wear)
  {
     action()
   { 
     "You sling the pack over your sholders. ";  
      wearpackAchievement.awardPointsOnce();
      inherited;
   }
  }
 wearpackAchievement : Achievement { +5 "wearing the backpack"}
;

You probably tripped over the + before the backpack object. It will be easier to give you compatible code if you post yours first.

backpack: BagOfHolding, Attachable, Wearable, OpenableContainer
	'standard military pack/backpack' 'backpack'
	"It is a standard military backpack, allowing a sleeping bag to be attached
	to it at the bottom. Its large main compartment can be opened or closed from
	the top, and, if you wear this pack, you can store many objects in it,
	allowing you to possess a much larger number of items than if you carried
	them in your hands. " 

	location = box.subContainer
	bulkCapacity = 3000
	minBulk = 1
	
	dobjFor(Take) {
		action() {
			inherited();
			makeWornBy(gActor);
			"You sling the pack over your shoulders. ";
			wearpackAchievement.awardPointsOnce();
		}
	}

	dobjFor(Doff) {
		action() {
			inherited();
			gActor.getDropDestination(self, nil).receiveDrop(self, dropTypeDrop);
			mainReport(&okayDoffMsg);
		}
	}

	dobjFor(Wear) asDobjFor(Take)
	dobjFor(Drop) asDobjFor(Doff)

	wearpackAchievement : Achievement { +5 "wearing the backpack"}
;

This should be a drop-in replacement for the code you posted.

That last post did it. I spent hours on this and can’t thank all of you enough for the help.

RonG