Moving player to another room of a specific kind?

Hi!

I’ve been using Inform 7 for a while, but today I met a problem I can’t figure out.

I want the player to be able to teleport anywhere on the map, but not every room will contain a teleport destination/landing point (for story reasons).
Therefore, I declared a new kind of room - a landing - and assigned that kind to every room which such feature.
The teleport action itself works as it should (i.e. it teleports the player to the room specified by the player) but what I really want is for the player to type something like “teleport to the computer room” and automatically end up at the nearest landing adjacent to the specified room, as the computer room doesn’t have a landing point itself.

Something like “Move the player to any landing adjacent to the noun”, but I can’t find a phrasing that works with Inform. Is this function even possible to achieve? I’m not even sure “adjacent” is the right preposition here, since the player could end up anywhere if there are no doors.

Any help is appreciated!

“Move the player to a random landing adjacent to the noun” should work. (Or “now the player is in a random landing adjacent to the noun”–I think the only difference between these formulations is that you can say “move the player to [room], without printing a room description” and that doesn’t work with “now the player is in [room].”)

Here’s a worked-out example:

[code]A landing is a kind of room.

South Lab is a room. North lab is north of South Lab. Entrance point is a landing, north of North Lab. Hallway is west of Entrance point. Safety Shower is west of Hallway. Back Teleport is a landing, west of Safety Shower.

Teleporting is an action applying to one visible thing. Understand “Teleport to [any room]” as teleporting.

Instead of teleporting:
if the noun is a landing:
now the player is in the noun;
otherwise if there is a landing adjacent to the noun:
now the player is in a random landing adjacent to the noun;
otherwise:
say “There isn’t a landing close enough to [the noun].”[/code]

Now, as this shows, you have to check whether there’s a landing adjacent to the destination. Is the point that you’re making at the end there that you want the player to land at the nearest landing to the destination, even if it isn’t adjacent to it?

Here’s an extension to matt’s example that doesn’t require that the landing be adjacent to the destination.

A landing is a kind of room.

South Lab is a room. North lab is north of South Lab. Entrance point is a landing, north of North Lab. Hallway is west of Entrance point. Safety Shower is west of Hallway. Back Teleport is a landing, west of Safety Shower.

[Disconnected cluster of rooms with a landing]
Distant Landing is a landing, west of Distant Lab.

[Disconnected room with no landing]
Remote Lab is a room.

[Room separated from landing by a locked door (and the means to unlock it)]
The back door is a locked door. The indefinite article is "the". It is south of Back Teleport and north of Back Lab.
The back key is in the Back Teleport. The indefinite article is "the". It unlocks the back door.

Teleporting is an action applying to one visible thing. Understand "Teleport to [any room]" as teleporting.

To really decide on nothing: (- return nothing; -).

[Returns the closest landing to R, or nothing if there's no landing reachable from R.]
To decide which landing is the closest landing to (R - room):
	let shortest num moves be -1;
	let closest landing be a random landing;
	repeat with L running through landings:
		let num moves be the number of moves from L to R;
		if num moves is -1, next;
		if shortest num moves is -1 or shortest num moves > num moves:		
			now shortest num moves is num moves;
			now closest landing is L;
	if the shortest num moves is -1, really decide on nothing;
	otherwise decide on closest landing.
		
Instead of teleporting:
	if the noun is the location, instead say "[We] [are] already in [the noun].";
	let dest be the noun;
	if dest is not a landing, now dest is the closest landing to the noun;
	if dest is nothing, instead say "There isn't a landing near [the noun].";
	if dest is the location, instead say "This is already the closest landing to [the noun].";
	now the player is in dest.

test me with "teleport to north lab / teleport to shower / teleport to distant lab / teleport to remote lab / teleport to hallway / w / teleport to south lab / teleport to entrance point / teleport to south lab / teleport to back lab".

If you want the pathfinding to work through doors, change:

		let num moves be the number of moves from L to R;

to

		let num moves be the number of moves from L to R, using doors;

or

		let num moves be the number of moves from L to R, using even locked doors;

You are correct, that is the only difference.

Thank you so much, all of you!

The short version works perfectly for my game at this point! I realise I had somewhat the right thinking, but I used the wrong syntaxes.

I guess I was just thinking out loud. The description of Adjacent in the documentation made me think that any two rooms were adjacent if there were an unobstructed path between them, but I realise from Vlaviano’s extended version that that’s pathfinding and that adjacent doesn’t work like that. But come to think of it, it makes sense to use the same landing for a connected chain of rooms. At that point I would have to use the extended version.

Again, thanks! I’m still learning the more advanced functions of Inform and studying your examples has been great help!