I6: Examine north wall == Examine north

In Inform6, how can I make sure that “EXAMINE NORTH WALL” is always a synonym from “EXAMINE NORTH”? In the library and the Inform Designer’s Manual I see references to this sort of thing possibly being automatic, but I can’t seem to figure it out.

I just now realized a certain puzzle in Shadowgate has a “guess the noun” bug about it that I would fix if I knew the answer to this question.

That’s been removed from the 6/11 version due to it’s incompatibility with outdoor locations. So you’ll have to hack the section beginning on line 40 in the English.f file.

CompassDirection -> n_obj “north”
with door_dir n_to, name ‘n//’ ‘north’;

Simply add ‘wall’ after ‘north’.

Ah, so THAT’s what happened. A check back at the IF Archive shows me that I compiled the latest release of Shadowgate with version 6/10 of the library. So it works there, but when I compile it now it doesn’t. I’d rather not hack the library because it ruins my ability to pick up the code later and compile as it used to be. So, how about this: how can I have an object always be with the player, yet be invisible? That would then be the “wall” object.

When working with I6 you really have to archive the library code along with the project. Once you’re doing that, hacking the library becomes a non-issue.

To keep an object around, either give it a found_in property (making it a floating object), or give the player an add_to_scope property which names the object. For walls, the former probably makes more sense.

Create a PC object, assign the player to it, and then add_to_scope your wall object to the PC object. You’ll have to have a parse_name in your wall object that will catch north wall, south wall, east wall, and so on.

Something like this:

Object wallobj
with
parse_name [;
];

Object pc “me”
with
name ‘me’ ‘myself’,
description “As good looking as…well…you haven’t ever been attractive, really.”,
add_to_scope wallobj;

[Initialise;

ChangePlayer(pc);
];

I think I see how this would work, but I can’t seem to get the parse_name procedure right.

I get this response:

examine north wall
It’s a stone wall.
It’s a stone wall.
You can’t see any such thing.

How do I make the code below stop when it describes the stone wall just once? There are some other problems like this (all from the first room in Shadowgate):

Entrance
You are standing just south of the Castle Shadowgate. In front of you, to the
north, is a heavy wooden door set in the stone wall of the castle. A skull hangs
over the door.

open skull
(the skull)
As if by magic, the skull rises, revealing an iron key nestled in a tiny hollow.

get key
(the iron key)
Taken.

open door
(the wall)
That’s not something you can open.

Object wallobj "wall" with parse_name [ myname retval; retval = 0; myname = NextWord(); while (myname ~= nothing) { retval++; if (myname == 'north') { retval++; <<examine n_obj>>; } myname = NextWord(); } return retval; ], has scenery;

Ok, here’s what’s happening – the parse_name is just so the parser knows what you’re talking about. You can handle the examine, push, move, all the usual way (in before or react_before). Try this:

Object wallobj "wall"
        with
        parse_name [myname retval;
                retval = 0;
                myname = NextWord();
                if (myname == 'north' or 'northern' or 'east' or 'eastern' or 'west' or 'western' or 'south' or 'southern') 
                     {
                     retval++;
                     myname = NextWord();
                     }
                 if (myname == 'wall') retval++;
                 return retval;
                 ],
           before[;
                   Examine: "You find the wall ugly and boring, besides.";
                   Push: "The wall isn't going anywhere.";
                   ],
has static scenery;

If you need a specific northern wall, unique from say the southern wall, then make a north(ern) wall object (its parse_name would just do the ‘north’ and ‘northern’ wall), and group the other generic wall objects together.

Unless you want people to move the wall around, you need that static in there too. :wink:

embarassing goof deleted

A slight edit of Poster’s code yields most of what I want.

Object wallobj "wall"
        with direction,
        parse_name [ myname retval;
                retval = 0;
                myname = NextWord();
                if (myname == 'north' or 'northern') {
                        myname = NextWord();
                        retval++;
                        self.direction = n_obj; 
                        if (myname == 'wall') {        
                                retval++;
                                self.direction = n_obj;
                        }
                }
! other directions go here
                return retval;
        ],
        before [;
        Examine:
                <<examine self.direction>>;
        ],
        has static scenery;

Doing “EXAMINE NORTH WALL” will give the result of “LOOK NORTH”, but now if I do “EXAMINE NORTH”, I get this:

>examine north
(the north)
It's a stone wall.

>examine the north
(the north)
It's a stone wall.

How can I suppress that extraneous “(the north)” message. It pops up even in code that lacks this wall code.

There is only one way that I know of that works every time, and unfortunately, it involves hacking the library. I introduced a global variable that allowed the program to turn on/off the inference messages depending on the value of the global.

Here’s my code, in parserm.h:

!-- line 345 Added
Global inferpr = true;   ! If true, print inference messages

!-- line 1875 Modified
if ((inferfrm ~=0) && (inferpr)) { 
print "("; PrintCommand(inferfrom); print ")^";
}

You’d set inferpr to false whenever you’d want to kill the messages, and then turn it on right afterward, like this:

inferpr= false;
<examine wallobj>;
inferpr = true;
return true;

That would be tricky to apply to inferences about the directions. No inferences are made when referring to the walls. Wasn’t there something about a higher return value making an inference message disappear?