Your problem is a result of a number of issues:
a. The implementation found in the old Health bar in right side bar or in a status passage thread you are basing your code on was designed to be used in conjunction with the Right Side-bar implementation found in the old Creating A Panel Similar To The UI-Bar thread. This means that it makes a number of assumptions that aren't correct when trying to display the generated status-bar in the StoryCaption special passage instead.
b. The contents of StoryCaption special passage is processed after the code in the postrender task has been executed, this means that any updates to status-bar made within the task are overwritten by the contents of StoryCaption.
WARNING:
- The JavaScript code in the following answer relies on featues that were added in v2.22.0 of SugarCube 2, which was released after the current v2.2.1 release of the Twine 2 application.
- I strongly suggest that whenever possible people using the SugarCube 2 story format should keep thier version of it up to date by downloading and installing the latest release found on the its official web-site.
- For those unable to upgrade to a more up to date SugarCube 2 release I will (hopefully shortly) implement a v2.21.0 compatible version of this answer.
The following is a new implementation of the status-bar code that is compatable StoryCaption, it consists of five parts:
1. A new <<statusbar>> macro.
Place the following code within your project's Story Javascript area.
/*
<<statusbar "identifier" "$maximum" "$current" "$changer">>
identifier - The UNIQUE identifier used as the HTML element ID of this bar.
$maximum - The story variable that contains the maximum value this bar can be.
$current - The story variable than contains the current value of this bar.
$changer - The story variable this bar monitors to determine how much the current value should change by.
eg. <<statusbar "sanity-bar" "$totalSanity" "$sanity" "$abuse">>
*/
Macro.add('statusbar', {
skipArgs : false,
handler : function () {
/* Check if correct parameters were passed. */
if (this.args.length < 4) {
return this.error('not enough parameters specified');
}
/* TODO: Validate each of the four parameters being passed to the macro. */
var identifier = this.args[0],
maximum = State.getVar(this.args[1]),
current = State.getVar(this.args[2]),
change = State.getVar(this.args[3]),
barWidth = (current / maximum) * 100,
changeWidth = 0,
delayReset = false;
/* Generate the HTML structure. */
const $parent = jQuery(document.createElement('div'));
$parent
.addClass("status-bar")
.attr({
'id': identifier,
'data-maximum': maximum,
'data-current': current
});
const $bar = jQuery(document.createElement('div'));
$bar
.addClass("bar")
.css('width', barWidth + "%")
.appendTo($parent);
const $change = jQuery(document.createElement('div'));
$change
.addClass("change")
.css('width', changeWidth + "%")
.appendTo($bar);
$parent.appendTo(this.output);
/* Handle any required change to the current value. */
if (change != 0) {
changeWidth = (change / current) * 100;
current -= change;
barWidth = (current / maximum) * 100;
State.setVar(this.args[2], current);
State.setVar(this.args[3], 0);
delayReset = true;
}
/* Apply the change visual effect if needed. */
if (delayReset) {
setTimeout(function(){
$change.css({'width': '0'});
$bar.css('width', barWidth + "%");
}, 500);
}
}
});
2. New CSS to style the status-bar generated by the new macro.
Place the following code within your project's Story Stylesheet area.
/* Status Bar styling. */
.status-bar {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 200px;
height: 20px;
padding: 5px;
background: #ddd;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
position: relative;
}
.status-bar .bar {
background: #c54;
width: 100%;
height: 10px;
position: relative;
transition: width .5s linear;
}
.status-bar .change {
background: rgba(255,255,255,0.6);
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 0px;
transition: width .5s linear;
}
3. Initialise the Sanity related story variables within your StoryInit passage.
In the original example there were three Health related story variables used by status-bar code:
- $totalHealth - Used to indicate the maximum value of the status bar.
- $health - Used to track the current value of the status bar.
- $damage - Used to indicate how much the current value should lowered or raised by.
Changing the $damage variable from zero to a possitive integer value would lower the current value by that amount, and changing the $damage variable from zero to a negitive integer value would raise the current value by that amount.
In your example you are tracking Sanity, so I would suggest initialising the following story variables.
- $totalSanity - the maximum value.
- $sanity - the current value.
- $abuse - the value to change the current value by.
<<set $totalSanity to 100>>
<<set $sanity to $totalSanity>>
/* Delete the following $abuse story variable if you choose to use a temporary variable instead. */
<<set $abuse to 0>>
note: Because the $abuse variable's life-span may not need to extend past the life-span of the current Passage, which in turn means that it doesn't need to be persisted in History or a Save, a temporary variable could be used instead of a story variable. In this case delete the line initialising the $abuse variable from the above example.
4. Using the new <<statusbar>> macro in your project's StoryCaption special passage.
note: Only use one of the following two examples in your project, each status-bar displayed on the current page must have it's own UNIQUE identifier.
/* Example using a $abuse Story variable. */
<<statusbar "sanity-bar" "$totalSanity" "$sanity" "$abuse">>
/* Example using a _abuse Temporary variable. */
<<statusbar "sanity-bar" "$totalSanity" "$sanity" "_abuse">>
5. Changing the current value of the Sanity status bar.
Setting the value of the $abuse Story variable (or the _abuse Temporary variable is using the temporary variable based example) to a non zero interger value within the contents of the current Passage will cause the status-bar to change.
eg. Each of the following will lower the current value of the $sanity Story variable, which you use in your project depends on if you chose to.use an $abuse Story variable or an _abuse Temporary variable in points 3 & 4.
/* If you decided to use a $abuse Story variable with <<statusbar>>. */
<<set $abuse to 10>>
/* If you decided to use a )abuse Temporary variable with <<statusbar>>. */
<<set _abuse to 10>>
6. [optional] Individually styling multiple status bars.
The new <<statusbar>> macro can be used to create multiple status-bars as long as each one has it's own UNIQUE identifier, and that identifier can be used to customise the CSS styling for a specific status-bar.
eg. Assuming you have initilised the following variables within your StoryInit.
<<set $totalSanity to 100>>
<<set $sanity to $totalSanity>>
<<set $totalHealth to 100>>
<<set $health to $totalHealth>>
... and you have defined the following status-bars within your StoryCaption.
Sanity: <<statusbar "sanity-bar" "$totalSanity" "$sanity" "_abuse">>
Health: <<statusbar "health-bar" "$totalHealth" "$health" "_damage">>
... then you can use CSS like the following within your Story Stylesheet area to customise the Heath related status-bar to have a green bar.
#health-bar .bar {
background: green;
}
edited [23-aug-2018]: Added a warning about the minimum SugarCube 2 version required by this answer.