One object, multiple containers

Is there a straightforward(-ish) way to handle having an object be in multiple, non-nested containers at once?

Think about a large object in a warehouse—a boat, a tractor, whatever—covered by multiple tarps.

And if a container is the wrong way to approach this, what’s a different way to get “container-like” effects (blocking sense paths and so on)?

In this specific example it could be faked with a bunch of conditionals on either the tarp objects or on the boat/tractor/whatever object, but I’m more interested in a general solution.

Hm. I’m not sure I understand how the fooPresence flags on Thing work.

#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>

startRoom:      Room 'Warehouse'
        "This is a warehouse containing a boat. "
;
+me:    Person;
+boat: Thing, Heavy 'boat' 'boat'
        "A boat. "
        touchPresence = nil
;

versionInfo:    GameID
        name = 'sample'
        byline = 'nobody'
        authorEmail = 'nobody <foo@bar.com>'
        desc = '[This space intentionally left blank]'
        version = '1.0'
        IFID = '12345'
;
gameMain: GameMainDef initialPlayerChar = me ;

…implements (barely) a boat whose touchPresence is nil. But:

Warehouse
This is a warehouse containing a boat.

>touch boat
You feel nothing out of the ordinary.

…which is not what I’d expect. On the other hand, if you add sightPresence = nil, then:

Warehouse
This is a warehouse containing a boat.

>x boat
You see no boat here.

…which is what I’d expect to happen.

You can of course get it to report whatever you want by adding something like:

        dobjFor(Feel) {
                verify() { illogical('Nope. '); }
        }

…to the object definition, but I’m still not sure what twiddling touchPresence accomplishes.

I’ve said in another thread that I couldn’t get what I wanted with twiddling [sense]Presence. I don’t know if they’re used for anything other than generating a senseInfoTableSubset which is used for listing purposes. You can do more tampering with canBeSensed(obj) or (playerChar).senseObj(args).
As a side warning, don’t try to make a Container a MultiLoc! You’ll get stack overflows, unless you find a way to patch the problem.

1 Like

To force an object into scope regardless of usual factors like open/closedness, I’ve used:

me: Person
senseObj(sense,obj) { 
		if(special conditions) {
			local info = new SenseInfo(obj, transparent, nil, 3);
			obj.setVisualSenseInfo(info);
			return info; }
		else return inherited(sense,obj); }

For a toggle, like how I suspect you may be wishing for sightPresence to behave, I’ve done:

modify Thing
	canBeSensed(sense,trans,ambient) { 
		if(sense==sight) return sightCond && inherited(sense,trans,ambient);
		else if(sense==touch) return touchCond && inherited(sense,trans,ambient);
		else return inherited(sense,trans,ambient); }
    sightCond = true
    touchCond = true
    sightPresence = (sightCond && inherited)
    touchPresence = (touchCond && inherited)

where you can then do things like

boat: Thing
    sightCond = !coveredByTarp

or use the sightCond property as a toggle to be set by code statements

As far as the boat example, could MultiFaceted work?

Kinda. You could certainly come up with a solution for that particular problem with MultiFaceted, the problem is that I want a more general solution (because I have a bunch of different situations where I want to do this kind of thing).

Occluder also almost does what I want, but it still ends up involving a bunch of conditional spaghetti in a way that, for example, handling all the sense stuff via Container doesn’t.