| /* Copyright (c) 2000 by Kevin Forchione. All Rights Reserved. */ | |
| /* | |
| * TADS LIBRARY EXTENSION | |
| * TMORPH.T | |
| * version 3.0 | |
| * | |
| * tmorph.t provides a simple randomised "text morphing" | |
| * mechanism for TADS users. (Text morphing is the production | |
| * of randomised print strings). | |
| * | |
| * | |
| * Random Setting | |
| * -------------- | |
| * | |
| * To use this function embed the text morphing syntax within the text | |
| * string you wish to display. For example: | |
| * | |
| * "[|A ball/Balls] of searing flame burst[s/] | |
| * out of your magic ring, rebound[s/] off of the ground, and | |
| * vaporize[s/] the kni[fe/ves] before [it/they] | |
| * can reach you."; | |
| * | |
| * Place the elements to be morphed within [] brackets. No string | |
| * notation should be used inside of the brackets, as everything is | |
| * assumed to be text. | |
| * | |
| * Each separate element of the morphing text should be separated by | |
| * the '/' delimeter. If you do not wish to display any text simply | |
| * leave the element blank, for example: [silver/gold/] watch." | |
| * consists of 3 morphing elements, which would display: | |
| * | |
| * gold watch | |
| * silver watch | |
| * watch | |
| * | |
| * You can and should initialise the random generation at the beginning | |
| * of a display sequence by putting the '|' initialiser at the beginning | |
| * of the morphing sequence, e.g. [|apple/pear/peach]. The value used | |
| * by subsequent text morphing syntax will use the value set by the | |
| * initialiser. | |
| * | |
| * Note that the sequence generated is random unless you specify a | |
| * sequencer_name and style in the initialisation section. For example, | |
| * | |
| * MorphSequencer | |
| * -------------- | |
| * | |
| * [ringseq seq|A ball/Balls/A mighty fireball] | |
| * | |
| * will dynamically create a sequencer object with the noun property of | |
| * 'ringseq'. This object will be initialized with a value of 1, which | |
| * means that your text morphing string will begin with #1 in its | |
| * morphing element list and sequentially progress each time the | |
| * text switch with the initialiser is called. When the end of the list | |
| * is reached the last value in the list is displayed from that point | |
| * on. In our example the 1st time, 'A ball' is displayed; the 2nd, | |
| * 'Balls' displays, and all subsequent displays are 'A mighty | |
| * fireball'. | |
| * | |
| * MorphRandomizer | |
| * --------------- | |
| * | |
| * [ringrnd rnd|A ball/Balls/A mighty fireball] | |
| * | |
| * will dynamically create a sequencer object with the noun property of | |
| * 'ringrnd'. Display is produced in a completely random fashion. | |
| * | |
| * MorphModulus | |
| * ------------ | |
| * | |
| * [ringmod mod|A ball/Balls/A mighty fireball] | |
| * | |
| * will dynamically create a sequencer object with the noun property of | |
| * 'ringmod'. This object will be initialized with a value of 1, which | |
| * means that your text morphing string will begin with #1 in its | |
| * morphing element list and sequentially progress each time the text | |
| * switch with the initialiser is called. When the end of the list | |
| * is reached display starts over from the beginning. | |
| * | |
| * MorphRedRndSeq | |
| * -------------- | |
| * | |
| * [ringrrs rrs|A ball/Balls/A mighty fireball] | |
| * | |
| * will dynamically create a sequencer object with the noun property of | |
| * 'ringrrs'. This object works with a self-reducing random selection | |
| * list that then returns the last displayed element when the list has | |
| * been exhausted. | |
| * | |
| * MorphRedRndMod | |
| * -------------- | |
| * | |
| * [ringmod mod|A ball/Balls/A mighty fireball] | |
| * | |
| * will dynamically create a sequencer object with the noun property of | |
| * 'ringmod'. This object works with a self-reducing random selection | |
| * list that then resets the list when the list has been exhausted. | |
| * | |
| * Dynamic Control | |
| * --------------- | |
| * | |
| * For more dynamic control, based on game-state, you should first set | |
| * the value of global.randomHold and remove any initialiser from the | |
| * text morph. For example: | |
| * | |
| * global.randomHold = object.knifeCount; | |
| * [A ball/Balls/A mighty fireball] | |
| * | |
| *---------------------------------------------------------------------- | |
| * REQUIREMENTS | |
| * | |
| * + HTML TADS 2.2.6 or later | |
| * + Should be #included after ADV.T and STD.T or WorldClass.t or | |
| * pianosa.t | |
| * | |
| *---------------------------------------------------------------------- | |
| * IMPORTANT LIBRARY INTERFACE AND MODIFICATION | |
| * | |
| * None. | |
| * | |
| *---------------------------------------------------------------------- | |
| * COPYRIGHT NOTICE | |
| * | |
| * You may modify and use this file in any way you want, provided that | |
| * if you redistribute modified copies of this file in source form, the | |
| * copies must include the original copyright notice (including this | |
| * paragraph), and must be clearly marked as modified from the original | |
| * version. | |
| * | |
| *------------------------------------------------------------------------------ | |
| * REVISION HISTORY | |
| * | |
| * 20-Feb-00: Creation. | |
| * 21-Feb-00: Modified to include init in the function call. | |
| */ | |
| #define __TMORPH_MODULE_ | |
| #pragma C+ | |
| morphFilter: function; | |
| formatMorphText: function; | |
| tm: function; | |
| morphTracker: function; | |
| /* | |
| * morphFilter: function(str) | |
| * | |
| * Set this filter in commonInit(). It will continue to pass str to the | |
| * formatMorphText() function until the function returns nil. | |
| * | |
| * setOutputFilter(morphFilter); | |
| */ | |
| morphFilter: function(str) | |
| { | |
| local ret; | |
| ret = formatMorphText(str); | |
| while(ret) | |
| { | |
| str = ret; | |
| ret = formatMorphText(str); | |
| } | |
| return str; | |
| } | |
| /* | |
| * formatMorphText: function(str) | |
| * | |
| * This function locates the first occurrence of a "text switch" and | |
| * replaces it with the generated switch value from tm(). | |
| */ | |
| formatMorphText: function(str) | |
| { | |
| local i, f1, f2, bit, len, val, ret, grp, newstr = ''; | |
| // Find the "text switch" | |
| ret = reSearch('%[([^%[]*/+[^%[]*)%]', str); | |
| if (ret == nil) return nil; | |
| f1 = ret[1]; | |
| f2 = ret[2]; | |
| // Get the information within the brackets | |
| grp = reGetGroup(1); | |
| bit = grp[3]; | |
| // Search for '|' initialiser symbol and set init val | |
| ret = reSearch('(.*)%|', bit); | |
| if (ret != nil) | |
| { | |
| grp = reGetGroup(1); | |
| if (grp != nil) | |
| { | |
| if (grp[2] > 0) | |
| val = grp[3]; | |
| else val = 0; | |
| } | |
| else val = nil; | |
| // strip initialiser symbol and any val from bit | |
| bit = substr(bit, ret[2]+1, length(bit)); | |
| } | |
| // Translate switches into a single value | |
| bit = tm(bit, val); | |
| // Build new string | |
| if (f1 != 1) | |
| newstr += substr(str, 1, f1-1); | |
| newstr += bit; | |
| if (f1+f2 != length(str)) | |
| newstr += substr(str, f1+f2, length(str)); | |
| return newstr; | |
| } | |
| /* | |
| * tm: function(str, val) | |
| * | |
| * This function creates a list of single-quote strings from the str | |
| * parameter, using '/' as delimiters. It also sets the | |
| * global.randomHold used to maintain morphing consistency. | |
| */ | |
| tm: function(str, val) | |
| { | |
| local i, s, w = '', list = []; | |
| for (i = 1; i <= length(str); ++i) | |
| { | |
| s = substr(str, i, 1); | |
| if (s == '/') | |
| { | |
| list += w; | |
| w = ''; | |
| } | |
| else w += s; | |
| } | |
| list += w; | |
| if (val == 0) | |
| global.randomHold = val; | |
| else if (val != nil) | |
| global.randomHold = morphTracker(val, length(list)); | |
| if (proptype(global, &randomHold) != DTY_NUMBER | |
| || global.randomHold < 1) | |
| global.randomHold = _rand(length(list)); | |
| return list[global.randomHold]; | |
| } | |
| /* | |
| * morphTracker: function(str, len) | |
| * | |
| * Function creates a dynamic object using the sequence_name provided | |
| * by the initialisation area of the text morph. This object is | |
| * initialised with val and given the noun vocabulary of the | |
| * sequence_name. | |
| * | |
| * If no val was provided then the object is initialised for position | |
| * 1 in the list of morphing elements. | |
| */ | |
| morphTracker: function(str, len) | |
| { | |
| local tokenList, typeList, objList, mt, tk, ty, o; | |
| tokenList = parserTokenize(str); | |
| typeList = parserGetTokTypes(tokenList); | |
| tk = tokenList[1]; | |
| ty = typeList[1]; | |
| if (length(tokenList) == 2) | |
| mt = tokenList[2]; | |
| else mt = 'rnd'; | |
| objList = parserDictLookup([tk], [ty]); | |
| if (objList && length(objList)) | |
| o = objList[1]; | |
| else | |
| { | |
| switch(mt) | |
| { | |
| case 'seq': | |
| o = MorphSequencer.instantiate(tk, len); | |
| break; | |
| case 'mod': | |
| o = MorphModulus.instantiate(tk, len); | |
| break; | |
| case 'rrm': | |
| o = MorphRedRandMod.instantiate(tk, len); | |
| break; | |
| case 'rrs': | |
| o = MorphRedRandSeq.instantiate(tk, len); | |
| break; | |
| default: | |
| o = MorphRandomizer.instantiate(tk, len); | |
| break; | |
| } | |
| } | |
| return o.getVal; | |
| } | |
| class MorphSequencer: object | |
| noun = '' | |
| len = 0 | |
| val = 0 | |
| getVal = { | |
| self.val++; | |
| if (self.val > self.len) | |
| self.val = len; | |
| return self.val; | |
| } | |
| instantiate(tk, l) = { | |
| local x = new MorphSequencer; | |
| x.len = l; | |
| addword(x, &noun, tk); | |
| return x; | |
| } | |
| ; | |
| class MorphRandomizer: MorphSequencer | |
| getVal = { | |
| self.val = _rand(self.len); | |
| return self.val; | |
| } | |
| instantiate(tk, l, ) = { | |
| local x = new MorphRandomizer; | |
| x.len = l; | |
| addword(x, &noun, tk); | |
| return x; | |
| } | |
| ; | |
| class MorphModulus: MorphSequencer | |
| getVal = { | |
| self.val++; | |
| if (self.val > self.len) | |
| self.val = 1; | |
| return self.val; | |
| } | |
| instantiate(tk, l) = { | |
| local x = new MorphModulus; | |
| x.len = l; | |
| addword(x, &noun, tk); | |
| return x; | |
| } | |
| ; | |
| class MorphRedRandMod: MorphSequencer | |
| rndList = [] | |
| getVal = { | |
| local i, ln, n, newList = []; | |
| ln = length(self.rndList); | |
| if (ln == 0) | |
| { | |
| // rebuild the rndList | |
| ln = self.len; | |
| self.rndList = []; | |
| for (i = 1; i <= ln; ++i) | |
| self.rndList += i; | |
| } | |
| n = _rand(ln); | |
| self.val = self.rndList[n]; | |
| for (i = 1; i <= ln; ++i) | |
| if (self.rndList[i] != self.val) | |
| newList += self.rndList[i]; | |
| self.rndList = newList; | |
| return self.val; | |
| } | |
| instantiate(tk, l) = { | |
| local x = new MorphRedRandMod; | |
| local i; | |
| x.len = l; | |
| x.rndList = []; | |
| for (i = 1; i <= l; ++i) | |
| x.rndList += i; | |
| addword(x, &noun, tk); | |
| return x; | |
| } | |
| ; | |
| class MorphRedRandSeq: MorphSequencer | |
| rndList = [] | |
| getVal = { | |
| local i, ln, n, newList = []; | |
| ln = length(self.rndList); | |
| if (ln == 0) | |
| { | |
| return self.val; | |
| } | |
| n = _rand(ln); | |
| self.val = self.rndList[n]; | |
| for (i = 1; i <= ln; ++i) | |
| if (self.rndList[i] != self.val) | |
| newList += self.rndList[i]; | |
| self.rndList = newList; | |
| return self.val; | |
| } | |
| instantiate(tk, l) = { | |
| local x = new MorphRedRandSeq; | |
| local i; | |
| x.len = l; | |
| x.rndList = []; | |
| for (i = 1; i <= l; ++i) | |
| x.rndList += i; | |
| addword(x, &noun, tk); | |
| return x; | |
| } | |
| ; | |
| #pragma C- | |
Xet Storage Details
- Size:
- 11.9 kB
- Xet hash:
- 7ea5028c4c2558fafdd382a511a0ec5ad736672fa383ceec0bb3f0793300d535
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.