0 votes
by (600 points)
Is it possible to set the tag of a passage based on a variable? For example I have a 'dark' tag where the background is black with white text. I have a 'Turn lamp on' passage as follows which responds to a variable $battery:
You turn the lamp on<<if $battery gte 60>> and it's shining brightly.
<<elseif $battery gte 40>>, might need a new battery soon though.
<<elseif $battery gte 10>> but it's not very bright.
<<elseif $battery gte 1>> but it only glows dimly.
<<else>> but the battery appears to be dead.<<if tags(previous()).includes("dark")>>You still can't see anything.<</if>>
<<set $battery -= 1>>
[[Continue|previous()]] [[Turm the lamp off|previous()][$lampon = false]]

I'd like this 'Turn lamp on' passage to use the 'dark' tag if the $battery value is zero or less AND the previous passage had the 'dark' tag..

2 Answers

0 votes
by (600 points)
edited by
I've found a solution using <<toggleclass "body" "dark light">> and creating a blank class file 'light {} in the stylesheet. It doesn't seem very elegant though. If, for example the passage is re-visited it will turn back to 'light.' Any suggestions to improve it?

You turn the lamp on<<if $battery gte 60>> and it's shining brightly.
<<elseif $battery gte 40>>, might need a new battery soon though.
<<elseif $battery gte 10>> but it's not very bright.
<<elseif $battery gte 1>> but it only glows dimly.
<<else>> but the battery appears to be dead.<<if tags(previous()).includes("dark") and ($battery is 0)>><<toggleclass "body" "dark light">>You still can't see anything.<</if>>
<</if>>
<<set $battery -= 1>>
[[Continue|previous()]] [[Turm the lamp off|previous()][$lampon = false]]
0 votes
by (159k points)

note: You didn't actually state this but I am assuming that you have other passages that have been assigned the 'dark' passage tag, and that while the lamp it lit you want it to potentially effect the CSS of every 'dark' passage. Also because your 'dark' styling is "white text on a black background" I will assume you are using something like SugarCube's Bleached stylesheet to alther the default styling of your project.

When viewing a Passage that has been assigned a Passage Tag (like 'dark') the story format's engine will added that tag to the Document Object Model of the current web-page in multiple places, which you can then use as targets of custom CSS.

a. As a member of the data-tags attribute of the: html, body, and .passage elements.
b. As a member of the class attribute of the: body and .passage elements.

You can also use macros like <<removeclass>> and <<addclass>>, and the jQuery <element>.removeClass() function to programatically modify which CSS classes are currently assigned to an element.

1. Initialise the required story variables within your project's StoryInit special passage, I will assume the lamp defaults to off and the battery to 100%.

<<set $lampon to false>>
<<set $battery to 100>>

2. Use the body element's class attribute as the target of your 'dark' related CSS within your project's Story Stylesheet area.

body.dark {
	background-color: black;
	color: white;
}

note: your existing 'dark' CSS rule may contain more property changes than the above, if so then move those extra changes into the above selector.

3. Turning the lamp on.

The following example use the <<removeclass>> macro to remove the 'dark' class from the body element if there is enough power in the battery, doing this will cause the above CSS rule to no longer effect the current passage while the reader doesn't transition to another passage.

<<link "Light Lamp">>
	<<set $lampon to true>>
	<<if $battery > 0>>
		<<removeclass "body" "dark">>
	<</if>>
<</link>>

note: The above link currently only concerns itself with the bare minimum required to cause the current page to change it's styling, you may want to also add code that displays the "lamp is lit" related text to the above link.

4. Conditionally lighting the 'dark' passages visited by the Reader.

The following JavaScript example uses a :passagedisplay event handler to minitor each time the Reader visits a passage, it uses the tags() function to determine if the current passage has been assigned the 'dark' passage tage, it uses the State.variables object to gain access to the current value of $lampon and $battery story variables, and it conditionally uses the jQuery <element>.removeClass() function to remove the 'dark' class from the body element if a lamp with power is on.

$(document).on(':passagedisplay', function (ev) {
	var SV = State.variables;
	if (tags().includes("dark") && SV.lampon && SV.battery > 0) {
		console.log(passage() + ' matched.');
		$('body')
			.removeClass('dark');
	}
});

note: Place the above code within your project's Story Javascript area.

5. Turning the Lamp off.

The following example uses the tags() function to determine if the current passage has been assigned the 'dark' passage tag, and if it does it use the <<addclass>> macro to add the 'dark' class to the body element if the class is missing.

<<link "Extinguish  Lamp">>
	<<set $lampon to false>>
	<<if tags().includes('dark')>>
		<<addclass "body" "dark">>
	<</if>>
<</link>>

 

by (600 points)
edited by

Thanks for that. It was very helpful. I've incorporated the passage and javascript code you suggested. However I made some modifications as follows:

I called the passage with the lamp controls using this  which sets the variables $haslamp, $lampon and $battery.
$haslamp is true or false (you can't switch on or off a lamp you don't have). It's set to true.
$lampon is set initially to false
$battery is set to a value of 3 and should decrease by 1 every time the lamp is switched on

--------------------------------------------------------------------------------------------------------

test

[[Dark passage]]
<<set $battery to 3>> <<set $lampon to false>> <<set $haslamp to true>

--------------------------------------------------------------------------------------------------------

This leads to 'Dark passage' which has the tag 'dark'

As you surmised I'm using the Bleached stylesheet to which I'v customized to include:

body.dark {
background-color: black;
color: #ffffff;  
}

a {
    background-color: #4444ff;
  box-shadow: 0 5px 0 darkblue;
  color: white;
  padding: 0.15em 1.5em;
  position: relative;
  text-decoration: none;
  border-radius:16px;
}

a:hover {
  background-color: #0000ff;
  cursor: pointer;
}

a:active {
  box-shadow: none;
  top: 5px;
}

These additions add an inverted 'dark' passage style with black background and white text. It also changes all links to buttons

There's not much point in having a 'Lamp on' button on an already lit passage or a 'Lamp off' button in a passage which is already dark so the 'Dark passage is as follows:

--------------------------------------------------------------------------------------------------------

Dark passage  (tag = dark)

<<if ($haslamp is true) and ($lampon is false)>>
    /*unlit graphic goes here*/ 
    <<link [[lamp on|passage()]]>> <<set $battery -=1>> <<set $lampon to true>>
        <<if $battery > 0>> <<removeclass "body" "dark">><</if>><</link>>
<<elseif ($haslamp is true) and ($lampon is true) and ($battery > 0)>>
    /*lit graphic here*/
    <<link [[lamp off|passage()]]>> <<set $lampon to false>> 
        <<if tags().includes('dark')>> <<addclass "body" "dark">> 
        <</if>> <</link>>
        <<else>>/*unlit graphic goes here again*/ 
        The lamp battery is dead.
<</if>

--------------------------------------------------------------------------------------------------------

For the most part it works fine. The dark passage displays a suitable unlit graphic (http://avestedinterest.info/twine/images/Guardroom.jpg) and a 'Lamp on' button. When that is clicked the passage becomes lit (white background and black text), the image changes to a 'lit' image (http://avestedinterest.info/twine/images/guardroom2.jpg) with a 'Lamp off' button. Exactly as it should. 
BUT
It's a little clumsy in that I have to enter the dark image twice

Any suggestions?

Incidentally - if you recognise the scene - you are getting old This is based on a 1982 text onlyadventure game..

This site has been placed in read-only mode. Please use the Interactive Fiction Community Forum instead.
...