Open door only after action taken

Hi
I’m trying to have a way to stop the door being opened unless another action has already occurred.
I have a global boolean variable for the action and if false I want the door to not open and give one answer reply. If the variable is true I want the door to be opened and let the player through.
I can see example for Inform 7 and others but punyinform seems a lot different.

I don’t know much about PunyInform, regrettably, but from a general Inform 6 perspective:

  1. You may wish to use a property of the door to store the boolean instead of a global. (See DM4 section 3.5.) Only so many globals are allowed (though it is quite a few, plenty for a small project).

  2. You probably want to check your boolean and respond appropriately in the context of a .before() routine for the door in question. (See DM4 section 5.)

1 Like

Can an external action access a local boolean?
(Ah, I see. Access as a property).
I think my main issue is overriding the built-in door opening code to not open when ‘open door’ is typed.

Example of what I’m trying to do:

		react_before [;
			Open:
				return self.open__door;
		],
		open_door [;
			if ( Thing.Taken == true ) {
				print "The door swings open";
				rtrue;
			}
			
			if ( Thing.Taken == false ) {
				print "You can't open the door";
				rfalse;
			}
		],

OK finally figured it out myself. Here’s an example if anyone else needs to do this :

Object TheDoor "the red door"
	with
		description "A red door",
		parse_name [ w1 w2 w3;
			w1 = NextWord(); w2 = NextWord(); w3 = NextWord();
			if(w1 == 'the' && w2 == 'red' && w3 == 'door') return 3;
			if(w1 == 'closet' && w2 == 'door') return 2;
			if(w1 == 'door') return 1;
		],
		after [;
			Open:
			if ( Thing.Taken == true ) {
				print "The door swings open!";
				give self open;
				rtrue;
			}
			
			if ( Thing.Taken == false) {
				print "You can't open the door!";
				give self ~open;
				rtrue;
			}
		],
		found_in Room1 Room2,
		door_dir (e_to) (w_to),
	has static door openable;
1 Like

Glad you got it to work. The solution is a bit backwards as it allows the action to happen and then reverses it. It’s cleaner to stop it in the before routine.

Also: You don’t need a parse_name for every object. And if you have a parse_name routine, you don’t have to check for ‘the’ as this is skipped automatically. I think a regular name property would do the trick here, no?

Also: Don’t include the article in the name, as it’s added automatically when needed. If the name is “the red door” it will be printed like “There’s nothing special about the the red door.”

Object TheDoor "red door"
	with
		description "A red door",
		name 'red' 'door',
		before [;
			Open:
				if ( Thing.Taken == false)
					"You can't open the door!";
		],
		after [;
			Open:
				"The door swings open!";
		],
		found_in Room1 Room2,
		door_dir (e_to) (w_to),
	has static door openable;

The basic stuff is like 98% the same in PunyInform as in regular Inform 6. The biggest difference lies in handling directions in code.

So your Inform 6 knowledge of before, after, react_before, react_after, each_turn, daemons, timers, add_to_scope etc is generally all valid for PunyInform as well.

1 Like

Thanks. Actually, this isn’t verbatim my code. I changed the sample here to not have my exact code and substituted stuff :smiley:

1 Like