0 votes
by (180 points)

Hi. In my story's sidebar caption I have a "Locations: " section intended to show the player their current location in the setting. I'm trying to figure out the best to set up the story so that the Location automatically updates when moving to a new passage.

Right now, I have a setup to alter the $location variable if a passage has a particular tag, then display the $location variable in the sidebar.

Right now, this is the code I have in the StoryCaption passage:

<<silently>>
	<<if tags().includes("LivingRoom")>>
		<<set $location to "Living Room">>
	<</if>>
	<<if tags().includes("Store")>>
		<<set $location to "Store">>
	<</if>>
	<<if tags().includes("School")>>
		<<set $location to "School">>
	<</if>>
<</silently>>

Location: $location

 

My problem with this method is that the more locations I add, the more if-statements I have to add to the story. In the example, I only have three, but in practice, my story is going to have at least a couple dozen locations, so I'm wondering if there's a better / easier / more elegant method for what I'm trying to accomplish.

Thanks.

2 Answers

+1 vote
by (68.6k points)
selected by
 
Best answer

You could automate the process with a bit of JavaScript, if you're willing to change your tags a bit to something like: loc.Living_Room, loc.Store, and loc.School.

For example: (goes in Story JavaScript)

var locTagRe = /^loc\./;
predisplay['set-location'] = function () {
	var loc = tags().find(function (tag) {
		return locTagRe.test(tag);
	});

	State.variables['location'] = loc
		? loc.replace(locTagRe, '').replace('_', ' ')
		: 'Unknown';
};

That will set $location to a value based on the tag (e.g. the tag loc.Living_Room becomes Living Room and loc.Store becomes Store).

 

by (180 points)
Thanks for the reply. This is definitely a step in the direction I was looking for.

The only downside to this method is that it requires putting a "loc." tag on every single passage or else the location is returned as Unknown. There are some passages in my story that can be visited from multiple different "location", so I would like to have a setup that would account for that. Would there be a way to set it up so that if a passage isn't tagged, the location just uses the previous value? I know basically nothing about JavaScript, so I don't know how I'd go about accomplishing that.

Thanks.
by (68.6k points)

Changing the code to something like the following should work:

var locTagRe = /^loc\./;
predisplay['set-location'] = function () {
	var loc = tags().find(function (tag) {
		return locTagRe.test(tag);
	});

	if (loc) {
		State.variables['location'] = loc.replace(locTagRe, '').replace('_', ' ');
	}
};

 

by (180 points)
That works great! Thank you!
0 votes
by (159k points)

If the passages within your project can be divided into two groups:

1. Those that contain the description of a location. ex. "Living Room", "Store", "School"

2. Those that don't. ex. "Watch TV", "Buy Eggs", "Talk to Teacher"

Then you could simply assign a 'location' tag to all the passages in the 1st group and use JavaScript code to automatically check if the current passage being shown is a 'location', and if it is then assign it's Name to your $location story variable. The follow goes in your project's Story JavaScript area.

predisplay['set-location'] = function () {
	var V        = State.variables;
	var leaving  = V.location;
	var arriving = State.passage;

	/*
	If the Passage about to be shown has a 'location' tag and its Name differs from
	the value stored in $location, then the Player is changing locations.
	*/
	if (tags(arriving).includes('location') && arriving !== leaving) {
		V.location = arriving;
	}
};

 

...