@Commissar64 requested the source to my recent Twine game “The Whispering Thing.” We’ll do that sometime soon, but for now I can easily share the modifications to the CyclingLink macro necessary to make it work with the Sugarcube header without creating JS errors.
The code follows. It’s basically just a modification to how the anchor element is created. I can’t guarantee that this will do everything you want it to, as it’s a bit hacky.
version.extensions.cyclinglinkMacro = {
major: 3,
minor: 3,
revision: 0
};
macros.cyclinglink = {
handler: function (a, b, c) {
var rl = "cyclingLink";
function toggleText(w) {
w.classList.remove("cyclingLinkInit");
w.classList.toggle(rl + "Enabled");
w.classList.toggle(rl + "Disabled");
w.style.display = ((w.style.display == "none") ? "inline" : "none")
}
switch (c[c.length - 1]) {
case "end":
var end = true;
c.pop();
break;
case "out":
var out = true;
c.pop();
break
}
var v = "";
if (c.length && c[0][0] == "$") {
v = c[0].slice(1);
c.shift()
}
var h = state.active.variables;
if (out && h[v] === "") {
return
}
var l = document.createElement("a");
a.appendChild(l);
l.className = "internalLink cyclingLink";
l.setAttribute("data-cycle", 0);
for (var i = 0; i < c.length; i++) {
var on = (i == Math.max(c.indexOf(h[v]), 0));
var d = insertElement(null, "span", null, "cyclingLinkInit cyclingLink" + ((on) ? "En" : "Dis") + "abled");
if (on) {
h[v] = c[i];
l.setAttribute("data-cycle", i)
} else {
d.style.display = "none"
}
insertText(d, c[i]);
if (on && end && i == c.length - 1) {
l.parentNode.replaceChild(d, l)
} else {
l.appendChild(d)
}
}
l.onclick = function () {
var t = this.childNodes;
var u = this.getAttribute("data-cycle") - 0;
var m = t.length;
toggleText(t[u]);
u = (u + 1);
if (!(out && u == m)) {
u %= m;
if (v) {
h[v] = c[u]
}
} else {
h[v] = ""
} if ((end || out) && u == m - (end ? 1 : 0)) {
if (end) {
var n = this.removeChild(t[u]);
n.className = rl + "End";
n.style.display = "inline";
this.parentNode.replaceChild(n, this)
} else {
this.parentNode.removeChild(this);
return
}
return
}
toggleText(t[u]);
this.setAttribute("data-cycle", u)
}
}
};
Hello, the author of SugarCube here.
For the above to work correctly, you’ll need to change the line:
var h = state.history[0].variables;
To:
var h = state.active.variables;
SugarCube’s History class, which is what the state variable contains an instance of, is somewhat different from its counterpart in the vanilla headers.
Ah! Yes! I remember looking at that and then not bothering to fix it because I didn’t care about history for cycling links. I’ll fix it in this post!
Oh, one thing I should mention for those that do want $variable manipulation. When you call the macro, you’ll need to quote the $variable. This is because all macros in SugarCube get $variable substitution automatically, unlike the old headers where each macro had to perform $variable substitution itself. So, if you don’t quote the $variable, instead of getting the $variable name the macro will get the value instead.
For example, do this:
<<cyclinglink “$heat” “off” “low” “high” “fearsome”>>
Not this:
<<cyclinglink $heat “off” “low” “high” “fearsome”>>