I don’t know what could be wrong with the Javascript, I coped all of it, and I don’t know if any other javascripts I have are interfereing with it or not, because some have before but then things worked when I removed them, but I’d rather not have to remove the ones I’m finding useful. Here’s a copy of what I have so far so someone can try to find what’s wrong.
if (document.location.href.toLowerCase().includes("/temp/") || document.location.href.toLowerCase().includes("/private/") || hasOwnProperty.call(window, "storyFormat")) {
// Change this to the path where the HTML file is
// located if you want to run this from inside Twine.
setup.Path = "C:/Stories/AttachmentPart1"; // Running inside Twine application
} else {
setup.Path = ""; // Running in a browser
}
setup.SoundPath = setup.Path + "sounds/";
// Volume Slider, by Chapel; for SugarCube 2
// version 1.2.0 (modified by HiEv)
// For custom CSS for slider use: http://danielstern.ca/range.css/#/
/*
Changelog:
v1.2.0:
- Fixed using/storing the current volume level in the settings.
v1.1.0:
- Fixed compatibility issues with SugarCube version 2.28 (still
compatible with older versions, too).
- Added settings API integration for SugarCube 2.26.
- Internal improvements and greater style consistency with my
other work.
- Added a pre-minified version.
- By default, the slider is now more granular than before
(101 possible positions vs 11). Change the 'current' and
'rangeMax' options to 10 to restore the old feel.
*/
(function () {
// Set initial values.
var options = {
current : 50, // Default volume level.
rangeMax : 100,
step : 1,
setting : true
};
Setting.load();
if (options.setting && settings.volume) {
options.current = parseInt(settings.volume);
}
var vol = {
last: options.current,
start: (options.current / options.rangeMax).toFixed(2)
};
// Function to update the volume level.
function setVolume (val) {
if (typeof val !== 'number') val = Number(val);
if (Number.isNaN(val) || val < 0) val = 0;
if (val > 1) val = 1;
options.current = Math.round(val * options.rangeMax);
if (options.setting) {
settings.volume = options.current;
Setting.save();
}
if ($('input[name=volume]').val() != options.current) {
$('input[name=volume]').val(options.current);
}
try {
if (SimpleAudio) {
if (typeof SimpleAudio.volume === 'function') {
SimpleAudio.volume(val);
} else {
SimpleAudio.volume = val;
}
return val;
} else {
throw new Error('Cannot access audio API.');
}
} catch (err) {
// Fall back to the wikifier if we have to.
console.error(err.message, err);
$.wiki('<<masteraudio volume ' + val + '>>');
return val;
}
}
// Fix the initial volume level display.
postdisplay['volume-task'] = function (taskName) {
delete postdisplay[taskName];
setVolume(vol.start);
};
// Grab volume level changes from the volume slider.
$(document).on('input', 'input[name=volume]', function() {
var change = parseInt($('input[name=volume]').val());
setVolume(change / options.rangeMax);
vol.last = change;
});
// Create the <<volume>> macro.
Macro.add('volume', {
handler : function () {
var wrapper = $(document.createElement('span'));
var slider = $(document.createElement('input'));
var className = 'macro-' + this.name;
slider.attr({
id : 'volume-control',
type : 'range',
name : 'volume',
min : '0',
max : options.rangeMax,
step : options.step,
value : options.current
});
// Class '.macro-volume' and ID '#volume-control' for styling the slider
wrapper.append(slider).addClass(className).appendTo(this.output);
}
});
// Add Setting API integration for SugarCube 2.26 and higher.
function updateVolume () {
setVolume(settings.volume / options.rangeMax);
}
if (options.setting) {
if (Setting && Setting.addRange && typeof Setting.addRange === 'function') {
Setting.addRange('volume', {
label : 'Volume: ',
min : 0,
max : options.rangeMax,
step : options.step,
default : options.current,
onInit : updateVolume,
onChange : updateVolume
});
} else {
console.error('This version of SugarCube does not include the `Settings.addRange()` method; please try updating to the latest version of SugarCube.');
}
}
}());
function revealFirstHidden(ev) {
if(ev.target.nodeName === 'A') return
const hidden = $('.passage .hide')
if(hidden.length > 0) {
let show = hidden.first()
show.addClass('fadein')
show.removeClass('hide')
if(show[0].scrollIntoView)
show[0].scrollIntoView({behavior: 'smooth', block: 'nearest'})
}
}
(function () {
"use strict";
$(document).on(":passageinit", () => {
CTP.Logs.forEach((_, id) => {
if (!CTP.Repository.get(id)?.persist) CTP.Logs.delete(id);
});
CTP.Repository.forEach(({ persist }, id) => {
if (!persist) CTP.Repository.delete(id);
});
});
window.CTP = class CTP {
constructor(id, persist = false) {
this.stack = [];
this.clears = [];
this.options = {};
if (!id?.trim()) throw new Error(`No ID specified!`);
this.id = id;
this.persist = persist;
CTP.Repository.set(id, this);
}
static get Repository() {
if (!setup["@CTP/Repository"]) setup["@CTP/Repository"] = new Map();
return setup["@CTP/Repository"];
}
static get Logs() {
if (!variables()["@CTP/Logs"]) variables()["@CTP/Logs"] = new Map();
return variables()["@CTP/Logs"];
}
get log() {
if (!CTP.Logs.get(this.id)) CTP.Logs.set(this.id, { lastClear: -1, index: -1, seen: -1 });
return CTP.Logs.get(this.id);
}
static getCTP(id) {
return CTP.Repository.get(id);
}
add(content, options = {}) {
options = {
...this.options,
...options
};
if (options.clear) this.clears.push(this.stack.length);
this.stack.push({
options, content,
index: this.stack.length,
element: $()
});
return this;
}
print(index) {
const { content, options: iOpts } = this.stack[index];
const options = {
...this.options,
...iOpts
};
const element = $(document.createElement(options.element || "span"))
.addClass("--macro-ctp-hidden")
.attr({
"data-macro-ctp-id": this.id,
"data-macro-ctp-index": index,
})
.on("update-internal.macro-ctp", (event, firstTime) => {
if ($(event.target).is(element)) {
if (index === this.log.index) {
if (firstTime) {
if (typeof content === "string") element.wiki(content);
else element.append(content);
element.addClass(options.transition ? "--macro-ctp-t8n" : "");
}
element.removeClass("--macro-ctp-hidden");
} else {
if (index < this.log.seen) element.removeClass("--macro-ctp-t8n");
element.toggleClass("--macro-ctp-hidden", index > this.log.index || index < this.log.lastClear);
}
}
});
this.stack[index].element = element;
return element;
}
output() {
const wrapper = document.createDocumentFragment();
for (let i = 0; i < this.stack.length; i++) {
this.print(i).appendTo(wrapper);
}
return wrapper;
}
advance() {
if (this.log.index < this.stack.length - 1) {
this.log.index++;
const firstTime = this.log.index > this.log.seen;
this.log.seen = Math.max(this.log.seen, this.log.index);
this.log.lastClear = this.clears.slice().reverse().find(el => el <= this.log.index) ?? -1;
$(document).trigger("update.macro-ctp", ["advance", this.id, this.log.index]);
this.stack.forEach(({ element }) => element.trigger("update-internal.macro-ctp", [firstTime, "advance", this.id, this.log.index]));
}
return this;
}
back() {
if (this.log.index > 0) {
this.log.index--;
this.log.lastClear = this.clears.slice().reverse().find(el => el <= this.log.index) ?? -1;
$(document).trigger("update.macro-ctp", ["back", this.id, this.log.index]);
this.stack.forEach(({ element }) => element.trigger("update-internal.macro-ctp", [false, "back", this.id, this.log.index]));
}
return this;
}
}
Macro.add("ctp", {
tags: ["ctpNext"],
handler() {
const id = this.args[0];
const persist = this.args.slice(1).includes("persist");
const ctp = new CTP(id, persist);
const _passage = passage();
this.payload.forEach(({ args, name, contents }) => {
const options = {};
if (args.includes("clear")) options.clear = true;
if (args.includesAny("t8n", "transition")) options.transition = true;
const elementArg = (args.find((el) => el.startsWith("element:")) ?? "");
if (elementArg) options.element = elementArg.replace("element:", "");
if (name === "ctp") ctp.options = { ...options };
ctp.add(contents, options);
});
$(this.output).append(ctp.output());
$(document).one(":passagedisplay", () => {
if (_passage === passage()) {
const i = Math.max(ctp.log.index, 0);
ctp.log.index = -1;
ctp.log.seen = -1;
while (ctp.log.index < i) ctp.advance();
}
});
}
});
Macro.add("ctpAdvance", {
handler() {
const id = this.args[0];
if (id) {
const ctp = CTP.getCTP(id);
if (ctp) ctp.advance();
else throw new Error(`No CTP with ID '${id}' found!`);
} else throw new Error(`No ID specified!`);
}
});
Macro.add("ctpBack", {
handler() {
const id = this.args[0];
if (id) {
const ctp = CTP.getCTP(id);
if (ctp) ctp.back();
else throw new Error(`No CTP with ID '${id}' found!`);
} else throw new Error(`No ID specified!`);
}
});
})();
(function () {
// v1.1.1
'use strict';
var characters = new Map();
function addCharacter (name, displayname, icon) {
if(icon === undefined && displayname){
icon = displayname;
displayname = null;
}
if (State.length) {
throw new Error('addCharacter() -> must be called before story starts');
}
if (!name || !icon) {
console.error('addCharacter() -> invalid arguments');
return;
}
if (characters.has(name)) {
console.error('addCharacter() -> overwriting character "' + name + '"');
}
characters.set(name, {displayName: displayname, image: icon});
}
function say ($output, character, text, imgSrc) {
//
var $box = $(document.createElement('div'))
.addClass(Util.slugify(character) + ' say');
// portrait
var _img = characters.has(character) ? characters.get(character).image : null;
var $img = $(document.createElement('img'))
.attr('src', imgSrc || _img || '');
if ($img.attr('src') && $img.attr('src').trim()) {
$box.append($img);
}
// name and content boxes
var _name = character.toUpperFirst();
if (characters.has(character) && characters.get(character).displayName) {
_name = characters.get(character).displayName;
}
$box.append($(document.createElement('p'))
.wiki(_name))
.append($(document.createElement('p'))
.wiki(text));
if ($output) {
if (!($output instanceof $)) {
$output = $($output);
}
$box.appendTo($output);
}
return $box;
}
setup.say = say;
setup.addCharacter = addCharacter;
Macro.add('character', {
// character macro
handler : function () {
addCharacter(this.args[0], this.args[1], this.args[2]);
}
});
$(document).one(':passagestart', function () {
// construct array of character names
var names = Array.from(characters.keys());
names.push('say');
// generate macros
Macro.add(names, {
tags : null,
handler : function () {
if (this.name !== 'say') {
say(this.output, this.name, this.payload[0].contents);
} else {
say(this.output, this.args[0], this.payload[0].contents, this.args[1]);
}
}
});
});
}());
(function () {
"use strict";
$(document).on(":liveupdate", function () {
$(".macro-live").trigger(":liveupdateinternal");
});
Macro.add(['update', 'upd'], {
handler: function handler() {
$(document).trigger(":liveupdate");
}
});
Macro.add(['live', 'l', 'lh'], {
skipArgs: true,
handler: function handler() {
if (this.args.full.length === 0) {
return this.error('no expression specified');
}
try {
var statement = this.args.full;
var result = toStringOrDefault(Scripting.evalJavaScript(statement), null);
if (result !== null) {
var lh = this.name === "lh";
var $el = $("<span></span>").addClass("macro-live").wiki(lh ? Util.escape(result) : result).appendTo(this.output);
$el.on(":liveupdateinternal", this.createShadowWrapper(function (ev) {
var out = toStringOrDefault(Scripting.evalJavaScript(statement), null);
$el.empty().wiki(lh ? Util.escape(out) : out);
}));
}
} catch (ex) {
return this.error("bad evaluation: " + (_typeof(ex) === 'object' ? ex.message : ex));
}
}
});
Macro.add(['liveblock', 'lb'], {
tags: null,
handler: function handler() {
try {
var content = this.payload[0].contents.trim();
if (content) {
var $el = $("<span></span>").addClass("macro-live macro-live-block").wiki(content).appendTo(this.output);
$el.on(":liveupdateinternal", this.createShadowWrapper(function (ev) {
$el.empty().wiki(content);
}));
}
} catch (ex) {
return this.error("bad evaluation: " + (_typeof(ex) === 'object' ? ex.message : ex));
}
}
});
})();