├── .project
├── TwineQuest.mob.twee
├── TwineQuest.twee
├── Wiki
└── TiddlyWiki Refrence Here.txt
├── demo
├── TwineQuest_proposal.html
├── TwineQuest_proposal.twee
└── TwineQuest_proposal.tws
├── eturnerx.tq.autosynonym.twee
├── eturnerx.tq.helloworld.twee
├── eturnerx.tq.mobnamer.elvish.twee
├── eturnerx.tq.mobnamer.goblin.twee
├── eturnerx.tq.mobnamer.roman.twee
├── eturnerx.tq.mobnamer.twee
├── examples
├── 9999 Macro name.twee
└── Item syntax example.twee
├── macros
├── 9999 Macro atend.twee
├── 9999 Macro br.twee
└── 9999 Macro while.twee
├── mods
└── 9990 Display Console.twee
└── styles
├── 9991 Style BlueScreen.twee
└── 9991 Style GreenScreen.twee
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TwineQuest
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TwineQuest.mob.twee:
--------------------------------------------------------------------------------
1 | ::TwineQuest.mob.twee About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | PURPOSE:
5 | TwineQuest plugin for mobs (monster objects)
6 |
7 | This plugin implements basic functionality and can be extended by other
8 | TwineQuest plugins to add custom attributes and functionality to the
9 | mobs.
10 |
11 | USAGE: {mob}
12 |
13 | CONTRIBUTORS:
14 | (Add your name as you contribute)
15 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
16 |
17 |
18 | //TODO: state.history[0].variables[i] = this._internalstore[i]; should copy not reference the data
19 |
20 | ::TwineQuest.mob [tq.system.plugin]
21 | {
22 | version: '0.1.0',
23 |
24 | tag: 'mob',
25 |
26 | onInit: null,
27 |
28 | onPassage: function(passage) {
29 | if(passage && passage.text) {
30 | var t = TwineQuest.acnToObject(passage.text);
31 | if(t.id == null) {
32 | t.id = passage.title;
33 | }
34 | this.onInitMob(t.id, t);
35 | }
36 | },
37 |
38 | onStart: function() {
39 | for(var i in this._internalstore) {
40 | state.history[0].variables[i] = this._internalstore[i];
41 | TwineQuest.registerLabel(i, this.handleLabel, state.history[0].variables[i], this);
42 | }
43 | },
44 |
45 | onEvent: null,
46 |
47 | handleLabel: function(place, label, params, parser, data, plugin) {
48 | if(plugin.onLabel(place, label, params, parser, data, plugin)) {
49 | if(params.length == 0) {
50 | insertElement(place, 'span', null, 'tq_mob ' + data.name, data.name);
51 | } else if(params.length == 1 && params[0] == 'describe') {
52 | insertElement(place, 'span', null, 'tq_mob describe ' + data.name, plugin.onDescribe(place, label, params, parser, data, plugin));
53 | } else if(params.length == 1 && data[params[0]] != null) {
54 | insertElement(place, 'span', null, 'tq_mob ' + data.name, data[params[0]]);
55 | } else {
56 | insertElement(place, 'span', null, 'tq_mob ' + data.name, data.name + (params.length > 0 ? ' ' : '') + params.join(' '));
57 | }
58 | }
59 | },
60 |
61 | //The onInitMob member is for hooking by extensions when a mob's data structure is created
62 | onInitMob: function(tid, mob) {
63 | if(mob.name == null && mob.id) {
64 | mob.name = mob.id;
65 | }
66 | if(mob.type == null) {
67 | mob.type = 'tq.mob';
68 | }
69 | if(mob.description == null) {
70 | mob.description = mob.name + ' is indescribable.';
71 | }
72 | TwineQuest.findPluginById('TwineQuest.mob')._internalstore[tid] = mob;
73 | },
74 |
75 | //The onLabel member is for hooking by extensions to the mob. Return false to cancel default handling
76 | onLabel: function(place, label, params, parser, data, plugin){ return true; },
77 |
78 | //The onDescribe member is for hooking by extensions to the mob. Returns a string description
79 | onDescribe: function(place, label, params, parser, data, plugin){ return data.description; },
80 |
81 | _internalstore: {},
82 | }
83 |
--------------------------------------------------------------------------------
/TwineQuest.twee:
--------------------------------------------------------------------------------
1 | ::TwineQuest.twee About [Twine.private]
2 | LICENSE: Public Domain
3 | PURPOSE:
4 | This is the core TwineQuest file. It contains things that are common to
5 | all TwineQuest plugins. The purpose is to:
6 |
7 | 1) Bootstrap the TwineQuest system
8 | 2) Add TwineQuest support to the wikifier
9 | 3) Provide utility functions useful to TwineQuest plugins
10 | 3) Register TwineQuest plugins from the PassageStore
11 | 4) Send events to TwineQuest plugins: init, start
12 | 5) Built in plugins with near universal appeal tq.vars, tq.object
13 |
14 |
15 | TwineQuest plugins are optional. They should be as optional and rely on
16 | each other as little as practicable.
17 |
18 |
19 | USAGE:
20 | You will need a recent alpha version of v1.3.5 or v1.3.6 of Twine or
21 | later.
22 | Create a passage with the title "StoryIncludes"
23 | List this file (with relative path) on it's own line inside this passage
24 | (You may list file with an http url too)
25 | List the filenames of any TwineQuest plugins that you wish to use inside
26 | the StoryIncludes passage. One per line.
27 |
28 |
29 | CONTRIBUTORS:
30 | (Add your name as you contribute)
31 | Henry Soule
32 | Emmanuel King Turner (eturnerx / stormrose / Et) http://eturnerx.com
33 |
34 |
35 |
36 |
37 |
38 | ::TwineQuest Core Macro [script tq.core]
39 | try {
40 |
41 | // Bootstrap the TwineQuest System
42 | version.extensions['TwineQuestSystem'] = { major:0, minor:1, revision:0 };
43 | var TwineQuest = {
44 | plugins: [], // TwineQuest plugins
45 | tags: {}, // The passage tags that TwineQuest plugins handle
46 | labels: {}, // The {passagetext} that TwineQuest responds to
47 | };
48 |
49 | // Add TwineQuest support to the wikifier
50 | Wikifier.formatters.push({
51 | name: 'TwineQuest',
52 | match: '{',
53 | handler: function(w) {
54 | var s = w.source.substr(w.matchStart);
55 | if(s.length > 2 && s.indexOf('}') > 0) {
56 | s = s.substr(1,s.indexOf('}')-1);
57 | w.nextMatch = w.matchStart + s.length + 2;
58 | if(s.length == 0) {
59 | s = ['_'];
60 | } else {
61 | s = s.split(' ');
62 | }
63 | var label = s.shift();
64 | if(TwineQuest.labels[label] && typeof TwineQuest.labels[label].handler == 'function') {
65 | TwineQuest.labels[label].handler(
66 | w.output, label, s, w,
67 | (TwineQuest.labels[label].data ? TwineQuest.labels[label].data : null),
68 | (TwineQuest.labels[label].plugin ? TwineQuest.labels[label].plugin : null)
69 | );
70 | } else {
71 | var label1 = (label.indexOf('$') == 0 ? label.substr(1) : label);
72 | var branches = label1.split('.');
73 | branches = branches.concat(s);
74 | var node = state.history[0].variables;
75 | var traverse = true;
76 | var newnode;
77 | var i = branches.length;
78 | while(traverse == true && i--) {
79 | newnode = branches.shift();
80 | if(node[newnode] != null) {
81 | node = node[newnode];
82 | } else {
83 | traverse = false;
84 | }
85 | }
86 | if(traverse) {
87 | insertElement(w.output,'span',null,'tq_print_var',node);
88 | } else {
89 | insertElement(w.output,'span',null,'marked',label + (s.length > 0 ? ' ' : '') + s.join(' '));
90 | }
91 | }
92 | } else {
93 | insertElement(w.output,'span',null,'marked','TwineQuest:Opening Curly Brace with no match closing curly brace:');
94 | }
95 | }
96 | });
97 |
98 |
99 | // Provide utility functions useful to TwineQuest plugins
100 |
101 | //isNumber() from: http://stackoverflow.com/a/1830844
102 | TwineQuest.isNumber = function(n) {
103 | return !isNaN(parseFloat(n)) && isFinite(n);
104 | };
105 | TwineQuest.registerPlugin = function(a) {
106 | if(a != null) {
107 | if(a.priority == null) {
108 | a.priority = 1000;
109 | }
110 | this.plugins.push(a);
111 | this.plugins.sort(function(a,b){ return a.priority - b.priority; });
112 | }
113 | };
114 | TwineQuest.registerLabel = function(label, xhandler, xdata, xplugin) {
115 | this.labels[label] = { handler: xhandler, data: xdata, plugin: xplugin };
116 | };
117 | TwineQuest.findPluginById = function(id) {
118 | var r = null;
119 | var i = this.plugins.length - 1;
120 | do {
121 | if(this.plugins[i].id == id) {
122 | r = this.plugins[i];
123 | break;
124 | }
125 | } while(i--);
126 | return r;
127 | };
128 | TwineQuest.acnToObject = function(text) {
129 | var r = {};
130 | var kv = [];
131 | var t = null;
132 | var state = 0; //0 looking for var, 1 adding to value, 2 lastlineblank
133 |
134 | var _numvar = function(t) {
135 | var r = t;
136 | if(TwineQuest.isNumber(t)) {
137 | t = parseFloat(r);
138 | if(!isNaN(t)) {
139 | r = t;
140 | } else {
141 | t = parseInt(r);
142 | if(!isNaN(t)) {
143 | r = t;
144 | }
145 | }
146 | }
147 | return r;
148 | }
149 |
150 | var lines = text.split(String.fromCharCode(10));
151 | for(var i in lines) {
152 | var line = lines[i];
153 | switch(state) {
154 | case 0:
155 | if(line.indexOf(':')>-1) {
156 | kv = line.split(':');
157 | kv[0] = kv[0].trim();
158 | kv[1] = kv[1].trim();
159 | if(kv[1].length > 0) {
160 | r[kv[0]] = _numvar(kv[1]);
161 | } else {
162 | state = 1;
163 | }
164 | }
165 | break;
166 |
167 | case 1:
168 | line = line.trim();
169 | if(line.length == 0) {
170 | state = 2;
171 | kv[1] = kv[1] + String.fromCharCode(10);
172 | } else {
173 | kv[1] = kv[1] + line + String.fromCharCode(10);
174 | }
175 | break;
176 |
177 | case 2:
178 | line = line.trim();
179 | var icolon = line.indexOf(':');
180 | var ispace = line.indexOf(' ');
181 | if(icolon > 0 && (ispace < 0 || ispace >= icolon - 1)) {
182 | r[kv[0]] = _numvar(kv[1].trim());
183 | kv = line.split(':');
184 | kv[0] = kv[0].trim();
185 | kv[1] = kv[1].trim();
186 | if(kv[1].length > 0) {
187 | r[kv[0]] = kv[1];
188 | state = 0;
189 | } else {
190 | state = 1;
191 | }
192 | } else {
193 | kv[1] = kv[1] + line + String.fromCharCode(10);
194 | if(line.length > 0) {
195 | state = 1;
196 | }
197 | }
198 | break;
199 | }
200 | }
201 | if(state != 0) {
202 | r[kv[0]] = _numvar(kv[1].trim());
203 | }
204 | return r;
205 | };
206 | TwineQuest.initPlugins = function() {
207 | for(var ip = 0; ip < this.plugins.length; ip++) {
208 | var a = this.plugins[ip];
209 | if(a != null) {
210 | if(typeof a.onInit == 'function') {
211 | a.onInit();
212 | }
213 | if(typeof a.onEvent == 'function') {
214 | a.onEvent('init',null);
215 | }
216 | }
217 | }
218 | };
219 | TwineQuest.tagFindPlugins = function() {
220 | var ip = this.plugins.length - 1;
221 | do {
222 | var a = this.plugins[ip];
223 | if(a && a.tag && (typeof a.onPassage == 'function' || typeof a.onEvent == 'function')) {
224 | var p = tale.lookup('tags', 'tq.' + a.tag);
225 | for(var i = 0; i < p.length; i++) {
226 | if(typeof a.onPassage == 'function') {
227 | a.onPassage(p[i]);
228 | }
229 | if(typeof a.onEvent == 'function') {
230 | a.onEvent('passage', p[i]);
231 | }
232 | }
233 | }
234 | } while(ip--);
235 | };
236 |
237 |
238 | // Built in plugins with near universal appeal
239 | // Automatically set twine variables from tagged passages at story start
240 | TwineQuest.registerPlugin({
241 | id: 'TwineQuest.AutoVars',
242 | version: '0.1.0',
243 | tag: 'vars',
244 | onPassage: function(passage) {
245 | if(passage && passage.text) {
246 | var t = TwineQuest.acnToObject(passage.text);
247 | for(var i in t) {
248 | this._internalstore[i] = t[i];
249 | }
250 | }
251 | },
252 | onStart: function() {
253 | for(var i in this._internalstore) {
254 | state.history[0].variables[i] = this._internalstore[i];
255 | }
256 | },
257 | _internalstore: {},
258 | });
259 |
260 | // Automatically set twine objects from tagged passages at story start
261 | TwineQuest.registerPlugin({
262 | id: 'TwineQuest.AutoObject',
263 | version: '0.1.0',
264 | tag: 'object',
265 | onPassage: function(passage) {
266 | var tid;
267 | if(passage && passage.text) {
268 | var t = TwineQuest.acnToObject(passage.text);
269 | tid = (t.id == null ? passage.title : t.id);
270 | if(t.type == null) {
271 | t.type = 'tq.object';
272 | }
273 | this._internalstore[tid] = t;
274 | }
275 | },
276 | onStart: function() {
277 | for(var i in this._internalstore) {
278 | state.history[0].variables[i] = Object.create(this._internalstore[i]);
279 | }
280 | },
281 | _internalstore: {},
282 | });
283 |
284 |
285 | // Register TwineQuest plugins from the PassageStore
286 | var p = tale.lookup('tags','tq.system.plugin');
287 | for(var tqi=0;tqi
>{tpms}
23 |
24 |
25 | Is the TwineQuest.AutoVars built-in plugin working?
26 | 1: <>
27 | 2: <>
28 | 3: <>
29 |
30 | -and with alternative curly bracket syntax?
31 | 4: {$autovar4}
32 | 5: {autovar5}
33 |
34 |
35 | Does the TwineQuest.AutoObjects built-in plugin work?
36 | Object One: <>
37 | <>
38 |
39 | -and with alternative curly bracket syntax?
40 | Object Two: {$bananaman.name}
41 | {bananaman description}
42 |
43 |
44 | What about mobs (monster objects)?
45 | As you enter you see {mob1 describe}. His name is {mob1} and he is <> (yes, {mob1.age}) years old.
46 | {mob2}: {mob2 describe} -- (use the tq.mob plugin)
47 | {$mob3.name}: {$mob3 description} -- (autogen use print macro shortcut by prefixing a $)
48 | {mob4} is a {mob4 culture}. - autogen with culture name
49 |
50 | [[Link 1]] (will set the $test var after the jump)
51 |
52 |
53 |
54 | ::Link 1
55 | <>
56 | More frelling syntax: {test will still fail}, but try going back again.
57 |
58 | [[Start again|RealStart]]
59 |
60 |
61 |
62 | ::Autoset some variables [tq.vars]
63 | autovar1: harro
64 | autovar2:
65 | This is a big longer and includes much more stuff that goes over several
66 | lines like this. We'd use this for things that are more descriptive.
67 |
68 | autovar3:
69 | Since acn (attribute colon newline) format terminates on a blank line
70 | then how does one handle this problem?
71 |
72 | Where a var needs to include it's own newlines.
73 |
74 | Before we can start another variable.
75 |
76 | autovar4: Just detect colon with no preceding spaces
77 |
78 |
79 | ::Autoset some more variables [tq.vars]
80 | autovar5: whee!
81 |
82 |
83 | ::potatoman [tq.object]
84 | name: Mr. PotatoMan
85 | description:
86 | Brown skinned and irregularly shaped. At home in the dirt.
87 |
88 |
89 | ::another auto raw object [tq.object]
90 | id: bananaman
91 | name: Mr. BananaMan
92 | description: Yellow, long and hangs in trees.
93 |
94 |
95 |
96 | ::mob1 [tq.mob]
97 | name: Tom
98 | description: a small, confused boy
99 | age: 7
100 |
101 | ::Another mob monster object [tq.mob]
102 | id: mob2
103 | name: Richard
104 | description:
105 | A small boy about eight years old. Afraid but putting on a brave face.
106 |
107 | ::Empty Mob [tq.mob]
108 | id: mob3
109 |
110 | ::Generated Mob [tq.mob]
111 | id: mob4
112 | culture: Goblin
113 |
114 |
115 | ::Some Stylesheet [stylesheet]
116 | .TwineQuest, .tq_mob {
117 | color: #000;
118 | background-color: #ff9;
119 | }
120 |
--------------------------------------------------------------------------------
/demo/TwineQuest_proposal.tws:
--------------------------------------------------------------------------------
1 | (dp0
2 | S'buildDestination'
3 | p1
4 | VC:\u005cDocuments and Settings\u005cAdministrator\u005cgit\u005ctweecode\u005cTwineQuest\u005cdemo\u005cTwineQuest_proposal.html
5 | p2
6 | sS'saveDestination'
7 | p3
8 | VC:\u005cDocuments and Settings\u005cAdministrator\u005cgit\u005ctweecode\u005cTwineQuest\u005cdemo\u005cTwineQuest_proposal.tws
9 | p4
10 | sS'target'
11 | p5
12 | S'Responsive'
13 | p6
14 | sS'storyPanel'
15 | p7
16 | (dp8
17 | S'widgets'
18 | p9
19 | (lp10
20 | (dp11
21 | S'selected'
22 | p12
23 | I00
24 | sS'pos'
25 | p13
26 | (lp14
27 | I10
28 | aI10
29 | asS'passage'
30 | p15
31 | (itiddlywiki
32 | Tiddler
33 | p16
34 | (dp17
35 | S'text'
36 | p18
37 | V<>
\u000a
38 | p19
39 | sS'tags'
40 | p20
41 | (lp21
42 | sS'created'
43 | p22
44 | ctime
45 | struct_time
46 | p23
47 | ((I2013
48 | I3
49 | I1
50 | I23
51 | I13
52 | I59
53 | I4
54 | I60
55 | I1
56 | tp24
57 | (dp25
58 | tp26
59 | Rp27
60 | sS'modified'
61 | p28
62 | g27
63 | sS'title'
64 | p29
65 | VStart
66 | p30
67 | sbsa(dp31
68 | g12
69 | I00
70 | sg13
71 | (lp32
72 | I150
73 | aI10
74 | asg15
75 | (itiddlywiki
76 | Tiddler
77 | p33
78 | (dp34
79 | g18
80 | VTwineQuest Demo
81 | p35
82 | sg20
83 | (lp36
84 | sg22
85 | g23
86 | ((I2013
87 | I3
88 | I1
89 | I23
90 | I16
91 | I46
92 | I4
93 | I60
94 | I1
95 | tp37
96 | (dp38
97 | tp39
98 | Rp40
99 | sg28
100 | g40
101 | sg29
102 | VStoryTitle
103 | p41
104 | sbsa(dp42
105 | g12
106 | I00
107 | sg13
108 | (lp43
109 | I290
110 | aI10
111 | asg15
112 | (itiddlywiki
113 | Tiddler
114 | p44
115 | (dp45
116 | g18
117 | VA proposal
118 | p46
119 | sg20
120 | (lp47
121 | sg22
122 | g23
123 | ((I2013
124 | I3
125 | I1
126 | I23
127 | I17
128 | I7
129 | I4
130 | I60
131 | I1
132 | tp48
133 | (dp49
134 | tp50
135 | Rp51
136 | sg28
137 | g51
138 | sg29
139 | VStorySubtitle
140 | p52
141 | sbsa(dp53
142 | g12
143 | I00
144 | sg13
145 | (lp54
146 | I430
147 | aI10
148 | asg15
149 | (itiddlywiki
150 | Tiddler
151 | p55
152 | (dp56
153 | g18
154 | VTwineQuest contributors
155 | p57
156 | sg20
157 | (lp58
158 | sg22
159 | g23
160 | ((I2013
161 | I3
162 | I1
163 | I23
164 | I17
165 | I22
166 | I4
167 | I60
168 | I1
169 | tp59
170 | (dp60
171 | tp61
172 | Rp62
173 | sg28
174 | g62
175 | sg29
176 | VStoryAuthor
177 | p63
178 | sbsa(dp64
179 | g12
180 | I00
181 | sg13
182 | (lp65
183 | I570
184 | aI10
185 | asg15
186 | (itiddlywiki
187 | Tiddler
188 | p66
189 | (dp67
190 | g18
191 | VTwineQuest_proposal.twee
\u000a../TwineQuest.twee
\u000a../TwineQuest.mob.twee
\u000a../TwineQuest.getset.twee
\u000a../eturnerx.tq.helloworld.twee
\u000a../eturnerx.tq.mobnamer.twee
\u000a../eturnerx.tq.mobnamer.elvish.twee
\u000a../eturnerx.tq.mobnamer.goblin.twee
\u000a../eturnerx.tq.mobnamer.roman.twee
\u000a
192 | p68
193 | sg20
194 | (lp69
195 | sg22
196 | g23
197 | ((I2013
198 | I3
199 | I1
200 | I23
201 | I17
202 | I43
203 | I4
204 | I60
205 | I1
206 | tp70
207 | (dp71
208 | tp72
209 | Rp73
210 | sg28
211 | g73
212 | sg29
213 | VStoryIncludes
214 | p74
215 | sbsasS'scale'
216 | p75
217 | I1
218 | ss.
--------------------------------------------------------------------------------
/eturnerx.tq.autosynonym.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.autosynonym.twee About [Twine.private]
2 | VERSION: 20130317
3 | LICENSE: Creative Commons. Attribute. Share.
4 | DESCRIPTION: Automagically replace synonyms to give magical random flavour
5 | HISTORY: made for the "Regen" project began Nov 2012
6 | CONTRIBUTORS: Emmanuel King Turner (Et / eturnerx / @stormrose)
7 | USAGE:
8 | Adds a $$prefix to the wikifier. Just use $$ in normal passage text
9 |
10 | Each line is a synonym set. Items in lines are separated by commas
11 |
12 | The first item in each line is the term in the story to match for
13 | replacement. The first item may not contain spaces.
14 |
15 | The second item is commands. Nothing for now so leave blank.
16 |
17 | The third and subsequent items are the replacements. This may have
18 | spaces if you like.
19 |
20 | e.g.
21 |
22 | celebrate, ,celebrate, praise, mark, observe
23 |
24 |
25 | TODO:
26 | 2nd option modes, like choose once, replace always, choice twice replace one or two, never repeat
27 | Convert to TwineQuest plugin
28 | Make it possible to limit synonym matching to a passage, or global
29 |
30 |
31 | ::eturnerx.tq.autosynonym [tq.system.plugin]
32 | {
33 | version: '0.1.0',
34 |
35 | tag: 'eturnerx.autosynonym',
36 |
37 | onInit: function() {
38 | this._synonyms = [ ];
39 | Wikifier.formatters.push({
40 | name: 'eturner.tq.autosynonym',
41 | match: String.fromCharCode(92) + '$' + String.fromCharCode(92) + '$' + String.fromCharCode(92) + 'S',
42 | handler: function(w) {
43 | var s = w.source.substr(w.matchStart);
44 | if(s.length > 2 && s.indexOf(' ') > 0) {
45 | s = s.substr(2,s.indexOf(' ')-2).toLowerCase();
46 | w.nextMatch = w.matchStart + s.length + 2;
47 | var replacement = s;
48 | var sl = this._autosynonymplugin._synonyms;
49 | var i = sl.length;
50 | while(i > 0) {
51 | i--;
52 | if(sl[i].match == s) {
53 | var candidates = sl[i].candidates;
54 | replacement = candidates[Math.floor(Math.random()*candidates.length)];
55 | break;
56 | }
57 | }
58 | }
59 | insertText(w.output, replacement);
60 | },
61 | _autosynonymplugin: TwineQuest.findPluginById('eturnerx.tq.autosynonym'),
62 | });
63 | },
64 |
65 | onPassage: function(passage) {
66 | var g = passage.text.split(String.fromCharCode(10));
67 | for(var gi in g) {
68 | var l = g[gi].split(',');
69 | if(l.length == 0) continue;
70 | if(l.length < 3) throw('Entry for ' + l[0] + ' is malformed. Use: PATTERNWORD, MODE, REPLACE1, REPLACE2, ....');
71 | var synonymindex = null;
72 | var synonymmode = null;
73 | var synonymcandidates = [];
74 | for(var li in l) {
75 | var t = l[li].trim();
76 | if(t.substr(0,2) == '$$') t = t.substr(2).toLowerCase();
77 | if(synonymindex == null) synonymindex = t.toLowerCase();
78 | else if(synonymmode == null) synonymmode = t;
79 | else synonymcandidates.push(t.toLowerCase());
80 | }
81 | this._synonyms.push({
82 | match: synonymindex,
83 | mode: synonymmode,
84 | last: '',
85 | candidates: synonymcandidates,
86 | });
87 | }
88 | },
89 |
90 | onStart: null,
91 |
92 | onEvent: null,
93 |
94 | _synonyms: null,
95 | }
96 |
--------------------------------------------------------------------------------
/eturnerx.tq.helloworld.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.helloworld.twee About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | PURPOSE:
5 | A simple plugin demonstration.
6 |
7 | This is called TwineQuest.eturnerx.X.twee because it is not "official"
8 | TwineQuest core plugin or to denote a set of plugins that play nice
9 | together/by the same authors.
10 |
11 | USAGE: {hello} / {hello and some text}
12 |
13 | CONTRIBUTORS:
14 | (Add your name as you contribute)
15 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
16 |
17 |
18 | ::eturnerx.tq.helloworld [tq.system.plugin]
19 | {
20 | version: '0.1.1',
21 |
22 | tag: null,
23 |
24 | onInit: function() {
25 | // Nothing to do on init
26 | },
27 |
28 | onPassage: function(passage) {
29 | // Nothing to do when TQ has a passage that matches 'tag'
30 | },
31 |
32 | onStart: function() {
33 | // Register our label and it's handler. It doesn't have any associated data
34 | TwineQuest.registerLabel('hello', this.handleLabel, null, this);
35 | },
36 |
37 | onEvent: function(evt, params) {
38 | },
39 |
40 | handleLabel: function(place, label, params, parser, data, plugin) {
41 | insertElement(place, 'span', null, 'TwineQuest HelloWorld', label + (params.length > 0 ? ' ' : '') + params.join(' '));
42 | },
43 | }
44 |
--------------------------------------------------------------------------------
/eturnerx.tq.mobnamer.elvish.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.mobnamer.elvish About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | Elvish culture name stems for automatic name generation provided by
5 | the eturnerx.tq.mobnamer.twee plugin.
6 | See: the About for eturnerx.tq.mobnamer.twee
7 |
8 | From the examples provided at:
9 | http://forum.codecall.net/topic/49665-java-random-name-generator/#axzz2B24xMDe8
10 |
11 |
12 | CONTRIBUTORS:
13 | (Add your name as you contribute)
14 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
15 |
16 |
17 |
18 | ::eturnerx.tq.mobnamer Elvish [tq.eturnerx.mobnamer.culture]
19 | -ael
20 | -aer
21 | -af
22 | -ah
23 | -am
24 | -ama
25 | -an
26 | -ang +v
27 | -ansr +v
28 | -cael
29 | -dae +c
30 | -dho
31 | -eir
32 | -fi
33 | -fir
34 | -la
35 | -seh
36 | -sel
37 | -ev
38 | -fis
39 | -hu
40 | -ha
41 | -gar
42 | -gil
43 | -ka
44 | -kan
45 | -ya
46 | -za
47 | -zy
48 | -mara
49 | -mai +c
50 | -lue +c
51 | -ny
52 | -she
53 | -sum
54 | -syl
55 | ae +c -c
56 | ael -c
57 | dar
58 | deth +v
59 | dre -v
60 | drim -v
61 | dul
62 | ean -c
63 | el
64 | emar
65 | hal
66 | iat -c
67 | mah
68 | ten
69 | que -v +c
70 | ria
71 | rail
72 | ther
73 | thus
74 | thi
75 | san
76 | +ael -c
77 | +dar
78 | +deth
79 | +dre
80 | +drim
81 | +dul
82 | +ean -c
83 | +el
84 | +emar
85 | +nes
86 | +nin
87 | +oth
88 | +hal
89 | +iat
90 | +mah
91 | +ten
92 | +ther
93 | +thus
94 | +thi
95 | +ran
96 | +ath
97 | +ess
98 | +san
99 | +yth
100 | +las
101 | +lian
102 | +evar
103 |
--------------------------------------------------------------------------------
/eturnerx.tq.mobnamer.goblin.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.mobnamer.goblin About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | Goblin culture name stems for automatic name generation provided by
5 | the eturnerx.tq.mobnamer.twee plugin.
6 | See: the About for eturnerx.tq.mobnamer.twee
7 |
8 | From the examples provided at:
9 | http://forum.codecall.net/topic/49665-java-random-name-generator/#axzz2B24xMDe8
10 |
11 |
12 | CONTRIBUTORS:
13 | (Add your name as you contribute)
14 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
15 |
16 |
17 |
18 | ::eturnerx.tq.mobnamer Goblin [tq.eturnerx.mobnamer.culture]
19 | -waa +c
20 | -boo +c
21 | -gar
22 | -bar
23 | -dar
24 | -jar
25 | -var
26 | -kra
27 | -gra
28 | -dra
29 | -zra
30 | -gob
31 | -dob
32 | -rob
33 | -fob
34 | -zob
35 | -rag
36 | -nag
37 | -dag
38 | bra
39 | ga
40 | da
41 | do
42 | go
43 | ze
44 | sha
45 | naz
46 | zub
47 | zu
48 | na
49 | gor
50 | boo +c
51 | +byr
52 | +gyr
53 | +dyr
54 | +vyr
55 | +zyr
56 | +yr -c
57 | +zog
58 | +rog
59 | +gog
60 | +og -c
61 | +gul
62 | +dul
63 | +bul
64 | +rul
65 | +ul -c
66 | +rgh -v
67 |
--------------------------------------------------------------------------------
/eturnerx.tq.mobnamer.roman.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.mobnamer.roman About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | Roman culture name stems for automatic name generation provided by
5 | the eturnerx.tq.mobnamer.twee plugin.
6 | See: the About for eturnerx.tq.mobnamer.twee
7 |
8 | From the examples provided at:
9 | http://forum.codecall.net/topic/49665-java-random-name-generator/#axzz2B24xMDe8
10 |
11 |
12 | CONTRIBUTORS:
13 | (Add your name as you contribute)
14 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
15 |
16 |
17 |
18 | ::eturnerx.tq.mobnamer Roman [tq.eturnerx.mobnamer.culture]
19 | -a
20 | -al
21 | -au +c
22 | -an
23 | -ba
24 | -be
25 | -bi
26 | -br +v
27 | -da
28 | -di
29 | -do
30 | -du
31 | -e
32 | -eu +c
33 | -fa
34 | bi
35 | be
36 | bo
37 | bu
38 | nul +v
39 | gu
40 | da
41 | au +c -c
42 | fri
43 | gus
44 | +tus
45 | +lus
46 | +lius
47 | +nus
48 | +es
49 | +ius -c
50 | +cus
51 | +tor
52 | +cio
53 | +tin
54 |
--------------------------------------------------------------------------------
/eturnerx.tq.mobnamer.twee:
--------------------------------------------------------------------------------
1 | ::eturnerx.tq.mobnamer.twee About [Twine.private]
2 | LICENSE: Public Domain
3 |
4 | PURPOSE:
5 | This plugin extends TwineQuest.mob and adds the ability to automatically
6 | generate names for mobs
7 |
8 | The basic name segment generation is based on:
9 | http://forum.codecall.net/topic/49665-java-random-name-generator/#axzz2B24xMDe8
10 |
11 |
12 | USAGE:
13 | Initialise a mob without a name assigned.
14 | Specify an optional culture attribute in the mob to select different name generation cultures
15 |
16 |
17 | CONTRIBUTORS:
18 | (Add your name as you contribute)
19 | Emmanuel King Turner (eturnerx / @stormrose / Et) http://eturnerx.com
20 |
21 |
22 |
23 | ::eturnerx.tq.mobnamer [tq.system.plugin]
24 | {
25 | version: '0.1.0',
26 |
27 | tag: 'eturnerx.mobnamer.culture',
28 |
29 | priority: 2000,
30 |
31 | onInit: function() {
32 | this._mobplugin = TwineQuest.findPluginById('TwineQuest.mob');
33 | if(this._mobplugin) {
34 | this._old_onInitMob = this._mobplugin.onInitMob;
35 | this._mobplugin.onInitMob = this.onInitMob;
36 | this._mobplugin['_eturnerx.tq.mobnamer'] = this;
37 | this._cultures = {};
38 | }
39 | },
40 |
41 | onPassage: function(passage) {
42 | if(passage && passage.title && passage.text) {
43 | var culture = passage.title.substring(passage.title.lastIndexOf(' ') + 1);
44 | this.addCulture(culture.toLowerCase(), passage.text);
45 | }
46 | },
47 |
48 | onStart: null,
49 |
50 | onEvent: null,
51 |
52 | onInitMob: function(tid, mob) {
53 | if(mob.name == null) {
54 | mob.name = this['_eturnerx.tq.mobnamer'].generateName(mob.culture ? mob.culture : 'Default');
55 | }
56 | return this['_eturnerx.tq.mobnamer']._old_onInitMob(tid, mob);
57 | },
58 |
59 | addCulture: function(culture, text) {
60 | this._cultures[culture] = { prefix:[], middle:[], suffix:[] };
61 | var g = text.split(String.fromCharCode(10));
62 | for(var gi = 0; gi < g.length; gi++) {
63 | var l = g[gi].split(' ');
64 | var entry = { syllable:null, nextConsonant:false, nextVowel:false, lastConsonant:false, lastVowel:false };
65 | for(var li = 0; li < l.length; li++) {
66 | var t = l[li];
67 | if(entry['syllable'] == null) entry['syllable'] = t;
68 | else if(t == '+c') entry['nextConsonant'] = true;
69 | else if(t == '+v') entry['nextVowel'] = true;
70 | else if(t == '-c') entry['lastConsonant'] = true;
71 | else if(t == '-v') entry['lastVowel'] = true;
72 | }
73 | var c = '';
74 | if(entry['syllable'][0] == '-') {
75 | entry['syllable'] = entry['syllable'].substring(1);
76 | c = entry['syllable'][0];
77 | entry['startsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
78 | c = entry['syllable'][entry['syllable'].length-1];
79 | entry['endsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
80 | this._cultures[culture].prefix.push(entry);
81 | } else if(entry['syllable'][0] == '+') {
82 | entry['syllable'] = entry['syllable'].substring(1);
83 | c = entry['syllable'][0];
84 | entry['startsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
85 | c = entry['syllable'][entry['syllable'].length-1];
86 | entry['endsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
87 | this._cultures[culture].suffix.push(entry);
88 | } else {
89 | c = entry['syllable'][0];
90 | entry['startsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
91 | c = entry['syllable'][entry['syllable'].length-1];
92 | entry['endsWithVowel'] = (c=='a'||c=='e'||c=='i'||c=='o'||c=='u');
93 | this._cultures[culture].middle.push(entry);
94 | }
95 | }
96 | },
97 |
98 | generateName: function(culture) {
99 | if(culture == null) {
100 | culture = 'default';
101 | }
102 | var ns = this._cultures[culture.toLowerCase()];
103 | if(ns == null) ns = this._cultures['default'];
104 | var s1e, s2e, s3e, proceed, ok;
105 | s1e = ns.prefix[Math.floor(Math.random() * ns.prefix.length)];
106 | proceed = -1000;
107 | while(proceed < 0) {
108 | proceed++;
109 | s2e = ns.middle[Math.floor(Math.random() * ns.middle.length)];
110 | ok = true;
111 | if(s1e.nextConsonant == true && s2e.startsWithVowel == true) ok = false;
112 | if(s1e.nextVowel == true && s2e.startsWithVowel == false) ok = false;
113 | if(s2e.lastConsonant == true && s1e.endsWithVowel == true) ok = false;
114 | if(s2e.lastVowel == true && s1e.endsWithVowel == false) ok = false;
115 | if(ok) proceed = 1;
116 | }
117 | if(proceed == 0) s2e = { syllable:'_' };
118 | proceed = -1000;
119 | while(proceed < 0) {
120 | proceed++;
121 | s3e = ns.suffix[Math.floor(Math.random() * ns.suffix.length)];
122 | ok = true;
123 | if(s2e.nextConsonant == true && s3e.startsWithVowel == true) ok = false;
124 | if(s2e.nextVowel == true && s3e.startsWithVowel == false) ok = false;
125 | if(s3e.lastConsonant == true && s2e.endsWithVowel == true) ok = false;
126 | if(s3e.lastVowel == true && s2e.endsWithVowel == false) ok = false;
127 | if(ok) proceed = 1;
128 | }
129 | if(proceed == 0) s3e = { syllable:'_' };
130 | var segment = s1e.syllable + s2e.syllable + s3e.syllable;
131 | segment = segment.substr(0,1).toUpperCase() + segment.substr(1);
132 | return segment;
133 | },
134 |
135 | _mobplugin: null,
136 | _old_onInitMob: null,
137 | _cultures: null,
138 | }
139 |
140 |
141 | ::eturnerx.tq.mobnamer Default [tq.eturnerx.mobnamer.culture]
142 | -a
143 | -al
144 | -au +c
145 | -an
146 | -ba
147 | -be
148 | -bi
149 | -br +v
150 | -da
151 | -di
152 | -do
153 | -du
154 | -e
155 | -eu +c
156 | -fa
157 | bi
158 | be
159 | bo
160 | bu
161 | nul +v
162 | gu
163 | da
164 | au +c -c
165 | fri
166 | gus
167 | +tus
168 | +lus
169 | +lius
170 | +nus
171 | +es
172 | +ius -c
173 | +cus
174 | +tor
175 | +cio
176 | +tin
--------------------------------------------------------------------------------
/examples/9999 Macro name.twee:
--------------------------------------------------------------------------------
1 | ::9999 Macro name.twee [Twine.private]
2 | This passage is used to document the macro, acknowledgements etc.
3 | It does not end up in generated html files due to the tag
4 |
5 | credit Stormrose
6 |
7 | ::9999 Macro name [script]
8 | The actual code for the macro/s
9 |
--------------------------------------------------------------------------------
/examples/Item syntax example.twee:
--------------------------------------------------------------------------------
1 | ::The Golden Axe [TwineQuest.Item]
2 | LABEL: Golden Axe
3 | DESCRIPTION
4 | The Golden Axe of Sega, sort after by Amazons, Dwarves and Warriors. Forged of purist pixels and engraved into the memories of many.
5 |
6 | WEIGHT:5kg
7 | MATERIAL:
8 | Gold Alloy
9 | Leather
10 |
11 | LENGTH:1.5m
12 | SLOT: 2-handed-weapon
13 | ATTACK MODIFIER: +5
14 |
--------------------------------------------------------------------------------
/macros/9999 Macro atend.twee:
--------------------------------------------------------------------------------
1 | ::9999 Macro atend.twee About [Twine.private]
2 | VERSION: 20141206
3 | LICENSE: Public Domain
4 |
5 | USAGE:
6 | <>This text appears at the end of the passage<>
7 |
8 | PURPOSE:
9 | To output certain text at the end of the current passage.
10 |
11 | CONTRIBUTORS:
12 | Emmanuel King Turner (eturnerx / Et / @stormrose)
13 |
14 | ACKNOWLEDGEMENT:
15 | Originally made for use in "Raik" by Harry Giles http://ifdb.tads.org/viewgame?id=j8dfkrype8wk70k
16 | Uses the function decorators from http://me.dt.in.th/page/JavaScript-override/
17 |
18 | ::9999 Macro atend.twee [script]
19 | (function() {
20 | version.extensions.atendmacro = {
21 | major: 1,
22 | minor: 0,
23 | revision: 0
24 | };
25 |
26 | //Function decorators from: http://me.dt.in.th/page/JavaScript-override/
27 | function override(object, methodName, callback) {
28 | object[methodName] = callback(object[methodName])
29 | }
30 | function override_before(extraBehavior) {
31 | return function(original) {
32 | return function() {
33 | extraBehavior.apply(this, arguments)
34 | return original.apply(this, arguments)
35 | }
36 | }
37 | }
38 | function override_after(extraBehavior) {
39 | return function(original) {
40 | return function() {
41 | var returnValue = original.apply(this, arguments)
42 | extraBehavior.apply(this, arguments)
43 | return returnValue
44 | }
45 | }
46 | }
47 |
48 | //Setup a macro to always print text at end of passage.
49 | macros.atend = {};
50 | macros.atend.handler = function(place, macroName, params, parser) {
51 | var srcOffset = parser.source.indexOf(">>", parser.matchStart) + 2,
52 | src = parser.source.slice(srcOffset),
53 | i = src.indexOf('<>');
54 |
55 | if(i > -1) {
56 | if (tale.atend === undefined) {
57 | tale.atend = [ place, '' ];
58 | }
59 | tale.atend[1] += src.substr(0, i);
60 | parser.nextMatch = srcOffset + i + 10;
61 | } else {
62 | throwError(place, "<> can't find a matching <>", parser.fullMatch());
63 | }
64 | };
65 | macros.atendd = { handler: function() {} };
66 | override(Passage.prototype, 'render', override_after(function() {
67 | if(tale.atend !== undefined) {
68 | new Wikifier(tale.atend[0], tale.atend[1]);
69 | tale.atend = undefined;
70 | }
71 | }));
72 | }());
73 |
--------------------------------------------------------------------------------
/macros/9999 Macro br.twee:
--------------------------------------------------------------------------------
1 | ::9999 Macro br.twee About [Twine.private]
2 |
3 | VERSION: 20130317
4 |
5 | LICENSE: Public Domain
6 |
7 | USAGE:
8 | <
>
9 |
10 | (No parameters)
11 |
12 |
13 | PURPOSE:
14 | Gives author control that deals with Twine's "trim whitespace" around
15 | fragments behaviour.
16 | Useful at the start or end of passages.
17 | Useful at the start or end within <><><> blocks
18 | This macro <
> is a shortcut for
19 |
20 | CONTRIBUTORS:
21 | Emmanuel King Turner (eturnerx / Et / @stormrose)
22 |
23 | ACKNOWLEDGEMENT:
24 | Idea came from user frustration expressed here:
25 | http://groups.google.com/d/topic/tweecode/FBgGTBrH8aM/discussion
26 |
27 |
28 | ::9999 Macro br.twee [script]
29 | try { macros['br'] = {
30 | handler: function(place,macroName,params,parser) {
31 | new Wikifier(place, '
');
32 | },
33 | init: function() { }
34 | };} catch(e) {
35 | throwError(place,"Macro br Error: "+e.message);
36 | }
37 |
--------------------------------------------------------------------------------
/macros/9999 Macro while.twee:
--------------------------------------------------------------------------------
1 | ::9999 Macro while.twee About [Twine.private]
2 |
3 | VERSION: 20140827
4 |
5 | LICENSE: CC BY-SA 4.0 | Creative Commons Attribute Share-Alike. http://creativecommons.org/licenses/by-sa/4.0/
6 |
7 | USAGE:
8 | <>
9 | Do stuff.
10 | <>
11 |
12 | PURPOSE:
13 | Implementation of a while loop. Avoids using the awful hacks of the past.
14 |
15 | CONTRIBUTORS:
16 | Emmanuel King Turner (eturnerx / Et / @stormrose)
17 |
18 | ACKNOWLEDGEMENT:
19 | Basic idea taken from the <> macro, but works slightly differently.
20 |
21 |
22 | ::9999 Macro while.twee [script]
23 | try {
24 |
25 | version.extensions.whileMacros = {
26 | major: 1, minor: 0, revision: 0
27 | };
28 |
29 | macros['while'] = {
30 | handler: function(place, macroName, params, parser) {
31 | var srcOffset = parser.source.indexOf(">>", parser.matchStart) + 2,
32 | src = parser.source.slice(srcOffset),
33 | endPos = -1,
34 | condition = parser.fullArgs().trim(),
35 | body = "",
36 | nestlevel = 0,
37 | i = 0;
38 |
39 | for (; i < src.length; i++) {
40 | if (src.substr(i, 8) == "<>") {
44 | nestlevel--;
45 | if (nestlevel < 0) {
46 | endPos = srcOffset + i + 12;
47 | break;
48 | }
49 | }
50 | body += src.charAt(i);
51 | }
52 | body = body.trim();
53 |
54 | if (endPos != -1) {
55 | parser.nextMatch = endPos;
56 | try {
57 | while (internalEval(condition)) {
58 | new Wikifier(place, body);
59 | }
60 | } catch (e) {
61 | throwError(place, "<> bad condition: " + condition, parser.fullMatch());
62 | }
63 | } else {
64 | throwError(place, "I can't find a matching <>", parser.fullMatch());
65 | }
66 | },
67 | init: function() { }
68 | };
69 |
70 | macros["endwhile"] = {
71 | handler: function () {}
72 | };
73 |
74 | } catch(e) {
75 | throwError(place,"Macro while Error: "+e.message);
76 | }
77 |
--------------------------------------------------------------------------------
/mods/9990 Display Console.twee:
--------------------------------------------------------------------------------
1 | ::9990 Display Console About [Twine.private]
2 | LICENSE: Public Domain
3 | VERSION: 20130317
4 | DESCRIPTION:
5 | This provides some hacks to the Jonah story format to support a continuous
6 | scrolling story - similar to the text terminal games of yore.
7 |
8 | Useful for many oldschool text game conversions.
9 | Works best when partnered with a friendly style-sheet
10 | e.g. 9991 Style GreenScreen.twee
11 | 9991 Style BlueScreen.twee
12 |
13 | TECHNICAL:
14 | Replaces the Passage.prototype.render
15 | - Always appends text. Adds a timestamp to the passage id
16 | - Suppresses the passage title and toolbar from Jonah
17 | Replaces the <> macro to deactivate all choices once one has
18 | been selected by the user.
19 |
20 | Probably not compatible with anything else that replaces/extends
21 | - Passage.prototype.render
22 | - <> macro
23 |
24 | CONTRIBUTORS:
25 | Emmanuel King Turner (Et / eturnerx / @stormrose)
26 |
27 |
28 | ::9990 Display Console [script]
29 | // Needed to allow loops back through text while keeping output linear
30 | // Suppress title and toolbar while we're at it
31 | Passage.prototype.render = function() {
32 | var passagediv = insertElement(null, 'div', 'passage' + this.title + 'j' + (new Date).getTime(), 'passage');
33 | passagediv.style.visibility = 'hidden';
34 | passagediv.setAttribute('data-tags', this.tags.join(' '));
35 | var body = insertElement(passagediv, 'div', '', 'body');
36 | new Wikifier(body, this.text);
37 | // event handlers
38 | passagediv.onmouseover = function() { passagediv.className += ' selected' };
39 | passagediv.onmouseout = function() { passagediv.className = passagediv.className.replace(' selected', ''); };
40 | return passagediv;
41 | };
42 |
43 | //And hack the choice macro - no going back!
44 | macros['choice'].activate = function (el, destination) {
45 | var parentDiv = el.parentNode;
46 | while (parentDiv.className.indexOf('body') == -1)
47 | parentDiv = parentDiv.parentNode;
48 | var title = parentDiv.parentNode.id.substr(7);
49 | var links = parentDiv.getElementsByTagName('a');
50 | var trashed = [];
51 | for (var i = 0; i < links.length; i++)
52 | if (links[i].className.indexOf('choice') != -1) {
53 | var span = document.createElement('span');
54 | span.innerHTML = links[i].innerHTML;
55 | span.className = 'disabled';
56 | links[i].parentNode.insertBefore(span, links[i].nextSibling);
57 | trashed.push(links[i]);
58 | };
59 | tale.get(title).text = '' + parentDiv.childNodes[0].innerHTML + '';
60 | state.display(destination, el);
61 | for (var i = 0; i < trashed.length; i++)
62 | trashed[i].parentNode.removeChild(trashed[i]);
63 | }
64 |
--------------------------------------------------------------------------------
/styles/9991 Style BlueScreen.twee:
--------------------------------------------------------------------------------
1 | ::9991 Style BlueScreen.twee About [Twine.private]
2 | LICENSE: Public Domain
3 | CONTRIBUTORS: Emmanuel King Turner (eturnerx / Et / @stormrose)
4 | VERSION: 20130317
5 | DESCRIPTION:
6 | A blue version of an old console style greenscreen.
7 | Assumes the Jonah storyformat
8 |
9 | USAGE:
10 | Either (A is preferred)
11 | A) Include by listing the file in your StoryIncludes passage
12 | -or-
13 | B) Import the .twee file into your story.
14 |
15 |
16 | ::9991 Style BlueScreen [stylesheet]
17 | .passage .title { display:none; }
18 | body { background-color: #000; color: #36f; font-family: monospace; }
19 | #content2, .passage, #passages, h1, h2, h3 { background-color: #003; color: #69f; font-family: monospace; }
20 | #content2 { padding: 1em 2.5em; }
21 | #passages { padding-bottom: 5em; }
22 | .passage { font-size: 12px; line-height: 17px; }
23 | a.internalLink, a.externalLink, .disabled { color: #06f; }
24 | .disabled { font-style: normal; }
25 | #footer { position: fixed; bottom: 1em; right: 1em; width: 15em; background-color: #000; text-align: left; color: #006; }
26 | h1 { text-align: left; font-size: 28px; line-height: 34px; }
27 | h2 { text-align: left; font-size: 17px; line-height: 17px; font-style: normal; font-weight: bold; }
28 | h3 { text-align: left; font-size: 14px; line-height: 17px; font-weight: bold; margin: 0; padding: 0; }
29 | #storyTitle { display: block; text-align: center; font-size: 34px; line-height: 34px; }
30 |
--------------------------------------------------------------------------------
/styles/9991 Style GreenScreen.twee:
--------------------------------------------------------------------------------
1 | ::9991 Style GreenScreen About [Twine.private]
2 | LICENSE: Public Domain
3 | CONTRIBUTORS: Emmanuel King Turner (eturnerx / Et / @stormrose)
4 | VERSION: 20130317
5 | DESCRIPTION:
6 | A green version of an old console style greenscreen.
7 | Assumes the Jonah storyformat
8 |
9 | USAGE:
10 | Either (A is preferred)
11 | A) Include by listing the file in your StoryIncludes passage
12 | -or-
13 | B) Import the .twee file into your story.
14 |
15 |
16 | ::9991 Style GreenScreen.twee [stylesheet]
17 | .passage .title { display:none; }
18 | body { background-color: #000; color: #6f3; font-family: monospace; }
19 | #content2, .passage, #passages, h1, h2, h3 { background-color: #030; color: #6f3; font-family: monospace; }
20 | #content2 { padding: 1em 2.5em; }
21 | #passages { padding-bottom: 5em; }
22 | .passage { font-size: 12px; line-height: 17px; }
23 | a.internalLink, a.externalLink, .disabled { color: #6f0; }
24 | .disabled { font-style: normal; }
25 | #footer { position: fixed; bottom: 1em; right: 1em; width: 15em; background-color: #000; text-align: left; color: #060; }
26 | h1 { text-align: left; font-size: 28px; line-height: 34px; }
27 | h2 { text-align: left; font-size: 17px; line-height: 17px; font-style: normal; font-weight: bold; }
28 | h3 { text-align: left; font-size: 14px; line-height: 17px; font-weight: bold; margin: 0; padding: 0; }
29 | #storyTitle { display: block; text-align: center; font-size: 34px; line-height: 34px; }
30 |
--------------------------------------------------------------------------------