mirror of
https://github.com/Oreolek/raconteur.git
synced 2024-05-17 00:08:16 +03:00
Add tools.js
This commit is contained in:
parent
24bbe13945
commit
d6c0f50cab
|
@ -18,7 +18,7 @@ gulp.task('lib', function () {
|
|||
});
|
||||
|
||||
gulp.task('undularity', function () {
|
||||
return gulp.src('../undularity/undularity.js')
|
||||
return gulp.src('../undularity/*.js')
|
||||
.pipe(gulp.dest('./build/lib/'));
|
||||
});
|
||||
|
||||
|
@ -68,7 +68,7 @@ gulp.task('serve', ['default'], function () {
|
|||
gulp.watch('../template/less/*.less', ['less']);
|
||||
gulp.watch('../template/html/*.html', ['html']);
|
||||
gulp.watch('../undum/lib/*.js', ['browserify']);
|
||||
gulp.watch('../undularity/undularity.js', ['browserify']);
|
||||
gulp.watch('../undularity/*.js', ['browserify']);
|
||||
gulp.watch('../template/js/*.js', ['browserify']);
|
||||
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
var situation = require('../lib/undularity.js'),
|
||||
$ = require('jquery'),
|
||||
undum = require('../lib/undum.js');
|
||||
undum = require('../lib/undum.js'),
|
||||
tools = require('../lib/tools.js');
|
||||
|
||||
var a = situation.a,
|
||||
span = situation.span,
|
||||
|
@ -42,9 +43,9 @@ situation('markdown-features', {
|
|||
headers (as above), [external links](http://github.com), and even
|
||||
preformatted blocks of text:
|
||||
|
||||
situation('start', {
|
||||
content: "This is an example."
|
||||
});
|
||||
situation('start', {
|
||||
content: "This is an example."
|
||||
});
|
||||
|
||||
Additionally, we also support "smart quotes" and -- dashes.`,
|
||||
tags: ['testing-option'],
|
||||
|
@ -56,21 +57,21 @@ situation('special-links', {
|
|||
# Special Links
|
||||
|
||||
Undularity supports various special types of links, starting with
|
||||
${a.content('writer').class('once').writer('writerlink').tag()} links.
|
||||
${a('writer').class('once').writer('writerlink')} links.
|
||||
|
||||
Also notable are ${a.id('replacer-link').content('replacer').replacer('replacer-link').tag()}
|
||||
Also notable are ${a('replacer').id('replacer-link').replacer('replacer-link')}
|
||||
links, which replace the content of a given id.
|
||||
|
||||
And finally, we have ${
|
||||
a.class("once").content('inserter').inserter('inserter-link').tag()
|
||||
} links, which insert something into a specified element${span.id('inserter-link').tag()}.
|
||||
And finally, we have ${a('inserter').class("once").inserter('inserter-link')}
|
||||
links, which insert something into a specified element${span().id('inserter-link')}.
|
||||
`,
|
||||
writers: {
|
||||
writerlink: "Writer links can only be clicked once.",
|
||||
'replacer-link': "switching",
|
||||
'inserter-link': "-- like this"
|
||||
},
|
||||
tags: ['testing-option']
|
||||
tags: ['testing-option'],
|
||||
optionText: 'Special Links'
|
||||
});
|
||||
|
||||
situation('custom-actions', {
|
||||
|
@ -79,7 +80,7 @@ situation('custom-actions', {
|
|||
|
||||
You can define actions with custom effects that access the underlying
|
||||
Undum API. Try clicking
|
||||
${a.content('this link').action('specialaction').tag()} for example.
|
||||
${a('this link').action('specialaction')} for example.
|
||||
`,
|
||||
actions: {
|
||||
specialaction: function (character, system, from) {
|
||||
|
@ -94,6 +95,52 @@ situation('custom-actions', {
|
|||
optionText: 'Special Actions'
|
||||
});
|
||||
|
||||
situation('randomness', {
|
||||
content: (character, system, from) =>
|
||||
`
|
||||
# Randomness
|
||||
|
||||
Randomness in Undum is best if you use Undum's own random number
|
||||
generator, which ensures consistency across save games. For example,
|
||||
try saving and reloading to verify that this list of animals remains
|
||||
in the same order:
|
||||
${["dog", "cat", "alpaca", "crow"].shuffle(system).join(', ')}.
|
||||
`,
|
||||
tags: ['testing-option'],
|
||||
optionText: 'Randomness'
|
||||
});
|
||||
|
||||
var myIterators = {};
|
||||
|
||||
situation('iterators', {
|
||||
content: (character, system, from) =>
|
||||
`
|
||||
# Iterators
|
||||
|
||||
Iterators are an useful feature for generating adaptive text. For example,
|
||||
clicking ${a('this link').writer('iterator')} will output a
|
||||
new paragraph with a random animal.
|
||||
|
||||
Initialising iterators during your init function will make them even more
|
||||
useful, since it lets you pass the system object on to them to ensure
|
||||
consistency between saves. For example, ${a('this link')
|
||||
.writer('consistent')} will produce the same output every
|
||||
time.
|
||||
|
||||
Other iterators allow you to ${a('cycle').writer('cycler')} through
|
||||
different content in ${a('various ways').writer('stopper')}.
|
||||
`,
|
||||
writers: {
|
||||
iterator: tools.oneOf(['Cat', 'Dog', 'Crow', 'Alpaca']).randomly(),
|
||||
consistent: () => myIterators.consistentIterator(),
|
||||
cycler: tools.oneOf(['Spring', 'Summer', 'Fall', 'Winter']).cycling(),
|
||||
stopper: tools.oneOf(['First click', 'Second click', 'Another click']).stopping()
|
||||
},
|
||||
tags: ['testing-option'],
|
||||
optionText: 'Iterators'
|
||||
});
|
||||
|
||||
|
||||
qualities({
|
||||
stats: {
|
||||
name: 'Statistics',
|
||||
|
@ -107,6 +154,9 @@ undum.game.init = function (character, system) {
|
|||
character.qualities.intelligence = 10;
|
||||
character.qualities.perception = 10;
|
||||
character.qualities.size = 1;
|
||||
myIterators.consistentIterator =
|
||||
tools.oneOf(['Blue', 'Black', 'Green', 'Red', 'White'])
|
||||
.inRandomOrder(system);
|
||||
};
|
||||
|
||||
$(function(){undum.begin()});
|
130
undularity/tools.js
Normal file
130
undularity/tools.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Undularity Tools
|
||||
|
||||
Those functions are not a core part of Undularity, but provide some
|
||||
general functionality that relates to adaptive text generation.
|
||||
|
||||
This is provided partly as a helper to less technical users, and as
|
||||
a convenience for authors.
|
||||
*/
|
||||
|
||||
/* Monkey patching */
|
||||
|
||||
/* Array.prototype.shuffle() */
|
||||
|
||||
/*
|
||||
Shuffles an array. It can use Undum's random number generator implementation,
|
||||
so it expects a System.rnd object to be passed into it. If one isn't
|
||||
supplied, it will use Math.Random instead.
|
||||
|
||||
This is an implementation of the Fischer-Yates (Knuth) shuffle.
|
||||
|
||||
Returns the shuffled array.
|
||||
*/
|
||||
|
||||
Array.prototype.shuffle = function (system) {
|
||||
var rng = (system) ? system.rnd.random : Math.random;
|
||||
// slice() clones the array. Object members are copied by reference,
|
||||
// beware.
|
||||
var newArr = this.slice();
|
||||
var m = newArr.length;
|
||||
|
||||
while (m) {
|
||||
let i = Math.floor(rng() * m --);
|
||||
let t = newArr[m];
|
||||
newArr[m] = newArr[i];
|
||||
newArr[i] = t;
|
||||
}
|
||||
|
||||
return newArr;
|
||||
};
|
||||
|
||||
/*
|
||||
oneOf()
|
||||
|
||||
Takes an array and returns an object with several methods. Each method
|
||||
returns an iterator which iterates over the array in a specific way:
|
||||
|
||||
inOrder()
|
||||
Returns the array items in order.
|
||||
|
||||
cycling()
|
||||
Returns the array items in order, cycling back to the first item when
|
||||
it runs out.
|
||||
|
||||
stopping()
|
||||
Returns the array items in order, then repeats the last item when it
|
||||
runs out.
|
||||
|
||||
randomly()
|
||||
Returns the array items at random. Takes a system object, for consistent
|
||||
randomness. Will never return the same item twice in a row.
|
||||
|
||||
trulyAtRandom()
|
||||
Returns the array items purely at random. Takes a system object, for
|
||||
consistent randomness.
|
||||
|
||||
inRandomOrder()
|
||||
Returns the array items in a random order. Takes a system object, for
|
||||
consistent randomness.
|
||||
*/
|
||||
|
||||
var oneOf = function (ary) {
|
||||
|
||||
return {
|
||||
inOrder () {
|
||||
var i = 0;
|
||||
return function () {
|
||||
return ary[i++];
|
||||
};
|
||||
},
|
||||
|
||||
cycling () {
|
||||
var i = 0;
|
||||
return function () {
|
||||
if (i >= ary.length) i = 0;
|
||||
return ary[i++];
|
||||
};
|
||||
},
|
||||
|
||||
stopping () {
|
||||
var i = 0;
|
||||
return function () {
|
||||
if (i >= ary.length) i = ary.length - 1;
|
||||
return ary[i++];
|
||||
}
|
||||
},
|
||||
|
||||
randomly (system) {
|
||||
var rng = (system) ? system.random : Math.random,
|
||||
last;
|
||||
return function () {
|
||||
var i;
|
||||
|
||||
do {
|
||||
i = Math.floor(rng() * ary.length);
|
||||
} while (i === last);
|
||||
|
||||
last = i;
|
||||
return ary[i];
|
||||
};
|
||||
},
|
||||
|
||||
trulyAtRandom (system) {
|
||||
var rng = (system) ? system.random : Math.random;
|
||||
return function () {
|
||||
return ary[Math.floor(rng() * ary.length)];
|
||||
};
|
||||
},
|
||||
|
||||
inRandomOrder (system) {
|
||||
var shuffled = ary.shuffle(system),
|
||||
i = 0;
|
||||
return function () {
|
||||
return shuffled[i++];
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
exports.oneOf = oneOf;
|
|
@ -179,18 +179,28 @@ UndularitySituation.prototype.act = function (character, system, action) {
|
|||
|
||||
var responses = {
|
||||
writer: function (ref) {
|
||||
if (self.writers[ref] === undefined) {
|
||||
console.log(self);
|
||||
throw new Error("Tried to call undefined writer:" + ref);
|
||||
}
|
||||
system.write(
|
||||
markdown.render(
|
||||
self.writers[ref].fcall(self, character, system, action)
|
||||
).fade());
|
||||
},
|
||||
replacer: function (ref) {
|
||||
if (self.writers[ref] === undefined) {
|
||||
throw new Error("Tried to call undefined replacer:" + ref);
|
||||
}
|
||||
system.replaceWith(
|
||||
markdown.renderInline(
|
||||
self.writers[ref].fcall(self, character, system, action)
|
||||
).spanWrap().fade(), `#${ref}`);
|
||||
},
|
||||
inserter: function (ref) {
|
||||
if (self.writers[ref] === undefined) {
|
||||
throw new Error("Tried to call undefined inserter:" + ref);
|
||||
}
|
||||
system.writeInto(
|
||||
markdown.renderInline(
|
||||
self.writers[ref].fcall(self, character, system, action)
|
||||
|
@ -229,11 +239,11 @@ UndularitySituation.prototype.act = function (character, system, action) {
|
|||
once: The 'once' special link class. A getter.
|
||||
*/
|
||||
|
||||
var elementMonad = function (element) {
|
||||
var elementHelper = function (element) {
|
||||
this.element = element;
|
||||
};
|
||||
|
||||
var monadSetterGen = function (prop) {
|
||||
var elementSetterGen = function (prop) {
|
||||
return function (value) {
|
||||
var newMonad = Object.create(this);
|
||||
newMonad['_' + prop] = value;
|
||||
|
@ -241,13 +251,13 @@ var monadSetterGen = function (prop) {
|
|||
}
|
||||
}
|
||||
|
||||
elementMonad.prototype.class = monadSetterGen("class");
|
||||
elementMonad.prototype.id = monadSetterGen("id");
|
||||
elementMonad.prototype.type = monadSetterGen("linkType");
|
||||
elementMonad.prototype.content = monadSetterGen("content");
|
||||
elementMonad.prototype.ref = monadSetterGen("ref");
|
||||
elementMonad.prototype.url = elementMonad.prototype.ref;
|
||||
elementMonad.prototype.situation = elementMonad.prototype.ref;
|
||||
elementHelper.prototype.class = elementSetterGen("class");
|
||||
elementHelper.prototype.id = elementSetterGen("id");
|
||||
elementHelper.prototype.type = elementSetterGen("linkType");
|
||||
elementHelper.prototype.content = elementSetterGen("content");
|
||||
elementHelper.prototype.ref = elementSetterGen("ref");
|
||||
elementHelper.prototype.url = elementHelper.prototype.ref;
|
||||
elementHelper.prototype.situation = elementHelper.prototype.ref;
|
||||
|
||||
var linkTypeGen = function (type) {
|
||||
return function (ref) {
|
||||
|
@ -255,12 +265,12 @@ var linkTypeGen = function (type) {
|
|||
}
|
||||
}
|
||||
|
||||
elementMonad.prototype.writer = linkTypeGen("writer");
|
||||
elementMonad.prototype.replacer = linkTypeGen("replacer");
|
||||
elementMonad.prototype.inserter = linkTypeGen("inserter");
|
||||
elementMonad.prototype.action = linkTypeGen("action");
|
||||
elementHelper.prototype.writer = linkTypeGen("writer");
|
||||
elementHelper.prototype.replacer = linkTypeGen("replacer");
|
||||
elementHelper.prototype.inserter = linkTypeGen("inserter");
|
||||
elementHelper.prototype.action = linkTypeGen("action");
|
||||
|
||||
elementMonad.prototype.tag = function () {
|
||||
elementHelper.prototype.toString = function () {
|
||||
var classes = "",
|
||||
classString = "",
|
||||
idString = "",
|
||||
|
@ -300,8 +310,18 @@ elementMonad.prototype.tag = function () {
|
|||
return `<${this.element}${classString}${idString}${hrefString}>${contentString}</${this.element}>`;
|
||||
};
|
||||
|
||||
var a = Object.freeze(new elementMonad("a"));
|
||||
var span = Object.freeze(new elementMonad("span"));
|
||||
var a_proto = Object.freeze(new elementHelper("a"));
|
||||
var span_proto = Object.freeze(new elementHelper("span"));
|
||||
|
||||
var a = function (content) {
|
||||
if (content) return a_proto.content(content);
|
||||
return a_proto;
|
||||
};
|
||||
|
||||
var span = function (content) {
|
||||
if (content) return span_proto.content(content);
|
||||
return span_proto;
|
||||
};
|
||||
|
||||
/*
|
||||
Quality definition function
|
||||
|
|
Loading…
Reference in a new issue