diff --git a/examples/references.gamebook b/examples/references.gamebook index 6159932..571a70f 100644 --- a/examples/references.gamebook +++ b/examples/references.gamebook @@ -8,14 +8,18 @@ section at [[next]]. * 1 start This is where the adventure begins. You can go on to the -next section, see [[next]] or try the other instead, see [[other]]. +next section, see [[next]] or try the random selection +feature at [[random]]. * next This is the next section. Go on to the end at [[end]]. -* other -This is another section. You can try the next section now, -see [[next]], or go on to the end, see [[end]]. +* random +[random]Pick a destination at random[/random] from +[[next]] or [[end]] or [[altend]]. + +* altend +Alternative ending. * end The end. diff --git a/templates/debug/random.debug b/templates/debug/random.debug new file mode 100644 index 0000000..57c4760 --- /dev/null +++ b/templates/debug/random.debug @@ -0,0 +1 @@ +[RANDOM]%(inner)s[/RANDOM] \ No newline at end of file diff --git a/templates/html/endscript.html b/templates/html/endscript.html index 2c82c28..d05590e 100644 --- a/templates/html/endscript.html +++ b/templates/html/endscript.html @@ -1,2 +1,3 @@ if (this.gamebook) { + gamebook.runActionsInIntroSections(); } diff --git a/templates/html/random.html b/templates/html/random.html new file mode 100644 index 0000000..c29028f --- /dev/null +++ b/templates/html/random.html @@ -0,0 +1 @@ +%(inner)s \ No newline at end of file diff --git a/templates/html/script.html b/templates/html/script.html index ead7c65..742dda7 100644 --- a/templates/html/script.html +++ b/templates/html/script.html @@ -1,5 +1,6 @@ var gamebook = { 'player' : { + 'started' : false, 'currentSection' : null, 'collections' : {}, @@ -56,7 +57,9 @@ }, 'turnTo' : function(nr) { - console.log("Turning to " + nr + "."); + if (!gamebook.player.started) { + gamebook.start(); + } if (!nr in this.sections) { throw new Exception("Can not turn to non-existing section " + nr + "."); @@ -67,7 +70,7 @@ 'start' : function() { this.hideIntroSections(); this.addClassToClass('startlink', 'nodisplay'); - this.turnTo(1); + gamebook.player.started = true; }, 'displaySection' : function(nr) { @@ -87,12 +90,19 @@ }, 'showIntroSections' : function() { + this.runActionsInIntroSections(); this.removeClassFromClass('introsection', 'nodisplay'); this.addClassToClass('displayintrolink', 'nodisplay'); this.removeClassFromClass('hideintrolink', 'nodisplay'); document.body.scrollIntoView(); }, + 'runActionsInIntroSections' : function() { + Array.prototype.forEach.call( + document.getElementsByClassName('introsectionbody'), + gamebook.runActions); + }, + 'addClassToClass' : function(className, addClass) { Array.prototype.forEach.call( document.getElementsByClassName(className), @@ -114,9 +124,13 @@ var hasXorScope = false; var hasAutoScope = false; var xorEnableNext = false; - var autoDisableAllRemainingLinks = false; + var autoDisableAllRemainingLinks = ( + gamebook.player.started && e.classList.contains('introsectionbody')); Array.prototype.forEach.call(e.childNodes, function(c) { - if (/sectionref$/.test(c.className)) { + if (!c.classList) { + return; + } + if (c.classList.contains('sectionref')) { if (enableNextLink && !autoDisableAllRemainingLinks) { gamebook.enableLink(c); if (hasAutoScope) { @@ -137,18 +151,20 @@ } else if (c.className === 'has') { enableNextLink = gamebook.player.has(c.dataset.type, c.dataset.what); - console.log("has " + c.dataset.type + - " " + c.dataset.what + " " + enableNextLink); } else if (c.className === 'hasnot') { enableNextLink = !gamebook.player.has(c.dataset.type, c.dataset.what); - console.log("has not " + c.dataset.type + - " " + c.dataset.what + " " + enableNextLink); } else if (c.className === 'xor') { hasXorScope = true; xorEnableNext = !enableNextLink; } else if (c.className === 'auto') { hasAutoScope = true; + } else if (c.classList.contains('random')) { + c.addEventListener('click', + gamebook.enableRandomLinkAfter); + c.classList.add("enabledlink"); + c.classList.remove("disabledlink"); + autoDisableAllRemainingLinks = true; } }); }, @@ -156,13 +172,35 @@ 'enableLink' : function(e) { e.addEventListener('click', gamebook.getTurnToFunction(e.dataset.ref)); - e.className = "enabledsectionref"; + e.classList.add("enabledLink"); + e.classList.remove("disabledlink"); }, 'disableLink' : function(e) { e.removeEventListener('click', gamebook.getTurnToFunction(e.dataset.ref)); - e.className = "disabledsectionref"; + e.classList.remove("enabledLink"); + e.classList.add("disabledlink"); + }, + + 'enableRandomLinkAfter' : function(event) { + this.classList.remove("enabledlink"); + this.classList.add("disabledlink"); + var links = []; + var e = this.nextSibling; + while (e) { + if (e.classList && e.classList.contains('sectionref')) { + links.push(e); + } + e = e.nextSibling; + } + if (links.length > 0) { + var selected = links[Math.floor(Math.random()*links.length)] + gamebook.enableLink(selected); + } else { + console.log("Random with nothing to select?"); + } + event.preventDefault(); }, 'addCollectionView' : function(type, name) { diff --git a/templates/html/section_ref.html b/templates/html/section_ref.html index 92cab1e..138883c 100644 --- a/templates/html/section_ref.html +++ b/templates/html/section_ref.html @@ -1 +1 @@ -%(nr)d \ No newline at end of file +%(nr)d \ No newline at end of file diff --git a/templates/html/sections_begin.html b/templates/html/sections_begin.html index db98d54..e4e7e6d 100644 --- a/templates/html/sections_begin.html +++ b/templates/html/sections_begin.html @@ -1,2 +1,2 @@ + onclick="gamebook.turnTo(1)">%(starttext)s diff --git a/templates/html/startlink.html b/templates/html/startlink.html deleted file mode 100644 index 5f8bd11..0000000 --- a/templates/html/startlink.html +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/templates/html/style.html b/templates/html/style.html index 660c7e1..f45cce2 100644 --- a/templates/html/style.html +++ b/templates/html/style.html @@ -1,5 +1,17 @@ - .enabledsectionref {font-weight: bold; cursor: pointer;} - .disabledsectionref {font-weight: bold; color: #aaa; cursor: not-allowed;} + .startlink,.sectionref,.displayintrolink,.hideintrolink { + font-weight: bold; + padding-left: 1.5em; + padding-right: 1.5em; + margin: 0.2em; + vertical-align: middle; + white-space: nowrap; + } + .startlink,.enabledlink,.displayintrolink,.hideintrolink {cursor: pointer; + background: #eef;} + .startlink:hover,.enabledlink:hover,.displayintrolink:hover, + .hideintrolink:hover {background: #a9f;} + .disabledlink {color: #bbb; cursor: not-allowed; background: #fee;} + .disabledlink:hover {background: #fee;} .sectionnumber {font-weight: bolder; margin-left: 50%%; margin-right: 50%%;} diff --git a/todo.org b/todo.org index 143a35f..3a5a503 100644 --- a/todo.org +++ b/todo.org @@ -1,4 +1,4 @@ -* TODO [37/65] [56%] +* TODO [38/65] [58%] - [X] Debug output - [X] DOT output - [X] LaTeX output @@ -43,7 +43,7 @@ - [X] HTML hide intro sections with link to display again - [X] Only accept specific characters in section names eg [a-z][a-z_0-9]+ -- [ ] Random pick of link to follow from a section. +- [X] Random pick of link to follow from a section. - [ ] Possibility to make predictable random numbers and shuffling for testing - [ ] Test generate examples and compare to expected output in all formats - [ ] Unit tests (finally...)