1
0
Fork 0
mirror of https://github.com/Oreolek/gamebookformat.git synced 2024-06-30 21:55:10 +03:00
gamebookformat/expected/references.html

375 lines
14 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Gamebook</title>
<script>
var gamebook = {
'player' : {
'started' : false,
'currentSection' : null,
'collections' : {},
'collect' : function(type, name) {
this.collections[type] = {
'name' : name,
'contents' : [],
'add' : function(what) {
if (this.contents.indexOf(what) === -1
&& !(what in gamebook.dropped[type])) {
this.contents.push(what);
this.contents.sort();
}
},
'drop' : function(what) {
var i = this.contents.indexOf(what);
if (i >= 0) {
this.contents.splice(i, 1);
gamebook.dropped[type][what] = true;
}
},
'has' : function(what) {
return this.contents.indexOf(what) >= 0;
}
};
gamebook.dropped[type] = {};
gamebook.addCollectionView(type, name);
},
'add' : function(type, what) {
this.collections[type].add(what);
gamebook.updateCollectionsView();
},
'drop' : function(type, what) {
this.collections[type].drop(what);
gamebook.updateCollectionsView();
},
'has' : function(type, what) {
return this.collections[type].has(what);
}
},
'sections' : {},
'turnToFunctions' : {},
'dropped' : {},
'addSection' : function(nr, element) {
var section = {'element' : element, 'nr' : nr};
this.sections[nr] = section;
},
'turnTo' : function(nr) {
if (!gamebook.player.started) {
gamebook.start();
}
if (!nr in this.sections) {
throw new Exception("Can not turn to non-existing section "
+ nr + ".");
}
this.displaySection(nr);
},
'start' : function() {
this.hideIntroSections();
this.addClassToClass('startlink', 'nodisplay');
gamebook.player.started = true;
},
'displaySection' : function(nr) {
if (this.player.currentSection) {
this.player.currentSection.element.style.display = 'none';
}
var e = this.sections[nr].element;
this.runActions(e.getElementsByClassName('sectiontext')[0]);
e.style.display = 'block';
this.player.currentSection = gamebook.sections[nr];
},
'hideIntroSections' : function() {
this.addClassToClass('introsection', 'nodisplay');
this.removeClassFromClass('displayintrolink', 'nodisplay');
this.addClassToClass('hideintrolink', 'nodisplay');
},
'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),
function(e) {
e.classList.add(addClass);
});
},
'removeClassFromClass' : function(className, removeClass) {
Array.prototype.forEach.call(
document.getElementsByClassName(className),
function(e) {
e.classList.remove(removeClass);
});
},
'runActions' : function(e) {
var enableNextLink = true;
var hasXorScope = false;
var hasAutoScope = false;
var xorEnableNext = false;
var autoDisableAllRemainingLinks = (
gamebook.player.started && e.classList.contains('introsectionbody'));
Array.prototype.forEach.call(e.childNodes, function(c) {
if (!c.classList) {
return;
}
if (c.classList.contains('sectionref')) {
if (enableNextLink && !autoDisableAllRemainingLinks) {
gamebook.enableLink(c);
if (hasAutoScope) {
autoDisableAllRemainingLinks = true;
}
} else {
gamebook.disableLink(c);
}
enableNextLink = !(hasXorScope && !xorEnableNext);
hasAutoScope = false;
hasXorScope = false;
} else if (c.classList.contains('collect')) {
gamebook.player.collect(c.dataset.type, c.dataset.name);
} else if (c.classList.contains('add')) {
gamebook.player.add(c.dataset.type, c.dataset.what);
} else if (c.classList.contains('drop')) {
gamebook.player.drop(c.dataset.type, c.dataset.what);
} else if (c.classList.contains('has')) {
enableNextLink = gamebook.player.has(c.dataset.type,
c.dataset.what);
} else if (c.classList.contains('hasnot')) {
enableNextLink = !gamebook.player.has(c.dataset.type,
c.dataset.what);
} else if (c.classList.contains('xor')) {
hasXorScope = true;
xorEnableNext = !enableNextLink;
} else if (c.classList.contains('auto')) {
hasAutoScope = true;
} else if (c.classList.contains('random')) {
c.addEventListener('click',
gamebook.enableRandomLinkAfter);
c.classList.add("enabledlink");
c.classList.remove("disabledlink");
autoDisableAllRemainingLinks = true;
}
});
},
'enableLink' : function(e) {
e.addEventListener('click',
gamebook.getTurnToFunction(e.dataset.ref));
e.classList.add("enabledlink");
e.classList.remove("disabledlink");
},
'disableLink' : function(e) {
e.removeEventListener('click',
gamebook.getTurnToFunction(e.dataset.ref));
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) {
var ce = document.getElementById('collections');
var template = document.getElementById('collectionTemplate');
var e = template.cloneNode(true);
e.className = "collection";
e.getElementsByClassName('collectionheading')[0].innerHTML = name;
e.dataset.type = type;
ce.appendChild(e);
},
'updateCollectionsView' : function() {
var ce = document.getElementById('collections');
Array.prototype.forEach.call(ce.childNodes, function(c) {
if (c.className === 'collection') {
var type = c.dataset.type;
var collection = gamebook.player.collections[type];
var cc = c.getElementsByClassName('collectioncontents')[0];
cc.innerHTML = collection.contents.join(', ');
}
});
},
'getTurnToFunction' : function(nr) {
if (nr in this.turnToFunctions) {
return this.turnToFunctions[nr];
} else {
var f = function () {
gamebook.turnTo(nr);
};
this.turnToFunctions[nr] = f;
return f;
}
}
};
</script>
<style>
.startlink,.sectionref,.displayintrolink,.hideintrolink,.found,.add,.random {
font-weight: bold;
margin: 0.2em;
vertical-align: middle;
white-space: nowrap;
}
.sectionref.enabledlink {
padding-left: 1.5em;
padding-right: 1.5em;
}
.startlink,.enabledlink,.displayintrolink,.hideintrolink,.found,.random {
cursor: pointer;}
.startlink,.enabledlink,.displayintrolink,.hideintrolink,.found,
.random {background: #eef;
}
.startlink:hover,.enabledlink:hover,.displayintrolink:hover,
.hideintrolink:hover {background: #a9f;}
.disabledlink {color: #bbb; cursor: not-allowed; background: inherit;}
.disabledlink:hover {background: inherit;}
.sectionnumber {font-weight: bolder;
margin-left: 50%;
margin-right: 50%;}
.section {display: none; width: 90%; margin-left: 5%; margin-right: 5%;}
.sectiontext {margin-top: 0.5em;}
.gamebook {max-width: 30em; padding: 1em; width: 100%; font-size: 133%;}
.collections {margin-top: 4em;}
.collection {background: #ddd; margin-top: 1em;}
.collectionheading {}
.collectionheading::after {content: ": ";}
.collectioncontents {}
.collect {}
.add {font-weight: bold;}
.drop {font-style: italic;}
.has {font-style: italic;}
.hasnot {font-style: italic;}
.collectionTemplate {display: none;}
.sectionimage {width: 100%; padding: 1em;}
.nodisplay {display: none;}
</style>
</head>
<body>
<div class="hideintrolink nodisplay"
onclick="gamebook.hideIntroSections()">(hide instructions)</div>
<div class="gamebook">
<div class="introsection">
<span class="introsectionheading">Introduction</span>
<div class="introsectionbody">
This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at <a class="sectionref enabledlink" data-ref="1">1</a> or the next section at <a class="sectionref enabledlink" data-ref="55">55</a>.
</div>
</div>
<div class="startlink"
onclick="gamebook.turnTo(1)">Turn to 1 to begin.</div>
<div class="section" id="section1">
<span class="sectionnumber" id="para1">1</span>
<div class="sectiontext">
This is where the adventure begins. You can go on to the next section, see <a class="sectionref enabledlink" data-ref="55">55</a> or try the random selection feature at <a class="sectionref enabledlink" data-ref="201">201</a>.
</div>
</div>
<script>
if (this.gamebook) {
gamebook.addSection(1, document.getElementById('section1'));
}
</script> <div class="section" id="section13">
<span class="sectionnumber" id="para13">13</span>
<div class="sectiontext">
Alternative ending.
</div>
</div>
<script>
if (this.gamebook) {
gamebook.addSection(13, document.getElementById('section13'));
}
</script> <div class="section" id="section55">
<span class="sectionnumber" id="para55">55</span>
<div class="sectiontext">
This is the next section. Go on to the end at <a class="sectionref enabledlink" data-ref="247">247</a>.
</div>
</div>
<script>
if (this.gamebook) {
gamebook.addSection(55, document.getElementById('section55'));
}
</script> <div class="section" id="section201">
<span class="sectionnumber" id="para201">201</span>
<div class="sectiontext">
<span class="random enabledlink">Pick a destination at random</span> from <a class="sectionref enabledlink" data-ref="55">55</a> or <a class="sectionref enabledlink" data-ref="247">247</a> or <a class="sectionref enabledlink" data-ref="13">13</a>.
</div>
</div>
<script>
if (this.gamebook) {
gamebook.addSection(201, document.getElementById('section201'));
}
</script> <div class="section" id="section247">
<span class="sectionnumber" id="para247">247</span>
<div class="sectiontext">
The end.
</div>
</div>
<script>
if (this.gamebook) {
gamebook.addSection(247, document.getElementById('section247'));
}
</script> <div id="collections" class="collections">
</div>
<div id="collectionTemplate" class="collectionTemplate">
<span class="collectionheading"></span>
<span class="collectioncontents"></span>
</div>
</div>
<script>
if (this.gamebook) {
gamebook.runActionsInIntroSections();
}
</script>
<div class="displayintrolink nodisplay"
onclick="gamebook.showIntroSections()">(show instructions)</div>
</body>
</html>