Weird spacing

This has been bugging me for a while and I just can’t get it to go away. I have a trunk that the player can also stand on, i.e. a container-supporter, which may be a fool’s errand, I don’t know. The whole source is a little long, so I’m collapsing it and providing what I think is the relevant part below.

Lab is a room. 


The black trunk is a supporter. It is enterable. It is in Lab. It is portable. The description is "This is a large, plain black trunk with steel trim. It latches shut, but doesn't have a locking mechanism.". [The mass is 3. ]Understand "chest" as the black trunk.
The black trunk's inside is a container. It is privately-named. The printed name is "black trunk". It is part of the black trunk.  It is openable and closed. The description is "This is a large, plain black trunk with steel trim. It latches shut, but doesn't have a locking mechanism.".

The black trunk's inside contains a doll.
The player carries a flute and a rubber ball.

Before entering the black trunk:
	if the black trunk's inside is open:
		say "(first closing the black trunk)[command clarification break]";
		silently try closing the black trunk's inside;
	continue the action.
	
Rule for listing contents of the black trunk:
	if something is on the black trunk:
		continue the activity;
	otherwise:
		carry out the listing contents activity with the black trunk's inside;

To write after entry for (O - object):
      (- WriteAfterEntry( {O} ); -).

To write after entry for (O - object) with depth (D - a number):
      (- WriteAfterEntry( {O}, {D} ); -).

Rule for printing room description details for the black trunk when nothing is on the black trunk:
      write after entry for the black trunk's inside.

Rule for printing inventory details for the black trunk:	
	if black trunk's inside is closed:
		say " (closed)";
	otherwise if black trunk's inside is open and black trunk's inside contains nothing:
		say " (open but empty)";
	otherwise:		
		write after entry for the black trunk's inside with depth 0;
	
Understand "black" and "trunk" as the black trunk's inside.

Does the player mean removing from the black trunk when the black trunk's inside is open:
	It is very unlikely.
	
Does the player mean removing from the black trunk when the black trunk's inside is closed:
	It is very likely.

Rule for clarifying the parser's choice of the black trunk: do nothing.
Rule for clarifying the parser's choice of the black trunk's inside: do nothing.
	
Before taking the black trunk when something is on the trunk and the player is not on the trunk:
	say "(first taking [the list of things that are on the black trunk])[command clarification break]";
	Repeat with X running through the list of things that are on the black trunk:
		silently try taking X;
	continue the action;

Instead of opening the black trunk when the player is on the black trunk:
	say "You'll have to get off the black trunk first.";
	
Instead of opening the black trunk when something (called T) is on the black trunk and T is not the player:
	say "(first taking [the list of things that are on the black trunk])[command clarification break]";
	Repeat with X running through the list of things that are on the black trunk:
		silently try taking X;
	continue the action;
 
Instead of opening the black trunk:
	try opening the black trunk's inside;
	
Instead of closing the black trunk:
	try closing the black trunk's inside;
	
Instead of inserting a thing (called T) into the black trunk:
	try inserting T into the black trunk's inside;
	
Instead of putting something (called T) on the black trunk when the black trunk's inside is open:
	if T is enclosed by the trunk:
		carry out the implicitly taking activity with the noun;
	say "(first closing the black trunk)[command clarification break]";
	silently try closing the black trunk's inside;
	continue the action;
	
Instead of examining the black trunk:
	if something is on the black trunk:
		continue the action;
	otherwise:
		try examining the black trunk's inside;
	
Instead of searching the black trunk:
	if something is on the black trunk:
		continue the action;
	otherwise:
		try searching the black trunk's inside;
		

Lab is a room. 


The black trunk is a supporter. It is enterable. It is in Lab. It is portable. The description is "This is a large, plain black trunk with steel trim. It latches shut, but doesn't have a locking mechanism.". [The mass is 3. ]Understand "chest" as the black trunk.
The black trunk's inside is a container. It is privately-named. The printed name is "black trunk". It is part of the black trunk.  It is openable and closed. The description is "This is a large, plain black trunk with steel trim. It latches shut, but doesn't have a locking mechanism.".

The black trunk's inside contains a doll.
The player carries a flute and a rubber ball.

Before entering the black trunk:
	if the black trunk's inside is open:
		say "(first closing the black trunk)[command clarification break]";
		silently try closing the black trunk's inside;
	continue the action.
	
Rule for listing contents of the black trunk:
	if something is on the black trunk:
		continue the activity;
	otherwise:
		carry out the listing contents activity with the black trunk's inside;

To write after entry for (O - object):
      (- WriteAfterEntry( {O} ); -).

Rule for printing room description details for the black trunk when nothing is on the black trunk:
      write after entry for the black trunk's inside.

Rule for printing inventory details for the black trunk:	
	if black trunk's inside is closed:
		say " (closed)";
	otherwise if black trunk's inside is open and black trunk's inside contains nothing:
		say " (open but empty)";
	otherwise:		
		write after entry for the black trunk's inside;

 
Instead of opening the black trunk:
	try opening the black trunk's inside;
	
Instead of closing the black trunk:
	try closing the black trunk's inside;

The issue is how inventory is formatted:


Lab
You can see a black trunk (closed) here.

>take trunk
Taken.

>i
You are carrying:
  a black trunk (closed)
  a flute
  a rubber ball

>open it
You open the black trunk, revealing a doll.

>i
You are carrying:
  a black trunk (open)
    a doll

  a flute
  a rubber ball

>

I’m not at all clear what I can do about the blank line between the trunk contents and the flute listing. Any ideas?

In a related question: is there a decent container-supporter implementation in an extension or otherwise, anywhere? So far I haven’t had any luck on either Google or the intfiction search.

I like the line, as it clearly tells me what’s in the trunk and what I’m just carrying. Is there a reason you want to get rid of it?

1 Like

I don’t object to it on aesthetic grounds. It’s just that the line doesn’t show up for any other container in the game. I’m using the default Inform 7 inventory, which doesn’t put in such a line normally.

The “U-stor-it” example in the documentation has a trunk that serves as both a supporter and a container. The lid (the supporter) is part of the container, instead of the other way around. The inventory listing seems to work better if you do it that way.

But if you do that, and make the lid enterable, and stand on the lid, it seems to behave as if you are inside the closed trunk, and announces that it is dark. I’m not sure why.

You never said that the trunk was supposed to be portable in your last post about this (Print room description details for parts).

There’s (what looks to me like) a small issue with the way that WriteAfterEntry() is constructed: It doesn’t fully defer to an author-supplied for printing inventory details of... rule. You need an I6 inclusion to address it, so hopefully you’re still using 6M62.

Include (-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! ListWriter.i6t: Write After Entry (modified)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

[ WriteAfterEntry o depth
    p recurse_flag parenth_flag eldest_child child_count combo act_flag; ! MODIFIED

    inventory_stage = 2;
    if (c_style & PARTINV_BIT) {
        BeginActivity(PRINTING_ROOM_DESC_DETAILS_ACT, o);
        if (ForActivity(PRINTING_ROOM_DESC_DETAILS_ACT, o) == false) {
		    combo = 0;
		    if (o has light && location hasnt light) combo=combo+1;
		    if (o has container && o hasnt open)     combo=combo+2;
		    if ((o has container && (o has open || o has transparent))
			    && (child(o)==0))                    combo=combo+4;
		    if (combo) LIST_WRITER_INTERNAL_RM('A'); ! space and open bracket
		    switch (combo) {
			    1: LIST_WRITER_INTERNAL_RM('D', o);
			    2: LIST_WRITER_INTERNAL_RM('E', o);
			    3: LIST_WRITER_INTERNAL_RM('H', o);
			    4: LIST_WRITER_INTERNAL_RM('F', o);
			    5: LIST_WRITER_INTERNAL_RM('I', o);
			    6: LIST_WRITER_INTERNAL_RM('G', o);
			    7: LIST_WRITER_INTERNAL_RM('J', o);
		    }
		    if (combo) LIST_WRITER_INTERNAL_RM('B'); ! close bracket
	    }
        EndActivity(PRINTING_ROOM_DESC_DETAILS_ACT, o);
    }   ! end of PARTINV_BIT processing

    if (c_style & FULLINV_BIT) {
        BeginActivity(PRINTING_INVENTORY_DETAILS_ACT, o);
        if ((act_flag = ForActivity(PRINTING_INVENTORY_DETAILS_ACT, o)) == false) { ! MODIFIED
		    if (o has light && o has worn) { LIST_WRITER_INTERNAL_RM('A'); LIST_WRITER_INTERNAL_RM('K', o);  parenth_flag = true; }
		    else {
			    if (o has light)           { LIST_WRITER_INTERNAL_RM('A'); LIST_WRITER_INTERNAL_RM('D', o);  parenth_flag = true; }
			    if (o has worn)            { LIST_WRITER_INTERNAL_RM('A'); LIST_WRITER_INTERNAL_RM('L', o); parenth_flag = true; }
		    }
    
		    if (o has container)
			    if (o has openable) {
				    if (parenth_flag) {
					    #Ifdef SERIAL_COMMA; print ","; #Endif;
					    LIST_WRITER_INTERNAL_RM('C');
				    } else            LIST_WRITER_INTERNAL_RM('A', o);
				    if (o has open)
					    if (child(o)) LIST_WRITER_INTERNAL_RM('M', o);
					    else          LIST_WRITER_INTERNAL_RM('N', o);
				    else
					    if (o has lockable && o has locked) LIST_WRITER_INTERNAL_RM('P', o);
					    else                                LIST_WRITER_INTERNAL_RM('O', o);
				    parenth_flag = true;
			    }
			    else
				    if (child(o)==0 && o has transparent)
					    if (parenth_flag) { LIST_WRITER_INTERNAL_RM('C'); LIST_WRITER_INTERNAL_RM('F'); }
					    else              { LIST_WRITER_INTERNAL_RM('A'); LIST_WRITER_INTERNAL_RM('F'); LIST_WRITER_INTERNAL_RM('B'); }
    
		    if (parenth_flag) LIST_WRITER_INTERNAL_RM('B');
	    }
        EndActivity(PRINTING_INVENTORY_DETAILS_ACT, o);
    }   ! end of FULLINV_BIT processing

    if (act_flag) rtrue;  ! ADDED

    child_count = 0;
    eldest_child = nothing;
    objectloop (p in o)
	    if ((c_style & CONCEAL_BIT == 0) || (ConcealedFromLists(p) == false))
		    if (p has list_filter_permits) {
			    child_count++;
			    if (eldest_child == nothing) eldest_child = p;
		    }

    if (child_count && (c_style & ALWAYS_BIT)) {
        if (c_style & ENGLISH_BIT) { print " "; LIST_WRITER_INTERNAL_RM('Q', o); print " "; }
        recurse_flag = true;
    }
    
    if (child_count && (c_style & RECURSE_BIT)) {
        if (o has supporter) {
            if (c_style & ENGLISH_BIT) {
                if (c_style & TERSE_BIT) {
                	LIST_WRITER_INTERNAL_RM('A', o);
                	LIST_WRITER_INTERNAL_RM('R', o);
                } else LIST_WRITER_INTERNAL_RM('S', o);
            }
            recurse_flag = true;
        }
        if (o has container && (o has open || o has transparent)) {
            if (c_style & ENGLISH_BIT) {
                if (c_style & TERSE_BIT) {
                	LIST_WRITER_INTERNAL_RM('A', o);
                	LIST_WRITER_INTERNAL_RM('T', o);
                } else LIST_WRITER_INTERNAL_RM('U', o);
            }
            recurse_flag = true;
        }
    }

    if (recurse_flag && (c_style & ENGLISH_BIT)) {
    	SetLWI(child_count, -1, eldest_child);
    	LIST_WRITER_INTERNAL_RM('V', o); print " ";
    }

    if (c_style & NEWLINE_BIT) new_line;

    if (recurse_flag) {
        o = child(o);
        @push lt_value; @push listing_together; @push listing_size;
        @push c_iterator;
        c_iterator = ObjectTreeIterator;
        lt_value = EMPTY_TEXT_VALUE; listing_together = 0; listing_size = 0;
        WriteListR(o, depth+1, true);
        @pull c_iterator;
        @pull listing_size; @pull listing_together; @pull lt_value;
        if (c_style & TERSE_BIT) LIST_WRITER_INTERNAL_RM('B');
    }
];

-) instead of "Write After Entry" in "ListWriter.i6t".

Also, there’s no need to duplicate the work in your own rule, so:

Rule for printing inventory details for the black trunk:	
    write after entry for the black trunk's inside.

Note that this is just a quick hotwire to address the issue you brought up. There may be unwanted side effects; I haven’t really studied this subsystem. Maybe someone else will chime in.

2 Likes

Oops. Kind of forgot I had posted about this before.

Anyway, this works, modulo one detail: it breaks rules like this:

Rule for printing inventory details for the crystal tiara when it is activated:
	say " (glowing)";

The inventory no longer prints a line break after (glowing), so the next item shows up on the same line. For now I’m content to just add a [line break]. This is a one-off game, not something I’ll be reusing.

I made an attempt to read the I6 code to see where that problem might arise, but it’s difficult enough to read without having the original source to compare to. Oh well.

Thanks so much for your help, now and in the past!

Trying to make a container a part of a supporter or vice versa without problematic side effects is hard… (I’ve taken a stab at it a couple of times and have concluded that one would need to rewrite some of the fundamental light-handling stuff from the ground up for lighting stuff to interact with it correctly.)

I’d say that’s fair behavior. When you write a for <activity>... rule, you’re basically choosing to bypass the default behavior for that activity, so you have to do the default behavior’s whole job (which in this case includes printing the new line) in your code. (Compare to a for printing the name... rule.)

That said, only a for printing the inventory details of... will trigger the short-circuit of WriteAfterEntry(). Activities also allow before and after rules. If the rule for the tiara is phrased as after printing the inventory details of..., then the short-circuit doesn’t happen, and normal new line behavior is preserved. That may work for your scenario.

1 Like

I think I’ve got the wrinkles ironed out now that otistdog has set me straight here. It’s a container inside a supporter to avoid the light problems. Seems to work.

I6 inclusions are surely still allowed in v10 aren’t they? (I haven’t tried it out yet; waiting for the IDE.)

They are, but the I6 template layer (now known as the “kits”) has changed enough that inclusions may require significant updates for it.